Add spawn category to registry handling

This commit is contained in:
IzzelAliz 2022-04-01 21:27:56 +08:00
parent 9f74767f79
commit 2a0f09bb19
No known key found for this signature in database
GPG Key ID: EE50E123A11D8338
5 changed files with 103 additions and 0 deletions

View File

@ -0,0 +1,33 @@
package io.izzel.arclight.common.mixin.bukkit;
import net.minecraft.world.entity.MobCategory;
import org.bukkit.craftbukkit.v.util.CraftSpawnCategory;
import org.bukkit.entity.SpawnCategory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(value = CraftSpawnCategory.class, remap = false)
public class CraftSpawnCategoryMixin {
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public static boolean isValidForLimits(SpawnCategory spawnCategory) {
return spawnCategory != null && spawnCategory.ordinal() < SpawnCategory.MISC.ordinal();
}
@Inject(method = "toBukkit", cancellable = true, at = @At(value = "NEW", target = "java/lang/UnsupportedOperationException"))
private static void arclight$modToBukkit(MobCategory mobCategory, CallbackInfoReturnable<SpawnCategory> cir) {
cir.setReturnValue(SpawnCategory.valueOf(mobCategory.name()));
}
@Inject(method = "toNMS", cancellable = true, at = @At(value = "NEW", target = "java/lang/UnsupportedOperationException"))
private static void arclight$bukkitToMod(SpawnCategory spawnCategory, CallbackInfoReturnable<MobCategory> cir) {
cir.setReturnValue(MobCategory.valueOf(spawnCategory.name()));
}
}

View File

@ -23,6 +23,7 @@ import net.minecraft.stats.StatType;
import net.minecraft.stats.Stats;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.entity.decoration.Motive;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.item.CreativeModeTab;
@ -48,9 +49,11 @@ import org.bukkit.craftbukkit.v.inventory.CraftCreativeCategory;
import org.bukkit.craftbukkit.v.potion.CraftPotionUtil;
import org.bukkit.craftbukkit.v.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v.util.CraftNamespacedKey;
import org.bukkit.craftbukkit.v.util.CraftSpawnCategory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.SpawnCategory;
import org.bukkit.entity.Villager;
import org.bukkit.inventory.CreativeCategory;
import org.bukkit.potion.PotionEffectType;
@ -100,6 +103,23 @@ public class BukkitRegistry {
loadArts();
loadStats();
loadCreativeTab();
loadSpawnCategory();
}
private static void loadSpawnCategory() {
var id = SpawnCategory.values().length;
var newTypes = new ArrayList<SpawnCategory>();
for (var category : MobCategory.values()) {
try {
CraftSpawnCategory.toBukkit(category);
} catch (Exception e) {
var name = category.name();
var spawnCategory = EnumHelper.makeEnum(SpawnCategory.class, name, id++, List.of(), List.of());
newTypes.add(spawnCategory);
ArclightMod.LOGGER.debug("Registered {} as spawn category {}", name, spawnCategory);
}
}
EnumHelper.addEnums(SpawnCategory.class, newTypes);
}
private static void loadCreativeTab() {

View File

@ -34,6 +34,7 @@
"CraftRegionAccessorMixin",
"CraftSchedulerMixin",
"CraftServerMixin",
"CraftSpawnCategoryMixin",
"CraftVillagerMixin",
"CraftWorldMixin",
"EntityTypeMixin",

View File

@ -54,6 +54,7 @@ public class ArclightImplementer implements ILaunchPluginService {
this.implementers.put("switch", SwitchTableFixer.INSTANCE);
this.implementers.put("async", AsyncCatcher.INSTANCE);
this.implementers.put("entitytype", EntityTypePatcher.INSTANCE);
this.implementers.put("enum", new EnumDefinalizer());
if (this.logger) {
this.implementers.put("logger", new LoggerTransformer());
}

View File

@ -0,0 +1,48 @@
package io.izzel.arclight.boot.asm;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import java.lang.reflect.Modifier;
import java.util.Set;
public class EnumDefinalizer implements Implementer {
private static final Set<String> ENUM = Set.of(
"org/bukkit/Material",
"org/bukkit/potion/PotionType",
"org/bukkit/entity/EntityType",
"org/bukkit/entity/Villager$Profession",
"org/bukkit/block/Biome",
"org/bukkit/Art",
"org/bukkit/Statistic",
"org/bukkit/inventory/CreativeCategory",
"org/bukkit/entity/SpawnCategory"
);
@Override
public boolean processClass(ClassNode node, ILaunchPluginService.ITransformerLoader transformerLoader) {
if (ENUM.contains(node.name)) {
var find = false;
for (FieldNode field : node.fields) {
if (Modifier.isStatic(field.access) && Modifier.isFinal(field.access)
&& field.name.equals("ENUM$VALUES")) {
field.access &= ~Opcodes.ACC_FINAL;
ArclightImplementer.LOGGER.debug("Definalize enum class {} values field {}", node.name, field.name);
if (find) {
throw new IllegalStateException("Duplicate static final field found for " + node.name + ": " + field.name);
} else {
find = true;
}
}
}
if (!find) {
throw new IllegalStateException("No static final field found for " + node.name);
}
return true;
}
return false;
}
}