Refactored and reformatted code to use less static variables

This commit is contained in:
CrushedPixel
2015-04-23 14:09:54 +02:00
parent f22416be2c
commit 0003f040ed
109 changed files with 9037 additions and 10229 deletions

View File

@@ -1,17 +1,18 @@
package eu.crushedpixel.replaymod; package eu.crushedpixel.replaymod;
import java.io.File; import eu.crushedpixel.replaymod.api.client.ApiClient;
import java.io.IOException; import eu.crushedpixel.replaymod.chat.ChatMessageHandler;
import eu.crushedpixel.replaymod.events.*;
import javax.swing.JOptionPane; import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import eu.crushedpixel.replaymod.registry.FileCopyHandler; import eu.crushedpixel.replaymod.registry.FileCopyHandler;
import org.apache.commons.io.FilenameUtils; import eu.crushedpixel.replaymod.registry.KeybindRegistry;
import eu.crushedpixel.replaymod.renderer.SafeEntityRenderer;
import eu.crushedpixel.replaymod.replay.ReplaySender;
import eu.crushedpixel.replaymod.settings.ReplaySettings;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.Mod.EventHandler;
@@ -19,25 +20,12 @@ import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import eu.crushedpixel.replaymod.api.client.ApiClient; import org.apache.commons.io.FilenameUtils;
import eu.crushedpixel.replaymod.api.client.ApiException;
import eu.crushedpixel.replaymod.events.GuiEventHandler; import java.io.File;
import eu.crushedpixel.replaymod.events.GuiReplayOverlay;
import eu.crushedpixel.replaymod.events.KeyInputHandler;
import eu.crushedpixel.replaymod.events.RecordingHandler;
import eu.crushedpixel.replaymod.events.TickAndRenderListener;
import eu.crushedpixel.replaymod.gui.GuiReplaySaving;
import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import eu.crushedpixel.replaymod.registry.KeybindRegistry;
import eu.crushedpixel.replaymod.registry.LightingHandler;
import eu.crushedpixel.replaymod.renderer.SafeEntityRenderer;
import eu.crushedpixel.replaymod.settings.ReplaySettings;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
@Mod(modid = ReplayMod.MODID, version = ReplayMod.VERSION) @Mod(modid = ReplayMod.MODID, version = ReplayMod.VERSION)
public class ReplayMod public class ReplayMod {
{
//TODO: Set ReplayHandler replaying to false when replay is exited //TODO: Set ReplayHandler replaying to false when replay is exited
//TODO: Hide Titles upon hurrying //TODO: Hide Titles upon hurrying
@@ -58,22 +46,16 @@ public class ReplayMod
public static final String MODID = "replaymod"; public static final String MODID = "replaymod";
public static final String VERSION = "0.0.1"; public static final String VERSION = "0.0.1";
public static final ApiClient apiClient = new ApiClient();
private static final Minecraft mc = Minecraft.getMinecraft(); private static final Minecraft mc = Minecraft.getMinecraft();
public static GuiReplayOverlay overlay = new GuiReplayOverlay(); public static GuiReplayOverlay overlay = new GuiReplayOverlay();
public static ReplaySettings replaySettings; public static ReplaySettings replaySettings;
public static Configuration config; public static Configuration config;
public static boolean firstMainMenu = true; public static boolean firstMainMenu = true;
public static RecordingHandler recordingHandler; public static RecordingHandler recordingHandler;
public static ChatMessageHandler chatMessageHandler = new ChatMessageHandler();
public static ReplaySender replaySender;
public static int TP_DISTANCE_LIMIT = 128; public static int TP_DISTANCE_LIMIT = 128;
public static final ApiClient apiClient = new ApiClient();
public static FileCopyHandler fileCopyHandler; public static FileCopyHandler fileCopyHandler;
// The instance of your mod that Forge uses. // The instance of your mod that Forge uses.
@@ -125,7 +107,7 @@ public class ReplayMod
//clean up replay_recordings folder //clean up replay_recordings folder
removeTmcprFiles(); removeTmcprFiles();
/*
boolean auth = false; boolean auth = false;
try { try {
auth = AuthenticationHandler.hasDonated(Minecraft.getMinecraft().getSession().getPlayerID()); auth = AuthenticationHandler.hasDonated(Minecraft.getMinecraft().getSession().getPlayerID());
@@ -138,14 +120,14 @@ public class ReplayMod
JOptionPane.showMessageDialog(null, "It seems like you didn't donate, so you can't use the Replay Mod yet."); JOptionPane.showMessageDialog(null, "It seems like you didn't donate, so you can't use the Replay Mod yet.");
FMLCommonHandler.instance().exitJava(0, false); FMLCommonHandler.instance().exitJava(0, false);
} }
*/
} }
private void removeTmcprFiles() { private void removeTmcprFiles() {
File folder = ReplayFileIO.getReplayFolder(); File folder = ReplayFileIO.getReplayFolder();
for(File f : folder.listFiles()) { for(File f : folder.listFiles()) {
if(("."+FilenameUtils.getExtension(f.getAbsolutePath())).equals(ConnectionEventHandler.TEMP_FILE_EXTENSION)) { if(("." + FilenameUtils.getExtension(f.getAbsolutePath())).equals(ConnectionEventHandler.TEMP_FILE_EXTENSION)) {
f.delete(); f.delete();
} }
} }

View File

@@ -1,5 +1,12 @@
package eu.crushedpixel.replaymod.api.client; package eu.crushedpixel.replaymod.api.client;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import eu.crushedpixel.replaymod.api.client.holders.*;
import eu.crushedpixel.replaymod.utils.StreamTools;
import org.apache.commons.io.FileUtils;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -9,25 +16,10 @@ import java.nio.file.Files;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.util.List; import java.util.List;
import org.apache.commons.io.FileUtils;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import eu.crushedpixel.replaymod.api.client.holders.ApiError;
import eu.crushedpixel.replaymod.api.client.holders.AuthKey;
import eu.crushedpixel.replaymod.api.client.holders.Donated;
import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
import eu.crushedpixel.replaymod.api.client.holders.SearchResult;
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 { public class ApiClient {
private static Gson gson = new Gson(); private static final Gson gson = new Gson();
private static JsonParser jsonParser = new JsonParser(); private static final JsonParser jsonParser = new JsonParser();
public AuthKey getLogin(String username, String password) throws IOException, ApiException { public AuthKey getLogin(String username, String password) throws IOException, ApiException {
QueryBuilder builder = new QueryBuilder(ApiMethods.login); QueryBuilder builder = new QueryBuilder(ApiMethods.login);
@@ -92,7 +84,7 @@ public class ApiClient {
builder.put("id", file); builder.put("id", file);
String url = builder.toString(); String url = builder.toString();
URL website = new URL(url); URL website = new URL(url);
HttpURLConnection con = (HttpURLConnection)website.openConnection(); HttpURLConnection con = (HttpURLConnection) website.openConnection();
InputStream is = con.getInputStream(); InputStream is = con.getInputStream();
if(con.getResponseCode() == 200) { if(con.getResponseCode() == 200) {
@@ -104,7 +96,8 @@ public class ApiClient {
if(err.getDesc() != null) { if(err.getDesc() != null) {
throw new ApiException(err); throw new ApiException(err);
} }
} catch(Exception e) {} } catch(Exception e) {
}
} }
} }
@@ -137,7 +130,7 @@ public class ApiClient {
if(idList == null) return null; if(idList == null) return null;
String ids = ""; String ids = "";
Integer x=0; Integer x = 0;
for(Object id : idList) { for(Object id : idList) {
x++; x++;
ids += id.toString(); ids += id.toString();

View File

@@ -1,28 +1,19 @@
package eu.crushedpixel.replaymod.api.client; package eu.crushedpixel.replaymod.api.client;
import java.io.BufferedReader; import com.google.gson.Gson;
import java.io.DataOutputStream; import eu.crushedpixel.replaymod.api.client.holders.ApiError;
import java.io.File; import eu.crushedpixel.replaymod.api.client.holders.Category;
import java.io.FileInputStream; import eu.crushedpixel.replaymod.gui.online.GuiUploadFile;
import java.io.IOException;
import java.io.InputStream; import java.io.*;
import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import com.google.gson.Gson;
import com.google.gson.JsonParser;
import eu.crushedpixel.replaymod.api.client.holders.ApiError;
import eu.crushedpixel.replaymod.api.client.holders.Category;
import eu.crushedpixel.replaymod.gui.online.GuiUploadFile;
public class FileUploader { public class FileUploader {
private static Gson gson = new Gson(); private static final Gson gson = new Gson();
private static JsonParser jsonParser = new JsonParser();
private boolean uploading = false; private boolean uploading = false;
private long filesize; private long filesize;
@@ -37,7 +28,6 @@ public class FileUploader {
private String boundary = "*****"; private String boundary = "*****";
private GuiUploadFile parent; private GuiUploadFile parent;
//private CountingHttpEntity counter;
public void uploadFile(GuiUploadFile gui, String auth, String filename, List<String> tags, File file, Category category) throws IOException, ApiException, RuntimeException { public void uploadFile(GuiUploadFile gui, String auth, String filename, List<String> tags, File file, Category category) throws IOException, ApiException, RuntimeException {
parent = gui; parent = gui;
@@ -47,23 +37,23 @@ public class FileUploader {
if(uploading) throw new RuntimeException("FileUploader is already uploading"); if(uploading) throw new RuntimeException("FileUploader is already uploading");
uploading = true; uploading = true;
String postData = "?auth="+auth+"&category="+category.getId(); String postData = "?auth=" + auth + "&category=" + category.getId();
if(tags.size() > 0) { if(tags.size() > 0) {
postData += "&tags="; postData += "&tags=";
for(String tag : tags) { for(String tag : tags) {
postData += tag; postData += tag;
if(!tag.equals(tags.get(tags.size()-1))) { if(!tag.equals(tags.get(tags.size() - 1))) {
postData += ","; postData += ",";
} }
} }
} }
postData +="&name="+URLEncoder.encode(filename, "UTF-8"); postData += "&name=" + URLEncoder.encode(filename, "UTF-8");
System.out.println(postData); System.out.println(postData);
String url = "http://ReplayMod.com/api/upload_file"+postData; String url = "http://ReplayMod.com/api/upload_file" + postData;
HttpURLConnection con = (HttpURLConnection)new URL(url).openConnection(); HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setUseCaches(false); con.setUseCaches(false);
con.setDoOutput(true); con.setDoOutput(true);
con.setRequestMethod("POST"); con.setRequestMethod("POST");
@@ -75,7 +65,7 @@ public class FileUploader {
HashMap<String, String> params = new HashMap<String, String>(); HashMap<String, String> params = new HashMap<String, String>();
params.put("auth", auth); params.put("auth", auth);
params.put("name", filename); params.put("name", filename);
params.put("category", category.getId()+""); params.put("category", category.getId() + "");
DataOutputStream request = new DataOutputStream(con.getOutputStream()); DataOutputStream request = new DataOutputStream(con.getOutputStream());
@@ -124,12 +114,11 @@ public class FileUploader {
BufferedReader r = new BufferedReader(new InputStreamReader(is)); BufferedReader r = new BufferedReader(new InputStreamReader(is));
info = null; info = null;
if(responseCode != 200) { if(responseCode != 200) {
ApiError error = new ApiError(-1, "An unknown error occured");
String json = ""; String json = "";
while(r.ready()) { while(r.ready()) {
json += r.readLine(); json += r.readLine();
} }
error = gson.fromJson(json, ApiError.class); ApiError error = gson.fromJson(json, ApiError.class);
info = error.getDesc(); info = error.getDesc();
System.out.println(info); System.out.println(info);
} }
@@ -147,7 +136,7 @@ public class FileUploader {
public float getUploadProgress() { public float getUploadProgress() {
if(!uploading || filesize == 0) return 0; if(!uploading || filesize == 0) return 0;
return (float)((double)current/(double)filesize); return (float) ((double) current / (double) filesize);
} }
public boolean isUploading() { public boolean isUploading() {

View File

@@ -1,12 +1,11 @@
package eu.crushedpixel.replaymod.api.client; package eu.crushedpixel.replaymod.api.client;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import com.google.gson.JsonObject;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
public class GsonApiClient { public class GsonApiClient {
private static final JsonParser parser = new JsonParser(); private static final JsonParser parser = new JsonParser();
@@ -21,7 +20,7 @@ public class GsonApiClient {
return wrapWithJson(apiResult); return wrapWithJson(apiResult);
} }
public static JsonElement invokeJson(String apiKey, String method, Map<String,Object> paramMap) throws IOException, ApiException { public static JsonElement invokeJson(String apiKey, String method, Map<String, Object> paramMap) throws IOException, ApiException {
String apiResult = SimpleApiClient.invoke(method, paramMap); String apiResult = SimpleApiClient.invoke(method, paramMap);
return wrapWithJson(apiResult); return wrapWithJson(apiResult);
} }

View File

@@ -10,68 +10,27 @@ public class QueryBuilder {
public static final String API_BASE_URL = "http://ReplayMod.com/api/"; public static final String API_BASE_URL = "http://ReplayMod.com/api/";
public String apiMethod; public String apiMethod;
public Map<String,String> paramMap; public Map<String, String> paramMap;
/**
* Creates an empty QueryBuilder from a given apikey.
* <br>Note that in order to use the QueryBuilder an apiMethod String has to be set.
* @param apiKey The apikey to use
*/
public QueryBuilder() { public QueryBuilder() {
this(null); this(null);
} }
/**
* Creates an empty QueryBuilder from a given apikey and apiMethod.
*
* @param apiKey The apikey to use
* @param apiMethod The apiMethod to use
*/
public QueryBuilder(String apiMethod) { public QueryBuilder(String apiMethod) {
this.apiMethod = apiMethod; this.apiMethod = apiMethod;
} }
/**
* Creates a QueryBuilder from a given apikey and apiMethod containing a single key/value parameter.
*
* @param apiKey The apikey to use
* @param apiMethod The apiMethod to use
* @param key The parameter key
* @param value The parameter value
*/
public QueryBuilder(String apiMethod, String key, String value) { public QueryBuilder(String apiMethod, String key, String value) {
this(apiMethod); this(apiMethod);
put(key, value); put(key, value);
} }
/**
* Creates a QueryBuilder from a given apikey and apiMethod containing two key/value parameters.
*
* @param apiKey The apikey to use
* @param apiMethod The apiMethod to use
* @param key1 The first parameter key
* @param value1 The first parameter value
* @param key2 The second parameter key
* @param value2 The second parameter value
*/
public QueryBuilder(String apiMethod, String key1, String value1, String key2, String value2) { public QueryBuilder(String apiMethod, String key1, String value1, String key2, String value2) {
this(apiMethod); this(apiMethod);
put(key1, value1); put(key1, value1);
put(key2, value2); put(key2, value2);
} }
/**
* Creates a QueryBuilder from a given apikey and apiMethod containing three key/value parameters.
*
* @param apiKey The apikey to use
* @param apiMethod The apiMethod to use
* @param key1 The first parameter key
* @param value1 The first parameter value
* @param key2 The second parameter key
* @param value2 The second parameter value
* @param key3 The third parameter key
* @param value3 The third parameter value
*/
public QueryBuilder(String apiMethod, String key1, String value1, String key2, String value2, String key3, String value3) { public QueryBuilder(String apiMethod, String key1, String value1, String key2, String value2, String key3, String value3) {
this(apiMethod); this(apiMethod);
put(key1, value1); put(key1, value1);
@@ -79,62 +38,33 @@ public class QueryBuilder {
put(key3, value3); put(key3, value3);
} }
/**
* Adds a key/value parameter to the QueryBuilder.
* @param key The parameter key
* @param value The parameter value
*/
public void put(String key, Object value) { public void put(String key, Object value) {
if(key != null && value != null) { if(key != null && value != null) {
if(paramMap == null) { if(paramMap == null) {
paramMap = new HashMap<String,String>(); paramMap = new HashMap<String, String>();
} }
paramMap.put(key, value.toString()); paramMap.put(key, value.toString());
} }
} }
/**
* Adds two key/value parameters to the QueryBuilder.
* @param key1 The first parameter key
* @param value1 The first parameter value
* @param key2 The second parameter key
* @param value2 The second parameter value
*/
public void put(String key1, Object value1, String key2, Object value2) { public void put(String key1, Object value1, String key2, Object value2) {
put(key1, value1); put(key1, value1);
put(key2, value2); put(key2, value2);
} }
/**
* Adds three key/value parameters to the QueryBuilder.
* @param key1 The first parameter key
* @param value1 The first parameter value
* @param key2 The second parameter key
* @param value2 The second parameter value
* @param key3 The third parameter key
* @param value3 The third parameter value
*/
public void put(String key1, Object value1, String key2, Object value2, String key3, Object value3) { public void put(String key1, Object value1, String key2, Object value2, String key3, Object value3) {
put(key1, value1); put(key1, value1);
put(key2, value2); put(key2, value2);
put(key3, value3); put(key3, value3);
} }
/** public void put(Map<String, Object> paraMap) {
* Adds a map of key/value parameters to the QueryBuilder.
* @param paraMap The map to add
*/
public void put(Map<String,Object> paraMap) {
if(paraMap == null) return; if(paraMap == null) return;
for(String key: paraMap.keySet()) { for(String key : paraMap.keySet()) {
put(key,paraMap.get(key)); put(key, paraMap.get(key));
} }
} }
/**
* Creates an URL from the QueryBuilder using the given apikey and apiMethod and applies all
* parameters to it.
*/
public String toString() { public String toString() {
if(apiMethod == null) throw new IllegalArgumentException("apiMethod may not be null"); if(apiMethod == null) throw new IllegalArgumentException("apiMethod may not be null");
@@ -148,7 +78,7 @@ public class QueryBuilder {
try { try {
if(paramMap != null) { if(paramMap != null) {
boolean first = true; boolean first = true;
for(String paramName: paramMap.keySet()) { for(String paramName : paramMap.keySet()) {
if(first) sb.append("?"); if(first) sb.append("?");
if(!first) sb.append("&"); if(!first) sb.append("&");
first = false; first = false;
@@ -159,7 +89,7 @@ public class QueryBuilder {
} }
} }
return sb.toString(); return sb.toString();
} catch (UnsupportedEncodingException e) { } catch(UnsupportedEncodingException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

View File

@@ -1,19 +1,18 @@
package eu.crushedpixel.replaymod.api.client; package eu.crushedpixel.replaymod.api.client;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
public class SearchPagination { public class SearchPagination {
private final SearchQuery searchQuery;
private int page; private int page;
private List<FileInfo> files = new ArrayList<FileInfo>(); private List<FileInfo> files = new ArrayList<FileInfo>();
private final SearchQuery searchQuery;
public SearchPagination(SearchQuery searchQuery) { public SearchPagination(SearchQuery searchQuery) {
this.page = -1; this.page = -1;
this.searchQuery = searchQuery; this.searchQuery = searchQuery;

View File

@@ -9,7 +9,8 @@ public class SearchQuery {
public String player, tag, version, server, name, auth; public String player, tag, version, server, name, auth;
public Integer category, offset; public Integer category, offset;
public SearchQuery() {} public SearchQuery() {
}
public SearchQuery(Boolean order, Boolean singleplayer, String player, public SearchQuery(Boolean order, Boolean singleplayer, String player,
String tag, String version, String server, String name, String tag, String version, String server, String name,
@@ -38,7 +39,7 @@ public class SearchQuery {
if(value == null) continue; if(value == null) continue;
query += first ? "?" : "&"; query += first ? "?" : "&";
first = false; first = false;
query += f.getName()+"="; query += f.getName() + "=";
query += URLEncoder.encode(String.valueOf(value), "UTF-8"); query += URLEncoder.encode(String.valueOf(value), "UTF-8");
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -1,18 +1,17 @@
package eu.crushedpixel.replaymod.api.client; package eu.crushedpixel.replaymod.api.client;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import eu.crushedpixel.replaymod.api.client.holders.ApiError;
import eu.crushedpixel.replaymod.utils.StreamTools;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.util.Map; import java.util.Map;
import com.google.gson.Gson;
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 { public class SimpleApiClient {
private static final JsonParser jsonParser = new JsonParser(); private static final JsonParser jsonParser = new JsonParser();
@@ -20,6 +19,7 @@ public class SimpleApiClient {
/** /**
* Returns a Json String from the given QueryBuilder * Returns a Json String from the given QueryBuilder
*
* @param query The QueryBuilder to use * @param query The QueryBuilder to use
* @return A Json String from the API * @return A Json String from the API
* @throws IOException * @throws IOException
@@ -31,6 +31,7 @@ public class SimpleApiClient {
/** /**
* Returns a Json String from the given URL * Returns a Json String from the given URL
*
* @param url The URL to parse the Json from * @param url The URL to parse the Json from
* @return A Json String from the API * @return A Json String from the API
* @throws IOException * @throws IOException
@@ -42,6 +43,7 @@ public class SimpleApiClient {
/** /**
* Returns a Json String from the API * Returns a Json String from the API
*
* @param apiKey The apikey to use * @param apiKey The apikey to use
* @param method The apiMethod to be called * @param method The apiMethod to be called
* @param paramMap The parameters to apply * @param paramMap The parameters to apply
@@ -49,12 +51,13 @@ public class SimpleApiClient {
* @throws IOException * @throws IOException
* @throws ApiException * @throws ApiException
*/ */
public static String invoke(String method, Map<String,Object> paramMap) throws IOException, ApiException { public static String invoke(String method, Map<String, Object> paramMap) throws IOException, ApiException {
return invokeImpl(method, paramMap); return invokeImpl(method, paramMap);
} }
/** /**
* Returns a Json String from the API * Returns a Json String from the API
*
* @param apiKey The apikey to use * @param apiKey The apikey to use
* @param method The apiMethod to be called * @param method The apiMethod to be called
* @return A Json String from the API * @return A Json String from the API
@@ -74,12 +77,12 @@ public class SimpleApiClient {
HttpURLConnection.setFollowRedirects(false); HttpURLConnection.setFollowRedirects(false);
try { try {
URL url = new URL(urlString); URL url = new URL(urlString);
httpUrlConnection = (HttpURLConnection)url.openConnection(); httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setRequestMethod("GET"); httpUrlConnection.setRequestMethod("GET");
// give it 15 seconds to respond // give it 15 seconds to respond
httpUrlConnection.setReadTimeout(15*1000); httpUrlConnection.setReadTimeout(15 * 1000);
httpUrlConnection.connect(); httpUrlConnection.connect();
int responseCode = httpUrlConnection.getResponseCode(); int responseCode = httpUrlConnection.getResponseCode();
@@ -87,7 +90,7 @@ public class SimpleApiClient {
if(responseCode != 200) { if(responseCode != 200) {
is = httpUrlConnection.getErrorStream(); is = httpUrlConnection.getErrorStream();
if(is != null) { if(is != null) {
responseContent = StreamTools.readStreamtoString(is,"UTF-8"); responseContent = StreamTools.readStreamtoString(is, "UTF-8");
} else { } else {
responseContent = ""; responseContent = "";
} }
@@ -97,7 +100,7 @@ public class SimpleApiClient {
is = httpUrlConnection.getInputStream(); is = httpUrlConnection.getInputStream();
responseContent = StreamTools.readStreamtoString(is,"UTF-8"); responseContent = StreamTools.readStreamtoString(is, "UTF-8");
} catch(IOException e) { } catch(IOException e) {
throw e; throw e;
@@ -112,7 +115,7 @@ public class SimpleApiClient {
return responseContent; return responseContent;
} }
private static String invokeImpl(String method, Map<String,Object> paramMap) throws IOException, ApiException { private static String invokeImpl(String method, Map<String, Object> paramMap) throws IOException, ApiException {
QueryBuilder queryBuilder = new QueryBuilder(method); QueryBuilder queryBuilder = new QueryBuilder(method);
queryBuilder.put(paramMap); queryBuilder.put(paramMap);
return invokeImpl(queryBuilder.toString()); return invokeImpl(queryBuilder.toString());

View File

@@ -2,23 +2,25 @@ package eu.crushedpixel.replaymod.api.client.holders;
public class ApiError { public class ApiError {
private int id;
private String desc;
public ApiError(int id, String desc) { public ApiError(int id, String desc) {
this.id = id; this.id = id;
this.desc = desc; this.desc = desc;
} }
private int id;
private String desc;
public int getId() { public int getId() {
return id; return id;
} }
public void setId(int id) { public void setId(int id) {
this.id = id; this.id = id;
} }
public String getDesc() { public String getDesc() {
return desc; return desc;
} }
public void setDesc(String desc) { public void setDesc(String desc) {
this.desc = desc; this.desc = desc;
} }

View File

@@ -22,16 +22,16 @@ public enum Category {
} }
public String toNiceString() { public String toNiceString() {
return (""+this).charAt(0)+(""+this).substring(1).toLowerCase(); return ("" + this).charAt(0) + ("" + this).substring(1).toLowerCase();
} }
public Category next() { public Category next() {
for(int i=0; i<values().length; i++) { for(int i = 0; i < values().length; i++) {
if(values()[i] == this) { if(values()[i] == this) {
if(i == values().length-1) { if(i == values().length - 1) {
i=-1; i = -1;
} }
return values()[i+1]; return values()[i + 1];
} }
} }
return this; return this;

View File

@@ -32,30 +32,39 @@ public class FileInfo {
public int getId() { public int getId() {
return id; return id;
} }
public ReplayMetaData getMetadata() { public ReplayMetaData getMetadata() {
return metadata; return metadata;
} }
public String getOwner() { public String getOwner() {
return owner; return owner;
} }
public Rating getRatings() { public Rating getRatings() {
return ratings; return ratings;
} }
public int getSize() { public int getSize() {
return size; return size;
} }
public int getCategory() { public int getCategory() {
return category; return category;
} }
public int getDownloads() { public int getDownloads() {
return downloads; return downloads;
} }
public String getName() { public String getName() {
return name; return name;
} }
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
public boolean hasThumbnail() { public boolean hasThumbnail() {
return thumbnail; return thumbnail;
} }

View File

@@ -9,9 +9,11 @@ public class UserFiles {
public String getUser() { public String getUser() {
return user; return user;
} }
public FileInfo[] getFiles() { public FileInfo[] getFiles() {
return files; return files;
} }
public int getTotal_size() { public int getTotal_size() {
return total_size; return total_size;
} }

View File

@@ -0,0 +1,92 @@
package eu.crushedpixel.replaymod.chat;
import eu.crushedpixel.replaymod.ReplayMod;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.IChatComponent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@SideOnly(Side.CLIENT)
public class ChatMessageHandler {
private boolean active = true;
private boolean alive = true;
private Queue<IChatComponent> requests = new ConcurrentLinkedQueue<IChatComponent>();
private String prefix = "§8[§6Replay Mod§8]§r ";
private EntityPlayerSP player = null;
public Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(alive) {
while(active) {
try {
while(player == null) {
if(!alive) {
break;
}
try {
Thread.sleep(100);
player = Minecraft.getMinecraft().thePlayer;
} catch(Exception e) {
}
}
player.addChatComponentMessage(requests.poll());
Thread.sleep(100);
} catch(Exception e) {
}
}
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
public ChatMessageHandler() {
t.start();
}
public void addChatMessage(String message, ChatMessageType type) {
if(ReplayMod.replaySettings.isShowNotifications()) {
message = prefix + toColor(message, type);
ChatComponentText cct = new ChatComponentText(message);
requests.add(cct);
}
}
private String toColor(String message, ChatMessageType type) {
if(type == ChatMessageType.INFORMATION) {
return "§2" + message;
} else if(type == ChatMessageType.WARNING) {
return "§c" + message;
}
return message;
}
public void stop() {
active = false;
}
public void initialize() {
active = true;
requests.clear();
if(!ReplayMod.replaySettings.isShowNotifications()) {
System.out.println("Chat messages are disabled");
}
}
public enum ChatMessageType {
INFORMATION, WARNING;
}
}

View File

@@ -1,95 +0,0 @@
package eu.crushedpixel.replaymod.chat;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.IChatComponent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import eu.crushedpixel.replaymod.ReplayMod;
@SideOnly(Side.CLIENT)
public class ChatMessageRequests {
public enum ChatMessageType {
INFORMATION, WARNING;
}
private static boolean active = true;
private static boolean alive = true;
private static Queue<IChatComponent> requests = new ConcurrentLinkedQueue<IChatComponent>();
private static String prefix = "§8[§6Replay Mod§8]§r ";
private static EntityPlayerSP player = null;
public static Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(alive) {
while(active) {
try {
while(player == null) {
if(!alive) {
break;
}
try {
Thread.sleep(100);
player = Minecraft.getMinecraft().thePlayer;
} catch(Exception e) {}
}
player.addChatComponentMessage(requests.poll());
Thread.sleep(100);
} catch(Exception e) {}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
static {
t.start();
}
public static void addChatMessage(String message, ChatMessageType type) {
if(ReplayMod.replaySettings.isShowNotifications()) {
message = prefix+toColor(message, type);
ChatComponentText cct = new ChatComponentText(message);
requests.add(cct);
}
}
private static String toColor(String message, ChatMessageType type) {
if(type == ChatMessageType.INFORMATION) {
return "§2"+message;
} else if(type == ChatMessageType.WARNING) {
return "§c"+message;
}
return message;
}
public static void stop() {
active = false;
}
public static void initialize() {
active = true;
requests.clear();
if(ReplayMod.replaySettings.isShowNotifications()) {
} else {
System.out.println("Chat messages are disabled");
}
}
}

View File

@@ -1,11 +1,7 @@
package eu.crushedpixel.replaymod.coremod; package eu.crushedpixel.replaymod.coremod;
import java.util.ArrayList; import akka.japi.Pair;
import java.util.Iterator;
import java.util.List;
import net.minecraft.launchwrapper.IClassTransformer; import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
@@ -14,7 +10,9 @@ import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import akka.japi.Pair; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ClassTransformer implements IClassTransformer { public class ClassTransformer implements IClassTransformer {
@@ -46,7 +44,7 @@ public class ClassTransformer implements IClassTransformer {
ClassReader classReader = new ClassReader(bytes); ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0); classReader.accept(classNode, 0);
List<Pair<AbstractInsnNode, AbstractInsnNode>> toInsert = new ArrayList<Pair<AbstractInsnNode,AbstractInsnNode>>(); List<Pair<AbstractInsnNode, AbstractInsnNode>> toInsert = new ArrayList<Pair<AbstractInsnNode, AbstractInsnNode>>();
Iterator<MethodNode> iterator = classNode.methods.iterator(); Iterator<MethodNode> iterator = classNode.methods.iterator();
while(iterator.hasNext()) { while(iterator.hasNext()) {
@@ -58,8 +56,8 @@ public class ClassTransformer implements IClassTransformer {
while(nodeIterator.hasNext()) { while(nodeIterator.hasNext()) {
AbstractInsnNode node = nodeIterator.next(); AbstractInsnNode node = nodeIterator.next();
if(node instanceof MethodInsnNode) { if(node instanceof MethodInsnNode) {
MethodInsnNode min = (MethodInsnNode)node; MethodInsnNode min = (MethodInsnNode) node;
if(min.getOpcode() == Opcodes.INVOKESTATIC &&min.name.equals(getSystemTime) && if(min.getOpcode() == Opcodes.INVOKESTATIC && min.name.equals(getSystemTime) &&
min.owner.equals(minecraftClass) && min.desc.equals(sysTimeDesc)) { min.owner.equals(minecraftClass) && min.desc.equals(sysTimeDesc)) {
MethodInsnNode n = new MethodInsnNode(Opcodes.INVOKESTATIC, MethodInsnNode n = new MethodInsnNode(Opcodes.INVOKESTATIC,
"eu/crushedpixel/replaymod/timer/EnchantmentTimer", "getEnchantmentTime", "eu/crushedpixel/replaymod/timer/EnchantmentTimer", "getEnchantmentTime",

View File

@@ -1,9 +1,9 @@
package eu.crushedpixel.replaymod.coremod; package eu.crushedpixel.replaymod.coremod;
import java.util.Map;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
import java.util.Map;
public class LoadingPlugin implements IFMLLoadingPlugin { public class LoadingPlugin implements IFMLLoadingPlugin {
@Override @Override
@@ -22,7 +22,8 @@ public class LoadingPlugin implements IFMLLoadingPlugin {
} }
@Override @Override
public void injectData(Map<String, Object> data) {} public void injectData(Map<String, Object> data) {
}
@Override @Override
public String getAccessTransformerClass() { public String getAccessTransformerClass() {

View File

@@ -1,38 +1,36 @@
package eu.crushedpixel.replaymod.entities; package eu.crushedpixel.replaymod.entities;
import java.lang.reflect.Field;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.network.play.server.S03PacketTimeUpdate;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import org.lwjgl.Sys;
import eu.crushedpixel.replaymod.holders.Position; import eu.crushedpixel.replaymod.holders.Position;
import eu.crushedpixel.replaymod.replay.LesserDataWatcher; import eu.crushedpixel.replaymod.replay.LesserDataWatcher;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.replay.TimeHandler; import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import org.lwjgl.Sys;
import java.lang.reflect.Field;
public class CameraEntity extends EntityPlayer { public class CameraEntity extends EntityPlayer {
private static final double MAX_SPEED = 20;
private Vec3 direction; private Vec3 direction;
private double motion; private double motion;
private Field drawBlockOutline; private Field drawBlockOutline;
private static final double MAX_SPEED = 20;
private double decay = 4; private double decay = 4;
private long lastCall = 0; private long lastCall = 0;
private boolean speedup = false; private boolean speedup = false;
public CameraEntity(World worldIn) {
//super(worldIn);
super(worldIn, Minecraft.getMinecraft().getSession().getProfile());
}
//frac = time since last tick //frac = time since last tick
public void updateMovement() { public void updateMovement() {
Minecraft mc = Minecraft.getMinecraft(); Minecraft mc = Minecraft.getMinecraft();
@@ -58,11 +56,11 @@ public class CameraEntity extends EntityPlayer {
if(frac == 0) return; if(frac == 0) return;
Vec3 movement = direction.normalize(); Vec3 movement = direction.normalize();
double factor = motion*(frac/1000D); double factor = motion * (frac / 1000D);
moveRelative(movement.xCoord*factor, movement.yCoord*factor, movement.zCoord*factor); moveRelative(movement.xCoord * factor, movement.yCoord * factor, movement.zCoord * factor);
double decFac = Math.max(0, 1-(decay*(frac/1000D))); double decFac = Math.max(0, 1 - (decay * (frac / 1000D)));
if(!speedup) { if(!speedup) {
motion *= decFac; motion *= decFac;
@@ -78,7 +76,7 @@ public class CameraEntity extends EntityPlayer {
} }
public void speedUp() { public void speedUp() {
this.motion = Math.min(MAX_SPEED, motion+0.1); this.motion = Math.min(MAX_SPEED, motion + 0.1);
speedup = true; speedup = true;
} }
@@ -87,7 +85,7 @@ public class CameraEntity extends EntityPlayer {
switch(dir) { switch(dir) {
case BACKWARD: case BACKWARD:
direction = this.getVectorForRotation(-rotationPitch, rotationYaw-180); direction = this.getVectorForRotation(-rotationPitch, rotationYaw - 180);
break; break;
case DOWN: case DOWN:
direction = this.getVectorForRotation(90, 0); direction = this.getVectorForRotation(90, 0);
@@ -96,17 +94,18 @@ public class CameraEntity extends EntityPlayer {
direction = this.getVectorForRotation(rotationPitch, rotationYaw); direction = this.getVectorForRotation(rotationPitch, rotationYaw);
break; break;
case LEFT: case LEFT:
direction = this.getVectorForRotation(0, rotationYaw-90); direction = this.getVectorForRotation(0, rotationYaw - 90);
break; break;
case RIGHT: case RIGHT:
direction = this.getVectorForRotation(0, rotationYaw+90); direction = this.getVectorForRotation(0, rotationYaw + 90);
break; break;
case UP: case UP:
direction = this.getVectorForRotation(-90, 0); direction = this.getVectorForRotation(-90, 0);
break; break;
} }
if(oldDir != null) direction = direction.normalize().add(new Vec3(oldDir.xCoord*(motion/4f), oldDir.yCoord*(motion/4f), oldDir.zCoord*(motion/4f)).normalize()); if(oldDir != null)
direction = direction.normalize().add(new Vec3(oldDir.xCoord * (motion / 4f), oldDir.yCoord * (motion / 4f), oldDir.zCoord * (motion / 4f)).normalize());
} }
public void moveAbsolute(double x, double y, double z) { public void moveAbsolute(double x, double y, double z) {
@@ -118,9 +117,9 @@ public class CameraEntity extends EntityPlayer {
public void moveRelative(double x, double y, double z) { public void moveRelative(double x, double y, double z) {
if(ReplayHandler.isInPath()) return; if(ReplayHandler.isInPath()) return;
this.lastTickPosX = this.prevPosX = this.posX = this.posX+x; this.lastTickPosX = this.prevPosX = this.posX = this.posX + x;
this.lastTickPosY = this.prevPosY = this.posY = this.posY+y; this.lastTickPosY = this.prevPosY = this.posY = this.posY + y;
this.lastTickPosZ = this.prevPosZ = this.posZ = this.posZ+z; this.lastTickPosZ = this.prevPosZ = this.posZ = this.posZ + z;
} }
public void movePath(Position pos) { public void movePath(Position pos) {
@@ -136,17 +135,10 @@ public class CameraEntity extends EntityPlayer {
this.dataWatcher = new LesserDataWatcher(this); this.dataWatcher = new LesserDataWatcher(this);
} }
public CameraEntity(World worldIn) {
//super(worldIn);
super(worldIn, Minecraft.getMinecraft().getSession().getProfile());
}
@Override @Override
public void setAngles(float yaw, float pitch) public void setAngles(float yaw, float pitch) {
{ this.rotationYaw = (float) ((double) this.rotationYaw + (double) yaw * 0.15D);
this.rotationYaw = (float)((double)this.rotationYaw + (double)yaw * 0.15D); this.rotationPitch = (float) ((double) this.rotationPitch - (double) pitch * 0.15D);
this.rotationPitch = (float)((double)this.rotationPitch - (double)pitch * 0.15D);
this.rotationPitch = MathHelper.clamp_float(this.rotationPitch, -90.0F, 90.0F); this.rotationPitch = MathHelper.clamp_float(this.rotationPitch, -90.0F, 90.0F);
this.prevRotationPitch = this.rotationPitch; this.prevRotationPitch = this.rotationPitch;
this.prevRotationYaw = this.rotationYaw; this.prevRotationYaw = this.rotationYaw;
@@ -164,23 +156,22 @@ public class CameraEntity extends EntityPlayer {
} }
@Override @Override
protected void createRunningParticles() {} protected void createRunningParticles() {
}
@Override @Override
public boolean canBeCollidedWith() { public boolean canBeCollidedWith() {
return false; return false;
} }
@Override @Override
public boolean canRenderOnFire() { public boolean canRenderOnFire() {
return false; return false;
} }
public enum MoveDirection {
UP, DOWN, LEFT, RIGHT, FORWARD, BACKWARD;
}
@Override @Override
public void setCurrentItemOrArmor(int slotIn, ItemStack stack) {} public void setCurrentItemOrArmor(int slotIn, ItemStack stack) {
}
@Override @Override
public ItemStack[] getInventory() { public ItemStack[] getInventory() {
@@ -192,4 +183,8 @@ public class CameraEntity extends EntityPlayer {
return true; return true;
} }
public enum MoveDirection {
UP, DOWN, LEFT, RIGHT, FORWARD, BACKWARD;
}
} }

View File

@@ -1,26 +1,5 @@
package eu.crushedpixel.replaymod.events; package eu.crushedpixel.replaymod.events;
import java.awt.Color;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiChat;
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.multiplayer.WorldClient;
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.DrawScreenEvent;
import net.minecraftforge.client.event.GuiScreenEvent.InitGuiEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.gui.GuiCancelRender; import eu.crushedpixel.replaymod.gui.GuiCancelRender;
import eu.crushedpixel.replaymod.gui.GuiConstants; import eu.crushedpixel.replaymod.gui.GuiConstants;
@@ -42,14 +21,26 @@ import eu.crushedpixel.replaymod.utils.MouseUtils;
import eu.crushedpixel.replaymod.utils.ReplayFileIO; import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import eu.crushedpixel.replaymod.utils.ResourceHelper; import eu.crushedpixel.replaymod.utils.ResourceHelper;
import eu.crushedpixel.replaymod.video.VideoWriter; import eu.crushedpixel.replaymod.video.VideoWriter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.client.event.GuiScreenEvent.ActionPerformedEvent;
import net.minecraftforge.client.event.GuiScreenEvent.DrawScreenEvent;
import net.minecraftforge.client.event.GuiScreenEvent.InitGuiEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class GuiEventHandler { public class GuiEventHandler {
private static Minecraft mc = Minecraft.getMinecraft(); private static final Color DARK_RED = Color.decode("#DF0101");
private static final Color DARK_GREEN = Color.decode("#01DF01");
private static int replayCount = 0; private final Minecraft mc = Minecraft.getMinecraft();
private final List<Class> allowedGUIs = new ArrayList<Class>() {
private static List<Class> allowedGUIs = new ArrayList<Class>() {
{ {
add(GuiReplaySettings.class); add(GuiReplaySettings.class);
add(GuiReplaySaving.class); add(GuiReplaySaving.class);
@@ -58,6 +49,8 @@ public class GuiEventHandler {
add(GuiVideoSettings.class); add(GuiVideoSettings.class);
} }
}; };
private int replayCount = 0;
private GuiButton editorButton;
@SubscribeEvent @SubscribeEvent
public void onGui(GuiOpenEvent event) { public void onGui(GuiOpenEvent event) {
@@ -66,7 +59,8 @@ public class GuiEventHandler {
return; return;
} }
if(!(event.gui instanceof GuiReplayViewer || event.gui instanceof GuiUploadFile)) ResourceHelper.freeAllResources(); if(!(event.gui instanceof GuiReplayViewer || event.gui instanceof GuiUploadFile))
ResourceHelper.freeAllResources();
if(event.gui instanceof GuiMainMenu) { if(event.gui instanceof GuiMainMenu) {
if(ReplayMod.firstMainMenu) { if(ReplayMod.firstMainMenu) {
@@ -76,7 +70,7 @@ public class GuiEventHandler {
} else { } else {
try { try {
MCTimerHandler.setTimerSpeed(1); MCTimerHandler.setTimerSpeed(1);
} catch (Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -91,18 +85,13 @@ public class GuiEventHandler {
if(ReplayHandler.isInReplay()) { if(ReplayHandler.isInReplay()) {
event.setCanceled(true); event.setCanceled(true);
} }
} } else if(event.gui instanceof GuiDisconnected) {
else if(event.gui instanceof GuiDisconnected) {
if(!ReplayHandler.isInReplay() && System.currentTimeMillis() - ReplayHandler.lastExit < 5000) { if(!ReplayHandler.isInReplay() && System.currentTimeMillis() - ReplayHandler.lastExit < 5000) {
event.setCanceled(true); event.setCanceled(true);
} }
} }
} }
private static final Color DARK_RED = Color.decode("#DF0101");
private static final Color DARK_GREEN = Color.decode("#01DF01");
@SubscribeEvent @SubscribeEvent
public void onDraw(DrawScreenEvent e) { public void onDraw(DrawScreenEvent e) {
if(e.gui instanceof GuiMainMenu) { if(e.gui instanceof GuiMainMenu) {
@@ -116,57 +105,55 @@ public class GuiEventHandler {
if(replayCount == 0) { if(replayCount == 0) {
if(editorButton.isMouseOver()) { if(editorButton.isMouseOver()) {
Point mouse = MouseUtils.getMousePos(); Point mouse = MouseUtils.getMousePos();
e.gui.drawCenteredString(mc.fontRendererObj, "At least one Replay required", (int)mouse.getX(), (int)mouse.getY()+4, Color.RED.getRGB()); e.gui.drawCenteredString(mc.fontRendererObj, "At least one Replay required", (int) mouse.getX(), (int) mouse.getY() + 4, Color.RED.getRGB());
} }
} else if(!VersionValidator.isValid) { } else if(!VersionValidator.isValid) {
if(editorButton.isMouseOver()) { if(editorButton.isMouseOver()) {
Point mouse = MouseUtils.getMousePos(); Point mouse = MouseUtils.getMousePos();
e.gui.drawCenteredString(mc.fontRendererObj, "Java 1.7 or newer required", (int)mouse.getX(), (int)mouse.getY()+4, Color.RED.getRGB()); e.gui.drawCenteredString(mc.fontRendererObj, "Java 1.7 or newer required", (int) mouse.getX(), (int) mouse.getY() + 4, Color.RED.getRGB());
} }
} }
} }
} }
private GuiButton editorButton;
@SubscribeEvent @SubscribeEvent
public void onInit(InitGuiEvent event) { public void onInit(InitGuiEvent event) {
if(event.gui instanceof GuiIngameMenu && ReplayHandler.isInReplay()) { if(event.gui instanceof GuiIngameMenu && ReplayHandler.isInReplay()) {
for(GuiButton b : new ArrayList<GuiButton>(event.buttonList)) { for(GuiButton b : new ArrayList<GuiButton>(event.buttonList)) {
if(b.id == 1) { if(b.id == 1) {
b.displayString = "Exit Replay"; b.displayString = "Exit Replay";
b.yPosition -= 24*2; b.yPosition -= 24 * 2;
b.id = GuiConstants.EXIT_REPLAY_BUTTON; b.id = GuiConstants.EXIT_REPLAY_BUTTON;
} else if(b.id >= 5 && b.id <= 7) { } else if(b.id >= 5 && b.id <= 7) {
event.buttonList.remove(b); event.buttonList.remove(b);
} else if(b.id != 4) { } else if(b.id != 4) {
b.yPosition -= 24*2; b.yPosition -= 24 * 2;
} }
} }
} else if(event.gui instanceof GuiMainMenu) { } else if(event.gui instanceof GuiMainMenu) {
int i1 = event.gui.height / 4 + 24 + 10; int i1 = event.gui.height / 4 + 24 + 10;
for(GuiButton b : (List<GuiButton>)event.buttonList) { for(GuiButton b : (List<GuiButton>) event.buttonList) {
if(b.id != 0 && b.id != 4 && b.id != 5) { if(b.id != 0 && b.id != 4 && b.id != 5) {
b.yPosition = b.yPosition - 2*24 + 10; b.yPosition = b.yPosition - 2 * 24 + 10;
} }
} }
GuiButton rm = new GuiButton(GuiConstants.REPLAY_MANAGER_BUTTON_ID, event.gui.width / 2 - 100, i1 + 2*24, "Replay Viewer"); GuiButton rm = new GuiButton(GuiConstants.REPLAY_MANAGER_BUTTON_ID, event.gui.width / 2 - 100, i1 + 2 * 24, "Replay Viewer");
rm.width = rm.width/2 - 2; rm.width = rm.width / 2 - 2;
//rm.enabled = AuthenticationHandler.isAuthenticated(); //rm.enabled = AuthenticationHandler.isAuthenticated();
event.buttonList.add(rm); event.buttonList.add(rm);
replayCount = ReplayFileIO.getAllReplayFiles().size(); replayCount = ReplayFileIO.getAllReplayFiles().size();
GuiButton re = new GuiButton(GuiConstants.REPLAY_EDITOR_BUTTON_ID, event.gui.width / 2 + 2, i1 + 2*24, "Replay Editor"); GuiButton re = new GuiButton(GuiConstants.REPLAY_EDITOR_BUTTON_ID, event.gui.width / 2 + 2, i1 + 2 * 24, "Replay Editor");
re.width = re.width/2 - 2; re.width = re.width / 2 - 2;
re.enabled = VersionValidator.isValid && replayCount > 0; re.enabled = VersionValidator.isValid && replayCount > 0;
event.buttonList.add(re); event.buttonList.add(re);
editorButton = re; editorButton = re;
GuiButton rc = new GuiButton(GuiConstants.REPLAY_CENTER_BUTTON_ID, event.gui.width / 2 - 100, i1 + 3*24, "Replay Center"); GuiButton rc = new GuiButton(GuiConstants.REPLAY_CENTER_BUTTON_ID, event.gui.width / 2 - 100, i1 + 3 * 24, "Replay Center");
rc.enabled = true; rc.enabled = true;
event.buttonList.add(rc); event.buttonList.add(rc);
@@ -206,7 +193,7 @@ public class GuiEventHandler {
ReplayHandler.lastExit = System.currentTimeMillis(); ReplayHandler.lastExit = System.currentTimeMillis();
mc.theWorld.sendQuittingDisconnectingPacket(); mc.theWorld.sendQuittingDisconnectingPacket();
mc.loadWorld((WorldClient)null); mc.loadWorld((WorldClient) null);
mc.displayGuiScreen(new GuiMainMenu()); mc.displayGuiScreen(new GuiMainMenu());
ReplayGuiRegistry.show(); ReplayGuiRegistry.show();

View File

@@ -1,10 +1,21 @@
package eu.crushedpixel.replaymod.events; package eu.crushedpixel.replaymod.events;
import java.awt.Color; import eu.crushedpixel.replaymod.ReplayMod;
import java.awt.Point; import eu.crushedpixel.replaymod.entities.CameraEntity;
import java.util.concurrent.TimeUnit; import eu.crushedpixel.replaymod.gui.GuiCancelRender;
import eu.crushedpixel.replaymod.gui.GuiMouseInput;
import eu.crushedpixel.replaymod.gui.GuiReplaySpeedSlider;
import eu.crushedpixel.replaymod.gui.GuiSpectateSelection;
import eu.crushedpixel.replaymod.holders.Keyframe;
import eu.crushedpixel.replaymod.holders.Position;
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import eu.crushedpixel.replaymod.registry.ReplayGuiRegistry;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.replay.ReplayProcess;
import eu.crushedpixel.replaymod.utils.MouseUtils;
import eu.crushedpixel.replaymod.video.VideoWriter;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiChat; import net.minecraft.client.gui.GuiChat;
@@ -16,62 +27,62 @@ import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import eu.crushedpixel.replaymod.ReplayMod; import java.awt.*;
import eu.crushedpixel.replaymod.entities.CameraEntity; import java.util.concurrent.TimeUnit;
import eu.crushedpixel.replaymod.gui.GuiCancelRender;
import eu.crushedpixel.replaymod.gui.GuiReplaySpeedSlider;
import eu.crushedpixel.replaymod.gui.GuiSpectateSelection;
import eu.crushedpixel.replaymod.gui.elements.GuiMouseInput;
import eu.crushedpixel.replaymod.holders.Keyframe;
import eu.crushedpixel.replaymod.holders.Position;
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import eu.crushedpixel.replaymod.registry.ReplayGuiRegistry;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.replay.ReplayProcess;
import eu.crushedpixel.replaymod.utils.MouseUtils;
import eu.crushedpixel.replaymod.video.VideoWriter;
public class GuiReplayOverlay extends Gui { public class GuiReplayOverlay extends Gui {
private Minecraft mc = Minecraft.getMinecraft(); private final Minecraft mc = Minecraft.getMinecraft();
int sl_begin_x = 0;
int sl_end_x = 63;
int sl_y = 40;
int plus_x = 0;
int plus_y = 0;
int minus_x = 0;
int minus_y = 9;
int slider_begin_x = 1;
int slider_begin_width = 1;
int slider_end_x = 62;
int slider_end_width = 1;
int slider_y = 50;
int slider_height = 7;
private int sliderX = 35; private int sliderX = 35;
private int sliderY = 10; private int sliderY = 10;
private int timelineX = sliderX + 100 + 5;
private int timelineX = sliderX+100+5; private int realTimelineX = 10 + 4 * 25;
private int realTimelineX = 10 + 4*25; private int realTimelineY = 33 + 10;
private int realTimelineY = 33+10;
private int ppButtonX = 10; private int ppButtonX = 10;
private int ppButtonY = 10; private int ppButtonY = 10;
private int r_ppButtonX = 10; private int r_ppButtonX = 10;
private int r_ppButtonY = realTimelineY+1; private int r_ppButtonY = realTimelineY + 1;
private int exportButtonX = 35; private int exportButtonX = 35;
private int exportButtonY = realTimelineY+1; private int exportButtonY = realTimelineY + 1;
private int place_ButtonX = 60; private int place_ButtonX = 60;
private int place_ButtonY = realTimelineY+1; private int place_ButtonY = realTimelineY + 1;
private int time_ButtonX = 85; private int time_ButtonX = 85;
private int time_ButtonY = realTimelineY+1; private int time_ButtonY = realTimelineY + 1;
private long lastSystemTime = System.currentTimeMillis(); private long lastSystemTime = System.currentTimeMillis();
private ResourceLocation replay_gui = new ResourceLocation("replaymod", "replay_gui.png"); private ResourceLocation replay_gui = new ResourceLocation("replaymod", "replay_gui.png");
private ResourceLocation extended_gui = new ResourceLocation("replaymod", "extended_gui.png"); private ResourceLocation extended_gui = new ResourceLocation("replaymod", "extended_gui.png");
private ResourceLocation timeline_icons = new ResourceLocation("replaymod", "timeline_icons.png"); private ResourceLocation timeline_icons = new ResourceLocation("replaymod", "timeline_icons.png");
private GuiReplaySpeedSlider speedSlider; private GuiReplaySpeedSlider speedSlider;
private boolean mouseDown = false; private boolean mouseDown = false;
private int tl_begin_x = 0;
private int tl_begin_width = 4;
private int tl_end_x = 60;
private int tl_end_width = 4;
private int tl_middle_x = 4;
private int tl_y = 40;
private float zoom_scale = 0.1f; //can see 1/10th of the timeline
private float pos_left = 0f; //left border of timeline is at 0%
private float cursor_pos = 0f; //cursor is at 0%
private long timelineLength = 10 * 60 * 1000; //10 min of timeline
private float zoom_steps = 0.05f;
private boolean wasSliding = false;
private boolean mouseDwn = false;
public void resetUI() throws Exception { public void resetUI() throws Exception {
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
@@ -91,7 +102,7 @@ public class GuiReplayOverlay extends Gui {
@SubscribeEvent @SubscribeEvent
public void renderRecordingIndicator(RenderGameOverlayEvent.Text event) { public void renderRecordingIndicator(RenderGameOverlayEvent.Text event) {
if(!ReplayHandler.isInReplay() && ReplayMod.replaySettings.showRecordingIndicator() && ConnectionEventHandler.isRecording()) { if(!ReplayHandler.isInReplay() && ReplayMod.replaySettings.showRecordingIndicator() && ConnectionEventHandler.isRecording()) {
this.drawString(mc.fontRendererObj, "RECORDING", 30, 18-(mc.fontRendererObj.FONT_HEIGHT/2), Color.WHITE.getRGB()); this.drawString(mc.fontRendererObj, "RECORDING", 30, 18 - (mc.fontRendererObj.FONT_HEIGHT / 2), Color.WHITE.getRGB());
mc.renderEngine.bindTexture(replay_gui); mc.renderEngine.bindTexture(replay_gui);
GlStateManager.resetColor(); GlStateManager.resetColor();
GlStateManager.enableAlpha(); GlStateManager.enableAlpha();
@@ -119,8 +130,8 @@ public class GuiReplayOverlay extends Gui {
final int mouseY = (int) mousePoint.getY(); final int mouseY = (int) mousePoint.getY();
Point scaled = MouseUtils.getScaledDimensions(); Point scaled = MouseUtils.getScaledDimensions();
final int width = (int)scaled.getX(); final int width = (int) scaled.getX();
final int height = (int)scaled.getY(); final int height = (int) scaled.getY();
//Draw Timeline //Draw Timeline
drawTimeline(timelineX, width - 14, 9); drawTimeline(timelineX, width - 14, 9);
@@ -130,12 +141,12 @@ public class GuiReplayOverlay extends Gui {
int x = 0; int x = 0;
int y = 0; int y = 0;
boolean play = !ReplayHandler.isPaused(); boolean play = !ReplayMod.replaySender.paused();
boolean hover = false; boolean hover = false;
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
if(mouseX >= ppButtonX && mouseX <= ppButtonX+20 if(mouseX >= ppButtonX && mouseX <= ppButtonX + 20
&& mouseY >= ppButtonY && mouseY <= ppButtonY+20) { && mouseY >= ppButtonY && mouseY <= ppButtonY + 20) {
hover = true; hover = true;
} }
} }
@@ -153,28 +164,28 @@ public class GuiReplayOverlay extends Gui {
this.drawModalRectWithCustomSizedTexture(ppButtonX, ppButtonY, x, y, 20, 20, 64, 64); this.drawModalRectWithCustomSizedTexture(ppButtonX, ppButtonY, x, y, 20, 20, 64, 64);
//When hurrying, no Timeline jumping etc. is possible //When hurrying, no Timeline jumping etc. is possible
if(Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class) && !ReplayHandler.isHurrying()) { //clicking the Button if(Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class) && !ReplayMod.replaySender.isHurrying()) { //clicking the Button
speedSlider.mousePressed(mc, mouseX, mouseY); speedSlider.mousePressed(mc, mouseX, mouseY);
if(!mouseDown) { if(!mouseDown) {
mouseDown = true; mouseDown = true;
if(hover) { if(hover) {
boolean paused = !ReplayHandler.isPaused(); boolean paused = !ReplayMod.replaySender.paused();
if(paused) { if(paused) {
ReplayHandler.setSpeed(0); ReplayMod.replaySender.setReplaySpeed(0);
} else { } else {
ReplayHandler.setSpeed(speedSlider.getSliderValue()); ReplayMod.replaySender.setReplaySpeed(speedSlider.getSliderValue());
} }
} else if(mouseX >= exportButtonX && mouseX <= exportButtonX+20 && mouseY >= exportButtonY && exportButtonY <= exportButtonY+20) { } else if(mouseX >= exportButtonX && mouseX <= exportButtonX + 20 && mouseY >= exportButtonY && exportButtonY <= exportButtonY + 20) {
ReplayHandler.startPath(true); ReplayHandler.startPath(true);
} }
if(mouseX >= timelineX+4 && mouseX <= width - 18 && mouseY >= 11 && mouseY <= 29) { if(mouseX >= timelineX + 4 && mouseX <= width - 18 && mouseY >= 11 && mouseY <= 29) {
double tot = (width - 18)-(timelineX+4); double tot = (width - 18) - (timelineX + 4);
double perc = (mouseX-(timelineX+4))/tot; double perc = (mouseX - (timelineX + 4)) / tot;
double time = perc*(double)ReplayHandler.getReplayLength(); double time = perc * (double) ReplayMod.replaySender.replayLength();
if(time < ReplayHandler.getReplayTime()) { if(time < ReplayMod.replaySender.currentTimeStamp()) {
mc.displayGuiScreen(null); mc.displayGuiScreen(null);
} }
@@ -185,21 +196,17 @@ public class GuiReplayOverlay extends Gui {
ReplayHandler.setLastPosition(null); ReplayHandler.setLastPosition(null);
} }
if((int)time != ReplayHandler.getDesiredTimestamp()) if((int) time != ReplayMod.replaySender.getDesiredTimestamp())
ReplayHandler.setReplayTime((int)time); ReplayMod.replaySender.jumpToTime((int) time);
} }
} }
} else { } else {
/*
if(Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class) && ReplayHandler.isHurrying()) {
System.out.println("HURRYIN'");
}
*/
try { try {
speedSlider.mouseReleased(mouseX, mouseY); speedSlider.mouseReleased(mouseX, mouseY);
mouseDown = false; mouseDown = false;
} catch(Exception e) {} } catch(Exception e) {
}
} }
//TODO: Save Video Button //TODO: Save Video Button
@@ -208,8 +215,8 @@ public class GuiReplayOverlay extends Gui {
y = 18; y = 18;
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
if(mouseX >= exportButtonX && mouseX <= exportButtonX+20 if(mouseX >= exportButtonX && mouseX <= exportButtonX + 20
&& mouseY >= exportButtonY && mouseY <= exportButtonY+20) { && mouseY >= exportButtonY && mouseY <= exportButtonY + 20) {
hover = true; hover = true;
} }
} }
@@ -231,8 +238,8 @@ public class GuiReplayOverlay extends Gui {
y = 0; y = 0;
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
if(mouseX >= place_ButtonX && mouseX <= place_ButtonX+20 if(mouseX >= place_ButtonX && mouseX <= place_ButtonX + 20
&& mouseY >= place_ButtonY && mouseY <= place_ButtonY+20) { && mouseY >= place_ButtonY && mouseY <= place_ButtonY + 20) {
hover = true; hover = true;
} }
} }
@@ -273,8 +280,8 @@ public class GuiReplayOverlay extends Gui {
} }
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
if(mouseX >= time_ButtonX && mouseX <= time_ButtonX+20 if(mouseX >= time_ButtonX && mouseX <= time_ButtonX + 20
&& mouseY >= time_ButtonY && mouseY <= time_ButtonY+20) { && mouseY >= time_ButtonY && mouseY <= time_ButtonY + 20) {
hover = true; hover = true;
} }
} }
@@ -300,10 +307,10 @@ public class GuiReplayOverlay extends Gui {
GlStateManager.resetColor(); GlStateManager.resetColor();
this.drawModalRectWithCustomSizedTexture(time_ButtonX, time_ButtonY, x, y, 20, 20, 64, 64); this.drawModalRectWithCustomSizedTexture(time_ButtonX, time_ButtonY, x, y, 20, 20, 64, 64);
if(mouseX >= (timelineX+4) && mouseX <= width - 18 && mouseY >= 11 && mouseY <= 29) { if(mouseX >= (timelineX + 4) && mouseX <= width - 18 && mouseY >= 11 && mouseY <= 29) {
double tot = (width - 18)-(timelineX+4); double tot = (width - 18) - (timelineX + 4);
double perc = (mouseX-(timelineX+4))/tot; double perc = (mouseX - (timelineX + 4)) / tot;
long time = Math.round(perc*(double)ReplayHandler.getReplayLength()); long time = Math.round(perc * (double) ReplayMod.replaySender.replayLength());
String timestamp = (String.format("%02d:%02ds", String timestamp = (String.format("%02d:%02ds",
TimeUnit.MILLISECONDS.toMinutes(time), TimeUnit.MILLISECONDS.toMinutes(time),
@@ -311,16 +318,17 @@ public class GuiReplayOverlay extends Gui {
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time)) TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time))
)); ));
this.drawCenteredString(mc.fontRendererObj, timestamp, mouseX, mouseY+5, Color.WHITE.getRGB()); this.drawCenteredString(mc.fontRendererObj, timestamp, mouseX, mouseY + 5, Color.WHITE.getRGB());
} }
if(mc.inGameHasFocus) { if(mc.inGameHasFocus) {
Mouse.setCursorPosition(width/2, height/2); Mouse.setCursorPosition(width / 2, height / 2);
} }
try { try {
speedSlider.drawButton(mc, mouseX, mouseY); speedSlider.drawButton(mc, mouseX, mouseY);
} catch(Exception e) {} } catch(Exception e) {
}
GlStateManager.resetColor(); GlStateManager.resetColor();
@@ -332,122 +340,86 @@ public class GuiReplayOverlay extends Gui {
if(!Mouse.isButtonDown(0)) isClick(); if(!Mouse.isButtonDown(0)) isClick();
} }
private int tl_begin_x=0;
private int tl_begin_width = 4;
private int tl_end_x=60;
private int tl_end_width = 4;
private int tl_middle_x=4;
private int tl_y=40;
private void drawTimeline(int minX, int maxX, int y) { private void drawTimeline(int minX, int maxX, int y) {
int zero = minX+tl_begin_width; int zero = minX + tl_begin_width;
int full = maxX-tl_end_width; int full = maxX - tl_end_width;
GlStateManager.resetColor(); GlStateManager.resetColor();
mc.renderEngine.bindTexture(replay_gui); mc.renderEngine.bindTexture(replay_gui);
this.drawModalRectWithCustomSizedTexture(minX, y, tl_begin_x, tl_y, tl_begin_width, 22, 64, 64); this.drawModalRectWithCustomSizedTexture(minX, y, tl_begin_x, tl_y, tl_begin_width, 22, 64, 64);
for(int i=minX+tl_begin_width; i<maxX-tl_end_width; i += tl_end_x-tl_begin_width) { for(int i = minX + tl_begin_width; i < maxX - tl_end_width; i += tl_end_x - tl_begin_width) {
this.drawModalRectWithCustomSizedTexture(i, y, tl_begin_x+tl_begin_width this.drawModalRectWithCustomSizedTexture(i, y, tl_begin_x + tl_begin_width
, tl_y, Math.min(tl_end_x-tl_begin_width, maxX-tl_end_width-i) , tl_y, Math.min(tl_end_x - tl_begin_width, maxX - tl_end_width - i)
, 22, 64, 64); , 22, 64, 64);
} }
this.drawModalRectWithCustomSizedTexture(maxX-tl_end_width, y, tl_end_x, tl_y, tl_end_width, 22, 64, 64); this.drawModalRectWithCustomSizedTexture(maxX - tl_end_width, y, tl_end_x, tl_y, tl_end_width, 22, 64, 64);
//Cursor //Cursor
double width = full-zero; double width = full - zero;
double perc = (double)ReplayHandler.getReplayTime()/(double)ReplayHandler.getReplayLength(); double perc = (double) ReplayMod.replaySender.currentTimeStamp() / (double) ReplayMod.replaySender.replayLength();
int cursorX = (int)Math.round(zero+(perc*width)); int cursorX = (int) Math.round(zero + (perc * width));
this.drawModalRectWithCustomSizedTexture(cursorX-3, y+3, 44, 0, 8, 16, 64, 64); this.drawModalRectWithCustomSizedTexture(cursorX - 3, y + 3, 44, 0, 8, 16, 64, 64);
} }
int sl_begin_x = 0;
int sl_end_x = 63;
int sl_y = 40;
int plus_x = 0;
int plus_y = 0;
int minus_x = 0;
int minus_y = 9;
int slider_begin_x = 1;
int slider_begin_width = 1;
int slider_end_x = 62;
int slider_end_width = 1;
int slider_y = 50;
int slider_height = 7;
private float zoom_scale = 0.1f; //can see 1/10th of the timeline
private float pos_left = 0f; //left border of timeline is at 0%
private float cursor_pos = 0f; //cursor is at 0%
private long timelineLength = 10*60*1000; //10 min of timeline
private float zoom_steps = 0.05f;
private boolean wasSliding = false;
private void drawRealTimeline(int minX, int maxX, int y, int mouseX, int mouseY) { private void drawRealTimeline(int minX, int maxX, int y, int mouseX, int mouseY) {
int zero = minX+tl_begin_width; int zero = minX + tl_begin_width;
int full = maxX-tl_end_width; int full = maxX - tl_end_width;
//the real timeline //the real timeline
GlStateManager.resetColor(); GlStateManager.resetColor();
mc.renderEngine.bindTexture(replay_gui); mc.renderEngine.bindTexture(replay_gui);
this.drawModalRectWithCustomSizedTexture(minX, y, tl_begin_x, tl_y, tl_begin_width, 22, 64, 64); this.drawModalRectWithCustomSizedTexture(minX, y, tl_begin_x, tl_y, tl_begin_width, 22, 64, 64);
for(int i=minX+tl_begin_width; i<maxX-tl_end_width; i += tl_end_x-tl_begin_width) { for(int i = minX + tl_begin_width; i < maxX - tl_end_width; i += tl_end_x - tl_begin_width) {
this.drawModalRectWithCustomSizedTexture(i, y, tl_begin_x+tl_begin_width this.drawModalRectWithCustomSizedTexture(i, y, tl_begin_x + tl_begin_width
, tl_y, Math.min(tl_end_x-tl_begin_width, maxX-tl_end_width-i) , tl_y, Math.min(tl_end_x - tl_begin_width, maxX - tl_end_width - i)
, 22, 64, 64); , 22, 64, 64);
} }
this.drawModalRectWithCustomSizedTexture(maxX-tl_end_width, y, tl_end_x, tl_y, tl_end_width, 22, 64, 64); this.drawModalRectWithCustomSizedTexture(maxX - tl_end_width, y, tl_end_x, tl_y, tl_end_width, 22, 64, 64);
//Time Slider //Time Slider
int yo = y+22+1; int yo = y + 22 + 1;
GlStateManager.resetColor(); GlStateManager.resetColor();
mc.renderEngine.bindTexture(timeline_icons); mc.renderEngine.bindTexture(timeline_icons);
this.drawModalRectWithCustomSizedTexture(minX, yo, sl_begin_x, sl_y, 2, 9, 64, 64); this.drawModalRectWithCustomSizedTexture(minX, yo, sl_begin_x, sl_y, 2, 9, 64, 64);
for(int i=minX+2; i<maxX-1; i+= sl_end_x-2) { for(int i = minX + 2; i < maxX - 1; i += sl_end_x - 2) {
this.drawModalRectWithCustomSizedTexture(i, yo, 2, sl_y, this.drawModalRectWithCustomSizedTexture(i, yo, 2, sl_y,
Math.min(sl_end_x-2, maxX-1-i), 9, 64, 64); Math.min(sl_end_x - 2, maxX - 1 - i), 9, 64, 64);
} }
this.drawModalRectWithCustomSizedTexture(maxX-1, yo, sl_end_x, sl_y, 1, 9, 64, 64); this.drawModalRectWithCustomSizedTexture(maxX - 1, yo, sl_end_x, sl_y, 1, 9, 64, 64);
//Timeline Pos Slider //Timeline Pos Slider
int sl_y = yo+1; int sl_y = yo + 1;
int minPos = minX+1; int minPos = minX + 1;
int maxPos = maxX-2; int maxPos = maxX - 2;
int tlWidth = maxPos - minPos; int tlWidth = maxPos - minPos;
int slider_min = minPos+Math.round(pos_left*tlWidth); int slider_min = minPos + Math.round(pos_left * tlWidth);
int slider_width = Math.round(zoom_scale*tlWidth); int slider_width = Math.round(zoom_scale * tlWidth);
int sl_max = slider_min+slider_width; int sl_max = slider_min + slider_width;
this.drawModalRectWithCustomSizedTexture(slider_min, sl_y, slider_begin_x, slider_y, slider_begin_width, slider_height, 64, 64); this.drawModalRectWithCustomSizedTexture(slider_min, sl_y, slider_begin_x, slider_y, slider_begin_width, slider_height, 64, 64);
for(int i=slider_min+slider_begin_width; i<sl_max-slider_end_width; i+=slider_end_x-slider_begin_width-slider_begin_x) { for(int i = slider_min + slider_begin_width; i < sl_max - slider_end_width; i += slider_end_x - slider_begin_width - slider_begin_x) {
this.drawModalRectWithCustomSizedTexture(i, sl_y, slider_begin_x+slider_begin_width, slider_y, this.drawModalRectWithCustomSizedTexture(i, sl_y, slider_begin_x + slider_begin_width, slider_y,
Math.min(slider_end_x-slider_end_width-slider_begin_x, sl_max-slider_end_width-i), slider_height, 64, 64); Math.min(slider_end_x - slider_end_width - slider_begin_x, sl_max - slider_end_width - i), slider_height, 64, 64);
} }
this.drawModalRectWithCustomSizedTexture(sl_max-slider_end_width, sl_y, slider_end_x, slider_y, this.drawModalRectWithCustomSizedTexture(sl_max - slider_end_width, sl_y, slider_end_x, slider_y,
slider_end_width, slider_height, 64, 64); slider_end_width, slider_height, 64, 64);
//Slider dragging //Slider dragging
if(Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class) && (mouseX >= slider_min && mouseX <= sl_max && mouseY >= sl_y && mouseY <= sl_y+slider_height || wasSliding)) { if(Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class) && (mouseX >= slider_min && mouseX <= sl_max && mouseY >= sl_y && mouseY <= sl_y + slider_height || wasSliding)) {
wasSliding = true; wasSliding = true;
float dx = ((float)Mouse.getDX() * (float)new ScaledResolution(mc, mc.displayWidth, mc.displayHeight).getScaledWidth() / mc.displayWidth); float dx = ((float) Mouse.getDX() * (float) new ScaledResolution(mc, mc.displayWidth, mc.displayHeight).getScaledWidth() / mc.displayWidth);
this.pos_left = Math.min(1f-this.zoom_scale, Math.max(0f, this.pos_left+(dx/(float)tlWidth))); this.pos_left = Math.min(1f - this.zoom_scale, Math.max(0f, this.pos_left + (dx / (float) tlWidth)));
} }
if(!Mouse.isButtonDown(0)) { if(!Mouse.isButtonDown(0)) {
@@ -459,17 +431,17 @@ public class GuiReplayOverlay extends Gui {
boolean hover = false; boolean hover = false;
int px = plus_x; int px = plus_x;
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
if(mouseX >= maxX+2 && mouseX <= maxX+2+9 if(mouseX >= maxX + 2 && mouseX <= maxX + 2 + 9
&& mouseY >= y+1 && mouseY <= y+1+9) { && mouseY >= y + 1 && mouseY <= y + 1 + 9) {
hover = true; hover = true;
} }
} }
if(hover) { if(hover) {
px+=9; px += 9;
} }
this.drawModalRectWithCustomSizedTexture(maxX+2, y+1, px, plus_y, 9, 9, 64, 64); this.drawModalRectWithCustomSizedTexture(maxX + 2, y + 1, px, plus_y, 9, 9, 64, 64);
if(hover && Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(hover && Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
zoomIn(); zoomIn();
@@ -479,75 +451,75 @@ public class GuiReplayOverlay extends Gui {
int mx = minus_x; int mx = minus_x;
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
if(mouseX >= maxX+2 && mouseX <= maxX+2+9 if(mouseX >= maxX + 2 && mouseX <= maxX + 2 + 9
&& mouseY >= y+9+3 && mouseY <= y+9+3+9) { && mouseY >= y + 9 + 3 && mouseY <= y + 9 + 3 + 9) {
hover = true; hover = true;
} }
} }
if(hover) { if(hover) {
mx+=9; mx += 9;
} }
this.drawModalRectWithCustomSizedTexture(maxX+2, y+9+3, mx, minus_y, 9, 9, 64, 64); this.drawModalRectWithCustomSizedTexture(maxX + 2, y + 9 + 3, mx, minus_y, 9, 9, 64, 64);
if(hover && Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(hover && Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
zoomOut(); zoomOut();
} }
//show Time String //show Time String
if(mouseX >= zero && mouseX <= full && mouseY >= y && mouseY <= y+22) { if(mouseX >= zero && mouseX <= full && mouseY >= y && mouseY <= y + 22) {
long tot = Math.round((double)timelineLength*zoom_scale); long tot = Math.round((double) timelineLength * zoom_scale);
double perc = (mouseX-(realTimelineX+4))/(double)(full-zero); double perc = (mouseX - (realTimelineX + 4)) / (double) (full - zero);
long time = Math.round(this.pos_left*(double)timelineLength)+Math.round(perc*(double)tot); long time = Math.round(this.pos_left * (double) timelineLength) + Math.round(perc * (double) tot);
String timestamp = (String.format("%02d:%02ds", String timestamp = (String.format("%02d:%02ds",
TimeUnit.MILLISECONDS.toMinutes(time), TimeUnit.MILLISECONDS.toMinutes(time),
TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MILLISECONDS.toSeconds(time) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time)) TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time))
)); ));
this.drawCenteredString(mc.fontRendererObj, timestamp, mouseX, mouseY+5, Color.WHITE.getRGB()); this.drawCenteredString(mc.fontRendererObj, timestamp, mouseX, mouseY + 5, Color.WHITE.getRGB());
} }
//draw Markers on timeline //draw Markers on timeline
MarkerType mt = MarkerType.getMarkerType(zoom_scale, timelineLength); MarkerType mt = MarkerType.getMarkerType(zoom_scale, timelineLength);
//every x seconds, draw small marker //every x seconds, draw small marker
long left_real = Math.round(pos_left*(double)timelineLength); long left_real = Math.round(pos_left * (double) timelineLength);
long right_real = left_real+(Math.round(zoom_scale*timelineLength)); long right_real = left_real + (Math.round(zoom_scale * timelineLength));
long tot = Math.round((double)timelineLength*zoom_scale); long tot = Math.round((double) timelineLength * zoom_scale);
for(int s=0; s<=timelineLength; s+= mt.getSmallDistance()) { for(int s = 0; s <= timelineLength; s += mt.getSmallDistance()) {
if(s > right_real) break; if(s > right_real) break;
if(s >= left_real) { if(s >= left_real) {
//calculate absolute position on screen //calculate absolute position on screen
long relative = (s) - (left_real); long relative = (s) - (left_real);
double perc = ((double)relative/(double)tot); double perc = ((double) relative / (double) tot);
long real_width = full-zero; long real_width = full - zero;
long rel_x = Math.round(perc*(double)real_width); long rel_x = Math.round(perc * (double) real_width);
long real_x = zero+rel_x; long real_x = zero + rel_x;
this.drawVerticalLine((int)real_x, y+19-3, y+19, Color.WHITE.getRGB()); this.drawVerticalLine((int) real_x, y + 19 - 3, y + 19, Color.WHITE.getRGB());
} }
} }
//every x seconds, draw big marker //every x seconds, draw big marker
for(int s=0; s<=timelineLength; s+= mt.getDistance()) { for(int s = 0; s <= timelineLength; s += mt.getDistance()) {
if(s > right_real) break; if(s > right_real) break;
if(s >= left_real) { if(s >= left_real) {
//calculate absolute position on screen //calculate absolute position on screen
long relative = s - (left_real); long relative = s - (left_real);
double perc = ((double)relative/(double)tot); double perc = ((double) relative / (double) tot);
long real_width = full-zero; long real_width = full - zero;
long rel_x = Math.round(perc*(double)real_width); long rel_x = Math.round(perc * (double) real_width);
long real_x = zero+rel_x; long real_x = zero + rel_x;
this.drawVerticalLine((int)real_x, y+19-7, y+19, Color.LIGHT_GRAY.getRGB()); this.drawVerticalLine((int) real_x, y + 19 - 7, y + 19, Color.LIGHT_GRAY.getRGB());
//write text //write text
int time = s; int time = s;
@@ -557,31 +529,31 @@ public class GuiReplayOverlay extends Gui {
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time)) TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time))
)); ));
this.drawCenteredString(mc.fontRendererObj, timestamp, (int)real_x, y-8, Color.WHITE.getRGB()); this.drawCenteredString(mc.fontRendererObj, timestamp, (int) real_x, y - 8, Color.WHITE.getRGB());
} }
} }
//handle Mouse clicks on realTimeLine //handle Mouse clicks on realTimeLine
if(Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class) && !wasSliding && mouseX >= minX+tl_begin_width && mouseX <= maxX-tl_end_width && if(Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class) && !wasSliding && mouseX >= minX + tl_begin_width && mouseX <= maxX - tl_end_width &&
mouseY >= y && mouseY <= y+22) { mouseY >= y && mouseY <= y + 22) {
//calculate real time and set cursor accordingly //calculate real time and set cursor accordingly
int width = (maxX-tl_end_width) - (minX+tl_begin_width); int width = (maxX - tl_end_width) - (minX + tl_begin_width);
int rel_x = mouseX-(minX+tl_begin_width); int rel_x = mouseX - (minX + tl_begin_width);
float rel_pos = (float)rel_x/(float)width; float rel_pos = (float) rel_x / (float) width;
float abs_width = (zoom_scale*(float)timelineLength); float abs_width = (zoom_scale * (float) timelineLength);
int real_pos = Math.round(left_real+((rel_pos)*abs_width)); int real_pos = Math.round(left_real + ((rel_pos) * abs_width));
ReplayHandler.setRealTimelineCursor(real_pos); ReplayHandler.setRealTimelineCursor(real_pos);
//Keyframe click handling here //Keyframe click handling here
if(isClick()) { if(isClick()) {
//tolerance is 2 pixels multiplied with the timespan of one pixel //tolerance is 2 pixels multiplied with the timespan of one pixel
int tolerance = 2*Math.round(abs_width/(float)width); int tolerance = 2 * Math.round(abs_width / (float) width);
if(mouseY >= y+9) { if(mouseY >= y + 9) {
TimeKeyframe close = ReplayHandler.getClosestTimeKeyframeForRealTime(ReplayHandler.getRealTimelineCursor(), tolerance); TimeKeyframe close = ReplayHandler.getClosestTimeKeyframeForRealTime(ReplayHandler.getRealTimelineCursor(), tolerance);
ReplayHandler.selectKeyframe(close); //can be null, deselects keyframe ReplayHandler.selectKeyframe(close); //can be null, deselects keyframe
} else { } else {
@@ -593,18 +565,18 @@ public class GuiReplayOverlay extends Gui {
//Draw Realtime Cursor //Draw Realtime Cursor
if(ReplayHandler.getRealTimelineCursor() >= left_real && ReplayHandler.getRealTimelineCursor() <= right_real) { if(ReplayHandler.getRealTimelineCursor() >= left_real && ReplayHandler.getRealTimelineCursor() <= right_real) {
long rel_pos = ReplayHandler.getRealTimelineCursor()-left_real; long rel_pos = ReplayHandler.getRealTimelineCursor() - left_real;
long rel_width = right_real-left_real; long rel_width = right_real - left_real;
double perc = (double)rel_pos/(double)rel_width; double perc = (double) rel_pos / (double) rel_width;
int real_width = (maxX-tl_end_width) - (minX+tl_begin_width); int real_width = (maxX - tl_end_width) - (minX + tl_begin_width);
double rel_x = (float)real_width*perc; double rel_x = (float) real_width * perc;
int real_x = (int)Math.round((minX+tl_begin_width)+rel_x); int real_x = (int) Math.round((minX + tl_begin_width) + rel_x);
mc.renderEngine.bindTexture(this.replay_gui); mc.renderEngine.bindTexture(this.replay_gui);
GL11.glEnable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_BLEND);
this.drawModalRectWithCustomSizedTexture(real_x-3, y+3, 44, 0, 8, 16, 64, 64); this.drawModalRectWithCustomSizedTexture(real_x - 3, y + 3, 44, 0, 8, 16, 64, 64);
//this.drawModalRectWithCustomSizedTexture(real_x, sl_y, u, v, width, height, textureWidth, textureHeight) //this.drawModalRectWithCustomSizedTexture(real_x, sl_y, u, v, width, height, textureWidth, textureHeight)
} }
@@ -617,7 +589,7 @@ public class GuiReplayOverlay extends Gui {
int dx = 18; int dx = 18;
int dy = 0; int dy = 0;
int ry = y+3; int ry = y + 3;
if(kf instanceof TimeKeyframe) { if(kf instanceof TimeKeyframe) {
dy = 5; dy = 5;
@@ -628,14 +600,14 @@ public class GuiReplayOverlay extends Gui {
} }
long relative = kf.getRealTimestamp() - (left_real); long relative = kf.getRealTimestamp() - (left_real);
double perc = ((double)relative/(double)tot); double perc = ((double) relative / (double) tot);
long real_width = full-zero; long real_width = full - zero;
long rel_x = Math.round(perc*(double)real_width); long rel_x = Math.round(perc * (double) real_width);
long real_x = zero+rel_x - 2; long real_x = zero + rel_x - 2;
this.drawModalRectWithCustomSizedTexture((int)real_x, ry, dx, dy, 5, 5, 64, 64); this.drawModalRectWithCustomSizedTexture((int) real_x, ry, dx, dy, 5, 5, 64, 64);
} }
} }
@@ -649,8 +621,8 @@ public class GuiReplayOverlay extends Gui {
hover = false; hover = false;
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
if(mouseX >= r_ppButtonX && mouseX <= r_ppButtonX+20 if(mouseX >= r_ppButtonX && mouseX <= r_ppButtonX + 20
&& mouseY >= r_ppButtonY && mouseY <= r_ppButtonY+20) { && mouseY >= r_ppButtonY && mouseY <= r_ppButtonY + 20) {
hover = true; hover = true;
} }
} }
@@ -685,62 +657,20 @@ public class GuiReplayOverlay extends Gui {
} }
private void addTimeKeyframe() { private void addTimeKeyframe() {
ReplayHandler.addKeyframe(new TimeKeyframe(ReplayHandler.getRealTimelineCursor(), ReplayHandler.getReplayTime())); ReplayHandler.addKeyframe(new TimeKeyframe(ReplayHandler.getRealTimelineCursor(), ReplayMod.replaySender.currentTimeStamp()));
}
private enum MarkerType {
ONE_S(1*1000, 100),
FIVE_S(5*1000, 1*1000),
QUARTER_M(15*1000, 3*1000),
HALF_M(30*1000, 5*1000),
ONE_M(60*1000, 10*1000),
FIVE_M(5*60*1000, 50*1000);
int minimum;
int small_min;
int maximum = 10;
int getDistance() {
return minimum;
}
int getSmallDistance() {
return small_min;
}
MarkerType(int minimum, int small_min) {
this.minimum = minimum;
this.small_min = small_min;
}
public static MarkerType getMarkerType(float scale, long totalLength) {
long visible = Math.round((double)totalLength*scale);
long seconds = visible;
for(MarkerType mt : values()) {
if(seconds/mt.getDistance() <= 10) {
return mt;
}
}
return FIVE_M;
}
} }
private void zoomIn() { private void zoomIn() {
if(!isClick()) return; if(!isClick()) return;
this.zoom_scale = Math.max(0.025f, zoom_scale-zoom_steps); this.zoom_scale = Math.max(0.025f, zoom_scale - zoom_steps);
} }
private void zoomOut() { private void zoomOut() {
if(!isClick()) return; if(!isClick()) return;
this.zoom_scale = Math.min(1f, zoom_scale+zoom_steps); this.zoom_scale = Math.min(1f, zoom_scale + zoom_steps);
this.pos_left = Math.min(pos_left, 1f-zoom_scale); this.pos_left = Math.min(pos_left, 1f - zoom_scale);
} }
private boolean mouseDwn = false;
private boolean isClick() { private boolean isClick() {
if(Mouse.isButtonDown(0)) { if(Mouse.isButtonDown(0)) {
boolean bef = new Boolean(mouseDwn); boolean bef = new Boolean(mouseDwn);
@@ -751,4 +681,44 @@ public class GuiReplayOverlay extends Gui {
return false; return false;
} }
} }
private enum MarkerType {
ONE_S(1 * 1000, 100),
FIVE_S(5 * 1000, 1 * 1000),
QUARTER_M(15 * 1000, 3 * 1000),
HALF_M(30 * 1000, 5 * 1000),
ONE_M(60 * 1000, 10 * 1000),
FIVE_M(5 * 60 * 1000, 50 * 1000);
int minimum;
int small_min;
int maximum = 10;
MarkerType(int minimum, int small_min) {
this.minimum = minimum;
this.small_min = small_min;
}
public static MarkerType getMarkerType(float scale, long totalLength) {
long visible = Math.round((double) totalLength * scale);
long seconds = visible;
for(MarkerType mt : values()) {
if(seconds / mt.getDistance() <= 10) {
return mt;
}
}
return FIVE_M;
}
int getDistance() {
return minimum;
}
int getSmallDistance() {
return small_min;
}
}
} }

View File

@@ -1,28 +1,22 @@
package eu.crushedpixel.replaymod.events; package eu.crushedpixel.replaymod.events;
import org.lwjgl.input.Keyboard;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiIngame;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiYesNoCallback;
import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent.KeyInputEvent;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.entities.CameraEntity.MoveDirection; import eu.crushedpixel.replaymod.entities.CameraEntity.MoveDirection;
import eu.crushedpixel.replaymod.gui.GuiCancelRender; import eu.crushedpixel.replaymod.gui.GuiCancelRender;
import eu.crushedpixel.replaymod.gui.elements.GuiMouseInput; import eu.crushedpixel.replaymod.gui.GuiMouseInput;
import eu.crushedpixel.replaymod.registry.KeybindRegistry; import eu.crushedpixel.replaymod.registry.KeybindRegistry;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.replay.ReplayProcess; import eu.crushedpixel.replaymod.replay.ReplayProcess;
import eu.crushedpixel.replaymod.replay.spectate.SpectateHandler; import eu.crushedpixel.replaymod.replay.spectate.SpectateHandler;
import eu.crushedpixel.replaymod.video.ReplayScreenshot; import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent.KeyInputEvent;
import org.lwjgl.input.Keyboard;
public class KeyInputHandler { public class KeyInputHandler {
private Minecraft mc = Minecraft.getMinecraft(); private final Minecraft mc = Minecraft.getMinecraft();
private boolean escDown = false; private boolean escDown = false;

View File

@@ -1,10 +1,6 @@
package eu.crushedpixel.replaymod.events; package eu.crushedpixel.replaymod.events;
import java.io.IOException; import eu.crushedpixel.replaymod.reflection.MCPNames;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiChat; import net.minecraft.client.gui.GuiChat;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
@@ -17,14 +13,13 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.play.client.C16PacketClientStatus; import net.minecraft.network.play.client.C16PacketClientStatus;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.util.ReportedException; import net.minecraft.util.ReportedException;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import eu.crushedpixel.replaymod.entities.CameraEntity; import java.io.IOException;
import eu.crushedpixel.replaymod.reflection.MCPNames; import java.lang.reflect.Field;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MinecraftTicker { public class MinecraftTicker {
@@ -32,11 +27,6 @@ public class MinecraftTicker {
private static Method getSystemTime, updateDebugProfilerName, private static Method getSystemTime, updateDebugProfilerName,
clickMouse, middleClickMouse, rightClickMouse, sendClickBlockToController; clickMouse, middleClickMouse, rightClickMouse, sendClickBlockToController;
private static Minecraft mc = Minecraft.getMinecraft();
private static float camPitch, camYaw, smoothCamPartialTicks,
smoothCamFilterX, smoothCamFilterY;
static { static {
try { try {
debugCrashKeyPressTime = Minecraft.class.getDeclaredField(MCPNames.field("field_83002_am")); debugCrashKeyPressTime = Minecraft.class.getDeclaredField(MCPNames.field("field_83002_am"));
@@ -84,230 +74,175 @@ public class MinecraftTicker {
i = Mouse.getEventButton(); i = Mouse.getEventButton();
KeyBinding.setKeyBindState(i - 100, Mouse.getEventButtonState()); KeyBinding.setKeyBindState(i - 100, Mouse.getEventButtonState());
if (Mouse.getEventButtonState()) if(Mouse.getEventButtonState()) {
{ if(mc.thePlayer.isSpectator() && i == 2) {
if (mc.thePlayer.isSpectator() && i == 2)
{
mc.ingameGUI.func_175187_g().func_175261_b(); mc.ingameGUI.func_175187_g().func_175261_b();
} } else {
else
{
KeyBinding.onTick(i - 100); KeyBinding.onTick(i - 100);
} }
} }
long k = (Long)getSystemTime.invoke(mc) - (Long)systemTime.get(mc); long k = (Long) getSystemTime.invoke(mc) - (Long) systemTime.get(mc);
if (k <= 200L) if(k <= 200L) {
{
int j = Mouse.getEventDWheel(); int j = Mouse.getEventDWheel();
if (j != 0) if(j != 0) {
{ if(mc.thePlayer.isSpectator()) {
if (mc.thePlayer.isSpectator())
{
j = j < 0 ? -1 : 1; j = j < 0 ? -1 : 1;
if (mc.ingameGUI.func_175187_g().func_175262_a()) if(mc.ingameGUI.func_175187_g().func_175262_a()) {
{
mc.ingameGUI.func_175187_g().func_175259_b(-j); mc.ingameGUI.func_175187_g().func_175259_b(-j);
} } else {
else float f = MathHelper.clamp_float(mc.thePlayer.capabilities.getFlySpeed() + (float) j * 0.005F, 0.0F, 0.2F);
{
float f = MathHelper.clamp_float(mc.thePlayer.capabilities.getFlySpeed() + (float)j * 0.005F, 0.0F, 0.2F);
mc.thePlayer.capabilities.setFlySpeed(f); mc.thePlayer.capabilities.setFlySpeed(f);
} }
} } else {
else
{
mc.thePlayer.inventory.changeCurrentItem(j); mc.thePlayer.inventory.changeCurrentItem(j);
} }
} }
if (mc.currentScreen == null) if(mc.currentScreen == null) {
{ if(!mc.inGameHasFocus && Mouse.getEventButtonState()) {
if (!mc.inGameHasFocus && Mouse.getEventButtonState())
{
mc.setIngameFocus(); mc.setIngameFocus();
} }
} } else {
else
{
mc.currentScreen.handleMouseInput(); mc.currentScreen.handleMouseInput();
} }
} }
net.minecraftforge.fml.common.FMLCommonHandler.instance().fireMouseInput(); net.minecraftforge.fml.common.FMLCommonHandler.instance().fireMouseInput();
} }
if ((Integer)leftClickCounter.get(mc) > 0) if((Integer) leftClickCounter.get(mc) > 0) {
{ leftClickCounter.set(mc, (Integer) leftClickCounter.get(mc) - 1);
leftClickCounter.set(mc, (Integer)leftClickCounter.get(mc) - 1);
} }
mc.mcProfiler.endStartSection("keyboard"); mc.mcProfiler.endStartSection("keyboard");
while (Keyboard.next()) while(Keyboard.next()) {
{
i = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey(); i = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
KeyBinding.setKeyBindState(i, Keyboard.getEventKeyState()); KeyBinding.setKeyBindState(i, Keyboard.getEventKeyState());
if (Keyboard.getEventKeyState()) if(Keyboard.getEventKeyState()) {
{
KeyBinding.onTick(i); KeyBinding.onTick(i);
} }
if ((Long)debugCrashKeyPressTime.get(mc) > 0L) if((Long) debugCrashKeyPressTime.get(mc) > 0L) {
{ if((Long) getSystemTime.invoke(mc) - (Long) debugCrashKeyPressTime.get(mc) >= 6000L) {
if ((Long)getSystemTime.invoke(mc) - (Long)debugCrashKeyPressTime.get(mc) >= 6000L)
{
throw new ReportedException(new CrashReport("Manually triggered debug crash", new Throwable())); throw new ReportedException(new CrashReport("Manually triggered debug crash", new Throwable()));
} }
if (!Keyboard.isKeyDown(46) || !Keyboard.isKeyDown(61)) if(!Keyboard.isKeyDown(46) || !Keyboard.isKeyDown(61)) {
{
debugCrashKeyPressTime.set(mc, -1); debugCrashKeyPressTime.set(mc, -1);
} }
} } else if(Keyboard.isKeyDown(46) && Keyboard.isKeyDown(61)) {
else if (Keyboard.isKeyDown(46) && Keyboard.isKeyDown(61))
{
debugCrashKeyPressTime.set(mc, getSystemTime.invoke(mc)); debugCrashKeyPressTime.set(mc, getSystemTime.invoke(mc));
} }
mc.dispatchKeypresses(); mc.dispatchKeypresses();
if (Keyboard.getEventKeyState()) if(Keyboard.getEventKeyState()) {
{ if(i == 62 && mc.entityRenderer != null) {
if (i == 62 && mc.entityRenderer != null)
{
mc.entityRenderer.switchUseShader(); mc.entityRenderer.switchUseShader();
} }
if (mc.currentScreen != null) if(mc.currentScreen != null) {
{
mc.currentScreen.handleKeyboardInput(); mc.currentScreen.handleKeyboardInput();
} } else {
else if(i == 1) {
{
if (i == 1)
{
mc.displayInGameMenu(); mc.displayInGameMenu();
} }
if (i == 32 && Keyboard.isKeyDown(61) && mc.ingameGUI != null) if(i == 32 && Keyboard.isKeyDown(61) && mc.ingameGUI != null) {
{
mc.ingameGUI.getChatGUI().clearChatMessages(); mc.ingameGUI.getChatGUI().clearChatMessages();
} }
if (i == 31 && Keyboard.isKeyDown(61)) if(i == 31 && Keyboard.isKeyDown(61)) {
{
mc.refreshResources(); mc.refreshResources();
} }
if (i == 17 && Keyboard.isKeyDown(61)) if(i == 17 && Keyboard.isKeyDown(61)) {
{
; ;
} }
if (i == 18 && Keyboard.isKeyDown(61)) if(i == 18 && Keyboard.isKeyDown(61)) {
{
; ;
} }
if (i == 47 && Keyboard.isKeyDown(61)) if(i == 47 && Keyboard.isKeyDown(61)) {
{
; ;
} }
if (i == 38 && Keyboard.isKeyDown(61)) if(i == 38 && Keyboard.isKeyDown(61)) {
{
; ;
} }
if (i == 22 && Keyboard.isKeyDown(61)) if(i == 22 && Keyboard.isKeyDown(61)) {
{
; ;
} }
if (i == 20 && Keyboard.isKeyDown(61)) if(i == 20 && Keyboard.isKeyDown(61)) {
{
mc.refreshResources(); mc.refreshResources();
} }
if (i == 33 && Keyboard.isKeyDown(61)) if(i == 33 && Keyboard.isKeyDown(61)) {
{
boolean flag1 = Keyboard.isKeyDown(42) | Keyboard.isKeyDown(54); boolean flag1 = Keyboard.isKeyDown(42) | Keyboard.isKeyDown(54);
mc.gameSettings.setOptionValue(GameSettings.Options.RENDER_DISTANCE, flag1 ? -1 : 1); mc.gameSettings.setOptionValue(GameSettings.Options.RENDER_DISTANCE, flag1 ? -1 : 1);
} }
if (i == 30 && Keyboard.isKeyDown(61)) if(i == 30 && Keyboard.isKeyDown(61)) {
{
mc.renderGlobal.loadRenderers(); mc.renderGlobal.loadRenderers();
} }
if (i == 35 && Keyboard.isKeyDown(61)) if(i == 35 && Keyboard.isKeyDown(61)) {
{
mc.gameSettings.advancedItemTooltips = !mc.gameSettings.advancedItemTooltips; mc.gameSettings.advancedItemTooltips = !mc.gameSettings.advancedItemTooltips;
mc.gameSettings.saveOptions(); mc.gameSettings.saveOptions();
} }
if (i == 48 && Keyboard.isKeyDown(61)) if(i == 48 && Keyboard.isKeyDown(61)) {
{
mc.getRenderManager().setDebugBoundingBox(!mc.getRenderManager().isDebugBoundingBox()); mc.getRenderManager().setDebugBoundingBox(!mc.getRenderManager().isDebugBoundingBox());
} }
if (i == 25 && Keyboard.isKeyDown(61)) if(i == 25 && Keyboard.isKeyDown(61)) {
{
mc.gameSettings.pauseOnLostFocus = !mc.gameSettings.pauseOnLostFocus; mc.gameSettings.pauseOnLostFocus = !mc.gameSettings.pauseOnLostFocus;
mc.gameSettings.saveOptions(); mc.gameSettings.saveOptions();
} }
if (i == 59) if(i == 59) {
{
mc.gameSettings.hideGUI = !mc.gameSettings.hideGUI; mc.gameSettings.hideGUI = !mc.gameSettings.hideGUI;
} }
if (i == 61) if(i == 61) {
{
mc.gameSettings.showDebugInfo = !mc.gameSettings.showDebugInfo; mc.gameSettings.showDebugInfo = !mc.gameSettings.showDebugInfo;
mc.gameSettings.showDebugProfilerChart = GuiScreen.isShiftKeyDown(); mc.gameSettings.showDebugProfilerChart = GuiScreen.isShiftKeyDown();
} }
if (mc.gameSettings.keyBindTogglePerspective.isPressed()) if(mc.gameSettings.keyBindTogglePerspective.isPressed()) {
{
++mc.gameSettings.thirdPersonView; ++mc.gameSettings.thirdPersonView;
if (mc.gameSettings.thirdPersonView > 2) if(mc.gameSettings.thirdPersonView > 2) {
{
mc.gameSettings.thirdPersonView = 0; mc.gameSettings.thirdPersonView = 0;
} }
if (mc.gameSettings.thirdPersonView == 0) if(mc.gameSettings.thirdPersonView == 0) {
{
mc.entityRenderer.loadEntityShader(mc.getRenderViewEntity()); mc.entityRenderer.loadEntityShader(mc.getRenderViewEntity());
} } else if(mc.gameSettings.thirdPersonView == 1) {
else if (mc.gameSettings.thirdPersonView == 1) mc.entityRenderer.loadEntityShader((Entity) null);
{
mc.entityRenderer.loadEntityShader((Entity)null);
} }
} }
if (mc.gameSettings.keyBindSmoothCamera.isPressed()) if(mc.gameSettings.keyBindSmoothCamera.isPressed()) {
{
mc.gameSettings.smoothCamera = !mc.gameSettings.smoothCamera; mc.gameSettings.smoothCamera = !mc.gameSettings.smoothCamera;
} }
} }
if (mc.gameSettings.showDebugInfo && mc.gameSettings.showDebugProfilerChart) if(mc.gameSettings.showDebugInfo && mc.gameSettings.showDebugProfilerChart) {
{ if(i == 11) {
if (i == 11)
{
updateDebugProfilerName.invoke(mc, 0); updateDebugProfilerName.invoke(mc, 0);
} }
for (int l = 0; l < 9; ++l) for(int l = 0; l < 9; ++l) {
{ if(i == 2 + l) {
if (i == 2 + l) updateDebugProfilerName.invoke(mc, l + 1);
{
updateDebugProfilerName.invoke(mc, l+1);
} }
} }
} }
@@ -315,16 +250,11 @@ public class MinecraftTicker {
net.minecraftforge.fml.common.FMLCommonHandler.instance().fireKeyInput(); net.minecraftforge.fml.common.FMLCommonHandler.instance().fireKeyInput();
} }
for (i = 0; i < 9; ++i) for(i = 0; i < 9; ++i) {
{ if(mc.gameSettings.keyBindsHotbar[i].isPressed()) {
if (mc.gameSettings.keyBindsHotbar[i].isPressed()) if(mc.thePlayer.isSpectator()) {
{
if (mc.thePlayer.isSpectator())
{
mc.ingameGUI.func_175187_g().func_175260_a(i); mc.ingameGUI.func_175187_g().func_175260_a(i);
} } else {
else
{
mc.thePlayer.inventory.currentItem = i; mc.thePlayer.inventory.currentItem = i;
} }
} }
@@ -332,59 +262,44 @@ public class MinecraftTicker {
boolean flag = mc.gameSettings.chatVisibility != EntityPlayer.EnumChatVisibility.HIDDEN; boolean flag = mc.gameSettings.chatVisibility != EntityPlayer.EnumChatVisibility.HIDDEN;
while (mc.gameSettings.keyBindInventory.isPressed()) while(mc.gameSettings.keyBindInventory.isPressed()) {
{ if(mc.playerController.isRidingHorse()) {
if (mc.playerController.isRidingHorse())
{
mc.thePlayer.sendHorseInventory(); mc.thePlayer.sendHorseInventory();
} } else {
else
{
mc.getNetHandler().addToSendQueue(new C16PacketClientStatus(C16PacketClientStatus.EnumState.OPEN_INVENTORY_ACHIEVEMENT)); mc.getNetHandler().addToSendQueue(new C16PacketClientStatus(C16PacketClientStatus.EnumState.OPEN_INVENTORY_ACHIEVEMENT));
mc.displayGuiScreen(new GuiInventory(mc.thePlayer)); mc.displayGuiScreen(new GuiInventory(mc.thePlayer));
} }
} }
while (mc.gameSettings.keyBindDrop.isPressed()) while(mc.gameSettings.keyBindDrop.isPressed()) {
{ if(!mc.thePlayer.isSpectator()) {
if (!mc.thePlayer.isSpectator())
{
mc.thePlayer.dropOneItem(GuiScreen.isCtrlKeyDown()); mc.thePlayer.dropOneItem(GuiScreen.isCtrlKeyDown());
} }
} }
while (mc.gameSettings.keyBindChat.isPressed() && flag) while(mc.gameSettings.keyBindChat.isPressed() && flag) {
{
mc.displayGuiScreen(new GuiChat()); mc.displayGuiScreen(new GuiChat());
} }
if (mc.currentScreen == null && mc.gameSettings.keyBindCommand.isPressed() && flag) if(mc.currentScreen == null && mc.gameSettings.keyBindCommand.isPressed() && flag) {
{
mc.displayGuiScreen(new GuiChat("/")); mc.displayGuiScreen(new GuiChat("/"));
} }
if (mc.thePlayer != null && mc.thePlayer.isUsingItem()) if(mc.thePlayer != null && mc.thePlayer.isUsingItem()) {
{ if(!mc.gameSettings.keyBindUseItem.isKeyDown()) {
if (!mc.gameSettings.keyBindUseItem.isKeyDown())
{
mc.playerController.onStoppedUsingItem(mc.thePlayer); mc.playerController.onStoppedUsingItem(mc.thePlayer);
} }
label435: label435:
while (true) while(true) {
{ if(!mc.gameSettings.keyBindAttack.isPressed()) {
if (!mc.gameSettings.keyBindAttack.isPressed()) while(mc.gameSettings.keyBindUseItem.isPressed()) {
{
while (mc.gameSettings.keyBindUseItem.isPressed())
{
; ;
} }
while (true) while(true) {
{ if(mc.gameSettings.keyBindPickBlock.isPressed()) {
if (mc.gameSettings.keyBindPickBlock.isPressed())
{
continue; continue;
} }
@@ -392,50 +307,50 @@ public class MinecraftTicker {
} }
} }
} }
} } else {
else while(mc.gameSettings.keyBindAttack.isPressed()) {
{
while (mc.gameSettings.keyBindAttack.isPressed())
{
if(mc != null) if(mc != null)
try { try {
clickMouse.invoke(mc); clickMouse.invoke(mc);
} catch(Exception e) {} } catch(Exception e) {
}
} }
while (mc.gameSettings.keyBindUseItem.isPressed()) while(mc.gameSettings.keyBindUseItem.isPressed()) {
{
if(mc != null) if(mc != null)
try { try {
rightClickMouse.invoke(mc); rightClickMouse.invoke(mc);
} catch(Exception e) {} } catch(Exception e) {
}
} }
while (mc.gameSettings.keyBindPickBlock.isPressed()) while(mc.gameSettings.keyBindPickBlock.isPressed()) {
{
if(mc != null) if(mc != null)
try { try {
middleClickMouse.invoke(mc); middleClickMouse.invoke(mc);
} catch(Exception e) {} } catch(Exception e) {
}
} }
} }
if (mc.gameSettings.keyBindUseItem.isKeyDown() && (Integer)rightClickDelayTimer.get(mc) == 0 && !mc.thePlayer.isUsingItem()) if(mc.gameSettings.keyBindUseItem.isKeyDown() && (Integer) rightClickDelayTimer.get(mc) == 0 && !mc.thePlayer.isUsingItem()) {
{
if(mc != null) if(mc != null)
try { try {
rightClickMouse.invoke(mc); rightClickMouse.invoke(mc);
} catch(Exception e) {} } catch(Exception e) {
}
} }
if(mc != null) if(mc != null)
try { try {
sendClickBlockToController.invoke(mc, mc.currentScreen == null && mc.gameSettings.keyBindAttack.isKeyDown() && mc.inGameHasFocus); sendClickBlockToController.invoke(mc, mc.currentScreen == null && mc.gameSettings.keyBindAttack.isKeyDown() && mc.inGameHasFocus);
} catch(Exception e) {} } catch(Exception e) {
}
if(mc != null) if(mc != null)
systemTime.set(mc, getSystemTime.invoke(mc)); systemTime.set(mc, getSystemTime.invoke(mc));
} catch(Exception e) {} } catch(Exception e) {
}
} }
} }

View File

@@ -1,31 +1,17 @@
package eu.crushedpixel.replaymod.events; package eu.crushedpixel.replaymod.events;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import eu.crushedpixel.replaymod.reflection.MCPNames;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.Packet; import net.minecraft.network.Packet;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.S04PacketEntityEquipment; import net.minecraft.network.play.server.*;
import net.minecraft.network.play.server.S0APacketUseBed;
import net.minecraft.network.play.server.S0BPacketAnimation;
import net.minecraft.network.play.server.S0CPacketSpawnPlayer;
import net.minecraft.network.play.server.S0DPacketCollectItem;
import net.minecraft.network.play.server.S12PacketEntityVelocity;
import net.minecraft.network.play.server.S13PacketDestroyEntities;
import net.minecraft.network.play.server.S14PacketEntity.S17PacketEntityLookMove; import net.minecraft.network.play.server.S14PacketEntity.S17PacketEntityLookMove;
import net.minecraft.network.play.server.S18PacketEntityTeleport;
import net.minecraft.network.play.server.S19PacketEntityHeadLook;
import net.minecraft.network.play.server.S19PacketEntityStatus;
import net.minecraft.network.play.server.S1BPacketEntityAttach;
import net.minecraft.network.play.server.S38PacketPlayerListItem;
import net.minecraft.network.play.server.S38PacketPlayerListItem.Action; import net.minecraft.network.play.server.S38PacketPlayerListItem.Action;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent;
@@ -38,14 +24,32 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent.ItemPickupEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent.ItemPickupEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent; import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import eu.crushedpixel.replaymod.reflection.MCPNames; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class RecordingHandler { public class RecordingHandler {
private Minecraft mc = Minecraft.getMinecraft(); public static final int entityID = Integer.MIN_VALUE + 9001;
private static Field dataWatcherField;
public static final int entityID = Integer.MIN_VALUE+9001; static {
try {
dataWatcherField = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_148960_i"));
dataWatcherField.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
private final Minecraft mc = Minecraft.getMinecraft();
private Double lastX = null, lastY = null, lastZ = null;
private List<Integer> lastEffects = new ArrayList<Integer>();
private ItemStack[] playerItems = new ItemStack[5];
private int ticksSinceLastCorrection = 0;
private boolean wasSleeping = false;
private int lastRiding = -1;
@SubscribeEvent @SubscribeEvent
public void onPlayerJoin(EntityJoinWorldEvent e) { public void onPlayerJoin(EntityJoinWorldEvent e) {
@@ -53,7 +57,7 @@ public class RecordingHandler {
if(e.entity != mc.thePlayer) return; if(e.entity != mc.thePlayer) return;
if(!ConnectionEventHandler.isRecording()) return; if(!ConnectionEventHandler.isRecording()) return;
EntityPlayer player = (EntityPlayer)e.entity; EntityPlayer player = (EntityPlayer) e.entity;
S38PacketPlayerListItem ppli = new S38PacketPlayerListItem(); S38PacketPlayerListItem ppli = new S38PacketPlayerListItem();
ByteBuf buf = Unpooled.buffer(); ByteBuf buf = Unpooled.buffer();
@@ -80,17 +84,6 @@ public class RecordingHandler {
} }
} }
private static Field dataWatcherField;
static {
try {
dataWatcherField = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_148960_i"));
dataWatcherField.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
private S0CPacketSpawnPlayer spawnPlayer(EntityPlayer player) { private S0CPacketSpawnPlayer spawnPlayer(EntityPlayer player) {
try { try {
S0CPacketSpawnPlayer packet = new S0CPacketSpawnPlayer(); S0CPacketSpawnPlayer packet = new S0CPacketSpawnPlayer();
@@ -104,8 +97,8 @@ public class RecordingHandler {
pb.writeInt(MathHelper.floor_double(player.posX * 32.0D)); pb.writeInt(MathHelper.floor_double(player.posX * 32.0D));
pb.writeInt(MathHelper.floor_double(player.posY * 32.0D)); pb.writeInt(MathHelper.floor_double(player.posY * 32.0D));
pb.writeInt(MathHelper.floor_double(player.posZ * 32.0D)); pb.writeInt(MathHelper.floor_double(player.posZ * 32.0D));
pb.writeByte((byte)((int)(player.rotationYaw * 256.0F / 360.0F))); pb.writeByte((byte) ((int) (player.rotationYaw * 256.0F / 360.0F)));
pb.writeByte((byte)((int)(player.rotationPitch * 256.0F / 360.0F))); pb.writeByte((byte) ((int) (player.rotationPitch * 256.0F / 360.0F)));
ItemStack itemstack = player.inventory.getCurrentItem(); ItemStack itemstack = player.inventory.getCurrentItem();
pb.writeShort(itemstack == null ? 0 : Item.getIdFromItem(itemstack.getItem())); pb.writeShort(itemstack == null ? 0 : Item.getIdFromItem(itemstack.getItem()));
@@ -123,19 +116,12 @@ public class RecordingHandler {
} }
} }
private Double lastX = null, lastY = null, lastZ = null;
private List<Integer> lastEffects = new ArrayList<Integer>();
private ItemStack[] playerItems = new ItemStack[5];
public void resetVars() { public void resetVars() {
lastX = lastY = lastZ = null; lastX = lastY = lastZ = null;
lastEffects = new ArrayList<Integer>(); lastEffects = new ArrayList<Integer>();
playerItems = new ItemStack[5]; playerItems = new ItemStack[5];
} }
private int ticksSinceLastCorrection = 0;
@SubscribeEvent @SubscribeEvent
public void onPlayerTick(PlayerTickEvent e) { public void onPlayerTick(PlayerTickEvent e) {
if(!ConnectionEventHandler.isRecording()) return; if(!ConnectionEventHandler.isRecording()) return;
@@ -170,20 +156,20 @@ public class RecordingHandler {
int x = MathHelper.floor_double(e.player.posX * 32.0D); int x = MathHelper.floor_double(e.player.posX * 32.0D);
int y = MathHelper.floor_double(e.player.posY * 32.0D); int y = MathHelper.floor_double(e.player.posY * 32.0D);
int z = MathHelper.floor_double(e.player.posZ * 32.0D); int z = MathHelper.floor_double(e.player.posZ * 32.0D);
byte yaw = (byte)((int)(e.player.rotationYaw * 256.0F / 360.0F)); byte yaw = (byte) ((int) (e.player.rotationYaw * 256.0F / 360.0F));
byte pitch = (byte)((int)(e.player.rotationPitch * 256.0F / 360.0F)); byte pitch = (byte) ((int) (e.player.rotationPitch * 256.0F / 360.0F));
packet = new S18PacketEntityTeleport(entityID, x, y, z, yaw, pitch, e.player.onGround); packet = new S18PacketEntityTeleport(entityID, x, y, z, yaw, pitch, e.player.onGround);
} else { } else {
byte oldYaw = (byte)((int)(e.player.prevRotationYaw * 256.0F / 360.0F)); byte oldYaw = (byte) ((int) (e.player.prevRotationYaw * 256.0F / 360.0F));
byte newYaw = (byte)((int)(e.player.rotationYaw * 256.0F / 360.0F)); byte newYaw = (byte) ((int) (e.player.rotationYaw * 256.0F / 360.0F));
byte oldPitch = (byte)((int)(e.player.prevRotationPitch * 256.0F / 360.0F)); byte oldPitch = (byte) ((int) (e.player.prevRotationPitch * 256.0F / 360.0F));
byte newPitch = (byte)((int)(e.player.rotationPitch * 256.0F / 360.0F)); byte newPitch = (byte) ((int) (e.player.rotationPitch * 256.0F / 360.0F));
byte dPitch = (byte)(newPitch-oldPitch); byte dPitch = (byte) (newPitch - oldPitch);
byte dYaw = (byte)(newYaw-oldYaw); byte dYaw = (byte) (newYaw - oldYaw);
packet = new S17PacketEntityLookMove(entityID, packet = new S17PacketEntityLookMove(entityID,
(byte)Math.round(dx*32), (byte)Math.round(dy*32), (byte)Math.round(dz*32), (byte) Math.round(dx * 32), (byte) Math.round(dy * 32), (byte) Math.round(dz * 32),
newYaw, newPitch, e.player.onGround); newYaw, newPitch, e.player.onGround);
} }
@@ -195,7 +181,7 @@ public class RecordingHandler {
PacketBuffer pb1 = new PacketBuffer(bb1); PacketBuffer pb1 = new PacketBuffer(bb1);
pb1.writeVarIntToBuffer(entityID); pb1.writeVarIntToBuffer(entityID);
pb1.writeByte(((int)(e.player.rotationYawHead * 256.0F / 360.0F))); pb1.writeByte(((int) (e.player.rotationYawHead * 256.0F / 360.0F)));
head.readPacketData(pb1); head.readPacketData(pb1);
@@ -345,7 +331,8 @@ public class RecordingHandler {
try { try {
if(event.entity.getEntityId() != mc.thePlayer.getEntityId()) { if(event.entity.getEntityId() != mc.thePlayer.getEntityId()) {
return; return;
}; }
;
S19PacketEntityStatus packet = new S19PacketEntityStatus(); S19PacketEntityStatus packet = new S19PacketEntityStatus();
@@ -382,7 +369,8 @@ public class RecordingHandler {
try { try {
if(event.entity.getEntityId() != mc.thePlayer.getEntityId()) { if(event.entity.getEntityId() != mc.thePlayer.getEntityId()) {
return; return;
}; }
;
S19PacketEntityStatus packet = new S19PacketEntityStatus(); S19PacketEntityStatus packet = new S19PacketEntityStatus();
@@ -421,15 +409,14 @@ public class RecordingHandler {
} }
} }
private boolean wasSleeping = false;
@SubscribeEvent @SubscribeEvent
public void onSleep(PlayerSleepInBedEvent event) { public void onSleep(PlayerSleepInBedEvent event) {
if(!ConnectionEventHandler.isRecording()) return; if(!ConnectionEventHandler.isRecording()) return;
try { try {
if(event.entityPlayer != mc.thePlayer) { if(event.entityPlayer != mc.thePlayer) {
return; return;
}; }
;
System.out.println(event.getResult()); System.out.println(event.getResult());
S0APacketUseBed pub = new S0APacketUseBed(); S0APacketUseBed pub = new S0APacketUseBed();
@@ -451,15 +438,14 @@ public class RecordingHandler {
} }
} }
private int lastRiding = -1;
@SubscribeEvent @SubscribeEvent
public void enterMinecart(MinecartInteractEvent event) { public void enterMinecart(MinecartInteractEvent event) {
if(!ConnectionEventHandler.isRecording()) return; if(!ConnectionEventHandler.isRecording()) return;
try { try {
if(event.player != mc.thePlayer) { if(event.player != mc.thePlayer) {
return; return;
}; }
;
S1BPacketEntityAttach pea = new S1BPacketEntityAttach(); S1BPacketEntityAttach pea = new S1BPacketEntityAttach();

View File

@@ -1,14 +1,13 @@
package eu.crushedpixel.replaymod.events; package eu.crushedpixel.replaymod.events;
import java.io.IOException; import eu.crushedpixel.replaymod.ReplayMod;
import java.lang.reflect.Field; import eu.crushedpixel.replaymod.chat.ChatMessageHandler;
import java.lang.reflect.InvocationTargetException; import eu.crushedpixel.replaymod.gui.GuiCancelRender;
import eu.crushedpixel.replaymod.gui.GuiMouseInput;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests; import eu.crushedpixel.replaymod.reflection.MCPNames;
import org.lwjgl.input.Keyboard; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import org.lwjgl.input.Mouse; import eu.crushedpixel.replaymod.replay.ReplayProcess;
import org.lwjgl.opengl.Display; import eu.crushedpixel.replaymod.video.ReplayScreenshot;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.client.event.MouseEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.client.event.RenderWorldLastEvent;
@@ -16,21 +15,19 @@ import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent; import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.common.gameevent.TickEvent;
import eu.crushedpixel.replaymod.gui.GuiCancelRender; import org.lwjgl.input.Mouse;
import eu.crushedpixel.replaymod.gui.elements.GuiMouseInput; import org.lwjgl.opengl.Display;
import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import java.io.IOException;
import eu.crushedpixel.replaymod.replay.ReplayProcess; import java.lang.reflect.Field;
import eu.crushedpixel.replaymod.video.ReplayScreenshot; import java.lang.reflect.InvocationTargetException;
public class TickAndRenderListener { public class TickAndRenderListener {
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getMinecraft();
private double lastX, lastY, lastZ;
private float lastPitch, lastYaw;
private static Field isGamePaused; private static Field isGamePaused;
private static int requestScreenshot = 0;
static { static {
try { try {
@@ -41,6 +38,16 @@ public class TickAndRenderListener {
} }
} }
//private boolean f1Down = false;
public static void requestScreenshot() {
if(requestScreenshot == 0) requestScreenshot = 1;
}
public static void finishScreenshot() {
requestScreenshot = 0;
}
@SubscribeEvent @SubscribeEvent
public void onRenderWorld(RenderWorldLastEvent event) throws public void onRenderWorld(RenderWorldLastEvent event) throws
InvocationTargetException, IOException, IllegalAccessException, IllegalArgumentException { InvocationTargetException, IOException, IllegalAccessException, IllegalArgumentException {
@@ -50,7 +57,7 @@ public class TickAndRenderListener {
mc.addScheduledTask(new Runnable() { mc.addScheduledTask(new Runnable() {
@Override @Override
public void run() { public void run() {
ChatMessageRequests.addChatMessage("Saving Thumbnail...", ChatMessageRequests.ChatMessageType.INFORMATION); ReplayMod.chatMessageHandler.addChatMessage("Saving Thumbnail...", ChatMessageHandler.ChatMessageType.INFORMATION);
ReplayScreenshot.prepareScreenshot(); ReplayScreenshot.prepareScreenshot();
requestScreenshot = 2; requestScreenshot = 2;
} }
@@ -66,19 +73,13 @@ public class TickAndRenderListener {
if(ReplayHandler.isInPath()) ReplayProcess.unblockAndTick(false); if(ReplayHandler.isInPath()) ReplayProcess.unblockAndTick(false);
if(ReplayHandler.isCamera()) ReplayHandler.setCameraEntity(ReplayHandler.getCameraEntity()); if(ReplayHandler.isCamera()) ReplayHandler.setCameraEntity(ReplayHandler.getCameraEntity());
if(ReplayHandler.isInReplay() && ReplayHandler.isPaused()) { if(ReplayHandler.isInReplay() && ReplayMod.replaySender.paused()) {
if(mc != null && mc.thePlayer != null) if(mc != null && mc.thePlayer != null)
MinecraftTicker.runMouseKeyboardTick(mc); MinecraftTicker.runMouseKeyboardTick(mc);
} }
if((mc.getRenderViewEntity() == mc.thePlayer || !mc.getRenderViewEntity().isEntityAlive()) if((mc.getRenderViewEntity() == mc.thePlayer || !mc.getRenderViewEntity().isEntityAlive())
&& ReplayHandler.getCameraEntity() != null && !ReplayHandler.isInPath()) { && ReplayHandler.getCameraEntity() != null && !ReplayHandler.isInPath()) {
ReplayHandler.spectateCamera(); ReplayHandler.spectateCamera();
} else if(!ReplayHandler.isCamera()) {
lastX = mc.getRenderViewEntity().posX;
lastY = mc.getRenderViewEntity().posY;
lastZ = mc.getRenderViewEntity().posZ;
lastPitch = mc.getRenderViewEntity().rotationPitch;
lastYaw = mc.getRenderViewEntity().rotationYaw;
} }
if(mc.isGamePaused() && ReplayHandler.isInPath()) { if(mc.isGamePaused() && ReplayHandler.isInPath()) {
@@ -86,18 +87,6 @@ public class TickAndRenderListener {
} }
} }
//private boolean f1Down = false;
private static int requestScreenshot = 0;
public static void requestScreenshot() {
if(requestScreenshot == 0) requestScreenshot = 1;
}
public static void finishScreenshot() {
requestScreenshot = 0;
}
@SubscribeEvent @SubscribeEvent
public void tick(TickEvent event) { public void tick(TickEvent event) {
if(!ReplayHandler.isInReplay()) return; if(!ReplayHandler.isInReplay()) return;
@@ -120,8 +109,7 @@ public class TickAndRenderListener {
!(mc.currentScreen instanceof GuiMouseInput || mc.currentScreen instanceof GuiCancelRender)) { !(mc.currentScreen instanceof GuiMouseInput || mc.currentScreen instanceof GuiCancelRender)) {
mc.displayGuiScreen(new GuiMouseInput()); mc.displayGuiScreen(new GuiMouseInput());
} }
} } else onMouseMove(new MouseEvent());
else onMouseMove(new MouseEvent());
FMLCommonHandler.instance().bus().post(new InputEvent.KeyInputEvent()); FMLCommonHandler.instance().bus().post(new InputEvent.KeyInputEvent());
} }
@@ -133,29 +121,26 @@ public class TickAndRenderListener {
mc.mcProfiler.startSection("mouse"); mc.mcProfiler.startSection("mouse");
if (flag && Minecraft.isRunningOnMac && mc.inGameHasFocus && !Mouse.isInsideWindow()) if(flag && Minecraft.isRunningOnMac && mc.inGameHasFocus && !Mouse.isInsideWindow()) {
{
Mouse.setGrabbed(false); Mouse.setGrabbed(false);
Mouse.setCursorPosition(Display.getWidth() / 2, Display.getHeight() / 2); Mouse.setCursorPosition(Display.getWidth() / 2, Display.getHeight() / 2);
Mouse.setGrabbed(true); Mouse.setGrabbed(true);
} }
if (mc.inGameHasFocus && flag && !(ReplayHandler.isInPath())) if(mc.inGameHasFocus && flag && !(ReplayHandler.isInPath())) {
{
mc.mouseHelper.mouseXYChange(); mc.mouseHelper.mouseXYChange();
float f1 = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; float f1 = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F;
float f2 = f1 * f1 * f1 * 8.0F; float f2 = f1 * f1 * f1 * 8.0F;
float f3 = (float)mc.mouseHelper.deltaX * f2; float f3 = (float) mc.mouseHelper.deltaX * f2;
float f4 = (float)mc.mouseHelper.deltaY * f2; float f4 = (float) mc.mouseHelper.deltaY * f2;
byte b0 = 1; byte b0 = 1;
if (mc.gameSettings.invertMouse) if(mc.gameSettings.invertMouse) {
{
b0 = -1; b0 = -1;
} }
if(ReplayHandler.getCameraEntity() != null) { if(ReplayHandler.getCameraEntity() != null) {
ReplayHandler.getCameraEntity().setAngles(f3, f4 * (float)b0); ReplayHandler.getCameraEntity().setAngles(f3, f4 * (float) b0);
} }
} }
} }

View File

@@ -2,7 +2,6 @@ package eu.crushedpixel.replaymod.gui;
import eu.crushedpixel.replaymod.replay.ReplayProcess; import eu.crushedpixel.replaymod.replay.ReplayProcess;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNo;
import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.client.gui.GuiYesNoCallback;

View File

@@ -0,0 +1,7 @@
package eu.crushedpixel.replaymod.gui;
import net.minecraft.client.gui.GuiScreen;
public class GuiMouseInput extends GuiScreen {
}

View File

@@ -1,13 +1,7 @@
package eu.crushedpixel.replaymod.gui; package eu.crushedpixel.replaymod.gui;
import java.awt.Color;
import eu.crushedpixel.replaymod.gui.replayviewer.GuiReplayViewer;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiIngameMenu;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.fml.client.FMLClientHandler;
public class GuiReplaySaving extends GuiScreen { public class GuiReplaySaving extends GuiScreen {

View File

@@ -1,23 +1,20 @@
package eu.crushedpixel.replaymod.gui; package eu.crushedpixel.replaymod.gui;
import java.awt.Color;
import java.io.IOException;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
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;
import eu.crushedpixel.replaymod.settings.ReplaySettings.RecordingOptions; import eu.crushedpixel.replaymod.settings.ReplaySettings.RecordingOptions;
import eu.crushedpixel.replaymod.settings.ReplaySettings.RenderOptions; import eu.crushedpixel.replaymod.settings.ReplaySettings.RenderOptions;
import eu.crushedpixel.replaymod.settings.ReplaySettings.ReplayOptions; import eu.crushedpixel.replaymod.settings.ReplaySettings.ReplayOptions;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.fml.client.FMLClientHandler;
import java.awt.*;
import java.io.IOException;
public class GuiReplaySettings extends GuiScreen { public class GuiReplaySettings extends GuiScreen {
private GuiScreen parentGuiScreen;
protected String screenTitle = "Replay Mod Settings";
//TODO: Move to GuiConstants //TODO: Move to GuiConstants
private static final int QUALITY_SLIDER_ID = 9003; private static final int QUALITY_SLIDER_ID = 9003;
private static final int RECORDSERVER_ID = 9004; private static final int RECORDSERVER_ID = 9004;
@@ -29,7 +26,8 @@ public class GuiReplaySettings extends GuiScreen {
private static final int RESOURCEPACK_ID = 9010; private static final int RESOURCEPACK_ID = 9010;
private static final int WAITFORCHUNKS_ID = 9011; private static final int WAITFORCHUNKS_ID = 9011;
private static final int INDICATOR_ID = 9012; private static final int INDICATOR_ID = 9012;
protected String screenTitle = "Replay Mod Settings";
private GuiScreen parentGuiScreen;
private GuiButton recordServerButton, recordSPButton, sendChatButton, linearButton, lightingButton, private GuiButton recordServerButton, recordSPButton, sendChatButton, linearButton, lightingButton,
resourcePackButton, waitForChunksButton, showIndicatorButton; resourcePackButton, waitForChunksButton, showIndicatorButton;
@@ -51,17 +49,17 @@ public class GuiReplaySettings extends GuiScreen {
if(o == RecordingOptions.notifications) { if(o == RecordingOptions.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(settings.isShowNotifications()))); "Enable Notifications: " + onOff(settings.isShowNotifications())));
} else if(o == RecordingOptions.recordServer) { } else if(o == RecordingOptions.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: " this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20, "Record Server: "
+onOff(settings.isEnableRecordingServer()))); + onOff(settings.isEnableRecordingServer())));
} else if(o == RecordingOptions.recordSingleplayer) { } else if(o == RecordingOptions.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(settings.isEnableRecordingSingleplayer()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Record Singleplayer: " + onOff(settings.isEnableRecordingSingleplayer())));
} else if(o == RecordingOptions.indicator) { } else if(o == RecordingOptions.indicator) {
this.buttonList.add(showIndicatorButton = new GuiButton(INDICATOR_ID, this.width / 2 - 155 + i % 2 * 160, this.buttonList.add(showIndicatorButton = new GuiButton(INDICATOR_ID, this.width / 2 - 155 + i % 2 * 160,
this.height / 6 + 24 * (i >> 1), 150, 20, "Show Recording Indicator: "+onOff(settings.showRecordingIndicator()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Show Recording Indicator: " + onOff(settings.showRecordingIndicator())));
} }
++i; ++i;
@@ -69,29 +67,27 @@ public class GuiReplaySettings extends GuiScreen {
} }
if (i % 2 == 1) if(i % 2 == 1) {
{
++i; ++i;
} }
for(ReplayOptions o : ReplayOptions.values()) { for(ReplayOptions o : ReplayOptions.values()) {
if(o == ReplayOptions.lighting) { if(o == ReplayOptions.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(settings.isLightingEnabled()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Enable Lighting: " + onOff(settings.isLightingEnabled())));
} else if(o == ReplayOptions.linear) { } else if(o == ReplayOptions.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(settings.isLinearMovement()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Camera Path: " + linearOnOff(settings.isLinearMovement())));
} else if(o == ReplayOptions.useResources) { } else if(o == ReplayOptions.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(settings.getUseResourcePacks()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Server Resource Packs: " + onOff(settings.getUseResourcePacks())));
} }
++i; ++i;
++k; ++k;
} }
if (i % 2 == 1) if(i % 2 == 1) {
{
++i; ++i;
} }
@@ -101,10 +97,10 @@ public class GuiReplaySettings extends GuiScreen {
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), settings.getVideoFramerate(), "Video Framerate")); this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), settings.getVideoFramerate(), "Video Framerate"));
} else if(o == RenderOptions.videoQuality) { } else if(o == RenderOptions.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)settings.getVideoQuality(), "Video Quality")); this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), (float) settings.getVideoQuality(), "Video Quality"));
} else if(o == RenderOptions.waitForChunks) { } else if(o == RenderOptions.waitForChunks) {
this.buttonList.add(resourcePackButton = new GuiButton(WAITFORCHUNKS_ID, this.width / 2 - 155 + i % 2 * 160, this.buttonList.add(resourcePackButton = new GuiButton(WAITFORCHUNKS_ID, this.width / 2 - 155 + i % 2 * 160,
this.height / 6 + 24 * (i >> 1), 150, 20, "Force Render Chunks: "+onOff(settings.getWaitForChunks()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Force Render Chunks: " + onOff(settings.getWaitForChunks())));
} }
++i; ++i;
@@ -124,7 +120,7 @@ public class GuiReplaySettings extends GuiScreen {
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void drawScreen(int mouseX, int mouseY, float partialTicks) {
this.drawDefaultBackground(); this.drawDefaultBackground();
this.drawCenteredString(this.fontRendererObj, "Replay Mod Settings", this.width / 2, 20, 16777215); this.drawCenteredString(this.fontRendererObj, "Replay Mod Settings", this.width / 2, 20, 16777215);
if (FMLClientHandler.instance().getClient().thePlayer != null) { if(FMLClientHandler.instance().getClient().thePlayer != null) {
this.drawCenteredString(this.fontRendererObj, "WARNING: Recording settings are going to be", this.width / 2, 180, Color.RED.getRGB()); this.drawCenteredString(this.fontRendererObj, "WARNING: Recording settings are going to be", this.width / 2, 180, Color.RED.getRGB());
this.drawCenteredString(this.fontRendererObj, "applied the next time you join a world.", this.width / 2, 190, Color.RED.getRGB()); this.drawCenteredString(this.fontRendererObj, "applied the next time you join a world.", this.width / 2, 190, Color.RED.getRGB());
} }
@@ -133,7 +129,7 @@ public class GuiReplaySettings extends GuiScreen {
protected void actionPerformed(GuiButton button) throws IOException { protected void actionPerformed(GuiButton button) throws IOException {
if (button.enabled) { if(button.enabled) {
switch(button.id) { switch(button.id) {
case 200: case 200:
this.mc.displayGuiScreen(this.parentGuiScreen); this.mc.displayGuiScreen(this.parentGuiScreen);
@@ -141,49 +137,49 @@ public class GuiReplaySettings extends GuiScreen {
case RECORDSERVER_ID: case RECORDSERVER_ID:
boolean enabled = ReplayMod.replaySettings.isEnableRecordingServer(); boolean enabled = ReplayMod.replaySettings.isEnableRecordingServer();
enabled = !enabled; enabled = !enabled;
recordServerButton.displayString = "Record Server: "+onOff(enabled); recordServerButton.displayString = "Record Server: " + onOff(enabled);
ReplayMod.replaySettings.setEnableRecordingServer(enabled); ReplayMod.replaySettings.setEnableRecordingServer(enabled);
break; break;
case RECORDSP_ID: case RECORDSP_ID:
enabled = ReplayMod.replaySettings.isEnableRecordingSingleplayer(); enabled = ReplayMod.replaySettings.isEnableRecordingSingleplayer();
enabled = !enabled; enabled = !enabled;
recordSPButton.displayString = "Record Singleplayer: "+onOff(enabled); recordSPButton.displayString = "Record Singleplayer: " + onOff(enabled);
ReplayMod.replaySettings.setEnableRecordingSingleplayer(enabled); ReplayMod.replaySettings.setEnableRecordingSingleplayer(enabled);
break; break;
case SEND_CHAT: case SEND_CHAT:
enabled = ReplayMod.replaySettings.isShowNotifications(); enabled = ReplayMod.replaySettings.isShowNotifications();
enabled = !enabled; enabled = !enabled;
sendChatButton.displayString = "Enable Notifications: "+onOff(enabled); sendChatButton.displayString = "Enable Notifications: " + onOff(enabled);
ReplayMod.replaySettings.setShowNotifications(enabled); ReplayMod.replaySettings.setShowNotifications(enabled);
break; break;
case FORCE_LINEAR: case FORCE_LINEAR:
enabled = ReplayMod.replaySettings.isLinearMovement(); enabled = ReplayMod.replaySettings.isLinearMovement();
enabled = !enabled; enabled = !enabled;
linearButton.displayString = "Camera Path: "+linearOnOff(enabled); linearButton.displayString = "Camera Path: " + linearOnOff(enabled);
ReplayMod.replaySettings.setLinearMovement(enabled); ReplayMod.replaySettings.setLinearMovement(enabled);
break; break;
case ENABLE_LIGHTING: case ENABLE_LIGHTING:
enabled = ReplayMod.replaySettings.isLightingEnabled(); enabled = ReplayMod.replaySettings.isLightingEnabled();
enabled = !enabled; enabled = !enabled;
lightingButton.displayString = "Enable Lighting: "+onOff(enabled); lightingButton.displayString = "Enable Lighting: " + onOff(enabled);
ReplayMod.replaySettings.setLightingEnabled(enabled); ReplayMod.replaySettings.setLightingEnabled(enabled);
break; break;
case RESOURCEPACK_ID: case RESOURCEPACK_ID:
enabled = ReplayMod.replaySettings.getUseResourcePacks(); enabled = ReplayMod.replaySettings.getUseResourcePacks();
enabled = !enabled; enabled = !enabled;
resourcePackButton.displayString = "Server Resource Packs: "+onOff(enabled); resourcePackButton.displayString = "Server Resource Packs: " + onOff(enabled);
ReplayMod.replaySettings.setUseResourcePacks(enabled); ReplayMod.replaySettings.setUseResourcePacks(enabled);
break; break;
case WAITFORCHUNKS_ID: case WAITFORCHUNKS_ID:
enabled = ReplayMod.replaySettings.getWaitForChunks(); enabled = ReplayMod.replaySettings.getWaitForChunks();
enabled = !enabled; enabled = !enabled;
resourcePackButton.displayString = "Force Render Chunks: "+onOff(enabled); resourcePackButton.displayString = "Force Render Chunks: " + onOff(enabled);
ReplayMod.replaySettings.setWaitForChunks(enabled); ReplayMod.replaySettings.setWaitForChunks(enabled);
break; break;
case INDICATOR_ID: case INDICATOR_ID:
enabled = ReplayMod.replaySettings.showRecordingIndicator(); enabled = ReplayMod.replaySettings.showRecordingIndicator();
enabled = !enabled; enabled = !enabled;
showIndicatorButton.displayString = "Show Recording Indicator: "+onOff(enabled); showIndicatorButton.displayString = "Show Recording Indicator: " + onOff(enabled);
ReplayMod.replaySettings.setEnableIndicator(enabled); ReplayMod.replaySettings.setEnableIndicator(enabled);
break; break;
} }

View File

@@ -1,13 +1,10 @@
package eu.crushedpixel.replaymod.gui; package eu.crushedpixel.replaymod.gui;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.gui.elements.GuiMouseInput;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.client.FMLClientHandler;
@@ -19,22 +16,39 @@ public class GuiReplaySpeedSlider extends GuiButton {
private String displayKey; private String displayKey;
private boolean dragging = false; private boolean dragging = false;
public GuiReplaySpeedSlider(int buttonId, int p_i45017_2_, int p_i45017_3_, String displayKey) public GuiReplaySpeedSlider(int buttonId, int p_i45017_2_, int p_i45017_3_, String displayKey) {
{
super(buttonId, p_i45017_2_, p_i45017_3_, 150, 20, ""); super(buttonId, p_i45017_2_, p_i45017_3_, 150, 20, "");
sliderValue = (9f/38f); sliderValue = (9f / 38f);
this.width = 100; this.width = 100;
this.valueMin = 1; this.valueMin = 1;
this.valueMax = 38; this.valueMax = 38;
this.valueStep = 1; this.valueStep = 1;
this.displayString = displayKey+": 1x"; this.displayString = displayKey + ": 1x";
this.displayKey = displayKey; this.displayKey = displayKey;
Minecraft.getMinecraft().getTextureManager().bindTexture(buttonTextures); Minecraft.getMinecraft().getTextureManager().bindTexture(buttonTextures);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)), this.yPosition, 0, 66, 4, 20); this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20); this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
}
public static float convertScaleRet(float value) {
if(value <= 1) {
return Math.round(value * 10);
}
float steps = value - 1;
return Math.round(steps / 0.25f);
}
public static float convertScale(float value) {
if(value == 10) {
return 1;
}
if(value <= 9) {
return value / 10f;
}
return 1 + (0.25f * (value - 10));
} }
@Override @Override
@@ -43,10 +57,8 @@ public class GuiReplaySpeedSlider extends GuiButton {
} }
@Override @Override
public void drawButton(Minecraft mc, int mouseX, int mouseY) public void drawButton(Minecraft mc, int mouseX, int mouseY) {
{ if(this.visible) {
if (this.visible)
{
try { try {
FontRenderer fontrenderer = mc.fontRendererObj; FontRenderer fontrenderer = mc.fontRendererObj;
mc.getTextureManager().bindTexture(buttonTextures); mc.getTextureManager().bindTexture(buttonTextures);
@@ -61,76 +73,53 @@ public class GuiReplaySpeedSlider extends GuiButton {
this.mouseDragged(mc, mouseX, mouseY); this.mouseDragged(mc, mouseX, mouseY);
int l = 14737632; int l = 14737632;
if (packedFGColour != 0) if(packedFGColour != 0) {
{
l = packedFGColour; l = packedFGColour;
} } else if(!this.enabled) {
else if (!this.enabled)
{
l = 10526880; l = 10526880;
} } else if(this.hovered && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
else if (this.hovered && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class))
{
l = 16777120; l = 16777120;
} }
this.drawCenteredString(fontrenderer, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, l); this.drawCenteredString(fontrenderer, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, l);
} catch(Exception e) {} } catch(Exception e) {
}
} }
} }
private String translate(float f) { private String translate(float f) {
return f+"x"; return f + "x";
} }
public static float convertScaleRet(float value) {
if(value <= 1) {
return Math.round(value*10);
}
float steps = value-1;
return Math.round(steps/0.25f);
}
public static float convertScale(float value) {
if(value == 10) {
return 1;
}
if(value <= 9) {
return value/10f;
}
return 1+(0.25f*(value-10));
}
public double getSliderValue() { public double getSliderValue() {
return convertScale(normalizedToReal(sliderValue)); return convertScale(normalizedToReal(sliderValue));
} }
@Override @Override
protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) { protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) {
if (this.visible) { if(this.visible) {
try { try {
if(this.dragging) { if(this.dragging) {
sliderValue = (float)(mouseX - (this.xPosition + 4)) / (float)(this.width - 8); sliderValue = (float) (mouseX - (this.xPosition + 4)) / (float) (this.width - 8);
sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F); sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F);
float f = denormalizeValue(sliderValue); float f = denormalizeValue(sliderValue);
sliderValue = normalizeValue(f); sliderValue = normalizeValue(f);
if(ReplayHandler.getSpeed() != 0) { if(ReplayMod.replaySender.getReplaySpeed() != 0) {
ReplayHandler.setSpeed(convertScale(normalizedToReal(sliderValue))); ReplayMod.replaySender.setReplaySpeed(convertScale(normalizedToReal(sliderValue)));
} }
this.displayString = displayKey+": "+translate(convertScale(normalizedToReal(sliderValue))); this.displayString = displayKey + ": " + translate(convertScale(normalizedToReal(sliderValue)));
} }
mc.getTextureManager().bindTexture(buttonTextures); mc.getTextureManager().bindTexture(buttonTextures);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)), this.yPosition, 0, 66, 4, 20); this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20); this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
} catch(Exception e) {} } catch(Exception e) {
}
} }
} }
public float normalizeValue(float p_148266_1_) public float normalizeValue(float p_148266_1_) {
{
return MathHelper.clamp_float((this.snapToStepClamp(p_148266_1_) - this.valueMin) / (this.valueMax - this.valueMin), 0.0F, 1.0F); return MathHelper.clamp_float((this.snapToStepClamp(p_148266_1_) - this.valueMin) / (this.valueMax - this.valueMin), 0.0F, 1.0F);
} }
@@ -138,25 +127,21 @@ public class GuiReplaySpeedSlider extends GuiButton {
float min = 0 - valueMin; float min = 0 - valueMin;
float max = valueMax + min; float max = valueMax + min;
return value/(max) - min; return value / (max) - min;
} }
public float denormalizeValue(float p_148262_1_) public float denormalizeValue(float p_148262_1_) {
{
return this.snapToStepClamp(this.valueMin + (this.valueMax - this.valueMin) * MathHelper.clamp_float(p_148262_1_, 0.0F, 1.0F)); return this.snapToStepClamp(this.valueMin + (this.valueMax - this.valueMin) * MathHelper.clamp_float(p_148262_1_, 0.0F, 1.0F));
} }
public float snapToStepClamp(float p_148268_1_) public float snapToStepClamp(float p_148268_1_) {
{
p_148268_1_ = this.snapToStep(p_148268_1_); p_148268_1_ = this.snapToStep(p_148268_1_);
return MathHelper.clamp_float(p_148268_1_, this.valueMin, this.valueMax); return MathHelper.clamp_float(p_148268_1_, this.valueMin, this.valueMax);
} }
protected float snapToStep(float p_148264_1_) protected float snapToStep(float p_148264_1_) {
{ if(this.valueStep > 0.0F) {
if (this.valueStep > 0.0F) p_148264_1_ = this.valueStep * (float) Math.round(p_148264_1_ / this.valueStep);
{
p_148264_1_ = this.valueStep * (float)Math.round(p_148264_1_ / this.valueStep);
} }
return p_148264_1_; return p_148264_1_;
@@ -166,24 +151,19 @@ public class GuiReplaySpeedSlider extends GuiButton {
float min = 0 - valueMin; float min = 0 - valueMin;
float max = valueMax + min; float max = valueMax + min;
return Math.round(value*(max) - min); return Math.round(value * (max) - min);
} }
public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
{ if(super.mousePressed(mc, mouseX, mouseY)) {
if (super.mousePressed(mc, mouseX, mouseY))
{
this.dragging = true; this.dragging = true;
return true; return true;
} } else {
else
{
return false; return false;
} }
} }
public void mouseReleased(int mouseX, int mouseY) public void mouseReleased(int mouseX, int mouseY) {
{
this.dragging = false; this.dragging = false;
} }

View File

@@ -1,14 +1,8 @@
package eu.crushedpixel.replaymod.gui; package eu.crushedpixel.replaymod.gui;
import java.awt.Color; import com.mojang.realmsclient.util.Pair;
import java.io.IOException; import eu.crushedpixel.replaymod.ReplayMod;
import java.util.ArrayList; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.lwjgl.input.Mouse;
import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
@@ -17,10 +11,14 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EnumPlayerModelParts; import net.minecraft.entity.player.EnumPlayerModelParts;
import net.minecraft.potion.Potion; import net.minecraft.potion.Potion;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Mouse;
import com.mojang.realmsclient.util.Pair; import java.awt.*;
import java.io.IOException;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class GuiSpectateSelection extends GuiScreen { public class GuiSpectateSelection extends GuiScreen {
@@ -32,6 +30,168 @@ public class GuiSpectateSelection extends GuiScreen {
private int lowerBound; private int lowerBound;
private double prevSpeed; private double prevSpeed;
private boolean drag = false;
private int lastY = 0;
private int fitting = 0;
public GuiSpectateSelection(List<EntityPlayer> players) {
this.prevSpeed = ReplayMod.replaySender.getReplaySpeed();
Collections.sort(players, new PlayerComparator());
this.players = new ArrayList<Pair<EntityPlayer, ResourceLocation>>();
for(EntityPlayer p : players) {
ResourceLocation loc = new ResourceLocation("/temp-skins/" + p.getGameProfile().getName());
AbstractClientPlayer.getDownloadImageSkin(loc, p.getName());
this.players.add(Pair.of(p, loc));
}
playerCount = players.size();
ReplayMod.replaySender.setReplaySpeed(0);
}
private boolean isSpectator(EntityPlayer e) {
return e.isInvisible() && e.getActivePotionEffect(Potion.invisibility) == null;
}
@Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
throws IOException {
if(fitting < playerCount) {
float visiblePerc = (float) fitting / (float) playerCount;
int h = this.height - 32 - 32;
int offset = Math.round((upperPlayer / (fitting)) * visiblePerc * h);
int lower = Math.round(32 + offset + (h * visiblePerc)) - 2;
int k2 = (int) (this.width * 0.4);
if(mouseX >= k2 - 16 && mouseX <= k2 - 12 && mouseY >= 32 - 2 + offset && mouseY <= lower) {
lastY = mouseY;
drag = true;
return;
}
}
int k2 = (int) (this.width * 0.4);
int l2 = 30;
if(mouseX >= k2 && mouseX <= (this.width * 0.6) && mouseY >= 30 && mouseY <= lowerBound) {
int off = mouseY - 30;
int p = (off / 21) + upperPlayer;
ReplayHandler.spectateEntity(players.get(p).first());
ReplayMod.replaySender.setReplaySpeed(prevSpeed);
mc.displayGuiScreen(null);
}
}
@Override
protected void mouseClickMove(int mouseX, int mouseY,
int clickedMouseButton, long timeSinceLastClick) {
if(drag) {
float step = 1f / (float) playerCount;
int diff = mouseY - lastY;
int h = this.height - 32 - 32;
float percDiff = (float) diff / (float) h;
if(Math.abs(percDiff) > Math.abs(step)) {
int s = (int) (percDiff / step);
lastY = mouseY;
upperPlayer += s;
if(upperPlayer > playerCount - fitting) {
upperPlayer = playerCount - fitting;
} else if(upperPlayer < 0) {
upperPlayer = 0;
}
}
}
super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick);
}
@Override
public void onGuiClosed() {
ReplayMod.replaySender.setReplaySpeed(prevSpeed);
}
@Override
protected void mouseReleased(int mouseX, int mouseY, int state) {
drag = false;
super.mouseReleased(mouseX, mouseY, state);
}
@Override
public void initGui() {
upperPlayer = 0;
lowerBound = this.height - 10;
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
this.drawCenteredString(fontRendererObj, "Spectate Player", this.width / 2, 5, Color.WHITE.getRGB());
int k2 = (int) (this.width * 0.4);
int l2 = 30;
drawGradientRect(k2 - 10, l2 - 10, (int) (this.width * 0.6) + 20, this.height - 30 - 2 + 10, -1072689136, -804253680);
fitting = 0;
int sk = 0;
for(Pair<EntityPlayer, ResourceLocation> p : players) {
if(sk < upperPlayer) {
sk++;
continue;
}
boolean spec = isSpectator(p.first());
this.drawString(fontRendererObj, p.first().getName(), k2 + 16 + 5, l2 + 8 - (fontRendererObj.FONT_HEIGHT / 2),
spec ? Color.DARK_GRAY.getRGB() : Color.WHITE.getRGB());
mc.getTextureManager().bindTexture(p.second());
this.drawScaledCustomSizeModalRect(k2, l2, 8.0F, 8.0F, 8, 8, 16, 16, 64.0F, 64.0F);
if(p.first().func_175148_a(EnumPlayerModelParts.HAT))
Gui.drawScaledCustomSizeModalRect(k2, l2, 40.0F, 8.0F, 8, 8, 16, 16, 64.0F, 64.0F);
GlStateManager.resetColor();
l2 += 16 + 5;
fitting++;
if(l2 + 32 > lowerBound) {
break;
}
}
int dw = Mouse.getDWheel();
if(dw > 0) {
dw = -1;
} else if(dw < 0) {
dw = 1;
}
upperPlayer = Math.max(Math.min(upperPlayer + dw, playerCount - fitting), 0);
if(fitting < playerCount) {
float visiblePerc = ((float) fitting) / playerCount;
int barHeight = (int) (visiblePerc * (height - 32 - 32));
float posPerc = ((float) upperPlayer) / playerCount;
int barY = (int) (posPerc * (height - 32 - 32));
this.drawRect(k2 - 18, 30 - 2, k2 - 10, this.height - 30 - 2, Color.BLACK.getRGB());
this.drawRect(k2 - 16, 32 - 2 + barY, k2 - 12, 32 - 1 + barY + barHeight, Color.LIGHT_GRAY.getRGB());
} else {
}
super.drawScreen(mouseX, mouseY, partialTicks);
}
private class PlayerComparator implements Comparator<EntityPlayer> { private class PlayerComparator implements Comparator<EntityPlayer> {
@@ -47,169 +207,4 @@ public class GuiSpectateSelection extends GuiScreen {
} }
} }
private boolean isSpectator(EntityPlayer e) {
return e.isInvisible() && e.getActivePotionEffect(Potion.invisibility) == null;
}
public GuiSpectateSelection(List<EntityPlayer> players) {
this.prevSpeed = ReplayHandler.getSpeed();
Collections.sort(players, new PlayerComparator());
this.players = new ArrayList<Pair<EntityPlayer, ResourceLocation>>();
for(EntityPlayer p : players) {
ResourceLocation loc = new ResourceLocation("/temp-skins/"+p.getGameProfile().getName());
AbstractClientPlayer.getDownloadImageSkin(loc, p.getName());
this.players.add(Pair.of(p, loc));
}
playerCount = players.size();
ReplayHandler.setSpeed(0);
}
private boolean drag = false;
@Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
throws IOException {
if(fitting < playerCount) {
float visiblePerc = (float)fitting/(float)playerCount;
int h = this.height-32-32;
int offset = Math.round((upperPlayer/(fitting))*visiblePerc*h);
int lower = Math.round(32+offset+(h*visiblePerc))-2;
int k2 = (int)(this.width*0.4);
if(mouseX >= k2-16 && mouseX <= k2-12 && mouseY >= 32-2+offset && mouseY <= lower) {
lastY = mouseY;
drag = true;
return;
}
}
int k2 = (int)(this.width*0.4);
int l2 = 30;
if(mouseX >= k2 && mouseX <= (this.width*0.6) && mouseY >= 30 && mouseY <= lowerBound) {
int off = mouseY-30;
int p = (off/21) + upperPlayer;
ReplayHandler.spectateEntity(players.get(p).first());
ReplayHandler.setSpeed(prevSpeed);
mc.displayGuiScreen(null);
}
}
private int lastY = 0;
@Override
protected void mouseClickMove(int mouseX, int mouseY,
int clickedMouseButton, long timeSinceLastClick) {
if(drag) {
float step = 1f/(float)playerCount;
int diff = mouseY-lastY;
int h = this.height-32-32;
float percDiff = (float)diff/(float)h;
if(Math.abs(percDiff) > Math.abs(step)) {
int s = (int)(percDiff/step);
lastY = mouseY;
upperPlayer += s;
if(upperPlayer > playerCount-fitting) {
upperPlayer = playerCount-fitting;
} else if(upperPlayer < 0) {
upperPlayer = 0;
}
}
}
super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick);
}
@Override
public void onGuiClosed() {
ReplayHandler.setSpeed(prevSpeed);
}
@Override
protected void mouseReleased(int mouseX, int mouseY, int state) {
drag = false;
super.mouseReleased(mouseX, mouseY, state);
}
@Override
public void initGui() {
upperPlayer = 0;
lowerBound = this.height-10;
}
private int fitting = 0;
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
this.drawCenteredString(fontRendererObj, "Spectate Player", this.width/2, 5, Color.WHITE.getRGB());
int k2 = (int)(this.width*0.4);
int l2 = 30;
drawGradientRect(k2-10, l2-10, (int)(this.width*0.6)+20, this.height-30-2+10, -1072689136, -804253680);
fitting = 0;
int sk = 0;
for(Pair<EntityPlayer, ResourceLocation> p : players) {
if(sk < upperPlayer) {
sk++;
continue;
}
boolean spec = isSpectator(p.first());
this.drawString(fontRendererObj, p.first().getName(), k2+16+5, l2+8-(fontRendererObj.FONT_HEIGHT/2),
spec ? Color.DARK_GRAY.getRGB() : Color.WHITE.getRGB());
mc.getTextureManager().bindTexture(p.second());
this.drawScaledCustomSizeModalRect(k2, l2, 8.0F, 8.0F, 8, 8, 16, 16, 64.0F, 64.0F);
if(p.first().func_175148_a(EnumPlayerModelParts.HAT))
Gui.drawScaledCustomSizeModalRect(k2, l2, 40.0F, 8.0F, 8, 8, 16, 16, 64.0F, 64.0F);
GlStateManager.resetColor();
l2 += 16+5;
fitting++;
if(l2+32 > lowerBound) {
break;
}
}
int dw = Mouse.getDWheel();
if(dw > 0) {
dw = -1;
} else if(dw < 0) {
dw = 1;
}
upperPlayer = Math.max(Math.min(upperPlayer+dw, playerCount-fitting), 0);
if(fitting < playerCount) {
float visiblePerc = ((float)fitting)/playerCount;
int barHeight = (int)(visiblePerc*(height-32-32));
float posPerc = ((float)upperPlayer)/playerCount;
int barY = (int)(posPerc*(height-32-32));
this.drawRect(k2-18, 30-2, k2-10, this.height-30-2, Color.BLACK.getRGB());
this.drawRect(k2-16, 32-2+barY, k2-12, 32-1+barY+barHeight, Color.LIGHT_GRAY.getRGB());
} else {
}
super.drawScreen(mouseX, mouseY, partialTicks);
}
} }

View File

@@ -1,25 +1,23 @@
package eu.crushedpixel.replaymod.gui; package eu.crushedpixel.replaymod.gui;
import eu.crushedpixel.replaymod.ReplayMod;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import eu.crushedpixel.replaymod.ReplayMod;
public class GuiVideoFramerateSlider extends GuiButton { public class GuiVideoFramerateSlider extends GuiButton {
public boolean dragging;
private String displayKey;
private float sliderValue;
public GuiVideoFramerateSlider(int buttonId, int p_i45017_2_, int p_i45017_3_, int initialFramerate, String displayKey) { public GuiVideoFramerateSlider(int buttonId, int p_i45017_2_, int p_i45017_3_, int initialFramerate, 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(initialFramerate); this.sliderValue = normalizeValue(initialFramerate);
this.displayString = displayKey+": "+translate(initialFramerate); this.displayString = displayKey + ": " + translate(initialFramerate);
this.displayKey = displayKey; this.displayKey = displayKey;
} }
private String displayKey;
private float sliderValue;
public boolean dragging;
private String translate(int value) { private String translate(int value) {
return String.valueOf(value); return String.valueOf(value);
} }
@@ -30,34 +28,34 @@ public class GuiVideoFramerateSlider extends GuiButton {
@Override @Override
protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) { protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) {
if (this.visible) { if(this.visible) {
if (this.dragging) { if(this.dragging) {
sliderValue = (float)(mouseX - (this.xPosition + 4)) / (float)(this.width - 8); sliderValue = (float) (mouseX - (this.xPosition + 4)) / (float) (this.width - 8);
sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F); sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F);
int f = denormalizeValue(sliderValue); int f = denormalizeValue(sliderValue);
this.displayString = displayKey+": "+translate(f); this.displayString = displayKey + ": " + translate(f);
ReplayMod.replaySettings.setVideoFramerate(f); ReplayMod.replaySettings.setVideoFramerate(f);
} }
mc.getTextureManager().bindTexture(buttonTextures); mc.getTextureManager().bindTexture(buttonTextures);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)), this.yPosition, 0, 66, 4, 20); this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20); this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
} }
} }
private float normalizeValue(int val) { private float normalizeValue(int val) {
return (val-10)/110f; return (val - 10) / 110f;
} }
private int denormalizeValue(float val) { private int denormalizeValue(float val) {
//Transfers the value ranging from 0.0 to 1.0 to the scale of 10 to 120 //Transfers the value ranging from 0.0 to 1.0 to the scale of 10 to 120
float r = 110f*val; float r = 110f * val;
return Math.round(10+r); return Math.round(10 + r);
} }
public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
if (super.mousePressed(mc, mouseX, mouseY)) { if(super.mousePressed(mc, mouseX, mouseY)) {
this.dragging = true; this.dragging = true;
return true; return true;
} else { } else {

View File

@@ -1,25 +1,23 @@
package eu.crushedpixel.replaymod.gui; package eu.crushedpixel.replaymod.gui;
import eu.crushedpixel.replaymod.ReplayMod;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import eu.crushedpixel.replaymod.ReplayMod;
public class GuiVideoQualitySlider extends GuiButton { public class GuiVideoQualitySlider extends GuiButton {
public boolean dragging;
private String displayKey;
private float sliderValue;
public GuiVideoQualitySlider(int buttonId, int p_i45017_2_, int p_i45017_3_, float d, 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(d); this.sliderValue = normalizeValue(d);
this.displayString = displayKey+": "+translate(d); this.displayString = displayKey + ": " + translate(d);
this.displayKey = displayKey; this.displayKey = displayKey;
} }
private String displayKey;
private float sliderValue;
public boolean dragging;
private String translate(float value) { private String translate(float value) {
if(value <= 0.3) { if(value <= 0.3) {
return "Draft"; return "Draft";
@@ -37,41 +35,41 @@ public class GuiVideoQualitySlider extends GuiButton {
@Override @Override
protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) { protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) {
if (this.visible) { if(this.visible) {
if (this.dragging) { if(this.dragging) {
sliderValue = (float)(mouseX - (this.xPosition + 4)) / (float)(this.width - 8); sliderValue = (float) (mouseX - (this.xPosition + 4)) / (float) (this.width - 8);
sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F); sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F);
float f = denormalizeValue(sliderValue); float f = denormalizeValue(sliderValue);
f = snapValue(f); f = snapValue(f);
sliderValue = normalizeValue(f); sliderValue = normalizeValue(f);
this.displayString = displayKey+": "+translate(f); this.displayString = displayKey + ": " + translate(f);
ReplayMod.replaySettings.setVideoQuality(f); ReplayMod.replaySettings.setVideoQuality(f);
} }
mc.getTextureManager().bindTexture(buttonTextures); mc.getTextureManager().bindTexture(buttonTextures);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)), this.yPosition, 0, 66, 4, 20); this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20); this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
} }
} }
private float snapValue(float val) { private float snapValue(float val) {
int i = Math.round(val*10); int i = Math.round(val * 10);
return i/10f; return i / 10f;
} }
private float normalizeValue(float val) { private float normalizeValue(float val) {
return (val-0.1f)/0.8f; return (val - 0.1f) / 0.8f;
} }
private float denormalizeValue(float val) { private float denormalizeValue(float val) {
//Transfers the value ranging from 0.0 to 1.0 to the scale of 0.1 to 0.9 //Transfers the value ranging from 0.0 to 1.0 to the scale of 0.1 to 0.9
float r = 0.8f*val; float r = 0.8f * val;
return 0.1f+r; return 0.1f + r;
} }
public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
if (super.mousePressed(mc, mouseX, mouseY)) { if(super.mousePressed(mc, mouseX, mouseY)) {
this.dragging = true; this.dragging = true;
return true; return true;
} else { } else {

View File

@@ -1,11 +1,11 @@
package eu.crushedpixel.replaymod.gui; package eu.crushedpixel.replaymod.gui;
import java.lang.reflect.Field;
import eu.crushedpixel.replaymod.reflection.MCPNames; import eu.crushedpixel.replaymod.reflection.MCPNames;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.gui.GuiTextField;
import java.lang.reflect.Field;
public class PasswordTextField extends GuiTextField { public class PasswordTextField extends GuiTextField {
private static Field text; private static Field text;
@@ -30,7 +30,7 @@ public class PasswordTextField extends GuiTextField {
String prev = getText(); String prev = getText();
String pw = ""; String pw = "";
for(int i=0; i<prev.length(); i++) { for(int i = 0; i < prev.length(); i++) {
pw += "*"; pw += "*";
} }
@@ -38,9 +38,9 @@ public class PasswordTextField extends GuiTextField {
text.set(this, pw); text.set(this, pw);
super.drawTextBox(); super.drawTextBox();
text.set(this, prev); text.set(this, prev);
} catch(Exception e) {} } catch(Exception e) {
}
} }
} }

View File

@@ -1,13 +1,11 @@
package eu.crushedpixel.replaymod.gui.elements; package eu.crushedpixel.replaymod.gui.elements;
import java.awt.Color;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
public class GuiArrowButton extends GuiButton { import java.awt.*;
private Minecraft mc = Minecraft.getMinecraft(); public class GuiArrowButton extends GuiButton {
private boolean upwards = false; private boolean upwards = false;
@@ -24,12 +22,12 @@ public class GuiArrowButton extends GuiButton {
try { try {
super.drawButton(mc, mouseX, mouseY); super.drawButton(mc, mouseX, mouseY);
if(upwards) { if(upwards) {
for(int i=0; i<=Math.ceil(height/2)-5; i++) { for(int i = 0; i <= Math.ceil(height / 2) - 5; i++) {
drawHorizontalLine(xPosition+width-height+i+4, xPosition+width-i-6, yPosition+height-((height/3)+i+2), Color.BLACK.getRGB()); drawHorizontalLine(xPosition + width - height + i + 4, xPosition + width - i - 6, yPosition + height - ((height / 3) + i + 2), Color.BLACK.getRGB());
} }
} else { } else {
for(int i=0; i<=Math.ceil(height/2)-5; i++) { for(int i = 0; i <= Math.ceil(height / 2) - 5; i++) {
drawHorizontalLine(xPosition+width-height+i+4, xPosition+width-i-6, yPosition+(height/3)+i+2, Color.BLACK.getRGB()); drawHorizontalLine(xPosition + width - height + i + 4, xPosition + width - i - 6, yPosition + (height / 3) + i + 2, Color.BLACK.getRGB());
} }
} }
} catch(Exception e) { } catch(Exception e) {

View File

@@ -1,55 +1,52 @@
package eu.crushedpixel.replaymod.gui.elements; package eu.crushedpixel.replaymod.gui.elements;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.input.Mouse;
import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener; import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.gui.GuiTextField;
import org.lwjgl.input.Mouse;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class GuiDropdown<T> extends GuiTextField { public class GuiDropdown<T> extends GuiTextField {
private int selectionIndex = -1;
private boolean open = false;
private Minecraft mc = Minecraft.getMinecraft();
private final int visibleDropout; private final int visibleDropout;
private final int dropoutElementHeight = 14; private final int dropoutElementHeight = 14;
private final int maxDropoutHeight; private final int maxDropoutHeight;
private int selectionIndex = -1;
private boolean open = false;
private Minecraft mc = Minecraft.getMinecraft();
private List<SelectionListener> selectionListeners = new ArrayList<SelectionListener>(); private List<SelectionListener> selectionListeners = new ArrayList<SelectionListener>();
private int upperIndex = 0; private int upperIndex = 0;
private List<T> elements = new ArrayList<T>();
public GuiDropdown(int id, FontRenderer fontRenderer, public GuiDropdown(int id, FontRenderer fontRenderer,
int xPos, int yPos, int width, int visibleDropout) { int xPos, int yPos, int width, int visibleDropout) {
super(id, fontRenderer, xPos, yPos, width, 20); super(id, fontRenderer, xPos, yPos, width, 20);
this.visibleDropout = visibleDropout; this.visibleDropout = visibleDropout;
this.maxDropoutHeight = dropoutElementHeight*visibleDropout; this.maxDropoutHeight = dropoutElementHeight * visibleDropout;
} }
@Override @Override
public void drawTextBox() { public void drawTextBox() {
if(elements.size() > selectionIndex && selectionIndex >= 0) { if(elements.size() > selectionIndex && selectionIndex >= 0) {
setText(mc.fontRendererObj.trimStringToWidth( setText(mc.fontRendererObj.trimStringToWidth(
elements.get(selectionIndex).toString(), width-8)); elements.get(selectionIndex).toString(), width - 8));
} else { } else {
setText(""); setText("");
} }
super.drawTextBox(); super.drawTextBox();
//Draw the right part of the Dropdown //Draw the right part of the Dropdown
drawRect(xPosition+width-height, yPosition, xPosition+width, yPosition+height, -16777216); drawRect(xPosition + width - height, yPosition, xPosition + width, yPosition + height, -16777216);
drawRect(xPosition+width-height, yPosition, this.xPosition+width-height+1, yPosition+height, -6250336); drawRect(xPosition + width - height, yPosition, this.xPosition + width - height + 1, yPosition + height, -6250336);
//heroically draw the triangle line by line instead of using a texture //heroically draw the triangle line by line instead of using a texture
for(int i=0; i<=Math.ceil(height/2)-4; i++) { for(int i = 0; i <= Math.ceil(height / 2) - 4; i++) {
drawHorizontalLine(xPosition+width-height+i+4, xPosition+width-i-4, yPosition+(height/4)+i+2, -6250336); drawHorizontalLine(xPosition + width - height + i + 4, xPosition + width - i - 4, yPosition + (height / 4) + i + 2, -6250336);
} }
if(open && elements.size() > 0) { if(open && elements.size() > 0) {
@@ -57,29 +54,29 @@ public class GuiDropdown<T> extends GuiTextField {
boolean drawScrollBar = false; boolean drawScrollBar = false;
int requiredHeight = elements.size()*dropoutElementHeight; int requiredHeight = elements.size() * dropoutElementHeight;
if(requiredHeight > maxDropoutHeight) { if(requiredHeight > maxDropoutHeight) {
requiredHeight = maxDropoutHeight; requiredHeight = maxDropoutHeight;
drawScrollBar = true; drawScrollBar = true;
} }
//The light outline //The light outline
drawRect(xPosition-1, yPosition+height, xPosition+width+1, yPosition+height+requiredHeight+1, -6250336); drawRect(xPosition - 1, yPosition + height, xPosition + width + 1, yPosition + height + requiredHeight + 1, -6250336);
//The dark inside //The dark inside
drawRect(xPosition, yPosition+height+1, xPosition+width, yPosition+height+requiredHeight, -16777216); drawRect(xPosition, yPosition + height + 1, xPosition + width, yPosition + height + requiredHeight, -16777216);
//The elements //The elements
int y = 0; int y = 0;
int i = 0; int i = 0;
for(T obj : elements) { for(T obj : elements) {
if(i<upperIndex) { if(i < upperIndex) {
i++; i++;
continue; continue;
} }
drawHorizontalLine(xPosition, xPosition+width, yPosition+height+y, -6250336); drawHorizontalLine(xPosition, xPosition + width, yPosition + height + y, -6250336);
String toWrite = mc.fontRendererObj.trimStringToWidth(obj.toString(), width-8); String toWrite = mc.fontRendererObj.trimStringToWidth(obj.toString(), width - 8);
drawString(mc.fontRendererObj, toWrite, xPosition+4, yPosition+height+y+4, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, toWrite, xPosition + 4, yPosition + height + y + 4, Color.WHITE.getRGB());
y += dropoutElementHeight; y += dropoutElementHeight;
i++; i++;
@@ -97,30 +94,30 @@ public class GuiDropdown<T> extends GuiTextField {
dw = 1; dw = 1;
} }
upperIndex = Math.max(Math.min(upperIndex+dw, elements.size()-visibleDropout), 0); upperIndex = Math.max(Math.min(upperIndex + dw, elements.size() - visibleDropout), 0);
drawRect(xPosition+width-3, yPosition+height+1, xPosition+width, yPosition+height+requiredHeight, Color.DARK_GRAY.getRGB()); drawRect(xPosition + width - 3, yPosition + height + 1, xPosition + width, yPosition + height + requiredHeight, Color.DARK_GRAY.getRGB());
float visiblePerc = ((float)visibleDropout)/elements.size(); float visiblePerc = ((float) visibleDropout) / elements.size();
int barHeight = (int)(visiblePerc*(requiredHeight-1)); int barHeight = (int) (visiblePerc * (requiredHeight - 1));
float posPerc = ((float)upperIndex)/elements.size(); float posPerc = ((float) upperIndex) / elements.size();
int barY = (int)(posPerc*(requiredHeight-1)); int barY = (int) (posPerc * (requiredHeight - 1));
drawRect(xPosition+width-3, yPosition+height+barY, xPosition+width, yPosition+height+2+barY+barHeight, -6250336); drawRect(xPosition + width - 3, yPosition + height + barY, xPosition + width, yPosition + height + 2 + barY + barHeight, -6250336);
} }
} }
} }
@Override @Override
public void mouseClicked(int xPos, int yPos, int mouseButton) { public void mouseClicked(int xPos, int yPos, int mouseButton) {
if(xPos > xPosition+width-height && xPos < xPosition+width && yPos > yPosition && yPos < yPosition+height) { if(xPos > xPosition + width - height && xPos < xPosition + width && yPos > yPosition && yPos < yPosition + height) {
open = !open; open = !open;
} else { } else {
if(xPos > xPosition && xPos < xPosition+width && open) { if(xPos > xPosition && xPos < xPosition + width && open) {
int requiredHeight = Math.min(maxDropoutHeight, elements.size()*dropoutElementHeight); int requiredHeight = Math.min(maxDropoutHeight, elements.size() * dropoutElementHeight);
if(yPos > yPosition+height && yPos < yPosition+height+requiredHeight) { if(yPos > yPosition + height && yPos < yPosition + height + requiredHeight) {
int clickedIndex = (int)Math.floor((yPos - (yPosition+height)) / dropoutElementHeight) + upperIndex; int clickedIndex = (int) Math.floor((yPos - (yPosition + height)) / dropoutElementHeight) + upperIndex;
this.selectionIndex = clickedIndex; this.selectionIndex = clickedIndex;
fireSelectionChangeEvent(); fireSelectionChangeEvent();
} }
@@ -138,14 +135,6 @@ public class GuiDropdown<T> extends GuiTextField {
} }
} }
private List<T> elements = new ArrayList<T>();
public void setSelectionIndex(int index) {
this.selectionIndex = index;
if(selectionIndex < 0) selectionIndex = -1;
fireSelectionChangeEvent();
}
public void setElements(List<T> elements) { public void setElements(List<T> elements) {
this.elements = elements; this.elements = elements;
if(selectionIndex == -1 && elements.size() > 0) { if(selectionIndex == -1 && elements.size() > 0) {
@@ -177,6 +166,12 @@ public class GuiDropdown<T> extends GuiTextField {
return selectionIndex; return selectionIndex;
} }
public void setSelectionIndex(int index) {
this.selectionIndex = index;
if(selectionIndex < 0) selectionIndex = -1;
fireSelectionChangeEvent();
}
private void fireSelectionChangeEvent() { private void fireSelectionChangeEvent() {
for(SelectionListener listener : selectionListeners) { for(SelectionListener listener : selectionListeners) {
listener.onSelectionChanged(selectionIndex); listener.onSelectionChanged(selectionIndex);

View File

@@ -1,38 +1,35 @@
package eu.crushedpixel.replaymod.gui.elements; package eu.crushedpixel.replaymod.gui.elements;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.input.Mouse;
import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener; import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.gui.GuiTextField;
import org.lwjgl.input.Mouse;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class GuiEntryList<T> extends GuiTextField { public class GuiEntryList<T> extends GuiTextField {
private int selectionIndex = -1;
private Minecraft mc = Minecraft.getMinecraft();
private int visibleElements;
public final static int elementHeight = 14; public final static int elementHeight = 14;
private int selectionIndex = -1;
private Minecraft mc = Minecraft.getMinecraft();
private int visibleElements;
private int upperIndex = 0; private int upperIndex = 0;
private List<SelectionListener> selectionListeners = new ArrayList<SelectionListener>(); private List<SelectionListener> selectionListeners = new ArrayList<SelectionListener>();
private List<T> elements = new ArrayList<T>();
public GuiEntryList(int id, FontRenderer fontRenderer, public GuiEntryList(int id, FontRenderer fontRenderer,
int xPos, int yPos, int width, int visibleEntries) { int xPos, int yPos, int width, int visibleEntries) {
super(id, fontRenderer, xPos, yPos, width, elementHeight*visibleEntries-1); super(id, fontRenderer, xPos, yPos, width, elementHeight * visibleEntries - 1);
this.visibleElements = visibleEntries; this.visibleElements = visibleEntries;
} }
public void setVisibleElements(int rows) { public void setVisibleElements(int rows) {
this.visibleElements = rows; this.visibleElements = rows;
this.height = elementHeight*visibleElements-1; this.height = elementHeight * visibleElements - 1;
} }
@Override @Override
@@ -40,20 +37,20 @@ public class GuiEntryList<T> extends GuiTextField {
try { try {
super.drawTextBox(); super.drawTextBox();
//drawing the entries //drawing the entries
for(int i=0; i-upperIndex<visibleElements; i++) { for(int i = 0; i - upperIndex < visibleElements; i++) {
if(i<upperIndex) continue; if(i < upperIndex) continue;
if(i >= elements.size()) break; if(i >= elements.size()) break;
if(i == selectionIndex) { if(i == selectionIndex) {
drawRect(xPosition, yPosition+(i-upperIndex)*elementHeight, xPosition+width, drawRect(xPosition, yPosition + (i - upperIndex) * elementHeight, xPosition + width,
yPosition+(i+1-upperIndex)*elementHeight-1, Color.GRAY.getRGB()); yPosition + (i + 1 - upperIndex) * elementHeight - 1, Color.GRAY.getRGB());
} }
drawRect(xPosition, yPosition+(i+1-upperIndex)*elementHeight-1, xPosition+width, drawRect(xPosition, yPosition + (i + 1 - upperIndex) * elementHeight - 1, xPosition + width,
yPosition+(i+1-upperIndex)*elementHeight, -6250336); yPosition + (i + 1 - upperIndex) * elementHeight, -6250336);
drawString(mc.fontRendererObj, mc.fontRendererObj.trimStringToWidth(elements.get(i).toString(), width-4), drawString(mc.fontRendererObj, mc.fontRendererObj.trimStringToWidth(elements.get(i).toString(), width - 4),
xPosition+2, yPosition+(i-upperIndex)*elementHeight+3, Color.WHITE.getRGB()); xPosition + 2, yPosition + (i - upperIndex) * elementHeight + 3, Color.WHITE.getRGB());
} }
//drawing the scroll bar //drawing the scroll bar
@@ -66,16 +63,16 @@ public class GuiEntryList<T> extends GuiTextField {
dw = 1; dw = 1;
} }
upperIndex = Math.max(Math.min(upperIndex+dw, elements.size()-visibleElements), 0); upperIndex = Math.max(Math.min(upperIndex + dw, elements.size() - visibleElements), 0);
float visiblePerc = ((float)visibleElements)/elements.size(); float visiblePerc = ((float) visibleElements) / elements.size();
int barHeight = (int)(visiblePerc*(height-1)); int barHeight = (int) (visiblePerc * (height - 1));
float posPerc = ((float)upperIndex)/elements.size(); float posPerc = ((float) upperIndex) / elements.size();
int barY = (int)(posPerc*(height-1)); int barY = (int) (posPerc * (height - 1));
drawRect(xPosition+width-3, yPosition, xPosition+width, yPosition+height, Color.DARK_GRAY.getRGB()); drawRect(xPosition + width - 3, yPosition, xPosition + width, yPosition + height, Color.DARK_GRAY.getRGB());
drawRect(xPosition+width-3, yPosition+barY, xPosition+width, yPosition+1+barY+barHeight, -6250336); drawRect(xPosition + width - 3, yPosition + barY, xPosition + width, yPosition + 1 + barY + barHeight, -6250336);
} }
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -84,8 +81,8 @@ public class GuiEntryList<T> extends GuiTextField {
@Override @Override
public void mouseClicked(int xPos, int yPos, int mouseButton) { public void mouseClicked(int xPos, int yPos, int mouseButton) {
if(!(xPos >= xPosition && xPos <= xPosition+width && yPos >= yPosition && yPos <= yPosition+height)) return; if(!(xPos >= xPosition && xPos <= xPosition + width && yPos >= yPosition && yPos <= yPosition + height)) return;
int clickedIndex = (int)Math.floor((yPos-yPosition) / elementHeight) + upperIndex; int clickedIndex = (int) Math.floor((yPos - yPosition) / elementHeight) + upperIndex;
if(clickedIndex < elements.size() && clickedIndex >= 0) { if(clickedIndex < elements.size() && clickedIndex >= 0) {
selectionIndex = clickedIndex; selectionIndex = clickedIndex;
fireSelectionChangeEvent(); fireSelectionChangeEvent();
@@ -99,9 +96,8 @@ public class GuiEntryList<T> extends GuiTextField {
} }
@Override @Override
public void setText(String text) {} public void setText(String text) {
}
private List<T> elements = new ArrayList<T>();
public void setElements(List<T> elements) { public void setElements(List<T> elements) {
this.elements = elements; this.elements = elements;

View File

@@ -1,10 +0,0 @@
package eu.crushedpixel.replaymod.gui.elements;
import org.lwjgl.input.Keyboard;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
public class GuiMouseInput extends GuiScreen {
}

View File

@@ -1,6 +1,5 @@
package eu.crushedpixel.replaymod.gui.elements; package eu.crushedpixel.replaymod.gui.elements;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.gui.GuiTextField;
@@ -18,9 +17,10 @@ public class GuiNumberInput extends GuiTextField {
public void writeText(String text) { public void writeText(String text) {
try { try {
Integer.valueOf(text); Integer.valueOf(text);
if(limit > 0 && (getText()+text).length() > limit) return; if(limit > 0 && (getText() + text).length() > limit) return;
super.writeText(text); super.writeText(text);
} catch(NumberFormatException e) {} } catch(NumberFormatException e) {
}
} }
} }

View File

@@ -1,5 +1,14 @@
package eu.crushedpixel.replaymod.gui.elements; package eu.crushedpixel.replaymod.gui.elements;
import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
import eu.crushedpixel.replaymod.utils.ResourceHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiListExtended.IGuiListEntry;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.util.ResourceLocation;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.text.DateFormat; import java.text.DateFormat;
@@ -9,34 +18,18 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiListExtended.IGuiListEntry;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.util.ResourceLocation;
import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
import eu.crushedpixel.replaymod.utils.ResourceHelper;
public class GuiReplayListEntry implements IGuiListEntry { public class GuiReplayListEntry implements IGuiListEntry {
private Minecraft minecraft = Minecraft.getMinecraft();
private final DateFormat dateFormat = new SimpleDateFormat(); private final DateFormat dateFormat = new SimpleDateFormat();
boolean registered = false;
private Minecraft minecraft = Minecraft.getMinecraft();
private FileInfo fileInfo; private FileInfo fileInfo;
private ResourceLocation textureResource; private ResourceLocation textureResource;
private DynamicTexture dynTex = null; private DynamicTexture dynTex = null;
private File imageFile; private File imageFile;
private BufferedImage image = null; private BufferedImage image = null;
private GuiReplayListExtended parent; private GuiReplayListExtended parent;
public FileInfo getFileInfo() {
return fileInfo;
}
public GuiReplayListEntry(GuiReplayListExtended parent, FileInfo fileInfo, File imageFile) { public GuiReplayListEntry(GuiReplayListExtended parent, FileInfo fileInfo, File imageFile) {
this.fileInfo = fileInfo; this.fileInfo = fileInfo;
this.parent = parent; this.parent = parent;
@@ -44,7 +37,9 @@ public class GuiReplayListEntry implements IGuiListEntry {
this.imageFile = imageFile; this.imageFile = imageFile;
} }
boolean registered = false; public FileInfo getFileInfo() {
return fileInfo;
}
@Override @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) {
@@ -65,7 +60,7 @@ public class GuiReplayListEntry implements IGuiListEntry {
return; return;
} else { } else {
if(!registered) { if(!registered) {
textureResource = new ResourceLocation("thumbs/"+fileInfo.getName()+fileInfo.getId()); textureResource = new ResourceLocation("thumbs/" + fileInfo.getName() + fileInfo.getId());
if(imageFile == null) { if(imageFile == null) {
image = ResourceHelper.getDefaultThumbnail(); image = ResourceHelper.getDefaultThumbnail();
} else { } else {
@@ -79,11 +74,11 @@ public class GuiReplayListEntry implements IGuiListEntry {
} }
minecraft.getTextureManager().bindTexture(textureResource); minecraft.getTextureManager().bindTexture(textureResource);
Gui.drawScaledCustomSizeModalRect(x-60, y, 0, 0, 1280, 720, 57, 32, 1280, 720); Gui.drawScaledCustomSizeModalRect(x - 60, y, 0, 0, 1280, 720, 57, 32, 1280, 720);
} }
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<String>();
list.add(fileInfo.getMetadata().getServerName()+" ("+dateFormat.format(new Date(fileInfo.getMetadata().getDate()))+")"); list.add(fileInfo.getMetadata().getServerName() + " (" + dateFormat.format(new Date(fileInfo.getMetadata().getDate())) + ")");
list.add(String.format("%02dm%02ds", list.add(String.format("%02dm%02ds",
TimeUnit.MILLISECONDS.toMinutes(fileInfo.getMetadata().getDuration()), TimeUnit.MILLISECONDS.toMinutes(fileInfo.getMetadata().getDuration()),
@@ -91,8 +86,8 @@ public class GuiReplayListEntry implements IGuiListEntry {
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(fileInfo.getMetadata().getDuration())) TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(fileInfo.getMetadata().getDuration()))
)); ));
for (int l1 = 0; l1 < Math.min(list.size(), 2); ++l1) { 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); minecraft.fontRendererObj.drawString((String) list.get(l1), x + 3, y + 12 + minecraft.fontRendererObj.FONT_HEIGHT * l1, 8421504);
} }
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -100,12 +95,13 @@ public class GuiReplayListEntry implements IGuiListEntry {
} }
@Override @Override
public void setSelected(int p_178011_1_, int p_178011_2_, int p_178011_3_) {} public void setSelected(int p_178011_1_, int p_178011_2_, int p_178011_3_) {
}
@Override @Override
public boolean mousePressed(int p_148278_1_, int p_148278_2_, public boolean mousePressed(int p_148278_1_, int p_148278_2_,
int p_148278_3_, int p_148278_4_, int p_148278_5_, int p_148278_6_) { int p_148278_3_, int p_148278_4_, int p_148278_5_, int p_148278_6_) {
for(int slot = 0; slot<parent.getSize(); slot++) { for(int slot = 0; slot < parent.getSize(); slot++) {
if(parent.getListEntry(slot) == this) { if(parent.getListEntry(slot) == this) {
parent.elementClicked(slot, false, p_148278_5_, p_148278_6_); parent.elementClicked(slot, false, p_148278_5_, p_148278_6_);
break; break;
@@ -117,6 +113,7 @@ public class GuiReplayListEntry implements IGuiListEntry {
@Override @Override
public void mouseReleased(int slotIndex, int x, int y, int mouseEvent, public void mouseReleased(int slotIndex, int x, int y, int mouseEvent,
int relativeX, int relativeY) {} int relativeX, int relativeY) {
}
} }

View File

@@ -1,29 +1,28 @@
package eu.crushedpixel.replaymod.gui.elements; package eu.crushedpixel.replaymod.gui.elements;
import java.io.File; import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiListExtended; import net.minecraft.client.gui.GuiListExtended;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import eu.crushedpixel.replaymod.api.client.holders.FileInfo; import java.io.File;
import java.util.ArrayList;
import java.util.List;
public abstract class GuiReplayListExtended extends GuiListExtended { public abstract class GuiReplayListExtended extends GuiListExtended {
public int selected = -1;
private List<GuiReplayListEntry> entries = new ArrayList<GuiReplayListEntry>();
public GuiReplayListExtended(Minecraft mcIn, int p_i45010_2_, public GuiReplayListExtended(Minecraft mcIn, int p_i45010_2_,
int p_i45010_3_, int p_i45010_4_, int p_i45010_5_, int p_i45010_6_) { int p_i45010_3_, int p_i45010_4_, int p_i45010_5_, int p_i45010_6_) {
super(mcIn, p_i45010_2_, p_i45010_3_, p_i45010_4_, p_i45010_5_, p_i45010_6_); super(mcIn, p_i45010_2_, p_i45010_3_, p_i45010_4_, p_i45010_5_, p_i45010_6_);
} }
public int selected = -1;
@Override @Override
protected void elementClicked(int slotIndex, boolean isDoubleClick, protected void elementClicked(int slotIndex, boolean isDoubleClick,
int mouseX, int mouseY) { int mouseX, int mouseY) {
@@ -32,40 +31,36 @@ public abstract class GuiReplayListExtended extends GuiListExtended {
} }
@Override @Override
protected void drawSelectionBox(int p_148120_1_, int p_148120_2_, int p_148120_3_, int p_148120_4_) protected void drawSelectionBox(int p_148120_1_, int p_148120_2_, int p_148120_3_, int p_148120_4_) {
{
int i1 = this.getSize(); int i1 = this.getSize();
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldrenderer = tessellator.getWorldRenderer(); WorldRenderer worldrenderer = tessellator.getWorldRenderer();
for (int j1 = 0; j1 < i1; ++j1) for(int j1 = 0; j1 < i1; ++j1) {
{
int k1 = p_148120_2_ + j1 * this.slotHeight + this.headerPadding; int k1 = p_148120_2_ + j1 * this.slotHeight + this.headerPadding;
int l1 = this.slotHeight - 4; int l1 = this.slotHeight - 4;
if (k1 > this.bottom || k1 + l1 < this.top) if(k1 > this.bottom || k1 + l1 < this.top) {
{
this.func_178040_a(j1, p_148120_1_, k1); this.func_178040_a(j1, p_148120_1_, k1);
} }
if (this.showSelectionBox && selected == j1) if(this.showSelectionBox && selected == j1) {
{
int i2 = this.left + (this.width / 2 - this.getListWidth() / 2); int i2 = this.left + (this.width / 2 - this.getListWidth() / 2);
int j2 = this.left + this.width / 2 + this.getListWidth() / 2; int j2 = this.left + this.width / 2 + this.getListWidth() / 2;
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.disableTexture2D(); GlStateManager.disableTexture2D();
worldrenderer.startDrawingQuads(); worldrenderer.startDrawingQuads();
worldrenderer.setColorOpaque_I(8421504); worldrenderer.setColorOpaque_I(8421504);
worldrenderer.addVertexWithUV((double)i2, (double)(k1 + l1 + 2), 0.0D, 0.0D, 1.0D); worldrenderer.addVertexWithUV((double) i2, (double) (k1 + l1 + 2), 0.0D, 0.0D, 1.0D);
worldrenderer.addVertexWithUV((double)j2, (double)(k1 + l1 + 2), 0.0D, 1.0D, 1.0D); worldrenderer.addVertexWithUV((double) j2, (double) (k1 + l1 + 2), 0.0D, 1.0D, 1.0D);
worldrenderer.addVertexWithUV((double)j2, (double)(k1 - 2), 0.0D, 1.0D, 0.0D); worldrenderer.addVertexWithUV((double) j2, (double) (k1 - 2), 0.0D, 1.0D, 0.0D);
worldrenderer.addVertexWithUV((double)i2, (double)(k1 - 2), 0.0D, 0.0D, 0.0D); worldrenderer.addVertexWithUV((double) i2, (double) (k1 - 2), 0.0D, 0.0D, 0.0D);
worldrenderer.setColorOpaque_I(0); worldrenderer.setColorOpaque_I(0);
worldrenderer.addVertexWithUV((double)(i2 + 1), (double)(k1 + l1 + 1), 0.0D, 0.0D, 1.0D); worldrenderer.addVertexWithUV((double) (i2 + 1), (double) (k1 + l1 + 1), 0.0D, 0.0D, 1.0D);
worldrenderer.addVertexWithUV((double)(j2 - 1), (double)(k1 + l1 + 1), 0.0D, 1.0D, 1.0D); worldrenderer.addVertexWithUV((double) (j2 - 1), (double) (k1 + l1 + 1), 0.0D, 1.0D, 1.0D);
worldrenderer.addVertexWithUV((double)(j2 - 1), (double)(k1 - 1), 0.0D, 1.0D, 0.0D); worldrenderer.addVertexWithUV((double) (j2 - 1), (double) (k1 - 1), 0.0D, 1.0D, 0.0D);
worldrenderer.addVertexWithUV((double)(i2 + 1), (double)(k1 - 1), 0.0D, 0.0D, 0.0D); worldrenderer.addVertexWithUV((double) (i2 + 1), (double) (k1 - 1), 0.0D, 0.0D, 0.0D);
tessellator.draw(); tessellator.draw();
GlStateManager.enableTexture2D(); GlStateManager.enableTexture2D();
} }
@@ -74,9 +69,6 @@ public abstract class GuiReplayListExtended extends GuiListExtended {
} }
} }
private List<GuiReplayListEntry> entries = new ArrayList<GuiReplayListEntry>();
public void clearEntries() { public void clearEntries() {
entries = new ArrayList<GuiReplayListEntry>(); entries = new ArrayList<GuiReplayListEntry>();
} }
@@ -97,97 +89,72 @@ public abstract class GuiReplayListExtended extends GuiListExtended {
@Override @Override
public void handleMouseInput() public void handleMouseInput() {
{ if(this.isMouseYWithinSlotBounds(this.mouseY)) {
if (this.isMouseYWithinSlotBounds(this.mouseY)) if(Mouse.isButtonDown(0)) {
{ if(this.initialClickY == -1.0F) {
if (Mouse.isButtonDown(0))
{
if (this.initialClickY == -1.0F)
{
int i2 = this.getScrollBarX(); int i2 = this.getScrollBarX();
int i1 = i2 + 6; int i1 = i2 + 6;
boolean flag = true; boolean flag = true;
if (this.mouseY >= this.top && this.mouseY <= this.bottom && this.mouseX <= i1) if(this.mouseY >= this.top && this.mouseY <= this.bottom && this.mouseX <= i1) {
{
int i = this.width / 2 - this.getListWidth() / 2; int i = this.width / 2 - this.getListWidth() / 2;
int j = this.width / 2 + this.getListWidth() / 2; int j = this.width / 2 + this.getListWidth() / 2;
int k = this.mouseY - this.top - this.headerPadding + (int)this.amountScrolled - 4; int k = this.mouseY - this.top - this.headerPadding + (int) this.amountScrolled - 4;
int l = k / this.slotHeight; int l = k / this.slotHeight;
if (this.mouseX >= i && this.mouseX <= j && l >= 0 && k >= 0 && l < this.getSize()) if(this.mouseX >= i && this.mouseX <= j && l >= 0 && k >= 0 && l < this.getSize()) {
{
boolean flag1 = l == this.selectedElement && Minecraft.getSystemTime() - this.lastClicked < 250L; boolean flag1 = l == this.selectedElement && Minecraft.getSystemTime() - this.lastClicked < 250L;
this.elementClicked(l, flag1, this.mouseX, this.mouseY); this.elementClicked(l, flag1, this.mouseX, this.mouseY);
this.selectedElement = l; this.selectedElement = l;
this.lastClicked = Minecraft.getSystemTime(); this.lastClicked = Minecraft.getSystemTime();
} } else if(this.mouseX >= i && this.mouseX <= j && k < 0) {
else if (this.mouseX >= i && this.mouseX <= j && k < 0) this.func_148132_a(this.mouseX - i, this.mouseY - this.top + (int) this.amountScrolled - 4);
{
this.func_148132_a(this.mouseX - i, this.mouseY - this.top + (int)this.amountScrolled - 4);
flag = false; flag = false;
} }
if (this.mouseX >= i2 && this.mouseX <= i1) if(this.mouseX >= i2 && this.mouseX <= i1) {
{
this.scrollMultiplier = -1.0F; this.scrollMultiplier = -1.0F;
int j1 = this.func_148135_f(); int j1 = this.func_148135_f();
if (j1 < 1) if(j1 < 1) {
{
j1 = 1; j1 = 1;
} }
int k1 = (int)((float)((this.bottom - this.top) * (this.bottom - this.top)) / (float)this.getContentHeight()); int k1 = (int) ((float) ((this.bottom - this.top) * (this.bottom - this.top)) / (float) this.getContentHeight());
k1 = MathHelper.clamp_int(k1, 32, this.bottom - this.top - 8); k1 = MathHelper.clamp_int(k1, 32, this.bottom - this.top - 8);
this.scrollMultiplier /= (float)(this.bottom - this.top - k1) / (float)j1; this.scrollMultiplier /= (float) (this.bottom - this.top - k1) / (float) j1;
} } else {
else
{
this.scrollMultiplier = 1.0F; this.scrollMultiplier = 1.0F;
} }
if (flag) if(flag) {
{ this.initialClickY = (float) this.mouseY;
this.initialClickY = (float)this.mouseY; } else {
}
else
{
this.initialClickY = -2.0F; this.initialClickY = -2.0F;
} }
} } else {
else
{
this.initialClickY = -2.0F; this.initialClickY = -2.0F;
} }
} else if(this.initialClickY >= 0.0F) {
this.amountScrolled -= ((float) this.mouseY - this.initialClickY) * this.scrollMultiplier;
this.initialClickY = (float) this.mouseY;
} }
else if (this.initialClickY >= 0.0F) } else {
{
this.amountScrolled -= ((float)this.mouseY - this.initialClickY) * this.scrollMultiplier;
this.initialClickY = (float)this.mouseY;
}
}
else
{
this.initialClickY = -1.0F; this.initialClickY = -1.0F;
} }
int l1 = Mouse.getEventDWheel(); int l1 = Mouse.getEventDWheel();
if (l1 != 0) if(l1 != 0) {
{ if(l1 > 0) {
if (l1 > 0)
{
l1 = -1; l1 = -1;
} } else if(l1 < 0) {
else if (l1 < 0)
{
l1 = 1; l1 = 1;
} }
this.amountScrolled += (float)(l1 * this.slotHeight / 2); this.amountScrolled += (float) (l1 * this.slotHeight / 2);
} }
} }
} }

View File

@@ -1,7 +1,7 @@
package eu.crushedpixel.replaymod.gui.elements.listeners; package eu.crushedpixel.replaymod.gui.elements.listeners;
public abstract class SelectionListener { public interface SelectionListener {
public abstract void onSelectionChanged(int selectionIndex); void onSelectionChanged(int selectionIndex);
} }

View File

@@ -1,18 +1,16 @@
package eu.crushedpixel.replaymod.gui.online; package eu.crushedpixel.replaymod.gui.online;
import java.awt.Color;
import java.io.IOException;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import org.lwjgl.input.Keyboard;
import eu.crushedpixel.replaymod.gui.GuiConstants; import eu.crushedpixel.replaymod.gui.GuiConstants;
import eu.crushedpixel.replaymod.gui.PasswordTextField; import eu.crushedpixel.replaymod.gui.PasswordTextField;
import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler; import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import org.lwjgl.input.Keyboard;
import java.awt.*;
import java.io.IOException;
public class GuiLoginPrompt extends GuiScreen { public class GuiLoginPrompt extends GuiScreen {
@@ -20,17 +18,15 @@ public class GuiLoginPrompt extends GuiScreen {
private static final int LOGGING_IN = 1; private static final int LOGGING_IN = 1;
private static final int INVALID_LOGIN = 2; private static final int INVALID_LOGIN = 2;
private static final int NO_CONNECTION = 3; private static final int NO_CONNECTION = 3;
private GuiScreen parent, successScreen;
private int textState = 0;
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getMinecraft();
private GuiScreen parent, successScreen;
private int textState = 0;
private GuiTextField username; private GuiTextField username;
private PasswordTextField password; private PasswordTextField password;
private GuiButton loginButton; private GuiButton loginButton;
private GuiButton cancelButton; private GuiButton cancelButton;
private int lastMouseX, lastMouseY;
private float lastPartialTicks;
public GuiLoginPrompt(GuiScreen parent, GuiScreen successScreen) { public GuiLoginPrompt(GuiScreen parent, GuiScreen successScreen) {
this.parent = parent; this.parent = parent;
@@ -41,20 +37,20 @@ public class GuiLoginPrompt extends GuiScreen {
public void initGui() { public void initGui() {
Keyboard.enableRepeatEvents(true); Keyboard.enableRepeatEvents(true);
username = new GuiTextField(GuiConstants.REPLAY_CENTER_LOGIN_TEXT_ID, fontRendererObj, this.width/2 - 45, 30, 145, 20); username = new GuiTextField(GuiConstants.REPLAY_CENTER_LOGIN_TEXT_ID, fontRendererObj, this.width / 2 - 45, 30, 145, 20);
username.setEnabled(true); username.setEnabled(true);
username.setFocused(true); username.setFocused(true);
password = new PasswordTextField(GuiConstants.REPLAY_CENTER_PASSWORD_TEXT_ID, fontRendererObj, this.width/2 - 45, 60, 145, 20); password = new PasswordTextField(GuiConstants.REPLAY_CENTER_PASSWORD_TEXT_ID, fontRendererObj, this.width / 2 - 45, 60, 145, 20);
password.setEnabled(true); password.setEnabled(true);
password.setFocused(false); password.setFocused(false);
loginButton = new GuiButton(GuiConstants.LOGIN_OKAY_BUTTON, this.width/2 - 150 - 2, 110, "Login"); loginButton = new GuiButton(GuiConstants.LOGIN_OKAY_BUTTON, this.width / 2 - 150 - 2, 110, "Login");
loginButton.width = 150; loginButton.width = 150;
loginButton.enabled = false; loginButton.enabled = false;
buttonList.add(loginButton); buttonList.add(loginButton);
cancelButton = new GuiButton(GuiConstants.LOGIN_CANCEL_BUTTON, this.width/2 + 2, 110, "Cancel"); cancelButton = new GuiButton(GuiConstants.LOGIN_CANCEL_BUTTON, this.width / 2 + 2, 110, "Cancel");
cancelButton.width = 150; cancelButton.width = 150;
buttonList.add(cancelButton); buttonList.add(cancelButton);
} }
@@ -94,9 +90,6 @@ public class GuiLoginPrompt extends GuiScreen {
} }
} }
private int lastMouseX, lastMouseY;
private float lastPartialTicks;
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void drawScreen(int mouseX, int mouseY, float partialTicks) {
lastMouseX = mouseX; lastMouseX = mouseX;
@@ -104,23 +97,23 @@ public class GuiLoginPrompt extends GuiScreen {
lastPartialTicks = partialTicks; lastPartialTicks = partialTicks;
this.drawDefaultBackground(); this.drawDefaultBackground();
drawCenteredString(fontRendererObj, "Login to ReplayMod.com", this.width/2, 10, Color.WHITE.getRGB()); drawCenteredString(fontRendererObj, "Login to ReplayMod.com", this.width / 2, 10, Color.WHITE.getRGB());
drawString(fontRendererObj, "Username", this.width/2 - 100, 37, Color.WHITE.getRGB()); drawString(fontRendererObj, "Username", this.width / 2 - 100, 37, Color.WHITE.getRGB());
username.drawTextBox(); username.drawTextBox();
drawString(fontRendererObj, "Password", this.width/2 - 100, 67, Color.WHITE.getRGB()); drawString(fontRendererObj, "Password", this.width / 2 - 100, 67, Color.WHITE.getRGB());
password.drawTextBox(); password.drawTextBox();
switch(textState) { switch(textState) {
case INVALID_LOGIN: case INVALID_LOGIN:
drawCenteredString(fontRendererObj, "Incorrect username or password.", this.width/2, 92, Color.RED.getRGB()); drawCenteredString(fontRendererObj, "Incorrect username or password.", this.width / 2, 92, Color.RED.getRGB());
break; break;
case LOGGING_IN: case LOGGING_IN:
drawCenteredString(fontRendererObj, "Logging in...", this.width/2, 92, Color.WHITE.getRGB()); drawCenteredString(fontRendererObj, "Logging in...", this.width / 2, 92, Color.WHITE.getRGB());
break; break;
case NO_CONNECTION: case NO_CONNECTION:
drawCenteredString(fontRendererObj, "Could not connect to ReplayMod.com", this.width/2, 92, Color.RED.getRGB()); drawCenteredString(fontRendererObj, "Could not connect to ReplayMod.com", this.width / 2, 92, Color.RED.getRGB());
break; break;
} }
super.drawScreen(mouseX, mouseY, partialTicks); super.drawScreen(mouseX, mouseY, partialTicks);

View File

@@ -1,22 +1,6 @@
package eu.crushedpixel.replaymod.gui.online; package eu.crushedpixel.replaymod.gui.online;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiYesNo;
import net.minecraft.client.gui.GuiYesNoCallback;
import net.minecraft.client.resources.I18n;
import org.lwjgl.input.Keyboard;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.api.client.ApiException;
import eu.crushedpixel.replaymod.api.client.SearchPagination; import eu.crushedpixel.replaymod.api.client.SearchPagination;
import eu.crushedpixel.replaymod.api.client.SearchQuery; import eu.crushedpixel.replaymod.api.client.SearchQuery;
import eu.crushedpixel.replaymod.api.client.holders.FileInfo; import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
@@ -24,29 +8,36 @@ import eu.crushedpixel.replaymod.gui.GuiConstants;
import eu.crushedpixel.replaymod.gui.elements.GuiReplayListExtended; import eu.crushedpixel.replaymod.gui.elements.GuiReplayListExtended;
import eu.crushedpixel.replaymod.gui.replayviewer.GuiReplayViewer; import eu.crushedpixel.replaymod.gui.replayviewer.GuiReplayViewer;
import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler; import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler;
import net.minecraft.client.gui.*;
import net.minecraft.client.resources.I18n;
import org.lwjgl.input.Keyboard;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback { public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback {
private enum Tab {
RECENT_FILES, BEST_FILES, MY_FILES, SEARCH;
}
private GuiReplayListExtended currentList;
private ReplayFileList recentFileList, bestFileList, myFileList, searchFileList;
private Tab currentTab = Tab.RECENT_FILES;
private static final SearchQuery recentFileSearchQuery = new SearchQuery(false, null, null, null, null, null, private static final SearchQuery recentFileSearchQuery = new SearchQuery(false, null, null, null, null, null,
null, null, null, null); null, null, null, null);
private static final SearchQuery bestFileSearchQuery = new SearchQuery(true, null, null, null, null, null, private static final SearchQuery bestFileSearchQuery = new SearchQuery(true, null, null, null, null, null,
null, null, null, null); null, null, null, null);
private static final int LOGOUT_CALLBACK_ID = 1;
private final SearchPagination recentFilePagination = new SearchPagination(recentFileSearchQuery); private final SearchPagination recentFilePagination = new SearchPagination(recentFileSearchQuery);
private final SearchPagination bestFilePagination = new SearchPagination(bestFileSearchQuery); private final SearchPagination bestFilePagination = new SearchPagination(bestFileSearchQuery);
private GuiReplayListExtended currentList;
private ReplayFileList recentFileList, bestFileList, myFileList, searchFileList;
private Tab currentTab = Tab.RECENT_FILES;
private SearchPagination myFilePagination; private SearchPagination myFilePagination;
public static GuiYesNo getYesNoGui(GuiYesNoCallback p_152129_0_, int p_152129_2_) {
String s1 = I18n.format("Do you really want to log out?", new Object[0]);
GuiYesNo guiyesno = new GuiYesNo(p_152129_0_, s1, "", "Logout", "Cancel", p_152129_2_);
return guiyesno;
}
@Override @Override
public void initGui() { public void initGui() {
Keyboard.enableRepeatEvents(true); Keyboard.enableRepeatEvents(true);
@@ -77,12 +68,12 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback {
int i = 0; int i = 0;
for(GuiButton b : buttonBar) { for(GuiButton b : buttonBar) {
int w = this.width - 30; int w = this.width - 30;
int w2 = w/buttonBar.size(); int w2 = w / buttonBar.size();
int x = 15+(w2*i); int x = 15 + (w2 * i);
b.xPosition = x+2; b.xPosition = x + 2;
b.yPosition = 20; b.yPosition = 20;
b.width = w2-4; b.width = w2 - 4;
buttonList.add(b); buttonList.add(b);
@@ -104,12 +95,12 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback {
i = 0; i = 0;
for(GuiButton b : bottomBar) { for(GuiButton b : bottomBar) {
int w = this.width - 30; int w = this.width - 30;
int w2 = w/bottomBar.size(); int w2 = w / bottomBar.size();
int x = 15+(w2*i); int x = 15 + (w2 * i);
b.xPosition = x+2; b.xPosition = x + 2;
b.yPosition = height-30; b.yPosition = height - 30;
b.width = w2-4; b.width = w2 - 4;
buttonList.add(b); buttonList.add(b);
@@ -139,7 +130,6 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback {
} }
} }
private static final int LOGOUT_CALLBACK_ID = 1;
@Override @Override
public void confirmClicked(boolean result, int id) { public void confirmClicked(boolean result, int id) {
if(id == LOGOUT_CALLBACK_ID) { if(id == LOGOUT_CALLBACK_ID) {
@@ -157,16 +147,10 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback {
} }
} }
public static GuiYesNo getYesNoGui(GuiYesNoCallback p_152129_0_, int p_152129_2_) {
String s1 = I18n.format("Do you really want to log out?", new Object[0]);
GuiYesNo guiyesno = new GuiYesNo(p_152129_0_, s1, "", "Logout", "Cancel", p_152129_2_);
return guiyesno;
}
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void drawScreen(int mouseX, int mouseY, float partialTicks) {
this.drawDefaultBackground(); this.drawDefaultBackground();
this.drawCenteredString(fontRendererObj, "Replay Center", this.width/2, 8, Color.WHITE.getRGB()); this.drawCenteredString(fontRendererObj, "Replay Center", this.width / 2, 8, Color.WHITE.getRGB());
if(currentList != null) { if(currentList != null) {
currentList.drawScreen(mouseX, mouseY, partialTicks); currentList.drawScreen(mouseX, mouseY, partialTicks);
@@ -207,13 +191,13 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback {
private void updateCurrentList(ReplayFileList list, SearchPagination pagination) { private void updateCurrentList(ReplayFileList list, SearchPagination pagination) {
currentList = list; currentList = list;
if(currentList == null) { if(currentList == null) {
currentList = new ReplayFileList(mc, width, height, 50, height-40, 36); currentList = new ReplayFileList(mc, width, height, 50, height - 40, 36);
} else { } else {
currentList.clearEntries(); currentList.clearEntries();
currentList.width = width; currentList.width = width;
currentList.height = height; currentList.height = height;
currentList.top = 50; currentList.top = 50;
currentList.bottom = height-40; currentList.bottom = height - 40;
} }
if(pagination.getLoadedPages() < 0) { if(pagination.getLoadedPages() < 0) {
@@ -224,7 +208,7 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback {
try { try {
File tmp = null; File tmp = null;
if(i.hasThumbnail()) { if(i.hasThumbnail()) {
tmp = File.createTempFile("thumb_online_"+i.getId(), "jpg"); tmp = File.createTempFile("thumb_online_" + i.getId(), "jpg");
ReplayMod.apiClient.downloadThumbnail(i.getId(), tmp); ReplayMod.apiClient.downloadThumbnail(i.getId(), tmp);
} }
currentList.addEntry(i, tmp); currentList.addEntry(i, tmp);
@@ -267,4 +251,8 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback {
}); });
t.start(); t.start();
} }
private enum Tab {
RECENT_FILES, BEST_FILES, MY_FILES, SEARCH;
}
} }

View File

@@ -1,36 +1,6 @@
package eu.crushedpixel.replaymod.gui.online; package eu.crushedpixel.replaymod.gui.online;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.util.ResourceLocation;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FilenameUtils;
import org.lwjgl.input.Keyboard;
import com.google.gson.Gson; import com.google.gson.Gson;
import eu.crushedpixel.replaymod.api.client.ApiException; import eu.crushedpixel.replaymod.api.client.ApiException;
import eu.crushedpixel.replaymod.api.client.FileUploader; import eu.crushedpixel.replaymod.api.client.FileUploader;
import eu.crushedpixel.replaymod.api.client.holders.Category; import eu.crushedpixel.replaymod.api.client.holders.Category;
@@ -42,47 +12,59 @@ import eu.crushedpixel.replaymod.recording.ReplayMetaData;
import eu.crushedpixel.replaymod.reflection.MCPNames; import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.utils.ImageUtils; import eu.crushedpixel.replaymod.utils.ImageUtils;
import eu.crushedpixel.replaymod.utils.ResourceHelper; import eu.crushedpixel.replaymod.utils.ResourceHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.util.ResourceLocation;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FilenameUtils;
import org.lwjgl.input.Keyboard;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
public class GuiUploadFile extends GuiScreen { public class GuiUploadFile extends GuiScreen {
private static final Pattern p = Pattern.compile("[^a-z0-9 \\-_]", Pattern.CASE_INSENSITIVE);
private static final Pattern pt = Pattern.compile("[^a-z0-9,]", Pattern.CASE_INSENSITIVE);
private final ResourceLocation textureResource;
private GuiTextField fileTitleInput, tagInput, messageTextField, tagPlaceholder; private GuiTextField fileTitleInput, tagInput, messageTextField, tagPlaceholder;
private GuiButton categoryButton, startUploadButton, cancelUploadButton, backButton; private GuiButton categoryButton, startUploadButton, cancelUploadButton, backButton;
private Gson gson = new Gson(); private Gson gson = new Gson();
private File replayFile; private File replayFile;
private ReplayMetaData metaData; private ReplayMetaData metaData;
private BufferedImage thumb; private BufferedImage thumb;
private FileUploader uploader = new FileUploader(); private FileUploader uploader = new FileUploader();
private Category category = Category.MINIGAME; private Category category = Category.MINIGAME;
private final ResourceLocation textureResource;
private DynamicTexture dynTex = null; private DynamicTexture dynTex = null;
private Minecraft mc = Minecraft.getMinecraft(); private Minecraft mc = Minecraft.getMinecraft();
private static final Pattern p = Pattern.compile("[^a-z0-9 \\-_]", Pattern.CASE_INSENSITIVE);
private static final Pattern pt = Pattern.compile("[^a-z0-9,]", Pattern.CASE_INSENSITIVE);
private GuiReplayViewer parent; private GuiReplayViewer parent;
public GuiUploadFile(File file, GuiReplayViewer parent) { public GuiUploadFile(File file, GuiReplayViewer parent) {
this.parent = parent; this.parent = parent;
this.textureResource = new ResourceLocation("upload_thumbs/"+FilenameUtils.getBaseName(file.getAbsolutePath())); this.textureResource = new ResourceLocation("upload_thumbs/" + FilenameUtils.getBaseName(file.getAbsolutePath()));
dynTex = null; dynTex = null;
boolean correctFile = false; boolean correctFile = false;
this.replayFile = file; this.replayFile = file;
if(("."+FilenameUtils.getExtension(file.getAbsolutePath())).equals(ConnectionEventHandler.ZIP_FILE_EXTENSION)) { if(("." + FilenameUtils.getExtension(file.getAbsolutePath())).equals(ConnectionEventHandler.ZIP_FILE_EXTENSION)) {
ZipFile archive = null; ZipFile archive = null;
try { try {
archive = new ZipFile(file); archive = new ZipFile(file);
ZipArchiveEntry recfile = archive.getEntry("recording"+ConnectionEventHandler.TEMP_FILE_EXTENSION); ZipArchiveEntry recfile = archive.getEntry("recording" + ConnectionEventHandler.TEMP_FILE_EXTENSION);
ZipArchiveEntry metadata = archive.getEntry("metaData"+ConnectionEventHandler.JSON_FILE_EXTENSION); ZipArchiveEntry metadata = archive.getEntry("metaData" + ConnectionEventHandler.JSON_FILE_EXTENSION);
ZipArchiveEntry image = archive.getEntry("thumb"); ZipArchiveEntry image = archive.getEntry("thumb");
BufferedImage img = null; BufferedImage img = null;
@@ -109,7 +91,8 @@ public class GuiUploadFile extends GuiScreen {
if(archive != null) { if(archive != null) {
try { try {
archive.close(); archive.close();
} catch (IOException e) {} } catch(IOException e) {
}
} }
} }
} }
@@ -136,23 +119,23 @@ public class GuiUploadFile extends GuiScreen {
if(replayFile == null) return; if(replayFile == null) return;
if(fileTitleInput == null) { if(fileTitleInput == null) {
fileTitleInput = new GuiTextField(GuiConstants.UPLOAD_NAME_INPUT, fontRendererObj, (this.width/2)+20+10, 21, Math.min(200, this.width-20-260), 20); fileTitleInput = new GuiTextField(GuiConstants.UPLOAD_NAME_INPUT, fontRendererObj, (this.width / 2) + 20 + 10, 21, Math.min(200, this.width - 20 - 260), 20);
String fname = FilenameUtils.getBaseName(replayFile.getAbsolutePath()); String fname = FilenameUtils.getBaseName(replayFile.getAbsolutePath());
fileTitleInput.setText(fname); fileTitleInput.setText(fname);
fileTitleInput.setMaxStringLength(30); fileTitleInput.setMaxStringLength(30);
} else { } else {
fileTitleInput.xPosition = (this.width/2)+20+10; fileTitleInput.xPosition = (this.width / 2) + 20 + 10;
//fileTitleInput.yPosition = 21; //fileTitleInput.yPosition = 21;
fileTitleInput.width = Math.min(200, this.width-20-260); fileTitleInput.width = Math.min(200, this.width - 20 - 260);
//fileTitleInput.height = 20; //fileTitleInput.height = 20;
} }
if(categoryButton == null) { if(categoryButton == null) {
categoryButton = new GuiButton(GuiConstants.UPLOAD_CATEGORY_BUTTON, (this.width/2)+20+10-1, 80, "Category: "+category.toNiceString()); categoryButton = new GuiButton(GuiConstants.UPLOAD_CATEGORY_BUTTON, (this.width / 2) + 20 + 10 - 1, 80, "Category: " + category.toNiceString());
categoryButton.width = Math.min(202, this.width-20-260+2); categoryButton.width = Math.min(202, this.width - 20 - 260 + 2);
buttonList.add(categoryButton); buttonList.add(categoryButton);
} else { } else {
categoryButton.xPosition = (this.width/2)+20+10-1; categoryButton.xPosition = (this.width / 2) + 20 + 10 - 1;
} }
if(startUploadButton == null) { if(startUploadButton == null) {
@@ -170,12 +153,12 @@ public class GuiUploadFile extends GuiScreen {
int i = 0; int i = 0;
for(GuiButton b : bottomBar) { for(GuiButton b : bottomBar) {
int w = this.width - 30; int w = this.width - 30;
int w2 = w/bottomBar.size(); int w2 = w / bottomBar.size();
int x = 15+(w2*i); int x = 15 + (w2 * i);
b.xPosition = x+2; b.xPosition = x + 2;
b.yPosition = height-30; b.yPosition = height - 30;
b.width = w2-4; b.width = w2 - 4;
buttonList.add(b); buttonList.add(b);
@@ -191,12 +174,12 @@ public class GuiUploadFile extends GuiScreen {
int i = 0; int i = 0;
for(GuiButton b : bottomBar) { for(GuiButton b : bottomBar) {
int w = this.width - 30; int w = this.width - 30;
int w2 = w/bottomBar.size(); int w2 = w / bottomBar.size();
int x = 15+(w2*i); int x = 15 + (w2 * i);
b.xPosition = x+2; b.xPosition = x + 2;
b.yPosition = height-30; b.yPosition = height - 30;
b.width = w2-4; b.width = w2 - 4;
buttonList.add(b); buttonList.add(b);
@@ -205,30 +188,30 @@ public class GuiUploadFile extends GuiScreen {
} }
if(messageTextField == null) { if(messageTextField == null) {
messageTextField = new GuiTextField(GuiConstants.UPLOAD_INFO_FIELD, fontRendererObj, 20, height-80, width-40, 20); messageTextField = new GuiTextField(GuiConstants.UPLOAD_INFO_FIELD, fontRendererObj, 20, height - 80, width - 40, 20);
messageTextField.setEnabled(true); messageTextField.setEnabled(true);
messageTextField.setFocused(false); messageTextField.setFocused(false);
messageTextField.setMaxStringLength(Integer.MAX_VALUE); messageTextField.setMaxStringLength(Integer.MAX_VALUE);
} else { } else {
messageTextField.yPosition = height-80; messageTextField.yPosition = height - 80;
messageTextField.width = width-40; messageTextField.width = width - 40;
} }
if(tagInput == null) { if(tagInput == null) {
tagInput = new GuiTextField(GuiConstants.UPLOAD_TAG_INPUT, fontRendererObj, (this.width/2)+20+10, 110, Math.min(200, this.width-20-260), 20); tagInput = new GuiTextField(GuiConstants.UPLOAD_TAG_INPUT, fontRendererObj, (this.width / 2) + 20 + 10, 110, Math.min(200, this.width - 20 - 260), 20);
tagInput.setMaxStringLength(30); tagInput.setMaxStringLength(30);
} else { } else {
tagInput.xPosition = (this.width/2)+20+10; tagInput.xPosition = (this.width / 2) + 20 + 10;
tagInput.width = Math.min(200, this.width-20-260); tagInput.width = Math.min(200, this.width - 20 - 260);
} }
if(tagPlaceholder == null) { if(tagPlaceholder == null) {
tagPlaceholder = new GuiTextField(GuiConstants.UPLOAD_TAG_PLACEHOLDER, fontRendererObj, (this.width/2)+20+10, 110, Math.min(200, this.width-20-260), 20); tagPlaceholder = new GuiTextField(GuiConstants.UPLOAD_TAG_PLACEHOLDER, fontRendererObj, (this.width / 2) + 20 + 10, 110, Math.min(200, this.width - 20 - 260), 20);
tagPlaceholder.setTextColor(Color.DARK_GRAY.getRGB()); tagPlaceholder.setTextColor(Color.DARK_GRAY.getRGB());
tagPlaceholder.setText("Tags separated by comma"); tagPlaceholder.setText("Tags separated by comma");
} else { } else {
tagPlaceholder.xPosition = (this.width/2)+20+10; tagPlaceholder.xPosition = (this.width / 2) + 20 + 10;
tagPlaceholder.width = Math.min(200, this.width-20-260); tagPlaceholder.width = Math.min(200, this.width - 20 - 260);
} }
validateStartButton(); validateStartButton();
@@ -239,7 +222,7 @@ public class GuiUploadFile extends GuiScreen {
if(!button.enabled) return; if(!button.enabled) return;
if(button.id == GuiConstants.UPLOAD_CATEGORY_BUTTON) { if(button.id == GuiConstants.UPLOAD_CATEGORY_BUTTON) {
category = category.next(); category = category.next();
categoryButton.displayString = "Category: "+category.toNiceString(); categoryButton.displayString = "Category: " + category.toNiceString();
} else if(button.id == GuiConstants.UPLOAD_BACK_BUTTON) { } else if(button.id == GuiConstants.UPLOAD_BACK_BUTTON) {
mc.displayGuiScreen(parent); mc.displayGuiScreen(parent);
} else if(button.id == GuiConstants.UPLOAD_START_BUTTON) { } else if(button.id == GuiConstants.UPLOAD_START_BUTTON) {
@@ -257,13 +240,13 @@ public class GuiUploadFile extends GuiScreen {
} }
} }
uploader.uploadFile(GuiUploadFile.this, AuthenticationHandler.getKey(), name, tags, replayFile, category); uploader.uploadFile(GuiUploadFile.this, AuthenticationHandler.getKey(), name, tags, replayFile, category);
} catch (ApiException e) { //TODO: Error handling } catch(ApiException e) { //TODO: Error handling
e.printStackTrace(); e.printStackTrace();
//mc.displayGuiScreen(new GuiMainMenu()); //mc.displayGuiScreen(new GuiMainMenu());
} catch (RuntimeException e) { } catch(RuntimeException e) {
e.printStackTrace(); e.printStackTrace();
//mc.displayGuiScreen(new GuiMainMenu()); //mc.displayGuiScreen(new GuiMainMenu());
} catch (IOException e) { } catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -277,14 +260,14 @@ public class GuiUploadFile extends GuiScreen {
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void drawScreen(int mouseX, int mouseY, float partialTicks) {
this.drawDefaultBackground(); this.drawDefaultBackground();
drawString(fontRendererObj, metaData.getServerName(), (this.width/2)+20+10, 50, Color.GRAY.getRGB()); drawString(fontRendererObj, metaData.getServerName(), (this.width / 2) + 20 + 10, 50, Color.GRAY.getRGB());
drawString(fontRendererObj, "Duration: "+String.format("%02dm%02ds", drawString(fontRendererObj, "Duration: " + String.format("%02dm%02ds",
TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()), TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()),
TimeUnit.MILLISECONDS.toSeconds(metaData.getDuration()) - TimeUnit.MILLISECONDS.toSeconds(metaData.getDuration()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration())) TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()))
), (this.width/2)+20+10, 65, Color.GRAY.getRGB()); ), (this.width / 2) + 20 + 10, 65, Color.GRAY.getRGB());
drawCenteredString(fontRendererObj, "Upload File", this.width/2, 5, Color.WHITE.getRGB()); drawCenteredString(fontRendererObj, "Upload File", this.width / 2, 5, Color.WHITE.getRGB());
//Draw thumbnail //Draw thumbnail
if(thumb != null) { if(thumb != null) {
@@ -296,8 +279,8 @@ public class GuiUploadFile extends GuiScreen {
} }
mc.getTextureManager().bindTexture(textureResource); //Will be freed by the ResourceHelper mc.getTextureManager().bindTexture(textureResource); //Will be freed by the ResourceHelper
int wid = (this.width)/2; int wid = (this.width) / 2;
int hei = Math.round(wid*(720f/1280f)); int hei = Math.round(wid * (720f / 1280f));
Gui.drawScaledCustomSizeModalRect(19, 20, 0, 0, 1280, 720, wid, hei, 1280, 720); Gui.drawScaledCustomSizeModalRect(19, 20, 0, 0, 1280, 720, wid, hei, 1280, 720);
} }
@@ -312,17 +295,17 @@ public class GuiUploadFile extends GuiScreen {
super.drawScreen(mouseX, mouseY, partialTicks); super.drawScreen(mouseX, mouseY, partialTicks);
this.drawRect(19, this.height-52, width-19, this.height-37, Color.BLACK.getRGB()); this.drawRect(19, this.height - 52, width - 19, this.height - 37, Color.BLACK.getRGB());
this.drawRect(21, this.height-50, width-21, this.height-39, Color.WHITE.getRGB()); this.drawRect(21, this.height - 50, width - 21, this.height - 39, Color.WHITE.getRGB());
int width = this.width-21 - 21; int width = this.width - 21 - 21;
float prog = uploader.getUploadProgress(); float prog = uploader.getUploadProgress();
float w = width*prog; float w = width * prog;
this.drawRect(21, this.height-50, Math.round(21+w), this.height-39, Color.RED.getRGB()); this.drawRect(21, this.height - 50, Math.round(21 + w), this.height - 39, Color.RED.getRGB());
String perc = (int)Math.floor(prog*100)+"%"; String perc = (int) Math.floor(prog * 100) + "%";
fontRendererObj.drawString(perc, this.width/2 - fontRendererObj.getStringWidth(perc)/2, this.height-48, Color.BLACK.getRGB()); fontRendererObj.drawString(perc, this.width / 2 - fontRendererObj.getStringWidth(perc) / 2, this.height - 48, Color.BLACK.getRGB());
} }
@Override @Override

View File

@@ -1,7 +1,7 @@
package eu.crushedpixel.replaymod.gui.online; package eu.crushedpixel.replaymod.gui.online;
import net.minecraft.client.Minecraft;
import eu.crushedpixel.replaymod.gui.elements.GuiReplayListExtended; import eu.crushedpixel.replaymod.gui.elements.GuiReplayListExtended;
import net.minecraft.client.Minecraft;
public class ReplayFileList extends GuiReplayListExtended { public class ReplayFileList extends GuiReplayListExtended {

View File

@@ -1,23 +1,20 @@
package eu.crushedpixel.replaymod.gui.replaystudio; package eu.crushedpixel.replaymod.gui.replaystudio;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import org.apache.commons.io.FilenameUtils;
import eu.crushedpixel.replaymod.gui.GuiConstants; import eu.crushedpixel.replaymod.gui.GuiConstants;
import eu.crushedpixel.replaymod.gui.elements.GuiArrowButton; import eu.crushedpixel.replaymod.gui.elements.GuiArrowButton;
import eu.crushedpixel.replaymod.gui.elements.GuiDropdown; import eu.crushedpixel.replaymod.gui.elements.GuiDropdown;
import eu.crushedpixel.replaymod.gui.elements.GuiEntryList; import eu.crushedpixel.replaymod.gui.elements.GuiEntryList;
import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener; import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener;
import eu.crushedpixel.replaymod.registry.ReplayGuiRegistry;
import eu.crushedpixel.replaymod.utils.ReplayFileIO; import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import org.apache.commons.io.FilenameUtils;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class GuiConnectPart extends GuiStudioPart { public class GuiConnectPart extends GuiStudioPart {
@@ -69,12 +66,12 @@ public class GuiConnectPart extends GuiStudioPart {
concatList.setSelectionIndex(0); concatList.setSelectionIndex(0);
replayDropdown = new GuiDropdown(1, fontRendererObj, 250, yPos+5, 0, 4); replayDropdown = new GuiDropdown(1, fontRendererObj, 250, yPos + 5, 0, 4);
replayDropdown.clearElements(); replayDropdown.clearElements();
replayFiles = ReplayFileIO.getAllReplayFiles(); replayFiles = ReplayFileIO.getAllReplayFiles();
int index = -1; int index = -1;
int i=0; int i = 0;
for(File file : replayFiles) { for(File file : replayFiles) {
String name = FilenameUtils.getBaseName(file.getAbsolutePath()); String name = FilenameUtils.getBaseName(file.getAbsolutePath());
replayDropdown.addElement(name); replayDropdown.addElement(name);
@@ -91,19 +88,20 @@ public class GuiConnectPart extends GuiStudioPart {
@Override @Override
public void onSelectionChanged(int selectionIndex) { public void onSelectionChanged(int selectionIndex) {
try { try {
filesToConcat.set(concatList.getSelectionIndex(), (String)replayDropdown.getElement(selectionIndex)); filesToConcat.set(concatList.getSelectionIndex(), (String) replayDropdown.getElement(selectionIndex));
concatList.setElements(filesToConcat); concatList.setElements(filesToConcat);
} catch(Exception e) {} //Sorry, too lazy to properly avoid this Exception here } catch(Exception e) {
} //Sorry, too lazy to properly avoid this Exception here
} }
}); });
concatList.addSelectionListener(new SelectionListener() { concatList.addSelectionListener(new SelectionListener() {
@Override @Override
public void onSelectionChanged(int selectionIndex) { public void onSelectionChanged(int selectionIndex) {
String selName = (String)concatList.getElement(selectionIndex); String selName = (String) concatList.getElement(selectionIndex);
int i = 0; int i = 0;
for(Object s : replayDropdown.getAllElements()) { for(Object s : replayDropdown.getAllElements()) {
String str = (String)s; String str = (String) s;
if(str.equals(selName)) { if(str.equals(selName)) {
replayDropdown.setSelectionIndex(i); replayDropdown.setSelectionIndex(i);
break; break;
@@ -112,37 +110,37 @@ public class GuiConnectPart extends GuiStudioPart {
} }
removeButton.enabled = upButton.enabled = downButton.enabled = !(selectionIndex < 0 || selectionIndex >= filesToConcat.size()); removeButton.enabled = upButton.enabled = downButton.enabled = !(selectionIndex < 0 || selectionIndex >= filesToConcat.size());
if(upButton.enabled && selectionIndex == 0) upButton.enabled = false; if(upButton.enabled && selectionIndex == 0) upButton.enabled = false;
if(downButton.enabled && selectionIndex == filesToConcat.size()-1) downButton.enabled = false; if(downButton.enabled && selectionIndex == filesToConcat.size() - 1) downButton.enabled = false;
} }
}); });
upButton = new GuiArrowButton(GuiConstants.REPLAY_EDITOR_UP_BUTTON, 195, yPos+40, "", true); upButton = new GuiArrowButton(GuiConstants.REPLAY_EDITOR_UP_BUTTON, 195, yPos + 40, "", true);
buttonList.add(upButton); buttonList.add(upButton);
downButton = new GuiArrowButton(GuiConstants.REPLAY_EDITOR_DOWN_BUTTON, 219, yPos+40, "", false); downButton = new GuiArrowButton(GuiConstants.REPLAY_EDITOR_DOWN_BUTTON, 219, yPos + 40, "", false);
buttonList.add(downButton); buttonList.add(downButton);
int w = GuiReplayStudio.instance.width-243-20-4; int w = GuiReplayStudio.instance.width - 243 - 20 - 4;
removeButton = new GuiButton(GuiConstants.REPLAY_EDITOR_REMOVE_BUTTON, 249, yPos+40, "Remove"); removeButton = new GuiButton(GuiConstants.REPLAY_EDITOR_REMOVE_BUTTON, 249, yPos + 40, "Remove");
buttonList.add(removeButton); buttonList.add(removeButton);
addButton = new GuiButton(GuiConstants.REPLAY_EDITOR_ADD_BUTTON, 0, yPos+40, "Add"); addButton = new GuiButton(GuiConstants.REPLAY_EDITOR_ADD_BUTTON, 0, yPos + 40, "Add");
buttonList.add(addButton); buttonList.add(addButton);
concatList.setSelectionIndex(0); concatList.setSelectionIndex(0);
} }
int w = GuiReplayStudio.instance.width-249-20-4; int w = GuiReplayStudio.instance.width - 249 - 20 - 4;
addButton.xPosition = 249+6+(w/2); addButton.xPosition = 249 + 6 + (w / 2);
addButton.width = w/2+2; addButton.width = w / 2 + 2;
removeButton.width = w/2+2; removeButton.width = w / 2 + 2;
replayDropdown.width = GuiReplayStudio.instance.width-250-18; replayDropdown.width = GuiReplayStudio.instance.width - 250 - 18;
int h = GuiReplayStudio.instance.height-yPos-20; int h = GuiReplayStudio.instance.height - yPos - 20;
int rows = (int)(h / (float)GuiEntryList.elementHeight); int rows = (int) (h / (float) GuiEntryList.elementHeight);
concatList.setVisibleElements(rows); concatList.setVisibleElements(rows);
initialized = true; initialized = true;
@@ -161,7 +159,7 @@ public class GuiConnectPart extends GuiStudioPart {
concatList.drawTextBox(); concatList.drawTextBox();
replayDropdown.drawTextBox(); replayDropdown.drawTextBox();
drawString(fontRendererObj, "Replay:", 200, yPos+5+7, Color.WHITE.getRGB()); drawString(fontRendererObj, "Replay:", 200, yPos + 5 + 7, Color.WHITE.getRGB());
} }
@Override @Override
@@ -183,14 +181,14 @@ public class GuiConnectPart extends GuiStudioPart {
if(button.id == GuiConstants.REPLAY_EDITOR_ADD_BUTTON) { if(button.id == GuiConstants.REPLAY_EDITOR_ADD_BUTTON) {
filesToConcat.add(FilenameUtils.getBaseName(replayFiles.get(0).getAbsolutePath())); filesToConcat.add(FilenameUtils.getBaseName(replayFiles.get(0).getAbsolutePath()));
concatList.setElements(filesToConcat); concatList.setElements(filesToConcat);
concatList.setSelectionIndex(filesToConcat.size()-1); concatList.setSelectionIndex(filesToConcat.size() - 1);
} else if(button.id == GuiConstants.REPLAY_EDITOR_REMOVE_BUTTON) { } else if(button.id == GuiConstants.REPLAY_EDITOR_REMOVE_BUTTON) {
int indexBefore = concatList.getSelectionIndex(); int indexBefore = concatList.getSelectionIndex();
if(indexBefore >= 0 && indexBefore < filesToConcat.size()) { if(indexBefore >= 0 && indexBefore < filesToConcat.size()) {
filesToConcat.remove(indexBefore); filesToConcat.remove(indexBefore);
concatList.setElements(filesToConcat); concatList.setElements(filesToConcat);
if(filesToConcat.size() <= indexBefore) { if(filesToConcat.size() <= indexBefore) {
concatList.setSelectionIndex(filesToConcat.size()-1); concatList.setSelectionIndex(filesToConcat.size() - 1);
} else { } else {
concatList.setSelectionIndex(indexBefore); concatList.setSelectionIndex(indexBefore);
} }

View File

@@ -1,56 +1,34 @@
package eu.crushedpixel.replaymod.gui.replaystudio; package eu.crushedpixel.replaymod.gui.replaystudio;
import java.awt.Color; import eu.crushedpixel.replaymod.gui.GuiConstants;
import eu.crushedpixel.replaymod.gui.elements.GuiDropdown;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import org.apache.commons.io.FilenameUtils;
import java.awt.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import org.apache.commons.io.FilenameUtils;
import eu.crushedpixel.replaymod.gui.GuiConstants;
import eu.crushedpixel.replaymod.gui.elements.GuiDropdown;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
public class GuiReplayStudio extends GuiScreen { public class GuiReplayStudio extends GuiScreen {
public static GuiReplayStudio instance = null;
private static final int tabYPos = 110; private static final int tabYPos = 110;
public static GuiReplayStudio instance = null;
private enum StudioTab { private StudioTab currentTab = StudioTab.TRIM;
TRIM(new GuiTrimPart(tabYPos)), CONNECT(new GuiConnectPart(tabYPos)), MODIFY(new GuiConnectPart(tabYPos)); private GuiDropdown replayDropdown;
private GuiButton saveModeButton, saveButton;
private GuiStudioPart studioPart; private boolean overrideSave = false;
private boolean initialized = false;
public GuiStudioPart getStudioPart() { private List<File> replayFiles = new ArrayList<File>();
return studioPart;
}
private StudioTab(GuiStudioPart part) {
this.studioPart = part;
}
}
public GuiReplayStudio() { public GuiReplayStudio() {
instance = this; instance = this;
} }
private StudioTab currentTab = StudioTab.TRIM;
private GuiDropdown replayDropdown;
private GuiButton saveModeButton, saveButton;
private boolean overrideSave = false;
private boolean initialized = false;
private List<File> replayFiles = new ArrayList<File>();
public File getSelectedFile() { public File getSelectedFile() {
try { try {
return replayFiles.get(replayDropdown.getSelectionIndex()); return replayFiles.get(replayDropdown.getSelectionIndex());
@@ -77,13 +55,13 @@ public class GuiReplayStudio extends GuiScreen {
tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_MODIFY_TAB, 0, 0, "Modify Replay")); tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_MODIFY_TAB, 0, 0, "Modify Replay"));
int w = this.width - 30; int w = this.width - 30;
int w2 = w/tabButtons.size(); int w2 = w / tabButtons.size();
int i = 0; int i = 0;
for(GuiButton b : tabButtons) { for(GuiButton b : tabButtons) {
int x = 15+(w2*i); int x = 15 + (w2 * i);
b.xPosition = x+2; b.xPosition = x + 2;
b.yPosition = 30; b.yPosition = 30;
b.width = w2-4; b.width = w2 - 4;
buttonList.add(b); buttonList.add(b);
@@ -93,26 +71,26 @@ public class GuiReplayStudio extends GuiScreen {
int modeWidth = tabButtons.get(0).width; int modeWidth = tabButtons.get(0).width;
if(!initialized) { if(!initialized) {
replayDropdown = new GuiDropdown(1, fontRendererObj, 15+2+1+80, 60, this.width-30-8-80-modeWidth-4, 5); replayDropdown = new GuiDropdown(1, fontRendererObj, 15 + 2 + 1 + 80, 60, this.width - 30 - 8 - 80 - modeWidth - 4, 5);
refreshReplayDropdown(); refreshReplayDropdown();
} else { } else {
replayDropdown.width = this.width-30-8-80-modeWidth-4; replayDropdown.width = this.width - 30 - 8 - 80 - modeWidth - 4;
} }
if(!initialized) { if(!initialized) {
saveModeButton = new GuiButton(GuiConstants.REPLAY_EDITOR_SAVEMODE_BUTTON, width-15-modeWidth-3, 60, getSaveModeLabel()); saveModeButton = new GuiButton(GuiConstants.REPLAY_EDITOR_SAVEMODE_BUTTON, width - 15 - modeWidth - 3, 60, getSaveModeLabel());
} else { } else {
saveModeButton.xPosition = width-15-modeWidth-3; saveModeButton.xPosition = width - 15 - modeWidth - 3;
} }
saveModeButton.width = modeWidth; saveModeButton.width = modeWidth;
buttonList.add(saveModeButton); buttonList.add(saveModeButton);
GuiButton backButton = new GuiButton(GuiConstants.REPLAY_EDITOR_BACK_BUTTON, width-70-18, height-20-5, "Back"); GuiButton backButton = new GuiButton(GuiConstants.REPLAY_EDITOR_BACK_BUTTON, width - 70 - 18, height - 20 - 5, "Back");
backButton.width = 70; backButton.width = 70;
buttonList.add(backButton); buttonList.add(backButton);
saveButton = new GuiButton(GuiConstants.REPLAY_EDITOR_SAVE_BUTTON, width-70-18, height-(2*20)-5-3, "Save"); saveButton = new GuiButton(GuiConstants.REPLAY_EDITOR_SAVE_BUTTON, width - 70 - 18, height - (2 * 20) - 5 - 3, "Save");
saveButton.width = 70; saveButton.width = 70;
buttonList.add(saveButton); buttonList.add(saveButton);
@@ -121,12 +99,14 @@ public class GuiReplayStudio extends GuiScreen {
} }
initialized = true; initialized = true;
}; }
private String getSaveModeLabel() { private String getSaveModeLabel() {
return overrideSave ? "Replace Source File" : "Save to new File"; return overrideSave ? "Replace Source File" : "Save to new File";
} }
;
@Override @Override
protected void actionPerformed(GuiButton button) throws IOException { protected void actionPerformed(GuiButton button) throws IOException {
if(!button.enabled) return; if(!button.enabled) return;
@@ -145,13 +125,13 @@ public class GuiReplayStudio extends GuiScreen {
File outputFile = getSelectedFile(); File outputFile = getSelectedFile();
File folder = ReplayFileIO.getReplayFolder(); File folder = ReplayFileIO.getReplayFolder();
if(!overrideSave) { if(!overrideSave) {
String name = FilenameUtils.getBaseName(outputFile.getAbsolutePath())+"_edited"; String name = FilenameUtils.getBaseName(outputFile.getAbsolutePath()) + "_edited";
File f = new File(folder, name+".mcpr"); File f = new File(folder, name + ".mcpr");
int num = 0; int num = 0;
while(f.exists()) { while(f.exists()) {
num++; num++;
String fileName = name+"_"+num; String fileName = name + "_" + num;
f = new File(folder, fileName+".mcpr"); f = new File(folder, fileName + ".mcpr");
} }
outputFile = f; outputFile = f;
} }
@@ -173,7 +153,7 @@ public class GuiReplayStudio extends GuiScreen {
super.drawScreen(mouseX, mouseY, partialTicks); super.drawScreen(mouseX, mouseY, partialTicks);
currentTab.getStudioPart().drawScreen(mouseX, mouseY, partialTicks); currentTab.getStudioPart().drawScreen(mouseX, mouseY, partialTicks);
drawCenteredString(fontRendererObj, "§n"+currentTab.getStudioPart().getTitle(), width/2, 92, Color.WHITE.getRGB()); drawCenteredString(fontRendererObj, "§n" + currentTab.getStudioPart().getTitle(), width / 2, 92, Color.WHITE.getRGB());
List<String> rows = new ArrayList<String>(); List<String> rows = new ArrayList<String>();
String remaining = currentTab.getStudioPart().getDescription(); String remaining = currentTab.getStudioPart().getDescription();
@@ -181,22 +161,24 @@ public class GuiReplayStudio extends GuiScreen {
String[] split = remaining.split(" "); String[] split = remaining.split(" ");
String b = ""; String b = "";
for(String sp : split) { for(String sp : split) {
b += sp+" "; b += sp + " ";
if(fontRendererObj.getStringWidth(b.trim()) > width-30-70-20) { if(fontRendererObj.getStringWidth(b.trim()) > width - 30 - 70 - 20) {
b = b.substring(0, b.trim().length()-(sp.length())); b = b.substring(0, b.trim().length() - (sp.length()));
break; break;
} }
} }
String trimmed = b.trim(); String trimmed = b.trim();
rows.add(trimmed); rows.add(trimmed);
try { try {
remaining = remaining.substring(trimmed.length()+1); remaining = remaining.substring(trimmed.length() + 1);
} catch(Exception e) {break;} } catch(Exception e) {
break;
}
} }
int i=0; int i = 0;
for(String row : rows) { for(String row : rows) {
drawString(fontRendererObj, row, 30, height-(15*(rows.size()-i)), Color.WHITE.getRGB()); drawString(fontRendererObj, row, 30, height - (15 * (rows.size() - i)), Color.WHITE.getRGB());
i++; i++;
} }
@@ -217,4 +199,18 @@ public class GuiReplayStudio extends GuiScreen {
currentTab.getStudioPart().updateScreen(); currentTab.getStudioPart().updateScreen();
super.updateScreen(); super.updateScreen();
} }
private enum StudioTab {
TRIM(new GuiTrimPart(tabYPos)), CONNECT(new GuiConnectPart(tabYPos)), MODIFY(new GuiConnectPart(tabYPos));
private GuiStudioPart studioPart;
private StudioTab(GuiStudioPart part) {
this.studioPart = part;
}
public GuiStudioPart getStudioPart() {
return studioPart;
}
}
} }

View File

@@ -1,18 +1,18 @@
package eu.crushedpixel.replaymod.gui.replaystudio; package eu.crushedpixel.replaymod.gui.replaystudio;
import net.minecraft.client.gui.GuiScreen;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import net.minecraft.client.gui.GuiScreen;
public abstract class GuiStudioPart extends GuiScreen { public abstract class GuiStudioPart extends GuiScreen {
protected int yPos = 0;
public GuiStudioPart(int yPos) { public GuiStudioPart(int yPos) {
this.yPos = yPos; this.yPos = yPos;
} }
protected int yPos = 0;
public abstract void applyFilters(File replayFile, File outputFile); public abstract void applyFilters(File replayFile, File outputFile);
public abstract String getDescription(); public abstract String getDescription();

View File

@@ -1,27 +1,20 @@
package eu.crushedpixel.replaymod.gui.replaystudio; package eu.crushedpixel.replaymod.gui.replaystudio;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import org.lwjgl.input.Keyboard;
import eu.crushedpixel.replaymod.gui.elements.GuiNumberInput; import eu.crushedpixel.replaymod.gui.elements.GuiNumberInput;
import eu.crushedpixel.replaymod.studio.StudioImplementation; import eu.crushedpixel.replaymod.studio.StudioImplementation;
import net.minecraft.client.Minecraft;
import org.lwjgl.input.Keyboard;
import java.awt.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class GuiTrimPart extends GuiStudioPart { public class GuiTrimPart extends GuiStudioPart {
private Minecraft mc = Minecraft.getMinecraft();
private static final String DESCRIPTION = "Removes the beginning and end of a Replay File and only keeps the Replay between the given timestamps."; private static final String DESCRIPTION = "Removes the beginning and end of a Replay File and only keeps the Replay between the given timestamps.";
private static final String TITLE = "Trim Replay"; private static final String TITLE = "Trim Replay";
private Minecraft mc = Minecraft.getMinecraft();
private boolean initialized = false; private boolean initialized = false;
private GuiNumberInput startMinInput, startSecInput, startMsInput; private GuiNumberInput startMinInput, startSecInput, startMsInput;
@@ -56,7 +49,7 @@ public class GuiTrimPart extends GuiStudioPart {
int secs = valueOf(startSecInput.getText()); int secs = valueOf(startSecInput.getText());
int ms = valueOf(startMsInput.getText()); int ms = valueOf(startMsInput.getText());
return (mins*60*1000)+(secs*1000)+ms; return (mins * 60 * 1000) + (secs * 1000) + ms;
} }
private int getEndTimestamp() { private int getEndTimestamp() {
@@ -64,7 +57,7 @@ public class GuiTrimPart extends GuiStudioPart {
int secs = valueOf(endSecInput.getText()); int secs = valueOf(endSecInput.getText());
int ms = valueOf(endMsInput.getText()); int ms = valueOf(endMsInput.getText());
return (mins*60*1000)+(secs*1000)+ms; return (mins * 60 * 1000) + (secs * 1000) + ms;
} }
@Override @Override
@@ -84,9 +77,9 @@ public class GuiTrimPart extends GuiStudioPart {
startSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos, 25, 2); startSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos, 25, 2);
startMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos, 30, 3); startMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos, 30, 3);
endMinInput = new GuiNumberInput(1, fontRendererObj, 70, yPos+30, 30, 3); endMinInput = new GuiNumberInput(1, fontRendererObj, 70, yPos + 30, 30, 3);
endSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos+30, 25, 2); endSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos + 30, 25, 2);
endMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos+30, 30, 3); endMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos + 30, 30, 3);
inputOrder.clear(); inputOrder.clear();
@@ -103,26 +96,26 @@ public class GuiTrimPart extends GuiStudioPart {
@Override @Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) { public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
for(GuiNumberInput input: inputOrder) { for(GuiNumberInput input : inputOrder) {
input.mouseClicked(mouseX, mouseY, mouseButton); input.mouseClicked(mouseX, mouseY, mouseButton);
} }
} }
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void drawScreen(int mouseX, int mouseY, float partialTicks) {
drawString(mc.fontRendererObj, "Start:", 30, yPos+7, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "Start:", 30, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "End:", 30, yPos+7+30, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "End:", 30, yPos + 7 + 30, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "m", 105, yPos+7, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "m", 105, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "m", 105, yPos+7+30, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "m", 105, yPos + 7 + 30, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "s", 150, yPos+7, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "s", 150, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "s", 150, yPos+7+30, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "s", 150, yPos + 7 + 30, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "ms", 200, yPos+7, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "ms", 200, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "ms", 200, yPos+7+30, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "ms", 200, yPos + 7 + 30, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "Timestamp: "+getStartTimestamp(), 230, yPos+7, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "Timestamp: " + getStartTimestamp(), 230, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "Timestamp: "+getEndTimestamp(), 230, yPos+30+7, Color.WHITE.getRGB()); drawString(mc.fontRendererObj, "Timestamp: " + getEndTimestamp(), 230, yPos + 30 + 7, Color.WHITE.getRGB());
for(GuiNumberInput input: inputOrder) { for(GuiNumberInput input : inputOrder) {
input.drawTextBox(); input.drawTextBox();
} }
@@ -134,7 +127,7 @@ public class GuiTrimPart extends GuiStudioPart {
if(!initialized) { if(!initialized) {
initGui(); initGui();
} else { } else {
for(GuiNumberInput input: inputOrder) { for(GuiNumberInput input : inputOrder) {
input.updateCursorCounter(); input.updateCursorCounter();
} }
} }
@@ -143,19 +136,19 @@ public class GuiTrimPart extends GuiStudioPart {
@Override @Override
public void keyTyped(char typedChar, int keyCode) { public void keyTyped(char typedChar, int keyCode) {
if(keyCode == Keyboard.KEY_TAB) { //Tab handling if(keyCode == Keyboard.KEY_TAB) { //Tab handling
int i=0; int i = 0;
for(GuiNumberInput input: inputOrder) { for(GuiNumberInput input : inputOrder) {
if(input.isFocused()) { if(input.isFocused()) {
input.setFocused(false); input.setFocused(false);
i++; i++;
if(i >= inputOrder.size()) i=0; if(i >= inputOrder.size()) i = 0;
inputOrder.get(i).setFocused(true); inputOrder.get(i).setFocused(true);
break; break;
} }
i++; i++;
} }
} else { } else {
for(GuiNumberInput input: inputOrder) { for(GuiNumberInput input : inputOrder) {
input.textboxKeyTyped(typedChar, keyCode); input.textboxKeyTyped(typedChar, keyCode);
} }
} }

View File

@@ -1,40 +1,33 @@
package eu.crushedpixel.replaymod.gui.replayviewer; package eu.crushedpixel.replaymod.gui.replayviewer;
import java.io.File; import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import java.io.IOException; import eu.crushedpixel.replaymod.utils.ReplayFileIO;
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.gui.GuiTextField; import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler; import java.io.File;
import eu.crushedpixel.replaymod.utils.ReplayFileIO; import java.io.IOException;
public class GuiRenameReplay extends GuiScreen public class GuiRenameReplay extends GuiScreen {
{ private static final String __OBFID = "CL_00000709";
private GuiScreen field_146585_a; private GuiScreen field_146585_a;
private GuiTextField field_146583_f; private GuiTextField field_146583_f;
private static final String __OBFID = "CL_00000709";
private File file; private File file;
public GuiRenameReplay(GuiScreen parent, File file) public GuiRenameReplay(GuiScreen parent, File file) {
{
this.field_146585_a = parent; this.field_146585_a = parent;
this.file = file; this.file = file;
} }
public void updateScreen() public void updateScreen() {
{
this.field_146583_f.updateCursorCounter(); this.field_146583_f.updateCursorCounter();
} }
public void initGui() public void initGui() {
{
Keyboard.enableRepeatEvents(true); Keyboard.enableRepeatEvents(true);
this.buttonList.clear(); this.buttonList.clear();
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12, I18n.format("Rename", new Object[0]))); this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12, I18n.format("Rename", new Object[0])));
@@ -45,28 +38,22 @@ public class GuiRenameReplay extends GuiScreen
this.field_146583_f.setText(s); this.field_146583_f.setText(s);
} }
public void onGuiClosed() public void onGuiClosed() {
{
Keyboard.enableRepeatEvents(false); Keyboard.enableRepeatEvents(false);
} }
protected void actionPerformed(GuiButton button) throws IOException protected void actionPerformed(GuiButton button) throws IOException {
{ if(button.enabled) {
if (button.enabled) if(button.id == 1) {
{
if (button.id == 1)
{
this.mc.displayGuiScreen(this.field_146585_a); this.mc.displayGuiScreen(this.field_146585_a);
} } else if(button.id == 0) {
else if (button.id == 0)
{
File folder = ReplayFileIO.getReplayFolder(); File folder = ReplayFileIO.getReplayFolder();
File initRenamed = new File(folder, this.field_146583_f.getText().trim()+ConnectionEventHandler.ZIP_FILE_EXTENSION.replaceAll("[^a-zA-Z0-9\\.\\-]", "_")); File initRenamed = new File(folder, this.field_146583_f.getText().trim() + ConnectionEventHandler.ZIP_FILE_EXTENSION.replaceAll("[^a-zA-Z0-9\\.\\-]", "_"));
File renamed = initRenamed; File renamed = initRenamed;
int i=1; int i = 1;
while(renamed.isFile()) { while(renamed.isFile()) {
renamed = new File(initRenamed.getAbsolutePath()+"_"+i); renamed = new File(initRenamed.getAbsolutePath() + "_" + i);
i++; i++;
} }
file.renameTo(renamed); file.renameTo(renamed);
@@ -75,25 +62,21 @@ public class GuiRenameReplay extends GuiScreen
} }
} }
protected void keyTyped(char typedChar, int keyCode) throws IOException protected void keyTyped(char typedChar, int keyCode) throws IOException {
{
this.field_146583_f.textboxKeyTyped(typedChar, keyCode); this.field_146583_f.textboxKeyTyped(typedChar, keyCode);
((GuiButton)this.buttonList.get(0)).enabled = this.field_146583_f.getText().trim().length() > 0; ((GuiButton) this.buttonList.get(0)).enabled = this.field_146583_f.getText().trim().length() > 0;
if (keyCode == 28 || keyCode == 156) if(keyCode == 28 || keyCode == 156) {
{ this.actionPerformed((GuiButton) this.buttonList.get(0));
this.actionPerformed((GuiButton)this.buttonList.get(0));
} }
} }
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
{
super.mouseClicked(mouseX, mouseY, mouseButton); super.mouseClicked(mouseX, mouseY, mouseButton);
this.field_146583_f.mouseClicked(mouseX, mouseY, mouseButton); this.field_146583_f.mouseClicked(mouseX, mouseY, mouseButton);
} }
public void drawScreen(int mouseX, int mouseY, float partialTicks) public void drawScreen(int mouseX, int mouseY, float partialTicks) {
{
this.drawDefaultBackground(); this.drawDefaultBackground();
this.drawCenteredString(this.fontRendererObj, I18n.format("Rename World", new Object[0]), this.width / 2, 20, 16777215); this.drawCenteredString(this.fontRendererObj, I18n.format("Rename World", new Object[0]), this.width / 2, 20, 16777215);
this.drawString(this.fontRendererObj, I18n.format("Replay Name", new Object[0]), this.width / 2 - 100, 47, 10526880); this.drawString(this.fontRendererObj, I18n.format("Replay Name", new Object[0]), this.width / 2 - 100, 47, 10526880);

View File

@@ -1,37 +1,7 @@
package eu.crushedpixel.replaymod.gui.replayviewer; package eu.crushedpixel.replaymod.gui.replayviewer;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
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.resources.I18n;
import net.minecraft.util.Util;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FilenameUtils;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.mojang.realmsclient.util.Pair; import com.mojang.realmsclient.util.Pair;
import eu.crushedpixel.replaymod.api.client.holders.FileInfo; import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
import eu.crushedpixel.replaymod.gui.GuiReplaySettings; import eu.crushedpixel.replaymod.gui.GuiReplaySettings;
import eu.crushedpixel.replaymod.gui.elements.GuiReplayListExtended; import eu.crushedpixel.replaymod.gui.elements.GuiReplayListExtended;
@@ -42,9 +12,36 @@ import eu.crushedpixel.replaymod.recording.ReplayMetaData;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.utils.ImageUtils; import eu.crushedpixel.replaymod.utils.ImageUtils;
import eu.crushedpixel.replaymod.utils.ReplayFileIO; import eu.crushedpixel.replaymod.utils.ReplayFileIO;
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.resources.I18n;
import net.minecraft.util.Util;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FilenameUtils;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URI;
import java.util.*;
import java.util.List;
public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback { public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
private static final int LOAD_BUTTON_ID = 9001;
private static final int UPLOAD_BUTTON_ID = 9002;
private static final int FOLDER_BUTTON_ID = 9003;
private static final int RENAME_BUTTON_ID = 9004;
private static final int DELETE_BUTTON_ID = 9005;
private static final int SETTINGS_BUTTON_ID = 9006;
private static final int CANCEL_BUTTON_ID = 9007;
private static Gson gson = new Gson();
private GuiScreen parentScreen; private GuiScreen parentScreen;
private GuiButton btnEditServer; private GuiButton btnEditServer;
private GuiButton btnSelectServer; private GuiButton btnSelectServer;
@@ -54,20 +51,18 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
private GuiReplayListExtended replayGuiList; private GuiReplayListExtended replayGuiList;
private List<Pair<Pair<File, ReplayMetaData>, File>> replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>(); private List<Pair<Pair<File, ReplayMetaData>, File>> replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>();
private GuiButton loadButton, uploadButton, folderButton, renameButton, deleteButton, cancelButton, settingsButton; private GuiButton loadButton, uploadButton, folderButton, renameButton, deleteButton, cancelButton, settingsButton;
private static Gson gson = new Gson();
private boolean replaying = false; private boolean replaying = false;
private static final int LOAD_BUTTON_ID = 9001;
private static final int UPLOAD_BUTTON_ID = 9002;
private static final int FOLDER_BUTTON_ID = 9003;
private static final int RENAME_BUTTON_ID = 9004;
private static final int DELETE_BUTTON_ID = 9005;
private static final int SETTINGS_BUTTON_ID = 9006;
private static final int CANCEL_BUTTON_ID = 9007;
private boolean delete_file = false; private boolean delete_file = false;
public static GuiYesNo getYesNoGui(GuiYesNoCallback p_152129_0_, String file, int p_152129_2_) {
String s1 = I18n.format("Are you sure you want to delete this replay?", new Object[0]);
String s2 = "\'" + file + "\' " + I18n.format("will be lost forever! (A long time!)", new Object[0]);
String s3 = I18n.format("Delete", new Object[0]);
String s4 = I18n.format("Cancel", new Object[0]);
GuiYesNo guiyesno = new GuiYesNo(p_152129_0_, s1, s2, s3, s4, p_152129_2_);
return guiyesno;
}
private void reloadFiles() { private void reloadFiles() {
replayGuiList.clearEntries(); replayGuiList.clearEntries();
replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>(); replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>();
@@ -75,8 +70,8 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
for(File file : ReplayFileIO.getAllReplayFiles()) { for(File file : ReplayFileIO.getAllReplayFiles()) {
try { try {
ZipFile archive = new ZipFile(file); ZipFile archive = new ZipFile(file);
ZipArchiveEntry recfile = archive.getEntry("recording"+ConnectionEventHandler.TEMP_FILE_EXTENSION); ZipArchiveEntry recfile = archive.getEntry("recording" + ConnectionEventHandler.TEMP_FILE_EXTENSION);
ZipArchiveEntry metadata = archive.getEntry("metaData"+ConnectionEventHandler.JSON_FILE_EXTENSION); ZipArchiveEntry metadata = archive.getEntry("metaData" + ConnectionEventHandler.JSON_FILE_EXTENSION);
ZipArchiveEntry image = archive.getEntry("thumb"); ZipArchiveEntry image = archive.getEntry("thumb");
BufferedImage img = null; BufferedImage img = null;
@@ -107,7 +102,8 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
replayFileList.add(Pair.of(Pair.of(file, metaData), tmp)); replayFileList.add(Pair.of(Pair.of(file, metaData), tmp));
archive.close(); archive.close();
} catch(Exception e) {} } catch(Exception e) {
}
} }
Collections.sort(replayFileList, new FileAgeComparator()); Collections.sort(replayFileList, new FileAgeComparator());
@@ -119,29 +115,15 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
} }
} }
public class FileAgeComparator implements Comparator<Pair<Pair<File, ReplayMetaData>, File>> {
@Override
public int compare(Pair<Pair<File, ReplayMetaData>, File> o1, Pair<Pair<File, ReplayMetaData>, File> o2) {
try {
return (int)(new Date(o2.first().second().getDate()).compareTo(new Date(o1.first().second().getDate())));
} catch(Exception e) {
return 0;
}
}
}
@Override @Override
public void initGui() { public void initGui() {
replayGuiList = new ReplayList(this, this.mc, this.width, this.height, 32, this.height - 64, 36); replayGuiList = new ReplayList(this, this.mc, this.width, this.height, 32, this.height - 64, 36);
Keyboard.enableRepeatEvents(true); Keyboard.enableRepeatEvents(true);
this.buttonList.clear(); this.buttonList.clear();
if (!this.initialized) { if(!this.initialized) {
this.initialized = true; this.initialized = true;
} } else {
else {
this.replayGuiList.setDimensions(this.width, this.height, 32, this.height - 64); this.replayGuiList.setDimensions(this.width, this.height, 32, this.height - 64);
} }
@@ -192,60 +174,52 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
if(button.enabled) { if(button.enabled) {
if(button.id == LOAD_BUTTON_ID) { if(button.id == LOAD_BUTTON_ID) {
loadReplay(replayGuiList.selected); loadReplay(replayGuiList.selected);
} } else if(button.id == CANCEL_BUTTON_ID) {
else if(button.id == CANCEL_BUTTON_ID) {
mc.displayGuiScreen(parentScreen); mc.displayGuiScreen(parentScreen);
} } else if(button.id == DELETE_BUTTON_ID) {
else if(button.id == DELETE_BUTTON_ID) {
String s = replayGuiList.getListEntry(replayGuiList.selected).getFileInfo().getName(); String s = replayGuiList.getListEntry(replayGuiList.selected).getFileInfo().getName();
if (s != null) { if(s != null) {
delete_file = true; delete_file = true;
GuiYesNo guiyesno = getYesNoGui(this, s, 1); GuiYesNo guiyesno = getYesNoGui(this, s, 1);
this.mc.displayGuiScreen(guiyesno); this.mc.displayGuiScreen(guiyesno);
} }
} } else if(button.id == SETTINGS_BUTTON_ID) {
else if(button.id == SETTINGS_BUTTON_ID) {
this.mc.displayGuiScreen(new GuiReplaySettings(this)); this.mc.displayGuiScreen(new GuiReplaySettings(this));
} } else if(button.id == RENAME_BUTTON_ID) {
else if(button.id == RENAME_BUTTON_ID) {
File file = replayFileList.get(replayGuiList.selected).first().first(); File file = replayFileList.get(replayGuiList.selected).first().first();
this.mc.displayGuiScreen(new GuiRenameReplay(this, file)); this.mc.displayGuiScreen(new GuiRenameReplay(this, file));
} } else if(button.id == UPLOAD_BUTTON_ID) {
else if(button.id == UPLOAD_BUTTON_ID) {
File file = replayFileList.get(replayGuiList.selected).first().first(); File file = replayFileList.get(replayGuiList.selected).first().first();
this.mc.displayGuiScreen(new GuiUploadFile(file, this)); this.mc.displayGuiScreen(new GuiUploadFile(file, this));
} } else if(button.id == FOLDER_BUTTON_ID) {
else if(button.id == FOLDER_BUTTON_ID) {
File file1 = ReplayFileIO.getReplayFolder(); File file1 = ReplayFileIO.getReplayFolder();
String s = file1.getAbsolutePath(); String s = file1.getAbsolutePath();
if(Util.getOSType() == Util.EnumOS.OSX) { if(Util.getOSType() == Util.EnumOS.OSX) {
try { try {
Runtime.getRuntime().exec(new String[] {"/usr/bin/open", s}); Runtime.getRuntime().exec(new String[]{"/usr/bin/open", s});
return; return;
} catch(IOException ioexception1) {
} }
catch(IOException ioexception1) {} } else if(Util.getOSType() == Util.EnumOS.WINDOWS) {
} String s1 = String.format("cmd.exe /C start \"Open file\" \"%s\"", new Object[]{s});
else if(Util.getOSType() == Util.EnumOS.WINDOWS) {
String s1 = String.format("cmd.exe /C start \"Open file\" \"%s\"", new Object[] {s});
try{ try {
Runtime.getRuntime().exec(s1); Runtime.getRuntime().exec(s1);
return; return;
} catch(IOException ioexception) {
} }
catch(IOException ioexception) {}
} }
boolean flag = false; boolean flag = false;
try { try {
Class oclass = Class.forName("java.awt.Desktop"); Class oclass = Class.forName("java.awt.Desktop");
Object object = oclass.getMethod("getDesktop", new Class[0]).invoke((Object)null, new Object[0]); Object object = oclass.getMethod("getDesktop", new Class[0]).invoke((Object) null, new Object[0]);
oclass.getMethod("browse", new Class[] {URI.class}).invoke(object, new Object[] {file1.toURI()}); oclass.getMethod("browse", new Class[]{URI.class}).invoke(object, new Object[]{file1.toURI()});
} } catch(Throwable throwable) {
catch(Throwable throwable) {
flag = true; flag = true;
} }
@@ -257,12 +231,10 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
} }
public void confirmClicked(boolean result, int id) { public void confirmClicked(boolean result, int id) {
if (this.delete_file) if(this.delete_file) {
{
this.delete_file = false; this.delete_file = false;
if (result) if(result) {
{
replayFileList.get(replayGuiList.selected).first().first().delete(); replayFileList.get(replayGuiList.selected).first().first().delete();
replayFileList.remove(replayGuiList.selected); replayFileList.remove(replayGuiList.selected);
} }
@@ -271,15 +243,6 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
} }
} }
public static GuiYesNo getYesNoGui(GuiYesNoCallback p_152129_0_, String file, int p_152129_2_) {
String s1 = I18n.format("Are you sure you want to delete this replay?", new Object[0]);
String s2 = "\'" + file + "\' " + I18n.format("will be lost forever! (A long time!)", new Object[0]);
String s3 = I18n.format("Delete", new Object[0]);
String s4 = I18n.format("Cancel", new Object[0]);
GuiYesNo guiyesno = new GuiYesNo(p_152129_0_, s1, s2, s3, s4, p_152129_2_);
return guiyesno;
}
public void setButtonsEnabled(boolean b) { public void setButtonsEnabled(boolean b) {
loadButton.enabled = b; loadButton.enabled = b;
if(!b || !AuthenticationHandler.isAuthenticated()) { if(!b || !AuthenticationHandler.isAuthenticated()) {
@@ -293,7 +256,7 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
} }
public void loadReplay(int id) { public void loadReplay(int id) {
mc.displayGuiScreen((GuiScreen)null); mc.displayGuiScreen((GuiScreen) null);
try { try {
ReplayHandler.startReplay(replayFileList.get(id).first().first()); ReplayHandler.startReplay(replayFileList.get(id).first().first());
@@ -303,4 +266,17 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
} }
public class FileAgeComparator implements Comparator<Pair<Pair<File, ReplayMetaData>, File>> {
@Override
public int compare(Pair<Pair<File, ReplayMetaData>, File> o1, Pair<Pair<File, ReplayMetaData>, File> o2) {
try {
return (int) (new Date(o2.first().second().getDate()).compareTo(new Date(o1.first().second().getDate())));
} catch(Exception e) {
return 0;
}
}
}
} }

View File

@@ -2,7 +2,7 @@ package eu.crushedpixel.replaymod.holders;
public class Keyframe { public class Keyframe {
private int realTimestamp; private final int realTimestamp;
public Keyframe(int realTimestamp) { public Keyframe(int realTimestamp) {
this.realTimestamp = realTimestamp; this.realTimestamp = realTimestamp;
@@ -11,10 +11,4 @@ public class Keyframe {
public int getRealTimestamp() { public int getRealTimestamp() {
return realTimestamp; return realTimestamp;
} }
public void setRealTimestamp(int realTimestamp) {
this.realTimestamp = realTimestamp;
}
} }

View File

@@ -1,16 +1,16 @@
package eu.crushedpixel.replaymod.holders; package eu.crushedpixel.replaymod.holders;
import java.util.Comparator;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import java.util.Comparator;
public class KeyframeComparator implements Comparator<Keyframe> { public class KeyframeComparator implements Comparator<Keyframe> {
@Override @Override
public int compare(Keyframe o1, Keyframe o2) { public int compare(Keyframe o1, Keyframe o2) {
if(ReplayHandler.isSelected(o1)) return 1; if(ReplayHandler.isSelected(o1)) return 1;
if(ReplayHandler.isSelected(o2)) return -1; if(ReplayHandler.isSelected(o2)) return -1;
return ((Integer)o1.getRealTimestamp()).compareTo(o2.getRealTimestamp()); return ((Integer) o1.getRealTimestamp()).compareTo(o2.getRealTimestamp());
} }
} }

View File

@@ -1,8 +1,5 @@
package eu.crushedpixel.replaymod.holders; package eu.crushedpixel.replaymod.holders;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.Packet;
public class PacketData { public class PacketData {
private byte[] array; private byte[] array;
@@ -16,12 +13,15 @@ public class PacketData {
public byte[] getByteArray() { public byte[] getByteArray() {
return array; return array;
} }
public void setByteArray(byte[] array) { public void setByteArray(byte[] array) {
this.array = array; this.array = array;
} }
public int getTimestamp() { public int getTimestamp() {
return timestamp; return timestamp;
} }
public void setTimestamp(int timestamp) { public void setTimestamp(int timestamp) {
this.timestamp = timestamp; this.timestamp = timestamp;
} }

View File

@@ -65,6 +65,6 @@ public class Position {
@Override @Override
public String toString() { public String toString() {
return "X="+x+", Y="+y+", Z="+z+", Yaw="+yaw+", Pitch="+pitch; return "X=" + x + ", Y=" + y + ", Z=" + z + ", Yaw=" + yaw + ", Pitch=" + pitch;
} }
} }

View File

@@ -2,7 +2,7 @@ package eu.crushedpixel.replaymod.holders;
public class PositionKeyframe extends Keyframe { public class PositionKeyframe extends Keyframe {
private Position position; private final Position position;
public PositionKeyframe(int realTime, Position position) { public PositionKeyframe(int realTime, Position position) {
super(realTime); super(realTime);
@@ -12,9 +12,4 @@ public class PositionKeyframe extends Keyframe {
public Position getPosition() { public Position getPosition() {
return position; return position;
} }
public void setPosition(Position position) {
this.position = position;
}
} }

View File

@@ -1,100 +0,0 @@
package eu.crushedpixel.replaymod.holders;
/**
* Copyright (c) 2014 Johni0702
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
**/
public final class TimeInfo {
@Override
public String toString() {
return start+" | "+speedSince+" | "+speed+" | "+jumpTo;
}
public static TimeInfo create() {
long now = System.currentTimeMillis();
return new TimeInfo(now, now, 1, -1);
}
public TimeInfo(long start, long speedSince, double speed, long jumpTo) {
this.start = start;
this.speedSince = speedSince;
this.speed = speed;
this.jumpTo = jumpTo;
}
private final long start;
private final long speedSince;
private final double speed;
private final long jumpTo;
public long getActualStartTime(long now) {
long realTimePassed = now - speedSince;
long ingameTimePassed = (long) (realTimePassed * this.speed);
return start + realTimePassed - ingameTimePassed;
}
public long getInGameTimePassed(long now) {
long realTimePassed = now - speedSince;
long ingameTimePassed = (long) (realTimePassed * this.speed);
return speedSince - start + ingameTimePassed;
}
public TimeInfo updateSpeed(long now, double speed) {
if (isJumping()) {
return new TimeInfo(now-jumpTo, now, speed, -1);
} else {
if (this.speed == speed) {
return this;
}
long start;
if (this.speed == 1) {
start = this.start;
} else {
start = getActualStartTime(now);
}
return new TimeInfo(start, now, speed, -1);
}
}
public boolean isJumping() {
return jumpTo != -1;
}
public TimeInfo jumpTo(long jumpTo) {
return new TimeInfo(start, speedSince, speed, jumpTo);
}
public long getStart() {
return start;
}
public long getSpeedSince() {
return speedSince;
}
public double getSpeed() {
return speed;
}
public long getJumpTo() {
return jumpTo;
}
}

View File

@@ -2,7 +2,7 @@ package eu.crushedpixel.replaymod.holders;
public class TimeKeyframe extends Keyframe { public class TimeKeyframe extends Keyframe {
private int timestamp; private final int timestamp;
public TimeKeyframe(int realTime, int timestamp) { public TimeKeyframe(int realTime, int timestamp) {
super(realTime); super(realTime);
@@ -12,8 +12,4 @@ public class TimeKeyframe extends Keyframe {
public int getTimestamp() { public int getTimestamp() {
return timestamp; return timestamp;
} }
public void setTimestamp(int timestamp) {
this.timestamp = timestamp;
}
} }

View File

@@ -2,17 +2,16 @@ package eu.crushedpixel.replaymod.interpolation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
public abstract class BasicSpline { public abstract class BasicSpline {
public void calcNaturalCubic(List valueCollection, Field val, Collection<Cubic> cubicCollection) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { public void calcNaturalCubic(List valueCollection, Field val, Collection<Cubic> cubicCollection) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
int num = valueCollection.size()-1; int num = valueCollection.size() - 1;
double[] gamma = new double[num+1]; double[] gamma = new double[num + 1];
double[] delta = new double[num+1]; double[] delta = new double[num + 1];
double[] D = new double[num+1]; double[] D = new double[num + 1];
int i; int i;
/* /*
@@ -28,42 +27,43 @@ public abstract class BasicSpline {
and then back sustitution. The D[i] are the derivatives at the knots. and then back sustitution. The D[i] are the derivatives at the knots.
*/ */
gamma[0] = 1.0f / 2.0f; gamma[0] = 1.0f / 2.0f;
for(i=1; i< num; i++) { for(i = 1; i < num; i++) {
gamma[i] = 1.0f/(4.0f - gamma[i-1]); gamma[i] = 1.0f / (4.0f - gamma[i - 1]);
} }
gamma[num] = 1.0f/(2.0f - gamma[num-1]); gamma[num] = 1.0f / (2.0f - gamma[num - 1]);
Double p0 = val.getDouble(valueCollection.get(0)); Double p0 = val.getDouble(valueCollection.get(0));
Double p1 = val.getDouble(valueCollection.get(1)); Double p1 = val.getDouble(valueCollection.get(1));
delta[0] = 3.0f * (p1 - p0) * gamma[0]; delta[0] = 3.0f * (p1 - p0) * gamma[0];
for(i=1; i< num; i++) { for(i = 1; i < num; i++) {
p0 = val.getDouble(valueCollection.get(i-1)); p0 = val.getDouble(valueCollection.get(i - 1));
p1 = val.getDouble(valueCollection.get(i+1)); p1 = val.getDouble(valueCollection.get(i + 1));
delta[i] = (3.0f * (p1 - p0) - delta[i - 1]) * gamma[i]; delta[i] = (3.0f * (p1 - p0) - delta[i - 1]) * gamma[i];
} }
p0 = val.getDouble(valueCollection.get(num-1));
p0 = val.getDouble(valueCollection.get(num - 1));
p1 = val.getDouble(valueCollection.get(num)); p1 = val.getDouble(valueCollection.get(num));
delta[num] = (3.0f * (p1 - p0) - delta[num - 1]) * gamma[num]; delta[num] = (3.0f * (p1 - p0) - delta[num - 1]) * gamma[num];
D[num] = delta[num]; D[num] = delta[num];
for(i=num-1; i >= 0; i--) { for(i = num - 1; i >= 0; i--) {
D[i] = delta[i] - gamma[i] * D[i+1]; D[i] = delta[i] - gamma[i] * D[i + 1];
} }
//now compute the coefficients of the cubics //now compute the coefficients of the cubics
cubicCollection.clear(); cubicCollection.clear();
for(i=0; i<num; i++) { for(i = 0; i < num; i++) {
p0 = val.getDouble(valueCollection.get(i)); p0 = val.getDouble(valueCollection.get(i));
p1 = val.getDouble(valueCollection.get(i+1)); p1 = val.getDouble(valueCollection.get(i + 1));
cubicCollection.add(new Cubic( cubicCollection.add(new Cubic(
p0, p0,
D[i], D[i],
3*(p1 - p0) - 2*D[i] - D[i+1], 3 * (p1 - p0) - 2 * D[i] - D[i + 1],
2*(p0 - p1) + D[i] + D[i+1] 2 * (p0 - p1) + D[i] + D[i + 1]
) )
); );
} }

View File

@@ -1,16 +1,16 @@
package eu.crushedpixel.replaymod.interpolation; package eu.crushedpixel.replaymod.interpolation;
public class Cubic { public class Cubic {
private double a,b,c,d; private double a, b, c, d;
public Cubic(double p0, double d2, double e, double f) { public Cubic(double p0, double d2, double e, double f) {
this.a =p0; this.a = p0;
this.b =d2; this.b = d2;
this.c =e; this.c = e;
this.d =f; this.d = f;
} }
public double eval(double u) { public double eval(double u) {
return (((d*u) + c)*u + b)*u + a; return (((d * u) + c) * u + b) * u + a;
} }
} }

View File

@@ -1,18 +1,18 @@
package eu.crushedpixel.replaymod.interpolation; package eu.crushedpixel.replaymod.interpolation;
import akka.japi.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import akka.japi.Pair;
public abstract class LinearInterpolation<K> { public abstract class LinearInterpolation<K> {
protected List<K> points = new ArrayList<K>();
public LinearInterpolation() { public LinearInterpolation() {
points = new ArrayList<K>(); points = new ArrayList<K>();
} }
protected List<K> points = new ArrayList<K>();
public abstract K getPoint(float position); public abstract K getPoint(float position);
public void addPoint(K point) { public void addPoint(K point) {
@@ -25,22 +25,22 @@ public abstract class LinearInterpolation<K> {
protected Pair<Float, Pair<K, K>> getCurrentPoints(float position) { protected Pair<Float, Pair<K, K>> getCurrentPoints(float position) {
if(points.size() == 0) return null; if(points.size() == 0) return null;
position = position * (points.size()-1); position = position * (points.size() - 1);
int cubicNum = (int)Math.min(points.size()-1, position); int cubicNum = (int) Math.min(points.size() - 1, position);
float cubicPos = (position - cubicNum); float cubicPos = (position - cubicNum);
if(cubicNum == points.size()-1) { if(cubicNum == points.size() - 1) {
cubicNum--; cubicNum--;
cubicPos++; cubicPos++;
} }
if(cubicNum < 0) { if(cubicNum < 0) {
return new Pair<Float, Pair<K,K>>(cubicPos, new Pair<K,K>(points.get(cubicNum+1), points.get(cubicNum+1))); return new Pair<Float, Pair<K, K>>(cubicPos, new Pair<K, K>(points.get(cubicNum + 1), points.get(cubicNum + 1)));
} }
return new Pair<Float, Pair<K,K>>(cubicPos, new Pair<K,K>(points.get(cubicNum), points.get(cubicNum+1))); return new Pair<Float, Pair<K, K>>(cubicPos, new Pair<K, K>(points.get(cubicNum), points.get(cubicNum + 1)));
} }
protected double getInterpolatedValue(double val1, double val2, float perc) { protected double getInterpolatedValue(double val1, double val2, float perc) {
return val1+((val2-val1)*perc); return val1 + ((val2 - val1) * perc);
} }
} }

View File

@@ -19,8 +19,8 @@ public class LinearPoint extends LinearInterpolation<Position> {
double y = getInterpolatedValue(first.getY(), second.getY(), perc); double y = getInterpolatedValue(first.getY(), second.getY(), perc);
double z = getInterpolatedValue(first.getZ(), second.getZ(), perc); double z = getInterpolatedValue(first.getZ(), second.getZ(), perc);
float pitch = (float)getInterpolatedValue(first.getPitch(), second.getPitch(), perc); float pitch = (float) getInterpolatedValue(first.getPitch(), second.getPitch(), perc);
float yaw = (float)getInterpolatedValue(first.getYaw(), second.getYaw(), perc); float yaw = (float) getInterpolatedValue(first.getYaw(), second.getYaw(), perc);
Position inter = new Position(x, y, z, pitch, yaw); Position inter = new Position(x, y, z, pitch, yaw);

View File

@@ -1,7 +1,6 @@
package eu.crushedpixel.replaymod.interpolation; package eu.crushedpixel.replaymod.interpolation;
import akka.japi.Pair; import akka.japi.Pair;
import eu.crushedpixel.replaymod.holders.Position;
public class LinearTimestamp extends LinearInterpolation<Integer> { public class LinearTimestamp extends LinearInterpolation<Integer> {
@@ -15,7 +14,7 @@ public class LinearTimestamp extends LinearInterpolation<Integer> {
int first = pair.second().first(); int first = pair.second().first();
int second = pair.second().second(); int second = pair.second().second();
int val = (int)getInterpolatedValue(first, second, perc); int val = (int) getInterpolatedValue(first, second, perc);
return val; return val;
} }

View File

@@ -1,31 +1,25 @@
package eu.crushedpixel.replaymod.interpolation; package eu.crushedpixel.replaymod.interpolation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Vector;
import com.sun.javafx.geom.Vec3d;
import eu.crushedpixel.replaymod.holders.Position; import eu.crushedpixel.replaymod.holders.Position;
public class SplinePoint extends BasicSpline{ import java.lang.reflect.Field;
private Vector<Position> points; import java.lang.reflect.InvocationTargetException;
import java.util.Vector;
public class SplinePoint extends BasicSpline {
private static final Object[] EMPTYOBJ = new Object[]{};
private Vector<Position> points;
private Vector<Cubic> xCubics; private Vector<Cubic> xCubics;
private Vector<Cubic> yCubics; private Vector<Cubic> yCubics;
private Vector<Cubic> zCubics; private Vector<Cubic> zCubics;
private Vector<Cubic> pitchCubics; private Vector<Cubic> pitchCubics;
private Vector<Cubic> yawCubics; private Vector<Cubic> yawCubics;
private Field vectorX; private Field vectorX;
private Field vectorY; private Field vectorY;
private Field vectorZ; private Field vectorZ;
private Field vectorPitch; private Field vectorPitch;
private Field vectorYaw; private Field vectorYaw;
private static final Object[] EMPTYOBJ = new Object[] { };
public SplinePoint() { public SplinePoint() {
this.points = new Vector<Position>(); this.points = new Vector<Position>();
@@ -46,9 +40,9 @@ public class SplinePoint extends BasicSpline{
vectorZ.setAccessible(true); vectorZ.setAccessible(true);
vectorPitch.setAccessible(true); vectorPitch.setAccessible(true);
vectorYaw.setAccessible(true); vectorYaw.setAccessible(true);
} catch (SecurityException e) { } catch(SecurityException e) {
e.printStackTrace(); e.printStackTrace();
} catch (NoSuchFieldException e) { } catch(NoSuchFieldException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -68,25 +62,25 @@ public class SplinePoint extends BasicSpline{
calcNaturalCubic(points, vectorZ, zCubics); calcNaturalCubic(points, vectorZ, zCubics);
calcNaturalCubic(points, vectorPitch, pitchCubics); calcNaturalCubic(points, vectorPitch, pitchCubics);
calcNaturalCubic(points, vectorYaw, yawCubics); calcNaturalCubic(points, vectorYaw, yawCubics);
} catch (IllegalArgumentException e) { } catch(IllegalArgumentException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IllegalAccessException e) { } catch(IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InvocationTargetException e) { } catch(InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public Position getPoint(float position) { public Position getPoint(float position) {
position = position * xCubics.size(); position = position * xCubics.size();
int cubicNum = (int)Math.min(xCubics.size()-1, position); int cubicNum = (int) Math.min(xCubics.size() - 1, position);
float cubicPos = (position - cubicNum); float cubicPos = (position - cubicNum);
return new Position(xCubics.get(cubicNum).eval(cubicPos), return new Position(xCubics.get(cubicNum).eval(cubicPos),
yCubics.get(cubicNum).eval(cubicPos), yCubics.get(cubicNum).eval(cubicPos),
zCubics.get(cubicNum).eval(cubicPos), zCubics.get(cubicNum).eval(cubicPos),
(float)pitchCubics.get(cubicNum).eval(cubicPos), (float) pitchCubics.get(cubicNum).eval(cubicPos),
(float)yawCubics.get(cubicNum).eval(cubicPos)); (float) yawCubics.get(cubicNum).eval(cubicPos));
} }
} }

View File

@@ -1,15 +1,10 @@
package eu.crushedpixel.replaymod.online.authentication; package eu.crushedpixel.replaymod.online.authentication;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import net.minecraft.client.Minecraft;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.api.client.ApiClient; import eu.crushedpixel.replaymod.api.client.ApiClient;
import eu.crushedpixel.replaymod.api.client.ApiException; import eu.crushedpixel.replaymod.api.client.ApiException;
import eu.crushedpixel.replaymod.reflection.MCPNames;
import java.io.IOException;
public class AuthenticationHandler { public class AuthenticationHandler {
@@ -19,8 +14,6 @@ public class AuthenticationHandler {
private static final ApiClient apiClient = new ApiClient(); private static final ApiClient apiClient = new ApiClient();
private static Minecraft mc = Minecraft.getMinecraft();
private static String authkey = null; private static String authkey = null;
public static boolean isAuthenticated() { public static boolean isAuthenticated() {
@@ -48,7 +41,7 @@ public class AuthenticationHandler {
public static int logout() { public static int logout() {
try { try {
boolean success = ReplayMod.apiClient.logout(authkey); ReplayMod.apiClient.logout(authkey);
authkey = null; authkey = null;
return SUCCESS; return SUCCESS;
} catch(ApiException e) { } catch(ApiException e) {
@@ -57,26 +50,4 @@ public class AuthenticationHandler {
return NO_CONNECTION; return NO_CONNECTION;
} }
} }
private static final List<String> PREMIUM_USERS = new ArrayList<String>() {
{
add("Ender_Workbench");
add("oleoleMC");
add("Johni0702");
add("Rafessor");
add("bluffamachuck");
add("Panguino");
add("SixteenBy16");
}
};
private static boolean isPremiumUsername(String username) {
//TODO: API check with the website
return (PREMIUM_USERS.contains(username) || MCPNames.env.isMCPEnvironment());
}
private static boolean isPremiumUUID(String uuid) {
//TODO: API check with the website
return false;
}
} }

View File

@@ -1,8 +1,7 @@
package eu.crushedpixel.replaymod.recording; package eu.crushedpixel.replaymod.recording;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests; import eu.crushedpixel.replaymod.chat.ChatMessageHandler.ChatMessageType;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
import eu.crushedpixel.replaymod.utils.ReplayFileIO; import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
@@ -25,34 +24,31 @@ import java.util.Map.Entry;
public class ConnectionEventHandler { public class ConnectionEventHandler {
public static final String TEMP_FILE_EXTENSION = ".tmcpr";
public static final String JSON_FILE_EXTENSION = ".json";
public static final String ZIP_FILE_EXTENSION = ".mcpr";
private static final String decoderKey = "decoder"; private static final String decoderKey = "decoder";
private static final String packetHandlerKey = "packet_handler"; private static final String packetHandlerKey = "packet_handler";
private static final String DATE_FORMAT = "yyyy_MM_dd_HH_mm_ss"; private static final String DATE_FORMAT = "yyyy_MM_dd_HH_mm_ss";
private static final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); private static final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
public static final String TEMP_FILE_EXTENSION = ".tmcpr"; private static PacketListener packetListener = null;
public static final String JSON_FILE_EXTENSION = ".json"; private static boolean isRecording = false;
public static final String ZIP_FILE_EXTENSION = ".mcpr";
private File currentFile; private File currentFile;
private String fileName; private String fileName;
private static PacketListener packetListener = null;
private static boolean isRecording = false;
public static boolean isRecording() { public static boolean isRecording() {
return isRecording; return isRecording;
} }
public static void insertPacket(Packet packet) { public static void insertPacket(Packet packet) {
if(!isRecording || packetListener == null) { if(!isRecording || packetListener == null) {
String reason = isRecording ? " (recording)":" (null)"; String reason = isRecording ? " (recording)" : " (null)";
System.out.println("Invalid attempt to insert Packet!"+reason); System.out.println("Invalid attempt to insert Packet!" + reason);
return; return;
} }
try { try {
packetListener.saveOnly(packet); packetListener.saveOnly(packet);
} catch (Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -61,8 +57,7 @@ public class ConnectionEventHandler {
public void onConnectedToServerEvent(ClientConnectedToServerEvent event) { public void onConnectedToServerEvent(ClientConnectedToServerEvent event) {
System.out.println("Connected to server"); System.out.println("Connected to server");
ChatMessageRequests.initialize(); ReplayMod.chatMessageHandler.initialize();
ReplayMod.recordingHandler.resetVars(); ReplayMod.recordingHandler.resetVars();
try { try {
@@ -80,7 +75,7 @@ public class ConnectionEventHandler {
NetworkManager nm = event.manager; NetworkManager nm = event.manager;
String worldName = ""; String worldName = "";
if(!event.isLocal) { if(!event.isLocal) {
worldName = ((InetSocketAddress)nm.getRemoteAddress()).getHostName(); worldName = ((InetSocketAddress) nm.getRemoteAddress()).getHostName();
} }
Channel channel = nm.channel(); Channel channel = nm.channel();
ChannelPipeline pipeline = channel.pipeline(); ChannelPipeline pipeline = channel.pipeline();
@@ -95,7 +90,7 @@ public class ConnectionEventHandler {
File folder = ReplayFileIO.getReplayFolder(); File folder = ReplayFileIO.getReplayFolder();
fileName = sdf.format(Calendar.getInstance().getTime()); fileName = sdf.format(Calendar.getInstance().getTime());
currentFile = new File(folder, fileName+TEMP_FILE_EXTENSION); currentFile = new File(folder, fileName + TEMP_FILE_EXTENSION);
currentFile.createNewFile(); currentFile.createNewFile();
@@ -103,7 +98,7 @@ public class ConnectionEventHandler {
pipeline.addBefore(packetHandlerKey, "replay_recorder", insert = new PacketListener pipeline.addBefore(packetHandlerKey, "replay_recorder", insert = new PacketListener
(currentFile, fileName, worldName, System.currentTimeMillis(), event.isLocal)); (currentFile, fileName, worldName, System.currentTimeMillis(), event.isLocal));
ChatMessageRequests.addChatMessage("Recording started!", ChatMessageType.INFORMATION); ReplayMod.chatMessageHandler.addChatMessage("Recording started!", ChatMessageType.INFORMATION);
isRecording = true; isRecording = true;
final PacketListener listener = insert; final PacketListener listener = insert;
@@ -123,7 +118,7 @@ public class ConnectionEventHandler {
} catch(Exception e) { } catch(Exception e) {
try { try {
Thread.sleep(100); Thread.sleep(100);
} catch (InterruptedException e1) { } catch(InterruptedException e1) {
e1.printStackTrace(); e1.printStackTrace();
} }
} }
@@ -136,7 +131,7 @@ public class ConnectionEventHandler {
packetListener = listener; packetListener = listener;
} catch(Exception e) { } catch(Exception e) {
ChatMessageRequests.addChatMessage("Failed to start recording!", ChatMessageType.WARNING); ReplayMod.chatMessageHandler.addChatMessage("Failed to start recording!", ChatMessageType.WARNING);
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -146,6 +141,6 @@ public class ConnectionEventHandler {
System.out.println("Disconnected from server"); System.out.println("Disconnected from server");
isRecording = false; isRecording = false;
packetListener = null; packetListener = null;
ChatMessageRequests.stop(); ReplayMod.chatMessageHandler.stop();
} }
} }

View File

@@ -1,33 +1,19 @@
package eu.crushedpixel.replaymod.recording; package eu.crushedpixel.replaymod.recording;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import com.google.gson.Gson; import com.google.gson.Gson;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.gui.GuiReplaySaving; import eu.crushedpixel.replaymod.gui.GuiReplaySaving;
import eu.crushedpixel.replaymod.holders.PacketData; import eu.crushedpixel.replaymod.holders.PacketData;
import eu.crushedpixel.replaymod.utils.ReplayFileIO; import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import net.minecraft.client.Minecraft;
import java.io.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
public abstract class DataListener extends ChannelInboundHandlerAdapter { public abstract class DataListener extends ChannelInboundHandlerAdapter {
@@ -35,23 +21,12 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
protected Long startTime = null; protected Long startTime = null;
protected String name; protected String name;
protected String worldName; protected String worldName;
private boolean singleplayer;
protected long lastSentPacket = 0; protected long lastSentPacket = 0;
protected boolean alive = true; protected boolean alive = true;
protected DataWriter dataWriter; protected DataWriter dataWriter;
private Gson gson = new Gson();
protected Set<String> players = new HashSet<String>(); protected Set<String> players = new HashSet<String>();
private boolean singleplayer;
public void setWorldName(String worldName) { private Gson gson = new Gson();
this.worldName = worldName;
System.out.println(worldName);
}
public DataListener(File file, String name, String worldName, long startTime, boolean singleplayer) throws FileNotFoundException { public DataListener(File file, String name, String worldName, long startTime, boolean singleplayer) throws FileNotFoundException {
this.file = file; this.file = file;
@@ -68,6 +43,11 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
dataWriter = new DataWriter(out); dataWriter = new DataWriter(out);
} }
public void setWorldName(String worldName) {
this.worldName = worldName;
System.out.println(worldName);
}
@Override @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception { public void channelInactive(ChannelHandlerContext ctx) throws Exception {
dataWriter.requestFinish(players); dataWriter.requestFinish(players);
@@ -78,11 +58,7 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
private boolean active = true; private boolean active = true;
private ConcurrentLinkedQueue<PacketData> queue = new ConcurrentLinkedQueue<PacketData>(); private ConcurrentLinkedQueue<PacketData> queue = new ConcurrentLinkedQueue<PacketData>();
private DataOutputStream stream;
public void writeData(PacketData data) {
queue.add(data);
}
Thread outputThread = new Thread(new Runnable() { Thread outputThread = new Thread(new Runnable() {
@Override @Override
@@ -110,7 +86,7 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
try { try {
//let the Thread sleep for 1/4 second and queue up new Packets //let the Thread sleep for 1/4 second and queue up new Packets
Thread.sleep(250L); Thread.sleep(250L);
} catch (InterruptedException e) { } catch(InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -119,24 +95,26 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
try { try {
stream.flush(); stream.flush();
stream.close(); stream.close();
} catch (Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
for(Entry<Class, Integer> entries : counts.entrySet()) { for(Entry<Class, Integer> entries : counts.entrySet()) {
System.out.println(entries.getKey()+ "| "+entries.getValue()); System.out.println(entries.getKey() + "| " + entries.getValue());
} }
} }
}); });
private DataOutputStream stream;
public DataWriter(DataOutputStream stream) { public DataWriter(DataOutputStream stream) {
this.stream = stream; this.stream = stream;
outputThread.start(); outputThread.start();
} }
public void writeData(PacketData data) {
queue.add(data);
}
public void requestFinish(Set<String> players) { public void requestFinish(Set<String> players) {
active = false; active = false;
@@ -151,12 +129,12 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
String[] pl = players.toArray(new String[players.size()]); String[] pl = players.toArray(new String[players.size()]);
ReplayMetaData metaData = new ReplayMetaData(singleplayer, worldName, (int)lastSentPacket, startTime, pl, mcversion); ReplayMetaData metaData = new ReplayMetaData(singleplayer, worldName, (int) lastSentPacket, startTime, pl, mcversion);
String json = gson.toJson(metaData); String json = gson.toJson(metaData);
File folder = ReplayFileIO.getReplayFolder(); File folder = ReplayFileIO.getReplayFolder();
File archive = new File(folder, name+ConnectionEventHandler.ZIP_FILE_EXTENSION); File archive = new File(folder, name + ConnectionEventHandler.ZIP_FILE_EXTENSION);
archive.createNewFile(); archive.createNewFile();
ReplayFileIO.writeReplayFile(archive, file, metaData); ReplayFileIO.writeReplayFile(archive, file, metaData);

View File

@@ -1,8 +1,15 @@
package eu.crushedpixel.replaymod.recording; package eu.crushedpixel.replaymod.recording;
import io.netty.buffer.ByteBuf; import eu.crushedpixel.replaymod.holders.PacketData;
import io.netty.buffer.Unpooled; import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.DataWatcher;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S0CPacketSpawnPlayer;
import net.minecraft.network.play.server.S0DPacketCollectItem;
import net.minecraft.network.play.server.S0FPacketSpawnMob;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -10,33 +17,34 @@ import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.UUID; import java.util.UUID;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.DataWatcher;
import net.minecraft.network.EnumPacketDirection;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S0CPacketSpawnPlayer;
import net.minecraft.network.play.server.S0DPacketCollectItem;
import net.minecraft.network.play.server.S0FPacketSpawnMob;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
import eu.crushedpixel.replaymod.holders.PacketData;
import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
public class PacketListener extends DataListener { public class PacketListener extends DataListener {
private static final Minecraft mc = Minecraft.getMinecraft();
private static Field spawnMobDataWatcher, spawnPlayerDataWatcher;
static {
try {
spawnMobDataWatcher = S0FPacketSpawnMob.class.getDeclaredField(MCPNames.field("field_149043_l"));
spawnMobDataWatcher.setAccessible(true);
spawnPlayerDataWatcher = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_148960_i"));
spawnPlayerDataWatcher.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
private ChannelHandlerContext context = null;
public PacketListener(File file, String name, String worldName, long startTime, boolean singleplayer) throws FileNotFoundException { public PacketListener(File file, String name, String worldName, long startTime, boolean singleplayer) throws FileNotFoundException {
super(file, name, worldName, startTime, singleplayer); super(file, name, worldName, startTime, singleplayer);
} }
private static final Minecraft mc = Minecraft.getMinecraft();
private ChannelHandlerContext context = null;
public void saveOnly(Packet packet) { public void saveOnly(Packet packet) {
try { try {
if(packet instanceof S0CPacketSpawnPlayer) { if(packet instanceof S0CPacketSpawnPlayer) {
UUID uuid = ((S0CPacketSpawnPlayer)packet).func_179819_c(); UUID uuid = ((S0CPacketSpawnPlayer) packet).func_179819_c();
players.add(uuid.toString()); players.add(uuid.toString());
} }
@@ -47,7 +55,6 @@ public class PacketListener extends DataListener {
} }
} }
@Override @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(ctx == null) { if(ctx == null) {
@@ -64,18 +71,18 @@ public class PacketListener extends DataListener {
} }
if(msg instanceof Packet) { if(msg instanceof Packet) {
try { try {
Packet packet = (Packet)msg; Packet packet = (Packet) msg;
if(packet instanceof S0DPacketCollectItem) { if(packet instanceof S0DPacketCollectItem) {
if(mc.thePlayer != null || if(mc.thePlayer != null ||
((S0DPacketCollectItem)packet).func_149353_d() == mc.thePlayer.getEntityId()) { ((S0DPacketCollectItem) packet).func_149353_d() == mc.thePlayer.getEntityId()) {
super.channelRead(ctx, msg); super.channelRead(ctx, msg);
return; return;
} }
} }
if(packet instanceof S0CPacketSpawnPlayer) { if(packet instanceof S0CPacketSpawnPlayer) {
UUID uuid = ((S0CPacketSpawnPlayer)packet).func_179819_c(); UUID uuid = ((S0CPacketSpawnPlayer) packet).func_179819_c();
players.add(uuid.toString()); players.add(uuid.toString());
} }
@@ -95,28 +102,14 @@ public class PacketListener extends DataListener {
lastSentPacket = pd.getTimestamp(); lastSentPacket = pd.getTimestamp();
} }
private static Field spawnMobDataWatcher, spawnPlayerDataWatcher;
static {
try {
spawnMobDataWatcher = S0FPacketSpawnMob.class.getDeclaredField(MCPNames.field("field_149043_l"));
spawnMobDataWatcher.setAccessible(true);
spawnPlayerDataWatcher = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_148960_i"));
spawnPlayerDataWatcher.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
private PacketData getPacketData(ChannelHandlerContext ctx, Packet packet) throws IOException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { private PacketData getPacketData(ChannelHandlerContext ctx, Packet packet) throws IOException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
if(startTime == null) startTime = System.currentTimeMillis(); if(startTime == null) startTime = System.currentTimeMillis();
int timestamp = (int)(System.currentTimeMillis() - startTime); int timestamp = (int) (System.currentTimeMillis() - startTime);
if(packet instanceof S0FPacketSpawnMob) { if(packet instanceof S0FPacketSpawnMob) {
DataWatcher l = (DataWatcher)spawnMobDataWatcher.get(packet); DataWatcher l = (DataWatcher) spawnMobDataWatcher.get(packet);
DataWatcher dw = new DataWatcher(null); DataWatcher dw = new DataWatcher(null);
if(l == null) { if(l == null) {
spawnMobDataWatcher.set(packet, dw); spawnMobDataWatcher.set(packet, dw);
@@ -124,7 +117,7 @@ public class PacketListener extends DataListener {
} }
if(packet instanceof S0CPacketSpawnPlayer) { if(packet instanceof S0CPacketSpawnPlayer) {
DataWatcher l = (DataWatcher)spawnPlayerDataWatcher.get(packet); DataWatcher l = (DataWatcher) spawnPlayerDataWatcher.get(packet);
DataWatcher dw = new DataWatcher(null); DataWatcher dw = new DataWatcher(null);
if(l == null) { if(l == null) {
spawnPlayerDataWatcher.set(packet, dw); spawnPlayerDataWatcher.set(packet, dw);

View File

@@ -3,50 +3,17 @@ package eu.crushedpixel.replaymod.recording;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import net.minecraft.network.*;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.EnumPacketDirection;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.S0CPacketSpawnPlayer;
import net.minecraft.util.MessageSerializer; import net.minecraft.util.MessageSerializer;
import java.io.IOException;
public class PacketSerializer extends MessageSerializer { public class PacketSerializer extends MessageSerializer {
public PacketSerializer(EnumPacketDirection direction) { public PacketSerializer(EnumPacketDirection direction) {
super(direction); super(direction);
} }
@Override
public void encode(ChannelHandlerContext ctx, Packet packet, ByteBuf byteBuf) throws IOException {
EnumConnectionState state = ((EnumConnectionState)ctx.channel().attr(NetworkManager.attrKeyConnectionState).get());
encode(state, packet, byteBuf);
}
public void encode(EnumConnectionState state, Packet packet, ByteBuf byteBuf) {
Integer integer = state.getPacketId(EnumPacketDirection.CLIENTBOUND, packet);
if (integer == null) {
return;
} else {
PacketBuffer packetbuffer = new PacketBuffer(byteBuf);
packetbuffer.writeVarIntToBuffer(integer.intValue());
try {
packet.writePacketData(packetbuffer);
}
catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
public static ByteBuf toByteBuf(byte[] bytes) throws IOException, ClassNotFoundException { public static ByteBuf toByteBuf(byte[] bytes) throws IOException, ClassNotFoundException {
ByteBuf bb; ByteBuf bb;
bb = Unpooled.buffer(bytes.length); bb = Unpooled.buffer(bytes.length);
@@ -55,5 +22,28 @@ public class PacketSerializer extends MessageSerializer {
return bb; return bb;
} }
@Override
public void encode(ChannelHandlerContext ctx, Packet packet, ByteBuf byteBuf) throws IOException {
EnumConnectionState state = ((EnumConnectionState) ctx.channel().attr(NetworkManager.attrKeyConnectionState).get());
encode(state, packet, byteBuf);
}
public void encode(EnumConnectionState state, Packet packet, ByteBuf byteBuf) {
Integer integer = state.getPacketId(EnumPacketDirection.CLIENTBOUND, packet);
if(integer == null) {
return;
} else {
PacketBuffer packetbuffer = new PacketBuffer(byteBuf);
packetbuffer.writeVarIntToBuffer(integer.intValue());
try {
packet.writePacketData(packetbuffer);
} catch(Throwable throwable) {
throwable.printStackTrace();
}
}
}
} }

View File

@@ -1,8 +1,5 @@
package eu.crushedpixel.replaymod.recording; package eu.crushedpixel.replaymod.recording;
import java.util.Date;
import java.util.List;
public class ReplayMetaData { public class ReplayMetaData {
private boolean singleplayer; private boolean singleplayer;
@@ -21,24 +18,31 @@ public class ReplayMetaData {
this.players = players; this.players = players;
this.mcversion = mcversion; this.mcversion = mcversion;
} }
public boolean isSingleplayer() { public boolean isSingleplayer() {
return singleplayer; return singleplayer;
} }
public String getServerName() { public String getServerName() {
return serverName; return serverName;
} }
public int getDuration() { public int getDuration() {
return duration; return duration;
} }
public void setDuration(int duration) { public void setDuration(int duration) {
this.duration = duration; this.duration = duration;
} }
public long getDate() { public long getDate() {
return date; return date;
} }
public String[] getPlayers() { public String[] getPlayers() {
return players; return players;
} }
public String getMCVersion() { public String getMCVersion() {
return mcversion; return mcversion;
} }

View File

@@ -1,24 +0,0 @@
package eu.crushedpixel.replaymod.reflection;
import java.lang.reflect.Field;
import net.minecraft.client.gui.GuiMainMenu;
public class MCPEnvironment {
boolean eclipse = true;
public MCPEnvironment() {
eclipse = true;
Class<? extends GuiMainMenu> clazz = GuiMainMenu.class;
try {
Field viewportTexture = clazz.getDeclaredField("viewportTexture");
} catch(Exception e) {
eclipse = false;
}
}
public boolean isMCPEnvironment() {
return eclipse;
}
}

View File

@@ -1,30 +1,24 @@
package eu.crushedpixel.replaymod.reflection; package eu.crushedpixel.replaymod.reflection;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.google.common.io.LineProcessor; import com.google.common.io.LineProcessor;
import net.minecraft.launchwrapper.Launch;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
/** /**
* <p>A helper class for working with obfuscated field names.</p> * <p>A helper class for working with obfuscated field names.</p>
* <p>In the development environment the mappings file will automatically loaded. You can provide the location of a custom mappings file by * <p>In the development environment the mappings file will automatically loaded. You can provide the location of a custom mappings file by
* providing the system property {@code sevencommons.mappingsFile}.</p> * providing the system property {@code sevencommons.mappingsFile}.</p>
*
* @author diesieben07 * @author diesieben07
* @author CrushedPixel * @author CrushedPixel
*/ */
@@ -32,12 +26,9 @@ public final class MCPNames {
private static final Map<String, String> fields; private static final Map<String, String> fields;
private static final Map<String, String> methods; private static final Map<String, String> methods;
public static final MCPEnvironment env = new MCPEnvironment();
static { static {
if (use()) { if(use()) {
String mappingsDir = "./../build/unpacked/mappings/";
InputStream fieldsIs = MCPNames.class.getClassLoader().getResourceAsStream("fields.csv"); InputStream fieldsIs = MCPNames.class.getClassLoader().getResourceAsStream("fields.csv");
InputStream methodsIs = MCPNames.class.getClassLoader().getResourceAsStream("methods.csv"); InputStream methodsIs = MCPNames.class.getClassLoader().getResourceAsStream("methods.csv");
@@ -51,21 +42,23 @@ public final class MCPNames {
/** /**
* <p>Whether the code is running in a development environment or not.</p> * <p>Whether the code is running in a development environment or not.</p>
*
* @return true if the code is running in development mode (use MCP instead of SRG names) * @return true if the code is running in development mode (use MCP instead of SRG names)
*/ */
public static boolean use() { public static boolean use() {
return env.isMCPEnvironment(); return (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
} }
/** /**
* <p>Get the correct name for the given SRG field based on the context.</p> * <p>Get the correct name for the given SRG field based on the context.</p>
*
* @param srg the SRG name for a field * @param srg the SRG name for a field
* @return the input if the code is running outside of development mode or the matching MCP name otherwise * @return the input if the code is running outside of development mode or the matching MCP name otherwise
*/ */
public static String field(String srg) { public static String field(String srg) {
if (use()) { if(use()) {
String mcp = fields.get(srg); String mcp = fields.get(srg);
if (mcp == null) { if(mcp == null) {
// no mapping // no mapping
return srg; return srg;
} }
@@ -77,13 +70,14 @@ public final class MCPNames {
/** /**
* <p>Get the correct name for the given SRG method based on the context.</p> * <p>Get the correct name for the given SRG method based on the context.</p>
*
* @param srg the SRG name for a method * @param srg the SRG name for a method
* @return the input if the code is running outside of development mode or the matching MCP name otherwise * @return the input if the code is running outside of development mode or the matching MCP name otherwise
*/ */
public static String method(String srg) { public static String method(String srg) {
if (use()) { if(use()) {
String mcp = methods.get(srg); String mcp = methods.get(srg);
if (mcp == null) { if(mcp == null) {
// no mapping // no mapping
return srg; return srg;
} }
@@ -105,8 +99,8 @@ public final class MCPNames {
} }
return fileParser.getResult(); return fileParser.getResult();
} catch (IOException e) { } catch(IOException e) {
throw new RuntimeException("Couldn't read SRG->MCP mappings", e); throw new RuntimeException("Could not read SRG->MCP mappings", e);
} }
} }
@@ -118,7 +112,7 @@ public final class MCPNames {
@Override @Override
public boolean processLine(String line) throws IOException { public boolean processLine(String line) throws IOException {
if (!foundFirst) { if(!foundFirst) {
foundFirst = true; foundFirst = true;
return true; return true;
} }
@@ -127,10 +121,10 @@ public final class MCPNames {
try { try {
String srg = splitted.next(); String srg = splitted.next();
String mcp = splitted.next(); String mcp = splitted.next();
if (!map.containsKey(srg)) { if(!map.containsKey(srg)) {
map.put(srg, mcp); map.put(srg, mcp);
} }
} catch (NoSuchElementException e) { } catch(NoSuchElementException e) {
throw new IOException("Invalid Mappings file!", e); throw new IOException("Invalid Mappings file!", e);
} }
@@ -143,125 +137,4 @@ public final class MCPNames {
} }
} }
public static final String M_SPAWN_BABY = "func_75388_i";
public static final String F_TARGET_MATE = "field_75391_e";
public static final String F_THE_ANIMAL = "field_75390_d";
public static final String M_CLONE_PLAYER = "func_71049_a";
public static final String M_CONVERT_TO_VILLAGER = "func_82232_p";
public static final String M_SET_WORLD_AND_RESOLUTION = "func_73872_a";
public static final String F_BUTTON_LIST = "field_73887_h";
public static final String F_TAG_LIST = "field_74747_a";
public static final String F_TAG_MAP = "field_74784_a";
public static final String F_FOV_MODIFIER_HAND_PREV = "field_78506_S";
public static final String F_FOV_MODIFIER_HAND = "field_78507_R";
public static final String F_TRACKED_ENTITY_IDS = "field_72794_c";
public static final String F_MAP_TEXTURE_OBJECTS = "field_110585_a";
public static final String F_MY_ENTITY = "field_73132_a";
public static final String M_TRY_START_WATCHING_THIS = "func_73117_b";
public static final String M_ON_UPDATE = "func_70071_h_";
public static final String M_UPDATE_ENTITY = "func_70316_g";
public static final String M_DETECT_AND_SEND_CHANGES = "func_75142_b";
public static final String F_IS_REMOTE = "field_72995_K";
public static final String F_WORLD_OBJ_TILEENTITY = "field_70331_k";
public static final String F_WORLD_OBJ_ENTITY = "field_70170_p";
public static final String F_TIMER = "field_71428_T";
public static final String F_PACKET_CLASS_TO_ID_MAP = "field_73291_a";
public static final String M_SEND_PACKET_TO_PLAYER = "func_72567_b";
public static final String M_REMOVE_ENTITY = "func_72900_e";
public static final String M_WRITE_ENTITY_TO_NBT = "func_70014_b";
public static final String M_READ_ENTITY_FROM_NBT = "func_70037_a";
public static final String M_WRITE_TO_NBT_TILEENTITY = "func_70310_b";
public static final String M_READ_FROM_NBT_TILEENTITY = "func_70307_a";
public static final String F_ITEM_DAMAGE = "field_77991_e";
public static final String M_REGISTER_EXT_PROPS = "registerExtendedProperties";
public static final String M_READ_PACKET_DATA = "func_73267_a";
public static final String M_WRITE_PACKET_DATA = "func_73273_a";
public static final String M_GET_PACKET_SIZE = "func_73284_a";
public static final String F_UNLOCALIZED_NAME_BLOCK = "field_71968_b";
public static final String M_SET_HAS_SUBTYPES = "func_77627_a";
public static final String F_ICON_STRING = "field_111218_cA";
public static final String F_UNLOCALIZED_NAME_ITEM = "field_77774_bZ";
public static final String F_TEXTURE_NAME_BLOCK = "field_111026_f";
public static final String M_ACTION_PERFORMED = "func_73875_a";
public static final String F_Z_LEVEL = "field_73735_i";
public static final String M_ADD_SLOT_TO_CONTAINER = "func_75146_a";
public static final String M_MERGE_ITEM_STACK = "func_75135_a";
public static final String F_CRAFTERS = "field_75149_d";
public static final String M_GET_ICON_STRING = "func_111208_A";
public static final String M_GET_TEXTURE_NAME = "func_111023_E";
public static final String M_NBT_WRITE = "func_74734_a";
public static final String M_NBT_LOAD = "func_74735_a";
public static final String F_NBT_STRING_DATA = "field_74751_a";
public static final String F_NBT_BYTE_DATA = "field_74756_a";
public static final String F_NBT_SHORT_DATA = "field_74752_a";
public static final String F_NBT_INT_DATA = "field_74748_a";
public static final String F_NBT_LONG_DATA = "field_74753_a";
public static final String F_NBT_FLOAT_DATA = "field_74750_a";
public static final String F_NBT_DOUBLE_DATA = "field_74755_a";
public static final String M_SET_TAG = "func_74782_a";
public static final String M_NBT_GET_ID = "func_74732_a";
public static final String M_ITEMSTACK_WRITE_NBT = "func_77955_b";
public static final String M_LOAD_ITEMSTACK_FROM_NBT = "func_77949_a";
public static final String M_ADD_CRAFTING_TO_CRAFTERS = "func_75132_a";
public static final String M_CHECK_HOTBAR_KEYS = "func_82319_a";
public static final String M_HANDLE_MOUSE_CLICK = "func_74191_a";
public static final String F_GUICONTAINER_THE_SLOT = "field_82320_o";
private MCPNames() { }
} }

View File

@@ -12,6 +12,9 @@ import java.util.concurrent.ConcurrentLinkedQueue;
public class FileCopyHandler extends Thread { public class FileCopyHandler extends Thread {
private Queue<Pair<File, File>> filesToMove = new ConcurrentLinkedQueue<Pair<File, File>>();
private boolean shutdown = false;
public FileCopyHandler() { public FileCopyHandler() {
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override @Override
@@ -21,8 +24,6 @@ public class FileCopyHandler extends Thread {
})); }));
} }
private Queue<Pair<File, File>> filesToMove = new ConcurrentLinkedQueue<Pair<File, File>>();
public void registerModifiedFile(File tempFile, File destination) { public void registerModifiedFile(File tempFile, File destination) {
filesToMove.add(Pair.of(tempFile, destination)); filesToMove.add(Pair.of(tempFile, destination));
@@ -37,8 +38,6 @@ public class FileCopyHandler extends Thread {
shutdown = true; shutdown = true;
} }
private boolean shutdown = false;
@Override @Override
public void run() { public void run() {
while(!shutdown || !filesToMove.isEmpty()) { while(!shutdown || !filesToMove.isEmpty()) {
@@ -52,7 +51,8 @@ public class FileCopyHandler extends Thread {
} }
try { try {
Thread.sleep(1000); Thread.sleep(1000);
} catch(Exception e) {} } catch(Exception e) {
}
} }
} }

View File

@@ -1,21 +1,19 @@
package eu.crushedpixel.replaymod.registry; package eu.crushedpixel.replaymod.registry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import org.lwjgl.input.Keyboard;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import org.lwjgl.input.Keyboard;
public class KeybindRegistry { public class KeybindRegistry {
private static Minecraft mc = Minecraft.getMinecraft();
public static final String KEY_LIGHTING = "Toggle Lighting"; public static final String KEY_LIGHTING = "Toggle Lighting";
public static final String KEY_THUMBNAIL = "Create Thumbnail"; public static final String KEY_THUMBNAIL = "Create Thumbnail";
public static final String KEY_SPECTATE = "Spectate Entity"; public static final String KEY_SPECTATE = "Spectate Entity";
private static Minecraft mc = Minecraft.getMinecraft();
public static void initialize() { public static void initialize() {
List<KeyBinding> bindings = new ArrayList<KeyBinding>(Arrays.asList(mc.gameSettings.keyBindings)); List<KeyBinding> bindings = new ArrayList<KeyBinding>(Arrays.asList(mc.gameSettings.keyBindings));

View File

@@ -1,10 +1,9 @@
package eu.crushedpixel.replaymod.registry; package eu.crushedpixel.replaymod.registry;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.timer.MCTimerHandler;
import net.minecraft.client.Minecraft; 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 eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.timer.MCTimerHandler;
public class LightingHandler { public class LightingHandler {
@@ -12,29 +11,26 @@ public class LightingHandler {
private static boolean enabled = false; private static boolean enabled = false;
public static void setInitialGamma(float gamma) { //TODO: Properly reset Gamma on game start
initialGamma = gamma; //TODO: Properly handle manual gamma changes while in Replay
}
public static void setLighting(boolean lighting) { public static void setLighting(boolean lighting) {
if(lighting) { if(lighting) {
if(!enabled) { if(!enabled) {
initialGamma = Minecraft.getMinecraft().gameSettings.getOptionFloatValue(Options.GAMMA); initialGamma = Minecraft.getMinecraft().gameSettings.getOptionFloatValue(Options.GAMMA);
} }
Minecraft.getMinecraft().gameSettings.setOptionFloatValue(Options.GAMMA, 1000); Minecraft.getMinecraft().gameSettings.setOptionFloatValue(Options.GAMMA, 1000);
} } else Minecraft.getMinecraft().gameSettings.setOptionFloatValue(Options.GAMMA, initialGamma);
else Minecraft.getMinecraft().gameSettings.setOptionFloatValue(Options.GAMMA, initialGamma);
enabled = lighting; enabled = lighting;
try { try {
if(ReplayHandler.isPaused()) { if(ReplayMod.replaySender.paused()) {
MCTimerHandler.advancePartialTicks(1); MCTimerHandler.advancePartialTicks(1);
MCTimerHandler.advanceRenderPartialTicks(1); MCTimerHandler.advanceRenderPartialTicks(1);
} else { } else {
Minecraft.getMinecraft().entityRenderer.updateCameraAndRender(0); Minecraft.getMinecraft().entityRenderer.updateCameraAndRender(0);
} }
} catch (Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@@ -1,30 +1,12 @@
package eu.crushedpixel.replaymod.registry; package eu.crushedpixel.replaymod.registry;
import java.lang.reflect.Field;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.network.play.server.S0CPacketSpawnPlayer;
import net.minecraftforge.client.GuiIngameForge; import net.minecraftforge.client.GuiIngameForge;
import eu.crushedpixel.replaymod.reflection.MCPNames;
public class ReplayGuiRegistry { public class ReplayGuiRegistry {
//private static Field renderHand;
private static Minecraft mc = Minecraft.getMinecraft();
public static boolean hidden = false; public static boolean hidden = false;
private static Minecraft mc = Minecraft.getMinecraft();
/*
static {
try {
//renderHand = EntityRenderer.class.getDeclaredField(MCPNames.field("field_175074_C"));
//renderHand.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
*/
public static void hide() { public static void hide() {
if(hidden) return; if(hidden) return;
@@ -42,14 +24,6 @@ public class ReplayGuiRegistry {
GuiIngameForge.renderJumpBar = false; GuiIngameForge.renderJumpBar = false;
GuiIngameForge.renderObjective = false; GuiIngameForge.renderObjective = false;
/*
try {
renderHand.set(mc.entityRenderer, false);
} catch(Exception e) {
e.printStackTrace();
}
*/
hidden = true; hidden = true;
} }
@@ -70,14 +44,6 @@ public class ReplayGuiRegistry {
GuiIngameForge.renderJumpBar = true; GuiIngameForge.renderJumpBar = true;
GuiIngameForge.renderObjective = true; GuiIngameForge.renderObjective = true;
/*
try {
renderHand.set(mc.entityRenderer, true);
} catch(Exception e) {
e.printStackTrace();
}
*/
hidden = false; hidden = false;
} }
} }

View File

@@ -1,15 +1,16 @@
package eu.crushedpixel.replaymod.renderer; package eu.crushedpixel.replaymod.renderer;
import java.lang.reflect.Field;
import eu.crushedpixel.replaymod.reflection.MCPNames; import eu.crushedpixel.replaymod.reflection.MCPNames;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManager;
import java.lang.reflect.Field;
public class SafeEntityRenderer extends EntityRenderer { public class SafeEntityRenderer extends EntityRenderer {
private static Field resourceManager; private static Field resourceManager;
static { static {
try { try {
resourceManager = EntityRenderer.class.getDeclaredField(MCPNames.field("field_147711_ac")); resourceManager = EntityRenderer.class.getDeclaredField(MCPNames.field("field_147711_ac"));
@@ -20,14 +21,15 @@ public class SafeEntityRenderer extends EntityRenderer {
} }
public SafeEntityRenderer(Minecraft mcIn, EntityRenderer renderer) throws IllegalArgumentException, IllegalAccessException { public SafeEntityRenderer(Minecraft mcIn, EntityRenderer renderer) throws IllegalArgumentException, IllegalAccessException {
super(mcIn, (IResourceManager)resourceManager.get(renderer)); super(mcIn, (IResourceManager) resourceManager.get(renderer));
} }
@Override @Override
public void updateCameraAndRender(float partialTicks) { public void updateCameraAndRender(float partialTicks) {
try { try {
super.updateCameraAndRender(partialTicks); super.updateCameraAndRender(partialTicks);
} catch(Exception e) {} //This is plain easier than doing proper error prevention. } catch(Exception e) {
} //This is plain easier than doing proper error prevention.
//If Johni reads this, don't think I'm a bad programmer... Just a lazy one :P //If Johni reads this, don't think I'm a bad programmer... Just a lazy one :P
} }
@@ -35,7 +37,8 @@ public class SafeEntityRenderer extends EntityRenderer {
public void updateRenderer() { public void updateRenderer() {
try { try {
super.updateRenderer(); super.updateRenderer();
} catch(Exception e) {} } catch(Exception e) {
}
} }
} }

View File

@@ -1,15 +1,17 @@
package eu.crushedpixel.replaymod.replay; package eu.crushedpixel.replaymod.replay;
import java.io.IOException;
import java.util.List;
import scala.actors.threadpool.Arrays;
import net.minecraft.entity.DataWatcher; import net.minecraft.entity.DataWatcher;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.Rotations; import net.minecraft.util.Rotations;
import java.io.IOException;
import java.util.List;
/**
* A Data Watcher which is applied to the Camera Entity to avoid both NPEs and the Screen constantly jittering (because of the entity being dead)
*/
public class LesserDataWatcher extends DataWatcher { public class LesserDataWatcher extends DataWatcher {
public LesserDataWatcher(Entity owner) { public LesserDataWatcher(Entity owner) {
@@ -100,6 +102,4 @@ public class LesserDataWatcher extends DataWatcher {
} }
} }

View File

@@ -1,8 +1,8 @@
package eu.crushedpixel.replaymod.replay; package eu.crushedpixel.replaymod.replay;
import net.minecraft.network.NetworkManager;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import net.minecraft.network.NetworkManager;
public class OpenEmbeddedChannel extends EmbeddedChannel { public class OpenEmbeddedChannel extends EmbeddedChannel {

View File

@@ -1,110 +0,0 @@
package eu.crushedpixel.replaymod.replay;
import gnu.trove.iterator.TIntObjectIterator;
import gnu.trove.map.TIntObjectMap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.EnumPacketDirection;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.MessageDeserializer;
import com.google.common.collect.BiMap;
import eu.crushedpixel.replaymod.reflection.MCPNames;
public class PacketDeserializer extends MessageDeserializer {
private final EnumPacketDirection direction;
private Field directionMaps;
private EnumConnectionState state;
public PacketDeserializer(EnumPacketDirection direction) {
super(direction);
this.direction = direction;
try {
directionMaps = EnumConnectionState.class.getDeclaredField(MCPNames.field("field_179247_h"));
directionMaps.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
public Packet getPacket(EnumPacketDirection direction, int packetId) throws InstantiationException, IllegalAccessException
{
Map map = ((Map)directionMaps.get(state));
BiMap biMap = ((BiMap)map.get(direction));
if(biMap == null) {
System.out.println("BiMap is null!");
}
Class oclass = (Class)biMap.get(Integer.valueOf(packetId));
return oclass == null ? null : (Packet)oclass.newInstance();
}
public void setEnumConnectionState(EnumConnectionState state) {
this.state = state;
}
@Override
public void decode(ChannelHandlerContext p_decode_1_,
ByteBuf p_decode_2_, List p_decode_3_) throws IOException,
InstantiationException, IllegalAccessException {
if (p_decode_2_.readableBytes() != 0)
{
PacketBuffer packetbuffer = new PacketBuffer(p_decode_2_);
int i = packetbuffer.readVarIntFromBuffer();
Field state_by_id = null;
try {
state_by_id = EnumConnectionState.class.getDeclaredField(MCPNames.field("field_150764_e"));
state_by_id.setAccessible(true);
state = (EnumConnectionState)((TIntObjectMap)state_by_id.get(null)).get(i);
TIntObjectMap map = (TIntObjectMap)state_by_id.get(null);
TIntObjectIterator it = map.iterator();
while(it.hasNext()) {
it.advance();
System.out.println(it.key() +" | "+it.value().getClass());
}
} catch(Exception e) {
e.printStackTrace();
}
if(state == null) {
System.out.println("state is null");
}
//Packet packet = getPacket(this.direction, i);
Packet packet = state.getPacket(EnumPacketDirection.CLIENTBOUND, i);
if (packet == null)
{
throw new IOException("Bad packet id " + i);
}
else
{
packet.readPacketData(packetbuffer);
if (packetbuffer.readableBytes() > 0)
{
throw new IOException("Packet " + ((EnumConnectionState)p_decode_1_.channel().attr(NetworkManager.attrKeyConnectionState).get()).getId() + "/" + i + " (" + packet.getClass().getSimpleName() + ") was larger than I expected, found " + packetbuffer.readableBytes() + " bytes extra whilst reading packet " + i);
}
else
{
p_decode_3_.add(packet);
}
}
}
}
}

View File

@@ -1,38 +0,0 @@
package eu.crushedpixel.replaymod.replay;
import net.minecraft.network.EnumConnectionState;
public class PacketInfo {
private byte[] bytes;
private EnumConnectionState connectionState;
private int packetID;
public PacketInfo(byte[] bytes, EnumConnectionState connectionState,
int packetID) {
super();
this.bytes = bytes;
this.connectionState = connectionState;
this.packetID = packetID;
}
public byte[] getBytes() {
return bytes;
}
public void setBytes(byte[] bytes) {
this.bytes = bytes;
}
public EnumConnectionState getConnectionState() {
return connectionState;
}
public void setConnectionState(EnumConnectionState connectionState) {
this.connectionState = connectionState;
}
public int getPacketID() {
return packetID;
}
public void setPacketID(int packetID) {
this.packetID = packetID;
}
}

View File

@@ -1,7 +1,17 @@
package eu.crushedpixel.replaymod.replay; package eu.crushedpixel.replaymod.replay;
import io.netty.channel.ChannelPipeline; import com.mojang.authlib.GameProfile;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.entities.CameraEntity;
import eu.crushedpixel.replaymod.holders.*;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
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;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@@ -9,67 +19,27 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.UUID; 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.Packet;
import net.minecraft.network.play.INetHandlerPlayClient;
import com.mojang.authlib.GameProfile;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
import eu.crushedpixel.replaymod.entities.CameraEntity;
import eu.crushedpixel.replaymod.holders.Keyframe;
import eu.crushedpixel.replaymod.holders.KeyframeComparator;
import eu.crushedpixel.replaymod.holders.Position;
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
public class ReplayHandler { public class ReplayHandler {
public static long lastExit = 0;
private static NetworkManager networkManager; private static NetworkManager networkManager;
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getMinecraft();
private static ReplaySender replaySender; //private static ReplaySender replaySender;
private static OpenEmbeddedChannel channel; private static OpenEmbeddedChannel channel;
private static int realTimelinePosition = 0; private static int realTimelinePosition = 0;
private static Keyframe selectedKeyframe; private static Keyframe selectedKeyframe;
private static boolean inPath = false; private static boolean inPath = false;
private static CameraEntity cameraEntity; private static CameraEntity cameraEntity;
private static List<Keyframe> keyframes = new ArrayList<Keyframe>(); private static List<Keyframe> keyframes = new ArrayList<Keyframe>();
private static boolean inReplay = false; private static boolean inReplay = false;
public static long lastExit = 0;
private static Entity currentEntity = null; private static Entity currentEntity = null;
private static Position lastPosition = null;
public static void insertPacketInstantly(Packet p) {
if(replaySender != null) {
try {
replaySender.channelRead(null, p);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void spectateEntity(Entity e) { public static void spectateEntity(Entity e) {
currentEntity = e; currentEntity = e;
mc.setRenderViewEntity(currentEntity); mc.setRenderViewEntity(currentEntity);
} }
public static Entity getSpectatedEntity() {
return currentEntity;
}
public static void spectateCamera() { public static void spectateCamera() {
if(currentEntity != null) { if(currentEntity != null) {
Position prev = new Position(currentEntity); Position prev = new Position(currentEntity);
@@ -83,18 +53,6 @@ public class ReplayHandler {
return currentEntity == cameraEntity; return currentEntity == cameraEntity;
} }
public static void setInPath(boolean replaying) {
inPath = replaying;
}
public static void resetToleratedTimestamp() {
if(replaySender != null) replaySender.resetToleratedTimeStamp();
}
public static void stopHurrying() {
if(replaySender != null) replaySender.stopHurrying();
}
public static void startPath(boolean save) { public static void startPath(boolean save) {
if(!ReplayHandler.isInPath()) ReplayProcess.startReplayProcess(save); if(!ReplayHandler.isInPath()) ReplayProcess.startReplayProcess(save);
} }
@@ -107,22 +65,18 @@ public class ReplayHandler {
return inPath; return inPath;
} }
public static void setCameraEntity(CameraEntity entity) { public static void setInPath(boolean replaying) {
if(entity == null) return; inPath = replaying;
cameraEntity = entity;
spectateCamera();
} }
public static CameraEntity getCameraEntity() { public static CameraEntity getCameraEntity() {
return cameraEntity; return cameraEntity;
} }
public static int getDesiredTimestamp() { public static void setCameraEntity(CameraEntity entity) {
return replaySender == null ? 0 : (int)replaySender.getDesiredTimestamp(); if(entity == null) return;
} cameraEntity = entity;
spectateCamera();
public static int getReplayTime() {
return replaySender == null ? 0 : (int)replaySender.currentTimeStamp();
} }
public static void sortKeyframes() { public static void sortKeyframes() {
@@ -181,15 +135,15 @@ public class ReplayHandler {
List<TimeKeyframe> found = new ArrayList<TimeKeyframe>(); List<TimeKeyframe> found = new ArrayList<TimeKeyframe>();
for(Keyframe kf : keyframes) { for(Keyframe kf : keyframes) {
if(!(kf instanceof TimeKeyframe)) continue; if(!(kf instanceof TimeKeyframe)) continue;
if(Math.abs(kf.getRealTimestamp()-realTime) <= tolerance) { if(Math.abs(kf.getRealTimestamp() - realTime) <= tolerance) {
found.add((TimeKeyframe)kf); found.add((TimeKeyframe) kf);
} }
} }
TimeKeyframe closest = null; TimeKeyframe closest = null;
for(TimeKeyframe kf : found) { for(TimeKeyframe kf : found) {
if(closest == null || Math.abs(closest.getTimestamp()-realTime) > Math.abs(kf.getRealTimestamp()-realTime)) { if(closest == null || Math.abs(closest.getTimestamp() - realTime) > Math.abs(kf.getRealTimestamp() - realTime)) {
closest = kf; closest = kf;
} }
} }
@@ -200,15 +154,15 @@ public class ReplayHandler {
List<PositionKeyframe> found = new ArrayList<PositionKeyframe>(); List<PositionKeyframe> found = new ArrayList<PositionKeyframe>();
for(Keyframe kf : keyframes) { for(Keyframe kf : keyframes) {
if(!(kf instanceof PositionKeyframe)) continue; if(!(kf instanceof PositionKeyframe)) continue;
if(Math.abs(kf.getRealTimestamp()-realTime) <= tolerance) { if(Math.abs(kf.getRealTimestamp() - realTime) <= tolerance) {
found.add((PositionKeyframe)kf); found.add((PositionKeyframe) kf);
} }
} }
PositionKeyframe closest = null; PositionKeyframe closest = null;
for(PositionKeyframe kf : found) { for(PositionKeyframe kf : found) {
if(closest == null || Math.abs(closest.getRealTimestamp()-realTime) > Math.abs(kf.getRealTimestamp()-realTime)) { if(closest == null || Math.abs(closest.getRealTimestamp() - realTime) > Math.abs(kf.getRealTimestamp() - realTime)) {
closest = kf; closest = kf;
} }
} }
@@ -221,12 +175,12 @@ public class ReplayHandler {
for(Keyframe kf : keyframes) { for(Keyframe kf : keyframes) {
if(!(kf instanceof PositionKeyframe)) continue; if(!(kf instanceof PositionKeyframe)) continue;
if(kf.getRealTimestamp() < realTime) { if(kf.getRealTimestamp() < realTime) {
found.add((PositionKeyframe)kf); found.add((PositionKeyframe) kf);
} }
} }
if(found.size() > 0) if(found.size() > 0)
return found.get(found.size()-1); //last element is nearest return found.get(found.size() - 1); //last element is nearest
else return null; else return null;
} }
@@ -235,7 +189,7 @@ public class ReplayHandler {
for(Keyframe kf : keyframes) { for(Keyframe kf : keyframes) {
if(!(kf instanceof PositionKeyframe)) continue; if(!(kf instanceof PositionKeyframe)) continue;
if(kf.getRealTimestamp() >= realTime) { if(kf.getRealTimestamp() >= realTime) {
return (PositionKeyframe)kf; //first found element is next return (PositionKeyframe) kf; //first found element is next
} }
} }
return null; return null;
@@ -247,12 +201,12 @@ public class ReplayHandler {
for(Keyframe kf : keyframes) { for(Keyframe kf : keyframes) {
if(!(kf instanceof TimeKeyframe)) continue; if(!(kf instanceof TimeKeyframe)) continue;
if(kf.getRealTimestamp() < realTime) { if(kf.getRealTimestamp() < realTime) {
found.add((TimeKeyframe)kf); found.add((TimeKeyframe) kf);
} }
} }
if(found.size() > 0) if(found.size() > 0)
return found.get(found.size()-1); //last element is nearest return found.get(found.size() - 1); //last element is nearest
else return null; else return null;
} }
@@ -261,7 +215,7 @@ public class ReplayHandler {
for(Keyframe kf : keyframes) { for(Keyframe kf : keyframes) {
if(!(kf instanceof TimeKeyframe)) continue; if(!(kf instanceof TimeKeyframe)) continue;
if(kf.getRealTimestamp() >= realTime) { if(kf.getRealTimestamp() >= realTime) {
return (TimeKeyframe)kf; //first found element is next return (TimeKeyframe) kf; //first found element is next
} }
} }
return null; return null;
@@ -277,27 +231,6 @@ public class ReplayHandler {
selectKeyframe(null); selectKeyframe(null);
} }
public static void setReplayTime(int pos) {
if(replaySender != null) {
replaySender.jumpToTime(pos);
}
}
public static boolean isHurrying() {
if(replaySender != null) {
return replaySender.isHurrying();
}
return false;
}
public static int getReplayLength() {
if(replaySender != null) {
return replaySender.replayLength();
}
return 1;
}
public static boolean isSelected(Keyframe kf) { public static boolean isSelected(Keyframe kf) {
return kf == selectedKeyframe; return kf == selectedKeyframe;
} }
@@ -311,48 +244,26 @@ public class ReplayHandler {
return inReplay; return inReplay;
} }
public static boolean isPaused() {
if(replaySender != null) {
return replaySender.paused();
}
return true;
}
public static void setSpeed(double d) {
if(replaySender != null) {
replaySender.setReplaySpeed(d);
}
}
public static double getSpeed() {
if(replaySender != null) {
return replaySender.getReplaySpeed();
}
return 0;
}
public static void startReplay(File file) throws NoSuchMethodException, SecurityException, NoSuchFieldException { public static void startReplay(File file) throws NoSuchMethodException, SecurityException, NoSuchFieldException {
ChatMessageRequests.initialize(); ReplayMod.chatMessageHandler.initialize();
mc.ingameGUI.getChatGUI().clearChatMessages(); mc.ingameGUI.getChatGUI().clearChatMessages();
resetKeyframes(); resetKeyframes();
if(replaySender != null) { ReplayMod.replaySender.terminateReplay();
replaySender.terminateReplay();
}
if(channel != null) { if(channel != null) {
channel.close(); channel.close();
} }
networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND); networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND);
INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, (GuiScreen)null, networkManager, new GameProfile(UUID.randomUUID(), "Player")); INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, (GuiScreen) null, networkManager, new GameProfile(UUID.randomUUID(), "Player"));
networkManager.setNetHandler(pc); networkManager.setNetHandler(pc);
channel = new OpenEmbeddedChannel(networkManager); channel = new OpenEmbeddedChannel(networkManager);
replaySender = new ReplaySender(file, networkManager); ReplayMod.replaySender = new ReplaySender(file, networkManager);
channel.pipeline().addFirst(replaySender); channel.pipeline().addFirst(ReplayMod.replaySender);
channel.pipeline().fireChannelActive(); channel.pipeline().fireChannelActive();
try { try {
@@ -366,7 +277,6 @@ public class ReplayHandler {
} }
public static void restartReplay() { public static void restartReplay() {
//mc.setRenderViewEntity(mc.thePlayer);
mc.ingameGUI.getChatGUI().clearChatMessages(); mc.ingameGUI.getChatGUI().clearChatMessages();
if(channel != null) { if(channel != null) {
@@ -374,16 +284,14 @@ public class ReplayHandler {
} }
networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND); networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND);
INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, (GuiScreen)null, networkManager, new GameProfile(UUID.randomUUID(), "Player")); INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, (GuiScreen) null, networkManager, new GameProfile(UUID.randomUUID(), "Player"));
networkManager.setNetHandler(pc); networkManager.setNetHandler(pc);
EmbeddedChannel channel = new OpenEmbeddedChannel(networkManager); EmbeddedChannel channel = new OpenEmbeddedChannel(networkManager);
channel.pipeline().addFirst(replaySender); channel.pipeline().addFirst(ReplayMod.replaySender);
channel.pipeline().fireChannelActive(); channel.pipeline().fireChannelActive();
ChannelPipeline pipeline = networkManager.channel().pipeline();
mc.addScheduledTask(new Runnable() { mc.addScheduledTask(new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -399,18 +307,12 @@ public class ReplayHandler {
} }
public static void endReplay() { public static void endReplay() {
if(replaySender != null) { if(ReplayMod.replaySender != null) {
replaySender.terminateReplay(); ReplayMod.replaySender.terminateReplay();
} }
resetKeyframes(); resetKeyframes();
/*
if(channel != null && channel.isOpen()) {
channel.close();
}
*/
inReplay = false; inReplay = false;
} }
@@ -426,18 +328,17 @@ public class ReplayHandler {
realTimelinePosition = pos; realTimelinePosition = pos;
} }
private static Position lastPosition = null;
public static void setLastPosition(Position position) {
lastPosition = position;
}
public static Position getLastPosition() { public static Position getLastPosition() {
return lastPosition; return lastPosition;
} }
public static void setLastPosition(Position position) {
lastPosition = position;
}
public static File getReplayFile() { public static File getReplayFile() {
if(replaySender != null) { if(ReplayMod.replaySender != null) {
return replaySender.getReplayFile(); return ReplayMod.replaySender.getReplayFile();
} }
return null; return null;
} }

View File

@@ -1,18 +1,7 @@
package eu.crushedpixel.replaymod.replay; package eu.crushedpixel.replaymod.replay;
import java.awt.image.BufferedImage;
import java.lang.reflect.Field;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiDownloadTerrain;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.ChunkRenderContainer;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.chunk.RenderChunk;
import net.minecraft.client.renderer.entity.RenderEntity;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests; import eu.crushedpixel.replaymod.chat.ChatMessageHandler.ChatMessageType;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
import eu.crushedpixel.replaymod.gui.GuiCancelRender; import eu.crushedpixel.replaymod.gui.GuiCancelRender;
import eu.crushedpixel.replaymod.holders.Keyframe; import eu.crushedpixel.replaymod.holders.Keyframe;
import eu.crushedpixel.replaymod.holders.Position; import eu.crushedpixel.replaymod.holders.Position;
@@ -21,11 +10,14 @@ import eu.crushedpixel.replaymod.holders.TimeKeyframe;
import eu.crushedpixel.replaymod.interpolation.LinearPoint; import eu.crushedpixel.replaymod.interpolation.LinearPoint;
import eu.crushedpixel.replaymod.interpolation.LinearTimestamp; import eu.crushedpixel.replaymod.interpolation.LinearTimestamp;
import eu.crushedpixel.replaymod.interpolation.SplinePoint; import eu.crushedpixel.replaymod.interpolation.SplinePoint;
import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.timer.EnchantmentTimer; import eu.crushedpixel.replaymod.timer.EnchantmentTimer;
import eu.crushedpixel.replaymod.timer.MCTimerHandler; import eu.crushedpixel.replaymod.timer.MCTimerHandler;
import eu.crushedpixel.replaymod.video.ScreenCapture; import eu.crushedpixel.replaymod.video.ScreenCapture;
import eu.crushedpixel.replaymod.video.VideoWriter; import eu.crushedpixel.replaymod.video.VideoWriter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.chunk.RenderChunk;
import java.awt.image.BufferedImage;
public class ReplayProcess { public class ReplayProcess {
@@ -51,6 +43,13 @@ public class ReplayProcess {
private static boolean calculated = false; private static boolean calculated = false;
private static boolean isVideoRecording = false; private static boolean isVideoRecording = false;
private static boolean blocked = false;
private static boolean deepBlock = false;
private static boolean requestFinish = false;
private static float lastPartialTicks, lastRenderPartialTicks;
private static int lastTicks;
private static boolean resetTimer = false;
private static boolean firstTime = false;
public static boolean isVideoRecording() { public static boolean isVideoRecording() {
return isVideoRecording; return isVideoRecording;
@@ -69,11 +68,11 @@ public class ReplayProcess {
calculated = false; calculated = false;
requestFinish = false; requestFinish = false;
ReplayHandler.resetToleratedTimestamp(); ReplayMod.replaySender.resetToleratedTimeStamp();
ChatMessageRequests.initialize(); ReplayMod.chatMessageHandler.initialize();
if(ReplayHandler.getPosKeyframeCount() < 2 && ReplayHandler.getTimeKeyframeCount() < 2) { if(ReplayHandler.getPosKeyframeCount() < 2 && ReplayHandler.getTimeKeyframeCount() < 2) {
ChatMessageRequests.addChatMessage("At least 2 position or time keyframes required!", ChatMessageType.WARNING); ReplayMod.chatMessageHandler.addChatMessage("At least 2 position or time keyframes required!", ChatMessageType.WARNING);
return; return;
} }
@@ -87,20 +86,20 @@ public class ReplayProcess {
linear = ReplayMod.replaySettings.isLinearMovement(); linear = ReplayMod.replaySettings.isLinearMovement();
ReplayHandler.sortKeyframes(); ReplayHandler.sortKeyframes();
ReplayHandler.setInPath(true); ReplayHandler.setInPath(true);
previousReplaySpeed = ReplayHandler.getSpeed(); previousReplaySpeed = ReplayMod.replaySender.getReplaySpeed();
EnchantmentTimer.resetRecordingTime(); EnchantmentTimer.resetRecordingTime();
TimeKeyframe tf = ReplayHandler.getNextTimeKeyframe(-1); TimeKeyframe tf = ReplayHandler.getNextTimeKeyframe(-1);
if(tf != null) { if(tf != null) {
int ts = tf.getTimestamp(); int ts = tf.getTimestamp();
if(ts < ReplayHandler.getReplayTime()) { if(ts < ReplayMod.replaySender.currentTimeStamp()) {
mc.displayGuiScreen(null); mc.displayGuiScreen(null);
} }
ReplayHandler.setReplayTime(ts); ReplayMod.replaySender.jumpToTime(ts);
} }
ChatMessageRequests.addChatMessage("Replay started!", ChatMessageType.INFORMATION); ReplayMod.chatMessageHandler.addChatMessage("Replay started!", ChatMessageType.INFORMATION);
if(isVideoRecording()) { if(isVideoRecording()) {
MCTimerHandler.setTimerSpeed(1f); MCTimerHandler.setTimerSpeed(1f);
@@ -110,25 +109,20 @@ public class ReplayProcess {
public static void stopReplayProcess(boolean finished) { public static void stopReplayProcess(boolean finished) {
if(!ReplayHandler.isInPath()) return; if(!ReplayHandler.isInPath()) return;
if(finished) ChatMessageRequests.addChatMessage("Replay finished!", ChatMessageType.INFORMATION); if(finished) ReplayMod.chatMessageHandler.addChatMessage("Replay finished!", ChatMessageType.INFORMATION);
else { else {
ChatMessageRequests.addChatMessage("Replay stopped!", ChatMessageType.INFORMATION); ReplayMod.chatMessageHandler.addChatMessage("Replay stopped!", ChatMessageType.INFORMATION);
if(isVideoRecording()) { if(isVideoRecording()) {
VideoWriter.abortRecording(); VideoWriter.abortRecording();
} }
} }
ReplayHandler.setInPath(false); ReplayHandler.setInPath(false);
ReplayHandler.stopHurrying(); ReplayMod.replaySender.stopHurrying();
MCTimerHandler.setActiveTimer(); MCTimerHandler.setActiveTimer();
ReplayHandler.setSpeed(previousReplaySpeed); ReplayMod.replaySender.setReplaySpeed(previousReplaySpeed);
ReplayHandler.setSpeed(0); ReplayMod.replaySender.setReplaySpeed(0);
} }
private static boolean blocked = false;
private static boolean deepBlock = false;
private static boolean requestFinish = false;
public static void unblockAndTick(boolean justCheck) { public static void unblockAndTick(boolean justCheck) {
if(!deepBlock) blocked = false; if(!deepBlock) blocked = false;
if(!blocked || !isVideoRecording()) if(!blocked || !isVideoRecording())
@@ -139,15 +133,8 @@ public class ReplayProcess {
pathTick(isVideoRecording(), justCheck); pathTick(isVideoRecording(), justCheck);
} }
private static float lastPartialTicks, lastRenderPartialTicks;
private static int lastTicks;
private static boolean resetTimer = false;
private static boolean firstTime = false;
private static void pathTick(boolean recording, boolean justCheck) { private static void pathTick(boolean recording, boolean justCheck) {
if(ReplayHandler.isHurrying()) { if(ReplayMod.replaySender.isHurrying()) {
lastRealTime = System.currentTimeMillis(); lastRealTime = System.currentTimeMillis();
return; return;
} }
@@ -160,7 +147,6 @@ public class ReplayProcess {
MCTimerHandler.setRenderPartialTicks(100); MCTimerHandler.setRenderPartialTicks(100);
MCTimerHandler.setPartialTicks(100); MCTimerHandler.setPartialTicks(100);
MCTimerHandler.setTicks(100); MCTimerHandler.setTicks(100);
System.out.println(ReplayHandler.getReplayTime());
} }
if(recording && ((ReplayMod.replaySettings.getWaitForChunks() && RenderChunk.renderChunksUpdated != 0) || mc.currentScreen instanceof GuiCancelRender)) { if(recording && ((ReplayMod.replaySettings.getWaitForChunks() && RenderChunk.renderChunksUpdated != 0) || mc.currentScreen instanceof GuiCancelRender)) {
@@ -172,8 +158,8 @@ public class ReplayProcess {
resetTimer = true; resetTimer = true;
} }
return; return;
} else if (recording && ReplayMod.replaySettings.getWaitForChunks()) { } else if(recording && ReplayMod.replaySettings.getWaitForChunks()) {
MCTimerHandler.setTimerSpeed((float)lastSpeed); MCTimerHandler.setTimerSpeed((float) lastSpeed);
//MCTimerHandler.setRenderPartialTicks(lastRenderPartialTicks); //MCTimerHandler.setRenderPartialTicks(lastRenderPartialTicks);
if(resetTimer) { if(resetTimer) {
MCTimerHandler.setPartialTicks(lastPartialTicks); MCTimerHandler.setPartialTicks(lastPartialTicks);
@@ -200,7 +186,7 @@ public class ReplayProcess {
motionSpline = new SplinePoint(); motionSpline = new SplinePoint();
for(Keyframe kf : ReplayHandler.getKeyframes()) { for(Keyframe kf : ReplayHandler.getKeyframes()) {
if(kf instanceof PositionKeyframe) { if(kf instanceof PositionKeyframe) {
PositionKeyframe pkf = (PositionKeyframe)kf; PositionKeyframe pkf = (PositionKeyframe) kf;
Position pos = pkf.getPosition(); Position pos = pkf.getPosition();
motionSpline.addPoint(pos); motionSpline.addPoint(pos);
} }
@@ -212,7 +198,7 @@ public class ReplayProcess {
motionLinear = new LinearPoint(); motionLinear = new LinearPoint();
for(Keyframe kf : ReplayHandler.getKeyframes()) { for(Keyframe kf : ReplayHandler.getKeyframes()) {
if(kf instanceof PositionKeyframe) { if(kf instanceof PositionKeyframe) {
PositionKeyframe pkf = (PositionKeyframe)kf; PositionKeyframe pkf = (PositionKeyframe) kf;
Position pos = pkf.getPosition(); Position pos = pkf.getPosition();
motionLinear.addPoint(pos); motionLinear.addPoint(pos);
} }
@@ -222,7 +208,7 @@ public class ReplayProcess {
timeLinear = new LinearTimestamp(); timeLinear = new LinearTimestamp();
for(Keyframe kf : ReplayHandler.getKeyframes()) { for(Keyframe kf : ReplayHandler.getKeyframes()) {
if(kf instanceof TimeKeyframe) { if(kf instanceof TimeKeyframe) {
timeLinear.addPoint(((TimeKeyframe)kf).getTimestamp()); timeLinear.addPoint(((TimeKeyframe) kf).getTimestamp());
} }
} }
} }
@@ -236,12 +222,12 @@ public class ReplayProcess {
long curTime = System.currentTimeMillis(); long curTime = System.currentTimeMillis();
long timeStep; long timeStep;
if(recording) { if(recording) {
timeStep = 1000/ReplayMod.replaySettings.getVideoFramerate(); timeStep = 1000 / ReplayMod.replaySettings.getVideoFramerate();
} else { } else {
timeStep = curTime - lastRealTime; timeStep = curTime - lastRealTime;
} }
int curRealReplayTime = (int)(lastRealReplayTime + timeStep); int curRealReplayTime = (int) (lastRealReplayTime + timeStep);
PositionKeyframe lastPos = ReplayHandler.getPreviousPositionKeyframe(curRealReplayTime); PositionKeyframe lastPos = ReplayHandler.getPreviousPositionKeyframe(curRealReplayTime);
PositionKeyframe nextPos = ReplayHandler.getNextPositionKeyframe(curRealReplayTime); PositionKeyframe nextPos = ReplayHandler.getNextPositionKeyframe(curRealReplayTime);
@@ -292,7 +278,8 @@ public class ReplayProcess {
if(!(nextTime == null || lastTime == null)) { if(!(nextTime == null || lastTime == null)) {
if(lastTimeStamp == nextTimeStamp) curSpeed = 0f; if(lastTimeStamp == nextTimeStamp) curSpeed = 0f;
else curSpeed = ((double)((nextTime.getTimestamp()-lastTime.getTimestamp())))/((double)((nextTimeStamp-lastTimeStamp))); else
curSpeed = ((double) ((nextTime.getTimestamp() - lastTime.getTimestamp()))) / ((double) ((nextTimeStamp - lastTimeStamp)));
} }
if(lastTimeStamp == nextTimeStamp) { if(lastTimeStamp == nextTimeStamp) {
@@ -304,17 +291,17 @@ public class ReplayProcess {
int currentPosDiff = nextPosStamp - lastPosStamp; int currentPosDiff = nextPosStamp - lastPosStamp;
int currentPos = curRealReplayTime - lastPosStamp; int currentPos = curRealReplayTime - lastPosStamp;
float currentPosStepPerc = (float)currentPos/(float)currentPosDiff; //The percentage of the travelled path between the current positions float currentPosStepPerc = (float) currentPos / (float) currentPosDiff; //The percentage of the travelled path between the current positions
if(Float.isInfinite(currentPosStepPerc)) currentPosStepPerc = 0; if(Float.isInfinite(currentPosStepPerc)) currentPosStepPerc = 0;
int currentTimeDiff = nextTimeStamp - lastTimeStamp; int currentTimeDiff = nextTimeStamp - lastTimeStamp;
int currentTime = curRealReplayTime - lastTimeStamp; int currentTime = curRealReplayTime - lastTimeStamp;
float currentTimeStepPerc = (float)currentTime/(float)currentTimeDiff; //The percentage of the travelled path between the current timestamps float currentTimeStepPerc = (float) currentTime / (float) currentTimeDiff; //The percentage of the travelled path between the current timestamps
if(Float.isInfinite(currentTimeStepPerc)) currentTimeStepPerc = 0; if(Float.isInfinite(currentTimeStepPerc)) currentTimeStepPerc = 0;
float splinePos = ((float)ReplayHandler.getKeyframeIndex(lastPos) + currentPosStepPerc)/(float)(posCount-1); float splinePos = ((float) ReplayHandler.getKeyframeIndex(lastPos) + currentPosStepPerc) / (float) (posCount - 1);
float timePos = ((float)ReplayHandler.getKeyframeIndex(lastTime) + currentTimeStepPerc)/(float)(timeCount-1); float timePos = ((float) ReplayHandler.getKeyframeIndex(lastTime) + currentTimeStepPerc) / (float) (timeCount - 1);
Position pos = null; Position pos = null;
if(posCount > 1) { if(posCount > 1) {
@@ -339,20 +326,21 @@ public class ReplayProcess {
} }
if(curSpeed > 0) { if(curSpeed > 0) {
ReplayHandler.setSpeed(curSpeed); ReplayMod.replaySender.setReplaySpeed(curSpeed);
lastSpeed = curSpeed; lastSpeed = curSpeed;
} }
if(recording) { if(recording) {
MCTimerHandler.updateTimer((1f/ReplayMod.replaySettings.getVideoFramerate())); MCTimerHandler.updateTimer((1f / ReplayMod.replaySettings.getVideoFramerate()));
EnchantmentTimer.increaseRecordingTime((1000/ReplayMod.replaySettings.getVideoFramerate())); EnchantmentTimer.increaseRecordingTime((1000 / ReplayMod.replaySettings.getVideoFramerate()));
} }
lastPartialTicks = MCTimerHandler.getPartialTicks(); lastPartialTicks = MCTimerHandler.getPartialTicks();
lastRenderPartialTicks = MCTimerHandler.getRenderTicks(); lastRenderPartialTicks = MCTimerHandler.getRenderTicks();
lastTicks = MCTimerHandler.getTicks(); lastTicks = MCTimerHandler.getTicks();
if(curTimestamp != null && curTimestamp != ReplayHandler.getDesiredTimestamp()) ReplayHandler.setReplayTime(curTimestamp); if(curTimestamp != null && curTimestamp != ReplayMod.replaySender.getDesiredTimestamp())
ReplayMod.replaySender.jumpToTime(curTimestamp);
//splinePos = (index of last entry + add) / total entries //splinePos = (index of last entry + add) / total entries

View File

@@ -1,66 +1,6 @@
package eu.crushedpixel.replaymod.replay; package eu.crushedpixel.replaymod.replay;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
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;
import java.net.URL;
import java.util.ArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiDownloadTerrain;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.resources.ResourcePackRepository;
import net.minecraft.entity.Entity;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S01PacketJoinGame;
import net.minecraft.network.play.server.S02PacketChat;
import net.minecraft.network.play.server.S03PacketTimeUpdate;
import net.minecraft.network.play.server.S06PacketUpdateHealth;
import net.minecraft.network.play.server.S07PacketRespawn;
import net.minecraft.network.play.server.S08PacketPlayerPosLook;
import net.minecraft.network.play.server.S0BPacketAnimation;
import net.minecraft.network.play.server.S0CPacketSpawnPlayer;
import net.minecraft.network.play.server.S1CPacketEntityMetadata;
import net.minecraft.network.play.server.S1DPacketEntityEffect;
import net.minecraft.network.play.server.S1FPacketSetExperience;
import net.minecraft.network.play.server.S28PacketEffect;
import net.minecraft.network.play.server.S29PacketSoundEffect;
import net.minecraft.network.play.server.S2APacketParticles;
import net.minecraft.network.play.server.S2BPacketChangeGameState;
import net.minecraft.network.play.server.S2DPacketOpenWindow;
import net.minecraft.network.play.server.S2EPacketCloseWindow;
import net.minecraft.network.play.server.S2FPacketSetSlot;
import net.minecraft.network.play.server.S30PacketWindowItems;
import net.minecraft.network.play.server.S36PacketSignEditorOpen;
import net.minecraft.network.play.server.S37PacketStatistics;
import net.minecraft.network.play.server.S38PacketPlayerListItem;
import net.minecraft.network.play.server.S39PacketPlayerAbilities;
import net.minecraft.network.play.server.S43PacketCamera;
import net.minecraft.network.play.server.S45PacketTitle;
import net.minecraft.network.play.server.S48PacketResourcePackSend;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.WorldSettings.GameType;
import net.minecraft.world.WorldType;
import net.minecraftforge.fml.client.FMLClientHandler;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import com.google.gson.Gson; import com.google.gson.Gson;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.entities.CameraEntity; import eu.crushedpixel.replaymod.entities.CameraEntity;
import eu.crushedpixel.replaymod.events.RecordingHandler; import eu.crushedpixel.replaymod.events.RecordingHandler;
@@ -69,181 +9,99 @@ import eu.crushedpixel.replaymod.holders.Position;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler; import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import eu.crushedpixel.replaymod.recording.ReplayMetaData; import eu.crushedpixel.replaymod.recording.ReplayMetaData;
import eu.crushedpixel.replaymod.reflection.MCPNames; import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.registry.LightingHandler;
import eu.crushedpixel.replaymod.timer.MCTimerHandler; import eu.crushedpixel.replaymod.timer.MCTimerHandler;
import eu.crushedpixel.replaymod.utils.ReplayFileIO; import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.resources.ResourcePackRepository;
import net.minecraft.entity.Entity;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.*;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.WorldSettings.GameType;
import net.minecraft.world.WorldType;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
@Sharable @Sharable
public class ReplaySender extends ChannelInboundHandlerAdapter { public class ReplaySender extends ChannelInboundHandlerAdapter {
private long currentTimeStamp; private static Field playerUUIDField;
private static Field gameProfileField;
static {
try {
playerUUIDField = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_179820_b"));
playerUUIDField.setAccessible(true);
gameProfileField = S38PacketPlayerListItem.AddPlayerData.class.getDeclaredField("field_179964_d");
gameProfileField.setAccessible(true);
//dataWatcherField = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_148960_i"));
//dataWatcherField.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
private int currentTimeStamp;
private boolean hurryToTimestamp; private boolean hurryToTimestamp;
private long desiredTimeStamp = -1; private long desiredTimeStamp = -1;
private long toleratedTimeStamp = -1; private long toleratedTimeStamp = -1;
private long lastTimeStamp, lastPacketSent; private long lastTimeStamp, lastPacketSent;
private boolean hasRestarted = false; private boolean hasRestarted = false;
private File replayFile; private File replayFile;
private boolean active = true; private boolean active = true;
private ZipFile archive; private ZipFile archive;
private DataInputStream dis; private DataInputStream dis;
private ChannelHandlerContext ctx = null; private ChannelHandlerContext ctx = null;
private boolean startFromBeginning = true; private boolean startFromBeginning = true;
private NetworkManager networkManager; private NetworkManager networkManager;
private boolean terminate = false; private boolean terminate = false;
private double replaySpeed = 1f; private double replaySpeed = 1f;
private boolean hasWorldLoaded = false; private boolean hasWorldLoaded = false;
private Field joinPacketEntityId, joinPacketWorldType, private Field joinPacketEntityId, joinPacketWorldType,
joinPacketDimension, joinPacketDifficulty, joinPacketMaxPlayers; joinPacketDimension, joinPacketDifficulty, joinPacketMaxPlayers;
private Field effectPacketEntityId; private Field effectPacketEntityId;
private Field metadataPacketEntityId, metadataPacketList; private Field metadataPacketEntityId, metadataPacketList;
private Field animationPacketEntityId; private Field animationPacketEntityId;
private Field entityDataWatcher; private Field entityDataWatcher;
private Field chatPacketPosition; private Field chatPacketPosition;
private Minecraft mc = Minecraft.getMinecraft(); private Minecraft mc = Minecraft.getMinecraft();
private long now = System.currentTimeMillis(); private long now = System.currentTimeMillis();
private int replayLength = 0; private int replayLength = 0;
private int actualID = -1; private int actualID = -1;
private EffectRenderer old = mc.effectRenderer; private EffectRenderer old = mc.effectRenderer;
private ZipArchiveEntry replayEntry; private ZipArchiveEntry replayEntry;
private ArrayList<Class> badPackets = new ArrayList<Class>() {
public boolean isHurrying() { {
return hurryToTimestamp; add(S28PacketEffect.class);
add(S2BPacketChangeGameState.class);
add(S06PacketUpdateHealth.class);
add(S2DPacketOpenWindow.class);
add(S2EPacketCloseWindow.class);
add(S2FPacketSetSlot.class);
add(S30PacketWindowItems.class);
add(S36PacketSignEditorOpen.class);
add(S37PacketStatistics.class);
add(S1FPacketSetExperience.class);
add(S43PacketCamera.class);
add(S39PacketPlayerAbilities.class);
} }
};
public long currentTimeStamp() { private boolean allowMovement = false;
return currentTimeStamp;
}
public int replayLength() {
return replayLength;
}
public void stopHurrying() {
hurryToTimestamp = false;
}
public void terminateReplay() {
terminate = true;
try {
channelInactive(ctx);
ctx.channel().pipeline().close();
} catch (Exception e) {
e.printStackTrace();
}
}
public long getDesiredTimestamp() {
return desiredTimeStamp;
}
public void resetToleratedTimeStamp() {
toleratedTimeStamp = -1;
}
public void jumpToTime(int millis) {
if(!(ReplayHandler.isInPath() && ReplayProcess.isVideoRecording())) setReplaySpeed(replaySpeed);
if((millis < currentTimeStamp && !isHurrying())) {
if(ReplayHandler.isInPath()) {
if(millis >= toleratedTimeStamp && toleratedTimeStamp >= 0) {
return;
}
}
startFromBeginning = true;
}
desiredTimeStamp = millis;
if(ReplayHandler.isInPath()) {
toleratedTimeStamp = millis;
}
hurryToTimestamp = true;
}
public void setReplaySpeed(final double d) {
if(d != 0) this.replaySpeed = d;
MCTimerHandler.setTimerSpeed((float)d);
}
public ReplaySender(final File replayFile, NetworkManager nm) {
try {
joinPacketEntityId = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149206_a"));
joinPacketEntityId.setAccessible(true);
joinPacketDifficulty = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149203_e"));
joinPacketDifficulty.setAccessible(true);
joinPacketDimension = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149202_d"));
joinPacketDimension.setAccessible(true);
joinPacketMaxPlayers = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149200_f"));
joinPacketMaxPlayers.setAccessible(true);
joinPacketWorldType = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149201_g"));
joinPacketWorldType.setAccessible(true);
effectPacketEntityId = S1DPacketEntityEffect.class.getDeclaredField(MCPNames.field("field_149434_a"));
effectPacketEntityId.setAccessible(true);
metadataPacketEntityId = S1CPacketEntityMetadata.class.getDeclaredField(MCPNames.field("field_149379_a"));
metadataPacketEntityId.setAccessible(true);
metadataPacketList = S1CPacketEntityMetadata.class.getDeclaredField(MCPNames.field("field_149378_b"));
metadataPacketList.setAccessible(true);
animationPacketEntityId = S0BPacketAnimation.class.getDeclaredField(MCPNames.field("field_148981_a"));
animationPacketEntityId.setAccessible(true);
entityDataWatcher = Entity.class.getDeclaredField(MCPNames.field("field_70180_af"));
entityDataWatcher.setAccessible(true);
chatPacketPosition = S02PacketChat.class.getDeclaredField(MCPNames.field("field_179842_b"));
chatPacketPosition.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
}
this.replayFile = replayFile;
this.networkManager = nm;
if(("."+FilenameUtils.getExtension(replayFile.getAbsolutePath())).equals(ConnectionEventHandler.ZIP_FILE_EXTENSION)) {
try {
archive = new ZipFile(replayFile);
replayEntry = archive.getEntry("recording"+ConnectionEventHandler.TEMP_FILE_EXTENSION);
ZipArchiveEntry metadata = archive.getEntry("metaData"+ConnectionEventHandler.JSON_FILE_EXTENSION);
InputStream is = archive.getInputStream(metadata);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String json = br.readLine();
ReplayMetaData metaData = new Gson().fromJson(json, ReplayMetaData.class);
this.replayLength = metaData.getDuration();
sender.start();
} catch(Exception e) {
e.printStackTrace();
}
}
}
private Thread sender = new Thread(new Runnable() { private Thread sender = new Thread(new Runnable() {
@Override @Override
@@ -294,10 +152,10 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
//System.out.println(currentTimeStamp); //System.out.println(currentTimeStamp);
if(!ReplayHandler.isInPath() && !hurryToTimestamp && hasWorldLoaded) { if(!ReplayHandler.isInPath() && !hurryToTimestamp && hasWorldLoaded) {
int timeWait = (int)Math.round((currentTimeStamp - lastTimeStamp)/replaySpeed); int timeWait = (int) Math.round((currentTimeStamp - lastTimeStamp) / replaySpeed);
long timeDiff = System.currentTimeMillis() - lastPacketSent; long timeDiff = System.currentTimeMillis() - lastPacketSent;
lastPacketSent = System.currentTimeMillis(); lastPacketSent = System.currentTimeMillis();
long timeToSleep = Math.max(0, timeWait-timeDiff); long timeToSleep = Math.max(0, timeWait - timeDiff);
Thread.sleep(timeToSleep); Thread.sleep(timeToSleep);
} }
@@ -345,38 +203,356 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
} }
}); });
private ArrayList<Class> badPackets = new ArrayList<Class>() { public ReplaySender(final File replayFile, NetworkManager nm) {
{ try {
add(S28PacketEffect.class); joinPacketEntityId = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149206_a"));
add(S2BPacketChangeGameState.class); joinPacketEntityId.setAccessible(true);
add(S06PacketUpdateHealth.class);
add(S2DPacketOpenWindow.class); joinPacketDifficulty = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149203_e"));
add(S2EPacketCloseWindow.class); joinPacketDifficulty.setAccessible(true);
add(S2FPacketSetSlot.class);
add(S30PacketWindowItems.class); joinPacketDimension = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149202_d"));
add(S36PacketSignEditorOpen.class); joinPacketDimension.setAccessible(true);
add(S37PacketStatistics.class);
add(S1FPacketSetExperience.class); joinPacketMaxPlayers = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149200_f"));
add(S43PacketCamera.class); joinPacketMaxPlayers.setAccessible(true);
add(S39PacketPlayerAbilities.class);
joinPacketWorldType = S01PacketJoinGame.class.getDeclaredField(MCPNames.field("field_149201_g"));
joinPacketWorldType.setAccessible(true);
effectPacketEntityId = S1DPacketEntityEffect.class.getDeclaredField(MCPNames.field("field_149434_a"));
effectPacketEntityId.setAccessible(true);
metadataPacketEntityId = S1CPacketEntityMetadata.class.getDeclaredField(MCPNames.field("field_149379_a"));
metadataPacketEntityId.setAccessible(true);
metadataPacketList = S1CPacketEntityMetadata.class.getDeclaredField(MCPNames.field("field_149378_b"));
metadataPacketList.setAccessible(true);
animationPacketEntityId = S0BPacketAnimation.class.getDeclaredField(MCPNames.field("field_148981_a"));
animationPacketEntityId.setAccessible(true);
entityDataWatcher = Entity.class.getDeclaredField(MCPNames.field("field_70180_af"));
entityDataWatcher.setAccessible(true);
chatPacketPosition = S02PacketChat.class.getDeclaredField(MCPNames.field("field_179842_b"));
chatPacketPosition.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
} }
};
private boolean allowMovement = false; this.replayFile = replayFile;
this.networkManager = nm;
if(("." + FilenameUtils.getExtension(replayFile.getAbsolutePath())).equals(ConnectionEventHandler.ZIP_FILE_EXTENSION)) {
try {
archive = new ZipFile(replayFile);
replayEntry = archive.getEntry("recording" + ConnectionEventHandler.TEMP_FILE_EXTENSION);
private static Field playerUUIDField; ZipArchiveEntry metadata = archive.getEntry("metaData" + ConnectionEventHandler.JSON_FILE_EXTENSION);
private static Field gameProfileField; InputStream is = archive.getInputStream(metadata);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String json = br.readLine();
ReplayMetaData metaData = new Gson().fromJson(json, ReplayMetaData.class);
this.replayLength = metaData.getDuration();
sender.start();
} catch(Exception e) {
e.printStackTrace();
}
}
}
public boolean isHurrying() {
return hurryToTimestamp;
}
public int currentTimeStamp() {
return currentTimeStamp;
}
public int replayLength() {
return replayLength;
}
public void stopHurrying() {
hurryToTimestamp = false;
}
public void terminateReplay() {
terminate = true;
try {
channelInactive(ctx);
ctx.channel().pipeline().close();
} catch(Exception e) {
e.printStackTrace();
}
}
public long getDesiredTimestamp() {
return desiredTimeStamp;
}
public void resetToleratedTimeStamp() {
toleratedTimeStamp = -1;
}
public void jumpToTime(int millis) {
if(!(ReplayHandler.isInPath() && ReplayProcess.isVideoRecording())) setReplaySpeed(replaySpeed);
if((millis < currentTimeStamp && !isHurrying())) {
if(ReplayHandler.isInPath()) {
if(millis >= toleratedTimeStamp && toleratedTimeStamp >= 0) {
return;
}
}
startFromBeginning = true;
}
desiredTimeStamp = millis;
if(ReplayHandler.isInPath()) {
toleratedTimeStamp = millis;
}
hurryToTimestamp = true;
}
//private static Field dataWatcherField; //private static Field dataWatcherField;
private static class ResourcePackCheck extends Thread { @Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
public ResourcePackCheck(String url, String hash) { throws Exception {
this.url = url; if(terminate) {
this.hash = hash; return;
} }
private String url, hash; if(ctx == null) {
ctx = this.ctx;
}
if(msg instanceof Packet) {
super.channelRead(ctx, msg);
return;
}
byte[] ba = (byte[]) msg;
try {
Packet p = ReplayFileIO.deserializePacket(ba);
if(p == null) return;
//If hurrying, ignore some packets, unless during Replay Path and *not* in initial hurry
if(hurryToTimestamp && (!ReplayHandler.isInPath() || (desiredTimeStamp - currentTimeStamp > 1000))) {
if(p instanceof S45PacketTitle ||
p instanceof S2APacketParticles) return;
}
if(p instanceof S29PacketSoundEffect && ReplayHandler.isInPath() && ReplayProcess.isVideoRecording()) {
return;
}
if(p instanceof S03PacketTimeUpdate) {
p = TimeHandler.getTimePacket((S03PacketTimeUpdate) p);
}
if(p instanceof S48PacketResourcePackSend) {
S48PacketResourcePackSend pa = (S48PacketResourcePackSend) p;
Thread t = new ResourcePackCheck(pa.func_179783_a(), pa.func_179784_b());
t.start();
return;
}
if(p instanceof S02PacketChat) {
byte pos = (Byte) chatPacketPosition.get(p);
if(pos == 1) { //Ignores command block output sent
return;
}
}
if(badPackets.contains(p.getClass())) return;
/*
if(p instanceof S0EPacketSpawnObject) {
if(mc.theWorld != null) {
List<EntityArrow> arrows = mc.theWorld.getEntities(EntityArrow.class, new Predicate<EntityArrow>() {
@Override
public boolean apply(EntityArrow input) {
return true;
}
});
if(arrows.size() > 20) {
System.out.println(currentTimeStamp);
}
}
}
*/
try {
if(p instanceof S1CPacketEntityMetadata) {
if((Integer) metadataPacketEntityId.get(p) == actualID) {
metadataPacketEntityId.set(p, RecordingHandler.entityID);
}
}
if(p instanceof S01PacketJoinGame) {
//System.out.println("FOUND JOIN PACKET");
allowMovement = true;
int entId = (Integer) joinPacketEntityId.get(p);
actualID = entId;
entId = Integer.MIN_VALUE + 9002;
int dimension = (Integer) joinPacketDimension.get(p);
EnumDifficulty difficulty = (EnumDifficulty) joinPacketDifficulty.get(p);
int maxPlayers = (Integer) joinPacketMaxPlayers.get(p);
WorldType worldType = (WorldType) joinPacketWorldType.get(p);
p = new S01PacketJoinGame(entId, GameType.SPECTATOR, false, dimension,
difficulty, maxPlayers, worldType, false);
}
if(p instanceof S07PacketRespawn) {
S07PacketRespawn respawn = (S07PacketRespawn) p;
p = new S07PacketRespawn(respawn.func_149082_c(),
respawn.func_149081_d(), respawn.func_149080_f(), GameType.SPECTATOR);
allowMovement = true;
}
/*
* Proof of concept for some nasty player manipulation ;)
String crPxl = "2cb08a5951f34e98bd0985d9747e80df";
String johni = "cd3d4be14ffc2f9db432db09e0cd254b";
if(p instanceof S38PacketPlayerListItem) {
S38PacketPlayerListItem pp = (S38PacketPlayerListItem)p;
if(((AddPlayerData)pp.func_179767_a().get(0)).func_179962_a().getId().toString().replace("-", "").equals(crPxl)) {
GameProfile johniGP = new GameProfile(UUID.fromString(johni.replaceAll(
"(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})",
"$1-$2-$3-$4-$5")), "Johni0702");
gameProfileField.set(pp.func_179767_a().get(0), johniGP);
//pp.func_179767_a().set(0, johniGP);
p = pp;
}
}
if(p instanceof S0CPacketSpawnPlayer) {
S0CPacketSpawnPlayer sp = (S0CPacketSpawnPlayer)p;
if(sp.func_179819_c().toString().replace("-", "").equals(crPxl)) {
playerUUIDField.set(sp, UUID.fromString(johni.replaceAll(
"(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})",
"$1-$2-$3-$4-$5")));
}
p = sp;
}
*/
/*
if(p instanceof S0CPacketSpawnPlayer) {
System.out.println(dataWatcherField.get(p));
System.out.println(((S0CPacketSpawnPlayer) p).func_148944_c());
}
*/
if(p instanceof S08PacketPlayerPosLook) {
if(!hasWorldLoaded) hasWorldLoaded = true;
final S08PacketPlayerPosLook ppl = (S08PacketPlayerPosLook) p;
if(ReplayHandler.isInPath() && !hurryToTimestamp) return;
CameraEntity cent = ReplayHandler.getCameraEntity();
if(cent != null) {
if(!allowMovement && !((Math.abs(cent.posX - ppl.func_148932_c()) > ReplayMod.TP_DISTANCE_LIMIT) ||
(Math.abs(cent.posZ - ppl.func_148933_e()) > ReplayMod.TP_DISTANCE_LIMIT))) {
return;
} else {
allowMovement = false;
}
}
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(mc.theWorld == null) {
try {
Thread.sleep(10);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
Entity ent = ReplayHandler.getCameraEntity();
if(ent == null || !(ent instanceof CameraEntity)) ent = new CameraEntity(mc.theWorld);
CameraEntity cent = (CameraEntity) ent;
cent.moveAbsolute(ppl.func_148932_c(), ppl.func_148928_d(), ppl.func_148933_e());
ReplayHandler.setCameraEntity(cent);
}
});
t.start();
}
if(p instanceof S43PacketCamera) {
return;
}
super.channelRead(ctx, p);
} catch(Exception e) {
System.out.println(p.getClass());
e.printStackTrace();
}
} catch(Exception e) {
e.printStackTrace();
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
this.ctx = ctx;
networkManager.channel().attr(networkManager.attrKeyConnectionState).set(EnumConnectionState.PLAY);
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
archive.close();
super.channelInactive(ctx);
}
public boolean paused() {
try {
return MCTimerHandler.getTimerSpeed() == 0;
} catch(Exception e) {
}
return true;
}
public double getReplaySpeed() {
if(!paused()) return replaySpeed;
else return 0;
}
public void setReplaySpeed(final double d) {
if(d != 0) this.replaySpeed = d;
MCTimerHandler.setTimerSpeed((float) d);
}
public File getReplayFile() {
return replayFile;
}
private static class ResourcePackCheck extends Thread {
private static Field serverResourcePackDirectory; private static Field serverResourcePackDirectory;
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getMinecraft();
@@ -391,29 +567,34 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
} }
} }
private String url, hash;
public ResourcePackCheck(String url, String hash) {
this.url = url;
this.hash = hash;
}
private File getServerResourcePackLocation(String url, String hash) throws IOException, IllegalArgumentException, IllegalAccessException { private File getServerResourcePackLocation(String url, String hash) throws IOException, IllegalArgumentException, IllegalAccessException {
String filename; String filename;
if (hash.matches("^[a-f0-9]{40}$")) { if(hash.matches("^[a-f0-9]{40}$")) {
filename = hash; filename = hash;
} else { } else {
filename = url.substring(url.lastIndexOf("/") + 1); filename = url.substring(url.lastIndexOf("/") + 1);
if (filename.contains("?")) if(filename.contains("?")) {
{
filename = filename.substring(0, filename.indexOf("?")); filename = filename.substring(0, filename.indexOf("?"));
} }
if (!filename.endsWith(".zip")) if(!filename.endsWith(".zip")) {
{
return null; return null;
} }
filename = "legacy_" + filename.replaceAll("\\W", ""); filename = "legacy_" + filename.replaceAll("\\W", "");
} }
File folder = (File)serverResourcePackDirectory.get(repo); File folder = (File) serverResourcePackDirectory.get(repo);
File rp = new File(folder, filename); File rp = new File(folder, filename);
return rp; return rp;
@@ -461,243 +642,4 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
} }
} }
static {
try {
playerUUIDField = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_179820_b"));
playerUUIDField.setAccessible(true);
gameProfileField = S38PacketPlayerListItem.AddPlayerData.class.getDeclaredField("field_179964_d");
gameProfileField.setAccessible(true);
//dataWatcherField = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_148960_i"));
//dataWatcherField.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
if(terminate) {
return;
}
if(ctx == null) {
ctx = this.ctx;
}
if(msg instanceof Packet) {
super.channelRead(ctx, msg);
return;
}
byte[] ba = (byte[])msg;
try {
Packet p = ReplayFileIO.deserializePacket(ba);
if(p == null) return;
//If hurrying, ignore some packets, unless during Replay Path and *not* in initial hurry
if(hurryToTimestamp && (!ReplayHandler.isInPath() || (desiredTimeStamp-currentTimeStamp > 1000))) {
if(p instanceof S45PacketTitle ||
p instanceof S2APacketParticles) return;
}
if(p instanceof S29PacketSoundEffect && ReplayHandler.isInPath() && ReplayProcess.isVideoRecording()) {
return;
}
if(p instanceof S03PacketTimeUpdate) {
p = TimeHandler.getTimePacket((S03PacketTimeUpdate)p);
}
if(p instanceof S48PacketResourcePackSend) {
S48PacketResourcePackSend pa = (S48PacketResourcePackSend)p;
Thread t = new ResourcePackCheck(pa.func_179783_a(), pa.func_179784_b());
t.start();
return;
}
if(p instanceof S02PacketChat) {
byte pos = (Byte)chatPacketPosition.get(p);
if(pos == 1) { //Ignores command block output sent
return;
}
}
if(badPackets.contains(p.getClass())) return;
/*
if(p instanceof S0EPacketSpawnObject) {
if(mc.theWorld != null) {
List<EntityArrow> arrows = mc.theWorld.getEntities(EntityArrow.class, new Predicate<EntityArrow>() {
@Override
public boolean apply(EntityArrow input) {
return true;
}
});
if(arrows.size() > 20) {
System.out.println(currentTimeStamp);
}
}
}
*/
try {
if(p instanceof S1CPacketEntityMetadata) {
if((Integer)metadataPacketEntityId.get(p) == actualID) {
metadataPacketEntityId.set(p, RecordingHandler.entityID);
}
}
if(p instanceof S01PacketJoinGame) {
//System.out.println("FOUND JOIN PACKET");
allowMovement = true;
int entId = (Integer)joinPacketEntityId.get(p);
actualID = entId;
entId = Integer.MIN_VALUE+9002;
int dimension = (Integer)joinPacketDimension.get(p);
EnumDifficulty difficulty = (EnumDifficulty)joinPacketDifficulty.get(p);
int maxPlayers = (Integer)joinPacketMaxPlayers.get(p);
WorldType worldType = (WorldType)joinPacketWorldType.get(p);
p = new S01PacketJoinGame(entId, GameType.SPECTATOR, false, dimension,
difficulty, maxPlayers, worldType, false);
}
if(p instanceof S07PacketRespawn) {
S07PacketRespawn respawn = (S07PacketRespawn)p;
p = new S07PacketRespawn(respawn.func_149082_c(),
respawn.func_149081_d(), respawn.func_149080_f(), GameType.SPECTATOR);
allowMovement = true;
}
/*
* Proof of concept for some nasty player manipulation ;)
String crPxl = "2cb08a5951f34e98bd0985d9747e80df";
String johni = "cd3d4be14ffc2f9db432db09e0cd254b";
if(p instanceof S38PacketPlayerListItem) {
S38PacketPlayerListItem pp = (S38PacketPlayerListItem)p;
if(((AddPlayerData)pp.func_179767_a().get(0)).func_179962_a().getId().toString().replace("-", "").equals(crPxl)) {
GameProfile johniGP = new GameProfile(UUID.fromString(johni.replaceAll(
"(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})",
"$1-$2-$3-$4-$5")), "Johni0702");
gameProfileField.set(pp.func_179767_a().get(0), johniGP);
//pp.func_179767_a().set(0, johniGP);
p = pp;
}
}
if(p instanceof S0CPacketSpawnPlayer) {
S0CPacketSpawnPlayer sp = (S0CPacketSpawnPlayer)p;
if(sp.func_179819_c().toString().replace("-", "").equals(crPxl)) {
playerUUIDField.set(sp, UUID.fromString(johni.replaceAll(
"(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})",
"$1-$2-$3-$4-$5")));
}
p = sp;
}
*/
/*
if(p instanceof S0CPacketSpawnPlayer) {
System.out.println(dataWatcherField.get(p));
System.out.println(((S0CPacketSpawnPlayer) p).func_148944_c());
}
*/
if(p instanceof S08PacketPlayerPosLook) {
if(!hasWorldLoaded) hasWorldLoaded = true;
final S08PacketPlayerPosLook ppl = (S08PacketPlayerPosLook)p;
if(ReplayHandler.isInPath() && !hurryToTimestamp) return;
CameraEntity cent = ReplayHandler.getCameraEntity();
if(cent != null) {
if(!allowMovement && !((Math.abs(cent.posX - ppl.func_148932_c()) > ReplayMod.TP_DISTANCE_LIMIT) ||
(Math.abs(cent.posZ - ppl.func_148933_e()) > ReplayMod.TP_DISTANCE_LIMIT))) {
return;
} else {
allowMovement = false;
}
}
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(mc.theWorld == null) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Entity ent = ReplayHandler.getCameraEntity();
if(ent == null || !(ent instanceof CameraEntity)) ent = new CameraEntity(mc.theWorld);
CameraEntity cent = (CameraEntity)ent;
cent.moveAbsolute(ppl.func_148932_c(), ppl.func_148928_d(), ppl.func_148933_e());
ReplayHandler.setCameraEntity(cent);
}
});
t.start();
}
if(p instanceof S43PacketCamera) {
return;
}
super.channelRead(ctx, p);
} catch(Exception e) {
System.out.println(p.getClass());
e.printStackTrace();
}
} catch(Exception e) {
e.printStackTrace();
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
this.ctx = ctx;
networkManager.channel().attr(networkManager.attrKeyConnectionState).set(EnumConnectionState.PLAY);
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
archive.close();
super.channelInactive(ctx);
}
public boolean paused() {
try {
return MCTimerHandler.getTimerSpeed() == 0;
} catch(Exception e) {}
return true;
}
public double getReplaySpeed() {
if(!paused()) return replaySpeed;
else return 0;
}
public File getReplayFile() {
return replayFile;
}
} }

View File

@@ -13,14 +13,14 @@ public class TimeHandler {
return timeOverridden; return timeOverridden;
} }
public static void setDesiredDaytime(long ddt) {
desiredDaytime = ddt;
}
public static void setTimeOverridden(boolean overridden) { public static void setTimeOverridden(boolean overridden) {
timeOverridden = overridden; timeOverridden = overridden;
} }
public static void setDesiredDaytime(long ddt) {
desiredDaytime = ddt;
}
public static S03PacketTimeUpdate getTimePacket(S03PacketTimeUpdate packet) { public static S03PacketTimeUpdate getTimePacket(S03PacketTimeUpdate packet) {
if(!timeOverridden) return packet; if(!timeOverridden) return packet;
return new S03PacketTimeUpdate(packet.func_149366_c(), desiredDaytime, true); return new S03PacketTimeUpdate(packet.func_149366_c(), desiredDaytime, true);

View File

@@ -1,15 +1,13 @@
package eu.crushedpixel.replaymod.replay.spectate; 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 com.google.common.base.Predicate;
import eu.crushedpixel.replaymod.entities.CameraEntity; import eu.crushedpixel.replaymod.entities.CameraEntity;
import eu.crushedpixel.replaymod.gui.GuiSpectateSelection; import eu.crushedpixel.replaymod.gui.GuiSpectateSelection;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import java.util.List;
public class SpectateHandler { public class SpectateHandler {

View File

@@ -1,99 +1,16 @@
package eu.crushedpixel.replaymod.settings; package eu.crushedpixel.replaymod.settings;
import java.lang.reflect.Field; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.registry.LightingHandler;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
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.registry.LightingHandler;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
public class ReplaySettings { public class ReplaySettings {
public static interface ValueEnum {
public Object getValue();
public void setValue(Object value);
}
public enum RecordingOptions implements ValueEnum {
recordServer(true), recordSingleplayer(true), notifications(true), indicator(true);
private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
RecordingOptions(Object value) {
this.value = value;
}
}
public enum ReplayOptions implements ValueEnum {
linear(false), lighting(false), useResources(true);
private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
ReplayOptions(Object value) {
this.value = value;
}
}
public enum RenderOptions implements ValueEnum {
videoQuality(0.5f), videoFramerate(30), waitForChunks(true);
private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
RenderOptions(Object value) {
this.value = value;
}
}
public enum AdvancedOptions implements ValueEnum {
recordingPath("./replay_recordings/"), renderPath("./replay_videos/");
private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
AdvancedOptions(Object value) {
this.value = value;
}
}
public List<ValueEnum> getValueEnums() { public List<ValueEnum> getValueEnums() {
List<ValueEnum> enums = new ArrayList<ReplaySettings.ValueEnum>(); List<ValueEnum> enums = new ArrayList<ReplaySettings.ValueEnum>();
enums.addAll(Arrays.asList(ReplayOptions.values())); enums.addAll(Arrays.asList(ReplayOptions.values()));
@@ -128,77 +45,78 @@ public class ReplaySettings {
} }
public String getRecordingPath() { public String getRecordingPath() {
return (String)AdvancedOptions.recordingPath.getValue(); return (String) AdvancedOptions.recordingPath.getValue();
} }
public String getRenderPath() { public String getRenderPath() {
return (String)AdvancedOptions.renderPath.getValue(); return (String) AdvancedOptions.renderPath.getValue();
} }
public int getVideoFramerate() { public int getVideoFramerate() {
return (Integer)RenderOptions.videoFramerate.getValue(); return (Integer) RenderOptions.videoFramerate.getValue();
} }
public void setVideoFramerate(int framerate) { public void setVideoFramerate(int framerate) {
RenderOptions.videoFramerate.setValue(Math.min(120, Math.max(10, framerate))); RenderOptions.videoFramerate.setValue(Math.min(120, Math.max(10, framerate)));
rewriteSettings(); rewriteSettings();
} }
public double getVideoQuality() { public double getVideoQuality() {
return (Double)RenderOptions.videoQuality.getValue(); return (Double) RenderOptions.videoQuality.getValue();
}
public void setEnableIndicator(boolean enable) {
RecordingOptions.indicator.setValue(enable);
rewriteSettings();
}
public boolean showRecordingIndicator() {
return (Boolean)RecordingOptions.indicator.getValue();
} }
public void setVideoQuality(double videoQuality) { public void setVideoQuality(double videoQuality) {
RenderOptions.videoQuality.setValue(Math.min(0.9f, Math.max(0.1f, videoQuality))); RenderOptions.videoQuality.setValue(Math.min(0.9f, Math.max(0.1f, videoQuality)));
rewriteSettings(); rewriteSettings();
} }
public boolean isEnableRecordingServer() {
return (Boolean)RecordingOptions.recordServer.getValue(); public void setEnableIndicator(boolean enable) {
RecordingOptions.indicator.setValue(enable);
rewriteSettings();
} }
public boolean showRecordingIndicator() {
return (Boolean) RecordingOptions.indicator.getValue();
}
public boolean isEnableRecordingServer() {
return (Boolean) RecordingOptions.recordServer.getValue();
}
public void setEnableRecordingServer(boolean enableRecordingServer) { public void setEnableRecordingServer(boolean enableRecordingServer) {
RecordingOptions.recordServer.setValue(enableRecordingServer); RecordingOptions.recordServer.setValue(enableRecordingServer);
rewriteSettings(); rewriteSettings();
} }
public boolean isEnableRecordingSingleplayer() { public boolean isEnableRecordingSingleplayer() {
return (Boolean)RecordingOptions.recordSingleplayer.getValue(); return (Boolean) RecordingOptions.recordSingleplayer.getValue();
} }
public void setEnableRecordingSingleplayer(boolean enableRecordingSingleplayer) { public void setEnableRecordingSingleplayer(boolean enableRecordingSingleplayer) {
RecordingOptions.recordSingleplayer.setValue(enableRecordingSingleplayer); RecordingOptions.recordSingleplayer.setValue(enableRecordingSingleplayer);
rewriteSettings(); rewriteSettings();
} }
public boolean isShowNotifications() { public boolean isShowNotifications() {
return (Boolean)RecordingOptions.notifications.getValue(); return (Boolean) RecordingOptions.notifications.getValue();
} }
public void setShowNotifications(boolean showNotifications) { public void setShowNotifications(boolean showNotifications) {
RecordingOptions.notifications.setValue(showNotifications); RecordingOptions.notifications.setValue(showNotifications);
rewriteSettings(); rewriteSettings();
} }
public boolean isLinearMovement() { public boolean isLinearMovement() {
return (Boolean)ReplayOptions.linear.getValue(); return (Boolean) ReplayOptions.linear.getValue();
} }
public void setLinearMovement(boolean linear) { public void setLinearMovement(boolean linear) {
ReplayOptions.linear.setValue(linear); ReplayOptions.linear.setValue(linear);
rewriteSettings(); rewriteSettings();
} }
public boolean isLightingEnabled() { public boolean isLightingEnabled() {
return (Boolean)ReplayOptions.lighting.getValue(); return (Boolean) ReplayOptions.lighting.getValue();
}
public void setUseResourcePacks(boolean use) {
ReplayOptions.useResources.setValue(use);
rewriteSettings();
}
public boolean getUseResourcePacks() {
return (Boolean)ReplayOptions.useResources.getValue();
}
public void setWaitForChunks(boolean wait) {
RenderOptions.waitForChunks.setValue(wait);
rewriteSettings();
}
public boolean getWaitForChunks() {
return (Boolean)RenderOptions.waitForChunks.getValue();
} }
public void setLightingEnabled(boolean enabled) { public void setLightingEnabled(boolean enabled) {
@@ -207,6 +125,24 @@ public class ReplaySettings {
rewriteSettings(); rewriteSettings();
} }
public boolean getUseResourcePacks() {
return (Boolean) ReplayOptions.useResources.getValue();
}
public void setUseResourcePacks(boolean use) {
ReplayOptions.useResources.setValue(use);
rewriteSettings();
}
public boolean getWaitForChunks() {
return (Boolean) RenderOptions.waitForChunks.getValue();
}
public void setWaitForChunks(boolean wait) {
RenderOptions.waitForChunks.setValue(wait);
rewriteSettings();
}
public void rewriteSettings() { public void rewriteSettings() {
ReplayMod.instance.config.load(); ReplayMod.instance.config.load();
@@ -237,31 +173,32 @@ public class ReplaySettings {
if(warning) { if(warning) {
String warningMsg = "Please be careful when modifying this setting, as setting it to an invalid value might harm your computer."; String warningMsg = "Please be careful when modifying this setting, as setting it to an invalid value might harm your computer.";
if(value instanceof Integer) { if(value instanceof Integer) {
return config.get(category, name, (Integer)value, warningMsg); return config.get(category, name, (Integer) value, warningMsg);
} else if(value instanceof Boolean) { } else if(value instanceof Boolean) {
return config.get(category, name, (Boolean)value, warningMsg); return config.get(category, name, (Boolean) value, warningMsg);
} else if(value instanceof Double) { } else if(value instanceof Double) {
return config.get(category, name, (Double)value, warningMsg); return config.get(category, name, (Double) value, warningMsg);
} else if(value instanceof Float) { } else if(value instanceof Float) {
return config.get(category, name, (double)(Float)value, warningMsg); return config.get(category, name, (double) (Float) value, warningMsg);
} else if(value instanceof String) { } else if(value instanceof String) {
return config.get(category, name, (String)value, warningMsg); return config.get(category, name, (String) value, warningMsg);
} }
} else { } else {
if(value instanceof Integer) { if(value instanceof Integer) {
return config.get(category, name, (Integer)value); return config.get(category, name, (Integer) value);
} else if(value instanceof Boolean) { } else if(value instanceof Boolean) {
return config.get(category, name, (Boolean)value); return config.get(category, name, (Boolean) value);
} else if(value instanceof Double) { } else if(value instanceof Double) {
return config.get(category, name, (Double)value); return config.get(category, name, (Double) value);
} else if(value instanceof Float) { } else if(value instanceof Float) {
return config.get(category, name, (double)(Float)value); return config.get(category, name, (double) (Float) value);
} else if(value instanceof String) { } else if(value instanceof String) {
return config.get(category, name, (String)value); return config.get(category, name, (String) value);
} }
} }
return null; return null;
} }
private Object getValueObject(Property p) { private Object getValueObject(Property p) {
if(p.isIntValue()) { if(p.isIntValue()) {
return p.getInt(); return p.getInt();
@@ -273,4 +210,82 @@ public class ReplaySettings {
return p.getString(); return p.getString();
} }
} }
public enum RecordingOptions implements ValueEnum {
recordServer(true), recordSingleplayer(true), notifications(true), indicator(true);
private Object value;
RecordingOptions(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
public enum ReplayOptions implements ValueEnum {
linear(false), lighting(false), useResources(true);
private Object value;
ReplayOptions(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
public enum RenderOptions implements ValueEnum {
videoQuality(0.5f), videoFramerate(30), waitForChunks(true);
private Object value;
RenderOptions(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
public enum AdvancedOptions implements ValueEnum {
recordingPath("./replay_recordings/"), renderPath("./replay_videos/");
private Object value;
AdvancedOptions(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
public static interface ValueEnum {
public Object getValue();
public void setValue(Object value);
}
} }

View File

@@ -1,13 +1,6 @@
package eu.crushedpixel.replaymod.studio; package eu.crushedpixel.replaymod.studio;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import de.johni0702.replaystudio.PacketData; import de.johni0702.replaystudio.PacketData;
import de.johni0702.replaystudio.filter.ChangeTimestampFilter; import de.johni0702.replaystudio.filter.ChangeTimestampFilter;
import de.johni0702.replaystudio.filter.RemoveFilter; import de.johni0702.replaystudio.filter.RemoveFilter;
@@ -18,6 +11,12 @@ import de.johni0702.replaystudio.studio.ReplayStudio;
import eu.crushedpixel.replaymod.recording.ReplayMetaData; import eu.crushedpixel.replaymod.recording.ReplayMetaData;
import eu.crushedpixel.replaymod.utils.ReplayFileIO; import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
public class StudioImplementation { public class StudioImplementation {
public static void trimReplay(File replayFile, boolean isTmcpr, int beginning, int ending, File outputFile) throws IOException { public static void trimReplay(File replayFile, boolean isTmcpr, int beginning, int ending, File outputFile) throws IOException {
@@ -52,13 +51,14 @@ public class StudioImplementation {
ReplayMetaData metaData = ReplayFileIO.getMetaData(replayFile); ReplayMetaData metaData = ReplayFileIO.getMetaData(replayFile);
ending = Math.min(metaData.getDuration(), ending); ending = Math.min(metaData.getDuration(), ending);
metaData.setDuration(ending-beginning); metaData.setDuration(ending - beginning);
outputFile.createNewFile(); outputFile.createNewFile();
ReplayFileIO.writeReplayFile(outputFile, temp, metaData); ReplayFileIO.writeReplayFile(outputFile, temp, metaData);
} }
//TODO Work with Johni to connect multiple Replay Files
public static void connectReplayFiles(List<File> filesToConnect, File outputFile) { public static void connectReplayFiles(List<File> filesToConnect, File outputFile) {
} }

View File

@@ -1,5 +1,6 @@
package eu.crushedpixel.replaymod.timer; package eu.crushedpixel.replaymod.timer;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.replay.ReplayProcess; import eu.crushedpixel.replaymod.replay.ReplayProcess;
@@ -22,8 +23,8 @@ public class EnchantmentTimer {
if(!(ReplayHandler.isInPath() && ReplayProcess.isVideoRecording())) { if(!(ReplayHandler.isInPath() && ReplayProcess.isVideoRecording())) {
if(ReplayHandler.isInReplay()) { if(ReplayHandler.isInReplay()) {
long timeDiff = System.currentTimeMillis() - lastRealTime; long timeDiff = System.currentTimeMillis() - lastRealTime;
double toAdd = timeDiff*ReplayHandler.getSpeed(); double toAdd = timeDiff * ReplayMod.replaySender.getReplaySpeed();
lastFakeTime = Math.round(lastFakeTime+toAdd); lastFakeTime = Math.round(lastFakeTime + toAdd);
lastRealTime = System.currentTimeMillis(); lastRealTime = System.currentTimeMillis();
return lastFakeTime; return lastFakeTime;
} }

View File

@@ -1,13 +1,11 @@
package eu.crushedpixel.replaymod.timer; package eu.crushedpixel.replaymod.timer;
import java.lang.reflect.Field;
import net.minecraft.client.Minecraft;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Timer;
import eu.crushedpixel.replaymod.reflection.MCPNames; import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.video.ReplayTimer; import eu.crushedpixel.replaymod.video.ReplayTimer;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Timer;
import java.lang.reflect.Field;
public class MCTimerHandler { public class MCTimerHandler {
@@ -57,6 +55,14 @@ public class MCTimerHandler {
return 0; return 0;
} }
public static void setTicks(int ticks) {
try {
getTimer().elapsedTicks = ticks;
} catch(Exception e) {
e.printStackTrace();
}
}
public static float getPartialTicks() { public static float getPartialTicks() {
try { try {
Timer t = getTimer(); Timer t = getTimer();
@@ -67,6 +73,14 @@ public class MCTimerHandler {
return 0; return 0;
} }
public static void setPartialTicks(float ticks) {
try {
getTimer().elapsedPartialTicks = ticks;
} catch(Exception e) {
e.printStackTrace();
}
}
public static float getRenderTicks() { public static float getRenderTicks() {
try { try {
Timer t = getTimer(); Timer t = getTimer();
@@ -78,7 +92,7 @@ public class MCTimerHandler {
} }
private static Timer getTimer() throws IllegalArgumentException, IllegalAccessException { private static Timer getTimer() throws IllegalArgumentException, IllegalAccessException {
return (Timer)mcTimer.get(mc); return (Timer) mcTimer.get(mc);
} }
public static void advanceTicks(int ticks) { public static void advanceTicks(int ticks) {
@@ -108,18 +122,6 @@ public class MCTimerHandler {
} }
} }
public static void setTimerSpeed(float speed) {
try {
Timer t = getTimer();
t.timerSpeed = speed;
if(timerBefore != null) {
timerBefore.timerSpeed = speed;
}
} catch(Exception e) {
e.printStackTrace();
}
}
public static void setRenderPartialTicks(float ticks) { public static void setRenderPartialTicks(float ticks) {
try { try {
getTimer().renderPartialTicks = ticks; getTimer().renderPartialTicks = ticks;
@@ -128,22 +130,6 @@ public class MCTimerHandler {
} }
} }
public static void setPartialTicks(float ticks) {
try {
getTimer().elapsedPartialTicks = ticks;
} catch(Exception e) {
e.printStackTrace();
}
}
public static void setTicks(int ticks) {
try {
getTimer().elapsedTicks = ticks;
} catch(Exception e) {
e.printStackTrace();
}
}
public static float getTimerSpeed() { public static float getTimerSpeed() {
try { try {
return getTimer().timerSpeed; return getTimer().timerSpeed;
@@ -153,17 +139,28 @@ public class MCTimerHandler {
return 1; return 1;
} }
public static void setTimerSpeed(float speed) {
try {
Timer t = getTimer();
t.timerSpeed = speed;
if(timerBefore != null) {
timerBefore.timerSpeed = speed;
}
} catch(Exception e) {
e.printStackTrace();
}
}
public static void updateTimer(double d) { public static void updateTimer(double d) {
try { try {
Timer t = getTimer(); Timer t = getTimer();
double d2 = d; double d2 = d;
//d2 = MathHelper.clamp_double(d2, 0.0D, 1.0D); //d2 = MathHelper.clamp_double(d2, 0.0D, 1.0D);
t.elapsedPartialTicks = (float)((double)t.elapsedPartialTicks + d2 * (double)t.timerSpeed * 20); t.elapsedPartialTicks = (float) ((double) t.elapsedPartialTicks + d2 * (double) t.timerSpeed * 20);
t.elapsedTicks = (int)t.elapsedPartialTicks; t.elapsedTicks = (int) t.elapsedPartialTicks;
t.elapsedPartialTicks -= (float)t.elapsedTicks; t.elapsedPartialTicks -= (float) t.elapsedTicks;
if (t.elapsedTicks > 10) if(t.elapsedTicks > 10) {
{
t.elapsedTicks = 10; t.elapsedTicks = 10;
} }

View File

@@ -1,9 +1,6 @@
package eu.crushedpixel.replaymod.utils; package eu.crushedpixel.replaymod.utils;
import java.awt.Dimension; import java.awt.*;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
public class ImageUtils { public class ImageUtils {
@@ -52,8 +49,15 @@ public class ImageUtils {
static float getBinFactor(int width, int height, Dimension dim) { static float getBinFactor(int width, int height, Dimension dim) {
float factor = 1; float factor = 1;
float target = getFactor(width, height, dim); float target = getFactor(width, height, dim);
if (target <= 1) { while (factor / 2 > target) { factor /= 2; } if(target <= 1) {
} else { while (factor * 2 < target) { factor *= 2; } } while(factor / 2 > target) {
factor /= 2;
}
} else {
while(factor * 2 < target) {
factor *= 2;
}
}
return factor; return factor;
} }

View File

@@ -1,20 +1,19 @@
package eu.crushedpixel.replaymod.utils; package eu.crushedpixel.replaymod.utils;
import java.awt.Point;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.ScaledResolution;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import java.awt.*;
public class MouseUtils { public class MouseUtils {
private static final Minecraft mc = Minecraft.getMinecraft(); private static final Minecraft mc = Minecraft.getMinecraft();
public static Point getMousePos() { public static Point getMousePos() {
Point scaled = getScaledDimensions(); Point scaled = getScaledDimensions();
int width = (int)scaled.getX(); int width = (int) scaled.getX();
int height = (int)scaled.getY(); int height = (int) scaled.getY();
final int mouseX = (Mouse.getX() * width / mc.displayWidth); final int mouseX = (Mouse.getX() * width / mc.displayWidth);
final int mouseY = (height - Mouse.getY() * height / mc.displayHeight); final int mouseY = (height - Mouse.getY() * height / mc.displayHeight);

View File

@@ -7,7 +7,6 @@ import eu.crushedpixel.replaymod.holders.PacketData;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler; import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import eu.crushedpixel.replaymod.recording.PacketSerializer; import eu.crushedpixel.replaymod.recording.PacketSerializer;
import eu.crushedpixel.replaymod.recording.ReplayMetaData; import eu.crushedpixel.replaymod.recording.ReplayMetaData;
import eu.crushedpixel.replaymod.replay.PacketDeserializer;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.minecraft.network.EnumConnectionState; import net.minecraft.network.EnumConnectionState;
@@ -21,9 +20,6 @@ import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import java.io.*; import java.io.*;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@@ -34,6 +30,11 @@ import java.util.zip.ZipOutputStream;
@SuppressWarnings("resource") //Gets handled by finalizer @SuppressWarnings("resource") //Gets handled by finalizer
public class ReplayFileIO { public class ReplayFileIO {
private static final PacketSerializer packetSerializer = new PacketSerializer(EnumPacketDirection.CLIENTBOUND);
private static final byte[] uniqueBytes = new byte[]{0, 1, 1, 2, 3, 5, 8};
private static File lastReplayFile = null;
private static boolean lastContainsJoinPacket = false;
public static File getRenderFolder() { public static File getRenderFolder() {
File folder = new File(ReplayMod.replaySettings.getRenderPath()); File folder = new File(ReplayMod.replaySettings.getRenderPath());
folder.mkdirs(); folder.mkdirs();
@@ -51,7 +52,7 @@ public class ReplayFileIO {
List<File> files = new ArrayList<File>(); List<File> files = new ArrayList<File>();
File folder = getReplayFolder(); File folder = getReplayFolder();
for(File file : folder.listFiles()) { for(File file : folder.listFiles()) {
if(("."+FilenameUtils.getExtension(file.getAbsolutePath())).equals( if(("." + FilenameUtils.getExtension(file.getAbsolutePath())).equals(
ConnectionEventHandler.ZIP_FILE_EXTENSION)) { ConnectionEventHandler.ZIP_FILE_EXTENSION)) {
files.add(file); files.add(file);
} }
@@ -64,7 +65,7 @@ public class ReplayFileIO {
try { try {
archive = new ZipFile(replayFile); archive = new ZipFile(replayFile);
ZipArchiveEntry tmcpr = archive.getEntry("metaData"+ ZipArchiveEntry tmcpr = archive.getEntry("metaData" +
ConnectionEventHandler.JSON_FILE_EXTENSION); ConnectionEventHandler.JSON_FILE_EXTENSION);
return new DataInputStream(archive.getInputStream(tmcpr)); return new DataInputStream(archive.getInputStream(tmcpr));
@@ -91,7 +92,7 @@ public class ReplayFileIO {
pw.flush(); pw.flush();
zos.closeEntry(); zos.closeEntry();
zos.putNextEntry(new ZipEntry("recording"+ConnectionEventHandler.TEMP_FILE_EXTENSION)); zos.putNextEntry(new ZipEntry("recording" + ConnectionEventHandler.TEMP_FILE_EXTENSION));
FileInputStream fis = new FileInputStream(tempFile); FileInputStream fis = new FileInputStream(tempFile);
int len; int len;
while((len = fis.read(buffer)) > 0) { while((len = fis.read(buffer)) > 0) {
@@ -109,7 +110,7 @@ public class ReplayFileIO {
try { try {
archive = new ZipFile(replayFile); archive = new ZipFile(replayFile);
ZipArchiveEntry tmcpr = archive.getEntry("recording"+ ZipArchiveEntry tmcpr = archive.getEntry("recording" +
ConnectionEventHandler.TEMP_FILE_EXTENSION); ConnectionEventHandler.TEMP_FILE_EXTENSION);
long size = tmcpr.getSize(); long size = tmcpr.getSize();
@@ -147,7 +148,8 @@ public class ReplayFileIO {
if(p instanceof S01PacketJoinGame) { if(p instanceof S01PacketJoinGame) {
lastContainsJoinPacket = true; lastContainsJoinPacket = true;
return lastContainsJoinPacket; return lastContainsJoinPacket;
} if(p instanceof S08PacketPlayerPosLook) { }
if(p instanceof S08PacketPlayerPosLook) {
lastContainsJoinPacket = false; lastContainsJoinPacket = false;
return lastContainsJoinPacket; return lastContainsJoinPacket;
} }
@@ -159,7 +161,8 @@ public class ReplayFileIO {
if(dis != null) { if(dis != null) {
dis.close(); dis.close();
} }
} catch(Exception e) {} } catch(Exception e) {
}
} }
return false; return false;
@@ -209,7 +212,7 @@ public class ReplayFileIO {
} }
public static int getWrittenByteSize(PacketData pd) { public static int getWrittenByteSize(PacketData pd) {
return (2*4)+pd.getByteArray().length; return (2 * 4) + pd.getByteArray().length;
} }
public static void writePackets(Collection<PacketData> p, DataOutput out) throws IOException { public static void writePackets(Collection<PacketData> p, DataOutput out) throws IOException {
@@ -218,14 +221,7 @@ public class ReplayFileIO {
} }
} }
private static final PacketSerializer packetSerializer = new PacketSerializer(EnumPacketDirection.CLIENTBOUND);
private static final PacketDeserializer deserializer = new PacketDeserializer(EnumPacketDirection.SERVERBOUND);
private static File lastReplayFile = null;
private static boolean lastContainsJoinPacket = false;
/** /**
*
* @param replayFile The File to reverse * @param replayFile The File to reverse
* @param outputFile The File to save the reversed Packets in * @param outputFile The File to save the reversed Packets in
* @param seekJoinPacket Whether a {@link S01PacketJoinGame} should be seeked in the Replay File. If containsJoinPacket is being * @param seekJoinPacket Whether a {@link S01PacketJoinGame} should be seeked in the Replay File. If containsJoinPacket is being
@@ -302,14 +298,13 @@ public class ReplayFileIO {
if(dis != null) { if(dis != null) {
dis.close(); dis.close();
} }
} catch(Exception e) {} } catch(Exception e) {
}
} }
return false; return false;
} }
private static final byte[] uniqueBytes = new byte[]{0,1,1,2,3,5,8};
public static void addThumbToZip(File zipFile, File thumb) throws IOException { public static void addThumbToZip(File zipFile, File thumb) throws IOException {
// get a temp file // get a temp file
File tempFile = File.createTempFile(zipFile.getName(), null, zipFile.getParentFile()); File tempFile = File.createTempFile(zipFile.getName(), null, zipFile.getParentFile());
@@ -321,15 +316,15 @@ public class ReplayFileIO {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(tempFile)); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(tempFile));
ZipEntry entry = zin.getNextEntry(); ZipEntry entry = zin.getNextEntry();
while (entry != null) { while(entry != null) {
String name = entry.getName(); String name = entry.getName();
boolean isThumb = name.contains("thumb"); boolean isThumb = name.contains("thumb");
if (!isThumb) { if(!isThumb) {
// Add ZIP entry to output stream. // Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(name)); out.putNextEntry(new ZipEntry(name));
// Transfer bytes from the ZIP file to the output file // Transfer bytes from the ZIP file to the output file
int len; int len;
while ((len = zin.read(buf)) > 0) { while((len = zin.read(buf)) > 0) {
out.write(buf, 0, len); out.write(buf, 0, len);
} }
} }
@@ -347,7 +342,7 @@ public class ReplayFileIO {
out.write(uniqueBytes); out.write(uniqueBytes);
while ((len = in.read(buf)) > 0) { while((len = in.read(buf)) > 0) {
out.write(buf, 0, len); out.write(buf, 0, len);
} }
// Complete the entry // Complete the entry

View File

@@ -1,18 +1,18 @@
package eu.crushedpixel.replaymod.utils; package eu.crushedpixel.replaymod.utils;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import eu.crushedpixel.replaymod.reflection.MCPNames; import eu.crushedpixel.replaymod.reflection.MCPNames;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class ResourceHelper { public class ResourceHelper {
private static BufferedImage defaultThumb; private static BufferedImage defaultThumb;
private static List<ResourceLocation> openResources = new ArrayList<ResourceLocation>();
static { static {
try { try {
@@ -22,7 +22,6 @@ public class ResourceHelper {
e.printStackTrace(); e.printStackTrace();
} }
} }
private static List<ResourceLocation> openResources = new ArrayList<ResourceLocation>();
public static void registerResource(ResourceLocation loc) { public static void registerResource(ResourceLocation loc) {
openResources.add(loc); openResources.add(loc);

View File

@@ -17,21 +17,13 @@
*/ */
package eu.crushedpixel.replaymod.utils; package eu.crushedpixel.replaymod.utils;
import java.io.ByteArrayInputStream; import java.io.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
/** /**
*
* @author Marc Schunk, created on 21.06.2004 * @author Marc Schunk, created on 21.06.2004
* * <p/>
* A Class to provide helpers of commonly user operations with binary * A Class to provide helpers of commonly user operations with binary
* and character Streams, such as read to an OutputStream/Writer, * and character Streams, such as read to an OutputStream/Writer,
* String, ByteArray. In addition streams can be compressed. * String, ByteArray. In addition streams can be compressed.
@@ -39,15 +31,17 @@ import java.util.zip.GZIPOutputStream;
public class StreamTools { public class StreamTools {
public static final String[] umlauteString = {"&amp;", "&#223;", "&auml;",
"&Auml;", "&ouml;", "&Ouml;", "&uuml;", "&Uuml;", "&szlig;"};
public static final String[] umlauteReplacement = {"&", "ß", "ä", "Ä", "ö",
"Ö", "ü", "Ü", "ß"};
/** /**
* Checks weather the given array is contained in the first array * Checks weather the given array is contained in the first array
* *
* @param ar1 * @param ar1 - the containing array
* - the containing array * @param index1 - the index where the search starts
* @param index1 * @param ar2 - the array that schould be contained
* - the index where the search starts
* @param ar2
* - the array that schould be contained
* @return - true of ar2 is contained in ar1 * @return - true of ar2 is contained in ar1
*/ */
public static final boolean arrayMatch(char[] ar1, int index1, char[] ar2) { public static final boolean arrayMatch(char[] ar1, int index1, char[] ar2) {
@@ -64,10 +58,8 @@ public class StreamTools {
* Reads inStream completly and writes it to outStream. Streams will not be * Reads inStream completly and writes it to outStream. Streams will not be
* closed. * closed.
* *
* @param inStream * @param inStream - an InputStream to be read completely
* - an InputStream to be read completely * @param outStream - the destination Stream
* @param outStream
* - the destination Stream
* @throws IOException * @throws IOException
*/ */
public static void readStream(InputStream inStream, OutputStream outStream) public static void readStream(InputStream inStream, OutputStream outStream)
@@ -82,10 +74,8 @@ public class StreamTools {
/** /**
* Reads inStream completly into an byte[]. Streams will not be closed. * Reads inStream completly into an byte[]. Streams will not be closed.
* *
* @param inStream * @param inStream - an InputStream to be read completely
* - an InputStream to be read completely * @param outStream - the destination Stream
* @param outStream
* - the destination Stream
* @throws IOException * @throws IOException
*/ */
public static byte[] readStream(InputStream inStream) throws IOException { public static byte[] readStream(InputStream inStream) throws IOException {
@@ -147,11 +137,6 @@ public class StreamTools {
return sw.toString(); return sw.toString();
} }
public static final String[] umlauteString = {"&amp;", "&#223;", "&auml;",
"&Auml;", "&ouml;", "&Ouml;", "&uuml;", "&Uuml;", "&szlig;"};
public static final String[] umlauteReplacement = {"&", "ß", "ä", "Ä", "ö",
"Ö", "ü", "Ü", "ß"};
public static String replaceSpecialCharacters(String s) { public static String replaceSpecialCharacters(String s) {
for(int i = 0; i < umlauteString.length; i++) { for(int i = 0; i < umlauteString.length; i++) {
s = s.replaceAll(umlauteString[i], umlauteReplacement[i]); s = s.replaceAll(umlauteString[i], umlauteReplacement[i]);
@@ -163,10 +148,8 @@ public class StreamTools {
* Stores the given Stream in an byte[]. Stream is compressed on the fly. * Stores the given Stream in an byte[]. Stream is compressed on the fly.
* Streams will not be closed. * Streams will not be closed.
* *
* @param inStream * @param inStream - an InputStream to be read completely
* - an InputStream to be read completely * @param outStream - the destination Stream
* @param outStream
* - the destination Stream
* @throws IOException * @throws IOException
*/ */
public static byte[] compressStreamToByteArray(InputStream inStream) public static byte[] compressStreamToByteArray(InputStream inStream)
@@ -187,10 +170,8 @@ public class StreamTools {
* Stores the given Stream in an byte[]. Stream is compressed on the fly. * Stores the given Stream in an byte[]. Stream is compressed on the fly.
* Streams will not be closed. * Streams will not be closed.
* *
* @param inStream * @param inStream - an InputStream to be read completely
* - an InputStream to be read completely * @param outStream - the destination Stream
* @param outStream
* - the destination Stream
* @throws IOException * @throws IOException
*/ */
public static byte[] compress(byte[] uncompressed) throws IOException { public static byte[] compress(byte[] uncompressed) throws IOException {
@@ -203,10 +184,8 @@ public class StreamTools {
* Thus, the input stream should contain compressed content. Streams will * Thus, the input stream should contain compressed content. Streams will
* not be closed. * not be closed.
* *
* @param inStream * @param inStream - an InputStream to be read completely
* - an InputStream to be read completely * @param outStream - the destination Stream
* @param outStream
* - the destination Stream
* @throws IOException * @throws IOException
*/ */
public static byte[] decompressStreamToByteArray(InputStream inStream) public static byte[] decompressStreamToByteArray(InputStream inStream)

View File

@@ -17,10 +17,9 @@ public class ZipFileUtils {
// delete it, otherwise you cannot rename your existing zip to it. // delete it, otherwise you cannot rename your existing zip to it.
tempFile.delete(); tempFile.delete();
tempFile.deleteOnExit(); tempFile.deleteOnExit();
boolean renameOk=zipFile.renameTo(tempFile); boolean renameOk = zipFile.renameTo(tempFile);
if (!renameOk) if(!renameOk) {
{ throw new RuntimeException("could not rename the file " + zipFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath());
throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
} }
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
@@ -28,21 +27,21 @@ public class ZipFileUtils {
ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zipFile)); ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zipFile));
ZipEntry entry = zin.getNextEntry(); ZipEntry entry = zin.getNextEntry();
while (entry != null) { while(entry != null) {
String name = entry.getName(); String name = entry.getName();
boolean toBeDeleted = false; boolean toBeDeleted = false;
for (String f : files) { for(String f : files) {
if (f.equals(name)) { if(f.equals(name)) {
toBeDeleted = true; toBeDeleted = true;
break; break;
} }
} }
if (!toBeDeleted) { if(!toBeDeleted) {
// Add ZIP entry to output stream. // Add ZIP entry to output stream.
zout.putNextEntry(new ZipEntry(name)); zout.putNextEntry(new ZipEntry(name));
// Transfer bytes from the ZIP file to the output file // Transfer bytes from the ZIP file to the output file
int len; int len;
while ((len = zin.read(buf)) > 0) { while((len = zin.read(buf)) > 0) {
zout.write(buf, 0, len); zout.write(buf, 0, len);
} }
} }

View File

@@ -1,36 +1,19 @@
package eu.crushedpixel.replaymod.video; package eu.crushedpixel.replaymod.video;
import java.awt.Dimension; import eu.crushedpixel.replaymod.ReplayMod;
import java.awt.Rectangle; import eu.crushedpixel.replaymod.chat.ChatMessageHandler.ChatMessageType;
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 eu.crushedpixel.replaymod.events.TickAndRenderListener; import eu.crushedpixel.replaymod.events.TickAndRenderListener;
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.gui.GuiReplaySaving;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.replay.ReplayHandler;
import eu.crushedpixel.replaymod.utils.ImageUtils; import eu.crushedpixel.replaymod.utils.ImageUtils;
import eu.crushedpixel.replaymod.utils.ReplayFileIO; import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
public class ReplayScreenshot { public class ReplayScreenshot {
@@ -41,15 +24,14 @@ public class ReplayScreenshot {
private static boolean before; private static boolean before;
private static double beforeSpeed; private static double beforeSpeed;
private static GuiScreen beforeScreen; private static GuiScreen beforeScreen;
private static boolean locked = false;
public static void prepareScreenshot() { public static void prepareScreenshot() {
before = mc.gameSettings.hideGUI; before = mc.gameSettings.hideGUI;
beforeSpeed = ReplayHandler.getSpeed(); beforeSpeed = ReplayMod.replaySender.getReplaySpeed();
beforeScreen = mc.currentScreen; beforeScreen = mc.currentScreen;
} }
private static boolean locked = false;
public static void saveScreenshot() { public static void saveScreenshot() {
if(locked) return; if(locked) return;
@@ -62,13 +44,13 @@ public class ReplayScreenshot {
mc.currentScreen = null; mc.currentScreen = null;
mc.entityRenderer.updateCameraAndRender(0); mc.entityRenderer.updateCameraAndRender(0);
ReplayHandler.setSpeed(0); ReplayMod.replaySender.setReplaySpeed(0);
final BufferedImage fbi = ScreenCapture.captureScreen(); final BufferedImage fbi = ScreenCapture.captureScreen();
mc.gameSettings.hideGUI = before; mc.gameSettings.hideGUI = before;
mc.currentScreen = beforeScreen; mc.currentScreen = beforeScreen;
ReplayHandler.setSpeed(beforeSpeed); ReplayMod.replaySender.setReplaySpeed(beforeSpeed);
//The actual cropping and saving should be executed in a separate thread //The actual cropping and saving should be executed in a separate thread
Thread ioThread = new Thread(new Runnable() { Thread ioThread = new Thread(new Runnable() {
@@ -76,16 +58,16 @@ public class ReplayScreenshot {
@Override @Override
public void run() { public void run() {
try { try {
float aspect = 1280f/720f; float aspect = 1280f / 720f;
Rectangle rect; Rectangle rect;
if((float)fbi.getWidth()/(float)fbi.getHeight() <= aspect) { if((float) fbi.getWidth() / (float) fbi.getHeight() <= aspect) {
int h = Math.round(fbi.getWidth()/aspect); int h = Math.round(fbi.getWidth() / aspect);
int y = (fbi.getHeight()/2) - (h/2); int y = (fbi.getHeight() / 2) - (h / 2);
rect = new Rectangle(0, y, fbi.getWidth(), h); rect = new Rectangle(0, y, fbi.getWidth(), h);
} else { } else {
int w = Math.round(fbi.getHeight()*aspect); int w = Math.round(fbi.getHeight() * aspect);
int x = (fbi.getWidth()/2) - (w/2); int x = (fbi.getWidth() / 2) - (w / 2);
rect = new Rectangle(x, 0, w, fbi.getHeight()); rect = new Rectangle(x, 0, w, fbi.getHeight());
} }
@@ -155,11 +137,10 @@ public class ReplayScreenshot {
tempImage.delete(); tempImage.delete();
*/ */
ChatMessageRequests.addChatMessage("Thumbnail has been successfully saved", ChatMessageType.INFORMATION); ReplayMod.chatMessageHandler.addChatMessage("Thumbnail has been successfully saved", ChatMessageType.INFORMATION);
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} } finally {
finally {
GuiReplaySaving.replaySaving = false; GuiReplaySaving.replaySaving = false;
locked = false; locked = false;
TickAndRenderListener.finishScreenshot(); TickAndRenderListener.finishScreenshot();
@@ -168,14 +149,13 @@ public class ReplayScreenshot {
}); });
ioThread.start(); ioThread.start();
} } catch(Exception exception) {
catch (Exception exception) {
exception.printStackTrace(); exception.printStackTrace();
mc.gameSettings.hideGUI = before; mc.gameSettings.hideGUI = before;
mc.currentScreen = beforeScreen; mc.currentScreen = beforeScreen;
ReplayHandler.setSpeed(beforeSpeed); ReplayMod.replaySender.setReplaySpeed(beforeSpeed);
exception.printStackTrace(); exception.printStackTrace();
ChatMessageRequests.addChatMessage("Thumbnail could not be saved", ChatMessageType.WARNING); ReplayMod.chatMessageHandler.addChatMessage("Thumbnail could not be saved", ChatMessageType.WARNING);
} }
last_finish = System.currentTimeMillis(); last_finish = System.currentTimeMillis();

View File

@@ -1,21 +1,16 @@
package eu.crushedpixel.replaymod.video; package eu.crushedpixel.replaymod.video;
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.nio.IntBuffer;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.texture.TextureUtil; import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.shader.Framebuffer; import net.minecraft.client.shader.Framebuffer;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12; import org.lwjgl.opengl.GL12;
import org.monte.screenrecorder.ScreenRecorder;
import java.awt.image.BufferedImage;
import java.nio.IntBuffer;
public class ScreenCapture { public class ScreenCapture {
@@ -30,16 +25,14 @@ public class ScreenCapture {
Framebuffer buffer = mc.getFramebuffer(); Framebuffer buffer = mc.getFramebuffer();
if (OpenGlHelper.isFramebufferEnabled()) if(OpenGlHelper.isFramebufferEnabled()) {
{
width = buffer.framebufferTextureWidth; width = buffer.framebufferTextureWidth;
height = buffer.framebufferTextureHeight; height = buffer.framebufferTextureHeight;
} }
int k = width * height; int k = width * height;
if (pixelBuffer == null || pixelBuffer.capacity() < k) if(pixelBuffer == null || pixelBuffer.capacity() < k) {
{
pixelBuffer = BufferUtils.createIntBuffer(k); pixelBuffer = BufferUtils.createIntBuffer(k);
pixelValues = new int[k]; pixelValues = new int[k];
} }
@@ -48,11 +41,10 @@ public class ScreenCapture {
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1); GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
pixelBuffer.clear(); pixelBuffer.clear();
if (OpenGlHelper.isFramebufferEnabled()) { if(OpenGlHelper.isFramebufferEnabled()) {
GlStateManager.bindTexture(buffer.framebufferTexture); GlStateManager.bindTexture(buffer.framebufferTexture);
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer); GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);
} } else {
else {
GL11.glReadPixels(0, 0, width, height, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer); GL11.glReadPixels(0, 0, width, height, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);
} }
@@ -61,20 +53,16 @@ public class ScreenCapture {
BufferedImage bufferedimage = null; BufferedImage bufferedimage = null;
if (OpenGlHelper.isFramebufferEnabled()) if(OpenGlHelper.isFramebufferEnabled()) {
{
bufferedimage = new BufferedImage(buffer.framebufferWidth, buffer.framebufferHeight, 1); bufferedimage = new BufferedImage(buffer.framebufferWidth, buffer.framebufferHeight, 1);
int l = buffer.framebufferTextureHeight - buffer.framebufferHeight; int l = buffer.framebufferTextureHeight - buffer.framebufferHeight;
for (int i1 = l; i1 < buffer.framebufferTextureHeight; ++i1) for(int i1 = l; i1 < buffer.framebufferTextureHeight; ++i1) {
{ for(int j1 = 0; j1 < buffer.framebufferWidth; ++j1) {
for (int j1 = 0; j1 < buffer.framebufferWidth; ++j1)
{
bufferedimage.setRGB(j1, i1 - l, pixelValues[i1 * buffer.framebufferTextureWidth + j1]); bufferedimage.setRGB(j1, i1 - l, pixelValues[i1 * buffer.framebufferTextureWidth + j1]);
} }
} }
} } else {
else {
bufferedimage = new BufferedImage(width, height, 1); bufferedimage = new BufferedImage(width, height, 1);
bufferedimage.setRGB(0, 0, width, height, pixelValues, 0, width); bufferedimage.setRGB(0, 0, width, height, pixelValues, 0, width);
} }

View File

@@ -1,5 +1,11 @@
package eu.crushedpixel.replaymod.video; package eu.crushedpixel.replaymod.video;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import org.monte.media.*;
import org.monte.media.FormatKeys.MediaType;
import org.monte.media.math.Rational;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -8,18 +14,6 @@ import java.util.Calendar;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import org.monte.media.Buffer;
import org.monte.media.Format;
import org.monte.media.FormatKeys;
import org.monte.media.FormatKeys.MediaType;
import org.monte.media.MovieWriter;
import org.monte.media.Registry;
import org.monte.media.VideoFormatKeys;
import org.monte.media.math.Rational;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
public class VideoWriter { public class VideoWriter {
private static final String DATE_FORMAT = "yyyy_MM_dd_HH_mm_ss"; private static final String DATE_FORMAT = "yyyy_MM_dd_HH_mm_ss";
@@ -35,6 +29,7 @@ public class VideoWriter {
private static Buffer buf; private static Buffer buf;
private static int track; private static int track;
private static Queue<BufferedImage> toWrite = new LinkedBlockingQueue<BufferedImage>();
public static boolean isRecording() { public static boolean isRecording() {
return isRecording; return isRecording;
@@ -54,7 +49,7 @@ public class VideoWriter {
String fileName = sdf.format(Calendar.getInstance().getTime()); String fileName = sdf.format(Calendar.getInstance().getTime());
file = new File(folder, fileName+VIDEO_EXTENSION); file = new File(folder, fileName + VIDEO_EXTENSION);
file.createNewFile(); file.createNewFile();
out = Registry.getInstance().getWriter(file); out = Registry.getInstance().getWriter(file);
@@ -64,7 +59,7 @@ public class VideoWriter {
VideoFormatKeys.WidthKey, width, VideoFormatKeys.WidthKey, width,
VideoFormatKeys.HeightKey, height, VideoFormatKeys.HeightKey, height,
VideoFormatKeys.DepthKey, 24, VideoFormatKeys.DepthKey, 24,
VideoFormatKeys.QualityKey, (float)ReplayMod.replaySettings.getVideoQuality()); VideoFormatKeys.QualityKey, (float) ReplayMod.replaySettings.getVideoQuality());
track = out.addTrack(format); track = out.addTrack(format);
@@ -72,7 +67,7 @@ public class VideoWriter {
buf = new Buffer(); buf = new Buffer();
buf.format = new Format(VideoFormatKeys.DataClassKey, BufferedImage.class); buf.format = new Format(VideoFormatKeys.DataClassKey, BufferedImage.class);
buf.sampleDuration = out.getFormat(track).get(VideoFormatKeys.FrameRateKey).inverse(); buf.sampleDuration = out.getFormat(track).get(VideoFormatKeys.FrameRateKey).inverse();
} catch (IOException e) { } catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -90,7 +85,7 @@ public class VideoWriter {
if(abort) { if(abort) {
file.delete(); file.delete();
} }
} catch (IOException e) { } catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
abort = false; abort = false;
@@ -111,8 +106,6 @@ public class VideoWriter {
t.start(); 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) {
IllegalStateException up = new IllegalStateException( IllegalStateException up = new IllegalStateException(
@@ -135,7 +128,7 @@ public class VideoWriter {
buf.data = img; buf.data = img;
out.write(track, buf); out.write(track, buf);
} }
} catch (IOException e) { } catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }