Split mod into core, recording, replay, render[todo], paths[todo] and extras[wip] modules
Move everything to com.replaymod package Add KeyBindingRegistry and SettingsRegistry Recreate settings GUI with new GUI API and dynamically from SettingsRegistry Use ReplayFile from ReplayStudio ReplayHandler is now object oriented Add GuiOverlay, GuiSlider and GuiTexturedButton to GUI API Rewrite both overlays to use new GUI API Fix size capping in vertical and horizontal layout Allow CustomLayouts to have parents Fix tooltip rendering when close to screen border Allow changing of columns in GridLayout
This commit is contained in:
60
src/main/java/com/replaymod/core/KeyBindingRegistry.java
Normal file
60
src/main/java/com/replaymod/core/KeyBindingRegistry.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package com.replaymod.core;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
import net.minecraft.util.ReportedException;
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.InputEvent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class KeyBindingRegistry {
|
||||
private Map<String, KeyBinding> keyBindings = new HashMap<String, KeyBinding>();
|
||||
private Multimap<KeyBinding, Runnable> keyBindingHandlers = ArrayListMultimap.create();
|
||||
|
||||
public void registerKeyBinding(String name, int keyCode, Runnable whenPressed) {
|
||||
KeyBinding keyBinding = keyBindings.get(name);
|
||||
if (keyBinding == null) {
|
||||
keyBinding = new KeyBinding(name, keyCode, "replaymod.title");
|
||||
keyBindings.put(name, keyBinding);
|
||||
ClientRegistry.registerKeyBinding(keyBinding);
|
||||
}
|
||||
keyBindingHandlers.put(keyBinding, whenPressed);
|
||||
}
|
||||
|
||||
public Map<String, KeyBinding> getKeyBindings() {
|
||||
return Collections.unmodifiableMap(keyBindings);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKeyInput(InputEvent.KeyInputEvent event) {
|
||||
for (Map.Entry<KeyBinding, Collection<Runnable>> entry : keyBindingHandlers.asMap().entrySet()) {
|
||||
while (entry.getKey().isPressed()) {
|
||||
for (final Runnable runnable : entry.getValue()) {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Throwable cause) {
|
||||
CrashReport crashReport = CrashReport.makeCrashReport(cause, "Handling Key Binding");
|
||||
CrashReportCategory category = crashReport.makeCategory("Key Binding");
|
||||
category.addCrashSection("Key Binding", entry.getKey());
|
||||
category.addCrashSectionCallable("Handler", new Callable() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
return runnable;
|
||||
}
|
||||
});
|
||||
throw new ReportedException(crashReport);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
450
src/main/java/com/replaymod/core/ReplayMod.java
Executable file
450
src/main/java/com/replaymod/core/ReplayMod.java
Executable file
@@ -0,0 +1,450 @@
|
||||
package com.replaymod.core;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFutureTask;
|
||||
import com.replaymod.replay.ReplaySender;
|
||||
import eu.crushedpixel.replaymod.api.ApiClient;
|
||||
import eu.crushedpixel.replaymod.api.replay.holders.FileInfo;
|
||||
import eu.crushedpixel.replaymod.chat.ChatMessageHandler;
|
||||
import eu.crushedpixel.replaymod.events.handlers.CrosshairRenderHandler;
|
||||
import eu.crushedpixel.replaymod.events.handlers.GuiEventHandler;
|
||||
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.gui.online.GuiReplayDownloading;
|
||||
import eu.crushedpixel.replaymod.localization.LocalizedResourcePack;
|
||||
import eu.crushedpixel.replaymod.online.authentication.ConfigurationAuthData;
|
||||
import eu.crushedpixel.replaymod.online.urischeme.UriScheme;
|
||||
import eu.crushedpixel.replaymod.registry.*;
|
||||
import eu.crushedpixel.replaymod.renderer.CustomObjectRenderer;
|
||||
import eu.crushedpixel.replaymod.renderer.InvisibilityRender;
|
||||
import eu.crushedpixel.replaymod.renderer.PathPreviewRenderer;
|
||||
import eu.crushedpixel.replaymod.renderer.SpectatorRenderer;
|
||||
import eu.crushedpixel.replaymod.settings.EncodingPreset;
|
||||
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
||||
import eu.crushedpixel.replaymod.settings.ReplaySettings;
|
||||
import eu.crushedpixel.replaymod.sound.SoundHandler;
|
||||
import eu.crushedpixel.replaymod.timer.ReplayTimer;
|
||||
import eu.crushedpixel.replaymod.utils.OpenGLUtils;
|
||||
import eu.crushedpixel.replaymod.utils.TooltipRenderer;
|
||||
import eu.crushedpixel.replaymod.video.rendering.Pipelines;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.entity.RenderPlayer;
|
||||
import net.minecraft.client.resources.IResourcePack;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||
import net.minecraftforge.fml.common.Mod.Instance;
|
||||
import net.minecraftforge.fml.common.ModContainer;
|
||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
@Mod(modid = ReplayMod.MOD_ID, useMetadata = true)
|
||||
public class ReplayMod {
|
||||
|
||||
public static ModContainer getContainer() {
|
||||
return Loader.instance().getIndexedModList().get(MOD_ID);
|
||||
}
|
||||
|
||||
@Getter(lazy = true)
|
||||
private static final String minecraftVersion = parseMinecraftVersion();
|
||||
private static String parseMinecraftVersion() {
|
||||
CrashReport crashReport = new CrashReport("", new Throwable());
|
||||
@SuppressWarnings("unchecked")
|
||||
List<CrashReportCategory.Entry> list = crashReport.getCategory().children;
|
||||
for (CrashReportCategory.Entry entry : list) {
|
||||
if ("Minecraft Version".equals(entry.getKey())) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
public static final String MOD_ID = "replaymod";
|
||||
|
||||
public static final ResourceLocation TEXTURE = new ResourceLocation("replaymod", "replay_gui.png");
|
||||
public static final int TEXTURE_SIZE = 128;
|
||||
|
||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
||||
public static GuiEventHandler guiEventHandler;
|
||||
public static ReplaySettings replaySettings;
|
||||
public static Configuration config;
|
||||
public static boolean firstMainMenu = true;
|
||||
public static ChatMessageHandler chatMessageHandler = new ChatMessageHandler();
|
||||
public static KeyInputHandler keyInputHandler = new KeyInputHandler();
|
||||
public static MouseInputHandler mouseInputHandler = new MouseInputHandler();
|
||||
public static ReplaySender replaySender;
|
||||
public static int TP_DISTANCE_LIMIT = 128;
|
||||
public static ReplayFileAppender replayFileAppender;
|
||||
public static UploadedFileHandler uploadedFileHandler;
|
||||
public static DownloadedFileHandler downloadedFileHandler;
|
||||
public static FavoritedFileHandler favoritedFileHandler;
|
||||
public static RatedFileHandler ratedFileHandler;
|
||||
public static SpectatorRenderer spectatorRenderer;
|
||||
public static TooltipRenderer tooltipRenderer;
|
||||
public static PathPreviewRenderer pathPreviewRenderer;
|
||||
public static CustomObjectRenderer customObjectRenderer;
|
||||
public static SoundHandler soundHandler = new SoundHandler();
|
||||
public static CrosshairRenderHandler crosshairRenderHandler;
|
||||
public static ApiClient apiClient;
|
||||
|
||||
private final KeyBindingRegistry keyBindingRegistry = new KeyBindingRegistry();
|
||||
private final SettingsRegistry settingsRegistry = new SettingsRegistry();
|
||||
|
||||
@Getter
|
||||
private static boolean latestModVersion = true;
|
||||
|
||||
// The instance of your mod that Forge uses.
|
||||
@Instance(MOD_ID)
|
||||
public static ReplayMod instance;
|
||||
|
||||
public KeyBindingRegistry getKeyBindingRegistry() {
|
||||
return keyBindingRegistry;
|
||||
}
|
||||
|
||||
public SettingsRegistry getSettingsRegistry() {
|
||||
return settingsRegistry;
|
||||
}
|
||||
|
||||
public File getReplayFolder() throws IOException {
|
||||
File folder = new File(replaySettings.getRecordingPath());
|
||||
FileUtils.forceMkdir(folder);
|
||||
return folder;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void preInit(FMLPreInitializationEvent event) {
|
||||
try {
|
||||
UriScheme uriScheme = UriScheme.create();
|
||||
if (uriScheme == null) {
|
||||
throw new UnsupportedOperationException("OS not supported.");
|
||||
}
|
||||
uriScheme.install();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to install UriScheme handler:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Initialize the static OpenGL info field from the minecraft main thread
|
||||
// Unfortunately lwjgl uses static methods so we have to make use of magic init calls as well
|
||||
OpenGLUtils.init();
|
||||
|
||||
config = new Configuration(event.getSuggestedConfigurationFile());
|
||||
config.load();
|
||||
settingsRegistry.setConfiguration(config);
|
||||
ConfigurationAuthData authData = new ConfigurationAuthData(config);
|
||||
apiClient = new ApiClient(authData);
|
||||
authData.load(apiClient);
|
||||
|
||||
uploadedFileHandler = new UploadedFileHandler(event.getModConfigurationDirectory());
|
||||
|
||||
replaySettings = new ReplaySettings();
|
||||
|
||||
downloadedFileHandler = new DownloadedFileHandler();
|
||||
favoritedFileHandler = new FavoritedFileHandler();
|
||||
ratedFileHandler = new RatedFileHandler();
|
||||
|
||||
replayFileAppender = new ReplayFileAppender();
|
||||
FMLCommonHandler.instance().bus().register(replayFileAppender);
|
||||
|
||||
//check if latest mod version
|
||||
try {
|
||||
latestModVersion = apiClient.isVersionUpToDate(getContainer().getVersion());
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void init(FMLInitializationEvent event) {
|
||||
mc.timer = new ReplayTimer();
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(guiEventHandler = new GuiEventHandler());
|
||||
|
||||
FMLCommonHandler.instance().bus().register(keyInputHandler);
|
||||
FMLCommonHandler.instance().bus().register(keyBindingRegistry);
|
||||
FMLCommonHandler.instance().bus().register(mouseInputHandler);
|
||||
MinecraftForge.EVENT_BUS.register(mouseInputHandler);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void postInit(FMLPostInitializationEvent event) throws IOException {
|
||||
settingsRegistry.save(); // Save default values to disk
|
||||
|
||||
if(!FMLClientHandler.instance().hasOptifine())
|
||||
GameSettings.Options.RENDER_DISTANCE.setValueMax(64f);
|
||||
|
||||
TickAndRenderListener tarl = new TickAndRenderListener();
|
||||
FMLCommonHandler.instance().bus().register(tarl);
|
||||
MinecraftForge.EVENT_BUS.register(tarl);
|
||||
|
||||
spectatorRenderer = new SpectatorRenderer();
|
||||
|
||||
customObjectRenderer = new CustomObjectRenderer();
|
||||
FMLCommonHandler.instance().bus().register(customObjectRenderer);
|
||||
MinecraftForge.EVENT_BUS.register(customObjectRenderer);
|
||||
|
||||
pathPreviewRenderer = new PathPreviewRenderer();
|
||||
FMLCommonHandler.instance().bus().register(pathPreviewRenderer);
|
||||
MinecraftForge.EVENT_BUS.register(pathPreviewRenderer);
|
||||
|
||||
crosshairRenderHandler = new CrosshairRenderHandler();
|
||||
FMLCommonHandler.instance().bus().register(crosshairRenderHandler);
|
||||
MinecraftForge.EVENT_BUS.register(crosshairRenderHandler);
|
||||
|
||||
KeybindRegistry.initialize();
|
||||
|
||||
tooltipRenderer = new TooltipRenderer();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, RenderPlayer> skinMap = mc.getRenderManager().skinMap;
|
||||
skinMap.put("default", new InvisibilityRender(mc.getRenderManager()));
|
||||
skinMap.put("slim", new InvisibilityRender(mc.getRenderManager(), true));
|
||||
|
||||
Thread localizedResourcePackLoader = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IResourcePack> defaultResourcePacks = mc.defaultResourcePacks;
|
||||
defaultResourcePacks.add(new LocalizedResourcePack());
|
||||
mc.addScheduledTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mc.refreshResources();
|
||||
}
|
||||
});
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, "localizedResourcePackLoader");
|
||||
localizedResourcePackLoader.start();
|
||||
|
||||
if (System.getProperty("replaymod.render.file") != null) {
|
||||
final File file = new File(System.getProperty("replaymod.render.file"));
|
||||
if (!file.exists()) {
|
||||
throw new IOException("File \"" + file.getPath() + "\" not found.");
|
||||
}
|
||||
|
||||
final String path = System.getProperty("replaymod.render.path");
|
||||
String type = System.getProperty("replaymod.render.type");
|
||||
String bitrate = System.getProperty("replaymod.render.bitrate");
|
||||
String fps = System.getProperty("replaymod.render.fps");
|
||||
String waitForChunks = System.getProperty("replaymod.render.waitforchunks");
|
||||
String linearMovement = System.getProperty("replaymod.render.linearmovement");
|
||||
String skyColor = System.getProperty("replaymod.render.skycolor");
|
||||
String width = System.getProperty("replaymod.render.width");
|
||||
String height = System.getProperty("replaymod.render.height");
|
||||
String exportCommand = System.getProperty("replaymod.render.exportcommand");
|
||||
String exportCommandArgs = System.getProperty("replaymod.render.exportcommandargs");
|
||||
final RenderOptions options = new RenderOptions();
|
||||
if (bitrate != null) {
|
||||
options.setBitrate(bitrate);
|
||||
}
|
||||
if (fps != null) {
|
||||
options.setFps(Integer.parseInt(fps));
|
||||
}
|
||||
if (waitForChunks != null) {
|
||||
options.setWaitForChunks(Boolean.parseBoolean(waitForChunks));
|
||||
}
|
||||
if (linearMovement != null) {
|
||||
options.setLinearMovement(Boolean.parseBoolean(linearMovement));
|
||||
}
|
||||
if (skyColor != null) {
|
||||
if (skyColor.startsWith("0x")) {
|
||||
options.setSkyColor(Integer.parseInt(skyColor.substring(2), 16));
|
||||
} else {
|
||||
options.setSkyColor(Integer.parseInt(skyColor));
|
||||
}
|
||||
}
|
||||
if (width != null) {
|
||||
options.setWidth(Integer.parseInt(width));
|
||||
}
|
||||
if (height != null) {
|
||||
options.setHeight(Integer.parseInt(height));
|
||||
}
|
||||
|
||||
if (exportCommand != null) {
|
||||
options.setExportCommand(exportCommand);
|
||||
}
|
||||
if (exportCommandArgs != null) {
|
||||
options.setExportCommandArgs(exportCommandArgs);
|
||||
} else {
|
||||
options.setExportCommandArgs(EncodingPreset.MP4DEFAULT.getCommandLineArgs());
|
||||
}
|
||||
|
||||
options.setOutputFile(new File(String.valueOf(System.currentTimeMillis())));
|
||||
|
||||
Pipelines.Preset pipelinePreset = Pipelines.Preset.DEFAULT;
|
||||
if (type != null) {
|
||||
String[] parts = type.split(":");
|
||||
type = parts[0].toUpperCase();
|
||||
if ("NORMAL".equals(type) || "DEFAULT".equals(type)) {
|
||||
pipelinePreset = Pipelines.Preset.DEFAULT;
|
||||
} else if ("STEREO".equals(type) || "STEREOSCOPIC".equals(type)) {
|
||||
pipelinePreset = Pipelines.Preset.STEREOSCOPIC;
|
||||
} else if ("CUBIC".equals(type)) {
|
||||
if (parts.length < 2) {
|
||||
throw new IllegalArgumentException("Cubic renderer requires boolean for whether it's stable.");
|
||||
}
|
||||
pipelinePreset = Pipelines.Preset.CUBIC;
|
||||
} else if ("EQUIRECTANGULAR".equals(type)) {
|
||||
if (parts.length < 2) {
|
||||
throw new IllegalArgumentException("Equirectangular renderer requires boolean for whether it's stable.");
|
||||
}
|
||||
pipelinePreset = Pipelines.Preset.EQUIRECTANGULAR;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown type: " + parts[0]);
|
||||
}
|
||||
}
|
||||
options.setMode(pipelinePreset);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Queue<ListenableFutureTask> tasks = mc.scheduledTasks;
|
||||
synchronized (mc.scheduledTasks) {
|
||||
tasks.add(ListenableFutureTask.create(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String renderDistance = System.getProperty("replaymod.render.mc.renderdistance");
|
||||
String clouds = System.getProperty("replaymod.render.mc.clouds");
|
||||
if (renderDistance != null) {
|
||||
mc.gameSettings.renderDistanceChunks = Integer.parseInt(renderDistance);
|
||||
}
|
||||
if (clouds != null) {
|
||||
mc.gameSettings.clouds = Boolean.parseBoolean(clouds);
|
||||
}
|
||||
|
||||
System.out.println("Loading replay...");
|
||||
// TODO
|
||||
// try {
|
||||
// ReplayHandler.startReplay(file, false);
|
||||
// } catch (Throwable t) {
|
||||
// t.printStackTrace();
|
||||
// FMLCommonHandler.instance().exitJava(1, false);
|
||||
// }
|
||||
//
|
||||
// int index = 0;
|
||||
// if (path != null) {
|
||||
// for (KeyframeSet set : ReplayHandler.getKeyframeRepository()) {
|
||||
// if (set.getName().equals(path)) {
|
||||
// break;
|
||||
// }
|
||||
// index++;
|
||||
// }
|
||||
// if (index >= ReplayHandler.getKeyframeRepository().length) {
|
||||
// throw new IllegalArgumentException("No path named \"" + path + "\".");
|
||||
// }
|
||||
// } else if (ReplayHandler.getKeyframeRepository().length == 0) {
|
||||
// throw new IllegalArgumentException("Replay file has no paths defined.");
|
||||
// }
|
||||
// ReplayHandler.useKeyframePresetFromRepository(index);
|
||||
//
|
||||
// System.out.println("Rendering started...");
|
||||
// try {
|
||||
// ReplayProcess.startReplayProcess(options, true);
|
||||
// } catch (Throwable t) {
|
||||
// t.printStackTrace();
|
||||
// FMLCommonHandler.instance().exitJava(1, false);
|
||||
// }
|
||||
// if (mc.hasCrashed) {
|
||||
// System.out.println(mc.crashReporter.getCompleteReport());
|
||||
// }
|
||||
// System.out.println("Rendering done. Shutting down...");
|
||||
// mc.shutdown();
|
||||
}
|
||||
}, null));
|
||||
}
|
||||
|
||||
testIfMoeshAndExitMinecraft();
|
||||
}
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ServerSocket serverSocket = null;
|
||||
try {
|
||||
serverSocket = new ServerSocket(UriScheme.PROCESS_PORT);
|
||||
while (!Thread.interrupted()) {
|
||||
Socket clientSocket = serverSocket.accept();
|
||||
try {
|
||||
InputStream inputStream = clientSocket.getInputStream();
|
||||
String replayId = IOUtils.toString(inputStream);
|
||||
final int id = Integer.parseInt(replayId);
|
||||
mc.addScheduledTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadOnlineReplay(id);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
IOUtils.closeQuietly(clientSocket);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
IOUtils.closeQuietly(serverSocket);
|
||||
}
|
||||
}
|
||||
}, "UriSchemeHandler").start();
|
||||
|
||||
String replayId = System.getenv("replaymod.uri.replayid");
|
||||
if (replayId != null) {
|
||||
final int id = Integer.parseInt(replayId);
|
||||
@SuppressWarnings("unchecked")
|
||||
Queue<ListenableFutureTask> tasks = mc.scheduledTasks;
|
||||
synchronized (mc.scheduledTasks) {
|
||||
tasks.add(ListenableFutureTask.create(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadOnlineReplay(id);
|
||||
}
|
||||
}, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadOnlineReplay(int id) {
|
||||
File file = ReplayMod.downloadedFileHandler.getFileForID(id);
|
||||
if (file == null) {
|
||||
FileInfo info = new FileInfo(id, null, null, null, 0, 0, 0, String.valueOf(id), false, 0);
|
||||
new GuiReplayDownloading(info).display();
|
||||
} else {
|
||||
try {
|
||||
// TODO
|
||||
// ReplayHandler.startReplay(file);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testIfMoeshAndExitMinecraft() {
|
||||
if("currentPlayer".equals("Moesh")) {
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
133
src/main/java/com/replaymod/core/SettingsRegistry.java
Normal file
133
src/main/java/com/replaymod/core/SettingsRegistry.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package com.replaymod.core;
|
||||
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SettingsRegistry {
|
||||
private static final Object NULL_OBJECT = new Object();
|
||||
private Map<SettingKey<?>, Object> settings = new ConcurrentHashMap<>();
|
||||
private Configuration configuration;
|
||||
|
||||
public void setConfiguration(Configuration configuration) {
|
||||
this.configuration = configuration;
|
||||
|
||||
List<SettingKey<?>> keys = new ArrayList<>(settings.keySet());
|
||||
settings.clear();
|
||||
for (SettingKey key : keys) {
|
||||
register(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void register(Class<?> settingsClass) {
|
||||
for (Field field : settingsClass.getDeclaredFields()) {
|
||||
if ((field.getModifiers() & (Modifier.STATIC | Modifier.PUBLIC)) != 0
|
||||
&& SettingKey.class.isAssignableFrom(field.getType())) {
|
||||
try {
|
||||
register((SettingKey<?>) field.get(null));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void register(SettingKey<?> key) {
|
||||
Object value;
|
||||
if (configuration != null) {
|
||||
if (key.getDefault() instanceof Boolean) {
|
||||
value = configuration.get(key.getCategory(), key.getKey(), (Boolean) key.getDefault()).getBoolean();
|
||||
} else if (key.getDefault() instanceof Integer) {
|
||||
value = configuration.get(key.getCategory(), key.getKey(), (Integer) key.getDefault()).getInt();
|
||||
} else if (key.getDefault() instanceof Double) {
|
||||
value = configuration.get(key.getCategory(), key.getKey(), (Double) key.getDefault()).getDouble();
|
||||
} else if (key.getDefault() instanceof String) {
|
||||
value = configuration.get(key.getCategory(), key.getKey(), (String) key.getDefault()).getString();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported.");
|
||||
}
|
||||
} else {
|
||||
value = NULL_OBJECT;
|
||||
}
|
||||
settings.put(key, value);
|
||||
}
|
||||
|
||||
public Set<SettingKey<?>> getSettings() {
|
||||
return settings.keySet();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(SettingKey<T> key) {
|
||||
if (!settings.containsKey(key)) {
|
||||
throw new IllegalArgumentException("Setting " + key + " unknown.");
|
||||
}
|
||||
return (T) settings.get(key);
|
||||
}
|
||||
|
||||
public <T> void set(SettingKey<T> key, T value) {
|
||||
if (key.getDefault() instanceof Boolean) {
|
||||
configuration.get(key.getCategory(), key.getKey(), (Boolean) key.getDefault()).set((Boolean) value);
|
||||
} else if (key.getDefault() instanceof Integer) {
|
||||
configuration.get(key.getCategory(), key.getKey(), (Integer) key.getDefault()).set((Integer) value);
|
||||
} else if (key.getDefault() instanceof Double) {
|
||||
configuration.get(key.getCategory(), key.getKey(), (Double) key.getDefault()).set((Double) value);
|
||||
} else if (key.getDefault() instanceof String) {
|
||||
configuration.get(key.getCategory(), key.getKey(), (String) key.getDefault()).set((String) value);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported.");
|
||||
}
|
||||
settings.put(key, value);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
configuration.save();
|
||||
}
|
||||
|
||||
public interface SettingKey<T> {
|
||||
String getCategory();
|
||||
String getKey();
|
||||
String getDisplayString();
|
||||
T getDefault();
|
||||
}
|
||||
|
||||
public static class SettingKeys<T> implements SettingKey<T> {
|
||||
private final String category;
|
||||
private final String key;
|
||||
private final String displayString;
|
||||
private final T defaultValue;
|
||||
|
||||
public SettingKeys(String category, String key, String displayString, T defaultValue) {
|
||||
this.category = category;
|
||||
this.key = key;
|
||||
this.displayString = displayString;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayString() {
|
||||
return I18n.format(displayString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getDefault() {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
75
src/main/java/com/replaymod/core/gui/GuiReplaySettings.java
Normal file
75
src/main/java/com/replaymod/core/gui/GuiReplaySettings.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package com.replaymod.core.gui;
|
||||
|
||||
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
|
||||
import de.johni0702.minecraft.gui.container.GuiPanel;
|
||||
import de.johni0702.minecraft.gui.element.GuiButton;
|
||||
import de.johni0702.minecraft.gui.element.GuiElement;
|
||||
import de.johni0702.minecraft.gui.element.GuiLabel;
|
||||
import de.johni0702.minecraft.gui.element.GuiToggleButton;
|
||||
import de.johni0702.minecraft.gui.layout.CustomLayout;
|
||||
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
|
||||
import de.johni0702.minecraft.gui.layout.VerticalLayout;
|
||||
import com.replaymod.core.SettingsRegistry;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
public class GuiReplaySettings extends AbstractGuiScreen<GuiReplaySettings> {
|
||||
|
||||
public GuiReplaySettings(final net.minecraft.client.gui.GuiScreen parent, final SettingsRegistry settingsRegistry) {
|
||||
final GuiButton doneButton = new GuiButton(this).setI18nLabel("gui.done").setSize(200, 20).onClick(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getMinecraft().displayGuiScreen(parent);
|
||||
}
|
||||
});
|
||||
|
||||
final GuiPanel allElements = new GuiPanel(this).setLayout(new HorizontalLayout().setSpacing(10));
|
||||
GuiPanel leftColumn = new GuiPanel().setLayout(new VerticalLayout().setSpacing(4));
|
||||
GuiPanel rightColumn = new GuiPanel().setLayout(new VerticalLayout().setSpacing(4));
|
||||
allElements.addElements(new VerticalLayout.Data(0), leftColumn, rightColumn);
|
||||
HorizontalLayout.Data leftHorizontalData = new HorizontalLayout.Data(1);
|
||||
HorizontalLayout.Data rightHorizontalData = new HorizontalLayout.Data(0);
|
||||
int i = 0;
|
||||
for (final SettingsRegistry.SettingKey<?> key : settingsRegistry.getSettings()) {
|
||||
if (key.getDisplayString() != null) {
|
||||
GuiElement<?> element;
|
||||
if (key.getDefault() instanceof Boolean) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final SettingsRegistry.SettingKey<Boolean> booleanKey = (SettingsRegistry.SettingKey<Boolean>) key;
|
||||
final GuiToggleButton button = new GuiToggleButton<>().setSize(150, 20)
|
||||
.setLabel(key.getDisplayString()).setSelected(settingsRegistry.get(booleanKey) ? 0 : 1)
|
||||
.setValues(I18n.format("options.on"), I18n.format("options.off"));
|
||||
element = button.onClick(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
settingsRegistry.set(booleanKey, button.getSelected() == 0);
|
||||
settingsRegistry.save();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new IllegalArgumentException("Type " + key.getDefault().getClass() + " not supported.");
|
||||
}
|
||||
|
||||
if (i++ % 2 == 0) {
|
||||
leftColumn.addElements(leftHorizontalData, element);
|
||||
} else {
|
||||
rightColumn.addElements(rightHorizontalData, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setLayout(new CustomLayout<GuiReplaySettings>() {
|
||||
@Override
|
||||
protected void layout(GuiReplaySettings container, int width, int height) {
|
||||
pos(allElements, width / 2 - 155, height / 6);
|
||||
pos(doneButton, width / 2 - 100, height - 27);
|
||||
}
|
||||
});
|
||||
|
||||
setTitle(new GuiLabel().setI18nText("replaymod.gui.settings.title"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GuiReplaySettings getThis() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user