minecraft-src/net/minecraft/server/dedicated/Settings.java
2025-07-04 01:41:11 +03:00

256 lines
7.4 KiB
Java

package net.minecraft.server.dedicated;
import com.google.common.base.MoreObjects;
import com.mojang.logging.LogUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Properties;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import net.minecraft.core.RegistryAccess;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
public abstract class Settings<T extends Settings<T>> {
private static final Logger LOGGER = LogUtils.getLogger();
protected final Properties properties;
public Settings(Properties properties) {
this.properties = properties;
}
public static Properties loadFromFile(Path path) {
try {
try {
InputStream inputStream = Files.newInputStream(path);
Properties var13;
try {
CharsetDecoder charsetDecoder = StandardCharsets.UTF_8
.newDecoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
Properties properties = new Properties();
properties.load(new InputStreamReader(inputStream, charsetDecoder));
var13 = properties;
} catch (Throwable var8) {
if (inputStream != null) {
try {
inputStream.close();
} catch (Throwable var6) {
var8.addSuppressed(var6);
}
}
throw var8;
}
if (inputStream != null) {
inputStream.close();
}
return var13;
} catch (CharacterCodingException var9) {
LOGGER.info("Failed to load properties as UTF-8 from file {}, trying ISO_8859_1", path);
Reader reader = Files.newBufferedReader(path, StandardCharsets.ISO_8859_1);
Properties var4;
try {
Properties properties = new Properties();
properties.load(reader);
var4 = properties;
} catch (Throwable var7) {
if (reader != null) {
try {
reader.close();
} catch (Throwable var5) {
var7.addSuppressed(var5);
}
}
throw var7;
}
if (reader != null) {
reader.close();
}
return var4;
}
} catch (IOException var10) {
LOGGER.error("Failed to load properties from file: {}", path, var10);
return new Properties();
}
}
public void store(Path path) {
try {
Writer writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8);
try {
this.properties.store(writer, "Minecraft server properties");
} catch (Throwable var6) {
if (writer != null) {
try {
writer.close();
} catch (Throwable var5) {
var6.addSuppressed(var5);
}
}
throw var6;
}
if (writer != null) {
writer.close();
}
} catch (IOException var7) {
LOGGER.error("Failed to store properties to file: {}", path);
}
}
private static <V extends Number> Function<String, V> wrapNumberDeserializer(Function<String, V> parseFunc) {
return string -> {
try {
return (Number)parseFunc.apply(string);
} catch (NumberFormatException var3) {
return null;
}
};
}
protected static <V> Function<String, V> dispatchNumberOrString(IntFunction<V> byId, Function<String, V> byName) {
return string -> {
try {
return byId.apply(Integer.parseInt(string));
} catch (NumberFormatException var4) {
return byName.apply(string);
}
};
}
@Nullable
private String getStringRaw(String key) {
return (String)this.properties.get(key);
}
@Nullable
protected <V> V getLegacy(String key, Function<String, V> serializer) {
String string = this.getStringRaw(key);
if (string == null) {
return null;
} else {
this.properties.remove(key);
return (V)serializer.apply(string);
}
}
protected <V> V get(String key, Function<String, V> serializer, Function<V, String> deserializer, V defaultValue) {
String string = this.getStringRaw(key);
V object = MoreObjects.firstNonNull((V)(string != null ? serializer.apply(string) : null), defaultValue);
this.properties.put(key, deserializer.apply(object));
return object;
}
protected <V> Settings<T>.MutableValue<V> getMutable(String key, Function<String, V> serializer, Function<V, String> deserializer, V defaultValue) {
String string = this.getStringRaw(key);
V object = MoreObjects.firstNonNull((V)(string != null ? serializer.apply(string) : null), defaultValue);
this.properties.put(key, deserializer.apply(object));
return new Settings.MutableValue<>(key, object, deserializer);
}
protected <V> V get(String key, Function<String, V> serializer, UnaryOperator<V> modifier, Function<V, String> deserializer, V defaultValue) {
return this.get(key, string -> {
V object = (V)serializer.apply(string);
return object != null ? modifier.apply(object) : null;
}, deserializer, defaultValue);
}
protected <V> V get(String key, Function<String, V> mapper, V value) {
return this.get(key, mapper, Objects::toString, value);
}
protected <V> Settings<T>.MutableValue<V> getMutable(String key, Function<String, V> serializer, V defaultValue) {
return this.getMutable(key, serializer, Objects::toString, defaultValue);
}
protected String get(String key, String defaultValue) {
return this.get(key, Function.identity(), Function.identity(), defaultValue);
}
@Nullable
protected String getLegacyString(String key) {
return this.getLegacy(key, Function.identity());
}
protected int get(String key, int defaultValue) {
return this.get(key, wrapNumberDeserializer(Integer::parseInt), Integer.valueOf(defaultValue));
}
protected Settings<T>.MutableValue<Integer> getMutable(String key, int defaultValue) {
return this.getMutable(key, wrapNumberDeserializer(Integer::parseInt), defaultValue);
}
protected int get(String key, UnaryOperator<Integer> modifier, int defaultValue) {
return this.get(key, wrapNumberDeserializer(Integer::parseInt), modifier, Objects::toString, defaultValue);
}
protected long get(String key, long defaultValue) {
return this.get(key, wrapNumberDeserializer(Long::parseLong), defaultValue);
}
protected boolean get(String key, boolean defaultValue) {
return this.get(key, Boolean::valueOf, defaultValue);
}
protected Settings<T>.MutableValue<Boolean> getMutable(String key, boolean defaultValue) {
return this.getMutable(key, Boolean::valueOf, defaultValue);
}
@Nullable
protected Boolean getLegacyBoolean(String key) {
return this.getLegacy(key, Boolean::valueOf);
}
protected Properties cloneProperties() {
Properties properties = new Properties();
properties.putAll(this.properties);
return properties;
}
protected abstract T reload(RegistryAccess registryAccess, Properties properties);
public class MutableValue<V> implements Supplier<V> {
private final String key;
private final V value;
private final Function<V, String> serializer;
MutableValue(final String key, final V value, final Function<V, String> serializer) {
this.key = key;
this.value = value;
this.serializer = serializer;
}
public V get() {
return this.value;
}
public T update(RegistryAccess registryAccess, V newValue) {
Properties properties = Settings.this.cloneProperties();
properties.put(this.key, this.serializer.apply(newValue));
return Settings.this.reload(registryAccess, properties);
}
}
}