refactor(ALL): bump minecraft version to 1.21.5
trimmed unused feature: /gamerule CustomEntity API, Custom Item API We'll use Polymer for replacement in the future. Tests needed.
This commit is contained in:
39 files changed
+124
-658
No files matched your search
+1
-2
@@ -2,7 +2,7 @@ plugins {
|
|||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
id("io.freefair.lombok") version "8.6"
|
id("io.freefair.lombok") version "8.6"
|
||||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||||
id 'fabric-loom' version '1.7.3'
|
id 'fabric-loom' version '1.10.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
version = project.mod_version
|
version = project.mod_version
|
||||||
@@ -18,7 +18,6 @@ repositories {
|
|||||||
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
||||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
||||||
// for more information about repositories.
|
// for more information about repositories.
|
||||||
maven { url 'https://maven.wispforest.io/releases/' }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
+9
-17
@@ -1,19 +1,11 @@
|
|||||||
# Done to increase the memory available to gradle.
|
# Done to increase the memory available to gradle.
|
||||||
org.gradle.jvmargs=-Xmx1G
|
org.gradle.jvmargs=-Xmx4G
|
||||||
|
minecraft_version=1.21.5
|
||||||
# Fabric Properties
|
yarn_mappings=1.21.5+build.1
|
||||||
# check these on https://modmuss50.me/fabric.html
|
loader_version=0.16.10
|
||||||
minecraft_version=1.21
|
# Fabric API
|
||||||
yarn_mappings=1.21+build.7
|
fabric_version=0.119.5+1.21.5
|
||||||
loader_version=0.15.11
|
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 1.0.0
|
mod_version=1.0.0
|
||||||
maven_group = io.ib67
|
maven_group=io.ib67
|
||||||
archives_base_name = sfcraft
|
archives_base_name=sfcraft
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
# check this on https://modmuss50.me/fabric.html
|
|
||||||
fabric_version=0.100.4+1.21
|
|
||||||
owo_version=0.12.10+1.21
|
|
||||||
|
|
||||||
@@ -8,7 +8,6 @@ import io.ib67.sfcraft.module.chat.ChatPrefixModule;
|
|||||||
import io.ib67.sfcraft.module.chat.decorator.ChatPingModule;
|
import io.ib67.sfcraft.module.chat.decorator.ChatPingModule;
|
||||||
import io.ib67.sfcraft.module.chat.decorator.ChatSendLocModule;
|
import io.ib67.sfcraft.module.chat.decorator.ChatSendLocModule;
|
||||||
import io.ib67.sfcraft.module.compat.ModCompatModule;
|
import io.ib67.sfcraft.module.compat.ModCompatModule;
|
||||||
import io.ib67.sfcraft.module.randomevt.LongNightModule;
|
|
||||||
import io.ib67.sfcraft.module.room.CreativeRoomModule;
|
import io.ib67.sfcraft.module.room.CreativeRoomModule;
|
||||||
import io.ib67.sfcraft.module.supervisor.WebModule;
|
import io.ib67.sfcraft.module.supervisor.WebModule;
|
||||||
import io.ib67.sfcraft.module.supervisor.web.SchematicUploader;
|
import io.ib67.sfcraft.module.supervisor.web.SchematicUploader;
|
||||||
@@ -25,9 +24,6 @@ import io.ib67.sfcraft.module.command.ManagementModule;
|
|||||||
import io.ib67.sfcraft.registry.room.SimpleRoomRegistry;
|
import io.ib67.sfcraft.registry.room.SimpleRoomRegistry;
|
||||||
import io.ib67.sfcraft.room.RoomTeleporter;
|
import io.ib67.sfcraft.room.RoomTeleporter;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
|
||||||
import net.minecraft.registry.Registries;
|
|
||||||
import net.minecraft.registry.Registry;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@@ -61,12 +57,10 @@ public class SFCraftInitializer extends GuiceModInitializer {
|
|||||||
registerFeature(FartFertilizerModule.class);
|
registerFeature(FartFertilizerModule.class);
|
||||||
registerFeature(ChatPingModule.class);
|
registerFeature(ChatPingModule.class);
|
||||||
registerFeature(ChatSendLocModule.class);
|
registerFeature(ChatSendLocModule.class);
|
||||||
registerFeature(LongNightModule.class);
|
|
||||||
registerFeature(ModCompatModule.class);
|
registerFeature(ModCompatModule.class);
|
||||||
registerFeature(RoomModule.class);
|
registerFeature(RoomModule.class);
|
||||||
registerFeature(CreativeRoomModule.class);
|
registerFeature(CreativeRoomModule.class);
|
||||||
registerFeature(ChatPrefixModule.class);
|
registerFeature(ChatPrefixModule.class);
|
||||||
registerFeature(CustomItemModule.class);
|
|
||||||
registerWebModules();
|
registerWebModules();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +85,6 @@ public class SFCraftInitializer extends GuiceModInitializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Injector onInit() {
|
protected Injector onInit() {
|
||||||
SFEntityType.registerEntities();
|
|
||||||
return SFCraft.injector = Guice.createInjector(
|
return SFCraft.injector = Guice.createInjector(
|
||||||
new SFCraft(),
|
new SFCraft(),
|
||||||
this
|
this
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
package io.ib67.sfcraft;
|
|
||||||
|
|
||||||
import io.ib67.sfcraft.entity.SFGuiderEntity;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
|
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
|
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.entity.SpawnGroup;
|
|
||||||
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
|
||||||
import net.minecraft.registry.Registries;
|
|
||||||
import net.minecraft.registry.Registry;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
@Log4j2
|
|
||||||
public class SFEntityType {
|
|
||||||
public static final EntityType<SFGuiderEntity> GUIDER = Registry.register(
|
|
||||||
Registries.ENTITY_TYPE,
|
|
||||||
Identifier.of(SFCraft.MOD_ID , "guider"),
|
|
||||||
EntityType.Builder.create(SFGuiderEntity::new, SpawnGroup.CREATURE)
|
|
||||||
.dimensions(0.35F, 0.6F)
|
|
||||||
.eyeHeight(0.36F)
|
|
||||||
.vehicleAttachment(0.04F)
|
|
||||||
.maxTrackingRange(8)
|
|
||||||
.trackingTickInterval(2).build()
|
|
||||||
);
|
|
||||||
private static SFEntityType registry;
|
|
||||||
private final Map<EntityType<?>, EntityType<?>> mappedEntityTypes = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
register(GUIDER, EntityType.ALLAY, SFGuiderEntity.createAllayAttributes().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private <A extends LivingEntity, B extends LivingEntity> void register(EntityType<B> custom, EntityType<A> origin, DefaultAttributeContainer attr) {
|
|
||||||
FabricDefaultAttributeRegistry.register(custom, attr);
|
|
||||||
mappedEntityTypes.put(custom, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void registerEntities() {
|
|
||||||
registry = new SFEntityType();
|
|
||||||
registry.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends LivingEntity> EntityType<T> mapToVanilla(EntityType<?> type) {
|
|
||||||
return (EntityType<T>) registry.mappedEntityTypes.getOrDefault(type, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package io.ib67.sfcraft;
|
|
||||||
|
|
||||||
import io.ib67.sfcraft.item.AeroBackpack;
|
|
||||||
import io.ib67.sfcraft.mixin.common.bridge.ItemBridge;
|
|
||||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
|
||||||
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
|
|
||||||
import net.minecraft.item.ArmorItem;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.registry.Registry;
|
|
||||||
import net.minecraft.registry.RegistryKey;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
|
|
||||||
import static io.ib67.sfcraft.SFRegistries.ITEMS;
|
|
||||||
|
|
||||||
public class SFItems {
|
|
||||||
public static final Item AERO_BACKPACK = register(
|
|
||||||
new AeroBackpack(new Item.Settings().maxDamage(ArmorItem.Type.CHESTPLATE.getMaxDamage(15))), "aero_backpack");
|
|
||||||
public static final String SF_ITEM_TYPE_KEY = "sf_type";
|
|
||||||
|
|
||||||
public static void init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Item register(Item item, String id) {
|
|
||||||
Identifier itemID = Identifier.of(SFCraft.MOD_ID, id);
|
|
||||||
Item registeredItem = Registry.register(ITEMS, itemID, item);
|
|
||||||
((ItemBridge) registeredItem).setRegistryEntry(ITEMS.getEntry(itemID).get());
|
|
||||||
return registeredItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Item getById(Identifier item) {
|
|
||||||
return ITEMS.get(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package io.ib67.sfcraft.item;
|
|
||||||
|
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.*;
|
|
||||||
import net.minecraft.registry.entry.RegistryEntry;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
|
|
||||||
public class AeroBackpack extends ArmorItem implements TickableItem, SFItem {
|
|
||||||
private static final Text STATUS_MESSAGE = Text.of("You're wearing aero backpack!");
|
|
||||||
|
|
||||||
public AeroBackpack(Settings settings) {
|
|
||||||
super(ArmorMaterials.IRON, Type.CHESTPLATE, settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpdate(PlayerEntity player, ItemStack stack, EquipmentSlot slot) {
|
|
||||||
if (slot != EquipmentSlot.CHEST) return;
|
|
||||||
player.sendMessage(STATUS_MESSAGE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Item getMappedItem() {
|
|
||||||
return Items.IRON_CHESTPLATE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package io.ib67.sfcraft.item;
|
|
||||||
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.registry.entry.RegistryEntry;
|
|
||||||
|
|
||||||
public interface SFItem {
|
|
||||||
Item getMappedItem();
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package io.ib67.sfcraft.item;
|
|
||||||
|
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
|
|
||||||
public interface TickableItem {
|
|
||||||
void onUpdate(PlayerEntity player, ItemStack stack, EquipmentSlot slot);
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.gen.Invoker;
|
|||||||
|
|
||||||
@Mixin(Entity.class)
|
@Mixin(Entity.class)
|
||||||
public interface EntityBridge {
|
public interface EntityBridge {
|
||||||
@Accessor("FALL_FLYING_FLAG_INDEX")
|
@Accessor("GLIDING_FLAG_INDEX")
|
||||||
static int sfcraft$getFlyingFlagIndex() {
|
static int sfcraft$getFlyingFlagIndex() {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import net.minecraft.block.entity.AbstractFurnaceBlockEntity;
|
|||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityTicker;
|
import net.minecraft.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.GameRules;
|
import net.minecraft.world.GameRules;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@@ -26,15 +27,17 @@ public abstract class AbstractFurnaceBlockMixin extends BlockWithEntity {
|
|||||||
* @author icybear
|
* @author icybear
|
||||||
* @reason to replace their ticker
|
* @reason to replace their ticker
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public static <T extends BlockEntity> @Nullable BlockEntityTicker<T> validateTicker(
|
public static <T extends BlockEntity> BlockEntityTicker<T> validateTicker(
|
||||||
World world, BlockEntityType<T> givenType, BlockEntityType<? extends AbstractFurnaceBlockEntity> expectedType
|
World world, BlockEntityType<T> givenType, BlockEntityType<? extends AbstractFurnaceBlockEntity> expectedType
|
||||||
) {
|
) {
|
||||||
return world.isClient ? null : BlockWithEntity.validateTicker(givenType, expectedType, AbstractFurnaceBlockMixin::tickMultiple);
|
return world instanceof ServerWorld sw ? BlockWithEntity.validateTicker(givenType, expectedType, AbstractFurnaceBlockMixin::tickMultiple) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private static void tickMultiple(World world, BlockPos pos, BlockState state, AbstractFurnaceBlockEntity blockEntity) {
|
private static <E extends AbstractFurnaceBlockEntity> void tickMultiple(World _world, BlockPos pos, BlockState state, E blockEntity) {
|
||||||
|
var world = (ServerWorld) _world;
|
||||||
AbstractFurnaceBlockEntity.tick(world, pos, state, blockEntity);
|
AbstractFurnaceBlockEntity.tick(world, pos, state, blockEntity);
|
||||||
int i = world.getGameRules().getInt(GameRules.PLAYERS_SLEEPING_PERCENTAGE);
|
int i = world.getGameRules().getInt(GameRules.PLAYERS_SLEEPING_PERCENTAGE);
|
||||||
if (((ServerWorldBridge) world).getSleepManager().canSkipNight(i)) {
|
if (((ServerWorldBridge) world).getSleepManager().canSkipNight(i)) {
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package io.ib67.sfcraft.mixin.server;
|
||||||
|
|
||||||
|
import net.minecraft.server.world.ChunkLevelManager;
|
||||||
|
import net.minecraft.server.world.ServerChunkManager;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(ServerChunkManager.class)
|
||||||
|
public interface ServerChunkManagerMixin {
|
||||||
|
@Accessor("levelManager")
|
||||||
|
ChunkLevelManager getLevelManager();
|
||||||
|
}
|
||||||
@@ -1,11 +1,19 @@
|
|||||||
package io.ib67.sfcraft.mixin.server;
|
package io.ib67.sfcraft.mixin.server;
|
||||||
|
|
||||||
|
import io.ib67.sfcraft.SFCraft;
|
||||||
import io.ib67.sfcraft.mixin.common.bridge.ServerWorldBridge;
|
import io.ib67.sfcraft.mixin.common.bridge.ServerWorldBridge;
|
||||||
|
import io.ib67.sfcraft.module.RoomModule;
|
||||||
import io.ib67.sfcraft.util.MixinHelper;
|
import io.ib67.sfcraft.util.MixinHelper;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.world.GameRules;
|
import net.minecraft.world.GameRules;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.*;
|
import org.spongepowered.asm.mixin.injection.*;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
@Mixin(ServerWorld.class)
|
@Mixin(ServerWorld.class)
|
||||||
public abstract class ServerWorldMixin {
|
public abstract class ServerWorldMixin {
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package io.ib67.sfcraft.mixin.server.hack;
|
|
||||||
|
|
||||||
import io.ib67.sfcraft.SFCraftInitializer;
|
|
||||||
import io.ib67.sfcraft.SFEntityType;
|
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|
||||||
|
|
||||||
@Mixin(EntitySpawnS2CPacket.class)
|
|
||||||
public class EntitySpawnS2CPacketMixin {
|
|
||||||
@ModifyArg(method = "write", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/codec/PacketCodec;encode(Ljava/lang/Object;Ljava/lang/Object;)V"), index = 1)
|
|
||||||
public Object mapModType(Object type) {
|
|
||||||
return SFEntityType.mapToVanilla((EntityType<?>) type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package io.ib67.sfcraft.mixin.server.hack;
|
|
||||||
|
|
||||||
import io.ib67.sfcraft.SFCraftInitializer;
|
|
||||||
import io.ib67.sfcraft.SFEntityType;
|
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.text.HoverEvent;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
@Mixin(HoverEvent.EntityContent.class)
|
|
||||||
public class HoverEntityContentMixin {
|
|
||||||
@Inject(method = "method_54198", at = @At("HEAD"), cancellable = true)
|
|
||||||
private static void sf$mapToVanilla(HoverEvent.EntityContent content, CallbackInfoReturnable<EntityType> cir) {
|
|
||||||
cir.setReturnValue(SFEntityType.mapToVanilla(content.entityType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package io.ib67.sfcraft.mixin.server.hack;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
|
||||||
import net.fabricmc.fabric.impl.registry.sync.packet.DirectRegistryPacketHandler;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Mixin(DirectRegistryPacketHandler.class)
|
|
||||||
public abstract class RegistryHandlerMixin {
|
|
||||||
@Inject(method = "sendPacket", at = @At("HEAD"), remap = false)
|
|
||||||
public void sf$removeRegistry(Consumer<DirectRegistryPacketHandler.Payload> sender, Map<Identifier, Object2IntMap<Identifier>> registryMap, CallbackInfo ci) {
|
|
||||||
registryMap.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package io.ib67.sfcraft.mixin.server.item;
|
|
||||||
|
|
||||||
import io.ib67.sfcraft.item.SFItem;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.registry.DefaultedRegistry;
|
|
||||||
import net.minecraft.registry.entry.RegistryEntry;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
@Mixin(Item.class)
|
|
||||||
public abstract class ItemMixin {
|
|
||||||
@Redirect(
|
|
||||||
method ="<init>",
|
|
||||||
at= @At(value = "INVOKE", target = "Lnet/minecraft/registry/DefaultedRegistry;createEntry(Ljava/lang/Object;)Lnet/minecraft/registry/entry/RegistryEntry$Reference;")
|
|
||||||
)
|
|
||||||
public RegistryEntry.Reference sf$redirectCreateEntry(DefaultedRegistry instance, Object o){
|
|
||||||
if(this instanceof SFItem) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return instance.createEntry(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package io.ib67.sfcraft.mixin.server.item;
|
|
||||||
|
|
||||||
import io.ib67.sfcraft.SFCraft;
|
|
||||||
import io.ib67.sfcraft.SFItems;
|
|
||||||
import io.ib67.sfcraft.SFRegistries;
|
|
||||||
import net.minecraft.component.ComponentHolder;
|
|
||||||
import net.minecraft.component.ComponentMapImpl;
|
|
||||||
import net.minecraft.component.DataComponentTypes;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemConvertible;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.Items;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
@Mixin(ItemStack.class)
|
|
||||||
public abstract class ItemStackMixin implements ComponentHolder {
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
@Deprecated
|
|
||||||
@Nullable
|
|
||||||
private Item item;
|
|
||||||
|
|
||||||
@Shadow @Final private static Logger LOGGER;
|
|
||||||
@Unique
|
|
||||||
private Item sfItem;
|
|
||||||
|
|
||||||
@Shadow public abstract boolean isEmpty();
|
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/item/ItemConvertible;ILnet/minecraft/component/ComponentMapImpl;)V", at = @At("TAIL"))
|
|
||||||
private void initSFItem(ItemConvertible item, int count, ComponentMapImpl components, CallbackInfo ci) {
|
|
||||||
var _id = get(DataComponentTypes.CUSTOM_DATA);
|
|
||||||
if (_id != null && _id.contains(SFItems.SF_ITEM_TYPE_KEY)) {
|
|
||||||
var id = _id.copyNbt().getString(SFItems.SF_ITEM_TYPE_KEY);
|
|
||||||
try {
|
|
||||||
sfItem = SFRegistries.ITEMS.get(Identifier.of(SFCraft.MOD_ID, id));
|
|
||||||
}catch(Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
if(sfItem == null){
|
|
||||||
LOGGER.warn("A invalid sfItem is being created: {}", id);
|
|
||||||
new IllegalStateException("Just stacktrace").printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "getItem", at = @At("HEAD"), cancellable = true)
|
|
||||||
private void beforeGetItem(CallbackInfoReturnable<Item> cir) {
|
|
||||||
if (sfItem != null) cir.setReturnValue(sfItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "getRegistryEntry", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;"))
|
|
||||||
private Item sf$getMappedEntry(ItemStack instance) {
|
|
||||||
return isEmpty() ? Items.AIR : this.item;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "copy", at= @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;"))
|
|
||||||
private Item sf$getCopySubject(ItemStack instance){
|
|
||||||
return isEmpty() ? Items.AIR : this.item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package io.ib67.sfcraft.mixin.server.item;
|
|
||||||
|
|
||||||
import io.ib67.sfcraft.item.TickableItem;
|
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(PlayerEntity.class)
|
|
||||||
public abstract class PlayerEntityMixin {
|
|
||||||
@Shadow
|
|
||||||
public abstract ItemStack getEquippedStack(EquipmentSlot slot);
|
|
||||||
|
|
||||||
@Inject(method = "updateTurtleHelmet", at = @At("TAIL"))
|
|
||||||
public void sf$tickMyItems(CallbackInfo ci) {
|
|
||||||
checkAndUpdate(EquipmentSlot.OFFHAND);
|
|
||||||
checkAndUpdate(EquipmentSlot.MAINHAND);
|
|
||||||
checkAndUpdate(EquipmentSlot.HEAD);
|
|
||||||
checkAndUpdate(EquipmentSlot.CHEST);
|
|
||||||
checkAndUpdate(EquipmentSlot.LEGS);
|
|
||||||
checkAndUpdate(EquipmentSlot.FEET);
|
|
||||||
checkAndUpdate(EquipmentSlot.BODY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private void checkAndUpdate(EquipmentSlot equipmentSlot) {
|
|
||||||
var item = getEquippedStack(equipmentSlot);
|
|
||||||
if (item.getItem() instanceof TickableItem tickableItem) {
|
|
||||||
tickableItem.onUpdate($this(), item, equipmentSlot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private PlayerEntity $this() {
|
|
||||||
return (PlayerEntity) (Object) this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,7 @@ package io.ib67.sfcraft.mixin.server.subserver;
|
|||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import io.ib67.sfcraft.SFCraft;
|
import io.ib67.sfcraft.SFCraft;
|
||||||
|
import io.ib67.sfcraft.mixin.server.ServerChunkManagerMixin;
|
||||||
import io.ib67.sfcraft.module.RoomModule;
|
import io.ib67.sfcraft.module.RoomModule;
|
||||||
import io.ib67.sfcraft.registry.RoomRegistry;
|
import io.ib67.sfcraft.registry.RoomRegistry;
|
||||||
import io.ib67.sfcraft.util.Helper;
|
import io.ib67.sfcraft.util.Helper;
|
||||||
@@ -70,8 +71,8 @@ public abstract class PlayerManagerMixin {
|
|||||||
private void teleportToRoom(ServerPlayerEntity player, GlobalPos spawn) {
|
private void teleportToRoom(ServerPlayerEntity player, GlobalPos spawn) {
|
||||||
var world = player.getServer().getWorld(spawn.dimension());
|
var world = player.getServer().getWorld(spawn.dimension());
|
||||||
var pos = spawn.pos();
|
var pos = spawn.pos();
|
||||||
world.getChunkManager().chunkLoadingManager.getTicketManager().handleChunkEnter(player.getWatchedSection(), player);
|
((ServerChunkManagerMixin)world.getChunkManager()).getLevelManager().handleChunkEnter(player.getWatchedSection(), player);
|
||||||
player.teleport(world, pos.getX(), pos.getY(), pos.getZ(), Set.of(), 0, 0);
|
player.teleport(world, pos.getX(), pos.getY(), pos.getZ(), Set.of(), 0, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "remove", at = @At("HEAD"))
|
@Inject(method = "remove", at = @At("HEAD"))
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ import java.util.Set;
|
|||||||
|
|
||||||
@Mixin(ServerPlayerEntity.class)
|
@Mixin(ServerPlayerEntity.class)
|
||||||
public abstract class ServerPlayerEntityMixin {
|
public abstract class ServerPlayerEntityMixin {
|
||||||
@Inject(at = @At("HEAD"), method = "teleport(Lnet/minecraft/server/world/ServerWorld;DDDLjava/util/Set;FF)Z", cancellable = true)
|
//todo test this
|
||||||
public void sf$interceptTeleport(ServerWorld world, double destX, double destY, double destZ, Set<PositionFlag> flags, float yaw, float pitch, CallbackInfoReturnable<Boolean> cir) {
|
//todo fix playground operate players in main world
|
||||||
|
@Inject(at=@At("HEAD"), method = "teleport(Lnet/minecraft/server/world/ServerWorld;DDDLjava/util/Set;FFZ)Z")
|
||||||
|
public void sf$interceptTeleport(ServerWorld world, double destX, double destY, double destZ, Set<PositionFlag> flags, float yaw, float pitch, boolean resetCamera, CallbackInfoReturnable<Boolean> cir) {
|
||||||
var room = roomRegistry().getRoomBy($this().getUuid());
|
var room = roomRegistry().getRoomBy($this().getUuid());
|
||||||
if (room != null) {
|
if (room != null) {
|
||||||
if (world.getRegistryKey() != room.getSpawnPosition().dimension()) {
|
if (world.getRegistryKey() != room.getSpawnPosition().dimension()) {
|
||||||
@@ -25,16 +27,6 @@ public abstract class ServerPlayerEntityMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At("HEAD"), method = "teleport(Lnet/minecraft/server/world/ServerWorld;DDDFF)V", cancellable = true)
|
|
||||||
public void sf$interceptTeleport(ServerWorld targetWorld, double x, double y, double z, float yaw, float pitch, CallbackInfo ci) {
|
|
||||||
var room = roomRegistry().getRoomBy($this().getUuid());
|
|
||||||
if (room != null) {
|
|
||||||
if (targetWorld.getRegistryKey() != room.getSpawnPosition().dimension()) {
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RoomRegistry roomRegistry() {
|
private RoomRegistry roomRegistry() {
|
||||||
return SFCraft.getInjector().getInstance(RoomRegistry.class);
|
return SFCraft.getInjector().getInstance(RoomRegistry.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
package io.ib67.sfcraft.mixin.server.subserver;
|
|
||||||
|
|
||||||
import io.ib67.sfcraft.SFCraft;
|
|
||||||
import io.ib67.sfcraft.module.RoomModule;
|
|
||||||
import net.minecraft.registry.RegistryKey;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.world.GameRules;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import org.spongepowered.asm.mixin.*;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
@Mixin(World.class)
|
|
||||||
public abstract class WorldMixin {
|
|
||||||
@Shadow
|
|
||||||
public abstract boolean isClient();
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private RegistryKey<World> registryKey;
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private GameRules sfcraft$customGameRule;
|
|
||||||
|
|
||||||
@Inject(method = "getGameRules", at = @At("HEAD"), cancellable = true)
|
|
||||||
private void beforeGetGameRules(CallbackInfoReturnable<GameRules> cir) {
|
|
||||||
if (!isClient() && registryKey.getValue().getNamespace().equals(SFCraft.MOD_ID)) {
|
|
||||||
if (sfcraft$customGameRule == null) {
|
|
||||||
sfcraft$customGameRule = SFCraft.getInjector().getInstance(RoomModule.class).readGameRuleForRoom((ServerWorld) (Object) this);
|
|
||||||
}
|
|
||||||
cir.setReturnValue(sfcraft$customGameRule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package io.ib67.sfcraft.module;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
||||||
import io.ib67.sfcraft.SFItems;
|
|
||||||
import io.ib67.sfcraft.ServerModule;
|
|
||||||
import io.ib67.sfcraft.item.SFItem;
|
|
||||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
|
||||||
import net.minecraft.command.CommandRegistryAccess;
|
|
||||||
import net.minecraft.command.argument.IdentifierArgumentType;
|
|
||||||
import net.minecraft.component.DataComponentTypes;
|
|
||||||
import net.minecraft.component.type.NbtComponent;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
|
||||||
import net.minecraft.server.command.CommandManager;
|
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
|
|
||||||
public class CustomItemModule extends ServerModule {
|
|
||||||
@Override
|
|
||||||
public void onInitialize() {
|
|
||||||
SFItems.init();
|
|
||||||
CommandRegistrationCallback.EVENT
|
|
||||||
.register(this::registerCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerCommand(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess registryAccess, CommandManager.RegistrationEnvironment environment) {
|
|
||||||
dispatcher.register(
|
|
||||||
CommandManager.literal("sfgive")
|
|
||||||
.then(
|
|
||||||
CommandManager.argument("item", IdentifierArgumentType.identifier())
|
|
||||||
.executes(this::performGive)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ItemStack getItemByName(Identifier id) throws CommandSyntaxException {
|
|
||||||
var item = SFItems.getById(id);
|
|
||||||
if(item == null) return null;
|
|
||||||
var stack = new ItemStack(((SFItem) item).getMappedItem());
|
|
||||||
var cmp = new NbtCompound();
|
|
||||||
cmp.putString(SFItems.SF_ITEM_TYPE_KEY, item.getRegistryEntry().getKey().map(it -> it.getValue().getPath()).orElseThrow());
|
|
||||||
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(cmp));
|
|
||||||
return stack.copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private int performGive(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
|
|
||||||
var item = IdentifierArgumentType.getIdentifier(context, "item");
|
|
||||||
if (!context.getSource().isExecutedByPlayer()) {
|
|
||||||
context.getSource().sendMessage(Text.of("Can't be executed by non-players"));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
var player = context.getSource().getPlayer();
|
|
||||||
var itemStack = getItemByName(item);
|
|
||||||
if (itemStack != null) {
|
|
||||||
player.giveItemStack(itemStack);
|
|
||||||
}else{
|
|
||||||
player.sendMessage(Text.of("Item with id "+item.toString()+" not exists."));
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,16 +2,10 @@ package io.ib67.sfcraft.module;
|
|||||||
|
|
||||||
import io.ib67.sfcraft.ServerModule;
|
import io.ib67.sfcraft.ServerModule;
|
||||||
import io.ib67.sfcraft.callback.SFCallbacks;
|
import io.ib67.sfcraft.callback.SFCallbacks;
|
||||||
import io.ib67.sfcraft.util.ColorHelper;
|
|
||||||
import it.unimi.dsi.fastutil.objects.*;
|
import it.unimi.dsi.fastutil.objects.*;
|
||||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
|
||||||
import net.minecraft.item.ElytraItem;
|
|
||||||
import net.minecraft.network.packet.Packet;
|
|
||||||
import net.minecraft.network.packet.s2c.play.SubtitleS2CPacket;
|
|
||||||
import net.minecraft.network.packet.s2c.play.TitleFadeS2CPacket;
|
|
||||||
import net.minecraft.network.packet.s2c.play.TitleS2CPacket;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
@@ -19,10 +13,6 @@ import net.minecraft.text.MutableText;
|
|||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Colors;
|
import net.minecraft.util.Colors;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
|
|
||||||
public class ElytraSpeedMeterModule extends ServerModule {
|
public class ElytraSpeedMeterModule extends ServerModule {
|
||||||
private static final int BAR_LEN = 20;
|
private static final int BAR_LEN = 20;
|
||||||
@@ -89,7 +79,7 @@ public class ElytraSpeedMeterModule extends ServerModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Text generateDurabilityMeter(long f, PlayerEntity player) {
|
private Text generateDurabilityMeter(long f, PlayerEntity player) {
|
||||||
var stack = player.getInventory().getArmorStack(PlayerInventory.ARMOR_SLOTS[2]);
|
var stack = player.getEquippedStack(EquipmentSlot.CHEST);
|
||||||
if (stack.isDamageable() && stack.isDamaged()) {
|
if (stack.isDamageable() && stack.isDamaged()) {
|
||||||
var remaining = stack.getMaxDamage() - stack.getDamage();
|
var remaining = stack.getMaxDamage() - stack.getDamage();
|
||||||
var percent = (int) Math.ceil(((double) remaining / stack.getMaxDamage()) * 100);
|
var percent = (int) Math.ceil(((double) remaining / stack.getMaxDamage()) * 100);
|
||||||
|
|||||||
@@ -2,48 +2,32 @@ package io.ib67.sfcraft.module;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import com.mojang.brigadier.Command;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import io.ib67.sfcraft.ServerModule;
|
import io.ib67.sfcraft.ServerModule;
|
||||||
import io.ib67.sfcraft.config.SFConfig;
|
import io.ib67.sfcraft.config.SFConfig;
|
||||||
import io.ib67.sfcraft.inject.MinecraftServerSupplier;
|
import io.ib67.sfcraft.inject.MinecraftServerSupplier;
|
||||||
import io.ib67.sfcraft.room.RequestedRoom;
|
|
||||||
import io.ib67.sfcraft.registry.RoomRegistry;
|
import io.ib67.sfcraft.registry.RoomRegistry;
|
||||||
import io.ib67.sfcraft.room.data.RoomWorldDataLoader;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||||
import net.minecraft.command.CommandRegistryAccess;
|
import net.minecraft.command.CommandRegistryAccess;
|
||||||
import net.minecraft.network.PacketCallbacks;
|
import net.minecraft.network.PacketCallbacks;
|
||||||
import net.minecraft.network.codec.PacketCodecs;
|
|
||||||
import net.minecraft.network.packet.s2c.common.ServerTransferS2CPacket;
|
import net.minecraft.network.packet.s2c.common.ServerTransferS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.common.StoreCookieS2CPacket;
|
import net.minecraft.network.packet.s2c.common.StoreCookieS2CPacket;
|
||||||
import net.minecraft.registry.RegistryKey;
|
import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.server.command.CommandManager;
|
import net.minecraft.server.command.CommandManager;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.server.world.ChunkTicketType;
|
import net.minecraft.server.world.ChunkTicketType;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.Pair;
|
import net.minecraft.util.Pair;
|
||||||
import net.minecraft.util.Unit;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
import net.minecraft.world.GameRules;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.SecretKey;
|
|
||||||
import javax.crypto.SecretKeyFactory;
|
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.spec.KeySpec;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@@ -76,7 +60,7 @@ public class RoomModule extends ServerModule {
|
|||||||
log.warn("Cannot find world {}", registryKeyBlockPosPair.getLeft());
|
log.warn("Cannot find world {}", registryKeyBlockPosPair.getLeft());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
world.getChunkManager().addTicket(ChunkTicketType.START, new ChunkPos(registryKeyBlockPosPair.getRight()), 64, Unit.INSTANCE);
|
world.getChunkManager().addTicket(ChunkTicketType.START, new ChunkPos(registryKeyBlockPosPair.getRight()), 64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +74,9 @@ public class RoomModule extends ServerModule {
|
|||||||
|
|
||||||
private int onCleanReconnect(CommandContext<ServerCommandSource> serverCommandSourceCommandContext) {
|
private int onCleanReconnect(CommandContext<ServerCommandSource> serverCommandSourceCommandContext) {
|
||||||
var player = serverCommandSourceCommandContext.getSource().getPlayer();
|
var player = serverCommandSourceCommandContext.getSource().getPlayer();
|
||||||
|
if (player == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (!isVirtual(player.getUuid())) {
|
if (!isVirtual(player.getUuid())) {
|
||||||
player.sendMessage(Text.literal("你不在任何 \"房间\" 内。"));
|
player.sendMessage(Text.literal("你不在任何 \"房间\" 内。"));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -119,8 +106,4 @@ public class RoomModule extends ServerModule {
|
|||||||
public GameProfile devirtualize(UUID virtual) {
|
public GameProfile devirtualize(UUID virtual) {
|
||||||
return uuidMapper.get(virtual);
|
return uuidMapper.get(virtual);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameRules readGameRuleForRoom(ServerWorld world){
|
|
||||||
return RoomWorldDataLoader.get(world).getGameRules();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,7 @@ import net.minecraft.text.RawFilteredPair;
|
|||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
@@ -51,7 +52,7 @@ public class WelcomeModule extends ServerModule {
|
|||||||
player.sendMessage(Text.of("§a您受本服务器成员邀请加入本服务器,以下是一些注意事项:"));
|
player.sendMessage(Text.of("§a您受本服务器成员邀请加入本服务器,以下是一些注意事项:"));
|
||||||
player.sendMessage(Text.of(" - 服务器内已有的设施均为其他玩家的财产,(如可以)使用时请注意礼貌"));
|
player.sendMessage(Text.of(" - 服务器内已有的设施均为其他玩家的财产,(如可以)使用时请注意礼貌"));
|
||||||
player.sendMessage(Text.literal(" - 服务器内有一些非原版特性,可以点击此条消息查看 [特性列表]")
|
player.sendMessage(Text.literal(" - 服务器内有一些非原版特性,可以点击此条消息查看 [特性列表]")
|
||||||
.styled(s -> s.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://wiki.sfclub.cc/s/sfcraft-features"))));
|
.styled(s -> s.withClickEvent(new ClickEvent.OpenUrl(URI.create("https://wiki.sfclub.cc/s/sfcraft-features")))));
|
||||||
player.sendMessage(Text.of("§c - 邀请新成员即等同为其作担保"));
|
player.sendMessage(Text.of("§c - 邀请新成员即等同为其作担保"));
|
||||||
player.sendMessage(Text.of("§7如果您想邀请朋友加入服务器, 可以向管理员提出申请§7 (需备注正/盗版/小号)"));
|
player.sendMessage(Text.of("§7如果您想邀请朋友加入服务器, 可以向管理员提出申请§7 (需备注正/盗版/小号)"));
|
||||||
player.sendMessage(Text.of("§7此外, 本服务器无密码登录,盗版账号安全责任自负"));
|
player.sendMessage(Text.of("§7此外, 本服务器无密码登录,盗版账号安全责任自负"));
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import java.util.regex.MatchResult;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class ChatPingModule extends ServerModule implements MessageDecorator {
|
public class ChatPingModule extends ServerModule implements MessageDecorator {
|
||||||
private static final Pattern PING = Pattern.compile("(@[\\w]+)?");
|
private static final Pattern PING = Pattern.compile("(@[\\w]+)?"); //todo remove the need of prefix
|
||||||
@Inject
|
@Inject
|
||||||
MinecraftServerSupplier serverSupplier;
|
MinecraftServerSupplier serverSupplier;
|
||||||
@Inject
|
@Inject
|
||||||
@@ -51,7 +51,7 @@ public class ChatPingModule extends ServerModule implements MessageDecorator {
|
|||||||
var r = Text.literal(match.replaceAll(it -> this.matchPlayer(it, names, foundPlayers)));
|
var r = Text.literal(match.replaceAll(it -> this.matchPlayer(it, names, foundPlayers)));
|
||||||
for (PlayerEntity foundPlayer : foundPlayers) {
|
for (PlayerEntity foundPlayer : foundPlayers) {
|
||||||
if (sender != null) {
|
if (sender != null) {
|
||||||
foundPlayer.sendMessage(Text.literal(sender.getName().getLiteralString() + " 正在叫你。").withColor(Colors.LIGHT_GRAY));
|
foundPlayer.sendMessage(Text.literal(sender.getName().getLiteralString() + " 正在叫你。").withColor(Colors.LIGHT_GRAY), true);
|
||||||
}
|
}
|
||||||
foundPlayer.playSoundToPlayer(
|
foundPlayer.playSoundToPlayer(
|
||||||
SoundEvents.ENTITY_ITEM_PICKUP,
|
SoundEvents.ENTITY_ITEM_PICKUP,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class ChatSendLocModule extends ServerModule implements MessageDecorator
|
|||||||
|
|
||||||
private static Text generateLocText(ServerPlayerEntity sender) {
|
private static Text generateLocText(ServerPlayerEntity sender) {
|
||||||
if (sender == null) return Text.of(" (invalid position) ");
|
if (sender == null) return Text.of(" (invalid position) ");
|
||||||
sender.addStatusEffect(new StatusEffectInstance(StatusEffects.GLOWING, 15*20));
|
sender.addStatusEffect(new StatusEffectInstance(StatusEffects.GLOWING, 15 * 20));
|
||||||
var x = sender.getBlockPos().getX();
|
var x = sender.getBlockPos().getX();
|
||||||
var y = sender.getBlockPos().getY();
|
var y = sender.getBlockPos().getY();
|
||||||
var z = sender.getBlockPos().getZ();
|
var z = sender.getBlockPos().getZ();
|
||||||
@@ -46,7 +46,7 @@ public class ChatSendLocModule extends ServerModule implements MessageDecorator
|
|||||||
return Text
|
return Text
|
||||||
.literal(" " + x + ", " + y + ", " + z + world + " ")
|
.literal(" " + x + ", " + y + ", " + z + world + " ")
|
||||||
.withColor(Helper.fromRgb(63, 254, 254))
|
.withColor(Helper.fromRgb(63, 254, 254))
|
||||||
.styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/gps " + key + " " + x + " " + y + " " + z)));
|
.styled(style -> style.withClickEvent(new ClickEvent.RunCommand("/gps " + key + " " + x + " " + y + " " + z)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String translate(RegistryKey<World> registryKey) {
|
private static String translate(RegistryKey<World> registryKey) {
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class BackModule extends ServerModule {
|
|||||||
|
|
||||||
public void onPlayerDeath(PlayerEntity player, DamageSource damageSource) {
|
public void onPlayerDeath(PlayerEntity player, DamageSource damageSource) {
|
||||||
if (this.isEnabled() && Helper.canBack((ServerPlayerEntity) player)) {
|
if (this.isEnabled() && Helper.canBack((ServerPlayerEntity) player)) {
|
||||||
player.sendMessage(Text.of("Tip: 死亡地点附近有玩家,可以使用 /back 传送到他们那里。(即使在对方也死亡的状态下)"));
|
player.sendMessage(Text.of("Tip: 死亡地点附近有玩家,可以使用 /back 传送到他们那里。(即使在对方也死亡的状态下)"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package io.ib67.sfcraft.module.randomevt;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.mojang.datafixers.util.Either;
|
|
||||||
import io.ib67.sfcraft.ServerModule;
|
|
||||||
import io.ib67.sfcraft.callback.SFCallbacks;
|
|
||||||
import io.ib67.sfcraft.module.randomevt.longnight.DawnAfterLongNightEvent;
|
|
||||||
import io.ib67.sfcraft.module.randomevt.longnight.LongNightEvent;
|
|
||||||
import io.ib67.sfcraft.registry.RandomEventRegistry;
|
|
||||||
import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.Items;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.util.*;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
public class LongNightModule extends ServerModule {
|
|
||||||
@Inject
|
|
||||||
RandomEventRegistry registry;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onInitialize() {
|
|
||||||
registry.registerEvent(LongNightEvent::new, World.OVERWORLD
|
|
||||||
, world -> !LongNightEvent.isRunning()
|
|
||||||
&& isEnabled()
|
|
||||||
&& world.getTimeOfDay() % 24000 == 18000
|
|
||||||
&& world.getRandom().nextBetween(0, 100) < 5); // At midnight
|
|
||||||
registry.registerEvent(DawnAfterLongNightEvent::new, World.OVERWORLD
|
|
||||||
, world -> world.getTimeOfDay() % 22200 == 0); // At dawn
|
|
||||||
SFCallbacks.PLAYER_SLEEP.register(this::onPlayerSleep);
|
|
||||||
UseItemCallback.EVENT.register(this::onUseClock);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypedActionResult<ItemStack> onUseClock(PlayerEntity player, World world, Hand hand) {
|
|
||||||
if (player.isSpectator()) return TypedActionResult.pass(ItemStack.EMPTY);
|
|
||||||
if (player.getStackInHand(hand).isOf(Items.CLOCK)) {
|
|
||||||
if (LongNightEvent.isRunning())
|
|
||||||
player.sendMessage(Text.literal("永夜还将持续约 " + LongNightEvent.getRemainingTicks() / 20 + " 秒。").withColor(Colors.LIGHT_GRAY));
|
|
||||||
}
|
|
||||||
return TypedActionResult.pass(ItemStack.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Either<PlayerEntity.SleepFailureReason, Unit> onPlayerSleep(PlayerEntity player, BlockPos pos) {
|
|
||||||
if (!isEnabled()) return Either.right(Unit.INSTANCE);
|
|
||||||
if (LongNightEvent.isRunning()) {
|
|
||||||
player.sendMessage(Text.literal("你感到焦躁不安!").withColor(Colors.LIGHT_RED)
|
|
||||||
.append(Text.literal(" (永夜事件期间无法睡觉)").withColor(Colors.LIGHT_GRAY)));
|
|
||||||
return Either.left(PlayerEntity.SleepFailureReason.NOT_POSSIBLE_HERE);
|
|
||||||
}
|
|
||||||
return Either.right(Unit.INSTANCE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,7 @@ package io.ib67.sfcraft.module.randomevt.longnight;
|
|||||||
import io.ib67.sfcraft.module.randomevt.RandomEvent;
|
import io.ib67.sfcraft.module.randomevt.RandomEvent;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Colors;
|
import net.minecraft.util.Colors;
|
||||||
import net.minecraft.world.GameRules;
|
import net.minecraft.world.GameRules;
|
||||||
@@ -14,7 +15,7 @@ public class LongNightEvent extends RandomEvent {
|
|||||||
static boolean isAtLongNight;
|
static boolean isAtLongNight;
|
||||||
@Getter
|
@Getter
|
||||||
private static int remainingTicks;
|
private static int remainingTicks;
|
||||||
private final World world;
|
private final ServerWorld world;
|
||||||
private boolean doDaylightCycle;
|
private boolean doDaylightCycle;
|
||||||
private boolean doTraderSpawning;
|
private boolean doTraderSpawning;
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class CreativeRoomModule extends ServerModule {
|
public class CreativeRoomModule extends ServerModule {
|
||||||
private static final Set<String> BYPASS_PERMISSIONS = Set.of(
|
private static final Set<String> BYPASS_PERMISSIONS = Set.of(
|
||||||
"minecraft.command.gamerule",
|
|
||||||
"carpet.command.player",
|
"carpet.command.player",
|
||||||
"carpet.command.track",
|
"carpet.command.track",
|
||||||
"minecraft.command.setblock",
|
"minecraft.command.setblock",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import net.minecraft.text.Text;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.net.URI;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
@@ -69,7 +70,7 @@ public class SchematicUploader extends WebHandler {
|
|||||||
}
|
}
|
||||||
var url = generateSchematicUrl(source.isExecutedByPlayer() ? source.getPlayer().getName().getLiteralString() : "CONSOLE");
|
var url = generateSchematicUrl(source.isExecutedByPlayer() ? source.getPlayer().getName().getLiteralString() : "CONSOLE");
|
||||||
source.sendMessage(Text.literal("Click this URL to upload schematic files.").withColor(Color.GREEN.getRGB()));
|
source.sendMessage(Text.literal("Click this URL to upload schematic files.").withColor(Color.GREEN.getRGB()));
|
||||||
source.sendMessage(Text.literal(url).styled(it -> it.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url))));
|
source.sendMessage(Text.literal(url).styled(it -> it.withClickEvent(new ClickEvent.OpenUrl(URI.create(url)))));
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,8 +174,8 @@ public class SchematicUploader extends WebHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player.sendMessage(Text.literal("Schematic " + fileName + " has been saved! Use //schem list to find it").withColor(Color.GREEN.getRGB()));
|
player.sendMessage(Text.literal("Schematic " + fileName + " has been saved! Use //schem list to find it").withColor(Color.GREEN.getRGB()));
|
||||||
player.sendMessage(Text.literal("Or you can click this").styled(it->it.withUnderline(true).withClickEvent(
|
player.sendMessage(Text.literal("Or you can click this").styled(it -> it.withUnderline(true).withClickEvent(
|
||||||
new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "//schem load " + fileName)
|
new ClickEvent.SuggestCommand("//schem load " + fileName)
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package io.ib67.sfcraft.room.data;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Dynamic;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.minecraft.datafixer.DataFixTypes;
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
|
||||||
import net.minecraft.nbt.NbtOps;
|
|
||||||
import net.minecraft.registry.RegistryWrapper;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.world.GameRules;
|
|
||||||
import net.minecraft.world.PersistentState;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public class RoomWorldDataLoader extends PersistentState {
|
|
||||||
|
|
||||||
private static final String NAME = "sfcraft_room_data";
|
|
||||||
private static final Type<RoomWorldDataLoader> TYPE = new Type<>(RoomWorldDataLoader::new, RoomWorldDataLoader::readNbt, DataFixTypes.LEVEL);
|
|
||||||
|
|
||||||
private static final String TAG_GAME_RULES = "gameRules";
|
|
||||||
|
|
||||||
private final GameRules gameRules;
|
|
||||||
|
|
||||||
public RoomWorldDataLoader() {
|
|
||||||
this(new GameRules());
|
|
||||||
}
|
|
||||||
|
|
||||||
public RoomWorldDataLoader(GameRules gameRules) {
|
|
||||||
this.gameRules = gameRules;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RoomWorldDataLoader get(ServerWorld world) {
|
|
||||||
Objects.requireNonNull(world);
|
|
||||||
var state = world.getPersistentStateManager().getOrCreate(TYPE, NAME);
|
|
||||||
state.markDirty();
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registry) {
|
|
||||||
nbt.put(TAG_GAME_RULES, gameRules.toNbt());
|
|
||||||
return nbt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static RoomWorldDataLoader readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registry) {
|
|
||||||
if (nbt.contains(TAG_GAME_RULES)) {
|
|
||||||
var c = nbt.getCompound(TAG_GAME_RULES);
|
|
||||||
var dynamic = new Dynamic<>(NbtOps.INSTANCE, c);
|
|
||||||
var rule = new GameRules(dynamic);
|
|
||||||
return new RoomWorldDataLoader(rule);
|
|
||||||
}
|
|
||||||
return new RoomWorldDataLoader();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -31,6 +31,7 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ public class Helper {
|
|||||||
deltaZ = stand.getCollisionShape(world, pos).getMax(Direction.Axis.X);
|
deltaZ = stand.getCollisionShape(world, pos).getMax(Direction.Axis.X);
|
||||||
deltaZ = Double.isFinite(deltaZ) ? deltaZ / 2 : 0.5;
|
deltaZ = Double.isFinite(deltaZ) ? deltaZ / 2 : 0.5;
|
||||||
}
|
}
|
||||||
player.teleport(world, x + deltaX, y + deltaY, z + deltaZ, yaw, pitch);
|
player.teleport(world, x + deltaX, y + deltaY, z + deltaZ, Set.of(), yaw, pitch, true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,15 @@ import java.io.IOException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TypedNbtList extends NbtList {
|
public class TypedNbtList extends NbtList {
|
||||||
|
private final byte heldType;
|
||||||
public TypedNbtList(List<NbtElement> list, byte type) {
|
public TypedNbtList(List<NbtElement> list, byte type) {
|
||||||
super(list, type);
|
super(list);
|
||||||
|
this.heldType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(DataOutput output) throws IOException {
|
public void write(DataOutput output) throws IOException {
|
||||||
output.writeByte(this.getHeldType());
|
output.writeByte(heldType);
|
||||||
output.writeInt(this.size());
|
output.writeInt(this.size());
|
||||||
|
|
||||||
for (NbtElement nbtElement : this) {
|
for (NbtElement nbtElement : this) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.apache.commons.compress.utils.Lists;
|
|||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -31,11 +32,14 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
BiConsumer<String, NbtCompound> schematicOutput
|
BiConsumer<String, NbtCompound> schematicOutput
|
||||||
) {
|
) {
|
||||||
var root = NbtIo.readCompressed(input, sizeTracker);
|
var root = NbtIo.readCompressed(input, sizeTracker);
|
||||||
var dataVersion = root.getInt("MinecraftDataVersion");
|
var dataVersion = root.getInt("MinecraftDataVersion")
|
||||||
var regionsNbt = root.getCompound("Regions");
|
.orElseThrow(() -> new IllegalStateException("MinecraftDataVersion not found"));
|
||||||
|
var regionsNbt = root.getCompound("Regions")
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Regions not found"));
|
||||||
var i = 0;
|
var i = 0;
|
||||||
for (String regionName : regionsNbt.getKeys()) {
|
for (String regionName : regionsNbt.getKeys()) {
|
||||||
var compound = regionsNbt.getCompound(regionName);
|
var compound = regionsNbt.getCompound(regionName)
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Region " + regionName + " not found"));
|
||||||
var j = i++;
|
var j = i++;
|
||||||
var schematic = convertRegionToSchematic(dataVersion, compound);
|
var schematic = convertRegionToSchematic(dataVersion, compound);
|
||||||
schematicOutput.accept(regionName, schematic);
|
schematicOutput.accept(regionName, schematic);
|
||||||
@@ -56,11 +60,11 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
worldEditTag.putShort("Width", (short) Math.abs(size.x));
|
worldEditTag.putShort("Width", (short) Math.abs(size.x));
|
||||||
|
|
||||||
// block & tile entities
|
// block & tile entities
|
||||||
var paletteNbt = region.getList("BlockStatePalette", NbtElement.COMPOUND_TYPE);
|
var paletteNbt = region.getListOrEmpty("BlockStatePalette");
|
||||||
var wePalette = convertToWEPalette(paletteNbt);
|
var wePalette = convertToWEPalette(paletteNbt);
|
||||||
worldEditTag.putInt("PaletteMax", wePalette.getKeys().size());
|
worldEditTag.putInt("PaletteMax", wePalette.getKeys().size());
|
||||||
worldEditTag.put("Palette", wePalette);
|
worldEditTag.put("Palette", wePalette);
|
||||||
var tileEntities = region.getList("TileEntities", NbtElement.COMPOUND_TYPE);
|
var tileEntities = region.getListOrEmpty("TileEntities");
|
||||||
worldEditTag.put("BlockEntities", convertToWETileEntities(tileEntities));
|
worldEditTag.put("BlockEntities", convertToWETileEntities(tileEntities));
|
||||||
worldEditTag.putInt("Version", 2);
|
worldEditTag.putInt("Version", 2);
|
||||||
worldEditTag.putIntArray("Offset", new int[3]);
|
worldEditTag.putIntArray("Offset", new int[3]);
|
||||||
@@ -72,9 +76,15 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
|
|
||||||
protected SizeTuple readSizeTuple(NbtCompound region) {
|
protected SizeTuple readSizeTuple(NbtCompound region) {
|
||||||
var size = (NbtCompound) region.get("Size");
|
var size = (NbtCompound) region.get("Size");
|
||||||
var sizeX = size.getInt("x");
|
if (size == null) {
|
||||||
var sizeY = size.getInt("y");
|
throw new IllegalStateException("Size not found");
|
||||||
var sizeZ = size.getInt("z");
|
}
|
||||||
|
var sizeX = size.getInt("x")
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Size X not found"));
|
||||||
|
var sizeY = size.getInt("y")
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Size Y not found"));
|
||||||
|
var sizeZ = size.getInt("z")
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Size Z not found"));
|
||||||
return new SizeTuple(sizeX, sizeY, sizeZ);
|
return new SizeTuple(sizeX, sizeY, sizeZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,11 +95,14 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
var weTE = new NbtCompound();
|
var weTE = new NbtCompound();
|
||||||
var tE = (NbtCompound) _tileEntity;
|
var tE = (NbtCompound) _tileEntity;
|
||||||
weTE.putIntArray("Pos", new int[]{
|
weTE.putIntArray("Pos", new int[]{
|
||||||
tE.getInt("x"),
|
tE.getInt("x")
|
||||||
tE.getInt("y"),
|
.orElseThrow(() -> new IllegalStateException("Pos X not found")),
|
||||||
|
tE.getInt("y")
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Pos Y not found")),
|
||||||
tE.getInt("z")
|
tE.getInt("z")
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Pos Z not found"))
|
||||||
});
|
});
|
||||||
weTE.putString("Id", tE.getString("id"));
|
weTE.putString("Id", tE.getString("id").orElseThrow(() -> new IllegalStateException("Id not found")));
|
||||||
// other properties
|
// other properties
|
||||||
tE.remove("x");
|
tE.remove("x");
|
||||||
tE.remove("y");
|
tE.remove("y");
|
||||||
@@ -105,15 +118,15 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
var wePalette = new NbtCompound();
|
var wePalette = new NbtCompound();
|
||||||
for (int i = 0; i < paletteNbt.size(); i++) {
|
for (int i = 0; i < paletteNbt.size(); i++) {
|
||||||
var entry = (NbtCompound) paletteNbt.get(i);
|
var entry = (NbtCompound) paletteNbt.get(i);
|
||||||
var name = new StringBuilder(entry.getString("Name"));
|
var name = new StringBuilder(entry.getString("Name").orElseThrow(() -> new IllegalStateException("Name not found")));
|
||||||
var properties = entry.getCompound("Properties");
|
var properties = entry.getCompound("Properties").orElseThrow(() -> new IllegalStateException("Properties not found"));
|
||||||
if (!properties.isEmpty()) {
|
if (!properties.isEmpty()) {
|
||||||
name.append("[");
|
name.append("[");
|
||||||
var props = new ArrayList<String>();
|
var props = new ArrayList<String>();
|
||||||
for (String key : properties.getKeys()) {
|
for (String key : properties.getKeys()) {
|
||||||
props.add(key + "=" + properties.getString(key));
|
props.add(key + "=" + properties.getString(key));
|
||||||
}
|
}
|
||||||
name.append(props.stream().collect(Collectors.joining(",")));
|
name.append(String.join(",", props));
|
||||||
name.append("]");
|
name.append("]");
|
||||||
}
|
}
|
||||||
wePalette.putInt(name.toString(), i);
|
wePalette.putInt(name.toString(), i);
|
||||||
@@ -123,17 +136,20 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
|
|
||||||
protected NbtElement convertToWeMeta(SizeTuple size, NbtCompound region) {
|
protected NbtElement convertToWeMeta(SizeTuple size, NbtCompound region) {
|
||||||
var pos = (NbtCompound) region.get("Position");
|
var pos = (NbtCompound) region.get("Position");
|
||||||
|
if (pos == null){
|
||||||
|
throw new IllegalStateException("Pos not found");
|
||||||
|
}
|
||||||
var nbt = new NbtCompound();
|
var nbt = new NbtCompound();
|
||||||
nbt.putInt("WEOffsetX", pos.getInt("x") + (size.x < 0 ? size.x + 1 : 0));
|
nbt.putInt("WEOffsetX", pos.getInt("x").orElseThrow() + (size.x < 0 ? size.x + 1 : 0));
|
||||||
nbt.putInt("WEOffsetY", pos.getInt("y") + (size.y < 0 ? size.y + 1 : 0));
|
nbt.putInt("WEOffsetY", pos.getInt("y").orElseThrow() + (size.y < 0 ? size.y + 1 : 0));
|
||||||
nbt.putInt("WEOffsetZ", pos.getInt("z") + (size.z < 0 ? size.z + 1 : 0));
|
nbt.putInt("WEOffsetZ", pos.getInt("z").orElseThrow() + (size.z < 0 ? size.z + 1 : 0));
|
||||||
return nbt;
|
return nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] convertToWEBlocks(SizeTuple size, NbtCompound region) {
|
protected byte[] convertToWEBlocks(SizeTuple size, NbtCompound region) {
|
||||||
var blockCount = Math.abs(size.x * size.y * size.z);
|
var blockCount = Math.abs(size.x * size.y * size.z);
|
||||||
var blockStates = region.getLongArray("BlockStates");
|
var blockStates = region.getLongArray("BlockStates").orElse(new long[0]);
|
||||||
int bitsPerBlock = region.getList("BlockStatePalette", NbtElement.COMPOUND_TYPE).size();
|
int bitsPerBlock = region.getListOrEmpty("BlockStatePalette").size();
|
||||||
bitsPerBlock = Math.max(2, Integer.SIZE - Integer.numberOfLeadingZeros(bitsPerBlock - 1));
|
bitsPerBlock = Math.max(2, Integer.SIZE - Integer.numberOfLeadingZeros(bitsPerBlock - 1));
|
||||||
int maxEntryValue = (1 << bitsPerBlock) - 1;
|
int maxEntryValue = (1 << bitsPerBlock) - 1;
|
||||||
var buffer = new PacketByteBuf(Unpooled.buffer());
|
var buffer = new PacketByteBuf(Unpooled.buffer());
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ public class LitematicConverterV3 extends LitematicConverter {
|
|||||||
schematicsTag.putShort("Width", (short) Math.abs(size.x()));
|
schematicsTag.putShort("Width", (short) Math.abs(size.x()));
|
||||||
|
|
||||||
// block & tile entities
|
// block & tile entities
|
||||||
var paletteNbt = region.getList("BlockStatePalette", NbtElement.COMPOUND_TYPE);
|
var paletteNbt = region.getListOrEmpty("BlockStatePalette");
|
||||||
var wePalette = convertToWEPalette(paletteNbt);
|
var wePalette = convertToWEPalette(paletteNbt);
|
||||||
var tileEntities = region.getList("TileEntities", NbtElement.COMPOUND_TYPE);
|
var tileEntities = region.getListOrEmpty("TileEntities");
|
||||||
|
|
||||||
var blocksNbt = new NbtCompound();
|
var blocksNbt = new NbtCompound();
|
||||||
blocksNbt.put("Palette", wePalette);
|
blocksNbt.put("Palette", wePalette);
|
||||||
@@ -63,7 +63,11 @@ public class LitematicConverterV3 extends LitematicConverter {
|
|||||||
var paletteIds = new Int2ObjectOpenHashMap<>();
|
var paletteIds = new Int2ObjectOpenHashMap<>();
|
||||||
var touchedIds = new IntOpenHashSet();
|
var touchedIds = new IntOpenHashSet();
|
||||||
for (String key : wePalette.getKeys()) {
|
for (String key : wePalette.getKeys()) {
|
||||||
paletteIds.put(wePalette.getInt(key), key);
|
paletteIds.put(
|
||||||
|
wePalette.getInt(key)
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Cannot find key " + key + " in palette from worldedit schematic"))
|
||||||
|
, key
|
||||||
|
);
|
||||||
}
|
}
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
try {
|
try {
|
||||||
@@ -79,8 +83,8 @@ public class LitematicConverterV3 extends LitematicConverter {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error validing schematic", e);
|
log.error("Error validing schematic", e);
|
||||||
}
|
}
|
||||||
paletteIds.keySet().intStream().filter(it->!touchedIds.contains(it))
|
paletteIds.keySet().intStream().filter(it -> !touchedIds.contains(it))
|
||||||
.forEach(it-> log.error("Unused palette id: {}, blockState: {}", it, paletteIds.get(it)));
|
.forEach(it -> log.error("Unused palette id: {}, blockState: {}", it, paletteIds.get(it)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vec3i decodePositionFromDataIndex(int width, int length, int index) {
|
private static Vec3i decodePositionFromDataIndex(int width, int length, int index) {
|
||||||
@@ -95,11 +99,14 @@ public class LitematicConverterV3 extends LitematicConverter {
|
|||||||
@Override
|
@Override
|
||||||
protected NbtElement convertToWeMeta(SizeTuple size, NbtCompound region) {
|
protected NbtElement convertToWeMeta(SizeTuple size, NbtCompound region) {
|
||||||
var pos = (NbtCompound) region.get("Position");
|
var pos = (NbtCompound) region.get("Position");
|
||||||
|
if (pos == null) {
|
||||||
|
throw new IllegalStateException("Cannot find Position");
|
||||||
|
}
|
||||||
var worldEditNbt = new NbtCompound();
|
var worldEditNbt = new NbtCompound();
|
||||||
worldEditNbt.putIntArray("Origin", new int[]{
|
worldEditNbt.putIntArray("Origin", new int[]{
|
||||||
pos.getInt("x") + (size.x() < 0 ? size.x() + 1 : 0),
|
pos.getInt("x").orElseThrow() + (size.x() < 0 ? size.x() + 1 : 0),
|
||||||
pos.getInt("y") + (size.y() < 0 ? size.y() + 1 : 0),
|
pos.getInt("y").orElseThrow() + (size.y() < 0 ? size.y() + 1 : 0),
|
||||||
pos.getInt("z") + (size.z() < 0 ? size.z() + 1 : 0)
|
pos.getInt("z").orElseThrow() + (size.z() < 0 ? size.z() + 1 : 0)
|
||||||
});
|
});
|
||||||
var Metadata = new NbtCompound();
|
var Metadata = new NbtCompound();
|
||||||
Metadata.put("WorldEdit", worldEditNbt);
|
Metadata.put("WorldEdit", worldEditNbt);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
accessWidener v2 named
|
accessWidener v2 named
|
||||||
mutable field net/minecraft/item/Item registryEntry Lnet/minecraft/registry/entry/RegistryEntry$Reference;
|
mutable field net/minecraft/item/Item registryEntry Lnet/minecraft/registry/entry/RegistryEntry$Reference;
|
||||||
accessible method net/minecraft/nbt/NbtList <init> (Ljava/util/List;B)V
|
accessible method net/minecraft/nbt/NbtList <init> (Ljava/util/List;)V
|
||||||
|
extendable class net/minecraft/nbt/NbtList
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
"common.bridge.EntityBridge",
|
"common.bridge.EntityBridge",
|
||||||
"common.bridge.ItemBridge",
|
"common.bridge.ItemBridge",
|
||||||
"common.bridge.ServerPlayerBridge",
|
"common.bridge.ServerPlayerBridge",
|
||||||
"common.bridge.ServerWorldBridge"
|
"common.bridge.ServerWorldBridge",
|
||||||
|
"server.ServerChunkManagerMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
],
|
],
|
||||||
@@ -26,12 +27,6 @@
|
|||||||
"server.SleepManagerMixin",
|
"server.SleepManagerMixin",
|
||||||
"server.fixes.EndermanEntityMixin",
|
"server.fixes.EndermanEntityMixin",
|
||||||
"server.fixes.ProjectileEntityMixin",
|
"server.fixes.ProjectileEntityMixin",
|
||||||
"server.hack.EntitySpawnS2CPacketMixin",
|
|
||||||
"server.hack.HoverEntityContentMixin",
|
|
||||||
"server.hack.RegistryHandlerMixin",
|
|
||||||
"server.item.ItemMixin",
|
|
||||||
"server.item.ItemStackMixin",
|
|
||||||
"server.item.PlayerEntityMixin",
|
|
||||||
"server.optimize.LivingEntityMixin",
|
"server.optimize.LivingEntityMixin",
|
||||||
"server.subserver.EntityMixin",
|
"server.subserver.EntityMixin",
|
||||||
"server.subserver.PlayerListS2CPacket$EntryMixin",
|
"server.subserver.PlayerListS2CPacket$EntryMixin",
|
||||||
@@ -39,7 +34,6 @@
|
|||||||
"server.subserver.PlayerSaveHandlerMixin",
|
"server.subserver.PlayerSaveHandlerMixin",
|
||||||
"server.subserver.ServerLoginNetworkHandlerMixin",
|
"server.subserver.ServerLoginNetworkHandlerMixin",
|
||||||
"server.subserver.ServerPlayerEntityMixin",
|
"server.subserver.ServerPlayerEntityMixin",
|
||||||
"server.subserver.WorldMixin",
|
|
||||||
"server.subserver.command.GameRuleCommandMixin"
|
"server.subserver.command.GameRuleCommandMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
|
|||||||
Reference in new issue
Block a user