Skip to content

Commit

Permalink
Remove the notion of client-only modules
Browse files Browse the repository at this point in the history
  • Loading branch information
quat1024 committed Oct 26, 2023
1 parent 0fc95cc commit 4dad565
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import org.objectweb.asm.Type;
import vazkii.quark.base.Quark;
import vazkii.zeta.module.ModuleFinder;
import vazkii.zeta.module.ModuleSide;
import vazkii.zeta.module.ZetaLoadModuleAnnotationData;
import vazkii.zeta.module.ZetaModule;

Expand All @@ -31,9 +30,7 @@ public Stream<ZetaLoadModuleAnnotationData> get() {
throw new RuntimeException("Exception getting QuarkModule (legacy)", e);
}

//quark doesnt have client-only modules so just load everything on the server too
//its hasSubscriptions/subscribeOn behavior is emulated to not break the dedi server for now
return ZetaLoadModuleAnnotationData.fromForgeThing(clazz, ad.annotationData(), ModuleSide.ANY);
return ZetaLoadModuleAnnotationData.fromForgeThing(clazz, ad.annotationData());
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public class ChestSearchingModule extends ZetaModule {
private static long lastClick;
private static int matched;

@OnlyIn(Dist.CLIENT)
@LoadEvent
public final void clientSetup(ZClientSetup event) {
InventoryButtonHandler.addButtonProvider(this, ButtonTargetType.CONTAINER_INVENTORY, 1, (parent, x, y) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,27 @@
import vazkii.quark.base.module.config.Config;
import vazkii.zeta.event.bus.PlayEvent;
import vazkii.zeta.client.event.ZRenderChat;
import vazkii.zeta.module.ModuleSide;
import vazkii.zeta.module.ZetaLoadModule;
import vazkii.zeta.module.ZetaModule;

@ZetaLoadModule(category = "experimental", enabledByDefault = false, side = ModuleSide.CLIENT_ONLY)
@ZetaLoadModule(category = "experimental", enabledByDefault = false)
public class AdjustableChatModule extends ZetaModule {

@Config public static int horizontalShift = 0;
@Config public static int verticalShift = 0;

@PlayEvent
public void pre(ZRenderChat.Pre event) {
event.getPoseStack().translate(horizontalShift, verticalShift, 0);
}

@PlayEvent
public void post(ZRenderChat.Post event) {
event.getPoseStack().translate(-horizontalShift, -verticalShift, 0);

@ZetaLoadModule(clientReplacement = true)
public static class Client extends AdjustableChatModule {

@PlayEvent
public void pre(ZRenderChat.Pre event) {
event.getPoseStack().translate(horizontalShift, verticalShift, 0);
}

@PlayEvent
public void post(ZRenderChat.Post event) {
event.getPoseStack().translate(-horizontalShift, -verticalShift, 0);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import vazkii.quark.base.Quark;
import vazkii.zeta.module.ModuleSide;
import vazkii.zeta.module.ZetaLoadModule;
import vazkii.zeta.module.ZetaModule;
import vazkii.quark.base.module.config.Config;
Expand All @@ -19,7 +18,7 @@

import java.util.List;

@ZetaLoadModule(category = "experimental", enabledByDefault = false, side = ModuleSide.CLIENT_ONLY,
@ZetaLoadModule(category = "experimental", enabledByDefault = false,
description = "This feature generates Resource Pack Item Model predicates on the items defined in 'Items to Change'\n"
+ "for the Enchantments defined in 'Enchantments to Register'.\n\n"
+ "Example: if 'minecraft:silk_touch' is added to 'Enchantments to Register', and 'minecraft:netherite_pickaxe'\n"
Expand All @@ -33,24 +32,28 @@ public class EnchantmentPredicatesModule extends ZetaModule {
@Config
public static List<String> enchantmentsToRegister = Lists.newArrayList();

@LoadEvent
public void clientSetup(ZClientSetup e) {
if(enabled) {
e.enqueueWork(() -> {
List<Item> items = RegistryUtil.massRegistryGet(itemsToChange, Registry.ITEM);
List<Enchantment> enchants = RegistryUtil.massRegistryGet(enchantmentsToRegister, Registry.ENCHANTMENT);

for(Enchantment enchant : enchants) {
ResourceLocation enchantRes = Registry.ENCHANTMENT.getKey(enchant);
ResourceLocation name = new ResourceLocation(Quark.MOD_ID + "_has_enchant_" + enchantRes.getNamespace() + "_" + enchantRes.getPath());
ItemPropertyFunction fun = (stack, level, entity, i) -> EnchantmentHelper.getTagEnchantmentLevel(enchant, stack);

for(Item item : items)
ItemProperties.register(item, name, fun);
}
});
@ZetaLoadModule(clientReplacement = true)
public static class Client extends EnchantmentPredicatesModule {

@LoadEvent
public void clientSetup(ZClientSetup e) {
if(enabled) {
e.enqueueWork(() -> {
List<Item> items = RegistryUtil.massRegistryGet(itemsToChange, Registry.ITEM);
List<Enchantment> enchants = RegistryUtil.massRegistryGet(enchantmentsToRegister, Registry.ENCHANTMENT);

for(Enchantment enchant : enchants) {
ResourceLocation enchantRes = Registry.ENCHANTMENT.getKey(enchant);
ResourceLocation name = new ResourceLocation(Quark.MOD_ID + "_has_enchant_" + enchantRes.getNamespace() + "_" + enchantRes.getPath());
ItemPropertyFunction fun = (stack, level, entity, i) -> EnchantmentHelper.getTagEnchantmentLevel(enchant, stack);

for(Item item : items)
ItemProperties.register(item, name, fun);
}
});
}
}
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import vazkii.quark.base.Quark;
Expand Down Expand Up @@ -47,6 +49,7 @@ public final void register(ZRegister event) {
}

@LoadEvent
@OnlyIn(Dist.CLIENT)
public final void clientSetup(ZClientSetup event) {
BlockEntityRenderers.register(blockEntityType, CloudRenderer::new);
}
Expand Down
17 changes: 0 additions & 17 deletions src/main/java/vazkii/zeta/module/ModuleSide.java

This file was deleted.

13 changes: 5 additions & 8 deletions src/main/java/vazkii/zeta/module/TentativeModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public record TentativeModule(
Class<? extends ZetaModule> keyClass,

ZetaCategory category,
ModuleSide side,
String displayName,
String lowercaseName,
String description,
Expand All @@ -44,19 +43,16 @@ public static TentativeModule from(ZetaLoadModuleAnnotationData data, Function<S
String lowercaseName = displayName.toLowerCase(Locale.ROOT).replace(" ", "_");

boolean clientReplacement = data.clientReplacement();

Class<? extends ZetaModule> keyClass;
ModuleSide side;
if(clientReplacement) {
Class<?> sup = clazz.getSuperclass();
if(ZetaModule.class.isAssignableFrom(sup) && ZetaModule.class != sup)
keyClass = (Class<? extends ZetaModule>) clazz.getSuperclass();
else
throw new RuntimeException("Client extension module " + clazz.getName() + " should `extend` the module it's an extension of");

side = ModuleSide.CLIENT_ONLY;
} else {
keyClass = clazz;
side = data.side();

//leaving the category out of the annotation is only valid for client replacements
//TODO: maybe guess the category from the package name isntead ^^
Expand All @@ -68,7 +64,6 @@ public static TentativeModule from(ZetaLoadModuleAnnotationData data, Function<S
clazz,
keyClass,
categoryResolver.apply(data.category()),
side,
displayName,
lowercaseName,
data.description(),
Expand All @@ -85,7 +80,6 @@ public TentativeModule replaceWith(TentativeModule replacement) {
replacement.clazz,
this.keyClass,
this.category,
replacement.side,
this.displayName,
this.lowercaseName,
this.description,
Expand All @@ -98,6 +92,9 @@ public TentativeModule replaceWith(TentativeModule replacement) {
}

public boolean appliesTo(ZetaSide side) {
return this.side.appliesTo(side);
return switch(side) {
case CLIENT -> true;
case SERVER -> !clientReplacement;
};
}
}
5 changes: 0 additions & 5 deletions src/main/java/vazkii/zeta/module/ZetaLoadModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@
*/
String category() default "";

/**
* Which physical side this module will be loaded on.
*/
ModuleSide side() default ModuleSide.ANY;

/**
* The name of this module. If unspecified, defaults to de-camelcasing the module's class name.
* Ex "MyCoolModule"'s name defaults to "My Cool Module".
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public record ZetaLoadModuleAnnotationData(

//and the rest is from ZetaLoadModule
String category,
ModuleSide side,
String name,
String description,
String[] antiOverlap,
Expand All @@ -31,7 +30,6 @@ public static ZetaLoadModuleAnnotationData fromAnnotation(Class<?> clazz, ZetaLo
return new ZetaLoadModuleAnnotationData(
clazz,
annotation.category(),
annotation.side(),
annotation.name(),
annotation.description(),
annotation.antiOverlap(),
Expand All @@ -44,11 +42,10 @@ public static ZetaLoadModuleAnnotationData fromAnnotation(Class<?> clazz, ZetaLo

//clunky
@SuppressWarnings("unchecked")
public static ZetaLoadModuleAnnotationData fromForgeThing(Class<?> clazz, Map<String, Object> data, ModuleSide enumPls) {
public static ZetaLoadModuleAnnotationData fromForgeThing(Class<?> clazz, Map<String, Object> data) {
return new ZetaLoadModuleAnnotationData(
clazz,
(String) data.get("category"),
enumPls,
(String) data.getOrDefault("name", ""),
(String) data.getOrDefault("description", ""),
((List<String>) data.getOrDefault("antiOverlap", new ArrayList<String>())).toArray(new String[0]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@
import java.util.stream.Stream;

import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation;
import net.minecraftforge.forgespi.language.ModFileScanData;
import org.objectweb.asm.Type;
import vazkii.quark.base.module.LegacyQuarkModuleFinder;
import vazkii.zeta.module.ModuleFinder;
import vazkii.zeta.module.ModuleSide;
import vazkii.zeta.module.ZetaLoadModule;
import vazkii.zeta.module.ZetaLoadModuleAnnotationData;
import vazkii.zeta.module.ZetaModule;
Expand All @@ -33,15 +30,12 @@ public Stream<ZetaLoadModuleAnnotationData> get() {
.map(ad -> {
Class<? extends ZetaModule> clazz;
try {
clazz = (Class<? extends ZetaModule>) Class.forName(ad.clazz().getClassName(), false, LegacyQuarkModuleFinder.class.getClassLoader());
clazz = (Class<? extends ZetaModule>) Class.forName(ad.clazz().getClassName(), false, ModFileScanDataModuleFinder.class.getClassLoader());
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Exception getting QuarkModule (legacy)", e);
}

ModAnnotation.EnumHolder pls = (ModAnnotation.EnumHolder) ad.annotationData().get("side");
ModuleSide weird = pls == null ? ModuleSide.ANY : ModuleSide.valueOf(pls.getValue());

return ZetaLoadModuleAnnotationData.fromForgeThing(clazz, ad.annotationData(), weird);
return ZetaLoadModuleAnnotationData.fromForgeThing(clazz, ad.annotationData());
});
}
}
6 changes: 1 addition & 5 deletions zeta-todo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ The first module ported to `@ZetaLoadModule` is `DoubleDoorOpeningModule` if you
* There are two event busses - a "load bus" for lifecycle events, and a "play bus" for gameplay events.
* This loosely corresponds to the fml mod bus and MinecraftForge.EVENT_BUS, but the more important distinction is that *all* modules receive load events but only *enabled* modules receive play events.
* Zeta modules are automatically subscribed to both busses. Mark event handlers with `@LoadEvent` and `@PlayEvent`.
* **Client-only modules**.
* If a `@ZetaLoadModule` is annotated with `side = ModuleSide.CLIENT_ONLY`, it will not load at *all* on the server. It's like it's not even there.
* Yes this causes problems when you open the client and server at the same time on your computer, they disagree on what the config should be. Arguably client-only options shouldn't even be *in* the common config, but that will come later.
* This *replaces* Quark's `hasSubscriptions`/`subscribeOn` system.
* **Client module replacements**.
* On the client, if a class is annotated with `@ZetaLoadModule(clientReplacement = true)`, and the class extends another `ZetaModule`, the replacement module will load *instead* of its superclass.
* Since Fabric doesn't do side-stripping (the removal of things flagged `@OnlyIn(Dist.CLIENT)`), a client replacement module is the best place to put client-only code.
Expand All @@ -24,7 +20,7 @@ In the interim period `QuarkModule` extends `ZetaModule`, and some of the remain

So tl;dr for zeta-fying a module:

* swap LoadModule to ZetaLoadModule, remove hasSubscriptions/subscribeOn, and if the module is truly client-only add `side = ModuleSide.CLIENT_ONLY`,
* swap LoadModule to ZetaLoadModule, remove hasSubscriptions/subscribeOn
* change the superclass from `QuarkModule` to `ZetaModule`,
* move everything marked `@OnlyIn(Dist.CLIENT)` (and all `@SubscribeEvent`s if subscribeOn was formerly `Dist.CLIENT` only) into a client module replacement,
* create cross-platform versions of any missing `@SubscribeEvent`s in Zeta and subscribe to them with `@PlayEvent`,
Expand Down

0 comments on commit 4dad565

Please sign in to comment.