1659 lines
66 KiB
Java
1659 lines
66 KiB
Java
package net.minecraft.client;
|
|
|
|
import com.google.common.base.Charsets;
|
|
import com.google.common.base.MoreObjects;
|
|
import com.google.common.base.Splitter;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Sets;
|
|
import com.google.common.io.Files;
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.JsonElement;
|
|
import com.google.gson.JsonParser;
|
|
import com.google.gson.reflect.TypeToken;
|
|
import com.google.gson.stream.JsonReader;
|
|
import com.mojang.blaze3d.platform.InputConstants;
|
|
import com.mojang.blaze3d.platform.VideoMode;
|
|
import com.mojang.blaze3d.platform.Window;
|
|
import com.mojang.blaze3d.platform.InputConstants.Type;
|
|
import com.mojang.blaze3d.systems.RenderSystem;
|
|
import com.mojang.datafixers.util.Pair;
|
|
import com.mojang.logging.LogUtils;
|
|
import com.mojang.serialization.Codec;
|
|
import com.mojang.serialization.JsonOps;
|
|
import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.OutputStreamWriter;
|
|
import java.io.PrintWriter;
|
|
import java.io.StringReader;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Comparator;
|
|
import java.util.EnumSet;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.function.Function;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Stream;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.SharedConstants;
|
|
import net.minecraft.Util;
|
|
import net.minecraft.client.OptionInstance.AltEnum;
|
|
import net.minecraft.client.OptionInstance.ClampingLazyMaxIntRange;
|
|
import net.minecraft.client.OptionInstance.Enum;
|
|
import net.minecraft.client.OptionInstance.IntRange;
|
|
import net.minecraft.client.OptionInstance.LazyEnum;
|
|
import net.minecraft.client.OptionInstance.UnitDouble;
|
|
import net.minecraft.client.gui.components.ChatComponent;
|
|
import net.minecraft.client.gui.components.Tooltip;
|
|
import net.minecraft.client.renderer.GpuWarnlistManager;
|
|
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
|
import net.minecraft.client.sounds.SoundEngine;
|
|
import net.minecraft.client.sounds.SoundManager;
|
|
import net.minecraft.client.tutorial.TutorialSteps;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.nbt.StringTag;
|
|
import net.minecraft.nbt.Tag;
|
|
import net.minecraft.network.chat.CommonComponents;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.network.chat.MutableComponent;
|
|
import net.minecraft.server.level.ClientInformation;
|
|
import net.minecraft.server.level.ParticleStatus;
|
|
import net.minecraft.server.packs.repository.Pack;
|
|
import net.minecraft.server.packs.repository.PackRepository;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.util.ARGB;
|
|
import net.minecraft.util.GsonHelper;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.datafix.DataFixTypes;
|
|
import net.minecraft.world.entity.HumanoidArm;
|
|
import net.minecraft.world.entity.player.ChatVisiblity;
|
|
import net.minecraft.world.entity.player.PlayerModelPart;
|
|
import org.apache.commons.lang3.ArrayUtils;
|
|
import org.jetbrains.annotations.Nullable;
|
|
import org.slf4j.Logger;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class Options {
|
|
static final Logger LOGGER = LogUtils.getLogger();
|
|
static final Gson GSON = new Gson();
|
|
private static final TypeToken<List<String>> LIST_OF_STRINGS_TYPE = new TypeToken<List<String>>() {};
|
|
public static final int RENDER_DISTANCE_TINY = 2;
|
|
public static final int RENDER_DISTANCE_SHORT = 4;
|
|
public static final int RENDER_DISTANCE_NORMAL = 8;
|
|
public static final int RENDER_DISTANCE_FAR = 12;
|
|
public static final int RENDER_DISTANCE_REALLY_FAR = 16;
|
|
public static final int RENDER_DISTANCE_EXTREME = 32;
|
|
private static final Splitter OPTION_SPLITTER = Splitter.on(':').limit(2);
|
|
public static final String DEFAULT_SOUND_DEVICE = "";
|
|
private static final Component ACCESSIBILITY_TOOLTIP_DARK_MOJANG_BACKGROUND = Component.translatable("options.darkMojangStudiosBackgroundColor.tooltip");
|
|
private final OptionInstance<Boolean> darkMojangStudiosBackground = OptionInstance.createBoolean(
|
|
"options.darkMojangStudiosBackgroundColor", OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_DARK_MOJANG_BACKGROUND), false
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_HIDE_LIGHTNING_FLASHES = Component.translatable("options.hideLightningFlashes.tooltip");
|
|
private final OptionInstance<Boolean> hideLightningFlash = OptionInstance.createBoolean(
|
|
"options.hideLightningFlashes", OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_HIDE_LIGHTNING_FLASHES), false
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_HIDE_SPLASH_TEXTS = Component.translatable("options.hideSplashTexts.tooltip");
|
|
private final OptionInstance<Boolean> hideSplashTexts = OptionInstance.createBoolean(
|
|
"options.hideSplashTexts", OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_HIDE_SPLASH_TEXTS), false
|
|
);
|
|
private final OptionInstance<Double> sensitivity = new OptionInstance<>("options.sensitivity", OptionInstance.noTooltip(), (component, double_) -> {
|
|
if (double_ == 0.0) {
|
|
return genericValueLabel(component, Component.translatable("options.sensitivity.min"));
|
|
} else {
|
|
return double_ == 1.0 ? genericValueLabel(component, Component.translatable("options.sensitivity.max")) : percentValueLabel(component, 2.0 * double_);
|
|
}
|
|
}, UnitDouble.INSTANCE, 0.5, double_ -> {});
|
|
private final OptionInstance<Integer> renderDistance;
|
|
private final OptionInstance<Integer> simulationDistance;
|
|
private int serverRenderDistance = 0;
|
|
private final OptionInstance<Double> entityDistanceScaling = new OptionInstance<>(
|
|
"options.entityDistanceScaling",
|
|
OptionInstance.noTooltip(),
|
|
Options::percentValueLabel,
|
|
new IntRange(2, 20).xmap(i -> i / 4.0, double_ -> (int)(double_ * 4.0)),
|
|
Codec.doubleRange(0.5, 5.0),
|
|
1.0,
|
|
double_ -> {}
|
|
);
|
|
public static final int UNLIMITED_FRAMERATE_CUTOFF = 260;
|
|
private final OptionInstance<Integer> framerateLimit = new OptionInstance<>(
|
|
"options.framerateLimit",
|
|
OptionInstance.noTooltip(),
|
|
(component, integer) -> integer == 260
|
|
? genericValueLabel(component, Component.translatable("options.framerateLimit.max"))
|
|
: genericValueLabel(component, Component.translatable("options.framerate", integer)),
|
|
new IntRange(1, 26).xmap(i -> i * 10, integer -> integer / 10),
|
|
Codec.intRange(10, 260),
|
|
120,
|
|
integer -> Minecraft.getInstance().getFramerateLimitTracker().setFramerateLimit(integer)
|
|
);
|
|
private static final Component INACTIVITY_FPS_LIMIT_TOOLTIP_MINIMIZED = Component.translatable("options.inactivityFpsLimit.minimized.tooltip");
|
|
private static final Component INACTIVITY_FPS_LIMIT_TOOLTIP_AFK = Component.translatable("options.inactivityFpsLimit.afk.tooltip");
|
|
private final OptionInstance<InactivityFpsLimit> inactivityFpsLimit = new OptionInstance<>(
|
|
"options.inactivityFpsLimit",
|
|
inactivityFpsLimit -> {
|
|
return switch (inactivityFpsLimit) {
|
|
case MINIMIZED -> Tooltip.create(INACTIVITY_FPS_LIMIT_TOOLTIP_MINIMIZED);
|
|
case AFK -> Tooltip.create(INACTIVITY_FPS_LIMIT_TOOLTIP_AFK);
|
|
};
|
|
},
|
|
OptionInstance.forOptionEnum(),
|
|
new Enum<>(Arrays.asList(InactivityFpsLimit.values()), InactivityFpsLimit.CODEC),
|
|
InactivityFpsLimit.AFK,
|
|
inactivityFpsLimit -> {}
|
|
);
|
|
private final OptionInstance<CloudStatus> cloudStatus = new OptionInstance<>(
|
|
"options.renderClouds",
|
|
OptionInstance.noTooltip(),
|
|
OptionInstance.forOptionEnum(),
|
|
new Enum<>(
|
|
Arrays.asList(CloudStatus.values()), Codec.withAlternative(CloudStatus.CODEC, Codec.BOOL, boolean_ -> boolean_ ? CloudStatus.FANCY : CloudStatus.OFF)
|
|
),
|
|
CloudStatus.FANCY,
|
|
cloudStatus -> {}
|
|
);
|
|
private static final Component GRAPHICS_TOOLTIP_FAST = Component.translatable("options.graphics.fast.tooltip");
|
|
private static final Component GRAPHICS_TOOLTIP_FABULOUS = Component.translatable(
|
|
"options.graphics.fabulous.tooltip", Component.translatable("options.graphics.fabulous").withStyle(ChatFormatting.ITALIC)
|
|
);
|
|
private static final Component GRAPHICS_TOOLTIP_FANCY = Component.translatable("options.graphics.fancy.tooltip");
|
|
private final OptionInstance<GraphicsStatus> graphicsMode = new OptionInstance<>(
|
|
"options.graphics",
|
|
graphicsStatus -> {
|
|
return switch (graphicsStatus) {
|
|
case FANCY -> Tooltip.create(GRAPHICS_TOOLTIP_FANCY);
|
|
case FAST -> Tooltip.create(GRAPHICS_TOOLTIP_FAST);
|
|
case FABULOUS -> Tooltip.create(GRAPHICS_TOOLTIP_FABULOUS);
|
|
};
|
|
},
|
|
(component, graphicsStatus) -> {
|
|
MutableComponent mutableComponent = Component.translatable(graphicsStatus.getKey());
|
|
return graphicsStatus == GraphicsStatus.FABULOUS ? mutableComponent.withStyle(ChatFormatting.ITALIC) : mutableComponent;
|
|
},
|
|
new AltEnum<>(
|
|
Arrays.asList(GraphicsStatus.values()),
|
|
(List<GraphicsStatus>)Stream.of(GraphicsStatus.values()).filter(graphicsStatus -> graphicsStatus != GraphicsStatus.FABULOUS).collect(Collectors.toList()),
|
|
() -> Minecraft.getInstance().isRunning() && Minecraft.getInstance().getGpuWarnlistManager().isSkippingFabulous(),
|
|
(optionInstance, graphicsStatus) -> {
|
|
Minecraft minecraftx = Minecraft.getInstance();
|
|
GpuWarnlistManager gpuWarnlistManager = minecraftx.getGpuWarnlistManager();
|
|
if (graphicsStatus == GraphicsStatus.FABULOUS && gpuWarnlistManager.willShowWarning()) {
|
|
gpuWarnlistManager.showWarning();
|
|
} else {
|
|
optionInstance.set(graphicsStatus);
|
|
minecraftx.levelRenderer.allChanged();
|
|
}
|
|
},
|
|
Codec.INT.xmap(GraphicsStatus::byId, GraphicsStatus::getId)
|
|
),
|
|
GraphicsStatus.FANCY,
|
|
graphicsStatus -> {}
|
|
);
|
|
private final OptionInstance<Boolean> ambientOcclusion = OptionInstance.createBoolean(
|
|
"options.ao", true, boolean_ -> Minecraft.getInstance().levelRenderer.allChanged()
|
|
);
|
|
private static final Component PRIORITIZE_CHUNK_TOOLTIP_NONE = Component.translatable("options.prioritizeChunkUpdates.none.tooltip");
|
|
private static final Component PRIORITIZE_CHUNK_TOOLTIP_PLAYER_AFFECTED = Component.translatable("options.prioritizeChunkUpdates.byPlayer.tooltip");
|
|
private static final Component PRIORITIZE_CHUNK_TOOLTIP_NEARBY = Component.translatable("options.prioritizeChunkUpdates.nearby.tooltip");
|
|
private final OptionInstance<PrioritizeChunkUpdates> prioritizeChunkUpdates = new OptionInstance<>(
|
|
"options.prioritizeChunkUpdates",
|
|
prioritizeChunkUpdates -> {
|
|
return switch (prioritizeChunkUpdates) {
|
|
case NONE -> Tooltip.create(PRIORITIZE_CHUNK_TOOLTIP_NONE);
|
|
case PLAYER_AFFECTED -> Tooltip.create(PRIORITIZE_CHUNK_TOOLTIP_PLAYER_AFFECTED);
|
|
case NEARBY -> Tooltip.create(PRIORITIZE_CHUNK_TOOLTIP_NEARBY);
|
|
};
|
|
},
|
|
OptionInstance.forOptionEnum(),
|
|
new Enum<>(Arrays.asList(PrioritizeChunkUpdates.values()), Codec.INT.xmap(PrioritizeChunkUpdates::byId, PrioritizeChunkUpdates::getId)),
|
|
PrioritizeChunkUpdates.NONE,
|
|
prioritizeChunkUpdates -> {}
|
|
);
|
|
public List<String> resourcePacks = Lists.<String>newArrayList();
|
|
public List<String> incompatibleResourcePacks = Lists.<String>newArrayList();
|
|
private final OptionInstance<ChatVisiblity> chatVisibility = new OptionInstance<>(
|
|
"options.chat.visibility",
|
|
OptionInstance.noTooltip(),
|
|
OptionInstance.forOptionEnum(),
|
|
new Enum<>(Arrays.asList(ChatVisiblity.values()), Codec.INT.xmap(ChatVisiblity::byId, ChatVisiblity::getId)),
|
|
ChatVisiblity.FULL,
|
|
chatVisiblity -> {}
|
|
);
|
|
private final OptionInstance<Double> chatOpacity = new OptionInstance<>(
|
|
"options.chat.opacity",
|
|
OptionInstance.noTooltip(),
|
|
(component, double_) -> percentValueLabel(component, double_ * 0.9 + 0.1),
|
|
UnitDouble.INSTANCE,
|
|
1.0,
|
|
double_ -> Minecraft.getInstance().gui.getChat().rescaleChat()
|
|
);
|
|
private final OptionInstance<Double> chatLineSpacing = new OptionInstance<>(
|
|
"options.chat.line_spacing", OptionInstance.noTooltip(), Options::percentValueLabel, UnitDouble.INSTANCE, 0.0, double_ -> {}
|
|
);
|
|
private static final Component MENU_BACKGROUND_BLURRINESS_TOOLTIP = Component.translatable("options.accessibility.menu_background_blurriness.tooltip");
|
|
private static final int BLURRINESS_DEFAULT_VALUE = 5;
|
|
private final OptionInstance<Integer> menuBackgroundBlurriness = new OptionInstance<>(
|
|
"options.accessibility.menu_background_blurriness",
|
|
OptionInstance.cachedConstantTooltip(MENU_BACKGROUND_BLURRINESS_TOOLTIP),
|
|
Options::genericValueOrOffLabel,
|
|
new IntRange(0, 10),
|
|
5,
|
|
integer -> {}
|
|
);
|
|
private final OptionInstance<Double> textBackgroundOpacity = new OptionInstance<>(
|
|
"options.accessibility.text_background_opacity",
|
|
OptionInstance.noTooltip(),
|
|
Options::percentValueLabel,
|
|
UnitDouble.INSTANCE,
|
|
0.5,
|
|
double_ -> Minecraft.getInstance().gui.getChat().rescaleChat()
|
|
);
|
|
private final OptionInstance<Double> panoramaSpeed = new OptionInstance<>(
|
|
"options.accessibility.panorama_speed", OptionInstance.noTooltip(), Options::percentValueLabel, UnitDouble.INSTANCE, 1.0, double_ -> {}
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_CONTRAST_MODE = Component.translatable("options.accessibility.high_contrast.tooltip");
|
|
private final OptionInstance<Boolean> highContrast = OptionInstance.createBoolean(
|
|
"options.accessibility.high_contrast", OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_CONTRAST_MODE), false, boolean_ -> {
|
|
PackRepository packRepository = Minecraft.getInstance().getResourcePackRepository();
|
|
boolean blx = packRepository.getSelectedIds().contains("high_contrast");
|
|
if (!blx && boolean_) {
|
|
if (packRepository.addPack("high_contrast")) {
|
|
this.updateResourcePacks(packRepository);
|
|
}
|
|
} else if (blx && !boolean_ && packRepository.removePack("high_contrast")) {
|
|
this.updateResourcePacks(packRepository);
|
|
}
|
|
}
|
|
);
|
|
private static final Component HIGH_CONTRAST_BLOCK_OUTLINE_TOOLTIP = Component.translatable("options.accessibility.high_contrast_block_outline.tooltip");
|
|
private final OptionInstance<Boolean> highContrastBlockOutline = OptionInstance.createBoolean(
|
|
"options.accessibility.high_contrast_block_outline", OptionInstance.cachedConstantTooltip(HIGH_CONTRAST_BLOCK_OUTLINE_TOOLTIP), false
|
|
);
|
|
private final OptionInstance<Boolean> narratorHotkey = OptionInstance.createBoolean(
|
|
"options.accessibility.narrator_hotkey",
|
|
OptionInstance.cachedConstantTooltip(
|
|
Minecraft.ON_OSX
|
|
? Component.translatable("options.accessibility.narrator_hotkey.mac.tooltip")
|
|
: Component.translatable("options.accessibility.narrator_hotkey.tooltip")
|
|
),
|
|
true
|
|
);
|
|
@Nullable
|
|
public String fullscreenVideoModeString;
|
|
public boolean hideServerAddress;
|
|
public boolean advancedItemTooltips;
|
|
public boolean pauseOnLostFocus = true;
|
|
private final Set<PlayerModelPart> modelParts = EnumSet.allOf(PlayerModelPart.class);
|
|
private final OptionInstance<HumanoidArm> mainHand = new OptionInstance<>(
|
|
"options.mainHand",
|
|
OptionInstance.noTooltip(),
|
|
OptionInstance.forOptionEnum(),
|
|
new Enum<>(Arrays.asList(HumanoidArm.values()), HumanoidArm.CODEC),
|
|
HumanoidArm.RIGHT,
|
|
humanoidArm -> {}
|
|
);
|
|
public int overrideWidth;
|
|
public int overrideHeight;
|
|
private final OptionInstance<Double> chatScale = new OptionInstance<>(
|
|
"options.chat.scale",
|
|
OptionInstance.noTooltip(),
|
|
(component, double_) -> (Component)(double_ == 0.0 ? CommonComponents.optionStatus(component, false) : percentValueLabel(component, double_)),
|
|
UnitDouble.INSTANCE,
|
|
1.0,
|
|
double_ -> Minecraft.getInstance().gui.getChat().rescaleChat()
|
|
);
|
|
private final OptionInstance<Double> chatWidth = new OptionInstance<>(
|
|
"options.chat.width",
|
|
OptionInstance.noTooltip(),
|
|
(component, double_) -> pixelValueLabel(component, ChatComponent.getWidth(double_)),
|
|
UnitDouble.INSTANCE,
|
|
1.0,
|
|
double_ -> Minecraft.getInstance().gui.getChat().rescaleChat()
|
|
);
|
|
private final OptionInstance<Double> chatHeightUnfocused = new OptionInstance<>(
|
|
"options.chat.height.unfocused",
|
|
OptionInstance.noTooltip(),
|
|
(component, double_) -> pixelValueLabel(component, ChatComponent.getHeight(double_)),
|
|
UnitDouble.INSTANCE,
|
|
ChatComponent.defaultUnfocusedPct(),
|
|
double_ -> Minecraft.getInstance().gui.getChat().rescaleChat()
|
|
);
|
|
private final OptionInstance<Double> chatHeightFocused = new OptionInstance<>(
|
|
"options.chat.height.focused",
|
|
OptionInstance.noTooltip(),
|
|
(component, double_) -> pixelValueLabel(component, ChatComponent.getHeight(double_)),
|
|
UnitDouble.INSTANCE,
|
|
1.0,
|
|
double_ -> Minecraft.getInstance().gui.getChat().rescaleChat()
|
|
);
|
|
private final OptionInstance<Double> chatDelay = new OptionInstance<>(
|
|
"options.chat.delay_instant",
|
|
OptionInstance.noTooltip(),
|
|
(component, double_) -> double_ <= 0.0
|
|
? Component.translatable("options.chat.delay_none")
|
|
: Component.translatable("options.chat.delay", String.format(Locale.ROOT, "%.1f", double_)),
|
|
new IntRange(0, 60).xmap(i -> i / 10.0, double_ -> (int)(double_ * 10.0)),
|
|
Codec.doubleRange(0.0, 6.0),
|
|
0.0,
|
|
double_ -> Minecraft.getInstance().getChatListener().setMessageDelay(double_)
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_NOTIFICATION_DISPLAY_TIME = Component.translatable("options.notifications.display_time.tooltip");
|
|
private final OptionInstance<Double> notificationDisplayTime = new OptionInstance<>(
|
|
"options.notifications.display_time",
|
|
OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_NOTIFICATION_DISPLAY_TIME),
|
|
(component, double_) -> genericValueLabel(component, Component.translatable("options.multiplier", double_)),
|
|
new IntRange(5, 100).xmap(i -> i / 10.0, double_ -> (int)(double_ * 10.0)),
|
|
Codec.doubleRange(0.5, 10.0),
|
|
1.0,
|
|
double_ -> {}
|
|
);
|
|
private final OptionInstance<Integer> mipmapLevels = new OptionInstance<>(
|
|
"options.mipmapLevels",
|
|
OptionInstance.noTooltip(),
|
|
(component, integer) -> (Component)(integer == 0 ? CommonComponents.optionStatus(component, false) : genericValueLabel(component, integer)),
|
|
new IntRange(0, 4),
|
|
4,
|
|
integer -> {}
|
|
);
|
|
public boolean useNativeTransport = true;
|
|
private final OptionInstance<AttackIndicatorStatus> attackIndicator = new OptionInstance<>(
|
|
"options.attackIndicator",
|
|
OptionInstance.noTooltip(),
|
|
OptionInstance.forOptionEnum(),
|
|
new Enum<>(Arrays.asList(AttackIndicatorStatus.values()), Codec.INT.xmap(AttackIndicatorStatus::byId, AttackIndicatorStatus::getId)),
|
|
AttackIndicatorStatus.CROSSHAIR,
|
|
attackIndicatorStatus -> {}
|
|
);
|
|
public TutorialSteps tutorialStep = TutorialSteps.MOVEMENT;
|
|
public boolean joinedFirstServer = false;
|
|
private final OptionInstance<Integer> biomeBlendRadius = new OptionInstance<>(
|
|
"options.biomeBlendRadius", OptionInstance.noTooltip(), (component, integer) -> {
|
|
int i = integer * 2 + 1;
|
|
return genericValueLabel(component, Component.translatable("options.biomeBlendRadius." + i));
|
|
}, new IntRange(0, 7, false), 2, integer -> Minecraft.getInstance().levelRenderer.allChanged()
|
|
);
|
|
private final OptionInstance<Double> mouseWheelSensitivity = new OptionInstance<>(
|
|
"options.mouseWheelSensitivity",
|
|
OptionInstance.noTooltip(),
|
|
(component, double_) -> genericValueLabel(component, Component.literal(String.format(Locale.ROOT, "%.2f", double_))),
|
|
new IntRange(-200, 100).xmap(Options::logMouse, Options::unlogMouse),
|
|
Codec.doubleRange(logMouse(-200), logMouse(100)),
|
|
logMouse(0),
|
|
double_ -> {}
|
|
);
|
|
private final OptionInstance<Boolean> rawMouseInput = OptionInstance.createBoolean("options.rawMouseInput", true, boolean_ -> {
|
|
Window window = Minecraft.getInstance().getWindow();
|
|
if (window != null) {
|
|
window.updateRawMouseInput(boolean_);
|
|
}
|
|
});
|
|
public int glDebugVerbosity = 1;
|
|
private final OptionInstance<Boolean> autoJump = OptionInstance.createBoolean("options.autoJump", false);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_ROTATE_WITH_MINECART = Component.translatable("options.rotateWithMinecart.tooltip");
|
|
private final OptionInstance<Boolean> rotateWithMinecart = OptionInstance.createBoolean(
|
|
"options.rotateWithMinecart", OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_ROTATE_WITH_MINECART), false
|
|
);
|
|
private final OptionInstance<Boolean> operatorItemsTab = OptionInstance.createBoolean("options.operatorItemsTab", false);
|
|
private final OptionInstance<Boolean> autoSuggestions = OptionInstance.createBoolean("options.autoSuggestCommands", true);
|
|
private final OptionInstance<Boolean> chatColors = OptionInstance.createBoolean("options.chat.color", true);
|
|
private final OptionInstance<Boolean> chatLinks = OptionInstance.createBoolean("options.chat.links", true);
|
|
private final OptionInstance<Boolean> chatLinksPrompt = OptionInstance.createBoolean("options.chat.links.prompt", true);
|
|
private final OptionInstance<Boolean> enableVsync = OptionInstance.createBoolean("options.vsync", true, boolean_ -> {
|
|
if (Minecraft.getInstance().getWindow() != null) {
|
|
Minecraft.getInstance().getWindow().updateVsync(boolean_);
|
|
}
|
|
});
|
|
private final OptionInstance<Boolean> entityShadows = OptionInstance.createBoolean("options.entityShadows", true);
|
|
private final OptionInstance<Boolean> forceUnicodeFont = OptionInstance.createBoolean("options.forceUnicodeFont", false, boolean_ -> updateFontOptions());
|
|
private final OptionInstance<Boolean> japaneseGlyphVariants = OptionInstance.createBoolean(
|
|
"options.japaneseGlyphVariants",
|
|
OptionInstance.cachedConstantTooltip(Component.translatable("options.japaneseGlyphVariants.tooltip")),
|
|
japaneseGlyphVariantsDefault(),
|
|
boolean_ -> updateFontOptions()
|
|
);
|
|
private final OptionInstance<Boolean> invertYMouse = OptionInstance.createBoolean("options.invertMouse", false);
|
|
private final OptionInstance<Boolean> discreteMouseScroll = OptionInstance.createBoolean("options.discrete_mouse_scroll", false);
|
|
private static final Component REALMS_NOTIFICATIONS_TOOLTIP = Component.translatable("options.realmsNotifications.tooltip");
|
|
private final OptionInstance<Boolean> realmsNotifications = OptionInstance.createBoolean(
|
|
"options.realmsNotifications", OptionInstance.cachedConstantTooltip(REALMS_NOTIFICATIONS_TOOLTIP), true
|
|
);
|
|
private static final Component ALLOW_SERVER_LISTING_TOOLTIP = Component.translatable("options.allowServerListing.tooltip");
|
|
private final OptionInstance<Boolean> allowServerListing = OptionInstance.createBoolean(
|
|
"options.allowServerListing", OptionInstance.cachedConstantTooltip(ALLOW_SERVER_LISTING_TOOLTIP), true, boolean_ -> {}
|
|
);
|
|
private final OptionInstance<Boolean> reducedDebugInfo = OptionInstance.createBoolean("options.reducedDebugInfo", false);
|
|
private final Map<SoundSource, OptionInstance<Double>> soundSourceVolumes = Util.makeEnumMap(
|
|
SoundSource.class, soundSource -> this.createSoundSliderOptionInstance("soundCategory." + soundSource.getName(), soundSource)
|
|
);
|
|
private final OptionInstance<Boolean> showSubtitles = OptionInstance.createBoolean("options.showSubtitles", false);
|
|
private static final Component DIRECTIONAL_AUDIO_TOOLTIP_ON = Component.translatable("options.directionalAudio.on.tooltip");
|
|
private static final Component DIRECTIONAL_AUDIO_TOOLTIP_OFF = Component.translatable("options.directionalAudio.off.tooltip");
|
|
private final OptionInstance<Boolean> directionalAudio = OptionInstance.createBoolean(
|
|
"options.directionalAudio",
|
|
boolean_ -> boolean_ ? Tooltip.create(DIRECTIONAL_AUDIO_TOOLTIP_ON) : Tooltip.create(DIRECTIONAL_AUDIO_TOOLTIP_OFF),
|
|
false,
|
|
boolean_ -> {
|
|
SoundManager soundManager = Minecraft.getInstance().getSoundManager();
|
|
soundManager.reload();
|
|
soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
|
}
|
|
);
|
|
private final OptionInstance<Boolean> backgroundForChatOnly = new OptionInstance<>(
|
|
"options.accessibility.text_background",
|
|
OptionInstance.noTooltip(),
|
|
(component, boolean_) -> boolean_
|
|
? Component.translatable("options.accessibility.text_background.chat")
|
|
: Component.translatable("options.accessibility.text_background.everywhere"),
|
|
OptionInstance.BOOLEAN_VALUES,
|
|
true,
|
|
boolean_ -> {}
|
|
);
|
|
private final OptionInstance<Boolean> touchscreen = OptionInstance.createBoolean("options.touchscreen", false);
|
|
private final OptionInstance<Boolean> fullscreen = OptionInstance.createBoolean("options.fullscreen", false, boolean_ -> {
|
|
Minecraft minecraftx = Minecraft.getInstance();
|
|
if (minecraftx.getWindow() != null && minecraftx.getWindow().isFullscreen() != boolean_) {
|
|
minecraftx.getWindow().toggleFullScreen();
|
|
this.fullscreen().set(minecraftx.getWindow().isFullscreen());
|
|
}
|
|
});
|
|
private final OptionInstance<Boolean> bobView = OptionInstance.createBoolean("options.viewBobbing", true);
|
|
private static final Component MOVEMENT_TOGGLE = Component.translatable("options.key.toggle");
|
|
private static final Component MOVEMENT_HOLD = Component.translatable("options.key.hold");
|
|
private final OptionInstance<Boolean> toggleCrouch = new OptionInstance<>(
|
|
"key.sneak",
|
|
OptionInstance.noTooltip(),
|
|
(component, boolean_) -> boolean_ ? MOVEMENT_TOGGLE : MOVEMENT_HOLD,
|
|
OptionInstance.BOOLEAN_VALUES,
|
|
false,
|
|
boolean_ -> {}
|
|
);
|
|
private final OptionInstance<Boolean> toggleSprint = new OptionInstance<>(
|
|
"key.sprint",
|
|
OptionInstance.noTooltip(),
|
|
(component, boolean_) -> boolean_ ? MOVEMENT_TOGGLE : MOVEMENT_HOLD,
|
|
OptionInstance.BOOLEAN_VALUES,
|
|
false,
|
|
boolean_ -> {}
|
|
);
|
|
public boolean skipMultiplayerWarning;
|
|
private static final Component CHAT_TOOLTIP_HIDE_MATCHED_NAMES = Component.translatable("options.hideMatchedNames.tooltip");
|
|
private final OptionInstance<Boolean> hideMatchedNames = OptionInstance.createBoolean(
|
|
"options.hideMatchedNames", OptionInstance.cachedConstantTooltip(CHAT_TOOLTIP_HIDE_MATCHED_NAMES), true
|
|
);
|
|
private final OptionInstance<Boolean> showAutosaveIndicator = OptionInstance.createBoolean("options.autosaveIndicator", true);
|
|
private static final Component CHAT_TOOLTIP_ONLY_SHOW_SECURE = Component.translatable("options.onlyShowSecureChat.tooltip");
|
|
private final OptionInstance<Boolean> onlyShowSecureChat = OptionInstance.createBoolean(
|
|
"options.onlyShowSecureChat", OptionInstance.cachedConstantTooltip(CHAT_TOOLTIP_ONLY_SHOW_SECURE), false
|
|
);
|
|
public final KeyMapping keyUp = new KeyMapping("key.forward", 87, "key.categories.movement");
|
|
public final KeyMapping keyLeft = new KeyMapping("key.left", 65, "key.categories.movement");
|
|
public final KeyMapping keyDown = new KeyMapping("key.back", 83, "key.categories.movement");
|
|
public final KeyMapping keyRight = new KeyMapping("key.right", 68, "key.categories.movement");
|
|
public final KeyMapping keyJump = new KeyMapping("key.jump", 32, "key.categories.movement");
|
|
public final KeyMapping keyShift = new ToggleKeyMapping("key.sneak", 340, "key.categories.movement", this.toggleCrouch::get);
|
|
public final KeyMapping keySprint = new ToggleKeyMapping("key.sprint", 341, "key.categories.movement", this.toggleSprint::get);
|
|
public final KeyMapping keyInventory = new KeyMapping("key.inventory", 69, "key.categories.inventory");
|
|
public final KeyMapping keySwapOffhand = new KeyMapping("key.swapOffhand", 70, "key.categories.inventory");
|
|
public final KeyMapping keyDrop = new KeyMapping("key.drop", 81, "key.categories.inventory");
|
|
public final KeyMapping keyUse = new KeyMapping("key.use", Type.MOUSE, 1, "key.categories.gameplay");
|
|
public final KeyMapping keyAttack = new KeyMapping("key.attack", Type.MOUSE, 0, "key.categories.gameplay");
|
|
public final KeyMapping keyPickItem = new KeyMapping("key.pickItem", Type.MOUSE, 2, "key.categories.gameplay");
|
|
public final KeyMapping keyChat = new KeyMapping("key.chat", 84, "key.categories.multiplayer");
|
|
public final KeyMapping keyPlayerList = new KeyMapping("key.playerlist", 258, "key.categories.multiplayer");
|
|
public final KeyMapping keyCommand = new KeyMapping("key.command", 47, "key.categories.multiplayer");
|
|
public final KeyMapping keySocialInteractions = new KeyMapping("key.socialInteractions", 80, "key.categories.multiplayer");
|
|
public final KeyMapping keyScreenshot = new KeyMapping("key.screenshot", 291, "key.categories.misc");
|
|
public final KeyMapping keyTogglePerspective = new KeyMapping("key.togglePerspective", 294, "key.categories.misc");
|
|
public final KeyMapping keySmoothCamera = new KeyMapping("key.smoothCamera", InputConstants.UNKNOWN.getValue(), "key.categories.misc");
|
|
public final KeyMapping keyFullscreen = new KeyMapping("key.fullscreen", 300, "key.categories.misc");
|
|
public final KeyMapping keySpectatorOutlines = new KeyMapping("key.spectatorOutlines", InputConstants.UNKNOWN.getValue(), "key.categories.misc");
|
|
public final KeyMapping keyAdvancements = new KeyMapping("key.advancements", 76, "key.categories.misc");
|
|
public final KeyMapping[] keyHotbarSlots = new KeyMapping[]{
|
|
new KeyMapping("key.hotbar.1", 49, "key.categories.inventory"),
|
|
new KeyMapping("key.hotbar.2", 50, "key.categories.inventory"),
|
|
new KeyMapping("key.hotbar.3", 51, "key.categories.inventory"),
|
|
new KeyMapping("key.hotbar.4", 52, "key.categories.inventory"),
|
|
new KeyMapping("key.hotbar.5", 53, "key.categories.inventory"),
|
|
new KeyMapping("key.hotbar.6", 54, "key.categories.inventory"),
|
|
new KeyMapping("key.hotbar.7", 55, "key.categories.inventory"),
|
|
new KeyMapping("key.hotbar.8", 56, "key.categories.inventory"),
|
|
new KeyMapping("key.hotbar.9", 57, "key.categories.inventory")
|
|
};
|
|
public final KeyMapping keySaveHotbarActivator = new KeyMapping("key.saveToolbarActivator", 67, "key.categories.creative");
|
|
public final KeyMapping keyLoadHotbarActivator = new KeyMapping("key.loadToolbarActivator", 88, "key.categories.creative");
|
|
public final KeyMapping[] keyMappings = ArrayUtils.addAll(
|
|
(KeyMapping[])(new KeyMapping[]{
|
|
this.keyAttack,
|
|
this.keyUse,
|
|
this.keyUp,
|
|
this.keyLeft,
|
|
this.keyDown,
|
|
this.keyRight,
|
|
this.keyJump,
|
|
this.keyShift,
|
|
this.keySprint,
|
|
this.keyDrop,
|
|
this.keyInventory,
|
|
this.keyChat,
|
|
this.keyPlayerList,
|
|
this.keyPickItem,
|
|
this.keyCommand,
|
|
this.keySocialInteractions,
|
|
this.keyScreenshot,
|
|
this.keyTogglePerspective,
|
|
this.keySmoothCamera,
|
|
this.keyFullscreen,
|
|
this.keySpectatorOutlines,
|
|
this.keySwapOffhand,
|
|
this.keySaveHotbarActivator,
|
|
this.keyLoadHotbarActivator,
|
|
this.keyAdvancements
|
|
}),
|
|
(KeyMapping[])this.keyHotbarSlots
|
|
);
|
|
protected Minecraft minecraft;
|
|
private final File optionsFile;
|
|
public boolean hideGui;
|
|
private CameraType cameraType = CameraType.FIRST_PERSON;
|
|
public String lastMpIp = "";
|
|
public boolean smoothCamera;
|
|
private final OptionInstance<Integer> fov = new OptionInstance<>(
|
|
"options.fov",
|
|
OptionInstance.noTooltip(),
|
|
(component, integer) -> {
|
|
return switch (integer) {
|
|
case 70 -> genericValueLabel(component, Component.translatable("options.fov.min"));
|
|
case 110 -> genericValueLabel(component, Component.translatable("options.fov.max"));
|
|
default -> genericValueLabel(component, integer);
|
|
};
|
|
},
|
|
new IntRange(30, 110),
|
|
Codec.DOUBLE.xmap(double_ -> (int)(double_ * 40.0 + 70.0), integer -> (integer.intValue() - 70.0) / 40.0),
|
|
70,
|
|
integer -> Minecraft.getInstance().levelRenderer.needsUpdate()
|
|
);
|
|
private static final Component TELEMETRY_TOOLTIP = Component.translatable(
|
|
"options.telemetry.button.tooltip", Component.translatable("options.telemetry.state.minimal"), Component.translatable("options.telemetry.state.all")
|
|
);
|
|
private final OptionInstance<Boolean> telemetryOptInExtra = OptionInstance.createBoolean(
|
|
"options.telemetry.button",
|
|
OptionInstance.cachedConstantTooltip(TELEMETRY_TOOLTIP),
|
|
(component, boolean_) -> {
|
|
Minecraft minecraftx = Minecraft.getInstance();
|
|
if (!minecraftx.allowsTelemetry()) {
|
|
return Component.translatable("options.telemetry.state.none");
|
|
} else {
|
|
return boolean_ && minecraftx.extraTelemetryAvailable()
|
|
? Component.translatable("options.telemetry.state.all")
|
|
: Component.translatable("options.telemetry.state.minimal");
|
|
}
|
|
},
|
|
false,
|
|
boolean_ -> {}
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_SCREEN_EFFECT = Component.translatable("options.screenEffectScale.tooltip");
|
|
private final OptionInstance<Double> screenEffectScale = new OptionInstance<>(
|
|
"options.screenEffectScale",
|
|
OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_SCREEN_EFFECT),
|
|
Options::percentValueOrOffLabel,
|
|
UnitDouble.INSTANCE,
|
|
1.0,
|
|
double_ -> {}
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_FOV_EFFECT = Component.translatable("options.fovEffectScale.tooltip");
|
|
private final OptionInstance<Double> fovEffectScale = new OptionInstance<>(
|
|
"options.fovEffectScale",
|
|
OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_FOV_EFFECT),
|
|
Options::percentValueOrOffLabel,
|
|
UnitDouble.INSTANCE.xmap(Mth::square, Math::sqrt),
|
|
Codec.doubleRange(0.0, 1.0),
|
|
1.0,
|
|
double_ -> {}
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_DARKNESS_EFFECT = Component.translatable("options.darknessEffectScale.tooltip");
|
|
private final OptionInstance<Double> darknessEffectScale = new OptionInstance<>(
|
|
"options.darknessEffectScale",
|
|
OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_DARKNESS_EFFECT),
|
|
Options::percentValueOrOffLabel,
|
|
UnitDouble.INSTANCE.xmap(Mth::square, Math::sqrt),
|
|
1.0,
|
|
double_ -> {}
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_GLINT_SPEED = Component.translatable("options.glintSpeed.tooltip");
|
|
private final OptionInstance<Double> glintSpeed = new OptionInstance<>(
|
|
"options.glintSpeed",
|
|
OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_GLINT_SPEED),
|
|
Options::percentValueOrOffLabel,
|
|
UnitDouble.INSTANCE,
|
|
0.5,
|
|
double_ -> {}
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_GLINT_STRENGTH = Component.translatable("options.glintStrength.tooltip");
|
|
private final OptionInstance<Double> glintStrength = new OptionInstance<>(
|
|
"options.glintStrength",
|
|
OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_GLINT_STRENGTH),
|
|
Options::percentValueOrOffLabel,
|
|
UnitDouble.INSTANCE,
|
|
0.75,
|
|
RenderSystem::setShaderGlintAlpha
|
|
);
|
|
private static final Component ACCESSIBILITY_TOOLTIP_DAMAGE_TILT_STRENGTH = Component.translatable("options.damageTiltStrength.tooltip");
|
|
private final OptionInstance<Double> damageTiltStrength = new OptionInstance<>(
|
|
"options.damageTiltStrength",
|
|
OptionInstance.cachedConstantTooltip(ACCESSIBILITY_TOOLTIP_DAMAGE_TILT_STRENGTH),
|
|
Options::percentValueOrOffLabel,
|
|
UnitDouble.INSTANCE,
|
|
1.0,
|
|
double_ -> {}
|
|
);
|
|
private final OptionInstance<Double> gamma = new OptionInstance<>("options.gamma", OptionInstance.noTooltip(), (component, double_) -> {
|
|
int i = (int)(double_ * 100.0);
|
|
if (i == 0) {
|
|
return genericValueLabel(component, Component.translatable("options.gamma.min"));
|
|
} else if (i == 50) {
|
|
return genericValueLabel(component, Component.translatable("options.gamma.default"));
|
|
} else {
|
|
return i == 100 ? genericValueLabel(component, Component.translatable("options.gamma.max")) : genericValueLabel(component, i);
|
|
}
|
|
}, UnitDouble.INSTANCE, 0.5, double_ -> {});
|
|
public static final int AUTO_GUI_SCALE = 0;
|
|
private static final int MAX_GUI_SCALE_INCLUSIVE = 2147483646;
|
|
private final OptionInstance<Integer> guiScale = new OptionInstance<>(
|
|
"options.guiScale",
|
|
OptionInstance.noTooltip(),
|
|
(component, integer) -> integer == 0 ? Component.translatable("options.guiScale.auto") : Component.literal(Integer.toString(integer)),
|
|
new ClampingLazyMaxIntRange(0, () -> {
|
|
Minecraft minecraftx = Minecraft.getInstance();
|
|
return !minecraftx.isRunning() ? 2147483646 : minecraftx.getWindow().calculateScale(0, minecraftx.isEnforceUnicode());
|
|
}, 2147483646),
|
|
0,
|
|
integer -> this.minecraft.resizeDisplay()
|
|
);
|
|
private final OptionInstance<ParticleStatus> particles = new OptionInstance<>(
|
|
"options.particles",
|
|
OptionInstance.noTooltip(),
|
|
OptionInstance.forOptionEnum(),
|
|
new Enum<>(Arrays.asList(ParticleStatus.values()), Codec.INT.xmap(ParticleStatus::byId, ParticleStatus::getId)),
|
|
ParticleStatus.ALL,
|
|
particleStatus -> {}
|
|
);
|
|
private final OptionInstance<NarratorStatus> narrator = new OptionInstance<>(
|
|
"options.narrator",
|
|
OptionInstance.noTooltip(),
|
|
(component, narratorStatus) -> (Component)(this.minecraft.getNarrator().isActive()
|
|
? narratorStatus.getName()
|
|
: Component.translatable("options.narrator.notavailable")),
|
|
new Enum<>(Arrays.asList(NarratorStatus.values()), Codec.INT.xmap(NarratorStatus::byId, NarratorStatus::getId)),
|
|
NarratorStatus.OFF,
|
|
narratorStatus -> this.minecraft.getNarrator().updateNarratorStatus(narratorStatus)
|
|
);
|
|
public String languageCode = "en_us";
|
|
private final OptionInstance<String> soundDevice = new OptionInstance<>(
|
|
"options.audioDevice",
|
|
OptionInstance.noTooltip(),
|
|
(component, string) -> {
|
|
if ("".equals(string)) {
|
|
return Component.translatable("options.audioDevice.default");
|
|
} else {
|
|
return string.startsWith("OpenAL Soft on ") ? Component.literal(string.substring(SoundEngine.OPEN_AL_SOFT_PREFIX_LENGTH)) : Component.literal(string);
|
|
}
|
|
},
|
|
new LazyEnum<>(
|
|
() -> Stream.concat(Stream.of(""), Minecraft.getInstance().getSoundManager().getAvailableSoundDevices().stream()).toList(),
|
|
string -> Minecraft.getInstance().isRunning() && string != "" && !Minecraft.getInstance().getSoundManager().getAvailableSoundDevices().contains(string)
|
|
? Optional.empty()
|
|
: Optional.of(string),
|
|
Codec.STRING
|
|
),
|
|
"",
|
|
string -> {
|
|
SoundManager soundManager = Minecraft.getInstance().getSoundManager();
|
|
soundManager.reload();
|
|
soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
|
}
|
|
);
|
|
public boolean onboardAccessibility = true;
|
|
public boolean syncWrites;
|
|
public boolean startedCleanly = true;
|
|
|
|
public OptionInstance<Boolean> darkMojangStudiosBackground() {
|
|
return this.darkMojangStudiosBackground;
|
|
}
|
|
|
|
public OptionInstance<Boolean> hideLightningFlash() {
|
|
return this.hideLightningFlash;
|
|
}
|
|
|
|
public OptionInstance<Boolean> hideSplashTexts() {
|
|
return this.hideSplashTexts;
|
|
}
|
|
|
|
public OptionInstance<Double> sensitivity() {
|
|
return this.sensitivity;
|
|
}
|
|
|
|
public OptionInstance<Integer> renderDistance() {
|
|
return this.renderDistance;
|
|
}
|
|
|
|
public OptionInstance<Integer> simulationDistance() {
|
|
return this.simulationDistance;
|
|
}
|
|
|
|
public OptionInstance<Double> entityDistanceScaling() {
|
|
return this.entityDistanceScaling;
|
|
}
|
|
|
|
public OptionInstance<Integer> framerateLimit() {
|
|
return this.framerateLimit;
|
|
}
|
|
|
|
public OptionInstance<InactivityFpsLimit> inactivityFpsLimit() {
|
|
return this.inactivityFpsLimit;
|
|
}
|
|
|
|
public OptionInstance<CloudStatus> cloudStatus() {
|
|
return this.cloudStatus;
|
|
}
|
|
|
|
public OptionInstance<GraphicsStatus> graphicsMode() {
|
|
return this.graphicsMode;
|
|
}
|
|
|
|
public OptionInstance<Boolean> ambientOcclusion() {
|
|
return this.ambientOcclusion;
|
|
}
|
|
|
|
public OptionInstance<PrioritizeChunkUpdates> prioritizeChunkUpdates() {
|
|
return this.prioritizeChunkUpdates;
|
|
}
|
|
|
|
public void updateResourcePacks(PackRepository packRepository) {
|
|
List<String> list = ImmutableList.copyOf(this.resourcePacks);
|
|
this.resourcePacks.clear();
|
|
this.incompatibleResourcePacks.clear();
|
|
|
|
for (Pack pack : packRepository.getSelectedPacks()) {
|
|
if (!pack.isFixedPosition()) {
|
|
this.resourcePacks.add(pack.getId());
|
|
if (!pack.getCompatibility().isCompatible()) {
|
|
this.incompatibleResourcePacks.add(pack.getId());
|
|
}
|
|
}
|
|
}
|
|
|
|
this.save();
|
|
List<String> list2 = ImmutableList.copyOf(this.resourcePacks);
|
|
if (!list2.equals(list)) {
|
|
this.minecraft.reloadResourcePacks();
|
|
}
|
|
}
|
|
|
|
public OptionInstance<ChatVisiblity> chatVisibility() {
|
|
return this.chatVisibility;
|
|
}
|
|
|
|
public OptionInstance<Double> chatOpacity() {
|
|
return this.chatOpacity;
|
|
}
|
|
|
|
public OptionInstance<Double> chatLineSpacing() {
|
|
return this.chatLineSpacing;
|
|
}
|
|
|
|
public OptionInstance<Integer> menuBackgroundBlurriness() {
|
|
return this.menuBackgroundBlurriness;
|
|
}
|
|
|
|
public int getMenuBackgroundBlurriness() {
|
|
return this.menuBackgroundBlurriness().get();
|
|
}
|
|
|
|
public OptionInstance<Double> textBackgroundOpacity() {
|
|
return this.textBackgroundOpacity;
|
|
}
|
|
|
|
public OptionInstance<Double> panoramaSpeed() {
|
|
return this.panoramaSpeed;
|
|
}
|
|
|
|
public OptionInstance<Boolean> highContrast() {
|
|
return this.highContrast;
|
|
}
|
|
|
|
public OptionInstance<Boolean> highContrastBlockOutline() {
|
|
return this.highContrastBlockOutline;
|
|
}
|
|
|
|
public OptionInstance<Boolean> narratorHotkey() {
|
|
return this.narratorHotkey;
|
|
}
|
|
|
|
public OptionInstance<HumanoidArm> mainHand() {
|
|
return this.mainHand;
|
|
}
|
|
|
|
public OptionInstance<Double> chatScale() {
|
|
return this.chatScale;
|
|
}
|
|
|
|
public OptionInstance<Double> chatWidth() {
|
|
return this.chatWidth;
|
|
}
|
|
|
|
public OptionInstance<Double> chatHeightUnfocused() {
|
|
return this.chatHeightUnfocused;
|
|
}
|
|
|
|
public OptionInstance<Double> chatHeightFocused() {
|
|
return this.chatHeightFocused;
|
|
}
|
|
|
|
public OptionInstance<Double> chatDelay() {
|
|
return this.chatDelay;
|
|
}
|
|
|
|
public OptionInstance<Double> notificationDisplayTime() {
|
|
return this.notificationDisplayTime;
|
|
}
|
|
|
|
public OptionInstance<Integer> mipmapLevels() {
|
|
return this.mipmapLevels;
|
|
}
|
|
|
|
public OptionInstance<AttackIndicatorStatus> attackIndicator() {
|
|
return this.attackIndicator;
|
|
}
|
|
|
|
public OptionInstance<Integer> biomeBlendRadius() {
|
|
return this.biomeBlendRadius;
|
|
}
|
|
|
|
private static double logMouse(int input) {
|
|
return Math.pow(10.0, input / 100.0);
|
|
}
|
|
|
|
private static int unlogMouse(double input) {
|
|
return Mth.floor(Math.log10(input) * 100.0);
|
|
}
|
|
|
|
public OptionInstance<Double> mouseWheelSensitivity() {
|
|
return this.mouseWheelSensitivity;
|
|
}
|
|
|
|
public OptionInstance<Boolean> rawMouseInput() {
|
|
return this.rawMouseInput;
|
|
}
|
|
|
|
public OptionInstance<Boolean> autoJump() {
|
|
return this.autoJump;
|
|
}
|
|
|
|
public OptionInstance<Boolean> rotateWithMinecart() {
|
|
return this.rotateWithMinecart;
|
|
}
|
|
|
|
public OptionInstance<Boolean> operatorItemsTab() {
|
|
return this.operatorItemsTab;
|
|
}
|
|
|
|
public OptionInstance<Boolean> autoSuggestions() {
|
|
return this.autoSuggestions;
|
|
}
|
|
|
|
public OptionInstance<Boolean> chatColors() {
|
|
return this.chatColors;
|
|
}
|
|
|
|
public OptionInstance<Boolean> chatLinks() {
|
|
return this.chatLinks;
|
|
}
|
|
|
|
public OptionInstance<Boolean> chatLinksPrompt() {
|
|
return this.chatLinksPrompt;
|
|
}
|
|
|
|
public OptionInstance<Boolean> enableVsync() {
|
|
return this.enableVsync;
|
|
}
|
|
|
|
public OptionInstance<Boolean> entityShadows() {
|
|
return this.entityShadows;
|
|
}
|
|
|
|
private static void updateFontOptions() {
|
|
Minecraft minecraft = Minecraft.getInstance();
|
|
if (minecraft.getWindow() != null) {
|
|
minecraft.updateFontOptions();
|
|
minecraft.resizeDisplay();
|
|
}
|
|
}
|
|
|
|
public OptionInstance<Boolean> forceUnicodeFont() {
|
|
return this.forceUnicodeFont;
|
|
}
|
|
|
|
private static boolean japaneseGlyphVariantsDefault() {
|
|
return Locale.getDefault().getLanguage().equalsIgnoreCase("ja");
|
|
}
|
|
|
|
public OptionInstance<Boolean> japaneseGlyphVariants() {
|
|
return this.japaneseGlyphVariants;
|
|
}
|
|
|
|
public OptionInstance<Boolean> invertYMouse() {
|
|
return this.invertYMouse;
|
|
}
|
|
|
|
public OptionInstance<Boolean> discreteMouseScroll() {
|
|
return this.discreteMouseScroll;
|
|
}
|
|
|
|
public OptionInstance<Boolean> realmsNotifications() {
|
|
return this.realmsNotifications;
|
|
}
|
|
|
|
public OptionInstance<Boolean> allowServerListing() {
|
|
return this.allowServerListing;
|
|
}
|
|
|
|
public OptionInstance<Boolean> reducedDebugInfo() {
|
|
return this.reducedDebugInfo;
|
|
}
|
|
|
|
public final float getSoundSourceVolume(SoundSource category) {
|
|
return this.getSoundSourceOptionInstance(category).get().floatValue();
|
|
}
|
|
|
|
public final OptionInstance<Double> getSoundSourceOptionInstance(SoundSource soundSource) {
|
|
return (OptionInstance<Double>)Objects.requireNonNull((OptionInstance)this.soundSourceVolumes.get(soundSource));
|
|
}
|
|
|
|
private OptionInstance<Double> createSoundSliderOptionInstance(String text, SoundSource soundSource) {
|
|
return new OptionInstance<>(
|
|
text,
|
|
OptionInstance.noTooltip(),
|
|
Options::percentValueOrOffLabel,
|
|
UnitDouble.INSTANCE,
|
|
1.0,
|
|
double_ -> Minecraft.getInstance().getSoundManager().updateSourceVolume(soundSource, double_.floatValue())
|
|
);
|
|
}
|
|
|
|
public OptionInstance<Boolean> showSubtitles() {
|
|
return this.showSubtitles;
|
|
}
|
|
|
|
public OptionInstance<Boolean> directionalAudio() {
|
|
return this.directionalAudio;
|
|
}
|
|
|
|
public OptionInstance<Boolean> backgroundForChatOnly() {
|
|
return this.backgroundForChatOnly;
|
|
}
|
|
|
|
public OptionInstance<Boolean> touchscreen() {
|
|
return this.touchscreen;
|
|
}
|
|
|
|
public OptionInstance<Boolean> fullscreen() {
|
|
return this.fullscreen;
|
|
}
|
|
|
|
public OptionInstance<Boolean> bobView() {
|
|
return this.bobView;
|
|
}
|
|
|
|
public OptionInstance<Boolean> toggleCrouch() {
|
|
return this.toggleCrouch;
|
|
}
|
|
|
|
public OptionInstance<Boolean> toggleSprint() {
|
|
return this.toggleSprint;
|
|
}
|
|
|
|
public OptionInstance<Boolean> hideMatchedNames() {
|
|
return this.hideMatchedNames;
|
|
}
|
|
|
|
public OptionInstance<Boolean> showAutosaveIndicator() {
|
|
return this.showAutosaveIndicator;
|
|
}
|
|
|
|
public OptionInstance<Boolean> onlyShowSecureChat() {
|
|
return this.onlyShowSecureChat;
|
|
}
|
|
|
|
public OptionInstance<Integer> fov() {
|
|
return this.fov;
|
|
}
|
|
|
|
public OptionInstance<Boolean> telemetryOptInExtra() {
|
|
return this.telemetryOptInExtra;
|
|
}
|
|
|
|
public OptionInstance<Double> screenEffectScale() {
|
|
return this.screenEffectScale;
|
|
}
|
|
|
|
public OptionInstance<Double> fovEffectScale() {
|
|
return this.fovEffectScale;
|
|
}
|
|
|
|
public OptionInstance<Double> darknessEffectScale() {
|
|
return this.darknessEffectScale;
|
|
}
|
|
|
|
public OptionInstance<Double> glintSpeed() {
|
|
return this.glintSpeed;
|
|
}
|
|
|
|
public OptionInstance<Double> glintStrength() {
|
|
return this.glintStrength;
|
|
}
|
|
|
|
public OptionInstance<Double> damageTiltStrength() {
|
|
return this.damageTiltStrength;
|
|
}
|
|
|
|
public OptionInstance<Double> gamma() {
|
|
return this.gamma;
|
|
}
|
|
|
|
public OptionInstance<Integer> guiScale() {
|
|
return this.guiScale;
|
|
}
|
|
|
|
public OptionInstance<ParticleStatus> particles() {
|
|
return this.particles;
|
|
}
|
|
|
|
public OptionInstance<NarratorStatus> narrator() {
|
|
return this.narrator;
|
|
}
|
|
|
|
public OptionInstance<String> soundDevice() {
|
|
return this.soundDevice;
|
|
}
|
|
|
|
public void onboardingAccessibilityFinished() {
|
|
this.onboardAccessibility = false;
|
|
this.save();
|
|
}
|
|
|
|
public Options(Minecraft minecraft, File gameDirectory) {
|
|
this.minecraft = minecraft;
|
|
this.optionsFile = new File(gameDirectory, "options.txt");
|
|
boolean bl = Runtime.getRuntime().maxMemory() >= 1000000000L;
|
|
this.renderDistance = new OptionInstance<>(
|
|
"options.renderDistance",
|
|
OptionInstance.noTooltip(),
|
|
(component, integer) -> genericValueLabel(component, Component.translatable("options.chunks", integer)),
|
|
new IntRange(2, bl ? 32 : 16, false),
|
|
12,
|
|
integer -> Minecraft.getInstance().levelRenderer.needsUpdate()
|
|
);
|
|
this.simulationDistance = new OptionInstance<>(
|
|
"options.simulationDistance",
|
|
OptionInstance.noTooltip(),
|
|
(component, integer) -> genericValueLabel(component, Component.translatable("options.chunks", integer)),
|
|
new IntRange(5, bl ? 32 : 16, false),
|
|
12,
|
|
integer -> {}
|
|
);
|
|
this.syncWrites = Util.getPlatform() == Util.OS.WINDOWS;
|
|
this.load();
|
|
}
|
|
|
|
public float getBackgroundOpacity(float opacity) {
|
|
return this.backgroundForChatOnly.get() ? opacity : this.textBackgroundOpacity().get().floatValue();
|
|
}
|
|
|
|
public int getBackgroundColor(float opacity) {
|
|
return ARGB.colorFromFloat(this.getBackgroundOpacity(opacity), 0.0F, 0.0F, 0.0F);
|
|
}
|
|
|
|
public int getBackgroundColor(int chatColor) {
|
|
return this.backgroundForChatOnly.get() ? chatColor : ARGB.colorFromFloat(this.textBackgroundOpacity.get().floatValue(), 0.0F, 0.0F, 0.0F);
|
|
}
|
|
|
|
private void processDumpedOptions(Options.OptionAccess optionAccess) {
|
|
optionAccess.process("ao", this.ambientOcclusion);
|
|
optionAccess.process("biomeBlendRadius", this.biomeBlendRadius);
|
|
optionAccess.process("enableVsync", this.enableVsync);
|
|
optionAccess.process("entityDistanceScaling", this.entityDistanceScaling);
|
|
optionAccess.process("entityShadows", this.entityShadows);
|
|
optionAccess.process("forceUnicodeFont", this.forceUnicodeFont);
|
|
optionAccess.process("japaneseGlyphVariants", this.japaneseGlyphVariants);
|
|
optionAccess.process("fov", this.fov);
|
|
optionAccess.process("fovEffectScale", this.fovEffectScale);
|
|
optionAccess.process("darknessEffectScale", this.darknessEffectScale);
|
|
optionAccess.process("glintSpeed", this.glintSpeed);
|
|
optionAccess.process("glintStrength", this.glintStrength);
|
|
optionAccess.process("prioritizeChunkUpdates", this.prioritizeChunkUpdates);
|
|
optionAccess.process("fullscreen", this.fullscreen);
|
|
optionAccess.process("gamma", this.gamma);
|
|
optionAccess.process("graphicsMode", this.graphicsMode);
|
|
optionAccess.process("guiScale", this.guiScale);
|
|
optionAccess.process("maxFps", this.framerateLimit);
|
|
optionAccess.process("inactivityFpsLimit", this.inactivityFpsLimit);
|
|
optionAccess.process("mipmapLevels", this.mipmapLevels);
|
|
optionAccess.process("narrator", this.narrator);
|
|
optionAccess.process("particles", this.particles);
|
|
optionAccess.process("reducedDebugInfo", this.reducedDebugInfo);
|
|
optionAccess.process("renderClouds", this.cloudStatus);
|
|
optionAccess.process("renderDistance", this.renderDistance);
|
|
optionAccess.process("simulationDistance", this.simulationDistance);
|
|
optionAccess.process("screenEffectScale", this.screenEffectScale);
|
|
optionAccess.process("soundDevice", this.soundDevice);
|
|
}
|
|
|
|
private void processOptions(Options.FieldAccess accessor) {
|
|
this.processDumpedOptions(accessor);
|
|
accessor.process("autoJump", this.autoJump);
|
|
accessor.process("rotateWithMinecart", this.rotateWithMinecart);
|
|
accessor.process("operatorItemsTab", this.operatorItemsTab);
|
|
accessor.process("autoSuggestions", this.autoSuggestions);
|
|
accessor.process("chatColors", this.chatColors);
|
|
accessor.process("chatLinks", this.chatLinks);
|
|
accessor.process("chatLinksPrompt", this.chatLinksPrompt);
|
|
accessor.process("discrete_mouse_scroll", this.discreteMouseScroll);
|
|
accessor.process("invertYMouse", this.invertYMouse);
|
|
accessor.process("realmsNotifications", this.realmsNotifications);
|
|
accessor.process("showSubtitles", this.showSubtitles);
|
|
accessor.process("directionalAudio", this.directionalAudio);
|
|
accessor.process("touchscreen", this.touchscreen);
|
|
accessor.process("bobView", this.bobView);
|
|
accessor.process("toggleCrouch", this.toggleCrouch);
|
|
accessor.process("toggleSprint", this.toggleSprint);
|
|
accessor.process("darkMojangStudiosBackground", this.darkMojangStudiosBackground);
|
|
accessor.process("hideLightningFlashes", this.hideLightningFlash);
|
|
accessor.process("hideSplashTexts", this.hideSplashTexts);
|
|
accessor.process("mouseSensitivity", this.sensitivity);
|
|
accessor.process("damageTiltStrength", this.damageTiltStrength);
|
|
accessor.process("highContrast", this.highContrast);
|
|
accessor.process("highContrastBlockOutline", this.highContrastBlockOutline);
|
|
accessor.process("narratorHotkey", this.narratorHotkey);
|
|
this.resourcePacks = accessor.process("resourcePacks", this.resourcePacks, Options::readListOfStrings, GSON::toJson);
|
|
this.incompatibleResourcePacks = accessor.process("incompatibleResourcePacks", this.incompatibleResourcePacks, Options::readListOfStrings, GSON::toJson);
|
|
this.lastMpIp = accessor.process("lastServer", this.lastMpIp);
|
|
this.languageCode = accessor.process("lang", this.languageCode);
|
|
accessor.process("chatVisibility", this.chatVisibility);
|
|
accessor.process("chatOpacity", this.chatOpacity);
|
|
accessor.process("chatLineSpacing", this.chatLineSpacing);
|
|
accessor.process("textBackgroundOpacity", this.textBackgroundOpacity);
|
|
accessor.process("backgroundForChatOnly", this.backgroundForChatOnly);
|
|
this.hideServerAddress = accessor.process("hideServerAddress", this.hideServerAddress);
|
|
this.advancedItemTooltips = accessor.process("advancedItemTooltips", this.advancedItemTooltips);
|
|
this.pauseOnLostFocus = accessor.process("pauseOnLostFocus", this.pauseOnLostFocus);
|
|
this.overrideWidth = accessor.process("overrideWidth", this.overrideWidth);
|
|
this.overrideHeight = accessor.process("overrideHeight", this.overrideHeight);
|
|
accessor.process("chatHeightFocused", this.chatHeightFocused);
|
|
accessor.process("chatDelay", this.chatDelay);
|
|
accessor.process("chatHeightUnfocused", this.chatHeightUnfocused);
|
|
accessor.process("chatScale", this.chatScale);
|
|
accessor.process("chatWidth", this.chatWidth);
|
|
accessor.process("notificationDisplayTime", this.notificationDisplayTime);
|
|
this.useNativeTransport = accessor.process("useNativeTransport", this.useNativeTransport);
|
|
accessor.process("mainHand", this.mainHand);
|
|
accessor.process("attackIndicator", this.attackIndicator);
|
|
this.tutorialStep = accessor.process("tutorialStep", this.tutorialStep, TutorialSteps::getByName, TutorialSteps::getName);
|
|
accessor.process("mouseWheelSensitivity", this.mouseWheelSensitivity);
|
|
accessor.process("rawMouseInput", this.rawMouseInput);
|
|
this.glDebugVerbosity = accessor.process("glDebugVerbosity", this.glDebugVerbosity);
|
|
this.skipMultiplayerWarning = accessor.process("skipMultiplayerWarning", this.skipMultiplayerWarning);
|
|
accessor.process("hideMatchedNames", this.hideMatchedNames);
|
|
this.joinedFirstServer = accessor.process("joinedFirstServer", this.joinedFirstServer);
|
|
this.syncWrites = accessor.process("syncChunkWrites", this.syncWrites);
|
|
accessor.process("showAutosaveIndicator", this.showAutosaveIndicator);
|
|
accessor.process("allowServerListing", this.allowServerListing);
|
|
accessor.process("onlyShowSecureChat", this.onlyShowSecureChat);
|
|
accessor.process("panoramaScrollSpeed", this.panoramaSpeed);
|
|
accessor.process("telemetryOptInExtra", this.telemetryOptInExtra);
|
|
this.onboardAccessibility = accessor.process("onboardAccessibility", this.onboardAccessibility);
|
|
accessor.process("menuBackgroundBlurriness", this.menuBackgroundBlurriness);
|
|
this.startedCleanly = accessor.process("startedCleanly", this.startedCleanly);
|
|
|
|
for (KeyMapping keyMapping : this.keyMappings) {
|
|
String string = keyMapping.saveString();
|
|
String string2 = accessor.process("key_" + keyMapping.getName(), string);
|
|
if (!string.equals(string2)) {
|
|
keyMapping.setKey(InputConstants.getKey(string2));
|
|
}
|
|
}
|
|
|
|
for (SoundSource soundSource : SoundSource.values()) {
|
|
accessor.process("soundCategory_" + soundSource.getName(), (OptionInstance)this.soundSourceVolumes.get(soundSource));
|
|
}
|
|
|
|
for (PlayerModelPart playerModelPart : PlayerModelPart.values()) {
|
|
boolean bl = this.modelParts.contains(playerModelPart);
|
|
boolean bl2 = accessor.process("modelPart_" + playerModelPart.getId(), bl);
|
|
if (bl2 != bl) {
|
|
this.setModelPart(playerModelPart, bl2);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads the options from the options file. It appears that this has replaced the previous 'loadOptions'
|
|
*/
|
|
public void load() {
|
|
try {
|
|
if (!this.optionsFile.exists()) {
|
|
return;
|
|
}
|
|
|
|
CompoundTag compoundTag = new CompoundTag();
|
|
BufferedReader bufferedReader = Files.newReader(this.optionsFile, Charsets.UTF_8);
|
|
|
|
try {
|
|
bufferedReader.lines().forEach(string -> {
|
|
try {
|
|
Iterator<String> iterator = OPTION_SPLITTER.split(string).iterator();
|
|
compoundTag.putString((String)iterator.next(), (String)iterator.next());
|
|
} catch (Exception var3x) {
|
|
LOGGER.warn("Skipping bad option: {}", string);
|
|
}
|
|
});
|
|
} catch (Throwable var6) {
|
|
if (bufferedReader != null) {
|
|
try {
|
|
bufferedReader.close();
|
|
} catch (Throwable var5) {
|
|
var6.addSuppressed(var5);
|
|
}
|
|
}
|
|
|
|
throw var6;
|
|
}
|
|
|
|
if (bufferedReader != null) {
|
|
bufferedReader.close();
|
|
}
|
|
|
|
final CompoundTag compoundTag2 = this.dataFix(compoundTag);
|
|
Optional<String> optional = compoundTag2.getString("fancyGraphics");
|
|
if (optional.isPresent() && !compoundTag2.contains("graphicsMode")) {
|
|
this.graphicsMode.set(isTrue((String)optional.get()) ? GraphicsStatus.FANCY : GraphicsStatus.FAST);
|
|
}
|
|
|
|
this.processOptions(
|
|
new Options.FieldAccess() {
|
|
@Nullable
|
|
private String getValue(String string) {
|
|
Tag tag = compoundTag2.get(string);
|
|
if (tag == null) {
|
|
return null;
|
|
} else if (tag instanceof StringTag(String var7x)) {
|
|
return var7x;
|
|
} else {
|
|
throw new IllegalStateException("Cannot read field of wrong type, expected string: " + tag);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public <T> void process(String name, OptionInstance<T> value) {
|
|
String string = this.getValue(name);
|
|
if (string != null) {
|
|
JsonReader jsonReader = new JsonReader(new StringReader(string.isEmpty() ? "\"\"" : string));
|
|
JsonElement jsonElement = JsonParser.parseReader(jsonReader);
|
|
value.codec()
|
|
.parse(JsonOps.INSTANCE, jsonElement)
|
|
.ifError(error -> Options.LOGGER.error("Error parsing option value {} for option {}: {}", string, value, error.message()))
|
|
.ifSuccess(value::set);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int process(String name, int value) {
|
|
String string = this.getValue(name);
|
|
if (string != null) {
|
|
try {
|
|
return Integer.parseInt(string);
|
|
} catch (NumberFormatException var5) {
|
|
Options.LOGGER.warn("Invalid integer value for option {} = {}", name, string, var5);
|
|
}
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public boolean process(String name, boolean value) {
|
|
String string = this.getValue(name);
|
|
return string != null ? Options.isTrue(string) : value;
|
|
}
|
|
|
|
@Override
|
|
public String process(String name, String value) {
|
|
return MoreObjects.firstNonNull(this.getValue(name), value);
|
|
}
|
|
|
|
@Override
|
|
public float process(String name, float value) {
|
|
String string = this.getValue(name);
|
|
if (string == null) {
|
|
return value;
|
|
} else if (Options.isTrue(string)) {
|
|
return 1.0F;
|
|
} else if (Options.isFalse(string)) {
|
|
return 0.0F;
|
|
} else {
|
|
try {
|
|
return Float.parseFloat(string);
|
|
} catch (NumberFormatException var5) {
|
|
Options.LOGGER.warn("Invalid floating point value for option {} = {}", name, string, var5);
|
|
return value;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public <T> T process(String name, T value, Function<String, T> stringValuefier, Function<T, String> valueStringifier) {
|
|
String string = this.getValue(name);
|
|
return (T)(string == null ? value : stringValuefier.apply(string));
|
|
}
|
|
}
|
|
);
|
|
compoundTag2.getString("fullscreenResolution").ifPresent(string -> this.fullscreenVideoModeString = string);
|
|
KeyMapping.resetMapping();
|
|
} catch (Exception var7) {
|
|
LOGGER.error("Failed to load options", (Throwable)var7);
|
|
}
|
|
}
|
|
|
|
static boolean isTrue(String value) {
|
|
return "true".equals(value);
|
|
}
|
|
|
|
static boolean isFalse(String value) {
|
|
return "false".equals(value);
|
|
}
|
|
|
|
private CompoundTag dataFix(CompoundTag nbt) {
|
|
int i = 0;
|
|
|
|
try {
|
|
i = (Integer)nbt.getString("version").map(Integer::parseInt).orElse(0);
|
|
} catch (RuntimeException var4) {
|
|
}
|
|
|
|
return DataFixTypes.OPTIONS.updateToCurrentVersion(this.minecraft.getFixerUpper(), nbt, i);
|
|
}
|
|
|
|
/**
|
|
* Saves the options to the options file.
|
|
*/
|
|
public void save() {
|
|
try {
|
|
final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(this.optionsFile), StandardCharsets.UTF_8));
|
|
|
|
try {
|
|
printWriter.println("version:" + SharedConstants.getCurrentVersion().getDataVersion().getVersion());
|
|
this.processOptions(
|
|
new Options.FieldAccess() {
|
|
public void writePrefix(String prefix) {
|
|
printWriter.print(prefix);
|
|
printWriter.print(':');
|
|
}
|
|
|
|
@Override
|
|
public <T> void process(String name, OptionInstance<T> value) {
|
|
value.codec()
|
|
.encodeStart(JsonOps.INSTANCE, value.get())
|
|
.ifError(error -> Options.LOGGER.error("Error saving option " + value + ": " + error))
|
|
.ifSuccess(jsonElement -> {
|
|
this.writePrefix(name);
|
|
printWriter.println(Options.GSON.toJson(jsonElement));
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public int process(String name, int value) {
|
|
this.writePrefix(name);
|
|
printWriter.println(value);
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public boolean process(String name, boolean value) {
|
|
this.writePrefix(name);
|
|
printWriter.println(value);
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public String process(String name, String value) {
|
|
this.writePrefix(name);
|
|
printWriter.println(value);
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public float process(String name, float value) {
|
|
this.writePrefix(name);
|
|
printWriter.println(value);
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public <T> T process(String name, T value, Function<String, T> stringValuefier, Function<T, String> valueStringifier) {
|
|
this.writePrefix(name);
|
|
printWriter.println((String)valueStringifier.apply(value));
|
|
return value;
|
|
}
|
|
}
|
|
);
|
|
String string = this.getFullscreenVideoModeString();
|
|
if (string != null) {
|
|
printWriter.println("fullscreenResolution:" + string);
|
|
}
|
|
} catch (Throwable var5) {
|
|
try {
|
|
printWriter.close();
|
|
} catch (Throwable var4) {
|
|
var5.addSuppressed(var4);
|
|
}
|
|
|
|
throw var5;
|
|
}
|
|
|
|
printWriter.close();
|
|
} catch (Exception var6) {
|
|
LOGGER.error("Failed to save options", (Throwable)var6);
|
|
}
|
|
|
|
this.broadcastOptions();
|
|
}
|
|
|
|
@Nullable
|
|
private String getFullscreenVideoModeString() {
|
|
Window window = this.minecraft.getWindow();
|
|
if (window == null) {
|
|
return this.fullscreenVideoModeString;
|
|
} else {
|
|
return window.getPreferredFullscreenVideoMode().isPresent() ? ((VideoMode)window.getPreferredFullscreenVideoMode().get()).write() : null;
|
|
}
|
|
}
|
|
|
|
public ClientInformation buildPlayerInformation() {
|
|
int i = 0;
|
|
|
|
for (PlayerModelPart playerModelPart : this.modelParts) {
|
|
i |= playerModelPart.getMask();
|
|
}
|
|
|
|
return new ClientInformation(
|
|
this.languageCode,
|
|
this.renderDistance.get(),
|
|
this.chatVisibility.get(),
|
|
this.chatColors.get(),
|
|
i,
|
|
this.mainHand.get(),
|
|
this.minecraft.isTextFilteringEnabled(),
|
|
this.allowServerListing.get(),
|
|
this.particles.get()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Send a client info packet with settings information to the server
|
|
*/
|
|
public void broadcastOptions() {
|
|
if (this.minecraft.player != null) {
|
|
this.minecraft.player.connection.broadcastClientInformation(this.buildPlayerInformation());
|
|
}
|
|
}
|
|
|
|
public void setModelPart(PlayerModelPart modelPart, boolean enable) {
|
|
if (enable) {
|
|
this.modelParts.add(modelPart);
|
|
} else {
|
|
this.modelParts.remove(modelPart);
|
|
}
|
|
}
|
|
|
|
public boolean isModelPartEnabled(PlayerModelPart playerModelPart) {
|
|
return this.modelParts.contains(playerModelPart);
|
|
}
|
|
|
|
public CloudStatus getCloudsType() {
|
|
return this.getEffectiveRenderDistance() >= 4 ? this.cloudStatus.get() : CloudStatus.OFF;
|
|
}
|
|
|
|
/**
|
|
* Returns {@code true} if the client connect to a server using the native transport system.
|
|
*/
|
|
public boolean useNativeTransport() {
|
|
return this.useNativeTransport;
|
|
}
|
|
|
|
public void loadSelectedResourcePacks(PackRepository resourcePackList) {
|
|
Set<String> set = Sets.<String>newLinkedHashSet();
|
|
Iterator<String> iterator = this.resourcePacks.iterator();
|
|
|
|
while (iterator.hasNext()) {
|
|
String string = (String)iterator.next();
|
|
Pack pack = resourcePackList.getPack(string);
|
|
if (pack == null && !string.startsWith("file/")) {
|
|
pack = resourcePackList.getPack("file/" + string);
|
|
}
|
|
|
|
if (pack == null) {
|
|
LOGGER.warn("Removed resource pack {} from options because it doesn't seem to exist anymore", string);
|
|
iterator.remove();
|
|
} else if (!pack.getCompatibility().isCompatible() && !this.incompatibleResourcePacks.contains(string)) {
|
|
LOGGER.warn("Removed resource pack {} from options because it is no longer compatible", string);
|
|
iterator.remove();
|
|
} else if (pack.getCompatibility().isCompatible() && this.incompatibleResourcePacks.contains(string)) {
|
|
LOGGER.info("Removed resource pack {} from incompatibility list because it's now compatible", string);
|
|
this.incompatibleResourcePacks.remove(string);
|
|
} else {
|
|
set.add(pack.getId());
|
|
}
|
|
}
|
|
|
|
resourcePackList.setSelected(set);
|
|
}
|
|
|
|
public CameraType getCameraType() {
|
|
return this.cameraType;
|
|
}
|
|
|
|
public void setCameraType(CameraType pointOfView) {
|
|
this.cameraType = pointOfView;
|
|
}
|
|
|
|
private static List<String> readListOfStrings(String json) {
|
|
List<String> list = GsonHelper.fromNullableJson(GSON, json, LIST_OF_STRINGS_TYPE);
|
|
return (List<String>)(list != null ? list : Lists.<String>newArrayList());
|
|
}
|
|
|
|
public File getFile() {
|
|
return this.optionsFile;
|
|
}
|
|
|
|
public String dumpOptionsForReport() {
|
|
final List<Pair<String, Object>> list = new ArrayList();
|
|
this.processDumpedOptions(new Options.OptionAccess() {
|
|
@Override
|
|
public <T> void process(String name, OptionInstance<T> value) {
|
|
list.add(Pair.of(name, value.get()));
|
|
}
|
|
});
|
|
list.add(Pair.of("fullscreenResolution", String.valueOf(this.fullscreenVideoModeString)));
|
|
list.add(Pair.of("glDebugVerbosity", this.glDebugVerbosity));
|
|
list.add(Pair.of("overrideHeight", this.overrideHeight));
|
|
list.add(Pair.of("overrideWidth", this.overrideWidth));
|
|
list.add(Pair.of("syncChunkWrites", this.syncWrites));
|
|
list.add(Pair.of("useNativeTransport", this.useNativeTransport));
|
|
list.add(Pair.of("resourcePacks", this.resourcePacks));
|
|
return (String)list.stream()
|
|
.sorted(Comparator.comparing(Pair::getFirst))
|
|
.map(pair -> (String)pair.getFirst() + ": " + pair.getSecond())
|
|
.collect(Collectors.joining(System.lineSeparator()));
|
|
}
|
|
|
|
public void setServerRenderDistance(int serverRenderDistance) {
|
|
this.serverRenderDistance = serverRenderDistance;
|
|
}
|
|
|
|
public int getEffectiveRenderDistance() {
|
|
return this.serverRenderDistance > 0 ? Math.min(this.renderDistance.get(), this.serverRenderDistance) : this.renderDistance.get();
|
|
}
|
|
|
|
private static Component pixelValueLabel(Component text, int value) {
|
|
return Component.translatable("options.pixel_value", text, value);
|
|
}
|
|
|
|
private static Component percentValueLabel(Component text, double value) {
|
|
return Component.translatable("options.percent_value", text, (int)(value * 100.0));
|
|
}
|
|
|
|
public static Component genericValueLabel(Component text, Component value) {
|
|
return Component.translatable("options.generic_value", text, value);
|
|
}
|
|
|
|
public static Component genericValueLabel(Component text, int value) {
|
|
return genericValueLabel(text, Component.literal(Integer.toString(value)));
|
|
}
|
|
|
|
public static Component genericValueOrOffLabel(Component text, int value) {
|
|
return value == 0 ? genericValueLabel(text, CommonComponents.OPTION_OFF) : genericValueLabel(text, value);
|
|
}
|
|
|
|
private static Component percentValueOrOffLabel(Component text, double value) {
|
|
return value == 0.0 ? genericValueLabel(text, CommonComponents.OPTION_OFF) : percentValueLabel(text, value);
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
interface FieldAccess extends Options.OptionAccess {
|
|
int process(String name, int value);
|
|
|
|
boolean process(String name, boolean value);
|
|
|
|
String process(String name, String value);
|
|
|
|
float process(String name, float value);
|
|
|
|
<T> T process(String name, T value, Function<String, T> stringValuefier, Function<T, String> valueStringifier);
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
interface OptionAccess {
|
|
<T> void process(String name, OptionInstance<T> value);
|
|
}
|
|
}
|