Remove lots of old code

Add some additional config settings
Update jGui and ReplayStudio
This commit is contained in:
johni0702
2016-08-14 19:59:32 +02:00
parent e8df61aeb2
commit edf57490a6
120 changed files with 210 additions and 9182 deletions

View File

@@ -0,0 +1,68 @@
package com.replaymod.core;
import net.minecraftforge.fml.relauncher.CoreModManager;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
import org.apache.logging.log4j.LogManager;
import org.spongepowered.asm.launch.MixinBootstrap;
import org.spongepowered.asm.mixin.MixinEnvironment;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.CodeSource;
import java.util.Map;
public class LoadingPlugin implements IFMLLoadingPlugin {
public LoadingPlugin() {
MixinBootstrap.init();
MixinEnvironment.getDefaultEnvironment().addConfiguration("mixins.replaymod.json");
MixinEnvironment.getDefaultEnvironment().addConfiguration("mixins.recording.replaymod.json");
MixinEnvironment.getDefaultEnvironment().addConfiguration("mixins.render.replaymod.json");
MixinEnvironment.getDefaultEnvironment().addConfiguration("mixins.replay.replaymod.json");
CodeSource codeSource = getClass().getProtectionDomain().getCodeSource();
if (codeSource != null) {
URL location = codeSource.getLocation();
try {
File file = new File(location.toURI());
if (file.isFile()) {
// This forces forge to reexamine the jar file for FML mods
// Should eventually be handled by Mixin itself, maybe?
CoreModManager.getLoadedCoremods().remove(file.getName());
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
} else {
LogManager.getLogger().warn("No CodeSource, if this is not a development environment we might run into problems!");
LogManager.getLogger().warn(getClass().getProtectionDomain());
}
}
@Override
public String[] getASMTransformerClass() {
return new String[]{
};
}
@Override
public String getModContainerClass() {
return null;
}
@Override
public String getSetupClass() {
return null;
}
@Override
public void injectData(Map<String, Object> data) {
}
@Override
public String getAccessTransformerClass() {
return null;
}
}

View File

@@ -4,20 +4,10 @@ import com.google.common.io.Files;
import com.google.common.util.concurrent.ListenableFutureTask;
import com.replaymod.core.gui.RestoreReplayGui;
import com.replaymod.core.handler.MainMenuHandler;
import com.replaymod.replay.ReplaySender;
import com.replaymod.replaystudio.util.I18n;
import de.johni0702.minecraft.gui.container.GuiScreen;
import eu.crushedpixel.replaymod.chat.ChatMessageHandler;
import eu.crushedpixel.replaymod.events.handlers.MouseInputHandler;
import eu.crushedpixel.replaymod.events.handlers.TickAndRenderListener;
import eu.crushedpixel.replaymod.events.handlers.keyboard.KeyInputHandler;
import eu.crushedpixel.replaymod.registry.KeybindRegistry;
import eu.crushedpixel.replaymod.registry.ReplayFileAppender;
import eu.crushedpixel.replaymod.registry.UploadedFileHandler;
import eu.crushedpixel.replaymod.renderer.CustomObjectRenderer;
import eu.crushedpixel.replaymod.settings.ReplaySettings;
import eu.crushedpixel.replaymod.sound.SoundHandler;
import eu.crushedpixel.replaymod.utils.OpenGLUtils;
import com.replaymod.render.utils.SoundHandler;
import com.replaymod.core.utils.OpenGLUtils;
import eu.crushedpixel.replaymod.utils.TooltipRenderer;
import lombok.Getter;
import net.minecraft.client.Minecraft;
@@ -25,7 +15,6 @@ import net.minecraft.client.settings.GameSettings;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.util.*;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.FMLCommonHandler;
@@ -74,31 +63,11 @@ public class ReplayMod {
private static final Minecraft mc = Minecraft.getMinecraft();
@Deprecated
public static ReplaySettings replaySettings;
@Deprecated
public static Configuration config;
@Deprecated
public static boolean firstMainMenu = true;
@Deprecated
public static ChatMessageHandler chatMessageHandler = new ChatMessageHandler();
@Deprecated
public static KeyInputHandler keyInputHandler = new KeyInputHandler();
@Deprecated
public static MouseInputHandler mouseInputHandler = new MouseInputHandler();
@Deprecated
public static ReplaySender replaySender;
@Deprecated
public static int TP_DISTANCE_LIMIT = 128;
@Deprecated
public static ReplayFileAppender replayFileAppender;
@Deprecated
public static UploadedFileHandler uploadedFileHandler;
@Deprecated
public static TooltipRenderer tooltipRenderer;
@Deprecated
public static CustomObjectRenderer customObjectRenderer;
@Deprecated
public static SoundHandler soundHandler = new SoundHandler();
private final KeyBindingRegistry keyBindingRegistry = new KeyBindingRegistry();
@@ -117,7 +86,7 @@ public class ReplayMod {
}
public File getReplayFolder() throws IOException {
File folder = new File(replaySettings.getRecordingPath());
File folder = new File(getSettingsRegistry().get(Setting.RECORDING_PATH));
FileUtils.forceMkdir(folder);
return folder;
}
@@ -133,23 +102,15 @@ public class ReplayMod {
config = new Configuration(event.getSuggestedConfigurationFile());
config.load();
settingsRegistry.setConfiguration(config);
uploadedFileHandler = new UploadedFileHandler(event.getModConfigurationDirectory());
replaySettings = new ReplaySettings();
replayFileAppender = new ReplayFileAppender();
FMLCommonHandler.instance().bus().register(replayFileAppender);
}
@EventHandler
public void init(FMLInitializationEvent event) {
getSettingsRegistry().register(Setting.class);
new MainMenuHandler().register();
FMLCommonHandler.instance().bus().register(keyInputHandler);
FMLCommonHandler.instance().bus().register(keyBindingRegistry);
FMLCommonHandler.instance().bus().register(mouseInputHandler);
MinecraftForge.EVENT_BUS.register(mouseInputHandler);
}
@EventHandler
@@ -159,16 +120,6 @@ public class ReplayMod {
if(!FMLClientHandler.instance().hasOptifine())
GameSettings.Options.RENDER_DISTANCE.setValueMax(64f);
TickAndRenderListener tarl = new TickAndRenderListener();
FMLCommonHandler.instance().bus().register(tarl);
MinecraftForge.EVENT_BUS.register(tarl);
customObjectRenderer = new CustomObjectRenderer();
FMLCommonHandler.instance().bus().register(customObjectRenderer);
MinecraftForge.EVENT_BUS.register(customObjectRenderer);
KeybindRegistry.initialize();
tooltipRenderer = new TooltipRenderer();
if (System.getProperty("replaymod.render.file") != null) {
@@ -360,7 +311,7 @@ public class ReplayMod {
}
private void printToChat(boolean warning, String message, Object... args) {
if (ReplayMod.replaySettings.isShowNotifications()) {
if (getSettingsRegistry().get(Setting.NOTIFICATIONS)) {
// Some nostalgia: "§8[§6Replay Mod§8]§r Your message goes here"
ChatStyle coloredDarkGray = new ChatStyle().setColor(EnumChatFormatting.DARK_GRAY);
ChatStyle coloredGold = new ChatStyle().setColor(EnumChatFormatting.GOLD);

View File

@@ -0,0 +1,18 @@
package com.replaymod.core;
public final class Setting<T> extends SettingsRegistry.SettingKeys<T> {
public static final Setting<Boolean> NOTIFICATIONS = make("notifications", "notifications", true);
public static final Setting<String> RECORDING_PATH = advanced("recordingPath", null, "./replay_recordings/");
private static <T> Setting<T> make(String key, String displayName, T defaultValue) {
return new Setting<>("core", key, displayName, defaultValue);
}
private static <T> Setting<T> advanced(String key, String displayName, T defaultValue) {
return new Setting<>("advanced", key, displayName, defaultValue);
}
public Setting(String category, String key, String displayString, T defaultValue) {
super(category, key, displayString == null ? null : "replaymod.gui.settings." + displayString, defaultValue);
}
}

View File

@@ -0,0 +1,49 @@
package com.replaymod.core.utils;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import java.nio.IntBuffer;
public class OpenGLUtils {
public static final int VIEWPORT_MAX_WIDTH;
public static final int VIEWPORT_MAX_HEIGHT;
static {
IntBuffer buffer = BufferUtils.createIntBuffer(16);
GL11.glGetInteger(GL11.GL_MAX_VIEWPORT_DIMS, buffer);
VIEWPORT_MAX_WIDTH = buffer.get();
VIEWPORT_MAX_HEIGHT = buffer.get();
}
/**
* Magic init method which has to be called from the OpenGL thread so the variables in this class
* can be initialized successfully.
* Does not perform any work on its own.
*/
public static void init() {
}
public static void drawRotatedRectWithCustomSizedTexture(int x, int y, float rotation, float u, float v, int width, int height, float textureWidth, float textureHeight) {
GlStateManager.pushMatrix();
float f4 = 1.0F / textureWidth;
float f5 = 1.0F / textureHeight;
Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldrenderer = tessellator.getWorldRenderer();
GlStateManager.translate(x+(width/2), y+(width/2), 0);
GlStateManager.rotate(rotation, 0, 0, 1);
worldrenderer.startDrawingQuads();
worldrenderer.addVertexWithUV(-width / 2, height / 2, 0.0D, (double) (u * f4), (double) ((v + (float) height) * f5));
worldrenderer.addVertexWithUV(width/2, height/2, 0.0D, (double)((u + (float)width) * f4), (double)((v + (float)height) * f5));
worldrenderer.addVertexWithUV(width/2, -height/2, 0.0D, (double)((u + (float)width) * f4), (double)(v * f5));
worldrenderer.addVertexWithUV(-width/2, -height/2, 0.0D, (double)(u * f4), (double)(v * f5));
tessellator.draw();
GlStateManager.popMatrix();
}
}

View File

@@ -0,0 +1,9 @@
package com.replaymod.core.utils;
import java.util.regex.Pattern;
public class Patterns {
public static final Pattern ALPHANUMERIC_UNDERSCORE = Pattern.compile("^[a-z0-9_]*$", Pattern.CASE_INSENSITIVE);
public static final Pattern ALPHANUMERIC_COMMA = Pattern.compile("^[a-z0-9,]*$", Pattern.CASE_INSENSITIVE);
public static final Pattern ALPHANUMERIC_SPACE_HYPHEN_UNDERSCORE = Pattern.compile("^[a-z0-9 \\-_]*$", Pattern.CASE_INSENSITIVE);
}

View File

@@ -0,0 +1,74 @@
package com.replaymod.core.utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.client.resources.DefaultPlayerSkin;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.ReadableDimension;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.UUID;
public class Utils {
public static final BufferedImage DEFAULT_THUMBNAIL;
static {
BufferedImage thumbnail;
try {
thumbnail = ImageIO.read(Utils.class.getClassLoader().getResourceAsStream("default_thumb.jpg"));
} catch (Exception e) {
thumbnail = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR);
e.printStackTrace();
}
DEFAULT_THUMBNAIL = thumbnail;
}
public static String convertSecondsToShortString(int seconds) {
int hours = seconds/(60*60);
int min = seconds/60 - hours*60;
int sec = seconds - ((min*60) + (hours*60*60));
StringBuilder builder = new StringBuilder();
if(hours > 0) builder.append(String.format("%02d", hours)).append(":");
builder.append(String.format("%02d", min)).append(":");
builder.append(String.format("%02d", sec));
return builder.toString();
}
public static Dimension fitIntoBounds(ReadableDimension toFit, ReadableDimension bounds) {
int width = toFit.getWidth();
int height = toFit.getHeight();
float w = (float) width / bounds.getWidth();
float h = (float) height / bounds.getHeight();
if (w > h) {
height = (int) (height / w);
width = (int) (width / w);
} else {
height = (int) (height / h);
width = (int) (width / h);
}
return new Dimension(width, height);
}
public static boolean isValidEmailAddress(String mail) {
return mail.matches("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$");
}
public static ResourceLocation getResourceLocationForPlayerUUID(UUID uuid) {
NetworkPlayerInfo info = Minecraft.getMinecraft().getNetHandler().getPlayerInfo(uuid);
ResourceLocation skinLocation;
if (info != null && info.hasLocationSkin()) {
skinLocation = info.getLocationSkin();
} else {
skinLocation = DefaultPlayerSkin.getDefaultSkin(uuid);
}
return skinLocation;
}
}

View File

@@ -1,5 +1,6 @@
package com.replaymod.extras.playeroverview;
import com.replaymod.core.utils.Utils;
import com.replaymod.replay.ReplayModReplay;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
@@ -12,7 +13,6 @@ import de.johni0702.minecraft.gui.function.Closeable;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.utils.Colors;
import eu.crushedpixel.replaymod.utils.SkinProvider;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EnumPlayerModelParts;
@@ -83,7 +83,7 @@ public class PlayerOverviewGui extends GuiScreen implements Closeable {
Collections.sort(players, new PlayerComparator()); // Sort by name, spectators last
for (final EntityPlayer p : players) {
final ResourceLocation texture = SkinProvider.getResourceLocationForPlayerUUID(p.getUniqueID());
final ResourceLocation texture = Utils.getResourceLocationForPlayerUUID(p.getUniqueID());
final GuiClickable panel = new GuiClickable().setLayout(new HorizontalLayout().setSpacing(2)).addElements(
new HorizontalLayout.Data(0.5), new GuiImage() {
@Override

View File

@@ -11,7 +11,6 @@ import com.replaymod.online.api.replay.SearchQuery;
import com.replaymod.online.api.replay.holders.*;
import eu.crushedpixel.replaymod.gui.elements.listeners.ProgressUpdateListener;
import com.replaymod.online.AuthenticationHash;
import eu.crushedpixel.replaymod.utils.Api;
import net.minecraft.client.Minecraft;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
@@ -222,7 +221,6 @@ public class ApiClient {
return invokeAndReturn(builder, Favorites.class).getFavorited();
}
@Api
public void removeFile(int file) throws IOException, ApiException {
QueryBuilder builder = new QueryBuilder(ReplayModApiMethods.remove_file);
builder.put("auth", authData.getAuthKey());

View File

@@ -26,7 +26,7 @@ public class GuiLoginPrompt extends AbstractGuiScreen<GuiLoginPrompt> {
private GuiButton registerButton = new GuiButton(this).setI18nLabel("replaymod.gui.register").setSize(150, 20);
private GuiTextField username = new GuiTextField(this).setSize(145, 20).setMaxLength(16).setFocused(true);
private GuiPasswordField password = new GuiPasswordField(this).setSize(145, 20)
.setMaxLength(GuiConstants.MAX_PW_LENGTH);
.setMaxLength(GuiRegister.MAX_PW_LENGTH);
{
Utils.link(username, password);

View File

@@ -11,14 +11,15 @@ import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.layout.VerticalLayout;
import de.johni0702.minecraft.gui.utils.Consumers;
import de.johni0702.minecraft.gui.utils.Utils;
import eu.crushedpixel.replaymod.gui.GuiConstants;
import eu.crushedpixel.replaymod.utils.EmailAddressUtils;
import eu.crushedpixel.replaymod.utils.RegexUtils;
import com.replaymod.core.utils.Patterns;
import net.minecraft.client.gui.FontRenderer;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.ReadableColor;
public class GuiRegister extends AbstractGuiScreen<GuiRegister> {
public static final int MIN_PW_LENGTH = 5;
public static final int MAX_PW_LENGTH = 1024;
private final GuiPanel inputs;
private final GuiTextField usernameInput, mailInput;
private final GuiPasswordField passwordInput, passwordConfirmation;
@@ -39,10 +40,10 @@ public class GuiRegister extends AbstractGuiScreen<GuiRegister> {
.addElements(data, mailInput = new GuiTextField().setSize(145, 20)),
new GuiPanel().setLayout(new HorizontalLayout(HorizontalLayout.Alignment.RIGHT).setSpacing(10))
.addElements(data, new GuiLabel().setI18nText("replaymod.gui.password"))
.addElements(data, passwordInput = new GuiPasswordField().setMaxLength(GuiConstants.MAX_PW_LENGTH+1).setSize(145, 20)),
.addElements(data, passwordInput = new GuiPasswordField().setMaxLength(MAX_PW_LENGTH+1).setSize(145, 20)),
new GuiPanel().setLayout(new HorizontalLayout(HorizontalLayout.Alignment.RIGHT).setSpacing(10))
.addElements(data, new GuiLabel().setI18nText("replaymod.gui.register.confirmpw"))
.addElements(data, passwordConfirmation = new GuiPasswordField().setMaxLength(GuiConstants.MAX_PW_LENGTH+1).setSize(145, 20))
.addElements(data, passwordConfirmation = new GuiPasswordField().setMaxLength(MAX_PW_LENGTH+1).setSize(145, 20))
);
Utils.link(usernameInput, mailInput, passwordInput, passwordConfirmation);
@@ -111,13 +112,13 @@ public class GuiRegister extends AbstractGuiScreen<GuiRegister> {
String status = null;
if (usernameInput.getText().length() < 5) {
status = "replaymod.gui.register.error.shortusername";
} else if(!RegexUtils.isValid(RegexUtils.ALPHANUMERIC_UNDERSCORE, usernameInput.getText().trim())) {
} else if(!Patterns.ALPHANUMERIC_UNDERSCORE.matcher(usernameInput.getText().trim()).matches()) {
status = "replaymod.gui.register.error.invalidname";
} else if (passwordInput.getText().length() < GuiConstants.MIN_PW_LENGTH) {
} else if (passwordInput.getText().length() < MIN_PW_LENGTH) {
status = "replaymod.gui.register.error.shortpw";
} else if (passwordInput.getText().length() > GuiConstants.MAX_PW_LENGTH) {
} else if (passwordInput.getText().length() > MAX_PW_LENGTH) {
status = "replaymod.gui.register.error.longpw";
} else if (!EmailAddressUtils.isValidEmailAddress(mailInput.getText())) {
} else if (!com.replaymod.core.utils.Utils.isValidEmailAddress(mailInput.getText())) {
status = "replaymod.api.invalidmail";
} else if (!passwordConfirmation.getText().equals(passwordInput.getText())) {
status = "replaymod.gui.register.error.nomatch";

View File

@@ -6,6 +6,7 @@ import com.google.common.primitives.Ints;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.mojang.realmsclient.gui.ChatFormatting;
import com.replaymod.core.utils.Utils;
import com.replaymod.online.ReplayModOnline;
import com.replaymod.online.api.ApiClient;
import com.replaymod.online.api.ApiException;
@@ -18,6 +19,7 @@ import com.replaymod.online.api.replay.pagination.DownloadedFilePagination;
import com.replaymod.online.api.replay.pagination.FavoritedFilePagination;
import com.replaymod.online.api.replay.pagination.Pagination;
import com.replaymod.online.api.replay.pagination.SearchPagination;
import com.replaymod.replaystudio.replay.ReplayMetaData;
import de.johni0702.minecraft.gui.container.AbstractGuiContainer;
import de.johni0702.minecraft.gui.container.GuiContainer;
import de.johni0702.minecraft.gui.container.GuiPanel;
@@ -33,9 +35,6 @@ import de.johni0702.minecraft.gui.layout.VerticalLayout;
import de.johni0702.minecraft.gui.popup.GuiYesNoPopup;
import de.johni0702.minecraft.gui.utils.Colors;
import de.johni0702.minecraft.gui.utils.Consumer;
import com.replaymod.replaystudio.replay.ReplayMetaData;
import eu.crushedpixel.replaymod.registry.ResourceHelper;
import eu.crushedpixel.replaymod.utils.DurationUtils;
import net.minecraftforge.fml.common.FMLLog;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.core.helpers.Strings;
@@ -333,7 +332,7 @@ public class GuiReplayCenter extends GuiScreen {
return this;
}
private final GuiImage defaultThumbnail = new GuiImage().setTexture(ResourceHelper.getDefaultThumbnail());
private final GuiImage defaultThumbnail = new GuiImage().setTexture(Utils.DEFAULT_THUMBNAIL);
public class GuiReplayEntry extends AbstractGuiContainer<GuiReplayEntry> implements Comparable<GuiReplayEntry> {
public final FileInfo fileInfo;
public final GuiLabel name = new GuiLabel();
@@ -414,7 +413,7 @@ public class GuiReplayCenter extends GuiScreen {
thumbnail = new GuiImage(this).setTexture(thumbImage);
}
thumbnail.setSize(45 * 16 / 9, 45);
duration.setText(DurationUtils.convertSecondsToShortString(metaData.getDuration() / 1000));
duration.setText(Utils.convertSecondsToShortString(metaData.getDuration() / 1000));
downloads.setText(fileInfo.getDownloads() + "");
favorites.setText("" + fileInfo.getFavorites());
likes.setText("" + fileInfo.getRatings().getPositive());

View File

@@ -2,6 +2,7 @@ package com.replaymod.online.gui;
import com.google.common.base.Optional;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.utils.Utils;
import com.replaymod.online.api.ApiClient;
import com.replaymod.replay.gui.screen.GuiReplayViewer;
import com.replaymod.replaystudio.replay.ReplayFile;
@@ -13,10 +14,8 @@ import com.replaymod.online.api.replay.holders.Category;
import eu.crushedpixel.replaymod.gui.GuiConstants;
import eu.crushedpixel.replaymod.gui.elements.*;
import eu.crushedpixel.replaymod.gui.elements.listeners.ProgressUpdateListener;
import eu.crushedpixel.replaymod.registry.ResourceHelper;
import eu.crushedpixel.replaymod.utils.ImageUtils;
import eu.crushedpixel.replaymod.utils.MouseUtils;
import eu.crushedpixel.replaymod.utils.RegexUtils;
import com.replaymod.core.utils.Patterns;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiButton;
@@ -34,7 +33,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.input.Keyboard;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
@@ -99,7 +97,7 @@ public class GuiUploadFile extends GuiScreen implements ProgressUpdateListener {
metaData = archive.getMetaData();
Optional<BufferedImage> img = archive.getThumb();
if(img.isPresent()) {
thumb = ImageUtils.scaleImage(img.get(), new Dimension(1280, 720));
thumb = img.get();
hasThumbnail = true;
}
@@ -125,11 +123,7 @@ public class GuiUploadFile extends GuiScreen implements ProgressUpdateListener {
//If thumb is null, set image to placeholder
if(thumb == null) {
try {
thumb = ImageIO.read(GuiUploadFile.class.getClassLoader().getResourceAsStream("default_thumb.jpg"));
} catch(Exception e) {
e.printStackTrace();
}
thumb = Utils.DEFAULT_THUMBNAIL;
}
}
@@ -321,8 +315,6 @@ public class GuiUploadFile extends GuiScreen implements ProgressUpdateListener {
} else {
uploader.uploadFile(GuiUploadFile.this, name, tags, replayFile, category, desc);
}
ReplayMod.uploadedFileHandler.markAsUploaded(replayFile);
} catch(Exception e) {
messageTextField.setText(I18n.format("replaymod.gui.unknownerror"));
messageTextField.setTextColor(Color.RED.getRGB());
@@ -347,7 +339,6 @@ public class GuiUploadFile extends GuiScreen implements ProgressUpdateListener {
dynTex = new DynamicTexture(thumb);
mc.getTextureManager().loadTexture(textureResource, dynTex);
dynTex.updateDynamicTexture();
ResourceHelper.registerResource(textureResource);
}
mc.getTextureManager().bindTexture(textureResource); //Will be freed by the ResourceHelper
@@ -388,7 +379,7 @@ public class GuiUploadFile extends GuiScreen implements ProgressUpdateListener {
@Override
public void onGuiClosed() {
ResourceHelper.freeAllResources();
// Note: Currently intentionally leaks resources, will be fixed soon
Keyboard.enableRepeatEvents(false);
super.onGuiClosed();
}
@@ -411,11 +402,11 @@ public class GuiUploadFile extends GuiScreen implements ProgressUpdateListener {
enabled = false;
name.setTextColor(Color.RED.getRGB());
startUploadButton.hoverText = I18n.format("replaymod.gui.upload.error.name.length");
} else if(!RegexUtils.isValid(RegexUtils.ALPHANUMERIC_SPACE_HYPHEN_UNDERSCORE, name.getText())) {
} else if(!Patterns.ALPHANUMERIC_SPACE_HYPHEN_UNDERSCORE.matcher(name.getText()).matches()) {
enabled = false;
name.setTextColor(Color.RED.getRGB());
startUploadButton.hoverText = I18n.format("replaymod.gui.upload.error.name");
} else if(!RegexUtils.isValid(RegexUtils.ALPHANUMERIC_COMMA, tags.getText())) {
} else if(!Patterns.ALPHANUMERIC_COMMA.matcher(tags.getText()).matches()) {
enabled = false;
tags.setTextColor(Color.RED.getRGB());
startUploadButton.hoverText = I18n.format("replaymod.gui.upload.error.tags");

View File

@@ -1,7 +1,6 @@
package com.replaymod.recording.handler;
import com.replaymod.recording.packet.PacketListener;
import eu.crushedpixel.replaymod.utils.Objects;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.client.Minecraft;
@@ -25,6 +24,8 @@ import net.minecraftforge.fml.common.gameevent.PlayerEvent.ItemPickupEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent;
import java.util.Objects;
public class RecordingEventHandler {
private final Minecraft mc = Minecraft.getMinecraft();

View File

@@ -4,13 +4,13 @@ import com.replaymod.core.utils.Restrictions;
import com.replaymod.replaystudio.data.Marker;
import com.replaymod.replaystudio.replay.ReplayFile;
import com.replaymod.replaystudio.replay.ReplayMetaData;
import eu.crushedpixel.replaymod.holders.AdvancedPosition;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.DataWatcher;
import net.minecraft.entity.Entity;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.EnumPacketDirection;
import net.minecraft.network.Packet;
@@ -231,17 +231,17 @@ public class PacketListener extends ChannelInboundHandlerAdapter {
}
public void addMarker() {
AdvancedPosition pos = new AdvancedPosition(Minecraft.getMinecraft().getRenderViewEntity());
Entity view = Minecraft.getMinecraft().getRenderViewEntity();
int timestamp = (int) (System.currentTimeMillis() - startTime);
Marker marker = new Marker();
marker.setTime(timestamp);
marker.setX(pos.getX());
marker.setY(pos.getY());
marker.setZ(pos.getZ());
marker.setYaw((float) pos.getYaw());
marker.setPitch((float) pos.getPitch());
marker.setRoll((float) pos.getRoll());
marker.setX(view.posX);
marker.setY(view.posY);
marker.setZ(view.posZ);
marker.setYaw(view.rotationYaw);
marker.setPitch(view.rotationPitch);
// Roll is always 0
saveService.submit(() -> {
synchronized (replayFile) {
try {

View File

@@ -3,7 +3,7 @@ package com.replaymod.render;
import com.replaymod.render.frame.RGBFrame;
import com.replaymod.render.rendering.FrameConsumer;
import com.replaymod.render.utils.ByteBufferPool;
import eu.crushedpixel.replaymod.utils.StreamPipe;
import com.replaymod.render.utils.StreamPipe;
import eu.crushedpixel.replaymod.utils.StringUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.crash.CrashReport;

View File

@@ -1,5 +1,6 @@
package com.replaymod.render.gui;
import com.replaymod.core.utils.Utils;
import com.replaymod.render.frame.RGBFrame;
import com.replaymod.render.rendering.VideoRenderer;
import de.johni0702.minecraft.gui.GuiRenderer;
@@ -12,7 +13,6 @@ import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.element.advanced.GuiProgressBar;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import eu.crushedpixel.replaymod.utils.BoundingUtils;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.resources.I18n;
@@ -257,7 +257,7 @@ public class GuiVideoRenderer extends GuiScreen {
private void renderPreviewTexture(GuiRenderer guiRenderer, ReadableDimension size,
int videoWidth, int videoHeight) {
Dimension dimension = BoundingUtils.fitIntoBounds(new Dimension(videoWidth, videoHeight), size);
Dimension dimension = Utils.fitIntoBounds(new Dimension(videoWidth, videoHeight), size);
int width = dimension.getWidth();
int height = dimension.getHeight();

View File

@@ -1,6 +1,6 @@
package com.replaymod.render.hooks;
import eu.crushedpixel.replaymod.utils.JailingQueue;
import com.replaymod.render.utils.JailingQueue;
import net.minecraft.client.renderer.RegionRenderCacheBuilder;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.chunk.ChunkCompileTaskGenerator;

View File

@@ -0,0 +1,120 @@
package com.replaymod.render.utils;
import com.google.common.base.Preconditions;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
public class JailingQueue<T> extends AbstractQueue<T> implements BlockingQueue<T> {
private final BlockingQueue<T> delegate;
private final Set<Thread> jailed = new HashSet<Thread>();
public JailingQueue(BlockingQueue<T> delegate) {
this.delegate = delegate;
}
public synchronized void jail(int atLeast) {
while (jailed.size() < atLeast) {
try {
wait();
} catch (InterruptedException e) {
Thread.interrupted();
}
}
}
public synchronized void free(Thread thread) {
Preconditions.checkState(jailed.remove(thread), "Thread is not jailed.");
thread.interrupt();
}
public synchronized void freeAll() {
jailed.clear();
notifyAll();
}
private synchronized void tryAccess() {
jailed.add(Thread.currentThread());
notifyAll();
while (jailed.contains(Thread.currentThread())) {
try {
wait();
} catch (InterruptedException e) {
Thread.interrupted();
}
}
}
@Override
public Iterator<T> iterator() {
tryAccess();
return delegate.iterator();
}
@Override
public int size() {
tryAccess();
return delegate.size();
}
@Override
public void put(T t) throws InterruptedException {
tryAccess();
delegate.put(t);
}
@Override
public boolean offer(T t, long timeout, TimeUnit unit) throws InterruptedException {
tryAccess();
return delegate.offer(t, timeout, unit);
}
@Override
public T take() throws InterruptedException {
tryAccess();
return delegate.take();
}
@Override
public T poll(long timeout, TimeUnit unit) throws InterruptedException {
tryAccess();
return delegate.poll(timeout, unit);
}
@Override
public int remainingCapacity() {
tryAccess();
return delegate.remainingCapacity();
}
@Override
public int drainTo(Collection<? super T> c) {
tryAccess();
return delegate.drainTo(c);
}
@Override
public int drainTo(Collection<? super T> c, int maxElements) {
tryAccess();
return delegate.drainTo(c, maxElements);
}
@Override
public boolean offer(T t) {
tryAccess();
return delegate.offer(t);
}
@Override
public T poll() {
tryAccess();
return delegate.poll();
}
@Override
public T peek() {
tryAccess();
return delegate.peek();
}
}

View File

@@ -0,0 +1,39 @@
package com.replaymod.render.utils;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import org.apache.commons.io.IOUtils;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
public class SoundHandler {
private final ResourceLocation successSoundLocation = new ResourceLocation("replaymod", "renderSuccess.wav");
public void playRenderSuccessSound() {
playSound(successSoundLocation);
}
/**
* Plays a <b>.wav</b> Sound from a ResourceLocation. This method does <b>not</b> respect Game Settings like Audio Volume.
* @param loc The Sound File's ResourceLocation
*/
public void playSound(ResourceLocation loc) {
try {
InputStream is = Minecraft.getMinecraft().getResourceManager().getResource(loc).getInputStream();
byte[] bytes = IOUtils.toByteArray(is);
is.close();
AudioInputStream ais = AudioSystem.getAudioInputStream(new ByteArrayInputStream(bytes));
Clip clip = AudioSystem.getClip();
clip.open(ais);
clip.start();
} catch(Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,28 @@
package com.replaymod.render.utils;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class StreamPipe extends Thread {
private final InputStream in;
private final OutputStream out;
public StreamPipe(InputStream in, OutputStream out) {
super("StreamPipe from " + in + " to " + out);
this.in = in;
this.out = out;
}
@Override
public void run() {
try {
IOUtils.copy(in, out);
} catch (IOException ignored) {
// We don't care
// Note: Once we use this for something important, we should probably care!
}
}
}

View File

@@ -9,9 +9,8 @@ import com.replaymod.replay.events.ReplayOpenEvent;
import com.replaymod.replay.gui.overlay.GuiReplayOverlay;
import com.replaymod.replaystudio.data.Marker;
import com.replaymod.replaystudio.replay.ReplayFile;
import eu.crushedpixel.replaymod.holders.AdvancedPosition;
import eu.crushedpixel.replaymod.registry.ReplayGuiRegistry;
import com.replaymod.core.utils.Restrictions;
import com.replaymod.replaystudio.util.Location;
import eu.crushedpixel.replaymod.utils.MouseUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.embedded.EmbeddedChannel;
@@ -69,7 +68,7 @@ public class ReplayHandler {
/**
* The position at which the camera should be located after the next jump.
*/
private AdvancedPosition targetCameraPosition;
private Location targetCameraPosition;
private UUID spectating;
@@ -123,9 +122,6 @@ public class ReplayHandler {
mc.timer.timerSpeed = 1;
overlay.setVisible(false);
// These might have been hidden by the overlay, so we have to make sure they're visible again
ReplayGuiRegistry.show();
ReplayModReplay.instance.replayHandler = null;
FMLCommonHandler.instance().bus().post(new ReplayCloseEvent.Post(this));
@@ -256,7 +252,7 @@ public class ReplayHandler {
return spectating;
}
public void setTargetPosition(AdvancedPosition pos) {
public void setTargetPosition(Location pos) {
targetCameraPosition = pos;
}
@@ -279,8 +275,8 @@ public class ReplayHandler {
if (retainCameraPosition) {
CameraEntity cam = getCameraEntity();
if (cam != null) {
targetCameraPosition = new AdvancedPosition(cam.posX, cam.posY, cam.posZ,
cam.rotationPitch, cam.rotationYaw, cam.roll);
targetCameraPosition = new Location(cam.posX, cam.posY, cam.posZ,
cam.rotationPitch, cam.rotationYaw);
} else {
targetCameraPosition = null;
}

View File

@@ -6,9 +6,8 @@ import com.google.common.util.concurrent.ListenableFutureTask;
import com.replaymod.core.utils.Restrictions;
import com.replaymod.replay.camera.CameraEntity;
import com.replaymod.replaystudio.replay.ReplayFile;
import eu.crushedpixel.replaymod.holders.PacketData;
import eu.crushedpixel.replaymod.settings.ReplaySettings;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
@@ -17,9 +16,7 @@ import net.minecraft.client.gui.GuiDownloadTerrain;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.Entity;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.*;
import net.minecraft.network.play.server.*;
import net.minecraft.util.IChatComponent;
import net.minecraft.world.EnumDifficulty;
@@ -253,7 +250,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
if (msg instanceof byte[]) {
try {
Packet p = ReplayFileIO.deserializePacket((byte[]) msg);
Packet p = deserializePacket((byte[]) msg);
if (p != null) {
p = processPacket(p);
@@ -299,6 +296,18 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
private Packet deserializePacket(byte[] bytes) throws IOException, IllegalAccessException, InstantiationException {
ByteBuf bb = Unpooled.wrappedBuffer(bytes);
PacketBuffer pb = new PacketBuffer(bb);
int i = pb.readVarIntFromBuffer();
Packet p = EnumConnectionState.PLAY.getPacket(EnumPacketDirection.CLIENTBOUND, i);
p.readPacketData(pb);
return p;
}
/**
* Process a packet and return the result.
* @param p The packet to process
@@ -453,7 +462,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
if (p instanceof S02PacketChat) {
if (ReplaySettings.ReplayOptions.showChat.getValue() != Boolean.TRUE) {
if (!ReplayModReplay.instance.getCore().getSettingsRegistry().get(Setting.SHOW_CHAT)) {
return null;
}
}
@@ -558,10 +567,10 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
// Read the next packet if we don't already have one
if (nextPacket == null) {
nextPacket = ReplayFileIO.readPacketData(dis);
nextPacket = new PacketData(dis);
}
int nextTimeStamp = nextPacket.getTimestamp();
int nextTimeStamp = nextPacket.timestamp;
// If we aren't jumping and the world has already been loaded (no dirt-screens) then wait
// the required amount to get proper packet timing
@@ -578,7 +587,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
// Process packet
channelRead(ctx, nextPacket.getByteArray());
channelRead(ctx, nextPacket.bytes);
nextPacket = null;
lastTimeStamp = nextTimeStamp;
@@ -725,10 +734,10 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
nextPacket = null;
} else {
// Otherwise read one from the input stream
pd = ReplayFileIO.readPacketData(dis);
pd = new PacketData(dis);
}
int nextTimeStamp = pd.getTimestamp();
int nextTimeStamp = pd.timestamp;
if (nextTimeStamp > timestamp) {
// We are done sending all packets
nextPacket = pd;
@@ -736,7 +745,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
// Process packet
channelRead(ctx, pd.getByteArray());
channelRead(ctx, pd.bytes);
// Store last timestamp
lastTimeStamp = nextTimeStamp;
@@ -823,4 +832,15 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
}
}
private static final class PacketData {
private final int timestamp;
private final byte[] bytes;
public PacketData(DataInputStream in) throws IOException {
timestamp = in.readInt();
bytes = new byte[in.readInt()];
in.readFully(bytes);
}
}
}

View File

@@ -3,9 +3,7 @@ package com.replaymod.replay;
import com.replaymod.core.SettingsRegistry;
public final class Setting<T> extends SettingsRegistry.SettingKeys<T> {
public static final Setting<Boolean> RECORD_SINGLEPLAYER = make("recordSingleplayer", "recordsingleplayer", true);
public static final Setting<Boolean> RECORD_SERVER = make("recordServer", "recordserver", true);
public static final Setting<Boolean> INDICATOR = make("indicator", "indicator", true);
public static final Setting<Boolean> SHOW_CHAT = make("showChat", "showchat", true);
public static final SettingsRegistry.MultipleChoiceSettingKeys<String> CAMERA =
new SettingsRegistry.MultipleChoiceSettingKeys<>(
"replay", "camera", "replaymod.gui.settings.camera", "replaymod.camera.classic");

View File

@@ -1,10 +1,10 @@
package com.replaymod.replay.camera;
import com.replaymod.core.events.SettingsChangedEvent;
import com.replaymod.core.utils.Utils;
import com.replaymod.replay.ReplayModReplay;
import com.replaymod.replay.Setting;
import eu.crushedpixel.replaymod.holders.AdvancedPosition;
import eu.crushedpixel.replaymod.utils.SkinProvider;
import com.replaymod.replaystudio.util.Location;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.block.material.Material;
@@ -107,8 +107,8 @@ public class CameraEntity extends EntityPlayerSP {
* Sets the camera position and rotation to that of the specified AdvancedPosition
* @param pos The position and rotation to set
*/
public void setCameraPosRot(AdvancedPosition pos) {
setCameraRotation((float) pos.getYaw(), (float) pos.getPitch(), (float) pos.getRoll());
public void setCameraPosRot(Location pos) {
setCameraRotation(pos.getYaw(), pos.getPitch(), roll);
setCameraPosition(pos.getX(), pos.getY(), pos.getZ());
}
@@ -238,7 +238,7 @@ public class CameraEntity extends EntityPlayerSP {
public ResourceLocation getLocationSkin() {
Entity view = mc.getRenderViewEntity();
if (view != this && view instanceof EntityPlayer) {
return SkinProvider.getResourceLocationForPlayerUUID(view.getUniqueID());
return Utils.getResourceLocationForPlayerUUID(view.getUniqueID());
}
return super.getLocationSkin();
}

View File

@@ -2,12 +2,12 @@ package com.replaymod.replay.gui.overlay;
import com.replaymod.core.ReplayMod;
import com.replaymod.replay.ReplayHandler;
import com.replaymod.replaystudio.util.Location;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.element.advanced.AbstractGuiTimeline;
import de.johni0702.minecraft.gui.function.Draggable;
import com.replaymod.replaystudio.data.Marker;
import eu.crushedpixel.replaymod.holders.AdvancedPosition;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.MathHelper;
import org.lwjgl.util.Point;
@@ -126,9 +126,9 @@ public class GuiMarkerTimeline extends AbstractGuiTimeline<GuiMarkerTimeline> im
lastClickTime = now;
} else if (button == 1) { // Right click
selectedMarker = null;
replayHandler.setTargetPosition(new AdvancedPosition(
replayHandler.setTargetPosition(new Location(
marker.getX(), marker.getY(), marker.getZ(),
marker.getPitch(), marker.getYaw(), marker.getRoll()
marker.getPitch(), marker.getYaw()
));
replayHandler.doJump(marker.getTime(), false);
}

View File

@@ -24,9 +24,7 @@ import com.replaymod.replaystudio.replay.ReplayFile;
import com.replaymod.replaystudio.replay.ReplayMetaData;
import com.replaymod.replaystudio.replay.ZipReplayFile;
import com.replaymod.replaystudio.studio.ReplayStudio;
import eu.crushedpixel.replaymod.registry.ResourceHelper;
import eu.crushedpixel.replaymod.utils.DurationUtils;
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
import com.replaymod.core.utils.Utils;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.Util;
@@ -162,11 +160,9 @@ public class GuiReplayViewer extends GuiScreen {
popup.getYesButton().onClick();
}
}
}).onTextChanged(new Consumer<String>() {
@Override
public void consume(String obj) {
popup.getYesButton().setEnabled(!nameField.getText().isEmpty());
}
}).onTextChanged(obj -> {
popup.getYesButton().setEnabled(!nameField.getText().isEmpty()
&& !new File(file.getParentFile(), nameField.getText() + ".mcpr").exists());
});
Futures.addCallback(popup.getFuture(), new FutureCallback<Boolean>() {
@Override
@@ -176,11 +172,9 @@ public class GuiReplayViewer extends GuiScreen {
String name = nameField.getText().trim().replace("[^a-zA-Z0-9\\.\\- ]", "_");
// This file is what they want
File targetFile = new File(file.getParentFile(), name + ".mcpr");
// But if it's already used, this is what they get
File renamed = ReplayFileIO.getNextFreeFile(targetFile);
try {
// Finally, try to move it
FileUtils.moveFile(file, renamed);
FileUtils.moveFile(file, targetFile);
} catch (IOException e) {
// We failed (might also be their OS)
e.printStackTrace();
@@ -268,7 +262,7 @@ public class GuiReplayViewer extends GuiScreen {
});
}
private final GuiImage defaultThumbnail = new GuiImage().setTexture(ResourceHelper.getDefaultThumbnail());
private final GuiImage defaultThumbnail = new GuiImage().setTexture(Utils.DEFAULT_THUMBNAIL);
public class GuiReplayEntry extends AbstractGuiContainer<GuiReplayEntry> implements Comparable<GuiReplayEntry> {
public final File file;
public final GuiLabel name = new GuiLabel();
@@ -311,7 +305,7 @@ public class GuiReplayViewer extends GuiScreen {
} else {
thumbnail = new GuiImage(this).setTexture(thumbImage).setSize(30 * 16 / 9, 30);
}
duration.setText(DurationUtils.convertSecondsToShortString(metaData.getDuration() / 1000));
duration.setText(Utils.convertSecondsToShortString(metaData.getDuration() / 1000));
addElements(null, durationPanel);
setLayout(new CustomLayout<GuiReplayEntry>() {