Skip to content

Commit

Permalink
new: Add mixin rule override-ability, disable core overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
FlashyReese committed Jul 23, 2023
1 parent 7d0d742 commit 56140b9
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 3 deletions.
64 changes: 62 additions & 2 deletions src/main/java/me/jellysquid/mods/sodium/mixin/MixinConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class MixinConfig {
private MixinConfig() {
// Defines the default rules which can be configured by the user or other mods.
// You must manually add a rule for any new mixins not covered by an existing package rule.
this.addMixinRule("core", true); // TODO: Don't actually allow the user to disable this
this.addMixinRule("core", true, false);

this.addMixinRule("features", true);
this.addMixinRule("features.gui", true);
Expand Down Expand Up @@ -91,9 +91,20 @@ private MixinConfig() {
* @param enabled True if the rule will be enabled by default, otherwise false
*/
private void addMixinRule(String mixin, boolean enabled) {
this.addMixinRule(mixin, enabled, true);
}

/**
* Defines a Mixin rule which can be configured by users and other mods.
* @throws IllegalStateException If a rule with that name already exists
* @param mixin The name of the mixin package which will be controlled by this rule
* @param enabled True if the rule will be enabled by default, otherwise false
* @param overrideable True if the rule will be override-able by users/mods, otherwise false
*/
private void addMixinRule(String mixin, boolean enabled, boolean overrideable) {
String name = getMixinRuleName(mixin);

if (this.options.putIfAbsent(name, new MixinOption(name, enabled, false)) != null) {
if (this.options.putIfAbsent(name, new MixinOption(name, enabled, false, overrideable)) != null) {
throw new IllegalStateException("Mixin rule already defined: " + mixin);
}
}
Expand All @@ -110,6 +121,11 @@ private void readProperties(Properties props) {
continue;
}

if (!option.isOverrideable()) {
LOGGER.warn("User attempted to override option '{}' that is not overrideable, ignoring", key);
continue;
}

boolean enabled;

if (value.equalsIgnoreCase("true")) {
Expand Down Expand Up @@ -152,6 +168,11 @@ private void applyModOverride(ModMetadata meta, String name, CustomValue value)
return;
}

if (!option.isOverrideable()) {
LOGGER.warn("Mod '{}' attempted to override option '{}', which is not overrideable, ignoring", meta.getId(), name);
return;
}

if (value.getType() != CustomValue.CvType.BOOLEAN) {
LOGGER.warn("Mod '{}' attempted to override option '{}' with an invalid value, ignoring", meta.getId(), name);
return;
Expand All @@ -168,6 +189,41 @@ private void applyModOverride(ModMetadata meta, String name, CustomValue value)
option.addModOverride(enabled, meta.getId());
}
}

private void applyOverrideableChecks() {
for (MixinOption parentOption : this.options.values()) {
for (MixinOption childOption : this.options.values()) {
if (childOption.getName().startsWith(parentOption.getName() + '.') && childOption != parentOption) {
if (!parentOption.isOverrideable() && childOption.isOverrideable()) {
LOGGER.warn("Mixin option '{}' cannot be set as overrideable because its parent option '{}' is not overrideable. The mixin option will be treated as not overrideable.", childOption.getName(), parentOption.getName());
childOption.setOverrideable(false);
}
}
}
}
}

private void applyOverrideStates() {
for (MixinOption parentOption : this.options.values()) {
for (MixinOption childOption : this.options.values()) {
if (childOption.getName().startsWith(parentOption.getName() + '.') && childOption != parentOption) {
// Marks every child to parent state
if (childOption.isOverrideable() && (parentOption.isUserDefined() || parentOption.isModDefined())) {
childOption.setEnabled(parentOption.isEnabled(), parentOption.isUserDefined());
if (parentOption.isModDefined()) {
parentOption.getDefiningMods().forEach(mod -> childOption.addModOverride(parentOption.isEnabled(), mod));
}
} else {
if (parentOption.isUserDefined()) {
LOGGER.warn("User attempted to override option '{}' that is not overrideable by overriding '{}', ignoring", childOption.getName(), parentOption.getName());
} else if (parentOption.isModDefined()) {
LOGGER.warn("Mod '{}' attempted to override option '{}' that is not overrideable by overriding '{}', ignoring", parentOption.getDefiningMods(), childOption.getName(), parentOption.getName());
}
}
}
}
}
}

/**
* Returns the effective option for the specified class name. This traverses the package path of the given mixin
Expand Down Expand Up @@ -215,7 +271,9 @@ public static MixinConfig load(File file) {
}

MixinConfig config = new MixinConfig();
config.applyOverrideableChecks();
config.applyModOverrides();
config.applyOverrideStates();

return config;
}
Expand All @@ -229,8 +287,10 @@ public static MixinConfig load(File file) {
}

MixinConfig config = new MixinConfig();
config.applyOverrideableChecks();
config.readProperties(props);
config.applyModOverrides();
config.applyOverrideStates();

return config;
}
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/me/jellysquid/mods/sodium/mixin/MixinOption.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ public class MixinOption {
private Set<String> modDefined = null;
private boolean enabled;
private boolean userDefined;
private boolean overrideable;

public MixinOption(String name, boolean enabled, boolean userDefined) {
public MixinOption(String name, boolean enabled, boolean userDefined, boolean overrideable) {
this.name = name;
this.enabled = enabled;
this.userDefined = userDefined;
this.overrideable = overrideable;
}

public void setOverrideable(boolean overrideable) {
this.overrideable = overrideable;
}

public void setEnabled(boolean enabled, boolean userDefined) {
Expand Down Expand Up @@ -49,6 +55,10 @@ public boolean isModDefined() {
return this.modDefined != null;
}

public boolean isOverrideable() {
return overrideable;
}

public String getName() {
return this.name;
}
Expand Down

0 comments on commit 56140b9

Please sign in to comment.