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,114 +20,95 @@ 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
//TODO: Override Enchantment Rendering for items when replaying (to adjust speed of animation) //TODO: Override Enchantment Rendering for items when replaying (to adjust speed of animation)
//TODO: Show the player whether he has already uploaded a replay //TODO: Show the player whether he has already uploaded a replay
//TODO: Hinting to the b/v key feature //TODO: Hinting to the b/v key feature
//XXX //XXX
//Known Bugs //Known Bugs
// //
//Keyframes have problems with Linear Paths //Keyframes have problems with Linear Paths
//Rain isn't working //Rain isn't working
//Incompatible with Shaders Mod //Incompatible with Shaders Mod
// //
// //
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();
public static GuiReplayOverlay overlay = new GuiReplayOverlay();
public static ReplaySettings replaySettings;
public static Configuration config;
public static boolean firstMainMenu = true;
public static RecordingHandler recordingHandler;
public static ChatMessageHandler chatMessageHandler = new ChatMessageHandler();
public static ReplaySender replaySender;
public static int TP_DISTANCE_LIMIT = 128;
public static FileCopyHandler fileCopyHandler;
private static final Minecraft mc = Minecraft.getMinecraft(); // The instance of your mod that Forge uses.
@Instance(value = "ReplayModID")
public static ReplayMod instance;
public static GuiReplayOverlay overlay = new GuiReplayOverlay(); @EventHandler
public void preInit(FMLPreInitializationEvent event) {
config = new Configuration(event.getSuggestedConfigurationFile());
config.load();
public static ReplaySettings replaySettings; replaySettings = new ReplaySettings();
public static Configuration config; replaySettings.readValues();
public static boolean firstMainMenu = true; fileCopyHandler = new FileCopyHandler();
fileCopyHandler.start();
}
public static RecordingHandler recordingHandler; @EventHandler
public void init(FMLInitializationEvent event) {
FMLCommonHandler.instance().bus().register(new ConnectionEventHandler());
MinecraftForge.EVENT_BUS.register(new GuiEventHandler());
public static int TP_DISTANCE_LIMIT = 128; FMLCommonHandler.instance().bus().register(new KeyInputHandler());
public static final ApiClient apiClient = new ApiClient(); recordingHandler = new RecordingHandler();
FMLCommonHandler.instance().bus().register(recordingHandler);
MinecraftForge.EVENT_BUS.register(recordingHandler);
}
public static FileCopyHandler fileCopyHandler; @EventHandler
public void postInit(FMLPostInitializationEvent event) {
overlay = new GuiReplayOverlay();
FMLCommonHandler.instance().bus().register(overlay);
MinecraftForge.EVENT_BUS.register(overlay);
// The instance of your mod that Forge uses. TickAndRenderListener tarl = new TickAndRenderListener();
@Instance(value = "ReplayModID") FMLCommonHandler.instance().bus().register(tarl);
public static ReplayMod instance; MinecraftForge.EVENT_BUS.register(tarl);
@EventHandler KeybindRegistry.initialize();
public void preInit(FMLPreInitializationEvent event) {
config = new Configuration(event.getSuggestedConfigurationFile());
config.load();
replaySettings = new ReplaySettings(); try {
replaySettings.readValues(); mc.entityRenderer = new SafeEntityRenderer(mc, mc.entityRenderer);
} catch(Exception e) {
e.printStackTrace();
}
fileCopyHandler = new FileCopyHandler(); //clean up replay_recordings folder
fileCopyHandler.start(); removeTmcprFiles();
}
@EventHandler /*
public void init(FMLInitializationEvent event) { boolean auth = false;
FMLCommonHandler.instance().bus().register(new ConnectionEventHandler());
MinecraftForge.EVENT_BUS.register(new GuiEventHandler());
FMLCommonHandler.instance().bus().register(new KeyInputHandler());
recordingHandler = new RecordingHandler();
FMLCommonHandler.instance().bus().register(recordingHandler);
MinecraftForge.EVENT_BUS.register(recordingHandler);
}
@EventHandler
public void postInit(FMLPostInitializationEvent event) {
overlay = new GuiReplayOverlay();
FMLCommonHandler.instance().bus().register(overlay);
MinecraftForge.EVENT_BUS.register(overlay);
TickAndRenderListener tarl = new TickAndRenderListener();
FMLCommonHandler.instance().bus().register(tarl);
MinecraftForge.EVENT_BUS.register(tarl);
KeybindRegistry.initialize();
try {
mc.entityRenderer = new SafeEntityRenderer(mc, mc.entityRenderer);
} catch(Exception e) {
e.printStackTrace();
}
//clean up replay_recordings folder
removeTmcprFiles();
boolean auth = false;
try { try {
auth = AuthenticationHandler.hasDonated(Minecraft.getMinecraft().getSession().getPlayerID()); auth = AuthenticationHandler.hasDonated(Minecraft.getMinecraft().getSession().getPlayerID());
} catch(Exception e) { } catch(Exception e) {
@@ -138,16 +120,16 @@ 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() {
File folder = ReplayFileIO.getReplayFolder();
private void removeTmcprFiles() { for(File f : folder.listFiles()) {
File folder = ReplayFileIO.getReplayFolder(); if(("." + FilenameUtils.getExtension(f.getAbsolutePath())).equals(ConnectionEventHandler.TEMP_FILE_EXTENSION)) {
f.delete();
for(File f : folder.listFiles()) { }
if(("."+FilenameUtils.getExtension(f.getAbsolutePath())).equals(ConnectionEventHandler.TEMP_FILE_EXTENSION)) { }
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,143 +16,129 @@ 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);
builder.put("user", username); builder.put("user", username);
builder.put("pw", password); builder.put("pw", password);
AuthKey auth = invokeAndReturn(builder, AuthKey.class); AuthKey auth = invokeAndReturn(builder, AuthKey.class);
return auth; return auth;
} }
public boolean logout(String auth) throws IOException, ApiException { public boolean logout(String auth) throws IOException, ApiException {
QueryBuilder builder = new QueryBuilder(ApiMethods.logout); QueryBuilder builder = new QueryBuilder(ApiMethods.logout);
builder.put("auth", auth); builder.put("auth", auth);
Success succ = invokeAndReturn(builder, Success.class); Success succ = invokeAndReturn(builder, Success.class);
return succ.isSuccess(); return succ.isSuccess();
} }
public boolean hasDonated(String uuid) throws IOException, ApiException { public boolean hasDonated(String uuid) throws IOException, ApiException {
QueryBuilder builder = new QueryBuilder(ApiMethods.check_auth); QueryBuilder builder = new QueryBuilder(ApiMethods.check_auth);
builder.put("uuid", uuid); builder.put("uuid", uuid);
Donated succ = invokeAndReturn(builder, Donated.class); Donated succ = invokeAndReturn(builder, Donated.class);
return succ.hasDonated(); return succ.hasDonated();
} }
public UserFiles getUserFiles(String auth, String user) throws IOException, ApiException { public UserFiles getUserFiles(String auth, String user) throws IOException, ApiException {
QueryBuilder builder = new QueryBuilder(ApiMethods.replay_files); QueryBuilder builder = new QueryBuilder(ApiMethods.replay_files);
builder.put("auth", auth); builder.put("auth", auth);
builder.put("user", user); builder.put("user", user);
UserFiles files = invokeAndReturn(builder, UserFiles.class); UserFiles files = invokeAndReturn(builder, UserFiles.class);
return files; return files;
} }
public FileInfo[] getFileInfo(String auth, List<Integer> ids) throws IOException, ApiException { public FileInfo[] getFileInfo(String auth, List<Integer> ids) throws IOException, ApiException {
QueryBuilder builder = new QueryBuilder(ApiMethods.replay_files); QueryBuilder builder = new QueryBuilder(ApiMethods.replay_files);
builder.put("auth", auth); builder.put("auth", auth);
builder.put("ids", buildListString(ids)); builder.put("ids", buildListString(ids));
FileInfo[] info = invokeAndReturn(builder, FileInfo[].class); FileInfo[] info = invokeAndReturn(builder, FileInfo[].class);
return info; return info;
} }
public FileInfo[] searchFiles(SearchQuery query) throws IOException, ApiException { public FileInfo[] searchFiles(SearchQuery query) throws IOException, ApiException {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
// build base url // build base url
sb.append(QueryBuilder.API_BASE_URL); sb.append(QueryBuilder.API_BASE_URL);
sb.append("search"); sb.append("search");
sb.append(query.buildQuery()); sb.append(query.buildQuery());
FileInfo[] info = invokeAndReturn(sb.toString(), SearchResult.class).getResults(); FileInfo[] info = invokeAndReturn(sb.toString(), SearchResult.class).getResults();
return info; return info;
} }
public void downloadThumbnail(int file, File target) throws IOException { public void downloadThumbnail(int file, File target) throws IOException {
QueryBuilder builder = new QueryBuilder(ApiMethods.get_thumbnail); QueryBuilder builder = new QueryBuilder(ApiMethods.get_thumbnail);
builder.put("id", file); builder.put("id", file);
URL url = new URL(builder.toString()); URL url = new URL(builder.toString());
FileUtils.copyURLToFile(url, target); FileUtils.copyURLToFile(url, target);
} }
public void downloadFile(String auth, int file, File target) throws IOException { public void downloadFile(String auth, int file, File target) throws IOException {
QueryBuilder builder = new QueryBuilder(ApiMethods.download_file); QueryBuilder builder = new QueryBuilder(ApiMethods.download_file);
builder.put("auth", auth); builder.put("auth", auth);
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) {
Files.copy(is, target.toPath(), StandardCopyOption.REPLACE_EXISTING); Files.copy(is, target.toPath(), StandardCopyOption.REPLACE_EXISTING);
} else { } else {
JsonElement element = jsonParser.parse(StreamTools.readStreamtoString(is)); JsonElement element = jsonParser.parse(StreamTools.readStreamtoString(is));
try { try {
ApiError err = gson.fromJson(element, ApiError.class); ApiError err = gson.fromJson(element, ApiError.class);
if(err.getDesc() != null) { if(err.getDesc() != null) {
throw new ApiException(err); throw new ApiException(err);
} }
} catch(Exception e) {} } catch(Exception e) {
} }
} }
}
public void rateFile(String auth, int file, boolean like) throws IOException, ApiException { public void rateFile(String auth, int file, boolean like) throws IOException, ApiException {
QueryBuilder builder = new QueryBuilder(ApiMethods.rate_file); QueryBuilder builder = new QueryBuilder(ApiMethods.rate_file);
builder.put("auth", auth); builder.put("auth", auth);
builder.put("id", file); builder.put("id", file);
builder.put("like", like); builder.put("like", like);
invokeAndReturn(builder, Success.class); invokeAndReturn(builder, Success.class);
} }
public void removeFile(String auth, int file) throws IOException, ApiException { public void removeFile(String auth, int file) throws IOException, ApiException {
QueryBuilder builder = new QueryBuilder(ApiMethods.remove_file); QueryBuilder builder = new QueryBuilder(ApiMethods.remove_file);
builder.put("auth", auth); builder.put("auth", auth);
builder.put("id", file); builder.put("id", file);
invokeAndReturn(builder, Success.class); invokeAndReturn(builder, Success.class);
} }
private <T> T invokeAndReturn(QueryBuilder builder, Class<T> classOfT) throws IOException, ApiException { private <T> T invokeAndReturn(QueryBuilder builder, Class<T> classOfT) throws IOException, ApiException {
return invokeAndReturn(builder.toString(), classOfT); return invokeAndReturn(builder.toString(), classOfT);
} }
private <T> T invokeAndReturn(String url, Class<T> classOfT) throws IOException, ApiException { private <T> T invokeAndReturn(String url, Class<T> classOfT) throws IOException, ApiException {
JsonElement ele = GsonApiClient.invokeJson(url); JsonElement ele = GsonApiClient.invokeJson(url);
return gson.fromJson(ele, classOfT); return gson.fromJson(ele, classOfT);
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private String buildListString(List idList) { private String buildListString(List idList) {
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();
if(x != idList.size()) { if(x != idList.size()) {
ids += ","; ids += ",";
} }
} }
return ids; return ids;
} }
} }

View File

@@ -4,17 +4,17 @@ import eu.crushedpixel.replaymod.api.client.holders.ApiError;
public class ApiException extends Exception { public class ApiException extends Exception {
private static final long serialVersionUID = 349073390504232810L; private static final long serialVersionUID = 349073390504232810L;
private ApiError error; private ApiError error;
public ApiException(ApiError error) { public ApiException(ApiError error) {
super(error.getDesc()); super(error.getDesc());
this.error = error; this.error = error;
} }
public ApiError getError() { public ApiError getError() {
return error; return error;
} }
} }

View File

@@ -2,15 +2,15 @@ package eu.crushedpixel.replaymod.api.client;
public class ApiMethods { public class ApiMethods {
public static final String login = "login"; public static final String login = "login";
public static final String logout = "logout"; public static final String logout = "logout";
public static final String replay_files = "replay_files"; public static final String replay_files = "replay_files";
public static final String file_details = "file_details"; public static final String file_details = "file_details";
public static final String upload_file = "upload_file"; public static final String upload_file = "upload_file";
public static final String download_file = "download_file"; public static final String download_file = "download_file";
public static final String get_thumbnail = "get_thumbnail"; public static final String get_thumbnail = "get_thumbnail";
public static final String remove_file = "remove_file"; public static final String remove_file = "remove_file";
public static final String rate_file = "rate_file"; public static final String rate_file = "rate_file";
public static final String check_auth = "check_auth"; public static final String check_auth = "check_auth";
} }

View File

@@ -1,160 +1,149 @@
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;
private long current; private long current;
private String attachmentName = "file"; private String attachmentName = "file";
private String attachmentFileName = "file.mcpr"; private String attachmentFileName = "file.mcpr";
private String crlf = "\r\n"; private String crlf = "\r\n";
private String twoHyphens = "--"; private String twoHyphens = "--";
private boolean cancel = false; private boolean cancel = false;
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;
gui.onStartUploading(); gui.onStartUploading();
filesize = 0; filesize = 0;
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");
con.setChunkedStreamingMode(1024); con.setChunkedStreamingMode(1024);
con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Cache-Control", "no-cache"); con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + this.boundary); con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + this.boundary);
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());
request.writeBytes(this.twoHyphens + this.boundary + this.crlf); request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" + this.attachmentName + "\";filename=\"" + this.attachmentFileName + "\"" + this.crlf); request.writeBytes("Content-Disposition: form-data; name=\"" + this.attachmentName + "\";filename=\"" + this.attachmentFileName + "\"" + this.crlf);
request.writeBytes(this.crlf); request.writeBytes(this.crlf);
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
FileInputStream fis = new FileInputStream(file); FileInputStream fis = new FileInputStream(file);
filesize = fis.getChannel().size(); filesize = fis.getChannel().size();
current = 0; current = 0;
int len; int len;
while((len = fis.read(buf)) != -1) { while((len = fis.read(buf)) != -1) {
request.write(buf); request.write(buf);
current += len; current += len;
if(cancel) { if(cancel) {
uploading = false; uploading = false;
current = 0; current = 0;
cancel = false; cancel = false;
parent.onFinishUploading(false, "Upload has been canceled"); parent.onFinishUploading(false, "Upload has been canceled");
fis.close(); fis.close();
return; return;
} }
} }
fis.close(); fis.close();
request.writeBytes(this.crlf); request.writeBytes(this.crlf);
request.writeBytes(this.twoHyphens + this.boundary + this.twoHyphens + this.crlf); request.writeBytes(this.twoHyphens + this.boundary + this.twoHyphens + this.crlf);
request.flush(); request.flush();
request.close(); request.close();
boolean success = false; boolean success = false;
int responseCode = con.getResponseCode(); int responseCode = con.getResponseCode();
InputStream is = null; InputStream is = null;
if(responseCode == 200) { if(responseCode == 200) {
success = true; success = true;
is = con.getInputStream(); is = con.getInputStream();
} else { } else {
is = con.getErrorStream(); is = con.getErrorStream();
} }
String info = null; String info = null;
if(is != null) { if(is != null) {
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(); }
} ApiError error = gson.fromJson(json, ApiError.class);
error = gson.fromJson(json, ApiError.class); info = error.getDesc();
info = error.getDesc(); System.out.println(info);
System.out.println(info); }
} }
}
con.disconnect(); con.disconnect();
if(info == null) info = "An unknown error occured"; if(info == null) info = "An unknown error occured";
parent.onFinishUploading(success, info); parent.onFinishUploading(success, info);
uploading = false; uploading = false;
} }
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() {
return uploading; return uploading;
} }
public void cancelUploading() { public void cancelUploading() {
cancel = true; cancel = true;
} }
} }

View File

@@ -1,38 +1,37 @@
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();
public static JsonElement invoke(QueryBuilder query) throws IOException, ApiException { public static JsonElement invoke(QueryBuilder query) throws IOException, ApiException {
String apiResult = SimpleApiClient.invoke(query); String apiResult = SimpleApiClient.invoke(query);
return wrapWithJson(apiResult); return wrapWithJson(apiResult);
} }
public static JsonElement invokeJson(String url) throws IOException, ApiException { public static JsonElement invokeJson(String url) throws IOException, ApiException {
String apiResult = SimpleApiClient.invokeUrl(url); String apiResult = SimpleApiClient.invokeUrl(url);
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);
} }
public static JsonElement invokeJson(String apiKey, String method) throws IOException, ApiException { public static JsonElement invokeJson(String apiKey, String method) throws IOException, ApiException {
String apiResult = SimpleApiClient.invoke(method, null); String apiResult = SimpleApiClient.invoke(method, null);
return wrapWithJson(apiResult); return wrapWithJson(apiResult);
} }
private static JsonElement wrapWithJson(String apiResult) { private static JsonElement wrapWithJson(String apiResult) {
JsonElement element = parser.parse(apiResult); JsonElement element = parser.parse(apiResult);
return element; return element;
} }
} }

View File

@@ -7,160 +7,90 @@ import java.util.Map;
public class QueryBuilder { 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;
/** public QueryBuilder() {
* Creates an empty QueryBuilder from a given apikey. this(null);
* <br>Note that in order to use the QueryBuilder an apiMethod String has to be set. }
* @param apiKey The apikey to use
*/
public QueryBuilder() {
this(null);
}
/** public QueryBuilder(String apiMethod) {
* Creates an empty QueryBuilder from a given apikey and apiMethod. this.apiMethod = apiMethod;
* }
* @param apiKey The apikey to use
* @param apiMethod The apiMethod to use
*/
public QueryBuilder(String apiMethod) {
this.apiMethod = apiMethod;
}
/** public QueryBuilder(String apiMethod, String key, String value) {
* Creates a QueryBuilder from a given apikey and apiMethod containing a single key/value parameter. this(apiMethod);
* put(key, value);
* @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) {
this(apiMethod);
put(key, value);
}
/** public QueryBuilder(String apiMethod, String key1, String value1, String key2, String value2) {
* Creates a QueryBuilder from a given apikey and apiMethod containing two key/value parameters. this(apiMethod);
* put(key1, value1);
* @param apiKey The apikey to use put(key2, value2);
* @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) {
this(apiMethod);
put(key1, value1);
put(key2, value2);
}
/** public QueryBuilder(String apiMethod, String key1, String value1, String key2, String value2, String key3, String value3) {
* Creates a QueryBuilder from a given apikey and apiMethod containing three key/value parameters. this(apiMethod);
* put(key1, value1);
* @param apiKey The apikey to use put(key2, value2);
* @param apiMethod The apiMethod to use put(key3, value3);
* @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) {
this(apiMethod);
put(key1, value1);
put(key2, value2);
put(key3, value3);
}
/** public void put(String key, Object value) {
* Adds a key/value parameter to the QueryBuilder. if(key != null && value != null) {
* @param key The parameter key if(paramMap == null) {
* @param value The parameter value paramMap = new HashMap<String, String>();
*/ }
public void put(String key, Object value) { paramMap.put(key, value.toString());
if(key != null && value != null) { }
if(paramMap == null) { }
paramMap = new HashMap<String,String>();
}
paramMap.put(key, value.toString());
}
}
/** public void put(String key1, Object value1, String key2, Object value2) {
* Adds two key/value parameters to the QueryBuilder. put(key1, value1);
* @param key1 The first parameter key put(key2, value2);
* @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) {
put(key1, value1);
put(key2, value2);
}
/** public void put(String key1, Object value1, String key2, Object value2, String key3, Object value3) {
* Adds three key/value parameters to the QueryBuilder. put(key1, value1);
* @param key1 The first parameter key put(key2, value2);
* @param value1 The first parameter value put(key3, value3);
* @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) {
put(key1, value1);
put(key2, value2);
put(key3, value3);
}
/** public void put(Map<String, Object> paraMap) {
* Adds a map of key/value parameters to the QueryBuilder. if(paraMap == null) return;
* @param paraMap The map to add for(String key : paraMap.keySet()) {
*/ put(key, paraMap.get(key));
public void put(Map<String,Object> paraMap) { }
if(paraMap == null) return; }
for(String key: paraMap.keySet()) {
put(key,paraMap.get(key));
}
}
/** public String toString() {
* Creates an URL from the QueryBuilder using the given apikey and apiMethod and applies all if(apiMethod == null) throw new IllegalArgumentException("apiMethod may not be null");
* parameters to it.
*/
public String toString() {
if(apiMethod == null) throw new IllegalArgumentException("apiMethod may not be null");
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
// build base url // build base url
sb.append(API_BASE_URL); sb.append(API_BASE_URL);
sb.append(apiMethod); sb.append(apiMethod);
// process parameters // process parameters
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;
sb.append(paramName); sb.append(paramName);
sb.append("="); sb.append("=");
String value = paramMap.get(paramName); String value = paramMap.get(paramName);
sb.append(URLEncoder.encode(value, "UTF-8")); sb.append(URLEncoder.encode(value, "UTF-8"));
} }
} }
return sb.toString(); return sb.toString();
} catch (UnsupportedEncodingException e) { } catch(UnsupportedEncodingException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
} }

View File

@@ -1,50 +1,49 @@
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 int page; private final SearchQuery searchQuery;
private List<FileInfo> files = new ArrayList<FileInfo>(); private int page;
private List<FileInfo> files = new ArrayList<FileInfo>();
private final SearchQuery searchQuery; public SearchPagination(SearchQuery searchQuery) {
this.page = -1;
this.searchQuery = searchQuery;
}
public SearchPagination(SearchQuery searchQuery) { public List<FileInfo> getFiles() {
this.page = -1; return new ArrayList<FileInfo>(files);
this.searchQuery = searchQuery; }
}
public List<FileInfo> getFiles() { public int getLoadedPages() {
return new ArrayList<FileInfo>(files); return page;
} }
public int getLoadedPages() { public boolean fetchPage() {
return page; page++;
} searchQuery.offset = page;
public boolean fetchPage() { try {
page++; FileInfo[] fis = ReplayMod.apiClient.searchFiles(searchQuery);
searchQuery.offset = page; if(fis.length <= 1) {
page--;
return false;
}
try { files.addAll(Arrays.asList(fis));
FileInfo[] fis = ReplayMod.apiClient.searchFiles(searchQuery);
if(fis.length <= 1) {
page--;
return false;
}
files.addAll(Arrays.asList(fis)); return true;
} catch(Exception e) {
return true; e.printStackTrace();
} catch(Exception e) { }
e.printStackTrace(); page--;
} return false;
page--; }
return false;
}
} }

View File

@@ -5,51 +5,52 @@ import java.net.URLEncoder;
public class SearchQuery { public class SearchQuery {
public Boolean order, singleplayer; public Boolean order, singleplayer;
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,
String auth, Integer category, Integer offset) { String auth, Integer category, Integer offset) {
this.order = order; this.order = order;
this.singleplayer = singleplayer; this.singleplayer = singleplayer;
this.player = player; this.player = player;
this.tag = tag; this.tag = tag;
this.version = version; this.version = version;
this.server = server; this.server = server;
this.name = name; this.name = name;
this.auth = auth; this.auth = auth;
this.category = category; this.category = category;
this.offset = offset; this.offset = offset;
} }
public String buildQuery() { public String buildQuery() {
String query = ""; String query = "";
boolean first = true; boolean first = true;
//Please don't slaughter me for this code, //Please don't slaughter me for this code,
//even if I deserve it, which I certainly do. //even if I deserve it, which I certainly do.
for(Field f : this.getClass().getDeclaredFields()) { for(Field f : this.getClass().getDeclaredFields()) {
try { try {
Object value = f.get(this); Object value = f.get(this);
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();
} }
} }
return query; return query;
} }
@Override @Override
public String toString() { public String toString() {
return buildQuery(); return buildQuery();
} }
} }

View File

@@ -1,120 +1,123 @@
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();
private static final Gson gson = new Gson(); private static final Gson gson = new Gson();
/** /**
* Returns a Json String from the given QueryBuilder * Returns a Json String from the given QueryBuilder
* @param query The QueryBuilder to use *
* @return A Json String from the API * @param query The QueryBuilder to use
* @throws IOException * @return A Json String from the API
* @throws ApiException * @throws IOException
*/ * @throws ApiException
public static String invoke(QueryBuilder query) throws IOException, ApiException { */
return invokeImpl(query.toString()); public static String invoke(QueryBuilder query) throws IOException, ApiException {
} return invokeImpl(query.toString());
}
/** /**
* 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 *
* @return A Json String from the API * @param url The URL to parse the Json from
* @throws IOException * @return A Json String from the API
* @throws ApiException * @throws IOException
*/ * @throws ApiException
public static String invokeUrl(String url) throws IOException, ApiException { */
return invokeImpl(url); public static String invokeUrl(String url) throws IOException, ApiException {
} return invokeImpl(url);
}
/** /**
* Returns a Json String from the API * Returns a Json String from the API
* @param apiKey The apikey to use *
* @param method The apiMethod to be called * @param apiKey The apikey to use
* @param paramMap The parameters to apply * @param method The apiMethod to be called
* @return A Json String from the API * @param paramMap The parameters to apply
* @throws IOException * @return A Json String from the API
* @throws ApiException * @throws IOException
*/ * @throws ApiException
public static String invoke(String method, Map<String,Object> paramMap) throws IOException, ApiException { */
return invokeImpl(method, paramMap); public static String invoke(String method, Map<String, Object> paramMap) throws IOException, ApiException {
} 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 method The apiMethod to be called * @param apiKey The apikey to use
* @return A Json String from the API * @param method The apiMethod to be called
* @throws IOException * @return A Json String from the API
* @throws ApiException * @throws IOException
*/ * @throws ApiException
public static String invoke(String method) throws IOException, ApiException { */
return invokeImpl(method, null); public static String invoke(String method) throws IOException, ApiException {
} return invokeImpl(method, null);
}
private static String invokeImpl(String urlString) throws IOException, ApiException { private static String invokeImpl(String urlString) throws IOException, ApiException {
// read response // read response
String responseContent = null; String responseContent = null;
InputStream is = null; InputStream is = null;
HttpURLConnection httpUrlConnection = null; HttpURLConnection httpUrlConnection = null;
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();
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 = "";
} }
JsonObject response = jsonParser.parse(responseContent).getAsJsonObject(); JsonObject response = jsonParser.parse(responseContent).getAsJsonObject();
throw new ApiException(gson.fromJson(response, ApiError.class)); throw new ApiException(gson.fromJson(response, ApiError.class));
} }
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;
} finally { } finally {
if(is != null) { if(is != null) {
is.close(); is.close();
} }
if(httpUrlConnection != null) { if(httpUrlConnection != null) {
httpUrlConnection.disconnect(); httpUrlConnection.disconnect();
} }
} }
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,26 +2,28 @@ package eu.crushedpixel.replaymod.api.client.holders;
public class ApiError { public class ApiError {
public ApiError(int id, String desc) { private int id;
this.id = id; private String desc;
this.desc = desc; public ApiError(int id, String desc) {
} this.id = id;
this.desc = desc;
}
private int id; public int getId() {
private String desc; return id;
}
public int getId() { public void setId(int id) {
return id; this.id = id;
} }
public void setId(int id) {
this.id = id; public String getDesc() {
} return desc;
public String getDesc() { }
return desc;
} public void setDesc(String desc) {
public void setDesc(String desc) { this.desc = desc;
this.desc = desc; }
}
} }

View File

@@ -2,13 +2,13 @@ package eu.crushedpixel.replaymod.api.client.holders;
public class AuthKey { public class AuthKey {
private String auth; private String auth;
public AuthKey(String authkey) { public AuthKey(String authkey) {
this.auth = authkey; this.auth = authkey;
} }
public String getAuthkey() { public String getAuthkey() {
return auth; return auth;
} }
} }

View File

@@ -2,38 +2,38 @@ package eu.crushedpixel.replaymod.api.client.holders;
public enum Category { public enum Category {
SURVIVAL(0), MINIGAME(1), BUILD(2); SURVIVAL(0), MINIGAME(1), BUILD(2);
private int id; private int id;
Category(int id) { Category(int id) {
this.id = id; this.id = id;
} }
public int getId() { public int getId() {
return this.id; return this.id;
} }
public Category fromId(int id) { public Category fromId(int id) {
for(Category c : values()) { for(Category c : values()) {
if(c.id == id) return c; if(c.id == id) return c;
} }
return null; return null;
} }
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

@@ -2,9 +2,9 @@ package eu.crushedpixel.replaymod.api.client.holders;
public class Donated { public class Donated {
private boolean donated = false; private boolean donated = false;
public boolean hasDonated() { public boolean hasDonated() {
return donated; return donated;
} }
} }

View File

@@ -4,61 +4,70 @@ import eu.crushedpixel.replaymod.recording.ReplayMetaData;
public class FileInfo { public class FileInfo {
private int id; private int id;
private ReplayMetaData metadata; private ReplayMetaData metadata;
private String owner; private String owner;
private Rating ratings; private Rating ratings;
private int size; private int size;
private int category; private int category;
private int downloads; private int downloads;
private String name; private String name;
private boolean thumbnail; private boolean thumbnail;
public FileInfo(int id, ReplayMetaData metadata, String owner, public FileInfo(int id, ReplayMetaData metadata, String owner,
Rating ratings, int size, int category, int downloads, String name, Rating ratings, int size, int category, int downloads, String name,
boolean thumbnail) { boolean thumbnail) {
this.id = id; this.id = id;
this.metadata = metadata; this.metadata = metadata;
this.owner = owner; this.owner = owner;
this.ratings = ratings; this.ratings = ratings;
this.size = size; this.size = size;
this.category = category; this.category = category;
this.downloads = downloads; this.downloads = downloads;
this.name = name; this.name = name;
this.thumbnail = thumbnail; this.thumbnail = thumbnail;
} }
public int getId() { public int getId() {
return id; return id;
} }
public ReplayMetaData getMetadata() {
return metadata; public ReplayMetaData getMetadata() {
} return metadata;
public String getOwner() { }
return owner;
} public String getOwner() {
public Rating getRatings() { return owner;
return ratings; }
}
public int getSize() { public Rating getRatings() {
return size; return ratings;
} }
public int getCategory() {
return category; public int getSize() {
} return size;
public int getDownloads() { }
return downloads;
} public int getCategory() {
public String getName() { return category;
return name; }
}
public void setName(String name) { public int getDownloads() {
this.name = name; return downloads;
} }
public boolean hasThumbnail() {
return thumbnail; public String getName() {
} return name;
}
public void setName(String name) {
this.name = name;
}
public boolean hasThumbnail() {
return thumbnail;
}
} }

View File

@@ -2,13 +2,13 @@ package eu.crushedpixel.replaymod.api.client.holders;
public class Rating { public class Rating {
private int negative, positive; private int negative, positive;
public int getNegative() { public int getNegative() {
return negative; return negative;
} }
public int getPositive() { public int getPositive() {
return positive; return positive;
} }
} }

View File

@@ -2,9 +2,9 @@ package eu.crushedpixel.replaymod.api.client.holders;
public class SearchResult { public class SearchResult {
private FileInfo[] results; private FileInfo[] results;
public FileInfo[] getResults() { public FileInfo[] getResults() {
return results; return results;
} }
} }

View File

@@ -2,9 +2,9 @@ package eu.crushedpixel.replaymod.api.client.holders;
public class Success { public class Success {
private boolean success = false; private boolean success = false;
public boolean isSuccess() { public boolean isSuccess() {
return success; return success;
} }
} }

View File

@@ -2,19 +2,21 @@ package eu.crushedpixel.replaymod.api.client.holders;
public class UserFiles { public class UserFiles {
private String user; private String user;
private FileInfo[] files; private FileInfo[] files;
private int total_size; private int total_size;
public String getUser() { public String getUser() {
return user; return user;
} }
public FileInfo[] getFiles() {
return files; public FileInfo[] getFiles() {
} return files;
public int getTotal_size() { }
return total_size;
} public int getTotal_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,75 +10,77 @@ 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 {
@Override @Override
public byte[] transform(String name, String transformedName, public byte[] transform(String name, String transformedName,
byte[] basicClass) { byte[] basicClass) {
if(name.equals("cqh")) { if(name.equals("cqh")) {
return patchRenderEffectMethod(name, basicClass, true); return patchRenderEffectMethod(name, basicClass, true);
} }
if(name.equals("net.minecraft.client.renderer.entity.RenderItem")) { if(name.equals("net.minecraft.client.renderer.entity.RenderItem")) {
return patchRenderEffectMethod(name, basicClass, false); return patchRenderEffectMethod(name, basicClass, false);
} }
return basicClass; return basicClass;
} }
public byte[] patchRenderEffectMethod(String name, byte[] bytes, boolean obfuscated) { public byte[] patchRenderEffectMethod(String name, byte[] bytes, boolean obfuscated) {
System.out.println("REPLAY MOD CORE PATCHER: Inside RenderItem class"); System.out.println("REPLAY MOD CORE PATCHER: Inside RenderItem class");
String methodName = obfuscated ? "a" : "renderEffect"; String methodName = obfuscated ? "a" : "renderEffect";
String classDescriptor = obfuscated ? "(Lcxe;)V" : "(Lnet/minecraft/client/resources/model/IBakedModel;)V"; String classDescriptor = obfuscated ? "(Lcxe;)V" : "(Lnet/minecraft/client/resources/model/IBakedModel;)V";
String minecraftClass = obfuscated ? "bsu" : "net/minecraft/client/Minecraft"; String minecraftClass = obfuscated ? "bsu" : "net/minecraft/client/Minecraft";
String getSystemTime = obfuscated ? "I" : "getSystemTime"; String getSystemTime = obfuscated ? "I" : "getSystemTime";
String sysTimeDesc = "()J"; String sysTimeDesc = "()J";
ClassNode classNode = new ClassNode(); ClassNode classNode = new ClassNode();
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()) {
MethodNode m = iterator.next(); MethodNode m = iterator.next();
if(m.name.equals(methodName) && m.desc.equals(classDescriptor)) { if(m.name.equals(methodName) && m.desc.equals(classDescriptor)) {
System.out.println("REPLAY MOD CORE PATCHER: Inside renderEffect method"); System.out.println("REPLAY MOD CORE PATCHER: Inside renderEffect method");
Iterator<AbstractInsnNode> nodeIterator = m.instructions.iterator(); Iterator<AbstractInsnNode> nodeIterator = m.instructions.iterator();
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",
min.desc, min.itf); min.desc, min.itf);
toInsert.add(new Pair<AbstractInsnNode, AbstractInsnNode>(min, n)); toInsert.add(new Pair<AbstractInsnNode, AbstractInsnNode>(min, n));
} }
} }
} }
for(Pair<AbstractInsnNode, AbstractInsnNode> pair : toInsert) { for(Pair<AbstractInsnNode, AbstractInsnNode> pair : toInsert) {
m.instructions.insertBefore(pair.first(), pair.second()); m.instructions.insertBefore(pair.first(), pair.second());
m.instructions.remove(pair.first()); m.instructions.remove(pair.first());
} }
} }
} }
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer); classNode.accept(writer);
return writer.toByteArray(); return writer.toByteArray();
} }
// net.minecraft.client.renderer.entity.RenderItem -> cqh // net.minecraft.client.renderer.entity.RenderItem -> cqh
// private void renderEffect(IBakedModel model) -> private void a(cxe paramcxe) // private void renderEffect(IBakedModel model) -> private void a(cxe paramcxe)
// float f = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F / 8.0F; -> float f1 = (float)(bsu.I() % 3000L) / 3000.0F / 8.0F; // float f = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F / 8.0F; -> float f1 = (float)(bsu.I() % 3000L) / 3000.0F / 8.0F;
} }

View File

@@ -1,32 +1,33 @@
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
public String[] getASMTransformerClass() { public String[] getASMTransformerClass() {
return new String[]{ClassTransformer.class.getName()}; return new String[]{ClassTransformer.class.getName()};
} }
@Override @Override
public String getModContainerClass() { public String getModContainerClass() {
return null; return null;
} }
@Override @Override
public String getSetupClass() { public String getSetupClass() {
return null; return null;
} }
@Override @Override
public void injectData(Map<String, Object> data) {} public void injectData(Map<String, Object> data) {
}
@Override @Override
public String getAccessTransformerClass() { public String getAccessTransformerClass() {
return null; return null;
} }
} }

View File

@@ -1,195 +1,190 @@
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 Vec3 direction; private static final double MAX_SPEED = 20;
private double motion; private Vec3 direction;
private double motion;
private Field drawBlockOutline;
private double decay = 4;
private Field drawBlockOutline; private long lastCall = 0;
private static final double MAX_SPEED = 20; private boolean speedup = false;
private double decay = 4; public CameraEntity(World worldIn) {
//super(worldIn);
super(worldIn, Minecraft.getMinecraft().getSession().getProfile());
}
private long lastCall = 0; //frac = time since last tick
public void updateMovement() {
Minecraft mc = Minecraft.getMinecraft();
if(ReplayHandler.getCameraEntity() != null && mc.thePlayer != null
&& mc.getRenderViewEntity() != null) {
//Aligns the particle rotation
mc.thePlayer.rotationPitch = mc.getRenderViewEntity().rotationPitch;
mc.thePlayer.rotationYaw = mc.getRenderViewEntity().rotationYaw;
private boolean speedup = false; //removes water/suffocation/shadow overlays in screen
mc.thePlayer.posX = 0;
mc.thePlayer.posY = 500;
mc.thePlayer.posZ = 0;
}
//frac = time since last tick if(direction == null || motion < 0.1) {
public void updateMovement() { lastCall = Sys.getTime();
Minecraft mc = Minecraft.getMinecraft(); return;
if(ReplayHandler.getCameraEntity() != null && mc.thePlayer != null }
&& mc.getRenderViewEntity() != null) {
//Aligns the particle rotation
mc.thePlayer.rotationPitch = mc.getRenderViewEntity().rotationPitch;
mc.thePlayer.rotationYaw = mc.getRenderViewEntity().rotationYaw;
//removes water/suffocation/shadow overlays in screen long frac = Sys.getTime() - lastCall;
mc.thePlayer.posX = 0;
mc.thePlayer.posY = 500;
mc.thePlayer.posZ = 0;
}
if(direction == null || motion < 0.1) { if(frac == 0) return;
lastCall = Sys.getTime();
return;
}
long frac = Sys.getTime() - lastCall; Vec3 movement = direction.normalize();
double factor = motion * (frac / 1000D);
if(frac == 0) return; moveRelative(movement.xCoord * factor, movement.yCoord * factor, movement.zCoord * factor);
Vec3 movement = direction.normalize(); double decFac = Math.max(0, 1 - (decay * (frac / 1000D)));
double factor = motion*(frac/1000D);
moveRelative(movement.xCoord*factor, movement.yCoord*factor, movement.zCoord*factor); if(!speedup) {
motion *= decFac;
} else {
speedup = false;
}
double decFac = Math.max(0, 1-(decay*(frac/1000D))); lastCall = Sys.getTime();
}
if(!speedup) { public void setDirection(float pitch, float yaw) {
motion *= decFac; this.setRotation(yaw, pitch);
} else { }
speedup = false;
}
lastCall = Sys.getTime(); public void speedUp() {
} this.motion = Math.min(MAX_SPEED, motion + 0.1);
speedup = true;
}
public void setDirection(float pitch, float yaw) { public void setMovement(MoveDirection dir) {
this.setRotation(yaw, pitch); Vec3 oldDir = direction;
}
public void speedUp() { switch(dir) {
this.motion = Math.min(MAX_SPEED, motion+0.1); case BACKWARD:
speedup = true; direction = this.getVectorForRotation(-rotationPitch, rotationYaw - 180);
} break;
case DOWN:
direction = this.getVectorForRotation(90, 0);
break;
case FORWARD:
direction = this.getVectorForRotation(rotationPitch, rotationYaw);
break;
case LEFT:
direction = this.getVectorForRotation(0, rotationYaw - 90);
break;
case RIGHT:
direction = this.getVectorForRotation(0, rotationYaw + 90);
break;
case UP:
direction = this.getVectorForRotation(-90, 0);
break;
}
public void setMovement(MoveDirection dir) { if(oldDir != null)
Vec3 oldDir = direction; direction = direction.normalize().add(new Vec3(oldDir.xCoord * (motion / 4f), oldDir.yCoord * (motion / 4f), oldDir.zCoord * (motion / 4f)).normalize());
}
switch(dir) { public void moveAbsolute(double x, double y, double z) {
case BACKWARD: if(ReplayHandler.isInPath()) return;
direction = this.getVectorForRotation(-rotationPitch, rotationYaw-180); this.lastTickPosX = this.prevPosX = this.posX = x;
break; this.lastTickPosY = this.prevPosY = this.posY = y;
case DOWN: this.lastTickPosZ = this.prevPosZ = this.posZ = z;
direction = this.getVectorForRotation(90, 0); }
break;
case FORWARD:
direction = this.getVectorForRotation(rotationPitch, rotationYaw);
break;
case LEFT:
direction = this.getVectorForRotation(0, rotationYaw-90);
break;
case RIGHT:
direction = this.getVectorForRotation(0, rotationYaw+90);
break;
case UP:
direction = this.getVectorForRotation(-90, 0);
break;
}
if(oldDir != null) direction = direction.normalize().add(new Vec3(oldDir.xCoord*(motion/4f), oldDir.yCoord*(motion/4f), oldDir.zCoord*(motion/4f)).normalize()); public void moveRelative(double x, double y, double z) {
} if(ReplayHandler.isInPath()) return;
this.lastTickPosX = this.prevPosX = this.posX = this.posX + x;
this.lastTickPosY = this.prevPosY = this.posY = this.posY + y;
this.lastTickPosZ = this.prevPosZ = this.posZ = this.posZ + z;
}
public void moveAbsolute(double x, double y, double z) { public void movePath(Position pos) {
if(ReplayHandler.isInPath()) return; this.prevRotationPitch = this.rotationPitch = pos.getPitch();
this.lastTickPosX = this.prevPosX = this.posX = x; this.prevRotationYaw = this.rotationYaw = pos.getYaw();
this.lastTickPosY = this.prevPosY = this.posY = y; this.lastTickPosX = this.prevPosX = this.posX = pos.getX();
this.lastTickPosZ = this.prevPosZ = this.posZ = z; this.lastTickPosY = this.prevPosY = this.posY = pos.getY();
} this.lastTickPosZ = this.prevPosZ = this.posZ = pos.getZ();
}
public void moveRelative(double x, double y, double z) { @Override
if(ReplayHandler.isInPath()) return; protected void entityInit() {
this.lastTickPosX = this.prevPosX = this.posX = this.posX+x; this.dataWatcher = new LesserDataWatcher(this);
this.lastTickPosY = this.prevPosY = this.posY = this.posY+y; }
this.lastTickPosZ = this.prevPosZ = this.posZ = this.posZ+z;
}
public void movePath(Position pos) { @Override
this.prevRotationPitch = this.rotationPitch = pos.getPitch(); public void setAngles(float yaw, float pitch) {
this.prevRotationYaw = this.rotationYaw = pos.getYaw(); this.rotationYaw = (float) ((double) this.rotationYaw + (double) yaw * 0.15D);
this.lastTickPosX = this.prevPosX = this.posX = pos.getX(); this.rotationPitch = (float) ((double) this.rotationPitch - (double) pitch * 0.15D);
this.lastTickPosY = this.prevPosY = this.posY = pos.getY(); this.rotationPitch = MathHelper.clamp_float(this.rotationPitch, -90.0F, 90.0F);
this.lastTickPosZ = this.prevPosZ = this.posZ = pos.getZ(); this.prevRotationPitch = this.rotationPitch;
} this.prevRotationYaw = this.rotationYaw;
}
@Override
protected void entityInit() {
this.dataWatcher = new LesserDataWatcher(this);
}
public CameraEntity(World worldIn) { @Override
//super(worldIn); public MovingObjectPosition rayTrace(double p_174822_1_, float p_174822_3_) {
super(worldIn, Minecraft.getMinecraft().getSession().getProfile()); return null;
} }
@Override @Override
public void setAngles(float yaw, float pitch) public boolean canBePushed() {
{ return false;
this.rotationYaw = (float)((double)this.rotationYaw + (double)yaw * 0.15D); }
this.rotationPitch = (float)((double)this.rotationPitch - (double)pitch * 0.15D);
this.rotationPitch = MathHelper.clamp_float(this.rotationPitch, -90.0F, 90.0F);
this.prevRotationPitch = this.rotationPitch;
this.prevRotationYaw = this.rotationYaw;
}
@Override
protected void createRunningParticles() {
}
@Override @Override
public MovingObjectPosition rayTrace(double p_174822_1_, float p_174822_3_) { public boolean canBeCollidedWith() {
return null; return false;
} }
@Override @Override
public boolean canBePushed() { public boolean canRenderOnFire() {
return false; return false;
} }
@Override @Override
protected void createRunningParticles() {} public void setCurrentItemOrArmor(int slotIn, ItemStack stack) {
}
@Override @Override
public boolean canBeCollidedWith() { public ItemStack[] getInventory() {
return false; return null;
} }
@Override
public boolean canRenderOnFire() {
return false;
}
public enum MoveDirection { @Override
UP, DOWN, LEFT, RIGHT, FORWARD, BACKWARD; public boolean isSpectator() {
} return true;
}
@Override public enum MoveDirection {
public void setCurrentItemOrArmor(int slotIn, ItemStack stack) {} UP, DOWN, LEFT, RIGHT, FORWARD, BACKWARD;
}
@Override
public ItemStack[] getInventory() {
return null;
}
@Override
public boolean isSpectator() {
return true;
}
} }

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,175 +21,183 @@ 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 final Minecraft mc = Minecraft.getMinecraft();
private final List<Class> allowedGUIs = new ArrayList<Class>() {
{
add(GuiReplaySettings.class);
add(GuiReplaySaving.class);
add(GuiIngameMenu.class);
add(GuiOptions.class);
add(GuiVideoSettings.class);
}
};
private int replayCount = 0;
private GuiButton editorButton;
private static int replayCount = 0; @SubscribeEvent
public void onGui(GuiOpenEvent event) {
if(VideoWriter.isRecording() && !(event.gui instanceof GuiCancelRender)) {
event.gui = null;
return;
}
private static List<Class> allowedGUIs = new ArrayList<Class>() { if(!(event.gui instanceof GuiReplayViewer || event.gui instanceof GuiUploadFile))
{ ResourceHelper.freeAllResources();
add(GuiReplaySettings.class);
add(GuiReplaySaving.class);
add(GuiIngameMenu.class);
add(GuiOptions.class);
add(GuiVideoSettings.class);
}
};
@SubscribeEvent if(event.gui instanceof GuiMainMenu) {
public void onGui(GuiOpenEvent event) { if(ReplayMod.firstMainMenu) {
if(VideoWriter.isRecording() && !(event.gui instanceof GuiCancelRender)) { ReplayMod.firstMainMenu = false;
event.gui = null; event.gui = new GuiLoginPrompt(event.gui, event.gui);
return; return;
} } else {
try {
MCTimerHandler.setTimerSpeed(1);
} catch(Exception e) {
e.printStackTrace();
}
}
}
if(!(event.gui instanceof GuiReplayViewer || event.gui instanceof GuiUploadFile)) ResourceHelper.freeAllResources(); if(!AuthenticationHandler.isAuthenticated()) return;
if(event.gui != null && GuiReplaySaving.replaySaving && !allowedGUIs.contains(event.gui.getClass())) {
event.gui = new GuiReplaySaving(event.gui);
return;
}
if(event.gui instanceof GuiChat || event.gui instanceof GuiInventory) {
if(ReplayHandler.isInReplay()) {
event.setCanceled(true);
}
} else if(event.gui instanceof GuiDisconnected) {
if(!ReplayHandler.isInReplay() && System.currentTimeMillis() - ReplayHandler.lastExit < 5000) {
event.setCanceled(true);
}
}
}
if(event.gui instanceof GuiMainMenu) { @SubscribeEvent
if(ReplayMod.firstMainMenu) { public void onDraw(DrawScreenEvent e) {
ReplayMod.firstMainMenu = false; if(e.gui instanceof GuiMainMenu) {
event.gui = new GuiLoginPrompt(event.gui, event.gui); e.gui.drawString(mc.fontRendererObj, "Replay Mod:", 5, 5, Color.WHITE.getRGB());
return; if(AuthenticationHandler.isAuthenticated()) {
} else { e.gui.drawString(mc.fontRendererObj, "LOGGED IN", 5, 15, DARK_GREEN.getRGB());
try { } else {
MCTimerHandler.setTimerSpeed(1); e.gui.drawString(mc.fontRendererObj, "LOGGED OUT", 5, 15, DARK_RED.getRGB());
} catch (Exception e) { }
e.printStackTrace();
}
}
}
if(!AuthenticationHandler.isAuthenticated()) return; if(replayCount == 0) {
if(event.gui != null && GuiReplaySaving.replaySaving && !allowedGUIs.contains(event.gui.getClass())) { if(editorButton.isMouseOver()) {
event.gui = new GuiReplaySaving(event.gui); Point mouse = MouseUtils.getMousePos();
return; e.gui.drawCenteredString(mc.fontRendererObj, "At least one Replay required", (int) mouse.getX(), (int) mouse.getY() + 4, Color.RED.getRGB());
} }
if(event.gui instanceof GuiChat || event.gui instanceof GuiInventory) { } else if(!VersionValidator.isValid) {
if(ReplayHandler.isInReplay()) { if(editorButton.isMouseOver()) {
event.setCanceled(true); 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());
} }
}
}
}
else if(event.gui instanceof GuiDisconnected) { @SubscribeEvent
if(!ReplayHandler.isInReplay() && System.currentTimeMillis() - ReplayHandler.lastExit < 5000) { public void onInit(InitGuiEvent event) {
event.setCanceled(true); if(event.gui instanceof GuiIngameMenu && ReplayHandler.isInReplay()) {
} for(GuiButton b : new ArrayList<GuiButton>(event.buttonList)) {
} if(b.id == 1) {
} b.displayString = "Exit Replay";
b.yPosition -= 24 * 2;
b.id = GuiConstants.EXIT_REPLAY_BUTTON;
} else if(b.id >= 5 && b.id <= 7) {
event.buttonList.remove(b);
} else if(b.id != 4) {
b.yPosition -= 24 * 2;
}
}
} else if(event.gui instanceof GuiMainMenu) {
int i1 = event.gui.height / 4 + 24 + 10;
private static final Color DARK_RED = Color.decode("#DF0101"); for(GuiButton b : (List<GuiButton>) event.buttonList) {
private static final Color DARK_GREEN = Color.decode("#01DF01"); if(b.id != 0 && b.id != 4 && b.id != 5) {
b.yPosition = b.yPosition - 2 * 24 + 10;
}
}
@SubscribeEvent GuiButton rm = new GuiButton(GuiConstants.REPLAY_MANAGER_BUTTON_ID, event.gui.width / 2 - 100, i1 + 2 * 24, "Replay Viewer");
public void onDraw(DrawScreenEvent e) { rm.width = rm.width / 2 - 2;
if(e.gui instanceof GuiMainMenu) { //rm.enabled = AuthenticationHandler.isAuthenticated();
e.gui.drawString(mc.fontRendererObj, "Replay Mod:", 5, 5, Color.WHITE.getRGB()); event.buttonList.add(rm);
if(AuthenticationHandler.isAuthenticated()) {
e.gui.drawString(mc.fontRendererObj, "LOGGED IN", 5, 15, DARK_GREEN.getRGB());
} else {
e.gui.drawString(mc.fontRendererObj, "LOGGED OUT", 5, 15, DARK_RED.getRGB());
}
if(replayCount == 0) { replayCount = ReplayFileIO.getAllReplayFiles().size();
if(editorButton.isMouseOver()) {
Point mouse = MouseUtils.getMousePos();
e.gui.drawCenteredString(mc.fontRendererObj, "At least one Replay required", (int)mouse.getX(), (int)mouse.getY()+4, Color.RED.getRGB());
}
} else if(!VersionValidator.isValid) {
if(editorButton.isMouseOver()) {
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());
}
}
}
}
private GuiButton editorButton; 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.enabled = VersionValidator.isValid && replayCount > 0;
event.buttonList.add(re);
@SubscribeEvent editorButton = re;
public void onInit(InitGuiEvent event) {
if(event.gui instanceof GuiIngameMenu && ReplayHandler.isInReplay()) {
for(GuiButton b : new ArrayList<GuiButton>(event.buttonList)) {
if(b.id == 1) {
b.displayString = "Exit Replay";
b.yPosition -= 24*2;
b.id = GuiConstants.EXIT_REPLAY_BUTTON;
} else if(b.id >= 5 && b.id <= 7) {
event.buttonList.remove(b);
} else if(b.id != 4) {
b.yPosition -= 24*2;
}
}
} else if(event.gui instanceof GuiMainMenu) {
int i1 = event.gui.height / 4 + 24 + 10;
for(GuiButton b : (List<GuiButton>)event.buttonList) { GuiButton rc = new GuiButton(GuiConstants.REPLAY_CENTER_BUTTON_ID, event.gui.width / 2 - 100, i1 + 3 * 24, "Replay Center");
if(b.id != 0 && b.id != 4 && b.id != 5) { rc.enabled = true;
b.yPosition = b.yPosition - 2*24 + 10; event.buttonList.add(rc);
}
}
GuiButton rm = new GuiButton(GuiConstants.REPLAY_MANAGER_BUTTON_ID, event.gui.width / 2 - 100, i1 + 2*24, "Replay Viewer"); } else if(event.gui instanceof GuiOptions) {
rm.width = rm.width/2 - 2; event.buttonList.add(new GuiButton(GuiConstants.REPLAY_OPTIONS_BUTTON_ID,
//rm.enabled = AuthenticationHandler.isAuthenticated(); event.gui.width / 2 - 155, event.gui.height / 6 + 48 - 6 - 24, 310, 20, "Replay Mod Settings..."));
event.buttonList.add(rm); }
}
replayCount = ReplayFileIO.getAllReplayFiles().size(); @SubscribeEvent
public void onButton(ActionPerformedEvent event) {
if(!event.button.enabled) return;
if(event.gui instanceof GuiMainMenu) {
if(event.button.id == GuiConstants.REPLAY_MANAGER_BUTTON_ID) {
mc.displayGuiScreen(new GuiReplayViewer());
} else if(event.button.id == GuiConstants.REPLAY_CENTER_BUTTON_ID) {
if(AuthenticationHandler.isAuthenticated()) {
mc.displayGuiScreen(new GuiReplayCenter());
} else {
mc.displayGuiScreen(new GuiLoginPrompt(event.gui, new GuiReplayCenter()));
}
} else if(event.button.id == GuiConstants.REPLAY_EDITOR_BUTTON_ID) {
mc.displayGuiScreen(new GuiReplayStudio());
}
} else if(event.gui instanceof GuiOptions && event.button.id == GuiConstants.REPLAY_OPTIONS_BUTTON_ID) {
mc.displayGuiScreen(new GuiReplaySettings(event.gui));
}
GuiButton re = new GuiButton(GuiConstants.REPLAY_EDITOR_BUTTON_ID, event.gui.width / 2 + 2, i1 + 2*24, "Replay Editor"); if(ReplayHandler.isInReplay() && event.gui instanceof GuiIngameMenu && event.button.id == GuiConstants.EXIT_REPLAY_BUTTON) {
re.width = re.width/2 - 2; if(ReplayHandler.isInPath()) ReplayProcess.stopReplayProcess(false);
re.enabled = VersionValidator.isValid && replayCount > 0; ReplayHandler.endReplay();
event.buttonList.add(re);
editorButton = re; event.button.enabled = false;
GuiButton rc = new GuiButton(GuiConstants.REPLAY_CENTER_BUTTON_ID, event.gui.width / 2 - 100, i1 + 3*24, "Replay Center"); LightingHandler.setLighting(false);
rc.enabled = true;
event.buttonList.add(rc);
} else if(event.gui instanceof GuiOptions) { ReplayHandler.lastExit = System.currentTimeMillis();
event.buttonList.add(new GuiButton(GuiConstants.REPLAY_OPTIONS_BUTTON_ID,
event.gui.width / 2 - 155, event.gui.height / 6 + 48 - 6 - 24, 310, 20, "Replay Mod Settings..."));
}
}
@SubscribeEvent mc.theWorld.sendQuittingDisconnectingPacket();
public void onButton(ActionPerformedEvent event) { mc.loadWorld((WorldClient) null);
if(!event.button.enabled) return; mc.displayGuiScreen(new GuiMainMenu());
if(event.gui instanceof GuiMainMenu) {
if(event.button.id == GuiConstants.REPLAY_MANAGER_BUTTON_ID) {
mc.displayGuiScreen(new GuiReplayViewer());
} else if(event.button.id == GuiConstants.REPLAY_CENTER_BUTTON_ID) {
if(AuthenticationHandler.isAuthenticated()) {
mc.displayGuiScreen(new GuiReplayCenter());
} else {
mc.displayGuiScreen(new GuiLoginPrompt(event.gui, new GuiReplayCenter()));
}
} else if(event.button.id == GuiConstants.REPLAY_EDITOR_BUTTON_ID) {
mc.displayGuiScreen(new GuiReplayStudio());
}
} else if(event.gui instanceof GuiOptions && event.button.id == GuiConstants.REPLAY_OPTIONS_BUTTON_ID) {
mc.displayGuiScreen(new GuiReplaySettings(event.gui));
}
if(ReplayHandler.isInReplay() && event.gui instanceof GuiIngameMenu && event.button.id == GuiConstants.EXIT_REPLAY_BUTTON) { ReplayGuiRegistry.show();
if(ReplayHandler.isInPath()) ReplayProcess.stopReplayProcess(false); }
ReplayHandler.endReplay(); }
event.button.enabled = false;
LightingHandler.setLighting(false);
ReplayHandler.lastExit = System.currentTimeMillis();
mc.theWorld.sendQuittingDisconnectingPacket();
mc.loadWorld((WorldClient)null);
mc.displayGuiScreen(new GuiMainMenu());
ReplayGuiRegistry.show();
}
}
} }

View File

@@ -1,119 +1,113 @@
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;
@SubscribeEvent @SubscribeEvent
public void onKeyInput(KeyInputEvent event) { public void onKeyInput(KeyInputEvent event) {
if(!ReplayHandler.isInReplay()) return; if(!ReplayHandler.isInReplay()) return;
if(mc.currentScreen != null) { if(mc.currentScreen != null) {
return; return;
} }
if(Keyboard.getEventKeyState() && !Keyboard.isRepeatEvent() && Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) if(Keyboard.getEventKeyState() && !Keyboard.isRepeatEvent() && Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)
&& ReplayHandler.isInPath() && ReplayProcess.isVideoRecording() && ReplayHandler.isInPath() && ReplayProcess.isVideoRecording()
&& mc.currentScreen == null && !escDown) { && mc.currentScreen == null && !escDown) {
mc.displayGuiScreen(new GuiCancelRender()); mc.displayGuiScreen(new GuiCancelRender());
} }
escDown = Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) && Keyboard.getEventKeyState(); escDown = Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) && Keyboard.getEventKeyState();
boolean found = false; boolean found = false;
KeyBinding[] keyBindings = Minecraft.getMinecraft().gameSettings.keyBindings; KeyBinding[] keyBindings = Minecraft.getMinecraft().gameSettings.keyBindings;
for(KeyBinding kb : keyBindings) { for(KeyBinding kb : keyBindings) {
if(!kb.isKeyDown()) { if(!kb.isKeyDown()) {
continue; continue;
} }
try { try {
boolean speedup = false; boolean speedup = false;
if(ReplayHandler.isCamera()) { if(ReplayHandler.isCamera()) {
if(kb.getKeyDescription().equals("key.forward")) { if(kb.getKeyDescription().equals("key.forward")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.FORWARD); ReplayHandler.getCameraEntity().setMovement(MoveDirection.FORWARD);
speedup = true; speedup = true;
} }
if(kb.getKeyDescription().equals("key.back")) { if(kb.getKeyDescription().equals("key.back")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.BACKWARD); ReplayHandler.getCameraEntity().setMovement(MoveDirection.BACKWARD);
speedup = true; speedup = true;
} }
if(kb.getKeyDescription().equals("key.jump")) { if(kb.getKeyDescription().equals("key.jump")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.UP); ReplayHandler.getCameraEntity().setMovement(MoveDirection.UP);
speedup = true; speedup = true;
} }
if(kb.getKeyDescription().equals("key.left")) { if(kb.getKeyDescription().equals("key.left")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.LEFT); ReplayHandler.getCameraEntity().setMovement(MoveDirection.LEFT);
speedup = true; speedup = true;
} }
if(kb.getKeyDescription().equals("key.right")) { if(kb.getKeyDescription().equals("key.right")) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.RIGHT); ReplayHandler.getCameraEntity().setMovement(MoveDirection.RIGHT);
speedup = true; speedup = true;
} }
} }
if(kb.getKeyDescription().equals("key.sneak")) { if(kb.getKeyDescription().equals("key.sneak")) {
if(ReplayHandler.isCamera()) { if(ReplayHandler.isCamera()) {
ReplayHandler.getCameraEntity().setMovement(MoveDirection.DOWN); ReplayHandler.getCameraEntity().setMovement(MoveDirection.DOWN);
speedup = true; speedup = true;
} else { } else {
ReplayHandler.spectateCamera(); ReplayHandler.spectateCamera();
} }
} }
if(speedup) { if(speedup) {
ReplayHandler.getCameraEntity().speedUp(); ReplayHandler.getCameraEntity().speedUp();
} }
if(kb.getKeyDescription().equals("key.chat")) { if(kb.getKeyDescription().equals("key.chat")) {
mc.displayGuiScreen(new GuiMouseInput()); mc.displayGuiScreen(new GuiMouseInput());
break; break;
} }
//Custom registered handlers //Custom registered handlers
if(kb.getKeyDescription().equals(KeybindRegistry.KEY_THUMBNAIL) && kb.isPressed() && !found) { if(kb.getKeyDescription().equals(KeybindRegistry.KEY_THUMBNAIL) && kb.isPressed() && !found) {
TickAndRenderListener.requestScreenshot(); TickAndRenderListener.requestScreenshot();
//TODO: Make this properly work //TODO: Make this properly work
} }
if(kb.getKeyDescription().equals(KeybindRegistry.KEY_SPECTATE) && kb.isPressed() && !found) { if(kb.getKeyDescription().equals(KeybindRegistry.KEY_SPECTATE) && kb.isPressed() && !found) {
SpectateHandler.openSpectateSelection(); SpectateHandler.openSpectateSelection();
} }
if(kb.getKeyDescription().equals(KeybindRegistry.KEY_LIGHTING) && kb.isPressed()) { if(kb.getKeyDescription().equals(KeybindRegistry.KEY_LIGHTING) && kb.isPressed()) {
ReplayMod.replaySettings.setLightingEnabled(!ReplayMod.replaySettings.isLightingEnabled()); ReplayMod.replaySettings.setLightingEnabled(!ReplayMod.replaySettings.isLightingEnabled());
} }
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
found = true; found = true;
} }
} }
} }

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,425 +13,344 @@ 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 {
private static Field debugCrashKeyPressTime, rightClickDelayTimer, systemTime, leftClickCounter; private static Field debugCrashKeyPressTime, rightClickDelayTimer, systemTime, leftClickCounter;
private static Method getSystemTime, updateDebugProfilerName, private static Method getSystemTime, updateDebugProfilerName,
clickMouse, middleClickMouse, rightClickMouse, sendClickBlockToController; clickMouse, middleClickMouse, rightClickMouse, sendClickBlockToController;
private static Minecraft mc = Minecraft.getMinecraft(); static {
try {
private static float camPitch, camYaw, smoothCamPartialTicks, debugCrashKeyPressTime = Minecraft.class.getDeclaredField(MCPNames.field("field_83002_am"));
smoothCamFilterX, smoothCamFilterY; debugCrashKeyPressTime.setAccessible(true);
static { rightClickDelayTimer = Minecraft.class.getDeclaredField(MCPNames.field("field_71467_ac"));
try { rightClickDelayTimer.setAccessible(true);
debugCrashKeyPressTime = Minecraft.class.getDeclaredField(MCPNames.field("field_83002_am"));
debugCrashKeyPressTime.setAccessible(true); systemTime = Minecraft.class.getDeclaredField(MCPNames.field("field_71423_H"));
systemTime.setAccessible(true);
rightClickDelayTimer = Minecraft.class.getDeclaredField(MCPNames.field("field_71467_ac"));
rightClickDelayTimer.setAccessible(true); leftClickCounter = Minecraft.class.getDeclaredField(MCPNames.field("field_71429_W"));
leftClickCounter.setAccessible(true);
systemTime = Minecraft.class.getDeclaredField(MCPNames.field("field_71423_H"));
systemTime.setAccessible(true); getSystemTime = Minecraft.class.getDeclaredMethod(MCPNames.method("func_71386_F"));
getSystemTime.setAccessible(true);
leftClickCounter = Minecraft.class.getDeclaredField(MCPNames.field("field_71429_W"));
leftClickCounter.setAccessible(true); updateDebugProfilerName = Minecraft.class.getDeclaredMethod(MCPNames.method("func_71383_b"), int.class);
updateDebugProfilerName.setAccessible(true);
getSystemTime = Minecraft.class.getDeclaredMethod(MCPNames.method("func_71386_F"));
getSystemTime.setAccessible(true); clickMouse = Minecraft.class.getDeclaredMethod(MCPNames.method("func_147116_af"));
clickMouse.setAccessible(true);
updateDebugProfilerName = Minecraft.class.getDeclaredMethod(MCPNames.method("func_71383_b"), int.class);
updateDebugProfilerName.setAccessible(true); rightClickMouse = Minecraft.class.getDeclaredMethod(MCPNames.method("func_147121_ag"));
rightClickMouse.setAccessible(true);
clickMouse = Minecraft.class.getDeclaredMethod(MCPNames.method("func_147116_af"));
clickMouse.setAccessible(true); middleClickMouse = Minecraft.class.getDeclaredMethod(MCPNames.method("func_147112_ai"));
middleClickMouse.setAccessible(true);
rightClickMouse = Minecraft.class.getDeclaredMethod(MCPNames.method("func_147121_ag"));
rightClickMouse.setAccessible(true); sendClickBlockToController = Minecraft.class.getDeclaredMethod(MCPNames.method("func_147115_a"), boolean.class);
sendClickBlockToController.setAccessible(true);
middleClickMouse = Minecraft.class.getDeclaredMethod(MCPNames.method("func_147112_ai"));
middleClickMouse.setAccessible(true); } catch(Exception e) {
e.printStackTrace();
sendClickBlockToController = Minecraft.class.getDeclaredMethod(MCPNames.method("func_147115_a"), boolean.class); }
sendClickBlockToController.setAccessible(true); }
} catch(Exception e) { public static void runMouseKeyboardTick(Minecraft mc) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
e.printStackTrace();
} if(mc.thePlayer == null) return;
} try {
mc.mcProfiler.endStartSection("mouse");
public static void runMouseKeyboardTick(Minecraft mc) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { int i;
while(Mouse.next()) {
if(mc.thePlayer == null) return; i = Mouse.getEventButton();
try { KeyBinding.setKeyBindState(i - 100, Mouse.getEventButtonState());
mc.mcProfiler.endStartSection("mouse");
int i; if(Mouse.getEventButtonState()) {
while(Mouse.next()) { if(mc.thePlayer.isSpectator() && i == 2) {
i = Mouse.getEventButton(); mc.ingameGUI.func_175187_g().func_175261_b();
KeyBinding.setKeyBindState(i - 100, Mouse.getEventButtonState()); } else {
KeyBinding.onTick(i - 100);
if (Mouse.getEventButtonState()) }
{ }
if (mc.thePlayer.isSpectator() && i == 2)
{ long k = (Long) getSystemTime.invoke(mc) - (Long) systemTime.get(mc);
mc.ingameGUI.func_175187_g().func_175261_b();
} if(k <= 200L) {
else int j = Mouse.getEventDWheel();
{
KeyBinding.onTick(i - 100); if(j != 0) {
} if(mc.thePlayer.isSpectator()) {
} j = j < 0 ? -1 : 1;
long k = (Long)getSystemTime.invoke(mc) - (Long)systemTime.get(mc); if(mc.ingameGUI.func_175187_g().func_175262_a()) {
mc.ingameGUI.func_175187_g().func_175259_b(-j);
if (k <= 200L) } else {
{ float f = MathHelper.clamp_float(mc.thePlayer.capabilities.getFlySpeed() + (float) j * 0.005F, 0.0F, 0.2F);
int j = Mouse.getEventDWheel(); mc.thePlayer.capabilities.setFlySpeed(f);
}
if (j != 0) } else {
{ mc.thePlayer.inventory.changeCurrentItem(j);
if (mc.thePlayer.isSpectator()) }
{ }
j = j < 0 ? -1 : 1;
if(mc.currentScreen == null) {
if (mc.ingameGUI.func_175187_g().func_175262_a()) if(!mc.inGameHasFocus && Mouse.getEventButtonState()) {
{ mc.setIngameFocus();
mc.ingameGUI.func_175187_g().func_175259_b(-j); }
} } else {
else mc.currentScreen.handleMouseInput();
{ }
float f = MathHelper.clamp_float(mc.thePlayer.capabilities.getFlySpeed() + (float)j * 0.005F, 0.0F, 0.2F); }
mc.thePlayer.capabilities.setFlySpeed(f); net.minecraftforge.fml.common.FMLCommonHandler.instance().fireMouseInput();
} }
}
else if((Integer) leftClickCounter.get(mc) > 0) {
{ leftClickCounter.set(mc, (Integer) leftClickCounter.get(mc) - 1);
mc.thePlayer.inventory.changeCurrentItem(j); }
} mc.mcProfiler.endStartSection("keyboard");
}
while(Keyboard.next()) {
if (mc.currentScreen == null) i = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
{ KeyBinding.setKeyBindState(i, Keyboard.getEventKeyState());
if (!mc.inGameHasFocus && Mouse.getEventButtonState())
{ if(Keyboard.getEventKeyState()) {
mc.setIngameFocus(); KeyBinding.onTick(i);
} }
}
else if((Long) debugCrashKeyPressTime.get(mc) > 0L) {
{ if((Long) getSystemTime.invoke(mc) - (Long) debugCrashKeyPressTime.get(mc) >= 6000L) {
mc.currentScreen.handleMouseInput(); throw new ReportedException(new CrashReport("Manually triggered debug crash", new Throwable()));
} }
}
net.minecraftforge.fml.common.FMLCommonHandler.instance().fireMouseInput(); if(!Keyboard.isKeyDown(46) || !Keyboard.isKeyDown(61)) {
} debugCrashKeyPressTime.set(mc, -1);
}
if ((Integer)leftClickCounter.get(mc) > 0) } else if(Keyboard.isKeyDown(46) && Keyboard.isKeyDown(61)) {
{ debugCrashKeyPressTime.set(mc, getSystemTime.invoke(mc));
leftClickCounter.set(mc, (Integer)leftClickCounter.get(mc) - 1); }
}
mc.mcProfiler.endStartSection("keyboard"); mc.dispatchKeypresses();
while (Keyboard.next()) if(Keyboard.getEventKeyState()) {
{ if(i == 62 && mc.entityRenderer != null) {
i = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey(); mc.entityRenderer.switchUseShader();
KeyBinding.setKeyBindState(i, Keyboard.getEventKeyState()); }
if (Keyboard.getEventKeyState()) if(mc.currentScreen != null) {
{ mc.currentScreen.handleKeyboardInput();
KeyBinding.onTick(i); } else {
} if(i == 1) {
mc.displayInGameMenu();
if ((Long)debugCrashKeyPressTime.get(mc) > 0L) }
{
if ((Long)getSystemTime.invoke(mc) - (Long)debugCrashKeyPressTime.get(mc) >= 6000L) if(i == 32 && Keyboard.isKeyDown(61) && mc.ingameGUI != null) {
{ mc.ingameGUI.getChatGUI().clearChatMessages();
throw new ReportedException(new CrashReport("Manually triggered debug crash", new Throwable())); }
}
if(i == 31 && Keyboard.isKeyDown(61)) {
if (!Keyboard.isKeyDown(46) || !Keyboard.isKeyDown(61)) mc.refreshResources();
{ }
debugCrashKeyPressTime.set(mc, -1);
} if(i == 17 && Keyboard.isKeyDown(61)) {
} ;
else if (Keyboard.isKeyDown(46) && Keyboard.isKeyDown(61)) }
{
debugCrashKeyPressTime.set(mc, getSystemTime.invoke(mc)); if(i == 18 && Keyboard.isKeyDown(61)) {
} ;
}
mc.dispatchKeypresses();
if(i == 47 && Keyboard.isKeyDown(61)) {
if (Keyboard.getEventKeyState()) ;
{ }
if (i == 62 && mc.entityRenderer != null)
{ if(i == 38 && Keyboard.isKeyDown(61)) {
mc.entityRenderer.switchUseShader(); ;
} }
if (mc.currentScreen != null) if(i == 22 && Keyboard.isKeyDown(61)) {
{ ;
mc.currentScreen.handleKeyboardInput(); }
}
else if(i == 20 && Keyboard.isKeyDown(61)) {
{ mc.refreshResources();
if (i == 1) }
{
mc.displayInGameMenu(); if(i == 33 && Keyboard.isKeyDown(61)) {
} boolean flag1 = Keyboard.isKeyDown(42) | Keyboard.isKeyDown(54);
mc.gameSettings.setOptionValue(GameSettings.Options.RENDER_DISTANCE, flag1 ? -1 : 1);
if (i == 32 && Keyboard.isKeyDown(61) && mc.ingameGUI != null) }
{
mc.ingameGUI.getChatGUI().clearChatMessages(); if(i == 30 && Keyboard.isKeyDown(61)) {
} mc.renderGlobal.loadRenderers();
}
if (i == 31 && Keyboard.isKeyDown(61))
{ if(i == 35 && Keyboard.isKeyDown(61)) {
mc.refreshResources(); mc.gameSettings.advancedItemTooltips = !mc.gameSettings.advancedItemTooltips;
} mc.gameSettings.saveOptions();
}
if (i == 17 && Keyboard.isKeyDown(61))
{ if(i == 48 && Keyboard.isKeyDown(61)) {
; mc.getRenderManager().setDebugBoundingBox(!mc.getRenderManager().isDebugBoundingBox());
} }
if (i == 18 && Keyboard.isKeyDown(61)) if(i == 25 && Keyboard.isKeyDown(61)) {
{ mc.gameSettings.pauseOnLostFocus = !mc.gameSettings.pauseOnLostFocus;
; mc.gameSettings.saveOptions();
} }
if (i == 47 && Keyboard.isKeyDown(61)) if(i == 59) {
{ mc.gameSettings.hideGUI = !mc.gameSettings.hideGUI;
; }
}
if(i == 61) {
if (i == 38 && Keyboard.isKeyDown(61)) mc.gameSettings.showDebugInfo = !mc.gameSettings.showDebugInfo;
{ mc.gameSettings.showDebugProfilerChart = GuiScreen.isShiftKeyDown();
; }
}
if(mc.gameSettings.keyBindTogglePerspective.isPressed()) {
if (i == 22 && Keyboard.isKeyDown(61)) ++mc.gameSettings.thirdPersonView;
{
; if(mc.gameSettings.thirdPersonView > 2) {
} mc.gameSettings.thirdPersonView = 0;
}
if (i == 20 && Keyboard.isKeyDown(61))
{ if(mc.gameSettings.thirdPersonView == 0) {
mc.refreshResources(); mc.entityRenderer.loadEntityShader(mc.getRenderViewEntity());
} } else if(mc.gameSettings.thirdPersonView == 1) {
mc.entityRenderer.loadEntityShader((Entity) null);
if (i == 33 && Keyboard.isKeyDown(61)) }
{ }
boolean flag1 = Keyboard.isKeyDown(42) | Keyboard.isKeyDown(54);
mc.gameSettings.setOptionValue(GameSettings.Options.RENDER_DISTANCE, flag1 ? -1 : 1); if(mc.gameSettings.keyBindSmoothCamera.isPressed()) {
} mc.gameSettings.smoothCamera = !mc.gameSettings.smoothCamera;
}
if (i == 30 && Keyboard.isKeyDown(61)) }
{
mc.renderGlobal.loadRenderers(); if(mc.gameSettings.showDebugInfo && mc.gameSettings.showDebugProfilerChart) {
} if(i == 11) {
updateDebugProfilerName.invoke(mc, 0);
if (i == 35 && Keyboard.isKeyDown(61)) }
{
mc.gameSettings.advancedItemTooltips = !mc.gameSettings.advancedItemTooltips; for(int l = 0; l < 9; ++l) {
mc.gameSettings.saveOptions(); if(i == 2 + l) {
} updateDebugProfilerName.invoke(mc, l + 1);
}
if (i == 48 && Keyboard.isKeyDown(61)) }
{ }
mc.getRenderManager().setDebugBoundingBox(!mc.getRenderManager().isDebugBoundingBox()); }
} net.minecraftforge.fml.common.FMLCommonHandler.instance().fireKeyInput();
}
if (i == 25 && Keyboard.isKeyDown(61))
{ for(i = 0; i < 9; ++i) {
mc.gameSettings.pauseOnLostFocus = !mc.gameSettings.pauseOnLostFocus; if(mc.gameSettings.keyBindsHotbar[i].isPressed()) {
mc.gameSettings.saveOptions(); if(mc.thePlayer.isSpectator()) {
} mc.ingameGUI.func_175187_g().func_175260_a(i);
} else {
if (i == 59) mc.thePlayer.inventory.currentItem = i;
{ }
mc.gameSettings.hideGUI = !mc.gameSettings.hideGUI; }
} }
if (i == 61) boolean flag = mc.gameSettings.chatVisibility != EntityPlayer.EnumChatVisibility.HIDDEN;
{
mc.gameSettings.showDebugInfo = !mc.gameSettings.showDebugInfo; while(mc.gameSettings.keyBindInventory.isPressed()) {
mc.gameSettings.showDebugProfilerChart = GuiScreen.isShiftKeyDown(); if(mc.playerController.isRidingHorse()) {
} mc.thePlayer.sendHorseInventory();
} else {
if (mc.gameSettings.keyBindTogglePerspective.isPressed()) mc.getNetHandler().addToSendQueue(new C16PacketClientStatus(C16PacketClientStatus.EnumState.OPEN_INVENTORY_ACHIEVEMENT));
{ mc.displayGuiScreen(new GuiInventory(mc.thePlayer));
++mc.gameSettings.thirdPersonView; }
}
if (mc.gameSettings.thirdPersonView > 2)
{ while(mc.gameSettings.keyBindDrop.isPressed()) {
mc.gameSettings.thirdPersonView = 0; if(!mc.thePlayer.isSpectator()) {
} mc.thePlayer.dropOneItem(GuiScreen.isCtrlKeyDown());
}
if (mc.gameSettings.thirdPersonView == 0) }
{
mc.entityRenderer.loadEntityShader(mc.getRenderViewEntity()); while(mc.gameSettings.keyBindChat.isPressed() && flag) {
} mc.displayGuiScreen(new GuiChat());
else if (mc.gameSettings.thirdPersonView == 1) }
{
mc.entityRenderer.loadEntityShader((Entity)null); if(mc.currentScreen == null && mc.gameSettings.keyBindCommand.isPressed() && flag) {
} mc.displayGuiScreen(new GuiChat("/"));
} }
if (mc.gameSettings.keyBindSmoothCamera.isPressed()) if(mc.thePlayer != null && mc.thePlayer.isUsingItem()) {
{ if(!mc.gameSettings.keyBindUseItem.isKeyDown()) {
mc.gameSettings.smoothCamera = !mc.gameSettings.smoothCamera; mc.playerController.onStoppedUsingItem(mc.thePlayer);
} }
}
label435:
if (mc.gameSettings.showDebugInfo && mc.gameSettings.showDebugProfilerChart)
{ while(true) {
if (i == 11) if(!mc.gameSettings.keyBindAttack.isPressed()) {
{ while(mc.gameSettings.keyBindUseItem.isPressed()) {
updateDebugProfilerName.invoke(mc, 0); ;
} }
for (int l = 0; l < 9; ++l) while(true) {
{ if(mc.gameSettings.keyBindPickBlock.isPressed()) {
if (i == 2 + l) continue;
{ }
updateDebugProfilerName.invoke(mc, l+1);
} break label435;
} }
} }
} }
net.minecraftforge.fml.common.FMLCommonHandler.instance().fireKeyInput(); } else {
} while(mc.gameSettings.keyBindAttack.isPressed()) {
if(mc != null)
for (i = 0; i < 9; ++i) try {
{ clickMouse.invoke(mc);
if (mc.gameSettings.keyBindsHotbar[i].isPressed()) } catch(Exception e) {
{ }
if (mc.thePlayer.isSpectator())
{ }
mc.ingameGUI.func_175187_g().func_175260_a(i);
} while(mc.gameSettings.keyBindUseItem.isPressed()) {
else if(mc != null)
{ try {
mc.thePlayer.inventory.currentItem = i; rightClickMouse.invoke(mc);
} } catch(Exception e) {
} }
} }
boolean flag = mc.gameSettings.chatVisibility != EntityPlayer.EnumChatVisibility.HIDDEN; while(mc.gameSettings.keyBindPickBlock.isPressed()) {
if(mc != null)
while (mc.gameSettings.keyBindInventory.isPressed()) try {
{ middleClickMouse.invoke(mc);
if (mc.playerController.isRidingHorse()) } catch(Exception e) {
{ }
mc.thePlayer.sendHorseInventory(); }
} }
else
{ if(mc.gameSettings.keyBindUseItem.isKeyDown() && (Integer) rightClickDelayTimer.get(mc) == 0 && !mc.thePlayer.isUsingItem()) {
mc.getNetHandler().addToSendQueue(new C16PacketClientStatus(C16PacketClientStatus.EnumState.OPEN_INVENTORY_ACHIEVEMENT)); if(mc != null)
mc.displayGuiScreen(new GuiInventory(mc.thePlayer)); try {
} rightClickMouse.invoke(mc);
} } catch(Exception e) {
}
while (mc.gameSettings.keyBindDrop.isPressed()) }
{
if (!mc.thePlayer.isSpectator()) if(mc != null)
{ try {
mc.thePlayer.dropOneItem(GuiScreen.isCtrlKeyDown()); sendClickBlockToController.invoke(mc, mc.currentScreen == null && mc.gameSettings.keyBindAttack.isKeyDown() && mc.inGameHasFocus);
} } catch(Exception e) {
} }
while (mc.gameSettings.keyBindChat.isPressed() && flag) if(mc != null)
{ systemTime.set(mc, getSystemTime.invoke(mc));
mc.displayGuiScreen(new GuiChat()); } catch(Exception e) {
} }
}
if (mc.currentScreen == null && mc.gameSettings.keyBindCommand.isPressed() && flag)
{
mc.displayGuiScreen(new GuiChat("/"));
}
if (mc.thePlayer != null && mc.thePlayer.isUsingItem())
{
if (!mc.gameSettings.keyBindUseItem.isKeyDown())
{
mc.playerController.onStoppedUsingItem(mc.thePlayer);
}
label435:
while (true)
{
if (!mc.gameSettings.keyBindAttack.isPressed())
{
while (mc.gameSettings.keyBindUseItem.isPressed())
{
;
}
while (true)
{
if (mc.gameSettings.keyBindPickBlock.isPressed())
{
continue;
}
break label435;
}
}
}
}
else
{
while (mc.gameSettings.keyBindAttack.isPressed())
{
if(mc != null)
try {
clickMouse.invoke(mc);
} catch(Exception e) {}
}
while (mc.gameSettings.keyBindUseItem.isPressed())
{
if(mc != null)
try {
rightClickMouse.invoke(mc);
} catch(Exception e) {}
}
while (mc.gameSettings.keyBindPickBlock.isPressed())
{
if(mc != null)
try {
middleClickMouse.invoke(mc);
} catch(Exception e) {}
}
}
if (mc.gameSettings.keyBindUseItem.isKeyDown() && (Integer)rightClickDelayTimer.get(mc) == 0 && !mc.thePlayer.isUsingItem())
{
if(mc != null)
try {
rightClickMouse.invoke(mc);
} catch(Exception e) {}
}
if(mc != null)
try {
sendClickBlockToController.invoke(mc, mc.currentScreen == null && mc.gameSettings.keyBindAttack.isKeyDown() && mc.inGameHasFocus);
} catch(Exception e) {}
if(mc != null)
systemTime.set(mc, getSystemTime.invoke(mc));
} 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,190 +24,190 @@ 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();
}
}
@SubscribeEvent private final Minecraft mc = Minecraft.getMinecraft();
public void onPlayerJoin(EntityJoinWorldEvent e) { private Double lastX = null, lastY = null, lastZ = null;
try { private List<Integer> lastEffects = new ArrayList<Integer>();
if(e.entity != mc.thePlayer) return; private ItemStack[] playerItems = new ItemStack[5];
if(!ConnectionEventHandler.isRecording()) return; private int ticksSinceLastCorrection = 0;
private boolean wasSleeping = false;
private int lastRiding = -1;
EntityPlayer player = (EntityPlayer)e.entity; @SubscribeEvent
public void onPlayerJoin(EntityJoinWorldEvent e) {
try {
if(e.entity != mc.thePlayer) return;
if(!ConnectionEventHandler.isRecording()) return;
S38PacketPlayerListItem ppli = new S38PacketPlayerListItem(); EntityPlayer player = (EntityPlayer) e.entity;
ByteBuf buf = Unpooled.buffer();
PacketBuffer pbuf = new PacketBuffer(buf);
pbuf.writeEnumValue(Action.ADD_PLAYER); S38PacketPlayerListItem ppli = new S38PacketPlayerListItem();
pbuf.writeVarIntToBuffer(1); ByteBuf buf = Unpooled.buffer();
pbuf.writeUuid(e.entity.getUniqueID()); PacketBuffer pbuf = new PacketBuffer(buf);
pbuf.writeString(player.getName()); pbuf.writeEnumValue(Action.ADD_PLAYER);
pbuf.writeVarIntToBuffer(0); pbuf.writeVarIntToBuffer(1);
pbuf.writeVarIntToBuffer(mc.playerController.getCurrentGameType().getID()); pbuf.writeUuid(e.entity.getUniqueID());
pbuf.writeVarIntToBuffer(0);
pbuf.writeBoolean(true); pbuf.writeString(player.getName());
pbuf.writeChatComponent(player.getDisplayName()); pbuf.writeVarIntToBuffer(0);
pbuf.writeVarIntToBuffer(mc.playerController.getCurrentGameType().getID());
pbuf.writeVarIntToBuffer(0);
ppli.readPacketData(pbuf); pbuf.writeBoolean(true);
ConnectionEventHandler.insertPacket(ppli); pbuf.writeChatComponent(player.getDisplayName());
ConnectionEventHandler.insertPacket(spawnPlayer(mc.thePlayer)); ppli.readPacketData(pbuf);
} catch(Exception e1) { ConnectionEventHandler.insertPacket(ppli);
e1.printStackTrace();
}
}
private static Field dataWatcherField; ConnectionEventHandler.insertPacket(spawnPlayer(mc.thePlayer));
} catch(Exception e1) {
e1.printStackTrace();
}
}
static { private S0CPacketSpawnPlayer spawnPlayer(EntityPlayer player) {
try { try {
dataWatcherField = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_148960_i")); S0CPacketSpawnPlayer packet = new S0CPacketSpawnPlayer();
dataWatcherField.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
private S0CPacketSpawnPlayer spawnPlayer(EntityPlayer player) { ByteBuf bb = Unpooled.buffer();
try { PacketBuffer pb = new PacketBuffer(bb);
S0CPacketSpawnPlayer packet = new S0CPacketSpawnPlayer();
ByteBuf bb = Unpooled.buffer(); pb.writeVarIntToBuffer(entityID);
PacketBuffer pb = new PacketBuffer(bb); pb.writeUuid(player.getUUID(player.getGameProfile()));
pb.writeVarIntToBuffer(entityID); pb.writeInt(MathHelper.floor_double(player.posX * 32.0D));
pb.writeUuid(player.getUUID(player.getGameProfile())); pb.writeInt(MathHelper.floor_double(player.posY * 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.rotationPitch * 256.0F / 360.0F)));
pb.writeInt(MathHelper.floor_double(player.posX * 32.0D)); ItemStack itemstack = player.inventory.getCurrentItem();
pb.writeInt(MathHelper.floor_double(player.posY * 32.0D)); pb.writeShort(itemstack == null ? 0 : Item.getIdFromItem(itemstack.getItem()));
pb.writeInt(MathHelper.floor_double(player.posZ * 32.0D));
pb.writeByte((byte)((int)(player.rotationYaw * 256.0F / 360.0F)));
pb.writeByte((byte)((int)(player.rotationPitch * 256.0F / 360.0F)));
ItemStack itemstack = player.inventory.getCurrentItem(); player.getDataWatcher().writeTo(pb);
pb.writeShort(itemstack == null ? 0 : Item.getIdFromItem(itemstack.getItem()));
player.getDataWatcher().writeTo(pb); packet.readPacketData(pb);
packet.readPacketData(pb); dataWatcherField.set(packet, player.getDataWatcher());
dataWatcherField.set(packet, player.getDataWatcher()); return packet;
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
return packet; public void resetVars() {
} catch(Exception e) { lastX = lastY = lastZ = null;
e.printStackTrace(); lastEffects = new ArrayList<Integer>();
return null; playerItems = new ItemStack[5];
} }
}
private Double lastX = null, lastY = null, lastZ = null; @SubscribeEvent
private List<Integer> lastEffects = new ArrayList<Integer>(); public void onPlayerTick(PlayerTickEvent e) {
if(!ConnectionEventHandler.isRecording()) return;
try {
if(e.player != mc.thePlayer) return;
if(!ConnectionEventHandler.isRecording()) return;
private ItemStack[] playerItems = new ItemStack[5]; boolean force = false;
if(lastX == null || lastY == null || lastZ == null) {
force = true;
lastX = e.player.posX;
lastY = e.player.posY;
lastZ = e.player.posZ;
}
public void resetVars() { ticksSinceLastCorrection++;
lastX = lastY = lastZ = null; if(ticksSinceLastCorrection >= 100) {
lastEffects = new ArrayList<Integer>(); ticksSinceLastCorrection = 0;
playerItems = new ItemStack[5]; force = true;
} }
private int ticksSinceLastCorrection = 0; double dx = e.player.posX - lastX;
double dy = e.player.posY - lastY;
double dz = e.player.posZ - lastZ;
@SubscribeEvent lastX = e.player.posX;
public void onPlayerTick(PlayerTickEvent e) { lastY = e.player.posY;
if(!ConnectionEventHandler.isRecording()) return; lastZ = e.player.posZ;
try {
if(e.player != mc.thePlayer) return;
if(!ConnectionEventHandler.isRecording()) return;
boolean force = false; Packet packet = null;
if(lastX == null || lastY == null || lastZ == null) { if(force || Math.abs(dx) > 4.0 || Math.abs(dy) > 4.0 || Math.abs(dz) > 4.0) {
force = true; int x = MathHelper.floor_double(e.player.posX * 32.0D);
lastX = e.player.posX; int y = MathHelper.floor_double(e.player.posY * 32.0D);
lastY = e.player.posY; int z = MathHelper.floor_double(e.player.posZ * 32.0D);
lastZ = e.player.posZ; byte yaw = (byte) ((int) (e.player.rotationYaw * 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);
} else {
byte oldYaw = (byte) ((int) (e.player.prevRotationYaw * 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 newPitch = (byte) ((int) (e.player.rotationPitch * 256.0F / 360.0F));
ticksSinceLastCorrection++; byte dPitch = (byte) (newPitch - oldPitch);
if(ticksSinceLastCorrection >= 100) { byte dYaw = (byte) (newYaw - oldYaw);
ticksSinceLastCorrection = 0;
force = true;
}
double dx = e.player.posX - lastX; packet = new S17PacketEntityLookMove(entityID,
double dy = e.player.posY - lastY; (byte) Math.round(dx * 32), (byte) Math.round(dy * 32), (byte) Math.round(dz * 32),
double dz = e.player.posZ - lastZ; newYaw, newPitch, e.player.onGround);
}
lastX = e.player.posX; ConnectionEventHandler.insertPacket(packet);
lastY = e.player.posY;
lastZ = e.player.posZ;
Packet packet = null; //HEAD POS
if(force || Math.abs(dx) > 4.0 || Math.abs(dy) > 4.0 || Math.abs(dz) > 4.0) { S19PacketEntityHeadLook head = new S19PacketEntityHeadLook();
int x = MathHelper.floor_double(e.player.posX * 32.0D); ByteBuf bb1 = Unpooled.buffer();
int y = MathHelper.floor_double(e.player.posY * 32.0D); PacketBuffer pb1 = new PacketBuffer(bb1);
int z = MathHelper.floor_double(e.player.posZ * 32.0D);
byte yaw = (byte)((int)(e.player.rotationYaw * 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);
} else {
byte oldYaw = (byte)((int)(e.player.prevRotationYaw * 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 newPitch = (byte)((int)(e.player.rotationPitch * 256.0F / 360.0F));
byte dPitch = (byte)(newPitch-oldPitch); pb1.writeVarIntToBuffer(entityID);
byte dYaw = (byte)(newYaw-oldYaw); pb1.writeByte(((int) (e.player.rotationYawHead * 256.0F / 360.0F)));
packet = new S17PacketEntityLookMove(entityID, head.readPacketData(pb1);
(byte)Math.round(dx*32), (byte)Math.round(dy*32), (byte)Math.round(dz*32),
newYaw, newPitch, e.player.onGround);
}
ConnectionEventHandler.insertPacket(packet); ConnectionEventHandler.insertPacket(head);
//HEAD POS S12PacketEntityVelocity vel = new S12PacketEntityVelocity(entityID, e.player.motionX, e.player.motionY, e.player.motionZ);
S19PacketEntityHeadLook head = new S19PacketEntityHeadLook(); ConnectionEventHandler.insertPacket(vel);
ByteBuf bb1 = Unpooled.buffer();
PacketBuffer pb1 = new PacketBuffer(bb1);
pb1.writeVarIntToBuffer(entityID); //Animation Packets
pb1.writeByte(((int)(e.player.rotationYawHead * 256.0F / 360.0F))); //Swing Animation
if(e.player.swingProgressInt == 1) {
S0BPacketAnimation pac = new S0BPacketAnimation();
head.readPacketData(pb1); ByteBuf bb = Unpooled.buffer();
PacketBuffer pb = new PacketBuffer(bb);
ConnectionEventHandler.insertPacket(head); pb.writeVarIntToBuffer(entityID);
pb.writeByte(0);
S12PacketEntityVelocity vel = new S12PacketEntityVelocity(entityID, e.player.motionX, e.player.motionY, e.player.motionZ); pac.readPacketData(pb);
ConnectionEventHandler.insertPacket(vel);
//Animation Packets ConnectionEventHandler.insertPacket(pac);
//Swing Animation }
if(e.player.swingProgressInt == 1) {
S0BPacketAnimation pac = new S0BPacketAnimation();
ByteBuf bb = Unpooled.buffer();
PacketBuffer pb = new PacketBuffer(bb);
pb.writeVarIntToBuffer(entityID);
pb.writeByte(0);
pac.readPacketData(pb);
ConnectionEventHandler.insertPacket(pac);
}
/* /*
//Potion Effect Handling //Potion Effect Handling
List<Integer> found = new ArrayList<Integer>(); List<Integer> found = new ArrayList<Integer>();
for(PotionEffect pe : (Collection<PotionEffect>)e.player.getActivePotionEffects()) { for(PotionEffect pe : (Collection<PotionEffect>)e.player.getActivePotionEffects()) {
found.add(pe.getPotionID()); found.add(pe.getPotionID());
@@ -240,243 +226,243 @@ public class RecordingHandler {
lastEffects = found; lastEffects = found;
*/ */
//Inventory Handling //Inventory Handling
if(playerItems[0] != mc.thePlayer.getHeldItem()) { if(playerItems[0] != mc.thePlayer.getHeldItem()) {
playerItems[0] = mc.thePlayer.getHeldItem(); playerItems[0] = mc.thePlayer.getHeldItem();
S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 0, playerItems[0]); S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 0, playerItems[0]);
ConnectionEventHandler.insertPacket(pee); ConnectionEventHandler.insertPacket(pee);
} }
if(playerItems[1] != mc.thePlayer.inventory.armorInventory[0]) { if(playerItems[1] != mc.thePlayer.inventory.armorInventory[0]) {
playerItems[1] = mc.thePlayer.inventory.armorInventory[0]; playerItems[1] = mc.thePlayer.inventory.armorInventory[0];
S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 1, playerItems[1]); S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 1, playerItems[1]);
ConnectionEventHandler.insertPacket(pee); ConnectionEventHandler.insertPacket(pee);
} }
if(playerItems[2] != mc.thePlayer.inventory.armorInventory[1]) { if(playerItems[2] != mc.thePlayer.inventory.armorInventory[1]) {
playerItems[2] = mc.thePlayer.inventory.armorInventory[1]; playerItems[2] = mc.thePlayer.inventory.armorInventory[1];
S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 2, playerItems[2]); S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 2, playerItems[2]);
ConnectionEventHandler.insertPacket(pee); ConnectionEventHandler.insertPacket(pee);
} }
if(playerItems[3] != mc.thePlayer.inventory.armorInventory[2]) { if(playerItems[3] != mc.thePlayer.inventory.armorInventory[2]) {
playerItems[3] = mc.thePlayer.inventory.armorInventory[2]; playerItems[3] = mc.thePlayer.inventory.armorInventory[2];
S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 3, playerItems[3]); S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 3, playerItems[3]);
ConnectionEventHandler.insertPacket(pee); ConnectionEventHandler.insertPacket(pee);
} }
if(playerItems[4] != mc.thePlayer.inventory.armorInventory[3]) { if(playerItems[4] != mc.thePlayer.inventory.armorInventory[3]) {
playerItems[4] = mc.thePlayer.inventory.armorInventory[3]; playerItems[4] = mc.thePlayer.inventory.armorInventory[3];
S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 4, playerItems[4]); S04PacketEntityEquipment pee = new S04PacketEntityEquipment(entityID, 4, playerItems[4]);
ConnectionEventHandler.insertPacket(pee); ConnectionEventHandler.insertPacket(pee);
} }
//Leaving Ride //Leaving Ride
if((!mc.thePlayer.isRiding() && lastRiding != -1) || if((!mc.thePlayer.isRiding() && lastRiding != -1) ||
(mc.thePlayer.isRiding() && lastRiding != mc.thePlayer.ridingEntity.getEntityId())) { (mc.thePlayer.isRiding() && lastRiding != mc.thePlayer.ridingEntity.getEntityId())) {
if(!mc.thePlayer.isRiding()) { if(!mc.thePlayer.isRiding()) {
lastRiding = -1; lastRiding = -1;
} else { } else {
lastRiding = mc.thePlayer.ridingEntity.getEntityId(); lastRiding = mc.thePlayer.ridingEntity.getEntityId();
} }
S1BPacketEntityAttach pea = new S1BPacketEntityAttach(); S1BPacketEntityAttach pea = new S1BPacketEntityAttach();
ByteBuf buf = Unpooled.buffer(); ByteBuf buf = Unpooled.buffer();
PacketBuffer pbuf = new PacketBuffer(buf); PacketBuffer pbuf = new PacketBuffer(buf);
pbuf.writeInt(entityID); pbuf.writeInt(entityID);
pbuf.writeInt(lastRiding); pbuf.writeInt(lastRiding);
pbuf.writeBoolean(false); pbuf.writeBoolean(false);
pea.readPacketData(pbuf); pea.readPacketData(pbuf);
ConnectionEventHandler.insertPacket(pea); ConnectionEventHandler.insertPacket(pea);
} }
//Sleeping //Sleeping
if(!mc.thePlayer.isPlayerSleeping() && wasSleeping) { if(!mc.thePlayer.isPlayerSleeping() && wasSleeping) {
S0BPacketAnimation pac = new S0BPacketAnimation(); S0BPacketAnimation pac = new S0BPacketAnimation();
ByteBuf bb = Unpooled.buffer(); ByteBuf bb = Unpooled.buffer();
PacketBuffer pb = new PacketBuffer(bb); PacketBuffer pb = new PacketBuffer(bb);
pb.writeVarIntToBuffer(entityID); pb.writeVarIntToBuffer(entityID);
pb.writeByte(2); pb.writeByte(2);
pac.readPacketData(pb); pac.readPacketData(pb);
ConnectionEventHandler.insertPacket(pac); ConnectionEventHandler.insertPacket(pac);
wasSleeping = false; wasSleeping = false;
} }
} catch(Exception e1) { } catch(Exception e1) {
e1.printStackTrace(); e1.printStackTrace();
} }
} }
@SubscribeEvent @SubscribeEvent
public void onPickupItem(ItemPickupEvent event) { public void onPickupItem(ItemPickupEvent event) {
if(!ConnectionEventHandler.isRecording()) return; if(!ConnectionEventHandler.isRecording()) return;
try { try {
ConnectionEventHandler.insertPacket(new S0DPacketCollectItem(event.pickedUp.getEntityId(), entityID)); ConnectionEventHandler.insertPacket(new S0DPacketCollectItem(event.pickedUp.getEntityId(), entityID));
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@SubscribeEvent @SubscribeEvent
public void onRespawn(PlayerRespawnEvent event) { public void onRespawn(PlayerRespawnEvent event) {
if(!ConnectionEventHandler.isRecording()) return; if(!ConnectionEventHandler.isRecording()) return;
try { try {
//destroy entity, then respawn //destroy entity, then respawn
ConnectionEventHandler.insertPacket(new S13PacketDestroyEntities(entityID)); ConnectionEventHandler.insertPacket(new S13PacketDestroyEntities(entityID));
ConnectionEventHandler.insertPacket(spawnPlayer(mc.thePlayer)); ConnectionEventHandler.insertPacket(spawnPlayer(mc.thePlayer));
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@SubscribeEvent @SubscribeEvent
public void onHurt(LivingHurtEvent event) { public void onHurt(LivingHurtEvent event) {
if(!ConnectionEventHandler.isRecording()) return; if(!ConnectionEventHandler.isRecording()) return;
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();
ByteBuf buf = Unpooled.buffer(); ByteBuf buf = Unpooled.buffer();
PacketBuffer pbuf = new PacketBuffer(buf); PacketBuffer pbuf = new PacketBuffer(buf);
pbuf.writeInt(entityID); pbuf.writeInt(entityID);
pbuf.writeByte(2); pbuf.writeByte(2);
packet.readPacketData(pbuf); packet.readPacketData(pbuf);
ConnectionEventHandler.insertPacket(packet); ConnectionEventHandler.insertPacket(packet);
//Damage Animation //Damage Animation
S0BPacketAnimation pac = new S0BPacketAnimation(); S0BPacketAnimation pac = new S0BPacketAnimation();
ByteBuf bb = Unpooled.buffer(); ByteBuf bb = Unpooled.buffer();
PacketBuffer pb = new PacketBuffer(bb); PacketBuffer pb = new PacketBuffer(bb);
pb.writeVarIntToBuffer(entityID); pb.writeVarIntToBuffer(entityID);
pb.writeByte(1); pb.writeByte(1);
pac.readPacketData(pb); pac.readPacketData(pb);
ConnectionEventHandler.insertPacket(pac); ConnectionEventHandler.insertPacket(pac);
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@SubscribeEvent @SubscribeEvent
public void onDeath(LivingDeathEvent event) { public void onDeath(LivingDeathEvent event) {
if(!ConnectionEventHandler.isRecording()) return; if(!ConnectionEventHandler.isRecording()) return;
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();
ByteBuf buf = Unpooled.buffer(); ByteBuf buf = Unpooled.buffer();
PacketBuffer pbuf = new PacketBuffer(buf); PacketBuffer pbuf = new PacketBuffer(buf);
pbuf.writeInt(entityID); pbuf.writeInt(entityID);
pbuf.writeByte(3); pbuf.writeByte(3);
packet.readPacketData(pbuf); packet.readPacketData(pbuf);
ConnectionEventHandler.insertPacket(packet); ConnectionEventHandler.insertPacket(packet);
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@SubscribeEvent @SubscribeEvent
public void onStartEating(PlayerUseItemEvent.Start event) { public void onStartEating(PlayerUseItemEvent.Start event) {
if(!ConnectionEventHandler.isRecording()) return; if(!ConnectionEventHandler.isRecording()) return;
try { try {
if(!event.entityPlayer.isEating()) return; if(!event.entityPlayer.isEating()) return;
S0BPacketAnimation packet = new S0BPacketAnimation(); S0BPacketAnimation packet = new S0BPacketAnimation();
ByteBuf bb = Unpooled.buffer(); ByteBuf bb = Unpooled.buffer();
PacketBuffer pb = new PacketBuffer(bb); PacketBuffer pb = new PacketBuffer(bb);
pb.writeVarIntToBuffer(entityID); pb.writeVarIntToBuffer(entityID);
pb.writeByte(3); pb.writeByte(3);
packet.readPacketData(pb); packet.readPacketData(pb);
ConnectionEventHandler.insertPacket(packet); ConnectionEventHandler.insertPacket(packet);
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private boolean wasSleeping = false; @SubscribeEvent
public void onSleep(PlayerSleepInBedEvent event) {
if(!ConnectionEventHandler.isRecording()) return;
try {
if(event.entityPlayer != mc.thePlayer) {
return;
}
;
@SubscribeEvent System.out.println(event.getResult());
public void onSleep(PlayerSleepInBedEvent event) { S0APacketUseBed pub = new S0APacketUseBed();
if(!ConnectionEventHandler.isRecording()) return;
try {
if(event.entityPlayer != mc.thePlayer) {
return;
};
System.out.println(event.getResult()); ByteBuf buf = Unpooled.buffer();
S0APacketUseBed pub = new S0APacketUseBed(); PacketBuffer pbuf = new PacketBuffer(buf);
ByteBuf buf = Unpooled.buffer(); pbuf.writeVarIntToBuffer(entityID);
PacketBuffer pbuf = new PacketBuffer(buf); pbuf.writeBlockPos(event.pos);
pbuf.writeVarIntToBuffer(entityID); pub.readPacketData(pbuf);
pbuf.writeBlockPos(event.pos);
pub.readPacketData(pbuf); ConnectionEventHandler.insertPacket(pub);
ConnectionEventHandler.insertPacket(pub); wasSleeping = true;
wasSleeping = true; } catch(Exception e) {
e.printStackTrace();
}
}
} catch(Exception e) { @SubscribeEvent
e.printStackTrace(); public void enterMinecart(MinecartInteractEvent event) {
} if(!ConnectionEventHandler.isRecording()) return;
} try {
if(event.player != mc.thePlayer) {
return;
}
;
private int lastRiding = -1; S1BPacketEntityAttach pea = new S1BPacketEntityAttach();
@SubscribeEvent ByteBuf buf = Unpooled.buffer();
public void enterMinecart(MinecartInteractEvent event) { PacketBuffer pbuf = new PacketBuffer(buf);
if(!ConnectionEventHandler.isRecording()) return;
try {
if(event.player != mc.thePlayer) {
return;
};
S1BPacketEntityAttach pea = new S1BPacketEntityAttach(); pbuf.writeInt(entityID);
pbuf.writeInt(event.minecart.getEntityId());
pbuf.writeBoolean(false);
ByteBuf buf = Unpooled.buffer(); pea.readPacketData(pbuf);
PacketBuffer pbuf = new PacketBuffer(buf);
pbuf.writeInt(entityID); ConnectionEventHandler.insertPacket(pea);
pbuf.writeInt(event.minecart.getEntityId());
pbuf.writeBoolean(false);
pea.readPacketData(pbuf); lastRiding = event.minecart.getEntityId();
} catch(Exception e) {
ConnectionEventHandler.insertPacket(pea); e.printStackTrace();
}
lastRiding = event.minecart.getEntityId(); }
} catch(Exception e) {
e.printStackTrace();
}
}
} }

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,91 +15,81 @@ 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 static Field isGamePaused;
private float lastPitch, lastYaw; private static int requestScreenshot = 0;
private static Field isGamePaused; static {
try {
isGamePaused = Minecraft.class.getDeclaredField(MCPNames.field("field_71445_n"));
isGamePaused.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
static { //private boolean f1Down = false;
try {
isGamePaused = Minecraft.class.getDeclaredField(MCPNames.field("field_71445_n"));
isGamePaused.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
@SubscribeEvent public static void requestScreenshot() {
public void onRenderWorld(RenderWorldLastEvent event) throws if(requestScreenshot == 0) requestScreenshot = 1;
InvocationTargetException, IOException, IllegalAccessException, IllegalArgumentException { }
if(!ReplayHandler.isInReplay()) return; //If not in Replay, cancel
if(requestScreenshot == 1) { public static void finishScreenshot() {
mc.addScheduledTask(new Runnable() { requestScreenshot = 0;
@Override }
public void run() {
ChatMessageRequests.addChatMessage("Saving Thumbnail...", ChatMessageRequests.ChatMessageType.INFORMATION);
ReplayScreenshot.prepareScreenshot();
requestScreenshot = 2;
}
});
} else if(requestScreenshot == 2) {
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
ReplayScreenshot.saveScreenshot();
}
});
}
if(ReplayHandler.isInPath()) ReplayProcess.unblockAndTick(false); @SubscribeEvent
if(ReplayHandler.isCamera()) ReplayHandler.setCameraEntity(ReplayHandler.getCameraEntity()); public void onRenderWorld(RenderWorldLastEvent event) throws
if(ReplayHandler.isInReplay() && ReplayHandler.isPaused()) { InvocationTargetException, IOException, IllegalAccessException, IllegalArgumentException {
if(mc != null && mc.thePlayer != null) if(!ReplayHandler.isInReplay()) return; //If not in Replay, cancel
MinecraftTicker.runMouseKeyboardTick(mc);
}
if((mc.getRenderViewEntity() == mc.thePlayer || !mc.getRenderViewEntity().isEntityAlive())
&& ReplayHandler.getCameraEntity() != null && !ReplayHandler.isInPath()) {
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(requestScreenshot == 1) {
isGamePaused.set(mc, false); mc.addScheduledTask(new Runnable() {
} @Override
} public void run() {
ReplayMod.chatMessageHandler.addChatMessage("Saving Thumbnail...", ChatMessageHandler.ChatMessageType.INFORMATION);
ReplayScreenshot.prepareScreenshot();
requestScreenshot = 2;
}
});
} else if(requestScreenshot == 2) {
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
ReplayScreenshot.saveScreenshot();
}
});
}
//private boolean f1Down = false; if(ReplayHandler.isInPath()) ReplayProcess.unblockAndTick(false);
if(ReplayHandler.isCamera()) ReplayHandler.setCameraEntity(ReplayHandler.getCameraEntity());
if(ReplayHandler.isInReplay() && ReplayMod.replaySender.paused()) {
if(mc != null && mc.thePlayer != null)
MinecraftTicker.runMouseKeyboardTick(mc);
}
if((mc.getRenderViewEntity() == mc.thePlayer || !mc.getRenderViewEntity().isEntityAlive())
&& ReplayHandler.getCameraEntity() != null && !ReplayHandler.isInPath()) {
ReplayHandler.spectateCamera();
}
private static int requestScreenshot = 0; if(mc.isGamePaused() && ReplayHandler.isInPath()) {
isGamePaused.set(mc, false);
}
}
public static void requestScreenshot() { @SubscribeEvent
if(requestScreenshot == 0) requestScreenshot = 1; public void tick(TickEvent event) {
} if(!ReplayHandler.isInReplay()) return;
public static void finishScreenshot() {
requestScreenshot = 0;
}
@SubscribeEvent
public void tick(TickEvent event) {
if(!ReplayHandler.isInReplay()) return;
/* /*
if(Keyboard.getEventKeyState() && Keyboard.isKeyDown(Keyboard.KEY_F1) if(Keyboard.getEventKeyState() && Keyboard.isKeyDown(Keyboard.KEY_F1)
@@ -112,51 +101,47 @@ public class TickAndRenderListener {
f1Down = Keyboard.isKeyDown(Keyboard.KEY_F1) && Keyboard.getEventKeyState(); f1Down = Keyboard.isKeyDown(Keyboard.KEY_F1) && Keyboard.getEventKeyState();
*/ */
if(ReplayHandler.getCameraEntity() != null) if(ReplayHandler.getCameraEntity() != null)
ReplayHandler.getCameraEntity().updateMovement(); ReplayHandler.getCameraEntity().updateMovement();
if(ReplayHandler.isInPath()) { if(ReplayHandler.isInPath()) {
ReplayProcess.unblockAndTick(true); ReplayProcess.unblockAndTick(true);
if(ReplayProcess.isVideoRecording() && if(ReplayProcess.isVideoRecording() &&
!(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()); }
}
@SubscribeEvent @SubscribeEvent
public void onMouseMove(MouseEvent event) { public void onMouseMove(MouseEvent event) {
if(!ReplayHandler.isInReplay()) return; if(!ReplayHandler.isInReplay()) return;
boolean flag = Display.isActive(); boolean flag = Display.isActive();
flag = true; flag = true;
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,27 +2,26 @@ 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;
public class GuiCancelRender extends GuiYesNo { public class GuiCancelRender extends GuiYesNo {
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getMinecraft();
private static GuiYesNoCallback callback = new GuiYesNoCallback() { private static GuiYesNoCallback callback = new GuiYesNoCallback() {
@Override @Override
public void confirmClicked(boolean result, int id) { public void confirmClicked(boolean result, int id) {
if(result) { if(result) {
ReplayProcess.stopReplayProcess(false); ReplayProcess.stopReplayProcess(false);
} }
mc.displayGuiScreen(null); mc.displayGuiScreen(null);
} }
}; };
public GuiCancelRender() { public GuiCancelRender() {
super(callback, "Cancel Rendering", "Are you sure that you want to cancel the current rendering process?", 0); super(callback, "Cancel Rendering", "Are you sure that you want to cancel the current rendering process?", 0);
} }
} }

View File

@@ -2,47 +2,47 @@ package eu.crushedpixel.replaymod.gui;
public class GuiConstants { public class GuiConstants {
public static final int CENTER_MY_REPLAYS_BUTTON = 2001; public static final int CENTER_MY_REPLAYS_BUTTON = 2001;
public static final int CENTER_SEARCH_BUTTON = 2002; public static final int CENTER_SEARCH_BUTTON = 2002;
public static final int CENTER_BACK_BUTTON = 2003; public static final int CENTER_BACK_BUTTON = 2003;
public static final int CENTER_LOGOUT_BUTTON = 2004; public static final int CENTER_LOGOUT_BUTTON = 2004;
public static final int CENTER_RECENT_BUTTON = 2005; public static final int CENTER_RECENT_BUTTON = 2005;
public static final int CENTER_BEST_BUTTON = 2006; public static final int CENTER_BEST_BUTTON = 2006;
public static final int CENTER_MANAGER_BUTTON = 2007; public static final int CENTER_MANAGER_BUTTON = 2007;
public static final int UPLOAD_NAME_INPUT = 3001; public static final int UPLOAD_NAME_INPUT = 3001;
public static final int UPLOAD_CATEGORY_BUTTON = 3002; public static final int UPLOAD_CATEGORY_BUTTON = 3002;
public static final int UPLOAD_START_BUTTON = 3003; public static final int UPLOAD_START_BUTTON = 3003;
public static final int UPLOAD_CANCEL_BUTTON = 3004; public static final int UPLOAD_CANCEL_BUTTON = 3004;
public static final int UPLOAD_BACK_BUTTON = 3005; public static final int UPLOAD_BACK_BUTTON = 3005;
public static final int UPLOAD_INFO_FIELD = 3006; public static final int UPLOAD_INFO_FIELD = 3006;
public static final int UPLOAD_TAG_INPUT = 3007; public static final int UPLOAD_TAG_INPUT = 3007;
public static final int UPLOAD_TAG_PLACEHOLDER = 3008; public static final int UPLOAD_TAG_PLACEHOLDER = 3008;
public static final int EXIT_REPLAY_BUTTON = 4001; public static final int EXIT_REPLAY_BUTTON = 4001;
public static final int REPLAY_OPTIONS_BUTTON_ID = 8000; public static final int REPLAY_OPTIONS_BUTTON_ID = 8000;
public static final int REPLAY_MANAGER_BUTTON_ID = 9001; public static final int REPLAY_MANAGER_BUTTON_ID = 9001;
public static final int REPLAY_EDITOR_BUTTON_ID = 9002; public static final int REPLAY_EDITOR_BUTTON_ID = 9002;
public static final int REPLAY_CENTER_BUTTON_ID = 9003; public static final int REPLAY_CENTER_BUTTON_ID = 9003;
public static final int REPLAY_CENTER_LOGIN_TEXT_ID = 9004; public static final int REPLAY_CENTER_LOGIN_TEXT_ID = 9004;
public static final int REPLAY_CENTER_PASSWORD_TEXT_ID = 9005; public static final int REPLAY_CENTER_PASSWORD_TEXT_ID = 9005;
public static final int LOGIN_OKAY_BUTTON = 1100; public static final int LOGIN_OKAY_BUTTON = 1100;
public static final int LOGIN_CANCEL_BUTTON = 1101; public static final int LOGIN_CANCEL_BUTTON = 1101;
public static final int REPLAY_EDITOR_TRIM_TAB = 5000; public static final int REPLAY_EDITOR_TRIM_TAB = 5000;
public static final int REPLAY_EDITOR_CONNECT_TAB = 5001; public static final int REPLAY_EDITOR_CONNECT_TAB = 5001;
public static final int REPLAY_EDITOR_MODIFY_TAB = 5002; public static final int REPLAY_EDITOR_MODIFY_TAB = 5002;
public static final int REPLAY_EDITOR_SAVEMODE_BUTTON = 5003; public static final int REPLAY_EDITOR_SAVEMODE_BUTTON = 5003;
public static final int REPLAY_EDITOR_SAVE_BUTTON = 5004; public static final int REPLAY_EDITOR_SAVE_BUTTON = 5004;
public static final int REPLAY_EDITOR_BACK_BUTTON = 5005; public static final int REPLAY_EDITOR_BACK_BUTTON = 5005;
public static final int REPLAY_EDITOR_UP_BUTTON = 5006; public static final int REPLAY_EDITOR_UP_BUTTON = 5006;
public static final int REPLAY_EDITOR_DOWN_BUTTON = 5007; public static final int REPLAY_EDITOR_DOWN_BUTTON = 5007;
public static final int REPLAY_EDITOR_REMOVE_BUTTON = 5008; public static final int REPLAY_EDITOR_REMOVE_BUTTON = 5008;
public static final int REPLAY_EDITOR_ADD_BUTTON = 5009; public static final int REPLAY_EDITOR_ADD_BUTTON = 5009;
} }

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,33 +1,27 @@
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 {
public static boolean replaySaving = false; public static boolean replaySaving = false;
private GuiScreen waiting = null; private GuiScreen waiting = null;
public GuiReplaySaving(GuiScreen waiting) { public GuiReplaySaving(GuiScreen waiting) {
this.waiting = waiting; this.waiting = waiting;
} }
@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(this.fontRendererObj, "Saving Replay File...", this.width / 2, 20, 16777215); this.drawCenteredString(this.fontRendererObj, "Saving Replay File...", this.width / 2, 20, 16777215);
this.drawCenteredString(this.fontRendererObj, "Please wait while your recent Replay is being saved.", this.width / 2, 40, 16777215); this.drawCenteredString(this.fontRendererObj, "Please wait while your recent Replay is being saved.", this.width / 2, 40, 16777215);
super.drawScreen(mouseX, mouseY, partialTicks); super.drawScreen(mouseX, mouseY, partialTicks);
if(!replaySaving) { if(!replaySaving) {
Minecraft.getMinecraft().displayGuiScreen(waiting); Minecraft.getMinecraft().displayGuiScreen(waiting);
} }
} }
} }

View File

@@ -1,192 +1,188 @@
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; //TODO: Move to GuiConstants
protected String screenTitle = "Replay Mod Settings"; private static final int QUALITY_SLIDER_ID = 9003;
private static final int RECORDSERVER_ID = 9004;
private static final int RECORDSP_ID = 9005;
private static final int SEND_CHAT = 9006;
private static final int FORCE_LINEAR = 9007;
private static final int ENABLE_LIGHTING = 9008;
private static final int FRAMERATE_SLIDER_ID = 9009;
private static final int RESOURCEPACK_ID = 9010;
private static final int WAITFORCHUNKS_ID = 9011;
private static final int INDICATOR_ID = 9012;
protected String screenTitle = "Replay Mod Settings";
private GuiScreen parentGuiScreen;
private GuiButton recordServerButton, recordSPButton, sendChatButton, linearButton, lightingButton,
resourcePackButton, waitForChunksButton, showIndicatorButton;
//TODO: Move to GuiConstants public GuiReplaySettings(GuiScreen parentGuiScreen) {
private static final int QUALITY_SLIDER_ID = 9003; this.parentGuiScreen = parentGuiScreen;
private static final int RECORDSERVER_ID = 9004; }
private static final int RECORDSP_ID = 9005;
private static final int SEND_CHAT = 9006;
private static final int FORCE_LINEAR = 9007;
private static final int ENABLE_LIGHTING = 9008;
private static final int FRAMERATE_SLIDER_ID = 9009;
private static final int RESOURCEPACK_ID = 9010;
private static final int WAITFORCHUNKS_ID = 9011;
private static final int INDICATOR_ID = 9012;
private GuiButton recordServerButton, recordSPButton, sendChatButton, linearButton, lightingButton, public void initGui() {
resourcePackButton, waitForChunksButton, showIndicatorButton; this.screenTitle = I18n.format("Replay Mod Settings", new Object[0]);
this.buttonList.clear();
this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height - 27, I18n.format("gui.done", new Object[0])));
public GuiReplaySettings(GuiScreen parentGuiScreen) { ReplaySettings settings = ReplayMod.replaySettings;
this.parentGuiScreen = parentGuiScreen;
}
public void initGui() { int k = 0;
this.screenTitle = I18n.format("Replay Mod Settings", new Object[0]); int i = 0;
this.buttonList.clear();
this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height - 27, I18n.format("gui.done", new Object[0])));
ReplaySettings settings = ReplayMod.replaySettings; for(RecordingOptions o : RecordingOptions.values()) {
if(o == RecordingOptions.notifications) {
this.buttonList.add(sendChatButton = new GuiButton(SEND_CHAT,
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
"Enable Notifications: " + onOff(settings.isShowNotifications())));
} else if(o == RecordingOptions.recordServer) {
this.buttonList.add(recordServerButton = new GuiButton(RECORDSERVER_ID,
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20, "Record Server: "
+ onOff(settings.isEnableRecordingServer())));
} else if(o == RecordingOptions.recordSingleplayer) {
this.buttonList.add(recordSPButton = new GuiButton(RECORDSP_ID, this.width / 2 - 155 + i % 2 * 160,
this.height / 6 + 24 * (i >> 1), 150, 20, "Record Singleplayer: " + onOff(settings.isEnableRecordingSingleplayer())));
} else if(o == RecordingOptions.indicator) {
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())));
}
int k = 0; ++i;
int i = 0; ++k;
}
for(RecordingOptions o : RecordingOptions.values()) {
if(o == RecordingOptions.notifications) {
this.buttonList.add(sendChatButton = new GuiButton(SEND_CHAT,
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
"Enable Notifications: "+onOff(settings.isShowNotifications())));
} else if(o == RecordingOptions.recordServer) {
this.buttonList.add(recordServerButton = new GuiButton(RECORDSERVER_ID,
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20, "Record Server: "
+onOff(settings.isEnableRecordingServer())));
} else if(o == RecordingOptions.recordSingleplayer) {
this.buttonList.add(recordSPButton = new GuiButton(RECORDSP_ID, this.width / 2 - 155 + i % 2 * 160,
this.height / 6 + 24 * (i >> 1), 150, 20, "Record Singleplayer: "+onOff(settings.isEnableRecordingSingleplayer())));
} else if(o == RecordingOptions.indicator) {
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())));
}
++i;
++k;
}
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; }
}
for(RenderOptions o : RenderOptions.values()) { for(RenderOptions o : RenderOptions.values()) {
if(o == RenderOptions.videoFramerate) { if(o == RenderOptions.videoFramerate) {
this.buttonList.add(new GuiVideoFramerateSlider(FRAMERATE_SLIDER_ID, this.buttonList.add(new GuiVideoFramerateSlider(FRAMERATE_SLIDER_ID,
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 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;
++k; ++k;
} }
} }
private String onOff(boolean on) { private String onOff(boolean on) {
return on ? "ON" : "OFF"; return on ? "ON" : "OFF";
} }
private String linearOnOff(boolean on) { private String linearOnOff(boolean on) {
return on ? "Linear" : "Cubic"; return on ? "Linear" : "Cubic";
} }
@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(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());
} }
super.drawScreen(mouseX, mouseY, partialTicks); super.drawScreen(mouseX, mouseY, partialTicks);
} }
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);
break; break;
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,190 +1,170 @@
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;
public class GuiReplaySpeedSlider extends GuiButton { public class GuiReplaySpeedSlider extends GuiButton {
private float sliderValue; private float sliderValue;
private float valueStep, valueMin, valueMax; private float valueStep, valueMin, valueMax;
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);
} }
@Override public static float convertScaleRet(float value) {
protected int getHoverState(boolean mouseOver) { if(value <= 1) {
return 0; return Math.round(value * 10);
} }
float steps = value - 1;
return Math.round(steps / 0.25f);
}
@Override public static float convertScale(float value) {
public void drawButton(Minecraft mc, int mouseX, int mouseY) if(value == 10) {
{ return 1;
if (this.visible) }
{ if(value <= 9) {
try { return value / 10f;
FontRenderer fontrenderer = mc.fontRendererObj; }
mc.getTextureManager().bindTexture(buttonTextures); return 1 + (0.25f * (value - 10));
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); }
this.hovered = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height;
int k = this.getHoverState(this.hovered);
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.blendFunc(770, 771);
this.drawTexturedModalRect(this.xPosition, this.yPosition, 0, 46 + k * 20, this.width / 2, this.height);
this.drawTexturedModalRect(this.xPosition + this.width / 2, this.yPosition, 200 - this.width / 2, 46 + k * 20, this.width / 2, this.height);
this.mouseDragged(mc, mouseX, mouseY);
int l = 14737632;
if (packedFGColour != 0) @Override
{ protected int getHoverState(boolean mouseOver) {
l = packedFGColour; return 0;
} }
else if (!this.enabled)
{
l = 10526880;
}
else if (this.hovered && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class))
{
l = 16777120;
}
this.drawCenteredString(fontrenderer, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, l); @Override
} catch(Exception e) {} public void drawButton(Minecraft mc, int mouseX, int mouseY) {
} if(this.visible) {
} try {
FontRenderer fontrenderer = mc.fontRendererObj;
mc.getTextureManager().bindTexture(buttonTextures);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.hovered = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height;
int k = this.getHoverState(this.hovered);
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.blendFunc(770, 771);
this.drawTexturedModalRect(this.xPosition, this.yPosition, 0, 46 + k * 20, this.width / 2, this.height);
this.drawTexturedModalRect(this.xPosition + this.width / 2, this.yPosition, 200 - this.width / 2, 46 + k * 20, this.width / 2, this.height);
this.mouseDragged(mc, mouseX, mouseY);
int l = 14737632;
private String translate(float f) { if(packedFGColour != 0) {
return f+"x"; l = packedFGColour;
} } else if(!this.enabled) {
l = 10526880;
} else if(this.hovered && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
l = 16777120;
}
public static float convertScaleRet(float value) { this.drawCenteredString(fontrenderer, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, l);
if(value <= 1) { } catch(Exception e) {
return Math.round(value*10); }
} }
float steps = value-1; }
return Math.round(steps/0.25f);
}
public static float convertScale(float value) { private String translate(float f) {
if(value == 10) { return f + "x";
return 1; }
}
if(value <= 9) {
return value/10f;
}
return 1+(0.25f*(value-10));
}
public double getSliderValue() {
return convertScale(normalizedToReal(sliderValue));
}
public double getSliderValue() { @Override
return convertScale(normalizedToReal(sliderValue)); protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) {
} if(this.visible) {
try {
if(this.dragging) {
sliderValue = (float) (mouseX - (this.xPosition + 4)) / (float) (this.width - 8);
sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F);
float f = denormalizeValue(sliderValue);
sliderValue = normalizeValue(f);
if(ReplayMod.replaySender.getReplaySpeed() != 0) {
ReplayMod.replaySender.setReplaySpeed(convertScale(normalizedToReal(sliderValue)));
}
this.displayString = displayKey + ": " + translate(convertScale(normalizedToReal(sliderValue)));
}
@Override mc.getTextureManager().bindTexture(buttonTextures);
protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) { GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
if (this.visible) { this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
try { this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
if(this.dragging) { } catch(Exception e) {
sliderValue = (float)(mouseX - (this.xPosition + 4)) / (float)(this.width - 8); }
sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F); }
float f = denormalizeValue(sliderValue); }
sliderValue = normalizeValue(f);
if(ReplayHandler.getSpeed() != 0) {
ReplayHandler.setSpeed(convertScale(normalizedToReal(sliderValue)));
}
this.displayString = displayKey+": "+translate(convertScale(normalizedToReal(sliderValue)));
}
mc.getTextureManager().bindTexture(buttonTextures); public float normalizeValue(float p_148266_1_) {
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); return MathHelper.clamp_float((this.snapToStepClamp(p_148266_1_) - this.valueMin) / (this.valueMax - this.valueMin), 0.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)) + 4, this.yPosition, 196, 66, 4, 20);
} catch(Exception e) {}
}
}
public float normalizeValue(float p_148266_1_) public float realToNormalized(float value) {
{ float min = 0 - valueMin;
return MathHelper.clamp_float((this.snapToStepClamp(p_148266_1_) - this.valueMin) / (this.valueMax - this.valueMin), 0.0F, 1.0F); float max = valueMax + min;
}
public float realToNormalized(float value) { return value / (max) - min;
float min = 0 - valueMin; }
float max = valueMax + min;
return value/(max) - min; 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));
}
public float denormalizeValue(float p_148262_1_) public float snapToStepClamp(float p_148268_1_) {
{ p_148268_1_ = this.snapToStep(p_148268_1_);
return this.snapToStepClamp(this.valueMin + (this.valueMax - this.valueMin) * MathHelper.clamp_float(p_148262_1_, 0.0F, 1.0F)); return MathHelper.clamp_float(p_148268_1_, this.valueMin, this.valueMax);
} }
public float snapToStepClamp(float p_148268_1_) protected float snapToStep(float p_148264_1_) {
{ if(this.valueStep > 0.0F) {
p_148268_1_ = this.snapToStep(p_148268_1_); p_148264_1_ = this.valueStep * (float) Math.round(p_148264_1_ / this.valueStep);
return MathHelper.clamp_float(p_148268_1_, this.valueMin, this.valueMax); }
}
protected float snapToStep(float p_148264_1_) return p_148264_1_;
{ }
if (this.valueStep > 0.0F)
{
p_148264_1_ = this.valueStep * (float)Math.round(p_148264_1_ / this.valueStep);
}
return p_148264_1_; public float normalizedToReal(float value) {
} float min = 0 - valueMin;
float max = valueMax + min;
public float normalizedToReal(float value) { return Math.round(value * (max) - min);
float min = 0 - valueMin; }
float max = valueMax + min;
return Math.round(value*(max) - min); public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
} if(super.mousePressed(mc, mouseX, mouseY)) {
this.dragging = true;
return true;
} else {
return false;
}
}
public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) public void mouseReleased(int mouseX, int mouseY) {
{ this.dragging = false;
if (super.mousePressed(mc, mouseX, mouseY)) }
{
this.dragging = true;
return true;
}
else
{
return false;
}
}
public void mouseReleased(int mouseX, int mouseY)
{
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,199 +11,200 @@ 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 {
private List<Pair<EntityPlayer, ResourceLocation>> players; private List<Pair<EntityPlayer, ResourceLocation>> players;
private int playerCount; private int playerCount;
private int upperPlayer = 0; private int upperPlayer = 0;
private int upperBound = 30; private int upperBound = 30;
private int lowerBound; private int lowerBound;
private double prevSpeed; private double prevSpeed;
private boolean drag = false;
private int lastY = 0;
private int fitting = 0;
private class PlayerComparator implements Comparator<EntityPlayer> { public GuiSpectateSelection(List<EntityPlayer> players) {
this.prevSpeed = ReplayMod.replaySender.getReplaySpeed();
@Override Collections.sort(players, new PlayerComparator());
public int compare(EntityPlayer o1, EntityPlayer o2) {
if(isSpectator(o1) && !isSpectator(o2)) {
return 1;
} else if(isSpectator(o2) && !isSpectator(o1)) {
return -1;
} else {
return o1.getName().compareToIgnoreCase(o2.getName());
}
}
} this.players = new ArrayList<Pair<EntityPlayer, ResourceLocation>>();
private boolean isSpectator(EntityPlayer e) { for(EntityPlayer p : players) {
return e.isInvisible() && e.getActivePotionEffect(Potion.invisibility) == null; ResourceLocation loc = new ResourceLocation("/temp-skins/" + p.getGameProfile().getName());
} AbstractClientPlayer.getDownloadImageSkin(loc, p.getName());
this.players.add(Pair.of(p, loc));
}
public GuiSpectateSelection(List<EntityPlayer> players) { playerCount = players.size();
this.prevSpeed = ReplayHandler.getSpeed();
Collections.sort(players, new PlayerComparator()); ReplayMod.replaySender.setReplaySpeed(0);
}
this.players = new ArrayList<Pair<EntityPlayer, ResourceLocation>>(); private boolean isSpectator(EntityPlayer e) {
return e.isInvisible() && e.getActivePotionEffect(Potion.invisibility) == null;
}
for(EntityPlayer p : players) { @Override
ResourceLocation loc = new ResourceLocation("/temp-skins/"+p.getGameProfile().getName()); protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
AbstractClientPlayer.getDownloadImageSkin(loc, p.getName()); throws IOException {
this.players.add(Pair.of(p, loc));
}
playerCount = players.size(); if(fitting < playerCount) {
float visiblePerc = (float) fitting / (float) playerCount;
ReplayHandler.setSpeed(0); int h = this.height - 32 - 32;
} int offset = Math.round((upperPlayer / (fitting)) * visiblePerc * h);
private boolean drag = false; int lower = Math.round(32 + offset + (h * visiblePerc)) - 2;
@Override int k2 = (int) (this.width * 0.4);
protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
throws IOException {
if(fitting < playerCount) { if(mouseX >= k2 - 16 && mouseX <= k2 - 12 && mouseY >= 32 - 2 + offset && mouseY <= lower) {
float visiblePerc = (float)fitting/(float)playerCount; lastY = mouseY;
drag = true;
return;
}
}
int k2 = (int) (this.width * 0.4);
int l2 = 30;
int h = this.height-32-32; if(mouseX >= k2 && mouseX <= (this.width * 0.6) && mouseY >= 30 && mouseY <= lowerBound) {
int offset = Math.round((upperPlayer/(fitting))*visiblePerc*h); int off = mouseY - 30;
int p = (off / 21) + upperPlayer;
ReplayHandler.spectateEntity(players.get(p).first());
ReplayMod.replaySender.setReplaySpeed(prevSpeed);
mc.displayGuiScreen(null);
}
}
int lower = Math.round(32+offset+(h*visiblePerc))-2; @Override
protected void mouseClickMove(int mouseX, int mouseY,
int clickedMouseButton, long timeSinceLastClick) {
int k2 = (int)(this.width*0.4); if(drag) {
float step = 1f / (float) playerCount;
if(mouseX >= k2-16 && mouseX <= k2-12 && mouseY >= 32-2+offset && mouseY <= lower) { int diff = mouseY - lastY;
lastY = mouseY; int h = this.height - 32 - 32;
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) { float percDiff = (float) diff / (float) h;
int off = mouseY-30; if(Math.abs(percDiff) > Math.abs(step)) {
int p = (off/21) + upperPlayer; int s = (int) (percDiff / step);
ReplayHandler.spectateEntity(players.get(p).first()); lastY = mouseY;
ReplayHandler.setSpeed(prevSpeed); upperPlayer += s;
mc.displayGuiScreen(null); if(upperPlayer > playerCount - fitting) {
} upperPlayer = playerCount - fitting;
} } else if(upperPlayer < 0) {
upperPlayer = 0;
}
}
}
private int lastY = 0; super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick);
}
@Override @Override
protected void mouseClickMove(int mouseX, int mouseY, public void onGuiClosed() {
int clickedMouseButton, long timeSinceLastClick) { ReplayMod.replaySender.setReplaySpeed(prevSpeed);
}
if(drag) { @Override
float step = 1f/(float)playerCount; protected void mouseReleased(int mouseX, int mouseY, int state) {
drag = false;
int diff = mouseY-lastY; super.mouseReleased(mouseX, mouseY, state);
int h = this.height-32-32; }
float percDiff = (float)diff/(float)h; @Override
if(Math.abs(percDiff) > Math.abs(step)) { public void initGui() {
int s = (int)(percDiff/step); upperPlayer = 0;
lastY = mouseY; lowerBound = this.height - 10;
upperPlayer += s; }
if(upperPlayer > playerCount-fitting) {
upperPlayer = playerCount-fitting;
} else if(upperPlayer < 0) {
upperPlayer = 0;
}
}
}
super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick); @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;
@Override drawGradientRect(k2 - 10, l2 - 10, (int) (this.width * 0.6) + 20, this.height - 30 - 2 + 10, -1072689136, -804253680);
public void onGuiClosed() {
ReplayHandler.setSpeed(prevSpeed);
}
@Override fitting = 0;
protected void mouseReleased(int mouseX, int mouseY, int state) {
drag = false;
super.mouseReleased(mouseX, mouseY, state); int sk = 0;
} for(Pair<EntityPlayer, ResourceLocation> p : players) {
if(sk < upperPlayer) {
sk++;
continue;
}
boolean spec = isSpectator(p.first());
@Override this.drawString(fontRendererObj, p.first().getName(), k2 + 16 + 5, l2 + 8 - (fontRendererObj.FONT_HEIGHT / 2),
public void initGui() { spec ? Color.DARK_GRAY.getRGB() : Color.WHITE.getRGB());
upperPlayer = 0;
lowerBound = this.height-10;
}
private int fitting = 0; mc.getTextureManager().bindTexture(p.second());
@Override this.drawScaledCustomSizeModalRect(k2, l2, 8.0F, 8.0F, 8, 8, 16, 16, 64.0F, 64.0F);
public void drawScreen(int mouseX, int mouseY, float partialTicks) { if(p.first().func_175148_a(EnumPlayerModelParts.HAT))
this.drawCenteredString(fontRendererObj, "Spectate Player", this.width/2, 5, Color.WHITE.getRGB()); Gui.drawScaledCustomSizeModalRect(k2, l2, 40.0F, 8.0F, 8, 8, 16, 16, 64.0F, 64.0F);
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); GlStateManager.resetColor();
fitting = 0; l2 += 16 + 5;
fitting++;
if(l2 + 32 > lowerBound) {
break;
}
}
int sk = 0; int dw = Mouse.getDWheel();
for(Pair<EntityPlayer, ResourceLocation> p : players) { if(dw > 0) {
if(sk < upperPlayer) { dw = -1;
sk++; } else if(dw < 0) {
continue; dw = 1;
} }
boolean spec = isSpectator(p.first());
this.drawString(fontRendererObj, p.first().getName(), k2+16+5, l2+8-(fontRendererObj.FONT_HEIGHT/2), upperPlayer = Math.max(Math.min(upperPlayer + dw, playerCount - fitting), 0);
spec ? Color.DARK_GRAY.getRGB() : Color.WHITE.getRGB());
mc.getTextureManager().bindTexture(p.second()); if(fitting < playerCount) {
float visiblePerc = ((float) fitting) / playerCount;
int barHeight = (int) (visiblePerc * (height - 32 - 32));
this.drawScaledCustomSizeModalRect(k2, l2, 8.0F, 8.0F, 8, 8, 16, 16, 64.0F, 64.0F); float posPerc = ((float) upperPlayer) / playerCount;
if(p.first().func_175148_a(EnumPlayerModelParts.HAT)) int barY = (int) (posPerc * (height - 32 - 32));
Gui.drawScaledCustomSizeModalRect(k2, l2, 40.0F, 8.0F, 8, 8, 16, 16, 64.0F, 64.0F);
GlStateManager.resetColor(); 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 {
l2 += 16+5; }
fitting++;
if(l2+32 > lowerBound) {
break;
}
}
int dw = Mouse.getDWheel(); super.drawScreen(mouseX, mouseY, partialTicks);
if(dw > 0) { }
dw = -1;
} else if(dw < 0) {
dw = 1;
}
upperPlayer = Math.max(Math.min(upperPlayer+dw, playerCount-fitting), 0); private class PlayerComparator implements Comparator<EntityPlayer> {
if(fitting < playerCount) { @Override
float visiblePerc = ((float)fitting)/playerCount; public int compare(EntityPlayer o1, EntityPlayer o2) {
int barHeight = (int)(visiblePerc*(height-32-32)); if(isSpectator(o1) && !isSpectator(o2)) {
return 1;
} else if(isSpectator(o2) && !isSpectator(o1)) {
return -1;
} else {
return o1.getName().compareToIgnoreCase(o2.getName());
}
}
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,71 +1,69 @@
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 GuiVideoFramerateSlider(int buttonId, int p_i45017_2_, int p_i45017_3_, int initialFramerate, String displayKey) { public boolean dragging;
super(buttonId, p_i45017_2_, p_i45017_3_, 150, 20, ""); private String displayKey;
this.sliderValue = normalizeValue(initialFramerate); private float sliderValue;
this.displayString = displayKey+": "+translate(initialFramerate); public GuiVideoFramerateSlider(int buttonId, int p_i45017_2_, int p_i45017_3_, int initialFramerate, String displayKey) {
this.displayKey = displayKey; super(buttonId, p_i45017_2_, p_i45017_3_, 150, 20, "");
} this.sliderValue = normalizeValue(initialFramerate);
this.displayString = displayKey + ": " + translate(initialFramerate);
this.displayKey = displayKey;
}
private String displayKey; private String translate(int value) {
private float sliderValue; return String.valueOf(value);
public boolean dragging; }
private String translate(int value) { protected int getHoverState(boolean mouseOver) {
return String.valueOf(value); return 0;
} }
protected int getHoverState(boolean mouseOver) { @Override
return 0; protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) {
} if(this.visible) {
if(this.dragging) {
sliderValue = (float) (mouseX - (this.xPosition + 4)) / (float) (this.width - 8);
sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F);
int f = denormalizeValue(sliderValue);
this.displayString = displayKey + ": " + translate(f);
ReplayMod.replaySettings.setVideoFramerate(f);
}
@Override mc.getTextureManager().bindTexture(buttonTextures);
protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) { GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
if (this.visible) { this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
if (this.dragging) { this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
sliderValue = (float)(mouseX - (this.xPosition + 4)) / (float)(this.width - 8); }
sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F); }
int f = denormalizeValue(sliderValue);
this.displayString = displayKey+": "+translate(f);
ReplayMod.replaySettings.setVideoFramerate(f);
}
mc.getTextureManager().bindTexture(buttonTextures); private float normalizeValue(int val) {
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); return (val - 10) / 110f;
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);
}
}
private float normalizeValue(int val) { private int denormalizeValue(float val) {
return (val-10)/110f; //Transfers the value ranging from 0.0 to 1.0 to the scale of 10 to 120
} float r = 110f * val;
return Math.round(10 + r);
}
private int denormalizeValue(float val) { public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
//Transfers the value ranging from 0.0 to 1.0 to the scale of 10 to 120 if(super.mousePressed(mc, mouseX, mouseY)) {
float r = 110f*val; this.dragging = true;
return Math.round(10+r); return true;
} } else {
return false;
}
}
public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { public void mouseReleased(int mouseX, int mouseY) {
if (super.mousePressed(mc, mouseX, mouseY)) { this.dragging = false;
this.dragging = true; }
return true;
} else {
return false;
}
}
public void mouseReleased(int mouseX, int mouseY) {
this.dragging = false;
}
} }

View File

@@ -1,85 +1,83 @@
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 GuiVideoQualitySlider(int buttonId, int p_i45017_2_, int p_i45017_3_, float d, String displayKey) { public boolean dragging;
super(buttonId, p_i45017_2_, p_i45017_3_, 150, 20, ""); private String displayKey;
this.sliderValue = normalizeValue(d); private float sliderValue;
this.displayString = displayKey+": "+translate(d); public GuiVideoQualitySlider(int buttonId, int p_i45017_2_, int p_i45017_3_, float d, String displayKey) {
this.displayKey = displayKey; super(buttonId, p_i45017_2_, p_i45017_3_, 150, 20, "");
} this.sliderValue = normalizeValue(d);
this.displayString = displayKey + ": " + translate(d);
this.displayKey = displayKey;
}
private String displayKey; private String translate(float value) {
private float sliderValue; if(value <= 0.3) {
public boolean dragging; return "Draft";
} else if(value <= 0.5) {
return "Normal";
} else if(value <= 0.7) {
return "Good";
}
return "Best";
}
private String translate(float value) { protected int getHoverState(boolean mouseOver) {
if(value <= 0.3) { return 0;
return "Draft"; }
} else if(value <= 0.5) {
return "Normal";
} else if(value <= 0.7) {
return "Good";
}
return "Best";
}
protected int getHoverState(boolean mouseOver) { @Override
return 0; protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) {
} if(this.visible) {
if(this.dragging) {
sliderValue = (float) (mouseX - (this.xPosition + 4)) / (float) (this.width - 8);
sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F);
float f = denormalizeValue(sliderValue);
f = snapValue(f);
sliderValue = normalizeValue(f);
this.displayString = displayKey + ": " + translate(f);
ReplayMod.replaySettings.setVideoQuality(f);
}
@Override mc.getTextureManager().bindTexture(buttonTextures);
protected void mouseDragged(Minecraft mc, int mouseX, int mouseY) { GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
if (this.visible) { this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
if (this.dragging) { this.drawTexturedModalRect(this.xPosition + (int) (sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
sliderValue = (float)(mouseX - (this.xPosition + 4)) / (float)(this.width - 8); }
sliderValue = MathHelper.clamp_float(sliderValue, 0.0F, 1.0F); }
float f = denormalizeValue(sliderValue);
f = snapValue(f);
sliderValue = normalizeValue(f);
this.displayString = displayKey+": "+translate(f);
ReplayMod.replaySettings.setVideoQuality(f);
}
mc.getTextureManager().bindTexture(buttonTextures); private float snapValue(float val) {
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); int i = Math.round(val * 10);
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)), this.yPosition, 0, 66, 4, 20); return i / 10f;
this.drawTexturedModalRect(this.xPosition + (int)(sliderValue * (float)(this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20); }
}
}
private float snapValue(float val) { private float normalizeValue(float val) {
int i = Math.round(val*10); return (val - 0.1f) / 0.8f;
return i/10f; }
}
private float normalizeValue(float val) { private float denormalizeValue(float val) {
return (val-0.1f)/0.8f; //Transfers the value ranging from 0.0 to 1.0 to the scale of 0.1 to 0.9
} float r = 0.8f * val;
return 0.1f + r;
}
private float denormalizeValue(float val) { public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
//Transfers the value ranging from 0.0 to 1.0 to the scale of 0.1 to 0.9 if(super.mousePressed(mc, mouseX, mouseY)) {
float r = 0.8f*val; this.dragging = true;
return 0.1f+r; return true;
} } else {
return false;
}
}
public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { public void mouseReleased(int mouseX, int mouseY) {
if (super.mousePressed(mc, mouseX, mouseY)) { this.dragging = false;
this.dragging = true; }
return true;
} else {
return false;
}
}
public void mouseReleased(int mouseX, int mouseY) {
this.dragging = false;
}
} }

View File

@@ -1,46 +1,46 @@
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;
static { static {
try { try {
text = GuiTextField.class.getDeclaredField(MCPNames.field("field_146216_j")); text = GuiTextField.class.getDeclaredField(MCPNames.field("field_146216_j"));
text.setAccessible(true); text.setAccessible(true);
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public PasswordTextField(int p_i45542_1_, FontRenderer p_i45542_2_, public PasswordTextField(int p_i45542_1_, FontRenderer p_i45542_2_,
int p_i45542_3_, int p_i45542_4_, int p_i45542_5_, int p_i45542_6_) { int p_i45542_3_, int p_i45542_4_, int p_i45542_5_, int p_i45542_6_) {
super(p_i45542_1_, p_i45542_2_, p_i45542_3_, p_i45542_4_, p_i45542_5_, super(p_i45542_1_, p_i45542_2_, p_i45542_3_, p_i45542_4_, p_i45542_5_,
p_i45542_6_); p_i45542_6_);
} }
@Override @Override
public void drawTextBox() { public void drawTextBox() {
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 += "*";
} }
try {
text.set(this, pw);
super.drawTextBox();
text.set(this, prev);
} catch(Exception e) {}
}
try {
text.set(this, pw);
super.drawTextBox();
text.set(this, prev);
} catch(Exception e) {
}
}
} }

View File

@@ -1,40 +1,38 @@
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;
import java.awt.*;
public class GuiArrowButton extends GuiButton { public class GuiArrowButton extends GuiButton {
private Minecraft mc = Minecraft.getMinecraft(); private boolean upwards = false;
private boolean upwards = false; public GuiArrowButton(int buttonId, int x, int y, String buttonText, boolean upwards) {
super(buttonId, x, y, buttonText);
public GuiArrowButton(int buttonId, int x, int y, String buttonText, boolean upwards) { this.upwards = upwards;
super(buttonId, x, y, buttonText); width = 20;
height = 20;
}
this.upwards = upwards; @Override
width = 20; public void drawButton(Minecraft mc, int mouseX, int mouseY) {
height = 20; try {
} super.drawButton(mc, mouseX, mouseY);
if(upwards) {
@Override for(int i = 0; i <= Math.ceil(height / 2) - 5; i++) {
public void drawButton(Minecraft mc, int mouseX, int mouseY) { drawHorizontalLine(xPosition + width - height + i + 4, xPosition + width - i - 6, yPosition + height - ((height / 3) + i + 2), Color.BLACK.getRGB());
try { }
super.drawButton(mc, mouseX, mouseY); } else {
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 / 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 { } catch(Exception e) {
for(int i=0; i<=Math.ceil(height/2)-5; i++) { e.printStackTrace();
drawHorizontalLine(xPosition+width-height+i+4, xPosition+width-i-6, yPosition+(height/3)+i+2, Color.BLACK.getRGB()); }
} }
}
} catch(Exception e) {
e.printStackTrace();
}
}
} }

View File

@@ -1,197 +1,192 @@
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 final int visibleDropout;
private boolean open = false; private final int dropoutElementHeight = 14;
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 Minecraft mc = Minecraft.getMinecraft(); private int upperIndex = 0;
private List<T> elements = new ArrayList<T>();
private final int visibleDropout; public GuiDropdown(int id, FontRenderer fontRenderer,
private final int dropoutElementHeight = 14; int xPos, int yPos, int width, int visibleDropout) {
private final int maxDropoutHeight; super(id, fontRenderer, xPos, yPos, width, 20);
this.visibleDropout = visibleDropout;
this.maxDropoutHeight = dropoutElementHeight * visibleDropout;
}
private List<SelectionListener> selectionListeners = new ArrayList<SelectionListener>(); @Override
public void drawTextBox() {
if(elements.size() > selectionIndex && selectionIndex >= 0) {
setText(mc.fontRendererObj.trimStringToWidth(
elements.get(selectionIndex).toString(), width - 8));
} else {
setText("");
}
super.drawTextBox();
private int upperIndex = 0; //Draw the right part of the Dropdown
drawRect(xPosition + width - height, yPosition, xPosition + width, yPosition + height, -16777216);
drawRect(xPosition + width - height, yPosition, this.xPosition + width - height + 1, yPosition + height, -6250336);
public GuiDropdown(int id, FontRenderer fontRenderer, //heroically draw the triangle line by line instead of using a texture
int xPos, int yPos, int width, int visibleDropout) { for(int i = 0; i <= Math.ceil(height / 2) - 4; i++) {
super(id, fontRenderer, xPos, yPos, width, 20); drawHorizontalLine(xPosition + width - height + i + 4, xPosition + width - i - 4, yPosition + (height / 4) + i + 2, -6250336);
this.visibleDropout = visibleDropout; }
this.maxDropoutHeight = dropoutElementHeight*visibleDropout;
}
@Override if(open && elements.size() > 0) {
public void drawTextBox() { //draw the dropout part when opened
if(elements.size() > selectionIndex && selectionIndex >= 0) {
setText(mc.fontRendererObj.trimStringToWidth(
elements.get(selectionIndex).toString(), width-8));
} else {
setText("");
}
super.drawTextBox();
//Draw the right part of the Dropdown boolean drawScrollBar = false;
drawRect(xPosition+width-height, yPosition, xPosition+width, yPosition+height, -16777216);
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 int requiredHeight = elements.size() * dropoutElementHeight;
for(int i=0; i<=Math.ceil(height/2)-4; i++) { if(requiredHeight > maxDropoutHeight) {
drawHorizontalLine(xPosition+width-height+i+4, xPosition+width-i-4, yPosition+(height/4)+i+2, -6250336); requiredHeight = maxDropoutHeight;
} drawScrollBar = true;
}
if(open && elements.size() > 0) { //The light outline
//draw the dropout part when opened drawRect(xPosition - 1, yPosition + height, xPosition + width + 1, yPosition + height + requiredHeight + 1, -6250336);
boolean drawScrollBar = false; //The dark inside
drawRect(xPosition, yPosition + height + 1, xPosition + width, yPosition + height + requiredHeight, -16777216);
int requiredHeight = elements.size()*dropoutElementHeight; //The elements
if(requiredHeight > maxDropoutHeight) { int y = 0;
requiredHeight = maxDropoutHeight; int i = 0;
drawScrollBar = true; for(T obj : elements) {
} if(i < upperIndex) {
i++;
continue;
}
drawHorizontalLine(xPosition, xPosition + width, yPosition + height + y, -6250336);
String toWrite = mc.fontRendererObj.trimStringToWidth(obj.toString(), width - 8);
drawString(mc.fontRendererObj, toWrite, xPosition + 4, yPosition + height + y + 4, Color.WHITE.getRGB());
//The light outline y += dropoutElementHeight;
drawRect(xPosition-1, yPosition+height, xPosition+width+1, yPosition+height+requiredHeight+1, -6250336); i++;
if(y >= requiredHeight) {
break;
}
}
//The dark inside if(drawScrollBar) {
drawRect(xPosition, yPosition+height+1, xPosition+width, yPosition+height+requiredHeight, -16777216); //The scroll bar
int dw = Mouse.getDWheel();
if(dw > 0) {
dw = -1;
} else if(dw < 0) {
dw = 1;
}
//The elements upperIndex = Math.max(Math.min(upperIndex + dw, elements.size() - visibleDropout), 0);
int y = 0;
int i = 0;
for(T obj : elements) {
if(i<upperIndex) {
i++;
continue;
}
drawHorizontalLine(xPosition, xPosition+width, yPosition+height+y, -6250336);
String toWrite = mc.fontRendererObj.trimStringToWidth(obj.toString(), width-8);
drawString(mc.fontRendererObj, toWrite, xPosition+4, yPosition+height+y+4, Color.WHITE.getRGB());
y += dropoutElementHeight; drawRect(xPosition + width - 3, yPosition + height + 1, xPosition + width, yPosition + height + requiredHeight, Color.DARK_GRAY.getRGB());
i++;
if(y >= requiredHeight) {
break;
}
}
if(drawScrollBar) { float visiblePerc = ((float) visibleDropout) / elements.size();
//The scroll bar int barHeight = (int) (visiblePerc * (requiredHeight - 1));
int dw = Mouse.getDWheel();
if(dw > 0) {
dw = -1;
} else if(dw < 0) {
dw = 1;
}
upperIndex = Math.max(Math.min(upperIndex+dw, elements.size()-visibleDropout), 0); float posPerc = ((float) upperIndex) / elements.size();
int barY = (int) (posPerc * (requiredHeight - 1));
drawRect(xPosition+width-3, yPosition+height+1, xPosition+width, yPosition+height+requiredHeight, Color.DARK_GRAY.getRGB()); drawRect(xPosition + width - 3, yPosition + height + barY, xPosition + width, yPosition + height + 2 + barY + barHeight, -6250336);
}
}
}
float visiblePerc = ((float)visibleDropout)/elements.size(); @Override
int barHeight = (int)(visiblePerc*(requiredHeight-1)); public void mouseClicked(int xPos, int yPos, int mouseButton) {
if(xPos > xPosition + width - height && xPos < xPosition + width && yPos > yPosition && yPos < yPosition + height) {
open = !open;
} else {
if(xPos > xPosition && xPos < xPosition + width && open) {
int requiredHeight = Math.min(maxDropoutHeight, elements.size() * dropoutElementHeight);
if(yPos > yPosition + height && yPos < yPosition + height + requiredHeight) {
int clickedIndex = (int) Math.floor((yPos - (yPosition + height)) / dropoutElementHeight) + upperIndex;
this.selectionIndex = clickedIndex;
fireSelectionChangeEvent();
}
open = false;
} else {
open = false;
}
}
}
float posPerc = ((float)upperIndex)/elements.size(); @Override
int barY = (int)(posPerc*(requiredHeight-1)); public void setText(String text) {
if(!getText().equals(text)) {
super.setText(text);
}
}
drawRect(xPosition+width-3, yPosition+height+barY, xPosition+width, yPosition+height+2+barY+barHeight, -6250336); public void setElements(List<T> elements) {
} this.elements = elements;
} if(selectionIndex == -1 && elements.size() > 0) {
} selectionIndex = 0;
}
}
@Override public void clearElements() {
public void mouseClicked(int xPos, int yPos, int mouseButton) { this.elements = new ArrayList<T>();
if(xPos > xPosition+width-height && xPos < xPosition+width && yPos > yPosition && yPos < yPosition+height) { selectionIndex = -1;
open = !open; }
} else {
if(xPos > xPosition && xPos < xPosition+width && open) {
int requiredHeight = Math.min(maxDropoutHeight, elements.size()*dropoutElementHeight);
if(yPos > yPosition+height && yPos < yPosition+height+requiredHeight) {
int clickedIndex = (int)Math.floor((yPos - (yPosition+height)) / dropoutElementHeight) + upperIndex;
this.selectionIndex = clickedIndex;
fireSelectionChangeEvent();
}
open = false;
} else {
open = false;
}
}
}
@Override public void addElement(T element) {
public void setText(String text) { this.elements.add(element);
if(!getText().equals(text)) { if(selectionIndex == -1) {
super.setText(text); selectionIndex = 0;
} }
} }
private List<T> elements = new ArrayList<T>(); public T getElement(int index) {
return elements.get(index);
}
public void setSelectionIndex(int index) { public List<T> getAllElements() {
this.selectionIndex = index; return elements;
if(selectionIndex < 0) selectionIndex = -1; }
fireSelectionChangeEvent();
}
public void setElements(List<T> elements) { public int getSelectionIndex() {
this.elements = elements; return selectionIndex;
if(selectionIndex == -1 && elements.size() > 0) { }
selectionIndex = 0;
}
}
public void clearElements() { public void setSelectionIndex(int index) {
this.elements = new ArrayList<T>(); this.selectionIndex = index;
selectionIndex = -1; if(selectionIndex < 0) selectionIndex = -1;
} fireSelectionChangeEvent();
}
public void addElement(T element) { private void fireSelectionChangeEvent() {
this.elements.add(element); for(SelectionListener listener : selectionListeners) {
if(selectionIndex == -1) { listener.onSelectionChanged(selectionIndex);
selectionIndex = 0; }
} }
}
public T getElement(int index) { public void addSelectionListener(SelectionListener listener) {
return elements.get(index); this.selectionListeners.add(listener);
} }
public List<T> getAllElements() { public void removeSelectionListener(SelectionListener listener) {
return elements; this.selectionListeners.remove(listener);
} }
public int getSelectionIndex() { public boolean isExpanded() {
return selectionIndex; return open;
} }
private void fireSelectionChangeEvent() {
for(SelectionListener listener : selectionListeners) {
listener.onSelectionChanged(selectionIndex);
}
}
public void addSelectionListener(SelectionListener listener) {
this.selectionListeners.add(listener);
}
public void removeSelectionListener(SelectionListener listener) {
this.selectionListeners.remove(listener);
}
public boolean isExpanded() {
return open;
}
} }

View File

@@ -1,150 +1,146 @@
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; public final static int elementHeight = 14;
private int selectionIndex = -1;
private Minecraft mc = Minecraft.getMinecraft();
private int visibleElements;
private int upperIndex = 0;
private Minecraft mc = Minecraft.getMinecraft(); private List<SelectionListener> selectionListeners = new ArrayList<SelectionListener>();
private List<T> elements = new ArrayList<T>();
private int visibleElements; public GuiEntryList(int id, FontRenderer fontRenderer,
public final static int elementHeight = 14; int xPos, int yPos, int width, int visibleEntries) {
super(id, fontRenderer, xPos, yPos, width, elementHeight * visibleEntries - 1);
this.visibleElements = visibleEntries;
}
private int upperIndex = 0; public void setVisibleElements(int rows) {
this.visibleElements = rows;
this.height = elementHeight * visibleElements - 1;
}
private List<SelectionListener> selectionListeners = new ArrayList<SelectionListener>(); @Override
public void drawTextBox() {
try {
super.drawTextBox();
//drawing the entries
for(int i = 0; i - upperIndex < visibleElements; i++) {
if(i < upperIndex) continue;
public GuiEntryList(int id, FontRenderer fontRenderer, if(i >= elements.size()) break;
int xPos, int yPos, int width, int visibleEntries) {
super(id, fontRenderer, xPos, yPos, width, elementHeight*visibleEntries-1);
this.visibleElements = visibleEntries;
}
public void setVisibleElements(int rows) { if(i == selectionIndex) {
this.visibleElements = rows; drawRect(xPosition, yPosition + (i - upperIndex) * elementHeight, xPosition + width,
this.height = elementHeight*visibleElements-1; yPosition + (i + 1 - upperIndex) * elementHeight - 1, Color.GRAY.getRGB());
} }
@Override drawRect(xPosition, yPosition + (i + 1 - upperIndex) * elementHeight - 1, xPosition + width,
public void drawTextBox() { yPosition + (i + 1 - upperIndex) * elementHeight, -6250336);
try { drawString(mc.fontRendererObj, mc.fontRendererObj.trimStringToWidth(elements.get(i).toString(), width - 4),
super.drawTextBox(); xPosition + 2, yPosition + (i - upperIndex) * elementHeight + 3, Color.WHITE.getRGB());
//drawing the entries }
for(int i=0; i-upperIndex<visibleElements; i++) {
if(i<upperIndex) continue;
if(i >= elements.size()) break; //drawing the scroll bar
if(elements.size() > visibleElements) {
//handle scroll events
int dw = Mouse.getDWheel();
if(dw > 0) {
dw = -1;
} else if(dw < 0) {
dw = 1;
}
if(i == selectionIndex) { upperIndex = Math.max(Math.min(upperIndex + dw, elements.size() - visibleElements), 0);
drawRect(xPosition, yPosition+(i-upperIndex)*elementHeight, xPosition+width,
yPosition+(i+1-upperIndex)*elementHeight-1, Color.GRAY.getRGB());
}
drawRect(xPosition, yPosition+(i+1-upperIndex)*elementHeight-1, xPosition+width, float visiblePerc = ((float) visibleElements) / elements.size();
yPosition+(i+1-upperIndex)*elementHeight, -6250336); int barHeight = (int) (visiblePerc * (height - 1));
drawString(mc.fontRendererObj, mc.fontRendererObj.trimStringToWidth(elements.get(i).toString(), width-4),
xPosition+2, yPosition+(i-upperIndex)*elementHeight+3, Color.WHITE.getRGB());
}
//drawing the scroll bar float posPerc = ((float) upperIndex) / elements.size();
if(elements.size() > visibleElements) { int barY = (int) (posPerc * (height - 1));
//handle scroll events
int dw = Mouse.getDWheel();
if(dw > 0) {
dw = -1;
} else if(dw < 0) {
dw = 1;
}
upperIndex = Math.max(Math.min(upperIndex+dw, elements.size()-visibleElements), 0); 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);
}
} catch(Exception e) {
e.printStackTrace();
}
}
float visiblePerc = ((float)visibleElements)/elements.size(); @Override
int barHeight = (int)(visiblePerc*(height-1)); public void mouseClicked(int xPos, int yPos, int mouseButton) {
if(!(xPos >= xPosition && xPos <= xPosition + width && yPos >= yPosition && yPos <= yPosition + height)) return;
int clickedIndex = (int) Math.floor((yPos - yPosition) / elementHeight) + upperIndex;
if(clickedIndex < elements.size() && clickedIndex >= 0) {
selectionIndex = clickedIndex;
fireSelectionChangeEvent();
}
}
float posPerc = ((float)upperIndex)/elements.size(); private void fireSelectionChangeEvent() {
int barY = (int)(posPerc*(height-1)); for(SelectionListener listener : selectionListeners) {
listener.onSelectionChanged(selectionIndex);
}
}
drawRect(xPosition+width-3, yPosition, xPosition+width, yPosition+height, Color.DARK_GRAY.getRGB()); @Override
drawRect(xPosition+width-3, yPosition+barY, xPosition+width, yPosition+1+barY+barHeight, -6250336); public void setText(String text) {
} }
} catch(Exception e) {
e.printStackTrace();
}
}
@Override public void setElements(List<T> elements) {
public void mouseClicked(int xPos, int yPos, int mouseButton) { this.elements = elements;
if(!(xPos >= xPosition && xPos <= xPosition+width && yPos >= yPosition && yPos <= yPosition+height)) return; if(selectionIndex == -1 && elements.size() > 0) {
int clickedIndex = (int)Math.floor((yPos-yPosition) / elementHeight) + upperIndex; selectionIndex = 0;
if(clickedIndex < elements.size() && clickedIndex >= 0) { }
selectionIndex = clickedIndex; }
fireSelectionChangeEvent();
}
}
private void fireSelectionChangeEvent() { public void clearElements() {
for(SelectionListener listener : selectionListeners) { this.elements = new ArrayList<T>();
listener.onSelectionChanged(selectionIndex); selectionIndex = -1;
} }
}
@Override public void addElement(T element) {
public void setText(String text) {} this.elements.add(element);
if(selectionIndex == -1) {
selectionIndex = 0;
}
}
private List<T> elements = new ArrayList<T>(); public T getElement(int index) {
if(index >= 0) {
return elements.get(index);
}
return null;
}
public void setElements(List<T> elements) { public int getSelectionIndex() {
this.elements = elements; return selectionIndex;
if(selectionIndex == -1 && elements.size() > 0) { }
selectionIndex = 0;
}
}
public void clearElements() { public void setSelectionIndex(int index) {
this.elements = new ArrayList<T>(); this.selectionIndex = index;
selectionIndex = -1; if(selectionIndex < 0) selectionIndex = -1;
} fireSelectionChangeEvent();
}
public void addElement(T element) { public void addSelectionListener(SelectionListener listener) {
this.elements.add(element); this.selectionListeners.add(listener);
if(selectionIndex == -1) { }
selectionIndex = 0;
}
}
public T getElement(int index) { public void removeSelectionListener(SelectionListener listener) {
if(index >= 0) { this.selectionListeners.remove(listener);
return elements.get(index); }
}
return null;
}
public int getSelectionIndex() {
return selectionIndex;
}
public void setSelectionIndex(int index) {
this.selectionIndex = index;
if(selectionIndex < 0) selectionIndex = -1;
fireSelectionChangeEvent();
}
public void addSelectionListener(SelectionListener listener) {
this.selectionListeners.add(listener);
}
public void removeSelectionListener(SelectionListener listener) {
this.selectionListeners.remove(listener);
}
} }

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,26 +1,26 @@
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;
public class GuiNumberInput extends GuiTextField { public class GuiNumberInput extends GuiTextField {
private int limit; private int limit;
public GuiNumberInput(int id, FontRenderer fontRenderer, public GuiNumberInput(int id, FontRenderer fontRenderer,
int xPos, int yPos, int width, int limit) { int xPos, int yPos, int width, int limit) {
super(id, fontRenderer, xPos, yPos, width, 20); super(id, fontRenderer, xPos, yPos, width, 20);
this.limit = limit; this.limit = limit;
} }
@Override @Override
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,114 +18,102 @@ 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 ResourceLocation textureResource;
private DynamicTexture dynTex = null;
private File imageFile;
private BufferedImage image = null;
private GuiReplayListExtended parent;
private FileInfo fileInfo; public GuiReplayListEntry(GuiReplayListExtended parent, FileInfo fileInfo, File imageFile) {
this.fileInfo = fileInfo;
this.parent = parent;
dynTex = null;
this.imageFile = imageFile;
}
private ResourceLocation textureResource; public FileInfo getFileInfo() {
private DynamicTexture dynTex = null; return fileInfo;
}
private File imageFile; @Override
private BufferedImage image = null; public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected) {
private GuiReplayListExtended parent; try {
if(fileInfo.getName() == null || fileInfo.getName().length() < 1) {
fileInfo.setName("No Name");
}
minecraft.fontRendererObj.drawString(fileInfo.getName(), x + 3, y + 1, 16777215);
public FileInfo getFileInfo() { if(y < -slotHeight || y > parent.height) {
return fileInfo; if(registered) {
} registered = false;
ResourceHelper.freeResource(textureResource);
textureResource = null;
image = null;
dynTex = null;
}
return;
} else {
if(!registered) {
textureResource = new ResourceLocation("thumbs/" + fileInfo.getName() + fileInfo.getId());
if(imageFile == null) {
image = ResourceHelper.getDefaultThumbnail();
} else {
image = ImageIO.read(imageFile);
}
dynTex = new DynamicTexture(image);
minecraft.getTextureManager().loadTexture(textureResource, dynTex);
dynTex.updateDynamicTexture();
ResourceHelper.registerResource(textureResource);
registered = true;
}
public GuiReplayListEntry(GuiReplayListExtended parent, FileInfo fileInfo, File imageFile) { minecraft.getTextureManager().bindTexture(textureResource);
this.fileInfo = fileInfo; Gui.drawScaledCustomSizeModalRect(x - 60, y, 0, 0, 1280, 720, 57, 32, 1280, 720);
this.parent = parent; }
dynTex = null;
this.imageFile = imageFile;
}
boolean registered = false; List<String> list = new ArrayList<String>();
list.add(fileInfo.getMetadata().getServerName() + " (" + dateFormat.format(new Date(fileInfo.getMetadata().getDate())) + ")");
@Override list.add(String.format("%02dm%02ds",
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected) { TimeUnit.MILLISECONDS.toMinutes(fileInfo.getMetadata().getDuration()),
try { TimeUnit.MILLISECONDS.toSeconds(fileInfo.getMetadata().getDuration()) -
if(fileInfo.getName() == null || fileInfo.getName().length() < 1) { TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(fileInfo.getMetadata().getDuration()))
fileInfo.setName("No Name"); ));
}
minecraft.fontRendererObj.drawString(fileInfo.getName(), x + 3, y + 1, 16777215);
if(y < -slotHeight || y > parent.height) { for(int l1 = 0; l1 < Math.min(list.size(), 2); ++l1) {
if(registered) { minecraft.fontRendererObj.drawString((String) list.get(l1), x + 3, y + 12 + minecraft.fontRendererObj.FONT_HEIGHT * l1, 8421504);
registered = false; }
ResourceHelper.freeResource(textureResource); } catch(Exception e) {
textureResource = null; e.printStackTrace();
image = null; }
dynTex = null; }
}
return;
} else {
if(!registered) {
textureResource = new ResourceLocation("thumbs/"+fileInfo.getName()+fileInfo.getId());
if(imageFile == null) {
image = ResourceHelper.getDefaultThumbnail();
} else {
image = ImageIO.read(imageFile);
}
dynTex = new DynamicTexture(image);
minecraft.getTextureManager().loadTexture(textureResource, dynTex);
dynTex.updateDynamicTexture();
ResourceHelper.registerResource(textureResource);
registered = true;
}
minecraft.getTextureManager().bindTexture(textureResource); @Override
Gui.drawScaledCustomSizeModalRect(x-60, y, 0, 0, 1280, 720, 57, 32, 1280, 720); public void setSelected(int p_178011_1_, int p_178011_2_, int p_178011_3_) {
} }
List<String> list = new ArrayList<String>(); @Override
list.add(fileInfo.getMetadata().getServerName()+" ("+dateFormat.format(new Date(fileInfo.getMetadata().getDate()))+")"); 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_) {
for(int slot = 0; slot < parent.getSize(); slot++) {
if(parent.getListEntry(slot) == this) {
parent.elementClicked(slot, false, p_148278_5_, p_148278_6_);
break;
}
}
list.add(String.format("%02dm%02ds", return true;
TimeUnit.MILLISECONDS.toMinutes(fileInfo.getMetadata().getDuration()), }
TimeUnit.MILLISECONDS.toSeconds(fileInfo.getMetadata().getDuration()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(fileInfo.getMetadata().getDuration()))
));
for (int l1 = 0; l1 < Math.min(list.size(), 2); ++l1) { @Override
minecraft.fontRendererObj.drawString((String)list.get(l1), x + 3, y + 12 + minecraft.fontRendererObj.FONT_HEIGHT * l1, 8421504); public void mouseReleased(int slotIndex, int x, int y, int mouseEvent,
} int relativeX, int relativeY) {
} catch(Exception e) { }
e.printStackTrace();
}
}
@Override
public void setSelected(int p_178011_1_, int p_178011_2_, int p_178011_3_) {}
@Override
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_) {
for(int slot = 0; slot<parent.getSize(); slot++) {
if(parent.getListEntry(slot) == this) {
parent.elementClicked(slot, false, p_148278_5_, p_148278_6_);
break;
}
}
return true;
}
@Override
public void mouseReleased(int slotIndex, int x, int y, int mouseEvent,
int relativeX, int relativeY) {}
} }

View File

@@ -1,71 +1,66 @@
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 GuiReplayListExtended(Minecraft mcIn, int p_i45010_2_, public int selected = -1;
int p_i45010_3_, int p_i45010_4_, int p_i45010_5_, int p_i45010_6_) { private List<GuiReplayListEntry> entries = new ArrayList<GuiReplayListEntry>();
super(mcIn, p_i45010_2_, p_i45010_3_, p_i45010_4_, p_i45010_5_, p_i45010_6_);
}
public int selected = -1; public GuiReplayListExtended(Minecraft mcIn, int p_i45010_2_,
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_);
}
@Override @Override
protected void elementClicked(int slotIndex, boolean isDoubleClick, protected void elementClicked(int slotIndex, boolean isDoubleClick,
int mouseX, int mouseY) { int mouseX, int mouseY) {
super.elementClicked(slotIndex, isDoubleClick, mouseX, mouseY); super.elementClicked(slotIndex, isDoubleClick, mouseX, mouseY);
this.selected = slotIndex; this.selected = slotIndex;
} }
@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,120 +69,92 @@ public abstract class GuiReplayListExtended extends GuiListExtended {
} }
} }
public void clearEntries() {
entries = new ArrayList<GuiReplayListEntry>();
}
private List<GuiReplayListEntry> entries = new ArrayList<GuiReplayListEntry>(); public void addEntry(FileInfo fileInfo, File image) {
entries.add(new GuiReplayListEntry(this, fileInfo, image));
}
public void clearEntries() { @Override
entries = new ArrayList<GuiReplayListEntry>(); public GuiReplayListEntry getListEntry(int index) {
} return entries.get(index);
}
public void addEntry(FileInfo fileInfo, File image) { @Override
entries.add(new GuiReplayListEntry(this, fileInfo, image)); protected int getSize() {
} return entries.size();
}
@Override
public GuiReplayListEntry getListEntry(int index) {
return entries.get(index);
}
@Override
protected int getSize() {
return entries.size();
}
@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)) int i2 = this.getScrollBarX();
{
if (this.initialClickY == -1.0F)
{
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,170 +1,163 @@
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 {
private static final int EMPTY = 0; private static final int EMPTY = 0;
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 static Minecraft mc = Minecraft.getMinecraft();
private GuiScreen parent, successScreen;
private int textState = 0;
private GuiTextField username;
private PasswordTextField password;
private GuiButton loginButton;
private GuiButton cancelButton;
private int lastMouseX, lastMouseY;
private float lastPartialTicks;
private GuiScreen parent, successScreen; public GuiLoginPrompt(GuiScreen parent, GuiScreen successScreen) {
this.parent = parent;
this.successScreen = successScreen;
}
private int textState = 0; @Override
public void initGui() {
Keyboard.enableRepeatEvents(true);
private static Minecraft mc = Minecraft.getMinecraft(); username = new GuiTextField(GuiConstants.REPLAY_CENTER_LOGIN_TEXT_ID, fontRendererObj, this.width / 2 - 45, 30, 145, 20);
username.setEnabled(true);
username.setFocused(true);
private GuiTextField username; password = new PasswordTextField(GuiConstants.REPLAY_CENTER_PASSWORD_TEXT_ID, fontRendererObj, this.width / 2 - 45, 60, 145, 20);
private PasswordTextField password; password.setEnabled(true);
private GuiButton loginButton; password.setFocused(false);
private GuiButton cancelButton;
public GuiLoginPrompt(GuiScreen parent, GuiScreen successScreen) { loginButton = new GuiButton(GuiConstants.LOGIN_OKAY_BUTTON, this.width / 2 - 150 - 2, 110, "Login");
this.parent = parent; loginButton.width = 150;
this.successScreen = successScreen; loginButton.enabled = false;
} buttonList.add(loginButton);
@Override cancelButton = new GuiButton(GuiConstants.LOGIN_CANCEL_BUTTON, this.width / 2 + 2, 110, "Cancel");
public void initGui() { cancelButton.width = 150;
Keyboard.enableRepeatEvents(true); buttonList.add(cancelButton);
}
username = new GuiTextField(GuiConstants.REPLAY_CENTER_LOGIN_TEXT_ID, fontRendererObj, this.width/2 - 45, 30, 145, 20); @Override
username.setEnabled(true); protected void actionPerformed(GuiButton button) throws IOException {
username.setFocused(true); if(button.id == GuiConstants.LOGIN_OKAY_BUTTON) {
if(button.enabled) {
//Authenticate
textState = LOGGING_IN;
password = new PasswordTextField(GuiConstants.REPLAY_CENTER_PASSWORD_TEXT_ID, fontRendererObj, this.width/2 - 45, 60, 145, 20); new Thread(new Runnable() {
password.setEnabled(true); @Override
password.setFocused(false); public void run() {
switch(AuthenticationHandler.authenticate(username.getText(), password.getText())) {
case AuthenticationHandler.SUCCESS:
textState = EMPTY;
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
mc.displayGuiScreen(successScreen);
}
});
break;
case AuthenticationHandler.INVALID:
textState = INVALID_LOGIN;
break;
case AuthenticationHandler.NO_CONNECTION:
textState = NO_CONNECTION;
break;
}
}
}).start();
}
} else if(button.id == GuiConstants.LOGIN_CANCEL_BUTTON) {
mc.displayGuiScreen(parent);
}
}
loginButton = new GuiButton(GuiConstants.LOGIN_OKAY_BUTTON, this.width/2 - 150 - 2, 110, "Login"); @Override
loginButton.width = 150; public void drawScreen(int mouseX, int mouseY, float partialTicks) {
loginButton.enabled = false; lastMouseX = mouseX;
buttonList.add(loginButton); lastMouseY = mouseY;
lastPartialTicks = partialTicks;
cancelButton = new GuiButton(GuiConstants.LOGIN_CANCEL_BUTTON, this.width/2 + 2, 110, "Cancel"); this.drawDefaultBackground();
cancelButton.width = 150; drawCenteredString(fontRendererObj, "Login to ReplayMod.com", this.width / 2, 10, Color.WHITE.getRGB());
buttonList.add(cancelButton);
}
@Override drawString(fontRendererObj, "Username", this.width / 2 - 100, 37, Color.WHITE.getRGB());
protected void actionPerformed(GuiButton button) throws IOException { username.drawTextBox();
if(button.id == GuiConstants.LOGIN_OKAY_BUTTON) {
if(button.enabled) {
//Authenticate
textState = LOGGING_IN;
new Thread(new Runnable() { drawString(fontRendererObj, "Password", this.width / 2 - 100, 67, Color.WHITE.getRGB());
@Override password.drawTextBox();
public void run() {
switch(AuthenticationHandler.authenticate(username.getText(), password.getText())) {
case AuthenticationHandler.SUCCESS:
textState = EMPTY;
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
mc.displayGuiScreen(successScreen);
}
});
break;
case AuthenticationHandler.INVALID:
textState = INVALID_LOGIN;
break;
case AuthenticationHandler.NO_CONNECTION:
textState = NO_CONNECTION;
break;
}
}
}).start();
}
} else if(button.id == GuiConstants.LOGIN_CANCEL_BUTTON) {
mc.displayGuiScreen(parent);
}
}
private int lastMouseX, lastMouseY; switch(textState) {
private float lastPartialTicks; case INVALID_LOGIN:
drawCenteredString(fontRendererObj, "Incorrect username or password.", this.width / 2, 92, Color.RED.getRGB());
break;
case LOGGING_IN:
drawCenteredString(fontRendererObj, "Logging in...", this.width / 2, 92, Color.WHITE.getRGB());
break;
case NO_CONNECTION:
drawCenteredString(fontRendererObj, "Could not connect to ReplayMod.com", this.width / 2, 92, Color.RED.getRGB());
break;
}
super.drawScreen(mouseX, mouseY, partialTicks);
}
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
lastMouseX = mouseX; super.mouseClicked(mouseX, mouseY, mouseButton);
lastMouseY = mouseY; username.mouseClicked(mouseX, mouseY, mouseButton);
lastPartialTicks = partialTicks; password.mouseClicked(mouseX, mouseY, mouseButton);
}
this.drawDefaultBackground(); @Override
drawCenteredString(fontRendererObj, "Login to ReplayMod.com", this.width/2, 10, Color.WHITE.getRGB()); public void updateScreen() {
username.updateCursorCounter();
password.updateCursorCounter();
}
drawString(fontRendererObj, "Username", this.width/2 - 100, 37, Color.WHITE.getRGB()); @Override
username.drawTextBox(); public void onGuiClosed() {
Keyboard.enableRepeatEvents(false);
}
drawString(fontRendererObj, "Password", this.width/2 - 100, 67, Color.WHITE.getRGB()); @Override
password.drawTextBox(); protected void keyTyped(char typedChar, int keyCode) throws IOException {
if(keyCode == Keyboard.KEY_TAB) {
switch(textState) { if(password.isFocused()) {
case INVALID_LOGIN: password.setFocused(false);
drawCenteredString(fontRendererObj, "Incorrect username or password.", this.width/2, 92, Color.RED.getRGB()); username.setFocused(true);
break; } else {
case LOGGING_IN: username.setFocused(false);
drawCenteredString(fontRendererObj, "Logging in...", this.width/2, 92, Color.WHITE.getRGB()); password.setFocused(true);
break; }
case NO_CONNECTION: return;
drawCenteredString(fontRendererObj, "Could not connect to ReplayMod.com", this.width/2, 92, Color.RED.getRGB()); }
break; if(keyCode == 28) { //Enter key
} actionPerformed(loginButton);
super.drawScreen(mouseX, mouseY, partialTicks); return;
} }
if(username.isFocused()) {
@Override username.textboxKeyTyped(typedChar, keyCode);
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { } else if(password.isFocused()) {
super.mouseClicked(mouseX, mouseY, mouseButton); password.textboxKeyTyped(typedChar, keyCode);
username.mouseClicked(mouseX, mouseY, mouseButton); }
password.mouseClicked(mouseX, mouseY, mouseButton); loginButton.enabled = username.getText().length() > 0 && password.getText().length() > 0;
} }
@Override
public void updateScreen() {
username.updateCursorCounter();
password.updateCursorCounter();
}
@Override
public void onGuiClosed() {
Keyboard.enableRepeatEvents(false);
}
@Override
protected void keyTyped(char typedChar, int keyCode) throws IOException {
if(keyCode == Keyboard.KEY_TAB) {
if(password.isFocused()) {
password.setFocused(false);
username.setFocused(true);
} else {
username.setFocused(false);
password.setFocused(true);
}
return;
}
if(keyCode == 28) { //Enter key
actionPerformed(loginButton);
return;
}
if(username.isFocused()) {
username.textboxKeyTyped(typedChar, keyCode);
} else if(password.isFocused()) {
password.textboxKeyTyped(typedChar, keyCode);
}
loginButton.enabled = username.getText().length() > 0 && password.getText().length() > 0;
}
} }

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,247 +8,251 @@ 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 { private static final SearchQuery recentFileSearchQuery = new SearchQuery(false, null, null, null, null, null,
RECENT_FILES, BEST_FILES, MY_FILES, SEARCH; null, null, null, null);
} private static final SearchQuery bestFileSearchQuery = new SearchQuery(true, 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 bestFilePagination = new SearchPagination(bestFileSearchQuery);
private GuiReplayListExtended currentList;
private ReplayFileList recentFileList, bestFileList, myFileList, searchFileList;
private Tab currentTab = Tab.RECENT_FILES;
private SearchPagination myFilePagination;
private GuiReplayListExtended currentList; 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;
}
private ReplayFileList recentFileList, bestFileList, myFileList, searchFileList; @Override
public void initGui() {
Keyboard.enableRepeatEvents(true);
private Tab currentTab = Tab.RECENT_FILES; if(AuthenticationHandler.isAuthenticated()) {
SearchQuery query = new SearchQuery();
query.auth = AuthenticationHandler.getKey();
query.order = false;
myFilePagination = new SearchPagination(query);
}
private static final SearchQuery recentFileSearchQuery = new SearchQuery(false, null, null, null, null, null, //Top Button Bar
null, null, null, null); List<GuiButton> buttonBar = new ArrayList<GuiButton>();
private static final SearchQuery bestFileSearchQuery = new SearchQuery(true, null, null, null, null, null, GuiButton recentButton = new GuiButton(GuiConstants.CENTER_RECENT_BUTTON, 20, 30, "Newest Replays");
null, null, null, null); buttonBar.add(recentButton);
private final SearchPagination recentFilePagination = new SearchPagination(recentFileSearchQuery); GuiButton bestButton = new GuiButton(GuiConstants.CENTER_BEST_BUTTON, 20, 30, "Best Replays");
private final SearchPagination bestFilePagination = new SearchPagination(bestFileSearchQuery); buttonBar.add(bestButton);
private SearchPagination myFilePagination;
@Override GuiButton ownReplayButton = new GuiButton(GuiConstants.CENTER_MY_REPLAYS_BUTTON, 20, 30, "My Replays");
public void initGui() { ownReplayButton.enabled = AuthenticationHandler.isAuthenticated();
Keyboard.enableRepeatEvents(true); buttonBar.add(ownReplayButton);
if(AuthenticationHandler.isAuthenticated()) { GuiButton searchButton = new GuiButton(GuiConstants.CENTER_SEARCH_BUTTON, 20, 30, "Search");
SearchQuery query = new SearchQuery(); buttonBar.add(searchButton);
query.auth = AuthenticationHandler.getKey();
query.order = false;
myFilePagination = new SearchPagination(query);
}
//Top Button Bar int i = 0;
List<GuiButton> buttonBar = new ArrayList<GuiButton>(); for(GuiButton b : buttonBar) {
int w = this.width - 30;
int w2 = w / buttonBar.size();
GuiButton recentButton = new GuiButton(GuiConstants.CENTER_RECENT_BUTTON, 20, 30, "Newest Replays"); int x = 15 + (w2 * i);
buttonBar.add(recentButton); b.xPosition = x + 2;
b.yPosition = 20;
b.width = w2 - 4;
GuiButton bestButton = new GuiButton(GuiConstants.CENTER_BEST_BUTTON, 20, 30, "Best Replays"); buttonList.add(b);
buttonBar.add(bestButton);
GuiButton ownReplayButton = new GuiButton(GuiConstants.CENTER_MY_REPLAYS_BUTTON, 20, 30, "My Replays"); i++;
ownReplayButton.enabled = AuthenticationHandler.isAuthenticated(); }
buttonBar.add(ownReplayButton);
GuiButton searchButton = new GuiButton(GuiConstants.CENTER_SEARCH_BUTTON, 20, 30, "Search"); //Bottom Button Bar (dat alliteration)
buttonBar.add(searchButton); List<GuiButton> bottomBar = new ArrayList<GuiButton>();
int i = 0; GuiButton exitButton = new GuiButton(GuiConstants.CENTER_BACK_BUTTON, 20, 20, "Main Menu");
for(GuiButton b : buttonBar) { bottomBar.add(exitButton);
int w = this.width - 30;
int w2 = w/buttonBar.size();
int x = 15+(w2*i); GuiButton managerButton = new GuiButton(GuiConstants.CENTER_MANAGER_BUTTON, 20, 20, "Replay Viewer");
b.xPosition = x+2; bottomBar.add(managerButton);
b.yPosition = 20;
b.width = w2-4;
buttonList.add(b); GuiButton logoutButton = new GuiButton(GuiConstants.CENTER_LOGOUT_BUTTON, 20, 20, "Logout");
bottomBar.add(logoutButton);
i++; i = 0;
} for(GuiButton b : bottomBar) {
int w = this.width - 30;
int w2 = w / bottomBar.size();
//Bottom Button Bar (dat alliteration) int x = 15 + (w2 * i);
List<GuiButton> bottomBar = new ArrayList<GuiButton>(); b.xPosition = x + 2;
b.yPosition = height - 30;
b.width = w2 - 4;
GuiButton exitButton = new GuiButton(GuiConstants.CENTER_BACK_BUTTON, 20, 20, "Main Menu"); buttonList.add(b);
bottomBar.add(exitButton);
GuiButton managerButton = new GuiButton(GuiConstants.CENTER_MANAGER_BUTTON, 20, 20, "Replay Viewer"); i++;
bottomBar.add(managerButton); }
GuiButton logoutButton = new GuiButton(GuiConstants.CENTER_LOGOUT_BUTTON, 20, 20, "Logout"); showOnlineRecent();
bottomBar.add(logoutButton); }
i = 0; @Override
for(GuiButton b : bottomBar) { protected void actionPerformed(GuiButton button) throws java.io.IOException {
int w = this.width - 30; if(!button.enabled) return;
int w2 = w/bottomBar.size(); if(button.id == GuiConstants.CENTER_BACK_BUTTON) {
mc.displayGuiScreen(new GuiMainMenu());
} else if(button.id == GuiConstants.CENTER_LOGOUT_BUTTON) {
mc.displayGuiScreen(getYesNoGui(this, LOGOUT_CALLBACK_ID));
} else if(button.id == GuiConstants.CENTER_MANAGER_BUTTON) {
mc.displayGuiScreen(new GuiReplayViewer());
} else if(button.id == GuiConstants.CENTER_RECENT_BUTTON) {
showOnlineRecent();
} else if(button.id == GuiConstants.CENTER_BEST_BUTTON) {
showOnlineBest();
} else if(button.id == GuiConstants.CENTER_MY_REPLAYS_BUTTON) {
showOnlineOwnFiles();
} else if(button.id == GuiConstants.CENTER_SEARCH_BUTTON) {
int x = 15+(w2*i); }
b.xPosition = x+2; }
b.yPosition = height-30;
b.width = w2-4;
buttonList.add(b); @Override
public void confirmClicked(boolean result, int id) {
if(id == LOGOUT_CALLBACK_ID) {
if(result) {
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
AuthenticationHandler.logout();
mc.displayGuiScreen(new GuiMainMenu());
}
});
} else {
mc.displayGuiScreen(this);
}
}
}
i++; @Override
} public void drawScreen(int mouseX, int mouseY, float partialTicks) {
this.drawDefaultBackground();
this.drawCenteredString(fontRendererObj, "Replay Center", this.width / 2, 8, Color.WHITE.getRGB());
showOnlineRecent(); if(currentList != null) {
} currentList.drawScreen(mouseX, mouseY, partialTicks);
}
@Override super.drawScreen(mouseX, mouseY, partialTicks);
protected void actionPerformed(GuiButton button) throws java.io.IOException { }
if(!button.enabled) return;
if(button.id == GuiConstants.CENTER_BACK_BUTTON) {
mc.displayGuiScreen(new GuiMainMenu());
} else if(button.id == GuiConstants.CENTER_LOGOUT_BUTTON) {
mc.displayGuiScreen(getYesNoGui(this, LOGOUT_CALLBACK_ID));
} else if(button.id == GuiConstants.CENTER_MANAGER_BUTTON) {
mc.displayGuiScreen(new GuiReplayViewer());
} else if(button.id == GuiConstants.CENTER_RECENT_BUTTON) {
showOnlineRecent();
} else if(button.id == GuiConstants.CENTER_BEST_BUTTON) {
showOnlineBest();
} else if(button.id == GuiConstants.CENTER_MY_REPLAYS_BUTTON) {
showOnlineOwnFiles();
} else if(button.id == GuiConstants.CENTER_SEARCH_BUTTON) {
} @Override
} public void handleMouseInput() throws IOException {
super.handleMouseInput();
if(currentList != null) {
this.currentList.handleMouseInput();
}
}
private static final int LOGOUT_CALLBACK_ID = 1; @Override
@Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
public void confirmClicked(boolean result, int id) { super.mouseClicked(mouseX, mouseY, mouseButton);
if(id == LOGOUT_CALLBACK_ID) { if(currentList != null) {
if(result) { this.currentList.mouseClicked(mouseX, mouseY, mouseButton);
mc.addScheduledTask(new Runnable() { }
@Override }
public void run() {
AuthenticationHandler.logout();
mc.displayGuiScreen(new GuiMainMenu());
}
});
} else {
mc.displayGuiScreen(this);
}
}
}
public static GuiYesNo getYesNoGui(GuiYesNoCallback p_152129_0_, int p_152129_2_) { @Override
String s1 = I18n.format("Do you really want to log out?", new Object[0]); protected void mouseReleased(int mouseX, int mouseY, int state) {
GuiYesNo guiyesno = new GuiYesNo(p_152129_0_, s1, "", "Logout", "Cancel", p_152129_2_); super.mouseReleased(mouseX, mouseY, state);
return guiyesno; if(currentList != null) {
} this.currentList.mouseReleased(mouseX, mouseY, state);
}
}
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void onGuiClosed() {
this.drawDefaultBackground(); Keyboard.enableRepeatEvents(false);
this.drawCenteredString(fontRendererObj, "Replay Center", this.width/2, 8, Color.WHITE.getRGB()); }
if(currentList != null) { private void updateCurrentList(ReplayFileList list, SearchPagination pagination) {
currentList.drawScreen(mouseX, mouseY, partialTicks); currentList = list;
} if(currentList == null) {
currentList = new ReplayFileList(mc, width, height, 50, height - 40, 36);
} else {
currentList.clearEntries();
currentList.width = width;
currentList.height = height;
currentList.top = 50;
currentList.bottom = height - 40;
}
super.drawScreen(mouseX, mouseY, partialTicks); if(pagination.getLoadedPages() < 0) {
} pagination.fetchPage();
}
@Override for(FileInfo i : pagination.getFiles()) {
public void handleMouseInput() throws IOException { try {
super.handleMouseInput(); File tmp = null;
if(currentList != null) { if(i.hasThumbnail()) {
this.currentList.handleMouseInput(); tmp = File.createTempFile("thumb_online_" + i.getId(), "jpg");
} ReplayMod.apiClient.downloadThumbnail(i.getId(), tmp);
} }
currentList.addEntry(i, tmp);
} catch(Exception e) {
e.printStackTrace();
}
}
}
@Override public void showOnlineRecent() {
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { Thread t = new Thread(new Runnable() {
super.mouseClicked(mouseX, mouseY, mouseButton); @Override
if(currentList != null) { public void run() {
this.currentList.mouseClicked(mouseX, mouseY, mouseButton); updateCurrentList(recentFileList, recentFilePagination);
} currentTab = Tab.RECENT_FILES;
} }
});
t.start();
}
@Override public void showOnlineBest() {
protected void mouseReleased(int mouseX, int mouseY, int state) { Thread t = new Thread(new Runnable() {
super.mouseReleased(mouseX, mouseY, state); @Override
if(currentList != null) { public void run() {
this.currentList.mouseReleased(mouseX, mouseY, state); updateCurrentList(bestFileList, bestFilePagination);
} currentTab = Tab.BEST_FILES;
} }
});
t.start();
}
@Override public void showOnlineOwnFiles() {
public void onGuiClosed() { if(!AuthenticationHandler.isAuthenticated() || myFilePagination == null) return;
Keyboard.enableRepeatEvents(false); Thread t = new Thread(new Runnable() {
} @Override
public void run() {
updateCurrentList(myFileList, myFilePagination);
currentTab = Tab.MY_FILES;
}
});
t.start();
}
private void updateCurrentList(ReplayFileList list, SearchPagination pagination) { private enum Tab {
currentList = list; RECENT_FILES, BEST_FILES, MY_FILES, SEARCH;
if(currentList == null) { }
currentList = new ReplayFileList(mc, width, height, 50, height-40, 36);
} else {
currentList.clearEntries();
currentList.width = width;
currentList.height = height;
currentList.top = 50;
currentList.bottom = height-40;
}
if(pagination.getLoadedPages() < 0) {
pagination.fetchPage();
}
for(FileInfo i : pagination.getFiles()) {
try {
File tmp = null;
if(i.hasThumbnail()) {
tmp = File.createTempFile("thumb_online_"+i.getId(), "jpg");
ReplayMod.apiClient.downloadThumbnail(i.getId(), tmp);
}
currentList.addEntry(i, tmp);
} catch(Exception e) {
e.printStackTrace();
}
}
}
public void showOnlineRecent() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
updateCurrentList(recentFileList, recentFilePagination);
currentTab = Tab.RECENT_FILES;
}
});
t.start();
}
public void showOnlineBest() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
updateCurrentList(bestFileList, bestFilePagination);
currentTab = Tab.BEST_FILES;
}
});
t.start();
}
public void showOnlineOwnFiles() {
if(!AuthenticationHandler.isAuthenticated() || myFilePagination == null) return;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
updateCurrentList(myFileList, myFilePagination);
currentTab = Tab.MY_FILES;
}
});
t.start();
}
} }

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,361 +12,374 @@ 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 GuiTextField fileTitleInput, tagInput, messageTextField, tagPlaceholder; private static final Pattern p = Pattern.compile("[^a-z0-9 \\-_]", Pattern.CASE_INSENSITIVE);
private GuiButton categoryButton, startUploadButton, cancelUploadButton, backButton; private static final Pattern pt = Pattern.compile("[^a-z0-9,]", Pattern.CASE_INSENSITIVE);
private final ResourceLocation textureResource;
private GuiTextField fileTitleInput, tagInput, messageTextField, tagPlaceholder;
private GuiButton categoryButton, startUploadButton, cancelUploadButton, backButton;
private Gson gson = new Gson();
private File replayFile;
private ReplayMetaData metaData;
private BufferedImage thumb;
private FileUploader uploader = new FileUploader();
private Category category = Category.MINIGAME;
private DynamicTexture dynTex = null;
private Minecraft mc = Minecraft.getMinecraft();
private GuiReplayViewer parent;
private Gson gson = new Gson(); public GuiUploadFile(File file, GuiReplayViewer parent) {
this.parent = parent;
private File replayFile; this.textureResource = new ResourceLocation("upload_thumbs/" + FilenameUtils.getBaseName(file.getAbsolutePath()));
private ReplayMetaData metaData; dynTex = null;
private BufferedImage thumb;
private FileUploader uploader = new FileUploader(); boolean correctFile = false;
this.replayFile = file;
private Category category = Category.MINIGAME; if(("." + FilenameUtils.getExtension(file.getAbsolutePath())).equals(ConnectionEventHandler.ZIP_FILE_EXTENSION)) {
ZipFile archive = null;
try {
archive = new ZipFile(file);
ZipArchiveEntry recfile = archive.getEntry("recording" + ConnectionEventHandler.TEMP_FILE_EXTENSION);
ZipArchiveEntry metadata = archive.getEntry("metaData" + ConnectionEventHandler.JSON_FILE_EXTENSION);
private final ResourceLocation textureResource; ZipArchiveEntry image = archive.getEntry("thumb");
private DynamicTexture dynTex = null; BufferedImage img = null;
if(image != null) {
InputStream is = archive.getInputStream(image);
is.skip(7);
BufferedImage bimg = ImageIO.read(is);
if(bimg != null) {
thumb = ImageUtils.scaleImage(bimg, new Dimension(1280, 720));
}
}
private Minecraft mc = Minecraft.getMinecraft(); InputStream is = archive.getInputStream(metadata);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String json = br.readLine();
private static final Pattern p = Pattern.compile("[^a-z0-9 \\-_]", Pattern.CASE_INSENSITIVE); metaData = gson.fromJson(json, ReplayMetaData.class);
private static final Pattern pt = Pattern.compile("[^a-z0-9,]", Pattern.CASE_INSENSITIVE);
private GuiReplayViewer parent; archive.close();
correctFile = true;
} catch(Exception e) {
e.printStackTrace();
} finally {
if(archive != null) {
try {
archive.close();
} catch(IOException e) {
}
}
}
}
public GuiUploadFile(File file, GuiReplayViewer parent) { if(!correctFile) {
this.parent = parent; System.out.println("Invalid file provided to upload");
mc.displayGuiScreen(parent); //TODO: Error message
replayFile = null;
return;
}
this.textureResource = new ResourceLocation("upload_thumbs/"+FilenameUtils.getBaseName(file.getAbsolutePath())); //If thumb is null, set image to placeholder
dynTex = null; if(thumb == null) {
try {
thumb = ImageIO.read(MCPNames.class.getClassLoader().getResourceAsStream("default_thumb.jpg"));
} catch(Exception e) {
e.printStackTrace();
}
}
}
boolean correctFile = false; @Override
this.replayFile = file; public void initGui() {
if(replayFile == null) return;
if(("."+FilenameUtils.getExtension(file.getAbsolutePath())).equals(ConnectionEventHandler.ZIP_FILE_EXTENSION)) { if(fileTitleInput == null) {
ZipFile archive = null; fileTitleInput = new GuiTextField(GuiConstants.UPLOAD_NAME_INPUT, fontRendererObj, (this.width / 2) + 20 + 10, 21, Math.min(200, this.width - 20 - 260), 20);
try { String fname = FilenameUtils.getBaseName(replayFile.getAbsolutePath());
archive = new ZipFile(file); fileTitleInput.setText(fname);
ZipArchiveEntry recfile = archive.getEntry("recording"+ConnectionEventHandler.TEMP_FILE_EXTENSION); fileTitleInput.setMaxStringLength(30);
ZipArchiveEntry metadata = archive.getEntry("metaData"+ConnectionEventHandler.JSON_FILE_EXTENSION); } else {
fileTitleInput.xPosition = (this.width / 2) + 20 + 10;
//fileTitleInput.yPosition = 21;
fileTitleInput.width = Math.min(200, this.width - 20 - 260);
//fileTitleInput.height = 20;
}
ZipArchiveEntry image = archive.getEntry("thumb"); if(categoryButton == null) {
BufferedImage img = null; categoryButton = new GuiButton(GuiConstants.UPLOAD_CATEGORY_BUTTON, (this.width / 2) + 20 + 10 - 1, 80, "Category: " + category.toNiceString());
if(image != null) { categoryButton.width = Math.min(202, this.width - 20 - 260 + 2);
InputStream is = archive.getInputStream(image); buttonList.add(categoryButton);
is.skip(7); } else {
BufferedImage bimg = ImageIO.read(is); categoryButton.xPosition = (this.width / 2) + 20 + 10 - 1;
if(bimg != null) { }
thumb = ImageUtils.scaleImage(bimg, new Dimension(1280, 720));
}
}
InputStream is = archive.getInputStream(metadata); if(startUploadButton == null) {
BufferedReader br = new BufferedReader(new InputStreamReader(is)); List<GuiButton> bottomBar = new ArrayList<GuiButton>();
String json = br.readLine(); startUploadButton = new GuiButton(GuiConstants.UPLOAD_START_BUTTON, 0, 0, "Start Upload");
bottomBar.add(startUploadButton);
metaData = gson.fromJson(json, ReplayMetaData.class); cancelUploadButton = new GuiButton(GuiConstants.UPLOAD_CANCEL_BUTTON, 0, 0, "Cancel Upload");
cancelUploadButton.enabled = false;
bottomBar.add(cancelUploadButton);
archive.close(); backButton = new GuiButton(GuiConstants.UPLOAD_BACK_BUTTON, 0, 0, "Back");
correctFile = true; bottomBar.add(backButton);
} catch(Exception e) {
e.printStackTrace();
} finally {
if(archive != null) {
try {
archive.close();
} catch (IOException e) {}
}
}
}
if(!correctFile) { int i = 0;
System.out.println("Invalid file provided to upload"); for(GuiButton b : bottomBar) {
mc.displayGuiScreen(parent); //TODO: Error message int w = this.width - 30;
replayFile = null; int w2 = w / bottomBar.size();
return;
}
//If thumb is null, set image to placeholder int x = 15 + (w2 * i);
if(thumb == null) { b.xPosition = x + 2;
try { b.yPosition = height - 30;
thumb = ImageIO.read(MCPNames.class.getClassLoader().getResourceAsStream("default_thumb.jpg")); b.width = w2 - 4;
} catch(Exception e) {
e.printStackTrace();
}
}
}
@Override buttonList.add(b);
public void initGui() {
if(replayFile == null) return;
if(fileTitleInput == null) { i++;
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()); } else {
fileTitleInput.setText(fname); List<GuiButton> bottomBar = new ArrayList<GuiButton>();
fileTitleInput.setMaxStringLength(30);
} else {
fileTitleInput.xPosition = (this.width/2)+20+10;
//fileTitleInput.yPosition = 21;
fileTitleInput.width = Math.min(200, this.width-20-260);
//fileTitleInput.height = 20;
}
if(categoryButton == null) { bottomBar.add(startUploadButton);
categoryButton = new GuiButton(GuiConstants.UPLOAD_CATEGORY_BUTTON, (this.width/2)+20+10-1, 80, "Category: "+category.toNiceString()); bottomBar.add(cancelUploadButton);
categoryButton.width = Math.min(202, this.width-20-260+2); bottomBar.add(backButton);
buttonList.add(categoryButton);
} else {
categoryButton.xPosition = (this.width/2)+20+10-1;
}
if(startUploadButton == null) { int i = 0;
List<GuiButton> bottomBar = new ArrayList<GuiButton>(); for(GuiButton b : bottomBar) {
startUploadButton = new GuiButton(GuiConstants.UPLOAD_START_BUTTON, 0, 0, "Start Upload"); int w = this.width - 30;
bottomBar.add(startUploadButton); int w2 = w / bottomBar.size();
cancelUploadButton = new GuiButton(GuiConstants.UPLOAD_CANCEL_BUTTON, 0, 0, "Cancel Upload"); int x = 15 + (w2 * i);
cancelUploadButton.enabled = false; b.xPosition = x + 2;
bottomBar.add(cancelUploadButton); b.yPosition = height - 30;
b.width = w2 - 4;
backButton = new GuiButton(GuiConstants.UPLOAD_BACK_BUTTON, 0, 0, "Back"); buttonList.add(b);
bottomBar.add(backButton);
int i = 0; i++;
for(GuiButton b : bottomBar) { }
int w = this.width - 30; }
int w2 = w/bottomBar.size();
int x = 15+(w2*i); if(messageTextField == null) {
b.xPosition = x+2; messageTextField = new GuiTextField(GuiConstants.UPLOAD_INFO_FIELD, fontRendererObj, 20, height - 80, width - 40, 20);
b.yPosition = height-30; messageTextField.setEnabled(true);
b.width = w2-4; messageTextField.setFocused(false);
messageTextField.setMaxStringLength(Integer.MAX_VALUE);
} else {
messageTextField.yPosition = height - 80;
messageTextField.width = width - 40;
}
buttonList.add(b); 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.setMaxStringLength(30);
} else {
tagInput.xPosition = (this.width / 2) + 20 + 10;
tagInput.width = Math.min(200, this.width - 20 - 260);
}
i++; 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);
} else { tagPlaceholder.setTextColor(Color.DARK_GRAY.getRGB());
List<GuiButton> bottomBar = new ArrayList<GuiButton>(); tagPlaceholder.setText("Tags separated by comma");
} else {
tagPlaceholder.xPosition = (this.width / 2) + 20 + 10;
tagPlaceholder.width = Math.min(200, this.width - 20 - 260);
}
bottomBar.add(startUploadButton); validateStartButton();
bottomBar.add(cancelUploadButton); }
bottomBar.add(backButton);
int i = 0; @Override
for(GuiButton b : bottomBar) { protected void actionPerformed(GuiButton button) throws IOException {
int w = this.width - 30; if(!button.enabled) return;
int w2 = w/bottomBar.size(); if(button.id == GuiConstants.UPLOAD_CATEGORY_BUTTON) {
category = category.next();
categoryButton.displayString = "Category: " + category.toNiceString();
} else if(button.id == GuiConstants.UPLOAD_BACK_BUTTON) {
mc.displayGuiScreen(parent);
} else if(button.id == GuiConstants.UPLOAD_START_BUTTON) {
final String name = fileTitleInput.getText().trim();
new Thread(new Runnable() {
@Override
public void run() {
try {
String tagsRaw = tagInput.getText();
String[] split = tagsRaw.split(",");
List<String> tags = new ArrayList<String>();
for(String str : split) {
if(!tags.contains(str) && str.length() > 0) {
tags.add(str);
}
}
uploader.uploadFile(GuiUploadFile.this, AuthenticationHandler.getKey(), name, tags, replayFile, category);
} catch(ApiException e) { //TODO: Error handling
e.printStackTrace();
//mc.displayGuiScreen(new GuiMainMenu());
} catch(RuntimeException e) {
e.printStackTrace();
//mc.displayGuiScreen(new GuiMainMenu());
} catch(IOException e) {
e.printStackTrace();
}
}
}).start();
} else if(button.id == GuiConstants.UPLOAD_CANCEL_BUTTON) {
uploader.cancelUploading();
}
}
int x = 15+(w2*i); @Override
b.xPosition = x+2; public void drawScreen(int mouseX, int mouseY, float partialTicks) {
b.yPosition = height-30; this.drawDefaultBackground();
b.width = w2-4;
buttonList.add(b); drawString(fontRendererObj, metaData.getServerName(), (this.width / 2) + 20 + 10, 50, Color.GRAY.getRGB());
drawString(fontRendererObj, "Duration: " + String.format("%02dm%02ds",
TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()),
TimeUnit.MILLISECONDS.toSeconds(metaData.getDuration()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()))
), (this.width / 2) + 20 + 10, 65, Color.GRAY.getRGB());
i++; drawCenteredString(fontRendererObj, "Upload File", this.width / 2, 5, Color.WHITE.getRGB());
}
}
if(messageTextField == null) { //Draw thumbnail
messageTextField = new GuiTextField(GuiConstants.UPLOAD_INFO_FIELD, fontRendererObj, 20, height-80, width-40, 20); if(thumb != null) {
messageTextField.setEnabled(true); if(dynTex == null) {
messageTextField.setFocused(false); dynTex = new DynamicTexture(thumb);
messageTextField.setMaxStringLength(Integer.MAX_VALUE); mc.getTextureManager().loadTexture(textureResource, dynTex);
} else { dynTex.updateDynamicTexture();
messageTextField.yPosition = height-80; ResourceHelper.registerResource(textureResource);
messageTextField.width = width-40; }
}
if(tagInput == null) { mc.getTextureManager().bindTexture(textureResource); //Will be freed by the ResourceHelper
tagInput = new GuiTextField(GuiConstants.UPLOAD_TAG_INPUT, fontRendererObj, (this.width/2)+20+10, 110, Math.min(200, this.width-20-260), 20); int wid = (this.width) / 2;
tagInput.setMaxStringLength(30); int hei = Math.round(wid * (720f / 1280f));
} else { Gui.drawScaledCustomSizeModalRect(19, 20, 0, 0, 1280, 720, wid, hei, 1280, 720);
tagInput.xPosition = (this.width/2)+20+10; }
tagInput.width = Math.min(200, this.width-20-260);
}
if(tagPlaceholder == null) { fileTitleInput.drawTextBox();
tagPlaceholder = new GuiTextField(GuiConstants.UPLOAD_TAG_PLACEHOLDER, fontRendererObj, (this.width/2)+20+10, 110, Math.min(200, this.width-20-260), 20); messageTextField.drawTextBox();
tagPlaceholder.setTextColor(Color.DARK_GRAY.getRGB());
tagPlaceholder.setText("Tags separated by comma");
} else {
tagPlaceholder.xPosition = (this.width/2)+20+10;
tagPlaceholder.width = Math.min(200, this.width-20-260);
}
validateStartButton(); if(tagInput.getText().length() > 0 || tagInput.isFocused()) {
} tagInput.drawTextBox();
} else {
tagPlaceholder.drawTextBox();
}
@Override super.drawScreen(mouseX, mouseY, partialTicks);
protected void actionPerformed(GuiButton button) throws IOException {
if(!button.enabled) return;
if(button.id == GuiConstants.UPLOAD_CATEGORY_BUTTON) {
category = category.next();
categoryButton.displayString = "Category: "+category.toNiceString();
} else if(button.id == GuiConstants.UPLOAD_BACK_BUTTON) {
mc.displayGuiScreen(parent);
} else if(button.id == GuiConstants.UPLOAD_START_BUTTON) {
final String name = fileTitleInput.getText().trim();
new Thread(new Runnable() {
@Override
public void run() {
try {
String tagsRaw = tagInput.getText();
String[] split = tagsRaw.split(",");
List<String> tags = new ArrayList<String>();
for(String str : split) {
if(!tags.contains(str) && str.length() > 0) {
tags.add(str);
}
}
uploader.uploadFile(GuiUploadFile.this, AuthenticationHandler.getKey(), name, tags, replayFile, category);
} catch (ApiException e) { //TODO: Error handling
e.printStackTrace();
//mc.displayGuiScreen(new GuiMainMenu());
} catch (RuntimeException e) {
e.printStackTrace();
//mc.displayGuiScreen(new GuiMainMenu());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} else if(button.id == GuiConstants.UPLOAD_CANCEL_BUTTON) {
uploader.cancelUploading();
}
}
@Override this.drawRect(19, this.height - 52, width - 19, this.height - 37, Color.BLACK.getRGB());
public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawRect(21, this.height - 50, width - 21, this.height - 39, Color.WHITE.getRGB());
this.drawDefaultBackground();
drawString(fontRendererObj, metaData.getServerName(), (this.width/2)+20+10, 50, Color.GRAY.getRGB()); int width = this.width - 21 - 21;
drawString(fontRendererObj, "Duration: "+String.format("%02dm%02ds", float prog = uploader.getUploadProgress();
TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()), float w = width * prog;
TimeUnit.MILLISECONDS.toSeconds(metaData.getDuration()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(metaData.getDuration()))
), (this.width/2)+20+10, 65, Color.GRAY.getRGB());
drawCenteredString(fontRendererObj, "Upload File", this.width/2, 5, Color.WHITE.getRGB()); this.drawRect(21, this.height - 50, Math.round(21 + w), this.height - 39, Color.RED.getRGB());
//Draw thumbnail String perc = (int) Math.floor(prog * 100) + "%";
if(thumb != null) { fontRendererObj.drawString(perc, this.width / 2 - fontRendererObj.getStringWidth(perc) / 2, this.height - 48, Color.BLACK.getRGB());
if(dynTex == null) { }
dynTex = new DynamicTexture(thumb);
mc.getTextureManager().loadTexture(textureResource, dynTex);
dynTex.updateDynamicTexture();
ResourceHelper.registerResource(textureResource);
}
mc.getTextureManager().bindTexture(textureResource); //Will be freed by the ResourceHelper @Override
int wid = (this.width)/2; public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
int hei = Math.round(wid*(720f/1280f)); super.mouseClicked(mouseX, mouseY, mouseButton);
Gui.drawScaledCustomSizeModalRect(19, 20, 0, 0, 1280, 720, wid, hei, 1280, 720); fileTitleInput.mouseClicked(mouseX, mouseY, mouseButton);
} tagInput.mouseClicked(mouseX, mouseY, mouseButton);
}
fileTitleInput.drawTextBox(); @Override
messageTextField.drawTextBox(); public void updateScreen() {
fileTitleInput.updateCursorCounter();
tagInput.updateCursorCounter();
}
if(tagInput.getText().length() > 0 || tagInput.isFocused()) { @Override
tagInput.drawTextBox(); public void onGuiClosed() {
} else { Keyboard.enableRepeatEvents(false);
tagPlaceholder.drawTextBox(); }
}
super.drawScreen(mouseX, mouseY, partialTicks); @Override
protected void keyTyped(char typedChar, int keyCode) throws IOException {
if(fileTitleInput.isFocused()) {
fileTitleInput.textboxKeyTyped(typedChar, keyCode);
} else if(tagInput.isFocused()) {
tagInput.textboxKeyTyped(typedChar, keyCode);
}
this.drawRect(19, this.height-52, width-19, this.height-37, Color.BLACK.getRGB()); if(uploader.isUploading()) {
this.drawRect(21, this.height-50, width-21, this.height-39, Color.WHITE.getRGB()); startUploadButton.enabled = false;
} else {
validateStartButton();
}
}
int width = this.width-21 - 21; private void validateStartButton() {
float prog = uploader.getUploadProgress(); boolean enabled = true;
float w = width*prog; if(fileTitleInput.getText().trim().length() < 5 || fileTitleInput.getText().trim().length() > 30) {
enabled = false;
} else if(p.matcher(fileTitleInput.getText()).find()) {
enabled = false;
fileTitleInput.setTextColor(Color.RED.getRGB());
} else if(pt.matcher(tagInput.getText()).find()) {
enabled = false;
tagInput.setTextColor(Color.RED.getRGB());
} else {
fileTitleInput.setTextColor(Color.WHITE.getRGB());
tagInput.setTextColor(Color.WHITE.getRGB());
}
startUploadButton.enabled = enabled;
}
this.drawRect(21, this.height-50, Math.round(21+w), this.height-39, Color.RED.getRGB()); public void onStartUploading() {
startUploadButton.enabled = false;
cancelUploadButton.enabled = true;
backButton.enabled = false;
categoryButton.enabled = false;
fileTitleInput.setEnabled(false);
messageTextField.setText("Uploading...");
messageTextField.setTextColor(Color.WHITE.getRGB());
}
String perc = (int)Math.floor(prog*100)+"%"; public void onFinishUploading(boolean success, String info) {
fontRendererObj.drawString(perc, this.width/2 - fontRendererObj.getStringWidth(perc)/2, this.height-48, Color.BLACK.getRGB()); validateStartButton();
} cancelUploadButton.enabled = false;
backButton.enabled = true;
@Override categoryButton.enabled = true;
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { fileTitleInput.setEnabled(true);
super.mouseClicked(mouseX, mouseY, mouseButton); if(success) {
fileTitleInput.mouseClicked(mouseX, mouseY, mouseButton); messageTextField.setText("File has been successfully uploaded");
tagInput.mouseClicked(mouseX, mouseY, mouseButton); messageTextField.setTextColor(Color.GREEN.getRGB());
} } else {
messageTextField.setText(info);
@Override messageTextField.setTextColor(Color.RED.getRGB());
public void updateScreen() { }
fileTitleInput.updateCursorCounter(); }
tagInput.updateCursorCounter();
}
@Override
public void onGuiClosed() {
Keyboard.enableRepeatEvents(false);
}
@Override
protected void keyTyped(char typedChar, int keyCode) throws IOException {
if(fileTitleInput.isFocused()) {
fileTitleInput.textboxKeyTyped(typedChar, keyCode);
} else if(tagInput.isFocused()) {
tagInput.textboxKeyTyped(typedChar, keyCode);
}
if(uploader.isUploading()) {
startUploadButton.enabled = false;
} else {
validateStartButton();
}
}
private void validateStartButton() {
boolean enabled = true;
if(fileTitleInput.getText().trim().length() < 5 || fileTitleInput.getText().trim().length() > 30) {
enabled = false;
} else if(p.matcher(fileTitleInput.getText()).find()) {
enabled = false;
fileTitleInput.setTextColor(Color.RED.getRGB());
} else if(pt.matcher(tagInput.getText()).find()) {
enabled = false;
tagInput.setTextColor(Color.RED.getRGB());
} else {
fileTitleInput.setTextColor(Color.WHITE.getRGB());
tagInput.setTextColor(Color.WHITE.getRGB());
}
startUploadButton.enabled = enabled;
}
public void onStartUploading() {
startUploadButton.enabled = false;
cancelUploadButton.enabled = true;
backButton.enabled = false;
categoryButton.enabled = false;
fileTitleInput.setEnabled(false);
messageTextField.setText("Uploading...");
messageTextField.setTextColor(Color.WHITE.getRGB());
}
public void onFinishUploading(boolean success, String info) {
validateStartButton();
cancelUploadButton.enabled = false;
backButton.enabled = true;
categoryButton.enabled = true;
fileTitleInput.setEnabled(true);
if(success) {
messageTextField.setText("File has been successfully uploaded");
messageTextField.setTextColor(Color.GREEN.getRGB());
} else {
messageTextField.setText(info);
messageTextField.setTextColor(Color.RED.getRGB());
}
}
} }

View File

@@ -1,12 +1,12 @@
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 {
public ReplayFileList(Minecraft mcIn, int p_i45010_2_, int p_i45010_3_, public ReplayFileList(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_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_);
} }
} }

View File

@@ -1,200 +1,198 @@
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 {
private static final String DESCRIPTION = "Connects multiple Replays in the same order as the list."; private static final String DESCRIPTION = "Connects multiple Replays in the same order as the list.";
private static final String TITLE = "Connect Replays"; private static final String TITLE = "Connect Replays";
private boolean initialized = false; private boolean initialized = false;
private GuiEntryList<String> concatList; private GuiEntryList<String> concatList;
private GuiDropdown<String> replayDropdown; private GuiDropdown<String> replayDropdown;
private GuiButton removeButton, addButton; private GuiButton removeButton, addButton;
private GuiArrowButton upButton, downButton; private GuiArrowButton upButton, downButton;
private List<File> replayFiles; private List<File> replayFiles;
private List<String> filesToConcat; private List<String> filesToConcat;
public GuiConnectPart(int yPos) { public GuiConnectPart(int yPos) {
super(yPos); super(yPos);
this.mc = Minecraft.getMinecraft(); this.mc = Minecraft.getMinecraft();
fontRendererObj = mc.fontRendererObj; fontRendererObj = mc.fontRendererObj;
} }
@Override @Override
public void applyFilters(File replayFile, File outputFile) { public void applyFilters(File replayFile, File outputFile) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public String getDescription() { public String getDescription() {
return DESCRIPTION; return DESCRIPTION;
} }
@Override @Override
public String getTitle() { public String getTitle() {
return TITLE; return TITLE;
} }
@Override @Override
public void initGui() { public void initGui() {
if(!initialized) { if(!initialized) {
concatList = new GuiEntryList(1, fontRendererObj, 30, yPos, 150, 0); concatList = new GuiEntryList(1, fontRendererObj, 30, yPos, 150, 0);
filesToConcat = new ArrayList<String>(); filesToConcat = new ArrayList<String>();
String selectedName = FilenameUtils.getBaseName(GuiReplayStudio.instance.getSelectedFile().getAbsolutePath()); String selectedName = FilenameUtils.getBaseName(GuiReplayStudio.instance.getSelectedFile().getAbsolutePath());
filesToConcat.add(selectedName); filesToConcat.add(selectedName);
concatList.setElements(filesToConcat); concatList.setElements(filesToConcat);
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);
if(name.equals(selectedName)) { if(name.equals(selectedName)) {
index = i; index = i;
} }
i++; i++;
} }
replayDropdown.setSelectionPos(index); replayDropdown.setSelectionPos(index);
replayDropdown.addSelectionListener(new SelectionListener() { replayDropdown.addSelectionListener(new SelectionListener() {
@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;
} }
i++; i++;
} }
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;
} }
@Override @Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton); //call this first to ensure the dropdown is still open super.mouseClicked(mouseX, mouseY, mouseButton); //call this first to ensure the dropdown is still open
concatList.mouseClicked(mouseX, mouseY, mouseButton); concatList.mouseClicked(mouseX, mouseY, mouseButton);
replayDropdown.mouseClicked(mouseX, mouseY, mouseButton); replayDropdown.mouseClicked(mouseX, mouseY, mouseButton);
} }
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void drawScreen(int mouseX, int mouseY, float partialTicks) {
super.drawScreen(mouseX, mouseY, partialTicks); super.drawScreen(mouseX, mouseY, partialTicks);
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
public void updateScreen() { public void updateScreen() {
if(!initialized) initGui(); if(!initialized) initGui();
} }
@Override @Override
public void keyTyped(char typedChar, int keyCode) { public void keyTyped(char typedChar, int keyCode) {
} }
@Override @Override
protected void actionPerformed(GuiButton button) { protected void actionPerformed(GuiButton button) {
if(!button.enabled || replayDropdown.isExpanded()) { if(!button.enabled || replayDropdown.isExpanded()) {
return; return;
} }
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,220 +1,216 @@
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;
public static GuiReplayStudio instance = null;
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>();
private static final int tabYPos = 110; public GuiReplayStudio() {
instance = this;
}
private enum StudioTab { public File getSelectedFile() {
TRIM(new GuiTrimPart(tabYPos)), CONNECT(new GuiConnectPart(tabYPos)), MODIFY(new GuiConnectPart(tabYPos)); try {
return replayFiles.get(replayDropdown.getSelectionIndex());
} catch(ArrayIndexOutOfBoundsException e) {
return null;
}
}
private GuiStudioPart studioPart; private void refreshReplayDropdown() {
replayDropdown.clearElements();
replayFiles = ReplayFileIO.getAllReplayFiles();
for(File file : replayFiles) {
String name = FilenameUtils.getBaseName(file.getAbsolutePath());
replayDropdown.addElement(name);
}
}
public GuiStudioPart getStudioPart() { @Override
return studioPart; public void initGui() {
} List<GuiButton> tabButtons = new ArrayList<GuiButton>();
private StudioTab(GuiStudioPart part) { tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_TRIM_TAB, 0, 0, "Trim Replay"));
this.studioPart = part; tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_CONNECT_TAB, 0, 0, "Connect Replays"));
} tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_MODIFY_TAB, 0, 0, "Modify Replay"));
}
public GuiReplayStudio() { int w = this.width - 30;
instance = this; int w2 = w / tabButtons.size();
} int i = 0;
for(GuiButton b : tabButtons) {
int x = 15 + (w2 * i);
b.xPosition = x + 2;
b.yPosition = 30;
b.width = w2 - 4;
private StudioTab currentTab = StudioTab.TRIM; buttonList.add(b);
private GuiDropdown replayDropdown; i++;
private GuiButton saveModeButton, saveButton; }
private boolean overrideSave = false; int modeWidth = tabButtons.get(0).width;
private boolean initialized = false; if(!initialized) {
replayDropdown = new GuiDropdown(1, fontRendererObj, 15 + 2 + 1 + 80, 60, this.width - 30 - 8 - 80 - modeWidth - 4, 5);
refreshReplayDropdown();
} else {
replayDropdown.width = this.width - 30 - 8 - 80 - modeWidth - 4;
}
private List<File> replayFiles = new ArrayList<File>(); if(!initialized) {
saveModeButton = new GuiButton(GuiConstants.REPLAY_EDITOR_SAVEMODE_BUTTON, width - 15 - modeWidth - 3, 60, getSaveModeLabel());
public File getSelectedFile() { } else {
try { saveModeButton.xPosition = width - 15 - modeWidth - 3;
return replayFiles.get(replayDropdown.getSelectionIndex()); }
} catch(ArrayIndexOutOfBoundsException e) { saveModeButton.width = modeWidth;
return null; buttonList.add(saveModeButton);
}
}
private void refreshReplayDropdown() {
replayDropdown.clearElements();
replayFiles = ReplayFileIO.getAllReplayFiles();
for(File file : replayFiles) {
String name = FilenameUtils.getBaseName(file.getAbsolutePath());
replayDropdown.addElement(name);
}
}
@Override
public void initGui() {
List<GuiButton> tabButtons = new ArrayList<GuiButton>();
tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_TRIM_TAB, 0, 0, "Trim Replay"));
tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_CONNECT_TAB, 0, 0, "Connect Replays"));
tabButtons.add(new GuiButton(GuiConstants.REPLAY_EDITOR_MODIFY_TAB, 0, 0, "Modify Replay"));
int w = this.width - 30;
int w2 = w/tabButtons.size();
int i = 0;
for(GuiButton b : tabButtons) {
int x = 15+(w2*i);
b.xPosition = x+2;
b.yPosition = 30;
b.width = w2-4;
buttonList.add(b);
i++;
}
int modeWidth = tabButtons.get(0).width;
if(!initialized) {
replayDropdown = new GuiDropdown(1, fontRendererObj, 15+2+1+80, 60, this.width-30-8-80-modeWidth-4, 5);
refreshReplayDropdown();
} else {
replayDropdown.width = this.width-30-8-80-modeWidth-4;
}
if(!initialized) {
saveModeButton = new GuiButton(GuiConstants.REPLAY_EDITOR_SAVEMODE_BUTTON, width-15-modeWidth-3, 60, getSaveModeLabel());
} else {
saveModeButton.xPosition = width-15-modeWidth-3;
}
saveModeButton.width = modeWidth;
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);
for(StudioTab tab : StudioTab.values()) { for(StudioTab tab : StudioTab.values()) {
tab.getStudioPart().initGui(); tab.getStudioPart().initGui();
} }
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 ;
protected void actionPerformed(GuiButton button) throws IOException {
if(!button.enabled) return;
if(button.id == GuiConstants.REPLAY_EDITOR_SAVEMODE_BUTTON) {
overrideSave = !overrideSave;
button.displayString = getSaveModeLabel();
} else if(button.id == GuiConstants.REPLAY_EDITOR_BACK_BUTTON) {
mc.displayGuiScreen(new GuiMainMenu());
} else if(button.id == GuiConstants.REPLAY_EDITOR_TRIM_TAB) {
currentTab = StudioTab.TRIM;
} else if(button.id == GuiConstants.REPLAY_EDITOR_CONNECT_TAB) {
currentTab = StudioTab.CONNECT;
} else if(button.id == GuiConstants.REPLAY_EDITOR_MODIFY_TAB) {
currentTab = StudioTab.MODIFY;
} else if(button.id == GuiConstants.REPLAY_EDITOR_SAVE_BUTTON) {
File outputFile = getSelectedFile();
File folder = ReplayFileIO.getReplayFolder();
if(!overrideSave) {
String name = FilenameUtils.getBaseName(outputFile.getAbsolutePath())+"_edited";
File f = new File(folder, name+".mcpr");
int num = 0;
while(f.exists()) {
num++;
String fileName = name+"_"+num;
f = new File(folder, fileName+".mcpr");
}
outputFile = f;
}
currentTab.getStudioPart().applyFilters(getSelectedFile(), outputFile);
}
}
@Override @Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) protected void actionPerformed(GuiButton button) throws IOException {
throws IOException { if(!button.enabled) return;
replayDropdown.mouseClicked(mouseX, mouseY, mouseButton); if(button.id == GuiConstants.REPLAY_EDITOR_SAVEMODE_BUTTON) {
currentTab.getStudioPart().mouseClicked(mouseX, mouseY, mouseButton); overrideSave = !overrideSave;
super.mouseClicked(mouseX, mouseY, mouseButton); button.displayString = getSaveModeLabel();
} } else if(button.id == GuiConstants.REPLAY_EDITOR_BACK_BUTTON) {
mc.displayGuiScreen(new GuiMainMenu());
} else if(button.id == GuiConstants.REPLAY_EDITOR_TRIM_TAB) {
currentTab = StudioTab.TRIM;
} else if(button.id == GuiConstants.REPLAY_EDITOR_CONNECT_TAB) {
currentTab = StudioTab.CONNECT;
} else if(button.id == GuiConstants.REPLAY_EDITOR_MODIFY_TAB) {
currentTab = StudioTab.MODIFY;
} else if(button.id == GuiConstants.REPLAY_EDITOR_SAVE_BUTTON) {
File outputFile = getSelectedFile();
File folder = ReplayFileIO.getReplayFolder();
if(!overrideSave) {
String name = FilenameUtils.getBaseName(outputFile.getAbsolutePath()) + "_edited";
File f = new File(folder, name + ".mcpr");
int num = 0;
while(f.exists()) {
num++;
String fileName = name + "_" + num;
f = new File(folder, fileName + ".mcpr");
}
outputFile = f;
}
currentTab.getStudioPart().applyFilters(getSelectedFile(), outputFile);
}
}
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) { protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
drawDefaultBackground(); throws IOException {
super.drawScreen(mouseX, mouseY, partialTicks); replayDropdown.mouseClicked(mouseX, mouseY, mouseButton);
currentTab.getStudioPart().drawScreen(mouseX, mouseY, partialTicks); currentTab.getStudioPart().mouseClicked(mouseX, mouseY, mouseButton);
super.mouseClicked(mouseX, mouseY, mouseButton);
}
drawCenteredString(fontRendererObj, "§n"+currentTab.getStudioPart().getTitle(), width/2, 92, Color.WHITE.getRGB()); @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
drawDefaultBackground();
super.drawScreen(mouseX, mouseY, partialTicks);
currentTab.getStudioPart().drawScreen(mouseX, mouseY, partialTicks);
List<String> rows = new ArrayList<String>(); drawCenteredString(fontRendererObj, "§n" + currentTab.getStudioPart().getTitle(), width / 2, 92, Color.WHITE.getRGB());
String remaining = currentTab.getStudioPart().getDescription();
while(remaining.length() > 0) {
String[] split = remaining.split(" ");
String b = "";
for(String sp : split) {
b += sp+" ";
if(fontRendererObj.getStringWidth(b.trim()) > width-30-70-20) {
b = b.substring(0, b.trim().length()-(sp.length()));
break;
}
}
String trimmed = b.trim();
rows.add(trimmed);
try {
remaining = remaining.substring(trimmed.length()+1);
} catch(Exception e) {break;}
}
int i=0; List<String> rows = new ArrayList<String>();
for(String row : rows) { String remaining = currentTab.getStudioPart().getDescription();
drawString(fontRendererObj, row, 30, height-(15*(rows.size()-i)), Color.WHITE.getRGB()); while(remaining.length() > 0) {
i++; String[] split = remaining.split(" ");
} String b = "";
for(String sp : split) {
b += sp + " ";
if(fontRendererObj.getStringWidth(b.trim()) > width - 30 - 70 - 20) {
b = b.substring(0, b.trim().length() - (sp.length()));
break;
}
}
String trimmed = b.trim();
rows.add(trimmed);
try {
remaining = remaining.substring(trimmed.length() + 1);
} catch(Exception e) {
break;
}
}
drawCenteredString(fontRendererObj, "Replay Studio", this.width / 2, 10, 16777215); int i = 0;
drawString(fontRendererObj, "Replay File:", 30, 67, Color.WHITE.getRGB()); for(String row : rows) {
drawString(fontRendererObj, row, 30, height - (15 * (rows.size() - i)), Color.WHITE.getRGB());
i++;
}
replayDropdown.drawTextBox(); drawCenteredString(fontRendererObj, "Replay Studio", this.width / 2, 10, 16777215);
} drawString(fontRendererObj, "Replay File:", 30, 67, Color.WHITE.getRGB());
@Override replayDropdown.drawTextBox();
protected void keyTyped(char typedChar, int keyCode) throws IOException { }
currentTab.getStudioPart().keyTyped(typedChar, keyCode);
super.keyTyped(typedChar, keyCode);
}
@Override @Override
public void updateScreen() { protected void keyTyped(char typedChar, int keyCode) throws IOException {
currentTab.getStudioPart().updateScreen(); currentTab.getStudioPart().keyTyped(typedChar, keyCode);
super.updateScreen(); super.keyTyped(typedChar, keyCode);
} }
@Override
public void updateScreen() {
currentTab.getStudioPart().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,29 +1,29 @@
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 {
public GuiStudioPart(int yPos) { protected int yPos = 0;
this.yPos = yPos;
}
protected int yPos = 0; public GuiStudioPart(int yPos) {
this.yPos = yPos;
}
public abstract void applyFilters(File replayFile, File outputFile); public abstract void applyFilters(File replayFile, File outputFile);
public abstract String getDescription(); public abstract String getDescription();
public abstract String getTitle(); public abstract String getTitle();
@Override @Override
public abstract void keyTyped(char typedChar, int keyCode); public abstract void keyTyped(char typedChar, int keyCode);
@Override @Override
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton); super.mouseClicked(mouseX, mouseY, mouseButton);
} }
} }

View File

@@ -1,163 +1,156 @@
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 TITLE = "Trim Replay";
private Minecraft mc = Minecraft.getMinecraft();
private boolean initialized = false;
private static final String DESCRIPTION = "Removes the beginning and end of a Replay File and only keeps the Replay between the given timestamps."; private GuiNumberInput startMinInput, startSecInput, startMsInput;
private static final String TITLE = "Trim Replay"; private GuiNumberInput endMinInput, endSecInput, endMsInput;
private boolean initialized = false; private List<GuiNumberInput> inputOrder = new ArrayList<GuiNumberInput>();
private GuiNumberInput startMinInput, startSecInput, startMsInput; public GuiTrimPart(int yPos) {
private GuiNumberInput endMinInput, endSecInput, endMsInput; super(yPos);
fontRendererObj = mc.fontRendererObj;
}
private List<GuiNumberInput> inputOrder = new ArrayList<GuiNumberInput>(); @Override
public void applyFilters(File replayFile, File outputFile) {
try {
StudioImplementation.trimReplay(replayFile, false, getStartTimestamp(), getEndTimestamp(), outputFile);
} catch(Exception e) {
e.printStackTrace();
}
}
public GuiTrimPart(int yPos) { private int valueOf(String text) {
super(yPos); try {
fontRendererObj = mc.fontRendererObj; return Integer.valueOf(text);
} } catch(NumberFormatException e) {
return 0;
}
}
@Override private int getStartTimestamp() {
public void applyFilters(File replayFile, File outputFile) { int mins = valueOf(startMinInput.getText());
try { int secs = valueOf(startSecInput.getText());
StudioImplementation.trimReplay(replayFile, false, getStartTimestamp(), getEndTimestamp(), outputFile); int ms = valueOf(startMsInput.getText());
} catch(Exception e) {
e.printStackTrace();
}
}
private int valueOf(String text) { return (mins * 60 * 1000) + (secs * 1000) + ms;
try { }
return Integer.valueOf(text);
} catch(NumberFormatException e) {
return 0;
}
}
private int getStartTimestamp() { private int getEndTimestamp() {
int mins = valueOf(startMinInput.getText()); int mins = valueOf(endMinInput.getText());
int secs = valueOf(startSecInput.getText()); int secs = valueOf(endSecInput.getText());
int ms = valueOf(startMsInput.getText()); int ms = valueOf(endMsInput.getText());
return (mins*60*1000)+(secs*1000)+ms; return (mins * 60 * 1000) + (secs * 1000) + ms;
} }
private int getEndTimestamp() { @Override
int mins = valueOf(endMinInput.getText()); public String getDescription() {
int secs = valueOf(endSecInput.getText()); return DESCRIPTION;
int ms = valueOf(endMsInput.getText()); }
return (mins*60*1000)+(secs*1000)+ms; @Override
} public String getTitle() {
return TITLE;
}
@Override @Override
public String getDescription() { public void initGui() {
return DESCRIPTION; if(!initialized) {
} startMinInput = new GuiNumberInput(1, fontRendererObj, 70, yPos, 30, 3);
startSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos, 25, 2);
startMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos, 30, 3);
@Override endMinInput = new GuiNumberInput(1, fontRendererObj, 70, yPos + 30, 30, 3);
public String getTitle() { endSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos + 30, 25, 2);
return TITLE; endMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos + 30, 30, 3);
}
@Override inputOrder.clear();
public void initGui() {
if(!initialized) {
startMinInput = new GuiNumberInput(1, fontRendererObj, 70, yPos, 30, 3);
startSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos, 25, 2);
startMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos, 30, 3);
endMinInput = new GuiNumberInput(1, fontRendererObj, 70, yPos+30, 30, 3); inputOrder.add(startMinInput);
endSecInput = new GuiNumberInput(1, fontRendererObj, 120, yPos+30, 25, 2); inputOrder.add(startSecInput);
endMsInput = new GuiNumberInput(1, fontRendererObj, 165, yPos+30, 30, 3); inputOrder.add(startMsInput);
inputOrder.add(endMinInput);
inputOrder.add(endSecInput);
inputOrder.add(endMsInput);
}
inputOrder.clear(); initialized = true;
}
inputOrder.add(startMinInput); @Override
inputOrder.add(startSecInput); public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
inputOrder.add(startMsInput); for(GuiNumberInput input : inputOrder) {
inputOrder.add(endMinInput); input.mouseClicked(mouseX, mouseY, mouseButton);
inputOrder.add(endSecInput); }
inputOrder.add(endMsInput); }
}
initialized = true; @Override
} public void drawScreen(int mouseX, int mouseY, float partialTicks) {
drawString(mc.fontRendererObj, "Start:", 30, yPos + 7, 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 + 30, 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, "ms", 200, yPos + 7, Color.WHITE.getRGB());
drawString(mc.fontRendererObj, "ms", 200, yPos + 7 + 30, Color.WHITE.getRGB());
@Override drawString(mc.fontRendererObj, "Timestamp: " + getStartTimestamp(), 230, yPos + 7, Color.WHITE.getRGB());
public void mouseClicked(int mouseX, int mouseY, int mouseButton) { drawString(mc.fontRendererObj, "Timestamp: " + getEndTimestamp(), 230, yPos + 30 + 7, Color.WHITE.getRGB());
for(GuiNumberInput input: inputOrder) {
input.mouseClicked(mouseX, mouseY, mouseButton);
}
}
@Override for(GuiNumberInput input : inputOrder) {
public void drawScreen(int mouseX, int mouseY, float partialTicks) { input.drawTextBox();
drawString(mc.fontRendererObj, "Start:", 30, yPos+7, 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+30, 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, "ms", 200, yPos+7, 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()); super.drawScreen(mouseX, mouseY, partialTicks);
drawString(mc.fontRendererObj, "Timestamp: "+getEndTimestamp(), 230, yPos+30+7, Color.WHITE.getRGB()); }
for(GuiNumberInput input: inputOrder) { @Override
input.drawTextBox(); public void updateScreen() {
} if(!initialized) {
initGui();
} else {
for(GuiNumberInput input : inputOrder) {
input.updateCursorCounter();
}
}
}
super.drawScreen(mouseX, mouseY, partialTicks); @Override
} public void keyTyped(char typedChar, int keyCode) {
if(keyCode == Keyboard.KEY_TAB) { //Tab handling
@Override int i = 0;
public void updateScreen() { for(GuiNumberInput input : inputOrder) {
if(!initialized) { if(input.isFocused()) {
initGui(); input.setFocused(false);
} else { i++;
for(GuiNumberInput input: inputOrder) { if(i >= inputOrder.size()) i = 0;
input.updateCursorCounter(); inputOrder.get(i).setFocused(true);
} break;
} }
} i++;
}
@Override } else {
public void keyTyped(char typedChar, int keyCode) { for(GuiNumberInput input : inputOrder) {
if(keyCode == Keyboard.KEY_TAB) { //Tab handling input.textboxKeyTyped(typedChar, keyCode);
int i=0; }
for(GuiNumberInput input: inputOrder) { }
if(input.isFocused()) { }
input.setFocused(false);
i++;
if(i >= inputOrder.size()) i=0;
inputOrder.get(i).setFocused(true);
break;
}
i++;
}
} else {
for(GuiNumberInput input: inputOrder) {
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,29 +38,23 @@ 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);
this.mc.displayGuiScreen(this.field_146585_a); this.mc.displayGuiScreen(this.field_146585_a);
@@ -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,265 +12,271 @@ 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 GuiScreen parentScreen; private static final int LOAD_BUTTON_ID = 9001;
private GuiButton btnEditServer; private static final int UPLOAD_BUTTON_ID = 9002;
private GuiButton btnSelectServer; private static final int FOLDER_BUTTON_ID = 9003;
private GuiButton btnDeleteServer; private static final int RENAME_BUTTON_ID = 9004;
private String hoveringText; private static final int DELETE_BUTTON_ID = 9005;
private boolean initialized; private static final int SETTINGS_BUTTON_ID = 9006;
private GuiReplayListExtended replayGuiList; private static final int CANCEL_BUTTON_ID = 9007;
private List<Pair<Pair<File, ReplayMetaData>, File>> replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>(); private static Gson gson = new Gson();
private GuiButton loadButton, uploadButton, folderButton, renameButton, deleteButton, cancelButton, settingsButton; private GuiScreen parentScreen;
private GuiButton btnEditServer;
private GuiButton btnSelectServer;
private GuiButton btnDeleteServer;
private String hoveringText;
private boolean initialized;
private GuiReplayListExtended replayGuiList;
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 boolean replaying = false;
private boolean delete_file = false;
private static Gson gson = new Gson(); public static GuiYesNo getYesNoGui(GuiYesNoCallback p_152129_0_, String file, int p_152129_2_) {
private boolean replaying = false; 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 static final int LOAD_BUTTON_ID = 9001; private void reloadFiles() {
private static final int UPLOAD_BUTTON_ID = 9002; replayGuiList.clearEntries();
private static final int FOLDER_BUTTON_ID = 9003; replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>();
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; for(File file : ReplayFileIO.getAllReplayFiles()) {
try {
ZipFile archive = new ZipFile(file);
ZipArchiveEntry recfile = archive.getEntry("recording" + ConnectionEventHandler.TEMP_FILE_EXTENSION);
ZipArchiveEntry metadata = archive.getEntry("metaData" + ConnectionEventHandler.JSON_FILE_EXTENSION);
private void reloadFiles() { ZipArchiveEntry image = archive.getEntry("thumb");
replayGuiList.clearEntries(); BufferedImage img = null;
replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>(); if(image != null) {
InputStream is = archive.getInputStream(image);
is.skip(7);
BufferedImage bimg = ImageIO.read(is);
if(bimg != null) {
img = ImageUtils.scaleImage(bimg, new Dimension(1280, 720));
}
}
for(File file : ReplayFileIO.getAllReplayFiles()) { File tmp = null;
try { if(img != null) {
ZipFile archive = new ZipFile(file); tmp = File.createTempFile(FilenameUtils.getBaseName(file.getAbsolutePath()), "jpg");
ZipArchiveEntry recfile = archive.getEntry("recording"+ConnectionEventHandler.TEMP_FILE_EXTENSION); tmp.deleteOnExit();
ZipArchiveEntry metadata = archive.getEntry("metaData"+ConnectionEventHandler.JSON_FILE_EXTENSION);
ZipArchiveEntry image = archive.getEntry("thumb"); ImageIO.write(img, "jpg", tmp);
BufferedImage img = null; }
if(image != null) {
InputStream is = archive.getInputStream(image);
is.skip(7);
BufferedImage bimg = ImageIO.read(is);
if(bimg != null) {
img = ImageUtils.scaleImage(bimg, new Dimension(1280, 720));
}
}
File tmp = null; InputStream is = archive.getInputStream(metadata);
if(img != null) { BufferedReader br = new BufferedReader(new InputStreamReader(is));
tmp = File.createTempFile(FilenameUtils.getBaseName(file.getAbsolutePath()), "jpg");
tmp.deleteOnExit();
ImageIO.write(img, "jpg", tmp); String json = br.readLine();
}
InputStream is = archive.getInputStream(metadata); ReplayMetaData metaData = gson.fromJson(json, ReplayMetaData.class);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String json = br.readLine(); replayFileList.add(Pair.of(Pair.of(file, metaData), tmp));
ReplayMetaData metaData = gson.fromJson(json, ReplayMetaData.class); archive.close();
} catch(Exception e) {
}
}
replayFileList.add(Pair.of(Pair.of(file, metaData), tmp)); Collections.sort(replayFileList, new FileAgeComparator());
archive.close(); for(Pair<Pair<File, ReplayMetaData>, File> p : replayFileList) {
} catch(Exception e) {} FileInfo fileInfo = new FileInfo(-1, p.first().second(), null, null,
} -1, -1, -1, FilenameUtils.getBaseName(p.first().first().getName()), true);
replayGuiList.addEntry(fileInfo, p.second());
}
}
Collections.sort(replayFileList, new FileAgeComparator()); @Override
public void initGui() {
replayGuiList = new ReplayList(this, this.mc, this.width, this.height, 32, this.height - 64, 36);
Keyboard.enableRepeatEvents(true);
this.buttonList.clear();
for(Pair<Pair<File, ReplayMetaData>, File> p : replayFileList) { if(!this.initialized) {
FileInfo fileInfo = new FileInfo(-1, p.first().second(), null, null, this.initialized = true;
-1, -1, -1, FilenameUtils.getBaseName(p.first().first().getName()), true); } else {
replayGuiList.addEntry(fileInfo, p.second()); this.replayGuiList.setDimensions(this.width, this.height, 32, this.height - 64);
} }
}
public class FileAgeComparator implements Comparator<Pair<Pair<File, ReplayMetaData>, File>> { reloadFiles();
this.createButtons();
}
@Override private void createButtons() {
public int compare(Pair<Pair<File, ReplayMetaData>, File> o1, Pair<Pair<File, ReplayMetaData>, File> o2) { this.buttonList.add(loadButton = new GuiButton(LOAD_BUTTON_ID, this.width / 2 - 154, this.height - 52, 73, 20, I18n.format("Load", new Object[0])));
try { this.buttonList.add(uploadButton = new GuiButton(UPLOAD_BUTTON_ID, this.width / 2 - 154 + 78, this.height - 52, 73, 20, I18n.format("Upload", new Object[0])));
return (int)(new Date(o2.first().second().getDate()).compareTo(new Date(o1.first().second().getDate()))); this.buttonList.add(folderButton = new GuiButton(FOLDER_BUTTON_ID, this.width / 2 + 4, this.height - 52, 150, 20, I18n.format("Open Replay Folder...", new Object[0])));
} catch(Exception e) { this.buttonList.add(renameButton = new GuiButton(RENAME_BUTTON_ID, this.width / 2 - 154, this.height - 28, 72, 20, I18n.format("Rename", new Object[0])));
return 0; this.buttonList.add(deleteButton = new GuiButton(DELETE_BUTTON_ID, this.width / 2 - 76, this.height - 28, 72, 20, I18n.format("Delete", new Object[0])));
} this.buttonList.add(settingsButton = new GuiButton(SETTINGS_BUTTON_ID, this.width / 2 + 4, this.height - 28, 72, 20, I18n.format("Settings", new Object[0])));
} this.buttonList.add(cancelButton = new GuiButton(CANCEL_BUTTON_ID, this.width / 2 + 4 + 78, this.height - 28, 72, 20, I18n.format("Cancel", new Object[0])));
setButtonsEnabled(false);
}
} @Override
public void handleMouseInput() throws IOException {
super.handleMouseInput();
this.replayGuiList.handleMouseInput();
}
@Override @Override
public void initGui() { protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
replayGuiList = new ReplayList(this, this.mc, this.width, this.height, 32, this.height - 64, 36); super.mouseClicked(mouseX, mouseY, mouseButton);
Keyboard.enableRepeatEvents(true); this.replayGuiList.mouseClicked(mouseX, mouseY, mouseButton);
this.buttonList.clear(); }
if (!this.initialized) { @Override
this.initialized = true; protected void mouseReleased(int mouseX, int mouseY, int state) {
} super.mouseReleased(mouseX, mouseY, state);
else { this.replayGuiList.mouseReleased(mouseX, mouseY, state);
this.replayGuiList.setDimensions(this.width, this.height, 32, this.height - 64); }
}
reloadFiles(); @Override
this.createButtons(); public void drawScreen(int mouseX, int mouseY, float partialTicks) {
} this.hoveringText = null;
this.drawDefaultBackground();
this.replayGuiList.drawScreen(mouseX, mouseY, partialTicks);
this.drawCenteredString(this.fontRendererObj, "Replay Viewer", this.width / 2, 20, 16777215);
super.drawScreen(mouseX, mouseY, partialTicks);
}
private void createButtons() { @Override
this.buttonList.add(loadButton = new GuiButton(LOAD_BUTTON_ID, this.width / 2 - 154, this.height - 52, 73, 20, I18n.format("Load", new Object[0]))); protected void actionPerformed(GuiButton button) throws IOException {
this.buttonList.add(uploadButton = new GuiButton(UPLOAD_BUTTON_ID, this.width / 2 - 154 + 78, this.height - 52, 73, 20, I18n.format("Upload", new Object[0]))); if(button.enabled) {
this.buttonList.add(folderButton = new GuiButton(FOLDER_BUTTON_ID, this.width / 2 + 4, this.height - 52, 150, 20, I18n.format("Open Replay Folder...", new Object[0]))); if(button.id == LOAD_BUTTON_ID) {
this.buttonList.add(renameButton = new GuiButton(RENAME_BUTTON_ID, this.width / 2 - 154, this.height - 28, 72, 20, I18n.format("Rename", new Object[0]))); loadReplay(replayGuiList.selected);
this.buttonList.add(deleteButton = new GuiButton(DELETE_BUTTON_ID, this.width / 2 - 76, this.height - 28, 72, 20, I18n.format("Delete", new Object[0]))); } else if(button.id == CANCEL_BUTTON_ID) {
this.buttonList.add(settingsButton = new GuiButton(SETTINGS_BUTTON_ID, this.width / 2 + 4, this.height - 28, 72, 20, I18n.format("Settings", new Object[0]))); mc.displayGuiScreen(parentScreen);
this.buttonList.add(cancelButton = new GuiButton(CANCEL_BUTTON_ID, this.width / 2 + 4 + 78, this.height - 28, 72, 20, I18n.format("Cancel", new Object[0]))); } else if(button.id == DELETE_BUTTON_ID) {
setButtonsEnabled(false); String s = replayGuiList.getListEntry(replayGuiList.selected).getFileInfo().getName();
}
@Override if(s != null) {
public void handleMouseInput() throws IOException { delete_file = true;
super.handleMouseInput(); GuiYesNo guiyesno = getYesNoGui(this, s, 1);
this.replayGuiList.handleMouseInput(); this.mc.displayGuiScreen(guiyesno);
} }
} else if(button.id == SETTINGS_BUTTON_ID) {
this.mc.displayGuiScreen(new GuiReplaySettings(this));
} else if(button.id == RENAME_BUTTON_ID) {
File file = replayFileList.get(replayGuiList.selected).first().first();
this.mc.displayGuiScreen(new GuiRenameReplay(this, file));
} else if(button.id == UPLOAD_BUTTON_ID) {
File file = replayFileList.get(replayGuiList.selected).first().first();
this.mc.displayGuiScreen(new GuiUploadFile(file, this));
} else if(button.id == FOLDER_BUTTON_ID) {
File file1 = ReplayFileIO.getReplayFolder();
@Override String s = file1.getAbsolutePath();
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton);
this.replayGuiList.mouseClicked(mouseX, mouseY, mouseButton);
}
@Override if(Util.getOSType() == Util.EnumOS.OSX) {
protected void mouseReleased(int mouseX, int mouseY, int state) { try {
super.mouseReleased(mouseX, mouseY, state); Runtime.getRuntime().exec(new String[]{"/usr/bin/open", s});
this.replayGuiList.mouseReleased(mouseX, mouseY, state); return;
} } catch(IOException ioexception1) {
}
} else if(Util.getOSType() == Util.EnumOS.WINDOWS) {
String s1 = String.format("cmd.exe /C start \"Open file\" \"%s\"", new Object[]{s});
@Override try {
public void drawScreen(int mouseX, int mouseY, float partialTicks) { Runtime.getRuntime().exec(s1);
this.hoveringText = null; return;
this.drawDefaultBackground(); } catch(IOException ioexception) {
this.replayGuiList.drawScreen(mouseX, mouseY, partialTicks); }
this.drawCenteredString(this.fontRendererObj, "Replay Viewer", this.width / 2, 20, 16777215); }
super.drawScreen(mouseX, mouseY, partialTicks);
}
@Override boolean flag = false;
protected void actionPerformed(GuiButton button) throws IOException {
if(button.enabled) {
if(button.id == LOAD_BUTTON_ID) {
loadReplay(replayGuiList.selected);
}
else if(button.id == CANCEL_BUTTON_ID) {
mc.displayGuiScreen(parentScreen);
}
else if(button.id == DELETE_BUTTON_ID) {
String s = replayGuiList.getListEntry(replayGuiList.selected).getFileInfo().getName();
if (s != null) { try {
delete_file = true; Class oclass = Class.forName("java.awt.Desktop");
GuiYesNo guiyesno = getYesNoGui(this, s, 1); Object object = oclass.getMethod("getDesktop", new Class[0]).invoke((Object) null, new Object[0]);
this.mc.displayGuiScreen(guiyesno); oclass.getMethod("browse", new Class[]{URI.class}).invoke(object, new Object[]{file1.toURI()});
} } catch(Throwable throwable) {
} flag = true;
else if(button.id == SETTINGS_BUTTON_ID) { }
this.mc.displayGuiScreen(new GuiReplaySettings(this));
}
else if(button.id == RENAME_BUTTON_ID) {
File file = replayFileList.get(replayGuiList.selected).first().first();
this.mc.displayGuiScreen(new GuiRenameReplay(this, file));
}
else if(button.id == UPLOAD_BUTTON_ID) {
File file = replayFileList.get(replayGuiList.selected).first().first();
this.mc.displayGuiScreen(new GuiUploadFile(file, this));
}
else if(button.id == FOLDER_BUTTON_ID) {
File file1 = ReplayFileIO.getReplayFolder();
String s = file1.getAbsolutePath(); if(flag) {
Sys.openURL("file://" + s);
}
}
}
}
if(Util.getOSType() == Util.EnumOS.OSX) { public void confirmClicked(boolean result, int id) {
try { if(this.delete_file) {
Runtime.getRuntime().exec(new String[] {"/usr/bin/open", s}); this.delete_file = false;
return;
}
catch(IOException ioexception1) {}
}
else if(Util.getOSType() == Util.EnumOS.WINDOWS) {
String s1 = String.format("cmd.exe /C start \"Open file\" \"%s\"", new Object[] {s});
try{ if(result) {
Runtime.getRuntime().exec(s1); replayFileList.get(replayGuiList.selected).first().first().delete();
return; replayFileList.remove(replayGuiList.selected);
} }
catch(IOException ioexception) {}
}
boolean flag = false; this.mc.displayGuiScreen(this);
}
}
try { public void setButtonsEnabled(boolean b) {
Class oclass = Class.forName("java.awt.Desktop"); loadButton.enabled = b;
Object object = oclass.getMethod("getDesktop", new Class[0]).invoke((Object)null, new Object[0]); if(!b || !AuthenticationHandler.isAuthenticated()) {
oclass.getMethod("browse", new Class[] {URI.class}).invoke(object, new Object[] {file1.toURI()}); uploadButton.enabled = false;
} } else {
catch(Throwable throwable) { uploadButton.enabled = true;
flag = true; }
}
if(flag) { renameButton.enabled = b;
Sys.openURL("file://" + s); deleteButton.enabled = b;
} }
}
}
}
public void confirmClicked(boolean result, int id) { public void loadReplay(int id) {
if (this.delete_file) mc.displayGuiScreen((GuiScreen) null);
{
this.delete_file = false;
if (result) try {
{ ReplayHandler.startReplay(replayFileList.get(id).first().first());
replayFileList.get(replayGuiList.selected).first().first().delete(); } catch(Exception e) {
replayFileList.remove(replayGuiList.selected); e.printStackTrace();
} }
this.mc.displayGuiScreen(this); }
}
}
public static GuiYesNo getYesNoGui(GuiYesNoCallback p_152129_0_, String file, int p_152129_2_) { public class FileAgeComparator implements Comparator<Pair<Pair<File, ReplayMetaData>, File>> {
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) { @Override
loadButton.enabled = b; public int compare(Pair<Pair<File, ReplayMetaData>, File> o1, Pair<Pair<File, ReplayMetaData>, File> o2) {
if(!b || !AuthenticationHandler.isAuthenticated()) { try {
uploadButton.enabled = false; return (int) (new Date(o2.first().second().getDate()).compareTo(new Date(o1.first().second().getDate())));
} else { } catch(Exception e) {
uploadButton.enabled = true; return 0;
} }
}
renameButton.enabled = b; }
deleteButton.enabled = b;
}
public void loadReplay(int id) {
mc.displayGuiScreen((GuiScreen)null);
try {
ReplayHandler.startReplay(replayFileList.get(id).first().first());
} catch(Exception e) {
e.printStackTrace();
}
}
} }

View File

@@ -5,25 +5,25 @@ import net.minecraft.client.Minecraft;
public class ReplayList extends GuiReplayListExtended { public class ReplayList extends GuiReplayListExtended {
private GuiReplayViewer parent; private GuiReplayViewer parent;
public ReplayList(GuiReplayViewer parent, Minecraft mcIn, public ReplayList(GuiReplayViewer parent, Minecraft mcIn,
int p_i45010_2_, int p_i45010_3_, int p_i45010_4_, int p_i45010_5_, int p_i45010_2_, int p_i45010_3_, int p_i45010_4_, int p_i45010_5_,
int p_i45010_6_) { int p_i45010_6_) {
super(mcIn, p_i45010_2_, p_i45010_3_, p_i45010_4_, p_i45010_5_, super(mcIn, p_i45010_2_, p_i45010_3_, p_i45010_4_, p_i45010_5_,
p_i45010_6_); p_i45010_6_);
this.parent = parent; this.parent = parent;
} }
@Override @Override
protected void elementClicked(int slotIndex, boolean isDoubleClick, protected void elementClicked(int slotIndex, boolean isDoubleClick,
int mouseX, int mouseY) { int mouseX, int mouseY) {
super.elementClicked(slotIndex, isDoubleClick, mouseX, mouseY); super.elementClicked(slotIndex, isDoubleClick, mouseX, mouseY);
parent.setButtonsEnabled(true); parent.setButtonsEnabled(true);
if(isDoubleClick) { if(isDoubleClick) {
parent.loadReplay(slotIndex); parent.loadReplay(slotIndex);
} }
} }
} }

View File

@@ -2,19 +2,13 @@ package eu.crushedpixel.replaymod.holders;
public class Keyframe { public class Keyframe {
private int realTimestamp; private final int realTimestamp;
public Keyframe(int realTimestamp) {
this.realTimestamp = realTimestamp;
}
public int getRealTimestamp() {
return realTimestamp;
}
public void setRealTimestamp(int realTimestamp) {
this.realTimestamp = realTimestamp;
}
public Keyframe(int realTimestamp) {
this.realTimestamp = realTimestamp;
}
public int getRealTimestamp() {
return 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,30 +1,30 @@
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;
private int timestamp; private int timestamp;
public PacketData(byte[] array, int timestamp) { public PacketData(byte[] array, int timestamp) {
this.array = array; this.array = array;
this.timestamp = timestamp; this.timestamp = timestamp;
} }
public byte[] getByteArray() { public byte[] getByteArray() {
return array; return array;
} }
public void setByteArray(byte[] array) {
this.array = array; public void setByteArray(byte[] array) {
} this.array = array;
public int getTimestamp() { }
return timestamp;
} public int getTimestamp() {
public void setTimestamp(int timestamp) { return timestamp;
this.timestamp = timestamp; }
}
public void setTimestamp(int timestamp) {
this.timestamp = timestamp;
}
} }

View File

@@ -4,67 +4,67 @@ import net.minecraft.entity.Entity;
public class Position { public class Position {
private double x, y, z; private double x, y, z;
private float pitch, yaw; private float pitch, yaw;
public Position(Entity e) { public Position(Entity e) {
this.x = e.posX; this.x = e.posX;
this.y = e.posY; this.y = e.posY;
this.z = e.posZ; this.z = e.posZ;
this.pitch = e.rotationPitch; this.pitch = e.rotationPitch;
this.yaw = e.rotationYaw; this.yaw = e.rotationYaw;
} }
public Position(double x, double y, double z, float pitch, float yaw) { public Position(double x, double y, double z, float pitch, float yaw) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.pitch = pitch; this.pitch = pitch;
this.yaw = yaw; this.yaw = yaw;
} }
public double getX() { public double getX() {
return x; return x;
} }
public void setX(double x) { public void setX(double x) {
this.x = x; this.x = x;
} }
public double getY() { public double getY() {
return y; return y;
} }
public void setY(double y) { public void setY(double y) {
this.y = y; this.y = y;
} }
public double getZ() { public double getZ() {
return z; return z;
} }
public void setZ(double z) { public void setZ(double z) {
this.z = z; this.z = z;
} }
public float getPitch() { public float getPitch() {
return pitch; return pitch;
} }
public void setPitch(float pitch) { public void setPitch(float pitch) {
this.pitch = pitch; this.pitch = pitch;
} }
public float getYaw() { public float getYaw() {
return yaw; return yaw;
} }
public void setYaw(float yaw) { public void setYaw(float yaw) {
this.yaw = yaw; this.yaw = yaw;
} }
@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,19 +2,14 @@ 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);
this.position = position; this.position = position;
} }
public Position getPosition() {
return position;
}
public void setPosition(Position position) {
this.position = position;
}
public Position getPosition() {
return 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,18 +2,14 @@ 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);
this.timestamp = timestamp; this.timestamp = timestamp;
} }
public int getTimestamp() { public int getTimestamp() {
return timestamp; return timestamp;
} }
public void setTimestamp(int timestamp) {
this.timestamp = timestamp;
}
} }

View File

@@ -2,21 +2,20 @@ 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;
/* /*
We solve the equation We solve the equation
[2 1 ] [D[0]] [3(x[1] - x[0]) ] [2 1 ] [D[0]] [3(x[1] - x[0]) ]
|1 4 1 | |D[1]| |3(x[2] - x[0]) | |1 4 1 | |D[1]| |3(x[2] - x[0]) |
| 1 4 1 | | . | = | . | | 1 4 1 | | . | = | . |
@@ -27,45 +26,46 @@ public abstract class BasicSpline {
by using row operations to convert the matrix to upper triangular by using row operations to convert the matrix to upper triangular
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));
p1 = val.getDouble(valueCollection.get(num));
delta[num] = (3.0f * (p1 - p0) - delta[num - 1]) * gamma[num]; p0 = val.getDouble(valueCollection.get(num - 1));
p1 = val.getDouble(valueCollection.get(num));
D[num] = delta[num]; delta[num] = (3.0f * (p1 - p0) - delta[num - 1]) * gamma[num];
for(i=num-1; i >= 0; i--) {
D[i] = delta[i] - gamma[i] * D[i+1];
}
//now compute the coefficients of the cubics D[num] = delta[num];
cubicCollection.clear(); for(i = num - 1; i >= 0; i--) {
D[i] = delta[i] - gamma[i] * D[i + 1];
}
for(i=0; i<num; i++) { //now compute the coefficients of the cubics
p0 = val.getDouble(valueCollection.get(i)); cubicCollection.clear();
p1 = val.getDouble(valueCollection.get(i+1));
cubicCollection.add(new Cubic( for(i = 0; i < num; i++) {
p0, p0 = val.getDouble(valueCollection.get(i));
D[i], p1 = val.getDouble(valueCollection.get(i + 1));
3*(p1 - p0) - 2*D[i] - D[i+1],
2*(p0 - p1) + D[i] + D[i+1] cubicCollection.add(new Cubic(
) p0,
); D[i],
} 3 * (p1 - p0) - 2 * 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,46 +1,46 @@
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> {
public LinearInterpolation() { protected List<K> points = new ArrayList<K>();
points = new ArrayList<K>();
}
protected List<K> points = new ArrayList<K>(); public LinearInterpolation() {
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) {
points.add(point); points.add(point);
} }
public void clearPoints() { public void clearPoints() {
points = new ArrayList<K>(); points = new ArrayList<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

@@ -5,25 +5,25 @@ import eu.crushedpixel.replaymod.holders.Position;
public class LinearPoint extends LinearInterpolation<Position> { public class LinearPoint extends LinearInterpolation<Position> {
@Override @Override
public Position getPoint(float positionIn) { public Position getPoint(float positionIn) {
Pair<Float, Pair<Position, Position>> pair = getCurrentPoints(positionIn); Pair<Float, Pair<Position, Position>> pair = getCurrentPoints(positionIn);
if(pair == null) return null; if(pair == null) return null;
float perc = pair.first(); float perc = pair.first();
Position first = pair.second().first(); Position first = pair.second().first();
Position second = pair.second().second(); Position second = pair.second().second();
double x = getInterpolatedValue(first.getX(), second.getX(), perc); double x = getInterpolatedValue(first.getX(), second.getX(), perc);
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);
return inter; return inter;
} }
} }

View File

@@ -1,22 +1,21 @@
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> {
@Override @Override
public Integer getPoint(float position) { public Integer getPoint(float position) {
Pair<Float, Pair<Integer, Integer>> pair = getCurrentPoints(position); Pair<Float, Pair<Integer, Integer>> pair = getCurrentPoints(position);
if(pair == null) return null; if(pair == null) return null;
float perc = pair.first(); float perc = pair.first();
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,92 +1,86 @@
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;
private Vector<Cubic> xCubics; public class SplinePoint extends BasicSpline {
private Vector<Cubic> yCubics; private static final Object[] EMPTYOBJ = new Object[]{};
private Vector<Cubic> zCubics; private Vector<Position> points;
private Vector<Cubic> pitchCubics; private Vector<Cubic> xCubics;
private Vector<Cubic> yawCubics; private Vector<Cubic> yCubics;
private Vector<Cubic> zCubics;
private Vector<Cubic> pitchCubics;
private Vector<Cubic> yawCubics;
private Field vectorX;
private Field vectorY;
private Field vectorZ;
private Field vectorPitch;
private Field vectorYaw;
private Field vectorX; public SplinePoint() {
private Field vectorY; this.points = new Vector<Position>();
private Field vectorZ;
private Field vectorPitch;
private Field vectorYaw;
private static final Object[] EMPTYOBJ = new Object[] { }; this.xCubics = new Vector<Cubic>();
this.yCubics = new Vector<Cubic>();
this.zCubics = new Vector<Cubic>();
this.pitchCubics = new Vector<Cubic>();
this.yawCubics = new Vector<Cubic>();
public SplinePoint() { try {
this.points = new Vector<Position>(); vectorX = Position.class.getDeclaredField("x");
vectorY = Position.class.getDeclaredField("y");
vectorZ = Position.class.getDeclaredField("z");
vectorPitch = Position.class.getDeclaredField("pitch");
vectorYaw = Position.class.getDeclaredField("yaw");
vectorX.setAccessible(true);
vectorY.setAccessible(true);
vectorZ.setAccessible(true);
vectorPitch.setAccessible(true);
vectorYaw.setAccessible(true);
} catch(SecurityException e) {
e.printStackTrace();
} catch(NoSuchFieldException e) {
e.printStackTrace();
}
}
this.xCubics = new Vector<Cubic>(); public void addPoint(Position point) {
this.yCubics = new Vector<Cubic>(); this.points.add(point);
this.zCubics = new Vector<Cubic>(); }
this.pitchCubics = new Vector<Cubic>();
this.yawCubics = new Vector<Cubic>();
try { public Vector<Position> getPoints() {
vectorX = Position.class.getDeclaredField("x"); return points;
vectorY = Position.class.getDeclaredField("y"); }
vectorZ = Position.class.getDeclaredField("z");
vectorPitch = Position.class.getDeclaredField("pitch");
vectorYaw = Position.class.getDeclaredField("yaw");
vectorX.setAccessible(true);
vectorY.setAccessible(true);
vectorZ.setAccessible(true);
vectorPitch.setAccessible(true);
vectorYaw.setAccessible(true);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
public void addPoint(Position point) { public void calcSpline() {
this.points.add(point); try {
} calcNaturalCubic(points, vectorX, xCubics);
calcNaturalCubic(points, vectorY, yCubics);
calcNaturalCubic(points, vectorZ, zCubics);
calcNaturalCubic(points, vectorPitch, pitchCubics);
calcNaturalCubic(points, vectorYaw, yawCubics);
} catch(IllegalArgumentException e) {
e.printStackTrace();
} catch(IllegalAccessException e) {
e.printStackTrace();
} catch(InvocationTargetException e) {
e.printStackTrace();
}
}
public Vector<Position> getPoints() { public Position getPoint(float position) {
return points; position = position * xCubics.size();
} int cubicNum = (int) Math.min(xCubics.size() - 1, position);
float cubicPos = (position - cubicNum);
public void calcSpline() { return new Position(xCubics.get(cubicNum).eval(cubicPos),
try { yCubics.get(cubicNum).eval(cubicPos),
calcNaturalCubic(points, vectorX, xCubics); zCubics.get(cubicNum).eval(cubicPos),
calcNaturalCubic(points, vectorY, yCubics); (float) pitchCubics.get(cubicNum).eval(cubicPos),
calcNaturalCubic(points, vectorZ, zCubics); (float) yawCubics.get(cubicNum).eval(cubicPos));
calcNaturalCubic(points, vectorPitch, pitchCubics); }
calcNaturalCubic(points, vectorYaw, yawCubics);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public Position getPoint(float position) {
position = position * xCubics.size();
int cubicNum = (int)Math.min(xCubics.size()-1, position);
float cubicPos = (position - cubicNum);
return new Position(xCubics.get(cubicNum).eval(cubicPos),
yCubics.get(cubicNum).eval(cubicPos),
zCubics.get(cubicNum).eval(cubicPos),
(float)pitchCubics.get(cubicNum).eval(cubicPos),
(float)yawCubics.get(cubicNum).eval(cubicPos));
}
} }

View File

@@ -1,82 +1,53 @@
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 {
public static final int SUCCESS = 1; public static final int SUCCESS = 1;
public static final int INVALID = 2; public static final int INVALID = 2;
public static final int NO_CONNECTION = 3; public static final int NO_CONNECTION = 3;
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() {
return authkey != null;
}
public static boolean isAuthenticated() { public static String getKey() {
return authkey != null; return authkey;
} }
public static String getKey() { public static boolean hasDonated(String uuid) throws IOException, ApiException {
return authkey; return apiClient.hasDonated(uuid);
} }
public static boolean hasDonated(String uuid) throws IOException, ApiException { public static int authenticate(String username, String password) {
return apiClient.hasDonated(uuid); try {
} authkey = ReplayMod.apiClient.getLogin(username, password).getAuthkey();
return SUCCESS;
} catch(ApiException e) {
return INVALID;
} catch(Exception e) {
return NO_CONNECTION;
}
}
public static int authenticate(String username, String password) { public static int logout() {
try { try {
authkey = ReplayMod.apiClient.getLogin(username, password).getAuthkey(); ReplayMod.apiClient.logout(authkey);
return SUCCESS; authkey = null;
} catch(ApiException e) { return SUCCESS;
return INVALID; } catch(ApiException e) {
} catch(Exception e) { return INVALID;
return NO_CONNECTION; } catch(Exception e) {
} return NO_CONNECTION;
} }
}
public static int logout() {
try {
boolean success = ReplayMod.apiClient.logout(authkey);
authkey = null;
return SUCCESS;
} catch(ApiException e) {
return INVALID;
} catch(Exception e) {
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,127 +24,123 @@ import java.util.Map.Entry;
public class ConnectionEventHandler { public class ConnectionEventHandler {
private static final String decoderKey = "decoder"; public static final String TEMP_FILE_EXTENSION = ".tmcpr";
private static final String packetHandlerKey = "packet_handler"; public static final String JSON_FILE_EXTENSION = ".json";
private static final String DATE_FORMAT = "yyyy_MM_dd_HH_mm_ss"; public static final String ZIP_FILE_EXTENSION = ".mcpr";
private static final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); private static final String decoderKey = "decoder";
public static final String TEMP_FILE_EXTENSION = ".tmcpr"; private static final String packetHandlerKey = "packet_handler";
public static final String JSON_FILE_EXTENSION = ".json"; private static final String DATE_FORMAT = "yyyy_MM_dd_HH_mm_ss";
public static final String ZIP_FILE_EXTENSION = ".mcpr"; private static final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
private static PacketListener packetListener = null;
private static boolean isRecording = false;
private File currentFile;
private String fileName;
private File currentFile; public static boolean isRecording() {
private String fileName; return isRecording;
}
private static PacketListener packetListener = null; public static void insertPacket(Packet packet) {
if(!isRecording || packetListener == null) {
String reason = isRecording ? " (recording)" : " (null)";
System.out.println("Invalid attempt to insert Packet!" + reason);
return;
}
try {
packetListener.saveOnly(packet);
} catch(Exception e) {
e.printStackTrace();
}
}
private static boolean isRecording = false; @SubscribeEvent
public void onConnectedToServerEvent(ClientConnectedToServerEvent event) {
System.out.println("Connected to server");
public static boolean isRecording() { ReplayMod.chatMessageHandler.initialize();
return isRecording; ReplayMod.recordingHandler.resetVars();
}
public static void insertPacket(Packet packet) { try {
if(!isRecording || packetListener == null) { if(event.isLocal) {
String reason = isRecording ? " (recording)":" (null)"; if(!ReplayMod.replaySettings.isEnableRecordingSingleplayer()) {
System.out.println("Invalid attempt to insert Packet!"+reason); System.out.println("Singleplayer Recording is disabled");
return; return;
} }
try { } else {
packetListener.saveOnly(packet); if(!ReplayMod.replaySettings.isEnableRecordingServer()) {
} catch (Exception e) { System.out.println("Multiplayer Recording is disabled");
e.printStackTrace(); return;
} }
} }
NetworkManager nm = event.manager;
String worldName = "";
if(!event.isLocal) {
worldName = ((InetSocketAddress) nm.getRemoteAddress()).getHostName();
}
Channel channel = nm.channel();
ChannelPipeline pipeline = channel.pipeline();
@SubscribeEvent List<String> channelHandlerKeys = new ArrayList<String>();
public void onConnectedToServerEvent(ClientConnectedToServerEvent event) { Iterator<Entry<String, ChannelHandler>> it = pipeline.iterator();
System.out.println("Connected to server"); while(it.hasNext()) {
Entry<String, ChannelHandler> entry = it.next();
channelHandlerKeys.add(entry.getKey());
}
ChatMessageRequests.initialize(); File folder = ReplayFileIO.getReplayFolder();
ReplayMod.recordingHandler.resetVars(); fileName = sdf.format(Calendar.getInstance().getTime());
currentFile = new File(folder, fileName + TEMP_FILE_EXTENSION);
try { currentFile.createNewFile();
if(event.isLocal) {
if(!ReplayMod.replaySettings.isEnableRecordingSingleplayer()) {
System.out.println("Singleplayer Recording is disabled");
return;
}
} else {
if(!ReplayMod.replaySettings.isEnableRecordingServer()) {
System.out.println("Multiplayer Recording is disabled");
return;
}
}
NetworkManager nm = event.manager;
String worldName = "";
if(!event.isLocal) {
worldName = ((InetSocketAddress)nm.getRemoteAddress()).getHostName();
}
Channel channel = nm.channel();
ChannelPipeline pipeline = channel.pipeline();
List<String> channelHandlerKeys = new ArrayList<String>(); PacketListener insert = null;
Iterator<Entry<String, ChannelHandler>> it = pipeline.iterator();
while(it.hasNext()) {
Entry<String, ChannelHandler> entry = it.next();
channelHandlerKeys.add(entry.getKey());
}
File folder = ReplayFileIO.getReplayFolder(); pipeline.addBefore(packetHandlerKey, "replay_recorder", insert = new PacketListener
(currentFile, fileName, worldName, System.currentTimeMillis(), event.isLocal));
ReplayMod.chatMessageHandler.addChatMessage("Recording started!", ChatMessageType.INFORMATION);
isRecording = true;
fileName = sdf.format(Calendar.getInstance().getTime()); final PacketListener listener = insert;
currentFile = new File(folder, fileName+TEMP_FILE_EXTENSION);
currentFile.createNewFile(); if(insert != null && event.isLocal) {
new Thread(new Runnable() {
PacketListener insert = null; @Override
public void run() {
String worldName = null;
while(worldName == null) {
try {
worldName = MinecraftServer.getServer().getWorldName();
listener.setWorldName(worldName);
return;
pipeline.addBefore(packetHandlerKey, "replay_recorder", insert = new PacketListener } catch(Exception e) {
(currentFile, fileName, worldName, System.currentTimeMillis(), event.isLocal)); try {
ChatMessageRequests.addChatMessage("Recording started!", ChatMessageType.INFORMATION); Thread.sleep(100);
isRecording = true; } catch(InterruptedException e1) {
e1.printStackTrace();
}
}
}
final PacketListener listener = insert; }
}).start();
}
if(insert != null && event.isLocal) { packetListener = listener;
new Thread(new Runnable() {
@Override } catch(Exception e) {
public void run() { ReplayMod.chatMessageHandler.addChatMessage("Failed to start recording!", ChatMessageType.WARNING);
String worldName = null; e.printStackTrace();
while(worldName == null) { }
try { }
worldName = MinecraftServer.getServer().getWorldName();
listener.setWorldName(worldName);
return;
} catch(Exception e) { @SubscribeEvent
try { public void onDisconnectedFromServerEvent(ClientDisconnectionFromServerEvent event) {
Thread.sleep(100); System.out.println("Disconnected from server");
} catch (InterruptedException e1) { isRecording = false;
e1.printStackTrace(); packetListener = null;
} ReplayMod.chatMessageHandler.stop();
} }
}
}
}).start();
}
packetListener = listener;
} catch(Exception e) {
ChatMessageRequests.addChatMessage("Failed to start recording!", ChatMessageType.WARNING);
e.printStackTrace();
}
}
@SubscribeEvent
public void onDisconnectedFromServerEvent(ClientDisconnectionFromServerEvent event) {
System.out.println("Disconnected from server");
isRecording = false;
packetListener = null;
ChatMessageRequests.stop();
}
} }

View File

@@ -1,175 +1,153 @@
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 {
protected File file; protected File file;
protected Long startTime = null; protected Long startTime = null;
protected String name; protected String name;
protected String worldName; protected String worldName;
protected long lastSentPacket = 0;
protected boolean alive = true;
protected DataWriter dataWriter;
protected Set<String> players = new HashSet<String>();
private boolean singleplayer;
private Gson gson = new Gson();
private boolean singleplayer; public DataListener(File file, String name, String worldName, long startTime, boolean singleplayer) throws FileNotFoundException {
this.file = file;
this.startTime = startTime;
this.name = name;
this.worldName = worldName;
this.singleplayer = singleplayer;
protected long lastSentPacket = 0; System.out.println(worldName);
protected boolean alive = true; FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream out = new DataOutputStream(bos);
dataWriter = new DataWriter(out);
}
protected DataWriter dataWriter; public void setWorldName(String worldName) {
this.worldName = worldName;
System.out.println(worldName);
}
private Gson gson = new Gson(); @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
dataWriter.requestFinish(players);
}
protected Set<String> players = new HashSet<String>(); public class DataWriter {
public void setWorldName(String worldName) { private boolean active = true;
this.worldName = worldName;
System.out.println(worldName);
}
public DataListener(File file, String name, String worldName, long startTime, boolean singleplayer) throws FileNotFoundException { private ConcurrentLinkedQueue<PacketData> queue = new ConcurrentLinkedQueue<PacketData>();
this.file = file; private DataOutputStream stream;
this.startTime = startTime; Thread outputThread = new Thread(new Runnable() {
this.name = name;
this.worldName = worldName;
this.singleplayer = singleplayer;
System.out.println(worldName); @Override
public void run() {
FileOutputStream fos = new FileOutputStream(file); HashMap<Class, Integer> counts = new HashMap<Class, Integer>();
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream out = new DataOutputStream(bos);
dataWriter = new DataWriter(out);
}
@Override while(active) {
public void channelInactive(ChannelHandlerContext ctx) throws Exception { PacketData dataReciever = queue.poll();
dataWriter.requestFinish(players); if(dataReciever != null) {
} //write the ByteBuf to the given OutputStream
public class DataWriter { byte[] array = dataReciever.getByteArray();
private boolean active = true; if(array != null) {
try {
ReplayFileIO.writePacket(dataReciever, stream);
stream.flush();
} catch(Exception e) {
e.printStackTrace();
}
}
private ConcurrentLinkedQueue<PacketData> queue = new ConcurrentLinkedQueue<PacketData>(); } else {
try {
//let the Thread sleep for 1/4 second and queue up new Packets
Thread.sleep(250L);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public void writeData(PacketData data) { try {
queue.add(data); stream.flush();
} stream.close();
} catch(Exception e) {
e.printStackTrace();
}
Thread outputThread = new Thread(new Runnable() { for(Entry<Class, Integer> entries : counts.entrySet()) {
System.out.println(entries.getKey() + "| " + entries.getValue());
}
@Override }
public void run() { });
HashMap<Class, Integer> counts = new HashMap<Class, Integer>(); public DataWriter(DataOutputStream stream) {
this.stream = stream;
outputThread.start();
}
while(active) { public void writeData(PacketData data) {
PacketData dataReciever = queue.poll(); queue.add(data);
if(dataReciever != null) { }
//write the ByteBuf to the given OutputStream
byte[] array = dataReciever.getByteArray(); public void requestFinish(Set<String> players) {
active = false;
if(array != null) { try {
try { GuiReplaySaving.replaySaving = true;
ReplayFileIO.writePacket(dataReciever, stream);
stream.flush();
} catch(Exception e) {
e.printStackTrace();
}
}
} else { String mcversion = Minecraft.getMinecraft().getVersion();
try { String[] split = mcversion.split("-");
//let the Thread sleep for 1/4 second and queue up new Packets if(split.length > 0) {
Thread.sleep(250L); mcversion = split[0];
} catch (InterruptedException e) { }
e.printStackTrace();
}
}
}
try { String[] pl = players.toArray(new String[players.size()]);
stream.flush();
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
for(Entry<Class, Integer> entries : counts.entrySet()) { ReplayMetaData metaData = new ReplayMetaData(singleplayer, worldName, (int) lastSentPacket, startTime, pl, mcversion);
System.out.println(entries.getKey()+ "| "+entries.getValue()); String json = gson.toJson(metaData);
}
} File folder = ReplayFileIO.getReplayFolder();
});
private DataOutputStream stream; File archive = new File(folder, name + ConnectionEventHandler.ZIP_FILE_EXTENSION);
archive.createNewFile();
public DataWriter(DataOutputStream stream) { ReplayFileIO.writeReplayFile(archive, file, metaData);
this.stream = stream;
outputThread.start();
}
public void requestFinish(Set<String> players) { file.delete();
active = false;
try { GuiReplaySaving.replaySaving = false;
GuiReplaySaving.replaySaving = true; } catch(Exception e) {
e.printStackTrace();
GuiReplaySaving.replaySaving = false;
}
}
String mcversion = Minecraft.getMinecraft().getVersion(); }
String[] split = mcversion.split("-");
if(split.length > 0) {
mcversion = split[0];
}
String[] pl = players.toArray(new String[players.size()]);
ReplayMetaData metaData = new ReplayMetaData(singleplayer, worldName, (int)lastSentPacket, startTime, pl, mcversion);
String json = gson.toJson(metaData);
File folder = ReplayFileIO.getReplayFolder();
File archive = new File(folder, name+ConnectionEventHandler.ZIP_FILE_EXTENSION);
archive.createNewFile();
ReplayFileIO.writeReplayFile(archive, file, metaData);
file.delete();
GuiReplaySaving.replaySaving = false;
} catch(Exception e) {
e.printStackTrace();
GuiReplaySaving.replaySaving = false;
}
}
}
} }

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,130 +17,116 @@ 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 {
public PacketListener(File file, String name, String worldName, long startTime, boolean singleplayer) throws FileNotFoundException { private static final Minecraft mc = Minecraft.getMinecraft();
super(file, name, worldName, startTime, singleplayer); private static Field spawnMobDataWatcher, spawnPlayerDataWatcher;
}
private static final Minecraft mc = Minecraft.getMinecraft(); static {
try {
spawnMobDataWatcher = S0FPacketSpawnMob.class.getDeclaredField(MCPNames.field("field_149043_l"));
spawnMobDataWatcher.setAccessible(true);
private ChannelHandlerContext context = null; spawnPlayerDataWatcher = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_148960_i"));
spawnPlayerDataWatcher.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
public void saveOnly(Packet packet) { private ChannelHandlerContext context = null;
try {
if(packet instanceof S0CPacketSpawnPlayer) {
UUID uuid = ((S0CPacketSpawnPlayer)packet).func_179819_c();
players.add(uuid.toString());
}
PacketData pd = getPacketData(context, packet);
writeData(pd);
} catch(Exception e) {
e.printStackTrace();
}
}
@Override public PacketListener(File file, String name, String worldName, long startTime, boolean singleplayer) throws FileNotFoundException {
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { super(file, name, worldName, startTime, singleplayer);
if(ctx == null) { }
if(context == null) {
return;
} else {
ctx = context;
}
}
this.context = ctx;
if(!alive) {
super.channelRead(ctx, msg);
return;
}
if(msg instanceof Packet) {
try {
Packet packet = (Packet)msg;
if(packet instanceof S0DPacketCollectItem) { public void saveOnly(Packet packet) {
if(mc.thePlayer != null || try {
((S0DPacketCollectItem)packet).func_149353_d() == mc.thePlayer.getEntityId()) { if(packet instanceof S0CPacketSpawnPlayer) {
super.channelRead(ctx, msg); UUID uuid = ((S0CPacketSpawnPlayer) packet).func_179819_c();
return; players.add(uuid.toString());
} }
}
if(packet instanceof S0CPacketSpawnPlayer) { PacketData pd = getPacketData(context, packet);
UUID uuid = ((S0CPacketSpawnPlayer)packet).func_179819_c(); writeData(pd);
players.add(uuid.toString()); } catch(Exception e) {
} e.printStackTrace();
}
}
PacketData pd = getPacketData(ctx, packet); @Override
writeData(pd); public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
} catch(Exception e) { if(ctx == null) {
e.printStackTrace(); if(context == null) {
} return;
} else {
ctx = context;
}
}
this.context = ctx;
if(!alive) {
super.channelRead(ctx, msg);
return;
}
if(msg instanceof Packet) {
try {
Packet packet = (Packet) msg;
} if(packet instanceof S0DPacketCollectItem) {
if(mc.thePlayer != null ||
((S0DPacketCollectItem) packet).func_149353_d() == mc.thePlayer.getEntityId()) {
super.channelRead(ctx, msg);
return;
}
}
super.channelRead(ctx, msg); if(packet instanceof S0CPacketSpawnPlayer) {
} UUID uuid = ((S0CPacketSpawnPlayer) packet).func_179819_c();
players.add(uuid.toString());
}
private void writeData(PacketData pd) { PacketData pd = getPacketData(ctx, packet);
dataWriter.writeData(pd); writeData(pd);
lastSentPacket = pd.getTimestamp(); } catch(Exception e) {
} e.printStackTrace();
}
private static Field spawnMobDataWatcher, spawnPlayerDataWatcher; }
static { super.channelRead(ctx, msg);
try { }
spawnMobDataWatcher = S0FPacketSpawnMob.class.getDeclaredField(MCPNames.field("field_149043_l"));
spawnMobDataWatcher.setAccessible(true);
spawnPlayerDataWatcher = S0CPacketSpawnPlayer.class.getDeclaredField(MCPNames.field("field_148960_i")); private void writeData(PacketData pd) {
spawnPlayerDataWatcher.setAccessible(true); dataWriter.writeData(pd);
} catch(Exception e) { lastSentPacket = pd.getTimestamp();
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);
} }
} }
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);
} }
} }
byte[] array = ReplayFileIO.serializePacket(packet); byte[] array = ReplayFileIO.serializePacket(packet);
return new PacketData(array, timestamp); return new PacketData(array, timestamp);
} }
} }

View File

@@ -3,36 +3,35 @@ 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 static ByteBuf toByteBuf(byte[] bytes) throws IOException, ClassNotFoundException {
public void encode(ChannelHandlerContext ctx, Packet packet, ByteBuf byteBuf) throws IOException { ByteBuf bb;
EnumConnectionState state = ((EnumConnectionState)ctx.channel().attr(NetworkManager.attrKeyConnectionState).get()); bb = Unpooled.buffer(bytes.length);
encode(state, packet, byteBuf); bb.writeBytes(bytes);
}
public void encode(EnumConnectionState state, Packet packet, ByteBuf byteBuf) { return bb;
Integer integer = state.getPacketId(EnumPacketDirection.CLIENTBOUND, packet); }
if (integer == null) { @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; return;
} else { } else {
PacketBuffer packetbuffer = new PacketBuffer(byteBuf); PacketBuffer packetbuffer = new PacketBuffer(byteBuf);
@@ -40,20 +39,11 @@ public class PacketSerializer extends MessageSerializer {
try { try {
packet.writePacketData(packetbuffer); packet.writePacketData(packetbuffer);
} } catch(Throwable throwable) {
catch (Throwable throwable) { throwable.printStackTrace();
throwable.printStackTrace();
} }
} }
} }
public static ByteBuf toByteBuf(byte[] bytes) throws IOException, ClassNotFoundException {
ByteBuf bb;
bb = Unpooled.buffer(bytes.length);
bb.writeBytes(bytes);
return bb;
}
} }

View File

@@ -1,45 +1,49 @@
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;
private String serverName; private String serverName;
private int duration; private int duration;
private long date; private long date;
private String[] players; private String[] players;
private String mcversion; private String mcversion;
public ReplayMetaData(boolean singleplayer, String serverName, public ReplayMetaData(boolean singleplayer, String serverName,
int duration, long date, String[] players, String mcversion) { int duration, long date, String[] players, String mcversion) {
this.singleplayer = singleplayer; this.singleplayer = singleplayer;
this.serverName = serverName; this.serverName = serverName;
this.duration = duration; this.duration = duration;
this.date = date; this.date = date;
this.players = players; this.players = players;
this.mcversion = mcversion; this.mcversion = mcversion;
} }
public boolean isSingleplayer() {
return singleplayer; public boolean isSingleplayer() {
} return singleplayer;
public String getServerName() { }
return serverName;
} public String getServerName() {
public int getDuration() { return serverName;
return duration; }
}
public void setDuration(int duration) { public int getDuration() {
this.duration = duration; return duration;
} }
public long getDate() {
return date; public void setDuration(int duration) {
} this.duration = duration;
public String[] getPlayers() { }
return players;
} public long getDate() {
public String getMCVersion() { return date;
return mcversion; }
}
public String[] getPlayers() {
return players;
}
public String getMCVersion() {
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,267 +1,140 @@
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
*/ */
public final class MCPNames { 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()) { InputStream fieldsIs = MCPNames.class.getClassLoader().getResourceAsStream("fields.csv");
String mappingsDir = "./../build/unpacked/mappings/"; InputStream methodsIs = MCPNames.class.getClassLoader().getResourceAsStream("methods.csv");
InputStream fieldsIs = MCPNames.class.getClassLoader().getResourceAsStream("fields.csv"); fields = readMappings(fieldsIs);
InputStream methodsIs = MCPNames.class.getClassLoader().getResourceAsStream("methods.csv"); methods = readMappings(methodsIs);
fields = readMappings(fieldsIs); } else {
methods = readMappings(methodsIs); methods = fields = null;
}
} else { }
methods = fields = null;
} /**
} * <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)
* <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) public static boolean use() {
*/ return (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
public static boolean use() { }
return env.isMCPEnvironment();
} /**
* <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; }
} return mcp;
return mcp; } else {
} else { return srg;
return srg; }
} }
}
/**
/** * <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;
} }
return mcp; return mcp;
} else { } else {
return srg; return srg;
} }
} }
private static Map<String, String> readMappings(InputStream is) { private static Map<String, String> readMappings(InputStream is) {
try { try {
InputStreamReader isr = new InputStreamReader(is); InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr); BufferedReader br = new BufferedReader(isr);
MCPFileParser fileParser = new MCPFileParser(); MCPFileParser fileParser = new MCPFileParser();
while(br.ready()) { while(br.ready()) {
fileParser.processLine(br.readLine()); fileParser.processLine(br.readLine());
} }
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);
} }
} }
private static class MCPFileParser implements LineProcessor<Map<String, String>> { private static class MCPFileParser implements LineProcessor<Map<String, String>> {
private static final Splitter splitter = Splitter.on(',').trimResults(); private static final Splitter splitter = Splitter.on(',').trimResults();
private final Map<String, String> map = Maps.newHashMap(); private final Map<String, String> map = Maps.newHashMap();
private boolean foundFirst; private boolean foundFirst;
@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;
} }
Iterator<String> splitted = splitter.split(line).iterator(); Iterator<String> splitted = splitter.split(line).iterator();
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);
} }
return true; return true;
} }
@Override @Override
public Map<String, String> getResult() { public Map<String, String> getResult() {
return ImmutableMap.copyOf(map); return ImmutableMap.copyOf(map);
} }
} }
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,29 +1,27 @@
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_THUMBNAIL = "Create Thumbnail";
public static final String KEY_SPECTATE = "Spectate Entity";
private static Minecraft mc = Minecraft.getMinecraft();
public static final String KEY_LIGHTING = "Toggle Lighting"; public static void initialize() {
public static final String KEY_THUMBNAIL = "Create Thumbnail"; List<KeyBinding> bindings = new ArrayList<KeyBinding>(Arrays.asList(mc.gameSettings.keyBindings));
public static final String KEY_SPECTATE = "Spectate Entity";
public static void initialize() { bindings.add(new KeyBinding(KEY_LIGHTING, Keyboard.KEY_V, "Replay Mod"));
List<KeyBinding> bindings = new ArrayList<KeyBinding>(Arrays.asList(mc.gameSettings.keyBindings)); bindings.add(new KeyBinding(KEY_THUMBNAIL, Keyboard.KEY_B, "Replay Mod"));
bindings.add(new KeyBinding(KEY_SPECTATE, Keyboard.KEY_C, "Replay Mod"));
bindings.add(new KeyBinding(KEY_LIGHTING, Keyboard.KEY_V, "Replay Mod")); mc.gameSettings.keyBindings = bindings.toArray(new KeyBinding[bindings.size()]);
bindings.add(new KeyBinding(KEY_THUMBNAIL, Keyboard.KEY_B, "Replay Mod")); }
bindings.add(new KeyBinding(KEY_SPECTATE, Keyboard.KEY_C, "Replay Mod"));
mc.gameSettings.keyBindings = bindings.toArray(new KeyBinding[bindings.size()]);
}
} }

View File

@@ -1,42 +1,38 @@
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 {
private static float initialGamma = 0; private static float initialGamma = 0;
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) {
if(lighting) {
if(!enabled) {
initialGamma = Minecraft.getMinecraft().gameSettings.getOptionFloatValue(Options.GAMMA);
}
Minecraft.getMinecraft().gameSettings.setOptionFloatValue(Options.GAMMA, 1000);
} else Minecraft.getMinecraft().gameSettings.setOptionFloatValue(Options.GAMMA, initialGamma);
public static void setLighting(boolean lighting) { enabled = lighting;
if(lighting) {
if(!enabled) {
initialGamma = Minecraft.getMinecraft().gameSettings.getOptionFloatValue(Options.GAMMA);
}
Minecraft.getMinecraft().gameSettings.setOptionFloatValue(Options.GAMMA, 1000);
}
else Minecraft.getMinecraft().gameSettings.setOptionFloatValue(Options.GAMMA, initialGamma);
enabled = lighting; try {
if(ReplayMod.replaySender.paused()) {
try { MCTimerHandler.advancePartialTicks(1);
if(ReplayHandler.isPaused()) { MCTimerHandler.advanceRenderPartialTicks(1);
MCTimerHandler.advancePartialTicks(1); } else {
MCTimerHandler.advanceRenderPartialTicks(1); Minecraft.getMinecraft().entityRenderer.updateCameraAndRender(0);
} else { }
Minecraft.getMinecraft().entityRenderer.updateCameraAndRender(0); } catch(Exception e) {
} e.printStackTrace();
} catch (Exception e) { }
e.printStackTrace(); }
}
}
} }

View File

@@ -1,83 +1,49 @@
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; public static boolean hidden = false;
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getMinecraft();
public static boolean hidden = false; public static void hide() {
if(hidden) return;
GuiIngameForge.renderExperiance = false;
GuiIngameForge.renderArmor = false;
GuiIngameForge.renderAir = false;
GuiIngameForge.renderHealth = false;
GuiIngameForge.renderHotbar = false;
GuiIngameForge.renderFood = false;
GuiIngameForge.renderBossHealth = false;
GuiIngameForge.renderCrosshairs = false;
GuiIngameForge.renderHelmet = false;
GuiIngameForge.renderPortal = false;
GuiIngameForge.renderHealthMount = false;
GuiIngameForge.renderJumpBar = false;
GuiIngameForge.renderObjective = false;
/* hidden = true;
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 show() {
if(hidden) return; mc.gameSettings.hideGUI = false;
GuiIngameForge.renderExperiance = false;
GuiIngameForge.renderArmor = false;
GuiIngameForge.renderAir = false;
GuiIngameForge.renderHealth = false;
GuiIngameForge.renderHotbar = false;
GuiIngameForge.renderFood = false;
GuiIngameForge.renderBossHealth = false;
GuiIngameForge.renderCrosshairs = false;
GuiIngameForge.renderHelmet = false;
GuiIngameForge.renderPortal = false;
GuiIngameForge.renderHealthMount = false;
GuiIngameForge.renderJumpBar = false;
GuiIngameForge.renderObjective = false;
/* GuiIngameForge.renderExperiance = true;
try { GuiIngameForge.renderArmor = true;
renderHand.set(mc.entityRenderer, false); GuiIngameForge.renderAir = true;
} catch(Exception e) { GuiIngameForge.renderHealth = true;
e.printStackTrace(); GuiIngameForge.renderHotbar = true;
} GuiIngameForge.renderFood = true;
*/ GuiIngameForge.renderBossHealth = true;
GuiIngameForge.renderCrosshairs = true;
GuiIngameForge.renderHelmet = true;
GuiIngameForge.renderPortal = true;
GuiIngameForge.renderHealthMount = true;
GuiIngameForge.renderJumpBar = true;
GuiIngameForge.renderObjective = true;
hidden = true; hidden = false;
} }
public static void show() {
mc.gameSettings.hideGUI = false;
GuiIngameForge.renderExperiance = true;
GuiIngameForge.renderArmor = true;
GuiIngameForge.renderAir = true;
GuiIngameForge.renderHealth = true;
GuiIngameForge.renderHotbar = true;
GuiIngameForge.renderFood = true;
GuiIngameForge.renderBossHealth = true;
GuiIngameForge.renderCrosshairs = true;
GuiIngameForge.renderHelmet = true;
GuiIngameForge.renderPortal = true;
GuiIngameForge.renderHealthMount = true;
GuiIngameForge.renderJumpBar = true;
GuiIngameForge.renderObjective = true;
/*
try {
renderHand.set(mc.entityRenderer, true);
} catch(Exception e) {
e.printStackTrace();
}
*/
hidden = false;
}
} }

View File

@@ -1,41 +1,44 @@
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 {
try {
resourceManager = EntityRenderer.class.getDeclaredField(MCPNames.field("field_147711_ac"));
resourceManager.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
public SafeEntityRenderer(Minecraft mcIn, EntityRenderer renderer) throws IllegalArgumentException, IllegalAccessException { static {
super(mcIn, (IResourceManager)resourceManager.get(renderer)); try {
} resourceManager = EntityRenderer.class.getDeclaredField(MCPNames.field("field_147711_ac"));
resourceManager.setAccessible(true);
} catch(Exception e) {
e.printStackTrace();
}
}
@Override public SafeEntityRenderer(Minecraft mcIn, EntityRenderer renderer) throws IllegalArgumentException, IllegalAccessException {
public void updateCameraAndRender(float partialTicks) { super(mcIn, (IResourceManager) resourceManager.get(renderer));
try { }
super.updateCameraAndRender(partialTicks);
} 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
}
@Override @Override
public void updateRenderer() { public void updateCameraAndRender(float partialTicks) {
try { try {
super.updateRenderer(); super.updateCameraAndRender(partialTicks);
} catch(Exception e) {} } 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
}
@Override
public void updateRenderer() {
try {
super.updateRenderer();
} catch(Exception e) {
}
}
} }

View File

@@ -1,105 +1,105 @@
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) {
super(owner); super(owner);
} }
@Override @Override
public void addObject(int id, Object object) { public void addObject(int id, Object object) {
} }
@Override @Override
public void addObjectByDataType(int id, int type) { public void addObjectByDataType(int id, int type) {
} }
@Override @Override
public byte getWatchableObjectByte(int id) { public byte getWatchableObjectByte(int id) {
return 10; return 10;
} }
@Override @Override
public short getWatchableObjectShort(int id) { public short getWatchableObjectShort(int id) {
return 10; return 10;
} }
@Override @Override
public int getWatchableObjectInt(int id) { public int getWatchableObjectInt(int id) {
return 10; return 10;
} }
@Override @Override
public float getWatchableObjectFloat(int id) { public float getWatchableObjectFloat(int id) {
return 10f; return 10f;
} }
@Override @Override
public String getWatchableObjectString(int id) { public String getWatchableObjectString(int id) {
return null; return null;
} }
@Override @Override
public ItemStack getWatchableObjectItemStack(int id) { public ItemStack getWatchableObjectItemStack(int id) {
return null; return null;
} }
@Override @Override
public Rotations getWatchableObjectRotations(int id) { public Rotations getWatchableObjectRotations(int id) {
return null; return null;
} }
@Override @Override
public void updateObject(int id, Object newData) { public void updateObject(int id, Object newData) {
} }
@Override @Override
public void setObjectWatched(int id) { public void setObjectWatched(int id) {
} }
@Override @Override
public boolean hasObjectChanged() { public boolean hasObjectChanged() {
return false; return false;
} }
@Override @Override
public List getChanged() { public List getChanged() {
return null; return null;
} }
@Override @Override
public void writeTo(PacketBuffer buffer) throws IOException { public void writeTo(PacketBuffer buffer) throws IOException {
} }
@Override @Override
public List getAllWatched() { public List getAllWatched() {
return null; return null;
} }
@Override @Override
public void updateWatchedObjectsFromList(List p_75687_1_) { public void updateWatchedObjectsFromList(List p_75687_1_) {
} }
@Override
public boolean getIsBlank() {
return true;
}
@Override
public void func_111144_e() {
}
@Override
public boolean getIsBlank() {
return true;
}
@Override
public void func_111144_e() {
}
} }

View File

@@ -1,34 +1,34 @@
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 {
private boolean ignoreClose = false; private boolean ignoreClose = false;
public OpenEmbeddedChannel(NetworkManager networkManager) { public OpenEmbeddedChannel(NetworkManager networkManager) {
super(networkManager); super(networkManager);
} }
@Override @Override
public boolean finish() { public boolean finish() {
System.out.println("wanted to finish"); System.out.println("wanted to finish");
ignoreClose = true; ignoreClose = true;
return super.finish(); return super.finish();
} }
@Override @Override
public ChannelFuture close() { public ChannelFuture close() {
if(ignoreClose) { if(ignoreClose) {
ignoreClose = false; ignoreClose = false;
return null; return null;
} }
return pipeline().close(); return pipeline().close();
} }
public ChannelFuture manualClose() { public ChannelFuture manualClose() {
return pipeline().close(); return pipeline().close();
} }
} }

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,436 +19,327 @@ 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 {
private static NetworkManager networkManager; public static long lastExit = 0;
private static Minecraft mc = Minecraft.getMinecraft(); private static NetworkManager networkManager;
private static ReplaySender replaySender; private static Minecraft mc = Minecraft.getMinecraft();
private static OpenEmbeddedChannel channel; //private static ReplaySender replaySender;
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 CameraEntity cameraEntity;
private static boolean inPath = false; private static List<Keyframe> keyframes = new ArrayList<Keyframe>();
private static boolean inReplay = false;
private static CameraEntity cameraEntity; private static Entity currentEntity = null;
private static Position lastPosition = null;
private static List<Keyframe> keyframes = new ArrayList<Keyframe>();
public static void spectateEntity(Entity e) {
private static boolean inReplay = false; currentEntity = e;
mc.setRenderViewEntity(currentEntity);
public static long lastExit = 0; }
private static Entity currentEntity = null; public static void spectateCamera() {
if(currentEntity != null) {
public static void insertPacketInstantly(Packet p) { Position prev = new Position(currentEntity);
if(replaySender != null) { cameraEntity.movePath(prev);
try { }
replaySender.channelRead(null, p); currentEntity = cameraEntity;
} catch (Exception e) { mc.setRenderViewEntity(cameraEntity);
e.printStackTrace(); }
}
} public static boolean isCamera() {
} return currentEntity == cameraEntity;
public static void spectateEntity(Entity e) { }
currentEntity = e;
mc.setRenderViewEntity(currentEntity); public static void startPath(boolean save) {
} if(!ReplayHandler.isInPath()) ReplayProcess.startReplayProcess(save);
}
public static Entity getSpectatedEntity() {
return currentEntity; public static void interruptReplay() {
} ReplayProcess.stopReplayProcess(false);
}
public static void spectateCamera() {
if(currentEntity != null) { public static boolean isInPath() {
Position prev = new Position(currentEntity); return inPath;
cameraEntity.movePath(prev); }
}
currentEntity = cameraEntity; public static void setInPath(boolean replaying) {
mc.setRenderViewEntity(cameraEntity); inPath = replaying;
} }
public static boolean isCamera() { public static CameraEntity getCameraEntity() {
return currentEntity == cameraEntity; return cameraEntity;
} }
public static void setInPath(boolean replaying) { public static void setCameraEntity(CameraEntity entity) {
inPath = replaying; if(entity == null) return;
} cameraEntity = entity;
spectateCamera();
public static void resetToleratedTimestamp() { }
if(replaySender != null) replaySender.resetToleratedTimeStamp();
} public static void sortKeyframes() {
Collections.sort(keyframes, new KeyframeComparator());
public static void stopHurrying() { }
if(replaySender != null) replaySender.stopHurrying();
} public static void addKeyframe(Keyframe keyframe) {
keyframes.add(keyframe);
public static void startPath(boolean save) { selectKeyframe(keyframe);
if(!ReplayHandler.isInPath()) ReplayProcess.startReplayProcess(save); }
}
public static void removeKeyframe(Keyframe keyframe) {
public static void interruptReplay() { keyframes.remove(keyframe);
ReplayProcess.stopReplayProcess(false); if(keyframe == selectedKeyframe) {
} selectKeyframe(null);
} else {
public static boolean isInPath() { sortKeyframes();
return inPath; }
} }
public static void setCameraEntity(CameraEntity entity) { public static int getKeyframeIndex(TimeKeyframe timeKeyframe) {
if(entity == null) return; int index = 0;
cameraEntity = entity; for(Keyframe kf : keyframes) {
spectateCamera(); if(kf == timeKeyframe) return index;
} else if(kf instanceof TimeKeyframe) index++;
}
public static CameraEntity getCameraEntity() { return -1;
return cameraEntity; }
}
public static int getKeyframeIndex(PositionKeyframe posKeyframe) {
public static int getDesiredTimestamp() { int index = 0;
return replaySender == null ? 0 : (int)replaySender.getDesiredTimestamp(); for(Keyframe kf : keyframes) {
} if(kf == posKeyframe) return index;
else if(kf instanceof PositionKeyframe) index++;
public static int getReplayTime() { }
return replaySender == null ? 0 : (int)replaySender.currentTimeStamp(); return -1;
} }
public static void sortKeyframes() { public static int getPosKeyframeCount() {
Collections.sort(keyframes, new KeyframeComparator()); int size = 0;
} for(Keyframe kf : keyframes) {
if(kf instanceof PositionKeyframe) size++;
public static void addKeyframe(Keyframe keyframe) { }
keyframes.add(keyframe); return size;
selectKeyframe(keyframe); }
}
public static int getTimeKeyframeCount() {
public static void removeKeyframe(Keyframe keyframe) { int size = 0;
keyframes.remove(keyframe); for(Keyframe kf : keyframes) {
if(keyframe == selectedKeyframe) { if(kf instanceof TimeKeyframe) size++;
selectKeyframe(null); }
} else { return size;
sortKeyframes(); }
}
} public static TimeKeyframe getClosestTimeKeyframeForRealTime(int realTime, int tolerance) {
List<TimeKeyframe> found = new ArrayList<TimeKeyframe>();
public static int getKeyframeIndex(TimeKeyframe timeKeyframe) { for(Keyframe kf : keyframes) {
int index = 0; if(!(kf instanceof TimeKeyframe)) continue;
for(Keyframe kf : keyframes) { if(Math.abs(kf.getRealTimestamp() - realTime) <= tolerance) {
if(kf == timeKeyframe) return index; found.add((TimeKeyframe) kf);
else if(kf instanceof TimeKeyframe) index++; }
} }
return -1;
} TimeKeyframe closest = null;
public static int getKeyframeIndex(PositionKeyframe posKeyframe) { for(TimeKeyframe kf : found) {
int index = 0; if(closest == null || Math.abs(closest.getTimestamp() - realTime) > Math.abs(kf.getRealTimestamp() - realTime)) {
for(Keyframe kf : keyframes) { closest = kf;
if(kf == posKeyframe) return index; }
else if(kf instanceof PositionKeyframe) index++; }
} return closest;
return -1; }
}
public static PositionKeyframe getClosestPlaceKeyframeForRealTime(int realTime, int tolerance) {
public static int getPosKeyframeCount() { List<PositionKeyframe> found = new ArrayList<PositionKeyframe>();
int size = 0; for(Keyframe kf : keyframes) {
for(Keyframe kf : keyframes) { if(!(kf instanceof PositionKeyframe)) continue;
if(kf instanceof PositionKeyframe) size++; if(Math.abs(kf.getRealTimestamp() - realTime) <= tolerance) {
} found.add((PositionKeyframe) kf);
return size; }
} }
public static int getTimeKeyframeCount() { PositionKeyframe closest = null;
int size = 0;
for(Keyframe kf : keyframes) { for(PositionKeyframe kf : found) {
if(kf instanceof TimeKeyframe) size++; if(closest == null || Math.abs(closest.getRealTimestamp() - realTime) > Math.abs(kf.getRealTimestamp() - realTime)) {
} closest = kf;
return size; }
} }
return closest;
public static TimeKeyframe getClosestTimeKeyframeForRealTime(int realTime, int tolerance) { }
List<TimeKeyframe> found = new ArrayList<TimeKeyframe>();
for(Keyframe kf : keyframes) { public static PositionKeyframe getPreviousPositionKeyframe(int realTime) {
if(!(kf instanceof TimeKeyframe)) continue; if(keyframes.isEmpty()) return null;
if(Math.abs(kf.getRealTimestamp()-realTime) <= tolerance) { List<PositionKeyframe> found = new ArrayList<PositionKeyframe>();
found.add((TimeKeyframe)kf); for(Keyframe kf : keyframes) {
} if(!(kf instanceof PositionKeyframe)) continue;
} if(kf.getRealTimestamp() < realTime) {
found.add((PositionKeyframe) kf);
TimeKeyframe closest = null; }
}
for(TimeKeyframe kf : found) {
if(closest == null || Math.abs(closest.getTimestamp()-realTime) > Math.abs(kf.getRealTimestamp()-realTime)) { if(found.size() > 0)
closest = kf; return found.get(found.size() - 1); //last element is nearest
} else return null;
} }
return closest;
} public static PositionKeyframe getNextPositionKeyframe(int realTime) {
if(keyframes.isEmpty()) return null;
public static PositionKeyframe getClosestPlaceKeyframeForRealTime(int realTime, int tolerance) { for(Keyframe kf : keyframes) {
List<PositionKeyframe> found = new ArrayList<PositionKeyframe>(); if(!(kf instanceof PositionKeyframe)) continue;
for(Keyframe kf : keyframes) { if(kf.getRealTimestamp() >= realTime) {
if(!(kf instanceof PositionKeyframe)) continue; return (PositionKeyframe) kf; //first found element is next
if(Math.abs(kf.getRealTimestamp()-realTime) <= tolerance) { }
found.add((PositionKeyframe)kf); }
} return null;
} }
PositionKeyframe closest = null; public static TimeKeyframe getPreviousTimeKeyframe(int realTime) {
if(keyframes.isEmpty()) return null;
for(PositionKeyframe kf : found) { List<TimeKeyframe> found = new ArrayList<TimeKeyframe>();
if(closest == null || Math.abs(closest.getRealTimestamp()-realTime) > Math.abs(kf.getRealTimestamp()-realTime)) { for(Keyframe kf : keyframes) {
closest = kf; if(!(kf instanceof TimeKeyframe)) continue;
} if(kf.getRealTimestamp() < realTime) {
} found.add((TimeKeyframe) kf);
return closest; }
} }
public static PositionKeyframe getPreviousPositionKeyframe(int realTime) { if(found.size() > 0)
if(keyframes.isEmpty()) return null; return found.get(found.size() - 1); //last element is nearest
List<PositionKeyframe> found = new ArrayList<PositionKeyframe>(); else return null;
for(Keyframe kf : keyframes) { }
if(!(kf instanceof PositionKeyframe)) continue;
if(kf.getRealTimestamp() < realTime) { public static TimeKeyframe getNextTimeKeyframe(int realTime) {
found.add((PositionKeyframe)kf); if(keyframes.isEmpty()) return null;
} for(Keyframe kf : keyframes) {
} if(!(kf instanceof TimeKeyframe)) continue;
if(kf.getRealTimestamp() >= realTime) {
if(found.size() > 0) return (TimeKeyframe) kf; //first found element is next
return found.get(found.size()-1); //last element is nearest }
else return null; }
} return null;
}
public static PositionKeyframe getNextPositionKeyframe(int realTime) {
if(keyframes.isEmpty()) return null; public static List<Keyframe> getKeyframes() {
for(Keyframe kf : keyframes) { return new ArrayList<Keyframe>(keyframes);
if(!(kf instanceof PositionKeyframe)) continue; }
if(kf.getRealTimestamp() >= realTime) {
return (PositionKeyframe)kf; //first found element is next public static void resetKeyframes() {
} keyframes = new ArrayList<Keyframe>();
}
return null; selectKeyframe(null);
} }
public static TimeKeyframe getPreviousTimeKeyframe(int realTime) { public static boolean isSelected(Keyframe kf) {
if(keyframes.isEmpty()) return null; return kf == selectedKeyframe;
List<TimeKeyframe> found = new ArrayList<TimeKeyframe>(); }
for(Keyframe kf : keyframes) {
if(!(kf instanceof TimeKeyframe)) continue; public static void selectKeyframe(Keyframe kf) {
if(kf.getRealTimestamp() < realTime) { selectedKeyframe = kf;
found.add((TimeKeyframe)kf); sortKeyframes();
} }
}
public static boolean isInReplay() {
if(found.size() > 0) return inReplay;
return found.get(found.size()-1); //last element is nearest }
else return null;
} public static void startReplay(File file) throws NoSuchMethodException, SecurityException, NoSuchFieldException {
public static TimeKeyframe getNextTimeKeyframe(int realTime) { ReplayMod.chatMessageHandler.initialize();
if(keyframes.isEmpty()) return null; mc.ingameGUI.getChatGUI().clearChatMessages();
for(Keyframe kf : keyframes) { resetKeyframes();
if(!(kf instanceof TimeKeyframe)) continue;
if(kf.getRealTimestamp() >= realTime) { ReplayMod.replaySender.terminateReplay();
return (TimeKeyframe)kf; //first found element is next
} if(channel != null) {
} channel.close();
return null; }
}
networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND);
public static List<Keyframe> getKeyframes() { INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, (GuiScreen) null, networkManager, new GameProfile(UUID.randomUUID(), "Player"));
return new ArrayList<Keyframe>(keyframes); networkManager.setNetHandler(pc);
}
channel = new OpenEmbeddedChannel(networkManager);
public static void resetKeyframes() {
keyframes = new ArrayList<Keyframe>(); ReplayMod.replaySender = new ReplaySender(file, networkManager);
channel.pipeline().addFirst(ReplayMod.replaySender);
selectKeyframe(null); channel.pipeline().fireChannelActive();
}
try {
public static void setReplayTime(int pos) { ReplayMod.overlay.resetUI();
if(replaySender != null) { } catch(Exception e) {}
replaySender.jumpToTime(pos);
} //Load lighting and trigger update
} ReplayMod.replaySettings.setLightingEnabled(ReplayMod.replaySettings.isLightingEnabled());
public static boolean isHurrying() { inReplay = true;
if(replaySender != null) { }
return replaySender.isHurrying();
} public static void restartReplay() {
return false; mc.ingameGUI.getChatGUI().clearChatMessages();
}
if(channel != null) {
public static int getReplayLength() { channel.close();
if(replaySender != null) { }
return replaySender.replayLength();
} networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND);
INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, (GuiScreen) null, networkManager, new GameProfile(UUID.randomUUID(), "Player"));
return 1; networkManager.setNetHandler(pc);
}
EmbeddedChannel channel = new OpenEmbeddedChannel(networkManager);
public static boolean isSelected(Keyframe kf) {
return kf == selectedKeyframe; channel.pipeline().addFirst(ReplayMod.replaySender);
} channel.pipeline().fireChannelActive();
public static void selectKeyframe(Keyframe kf) { mc.addScheduledTask(new Runnable() {
selectedKeyframe = kf; @Override
sortKeyframes(); public void run() {
} try {
ReplayMod.overlay.resetUI();
public static boolean isInReplay() { } catch(Exception e) {
return inReplay; e.printStackTrace();
} }
}
public static boolean isPaused() { });
if(replaySender != null) {
return replaySender.paused(); inReplay = true;
} }
return true;
} public static void endReplay() {
if(ReplayMod.replaySender != null) {
public static void setSpeed(double d) { ReplayMod.replaySender.terminateReplay();
if(replaySender != null) { }
replaySender.setReplaySpeed(d);
} resetKeyframes();
}
public static double getSpeed() {
if(replaySender != null) {
return replaySender.getReplaySpeed();
}
return 0;
}
public static void startReplay(File file) throws NoSuchMethodException, SecurityException, NoSuchFieldException {
ChatMessageRequests.initialize();
mc.ingameGUI.getChatGUI().clearChatMessages();
resetKeyframes();
if(replaySender != null) {
replaySender.terminateReplay();
}
if(channel != null) {
channel.close();
}
networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND);
INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, (GuiScreen)null, networkManager, new GameProfile(UUID.randomUUID(), "Player"));
networkManager.setNetHandler(pc);
channel = new OpenEmbeddedChannel(networkManager);
replaySender = new ReplaySender(file, networkManager);
channel.pipeline().addFirst(replaySender);
channel.pipeline().fireChannelActive();
try {
ReplayMod.overlay.resetUI();
} catch(Exception e) {}
//Load lighting and trigger update
ReplayMod.replaySettings.setLightingEnabled(ReplayMod.replaySettings.isLightingEnabled());
inReplay = true;
}
public static void restartReplay() {
//mc.setRenderViewEntity(mc.thePlayer);
mc.ingameGUI.getChatGUI().clearChatMessages();
if(channel != null) {
channel.close();
}
networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND);
INetHandlerPlayClient pc = new NetHandlerPlayClient(mc, (GuiScreen)null, networkManager, new GameProfile(UUID.randomUUID(), "Player"));
networkManager.setNetHandler(pc);
EmbeddedChannel channel = new OpenEmbeddedChannel(networkManager);
channel.pipeline().addFirst(replaySender);
channel.pipeline().fireChannelActive();
ChannelPipeline pipeline = networkManager.channel().pipeline();
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
try {
ReplayMod.overlay.resetUI();
} catch(Exception e) {
e.printStackTrace();
}
}
});
inReplay = true;
}
public static void endReplay() {
if(replaySender != null) {
replaySender.terminateReplay();
}
resetKeyframes();
/*
if(channel != null && channel.isOpen()) {
channel.close();
}
*/
inReplay = false;
}
public static Keyframe getSelected() {
return selectedKeyframe;
}
public static int getRealTimelineCursor() {
return realTimelinePosition;
}
public static void setRealTimelineCursor(int pos) {
realTimelinePosition = pos;
}
private static Position lastPosition = null;
public static void setLastPosition(Position position) {
lastPosition = position;
}
public static Position getLastPosition() { inReplay = false;
return lastPosition; }
}
public static File getReplayFile() { public static Keyframe getSelected() {
if(replaySender != null) { return selectedKeyframe;
return replaySender.getReplayFile(); }
}
return null; public static int getRealTimelineCursor() {
} return realTimelinePosition;
}
public static void setRealTimelineCursor(int pos) {
realTimelinePosition = pos;
}
public static Position getLastPosition() {
return lastPosition;
}
public static void setLastPosition(Position position) {
lastPosition = position;
}
public static File getReplayFile() {
if(ReplayMod.replaySender != null) {
return ReplayMod.replaySender.getReplayFile();
}
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,371 +10,370 @@ 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 {
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getMinecraft();
private static long startRealTime; private static long startRealTime;
private static int lastRealReplayTime; private static int lastRealReplayTime;
private static long lastRealTime = 0; private static long lastRealTime = 0;
private static boolean linear = false; private static boolean linear = false;
private static Position lastPosition = null; private static Position lastPosition = null;
private static int lastTimestamp = -1; private static int lastTimestamp = -1;
private static SplinePoint motionSpline = null; private static SplinePoint motionSpline = null;
private static LinearPoint motionLinear = null; private static LinearPoint motionLinear = null;
private static LinearTimestamp timeLinear = null; private static LinearTimestamp timeLinear = null;
private static double lastSpeed = 1f; private static double lastSpeed = 1f;
private static double previousReplaySpeed = 0; private static double previousReplaySpeed = 0;
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;
public static boolean isVideoRecording() { private static boolean deepBlock = false;
return isVideoRecording; private static boolean requestFinish = false;
} private static float lastPartialTicks, lastRenderPartialTicks;
private static int lastTicks;
public static void startReplayProcess(boolean record) { private static boolean resetTimer = false;
ReplayHandler.selectKeyframe(null); private static boolean firstTime = false;
firstTime = true; public static boolean isVideoRecording() {
return isVideoRecording;
isVideoRecording = record; }
lastPosition = null;
motionSpline = null; public static void startReplayProcess(boolean record) {
motionLinear = null; ReplayHandler.selectKeyframe(null);
timeLinear = null;
calculated = false; firstTime = true;
requestFinish = false;
isVideoRecording = record;
ReplayHandler.resetToleratedTimestamp(); lastPosition = null;
motionSpline = null;
ChatMessageRequests.initialize(); motionLinear = null;
if(ReplayHandler.getPosKeyframeCount() < 2 && ReplayHandler.getTimeKeyframeCount() < 2) { timeLinear = null;
ChatMessageRequests.addChatMessage("At least 2 position or time keyframes required!", ChatMessageType.WARNING); calculated = false;
return; requestFinish = false;
}
ReplayMod.replaySender.resetToleratedTimeStamp();
blocked = deepBlock = false;
ReplayMod.chatMessageHandler.initialize();
startRealTime = System.currentTimeMillis(); if(ReplayHandler.getPosKeyframeCount() < 2 && ReplayHandler.getTimeKeyframeCount() < 2) {
lastRealTime = startRealTime; ReplayMod.chatMessageHandler.addChatMessage("At least 2 position or time keyframes required!", ChatMessageType.WARNING);
lastRealReplayTime = 0; return;
lastTimestamp = -1; }
lastSpeed = 1f;
linear = ReplayMod.replaySettings.isLinearMovement(); blocked = deepBlock = false;
ReplayHandler.sortKeyframes();
ReplayHandler.setInPath(true); startRealTime = System.currentTimeMillis();
previousReplaySpeed = ReplayHandler.getSpeed(); lastRealTime = startRealTime;
lastRealReplayTime = 0;
EnchantmentTimer.resetRecordingTime(); lastTimestamp = -1;
lastSpeed = 1f;
TimeKeyframe tf = ReplayHandler.getNextTimeKeyframe(-1); linear = ReplayMod.replaySettings.isLinearMovement();
if(tf != null) { ReplayHandler.sortKeyframes();
int ts = tf.getTimestamp(); ReplayHandler.setInPath(true);
if(ts < ReplayHandler.getReplayTime()) { previousReplaySpeed = ReplayMod.replaySender.getReplaySpeed();
mc.displayGuiScreen(null);
} EnchantmentTimer.resetRecordingTime();
ReplayHandler.setReplayTime(ts);
} TimeKeyframe tf = ReplayHandler.getNextTimeKeyframe(-1);
if(tf != null) {
ChatMessageRequests.addChatMessage("Replay started!", ChatMessageType.INFORMATION); int ts = tf.getTimestamp();
if(ts < ReplayMod.replaySender.currentTimeStamp()) {
if(isVideoRecording()) { mc.displayGuiScreen(null);
MCTimerHandler.setTimerSpeed(1f); }
MCTimerHandler.setPassiveTimer(); ReplayMod.replaySender.jumpToTime(ts);
} }
}
ReplayMod.chatMessageHandler.addChatMessage("Replay started!", ChatMessageType.INFORMATION);
public static void stopReplayProcess(boolean finished) {
if(!ReplayHandler.isInPath()) return; if(isVideoRecording()) {
if(finished) ChatMessageRequests.addChatMessage("Replay finished!", ChatMessageType.INFORMATION); MCTimerHandler.setTimerSpeed(1f);
else { MCTimerHandler.setPassiveTimer();
ChatMessageRequests.addChatMessage("Replay stopped!", ChatMessageType.INFORMATION); }
if(isVideoRecording()) { }
VideoWriter.abortRecording();
} public static void stopReplayProcess(boolean finished) {
} if(!ReplayHandler.isInPath()) return;
ReplayHandler.setInPath(false); if(finished) ReplayMod.chatMessageHandler.addChatMessage("Replay finished!", ChatMessageType.INFORMATION);
ReplayHandler.stopHurrying(); else {
MCTimerHandler.setActiveTimer(); ReplayMod.chatMessageHandler.addChatMessage("Replay stopped!", ChatMessageType.INFORMATION);
ReplayHandler.setSpeed(previousReplaySpeed); if(isVideoRecording()) {
ReplayHandler.setSpeed(0); VideoWriter.abortRecording();
} }
}
private static boolean blocked = false; ReplayHandler.setInPath(false);
private static boolean deepBlock = false; ReplayMod.replaySender.stopHurrying();
MCTimerHandler.setActiveTimer();
private static boolean requestFinish = false; ReplayMod.replaySender.setReplaySpeed(previousReplaySpeed);
ReplayMod.replaySender.setReplaySpeed(0);
public static void unblockAndTick(boolean justCheck) { }
if(!deepBlock) blocked = false;
if(!blocked || !isVideoRecording()) public static void unblockAndTick(boolean justCheck) {
ReplayProcess.tickReplay(justCheck); if(!deepBlock) blocked = false;
} if(!blocked || !isVideoRecording())
ReplayProcess.tickReplay(justCheck);
public static void tickReplay(boolean justCheck) { }
pathTick(isVideoRecording(), justCheck);
} public static void tickReplay(boolean justCheck) {
pathTick(isVideoRecording(), justCheck);
private static float lastPartialTicks, lastRenderPartialTicks; }
private static int lastTicks;
private static void pathTick(boolean recording, boolean justCheck) {
private static boolean resetTimer = false; if(ReplayMod.replaySender.isHurrying()) {
lastRealTime = System.currentTimeMillis();
private static boolean firstTime = false; return;
}
private static void pathTick(boolean recording, boolean justCheck) {
if(ReplayHandler.isHurrying()) { if(firstTime) {
lastRealTime = System.currentTimeMillis(); firstTime = false;
return; lastPartialTicks = 100;
} lastRenderPartialTicks = 100;
lastTicks = 100;
if(firstTime) { MCTimerHandler.setRenderPartialTicks(100);
firstTime = false; MCTimerHandler.setPartialTicks(100);
lastPartialTicks = 100; MCTimerHandler.setTicks(100);
lastRenderPartialTicks = 100; }
lastTicks = 100;
MCTimerHandler.setRenderPartialTicks(100); if(recording && ((ReplayMod.replaySettings.getWaitForChunks() && RenderChunk.renderChunksUpdated != 0) || mc.currentScreen instanceof GuiCancelRender)) {
MCTimerHandler.setPartialTicks(100); if(!firstTime) {
MCTimerHandler.setTicks(100); MCTimerHandler.setTimerSpeed(0f);
System.out.println(ReplayHandler.getReplayTime()); MCTimerHandler.setPartialTicks(0f);
} MCTimerHandler.setRenderPartialTicks(0f);
MCTimerHandler.setTicks(0);
if(recording && ((ReplayMod.replaySettings.getWaitForChunks() && RenderChunk.renderChunksUpdated != 0) || mc.currentScreen instanceof GuiCancelRender)) { resetTimer = true;
if(!firstTime) { }
MCTimerHandler.setTimerSpeed(0f); return;
MCTimerHandler.setPartialTicks(0f); } else if(recording && ReplayMod.replaySettings.getWaitForChunks()) {
MCTimerHandler.setRenderPartialTicks(0f); MCTimerHandler.setTimerSpeed((float) lastSpeed);
MCTimerHandler.setTicks(0); //MCTimerHandler.setRenderPartialTicks(lastRenderPartialTicks);
resetTimer = true; if(resetTimer) {
} MCTimerHandler.setPartialTicks(lastPartialTicks);
return; MCTimerHandler.setRenderPartialTicks(lastRenderPartialTicks);
} else if (recording && ReplayMod.replaySettings.getWaitForChunks()) { MCTimerHandler.setTicks(lastTicks);
MCTimerHandler.setTimerSpeed((float)lastSpeed); resetTimer = false;
//MCTimerHandler.setRenderPartialTicks(lastRenderPartialTicks); }
if(resetTimer) { }
MCTimerHandler.setPartialTicks(lastPartialTicks);
MCTimerHandler.setRenderPartialTicks(lastRenderPartialTicks); if(justCheck) return;
MCTimerHandler.setTicks(lastTicks);
resetTimer = false; if(recording) {
} if(blocked) return;
}
deepBlock = true;
if(justCheck) return; blocked = true;
}
if(recording) {
if(blocked) return; int posCount = ReplayHandler.getPosKeyframeCount();
int timeCount = ReplayHandler.getTimeKeyframeCount();
deepBlock = true;
blocked = true; if(!linear && motionSpline == null) {
} //set up spline path
motionSpline = new SplinePoint();
int posCount = ReplayHandler.getPosKeyframeCount(); for(Keyframe kf : ReplayHandler.getKeyframes()) {
int timeCount = ReplayHandler.getTimeKeyframeCount(); if(kf instanceof PositionKeyframe) {
PositionKeyframe pkf = (PositionKeyframe) kf;
if(!linear && motionSpline == null) { Position pos = pkf.getPosition();
//set up spline path motionSpline.addPoint(pos);
motionSpline = new SplinePoint(); }
for(Keyframe kf : ReplayHandler.getKeyframes()) { }
if(kf instanceof PositionKeyframe) { }
PositionKeyframe pkf = (PositionKeyframe)kf;
Position pos = pkf.getPosition(); if(linear && motionLinear == null) {
motionSpline.addPoint(pos); //set up linear path
} motionLinear = new LinearPoint();
} for(Keyframe kf : ReplayHandler.getKeyframes()) {
} if(kf instanceof PositionKeyframe) {
PositionKeyframe pkf = (PositionKeyframe) kf;
if(linear && motionLinear == null) { Position pos = pkf.getPosition();
//set up linear path motionLinear.addPoint(pos);
motionLinear = new LinearPoint(); }
for(Keyframe kf : ReplayHandler.getKeyframes()) { }
if(kf instanceof PositionKeyframe) { }
PositionKeyframe pkf = (PositionKeyframe)kf; if(timeLinear == null) {
Position pos = pkf.getPosition(); timeLinear = new LinearTimestamp();
motionLinear.addPoint(pos); for(Keyframe kf : ReplayHandler.getKeyframes()) {
} if(kf instanceof TimeKeyframe) {
} timeLinear.addPoint(((TimeKeyframe) kf).getTimestamp());
} }
if(timeLinear == null) { }
timeLinear = new LinearTimestamp(); }
for(Keyframe kf : ReplayHandler.getKeyframes()) {
if(kf instanceof TimeKeyframe) { if(!calculated) {
timeLinear.addPoint(((TimeKeyframe)kf).getTimestamp()); calculated = true;
} if(posCount > 1 && motionSpline != null)
} motionSpline.calcSpline();
} }
if(!calculated) { long curTime = System.currentTimeMillis();
calculated = true; long timeStep;
if(posCount > 1 && motionSpline != null) if(recording) {
motionSpline.calcSpline(); timeStep = 1000 / ReplayMod.replaySettings.getVideoFramerate();
} } else {
timeStep = curTime - lastRealTime;
long curTime = System.currentTimeMillis(); }
long timeStep;
if(recording) { int curRealReplayTime = (int) (lastRealReplayTime + timeStep);
timeStep = 1000/ReplayMod.replaySettings.getVideoFramerate();
} else { PositionKeyframe lastPos = ReplayHandler.getPreviousPositionKeyframe(curRealReplayTime);
timeStep = curTime - lastRealTime; PositionKeyframe nextPos = ReplayHandler.getNextPositionKeyframe(curRealReplayTime);
}
ReplayHandler.setRealTimelineCursor(curRealReplayTime);
int curRealReplayTime = (int)(lastRealReplayTime + timeStep);
int lastPosStamp = 0;
PositionKeyframe lastPos = ReplayHandler.getPreviousPositionKeyframe(curRealReplayTime); int nextPosStamp = 0;
PositionKeyframe nextPos = ReplayHandler.getNextPositionKeyframe(curRealReplayTime);
if(nextPos != null || lastPos != null) {
ReplayHandler.setRealTimelineCursor(curRealReplayTime); if(nextPos != null) {
nextPosStamp = nextPos.getRealTimestamp();
int lastPosStamp = 0; } else {
int nextPosStamp = 0; nextPosStamp = lastPos.getRealTimestamp();
}
if(nextPos != null || lastPos != null) {
if(nextPos != null) { if(lastPos != null) {
nextPosStamp = nextPos.getRealTimestamp(); lastPosStamp = lastPos.getRealTimestamp();
} else { } else {
nextPosStamp = lastPos.getRealTimestamp(); lastPosStamp = nextPos.getRealTimestamp();
} }
}
if(lastPos != null) {
lastPosStamp = lastPos.getRealTimestamp(); TimeKeyframe lastTime = ReplayHandler.getPreviousTimeKeyframe(curRealReplayTime);
} else { TimeKeyframe nextTime = ReplayHandler.getNextTimeKeyframe(curRealReplayTime);
lastPosStamp = nextPos.getRealTimestamp();
} int lastTimeStamp = 0;
} int nextTimeStamp = 0;
TimeKeyframe lastTime = ReplayHandler.getPreviousTimeKeyframe(curRealReplayTime); double curSpeed = 0;
TimeKeyframe nextTime = ReplayHandler.getNextTimeKeyframe(curRealReplayTime);
if(timeCount > 1 && (nextTime != null || lastTime != null)) {
int lastTimeStamp = 0;
int nextTimeStamp = 0; if(nextTime != null && lastTime != null && nextTime.getRealTimestamp() == lastTime.getRealTimestamp()) {
curSpeed = 0;
double curSpeed = 0; } else {
if(nextTime != null) {
if(timeCount > 1 && (nextTime != null || lastTime != null)) { nextTimeStamp = nextTime.getRealTimestamp();
} else {
if(nextTime != null && lastTime != null && nextTime.getRealTimestamp() == lastTime.getRealTimestamp()) { nextTimeStamp = lastTime.getRealTimestamp();
curSpeed = 0; }
} else {
if(nextTime != null) { if(lastTime != null) {
nextTimeStamp = nextTime.getRealTimestamp(); lastTimeStamp = lastTime.getRealTimestamp();
} else { } else {
nextTimeStamp = lastTime.getRealTimestamp(); lastTimeStamp = nextTime.getRealTimestamp();
} }
if(lastTime != null) { if(!(nextTime == null || lastTime == null)) {
lastTimeStamp = lastTime.getRealTimestamp(); if(lastTimeStamp == nextTimeStamp) curSpeed = 0f;
} else { else
lastTimeStamp = nextTime.getRealTimestamp(); curSpeed = ((double) ((nextTime.getTimestamp() - lastTime.getTimestamp()))) / ((double) ((nextTimeStamp - lastTimeStamp)));
} }
if(!(nextTime == null || lastTime == null)) { if(lastTimeStamp == nextTimeStamp) {
if(lastTimeStamp == nextTimeStamp) curSpeed = 0f; curSpeed = 0f;
else curSpeed = ((double)((nextTime.getTimestamp()-lastTime.getTimestamp())))/((double)((nextTimeStamp-lastTimeStamp))); }
} }
}
if(lastTimeStamp == nextTimeStamp) {
curSpeed = 0f; int currentPosDiff = nextPosStamp - lastPosStamp;
} int currentPos = curRealReplayTime - lastPosStamp;
}
} float currentPosStepPerc = (float) currentPos / (float) currentPosDiff; //The percentage of the travelled path between the current positions
if(Float.isInfinite(currentPosStepPerc)) currentPosStepPerc = 0;
int currentPosDiff = nextPosStamp - lastPosStamp;
int currentPos = curRealReplayTime - lastPosStamp; int currentTimeDiff = nextTimeStamp - lastTimeStamp;
int currentTime = curRealReplayTime - lastTimeStamp;
float currentPosStepPerc = (float)currentPos/(float)currentPosDiff; //The percentage of the travelled path between the current positions
if(Float.isInfinite(currentPosStepPerc)) currentPosStepPerc = 0; float currentTimeStepPerc = (float) currentTime / (float) currentTimeDiff; //The percentage of the travelled path between the current timestamps
if(Float.isInfinite(currentTimeStepPerc)) currentTimeStepPerc = 0;
int currentTimeDiff = nextTimeStamp - lastTimeStamp;
int currentTime = curRealReplayTime - lastTimeStamp; float splinePos = ((float) ReplayHandler.getKeyframeIndex(lastPos) + currentPosStepPerc) / (float) (posCount - 1);
float timePos = ((float) ReplayHandler.getKeyframeIndex(lastTime) + currentTimeStepPerc) / (float) (timeCount - 1);
float currentTimeStepPerc = (float)currentTime/(float)currentTimeDiff; //The percentage of the travelled path between the current timestamps
if(Float.isInfinite(currentTimeStepPerc)) currentTimeStepPerc = 0; Position pos = null;
if(posCount > 1) {
float splinePos = ((float)ReplayHandler.getKeyframeIndex(lastPos) + currentPosStepPerc)/(float)(posCount-1); if(!linear) {
float timePos = ((float)ReplayHandler.getKeyframeIndex(lastTime) + currentTimeStepPerc)/(float)(timeCount-1); pos = motionSpline.getPoint(Math.max(0, Math.min(1, splinePos)));
} else {
Position pos = null; pos = motionLinear.getPoint(Math.max(0, Math.min(1, splinePos)));
if(posCount > 1) { }
if(!linear) { } else {
pos = motionSpline.getPoint(Math.max(0, Math.min(1, splinePos))); if(posCount == 1) {
} else { pos = ReplayHandler.getNextPositionKeyframe(-1).getPosition();
pos = motionLinear.getPoint(Math.max(0, Math.min(1, splinePos))); }
} }
} else {
if(posCount == 1) { Integer curTimestamp = null;
pos = ReplayHandler.getNextPositionKeyframe(-1).getPosition(); if(timeLinear != null && timeCount > 1) {
} curTimestamp = timeLinear.getPoint(Math.max(0, Math.min(1, timePos)));
} }
Integer curTimestamp = null; if(pos != null) {
if(timeLinear != null && timeCount > 1) { ReplayHandler.getCameraEntity().movePath(pos);
curTimestamp = timeLinear.getPoint(Math.max(0, Math.min(1, timePos))); }
}
if(curSpeed > 0) {
if(pos != null) { ReplayMod.replaySender.setReplaySpeed(curSpeed);
ReplayHandler.getCameraEntity().movePath(pos); lastSpeed = curSpeed;
} }
if(curSpeed > 0) { if(recording) {
ReplayHandler.setSpeed(curSpeed); MCTimerHandler.updateTimer((1f / ReplayMod.replaySettings.getVideoFramerate()));
lastSpeed = curSpeed; EnchantmentTimer.increaseRecordingTime((1000 / ReplayMod.replaySettings.getVideoFramerate()));
} }
if(recording) { lastPartialTicks = MCTimerHandler.getPartialTicks();
MCTimerHandler.updateTimer((1f/ReplayMod.replaySettings.getVideoFramerate())); lastRenderPartialTicks = MCTimerHandler.getRenderTicks();
EnchantmentTimer.increaseRecordingTime((1000/ReplayMod.replaySettings.getVideoFramerate())); lastTicks = MCTimerHandler.getTicks();
}
if(curTimestamp != null && curTimestamp != ReplayMod.replaySender.getDesiredTimestamp())
lastPartialTicks = MCTimerHandler.getPartialTicks(); ReplayMod.replaySender.jumpToTime(curTimestamp);
lastRenderPartialTicks = MCTimerHandler.getRenderTicks();
lastTicks = MCTimerHandler.getTicks(); //splinePos = (index of last entry + add) / total entries
if(curTimestamp != null && curTimestamp != ReplayHandler.getDesiredTimestamp()) ReplayHandler.setReplayTime(curTimestamp); lastRealReplayTime = curRealReplayTime;
lastRealTime = curTime;
//splinePos = (index of last entry + add) / total entries
if(isVideoRecording()) {
lastRealReplayTime = curRealReplayTime; try {
lastRealTime = curTime; if(!VideoWriter.isRecording() && ReplayHandler.isInPath()) {
VideoWriter.startRecording(mc.displayWidth, mc.displayHeight);
if(isVideoRecording()) { } else {
try { final BufferedImage screen = ScreenCapture.captureScreen();
if(!VideoWriter.isRecording() && ReplayHandler.isInPath()) { VideoWriter.writeImage(screen);
VideoWriter.startRecording(mc.displayWidth, mc.displayHeight); }
} else { } catch(Exception e) {
final BufferedImage screen = ScreenCapture.captureScreen(); e.printStackTrace();
VideoWriter.writeImage(screen); }
} }
} catch(Exception e) {
e.printStackTrace(); if(requestFinish) {
} stopReplayProcess(true);
} requestFinish = false;
if(recording) {
if(requestFinish) { VideoWriter.endRecording();
stopReplayProcess(true); }
requestFinish = false; }
if(recording) {
VideoWriter.endRecording(); if((splinePos >= 1 || posCount <= 1) && (timePos >= 1 || timeCount <= 1)) {
} requestFinish = true;
} }
if((splinePos >= 1 || posCount <= 1) && (timePos >= 1 || timeCount <= 1)) { if(recording) {
requestFinish = true; deepBlock = false;
} }
}
if(recording) {
deepBlock = false;
}
}
} }

View File

@@ -4,25 +4,25 @@ import net.minecraft.network.play.server.S03PacketTimeUpdate;
public class TimeHandler { public class TimeHandler {
private static long actualDaytime; private static long actualDaytime;
private static long desiredDaytime; private static long desiredDaytime;
private static boolean timeOverridden = false; private static boolean timeOverridden = false;
public static boolean isTimeOverridden() { public static boolean isTimeOverridden() {
return timeOverridden; return timeOverridden;
} }
public static void setDesiredDaytime(long ddt) { public static void setTimeOverridden(boolean overridden) {
desiredDaytime = ddt; timeOverridden = overridden;
} }
public static void setTimeOverridden(boolean overridden) { public static void setDesiredDaytime(long ddt) {
timeOverridden = overridden; 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,34 +1,32 @@
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 {
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getMinecraft();
private static Predicate<EntityPlayer> playerPredicate = new Predicate<EntityPlayer>() { private static Predicate<EntityPlayer> playerPredicate = new Predicate<EntityPlayer>() {
@Override @Override
public boolean apply(EntityPlayer input) { public boolean apply(EntityPlayer input) {
if(input instanceof CameraEntity || input == mc.thePlayer) return false; if(input instanceof CameraEntity || input == mc.thePlayer) return false;
return true; return true;
} }
}; };
public static void openSpectateSelection() { public static void openSpectateSelection() {
if(!ReplayHandler.isInReplay()) { if(!ReplayHandler.isInReplay()) {
return; return;
} }
List<EntityPlayer> players = mc.theWorld.getEntities(EntityPlayer.class, playerPredicate); List<EntityPlayer> players = mc.theWorld.getEntities(EntityPlayer.class, playerPredicate);
mc.displayGuiScreen(new GuiSpectateSelection(players)); mc.displayGuiScreen(new GuiSpectateSelection(players));
} }
} }

View File

@@ -1,276 +1,291 @@
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 List<ValueEnum> getValueEnums() {
public Object getValue(); List<ValueEnum> enums = new ArrayList<ReplaySettings.ValueEnum>();
public void setValue(Object value); enums.addAll(Arrays.asList(ReplayOptions.values()));
} enums.addAll(Arrays.asList(RenderOptions.values()));
return enums;
}
public enum RecordingOptions implements ValueEnum { public void readValues() {
recordServer(true), recordSingleplayer(true), notifications(true), indicator(true); Configuration config = ReplayMod.config;
private Object value; for(RecordingOptions o : RecordingOptions.values()) {
Property p = getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "recording", false);
o.setValue(getValueObject(p));
}
public Object getValue() { for(ReplayOptions o : ReplayOptions.values()) {
return value; Property p = getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "replay", false);
} o.setValue(getValueObject(p));
}
public void setValue(Object value) { for(RenderOptions o : RenderOptions.values()) {
this.value = value; Property p = getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "render", false);
} o.setValue(getValueObject(p));
}
RecordingOptions(Object value) { for(AdvancedOptions o : AdvancedOptions.values()) {
this.value = value; Property p = getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "advanced", true);
} o.setValue(getValueObject(p));
} }
public enum ReplayOptions implements ValueEnum { config.save();
linear(false), lighting(false), useResources(true); }
private Object value; public String getRecordingPath() {
return (String) AdvancedOptions.recordingPath.getValue();
}
public Object getValue() { public String getRenderPath() {
return value; return (String) AdvancedOptions.renderPath.getValue();
} }
public void setValue(Object value) { public int getVideoFramerate() {
this.value = value; return (Integer) RenderOptions.videoFramerate.getValue();
} }
ReplayOptions(Object value) { public void setVideoFramerate(int framerate) {
this.value = value; RenderOptions.videoFramerate.setValue(Math.min(120, Math.max(10, framerate)));
} rewriteSettings();
} }
public enum RenderOptions implements ValueEnum { public double getVideoQuality() {
videoQuality(0.5f), videoFramerate(30), waitForChunks(true); return (Double) RenderOptions.videoQuality.getValue();
}
private Object value; public void setVideoQuality(double videoQuality) {
RenderOptions.videoQuality.setValue(Math.min(0.9f, Math.max(0.1f, videoQuality)));
rewriteSettings();
}
public Object getValue() { public void setEnableIndicator(boolean enable) {
return value; RecordingOptions.indicator.setValue(enable);
} rewriteSettings();
}
public void setValue(Object value) { public boolean showRecordingIndicator() {
this.value = value; return (Boolean) RecordingOptions.indicator.getValue();
} }
RenderOptions(Object value) { public boolean isEnableRecordingServer() {
this.value = value; return (Boolean) RecordingOptions.recordServer.getValue();
} }
}
public enum AdvancedOptions implements ValueEnum { public void setEnableRecordingServer(boolean enableRecordingServer) {
recordingPath("./replay_recordings/"), renderPath("./replay_videos/"); RecordingOptions.recordServer.setValue(enableRecordingServer);
rewriteSettings();
}
private Object value; public boolean isEnableRecordingSingleplayer() {
return (Boolean) RecordingOptions.recordSingleplayer.getValue();
}
public Object getValue() { public void setEnableRecordingSingleplayer(boolean enableRecordingSingleplayer) {
return value; RecordingOptions.recordSingleplayer.setValue(enableRecordingSingleplayer);
} rewriteSettings();
}
public void setValue(Object value) { public boolean isShowNotifications() {
this.value = value; return (Boolean) RecordingOptions.notifications.getValue();
} }
AdvancedOptions(Object value) { public void setShowNotifications(boolean showNotifications) {
this.value = value; RecordingOptions.notifications.setValue(showNotifications);
} rewriteSettings();
} }
public List<ValueEnum> getValueEnums() { public boolean isLinearMovement() {
List<ValueEnum> enums = new ArrayList<ReplaySettings.ValueEnum>(); return (Boolean) ReplayOptions.linear.getValue();
enums.addAll(Arrays.asList(ReplayOptions.values())); }
enums.addAll(Arrays.asList(RenderOptions.values()));
return enums;
}
public void readValues() { public void setLinearMovement(boolean linear) {
Configuration config = ReplayMod.config; ReplayOptions.linear.setValue(linear);
rewriteSettings();
}
for(RecordingOptions o : RecordingOptions.values()) { public boolean isLightingEnabled() {
Property p = getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "recording", false); return (Boolean) ReplayOptions.lighting.getValue();
o.setValue(getValueObject(p)); }
}
for(ReplayOptions o : ReplayOptions.values()) { public void setLightingEnabled(boolean enabled) {
Property p = getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "replay", false); ReplayOptions.lighting.setValue(enabled);
o.setValue(getValueObject(p)); LightingHandler.setLighting(enabled);
} rewriteSettings();
}
for(RenderOptions o : RenderOptions.values()) { public boolean getUseResourcePacks() {
Property p = getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "render", false); return (Boolean) ReplayOptions.useResources.getValue();
o.setValue(getValueObject(p)); }
}
for(AdvancedOptions o : AdvancedOptions.values()) { public void setUseResourcePacks(boolean use) {
Property p = getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "advanced", true); ReplayOptions.useResources.setValue(use);
o.setValue(getValueObject(p)); rewriteSettings();
} }
config.save(); public boolean getWaitForChunks() {
} return (Boolean) RenderOptions.waitForChunks.getValue();
}
public String getRecordingPath() { public void setWaitForChunks(boolean wait) {
return (String)AdvancedOptions.recordingPath.getValue(); RenderOptions.waitForChunks.setValue(wait);
} rewriteSettings();
public String getRenderPath() { }
return (String)AdvancedOptions.renderPath.getValue();
}
public int getVideoFramerate() { public void rewriteSettings() {
return (Integer)RenderOptions.videoFramerate.getValue(); ReplayMod.instance.config.load();
}
public void setVideoFramerate(int framerate) {
RenderOptions.videoFramerate.setValue(Math.min(120, Math.max(10, framerate)));
rewriteSettings();
}
public double getVideoQuality() {
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) {
RenderOptions.videoQuality.setValue(Math.min(0.9f, Math.max(0.1f, videoQuality)));
rewriteSettings();
}
public boolean isEnableRecordingServer() {
return (Boolean)RecordingOptions.recordServer.getValue();
}
public void setEnableRecordingServer(boolean enableRecordingServer) {
RecordingOptions.recordServer.setValue(enableRecordingServer);
rewriteSettings();
}
public boolean isEnableRecordingSingleplayer() {
return (Boolean)RecordingOptions.recordSingleplayer.getValue();
}
public void setEnableRecordingSingleplayer(boolean enableRecordingSingleplayer) {
RecordingOptions.recordSingleplayer.setValue(enableRecordingSingleplayer);
rewriteSettings();
}
public boolean isShowNotifications() {
return (Boolean)RecordingOptions.notifications.getValue();
}
public void setShowNotifications(boolean showNotifications) {
RecordingOptions.notifications.setValue(showNotifications);
rewriteSettings();
}
public boolean isLinearMovement() {
return (Boolean)ReplayOptions.linear.getValue();
}
public void setLinearMovement(boolean linear) {
ReplayOptions.linear.setValue(linear);
rewriteSettings();
}
public boolean isLightingEnabled() {
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) { for(String cat : ReplayMod.instance.config.getCategoryNames()) {
ReplayOptions.lighting.setValue(enabled); ReplayMod.instance.config.removeCategory(ReplayMod.instance.config.getCategory(cat));
LightingHandler.setLighting(enabled); }
rewriteSettings();
}
public void rewriteSettings() { for(RecordingOptions o : RecordingOptions.values()) {
ReplayMod.instance.config.load(); getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "recording", false);
}
for(String cat : ReplayMod.instance.config.getCategoryNames()) { for(ReplayOptions o : ReplayOptions.values()) {
ReplayMod.instance.config.removeCategory(ReplayMod.instance.config.getCategory(cat)); getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "replay", false);
} }
for(RecordingOptions o : RecordingOptions.values()) { for(RenderOptions o : RenderOptions.values()) {
getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "recording", false); getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "render", false);
} }
for(ReplayOptions o : ReplayOptions.values()) { for(AdvancedOptions o : AdvancedOptions.values()) {
getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "replay", false); getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "advanced", false);
} }
for(RenderOptions o : RenderOptions.values()) { ReplayMod.instance.config.save();
getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "render", false); }
}
for(AdvancedOptions o : AdvancedOptions.values()) { private Property getConfigSetting(Configuration config, String name, Object value, String category, boolean warning) {
getConfigSetting(ReplayMod.instance.config, o.name(), o.getValue(), "advanced", false); if(warning) {
} String warningMsg = "Please be careful when modifying this setting, as setting it to an invalid value might harm your computer.";
if(value instanceof Integer) {
return config.get(category, name, (Integer) value, warningMsg);
} else if(value instanceof Boolean) {
return config.get(category, name, (Boolean) value, warningMsg);
} else if(value instanceof Double) {
return config.get(category, name, (Double) value, warningMsg);
} else if(value instanceof Float) {
return config.get(category, name, (double) (Float) value, warningMsg);
} else if(value instanceof String) {
return config.get(category, name, (String) value, warningMsg);
}
} else {
if(value instanceof Integer) {
return config.get(category, name, (Integer) value);
} else if(value instanceof Boolean) {
return config.get(category, name, (Boolean) value);
} else if(value instanceof Double) {
return config.get(category, name, (Double) value);
} else if(value instanceof Float) {
return config.get(category, name, (double) (Float) value);
} else if(value instanceof String) {
return config.get(category, name, (String) value);
}
}
return null;
}
ReplayMod.instance.config.save(); private Object getValueObject(Property p) {
} if(p.isIntValue()) {
return p.getInt();
} else if(p.isDoubleValue()) {
return p.getDouble();
} else if(p.isBooleanValue()) {
return p.getBoolean();
} else {
return p.getString();
}
}
private Property getConfigSetting(Configuration config, String name, Object value, String category, boolean warning) { public enum RecordingOptions implements ValueEnum {
if(warning) { recordServer(true), recordSingleplayer(true), notifications(true), indicator(true);
String warningMsg = "Please be careful when modifying this setting, as setting it to an invalid value might harm your computer.";
if(value instanceof Integer) { private Object value;
return config.get(category, name, (Integer)value, warningMsg);
} else if(value instanceof Boolean) { RecordingOptions(Object value) {
return config.get(category, name, (Boolean)value, warningMsg); this.value = value;
} else if(value instanceof Double) { }
return config.get(category, name, (Double)value, warningMsg);
} else if(value instanceof Float) { public Object getValue() {
return config.get(category, name, (double)(Float)value, warningMsg); return value;
} else if(value instanceof String) { }
return config.get(category, name, (String)value, warningMsg);
} public void setValue(Object value) {
} else { this.value = value;
if(value instanceof Integer) { }
return config.get(category, name, (Integer)value); }
} else if(value instanceof Boolean) {
return config.get(category, name, (Boolean)value); public enum ReplayOptions implements ValueEnum {
} else if(value instanceof Double) { linear(false), lighting(false), useResources(true);
return config.get(category, name, (Double)value);
} else if(value instanceof Float) { private Object value;
return config.get(category, name, (double)(Float)value);
} else if(value instanceof String) { ReplayOptions(Object value) {
return config.get(category, name, (String)value); this.value = value;
} }
}
return null; public Object getValue() {
} return value;
private Object getValueObject(Property p) { }
if(p.isIntValue()) {
return p.getInt(); public void setValue(Object value) {
} else if(p.isDoubleValue()) { this.value = value;
return p.getDouble(); }
} else if(p.isBooleanValue()) { }
return p.getBoolean();
} else { public enum RenderOptions implements ValueEnum {
return p.getString(); 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,11 +11,17 @@ 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 {
ReplayStudio studio = new ReplayStudio(); ReplayStudio studio = new ReplayStudio();
studio.setWrappingEnabled(false); studio.setWrappingEnabled(false);
PacketStream stream = studio.createReplayStream(new FileInputStream(replayFile), isTmcpr); PacketStream stream = studio.createReplayStream(new FileInputStream(replayFile), isTmcpr);
stream.addFilter(new SquashFilter(), -1, beginning); stream.addFilter(new SquashFilter(), -1, beginning);
stream.addFilter(new RemoveFilter(), ending, -1); stream.addFilter(new RemoveFilter(), ending, -1);
@@ -52,14 +51,15 @@ 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);
} }
public static void connectReplayFiles(List<File> filesToConnect, File outputFile) { //TODO Work with Johni to connect multiple Replay Files
public static void connectReplayFiles(List<File> filesToConnect, File outputFile) {
} }
} }

View File

@@ -2,19 +2,19 @@ package eu.crushedpixel.replaymod.studio;
public class VersionValidator { public class VersionValidator {
public static final boolean isValid; public static final boolean isValid;
static { static {
String version = Runtime.class.getPackage().getSpecificationVersion(); String version = Runtime.class.getPackage().getSpecificationVersion();
if(version != null) { if(version != null) {
String[] split = version.split("\\."); String[] split = version.split("\\.");
if(split.length > 1) { if(split.length > 1) {
isValid = Integer.valueOf(split[1]) >= 7; isValid = Integer.valueOf(split[1]) >= 7;
} else { } else {
isValid = false; isValid = false;
} }
} else { } else {
isValid = false; isValid = false;
} }
} }
} }

View File

@@ -1,35 +1,36 @@
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;
public class EnchantmentTimer { public class EnchantmentTimer {
private static long lastRealTime = System.currentTimeMillis(); private static long lastRealTime = System.currentTimeMillis();
private static long lastFakeTime = System.currentTimeMillis(); private static long lastFakeTime = System.currentTimeMillis();
private static long recordingTime = 0; private static long recordingTime = 0;
public static void resetRecordingTime() { public static void resetRecordingTime() {
recordingTime = 0; recordingTime = 0;
} }
public static void increaseRecordingTime(long amount) { public static void increaseRecordingTime(long amount) {
recordingTime += amount; recordingTime += amount;
} }
public static long getEnchantmentTime() { public static long getEnchantmentTime() {
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;
} }
lastFakeTime = lastRealTime = System.currentTimeMillis(); lastFakeTime = lastRealTime = System.currentTimeMillis();
return lastRealTime; return lastRealTime;
} }
return recordingTime; return recordingTime;
} }
} }

View File

@@ -1,175 +1,172 @@
package eu.crushedpixel.replaymod.timer; package eu.crushedpixel.replaymod.timer;
import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.video.ReplayTimer;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Timer;
import java.lang.reflect.Field; 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.replay.ReplayHandler;
import eu.crushedpixel.replaymod.video.ReplayTimer;
public class MCTimerHandler { public class MCTimerHandler {
private static Field mcTimer; private static Field mcTimer;
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getMinecraft();
private static ReplayTimer rpt = new ReplayTimer(20); private static ReplayTimer rpt = new ReplayTimer(20);
private static Timer timerBefore; private static Timer timerBefore;
static { static {
try { try {
mcTimer = Minecraft.class.getDeclaredField(MCPNames.field("field_71428_T")); mcTimer = Minecraft.class.getDeclaredField(MCPNames.field("field_71428_T"));
mcTimer.setAccessible(true); mcTimer.setAccessible(true);
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void setActiveTimer() { public static void setActiveTimer() {
try { try {
if(timerBefore != null) { if(timerBefore != null) {
mcTimer.set(mc, timerBefore); mcTimer.set(mc, timerBefore);
} }
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void setPassiveTimer() { public static void setPassiveTimer() {
try { try {
if(!(getTimer() instanceof ReplayTimer)) { if(!(getTimer() instanceof ReplayTimer)) {
timerBefore = getTimer(); timerBefore = getTimer();
mcTimer.set(mc, rpt); mcTimer.set(mc, rpt);
} }
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static int getTicks() { public static int getTicks() {
try { try {
Timer t = getTimer(); Timer t = getTimer();
return t.elapsedTicks; return t.elapsedTicks;
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return 0; return 0;
} }
public static float getPartialTicks() { public static void setTicks(int ticks) {
try { try {
Timer t = getTimer(); getTimer().elapsedTicks = ticks;
return t.elapsedPartialTicks; } catch(Exception e) {
} catch(Exception e) { e.printStackTrace();
e.printStackTrace(); }
} }
return 0;
}
public static float getRenderTicks() { public static float getPartialTicks() {
try { try {
Timer t = getTimer(); Timer t = getTimer();
return t.renderPartialTicks; return t.elapsedPartialTicks;
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return 0; return 0;
} }
private static Timer getTimer() throws IllegalArgumentException, IllegalAccessException { public static void setPartialTicks(float ticks) {
return (Timer)mcTimer.get(mc); try {
} getTimer().elapsedPartialTicks = ticks;
} catch(Exception e) {
e.printStackTrace();
}
}
public static void advanceTicks(int ticks) { public static float getRenderTicks() {
try { try {
Timer t = getTimer(); Timer t = getTimer();
t.elapsedTicks += ticks; return t.renderPartialTicks;
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} return 0;
}
public static void advancePartialTicks(float ticks) { private static Timer getTimer() throws IllegalArgumentException, IllegalAccessException {
try { return (Timer) mcTimer.get(mc);
Timer t = getTimer(); }
t.elapsedPartialTicks += ticks;
} catch(Exception e) {
e.printStackTrace();
}
}
public static void advanceRenderPartialTicks(float ticks) { public static void advanceTicks(int ticks) {
try { try {
Timer t = getTimer(); Timer t = getTimer();
t.renderPartialTicks += ticks; t.elapsedTicks += ticks;
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void setTimerSpeed(float speed) { public static void advancePartialTicks(float ticks) {
try { try {
Timer t = getTimer(); Timer t = getTimer();
t.timerSpeed = speed; t.elapsedPartialTicks += ticks;
if(timerBefore != null) { } catch(Exception e) {
timerBefore.timerSpeed = speed; e.printStackTrace();
} }
} catch(Exception e) { }
e.printStackTrace();
}
}
public static void setRenderPartialTicks(float ticks) { public static void advanceRenderPartialTicks(float ticks) {
try { try {
getTimer().renderPartialTicks = ticks; Timer t = getTimer();
} catch(Exception e) { t.renderPartialTicks += ticks;
e.printStackTrace(); } catch(Exception e) {
} e.printStackTrace();
} }
}
public static void setPartialTicks(float ticks) { public static void setRenderPartialTicks(float ticks) {
try { try {
getTimer().elapsedPartialTicks = ticks; getTimer().renderPartialTicks = ticks;
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void setTicks(int ticks) { public static float getTimerSpeed() {
try { try {
getTimer().elapsedTicks = ticks; return getTimer().timerSpeed;
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} return 1;
}
public static float getTimerSpeed() { public static void setTimerSpeed(float speed) {
try { try {
return getTimer().timerSpeed; Timer t = getTimer();
} catch(Exception e) { t.timerSpeed = speed;
e.printStackTrace(); if(timerBefore != null) {
} timerBefore.timerSpeed = speed;
return 1; }
} } 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; }
}
t.renderPartialTicks = t.elapsedPartialTicks; t.renderPartialTicks = t.elapsedPartialTicks;
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@@ -1,69 +1,73 @@
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 {
public static BufferedImage scaleImage(BufferedImage img, Dimension d) { public static BufferedImage scaleImage(BufferedImage img, Dimension d) {
img = scaleByHalf(img, d); img = scaleByHalf(img, d);
img = scaleExact(img, d); img = scaleExact(img, d);
return img; return img;
} }
private static BufferedImage scaleByHalf(BufferedImage img, Dimension d) { private static BufferedImage scaleByHalf(BufferedImage img, Dimension d) {
int w = img.getWidth(); int w = img.getWidth();
int h = img.getHeight(); int h = img.getHeight();
float factor = getBinFactor(w, h, d); float factor = getBinFactor(w, h, d);
// make new size // make new size
w *= factor; w *= factor;
h *= factor; h *= factor;
BufferedImage scaled = new BufferedImage(w, h, BufferedImage scaled = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB); BufferedImage.TYPE_INT_RGB);
Graphics2D g = scaled.createGraphics(); Graphics2D g = scaled.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g.drawImage(img, 0, 0, w, h, null); g.drawImage(img, 0, 0, w, h, null);
g.dispose(); g.dispose();
return scaled; return scaled;
} }
private static BufferedImage scaleExact(BufferedImage img, Dimension d) { private static BufferedImage scaleExact(BufferedImage img, Dimension d) {
float factor = getFactor(img.getWidth(), img.getHeight(), d); float factor = getFactor(img.getWidth(), img.getHeight(), d);
// create the image // create the image
int w = (int) (img.getWidth() * factor); int w = (int) (img.getWidth() * factor);
int h = (int) (img.getHeight() * factor); int h = (int) (img.getHeight() * factor);
BufferedImage scaled = new BufferedImage(w, h, BufferedImage scaled = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB); BufferedImage.TYPE_INT_RGB);
Graphics2D g = scaled.createGraphics(); Graphics2D g = scaled.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR); RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, w, h, null); g.drawImage(img, 0, 0, w, h, null);
g.dispose(); g.dispose();
return scaled; return scaled;
} }
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) {
return factor; factor /= 2;
} }
} else {
while(factor * 2 < target) {
factor *= 2;
}
}
return factor;
}
static float getFactor(int width, int height, Dimension dim) { static float getFactor(int width, int height, Dimension dim) {
float sx = dim.width / (float) width; float sx = dim.width / (float) width;
float sy = dim.height / (float) height; float sy = dim.height / (float) height;
return Math.min(sx, sy); return Math.min(sx, sy);
} }
public static BufferedImage cropImage(BufferedImage src, Rectangle rect) { public static BufferedImage cropImage(BufferedImage src, Rectangle rect) {
return src.getSubimage(rect.x, rect.y, rect.width, rect.height); return src.getSubimage(rect.x, rect.y, rect.width, rect.height);
} }
} }

Some files were not shown because too many files have changed in this diff Show More