aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDJtheRedstoner <52044242+DJtheRedstoner@users.noreply.github.com>2020-10-04 21:02:19 -0400
committerDJtheRedstoner <52044242+DJtheRedstoner@users.noreply.github.com>2020-10-04 21:02:19 -0400
commit6a24fdcf34170ae927b1c0952c50b05131084911 (patch)
tree9a482c5d8111c7d677ba7d121f418d46714be3d2
parentfd4353e56faf69effedecebca0e1af233ecff4bb (diff)
downloadPerspectiveModv4-6a24fdcf34170ae927b1c0952c50b05131084911.tar.gz
PerspectiveModv4-6a24fdcf34170ae927b1c0952c50b05131084911.tar.bz2
PerspectiveModv4-6a24fdcf34170ae927b1c0952c50b05131084911.zip
Bug Fixes and new config
- Particles now face camera - Sk1er Modcore integration - New config gui using Vigilance - Invert pitch option
-rw-r--r--.github/perspectivemod.pngbin590636 -> 841026 bytes
-rw-r--r--README.md3
-rw-r--r--build.gradle9
-rw-r--r--gradle.properties2
-rw-r--r--[-rwxr-xr-x]gradlew0
-rw-r--r--libs/modcore.jarbin0 -> 9776522 bytes
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/ModCoreInstaller.java506
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/PerspectiveMod.java50
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/PerspectiveModCommand.java86
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/asm/ClassTransformer.java2
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/ActiveRenderInfoHook.java16
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/EntityRendererHook.java3
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/ActiveRenderInfoTransformer.java68
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/EntityRendererTransformer.java30
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/commands/PerspectiveModCommand.java60
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/config/PerspectiveModConfig.java36
-rw-r--r--src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModTweaker.java12
-rw-r--r--src/main/resources/LICENSE21
18 files changed, 750 insertions, 154 deletions
diff --git a/.github/perspectivemod.png b/.github/perspectivemod.png
index 13cb20e..4f1c8a9 100644
--- a/.github/perspectivemod.png
+++ b/.github/perspectivemod.png
Binary files differ
diff --git a/README.md b/README.md
index 8c07a63..5cbf643 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,11 @@ A remake of [Perspective Mod v3 by canelex](https://github.com/Canelex/Perspecti
Features:
- Mouse button support
- Nametags face camera
+- Config GUI
- Mod can be enabled/disabled
- Hold and toggle modes
+- Invert pitch/Y axis mode
+- Sk1er ModCore Integration
Mod can be enabled and disabled, and the mode can be changed with the `/perspectivemod` or `/pmod` commands.
diff --git a/build.gradle b/build.gradle
index 492b0ca..c5b0b3d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,8 @@ buildscript {
name = "forge"
url = "https://files.minecraftforge.net/maven"
}
- maven { url = "https://repo.spongepowered.org/maven" }
+
+ flatDir dirs: 'libs'
}
dependencies {
classpath "net.minecraftforge.gradle:ForgeGradle:2.1-SNAPSHOT"
@@ -33,6 +34,10 @@ minecraft {
clientJvmArgs += "-Dfml.coreMods.load=me.djtheredstoner.perspectivemod.forge.PerspectiveModTweaker"
}
+dependencies {
+ provided files("libs/modcore.jar")
+}
+
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
@@ -62,4 +67,6 @@ processResources
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
+
+ from(file("LICENSE"))
}
diff --git a/gradle.properties b/gradle.properties
index f484552..0068e23 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -3,4 +3,4 @@ org.gradle.jvmargs=-Xmx2G
# These are in here and not in build.gradle so that github actions can read them
modid = djperspectivemod
archivesBaseName = PerspectiveModv4
-version = 4.1 \ No newline at end of file
+version = 4.2 \ No newline at end of file
diff --git a/gradlew b/gradlew
index cccdd3d..cccdd3d 100755..100644
--- a/gradlew
+++ b/gradlew
diff --git a/libs/modcore.jar b/libs/modcore.jar
new file mode 100644
index 0000000..c1e7436
--- /dev/null
+++ b/libs/modcore.jar
Binary files differ
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/ModCoreInstaller.java b/src/main/java/me/djtheredstoner/perspectivemod/ModCoreInstaller.java
new file mode 100644
index 0000000..cda3837
--- /dev/null
+++ b/src/main/java/me/djtheredstoner/perspectivemod/ModCoreInstaller.java
@@ -0,0 +1,506 @@
+package me.djtheredstoner.perspectivemod;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import net.minecraft.launchwrapper.Launch;
+import net.minecraft.launchwrapper.LaunchClassLoader;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+
+import javax.swing.GroupLayout;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JProgressBar;
+import javax.swing.LayoutStyle;
+import javax.swing.SwingConstants;
+import javax.swing.UIManager;
+import java.awt.Font;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/*
+ Created by Sk1er for use in all mods. Install under exact package name each time.
+ */
+public class ModCoreInstaller {
+
+
+ private static final String VERSION_URL = "https://api.sk1er.club/modcore_versions";
+ private static final String className = "club.sk1er.mods.core.ModCore";
+ private static boolean errored = false;
+ private static String error;
+ private static File dataDir = null;
+ private static boolean isRunningModCore = false;
+
+ public static boolean isIsRunningModCore() {
+ return isRunningModCore;
+ }
+
+ private static boolean isInitalized() {
+ try {
+ LinkedHashSet<String> objects = new LinkedHashSet<>();
+ objects.add(className);
+ Launch.classLoader.clearNegativeEntries(objects);
+ Field invalidClasses = LaunchClassLoader.class.getDeclaredField("invalidClasses");
+ invalidClasses.setAccessible(true);
+ Object obj = invalidClasses.get(ModCoreInstaller.class.getClassLoader());
+ ((Set<String>) obj).remove(className);
+ return Class.forName("club.sk1er.mods.core.ModCore") != null;
+ } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException ignored) {
+ ignored.printStackTrace();
+ }
+ return false;
+ }
+
+ public static boolean isErrored() {
+ return errored;
+ }
+
+ public static String getError() {
+ return error;
+ }
+
+ private static void bail(String error) {
+ errored = true;
+ ModCoreInstaller.error = error;
+ }
+
+ private static JsonHolder readFile(File in) {
+ try {
+ return new JsonHolder(FileUtils.readFileToString(in));
+ } catch (IOException ignored) {
+
+ }
+ return new JsonHolder();
+ }
+
+ public static void initializeModCore(File gameDir) {
+ if (!isIsRunningModCore()) {
+ return;
+ }
+ try {
+ Class<?> modCore = Class.forName(className);
+ Method instanceMethod = modCore.getMethod("getInstance");
+ Method initialize = modCore.getMethod("initialize", File.class);
+ Object modCoreObject = instanceMethod.invoke(null);
+ initialize.invoke(modCoreObject, gameDir);
+ System.out.println("Loaded ModCore Successfully");
+ return;
+ } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ System.out.println("Did NOT ModCore Successfully");
+ }
+
+ public static int initialize(File gameDir, String minecraftVersion) {
+ if (isInitalized()) return -1;
+ dataDir = new File(gameDir, "modcore");
+ if (!dataDir.exists()) {
+ if (!dataDir.mkdirs()) {
+ bail("Unable to create necessary files");
+ return 1;
+ }
+ }
+ JsonHolder jsonHolder = fetchJSON(VERSION_URL);
+ String latestRemote = jsonHolder.optString(minecraftVersion);
+ boolean failed = jsonHolder.getKeys().size() == 0 || (jsonHolder.has("success") && !jsonHolder.optBoolean("success"));
+
+ File metadataFile = new File(dataDir, "metadata.json");
+ JsonHolder localMetadata = readFile(metadataFile);
+ if (failed) latestRemote = localMetadata.optString(minecraftVersion);
+ File modcoreFile = new File(dataDir, "Sk1er Modcore-" + latestRemote + " (" + minecraftVersion + ").jar");
+
+ if (!modcoreFile.exists() || !localMetadata.optString(minecraftVersion).equalsIgnoreCase(latestRemote) && !failed) {
+ //File does not exist, or is out of date, download it
+ File old = new File(dataDir, "Sk1er Modcore-" + localMetadata.optString(minecraftVersion) + " (" + minecraftVersion + ").jar");
+ if (old.exists()) old.delete();
+
+ if (!download("https://static.sk1er.club/repo/mods/modcore/" + latestRemote + "/" + minecraftVersion + "/ModCore-" + latestRemote + " (" + minecraftVersion + ").jar", latestRemote, modcoreFile, minecraftVersion, localMetadata)) {
+ bail("Unable to download");
+ return 2;
+ }
+
+ }
+
+ addToClasspath(modcoreFile);
+
+ if (!isInitalized()) {
+ bail("Something went wrong and it did not add the jar to the class path. Local file exists? " + modcoreFile.exists());
+ return 3;
+ }
+ isRunningModCore = true;
+ return 0;
+ }
+
+
+ public static void addToClasspath(File file) {
+ try {
+ URL url = file.toURI().toURL();
+
+ ClassLoader classLoader = ModCoreInstaller.class.getClassLoader();
+ Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class);
+ method.setAccessible(true);
+ method.invoke(classLoader, url);
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
+ private static boolean download(String url, String version, File file, String mcver, JsonHolder versionData) {
+ url = url.replace(" ", "%20");
+ System.out.println("Downloading ModCore " + " version " + version + " from: " + url);
+
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ JFrame frame = new JFrame("ModCore Initializer");
+ JProgressBar bar = new JProgressBar();
+ JLabel label = new JLabel("Downloading ModCore " + version, SwingConstants.CENTER);
+ label.setSize(600, 120);
+ frame.getContentPane().add(label);
+ frame.getContentPane().add(bar);
+ GroupLayout layout = new GroupLayout(frame.getContentPane());
+ frame.getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(label, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE)
+ .addComponent(bar, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap()));
+ layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(label, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(bar, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
+ frame.setResizable(false);
+ bar.setBorderPainted(true);
+ bar.setMinimum(0);
+ bar.setStringPainted(true);
+ Font font = bar.getFont();
+ bar.setFont(new Font(font.getName(), font.getStyle(), font.getSize() * 2));
+ label.setFont(new Font(font.getName(), font.getStyle(), font.getSize() * 2));
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+
+ HttpURLConnection connection = null;
+ InputStream is = null;
+ try (FileOutputStream outputStream = new FileOutputStream(file)) {
+ URL u = new URL(url);
+ connection = (HttpURLConnection) u.openConnection();
+ connection.setRequestMethod("GET");
+ connection.setUseCaches(true);
+ connection.addRequestProperty("User-Agent", "Mozilla/4.76 (Sk1er Modcore Initializer)");
+ connection.setReadTimeout(15000);
+ connection.setConnectTimeout(15000);
+ connection.setDoOutput(true);
+ is = connection.getInputStream();
+ int contentLength = connection.getContentLength();
+ byte[] buffer = new byte[1024];
+ System.out.println("MAX: " + contentLength);
+ bar.setMaximum(contentLength);
+ int read;
+ bar.setValue(0);
+ while ((read = is.read(buffer)) > 0) {
+ outputStream.write(buffer, 0, read);
+ bar.setValue(bar.getValue() + 1024);
+ }
+ FileUtils.write(new File(dataDir, "metadata.json"), versionData.put(mcver, version).toString());
+ } catch (Exception e) {
+ e.printStackTrace();
+ frame.dispose();
+ return false;
+ } finally {
+ try {
+ if (connection != null) {
+ connection.disconnect();
+ }
+
+ if (is != null) {
+ is.close();
+ }
+ } catch (Exception e) {
+ System.out.println("Failed cleaning up ModCoreInstaller#download");
+ e.printStackTrace();
+ }
+ }
+
+ frame.dispose();
+ return true;
+ }
+
+ public static JsonHolder fetchJSON(String url) {
+ return new JsonHolder(fetchString(url));
+ }
+
+ public static String fetchString(String url) {
+ url = url.replace(" ", "%20");
+ System.out.println("Fetching " + url);
+
+ HttpURLConnection connection = null;
+ InputStream is = null;
+ try {
+ URL u = new URL(url);
+ connection = (HttpURLConnection) u.openConnection();
+ connection.setRequestMethod("GET");
+ connection.setUseCaches(true);
+ connection.addRequestProperty("User-Agent", "Mozilla/4.76 (Sk1er ModCore)");
+ connection.setReadTimeout(15000);
+ connection.setConnectTimeout(15000);
+ connection.setDoOutput(true);
+ is = connection.getInputStream();
+ return IOUtils.toString(is, Charset.defaultCharset());
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (connection != null) {
+ connection.disconnect();
+ }
+
+ if (is != null) {
+ is.close();
+ }
+ } catch (Exception e) {
+ System.out.println("Failed cleaning up ModCoreInstaller#fetchString");
+ e.printStackTrace();
+ }
+ }
+
+ return "Failed to fetch";
+ }
+
+
+ //Added because we need to use before ModCore is loaded
+ static class JsonHolder {
+ private JsonObject object;
+
+ public JsonHolder(JsonObject object) {
+ this.object = object;
+ }
+
+ public JsonHolder(String raw) {
+ if (raw == null)
+ object = new JsonObject();
+ else
+ try {
+ this.object = new JsonParser().parse(raw).getAsJsonObject();
+ } catch (Exception e) {
+ this.object = new JsonObject();
+ e.printStackTrace();
+ }
+ }
+
+ public JsonHolder() {
+ this(new JsonObject());
+ }
+
+ @Override
+ public String toString() {
+ if (object != null)
+ return object.toString();
+ return "{}";
+ }
+
+ public JsonHolder put(String key, boolean value) {
+ object.addProperty(key, value);
+ return this;
+ }
+
+ public void mergeNotOverride(JsonHolder merge) {
+ merge(merge, false);
+ }
+
+ public void mergeOverride(JsonHolder merge) {
+ merge(merge, true);
+ }
+
+ public void merge(JsonHolder merge, boolean override) {
+ JsonObject object = merge.getObject();
+ for (String s : merge.getKeys()) {
+ if (override || !this.has(s))
+ put(s, object.get(s));
+ }
+ }
+
+ private void put(String s, JsonElement element) {
+ this.object.add(s, element);
+ }
+
+ public JsonHolder put(String key, String value) {
+ object.addProperty(key, value);
+ return this;
+ }
+
+ public JsonHolder put(String key, int value) {
+ object.addProperty(key, value);
+ return this;
+ }
+
+ public JsonHolder put(String key, double value) {
+ object.addProperty(key, value);
+ return this;
+ }
+
+ public JsonHolder put(String key, long value) {
+ object.addProperty(key, value);
+ return this;
+ }
+
+ private JsonHolder defaultOptJSONObject(String key, JsonObject fallBack) {
+ try {
+ return new JsonHolder(object.get(key).getAsJsonObject());
+ } catch (Exception e) {
+ return new JsonHolder(fallBack);
+ }
+ }
+
+ public JsonArray defaultOptJSONArray(String key, JsonArray fallback) {
+ try {
+ return object.get(key).getAsJsonArray();
+ } catch (Exception e) {
+ return fallback;
+ }
+ }
+
+ public JsonArray optJSONArray(String key) {
+ return defaultOptJSONArray(key, new JsonArray());
+ }
+
+
+ public boolean has(String key) {
+ return object.has(key);
+ }
+
+ public long optLong(String key, long fallback) {
+ try {
+ return object.get(key).getAsLong();
+ } catch (Exception e) {
+ return fallback;
+ }
+ }
+
+ public long optLong(String key) {
+ return optLong(key, 0);
+ }
+
+ public boolean optBoolean(String key, boolean fallback) {
+ try {
+ return object.get(key).getAsBoolean();
+ } catch (Exception e) {
+ return fallback;
+ }
+ }
+
+ public boolean optBoolean(String key) {
+ return optBoolean(key, false);
+ }
+
+ public JsonObject optActualJSONObject(String key) {
+ try {
+ return object.get(key).getAsJsonObject();
+ } catch (Exception e) {
+ return new JsonObject();
+ }
+ }
+
+ public JsonHolder optJSONObject(String key) {
+ return defaultOptJSONObject(key, new JsonObject());
+ }
+
+
+ public int optInt(String key, int fallBack) {
+ try {
+ return object.get(key).getAsInt();
+ } catch (Exception e) {
+ return fallBack;
+ }
+ }
+
+ public int optInt(String key) {
+ return optInt(key, 0);
+ }
+
+
+ public String defaultOptString(String key, String fallBack) {
+ try {
+ return object.get(key).getAsString();
+ } catch (Exception e) {
+ return fallBack;
+ }
+ }
+
+ public String optString(String key) {
+ return defaultOptString(key, "");
+ }
+
+
+ public double optDouble(String key, double fallBack) {
+ try {
+ return object.get(key).getAsDouble();
+ } catch (Exception e) {
+ return fallBack;
+ }
+ }
+
+ public List<String> getKeys() {
+ List<String> tmp = new ArrayList<>();
+ for (Map.Entry<String, JsonElement> e : object.entrySet()) {
+ tmp.add(e.getKey());
+ }
+ return tmp;
+ }
+
+ public double optDouble(String key) {
+ return optDouble(key, 0.0);
+ }
+
+
+ public JsonObject getObject() {
+ return object;
+ }
+
+ public boolean isNull(String key) {
+ return object.has(key) && object.get(key).isJsonNull();
+ }
+
+ public JsonHolder put(String values, JsonHolder values1) {
+ return put(values, values1.getObject());
+ }
+
+ public JsonHolder put(String values, JsonObject object) {
+ this.object.add(values, object);
+ return this;
+ }
+
+ public void put(String blacklisted, JsonArray jsonElements) {
+ this.object.add(blacklisted, jsonElements);
+ }
+
+ public void remove(String header) {
+ object.remove(header);
+ }
+ }
+
+
+} \ No newline at end of file
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveMod.java b/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveMod.java
index 75a0a5e..0133ff1 100644
--- a/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveMod.java
+++ b/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveMod.java
@@ -1,7 +1,6 @@
package me.djtheredstoner.perspectivemod;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
+import me.djtheredstoner.perspectivemod.commands.PerspectiveModCommand;
import me.djtheredstoner.perspectivemod.config.PerspectiveModConfig;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
@@ -12,23 +11,18 @@ import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
-import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
-import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
-import java.io.File;
-
-@Mod(modid = "djperspectivemod", name = "Perspective Mod v4", version = "4.1", acceptedMinecraftVersions = "[1.8.9]", clientSideOnly = true)
+@Mod(modid = "djperspectivemod", name = "Perspective Mod v4", version = "4.2", acceptedMinecraftVersions = "[1.8.9]", clientSideOnly = true)
public class PerspectiveMod {
private static final Minecraft mc = Minecraft.getMinecraft();
- private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static final KeyBinding perspectiveKey = new KeyBinding("Perspective", Keyboard.KEY_LMENU, "Perspective Mod");
private static final Logger logger = LogManager.getLogger("Perspective Mod v4");
@@ -40,14 +34,12 @@ public class PerspectiveMod {
private static int previousPerspective = 0;
@Mod.EventHandler
- public void preInit(FMLPreInitializationEvent event) {
- File configFile = new File(event.getModConfigurationDirectory(), "perspectivemodv4.json");
- loadConfig(configFile);
- Runtime.getRuntime().addShutdownHook(new Thread(() -> saveConfig(configFile)));
- }
-
- @Mod.EventHandler
public void init(FMLInitializationEvent event) {
+ ModCoreInstaller.initializeModCore(Minecraft.getMinecraft().mcDataDir);
+
+ config = new PerspectiveModConfig();
+ config.preload();
+
ClientRegistry.registerKeyBinding(perspectiveKey);
ClientCommandHandler.instance.registerCommand(new PerspectiveModCommand());
MinecraftForge.EVENT_BUS.register(this);
@@ -117,6 +109,10 @@ public class PerspectiveMod {
float f3 = (float) mc.mouseHelper.deltaX * f2;
float f4 = (float) mc.mouseHelper.deltaY * f2;
+ if(config.invertPitch) {
+ f4 = -f4;
+ }
+
cameraYaw += f3 * 0.15F;
cameraPitch += f4 * 0.15F;
@@ -131,28 +127,4 @@ public class PerspectiveMod {
perspectiveToggled = false;
mc.gameSettings.thirdPersonView = previousPerspective;
}
-
- public static void loadConfig(File configFile) {
- if (configFile.exists()) {
- try {
- String json = FileUtils.readFileToString(configFile);
- config = gson.fromJson(json, PerspectiveModConfig.class);
- } catch (Exception e) {
- logger.error("Error Loading Config, try deleting the file.");
- e.printStackTrace();
- }
- } else {
- config = new PerspectiveModConfig();
- saveConfig(configFile);
- }
- }
-
- public static void saveConfig(File configFile) {
- try {
- String json = gson.toJson(config);
- FileUtils.write(configFile, json);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
}
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveModCommand.java b/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveModCommand.java
deleted file mode 100644
index 3eae96a..0000000
--- a/src/main/java/me/djtheredstoner/perspectivemod/PerspectiveModCommand.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package me.djtheredstoner.perspectivemod;
-
-import net.minecraft.command.CommandBase;
-import net.minecraft.command.CommandException;
-import net.minecraft.command.ICommandSender;
-import net.minecraft.util.ChatComponentText;
-
-import java.util.Collections;
-import java.util.List;
-
-public class PerspectiveModCommand extends CommandBase {
-
- private final String PREFIX = "§c[§6Perspective Mod§c] §r";
-
- @Override
- public String getCommandName() {
- return "perspectivemod";
- }
-
- @Override
- public List<String> getCommandAliases() {
- return Collections.singletonList("pmod");
- }
-
- @Override
- public String getCommandUsage(ICommandSender sender) {
- return "§6Perspective Mod Help\n" +
- "§b/pmod <enable|disable> §7- Enables or disables the mod.\n" +
- "§b/pmod mode <hold|toggle> §7- Changes the mode.\n" +
- "§7Edit the keybind in the minecraft controls menu.";
- }
-
- @Override
- public void processCommand(ICommandSender sender, String[] args) throws CommandException {
- if (args.length > 0 && args.length < 3) {
- String arg = args[0];
- if (arg.equalsIgnoreCase("enable")) {
- PerspectiveMod.config.modEnabled = true;
-
- sendMessage(sender, "§bMod §aEnabled§b.");
- } else if (arg.equalsIgnoreCase("disable")) {
- PerspectiveMod.config.modEnabled = false;
-
- sendMessage(sender, "§bMod §cDisabled§b.");
- } else if (arg.equalsIgnoreCase("mode")) {
- if (args.length == 2) {
- String mode = args[1];
- if (mode.equalsIgnoreCase("hold")) {
- PerspectiveMod.config.holdMode = true;
-
- sendMessage(sender, "§bMode set to hold.");
- } else if (mode.equalsIgnoreCase("toggle")) {
- PerspectiveMod.config.holdMode = false;
-
- sendMessage(sender, "§bMode set to toggle.");
- } else {
- sendMessage(sender, "§cInvalid mode. Valid mode are hold and toggle.");
- }
- } else {
- sendMessage(sender, "§cYou must specify a mode. Valid Modes are hold and toggle.");
- }
- } else {
- sendHelp(sender);
- }
- } else {
- sendHelp(sender);
- }
- }
-
- @Override
- public int getRequiredPermissionLevel() {
- return -1;
- }
-
- private void sendHelp(ICommandSender sender) {
- sendMessage(sender, getCommandUsage(sender), false);
- }
-
- private void sendMessage(ICommandSender sender, String message, boolean addPrefix) {
- sender.addChatMessage(new ChatComponentText((addPrefix ? PREFIX : "") + message));
- }
-
- private void sendMessage(ICommandSender sender, String message) {
- sendMessage(sender, message, true);
- }
-}
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/ClassTransformer.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/ClassTransformer.java
index 63f693e..c7db68b 100644
--- a/src/main/java/me/djtheredstoner/perspectivemod/asm/ClassTransformer.java
+++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/ClassTransformer.java
@@ -2,6 +2,7 @@ package me.djtheredstoner.perspectivemod.asm;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
+import me.djtheredstoner.perspectivemod.asm.transformers.ActiveRenderInfoTransformer;
import me.djtheredstoner.perspectivemod.asm.transformers.EntityRendererTransformer;
import me.djtheredstoner.perspectivemod.asm.transformers.MinecraftTransformer;
import me.djtheredstoner.perspectivemod.asm.transformers.RenderManagerTransformer;
@@ -34,6 +35,7 @@ public class ClassTransformer implements IClassTransformer {
registerTransformer(new EntityRendererTransformer());
registerTransformer(new RenderManagerTransformer());
registerTransformer(new MinecraftTransformer());
+ registerTransformer(new ActiveRenderInfoTransformer());
}
private void registerTransformer(ITransformer transformer) {
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/ActiveRenderInfoHook.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/ActiveRenderInfoHook.java
new file mode 100644
index 0000000..e60ede4
--- /dev/null
+++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/ActiveRenderInfoHook.java
@@ -0,0 +1,16 @@
+package me.djtheredstoner.perspectivemod.asm.hooks;
+
+import me.djtheredstoner.perspectivemod.PerspectiveMod;
+import net.minecraft.entity.player.EntityPlayer;
+
+public class ActiveRenderInfoHook {
+
+ public static float rotationYawHook(EntityPlayer entity) {
+ return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraYaw : entity.rotationYaw;
+ }
+
+ public static float rotationPitchHook(EntityPlayer entity) {
+ return PerspectiveMod.perspectiveToggled ? PerspectiveMod.cameraPitch : entity.rotationPitch;
+ }
+
+}
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/EntityRendererHook.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/EntityRendererHook.java
index 3ee3c9e..193affb 100644
--- a/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/EntityRendererHook.java
+++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/hooks/EntityRendererHook.java
@@ -26,4 +26,7 @@ public class EntityRendererHook {
return PerspectiveMod.overrideMouse();
}
+ public static double distanceHook(double value) {
+ return value;
+ }
}
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/ActiveRenderInfoTransformer.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/ActiveRenderInfoTransformer.java
new file mode 100644
index 0000000..531ec90
--- /dev/null
+++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/ActiveRenderInfoTransformer.java
@@ -0,0 +1,68 @@
+package me.djtheredstoner.perspectivemod.asm.transformers;
+
+import me.djtheredstoner.perspectivemod.asm.ITransformer;
+import org.objectweb.asm.tree.*;
+
+import java.util.ListIterator;
+
+import static org.objectweb.asm.Opcodes.*;
+
+public class ActiveRenderInfoTransformer implements ITransformer {
+
+ private static final String HOOK_CLASS = "me/djtheredstoner/perspectivemod/asm/hooks/ActiveRenderInfoHook";
+
+ @Override
+ public String[] getClassName() {
+ return new String[]{"net.minecraft.client.renderer.ActiveRenderInfo"};
+ }
+
+ @Override
+ public void transform(ClassNode classNode, String name) {
+ for (MethodNode method : classNode.methods) {
+ String methodName = mapMethodName(classNode, method);
+
+ if (methodName.equals("updateRenderInfo") || methodName.equals("func_74583_a")) {
+ ListIterator<AbstractInsnNode> iterator = method.instructions.iterator();
+
+ while (iterator.hasNext()) {
+ AbstractInsnNode next = iterator.next();
+
+ if(next.getOpcode() == GETFIELD) {
+ FieldInsnNode insn = (FieldInsnNode) next;
+
+ String ownerName = mapClassName(insn.owner);
+ String fieldName = mapClassName(insn.name);
+
+ if(ownerName.equals("net/minecraft/entity/player/EntityPlayer") && insn.desc.equals("F")) {
+ InsnList insnList = null;
+
+ switch (fieldName) {
+ case "rotationPitch":
+ case "field_70125_A":
+ insnList = insertRotationHook("Pitch");
+ break;
+ case "rotationYaw":
+ case "field_70177_z":
+ insnList = insertRotationHook("Yaw");
+ break;
+ }
+
+ if(insnList != null) {
+ method.instructions.insertBefore(insn, insnList);
+ method.instructions.remove(insn);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private InsnList insertRotationHook(String field) {
+ InsnList insnList = new InsnList();
+
+ insnList.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, "rotation" + field + "Hook", "(Lnet/minecraft/entity/player/EntityPlayer;)F", false));
+
+ return insnList;
+ }
+}
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/EntityRendererTransformer.java b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/EntityRendererTransformer.java
index dadb1e0..ac47621 100644
--- a/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/EntityRendererTransformer.java
+++ b/src/main/java/me/djtheredstoner/perspectivemod/asm/transformers/EntityRendererTransformer.java
@@ -3,6 +3,8 @@ package me.djtheredstoner.perspectivemod.asm.transformers;
import me.djtheredstoner.perspectivemod.asm.ITransformer;
import org.objectweb.asm.tree.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.Iterator;
import static org.objectweb.asm.Opcodes.*;
@@ -37,7 +39,7 @@ public class EntityRendererTransformer implements ITransformer {
String ownerName = mapClassName(insn.owner);
String fieldName = mapFieldNameFromNode(insn);
- if(ownerName.equals("net/minecraft/entity/Entity" )&& insn.desc.equals("F")) {
+ if(ownerName.equals("net/minecraft/entity/Entity" ) && insn.desc.equals("F")) {
InsnList insnList = null;
@@ -65,9 +67,14 @@ public class EntityRendererTransformer implements ITransformer {
method.instructions.remove(insn);
}
}
- }
- }
+ } /*else if (next.getOpcode() == DLOAD) {
+ VarInsnNode insn = (VarInsnNode) next;
+ if(insn.getPrevious().getOpcode() == FCONST_0 && insn.getNext().getOpcode() == DNEG) {
+ method.instructions.insert(insn, insertDistanceHook());
+ }
+ }*/
+ }
} else if (methodName.equals("updateCameraAndRender") || methodName.equals("func_181560_a")) {
Iterator<AbstractInsnNode> iterator = method.instructions.iterator();
@@ -89,10 +96,15 @@ public class EntityRendererTransformer implements ITransformer {
}
}
}
+ //Poggers Ultra FPS Praseodymium mode.
+ /* else if (methodName.equals("renderWorldPass") || methodName.equals("func_175068_a")) {
+
+ method.instructions.insert(method.instructions.getFirst(), new InsnNode(RETURN));
+ }*/
}
}
- public InsnList insertRotationHook(String field) {
+ private InsnList insertRotationHook(String field) {
InsnList list = new InsnList();
list.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, field + "Hook", "(Lnet/minecraft/entity/Entity;)F", false));
@@ -100,11 +112,19 @@ public class EntityRendererTransformer implements ITransformer {
return list;
}
- public InsnList insertMouseHook() {
+ private InsnList insertMouseHook() {
InsnList list = new InsnList();
list.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, "mouseHook", "(Lnet/minecraft/client/Minecraft;)Z", false));
return list;
}
+
+ private InsnList insertDistanceHook() {
+ InsnList list = new InsnList();
+
+ list.add(new MethodInsnNode(INVOKESTATIC, HOOK_CLASS, "distanceHook", "(D)D", false));
+
+ return list;
+ }
}
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/commands/PerspectiveModCommand.java b/src/main/java/me/djtheredstoner/perspectivemod/commands/PerspectiveModCommand.java
new file mode 100644
index 0000000..68dd051
--- /dev/null
+++ b/src/main/java/me/djtheredstoner/perspectivemod/commands/PerspectiveModCommand.java
@@ -0,0 +1,60 @@
+package me.djtheredstoner.perspectivemod.commands;
+
+import club.sk1er.mods.core.ModCore;
+import me.djtheredstoner.perspectivemod.PerspectiveMod;
+import net.minecraft.client.Minecraft;
+import net.minecraft.command.CommandBase;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.util.ChatComponentText;
+
+import java.util.Collections;
+import java.util.List;
+
+public class PerspectiveModCommand extends CommandBase {
+
+ private final String PREFIX = "§c[§6Perspective Mod§c] §r";
+
+ @Override
+ public String getCommandName() {
+ return "perspectivemod";
+ }
+
+ @Override
+ public List<String> getCommandAliases() {
+ return Collections.singletonList("pmod");
+ }
+
+ @Override
+ public String getCommandUsage(ICommandSender sender) {
+ return "§6Perspective Mod Help\n" +
+ "§b/pmod <enable|disable> §7- Enables or disables the mod.\n" +
+ "§b/pmod mode <hold|toggle> §7- Changes the mode.\n" +
+ "§7Edit the keybind in the minecraft controls menu.";
+ }
+
+ @Override
+ public void processCommand(ICommandSender sender, String[] args) {
+ if (args.length == 1 && args[0].equals("eW91IGZvdW5kIGEgc2VjcmV0IQo=")) {
+ sendMessage("you found a secret!");
+ } else {
+ ModCore.getInstance().getGuiHandler().open(PerspectiveMod.config.gui());
+ }
+ }
+
+ @Override
+ public int getRequiredPermissionLevel() {
+ return -1;
+ }
+
+ private void sendHelp() {
+ sendMessage(getCommandUsage(Minecraft.getMinecraft().thePlayer), false);
+ }
+
+ private void sendMessage(String message, boolean addPrefix) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText((addPrefix ? PREFIX : "") + message));
+ }
+
+ private void sendMessage(String message) {
+ sendMessage(message, true);
+ }
+}
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/config/PerspectiveModConfig.java b/src/main/java/me/djtheredstoner/perspectivemod/config/PerspectiveModConfig.java
index d4b1922..3f15069 100644
--- a/src/main/java/me/djtheredstoner/perspectivemod/config/PerspectiveModConfig.java
+++ b/src/main/java/me/djtheredstoner/perspectivemod/config/PerspectiveModConfig.java
@@ -1,8 +1,42 @@
package me.djtheredstoner.perspectivemod.config;
-public class PerspectiveModConfig {
+import club.sk1er.vigilance.Vigilant;
+import club.sk1er.vigilance.data.Property;
+import club.sk1er.vigilance.data.PropertyType;
+import java.io.File;
+
+public class PerspectiveModConfig extends Vigilant {
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Perspective Mod",
+ category = "General",
+ subcategory = "General",
+ description = "Toggle Perspective Mod entirely."
+ )
public boolean modEnabled = true;
+
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Hold Mode",
+ category = "General",
+ subcategory = "General",
+ description = "Return to normal perspective after releasing keybind."
+ )
public boolean holdMode = true;
+ @Property(
+ type = PropertyType.SWITCH,
+ name = "Invert Pitch",
+ category = "General",
+ subcategory = "General",
+ description = "Invert the pitch while in perspective (same as blc/lunar)."
+ )
+ public boolean invertPitch = false;
+
+ public PerspectiveModConfig() {
+ super(new File("./config/perspectivemodv4.toml"));
+ initialize();
+ }
}
diff --git a/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModTweaker.java b/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModTweaker.java
index 695f7a2..f5128f0 100644
--- a/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModTweaker.java
+++ b/src/main/java/me/djtheredstoner/perspectivemod/forge/PerspectiveModTweaker.java
@@ -1,5 +1,6 @@
package me.djtheredstoner.perspectivemod.forge;
+import me.djtheredstoner.perspectivemod.ModCoreInstaller;
import me.djtheredstoner.perspectivemod.asm.ClassTransformer;
import net.minecraft.launchwrapper.Launch;
import net.minecraftforge.common.ForgeVersion;
@@ -52,6 +53,17 @@ public class PerspectiveModTweaker implements IFMLLoadingPlugin {
@Override
public String[] getASMTransformerClass() {
+ int initialize = ModCoreInstaller.initialize(Launch.minecraftHome, "1.8.9");
+
+ if (ModCoreInstaller.isErrored() || initialize != 0 && initialize != -1) {
+ System.out.println("Failed to load Sk1er Modcore - " + initialize + " - " + ModCoreInstaller.getError());
+ }
+ // If true the classes are loaded
+ if (ModCoreInstaller.isIsRunningModCore()) {
+ // register ModCore's class transformer
+ return new String[]{"club.sk1er.mods.core.forge.ClassTransformer", ClassTransformer.class.getName()};
+ }
+
return new String[]{ClassTransformer.class.getName()};
}
diff --git a/src/main/resources/LICENSE b/src/main/resources/LICENSE
deleted file mode 100644
index 45ae6c4..0000000
--- a/src/main/resources/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020 DJtheRedstoner
-
-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. \ No newline at end of file