ObjImportPage class

Пакет: com.hypixel.hytale.builtin.buildertools.objimport

Файл: com/hypixel/hytale/builtin/buildertools/objimport/ObjImportPage.java

extends: InteractiveCustomUIPage<ObjImportPage.PageData>

Поля (139)

МодификаторыТипИмя
public static final BuilderCodec<ObjImportPage.PageData> CODEC
final String DEFAULT_BLOCK
static final String KEY_AUTO_DETECT_TEXTURES
static final String KEY_BLOCK_PATTERN
static final String KEY_BROWSE
static final String KEY_BROWSER_CANCEL
static final String KEY_BROWSER_SELECT
static final String KEY_FILL_SOLID
static final String KEY_HEIGHT
static final String KEY_IMPORT
static final String KEY_OBJ_PATH
static final String KEY_ORIGIN
static final String KEY_ROTATION
static final String KEY_SCALE
static final String KEY_SIZE_MODE
static final String KEY_USE_MATERIALS
BOTTOM_FRONT_LEFT, BOTTOM_CENTER, CENTER, TOP_CENTER
NONE, Z_UP_TO_Y_UP, X_UP_TO_Y_UP
private Boolean autoDetectTextures
private String blockPattern
break
break
break
break
private Boolean browse
private Boolean browserCancel
private Boolean browserSelect
continue
continue
private Boolean doImport
private String file
private Boolean fillSolid
private Integer height
private String objPath
private String origin
return
private String rotation
private Float scale
private String searchQuery
private String searchResult
private String sizeMode
private Boolean useMaterials
UICommandBuilder var1
int var10
float var10
String var10
int var11
String var11
boolean var12
String var12
boolean var13
MtlParser.MtlMaterial var13
boolean var14
String var14
var14
ObjImportPage.Origin var15
Path var15
ObjImportPage.MeshRotation var16
BufferedImage var16
List var17
Path var17
int[] var17
ObjParser.ObjMesh var18
int var18
int var19
var19
var19
int[] var19
FileBrowserConfig var2
String var2
UIEventBuilder var2
List var2
float[] var20
int var20
float var21
Map var22
int var23
var23
boolean var24
boolean var25
MeshVoxelizer.VoxelResult var26
var26
var26
int var27
var27
var27
var27
int var28
var28
var28
int var29
var29
var29
var29
String var3
String[] var3
int var3
Path var3
BlockSelection var30
Random var31
boolean var32
int var36
var36
var36
var36
boolean var4
var4
var4
var4
var4
var4
var4
var4
var4
var4
Path var4
boolean var4
BlockColorIndex var40
Map var41
int var42
List var5
Path var5
List var5
List var6
Player var6
List var7
var7
PlayerRef var7
Path var7
int var8
var8
int var8
int var8
Map var8
String var9
var9
int var9
boolean var9
Path var9

Методы (62)

МодификаторыВозвратСигнатура
abstract throw new IllegalStateExceptionthrow new IllegalStateException("Cannot select from empty blocks list")
MeshRotation MeshRotation()
Origin Origin()
public PageDatapublic PageData()
private record WeightedBlockrecord WeightedBlock(int blockId, int weight)
private void buildBrowserPagevoid buildBrowserPage(@Nonnull UICommandBuilder var1, @Nonnull UIEventBuilder var2)
for for(String var7 : var3)
for for(ObjImportPage.WeightedBlock var5 : var1)
for for(ObjImportPage.WeightedBlock var7 : var1)
for for(String var5 : AUTO_DETECT_SUFFIXES)
for for(String var9 : AUTO_DETECT_EXTENSIONS)
abstract for for(int var33 = 0; var33 < var26.sizeX()
abstract for for(int var34 = 0; var34 < var26.sizeY()
abstract for for(int var35 = 0; var35 < var26.sizeZ()
private boolean handleBrowserEventboolean handleBrowserEvent(@Nonnull ObjImportPage.PageData var1)
public void handleDataEventvoid handleDataEvent(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull ObjImportPage.PageData var3)
if if(this.showBrowser)
if if(this.statusMessage != null)
if if(var3.browse != null && var3.browse)
if if(var3.objPath != null)
if if(var3.height != null)
if if(var3.scale != null)
if if(var3.sizeMode != null)
if if(var3.blockPattern != null)
if if(var3.fillSolid != null)
if if(var3.useMaterials != null)
if if(var3.autoDetectTextures != null)
if if(var3.origin != null)
if if(var3.rotation != null)
if if(var3.doImport != null && var3.doImport && !this.isProcessing)
if if(var4)
if if(var1.searchQuery != null)
if if(var1.file != null)
if if(var1.searchResult != null)
if if(var10 > 0)
if if(var11 == Integer.MIN_VALUE)
if if(var3 <= 0)
if if(var8 < var9)
if if(var5 == null)
if if(var6 != null && var7 != null)
if if(var9)
if if(var24)
if if(var32)
if if(var36 == 0)
if if(var14 == null && var6)
if if(var14 != null)
if if(var15 == null)
if if(var16 != null)
if if(var17 != null)
if if(var18 > 0)
if if(var19 != null)
if if(var20 > 0)
private void loadMaterialDatavoid loadMaterialData(@Nonnull Path var1, @Nonnull ObjParser.ObjMesh var2, @Nonnull BlockColorIndex var3, @Nonnull Map<String, BufferedImage> var4, @Nonnull Map<String, Integer> var5, boolean var6)
private void performImportvoid performImport(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2)
private void rebuildBrowservoid rebuildBrowser()
private int selectRandomBlockint selectRandomBlock(@Nonnull List<ObjImportPage.WeightedBlock> var1, @Nonnull Random var2)
private void setErrorvoid setError(@Nonnull Message var1)
private void setStatusvoid setStatus(@Nonnull Message var1)
abstract super super(var1, CustomPageLifetime.CanDismiss, ObjImportPage.PageData.CODEC)
switch switch(var16)
switch switch(var15)
private void updateStatusvoid updateStatus(@Nonnull UICommandBuilder var1)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.buildertools.objimport;

class="kw">import com.hypixel.hytale.builtin.buildertools.BlockColorIndex;
class="kw">import com.hypixel.hytale.builtin.buildertools.BuilderToolsPlugin;
class="kw">import com.hypixel.hytale.builtin.buildertools.utils.PasteToolUtil;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.common.util.PathUtil;
class="kw">import com.hypixel.hytale.common.util.StringUtil;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.Page;
class="kw">import com.hypixel.hytale.server.core.Constants;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.asset.AssetModule;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.entity.entities.Player;
class="kw">import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;
class="kw">import com.hypixel.hytale.server.core.modules.singleplayer.SingleplayerModule;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.standard.BlockSelection;
class="kw">import com.hypixel.hytale.server.core.ui.DropdownEntryInfo;
class="kw">import com.hypixel.hytale.server.core.ui.LocalizableString;
class="kw">import com.hypixel.hytale.server.core.ui.browser.FileBrowserConfig;
class="kw">import com.hypixel.hytale.server.core.ui.browser.FileBrowserEventData;
class="kw">import com.hypixel.hytale.server.core.ui.browser.ServerFileBrowser;
class="kw">import com.hypixel.hytale.server.core.ui.builder.EventData;
class="kw">import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
class="kw">import com.hypixel.hytale.server.core.ui.builder.UIEventBuilder;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import java.awt.image.BufferedImage;
class="kw">import java.io.IOException;
class="kw">import java.nio.file.Files;
class="kw">import java.nio.file.Path;
class="kw">import java.nio.file.Paths;
class="kw">import java.util.ArrayList;
class="kw">import java.util.HashMap;
class="kw">import java.util.List;
class="kw">import java.util.Locale;
class="kw">import java.util.Map;
class="kw">import java.util.Random;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3i;

class="kw">public class ObjImportPage class="kw">extends InteractiveCustomUIPage<ObjImportPage.PageData> {
   class="kw">private class="kw">static class="kw">final String DEFAULT_BLOCK = "Rock_Stone";
   class="kw">private class="kw">static class="kw">final int DEFAULT_HEIGHT = 20;
   class="kw">private class="kw">static class="kw">final int MIN_HEIGHT = 1;
   class="kw">private class="kw">static class="kw">final int MAX_HEIGHT = 320;
   class="kw">private class="kw">static class="kw">final float DEFAULT_SCALE = 1.0F;
   class="kw">private class="kw">static class="kw">final float MIN_SCALE = 0.01F;
   class="kw">private class="kw">static class="kw">final float MAX_SCALE = 100.0F;
   class="kw">private class="kw">static class="kw">final String ASSET_PACK_SUB_PATH = "Server/Imports/Models";
   @Nonnull
   class="kw">private String objPath = "";
   class="kw">private int targetHeight = 20;
   class="kw">private boolean useScaleMode = false;
   class="kw">private float scale = 1.0F;
   @Nonnull
   class="kw">private String blockPattern = "Rock_Stone";
   class="kw">private boolean fillSolid = true;
   class="kw">private boolean useMaterials = true;
   class="kw">private boolean autoDetectTextures = false;
   @Nonnull
   class="kw">private String originStr = "bottom_center";
   @Nonnull
   class="kw">private ObjImportPage.Origin origin = ObjImportPage.Origin.BOTTOM_CENTER;
   @Nonnull
   class="kw">private String rotationStr = "y_up";
   @Nonnull
   class="kw">private ObjImportPage.MeshRotation rotation = ObjImportPage.MeshRotation.NONE;
   @Nullable
   class="kw">private Message statusMessage = null;
   class="kw">private boolean isError = false;
   class="kw">private boolean isProcessing = false;
   class="kw">private boolean showBrowser = false;
   @Nonnull
   class="kw">private class="kw">final ServerFileBrowser browser;
   class="kw">private class="kw">static class="kw">final String[] AUTO_DETECT_SUFFIXES = new String[]{"", "_dif", "_diffuse"};
   class="kw">private class="kw">static class="kw">final String[] AUTO_DETECT_EXTENSIONS = new String[]{".png", ".jpg", ".jpeg"};

   class="kw">public ObjImportPage(@Nonnull PlayerRef var1) {
      super(var1, CustomPageLifetime.CanDismiss, ObjImportPage.PageData.CODEC);
      FileBrowserConfig var2 = FileBrowserConfig.builder()
         .listElementId("#BrowserPage #FileList")
         .searchInputId("#BrowserPage #SearchInput")
         .currentPathId("#BrowserPage #CurrentPath")
         .allowedExtensions(".obj")
         .enableRootSelector(false)
         .enableSearch(true)
         .enableDirectoryNav(true)
         .maxResults(50)
         .assetPackMode(true, "Server/Imports/Models")
         .build();
      this.browser = new ServerFileBrowser(var2);
   }

   @Override
   class="kw">public void build(@Nonnull Ref<EntityStore> var1, @Nonnull UICommandBuilder var2, @Nonnull UIEventBuilder var3, @Nonnull Store<EntityStore> var4) {
      var2.append("Pages/ObjImportPage.ui");
      var2.set("#ObjPath #Input.Value", this.objPath);
      var2.set("#HeightInput #Input.Value", this.targetHeight);
      var2.set("#ScaleInput #Input.Value", this.scale);
      var2.set("#BlockPattern #Input.Value", this.blockPattern);
      var2.set("#FillModeCheckbox #CheckBox.Value", this.fillSolid);
      var2.set("#UseMaterialsCheckbox #CheckBox.Value", this.useMaterials);
      var2.set("#AutoDetectTexturesCheckbox #CheckBox.Value", this.autoDetectTextures);
      var2.set("#HeightInput.Visible", !this.useScaleMode);
      var2.set("#ScaleInput.Visible", this.useScaleMode);
      List var5 = new ArrayList<>();
      var5.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.objImport.sizeMode.height"), "height"));
      var5.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.objImport.sizeMode.scale"), "scale"));
      var2.set("#SizeModeInput #Input.Entries", var5);
      var2.set("#SizeModeInput #Input.Value", this.useScaleMode ? "scale" : "height");
      List var6 = new ArrayList<>();
      var6.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.bottom_front_left"), "bottom_front_left"));
      var6.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.bottom_center"), "bottom_center"));
      var6.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.center"), "center"));
      var6.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.top_center"), "top_center"));
      var2.set("#OriginInput #Input.Entries", var6);
      var2.set("#OriginInput #Input.Value", this.originStr);
      List var7 = new ArrayList<>();
      var7.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.objImport.axis.yUp"), "y_up"));
      var7.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.objImport.axis.zUp"), "z_up"));
      var7.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.objImport.axis.xUp"), "x_up"));
      var2.set("#RotationInput #Input.Entries", var7);
      var2.set("#RotationInput #Input.Value", this.rotationStr);
      this.updateStatus(var2);
      var3.addEventBinding(CustomUIEventBindingType.ValueChanged, "#ObjPath #Input", EventData.of("@ObjPath", "#ObjPath #Input.Value"), false);
      var3.addEventBinding(CustomUIEventBindingType.ValueChanged, "#HeightInput #Input", EventData.of("@Height", "#HeightInput #Input.Value"), false);
      var3.addEventBinding(CustomUIEventBindingType.ValueChanged, "#ScaleInput #Input", EventData.of("@Scale", "#ScaleInput #Input.Value"), false);
      var3.addEventBinding(CustomUIEventBindingType.ValueChanged, "#SizeModeInput #Input", EventData.of("SizeMode", "#SizeModeInput #Input.Value"), false);
      var3.addEventBinding(CustomUIEventBindingType.ValueChanged, "#BlockPattern #Input", EventData.of("@BlockPattern", "#BlockPattern #Input.Value"), false);
      var3.addEventBinding(
         CustomUIEventBindingType.ValueChanged, "#FillModeCheckbox #CheckBox", EventData.of("@FillSolid", "#FillModeCheckbox #CheckBox.Value"), false
      );
      var3.addEventBinding(
         CustomUIEventBindingType.ValueChanged,
         "#UseMaterialsCheckbox #CheckBox",
         EventData.of("@UseMaterials", "#UseMaterialsCheckbox #CheckBox.Value"),
         false
      );
      var3.addEventBinding(
         CustomUIEventBindingType.ValueChanged,
         "#AutoDetectTexturesCheckbox #CheckBox",
         EventData.of("@AutoDetectTextures", "#AutoDetectTexturesCheckbox #CheckBox.Value"),
         false
      );
      var3.addEventBinding(CustomUIEventBindingType.ValueChanged, "#OriginInput #Input", EventData.of("@Origin", "#OriginInput #Input.Value"), false);
      var3.addEventBinding(CustomUIEventBindingType.ValueChanged, "#RotationInput #Input", EventData.of("@Rotation", "#RotationInput #Input.Value"), false);
      var3.addEventBinding(CustomUIEventBindingType.Activating, "#ImportButton", EventData.of("Import", "true"));
      var3.addEventBinding(CustomUIEventBindingType.Activating, "#ObjPath #BrowseButton", EventData.of("Browse", "true"));
      var2.set("#FormContainer.Visible", !this.showBrowser);
      var2.set("#BrowserPage.Visible", this.showBrowser);
      if (this.showBrowser) {
         this.buildBrowserPage(var2, var3);
      }
   }

   class="kw">private void buildBrowserPage(@Nonnull UICommandBuilder var1, @Nonnull UIEventBuilder var2) {
      this.browser.buildSearchInput(var1, var2);
      this.browser.buildCurrentPath(var1);
      this.browser.buildFileList(var1, var2);
      var2.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #SelectButton", EventData.of("BrowserSelect", "true"));
      var2.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #CancelButton", EventData.of("BrowserCancel", "true"));
   }

   class="kw">private void updateStatus(@Nonnull UICommandBuilder var1) {
      if (this.statusMessage != null) {
         var1.set("#StatusText.Text", this.statusMessage);
         var1.set("#StatusText.Visible", true);
         var1.set("#StatusText.Style.TextColor", this.isError ? "#e74c3c" : "#cfd8e3");
      } else {
         var1.set("#StatusText.Visible", false);
      }
   }

   class="kw">private void setError(@Nonnull Message var1) {
      this.statusMessage = var1;
      this.isError = true;
      this.isProcessing = false;
      this.rebuild();
   }

   class="kw">private void setStatus(@Nonnull Message var1) {
      this.statusMessage = var1;
      this.isError = false;
      this.rebuild();
   }

   class="kw">public void handleDataEvent(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2, @Nonnull ObjImportPage.PageData var3) {
      if (var3.browse != null && var3.browse) {
         this.showBrowser = true;
         this.rebuild();
      } else if (var3.browserCancel != null && var3.browserCancel) {
         this.showBrowser = false;
         this.rebuild();
      } else if (var3.browserSelect != null && var3.browserSelect) {
         this.showBrowser = false;
         this.rebuild();
      } else if (!this.showBrowser || !this.handleBrowserEvent(var3)) {
         boolean var4 = false;
         if (var3.objPath != null) {
            this.objPath = StringUtil.stripQuotes(var3.objPath.trim());
            this.statusMessage = null;
            var4 = true;
         }

         if (var3.height != null) {
            this.targetHeight = Math.max(1, Math.min(320, var3.height));
            var4 = true;
         }

         if (var3.scale != null) {
            this.scale = Math.max(0.01F, Math.min(100.0F, var3.scale));
            var4 = true;
         }

         if (var3.sizeMode != null) {
            this.useScaleMode = "scale".equalsIgnoreCase(var3.sizeMode);
            this.rebuild();
         } else {
            if (var3.blockPattern != null) {
               this.blockPattern = var3.blockPattern.trim();
               var4 = true;
            }

            if (var3.fillSolid != null) {
               this.fillSolid = var3.fillSolid;
               var4 = true;
            }

            if (var3.useMaterials != null) {
               this.useMaterials = var3.useMaterials;
               var4 = true;
            }

            if (var3.autoDetectTextures != null) {
               this.autoDetectTextures = var3.autoDetectTextures;
               var4 = true;
            }

            if (var3.origin != null) {
               this.originStr = var3.origin.trim().toLowerCase(Locale.ROOT);

               this.origin = class="kw">switch (this.originStr) {
                  case "bottom_front_left" -> ObjImportPage.Origin.BOTTOM_FRONT_LEFT;
                  case "center" -> ObjImportPage.Origin.CENTER;
                  case "top_center" -> ObjImportPage.Origin.TOP_CENTER;
                  class="kw">default -> ObjImportPage.Origin.BOTTOM_CENTER;
               };
               var4 = true;
            }

            if (var3.rotation != null) {
               this.rotationStr = var3.rotation.trim().toLowerCase(Locale.ROOT);

               this.rotation = class="kw">switch (this.rotationStr) {
                  case "z_up" -> ObjImportPage.MeshRotation.Z_UP_TO_Y_UP;
                  case "x_up" -> ObjImportPage.MeshRotation.X_UP_TO_Y_UP;
                  class="kw">default -> ObjImportPage.MeshRotation.NONE;
               };
               var4 = true;
            }

            if (var3.doImport != null && var3.doImport && !this.isProcessing) {
               this.performImport(var1, var2);
            } else {
               if (var4) {
                  this.sendUpdate();
               }
            }
         }
      }
   }

   class="kw">private boolean handleBrowserEvent(@Nonnull ObjImportPage.PageData var1) {
      if (var1.searchQuery != null) {
         this.browser.setSearchQuery(var1.searchQuery.trim().toLowerCase(Locale.ROOT));
         this.rebuildBrowser();
         class="kw">return true;
      }

      if (var1.file != null) {
         String var2 = var1.file;
         if ("..".equals(var2)) {
            this.browser.navigateUp();
            this.rebuildBrowser();
            class="kw">return true;
         }

         if (this.browser.handleEvent(FileBrowserEventData.file(var2))) {
            this.rebuildBrowser();
            class="kw">return true;
         }

         String var3 = this.browser.getAssetPackCurrentPath().isEmpty() ? var2 : this.browser.getAssetPackCurrentPath() + "/" + var2;
         Path var4 = this.browser.resolveAssetPackPath(var3);
         if (var4 != null && Files.isRegularFile(var4)) {
            this.objPath = var4.toString();
            this.showBrowser = false;
            this.rebuild();
            class="kw">return true;
         }
      }

      if (var1.searchResult != null) {
         Path var5 = this.browser.resolveAssetPackPath(var1.searchResult);
         if (var5 != null && Files.isRegularFile(var5)) {
            this.objPath = var5.toString();
            this.showBrowser = false;
            this.rebuild();
            class="kw">return true;
         }
      }

      class="kw">return false;
   }

   class="kw">private void rebuildBrowser() {
      UICommandBuilder var1 = new UICommandBuilder();
      UIEventBuilder var2 = new UIEventBuilder();
      this.browser.buildFileList(var1, var2);
      this.browser.buildCurrentPath(var1);
      this.sendUpdate(var1, var2, false);
   }

   @Nullable
   class="kw">private List<ObjImportPage.WeightedBlock> parseBlockPattern(@Nonnull String var1) {
      List var2 = new ArrayList<>();
      String[] var3 = var1.split(",", 0);

      for (String var7 : var3) {
         var7 = var7.trim();
         if (!var7.isEmpty()) {
            int var8 = 100;
            String var9 = var7;
            int var10 = var7.indexOf(37);
            if (var10 > 0) {
               try {
                  var8 = Integer.parseInt(var7.substring(0, var10).trim());
                  var9 = var7.substring(var10 + 1).trim();
               } catch (NumberFormatException var12) {
                  class="kw">return null;
               }
            }

            int var11 = BlockType.getAssetMap().getIndex(var9);
            if (var11 == Integer.MIN_VALUE) {
               class="kw">return null;
            }

            var2.add(new ObjImportPage.WeightedBlock(var11, var8));
         }
      }

      class="kw">return var2.isEmpty() ? null : var2;
   }

   class="kw">private int selectRandomBlock(@Nonnull List<ObjImportPage.WeightedBlock> var1, @Nonnull Random var2) {
      if (var1.isEmpty()) {
         throw new IllegalStateException("Cannot select from empty blocks list");
      }

      if (var1.size() == 1) {
         class="kw">return var1.getFirst().blockId;
      }

      int var3 = 0;

      for (ObjImportPage.WeightedBlock var5 : var1) {
         var3 += var5.weight;
      }

      if (var3 <= 0) {
         class="kw">return var1.getFirst().blockId;
      }

      int var8 = var2.nextInt(var3);
      int var9 = 0;

      for (ObjImportPage.WeightedBlock var7 : var1) {
         var9 += var7.weight;
         if (var8 < var9) {
            class="kw">return var7.blockId;
         }
      }

      class="kw">return var1.getFirst().blockId;
   }

   class="kw">private void performImport(@Nonnull Ref<EntityStore> var1, @Nonnull Store<EntityStore> var2) {
      if (this.objPath.isEmpty()) {
         this.setError(Message.translation("server.builderTools.objImport.emptyPath"));
      } else if (!this.objPath.toLowerCase(Locale.ROOT).endsWith(".obj")) {
         this.setError(Message.translation("server.builderTools.objImport.invalidExtension"));
      } else {
         Path var3 = Paths.get(this.objPath);
         boolean var4 = Constants.SINGLEPLAYER && SingleplayerModule.isOwner(this.playerRef);
         if (!var4 && !AssetModule.get().isWithinPackSubDir(var3, "Server/Imports/Models")) {
            this.setError(Message.translation("server.builderTools.objImport.notInImportsDir"));
         } else if (!Files.exists(var3)) {
            this.setError(Message.translation("server.builderTools.objImport.fileNotFound").param("path", this.objPath));
         } else {
            List var5 = this.parseBlockPattern(this.blockPattern);
            if (var5 == null) {
               this.setError(Message.translation("server.builderTools.objImport.invalidPattern").param("pattern", this.blockPattern));
            } else {
               this.isProcessing = true;
               this.setStatus(Message.translation("server.builderTools.objImport.processing"));
               Player var6 = var2.getComponent(var1, Player.getComponentType());
               PlayerRef var7 = var2.getComponent(var1, PlayerRef.getComponentType());
               if (var6 != null && var7 != null) {
                  int var8 = this.targetHeight;
                  boolean var9 = this.useScaleMode;
                  float var10 = this.scale;
                  String var11 = this.objPath;
                  boolean var12 = this.fillSolid;
                  boolean var13 = this.useMaterials;
                  boolean var14 = this.autoDetectTextures;
                  ObjImportPage.Origin var15 = this.origin;
                  ObjImportPage.MeshRotation var16 = this.rotation;
                  List var17 = var5;
                  BuilderToolsPlugin.addToQueue(
                     var6,
                     var7,
                     (var14x, var15x, var16x) -> {
                        try {
                           Path var17 = Paths.get(var11);
                           ObjParser.ObjMesh var18 = ObjParser.parse(var17);
                           class="kw">switch (var16) {
                              case Z_UP_TO_Y_UP:
                                 var18.transformZUpToYUp();
                                 break;
                              case X_UP_TO_Y_UP:
                                 var18.transformXUpToYUp();
                           }

                           int var19;
                           if (var9) {
                              float[] var20 = var18.getBounds();
                              float var21 = var20[4] - var20[1];
                              var19 = Math.max(1, (int)Math.ceil(var21 * var10));
                           } else {
                              var19 = var8;
                           }

                           if (var17.isEmpty()) {
                              this.setError(Message.translation("server.builderTools.objImport.noBlocks"));
                              class="kw">return;
                           }

                           BlockColorIndex var40 = BuilderToolsPlugin.get().getBlockColorIndex();
                           Map var41 = new HashMap<>();
                           Map var22 = new HashMap<>();
                           int var23 = var17.getFirst().blockId;
                           if (var13 && var18.mtlLib() != null) {
                              this.loadMaterialData(var17, var18, var40, var41, var22, var14);
                              if (!var22.isEmpty()) {
                                 var23 = var22.values().iterator().next();
                              }
                           }

                           boolean var24 = var18.hasUvCoordinates() && !var41.isEmpty();
                           boolean var25 = var15 == ObjImportPage.Origin.BOTTOM_FRONT_LEFT;
                           MeshVoxelizer.VoxelResult var26;
                           if (var24) {
                              var26 = MeshVoxelizer.voxelize(var18, var19, var12, var41, var22, var40, var23, var25);
                           } else {
                              var26 = MeshVoxelizer.voxelize(var18, var19, var12, null, var22, var40, var23, var25);
                           }

                           TextureSampler.clearCache();
                           int var27 = 0;
                           int var28 = 0;
                           int var29 = 0;
                           class="kw">switch (var15) {
                              case BOTTOM_FRONT_LEFT:
                              class="kw">default:
                                 break;
                              case BOTTOM_CENTER:
                                 var27 = -var26.sizeX() / 2;
                                 var29 = -var26.sizeZ() / 2;
                                 break;
                              case CENTER:
                                 var27 = -var26.sizeX() / 2;
                                 var28 = -var26.sizeY() / 2;
                                 var29 = -var26.sizeZ() / 2;
                                 break;
                              case TOP_CENTER:
                                 var27 = -var26.sizeX() / 2;
                                 var28 = -var26.sizeY();
                                 var29 = -var26.sizeZ() / 2;
                           }

                           BlockSelection var30 = new BlockSelection(var26.countSolid(), 0);
                           var30.setPosition(0, 0, 0);
                           Random var31 = new Random();
                           boolean var32 = var26.blockIds() != null;

                           for (int var33 = 0; var33 < var26.sizeX(); var33++) {
                              for (int var34 = 0; var34 < var26.sizeY(); var34++) {
                                 for (int var35 = 0; var35 < var26.sizeZ(); var35++) {
                                    if (var26.voxels()[var33][var34][var35]) {
                                       int var36;
                                       if (var32) {
                                          var36 = var26.getBlockId(var33, var34, var35);
                                          if (var36 == 0) {
                                             var36 = this.selectRandomBlock(var17, var31);
                                          }
                                       } else {
                                          var36 = this.selectRandomBlock(var17, var31);
                                       }

                                       var30.addBlockAtLocalPos(var33 + var27, var34 + var28, var35 + var29, var36, 0, 0, 0);
                                    }
                                 }
                              }
                           }

                           var30.setSelectionArea(
                              new Vector3i(var27, var28, var29), new Vector3i(var26.sizeX() - 1 + var27, var26.sizeY() - 1 + var28, var26.sizeZ() - 1 + var29)
                           );
                           var15x.setSelection(var30);
                           var15x.sendSelectionToClient();
                           int var42 = var26.countSolid();
                           this.statusMessage = Message.translation("server.builderTools.objImport.success")
                              .param("count", var42)
                              .param("width", var26.sizeX())
                              .param("height", var26.sizeY())
                              .param("depth", var26.sizeZ());
                           this.isProcessing = false;
                           var7.sendMessage(
                              Message.translation("server.builderTools.objImport.success")
                                 .param("count", var42)
                                 .param("width", var26.sizeX())
                                 .param("height", var26.sizeY())
                                 .param("depth", var26.sizeZ())
                           );
                           var6.getPageManager().setPage(var14x, var2, Page.None);
                           PasteToolUtil.switchToPasteTool(var14x, var7, var16x);
                        } catch (ObjParser.ObjParseException var37) {
                           BuilderToolsPlugin.get().getLogger().at(Level.WARNING).log("OBJ parse error: %s", var37.getMessage());
                           this.setError(Message.translation("server.builderTools.objImport.parseError").param("message", var37.getMessage()));
                        } catch (IOException var38) {
                           ((HytaleLogger.Api)BuilderToolsPlugin.get().getLogger().at(Level.WARNING).withCause(var38)).log("OBJ class="kw">import IO error");
                           this.setError(Message.translation("server.builderTools.objImport.ioError").param("message", var38.getMessage()));
                        } catch (Exception var39) {
                           ((HytaleLogger.Api)BuilderToolsPlugin.get().getLogger().at(Level.WARNING).withCause(var39)).log("OBJ class="kw">import error");
                           this.setError(Message.translation("server.builderTools.objImport.error").param("message", var39.getMessage()));
                        }
                     }
                  );
               } else {
                  this.setError(Message.translation("server.builderTools.objImport.playerNotFound"));
               }
            }
         }
      }
   }

   class="kw">private void loadMaterialData(
      @Nonnull Path var1,
      @Nonnull ObjParser.ObjMesh var2,
      @Nonnull BlockColorIndex var3,
      @Nonnull Map<String, BufferedImage> var4,
      @Nonnull Map<String, Integer> var5,
      boolean var6
   ) class="kw">throws IOException {
      if (var2.mtlLib() != null) {
         Path var7 = PathUtil.resolvePathWithinDir(var1.getParent(), var2.mtlLib());
         if (var7 != null && Files.exists(var7)) {
            Map var8 = MtlParser.parse(var7);
            Path var9 = var7.getParent();

            for (Entry var11 : var8.entrySet()) {
               String var12 = var11.getKey();
               MtlParser.MtlMaterial var13 = var11.getValue();
               String var14 = var13.diffuseTexturePath();
               if (var14 == null && var6) {
                  var14 = findMatchingTexture(var9, var12);
               }

               if (var14 != null) {
                  Path var15 = PathUtil.resolvePathWithinDir(var9, var14);
                  if (var15 == null) {
                     class="kw">continue;
                  }

                  BufferedImage var16 = TextureSampler.loadTexture(var15);
                  if (var16 != null) {
                     var4.put(var12, var16);
                     int[] var17 = TextureSampler.getAverageColor(var15);
                     if (var17 != null) {
                        int var18 = var3.findClosestBlock(var17[0], var17[1], var17[2]);
                        if (var18 > 0) {
                           var5.put(var12, var18);
                        }
                     }
                     class="kw">continue;
                  }
               }

               int[] var19 = var13.getDiffuseColorRGB();
               if (var19 != null) {
                  int var20 = var3.findClosestBlock(var19[0], var19[1], var19[2]);
                  if (var20 > 0) {
                     var5.put(var12, var20);
                  }
               }
            }
         }
      }
   }

   @Nullable
   class="kw">private class="kw">static String findMatchingTexture(@Nonnull Path var0, @Nonnull String var1) {
      for (String var5 : AUTO_DETECT_SUFFIXES) {
         for (String var9 : AUTO_DETECT_EXTENSIONS) {
            String var10 = var1 + var5 + var9;
            if (Files.exists(var0.resolve(var10))) {
               class="kw">return var10;
            }
         }
      }

      class="kw">return null;
   }

   class="kw">public enum MeshRotation {
      NONE,
      Z_UP_TO_Y_UP,
      X_UP_TO_Y_UP;

      MeshRotation() {
      }
   }

   class="kw">public enum Origin {
      BOTTOM_FRONT_LEFT,
      BOTTOM_CENTER,
      CENTER,
      TOP_CENTER;

      Origin() {
      }
   }

   class="kw">public class="kw">static class PageData {
      class="kw">static class="kw">final String KEY_OBJ_PATH = "@ObjPath";
      class="kw">static class="kw">final String KEY_HEIGHT = "@Height";
      class="kw">static class="kw">final String KEY_SCALE = "@Scale";
      class="kw">static class="kw">final String KEY_SIZE_MODE = "SizeMode";
      class="kw">static class="kw">final String KEY_BLOCK_PATTERN = "@BlockPattern";
      class="kw">static class="kw">final String KEY_FILL_SOLID = "@FillSolid";
      class="kw">static class="kw">final String KEY_USE_MATERIALS = "@UseMaterials";
      class="kw">static class="kw">final String KEY_AUTO_DETECT_TEXTURES = "@AutoDetectTextures";
      class="kw">static class="kw">final String KEY_ORIGIN = "@Origin";
      class="kw">static class="kw">final String KEY_ROTATION = "@Rotation";
      class="kw">static class="kw">final String KEY_IMPORT = "Import";
      class="kw">static class="kw">final String KEY_BROWSE = "Browse";
      class="kw">static class="kw">final String KEY_BROWSER_SELECT = "BrowserSelect";
      class="kw">static class="kw">final String KEY_BROWSER_CANCEL = "BrowserCancel";
      class="kw">public class="kw">static class="kw">final BuilderCodec<ObjImportPage.PageData> CODEC = BuilderCodec.builder(ObjImportPage.PageData.class, ObjImportPage.PageData::new)
         .append(new KeyedCodec<>("@ObjPath", Codec.STRING), (var0, var1) -> var0.objPath = var1, var0 -> var0.objPath)
         .add()
         .append(new KeyedCodec<>("@Height", Codec.INTEGER), (var0, var1) -> var0.height = var1, var0 -> var0.height)
         .add()
         .append(new KeyedCodec<>("@Scale", Codec.FLOAT), (var0, var1) -> var0.scale = var1, var0 -> var0.scale)
         .add()
         .append(new KeyedCodec<>("SizeMode", Codec.STRING), (var0, var1) -> var0.sizeMode = var1, var0 -> var0.sizeMode)
         .add()
         .append(new KeyedCodec<>("@BlockPattern", Codec.STRING), (var0, var1) -> var0.blockPattern = var1, var0 -> var0.blockPattern)
         .add()
         .append(new KeyedCodec<>("@FillSolid", Codec.BOOLEAN), (var0, var1) -> var0.fillSolid = var1, var0 -> var0.fillSolid)
         .add()
         .append(new KeyedCodec<>("@UseMaterials", Codec.BOOLEAN), (var0, var1) -> var0.useMaterials = var1, var0 -> var0.useMaterials)
         .add()
         .append(new KeyedCodec<>("@AutoDetectTextures", Codec.BOOLEAN), (var0, var1) -> var0.autoDetectTextures = var1, var0 -> var0.autoDetectTextures)
         .add()
         .append(new KeyedCodec<>("@Origin", Codec.STRING), (var0, var1) -> var0.origin = var1, var0 -> var0.origin)
         .add()
         .append(new KeyedCodec<>("@Rotation", Codec.STRING), (var0, var1) -> var0.rotation = var1, var0 -> var0.rotation)
         .add()
         .append(
            new KeyedCodec<>("Import", Codec.STRING),
            (var0, var1) -> var0.doImport = "true".equalsIgnoreCase(var1),
            var0 -> var0.doImport != null && var0.doImport ? "true" : null
         )
         .add()
         .append(
            new KeyedCodec<>("Browse", Codec.STRING),
            (var0, var1) -> var0.browse = "true".equalsIgnoreCase(var1),
            var0 -> var0.browse != null && var0.browse ? "true" : null
         )
         .add()
         .append(
            new KeyedCodec<>("BrowserSelect", Codec.STRING),
            (var0, var1) -> var0.browserSelect = "true".equalsIgnoreCase(var1),
            var0 -> var0.browserSelect != null && var0.browserSelect ? "true" : null
         )
         .add()
         .append(
            new KeyedCodec<>("BrowserCancel", Codec.STRING),
            (var0, var1) -> var0.browserCancel = "true".equalsIgnoreCase(var1),
            var0 -> var0.browserCancel != null && var0.browserCancel ? "true" : null
         )
         .add()
         .append(new KeyedCodec<>("File", Codec.STRING), (var0, var1) -> var0.file = var1, var0 -> var0.file)
         .add()
         .append(new KeyedCodec<>("@SearchQuery", Codec.STRING), (var0, var1) -> var0.searchQuery = var1, var0 -> var0.searchQuery)
         .add()
         .append(new KeyedCodec<>("SearchResult", Codec.STRING), (var0, var1) -> var0.searchResult = var1, var0 -> var0.searchResult)
         .add()
         .build();
      @Nullable
      class="kw">private String objPath;
      @Nullable
      class="kw">private Integer height;
      @Nullable
      class="kw">private Float scale;
      @Nullable
      class="kw">private String sizeMode;
      @Nullable
      class="kw">private String blockPattern;
      @Nullable
      class="kw">private Boolean fillSolid;
      @Nullable
      class="kw">private Boolean useMaterials;
      @Nullable
      class="kw">private Boolean autoDetectTextures;
      @Nullable
      class="kw">private String origin;
      @Nullable
      class="kw">private String rotation;
      @Nullable
      class="kw">private Boolean doImport;
      @Nullable
      class="kw">private Boolean browse;
      @Nullable
      class="kw">private Boolean browserSelect;
      @Nullable
      class="kw">private Boolean browserCancel;
      @Nullable
      class="kw">private String file;
      @Nullable
      class="kw">private String searchQuery;
      @Nullable
      class="kw">private String searchResult;

      class="kw">public PageData() {
      }
   }

   class="kw">private record WeightedBlock(int blockId, int weight) {
      class="kw">private WeightedBlock {
      }
   }
}