minecraft-source/src/net/minecraft/Util.java

398 lines
14 KiB
Java

package net.minecraft;
import java.net.URISyntaxException;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.io.IOException;
import java.security.PrivilegedActionException;
import org.apache.commons.io.IOUtils;
import java.security.AccessController;
import java.net.URL;
import org.apache.logging.log4j.LogManager;
import java.util.UUID;
import com.mojang.datafixers.Dynamic;
import com.mojang.datafixers.DataFixUtils;
import java.util.Optional;
import java.util.concurrent.CompletionStage;
import com.google.common.collect.Lists;
import it.unimi.dsi.fastutil.Hash;
import java.util.function.Consumer;
import java.util.function.Supplier;
import com.google.common.collect.Iterators;
import java.util.Iterator;
import java.util.List;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ManagementFactory;
import java.util.stream.Stream;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executor;
import net.minecraft.server.Bootstrap;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import com.google.common.util.concurrent.MoreExecutors;
import net.minecraft.util.Mth;
import java.time.Instant;
import javax.annotation.Nullable;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.state.properties.Property;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.Map;
import java.util.stream.Collector;
import org.apache.logging.log4j.Logger;
import java.util.function.LongSupplier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
public class Util {
private static final AtomicInteger WORKER_COUNT;
private static final ExecutorService BACKGROUND_EXECUTOR;
public static LongSupplier timeSource;
private static final Logger LOGGER;
public static <K, V> Collector<Map.Entry<? extends K, ? extends V>, ?, Map<K, V>> toMap() {
return Collectors.<Map.Entry<? extends K, ? extends V>, K, V>toMap(Map.Entry::getKey, Map.Entry::getValue);
}
public static <T extends Comparable<T>> String getPropertyName(final Property<T> bzm, final Object object) {
return bzm.getName((T)object);
}
public static String makeDescriptionId(final String string, @Nullable final ResourceLocation sm) {
if (sm == null) {
return string + ".unregistered_sadface";
}
return string + '.' + sm.getNamespace() + '.' + sm.getPath().replace('/', '.');
}
public static long getMillis() {
return getNanos() / 1000000L;
}
public static long getNanos() {
return Util.timeSource.getAsLong();
}
public static long getEpochMillis() {
return Instant.now().toEpochMilli();
}
private static ExecutorService makeBackgroundExecutor() {
final int integer1 = Mth.clamp(Runtime.getRuntime().availableProcessors() - 1, 1, 7);
ExecutorService executorService2;
if (integer1 <= 0) {
executorService2 = MoreExecutors.newDirectExecutorService();
}
else {
final ForkJoinWorkerThread forkJoinWorkerThread2;
executorService2 = new ForkJoinPool(integer1, forkJoinPool -> {
forkJoinWorkerThread2 = new ForkJoinWorkerThread(forkJoinPool) {
@Override
protected void onTermination(final Throwable throwable) {
if (throwable != null) {
Util.LOGGER.warn("{} died", this.getName(), throwable);
}
else {
Util.LOGGER.debug("{} shutdown", this.getName());
}
super.onTermination(throwable);
}
};
forkJoinWorkerThread2.setName("Server-Worker-" + Util.WORKER_COUNT.getAndIncrement());
return forkJoinWorkerThread2;
}, (thread, throwable) -> {
Util.<ReportedException>pauseInIde(throwable);
if (throwable instanceof CompletionException) {
throwable = (ReportedException)throwable.getCause();
}
if (throwable instanceof ReportedException) {
Bootstrap.realStdoutPrintln(throwable.getReport().getFriendlyReport());
System.exit(-1);
}
Util.LOGGER.error(String.format("Caught exception in thread %s", thread), (Throwable)throwable);
return;
}, true);
}
return executorService2;
}
public static Executor backgroundExecutor() {
return Util.BACKGROUND_EXECUTOR;
}
public static void shutdownBackgroundExecutor() {
Util.BACKGROUND_EXECUTOR.shutdown();
boolean boolean1;
try {
boolean1 = Util.BACKGROUND_EXECUTOR.awaitTermination(3L, TimeUnit.SECONDS);
}
catch (InterruptedException interruptedException2) {
boolean1 = false;
}
if (!boolean1) {
Util.BACKGROUND_EXECUTOR.shutdownNow();
}
}
public static <T> CompletableFuture<T> failedFuture(final Throwable throwable) {
final CompletableFuture<T> completableFuture2 = new CompletableFuture<T>();
completableFuture2.completeExceptionally(throwable);
return completableFuture2;
}
public static void throwAsRuntime(final Throwable throwable) {
throw (throwable instanceof RuntimeException) ? throwable : new RuntimeException(throwable);
}
public static OS getPlatform() {
final String string1 = System.getProperty("os.name").toLowerCase(Locale.ROOT);
if (string1.contains("win")) {
return OS.WINDOWS;
}
if (string1.contains("mac")) {
return OS.OSX;
}
if (string1.contains("solaris")) {
return OS.SOLARIS;
}
if (string1.contains("sunos")) {
return OS.SOLARIS;
}
if (string1.contains("linux")) {
return OS.LINUX;
}
if (string1.contains("unix")) {
return OS.LINUX;
}
return OS.UNKNOWN;
}
public static Stream<String> getVmArguments() {
final RuntimeMXBean runtimeMXBean1 = ManagementFactory.getRuntimeMXBean();
return runtimeMXBean1.getInputArguments().stream().filter(string -> string.startsWith("-X"));
}
public static <T> T lastOf(final List<T> list) {
return list.get(list.size() - 1);
}
public static <T> T findNextInIterable(final Iterable<T> iterable, @Nullable final T object) {
final Iterator<T> iterator3 = iterable.iterator();
final T object2 = iterator3.next();
if (object != null) {
for (T object3 = object2; object3 != object; object3 = iterator3.next()) {
if (iterator3.hasNext()) {}
}
if (iterator3.hasNext()) {
return iterator3.next();
}
}
return object2;
}
public static <T> T findPreviousInIterable(final Iterable<T> iterable, @Nullable final T object) {
final Iterator<T> iterator3 = iterable.iterator();
T object2 = null;
while (iterator3.hasNext()) {
final T object3 = iterator3.next();
if (object3 == object) {
if (object2 == null) {
object2 = (iterator3.hasNext() ? Iterators.<T>getLast(iterator3) : object);
break;
}
break;
}
else {
object2 = object3;
}
}
return object2;
}
public static <T> T make(final Supplier<T> supplier) {
return supplier.get();
}
public static <T> T make(final T object, final Consumer<T> consumer) {
consumer.accept(object);
return object;
}
public static <K> Hash.Strategy<K> identityStrategy() {
return (Hash.Strategy<K>)IdentityStrategy.INSTANCE;
}
public static <V> CompletableFuture<List<V>> sequence(final List<? extends CompletableFuture<? extends V>> list) {
final List<V> list2 = Lists.newArrayListWithCapacity(list.size());
final CompletableFuture<?>[] arr3 = new CompletableFuture[list.size()];
final CompletableFuture<Void> completableFuture5 = new CompletableFuture<Void>();
final List<Object> list3;
final int integer5;
final Object o;
final CompletableFuture completableFuture6;
final List<Object> list4;
final int n;
list.forEach(completableFuture4 -> {
integer5 = list3.size();
list3.add(null);
o[integer5] = completableFuture4.whenComplete((object, throwable) -> {
if (throwable != null) {
completableFuture6.completeExceptionally(throwable);
}
else {
list4.set(n, object);
}
});
return;
});
return CompletableFuture.allOf(arr3).<List<V>>applyToEither(completableFuture5, void2 -> list2);
}
public static <T> Stream<T> toStream(final Optional<? extends T> optional) {
return (Stream<T>)DataFixUtils.orElseGet((Optional)optional.map(Stream::of), (Supplier)Stream::empty);
}
public static <T> Optional<T> ifElse(final Optional<T> optional, final Consumer<T> consumer, final Runnable runnable) {
if (optional.isPresent()) {
consumer.accept(optional.get());
}
else {
runnable.run();
}
return optional;
}
public static Runnable name(final Runnable runnable, final Supplier<String> supplier) {
return runnable;
}
public static Optional<UUID> readUUID(final String string, final Dynamic<?> dynamic) {
return dynamic.get(string + "Most").asNumber().<UUID>flatMap(number -> dynamic.get(string + "Least").asNumber().map(number2 -> new UUID(number.longValue(), number2.longValue())));
}
public static <T> Dynamic<T> writeUUID(final String string, final UUID uUID, final Dynamic<T> dynamic) {
return (Dynamic<T>)dynamic.set(string + "Most", dynamic.createLong(uUID.getMostSignificantBits())).set(string + "Least", dynamic.createLong(uUID.getLeastSignificantBits()));
}
public static <T extends Throwable> T pauseInIde(final T throwable) {
if (SharedConstants.IS_RUNNING_IN_IDE) {
Util.LOGGER.error("Trying to throw a fatal exception, pausing in IDE", (Throwable)throwable);
try {
while (true) {
Thread.sleep(1000L);
Util.LOGGER.error("paused");
}
}
catch (InterruptedException interruptedException2) {
return throwable;
}
}
return throwable;
}
public static String describeError(final Throwable throwable) {
if (throwable.getCause() != null) {
return describeError(throwable.getCause());
}
if (throwable.getMessage() != null) {
return throwable.getMessage();
}
return throwable.toString();
}
static {
WORKER_COUNT = new AtomicInteger(1);
BACKGROUND_EXECUTOR = makeBackgroundExecutor();
Util.timeSource = System::nanoTime;
LOGGER = LogManager.getLogger();
}
public enum OS {
LINUX,
SOLARIS,
WINDOWS {
@Override
protected String[] getOpenUrlArguments(final URL uRL) {
return new String[] { "rundll32", "url.dll,FileProtocolHandler", uRL.toString() };
}
},
OSX {
@Override
protected String[] getOpenUrlArguments(final URL uRL) {
return new String[] { "open", uRL.toString() };
}
},
UNKNOWN;
public void openUrl(final URL uRL) {
try {
final Process process3 = AccessController.<Process>doPrivileged(() -> Runtime.getRuntime().exec(this.getOpenUrlArguments(uRL)));
for (final String string5 : IOUtils.readLines(process3.getErrorStream())) {
Util.LOGGER.error(string5);
}
process3.getInputStream().close();
process3.getErrorStream().close();
process3.getOutputStream().close();
}
catch (PrivilegedActionException | IOException ex2) {
final Exception ex;
final Exception exception3 = ex;
Util.LOGGER.error("Couldn't open url '{}'", uRL, exception3);
}
}
public void openUri(final URI uRI) {
try {
this.openUrl(uRI.toURL());
}
catch (MalformedURLException malformedURLException3) {
Util.LOGGER.error("Couldn't open uri '{}'", uRI, malformedURLException3);
}
}
public void openFile(final File file) {
try {
this.openUrl(file.toURI().toURL());
}
catch (MalformedURLException malformedURLException3) {
Util.LOGGER.error("Couldn't open file '{}'", file, malformedURLException3);
}
}
protected String[] getOpenUrlArguments(final URL uRL) {
String string3 = uRL.toString();
if ("file".equals(uRL.getProtocol())) {
string3 = string3.replace("file:", "file://");
}
return new String[] { "xdg-open", string3 };
}
public void openUri(final String string) {
try {
this.openUrl(new URI(string).toURL());
}
catch (URISyntaxException | MalformedURLException | IllegalArgumentException ex2) {
final Exception ex;
final Exception exception3 = ex;
Util.LOGGER.error("Couldn't open uri '{}'", string, exception3);
}
}
}
enum IdentityStrategy implements Hash.Strategy<Object> {
INSTANCE;
public int hashCode(final Object object) {
return System.identityHashCode(object);
}
public boolean equals(final Object object1, final Object object2) {
return object1 == object2;
}
}
}