Move Optifine code out of ReflectionHandler and into AbstractOptifineAccessor
This commit is contained in:
@@ -37,7 +37,7 @@ public interface IBindable
|
||||
* If no circular dependencies are required this method
|
||||
* doesn't have to be implemented.
|
||||
*/
|
||||
public default void finishDelayedSetup() { }
|
||||
default void finishDelayedSetup() { }
|
||||
|
||||
/**
|
||||
* Returns if this dependency has been setup yet. <Br> <Br>
|
||||
@@ -45,6 +45,6 @@ public interface IBindable
|
||||
* If this object doesn't require a delayed setup, this
|
||||
* method doesn't have to be implemented and should always return true.
|
||||
*/
|
||||
public default boolean getDelayedSetupComplete() { return true; }
|
||||
default boolean getDelayedSetupComplete() { return true; }
|
||||
|
||||
}
|
||||
|
||||
@@ -35,18 +35,13 @@ import com.seibel.lod.core.interfaces.dependencyInjection.IBindable;
|
||||
* different MC versions.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 3-5-2022
|
||||
* @version 2022-11-24
|
||||
*/
|
||||
public interface IReflectionHandler extends IBindable
|
||||
{
|
||||
/** @return Whether Optifine is set to render fog or not. */
|
||||
EFogDrawMode getFogDrawMode();
|
||||
|
||||
/** @return if Vivecraft is present. Attempts to find the "VRRenderer" class. */
|
||||
boolean vivecraftPresent();
|
||||
|
||||
/** @return if Sodium (or a sodium like) mod is present. Attempts to find the "SodiumWorldRenderer" class. */
|
||||
/** @return if Sodium (or a sodium like) mod is present. */
|
||||
boolean sodiumPresent();
|
||||
|
||||
boolean optifinePresent();
|
||||
|
||||
}
|
||||
|
||||
@@ -20,186 +20,69 @@
|
||||
package com.seibel.lod.core;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.seibel.lod.api.enums.rendering.EFogDrawMode;
|
||||
|
||||
/**
|
||||
* A singleton used to get variables from methods
|
||||
* where they are private or potentially absent.
|
||||
* For example: the fog setting in Optifine or the
|
||||
* presence/absence of Vivecraft.
|
||||
* A singleton used to determine if a class is present or
|
||||
* access variables from methods where they are private
|
||||
* or potentially absent. <br><br>
|
||||
*
|
||||
* For example: presence/absence of Optifine.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2022-7-15
|
||||
* @version 2022-11-24
|
||||
*/
|
||||
public class ReflectionHandler implements IReflectionHandler
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||
|
||||
public static ReflectionHandler instance;
|
||||
|
||||
private Field ofFogField = null;
|
||||
private Object mcOptionsObject;
|
||||
public static final ReflectionHandler INSTANCE = new ReflectionHandler();
|
||||
|
||||
// populated when the methods are called the first time
|
||||
private Boolean sodiumPresent = null;
|
||||
private boolean optifinePresent = false;
|
||||
|
||||
private boolean delayedSetupDone = false;
|
||||
private Boolean optifinePresent = false;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void finishDelayedSetup()
|
||||
{
|
||||
mcOptionsObject = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class).getOptionsObject();
|
||||
setupFogField(mcOptionsObject.getClass().getDeclaredFields());
|
||||
|
||||
this.delayedSetupDone = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDelayedSetupComplete() { return this.delayedSetupDone; }
|
||||
|
||||
private ReflectionHandler()
|
||||
{
|
||||
mcOptionsObject = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ReflectionHandler just created
|
||||
* @throws IllegalStateException if a ReflectionHandler already exists
|
||||
*/
|
||||
public static ReflectionHandler createSingleton() throws IllegalStateException
|
||||
{
|
||||
if (instance != null)
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
instance = new ReflectionHandler();
|
||||
return instance;
|
||||
}
|
||||
private ReflectionHandler() { }
|
||||
|
||||
|
||||
|
||||
//===================//
|
||||
// is [mod] present? //
|
||||
//===================//
|
||||
|
||||
|
||||
|
||||
/** finds the Optifine fog type field */
|
||||
private void setupFogField(Field[] optionFields)
|
||||
{
|
||||
// try and find the ofFogType variable in gameSettings
|
||||
for (Field field : optionFields)
|
||||
{
|
||||
if (field.getName().equals("ofFogType"))
|
||||
{
|
||||
optifinePresent = true;
|
||||
ofFogField = field;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// we didn't find the field,
|
||||
// either optifine isn't installed, or
|
||||
// optifine changed the name of the variable
|
||||
LOGGER.info("Unable to find the Optifine fog field. If Optifine isn't installed this can be ignored.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get what type of fog optifine is currently set to render.
|
||||
* @return the fog quality
|
||||
*/
|
||||
@Override
|
||||
public EFogDrawMode getFogDrawMode()
|
||||
{
|
||||
if (ofFogField == null)
|
||||
{
|
||||
// either optifine isn't installed,
|
||||
// the variable name was changed, or
|
||||
// the setup method wasn't called yet.
|
||||
return EFogDrawMode.FOG_ENABLED;
|
||||
}
|
||||
|
||||
int returnNum = 0;
|
||||
|
||||
try
|
||||
{
|
||||
returnNum = (int) ofFogField.get(mcOptionsObject);
|
||||
}
|
||||
catch (IllegalArgumentException | IllegalAccessException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
switch (returnNum)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
// optifine's "default" option,
|
||||
// it should never be called in this case
|
||||
|
||||
// normal options
|
||||
case 1: // fast
|
||||
case 2: // fancy
|
||||
return EFogDrawMode.FOG_ENABLED;
|
||||
case 3: // off
|
||||
return EFogDrawMode.FOG_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Detect if Vivecraft is present. Attempts to find the "VRRenderer" class. */
|
||||
@Override
|
||||
public boolean vivecraftPresent()
|
||||
{
|
||||
try
|
||||
{
|
||||
Class.forName("org.vivecraft.provider.VRRenderer");
|
||||
return true;
|
||||
}
|
||||
catch (ClassNotFoundException ignored)
|
||||
{
|
||||
LOGGER.info(ReflectionHandler.class.getSimpleName() + ": Vivecraft not detected.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean optifinePresent()
|
||||
{
|
||||
return optifinePresent;
|
||||
if (this.optifinePresent == null)
|
||||
{
|
||||
// call the base accessor so we don't have duplicate code
|
||||
this.optifinePresent = AbstractOptifineAccessor.isOptifinePresent();
|
||||
}
|
||||
return this.optifinePresent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean sodiumPresent()
|
||||
{
|
||||
// we don't want to run a potentially expensive
|
||||
// reflection search operation every time this method is called
|
||||
if (sodiumPresent == null)
|
||||
if (this.sodiumPresent == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Class.forName("me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer");
|
||||
|
||||
sodiumPresent = true;
|
||||
this.sodiumPresent = true;
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
sodiumPresent = false;
|
||||
this.sodiumPresent = false;
|
||||
}
|
||||
}
|
||||
|
||||
return sodiumPresent;
|
||||
return this.sodiumPresent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
/**
|
||||
* This class takes care of dependency injection for mods accessors. (for mod compatibility
|
||||
* This class takes care of dependency injection for mod accessors. (for mod compatibility
|
||||
* support). <Br> <Br>
|
||||
*
|
||||
* If a IModAccessor returns null either that means the mod isn't loaded in the game
|
||||
|
||||
@@ -21,10 +21,11 @@ package com.seibel.lod.core.render.fog;
|
||||
|
||||
import com.seibel.lod.api.enums.rendering.*;
|
||||
import com.seibel.lod.core.config.Config;
|
||||
import com.seibel.lod.core.IReflectionHandler;
|
||||
import com.seibel.lod.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.render.glObject.shader.Shader;
|
||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
||||
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -39,11 +40,11 @@ import static com.seibel.lod.core.render.glObject.GLProxy.GL_LOGGER;
|
||||
*
|
||||
* @author Leetom
|
||||
* @author James Seibel
|
||||
* @version 2022-4-14
|
||||
* @version 2022-11-24
|
||||
*/
|
||||
public class LodFogConfig
|
||||
{
|
||||
private static final IReflectionHandler REFLECTION_HANDLER = SingletonInjector.INSTANCE.get(IReflectionHandler.class);
|
||||
private static final IOptifineAccessor OPTIFINE = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
|
||||
private static final ILodConfigWrapperSingleton CONFIG = SingletonInjector.INSTANCE.get(ILodConfigWrapperSingleton.class);
|
||||
|
||||
public static final boolean DEBUG_DUMP_GENERATED_CODE = false;
|
||||
@@ -62,9 +63,10 @@ public class LodFogConfig
|
||||
public static LodFogConfig generateFogConfig()
|
||||
{
|
||||
EFogDrawMode fogMode = CONFIG.client().graphics().fogQuality().getFogDrawMode();
|
||||
if (fogMode == EFogDrawMode.USE_OPTIFINE_SETTING)
|
||||
fogMode = REFLECTION_HANDLER.getFogDrawMode();
|
||||
|
||||
if (fogMode == EFogDrawMode.USE_OPTIFINE_SETTING && OPTIFINE != null)
|
||||
{
|
||||
fogMode = OPTIFINE.getFogDrawMode();
|
||||
}
|
||||
return new LodFogConfig(fogMode);
|
||||
}
|
||||
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
package com.seibel.lod.core.wrapperInterfaces.modAccessor;
|
||||
|
||||
import com.seibel.lod.api.enums.rendering.EFogDrawMode;
|
||||
import com.seibel.lod.core.ReflectionHandler;
|
||||
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Contains any shared code between Optifine for Forge (official Optifine)
|
||||
* and Optifine on Fabric (unofficial ports).
|
||||
*
|
||||
* @version 2022-11-24
|
||||
* @author James Seibel
|
||||
*/
|
||||
public abstract class AbstractOptifineAccessor implements IOptifineAccessor
|
||||
{
|
||||
public Field ofFogField = null;
|
||||
public Object mcOptionsObject = null;
|
||||
|
||||
|
||||
|
||||
//=======//
|
||||
// setup //
|
||||
//=======//
|
||||
|
||||
public void finishDelayedSetup()
|
||||
{
|
||||
this.mcOptionsObject = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class).getOptionsObject();
|
||||
this.ofFogField = getOptifineFogField();
|
||||
}
|
||||
|
||||
/** Returns null if Optifine isn't installed. */
|
||||
public static Field getOptifineFogField()
|
||||
{
|
||||
Object mcOptions = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class).getOptionsObject();
|
||||
|
||||
// try and find the ofFogType variable in gameSettings
|
||||
for (Field field : mcOptions.getClass().getDeclaredFields())
|
||||
{
|
||||
if (field.getName().equals("ofFogType"))
|
||||
{
|
||||
return field;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should not be called frequently since this uses reflection calls to determine if Optifine is present. <br>
|
||||
* Use {@link ReflectionHandler#optifinePresent()} instead.
|
||||
*/
|
||||
public static boolean isOptifinePresent() { return getOptifineFogField() != null; }
|
||||
|
||||
|
||||
|
||||
//===================//
|
||||
// interface methods //
|
||||
//===================//
|
||||
|
||||
@Override
|
||||
public EFogDrawMode getFogDrawMode()
|
||||
{
|
||||
if (this.ofFogField == null)
|
||||
{
|
||||
// either optifine isn't installed,
|
||||
// the variable name was changed, or
|
||||
// the setup method wasn't called yet.
|
||||
return EFogDrawMode.FOG_ENABLED;
|
||||
}
|
||||
|
||||
int returnNum = 0;
|
||||
|
||||
try
|
||||
{
|
||||
returnNum = (int) this.ofFogField.get(this.mcOptionsObject);
|
||||
}
|
||||
catch (IllegalArgumentException | IllegalAccessException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
switch (returnNum)
|
||||
{
|
||||
default:
|
||||
case 0: // optifine's "default" option,
|
||||
// it should never be used, so default to fog Enabled
|
||||
|
||||
// normal options
|
||||
case 1: // fast
|
||||
case 2: // fancy
|
||||
return EFogDrawMode.FOG_ENABLED;
|
||||
case 3: // off
|
||||
return EFogDrawMode.FOG_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public double getRenderResolutionMultiplier()
|
||||
{
|
||||
/*
|
||||
* TODO remove comment when done, this is just here as reference
|
||||
* Returns the percentage multiplier of the screen's current resolution. <br>
|
||||
* 1.0 = 100% <br>
|
||||
* 1.5 = 150% <br>
|
||||
*/
|
||||
|
||||
// TODO
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -25,6 +25,8 @@ import com.seibel.lod.core.interfaces.dependencyInjection.IBindable;
|
||||
* @author Leetom
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IModAccessor extends IBindable {
|
||||
public interface IModAccessor extends IBindable
|
||||
{
|
||||
String getModName();
|
||||
|
||||
}
|
||||
|
||||
+9
-4
@@ -19,23 +19,28 @@
|
||||
|
||||
package com.seibel.lod.core.wrapperInterfaces.modAccessor;
|
||||
|
||||
import com.seibel.lod.api.enums.rendering.EFogDrawMode;
|
||||
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.pos.DhChunkPos;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashSet;
|
||||
|
||||
public interface IOptifineAccessor extends IModAccessor
|
||||
{
|
||||
|
||||
/** Can be null */
|
||||
HashSet<DhChunkPos> getNormalRenderedChunks();
|
||||
|
||||
/** Get what type of fog optifine is currently set to render. */
|
||||
EFogDrawMode getFogDrawMode();
|
||||
|
||||
/**
|
||||
* Returns the percentage multiplier of the screen's current resolution. <br>
|
||||
* 1.0 = 100% <br>
|
||||
* 1.5 = 150% <br>
|
||||
*/
|
||||
default double getRenderResolutionMultiplier()
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
double getRenderResolutionMultiplier();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user