// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.modules.interaction;

import com.hypixel.hytale.server.core.asset.type.blocktype.config.SoftBlockDropType;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockGathering;
import com.hypixel.hytale.protocol.BlockMaterial;
import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk;
import com.hypixel.hytale.server.core.asset.type.gameplay.WorldConfig;
import com.hypixel.hytale.server.core.universe.world.connectedblocks.ConnectedBlocksUtil;
import com.hypixel.hytale.server.core.modules.interaction.components.PlacedByInteractionComponent;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.universe.world.meta.state.PlacedByBlockState;
import com.hypixel.hytale.server.core.blocktype.component.BlockPhysics;
import com.hypixel.hytale.server.core.universe.world.chunk.ChunkColumn;
import com.hypixel.hytale.server.core.util.FillerBlockUtil;
import com.hypixel.hytale.server.core.asset.type.blockhitbox.BlockBoundingBoxes;
import com.hypixel.hytale.server.core.asset.type.environment.config.Environment;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.prefab.selection.buffer.impl.PrefabBuffer;
import com.hypixel.hytale.server.core.universe.world.World;
import java.nio.file.Path;
import com.hypixel.hytale.server.core.prefab.selection.buffer.impl.IPrefabBuffer;
import com.hypixel.hytale.server.core.util.PrefabUtil;
import java.util.Random;
import com.hypixel.hytale.server.core.prefab.selection.buffer.PrefabBufferUtil;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import com.hypixel.hytale.server.core.asset.type.buildertool.config.PrefabListAsset;
import org.bson.BsonValue;
import org.bson.BsonDocument;
import com.hypixel.hytale.sneakythrow.SneakyThrow;
import java.util.logging.Level;
import com.hypixel.hytale.server.core.universe.world.meta.BlockState;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackTransaction;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackSlotTransaction;
import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.protocol.GameMode;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.server.core.event.events.ecs.PlaceBlockEvent;
import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.Rotation;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.server.core.inventory.Inventory;
import com.hypixel.hytale.protocol.BlockRotation;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.Message;
import javax.annotation.Nonnull;
import com.hypixel.hytale.logger.HytaleLogger;

public class BlockPlaceUtils
{
    @Nonnull
    private static final HytaleLogger LOGGER;
    @Nonnull
    private static final Message MESSAGE_MODULES_INTERACTION_FAILED_ADD_BACK_AFTER_FAILED_PLACE;
    @Nonnull
    private static final Message MESSAGE_MODULES_INTERACTION_FAILED_CHECK_BLOCK;
    @Nonnull
    private static final Message MESSAGE_MODULES_INTERACTION_FAILED_CHECK_EMPTY;
    @Nonnull
    private static final Message MESSAGE_MODULES_INTERACTION_FAILED_CHECK_UNKNOWN;
    @Nonnull
    private static final Message MESSAGE_MODULES_INTERACTION_FAILED_CHECK;
    @Nonnull
    private static final Message MESSAGE_MODULES_INTERACTION_BUILD_FORBIDDEN;
    
    public static void placeBlock(@Nonnull final Ref<EntityStore> ref, @Nonnull ItemStack itemStack, @Nullable String blockTypeKey, @Nonnull final ItemContainer itemContainer, @Nonnull final Vector3i placementNormal, @Nonnull final Vector3i blockPosition, @Nonnull final BlockRotation blockRotation, @Nullable final Inventory inventory, final byte activeSlot, final boolean removeItemInHand, @Nonnull final Ref<ChunkStore> chunkReference, @Nonnull final ComponentAccessor<ChunkStore> chunkStore, @Nonnull final ComponentAccessor<EntityStore> entityStore) {
        if (blockPosition.getY() < 0 || blockPosition.getY() >= 320) {
            return;
        }
        Ref<ChunkStore> targetChunkReference = chunkReference;
        Vector3i targetBlockPosition = blockPosition;
        RotationTuple targetRotation = RotationTuple.of(Rotation.valueOf(blockRotation.rotationYaw), Rotation.valueOf(blockRotation.rotationPitch), Rotation.valueOf(blockRotation.rotationRoll));
        BlockChunk targetBlockChunkComponent = chunkStore.getComponent(chunkReference, BlockChunk.getComponentType());
        assert targetBlockChunkComponent != null;
        BlockSection targetBlockSection = targetBlockChunkComponent.getSectionAtBlockY(blockPosition.getY());
        final PlaceBlockEvent event = new PlaceBlockEvent(itemStack, blockPosition, targetRotation);
        entityStore.invoke(ref, event);
        if (event.isCancelled()) {
            targetBlockSection.invalidateBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
            return;
        }
        targetBlockPosition = event.getTargetBlock();
        targetRotation = event.getRotation();
        final boolean positionIsDifferent = !ChunkUtil.isSameChunk(targetBlockPosition.x, targetBlockPosition.z, blockPosition.x, blockPosition.z);
        if (positionIsDifferent) {
            final long chunkIndex = ChunkUtil.indexChunkFromBlock(targetBlockPosition.x, targetBlockPosition.z);
            targetChunkReference = chunkStore.getExternalData().getChunkReference(chunkIndex);
            if (targetChunkReference == null || !targetChunkReference.isValid()) {
                return;
            }
        }
        if (positionIsDifferent) {
            targetBlockSection.invalidateBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
        }
        if (!targetChunkReference.equals(chunkReference) || targetBlockPosition.y != blockPosition.y) {
            targetBlockChunkComponent = chunkStore.getComponent(targetChunkReference, BlockChunk.getComponentType());
            assert targetBlockChunkComponent != null;
            targetBlockSection = targetBlockChunkComponent.getSectionAtBlockY(targetBlockPosition.getY());
        }
        final PlayerRef playerRefComponent = entityStore.getComponent(ref, PlayerRef.getComponentType());
        final Player playerComponent = entityStore.getComponent(ref, Player.getComponentType());
        final boolean isAdventureMode = playerComponent == null || playerComponent.getGameMode() == GameMode.Adventure;
        if (isAdventureMode && removeItemInHand) {
            final ItemStackSlotTransaction transaction = itemContainer.removeItemStackFromSlot(activeSlot, itemStack, 1);
            if (!transaction.succeeded()) {
                if (playerRefComponent != null) {
                    playerRefComponent.sendMessage(BlockPlaceUtils.MESSAGE_MODULES_INTERACTION_FAILED_CHECK);
                }
                return;
            }
            itemStack = transaction.getOutput();
        }
        if (blockTypeKey == null && itemStack != null) {
            blockTypeKey = itemStack.getBlockKey();
        }
        if (!validateBlockToPlace(blockTypeKey, playerRefComponent)) {
            return;
        }
        assert blockTypeKey != null;
        final BlockType blockTypeAsset = BlockType.getAssetMap().getAsset(blockTypeKey);
        if (blockTypeAsset != null) {
            final String prefabListAssetId = blockTypeAsset.getPrefabListAssetId();
            if (prefabListAssetId != null && !validateAndPlacePrefab(blockPosition, prefabListAssetId, playerRefComponent, entityStore)) {
                return;
            }
        }
        final WorldChunk worldChunkComponent = chunkStore.getComponent(targetChunkReference, WorldChunk.getComponentType());
        if (worldChunkComponent == null) {
            return;
        }
        final boolean success = tryPlaceBlock(ref, placementNormal, targetBlockPosition, blockTypeKey, targetRotation, worldChunkComponent, targetBlockChunkComponent, chunkReference, chunkStore, entityStore);
        if (success) {
            onPlaceBlockSuccess(itemStack, worldChunkComponent, targetBlockPosition);
        }
        else {
            onPlaceBlockFailure(itemStack, inventory, activeSlot, playerComponent, targetBlockSection, targetBlockPosition);
        }
    }
    
    private static void onPlaceBlockFailure(@Nullable final ItemStack itemStack, @Nullable final Inventory inventory, final byte activeSlot, @Nullable final Player playerComponent, @Nonnull final BlockSection blockSection, @Nonnull final Vector3i blockPosition) {
        final boolean isAdventure = playerComponent == null || playerComponent.getGameMode() == GameMode.Adventure;
        if (inventory != null && itemStack != null && isAdventure) {
            final ItemContainer hotbar = inventory.getHotbar();
            final ItemStackSlotTransaction transaction = hotbar.addItemStackToSlot(activeSlot, itemStack);
            if (!transaction.succeeded()) {
                final ItemStackTransaction itemStackTransaction = hotbar.addItemStack(itemStack);
                if (!itemStackTransaction.succeeded() && playerComponent != null) {
                    playerComponent.sendMessage(BlockPlaceUtils.MESSAGE_MODULES_INTERACTION_FAILED_ADD_BACK_AFTER_FAILED_PLACE);
                }
                return;
            }
        }
        blockSection.invalidateBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
    }
    
    private static void onPlaceBlockSuccess(@Nullable final ItemStack itemStack, @Nonnull final WorldChunk worldChunkComponent, @Nonnull final Vector3i blockPosition) {
        if (itemStack == null) {
            return;
        }
        final BsonDocument metadata = itemStack.getMetadata();
        if (metadata == null) {
            return;
        }
        final BsonValue bsonValue = metadata.get("BlockState");
        if (bsonValue == null) {
            return;
        }
        try {
            final BsonDocument document = bsonValue.asDocument();
            final BlockState blockState = BlockState.load(document, worldChunkComponent, blockPosition.clone());
            if (blockState != null) {
                worldChunkComponent.setState(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), blockState);
            }
            else {
                BlockPlaceUtils.LOGGER.at(Level.WARNING).log("Failed to set BlockState from item metadata: %s, %s", itemStack.getItemId(), document);
            }
        }
        catch (final Exception e) {
            throw SneakyThrow.sneakyThrow(e);
        }
    }
    
    private static boolean validateBlockToPlace(@Nullable final String blockTypeKey, @Nullable final PlayerRef playerRefComponent) {
        if (blockTypeKey == null) {
            if (playerRefComponent != null) {
                playerRefComponent.sendMessage(BlockPlaceUtils.MESSAGE_MODULES_INTERACTION_FAILED_CHECK_BLOCK);
            }
            return false;
        }
        if (blockTypeKey.equals("Empty")) {
            if (playerRefComponent != null) {
                playerRefComponent.sendMessage(BlockPlaceUtils.MESSAGE_MODULES_INTERACTION_FAILED_CHECK_EMPTY);
            }
            return false;
        }
        if (blockTypeKey.equals("Unknown")) {
            if (playerRefComponent != null) {
                playerRefComponent.sendMessage(BlockPlaceUtils.MESSAGE_MODULES_INTERACTION_FAILED_CHECK_UNKNOWN);
            }
            return false;
        }
        return true;
    }
    
    private static boolean validateAndPlacePrefab(@Nonnull final Vector3i blockPosition, @Nonnull final String prefabListAssetId, @Nullable final PlayerRef playerRefComponent, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final PrefabListAsset prefabListAsset = PrefabListAsset.getAssetMap().getAsset(prefabListAssetId);
        if (prefabListAsset == null) {
            if (playerRefComponent != null) {
                playerRefComponent.sendMessage(Message.translation("server.modules.interaction.placeBlock.prefabListNotFound").param("name", prefabListAssetId));
            }
            return false;
        }
        final Path randomPrefab = prefabListAsset.getRandomPrefab();
        if (randomPrefab == null) {
            if (playerRefComponent != null) {
                playerRefComponent.sendMessage(Message.translation("server.modules.interaction.placeBlock.prefabListEmpty").param("name", prefabListAssetId));
            }
            return false;
        }
        if (!Files.exists(randomPrefab, new LinkOption[0])) {
            if (playerRefComponent != null) {
                playerRefComponent.sendMessage(Message.translation("server.commands.editprefab.prefabNotFound").param("name", randomPrefab.toString()));
            }
            return false;
        }
        final World world = componentAccessor.getExternalData().getWorld();
        final PrefabBuffer prefabBuffer = PrefabBufferUtil.loadBuffer(randomPrefab);
        world.execute(() -> {
            final Store<EntityStore> store = world.getEntityStore().getStore();
            final PrefabBuffer.PrefabBufferAccessor prefabBufferAccessor = prefabBuffer.newAccess();
            PrefabUtil.paste(prefabBufferAccessor, world, blockPosition, Rotation.None, true, new Random(), store);
            prefabBufferAccessor.release();
            return;
        });
        return true;
    }
    
    private static boolean tryPlaceBlock(@Nonnull final Ref<EntityStore> ref, @Nonnull final Vector3i placementNormal, @Nonnull final Vector3i blockPosition, @Nonnull final String blockTypeKey, @Nonnull final RotationTuple rotation, @Nonnull final WorldChunk worldChunkComponent, @Nonnull final BlockChunk blockChunkComponent, @Nonnull final Ref<ChunkStore> chunkReference, @Nonnull final ComponentAccessor<ChunkStore> chunkStore, @Nonnull final ComponentAccessor<EntityStore> entityStore) {
        final WorldConfig worldConfig = entityStore.getExternalData().getWorld().getGameplayConfig().getWorldConfig();
        if (!worldConfig.isBlockPlacementAllowed()) {
            return false;
        }
        final Player playerComponent = entityStore.getComponent(ref, Player.getComponentType());
        final PlayerRef playerRefComponent = entityStore.getComponent(ref, PlayerRef.getComponentType());
        final boolean isAdventure = playerComponent == null || playerComponent.getGameMode() == GameMode.Adventure;
        if (isAdventure) {
            final int environmentId = blockChunkComponent.getEnvironment(blockPosition);
            final Environment environment = Environment.getAssetMap().getAsset(environmentId);
            if (environment != null && !environment.isBlockModificationAllowed()) {
                if (playerRefComponent != null) {
                    playerRefComponent.sendMessage(BlockPlaceUtils.MESSAGE_MODULES_INTERACTION_BUILD_FORBIDDEN);
                }
                return false;
            }
        }
        final BlockType blockType = BlockType.getAssetMap().getAsset(blockTypeKey);
        final int rotationIndex = rotation.index();
        if (blockType == null || !worldChunkComponent.testPlaceBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), blockType, rotationIndex)) {
            return false;
        }
        final BlockBoundingBoxes hitBoxType = BlockBoundingBoxes.getAssetMap().getAsset(blockType.getHitboxTypeIndex());
        if (hitBoxType != null) {
            FillerBlockUtil.forEachFillerBlock(hitBoxType.get(rotationIndex), (x1, y1, z1) -> breakAndDropReplacedBlock(blockPosition.clone().add(x1, y1, z1), worldChunkComponent, chunkReference, ref, chunkStore, entityStore));
        }
        else {
            breakAndDropReplacedBlock(blockPosition, worldChunkComponent, chunkReference, ref, chunkStore, entityStore);
        }
        final int placeBlockSettings = 10;
        if (!worldChunkComponent.placeBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), blockTypeKey, rotation, 10, false)) {
            return false;
        }
        if (playerComponent != null && !playerComponent.isOverrideBlockPlacementRestrictions() && blockType.canBePlacedAsDeco()) {
            final ChunkColumn chunkColumnComponent = chunkStore.getComponent(chunkReference, ChunkColumn.getComponentType());
            assert chunkColumnComponent != null;
            final Ref<ChunkStore> sectionRef = chunkColumnComponent.getSection(ChunkUtil.chunkCoordinate(blockPosition.y));
            if (sectionRef != null && sectionRef.isValid()) {
                BlockPhysics.markDeco(chunkStore, sectionRef, blockPosition.x, blockPosition.y, blockPosition.z);
            }
        }
        final BlockState blockState = worldChunkComponent.getState(blockPosition.x, blockPosition.y, blockPosition.z);
        if (blockState instanceof final PlacedByBlockState placedByBlockState) {
            placedByBlockState.placedBy(ref, blockTypeKey, blockState, entityStore);
        }
        final int blockIndexInChunk = ChunkUtil.indexBlockInColumn(blockPosition.x, blockPosition.y, blockPosition.z);
        final BlockComponentChunk blockComponentChunk = worldChunkComponent.getBlockComponentChunk();
        final Ref<ChunkStore> blockRef = (blockComponentChunk == null) ? null : blockComponentChunk.getEntityReference(blockIndexInChunk);
        if (blockRef != null) {
            final UUIDComponent uuidComponent = entityStore.getComponent(ref, UUIDComponent.getComponentType());
            assert uuidComponent != null;
            final PlacedByInteractionComponent placedByInteractionComponent = new PlacedByInteractionComponent(uuidComponent.getUuid());
            chunkStore.putComponent(blockRef, PlacedByInteractionComponent.getComponentType(), placedByInteractionComponent);
        }
        ConnectedBlocksUtil.setConnectedBlockAndNotifyNeighbors(BlockType.getAssetMap().getIndex(blockTypeKey), rotation, placementNormal, blockPosition, worldChunkComponent, blockChunkComponent);
        return true;
    }
    
    private static void breakAndDropReplacedBlock(@Nonnull final Vector3i blockPosition, @Nonnull final WorldChunk worldChunkComponent, @Nonnull final Ref<ChunkStore> chunkReference, @Nonnull final Ref<EntityStore> ref, @Nonnull final ComponentAccessor<ChunkStore> chunkStore, @Nonnull final ComponentAccessor<EntityStore> entityStore) {
        final BlockType existingBlock = worldChunkComponent.getBlockType(blockPosition);
        if (existingBlock != null) {
            if (existingBlock.getMaterial() != BlockMaterial.Empty) {
                return;
            }
            final BlockGathering gathering = existingBlock.getGathering();
            final int dropQuantity = 1;
            String itemId = null;
            String dropListId = null;
            if (gathering != null) {
                final SoftBlockDropType softGathering = gathering.getSoft();
                if (softGathering != null) {
                    itemId = softGathering.getItemId();
                    dropListId = softGathering.getDropListId();
                }
            }
            final int setBlockSettings = 288;
            BlockHarvestUtils.performBlockBreak(chunkStore.getExternalData().getWorld(), blockPosition, existingBlock, null, dropQuantity, itemId, dropListId, 288, ref, chunkReference, entityStore, chunkStore);
        }
    }
    
    public static boolean canPlaceBlock(@Nonnull final BlockType blockType, @Nonnull final String placedBlockTypeKey) {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     1: invokevirtual   com/hypixel/hytale/server/core/asset/type/blocktype/config/BlockType.getId:()Ljava/lang/String;
        //     4: aload_1         /* placedBlockTypeKey */
        //     5: invokevirtual   java/lang/String.equals:(Ljava/lang/Object;)Z
        //     8: ifeq            13
        //    11: iconst_1       
        //    12: ireturn        
        //    13: aload_0         /* blockType */
        //    14: invokevirtual   com/hypixel/hytale/server/core/asset/type/blocktype/config/BlockType.getPlacementSettings:()invokevirtual  !!! ERROR
        //    17: astore_2        /* placementSettings */
        //    18: aload_2         /* placementSettings */
        //    19: ifnonnull       24
        //    22: iconst_0       
        //    23: ireturn        
        //    24: aload_1         /* placedBlockTypeKey */
        //    25: aload_2         /* placementSettings */
        //    26: invokevirtual   invokevirtual  !!! ERROR
        //    29: invokevirtual   java/lang/String.equals:(Ljava/lang/Object;)Z
        //    32: ifne            57
        //    35: aload_1         /* placedBlockTypeKey */
        //    36: aload_2         /* placementSettings */
        //    37: invokevirtual   invokevirtual  !!! ERROR
        //    40: invokevirtual   java/lang/String.equals:(Ljava/lang/Object;)Z
        //    43: ifne            57
        //    46: aload_1         /* placedBlockTypeKey */
        //    47: aload_2         /* placementSettings */
        //    48: invokevirtual   invokevirtual  !!! ERROR
        //    51: invokevirtual   java/lang/String.equals:(Ljava/lang/Object;)Z
        //    54: ifeq            61
        //    57: iconst_1       
        //    58: goto            62
        //    61: iconst_0       
        //    62: ireturn        
        //    StackMapTable: 00 05 0D FC 00 0A 07 02 42 20 03 40 01
        // 
        // The error that occurred was:
        // 
        // java.lang.ClassCastException: class com.strobel.assembler.ir.attributes.BlobAttribute cannot be cast to class com.strobel.assembler.ir.attributes.BootstrapMethodsAttribute (com.strobel.assembler.ir.attributes.BlobAttribute and com.strobel.assembler.ir.attributes.BootstrapMethodsAttribute are in unnamed module of loader 'app')
        //     at com.strobel.assembler.metadata.ClassFileReader$Scope.lookupDynamicCallSite(ClassFileReader.java:1543)
        //     at com.strobel.assembler.metadata.ClassFileReader$Scope.lookup(ClassFileReader.java:1629)
        //     at com.strobel.assembler.ir.MetadataReader.readAttributeCore(MetadataReader.java:307)
        //     at com.strobel.assembler.metadata.ClassFileReader.readAttributeCore(ClassFileReader.java:431)
        //     at com.strobel.assembler.ir.MetadataReader.inflateAttributes(MetadataReader.java:440)
        //     at com.strobel.assembler.metadata.ClassFileReader.visitAttributes(ClassFileReader.java:1403)
        //     at com.strobel.assembler.metadata.ClassFileReader.readClass(ClassFileReader.java:667)
        //     at com.strobel.assembler.metadata.ClassFileReader.readClass(ClassFileReader.java:605)
        //     at com.strobel.assembler.metadata.MetadataSystem.resolveType(MetadataSystem.java:129)
        //     at com.strobel.decompiler.NoRetryMetadataSystem.resolveType(DecompilerDriver.java:475)
        //     at com.strobel.assembler.metadata.MetadataSystem.resolveCore(MetadataSystem.java:81)
        //     at com.strobel.assembler.metadata.MetadataResolver.resolve(MetadataResolver.java:104)
        //     at com.strobel.assembler.metadata.CoreMetadataFactory$UnresolvedType.resolve(CoreMetadataFactory.java:616)
        //     at com.strobel.assembler.metadata.MetadataResolver.resolve(MetadataResolver.java:128)
        //     at com.strobel.assembler.metadata.CoreMetadataFactory$UnresolvedType.resolve(CoreMetadataFactory.java:626)
        //     at com.strobel.assembler.metadata.MethodReference.resolve(MethodReference.java:177)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2458)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2715)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferBinaryExpression(TypeAnalysis.java:2124)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1545)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1565)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:373)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:109)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
        //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
        //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
    
    static {
        LOGGER = HytaleLogger.forEnclosingClass();
        MESSAGE_MODULES_INTERACTION_FAILED_ADD_BACK_AFTER_FAILED_PLACE = Message.translation("server.modules.interaction.failedAddBackAfterFailedPlace");
        MESSAGE_MODULES_INTERACTION_FAILED_CHECK_BLOCK = Message.translation("server.modules.interaction.failedCheckBlock");
        MESSAGE_MODULES_INTERACTION_FAILED_CHECK_EMPTY = Message.translation("server.modules.interaction.failedCheckEmpty");
        MESSAGE_MODULES_INTERACTION_FAILED_CHECK_UNKNOWN = Message.translation("server.modules.interaction.failedCheckUnknown");
        MESSAGE_MODULES_INTERACTION_FAILED_CHECK = Message.translation("server.modules.interaction.failedCheck");
        MESSAGE_MODULES_INTERACTION_BUILD_FORBIDDEN = Message.translation("server.modules.interaction.buildForbidden");
    }
}
