trurwsuieghfdskg
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package com.mojang.realmsclient;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class KeyCombo {
|
||||
private final char[] chars;
|
||||
private int matchIndex;
|
||||
private final Runnable onCompletion;
|
||||
|
||||
public KeyCombo(char[] p_86225_, Runnable p_86226_) {
|
||||
this.onCompletion = p_86226_;
|
||||
if (p_86225_.length < 1) {
|
||||
throw new IllegalArgumentException("Must have at least one char");
|
||||
} else {
|
||||
this.chars = p_86225_;
|
||||
}
|
||||
}
|
||||
|
||||
public KeyCombo(char[] p_167171_) {
|
||||
this(p_167171_, () -> {
|
||||
});
|
||||
}
|
||||
|
||||
public boolean keyPressed(char p_86229_) {
|
||||
if (p_86229_ == this.chars[this.matchIndex++]) {
|
||||
if (this.matchIndex == this.chars.length) {
|
||||
this.reset();
|
||||
this.onCompletion.run();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.matchIndex = 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "KeyCombo{chars=" + Arrays.toString(this.chars) + ", matchIndex=" + this.matchIndex + "}";
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
||||
package com.mojang.realmsclient;
|
||||
|
||||
import java.util.Locale;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum Unit {
|
||||
B,
|
||||
KB,
|
||||
MB,
|
||||
GB;
|
||||
|
||||
private static final int BASE_UNIT = 1024;
|
||||
|
||||
public static Unit getLargest(long p_86941_) {
|
||||
if (p_86941_ < 1024L) {
|
||||
return B;
|
||||
} else {
|
||||
try {
|
||||
int i = (int)(Math.log((double)p_86941_) / Math.log(1024.0D));
|
||||
String s = String.valueOf("KMGTPE".charAt(i - 1));
|
||||
return valueOf(s + "B");
|
||||
} catch (Exception exception) {
|
||||
return GB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static double convertTo(long p_86943_, Unit p_86944_) {
|
||||
return p_86944_ == B ? (double)p_86943_ : (double)p_86943_ / Math.pow(1024.0D, (double)p_86944_.ordinal());
|
||||
}
|
||||
|
||||
public static String humanReadable(long p_86946_) {
|
||||
int i = 1024;
|
||||
if (p_86946_ < 1024L) {
|
||||
return p_86946_ + " B";
|
||||
} else {
|
||||
int j = (int)(Math.log((double)p_86946_) / Math.log(1024.0D));
|
||||
String s = "" + "KMGTPE".charAt(j - 1);
|
||||
return String.format(Locale.ROOT, "%.1f %sB", (double)p_86946_ / Math.pow(1024.0D, (double)j), s);
|
||||
}
|
||||
}
|
||||
|
||||
public static String humanReadable(long p_86948_, Unit p_86949_) {
|
||||
return String.format(Locale.ROOT, "%." + (p_86949_ == GB ? "1" : "0") + "f %s", convertTo(p_86948_, p_86949_), p_86949_.name());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.Files;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.dto.WorldDownload;
|
||||
import com.mojang.realmsclient.exception.RealmsDefaultUncaughtExceptionHandler;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsDownloadLatestWorldScreen;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.world.level.storage.LevelResource;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.validation.ContentValidationException;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.output.CountingOutputStream;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class FileDownload {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
volatile boolean cancelled;
|
||||
volatile boolean finished;
|
||||
volatile boolean error;
|
||||
volatile boolean extracting;
|
||||
@Nullable
|
||||
private volatile File tempFile;
|
||||
volatile File resourcePackPath;
|
||||
@Nullable
|
||||
private volatile HttpGet request;
|
||||
@Nullable
|
||||
private Thread currentThread;
|
||||
private final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(120000).build();
|
||||
private static final String[] INVALID_FILE_NAMES = new String[]{"CON", "COM", "PRN", "AUX", "CLOCK$", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"};
|
||||
|
||||
public long contentLength(String p_86990_) {
|
||||
CloseableHttpClient closeablehttpclient = null;
|
||||
HttpGet httpget = null;
|
||||
|
||||
long i;
|
||||
try {
|
||||
httpget = new HttpGet(p_86990_);
|
||||
closeablehttpclient = HttpClientBuilder.create().setDefaultRequestConfig(this.requestConfig).build();
|
||||
CloseableHttpResponse closeablehttpresponse = closeablehttpclient.execute(httpget);
|
||||
return Long.parseLong(closeablehttpresponse.getFirstHeader("Content-Length").getValue());
|
||||
} catch (Throwable throwable) {
|
||||
LOGGER.error("Unable to get content length for download");
|
||||
i = 0L;
|
||||
} finally {
|
||||
if (httpget != null) {
|
||||
httpget.releaseConnection();
|
||||
}
|
||||
|
||||
if (closeablehttpclient != null) {
|
||||
try {
|
||||
closeablehttpclient.close();
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Could not close http client", (Throwable)ioexception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public void download(WorldDownload p_86983_, String p_86984_, RealmsDownloadLatestWorldScreen.DownloadStatus p_86985_, LevelStorageSource p_86986_) {
|
||||
if (this.currentThread == null) {
|
||||
this.currentThread = new Thread(() -> {
|
||||
CloseableHttpClient closeablehttpclient = null;
|
||||
|
||||
try {
|
||||
this.tempFile = File.createTempFile("backup", ".tar.gz");
|
||||
this.request = new HttpGet(p_86983_.downloadLink);
|
||||
closeablehttpclient = HttpClientBuilder.create().setDefaultRequestConfig(this.requestConfig).build();
|
||||
HttpResponse httpresponse = closeablehttpclient.execute(this.request);
|
||||
p_86985_.totalBytes = Long.parseLong(httpresponse.getFirstHeader("Content-Length").getValue());
|
||||
if (httpresponse.getStatusLine().getStatusCode() == 200) {
|
||||
OutputStream outputstream = new FileOutputStream(this.tempFile);
|
||||
FileDownload.ProgressListener filedownload$progresslistener = new FileDownload.ProgressListener(p_86984_.trim(), this.tempFile, p_86986_, p_86985_);
|
||||
FileDownload.DownloadCountingOutputStream filedownload$downloadcountingoutputstream = new FileDownload.DownloadCountingOutputStream(outputstream);
|
||||
filedownload$downloadcountingoutputstream.setListener(filedownload$progresslistener);
|
||||
IOUtils.copy(httpresponse.getEntity().getContent(), filedownload$downloadcountingoutputstream);
|
||||
return;
|
||||
}
|
||||
|
||||
this.error = true;
|
||||
this.request.abort();
|
||||
} catch (Exception exception1) {
|
||||
LOGGER.error("Caught exception while downloading: {}", (Object)exception1.getMessage());
|
||||
this.error = true;
|
||||
return;
|
||||
} finally {
|
||||
this.request.releaseConnection();
|
||||
if (this.tempFile != null) {
|
||||
this.tempFile.delete();
|
||||
}
|
||||
|
||||
if (!this.error) {
|
||||
if (!p_86983_.resourcePackUrl.isEmpty() && !p_86983_.resourcePackHash.isEmpty()) {
|
||||
try {
|
||||
this.tempFile = File.createTempFile("resources", ".tar.gz");
|
||||
this.request = new HttpGet(p_86983_.resourcePackUrl);
|
||||
HttpResponse httpresponse1 = closeablehttpclient.execute(this.request);
|
||||
p_86985_.totalBytes = Long.parseLong(httpresponse1.getFirstHeader("Content-Length").getValue());
|
||||
if (httpresponse1.getStatusLine().getStatusCode() != 200) {
|
||||
this.error = true;
|
||||
this.request.abort();
|
||||
return;
|
||||
}
|
||||
|
||||
OutputStream outputstream1 = new FileOutputStream(this.tempFile);
|
||||
FileDownload.ResourcePackProgressListener filedownload$resourcepackprogresslistener = new FileDownload.ResourcePackProgressListener(this.tempFile, p_86985_, p_86983_);
|
||||
FileDownload.DownloadCountingOutputStream filedownload$downloadcountingoutputstream1 = new FileDownload.DownloadCountingOutputStream(outputstream1);
|
||||
filedownload$downloadcountingoutputstream1.setListener(filedownload$resourcepackprogresslistener);
|
||||
IOUtils.copy(httpresponse1.getEntity().getContent(), filedownload$downloadcountingoutputstream1);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Caught exception while downloading: {}", (Object)exception.getMessage());
|
||||
this.error = true;
|
||||
} finally {
|
||||
this.request.releaseConnection();
|
||||
if (this.tempFile != null) {
|
||||
this.tempFile.delete();
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
this.finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (closeablehttpclient != null) {
|
||||
try {
|
||||
closeablehttpclient.close();
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Failed to close Realms download client");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
this.currentThread.setUncaughtExceptionHandler(new RealmsDefaultUncaughtExceptionHandler(LOGGER));
|
||||
this.currentThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (this.request != null) {
|
||||
this.request.abort();
|
||||
}
|
||||
|
||||
if (this.tempFile != null) {
|
||||
this.tempFile.delete();
|
||||
}
|
||||
|
||||
this.cancelled = true;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.finished;
|
||||
}
|
||||
|
||||
public boolean isError() {
|
||||
return this.error;
|
||||
}
|
||||
|
||||
public boolean isExtracting() {
|
||||
return this.extracting;
|
||||
}
|
||||
|
||||
public static String findAvailableFolderName(String p_87002_) {
|
||||
p_87002_ = p_87002_.replaceAll("[\\./\"]", "_");
|
||||
|
||||
for(String s : INVALID_FILE_NAMES) {
|
||||
if (p_87002_.equalsIgnoreCase(s)) {
|
||||
p_87002_ = "_" + p_87002_ + "_";
|
||||
}
|
||||
}
|
||||
|
||||
return p_87002_;
|
||||
}
|
||||
|
||||
void untarGzipArchive(String p_86992_, @Nullable File p_86993_, LevelStorageSource p_86994_) throws IOException {
|
||||
Pattern pattern = Pattern.compile(".*-([0-9]+)$");
|
||||
int i = 1;
|
||||
|
||||
for(char c0 : SharedConstants.ILLEGAL_FILE_CHARACTERS) {
|
||||
p_86992_ = p_86992_.replace(c0, '_');
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(p_86992_)) {
|
||||
p_86992_ = "Realm";
|
||||
}
|
||||
|
||||
p_86992_ = findAvailableFolderName(p_86992_);
|
||||
|
||||
try {
|
||||
for(LevelStorageSource.LevelDirectory levelstoragesource$leveldirectory : p_86994_.findLevelCandidates()) {
|
||||
String s1 = levelstoragesource$leveldirectory.directoryName();
|
||||
if (s1.toLowerCase(Locale.ROOT).startsWith(p_86992_.toLowerCase(Locale.ROOT))) {
|
||||
Matcher matcher = pattern.matcher(s1);
|
||||
if (matcher.matches()) {
|
||||
int j = Integer.parseInt(matcher.group(1));
|
||||
if (j > i) {
|
||||
i = j;
|
||||
}
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception exception1) {
|
||||
LOGGER.error("Error getting level list", (Throwable)exception1);
|
||||
this.error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
String s;
|
||||
if (p_86994_.isNewLevelIdAcceptable(p_86992_) && i <= 1) {
|
||||
s = p_86992_;
|
||||
} else {
|
||||
s = p_86992_ + (i == 1 ? "" : "-" + i);
|
||||
if (!p_86994_.isNewLevelIdAcceptable(s)) {
|
||||
boolean flag = false;
|
||||
|
||||
while(!flag) {
|
||||
++i;
|
||||
s = p_86992_ + (i == 1 ? "" : "-" + i);
|
||||
if (p_86994_.isNewLevelIdAcceptable(s)) {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TarArchiveInputStream tararchiveinputstream = null;
|
||||
File file1 = new File(Minecraft.getInstance().gameDirectory.getAbsolutePath(), "saves");
|
||||
|
||||
try {
|
||||
file1.mkdir();
|
||||
tararchiveinputstream = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(p_86993_))));
|
||||
|
||||
for(TarArchiveEntry tararchiveentry = tararchiveinputstream.getNextTarEntry(); tararchiveentry != null; tararchiveentry = tararchiveinputstream.getNextTarEntry()) {
|
||||
File file2 = new File(file1, tararchiveentry.getName().replace("world", s));
|
||||
if (tararchiveentry.isDirectory()) {
|
||||
file2.mkdirs();
|
||||
} else {
|
||||
file2.createNewFile();
|
||||
|
||||
try (FileOutputStream fileoutputstream = new FileOutputStream(file2)) {
|
||||
IOUtils.copy(tararchiveinputstream, fileoutputstream);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Error extracting world", (Throwable)exception);
|
||||
this.error = true;
|
||||
} finally {
|
||||
if (tararchiveinputstream != null) {
|
||||
tararchiveinputstream.close();
|
||||
}
|
||||
|
||||
if (p_86993_ != null) {
|
||||
p_86993_.delete();
|
||||
}
|
||||
|
||||
try (LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess = p_86994_.validateAndCreateAccess(s)) {
|
||||
levelstoragesource$levelstorageaccess.renameLevel(s.trim());
|
||||
Path path = levelstoragesource$levelstorageaccess.getLevelPath(LevelResource.LEVEL_DATA_FILE);
|
||||
deletePlayerTag(path.toFile());
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Failed to rename unpacked realms level {}", s, ioexception);
|
||||
} catch (ContentValidationException contentvalidationexception) {
|
||||
LOGGER.warn("{}", (Object)contentvalidationexception.getMessage());
|
||||
}
|
||||
|
||||
this.resourcePackPath = new File(file1, s + File.separator + "resources.zip");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void deletePlayerTag(File p_86988_) {
|
||||
if (p_86988_.exists()) {
|
||||
try {
|
||||
CompoundTag compoundtag = NbtIo.readCompressed(p_86988_);
|
||||
CompoundTag compoundtag1 = compoundtag.getCompound("Data");
|
||||
compoundtag1.remove("Player");
|
||||
NbtIo.writeCompressed(compoundtag, p_86988_);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class DownloadCountingOutputStream extends CountingOutputStream {
|
||||
@Nullable
|
||||
private ActionListener listener;
|
||||
|
||||
public DownloadCountingOutputStream(OutputStream p_193509_) {
|
||||
super(p_193509_);
|
||||
}
|
||||
|
||||
public void setListener(ActionListener p_87017_) {
|
||||
this.listener = p_87017_;
|
||||
}
|
||||
|
||||
protected void afterWrite(int p_87019_) throws IOException {
|
||||
super.afterWrite(p_87019_);
|
||||
if (this.listener != null) {
|
||||
this.listener.actionPerformed(new ActionEvent(this, 0, (String)null));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class ProgressListener implements ActionListener {
|
||||
private final String worldName;
|
||||
private final File tempFile;
|
||||
private final LevelStorageSource levelStorageSource;
|
||||
private final RealmsDownloadLatestWorldScreen.DownloadStatus downloadStatus;
|
||||
|
||||
ProgressListener(String p_87027_, File p_87028_, LevelStorageSource p_87029_, RealmsDownloadLatestWorldScreen.DownloadStatus p_87030_) {
|
||||
this.worldName = p_87027_;
|
||||
this.tempFile = p_87028_;
|
||||
this.levelStorageSource = p_87029_;
|
||||
this.downloadStatus = p_87030_;
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent p_87039_) {
|
||||
this.downloadStatus.bytesWritten = ((FileDownload.DownloadCountingOutputStream)p_87039_.getSource()).getByteCount();
|
||||
if (this.downloadStatus.bytesWritten >= this.downloadStatus.totalBytes && !FileDownload.this.cancelled && !FileDownload.this.error) {
|
||||
try {
|
||||
FileDownload.this.extracting = true;
|
||||
FileDownload.this.untarGzipArchive(this.worldName, this.tempFile, this.levelStorageSource);
|
||||
} catch (IOException ioexception) {
|
||||
FileDownload.LOGGER.error("Error extracting archive", (Throwable)ioexception);
|
||||
FileDownload.this.error = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class ResourcePackProgressListener implements ActionListener {
|
||||
private final File tempFile;
|
||||
private final RealmsDownloadLatestWorldScreen.DownloadStatus downloadStatus;
|
||||
private final WorldDownload worldDownload;
|
||||
|
||||
ResourcePackProgressListener(File p_87046_, RealmsDownloadLatestWorldScreen.DownloadStatus p_87047_, WorldDownload p_87048_) {
|
||||
this.tempFile = p_87046_;
|
||||
this.downloadStatus = p_87047_;
|
||||
this.worldDownload = p_87048_;
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent p_87056_) {
|
||||
this.downloadStatus.bytesWritten = ((FileDownload.DownloadCountingOutputStream)p_87056_.getSource()).getByteCount();
|
||||
if (this.downloadStatus.bytesWritten >= this.downloadStatus.totalBytes && !FileDownload.this.cancelled) {
|
||||
try {
|
||||
String s = Hashing.sha1().hashBytes(Files.toByteArray(this.tempFile)).toString();
|
||||
if (s.equals(this.worldDownload.resourcePackHash)) {
|
||||
FileUtils.copyFile(this.tempFile, FileDownload.this.resourcePackPath);
|
||||
FileDownload.this.finished = true;
|
||||
} else {
|
||||
FileDownload.LOGGER.error("Resourcepack had wrong hash (expected {}, found {}). Deleting it.", this.worldDownload.resourcePackHash, s);
|
||||
FileUtils.deleteQuietly(this.tempFile);
|
||||
FileDownload.this.error = true;
|
||||
}
|
||||
} catch (IOException ioexception) {
|
||||
FileDownload.LOGGER.error("Error copying resourcepack file: {}", (Object)ioexception.getMessage());
|
||||
FileDownload.this.error = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.dto.UploadInfo;
|
||||
import com.mojang.realmsclient.gui.screens.UploadResult;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.User;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.InputStreamEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.Args;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class FileUpload {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int MAX_RETRIES = 5;
|
||||
private static final String UPLOAD_PATH = "/upload";
|
||||
private final File file;
|
||||
private final long worldId;
|
||||
private final int slotId;
|
||||
private final UploadInfo uploadInfo;
|
||||
private final String sessionId;
|
||||
private final String username;
|
||||
private final String clientVersion;
|
||||
private final UploadStatus uploadStatus;
|
||||
private final AtomicBoolean cancelled = new AtomicBoolean(false);
|
||||
@Nullable
|
||||
private CompletableFuture<UploadResult> uploadTask;
|
||||
private final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout((int)TimeUnit.MINUTES.toMillis(10L)).setConnectTimeout((int)TimeUnit.SECONDS.toMillis(15L)).build();
|
||||
|
||||
public FileUpload(File p_87071_, long p_87072_, int p_87073_, UploadInfo p_87074_, User p_87075_, String p_87076_, UploadStatus p_87077_) {
|
||||
this.file = p_87071_;
|
||||
this.worldId = p_87072_;
|
||||
this.slotId = p_87073_;
|
||||
this.uploadInfo = p_87074_;
|
||||
this.sessionId = p_87075_.getSessionId();
|
||||
this.username = p_87075_.getName();
|
||||
this.clientVersion = p_87076_;
|
||||
this.uploadStatus = p_87077_;
|
||||
}
|
||||
|
||||
public void upload(Consumer<UploadResult> p_87085_) {
|
||||
if (this.uploadTask == null) {
|
||||
this.uploadTask = CompletableFuture.supplyAsync(() -> {
|
||||
return this.requestUpload(0);
|
||||
});
|
||||
this.uploadTask.thenAccept(p_87085_);
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
this.cancelled.set(true);
|
||||
if (this.uploadTask != null) {
|
||||
this.uploadTask.cancel(false);
|
||||
this.uploadTask = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private UploadResult requestUpload(int p_87080_) {
|
||||
UploadResult.Builder uploadresult$builder = new UploadResult.Builder();
|
||||
if (this.cancelled.get()) {
|
||||
return uploadresult$builder.build();
|
||||
} else {
|
||||
this.uploadStatus.totalBytes = this.file.length();
|
||||
HttpPost httppost = new HttpPost(this.uploadInfo.getUploadEndpoint().resolve("/upload/" + this.worldId + "/" + this.slotId));
|
||||
CloseableHttpClient closeablehttpclient = HttpClientBuilder.create().setDefaultRequestConfig(this.requestConfig).build();
|
||||
|
||||
UploadResult uploadresult;
|
||||
try {
|
||||
this.setupRequest(httppost);
|
||||
HttpResponse httpresponse = closeablehttpclient.execute(httppost);
|
||||
long i = this.getRetryDelaySeconds(httpresponse);
|
||||
if (!this.shouldRetry(i, p_87080_)) {
|
||||
this.handleResponse(httpresponse, uploadresult$builder);
|
||||
return uploadresult$builder.build();
|
||||
}
|
||||
|
||||
uploadresult = this.retryUploadAfter(i, p_87080_);
|
||||
} catch (Exception exception) {
|
||||
if (!this.cancelled.get()) {
|
||||
LOGGER.error("Caught exception while uploading: ", (Throwable)exception);
|
||||
}
|
||||
|
||||
return uploadresult$builder.build();
|
||||
} finally {
|
||||
this.cleanup(httppost, closeablehttpclient);
|
||||
}
|
||||
|
||||
return uploadresult;
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanup(HttpPost p_87094_, @Nullable CloseableHttpClient p_87095_) {
|
||||
p_87094_.releaseConnection();
|
||||
if (p_87095_ != null) {
|
||||
try {
|
||||
p_87095_.close();
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Failed to close Realms upload client");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setupRequest(HttpPost p_87092_) throws FileNotFoundException {
|
||||
p_87092_.setHeader("Cookie", "sid=" + this.sessionId + ";token=" + this.uploadInfo.getToken() + ";user=" + this.username + ";version=" + this.clientVersion);
|
||||
FileUpload.CustomInputStreamEntity fileupload$custominputstreamentity = new FileUpload.CustomInputStreamEntity(new FileInputStream(this.file), this.file.length(), this.uploadStatus);
|
||||
fileupload$custominputstreamentity.setContentType("application/octet-stream");
|
||||
p_87092_.setEntity(fileupload$custominputstreamentity);
|
||||
}
|
||||
|
||||
private void handleResponse(HttpResponse p_87089_, UploadResult.Builder p_87090_) throws IOException {
|
||||
int i = p_87089_.getStatusLine().getStatusCode();
|
||||
if (i == 401) {
|
||||
LOGGER.debug("Realms server returned 401: {}", (Object)p_87089_.getFirstHeader("WWW-Authenticate"));
|
||||
}
|
||||
|
||||
p_87090_.withStatusCode(i);
|
||||
if (p_87089_.getEntity() != null) {
|
||||
String s = EntityUtils.toString(p_87089_.getEntity(), "UTF-8");
|
||||
if (s != null) {
|
||||
try {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonElement jsonelement = jsonparser.parse(s).getAsJsonObject().get("errorMsg");
|
||||
Optional<String> optional = Optional.ofNullable(jsonelement).map(JsonElement::getAsString);
|
||||
p_87090_.withErrorMessage(optional.orElse((String)null));
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean shouldRetry(long p_87082_, int p_87083_) {
|
||||
return p_87082_ > 0L && p_87083_ + 1 < 5;
|
||||
}
|
||||
|
||||
private UploadResult retryUploadAfter(long p_87098_, int p_87099_) throws InterruptedException {
|
||||
Thread.sleep(Duration.ofSeconds(p_87098_).toMillis());
|
||||
return this.requestUpload(p_87099_ + 1);
|
||||
}
|
||||
|
||||
private long getRetryDelaySeconds(HttpResponse p_87087_) {
|
||||
return Optional.ofNullable(p_87087_.getFirstHeader("Retry-After")).map(NameValuePair::getValue).map(Long::valueOf).orElse(0L);
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.uploadTask.isDone() || this.uploadTask.isCancelled();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static class CustomInputStreamEntity extends InputStreamEntity {
|
||||
private final long length;
|
||||
private final InputStream content;
|
||||
private final UploadStatus uploadStatus;
|
||||
|
||||
public CustomInputStreamEntity(InputStream p_87105_, long p_87106_, UploadStatus p_87107_) {
|
||||
super(p_87105_);
|
||||
this.content = p_87105_;
|
||||
this.length = p_87106_;
|
||||
this.uploadStatus = p_87107_;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream p_87109_) throws IOException {
|
||||
Args.notNull(p_87109_, "Output stream");
|
||||
InputStream inputstream = this.content;
|
||||
|
||||
try {
|
||||
byte[] abyte = new byte[4096];
|
||||
int j;
|
||||
if (this.length < 0L) {
|
||||
while((j = inputstream.read(abyte)) != -1) {
|
||||
p_87109_.write(abyte, 0, j);
|
||||
this.uploadStatus.bytesWritten += (long)j;
|
||||
}
|
||||
} else {
|
||||
long i = this.length;
|
||||
|
||||
while(i > 0L) {
|
||||
j = inputstream.read(abyte, 0, (int)Math.min(4096L, i));
|
||||
if (j == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
p_87109_.write(abyte, 0, j);
|
||||
this.uploadStatus.bytesWritten += (long)j;
|
||||
i -= (long)j;
|
||||
p_87109_.flush();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
inputstream.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.realmsclient.dto.RegionPingResult;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Ping {
|
||||
public static List<RegionPingResult> ping(Ping.Region... p_87131_) {
|
||||
for(Ping.Region ping$region : p_87131_) {
|
||||
ping(ping$region.endpoint);
|
||||
}
|
||||
|
||||
List<RegionPingResult> list = Lists.newArrayList();
|
||||
|
||||
for(Ping.Region ping$region1 : p_87131_) {
|
||||
list.add(new RegionPingResult(ping$region1.name, ping(ping$region1.endpoint)));
|
||||
}
|
||||
|
||||
list.sort(Comparator.comparingInt(RegionPingResult::ping));
|
||||
return list;
|
||||
}
|
||||
|
||||
private static int ping(String p_87127_) {
|
||||
int i = 700;
|
||||
long j = 0L;
|
||||
Socket socket = null;
|
||||
|
||||
for(int k = 0; k < 5; ++k) {
|
||||
try {
|
||||
SocketAddress socketaddress = new InetSocketAddress(p_87127_, 80);
|
||||
socket = new Socket();
|
||||
long l = now();
|
||||
socket.connect(socketaddress, 700);
|
||||
j += now() - l;
|
||||
} catch (Exception exception) {
|
||||
j += 700L;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(socket);
|
||||
}
|
||||
}
|
||||
|
||||
return (int)((double)j / 5.0D);
|
||||
}
|
||||
|
||||
private static long now() {
|
||||
return Util.getMillis();
|
||||
}
|
||||
|
||||
public static List<RegionPingResult> pingAllRegions() {
|
||||
return ping(Ping.Region.values());
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static enum Region {
|
||||
US_EAST_1("us-east-1", "ec2.us-east-1.amazonaws.com"),
|
||||
US_WEST_2("us-west-2", "ec2.us-west-2.amazonaws.com"),
|
||||
US_WEST_1("us-west-1", "ec2.us-west-1.amazonaws.com"),
|
||||
EU_WEST_1("eu-west-1", "ec2.eu-west-1.amazonaws.com"),
|
||||
AP_SOUTHEAST_1("ap-southeast-1", "ec2.ap-southeast-1.amazonaws.com"),
|
||||
AP_SOUTHEAST_2("ap-southeast-2", "ec2.ap-southeast-2.amazonaws.com"),
|
||||
AP_NORTHEAST_1("ap-northeast-1", "ec2.ap-northeast-1.amazonaws.com"),
|
||||
SA_EAST_1("sa-east-1", "ec2.sa-east-1.amazonaws.com");
|
||||
|
||||
final String name;
|
||||
final String endpoint;
|
||||
|
||||
private Region(String p_87148_, String p_87149_) {
|
||||
this.name = p_87148_;
|
||||
this.endpoint = p_87149_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.dto.BackupList;
|
||||
import com.mojang.realmsclient.dto.GuardedSerializer;
|
||||
import com.mojang.realmsclient.dto.Ops;
|
||||
import com.mojang.realmsclient.dto.PendingInvite;
|
||||
import com.mojang.realmsclient.dto.PendingInvitesList;
|
||||
import com.mojang.realmsclient.dto.PingResult;
|
||||
import com.mojang.realmsclient.dto.PlayerInfo;
|
||||
import com.mojang.realmsclient.dto.RealmsDescriptionDto;
|
||||
import com.mojang.realmsclient.dto.RealmsNews;
|
||||
import com.mojang.realmsclient.dto.RealmsNotification;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.RealmsServerAddress;
|
||||
import com.mojang.realmsclient.dto.RealmsServerList;
|
||||
import com.mojang.realmsclient.dto.RealmsServerPlayerLists;
|
||||
import com.mojang.realmsclient.dto.RealmsWorldOptions;
|
||||
import com.mojang.realmsclient.dto.RealmsWorldResetDto;
|
||||
import com.mojang.realmsclient.dto.ServerActivityList;
|
||||
import com.mojang.realmsclient.dto.Subscription;
|
||||
import com.mojang.realmsclient.dto.UploadInfo;
|
||||
import com.mojang.realmsclient.dto.WorldDownload;
|
||||
import com.mojang.realmsclient.dto.WorldTemplatePaginatedList;
|
||||
import com.mojang.realmsclient.exception.RealmsHttpException;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.exception.RetryCallException;
|
||||
import com.mojang.realmsclient.util.WorldGenerationInfo;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsClient {
|
||||
public static RealmsClient.Environment currentEnvironment = RealmsClient.Environment.PRODUCTION;
|
||||
private static boolean initialized;
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final String sessionId;
|
||||
private final String username;
|
||||
private final Minecraft minecraft;
|
||||
private static final String WORLDS_RESOURCE_PATH = "worlds";
|
||||
private static final String INVITES_RESOURCE_PATH = "invites";
|
||||
private static final String MCO_RESOURCE_PATH = "mco";
|
||||
private static final String SUBSCRIPTION_RESOURCE = "subscriptions";
|
||||
private static final String ACTIVITIES_RESOURCE = "activities";
|
||||
private static final String OPS_RESOURCE = "ops";
|
||||
private static final String REGIONS_RESOURCE = "regions/ping/stat";
|
||||
private static final String TRIALS_RESOURCE = "trial";
|
||||
private static final String NOTIFICATIONS_RESOURCE = "notifications";
|
||||
private static final String PATH_INITIALIZE = "/$WORLD_ID/initialize";
|
||||
private static final String PATH_GET_ACTIVTIES = "/$WORLD_ID";
|
||||
private static final String PATH_GET_LIVESTATS = "/liveplayerlist";
|
||||
private static final String PATH_GET_SUBSCRIPTION = "/$WORLD_ID";
|
||||
private static final String PATH_OP = "/$WORLD_ID/$PROFILE_UUID";
|
||||
private static final String PATH_PUT_INTO_MINIGAMES_MODE = "/minigames/$MINIGAME_ID/$WORLD_ID";
|
||||
private static final String PATH_AVAILABLE = "/available";
|
||||
private static final String PATH_TEMPLATES = "/templates/$WORLD_TYPE";
|
||||
private static final String PATH_WORLD_JOIN = "/v1/$ID/join/pc";
|
||||
private static final String PATH_WORLD_GET = "/$ID";
|
||||
private static final String PATH_WORLD_INVITES = "/$WORLD_ID";
|
||||
private static final String PATH_WORLD_UNINVITE = "/$WORLD_ID/invite/$UUID";
|
||||
private static final String PATH_PENDING_INVITES_COUNT = "/count/pending";
|
||||
private static final String PATH_PENDING_INVITES = "/pending";
|
||||
private static final String PATH_ACCEPT_INVITE = "/accept/$INVITATION_ID";
|
||||
private static final String PATH_REJECT_INVITE = "/reject/$INVITATION_ID";
|
||||
private static final String PATH_UNINVITE_MYSELF = "/$WORLD_ID";
|
||||
private static final String PATH_WORLD_UPDATE = "/$WORLD_ID";
|
||||
private static final String PATH_SLOT = "/$WORLD_ID/slot/$SLOT_ID";
|
||||
private static final String PATH_WORLD_OPEN = "/$WORLD_ID/open";
|
||||
private static final String PATH_WORLD_CLOSE = "/$WORLD_ID/close";
|
||||
private static final String PATH_WORLD_RESET = "/$WORLD_ID/reset";
|
||||
private static final String PATH_DELETE_WORLD = "/$WORLD_ID";
|
||||
private static final String PATH_WORLD_BACKUPS = "/$WORLD_ID/backups";
|
||||
private static final String PATH_WORLD_DOWNLOAD = "/$WORLD_ID/slot/$SLOT_ID/download";
|
||||
private static final String PATH_WORLD_UPLOAD = "/$WORLD_ID/backups/upload";
|
||||
private static final String PATH_CLIENT_COMPATIBLE = "/client/compatible";
|
||||
private static final String PATH_TOS_AGREED = "/tos/agreed";
|
||||
private static final String PATH_NEWS = "/v1/news";
|
||||
private static final String PATH_MARK_NOTIFICATIONS_SEEN = "/seen";
|
||||
private static final String PATH_DISMISS_NOTIFICATIONS = "/dismiss";
|
||||
private static final String PATH_STAGE_AVAILABLE = "/stageAvailable";
|
||||
private static final GuardedSerializer GSON = new GuardedSerializer();
|
||||
|
||||
public static RealmsClient create() {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
return create(minecraft);
|
||||
}
|
||||
|
||||
public static RealmsClient create(Minecraft p_239152_) {
|
||||
String s = p_239152_.getUser().getName();
|
||||
String s1 = p_239152_.getUser().getSessionId();
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
Optional<String> optional = Optional.ofNullable(System.getenv("realms.environment")).or(() -> {
|
||||
return Optional.ofNullable(System.getProperty("realms.environment"));
|
||||
});
|
||||
optional.flatMap(RealmsClient.Environment::byName).ifPresent((p_289648_) -> {
|
||||
currentEnvironment = p_289648_;
|
||||
});
|
||||
}
|
||||
|
||||
return new RealmsClient(s1, s, p_239152_);
|
||||
}
|
||||
|
||||
public static void switchToStage() {
|
||||
currentEnvironment = RealmsClient.Environment.STAGE;
|
||||
}
|
||||
|
||||
public static void switchToProd() {
|
||||
currentEnvironment = RealmsClient.Environment.PRODUCTION;
|
||||
}
|
||||
|
||||
public static void switchToLocal() {
|
||||
currentEnvironment = RealmsClient.Environment.LOCAL;
|
||||
}
|
||||
|
||||
public RealmsClient(String p_87166_, String p_87167_, Minecraft p_87168_) {
|
||||
this.sessionId = p_87166_;
|
||||
this.username = p_87167_;
|
||||
this.minecraft = p_87168_;
|
||||
RealmsClientConfig.setProxy(p_87168_.getProxy());
|
||||
}
|
||||
|
||||
public RealmsServerList listWorlds() throws RealmsServiceException {
|
||||
String s = this.url("worlds");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return RealmsServerList.parse(s1);
|
||||
}
|
||||
|
||||
public List<RealmsNotification> getNotifications() throws RealmsServiceException {
|
||||
String s = this.url("notifications");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
List<RealmsNotification> list = RealmsNotification.parseList(s1);
|
||||
return list.size() > 1 ? List.of(list.get(0)) : list;
|
||||
}
|
||||
|
||||
private static JsonArray uuidListToJsonArray(List<UUID> p_275393_) {
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for(UUID uuid : p_275393_) {
|
||||
if (uuid != null) {
|
||||
jsonarray.add(uuid.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return jsonarray;
|
||||
}
|
||||
|
||||
public void notificationsSeen(List<UUID> p_275212_) throws RealmsServiceException {
|
||||
String s = this.url("notifications/seen");
|
||||
this.execute(Request.post(s, GSON.toJson(uuidListToJsonArray(p_275212_))));
|
||||
}
|
||||
|
||||
public void notificationsDismiss(List<UUID> p_275407_) throws RealmsServiceException {
|
||||
String s = this.url("notifications/dismiss");
|
||||
this.execute(Request.post(s, GSON.toJson(uuidListToJsonArray(p_275407_))));
|
||||
}
|
||||
|
||||
public RealmsServer getOwnWorld(long p_87175_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$ID".replace("$ID", String.valueOf(p_87175_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return RealmsServer.parse(s1);
|
||||
}
|
||||
|
||||
public ServerActivityList getActivity(long p_167279_) throws RealmsServiceException {
|
||||
String s = this.url("activities" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_167279_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return ServerActivityList.parse(s1);
|
||||
}
|
||||
|
||||
public RealmsServerPlayerLists getLiveStats() throws RealmsServiceException {
|
||||
String s = this.url("activities/liveplayerlist");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return RealmsServerPlayerLists.parse(s1);
|
||||
}
|
||||
|
||||
public RealmsServerAddress join(long p_87208_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/v1/$ID/join/pc".replace("$ID", "" + p_87208_));
|
||||
String s1 = this.execute(Request.get(s, 5000, 30000));
|
||||
return RealmsServerAddress.parse(s1);
|
||||
}
|
||||
|
||||
public void initializeWorld(long p_87192_, String p_87193_, String p_87194_) throws RealmsServiceException {
|
||||
RealmsDescriptionDto realmsdescriptiondto = new RealmsDescriptionDto(p_87193_, p_87194_);
|
||||
String s = this.url("worlds" + "/$WORLD_ID/initialize".replace("$WORLD_ID", String.valueOf(p_87192_)));
|
||||
String s1 = GSON.toJson(realmsdescriptiondto);
|
||||
this.execute(Request.post(s, s1, 5000, 10000));
|
||||
}
|
||||
|
||||
public Boolean mcoEnabled() throws RealmsServiceException {
|
||||
String s = this.url("mco/available");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Boolean stageAvailable() throws RealmsServiceException {
|
||||
String s = this.url("mco/stageAvailable");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public RealmsClient.CompatibleVersionResponse clientCompatible() throws RealmsServiceException {
|
||||
String s = this.url("mco/client/compatible");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
|
||||
try {
|
||||
return RealmsClient.CompatibleVersionResponse.valueOf(s1);
|
||||
} catch (IllegalArgumentException illegalargumentexception) {
|
||||
throw new RealmsServiceException(500, "Could not check compatible version, got response: " + s1);
|
||||
}
|
||||
}
|
||||
|
||||
public void uninvite(long p_87184_, String p_87185_) throws RealmsServiceException {
|
||||
String s = this.url("invites" + "/$WORLD_ID/invite/$UUID".replace("$WORLD_ID", String.valueOf(p_87184_)).replace("$UUID", p_87185_));
|
||||
this.execute(Request.delete(s));
|
||||
}
|
||||
|
||||
public void uninviteMyselfFrom(long p_87223_) throws RealmsServiceException {
|
||||
String s = this.url("invites" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87223_)));
|
||||
this.execute(Request.delete(s));
|
||||
}
|
||||
|
||||
public RealmsServer invite(long p_87213_, String p_87214_) throws RealmsServiceException {
|
||||
PlayerInfo playerinfo = new PlayerInfo();
|
||||
playerinfo.setName(p_87214_);
|
||||
String s = this.url("invites" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87213_)));
|
||||
String s1 = this.execute(Request.post(s, GSON.toJson(playerinfo)));
|
||||
return RealmsServer.parse(s1);
|
||||
}
|
||||
|
||||
public BackupList backupsFor(long p_87231_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/backups".replace("$WORLD_ID", String.valueOf(p_87231_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return BackupList.parse(s1);
|
||||
}
|
||||
|
||||
public void update(long p_87216_, String p_87217_, String p_87218_) throws RealmsServiceException {
|
||||
RealmsDescriptionDto realmsdescriptiondto = new RealmsDescriptionDto(p_87217_, p_87218_);
|
||||
String s = this.url("worlds" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87216_)));
|
||||
this.execute(Request.post(s, GSON.toJson(realmsdescriptiondto)));
|
||||
}
|
||||
|
||||
public void updateSlot(long p_87180_, int p_87181_, RealmsWorldOptions p_87182_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/slot/$SLOT_ID".replace("$WORLD_ID", String.valueOf(p_87180_)).replace("$SLOT_ID", String.valueOf(p_87181_)));
|
||||
String s1 = p_87182_.toJson();
|
||||
this.execute(Request.post(s, s1));
|
||||
}
|
||||
|
||||
public boolean switchSlot(long p_87177_, int p_87178_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/slot/$SLOT_ID".replace("$WORLD_ID", String.valueOf(p_87177_)).replace("$SLOT_ID", String.valueOf(p_87178_)));
|
||||
String s1 = this.execute(Request.put(s, ""));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public void restoreWorld(long p_87225_, String p_87226_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/backups".replace("$WORLD_ID", String.valueOf(p_87225_)), "backupId=" + p_87226_);
|
||||
this.execute(Request.put(s, "", 40000, 600000));
|
||||
}
|
||||
|
||||
public WorldTemplatePaginatedList fetchWorldTemplates(int p_87171_, int p_87172_, RealmsServer.WorldType p_87173_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/templates/$WORLD_TYPE".replace("$WORLD_TYPE", p_87173_.toString()), String.format(Locale.ROOT, "page=%d&pageSize=%d", p_87171_, p_87172_));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return WorldTemplatePaginatedList.parse(s1);
|
||||
}
|
||||
|
||||
public Boolean putIntoMinigameMode(long p_87233_, String p_87234_) throws RealmsServiceException {
|
||||
String s = "/minigames/$MINIGAME_ID/$WORLD_ID".replace("$MINIGAME_ID", p_87234_).replace("$WORLD_ID", String.valueOf(p_87233_));
|
||||
String s1 = this.url("worlds" + s);
|
||||
return Boolean.valueOf(this.execute(Request.put(s1, "")));
|
||||
}
|
||||
|
||||
public Ops op(long p_87239_, String p_87240_) throws RealmsServiceException {
|
||||
String s = "/$WORLD_ID/$PROFILE_UUID".replace("$WORLD_ID", String.valueOf(p_87239_)).replace("$PROFILE_UUID", p_87240_);
|
||||
String s1 = this.url("ops" + s);
|
||||
return Ops.parse(this.execute(Request.post(s1, "")));
|
||||
}
|
||||
|
||||
public Ops deop(long p_87245_, String p_87246_) throws RealmsServiceException {
|
||||
String s = "/$WORLD_ID/$PROFILE_UUID".replace("$WORLD_ID", String.valueOf(p_87245_)).replace("$PROFILE_UUID", p_87246_);
|
||||
String s1 = this.url("ops" + s);
|
||||
return Ops.parse(this.execute(Request.delete(s1)));
|
||||
}
|
||||
|
||||
public Boolean open(long p_87237_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/open".replace("$WORLD_ID", String.valueOf(p_87237_)));
|
||||
String s1 = this.execute(Request.put(s, ""));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Boolean close(long p_87243_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/close".replace("$WORLD_ID", String.valueOf(p_87243_)));
|
||||
String s1 = this.execute(Request.put(s, ""));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Boolean resetWorldWithSeed(long p_167276_, WorldGenerationInfo p_167277_) throws RealmsServiceException {
|
||||
RealmsWorldResetDto realmsworldresetdto = new RealmsWorldResetDto(p_167277_.getSeed(), -1L, p_167277_.getLevelType().getDtoIndex(), p_167277_.shouldGenerateStructures());
|
||||
String s = this.url("worlds" + "/$WORLD_ID/reset".replace("$WORLD_ID", String.valueOf(p_167276_)));
|
||||
String s1 = this.execute(Request.post(s, GSON.toJson(realmsworldresetdto), 30000, 80000));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Boolean resetWorldWithTemplate(long p_87251_, String p_87252_) throws RealmsServiceException {
|
||||
RealmsWorldResetDto realmsworldresetdto = new RealmsWorldResetDto((String)null, Long.valueOf(p_87252_), -1, false);
|
||||
String s = this.url("worlds" + "/$WORLD_ID/reset".replace("$WORLD_ID", String.valueOf(p_87251_)));
|
||||
String s1 = this.execute(Request.post(s, GSON.toJson(realmsworldresetdto), 30000, 80000));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public Subscription subscriptionFor(long p_87249_) throws RealmsServiceException {
|
||||
String s = this.url("subscriptions" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87249_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return Subscription.parse(s1);
|
||||
}
|
||||
|
||||
public int pendingInvitesCount() throws RealmsServiceException {
|
||||
return this.pendingInvites().pendingInvites.size();
|
||||
}
|
||||
|
||||
public PendingInvitesList pendingInvites() throws RealmsServiceException {
|
||||
String s = this.url("invites/pending");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
PendingInvitesList pendinginviteslist = PendingInvitesList.parse(s1);
|
||||
pendinginviteslist.pendingInvites.removeIf(this::isBlocked);
|
||||
return pendinginviteslist;
|
||||
}
|
||||
|
||||
private boolean isBlocked(PendingInvite p_87198_) {
|
||||
try {
|
||||
UUID uuid = UUID.fromString(p_87198_.worldOwnerUuid);
|
||||
return this.minecraft.getPlayerSocialManager().isBlocked(uuid);
|
||||
} catch (IllegalArgumentException illegalargumentexception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void acceptInvitation(String p_87202_) throws RealmsServiceException {
|
||||
String s = this.url("invites" + "/accept/$INVITATION_ID".replace("$INVITATION_ID", p_87202_));
|
||||
this.execute(Request.put(s, ""));
|
||||
}
|
||||
|
||||
public WorldDownload requestDownloadInfo(long p_87210_, int p_87211_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/slot/$SLOT_ID/download".replace("$WORLD_ID", String.valueOf(p_87210_)).replace("$SLOT_ID", String.valueOf(p_87211_)));
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return WorldDownload.parse(s1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public UploadInfo requestUploadInfo(long p_87257_, @Nullable String p_87258_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID/backups/upload".replace("$WORLD_ID", String.valueOf(p_87257_)));
|
||||
return UploadInfo.parse(this.execute(Request.put(s, UploadInfo.createRequest(p_87258_))));
|
||||
}
|
||||
|
||||
public void rejectInvitation(String p_87220_) throws RealmsServiceException {
|
||||
String s = this.url("invites" + "/reject/$INVITATION_ID".replace("$INVITATION_ID", p_87220_));
|
||||
this.execute(Request.put(s, ""));
|
||||
}
|
||||
|
||||
public void agreeToTos() throws RealmsServiceException {
|
||||
String s = this.url("mco/tos/agreed");
|
||||
this.execute(Request.post(s, ""));
|
||||
}
|
||||
|
||||
public RealmsNews getNews() throws RealmsServiceException {
|
||||
String s = this.url("mco/v1/news");
|
||||
String s1 = this.execute(Request.get(s, 5000, 10000));
|
||||
return RealmsNews.parse(s1);
|
||||
}
|
||||
|
||||
public void sendPingResults(PingResult p_87200_) throws RealmsServiceException {
|
||||
String s = this.url("regions/ping/stat");
|
||||
this.execute(Request.post(s, GSON.toJson(p_87200_)));
|
||||
}
|
||||
|
||||
public Boolean trialAvailable() throws RealmsServiceException {
|
||||
String s = this.url("trial");
|
||||
String s1 = this.execute(Request.get(s));
|
||||
return Boolean.valueOf(s1);
|
||||
}
|
||||
|
||||
public void deleteWorld(long p_87255_) throws RealmsServiceException {
|
||||
String s = this.url("worlds" + "/$WORLD_ID".replace("$WORLD_ID", String.valueOf(p_87255_)));
|
||||
this.execute(Request.delete(s));
|
||||
}
|
||||
|
||||
private String url(String p_87228_) {
|
||||
return this.url(p_87228_, (String)null);
|
||||
}
|
||||
|
||||
private String url(String p_87204_, @Nullable String p_87205_) {
|
||||
try {
|
||||
return (new URI(currentEnvironment.protocol, currentEnvironment.baseUrl, "/" + p_87204_, p_87205_, (String)null)).toASCIIString();
|
||||
} catch (URISyntaxException urisyntaxexception) {
|
||||
throw new IllegalArgumentException(p_87204_, urisyntaxexception);
|
||||
}
|
||||
}
|
||||
|
||||
private String execute(Request<?> p_87196_) throws RealmsServiceException {
|
||||
p_87196_.cookie("sid", this.sessionId);
|
||||
p_87196_.cookie("user", this.username);
|
||||
p_87196_.cookie("version", SharedConstants.getCurrentVersion().getName());
|
||||
|
||||
try {
|
||||
int i = p_87196_.responseCode();
|
||||
if (i != 503 && i != 277) {
|
||||
String s1 = p_87196_.text();
|
||||
if (i >= 200 && i < 300) {
|
||||
return s1;
|
||||
} else if (i == 401) {
|
||||
String s2 = p_87196_.getHeader("WWW-Authenticate");
|
||||
LOGGER.info("Could not authorize you against Realms server: {}", (Object)s2);
|
||||
throw new RealmsServiceException(i, s2);
|
||||
} else {
|
||||
RealmsError realmserror = RealmsError.parse(s1);
|
||||
if (realmserror != null) {
|
||||
LOGGER.error("Realms http code: {} - error code: {} - message: {} - raw body: {}", i, realmserror.getErrorCode(), realmserror.getErrorMessage(), s1);
|
||||
throw new RealmsServiceException(i, s1, realmserror);
|
||||
} else {
|
||||
LOGGER.error("Realms http code: {} - raw body (message failed to parse): {}", i, s1);
|
||||
String s = getHttpCodeDescription(i);
|
||||
throw new RealmsServiceException(i, s);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int j = p_87196_.getRetryAfterHeader();
|
||||
throw new RetryCallException(j, i);
|
||||
}
|
||||
} catch (RealmsHttpException realmshttpexception) {
|
||||
throw new RealmsServiceException(500, "Could not connect to Realms: " + realmshttpexception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static String getHttpCodeDescription(int p_200937_) {
|
||||
String s;
|
||||
switch (p_200937_) {
|
||||
case 429:
|
||||
s = I18n.get("mco.errorMessage.serviceBusy");
|
||||
break;
|
||||
default:
|
||||
s = "Unknown error";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum CompatibleVersionResponse {
|
||||
COMPATIBLE,
|
||||
OUTDATED,
|
||||
OTHER;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Environment {
|
||||
PRODUCTION("pc.realms.minecraft.net", "https"),
|
||||
STAGE("pc-stage.realms.minecraft.net", "https"),
|
||||
LOCAL("localhost:8080", "http");
|
||||
|
||||
public String baseUrl;
|
||||
public String protocol;
|
||||
|
||||
private Environment(String p_87286_, String p_87287_) {
|
||||
this.baseUrl = p_87286_;
|
||||
this.protocol = p_87287_;
|
||||
}
|
||||
|
||||
public static Optional<RealmsClient.Environment> byName(String p_289688_) {
|
||||
Optional optional;
|
||||
switch (p_289688_.toLowerCase(Locale.ROOT)) {
|
||||
case "production":
|
||||
optional = Optional.of(PRODUCTION);
|
||||
break;
|
||||
case "local":
|
||||
optional = Optional.of(LOCAL);
|
||||
break;
|
||||
case "stage":
|
||||
optional = Optional.of(STAGE);
|
||||
break;
|
||||
default:
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
return optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import java.net.Proxy;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsClientConfig {
|
||||
@Nullable
|
||||
private static Proxy proxy;
|
||||
|
||||
@Nullable
|
||||
public static Proxy getProxy() {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public static void setProxy(Proxy p_87294_) {
|
||||
if (proxy == null) {
|
||||
proxy = p_87294_;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsError {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final String errorMessage;
|
||||
private final int errorCode;
|
||||
|
||||
private RealmsError(String p_87300_, int p_87301_) {
|
||||
this.errorMessage = p_87300_;
|
||||
this.errorCode = p_87301_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static RealmsError parse(String p_87304_) {
|
||||
if (Strings.isNullOrEmpty(p_87304_)) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
JsonObject jsonobject = JsonParser.parseString(p_87304_).getAsJsonObject();
|
||||
String s = JsonUtils.getStringOr("errorMsg", jsonobject, "");
|
||||
int i = JsonUtils.getIntOr("errorCode", jsonobject, -1);
|
||||
return new RealmsError(s, i);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse RealmsError: {}", (Object)exception.getMessage());
|
||||
LOGGER.error("The error was: {}", (Object)p_87304_);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return this.errorMessage;
|
||||
}
|
||||
|
||||
public int getErrorCode() {
|
||||
return this.errorCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import com.mojang.realmsclient.exception.RealmsHttpException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class Request<T extends Request<T>> {
|
||||
protected HttpURLConnection connection;
|
||||
private boolean connected;
|
||||
protected String url;
|
||||
private static final int DEFAULT_READ_TIMEOUT = 60000;
|
||||
private static final int DEFAULT_CONNECT_TIMEOUT = 5000;
|
||||
|
||||
public Request(String p_87310_, int p_87311_, int p_87312_) {
|
||||
try {
|
||||
this.url = p_87310_;
|
||||
Proxy proxy = RealmsClientConfig.getProxy();
|
||||
if (proxy != null) {
|
||||
this.connection = (HttpURLConnection)(new URL(p_87310_)).openConnection(proxy);
|
||||
} else {
|
||||
this.connection = (HttpURLConnection)(new URL(p_87310_)).openConnection();
|
||||
}
|
||||
|
||||
this.connection.setConnectTimeout(p_87311_);
|
||||
this.connection.setReadTimeout(p_87312_);
|
||||
} catch (MalformedURLException malformedurlexception) {
|
||||
throw new RealmsHttpException(malformedurlexception.getMessage(), malformedurlexception);
|
||||
} catch (IOException ioexception) {
|
||||
throw new RealmsHttpException(ioexception.getMessage(), ioexception);
|
||||
}
|
||||
}
|
||||
|
||||
public void cookie(String p_87323_, String p_87324_) {
|
||||
cookie(this.connection, p_87323_, p_87324_);
|
||||
}
|
||||
|
||||
public static void cookie(HttpURLConnection p_87336_, String p_87337_, String p_87338_) {
|
||||
String s = p_87336_.getRequestProperty("Cookie");
|
||||
if (s == null) {
|
||||
p_87336_.setRequestProperty("Cookie", p_87337_ + "=" + p_87338_);
|
||||
} else {
|
||||
p_87336_.setRequestProperty("Cookie", s + ";" + p_87337_ + "=" + p_87338_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public T header(String p_167286_, String p_167287_) {
|
||||
this.connection.addRequestProperty(p_167286_, p_167287_);
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
public int getRetryAfterHeader() {
|
||||
return getRetryAfterHeader(this.connection);
|
||||
}
|
||||
|
||||
public static int getRetryAfterHeader(HttpURLConnection p_87331_) {
|
||||
String s = p_87331_.getHeaderField("Retry-After");
|
||||
|
||||
try {
|
||||
return Integer.valueOf(s);
|
||||
} catch (Exception exception) {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
public int responseCode() {
|
||||
try {
|
||||
this.connect();
|
||||
return this.connection.getResponseCode();
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
public String text() {
|
||||
try {
|
||||
this.connect();
|
||||
String s;
|
||||
if (this.responseCode() >= 400) {
|
||||
s = this.read(this.connection.getErrorStream());
|
||||
} else {
|
||||
s = this.read(this.connection.getInputStream());
|
||||
}
|
||||
|
||||
this.dispose();
|
||||
return s;
|
||||
} catch (IOException ioexception) {
|
||||
throw new RealmsHttpException(ioexception.getMessage(), ioexception);
|
||||
}
|
||||
}
|
||||
|
||||
private String read(@Nullable InputStream p_87315_) throws IOException {
|
||||
if (p_87315_ == null) {
|
||||
return "";
|
||||
} else {
|
||||
InputStreamReader inputstreamreader = new InputStreamReader(p_87315_, StandardCharsets.UTF_8);
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
for(int i = inputstreamreader.read(); i != -1; i = inputstreamreader.read()) {
|
||||
stringbuilder.append((char)i);
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private void dispose() {
|
||||
byte[] abyte = new byte[1024];
|
||||
|
||||
try {
|
||||
InputStream inputstream = this.connection.getInputStream();
|
||||
|
||||
while(inputstream.read(abyte) > 0) {
|
||||
}
|
||||
|
||||
inputstream.close();
|
||||
return;
|
||||
} catch (Exception exception) {
|
||||
try {
|
||||
InputStream inputstream1 = this.connection.getErrorStream();
|
||||
if (inputstream1 != null) {
|
||||
while(inputstream1.read(abyte) > 0) {
|
||||
}
|
||||
|
||||
inputstream1.close();
|
||||
return;
|
||||
}
|
||||
} catch (IOException ioexception) {
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
if (this.connection != null) {
|
||||
this.connection.disconnect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected T connect() {
|
||||
if (this.connected) {
|
||||
return (T)this;
|
||||
} else {
|
||||
T t = this.doConnect();
|
||||
this.connected = true;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T doConnect();
|
||||
|
||||
public static Request<?> get(String p_87317_) {
|
||||
return new Request.Get(p_87317_, 5000, 60000);
|
||||
}
|
||||
|
||||
public static Request<?> get(String p_87319_, int p_87320_, int p_87321_) {
|
||||
return new Request.Get(p_87319_, p_87320_, p_87321_);
|
||||
}
|
||||
|
||||
public static Request<?> post(String p_87343_, String p_87344_) {
|
||||
return new Request.Post(p_87343_, p_87344_, 5000, 60000);
|
||||
}
|
||||
|
||||
public static Request<?> post(String p_87326_, String p_87327_, int p_87328_, int p_87329_) {
|
||||
return new Request.Post(p_87326_, p_87327_, p_87328_, p_87329_);
|
||||
}
|
||||
|
||||
public static Request<?> delete(String p_87341_) {
|
||||
return new Request.Delete(p_87341_, 5000, 60000);
|
||||
}
|
||||
|
||||
public static Request<?> put(String p_87354_, String p_87355_) {
|
||||
return new Request.Put(p_87354_, p_87355_, 5000, 60000);
|
||||
}
|
||||
|
||||
public static Request<?> put(String p_87346_, String p_87347_, int p_87348_, int p_87349_) {
|
||||
return new Request.Put(p_87346_, p_87347_, p_87348_, p_87349_);
|
||||
}
|
||||
|
||||
public String getHeader(String p_87352_) {
|
||||
return getHeader(this.connection, p_87352_);
|
||||
}
|
||||
|
||||
public static String getHeader(HttpURLConnection p_87333_, String p_87334_) {
|
||||
try {
|
||||
return p_87333_.getHeaderField(p_87334_);
|
||||
} catch (Exception exception) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Delete extends Request<Request.Delete> {
|
||||
public Delete(String p_87359_, int p_87360_, int p_87361_) {
|
||||
super(p_87359_, p_87360_, p_87361_);
|
||||
}
|
||||
|
||||
public Request.Delete doConnect() {
|
||||
try {
|
||||
this.connection.setDoOutput(true);
|
||||
this.connection.setRequestMethod("DELETE");
|
||||
this.connection.connect();
|
||||
return this;
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Get extends Request<Request.Get> {
|
||||
public Get(String p_87365_, int p_87366_, int p_87367_) {
|
||||
super(p_87365_, p_87366_, p_87367_);
|
||||
}
|
||||
|
||||
public Request.Get doConnect() {
|
||||
try {
|
||||
this.connection.setDoInput(true);
|
||||
this.connection.setDoOutput(true);
|
||||
this.connection.setUseCaches(false);
|
||||
this.connection.setRequestMethod("GET");
|
||||
return this;
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Post extends Request<Request.Post> {
|
||||
private final String content;
|
||||
|
||||
public Post(String p_87372_, String p_87373_, int p_87374_, int p_87375_) {
|
||||
super(p_87372_, p_87374_, p_87375_);
|
||||
this.content = p_87373_;
|
||||
}
|
||||
|
||||
public Request.Post doConnect() {
|
||||
try {
|
||||
if (this.content != null) {
|
||||
this.connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
||||
}
|
||||
|
||||
this.connection.setDoInput(true);
|
||||
this.connection.setDoOutput(true);
|
||||
this.connection.setUseCaches(false);
|
||||
this.connection.setRequestMethod("POST");
|
||||
OutputStream outputstream = this.connection.getOutputStream();
|
||||
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream, "UTF-8");
|
||||
outputstreamwriter.write(this.content);
|
||||
outputstreamwriter.close();
|
||||
outputstream.flush();
|
||||
return this;
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Put extends Request<Request.Put> {
|
||||
private final String content;
|
||||
|
||||
public Put(String p_87380_, String p_87381_, int p_87382_, int p_87383_) {
|
||||
super(p_87380_, p_87382_, p_87383_);
|
||||
this.content = p_87381_;
|
||||
}
|
||||
|
||||
public Request.Put doConnect() {
|
||||
try {
|
||||
if (this.content != null) {
|
||||
this.connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
||||
}
|
||||
|
||||
this.connection.setDoOutput(true);
|
||||
this.connection.setDoInput(true);
|
||||
this.connection.setRequestMethod("PUT");
|
||||
OutputStream outputstream = this.connection.getOutputStream();
|
||||
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream, "UTF-8");
|
||||
outputstreamwriter.write(this.content);
|
||||
outputstreamwriter.close();
|
||||
outputstream.flush();
|
||||
return this;
|
||||
} catch (Exception exception) {
|
||||
throw new RealmsHttpException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class UploadStatus {
|
||||
public volatile long bytesWritten;
|
||||
public volatile long totalBytes;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.realmsclient.client;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Backup extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public String backupId;
|
||||
public Date lastModifiedDate;
|
||||
public long size;
|
||||
private boolean uploadedVersion;
|
||||
public Map<String, String> metadata = Maps.newHashMap();
|
||||
public Map<String, String> changeList = Maps.newHashMap();
|
||||
|
||||
public static Backup parse(JsonElement p_87400_) {
|
||||
JsonObject jsonobject = p_87400_.getAsJsonObject();
|
||||
Backup backup = new Backup();
|
||||
|
||||
try {
|
||||
backup.backupId = JsonUtils.getStringOr("backupId", jsonobject, "");
|
||||
backup.lastModifiedDate = JsonUtils.getDateOr("lastModifiedDate", jsonobject);
|
||||
backup.size = JsonUtils.getLongOr("size", jsonobject, 0L);
|
||||
if (jsonobject.has("metadata")) {
|
||||
JsonObject jsonobject1 = jsonobject.getAsJsonObject("metadata");
|
||||
|
||||
for(Map.Entry<String, JsonElement> entry : jsonobject1.entrySet()) {
|
||||
if (!entry.getValue().isJsonNull()) {
|
||||
backup.metadata.put(entry.getKey(), entry.getValue().getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse Backup: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return backup;
|
||||
}
|
||||
|
||||
public boolean isUploadedVersion() {
|
||||
return this.uploadedVersion;
|
||||
}
|
||||
|
||||
public void setUploadedVersion(boolean p_87404_) {
|
||||
this.uploadedVersion = p_87404_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BackupList extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public List<Backup> backups;
|
||||
|
||||
public static BackupList parse(String p_87410_) {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
BackupList backuplist = new BackupList();
|
||||
backuplist.backups = Lists.newArrayList();
|
||||
|
||||
try {
|
||||
JsonElement jsonelement = jsonparser.parse(p_87410_).getAsJsonObject().get("backups");
|
||||
if (jsonelement.isJsonArray()) {
|
||||
Iterator<JsonElement> iterator = jsonelement.getAsJsonArray().iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
backuplist.backups.add(Backup.parse(iterator.next()));
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse BackupList: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return backuplist;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class GuardedSerializer {
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
public String toJson(ReflectionBasedSerialization p_87414_) {
|
||||
return this.gson.toJson(p_87414_);
|
||||
}
|
||||
|
||||
public String toJson(JsonElement p_275638_) {
|
||||
return this.gson.toJson(p_275638_);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T extends ReflectionBasedSerialization> T fromJson(String p_87416_, Class<T> p_87417_) {
|
||||
return this.gson.fromJson(p_87416_, p_87417_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import java.util.Set;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Ops extends ValueObject {
|
||||
public Set<String> ops = Sets.newHashSet();
|
||||
|
||||
public static Ops parse(String p_87421_) {
|
||||
Ops ops = new Ops();
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
|
||||
try {
|
||||
JsonElement jsonelement = jsonparser.parse(p_87421_);
|
||||
JsonObject jsonobject = jsonelement.getAsJsonObject();
|
||||
JsonElement jsonelement1 = jsonobject.get("ops");
|
||||
if (jsonelement1.isJsonArray()) {
|
||||
for(JsonElement jsonelement2 : jsonelement1.getAsJsonArray()) {
|
||||
ops.ops.add(jsonelement2.getAsString());
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
|
||||
return ops;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import java.util.Date;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PendingInvite extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public String invitationId;
|
||||
public String worldName;
|
||||
public String worldOwnerName;
|
||||
public String worldOwnerUuid;
|
||||
public Date date;
|
||||
|
||||
public static PendingInvite parse(JsonObject p_87431_) {
|
||||
PendingInvite pendinginvite = new PendingInvite();
|
||||
|
||||
try {
|
||||
pendinginvite.invitationId = JsonUtils.getStringOr("invitationId", p_87431_, "");
|
||||
pendinginvite.worldName = JsonUtils.getStringOr("worldName", p_87431_, "");
|
||||
pendinginvite.worldOwnerName = JsonUtils.getStringOr("worldOwnerName", p_87431_, "");
|
||||
pendinginvite.worldOwnerUuid = JsonUtils.getStringOr("worldOwnerUuid", p_87431_, "");
|
||||
pendinginvite.date = JsonUtils.getDateOr("date", p_87431_);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse PendingInvite: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return pendinginvite;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PendingInvitesList extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public List<PendingInvite> pendingInvites = Lists.newArrayList();
|
||||
|
||||
public static PendingInvitesList parse(String p_87437_) {
|
||||
PendingInvitesList pendinginviteslist = new PendingInvitesList();
|
||||
|
||||
try {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonObject jsonobject = jsonparser.parse(p_87437_).getAsJsonObject();
|
||||
if (jsonobject.get("invites").isJsonArray()) {
|
||||
Iterator<JsonElement> iterator = jsonobject.get("invites").getAsJsonArray().iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
pendinginviteslist.pendingInvites.add(PendingInvite.parse(iterator.next().getAsJsonObject()));
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse PendingInvitesList: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return pendinginviteslist;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.List;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PingResult extends ValueObject implements ReflectionBasedSerialization {
|
||||
@SerializedName("pingResults")
|
||||
public List<RegionPingResult> pingResults = Lists.newArrayList();
|
||||
@SerializedName("worldIds")
|
||||
public List<Long> worldIds = Lists.newArrayList();
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class PlayerInfo extends ValueObject implements ReflectionBasedSerialization {
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("uuid")
|
||||
private String uuid;
|
||||
@SerializedName("operator")
|
||||
private boolean operator;
|
||||
@SerializedName("accepted")
|
||||
private boolean accepted;
|
||||
@SerializedName("online")
|
||||
private boolean online;
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String p_87449_) {
|
||||
this.name = p_87449_;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String p_87454_) {
|
||||
this.uuid = p_87454_;
|
||||
}
|
||||
|
||||
public boolean isOperator() {
|
||||
return this.operator;
|
||||
}
|
||||
|
||||
public void setOperator(boolean p_87451_) {
|
||||
this.operator = p_87451_;
|
||||
}
|
||||
|
||||
public boolean getAccepted() {
|
||||
return this.accepted;
|
||||
}
|
||||
|
||||
public void setAccepted(boolean p_87456_) {
|
||||
this.accepted = p_87456_;
|
||||
}
|
||||
|
||||
public boolean getOnline() {
|
||||
return this.online;
|
||||
}
|
||||
|
||||
public void setOnline(boolean p_87459_) {
|
||||
this.online = p_87459_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsDescriptionDto extends ValueObject implements ReflectionBasedSerialization {
|
||||
@SerializedName("name")
|
||||
public String name;
|
||||
@SerializedName("description")
|
||||
public String description;
|
||||
|
||||
public RealmsDescriptionDto(String p_87465_, String p_87466_) {
|
||||
this.name = p_87465_;
|
||||
this.description = p_87466_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsNews extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public String newsLink;
|
||||
|
||||
public static RealmsNews parse(String p_87472_) {
|
||||
RealmsNews realmsnews = new RealmsNews();
|
||||
|
||||
try {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonObject jsonobject = jsonparser.parse(p_87472_).getAsJsonObject();
|
||||
realmsnews.newsLink = JsonUtils.getStringOr("newsLink", jsonobject, (String)null);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse RealmsNews: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return realmsnews;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.ConfirmLinkScreen;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsNotification {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final String NOTIFICATION_UUID = "notificationUuid";
|
||||
private static final String DISMISSABLE = "dismissable";
|
||||
private static final String SEEN = "seen";
|
||||
private static final String TYPE = "type";
|
||||
private static final String VISIT_URL = "visitUrl";
|
||||
final UUID uuid;
|
||||
final boolean dismissable;
|
||||
final boolean seen;
|
||||
final String type;
|
||||
|
||||
RealmsNotification(UUID p_275316_, boolean p_275303_, boolean p_275497_, String p_275401_) {
|
||||
this.uuid = p_275316_;
|
||||
this.dismissable = p_275303_;
|
||||
this.seen = p_275497_;
|
||||
this.type = p_275401_;
|
||||
}
|
||||
|
||||
public boolean seen() {
|
||||
return this.seen;
|
||||
}
|
||||
|
||||
public boolean dismissable() {
|
||||
return this.dismissable;
|
||||
}
|
||||
|
||||
public UUID uuid() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
public static List<RealmsNotification> parseList(String p_275464_) {
|
||||
List<RealmsNotification> list = new ArrayList<>();
|
||||
|
||||
try {
|
||||
for(JsonElement jsonelement : JsonParser.parseString(p_275464_).getAsJsonObject().get("notifications").getAsJsonArray()) {
|
||||
list.add(parse(jsonelement.getAsJsonObject()));
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse list of RealmsNotifications", (Throwable)exception);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static RealmsNotification parse(JsonObject p_275549_) {
|
||||
UUID uuid = JsonUtils.getUuidOr("notificationUuid", p_275549_, (UUID)null);
|
||||
if (uuid == null) {
|
||||
throw new IllegalStateException("Missing required property notificationUuid");
|
||||
} else {
|
||||
boolean flag = JsonUtils.getBooleanOr("dismissable", p_275549_, true);
|
||||
boolean flag1 = JsonUtils.getBooleanOr("seen", p_275549_, false);
|
||||
String s = JsonUtils.getRequiredString("type", p_275549_);
|
||||
RealmsNotification realmsnotification = new RealmsNotification(uuid, flag, flag1, s);
|
||||
return (RealmsNotification)("visitUrl".equals(s) ? RealmsNotification.VisitUrl.parse(realmsnotification, p_275549_) : realmsnotification);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class VisitUrl extends RealmsNotification {
|
||||
private static final String URL = "url";
|
||||
private static final String BUTTON_TEXT = "buttonText";
|
||||
private static final String MESSAGE = "message";
|
||||
private final String url;
|
||||
private final RealmsText buttonText;
|
||||
private final RealmsText message;
|
||||
|
||||
private VisitUrl(RealmsNotification p_275564_, String p_275312_, RealmsText p_275433_, RealmsText p_275541_) {
|
||||
super(p_275564_.uuid, p_275564_.dismissable, p_275564_.seen, p_275564_.type);
|
||||
this.url = p_275312_;
|
||||
this.buttonText = p_275433_;
|
||||
this.message = p_275541_;
|
||||
}
|
||||
|
||||
public static RealmsNotification.VisitUrl parse(RealmsNotification p_275651_, JsonObject p_275278_) {
|
||||
String s = JsonUtils.getRequiredString("url", p_275278_);
|
||||
RealmsText realmstext = JsonUtils.getRequired("buttonText", p_275278_, RealmsText::parse);
|
||||
RealmsText realmstext1 = JsonUtils.getRequired("message", p_275278_, RealmsText::parse);
|
||||
return new RealmsNotification.VisitUrl(p_275651_, s, realmstext, realmstext1);
|
||||
}
|
||||
|
||||
public Component getMessage() {
|
||||
return this.message.createComponent(Component.translatable("mco.notification.visitUrl.message.default"));
|
||||
}
|
||||
|
||||
public Button buildOpenLinkButton(Screen p_275412_) {
|
||||
Component component = this.buttonText.createComponent(Component.translatable("mco.notification.visitUrl.buttonText.default"));
|
||||
return Button.builder(component, ConfirmLinkScreen.confirmLink(this.url, p_275412_, true)).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import com.mojang.realmsclient.util.RealmsUtil;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ServerData;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsServer extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public long id;
|
||||
public String remoteSubscriptionId;
|
||||
public String name;
|
||||
public String motd;
|
||||
public RealmsServer.State state;
|
||||
public String owner;
|
||||
public String ownerUUID;
|
||||
public List<PlayerInfo> players;
|
||||
public Map<Integer, RealmsWorldOptions> slots;
|
||||
public boolean expired;
|
||||
public boolean expiredTrial;
|
||||
public int daysLeft;
|
||||
public RealmsServer.WorldType worldType;
|
||||
public int activeSlot;
|
||||
public String minigameName;
|
||||
public int minigameId;
|
||||
public String minigameImage;
|
||||
public RealmsServerPing serverPing = new RealmsServerPing();
|
||||
|
||||
public String getDescription() {
|
||||
return this.motd;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getMinigameName() {
|
||||
return this.minigameName;
|
||||
}
|
||||
|
||||
public void setName(String p_87509_) {
|
||||
this.name = p_87509_;
|
||||
}
|
||||
|
||||
public void setDescription(String p_87516_) {
|
||||
this.motd = p_87516_;
|
||||
}
|
||||
|
||||
public void updateServerPing(RealmsServerPlayerList p_87507_) {
|
||||
List<String> list = Lists.newArrayList();
|
||||
int i = 0;
|
||||
|
||||
for(String s : p_87507_.players) {
|
||||
if (!s.equals(Minecraft.getInstance().getUser().getUuid())) {
|
||||
String s1 = "";
|
||||
|
||||
try {
|
||||
s1 = RealmsUtil.uuidToName(s);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not get name for {}", s, exception);
|
||||
continue;
|
||||
}
|
||||
|
||||
list.add(s1);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
this.serverPing.nrOfPlayers = String.valueOf(i);
|
||||
this.serverPing.playerList = Joiner.on('\n').join(list);
|
||||
}
|
||||
|
||||
public static RealmsServer parse(JsonObject p_87500_) {
|
||||
RealmsServer realmsserver = new RealmsServer();
|
||||
|
||||
try {
|
||||
realmsserver.id = JsonUtils.getLongOr("id", p_87500_, -1L);
|
||||
realmsserver.remoteSubscriptionId = JsonUtils.getStringOr("remoteSubscriptionId", p_87500_, (String)null);
|
||||
realmsserver.name = JsonUtils.getStringOr("name", p_87500_, (String)null);
|
||||
realmsserver.motd = JsonUtils.getStringOr("motd", p_87500_, (String)null);
|
||||
realmsserver.state = getState(JsonUtils.getStringOr("state", p_87500_, RealmsServer.State.CLOSED.name()));
|
||||
realmsserver.owner = JsonUtils.getStringOr("owner", p_87500_, (String)null);
|
||||
if (p_87500_.get("players") != null && p_87500_.get("players").isJsonArray()) {
|
||||
realmsserver.players = parseInvited(p_87500_.get("players").getAsJsonArray());
|
||||
sortInvited(realmsserver);
|
||||
} else {
|
||||
realmsserver.players = Lists.newArrayList();
|
||||
}
|
||||
|
||||
realmsserver.daysLeft = JsonUtils.getIntOr("daysLeft", p_87500_, 0);
|
||||
realmsserver.expired = JsonUtils.getBooleanOr("expired", p_87500_, false);
|
||||
realmsserver.expiredTrial = JsonUtils.getBooleanOr("expiredTrial", p_87500_, false);
|
||||
realmsserver.worldType = getWorldType(JsonUtils.getStringOr("worldType", p_87500_, RealmsServer.WorldType.NORMAL.name()));
|
||||
realmsserver.ownerUUID = JsonUtils.getStringOr("ownerUUID", p_87500_, "");
|
||||
if (p_87500_.get("slots") != null && p_87500_.get("slots").isJsonArray()) {
|
||||
realmsserver.slots = parseSlots(p_87500_.get("slots").getAsJsonArray());
|
||||
} else {
|
||||
realmsserver.slots = createEmptySlots();
|
||||
}
|
||||
|
||||
realmsserver.minigameName = JsonUtils.getStringOr("minigameName", p_87500_, (String)null);
|
||||
realmsserver.activeSlot = JsonUtils.getIntOr("activeSlot", p_87500_, -1);
|
||||
realmsserver.minigameId = JsonUtils.getIntOr("minigameId", p_87500_, -1);
|
||||
realmsserver.minigameImage = JsonUtils.getStringOr("minigameImage", p_87500_, (String)null);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse McoServer: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return realmsserver;
|
||||
}
|
||||
|
||||
private static void sortInvited(RealmsServer p_87505_) {
|
||||
p_87505_.players.sort((p_87502_, p_87503_) -> {
|
||||
return ComparisonChain.start().compareFalseFirst(p_87503_.getAccepted(), p_87502_.getAccepted()).compare(p_87502_.getName().toLowerCase(Locale.ROOT), p_87503_.getName().toLowerCase(Locale.ROOT)).result();
|
||||
});
|
||||
}
|
||||
|
||||
private static List<PlayerInfo> parseInvited(JsonArray p_87498_) {
|
||||
List<PlayerInfo> list = Lists.newArrayList();
|
||||
|
||||
for(JsonElement jsonelement : p_87498_) {
|
||||
try {
|
||||
JsonObject jsonobject = jsonelement.getAsJsonObject();
|
||||
PlayerInfo playerinfo = new PlayerInfo();
|
||||
playerinfo.setName(JsonUtils.getStringOr("name", jsonobject, (String)null));
|
||||
playerinfo.setUuid(JsonUtils.getStringOr("uuid", jsonobject, (String)null));
|
||||
playerinfo.setOperator(JsonUtils.getBooleanOr("operator", jsonobject, false));
|
||||
playerinfo.setAccepted(JsonUtils.getBooleanOr("accepted", jsonobject, false));
|
||||
playerinfo.setOnline(JsonUtils.getBooleanOr("online", jsonobject, false));
|
||||
list.add(playerinfo);
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static Map<Integer, RealmsWorldOptions> parseSlots(JsonArray p_87514_) {
|
||||
Map<Integer, RealmsWorldOptions> map = Maps.newHashMap();
|
||||
|
||||
for(JsonElement jsonelement : p_87514_) {
|
||||
try {
|
||||
JsonObject jsonobject = jsonelement.getAsJsonObject();
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonElement jsonelement1 = jsonparser.parse(jsonobject.get("options").getAsString());
|
||||
RealmsWorldOptions realmsworldoptions;
|
||||
if (jsonelement1 == null) {
|
||||
realmsworldoptions = RealmsWorldOptions.createDefaults();
|
||||
} else {
|
||||
realmsworldoptions = RealmsWorldOptions.parse(jsonelement1.getAsJsonObject());
|
||||
}
|
||||
|
||||
int i = JsonUtils.getIntOr("slotId", jsonobject, -1);
|
||||
map.put(i, realmsworldoptions);
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
}
|
||||
|
||||
for(int j = 1; j <= 3; ++j) {
|
||||
if (!map.containsKey(j)) {
|
||||
map.put(j, RealmsWorldOptions.createEmptyDefaults());
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private static Map<Integer, RealmsWorldOptions> createEmptySlots() {
|
||||
Map<Integer, RealmsWorldOptions> map = Maps.newHashMap();
|
||||
map.put(1, RealmsWorldOptions.createEmptyDefaults());
|
||||
map.put(2, RealmsWorldOptions.createEmptyDefaults());
|
||||
map.put(3, RealmsWorldOptions.createEmptyDefaults());
|
||||
return map;
|
||||
}
|
||||
|
||||
public static RealmsServer parse(String p_87519_) {
|
||||
try {
|
||||
return parse((new JsonParser()).parse(p_87519_).getAsJsonObject());
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse McoServer: {}", (Object)exception.getMessage());
|
||||
return new RealmsServer();
|
||||
}
|
||||
}
|
||||
|
||||
private static RealmsServer.State getState(String p_87526_) {
|
||||
try {
|
||||
return RealmsServer.State.valueOf(p_87526_);
|
||||
} catch (Exception exception) {
|
||||
return RealmsServer.State.CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
private static RealmsServer.WorldType getWorldType(String p_87530_) {
|
||||
try {
|
||||
return RealmsServer.WorldType.valueOf(p_87530_);
|
||||
} catch (Exception exception) {
|
||||
return RealmsServer.WorldType.NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.id, this.name, this.motd, this.state, this.owner, this.expired);
|
||||
}
|
||||
|
||||
public boolean equals(Object p_87528_) {
|
||||
if (p_87528_ == null) {
|
||||
return false;
|
||||
} else if (p_87528_ == this) {
|
||||
return true;
|
||||
} else if (p_87528_.getClass() != this.getClass()) {
|
||||
return false;
|
||||
} else {
|
||||
RealmsServer realmsserver = (RealmsServer)p_87528_;
|
||||
return (new EqualsBuilder()).append(this.id, realmsserver.id).append((Object)this.name, (Object)realmsserver.name).append((Object)this.motd, (Object)realmsserver.motd).append((Object)this.state, (Object)realmsserver.state).append((Object)this.owner, (Object)realmsserver.owner).append(this.expired, realmsserver.expired).append((Object)this.worldType, (Object)this.worldType).isEquals();
|
||||
}
|
||||
}
|
||||
|
||||
public RealmsServer clone() {
|
||||
RealmsServer realmsserver = new RealmsServer();
|
||||
realmsserver.id = this.id;
|
||||
realmsserver.remoteSubscriptionId = this.remoteSubscriptionId;
|
||||
realmsserver.name = this.name;
|
||||
realmsserver.motd = this.motd;
|
||||
realmsserver.state = this.state;
|
||||
realmsserver.owner = this.owner;
|
||||
realmsserver.players = this.players;
|
||||
realmsserver.slots = this.cloneSlots(this.slots);
|
||||
realmsserver.expired = this.expired;
|
||||
realmsserver.expiredTrial = this.expiredTrial;
|
||||
realmsserver.daysLeft = this.daysLeft;
|
||||
realmsserver.serverPing = new RealmsServerPing();
|
||||
realmsserver.serverPing.nrOfPlayers = this.serverPing.nrOfPlayers;
|
||||
realmsserver.serverPing.playerList = this.serverPing.playerList;
|
||||
realmsserver.worldType = this.worldType;
|
||||
realmsserver.ownerUUID = this.ownerUUID;
|
||||
realmsserver.minigameName = this.minigameName;
|
||||
realmsserver.activeSlot = this.activeSlot;
|
||||
realmsserver.minigameId = this.minigameId;
|
||||
realmsserver.minigameImage = this.minigameImage;
|
||||
return realmsserver;
|
||||
}
|
||||
|
||||
public Map<Integer, RealmsWorldOptions> cloneSlots(Map<Integer, RealmsWorldOptions> p_87511_) {
|
||||
Map<Integer, RealmsWorldOptions> map = Maps.newHashMap();
|
||||
|
||||
for(Map.Entry<Integer, RealmsWorldOptions> entry : p_87511_.entrySet()) {
|
||||
map.put(entry.getKey(), entry.getValue().clone());
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public String getWorldName(int p_87496_) {
|
||||
return this.name + " (" + this.slots.get(p_87496_).getSlotName(p_87496_) + ")";
|
||||
}
|
||||
|
||||
public ServerData toServerData(String p_87523_) {
|
||||
return new ServerData(this.name, p_87523_, false);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class McoServerComparator implements Comparator<RealmsServer> {
|
||||
private final String refOwner;
|
||||
|
||||
public McoServerComparator(String p_87534_) {
|
||||
this.refOwner = p_87534_;
|
||||
}
|
||||
|
||||
public int compare(RealmsServer p_87536_, RealmsServer p_87537_) {
|
||||
return ComparisonChain.start().compareTrueFirst(p_87536_.state == RealmsServer.State.UNINITIALIZED, p_87537_.state == RealmsServer.State.UNINITIALIZED).compareTrueFirst(p_87536_.expiredTrial, p_87537_.expiredTrial).compareTrueFirst(p_87536_.owner.equals(this.refOwner), p_87537_.owner.equals(this.refOwner)).compareFalseFirst(p_87536_.expired, p_87537_.expired).compareTrueFirst(p_87536_.state == RealmsServer.State.OPEN, p_87537_.state == RealmsServer.State.OPEN).compare(p_87536_.id, p_87537_.id).result();
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum State {
|
||||
CLOSED,
|
||||
OPEN,
|
||||
UNINITIALIZED;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum WorldType {
|
||||
NORMAL,
|
||||
MINIGAME,
|
||||
ADVENTUREMAP,
|
||||
EXPERIENCE,
|
||||
INSPIRATION;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsServerAddress extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public String address;
|
||||
public String resourcePackUrl;
|
||||
public String resourcePackHash;
|
||||
|
||||
public static RealmsServerAddress parse(String p_87572_) {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
RealmsServerAddress realmsserveraddress = new RealmsServerAddress();
|
||||
|
||||
try {
|
||||
JsonObject jsonobject = jsonparser.parse(p_87572_).getAsJsonObject();
|
||||
realmsserveraddress.address = JsonUtils.getStringOr("address", jsonobject, (String)null);
|
||||
realmsserveraddress.resourcePackUrl = JsonUtils.getStringOr("resourcePackUrl", jsonobject, (String)null);
|
||||
realmsserveraddress.resourcePackHash = JsonUtils.getStringOr("resourcePackHash", jsonobject, (String)null);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse RealmsServerAddress: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return realmsserveraddress;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsServerList extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public List<RealmsServer> servers;
|
||||
|
||||
public static RealmsServerList parse(String p_87578_) {
|
||||
RealmsServerList realmsserverlist = new RealmsServerList();
|
||||
realmsserverlist.servers = Lists.newArrayList();
|
||||
|
||||
try {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonObject jsonobject = jsonparser.parse(p_87578_).getAsJsonObject();
|
||||
if (jsonobject.get("servers").isJsonArray()) {
|
||||
JsonArray jsonarray = jsonobject.get("servers").getAsJsonArray();
|
||||
Iterator<JsonElement> iterator = jsonarray.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
realmsserverlist.servers.add(RealmsServer.parse(iterator.next().getAsJsonObject()));
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse McoServerList: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return realmsserverlist;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsServerPing extends ValueObject {
|
||||
public volatile String nrOfPlayers = "0";
|
||||
public volatile String playerList = "";
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import java.util.List;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsServerPlayerList extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final JsonParser JSON_PARSER = new JsonParser();
|
||||
public long serverId;
|
||||
public List<String> players;
|
||||
|
||||
public static RealmsServerPlayerList parse(JsonObject p_87591_) {
|
||||
RealmsServerPlayerList realmsserverplayerlist = new RealmsServerPlayerList();
|
||||
|
||||
try {
|
||||
realmsserverplayerlist.serverId = JsonUtils.getLongOr("serverId", p_87591_, -1L);
|
||||
String s = JsonUtils.getStringOr("playerList", p_87591_, (String)null);
|
||||
if (s != null) {
|
||||
JsonElement jsonelement = JSON_PARSER.parse(s);
|
||||
if (jsonelement.isJsonArray()) {
|
||||
realmsserverplayerlist.players = parsePlayers(jsonelement.getAsJsonArray());
|
||||
} else {
|
||||
realmsserverplayerlist.players = Lists.newArrayList();
|
||||
}
|
||||
} else {
|
||||
realmsserverplayerlist.players = Lists.newArrayList();
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse RealmsServerPlayerList: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return realmsserverplayerlist;
|
||||
}
|
||||
|
||||
private static List<String> parsePlayers(JsonArray p_87589_) {
|
||||
List<String> list = Lists.newArrayList();
|
||||
|
||||
for(JsonElement jsonelement : p_87589_) {
|
||||
try {
|
||||
list.add(jsonelement.getAsString());
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsServerPlayerLists extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public List<RealmsServerPlayerList> servers;
|
||||
|
||||
public static RealmsServerPlayerLists parse(String p_87597_) {
|
||||
RealmsServerPlayerLists realmsserverplayerlists = new RealmsServerPlayerLists();
|
||||
realmsserverplayerlists.servers = Lists.newArrayList();
|
||||
|
||||
try {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonObject jsonobject = jsonparser.parse(p_87597_).getAsJsonObject();
|
||||
if (jsonobject.get("lists").isJsonArray()) {
|
||||
JsonArray jsonarray = jsonobject.get("lists").getAsJsonArray();
|
||||
Iterator<JsonElement> iterator = jsonarray.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
realmsserverplayerlists.servers.add(RealmsServerPlayerList.parse(iterator.next().getAsJsonObject()));
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse RealmsServerPlayerLists: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return realmsserverplayerlists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsText {
|
||||
private static final String TRANSLATION_KEY = "translationKey";
|
||||
private static final String ARGS = "args";
|
||||
private final String translationKey;
|
||||
@Nullable
|
||||
private final Object[] args;
|
||||
|
||||
private RealmsText(String p_275727_, @Nullable Object[] p_275314_) {
|
||||
this.translationKey = p_275727_;
|
||||
this.args = p_275314_;
|
||||
}
|
||||
|
||||
public Component createComponent(Component p_275681_) {
|
||||
if (!I18n.exists(this.translationKey)) {
|
||||
return p_275681_;
|
||||
} else {
|
||||
return this.args == null ? Component.translatable(this.translationKey) : Component.translatable(this.translationKey, this.args);
|
||||
}
|
||||
}
|
||||
|
||||
public static RealmsText parse(JsonObject p_275381_) {
|
||||
String s = JsonUtils.getRequiredString("translationKey", p_275381_);
|
||||
JsonElement jsonelement = p_275381_.get("args");
|
||||
String[] astring;
|
||||
if (jsonelement != null && !jsonelement.isJsonNull()) {
|
||||
JsonArray jsonarray = jsonelement.getAsJsonArray();
|
||||
astring = new String[jsonarray.size()];
|
||||
|
||||
for(int i = 0; i < jsonarray.size(); ++i) {
|
||||
astring[i] = jsonarray.get(i).getAsString();
|
||||
}
|
||||
} else {
|
||||
astring = null;
|
||||
}
|
||||
|
||||
return new RealmsText(s, astring);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsWorldOptions extends ValueObject {
|
||||
public final boolean pvp;
|
||||
public final boolean spawnAnimals;
|
||||
public final boolean spawnMonsters;
|
||||
public final boolean spawnNPCs;
|
||||
public final int spawnProtection;
|
||||
public final boolean commandBlocks;
|
||||
public final boolean forceGameMode;
|
||||
public final int difficulty;
|
||||
public final int gameMode;
|
||||
@Nullable
|
||||
private final String slotName;
|
||||
public long templateId;
|
||||
@Nullable
|
||||
public String templateImage;
|
||||
public boolean empty;
|
||||
private static final boolean DEFAULT_FORCE_GAME_MODE = false;
|
||||
private static final boolean DEFAULT_PVP = true;
|
||||
private static final boolean DEFAULT_SPAWN_ANIMALS = true;
|
||||
private static final boolean DEFAULT_SPAWN_MONSTERS = true;
|
||||
private static final boolean DEFAULT_SPAWN_NPCS = true;
|
||||
private static final int DEFAULT_SPAWN_PROTECTION = 0;
|
||||
private static final boolean DEFAULT_COMMAND_BLOCKS = false;
|
||||
private static final int DEFAULT_DIFFICULTY = 2;
|
||||
private static final int DEFAULT_GAME_MODE = 0;
|
||||
private static final String DEFAULT_SLOT_NAME = "";
|
||||
private static final long DEFAULT_TEMPLATE_ID = -1L;
|
||||
private static final String DEFAULT_TEMPLATE_IMAGE = null;
|
||||
|
||||
public RealmsWorldOptions(boolean p_167302_, boolean p_167303_, boolean p_167304_, boolean p_167305_, int p_167306_, boolean p_167307_, int p_167308_, int p_167309_, boolean p_167310_, @Nullable String p_167311_) {
|
||||
this.pvp = p_167302_;
|
||||
this.spawnAnimals = p_167303_;
|
||||
this.spawnMonsters = p_167304_;
|
||||
this.spawnNPCs = p_167305_;
|
||||
this.spawnProtection = p_167306_;
|
||||
this.commandBlocks = p_167307_;
|
||||
this.difficulty = p_167308_;
|
||||
this.gameMode = p_167309_;
|
||||
this.forceGameMode = p_167310_;
|
||||
this.slotName = p_167311_;
|
||||
}
|
||||
|
||||
public static RealmsWorldOptions createDefaults() {
|
||||
return new RealmsWorldOptions(true, true, true, true, 0, false, 2, 0, false, "");
|
||||
}
|
||||
|
||||
public static RealmsWorldOptions createEmptyDefaults() {
|
||||
RealmsWorldOptions realmsworldoptions = createDefaults();
|
||||
realmsworldoptions.setEmpty(true);
|
||||
return realmsworldoptions;
|
||||
}
|
||||
|
||||
public void setEmpty(boolean p_87631_) {
|
||||
this.empty = p_87631_;
|
||||
}
|
||||
|
||||
public static RealmsWorldOptions parse(JsonObject p_87629_) {
|
||||
RealmsWorldOptions realmsworldoptions = new RealmsWorldOptions(JsonUtils.getBooleanOr("pvp", p_87629_, true), JsonUtils.getBooleanOr("spawnAnimals", p_87629_, true), JsonUtils.getBooleanOr("spawnMonsters", p_87629_, true), JsonUtils.getBooleanOr("spawnNPCs", p_87629_, true), JsonUtils.getIntOr("spawnProtection", p_87629_, 0), JsonUtils.getBooleanOr("commandBlocks", p_87629_, false), JsonUtils.getIntOr("difficulty", p_87629_, 2), JsonUtils.getIntOr("gameMode", p_87629_, 0), JsonUtils.getBooleanOr("forceGameMode", p_87629_, false), JsonUtils.getStringOr("slotName", p_87629_, ""));
|
||||
realmsworldoptions.templateId = JsonUtils.getLongOr("worldTemplateId", p_87629_, -1L);
|
||||
realmsworldoptions.templateImage = JsonUtils.getStringOr("worldTemplateImage", p_87629_, DEFAULT_TEMPLATE_IMAGE);
|
||||
return realmsworldoptions;
|
||||
}
|
||||
|
||||
public String getSlotName(int p_87627_) {
|
||||
if (this.slotName != null && !this.slotName.isEmpty()) {
|
||||
return this.slotName;
|
||||
} else {
|
||||
return this.empty ? I18n.get("mco.configure.world.slot.empty") : this.getDefaultSlotName(p_87627_);
|
||||
}
|
||||
}
|
||||
|
||||
public String getDefaultSlotName(int p_87634_) {
|
||||
return I18n.get("mco.configure.world.slot", p_87634_);
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (!this.pvp) {
|
||||
jsonobject.addProperty("pvp", this.pvp);
|
||||
}
|
||||
|
||||
if (!this.spawnAnimals) {
|
||||
jsonobject.addProperty("spawnAnimals", this.spawnAnimals);
|
||||
}
|
||||
|
||||
if (!this.spawnMonsters) {
|
||||
jsonobject.addProperty("spawnMonsters", this.spawnMonsters);
|
||||
}
|
||||
|
||||
if (!this.spawnNPCs) {
|
||||
jsonobject.addProperty("spawnNPCs", this.spawnNPCs);
|
||||
}
|
||||
|
||||
if (this.spawnProtection != 0) {
|
||||
jsonobject.addProperty("spawnProtection", this.spawnProtection);
|
||||
}
|
||||
|
||||
if (this.commandBlocks) {
|
||||
jsonobject.addProperty("commandBlocks", this.commandBlocks);
|
||||
}
|
||||
|
||||
if (this.difficulty != 2) {
|
||||
jsonobject.addProperty("difficulty", this.difficulty);
|
||||
}
|
||||
|
||||
if (this.gameMode != 0) {
|
||||
jsonobject.addProperty("gameMode", this.gameMode);
|
||||
}
|
||||
|
||||
if (this.forceGameMode) {
|
||||
jsonobject.addProperty("forceGameMode", this.forceGameMode);
|
||||
}
|
||||
|
||||
if (!Objects.equals(this.slotName, "")) {
|
||||
jsonobject.addProperty("slotName", this.slotName);
|
||||
}
|
||||
|
||||
return jsonobject.toString();
|
||||
}
|
||||
|
||||
public RealmsWorldOptions clone() {
|
||||
return new RealmsWorldOptions(this.pvp, this.spawnAnimals, this.spawnMonsters, this.spawnNPCs, this.spawnProtection, this.commandBlocks, this.difficulty, this.gameMode, this.forceGameMode, this.slotName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsWorldResetDto extends ValueObject implements ReflectionBasedSerialization {
|
||||
@SerializedName("seed")
|
||||
private final String seed;
|
||||
@SerializedName("worldTemplateId")
|
||||
private final long worldTemplateId;
|
||||
@SerializedName("levelType")
|
||||
private final int levelType;
|
||||
@SerializedName("generateStructures")
|
||||
private final boolean generateStructures;
|
||||
|
||||
public RealmsWorldResetDto(String p_87643_, long p_87644_, int p_87645_, boolean p_87646_) {
|
||||
this.seed = p_87643_;
|
||||
this.worldTemplateId = p_87644_;
|
||||
this.levelType = p_87645_;
|
||||
this.generateStructures = p_87646_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ReflectionBasedSerialization {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.Locale;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RegionPingResult extends ValueObject implements ReflectionBasedSerialization {
|
||||
@SerializedName("regionName")
|
||||
private final String regionName;
|
||||
@SerializedName("ping")
|
||||
private final int ping;
|
||||
|
||||
public RegionPingResult(String p_87650_, int p_87651_) {
|
||||
this.regionName = p_87650_;
|
||||
this.ping = p_87651_;
|
||||
}
|
||||
|
||||
public int ping() {
|
||||
return this.ping;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format(Locale.ROOT, "%s --> %.2f ms", this.regionName, (float)this.ping);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ServerActivity extends ValueObject {
|
||||
public String profileUuid;
|
||||
public long joinTime;
|
||||
public long leaveTime;
|
||||
|
||||
public static ServerActivity parse(JsonObject p_167317_) {
|
||||
ServerActivity serveractivity = new ServerActivity();
|
||||
|
||||
try {
|
||||
serveractivity.profileUuid = JsonUtils.getStringOr("profileUuid", p_167317_, (String)null);
|
||||
serveractivity.joinTime = JsonUtils.getLongOr("joinTime", p_167317_, Long.MIN_VALUE);
|
||||
serveractivity.leaveTime = JsonUtils.getLongOr("leaveTime", p_167317_, Long.MIN_VALUE);
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
|
||||
return serveractivity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import java.util.List;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ServerActivityList extends ValueObject {
|
||||
public long periodInMillis;
|
||||
public List<ServerActivity> serverActivities = Lists.newArrayList();
|
||||
|
||||
public static ServerActivityList parse(String p_167322_) {
|
||||
ServerActivityList serveractivitylist = new ServerActivityList();
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
|
||||
try {
|
||||
JsonElement jsonelement = jsonparser.parse(p_167322_);
|
||||
JsonObject jsonobject = jsonelement.getAsJsonObject();
|
||||
serveractivitylist.periodInMillis = JsonUtils.getLongOr("periodInMillis", jsonobject, -1L);
|
||||
JsonElement jsonelement1 = jsonobject.get("playerActivityDto");
|
||||
if (jsonelement1 != null && jsonelement1.isJsonArray()) {
|
||||
for(JsonElement jsonelement2 : jsonelement1.getAsJsonArray()) {
|
||||
ServerActivity serveractivity = ServerActivity.parse(jsonelement2.getAsJsonObject());
|
||||
serveractivitylist.serverActivities.add(serveractivity);
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
|
||||
return serveractivitylist;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Subscription extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public long startDate;
|
||||
public int daysLeft;
|
||||
public Subscription.SubscriptionType type = Subscription.SubscriptionType.NORMAL;
|
||||
|
||||
public static Subscription parse(String p_87673_) {
|
||||
Subscription subscription = new Subscription();
|
||||
|
||||
try {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonObject jsonobject = jsonparser.parse(p_87673_).getAsJsonObject();
|
||||
subscription.startDate = JsonUtils.getLongOr("startDate", jsonobject, 0L);
|
||||
subscription.daysLeft = JsonUtils.getIntOr("daysLeft", jsonobject, 0);
|
||||
subscription.type = typeFrom(JsonUtils.getStringOr("subscriptionType", jsonobject, Subscription.SubscriptionType.NORMAL.name()));
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse Subscription: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
||||
private static Subscription.SubscriptionType typeFrom(String p_87675_) {
|
||||
try {
|
||||
return Subscription.SubscriptionType.valueOf(p_87675_);
|
||||
} catch (Exception exception) {
|
||||
return Subscription.SubscriptionType.NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum SubscriptionType {
|
||||
NORMAL,
|
||||
RECURRING;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class UploadInfo extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final String DEFAULT_SCHEMA = "http://";
|
||||
private static final int DEFAULT_PORT = 8080;
|
||||
private static final Pattern URI_SCHEMA_PATTERN = Pattern.compile("^[a-zA-Z][-a-zA-Z0-9+.]+:");
|
||||
private final boolean worldClosed;
|
||||
@Nullable
|
||||
private final String token;
|
||||
private final URI uploadEndpoint;
|
||||
|
||||
private UploadInfo(boolean p_87693_, @Nullable String p_87694_, URI p_87695_) {
|
||||
this.worldClosed = p_87693_;
|
||||
this.token = p_87694_;
|
||||
this.uploadEndpoint = p_87695_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static UploadInfo parse(String p_87701_) {
|
||||
try {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonObject jsonobject = jsonparser.parse(p_87701_).getAsJsonObject();
|
||||
String s = JsonUtils.getStringOr("uploadEndpoint", jsonobject, (String)null);
|
||||
if (s != null) {
|
||||
int i = JsonUtils.getIntOr("port", jsonobject, -1);
|
||||
URI uri = assembleUri(s, i);
|
||||
if (uri != null) {
|
||||
boolean flag = JsonUtils.getBooleanOr("worldClosed", jsonobject, false);
|
||||
String s1 = JsonUtils.getStringOr("token", jsonobject, (String)null);
|
||||
return new UploadInfo(flag, s1, uri);
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse UploadInfo: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@VisibleForTesting
|
||||
public static URI assembleUri(String p_87703_, int p_87704_) {
|
||||
Matcher matcher = URI_SCHEMA_PATTERN.matcher(p_87703_);
|
||||
String s = ensureEndpointSchema(p_87703_, matcher);
|
||||
|
||||
try {
|
||||
URI uri = new URI(s);
|
||||
int i = selectPortOrDefault(p_87704_, uri.getPort());
|
||||
return i != uri.getPort() ? new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), i, uri.getPath(), uri.getQuery(), uri.getFragment()) : uri;
|
||||
} catch (URISyntaxException urisyntaxexception) {
|
||||
LOGGER.warn("Failed to parse URI {}", s, urisyntaxexception);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static int selectPortOrDefault(int p_87698_, int p_87699_) {
|
||||
if (p_87698_ != -1) {
|
||||
return p_87698_;
|
||||
} else {
|
||||
return p_87699_ != -1 ? p_87699_ : 8080;
|
||||
}
|
||||
}
|
||||
|
||||
private static String ensureEndpointSchema(String p_87706_, Matcher p_87707_) {
|
||||
return p_87707_.find() ? p_87706_ : "http://" + p_87706_;
|
||||
}
|
||||
|
||||
public static String createRequest(@Nullable String p_87710_) {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (p_87710_ != null) {
|
||||
jsonobject.addProperty("token", p_87710_);
|
||||
}
|
||||
|
||||
return jsonobject.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getToken() {
|
||||
return this.token;
|
||||
}
|
||||
|
||||
public URI getUploadEndpoint() {
|
||||
return this.uploadEndpoint;
|
||||
}
|
||||
|
||||
public boolean isWorldClosed() {
|
||||
return this.worldClosed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class ValueObject {
|
||||
public String toString() {
|
||||
StringBuilder stringbuilder = new StringBuilder("{");
|
||||
|
||||
for(Field field : this.getClass().getFields()) {
|
||||
if (!isStatic(field)) {
|
||||
try {
|
||||
stringbuilder.append(getName(field)).append("=").append(field.get(this)).append(" ");
|
||||
} catch (IllegalAccessException illegalaccessexception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stringbuilder.deleteCharAt(stringbuilder.length() - 1);
|
||||
stringbuilder.append('}');
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
private static String getName(Field p_87714_) {
|
||||
SerializedName serializedname = p_87714_.getAnnotation(SerializedName.class);
|
||||
return serializedname != null ? serializedname.value() : p_87714_.getName();
|
||||
}
|
||||
|
||||
private static boolean isStatic(Field p_87716_) {
|
||||
return Modifier.isStatic(p_87716_.getModifiers());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class WorldDownload extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public String downloadLink;
|
||||
public String resourcePackUrl;
|
||||
public String resourcePackHash;
|
||||
|
||||
public static WorldDownload parse(String p_87725_) {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonObject jsonobject = jsonparser.parse(p_87725_).getAsJsonObject();
|
||||
WorldDownload worlddownload = new WorldDownload();
|
||||
|
||||
try {
|
||||
worlddownload.downloadLink = JsonUtils.getStringOr("downloadLink", jsonobject, "");
|
||||
worlddownload.resourcePackUrl = JsonUtils.getStringOr("resourcePackUrl", jsonobject, "");
|
||||
worlddownload.resourcePackHash = JsonUtils.getStringOr("resourcePackHash", jsonobject, "");
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse WorldDownload: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return worlddownload;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class WorldTemplate extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public String id = "";
|
||||
public String name = "";
|
||||
public String version = "";
|
||||
public String author = "";
|
||||
public String link = "";
|
||||
@Nullable
|
||||
public String image;
|
||||
public String trailer = "";
|
||||
public String recommendedPlayers = "";
|
||||
public WorldTemplate.WorldTemplateType type = WorldTemplate.WorldTemplateType.WORLD_TEMPLATE;
|
||||
|
||||
public static WorldTemplate parse(JsonObject p_87739_) {
|
||||
WorldTemplate worldtemplate = new WorldTemplate();
|
||||
|
||||
try {
|
||||
worldtemplate.id = JsonUtils.getStringOr("id", p_87739_, "");
|
||||
worldtemplate.name = JsonUtils.getStringOr("name", p_87739_, "");
|
||||
worldtemplate.version = JsonUtils.getStringOr("version", p_87739_, "");
|
||||
worldtemplate.author = JsonUtils.getStringOr("author", p_87739_, "");
|
||||
worldtemplate.link = JsonUtils.getStringOr("link", p_87739_, "");
|
||||
worldtemplate.image = JsonUtils.getStringOr("image", p_87739_, (String)null);
|
||||
worldtemplate.trailer = JsonUtils.getStringOr("trailer", p_87739_, "");
|
||||
worldtemplate.recommendedPlayers = JsonUtils.getStringOr("recommendedPlayers", p_87739_, "");
|
||||
worldtemplate.type = WorldTemplate.WorldTemplateType.valueOf(JsonUtils.getStringOr("type", p_87739_, WorldTemplate.WorldTemplateType.WORLD_TEMPLATE.name()));
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse WorldTemplate: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return worldtemplate;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum WorldTemplateType {
|
||||
WORLD_TEMPLATE,
|
||||
MINIGAME,
|
||||
ADVENTUREMAP,
|
||||
EXPERIENCE,
|
||||
INSPIRATION;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.util.JsonUtils;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class WorldTemplatePaginatedList extends ValueObject {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
public List<WorldTemplate> templates;
|
||||
public int page;
|
||||
public int size;
|
||||
public int total;
|
||||
|
||||
public WorldTemplatePaginatedList() {
|
||||
}
|
||||
|
||||
public WorldTemplatePaginatedList(int p_87761_) {
|
||||
this.templates = Collections.emptyList();
|
||||
this.page = 0;
|
||||
this.size = p_87761_;
|
||||
this.total = -1;
|
||||
}
|
||||
|
||||
public boolean isLastPage() {
|
||||
return this.page * this.size >= this.total && this.page > 0 && this.total > 0 && this.size > 0;
|
||||
}
|
||||
|
||||
public static WorldTemplatePaginatedList parse(String p_87763_) {
|
||||
WorldTemplatePaginatedList worldtemplatepaginatedlist = new WorldTemplatePaginatedList();
|
||||
worldtemplatepaginatedlist.templates = Lists.newArrayList();
|
||||
|
||||
try {
|
||||
JsonParser jsonparser = new JsonParser();
|
||||
JsonObject jsonobject = jsonparser.parse(p_87763_).getAsJsonObject();
|
||||
if (jsonobject.get("templates").isJsonArray()) {
|
||||
Iterator<JsonElement> iterator = jsonobject.get("templates").getAsJsonArray().iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
worldtemplatepaginatedlist.templates.add(WorldTemplate.parse(iterator.next().getAsJsonObject()));
|
||||
}
|
||||
}
|
||||
|
||||
worldtemplatepaginatedlist.page = JsonUtils.getIntOr("page", jsonobject, 0);
|
||||
worldtemplatepaginatedlist.size = JsonUtils.getIntOr("size", jsonobject, 0);
|
||||
worldtemplatepaginatedlist.total = JsonUtils.getIntOr("total", jsonobject, 0);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Could not parse WorldTemplatePaginatedList: {}", (Object)exception.getMessage());
|
||||
}
|
||||
|
||||
return worldtemplatepaginatedlist;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.realmsclient.dto;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.mojang.realmsclient.exception;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsDefaultUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
private final Logger logger;
|
||||
|
||||
public RealmsDefaultUncaughtExceptionHandler(Logger p_202332_) {
|
||||
this.logger = p_202332_;
|
||||
}
|
||||
|
||||
public void uncaughtException(Thread p_87768_, Throwable p_87769_) {
|
||||
this.logger.error("Caught previously unhandled exception", p_87769_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mojang.realmsclient.exception;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsHttpException extends RuntimeException {
|
||||
public RealmsHttpException(String p_87771_, Exception p_87772_) {
|
||||
super(p_87771_, p_87772_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.mojang.realmsclient.exception;
|
||||
|
||||
import com.mojang.realmsclient.client.RealmsError;
|
||||
import java.util.Locale;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsServiceException extends Exception {
|
||||
public final int httpResultCode;
|
||||
public final String rawResponse;
|
||||
@Nullable
|
||||
public final RealmsError realmsError;
|
||||
|
||||
public RealmsServiceException(int p_87783_, String p_87784_, RealmsError p_87785_) {
|
||||
super(p_87784_);
|
||||
this.httpResultCode = p_87783_;
|
||||
this.rawResponse = p_87784_;
|
||||
this.realmsError = p_87785_;
|
||||
}
|
||||
|
||||
public RealmsServiceException(int p_200943_, String p_200944_) {
|
||||
super(p_200944_);
|
||||
this.httpResultCode = p_200943_;
|
||||
this.rawResponse = p_200944_;
|
||||
this.realmsError = null;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
if (this.realmsError != null) {
|
||||
String s = "mco.errorMessage." + this.realmsError.getErrorCode();
|
||||
String s1 = I18n.exists(s) ? I18n.get(s) : this.realmsError.getErrorMessage();
|
||||
return String.format(Locale.ROOT, "Realms service error (%d/%d) %s", this.httpResultCode, this.realmsError.getErrorCode(), s1);
|
||||
} else {
|
||||
return String.format(Locale.ROOT, "Realms service error (%d) %s", this.httpResultCode, this.rawResponse);
|
||||
}
|
||||
}
|
||||
|
||||
public int realmsErrorCodeOrDefault(int p_200946_) {
|
||||
return this.realmsError != null ? this.realmsError.getErrorCode() : p_200946_;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.mojang.realmsclient.exception;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RetryCallException extends RealmsServiceException {
|
||||
public static final int DEFAULT_DELAY = 5;
|
||||
public final int delaySeconds;
|
||||
|
||||
public RetryCallException(int p_87789_, int p_87790_) {
|
||||
super(p_87790_, "Retry operation");
|
||||
if (p_87789_ >= 0 && p_87789_ <= 120) {
|
||||
this.delaySeconds = p_87789_;
|
||||
} else {
|
||||
this.delaySeconds = 5;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.realmsclient.exception;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.mojang.realmsclient.gui;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface ErrorCallback {
|
||||
void error(Component p_87793_);
|
||||
|
||||
default void error(String p_87792_) {
|
||||
this.error(Component.literal(p_87792_));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.mojang.realmsclient.gui;
|
||||
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsNews;
|
||||
import com.mojang.realmsclient.dto.RealmsNotification;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.RealmsServerPlayerLists;
|
||||
import com.mojang.realmsclient.gui.task.DataFetcher;
|
||||
import com.mojang.realmsclient.gui.task.RepeatedDelayStrategy;
|
||||
import com.mojang.realmsclient.util.RealmsPersistence;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsDataFetcher {
|
||||
public final DataFetcher dataFetcher = new DataFetcher(Util.ioPool(), TimeUnit.MILLISECONDS, Util.timeSource);
|
||||
public final DataFetcher.Task<List<RealmsNotification>> notificationsTask;
|
||||
public final DataFetcher.Task<List<RealmsServer>> serverListUpdateTask;
|
||||
public final DataFetcher.Task<RealmsServerPlayerLists> liveStatsTask;
|
||||
public final DataFetcher.Task<Integer> pendingInvitesTask;
|
||||
public final DataFetcher.Task<Boolean> trialAvailabilityTask;
|
||||
public final DataFetcher.Task<RealmsNews> newsTask;
|
||||
public final RealmsNewsManager newsManager = new RealmsNewsManager(new RealmsPersistence());
|
||||
|
||||
public RealmsDataFetcher(RealmsClient p_238853_) {
|
||||
this.serverListUpdateTask = this.dataFetcher.createTask("server list", () -> {
|
||||
return p_238853_.listWorlds().servers;
|
||||
}, Duration.ofSeconds(60L), RepeatedDelayStrategy.CONSTANT);
|
||||
this.liveStatsTask = this.dataFetcher.createTask("live stats", p_238853_::getLiveStats, Duration.ofSeconds(10L), RepeatedDelayStrategy.CONSTANT);
|
||||
this.pendingInvitesTask = this.dataFetcher.createTask("pending invite count", p_238853_::pendingInvitesCount, Duration.ofSeconds(10L), RepeatedDelayStrategy.exponentialBackoff(360));
|
||||
this.trialAvailabilityTask = this.dataFetcher.createTask("trial availablity", p_238853_::trialAvailable, Duration.ofSeconds(60L), RepeatedDelayStrategy.exponentialBackoff(60));
|
||||
this.newsTask = this.dataFetcher.createTask("unread news", p_238853_::getNews, Duration.ofMinutes(5L), RepeatedDelayStrategy.CONSTANT);
|
||||
this.notificationsTask = this.dataFetcher.createTask("notifications", p_238853_::getNotifications, Duration.ofMinutes(5L), RepeatedDelayStrategy.CONSTANT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.mojang.realmsclient.gui;
|
||||
|
||||
import com.mojang.realmsclient.dto.RealmsNews;
|
||||
import com.mojang.realmsclient.util.RealmsPersistence;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsNewsManager {
|
||||
private final RealmsPersistence newsLocalStorage;
|
||||
private boolean hasUnreadNews;
|
||||
private String newsLink;
|
||||
|
||||
public RealmsNewsManager(RealmsPersistence p_239304_) {
|
||||
this.newsLocalStorage = p_239304_;
|
||||
RealmsPersistence.RealmsPersistenceData realmspersistence$realmspersistencedata = p_239304_.read();
|
||||
this.hasUnreadNews = realmspersistence$realmspersistencedata.hasUnreadNews;
|
||||
this.newsLink = realmspersistence$realmspersistencedata.newsLink;
|
||||
}
|
||||
|
||||
public boolean hasUnreadNews() {
|
||||
return this.hasUnreadNews;
|
||||
}
|
||||
|
||||
public String newsLink() {
|
||||
return this.newsLink;
|
||||
}
|
||||
|
||||
public void updateUnreadNews(RealmsNews p_239191_) {
|
||||
RealmsPersistence.RealmsPersistenceData realmspersistence$realmspersistencedata = this.updateNewsStorage(p_239191_);
|
||||
this.hasUnreadNews = realmspersistence$realmspersistencedata.hasUnreadNews;
|
||||
this.newsLink = realmspersistence$realmspersistencedata.newsLink;
|
||||
}
|
||||
|
||||
private RealmsPersistence.RealmsPersistenceData updateNewsStorage(RealmsNews p_240153_) {
|
||||
RealmsPersistence.RealmsPersistenceData realmspersistence$realmspersistencedata = new RealmsPersistence.RealmsPersistenceData();
|
||||
realmspersistence$realmspersistencedata.newsLink = p_240153_.newsLink;
|
||||
RealmsPersistence.RealmsPersistenceData realmspersistence$realmspersistencedata1 = this.newsLocalStorage.read();
|
||||
boolean flag = realmspersistence$realmspersistencedata.newsLink == null || realmspersistence$realmspersistencedata.newsLink.equals(realmspersistence$realmspersistencedata1.newsLink);
|
||||
if (flag) {
|
||||
return realmspersistence$realmspersistencedata1;
|
||||
} else {
|
||||
realmspersistence$realmspersistencedata.hasUnreadNews = true;
|
||||
this.newsLocalStorage.save(realmspersistence$realmspersistencedata);
|
||||
return realmspersistence$realmspersistencedata;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.mojang.realmsclient.gui;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsServerList {
|
||||
private final Minecraft minecraft;
|
||||
private final Set<RealmsServer> removedServers = Sets.newHashSet();
|
||||
private List<RealmsServer> servers = Lists.newArrayList();
|
||||
|
||||
public RealmsServerList(Minecraft p_239233_) {
|
||||
this.minecraft = p_239233_;
|
||||
}
|
||||
|
||||
public List<RealmsServer> updateServersList(List<RealmsServer> p_239869_) {
|
||||
List<RealmsServer> list = new ArrayList<>(p_239869_);
|
||||
list.sort(new RealmsServer.McoServerComparator(this.minecraft.getUser().getName()));
|
||||
boolean flag = list.removeAll(this.removedServers);
|
||||
if (!flag) {
|
||||
this.removedServers.clear();
|
||||
}
|
||||
|
||||
this.servers = list;
|
||||
return List.copyOf(this.servers);
|
||||
}
|
||||
|
||||
public synchronized List<RealmsServer> removeItem(RealmsServer p_240077_) {
|
||||
this.servers.remove(p_240077_);
|
||||
this.removedServers.add(p_240077_);
|
||||
return List.copyOf(this.servers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
package com.mojang.realmsclient.gui;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.RealmsWorldOptions;
|
||||
import com.mojang.realmsclient.util.RealmsTextureManager;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsWorldSlotButton extends Button {
|
||||
public static final ResourceLocation SLOT_FRAME_LOCATION = new ResourceLocation("realms", "textures/gui/realms/slot_frame.png");
|
||||
public static final ResourceLocation EMPTY_SLOT_LOCATION = new ResourceLocation("realms", "textures/gui/realms/empty_frame.png");
|
||||
public static final ResourceLocation CHECK_MARK_LOCATION = new ResourceLocation("minecraft", "textures/gui/checkmark.png");
|
||||
public static final ResourceLocation DEFAULT_WORLD_SLOT_1 = new ResourceLocation("minecraft", "textures/gui/title/background/panorama_0.png");
|
||||
public static final ResourceLocation DEFAULT_WORLD_SLOT_2 = new ResourceLocation("minecraft", "textures/gui/title/background/panorama_2.png");
|
||||
public static final ResourceLocation DEFAULT_WORLD_SLOT_3 = new ResourceLocation("minecraft", "textures/gui/title/background/panorama_3.png");
|
||||
private static final Component SLOT_ACTIVE_TOOLTIP = Component.translatable("mco.configure.world.slot.tooltip.active");
|
||||
private static final Component SWITCH_TO_MINIGAME_SLOT_TOOLTIP = Component.translatable("mco.configure.world.slot.tooltip.minigame");
|
||||
private static final Component SWITCH_TO_WORLD_SLOT_TOOLTIP = Component.translatable("mco.configure.world.slot.tooltip");
|
||||
private static final Component MINIGAME = Component.translatable("mco.worldSlot.minigame");
|
||||
private final Supplier<RealmsServer> serverDataProvider;
|
||||
private final Consumer<Component> toolTipSetter;
|
||||
private final int slotIndex;
|
||||
@Nullable
|
||||
private RealmsWorldSlotButton.State state;
|
||||
|
||||
public RealmsWorldSlotButton(int p_87929_, int p_87930_, int p_87931_, int p_87932_, Supplier<RealmsServer> p_87933_, Consumer<Component> p_87934_, int p_87935_, Button.OnPress p_87936_) {
|
||||
super(p_87929_, p_87930_, p_87931_, p_87932_, CommonComponents.EMPTY, p_87936_, DEFAULT_NARRATION);
|
||||
this.serverDataProvider = p_87933_;
|
||||
this.slotIndex = p_87935_;
|
||||
this.toolTipSetter = p_87934_;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RealmsWorldSlotButton.State getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
RealmsServer realmsserver = this.serverDataProvider.get();
|
||||
if (realmsserver != null) {
|
||||
RealmsWorldOptions realmsworldoptions = realmsserver.slots.get(this.slotIndex);
|
||||
boolean flag2 = this.slotIndex == 4;
|
||||
boolean flag;
|
||||
String s;
|
||||
long i;
|
||||
String s1;
|
||||
boolean flag1;
|
||||
if (flag2) {
|
||||
flag = realmsserver.worldType == RealmsServer.WorldType.MINIGAME;
|
||||
s = MINIGAME.getString();
|
||||
i = (long)realmsserver.minigameId;
|
||||
s1 = realmsserver.minigameImage;
|
||||
flag1 = realmsserver.minigameId == -1;
|
||||
} else {
|
||||
flag = realmsserver.activeSlot == this.slotIndex && realmsserver.worldType != RealmsServer.WorldType.MINIGAME;
|
||||
s = realmsworldoptions.getSlotName(this.slotIndex);
|
||||
i = realmsworldoptions.templateId;
|
||||
s1 = realmsworldoptions.templateImage;
|
||||
flag1 = realmsworldoptions.empty;
|
||||
}
|
||||
|
||||
RealmsWorldSlotButton.Action realmsworldslotbutton$action = getAction(realmsserver, flag, flag2);
|
||||
Pair<Component, Component> pair = this.getTooltipAndNarration(realmsserver, s, flag1, flag2, realmsworldslotbutton$action);
|
||||
this.state = new RealmsWorldSlotButton.State(flag, s, i, s1, flag1, flag2, realmsworldslotbutton$action, pair.getFirst());
|
||||
this.setMessage(pair.getSecond());
|
||||
}
|
||||
}
|
||||
|
||||
private static RealmsWorldSlotButton.Action getAction(RealmsServer p_87960_, boolean p_87961_, boolean p_87962_) {
|
||||
if (p_87961_) {
|
||||
if (!p_87960_.expired && p_87960_.state != RealmsServer.State.UNINITIALIZED) {
|
||||
return RealmsWorldSlotButton.Action.JOIN;
|
||||
}
|
||||
} else {
|
||||
if (!p_87962_) {
|
||||
return RealmsWorldSlotButton.Action.SWITCH_SLOT;
|
||||
}
|
||||
|
||||
if (!p_87960_.expired) {
|
||||
return RealmsWorldSlotButton.Action.SWITCH_SLOT;
|
||||
}
|
||||
}
|
||||
|
||||
return RealmsWorldSlotButton.Action.NOTHING;
|
||||
}
|
||||
|
||||
private Pair<Component, Component> getTooltipAndNarration(RealmsServer p_87954_, String p_87955_, boolean p_87956_, boolean p_87957_, RealmsWorldSlotButton.Action p_87958_) {
|
||||
if (p_87958_ == RealmsWorldSlotButton.Action.NOTHING) {
|
||||
return Pair.of((Component)null, Component.literal(p_87955_));
|
||||
} else {
|
||||
Component component;
|
||||
if (p_87957_) {
|
||||
if (p_87956_) {
|
||||
component = CommonComponents.EMPTY;
|
||||
} else {
|
||||
component = CommonComponents.space().append(p_87955_).append(CommonComponents.SPACE).append(p_87954_.minigameName);
|
||||
}
|
||||
} else {
|
||||
component = CommonComponents.space().append(p_87955_);
|
||||
}
|
||||
|
||||
Component component1;
|
||||
if (p_87958_ == RealmsWorldSlotButton.Action.JOIN) {
|
||||
component1 = SLOT_ACTIVE_TOOLTIP;
|
||||
} else {
|
||||
component1 = p_87957_ ? SWITCH_TO_MINIGAME_SLOT_TOOLTIP : SWITCH_TO_WORLD_SLOT_TOOLTIP;
|
||||
}
|
||||
|
||||
Component component2 = component1.copy().append(component);
|
||||
return Pair.of(component1, component2);
|
||||
}
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_282947_, int p_87965_, int p_87966_, float p_87967_) {
|
||||
if (this.state != null) {
|
||||
this.drawSlotFrame(p_282947_, this.getX(), this.getY(), p_87965_, p_87966_, this.state.isCurrentlyActiveSlot, this.state.slotName, this.slotIndex, this.state.imageId, this.state.image, this.state.empty, this.state.minigame, this.state.action, this.state.actionPrompt);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawSlotFrame(GuiGraphics p_282493_, int p_282407_, int p_283212_, int p_283646_, int p_283633_, boolean p_282019_, String p_283553_, int p_283521_, long p_281546_, @Nullable String p_283361_, boolean p_283516_, boolean p_281611_, RealmsWorldSlotButton.Action p_281804_, @Nullable Component p_282910_) {
|
||||
boolean flag = this.isHoveredOrFocused();
|
||||
if (this.isMouseOver((double)p_283646_, (double)p_283633_) && p_282910_ != null) {
|
||||
this.toolTipSetter.accept(p_282910_);
|
||||
}
|
||||
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
ResourceLocation resourcelocation;
|
||||
if (p_281611_) {
|
||||
resourcelocation = RealmsTextureManager.worldTemplate(String.valueOf(p_281546_), p_283361_);
|
||||
} else if (p_283516_) {
|
||||
resourcelocation = EMPTY_SLOT_LOCATION;
|
||||
} else if (p_283361_ != null && p_281546_ != -1L) {
|
||||
resourcelocation = RealmsTextureManager.worldTemplate(String.valueOf(p_281546_), p_283361_);
|
||||
} else if (p_283521_ == 1) {
|
||||
resourcelocation = DEFAULT_WORLD_SLOT_1;
|
||||
} else if (p_283521_ == 2) {
|
||||
resourcelocation = DEFAULT_WORLD_SLOT_2;
|
||||
} else if (p_283521_ == 3) {
|
||||
resourcelocation = DEFAULT_WORLD_SLOT_3;
|
||||
} else {
|
||||
resourcelocation = EMPTY_SLOT_LOCATION;
|
||||
}
|
||||
|
||||
if (p_282019_) {
|
||||
p_282493_.setColor(0.56F, 0.56F, 0.56F, 1.0F);
|
||||
}
|
||||
|
||||
p_282493_.blit(resourcelocation, p_282407_ + 3, p_283212_ + 3, 0.0F, 0.0F, 74, 74, 74, 74);
|
||||
boolean flag1 = flag && p_281804_ != RealmsWorldSlotButton.Action.NOTHING;
|
||||
if (flag1) {
|
||||
p_282493_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
} else if (p_282019_) {
|
||||
p_282493_.setColor(0.8F, 0.8F, 0.8F, 1.0F);
|
||||
} else {
|
||||
p_282493_.setColor(0.56F, 0.56F, 0.56F, 1.0F);
|
||||
}
|
||||
|
||||
p_282493_.blit(SLOT_FRAME_LOCATION, p_282407_, p_283212_, 0.0F, 0.0F, 80, 80, 80, 80);
|
||||
p_282493_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
if (p_282019_) {
|
||||
this.renderCheckMark(p_282493_, p_282407_, p_283212_);
|
||||
}
|
||||
|
||||
p_282493_.drawCenteredString(minecraft.font, p_283553_, p_282407_ + 40, p_283212_ + 66, 16777215);
|
||||
}
|
||||
|
||||
private void renderCheckMark(GuiGraphics p_281366_, int p_281849_, int p_283407_) {
|
||||
RenderSystem.enableBlend();
|
||||
p_281366_.blit(CHECK_MARK_LOCATION, p_281849_ + 67, p_283407_ + 4, 0.0F, 0.0F, 9, 8, 9, 8);
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Action {
|
||||
NOTHING,
|
||||
SWITCH_SLOT,
|
||||
JOIN;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class State {
|
||||
final boolean isCurrentlyActiveSlot;
|
||||
final String slotName;
|
||||
final long imageId;
|
||||
@Nullable
|
||||
final String image;
|
||||
public final boolean empty;
|
||||
public final boolean minigame;
|
||||
public final RealmsWorldSlotButton.Action action;
|
||||
@Nullable
|
||||
final Component actionPrompt;
|
||||
|
||||
State(boolean p_87989_, String p_87990_, long p_87991_, @Nullable String p_87992_, boolean p_87993_, boolean p_87994_, RealmsWorldSlotButton.Action p_87995_, @Nullable Component p_87996_) {
|
||||
this.isCurrentlyActiveSlot = p_87989_;
|
||||
this.slotName = p_87990_;
|
||||
this.imageId = p_87991_;
|
||||
this.image = p_87992_;
|
||||
this.empty = p_87993_;
|
||||
this.minigame = p_87994_;
|
||||
this.action = p_87995_;
|
||||
this.actionPrompt = p_87996_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.mojang.realmsclient.gui;
|
||||
|
||||
import java.util.List;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.ObjectSelectionList;
|
||||
import net.minecraft.realms.RealmsObjectSelectionList;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class RowButton {
|
||||
public final int width;
|
||||
public final int height;
|
||||
public final int xOffset;
|
||||
public final int yOffset;
|
||||
|
||||
public RowButton(int p_88012_, int p_88013_, int p_88014_, int p_88015_) {
|
||||
this.width = p_88012_;
|
||||
this.height = p_88013_;
|
||||
this.xOffset = p_88014_;
|
||||
this.yOffset = p_88015_;
|
||||
}
|
||||
|
||||
public void drawForRowAt(GuiGraphics p_281584_, int p_88020_, int p_88021_, int p_88022_, int p_88023_) {
|
||||
int i = p_88020_ + this.xOffset;
|
||||
int j = p_88021_ + this.yOffset;
|
||||
boolean flag = p_88022_ >= i && p_88022_ <= i + this.width && p_88023_ >= j && p_88023_ <= j + this.height;
|
||||
this.draw(p_281584_, i, j, flag);
|
||||
}
|
||||
|
||||
protected abstract void draw(GuiGraphics p_281291_, int p_88025_, int p_88026_, boolean p_88027_);
|
||||
|
||||
public int getRight() {
|
||||
return this.xOffset + this.width;
|
||||
}
|
||||
|
||||
public int getBottom() {
|
||||
return this.yOffset + this.height;
|
||||
}
|
||||
|
||||
public abstract void onClick(int p_88017_);
|
||||
|
||||
public static void drawButtonsInRow(GuiGraphics p_281401_, List<RowButton> p_283164_, RealmsObjectSelectionList<?> p_282348_, int p_282527_, int p_281326_, int p_281575_, int p_282538_) {
|
||||
for(RowButton rowbutton : p_283164_) {
|
||||
if (p_282348_.getRowWidth() > rowbutton.getRight()) {
|
||||
rowbutton.drawForRowAt(p_281401_, p_282527_, p_281326_, p_281575_, p_282538_);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void rowButtonMouseClicked(RealmsObjectSelectionList<?> p_88037_, ObjectSelectionList.Entry<?> p_88038_, List<RowButton> p_88039_, int p_88040_, double p_88041_, double p_88042_) {
|
||||
if (p_88040_ == 0) {
|
||||
int i = p_88037_.children().indexOf(p_88038_);
|
||||
if (i > -1) {
|
||||
p_88037_.selectItem(i);
|
||||
int j = p_88037_.getRowLeft();
|
||||
int k = p_88037_.getRowTop(i);
|
||||
int l = (int)(p_88041_ - (double)j);
|
||||
int i1 = (int)(p_88042_ - (double)k);
|
||||
|
||||
for(RowButton rowbutton : p_88039_) {
|
||||
if (l >= rowbutton.xOffset && l <= rowbutton.getRight() && i1 >= rowbutton.yOffset && i1 <= rowbutton.getBottom()) {
|
||||
rowbutton.onClick(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.realmsclient.gui;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.realmsclient.dto.Backup;
|
||||
import java.util.Locale;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.ObjectSelectionList;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsBackupInfoScreen extends RealmsScreen {
|
||||
private static final Component UNKNOWN = Component.translatable("mco.backup.unknown");
|
||||
private final Screen lastScreen;
|
||||
final Backup backup;
|
||||
private RealmsBackupInfoScreen.BackupInfoList backupInfoList;
|
||||
|
||||
public RealmsBackupInfoScreen(Screen p_88048_, Backup p_88049_) {
|
||||
super(Component.translatable("mco.backup.info.title"));
|
||||
this.lastScreen = p_88048_;
|
||||
this.backup = p_88049_;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_280689_) -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}).bounds(this.width / 2 - 100, this.height / 4 + 120 + 24, 200, 20).build());
|
||||
this.backupInfoList = new RealmsBackupInfoScreen.BackupInfoList(this.minecraft);
|
||||
this.addWidget(this.backupInfoList);
|
||||
this.magicalSpecialHackyFocus(this.backupInfoList);
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88051_, int p_88052_, int p_88053_) {
|
||||
if (p_88051_ == 256) {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_88051_, p_88052_, p_88053_);
|
||||
}
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282729_, int p_282525_, int p_281883_, float p_281644_) {
|
||||
this.renderBackground(p_282729_);
|
||||
this.backupInfoList.render(p_282729_, p_282525_, p_281883_, p_281644_);
|
||||
p_282729_.drawCenteredString(this.font, this.title, this.width / 2, 10, 16777215);
|
||||
super.render(p_282729_, p_282525_, p_281883_, p_281644_);
|
||||
}
|
||||
|
||||
Component checkForSpecificMetadata(String p_88068_, String p_88069_) {
|
||||
String s = p_88068_.toLowerCase(Locale.ROOT);
|
||||
if (s.contains("game") && s.contains("mode")) {
|
||||
return this.gameModeMetadata(p_88069_);
|
||||
} else {
|
||||
return (Component)(s.contains("game") && s.contains("difficulty") ? this.gameDifficultyMetadata(p_88069_) : Component.literal(p_88069_));
|
||||
}
|
||||
}
|
||||
|
||||
private Component gameDifficultyMetadata(String p_88074_) {
|
||||
try {
|
||||
return RealmsSlotOptionsScreen.DIFFICULTIES.get(Integer.parseInt(p_88074_)).getDisplayName();
|
||||
} catch (Exception exception) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private Component gameModeMetadata(String p_88076_) {
|
||||
try {
|
||||
return RealmsSlotOptionsScreen.GAME_MODES.get(Integer.parseInt(p_88076_)).getShortDisplayName();
|
||||
} catch (Exception exception) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class BackupInfoList extends ObjectSelectionList<RealmsBackupInfoScreen.BackupInfoListEntry> {
|
||||
public BackupInfoList(Minecraft p_88082_) {
|
||||
super(p_88082_, RealmsBackupInfoScreen.this.width, RealmsBackupInfoScreen.this.height, 32, RealmsBackupInfoScreen.this.height - 64, 36);
|
||||
this.setRenderSelection(false);
|
||||
if (RealmsBackupInfoScreen.this.backup.changeList != null) {
|
||||
RealmsBackupInfoScreen.this.backup.changeList.forEach((p_88084_, p_88085_) -> {
|
||||
this.addEntry(RealmsBackupInfoScreen.this.new BackupInfoListEntry(p_88084_, p_88085_));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class BackupInfoListEntry extends ObjectSelectionList.Entry<RealmsBackupInfoScreen.BackupInfoListEntry> {
|
||||
private static final Component TEMPLATE_NAME = Component.translatable("mco.backup.entry.templateName");
|
||||
private static final Component GAME_DIFFICULTY = Component.translatable("mco.backup.entry.gameDifficulty");
|
||||
private static final Component NAME = Component.translatable("mco.backup.entry.name");
|
||||
private static final Component GAME_SERVER_VERSION = Component.translatable("mco.backup.entry.gameServerVersion");
|
||||
private static final Component UPLOADED = Component.translatable("mco.backup.entry.uploaded");
|
||||
private static final Component ENABLED_PACK = Component.translatable("mco.backup.entry.enabledPack");
|
||||
private static final Component DESCRIPTION = Component.translatable("mco.backup.entry.description");
|
||||
private static final Component GAME_MODE = Component.translatable("mco.backup.entry.gameMode");
|
||||
private static final Component SEED = Component.translatable("mco.backup.entry.seed");
|
||||
private static final Component WORLD_TYPE = Component.translatable("mco.backup.entry.worldType");
|
||||
private static final Component UNDEFINED = Component.translatable("mco.backup.entry.undefined");
|
||||
private final String key;
|
||||
private final String value;
|
||||
|
||||
public BackupInfoListEntry(String p_88091_, String p_88092_) {
|
||||
this.key = p_88091_;
|
||||
this.value = p_88092_;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282911_, int p_281482_, int p_283643_, int p_282795_, int p_283291_, int p_282540_, int p_282181_, int p_283535_, boolean p_281916_, float p_282116_) {
|
||||
p_282911_.drawString(RealmsBackupInfoScreen.this.font, this.translateKey(this.key), p_282795_, p_283643_, 10526880);
|
||||
p_282911_.drawString(RealmsBackupInfoScreen.this.font, RealmsBackupInfoScreen.this.checkForSpecificMetadata(this.key, this.value), p_282795_, p_283643_ + 12, 16777215);
|
||||
}
|
||||
|
||||
private Component translateKey(String p_287652_) {
|
||||
Component component;
|
||||
switch (p_287652_) {
|
||||
case "template_name":
|
||||
component = TEMPLATE_NAME;
|
||||
break;
|
||||
case "game_difficulty":
|
||||
component = GAME_DIFFICULTY;
|
||||
break;
|
||||
case "name":
|
||||
component = NAME;
|
||||
break;
|
||||
case "game_server_version":
|
||||
component = GAME_SERVER_VERSION;
|
||||
break;
|
||||
case "uploaded":
|
||||
component = UPLOADED;
|
||||
break;
|
||||
case "enabled_pack":
|
||||
component = ENABLED_PACK;
|
||||
break;
|
||||
case "description":
|
||||
component = DESCRIPTION;
|
||||
break;
|
||||
case "game_mode":
|
||||
component = GAME_MODE;
|
||||
break;
|
||||
case "seed":
|
||||
component = SEED;
|
||||
break;
|
||||
case "world_type":
|
||||
component = WORLD_TYPE;
|
||||
break;
|
||||
default:
|
||||
component = UNDEFINED;
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
public Component getNarration() {
|
||||
return Component.translatable("narrator.select", this.key + " " + this.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.Backup;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.util.RealmsUtil;
|
||||
import com.mojang.realmsclient.util.task.DownloadTask;
|
||||
import com.mojang.realmsclient.util.task.RestoreTask;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.ImageButton;
|
||||
import net.minecraft.client.gui.components.ObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.Tooltip;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsObjectSelectionList;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsBackupScreen extends RealmsScreen {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
static final ResourceLocation PLUS_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/plus_icon.png");
|
||||
static final ResourceLocation RESTORE_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/restore_icon.png");
|
||||
static final Component RESTORE_TOOLTIP = Component.translatable("mco.backup.button.restore");
|
||||
static final Component HAS_CHANGES_TOOLTIP = Component.translatable("mco.backup.changes.tooltip");
|
||||
private static final Component TITLE = Component.translatable("mco.configure.world.backup");
|
||||
private static final Component NO_BACKUPS_LABEL = Component.translatable("mco.backup.nobackups");
|
||||
private final RealmsConfigureWorldScreen lastScreen;
|
||||
List<Backup> backups = Collections.emptyList();
|
||||
RealmsBackupScreen.BackupObjectSelectionList backupObjectSelectionList;
|
||||
int selectedBackup = -1;
|
||||
private final int slotId;
|
||||
private Button downloadButton;
|
||||
private Button restoreButton;
|
||||
private Button changesButton;
|
||||
Boolean noBackups = false;
|
||||
final RealmsServer serverData;
|
||||
private static final String UPLOADED_KEY = "uploaded";
|
||||
|
||||
public RealmsBackupScreen(RealmsConfigureWorldScreen p_88126_, RealmsServer p_88127_, int p_88128_) {
|
||||
super(Component.translatable("mco.configure.world.backup"));
|
||||
this.lastScreen = p_88126_;
|
||||
this.serverData = p_88127_;
|
||||
this.slotId = p_88128_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.backupObjectSelectionList = new RealmsBackupScreen.BackupObjectSelectionList();
|
||||
(new Thread("Realms-fetch-backups") {
|
||||
public void run() {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
List<Backup> list = realmsclient.backupsFor(RealmsBackupScreen.this.serverData.id).backups;
|
||||
RealmsBackupScreen.this.minecraft.execute(() -> {
|
||||
RealmsBackupScreen.this.backups = list;
|
||||
RealmsBackupScreen.this.noBackups = RealmsBackupScreen.this.backups.isEmpty();
|
||||
RealmsBackupScreen.this.backupObjectSelectionList.clear();
|
||||
|
||||
for(Backup backup : RealmsBackupScreen.this.backups) {
|
||||
RealmsBackupScreen.this.backupObjectSelectionList.addEntry(backup);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
RealmsBackupScreen.LOGGER.error("Couldn't request backups", (Throwable)realmsserviceexception);
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
this.downloadButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.backup.button.download"), (p_88185_) -> {
|
||||
this.downloadClicked();
|
||||
}).bounds(this.width - 135, row(1), 120, 20).build());
|
||||
this.restoreButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.backup.button.restore"), (p_88179_) -> {
|
||||
this.restoreClicked(this.selectedBackup);
|
||||
}).bounds(this.width - 135, row(3), 120, 20).build());
|
||||
this.changesButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.backup.changes.tooltip"), (p_280692_) -> {
|
||||
this.minecraft.setScreen(new RealmsBackupInfoScreen(this, this.backups.get(this.selectedBackup)));
|
||||
this.selectedBackup = -1;
|
||||
}).bounds(this.width - 135, row(5), 120, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_280691_) -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}).bounds(this.width - 100, this.height - 35, 85, 20).build());
|
||||
this.addWidget(this.backupObjectSelectionList);
|
||||
this.magicalSpecialHackyFocus(this.backupObjectSelectionList);
|
||||
this.updateButtonStates();
|
||||
}
|
||||
|
||||
void updateButtonStates() {
|
||||
this.restoreButton.visible = this.shouldRestoreButtonBeVisible();
|
||||
this.changesButton.visible = this.shouldChangesButtonBeVisible();
|
||||
}
|
||||
|
||||
private boolean shouldChangesButtonBeVisible() {
|
||||
if (this.selectedBackup == -1) {
|
||||
return false;
|
||||
} else {
|
||||
return !(this.backups.get(this.selectedBackup)).changeList.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldRestoreButtonBeVisible() {
|
||||
if (this.selectedBackup == -1) {
|
||||
return false;
|
||||
} else {
|
||||
return !this.serverData.expired;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88133_, int p_88134_, int p_88135_) {
|
||||
if (p_88133_ == 256) {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_88133_, p_88134_, p_88135_);
|
||||
}
|
||||
}
|
||||
|
||||
void restoreClicked(int p_88167_) {
|
||||
if (p_88167_ >= 0 && p_88167_ < this.backups.size() && !this.serverData.expired) {
|
||||
this.selectedBackup = p_88167_;
|
||||
Date date = (this.backups.get(p_88167_)).lastModifiedDate;
|
||||
String s = DateFormat.getDateTimeInstance(3, 3).format(date);
|
||||
Component component = RealmsUtil.convertToAgePresentationFromInstant(date);
|
||||
Component component1 = Component.translatable("mco.configure.world.restore.question.line1", s, component);
|
||||
Component component2 = Component.translatable("mco.configure.world.restore.question.line2");
|
||||
this.minecraft.setScreen(new RealmsLongConfirmationScreen((p_280693_) -> {
|
||||
if (p_280693_) {
|
||||
this.restore();
|
||||
} else {
|
||||
this.selectedBackup = -1;
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
}, RealmsLongConfirmationScreen.Type.WARNING, component1, component2, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void downloadClicked() {
|
||||
Component component = Component.translatable("mco.configure.world.restore.download.question.line1");
|
||||
Component component1 = Component.translatable("mco.configure.world.restore.download.question.line2");
|
||||
this.minecraft.setScreen(new RealmsLongConfirmationScreen((p_280690_) -> {
|
||||
if (p_280690_) {
|
||||
this.downloadWorldData();
|
||||
} else {
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
}, RealmsLongConfirmationScreen.Type.INFO, component, component1, true));
|
||||
}
|
||||
|
||||
private void downloadWorldData() {
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this.lastScreen.getNewScreen(), new DownloadTask(this.serverData.id, this.slotId, this.serverData.name + " (" + this.serverData.slots.get(this.serverData.activeSlot).getSlotName(this.serverData.activeSlot) + ")", this)));
|
||||
}
|
||||
|
||||
private void restore() {
|
||||
Backup backup = this.backups.get(this.selectedBackup);
|
||||
this.selectedBackup = -1;
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this.lastScreen.getNewScreen(), new RestoreTask(backup, this.serverData.id, this.lastScreen)));
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_283405_, int p_282020_, int p_282404_, float p_281280_) {
|
||||
this.renderBackground(p_283405_);
|
||||
this.backupObjectSelectionList.render(p_283405_, p_282020_, p_282404_, p_281280_);
|
||||
p_283405_.drawCenteredString(this.font, this.title, this.width / 2, 12, 16777215);
|
||||
p_283405_.drawString(this.font, TITLE, (this.width - 150) / 2 - 90, 20, 10526880, false);
|
||||
if (this.noBackups) {
|
||||
p_283405_.drawString(this.font, NO_BACKUPS_LABEL, 20, this.height / 2 - 10, 16777215, false);
|
||||
}
|
||||
|
||||
this.downloadButton.active = !this.noBackups;
|
||||
super.render(p_283405_, p_282020_, p_282404_, p_281280_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class BackupObjectSelectionList extends RealmsObjectSelectionList<RealmsBackupScreen.Entry> {
|
||||
public BackupObjectSelectionList() {
|
||||
super(RealmsBackupScreen.this.width - 150, RealmsBackupScreen.this.height, 32, RealmsBackupScreen.this.height - 15, 36);
|
||||
}
|
||||
|
||||
public void addEntry(Backup p_88235_) {
|
||||
this.addEntry(RealmsBackupScreen.this.new Entry(p_88235_));
|
||||
}
|
||||
|
||||
public int getRowWidth() {
|
||||
return (int)((double)this.width * 0.93D);
|
||||
}
|
||||
|
||||
public int getMaxPosition() {
|
||||
return this.getItemCount() * 36;
|
||||
}
|
||||
|
||||
public void renderBackground(GuiGraphics p_282900_) {
|
||||
RealmsBackupScreen.this.renderBackground(p_282900_);
|
||||
}
|
||||
|
||||
public int getScrollbarPosition() {
|
||||
return this.width - 5;
|
||||
}
|
||||
|
||||
public void selectItem(int p_88225_) {
|
||||
super.selectItem(p_88225_);
|
||||
this.selectInviteListItem(p_88225_);
|
||||
}
|
||||
|
||||
public void selectInviteListItem(int p_88242_) {
|
||||
RealmsBackupScreen.this.selectedBackup = p_88242_;
|
||||
RealmsBackupScreen.this.updateButtonStates();
|
||||
}
|
||||
|
||||
public void setSelected(@Nullable RealmsBackupScreen.Entry p_88237_) {
|
||||
super.setSelected(p_88237_);
|
||||
RealmsBackupScreen.this.selectedBackup = this.children().indexOf(p_88237_);
|
||||
RealmsBackupScreen.this.updateButtonStates();
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class Entry extends ObjectSelectionList.Entry<RealmsBackupScreen.Entry> {
|
||||
private static final int Y_PADDING = 2;
|
||||
private static final int X_PADDING = 7;
|
||||
private final Backup backup;
|
||||
private final List<AbstractWidget> children = new ArrayList<>();
|
||||
@Nullable
|
||||
private ImageButton restoreButton;
|
||||
@Nullable
|
||||
private ImageButton changesButton;
|
||||
|
||||
public Entry(Backup p_88250_) {
|
||||
this.backup = p_88250_;
|
||||
this.populateChangeList(p_88250_);
|
||||
if (!p_88250_.changeList.isEmpty()) {
|
||||
this.addChangesButton();
|
||||
}
|
||||
|
||||
if (!RealmsBackupScreen.this.serverData.expired) {
|
||||
this.addRestoreButton();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void populateChangeList(Backup p_279365_) {
|
||||
int i = RealmsBackupScreen.this.backups.indexOf(p_279365_);
|
||||
if (i != RealmsBackupScreen.this.backups.size() - 1) {
|
||||
Backup backup = RealmsBackupScreen.this.backups.get(i + 1);
|
||||
|
||||
for(String s : p_279365_.metadata.keySet()) {
|
||||
if (!s.contains("uploaded") && backup.metadata.containsKey(s)) {
|
||||
if (!p_279365_.metadata.get(s).equals(backup.metadata.get(s))) {
|
||||
this.addToChangeList(s);
|
||||
}
|
||||
} else {
|
||||
this.addToChangeList(s);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void addToChangeList(String p_279195_) {
|
||||
if (p_279195_.contains("uploaded")) {
|
||||
String s = DateFormat.getDateTimeInstance(3, 3).format(this.backup.lastModifiedDate);
|
||||
this.backup.changeList.put(p_279195_, s);
|
||||
this.backup.setUploadedVersion(true);
|
||||
} else {
|
||||
this.backup.changeList.put(p_279195_, this.backup.metadata.get(p_279195_));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addChangesButton() {
|
||||
int i = 9;
|
||||
int j = 9;
|
||||
int k = RealmsBackupScreen.this.backupObjectSelectionList.getRowRight() - 9 - 28;
|
||||
int l = RealmsBackupScreen.this.backupObjectSelectionList.getRowTop(RealmsBackupScreen.this.backups.indexOf(this.backup)) + 2;
|
||||
this.changesButton = new ImageButton(k, l, 9, 9, 0, 0, 9, RealmsBackupScreen.PLUS_ICON_LOCATION, 9, 18, (p_279278_) -> {
|
||||
RealmsBackupScreen.this.minecraft.setScreen(new RealmsBackupInfoScreen(RealmsBackupScreen.this, this.backup));
|
||||
});
|
||||
this.changesButton.setTooltip(Tooltip.create(RealmsBackupScreen.HAS_CHANGES_TOOLTIP));
|
||||
this.children.add(this.changesButton);
|
||||
}
|
||||
|
||||
private void addRestoreButton() {
|
||||
int i = 17;
|
||||
int j = 10;
|
||||
int k = RealmsBackupScreen.this.backupObjectSelectionList.getRowRight() - 17 - 7;
|
||||
int l = RealmsBackupScreen.this.backupObjectSelectionList.getRowTop(RealmsBackupScreen.this.backups.indexOf(this.backup)) + 2;
|
||||
this.restoreButton = new ImageButton(k, l, 17, 10, 0, 0, 10, RealmsBackupScreen.RESTORE_ICON_LOCATION, 17, 20, (p_279191_) -> {
|
||||
RealmsBackupScreen.this.restoreClicked(RealmsBackupScreen.this.backups.indexOf(this.backup));
|
||||
});
|
||||
this.restoreButton.setTooltip(Tooltip.create(RealmsBackupScreen.RESTORE_TOOLTIP));
|
||||
this.children.add(this.restoreButton);
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_279279_, double p_279118_, int p_279445_) {
|
||||
if (this.restoreButton != null) {
|
||||
this.restoreButton.mouseClicked(p_279279_, p_279118_, p_279445_);
|
||||
}
|
||||
|
||||
if (this.changesButton != null) {
|
||||
this.changesButton.mouseClicked(p_279279_, p_279118_, p_279445_);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281408_, int p_281974_, int p_282495_, int p_282463_, int p_281562_, int p_282782_, int p_281638_, int p_283190_, boolean p_283105_, float p_282066_) {
|
||||
int i = this.backup.isUploadedVersion() ? -8388737 : 16777215;
|
||||
p_281408_.drawString(RealmsBackupScreen.this.font, Component.translatable("mco.backup.entry", RealmsUtil.convertToAgePresentationFromInstant(this.backup.lastModifiedDate)), p_282463_, p_282495_ + 1, i, false);
|
||||
p_281408_.drawString(RealmsBackupScreen.this.font, this.getMediumDatePresentation(this.backup.lastModifiedDate), p_282463_, p_282495_ + 12, 5000268, false);
|
||||
this.children.forEach((p_280700_) -> {
|
||||
p_280700_.setY(p_282495_ + 2);
|
||||
p_280700_.render(p_281408_, p_281638_, p_283190_, p_282066_);
|
||||
});
|
||||
}
|
||||
|
||||
private String getMediumDatePresentation(Date p_88276_) {
|
||||
return DateFormat.getDateTimeInstance(3, 3).format(p_88276_);
|
||||
}
|
||||
|
||||
public Component getNarration() {
|
||||
return Component.translatable("narrator.select", this.backup.lastModifiedDate.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.RealmsMainScreen;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.RealmsWorldOptions;
|
||||
import com.mojang.realmsclient.dto.WorldDownload;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.gui.RealmsWorldSlotButton;
|
||||
import com.mojang.realmsclient.util.RealmsTextureManager;
|
||||
import com.mojang.realmsclient.util.task.OpenServerTask;
|
||||
import com.mojang.realmsclient.util.task.SwitchSlotTask;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.ComponentUtils;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsBrokenWorldScreen extends RealmsScreen {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int DEFAULT_BUTTON_WIDTH = 80;
|
||||
private final Screen lastScreen;
|
||||
private final RealmsMainScreen mainScreen;
|
||||
@Nullable
|
||||
private RealmsServer serverData;
|
||||
private final long serverId;
|
||||
private final Component[] message = new Component[]{Component.translatable("mco.brokenworld.message.line1"), Component.translatable("mco.brokenworld.message.line2")};
|
||||
private int leftX;
|
||||
private int rightX;
|
||||
private final List<Integer> slotsThatHasBeenDownloaded = Lists.newArrayList();
|
||||
private int animTick;
|
||||
|
||||
public RealmsBrokenWorldScreen(Screen p_88296_, RealmsMainScreen p_88297_, long p_88298_, boolean p_88299_) {
|
||||
super(p_88299_ ? Component.translatable("mco.brokenworld.minigame.title") : Component.translatable("mco.brokenworld.title"));
|
||||
this.lastScreen = p_88296_;
|
||||
this.mainScreen = p_88297_;
|
||||
this.serverId = p_88298_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.leftX = this.width / 2 - 150;
|
||||
this.rightX = this.width / 2 + 190;
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_88333_) -> {
|
||||
this.backButtonClicked();
|
||||
}).bounds(this.rightX - 80 + 8, row(13) - 5, 70, 20).build());
|
||||
if (this.serverData == null) {
|
||||
this.fetchServerData(this.serverId);
|
||||
} else {
|
||||
this.addButtons();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return ComponentUtils.formatList(Stream.concat(Stream.of(this.title), Stream.of(this.message)).collect(Collectors.toList()), CommonComponents.SPACE);
|
||||
}
|
||||
|
||||
private void addButtons() {
|
||||
for(Map.Entry<Integer, RealmsWorldOptions> entry : this.serverData.slots.entrySet()) {
|
||||
int i = entry.getKey();
|
||||
boolean flag = i != this.serverData.activeSlot || this.serverData.worldType == RealmsServer.WorldType.MINIGAME;
|
||||
Button button;
|
||||
if (flag) {
|
||||
button = Button.builder(Component.translatable("mco.brokenworld.play"), (p_88347_) -> {
|
||||
if ((this.serverData.slots.get(i)).empty) {
|
||||
RealmsResetWorldScreen realmsresetworldscreen = new RealmsResetWorldScreen(this, this.serverData, Component.translatable("mco.configure.world.switch.slot"), Component.translatable("mco.configure.world.switch.slot.subtitle"), 10526880, CommonComponents.GUI_CANCEL, this::doSwitchOrReset, () -> {
|
||||
this.minecraft.setScreen(this);
|
||||
this.doSwitchOrReset();
|
||||
});
|
||||
realmsresetworldscreen.setSlot(i);
|
||||
realmsresetworldscreen.setResetTitle(Component.translatable("mco.create.world.reset.title"));
|
||||
this.minecraft.setScreen(realmsresetworldscreen);
|
||||
} else {
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this.lastScreen, new SwitchSlotTask(this.serverData.id, i, this::doSwitchOrReset)));
|
||||
}
|
||||
|
||||
}).bounds(this.getFramePositionX(i), row(8), 80, 20).build();
|
||||
} else {
|
||||
button = Button.builder(Component.translatable("mco.brokenworld.download"), (p_287302_) -> {
|
||||
Component component = Component.translatable("mco.configure.world.restore.download.question.line1");
|
||||
Component component1 = Component.translatable("mco.configure.world.restore.download.question.line2");
|
||||
this.minecraft.setScreen(new RealmsLongConfirmationScreen((p_280705_) -> {
|
||||
if (p_280705_) {
|
||||
this.downloadWorld(i);
|
||||
} else {
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
}, RealmsLongConfirmationScreen.Type.INFO, component, component1, true));
|
||||
}).bounds(this.getFramePositionX(i), row(8), 80, 20).build();
|
||||
}
|
||||
|
||||
if (this.slotsThatHasBeenDownloaded.contains(i)) {
|
||||
button.active = false;
|
||||
button.setMessage(Component.translatable("mco.brokenworld.downloaded"));
|
||||
}
|
||||
|
||||
this.addRenderableWidget(button);
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("mco.brokenworld.reset"), (p_280707_) -> {
|
||||
RealmsResetWorldScreen realmsresetworldscreen = new RealmsResetWorldScreen(this, this.serverData, this::doSwitchOrReset, () -> {
|
||||
this.minecraft.setScreen(this);
|
||||
this.doSwitchOrReset();
|
||||
});
|
||||
if (i != this.serverData.activeSlot || this.serverData.worldType == RealmsServer.WorldType.MINIGAME) {
|
||||
realmsresetworldscreen.setSlot(i);
|
||||
}
|
||||
|
||||
this.minecraft.setScreen(realmsresetworldscreen);
|
||||
}).bounds(this.getFramePositionX(i), row(10), 80, 20).build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
++this.animTick;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282934_, int p_88317_, int p_88318_, float p_88319_) {
|
||||
this.renderBackground(p_282934_);
|
||||
super.render(p_282934_, p_88317_, p_88318_, p_88319_);
|
||||
p_282934_.drawCenteredString(this.font, this.title, this.width / 2, 17, 16777215);
|
||||
|
||||
for(int i = 0; i < this.message.length; ++i) {
|
||||
p_282934_.drawCenteredString(this.font, this.message[i], this.width / 2, row(-1) + 3 + i * 12, 10526880);
|
||||
}
|
||||
|
||||
if (this.serverData != null) {
|
||||
for(Map.Entry<Integer, RealmsWorldOptions> entry : this.serverData.slots.entrySet()) {
|
||||
if ((entry.getValue()).templateImage != null && (entry.getValue()).templateId != -1L) {
|
||||
this.drawSlotFrame(p_282934_, this.getFramePositionX(entry.getKey()), row(1) + 5, p_88317_, p_88318_, this.serverData.activeSlot == entry.getKey() && !this.isMinigame(), entry.getValue().getSlotName(entry.getKey()), entry.getKey(), (entry.getValue()).templateId, (entry.getValue()).templateImage, (entry.getValue()).empty);
|
||||
} else {
|
||||
this.drawSlotFrame(p_282934_, this.getFramePositionX(entry.getKey()), row(1) + 5, p_88317_, p_88318_, this.serverData.activeSlot == entry.getKey() && !this.isMinigame(), entry.getValue().getSlotName(entry.getKey()), entry.getKey(), -1L, (String)null, (entry.getValue()).empty);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private int getFramePositionX(int p_88302_) {
|
||||
return this.leftX + (p_88302_ - 1) * 110;
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88304_, int p_88305_, int p_88306_) {
|
||||
if (p_88304_ == 256) {
|
||||
this.backButtonClicked();
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_88304_, p_88305_, p_88306_);
|
||||
}
|
||||
}
|
||||
|
||||
private void backButtonClicked() {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}
|
||||
|
||||
private void fetchServerData(long p_88314_) {
|
||||
(new Thread(() -> {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
this.serverData = realmsclient.getOwnWorld(p_88314_);
|
||||
this.addButtons();
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't get own world");
|
||||
this.minecraft.setScreen(new RealmsGenericErrorScreen(Component.nullToEmpty(realmsserviceexception.getMessage()), this.lastScreen));
|
||||
}
|
||||
|
||||
})).start();
|
||||
}
|
||||
|
||||
public void doSwitchOrReset() {
|
||||
(new Thread(() -> {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
if (this.serverData.state == RealmsServer.State.CLOSED) {
|
||||
this.minecraft.execute(() -> {
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this, new OpenServerTask(this.serverData, this, this.mainScreen, true, this.minecraft)));
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
RealmsServer realmsserver = realmsclient.getOwnWorld(this.serverId);
|
||||
this.minecraft.execute(() -> {
|
||||
this.mainScreen.newScreen().play(realmsserver, this);
|
||||
});
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't get own world");
|
||||
this.minecraft.execute(() -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})).start();
|
||||
}
|
||||
|
||||
private void downloadWorld(int p_88336_) {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
WorldDownload worlddownload = realmsclient.requestDownloadInfo(this.serverData.id, p_88336_);
|
||||
RealmsDownloadLatestWorldScreen realmsdownloadlatestworldscreen = new RealmsDownloadLatestWorldScreen(this, worlddownload, this.serverData.getWorldName(p_88336_), (p_280702_) -> {
|
||||
if (p_280702_) {
|
||||
this.slotsThatHasBeenDownloaded.add(p_88336_);
|
||||
this.clearWidgets();
|
||||
this.addButtons();
|
||||
} else {
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
});
|
||||
this.minecraft.setScreen(realmsdownloadlatestworldscreen);
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't download world data");
|
||||
this.minecraft.setScreen(new RealmsGenericErrorScreen(realmsserviceexception, this));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isMinigame() {
|
||||
return this.serverData != null && this.serverData.worldType == RealmsServer.WorldType.MINIGAME;
|
||||
}
|
||||
|
||||
private void drawSlotFrame(GuiGraphics p_281929_, int p_283393_, int p_281553_, int p_283523_, int p_282823_, boolean p_283032_, String p_283498_, int p_283330_, long p_283588_, @Nullable String p_282484_, boolean p_282283_) {
|
||||
ResourceLocation resourcelocation;
|
||||
if (p_282283_) {
|
||||
resourcelocation = RealmsWorldSlotButton.EMPTY_SLOT_LOCATION;
|
||||
} else if (p_282484_ != null && p_283588_ != -1L) {
|
||||
resourcelocation = RealmsTextureManager.worldTemplate(String.valueOf(p_283588_), p_282484_);
|
||||
} else if (p_283330_ == 1) {
|
||||
resourcelocation = RealmsWorldSlotButton.DEFAULT_WORLD_SLOT_1;
|
||||
} else if (p_283330_ == 2) {
|
||||
resourcelocation = RealmsWorldSlotButton.DEFAULT_WORLD_SLOT_2;
|
||||
} else if (p_283330_ == 3) {
|
||||
resourcelocation = RealmsWorldSlotButton.DEFAULT_WORLD_SLOT_3;
|
||||
} else {
|
||||
resourcelocation = RealmsTextureManager.worldTemplate(String.valueOf(this.serverData.minigameId), this.serverData.minigameImage);
|
||||
}
|
||||
|
||||
if (!p_283032_) {
|
||||
p_281929_.setColor(0.56F, 0.56F, 0.56F, 1.0F);
|
||||
} else if (p_283032_) {
|
||||
float f = 0.9F + 0.1F * Mth.cos((float)this.animTick * 0.2F);
|
||||
p_281929_.setColor(f, f, f, 1.0F);
|
||||
}
|
||||
|
||||
p_281929_.blit(resourcelocation, p_283393_ + 3, p_281553_ + 3, 0.0F, 0.0F, 74, 74, 74, 74);
|
||||
if (p_283032_) {
|
||||
p_281929_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
} else {
|
||||
p_281929_.setColor(0.56F, 0.56F, 0.56F, 1.0F);
|
||||
}
|
||||
|
||||
p_281929_.blit(RealmsWorldSlotButton.SLOT_FRAME_LOCATION, p_283393_, p_281553_, 0.0F, 0.0F, 80, 80, 80, 80);
|
||||
p_281929_.drawCenteredString(this.font, p_283498_, p_283393_ + 40, p_281553_ + 66, 16777215);
|
||||
p_281929_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsClientOutdatedScreen extends RealmsScreen {
|
||||
private static final Component INCOMPATIBLE_TITLE = Component.translatable("mco.client.incompatible.title");
|
||||
private static final Component[] INCOMPATIBLE_MESSAGES_SNAPSHOT = new Component[]{Component.translatable("mco.client.incompatible.msg.line1"), Component.translatable("mco.client.incompatible.msg.line2"), Component.translatable("mco.client.incompatible.msg.line3")};
|
||||
private static final Component[] INCOMPATIBLE_MESSAGES = new Component[]{Component.translatable("mco.client.incompatible.msg.line1"), Component.translatable("mco.client.incompatible.msg.line2")};
|
||||
private final Screen lastScreen;
|
||||
|
||||
public RealmsClientOutdatedScreen(Screen p_231304_) {
|
||||
super(INCOMPATIBLE_TITLE);
|
||||
this.lastScreen = p_231304_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_280710_) -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}).bounds(this.width / 2 - 100, row(12), 200, 20).build());
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_283142_, int p_88374_, int p_88375_, float p_88376_) {
|
||||
this.renderBackground(p_283142_);
|
||||
p_283142_.drawCenteredString(this.font, this.title, this.width / 2, row(3), 16711680);
|
||||
Component[] acomponent = this.getMessages();
|
||||
|
||||
for(int i = 0; i < acomponent.length; ++i) {
|
||||
p_283142_.drawCenteredString(this.font, acomponent[i], this.width / 2, row(5) + i * 12, 16777215);
|
||||
}
|
||||
|
||||
super.render(p_283142_, p_88374_, p_88375_, p_88376_);
|
||||
}
|
||||
|
||||
private Component[] getMessages() {
|
||||
return SharedConstants.getCurrentVersion().isStable() ? INCOMPATIBLE_MESSAGES : INCOMPATIBLE_MESSAGES_SNAPSHOT;
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88369_, int p_88370_, int p_88371_) {
|
||||
if (p_88369_ != 257 && p_88369_ != 335 && p_88369_ != 256) {
|
||||
return super.keyPressed(p_88369_, p_88370_, p_88371_);
|
||||
} else {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.RealmsMainScreen;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.RealmsWorldOptions;
|
||||
import com.mojang.realmsclient.dto.WorldTemplate;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.gui.RealmsWorldSlotButton;
|
||||
import com.mojang.realmsclient.util.task.CloseServerTask;
|
||||
import com.mojang.realmsclient.util.task.OpenServerTask;
|
||||
import com.mojang.realmsclient.util.task.SwitchMinigameTask;
|
||||
import com.mojang.realmsclient.util.task.SwitchSlotTask;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsConfigureWorldScreen extends RealmsScreen {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final ResourceLocation ON_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/on_icon.png");
|
||||
private static final ResourceLocation OFF_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/off_icon.png");
|
||||
private static final ResourceLocation EXPIRED_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/expired_icon.png");
|
||||
private static final ResourceLocation EXPIRES_SOON_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/expires_soon_icon.png");
|
||||
private static final Component WORLD_LIST_TITLE = Component.translatable("mco.configure.worlds.title");
|
||||
private static final Component TITLE = Component.translatable("mco.configure.world.title");
|
||||
private static final Component SERVER_EXPIRED_TOOLTIP = Component.translatable("mco.selectServer.expired");
|
||||
private static final Component SERVER_EXPIRING_SOON_TOOLTIP = Component.translatable("mco.selectServer.expires.soon");
|
||||
private static final Component SERVER_EXPIRING_IN_DAY_TOOLTIP = Component.translatable("mco.selectServer.expires.day");
|
||||
private static final Component SERVER_OPEN_TOOLTIP = Component.translatable("mco.selectServer.open");
|
||||
private static final Component SERVER_CLOSED_TOOLTIP = Component.translatable("mco.selectServer.closed");
|
||||
private static final int DEFAULT_BUTTON_WIDTH = 80;
|
||||
private static final int DEFAULT_BUTTON_OFFSET = 5;
|
||||
@Nullable
|
||||
private Component toolTip;
|
||||
private final RealmsMainScreen lastScreen;
|
||||
@Nullable
|
||||
private RealmsServer serverData;
|
||||
private final long serverId;
|
||||
private int leftX;
|
||||
private int rightX;
|
||||
private Button playersButton;
|
||||
private Button settingsButton;
|
||||
private Button subscriptionButton;
|
||||
private Button optionsButton;
|
||||
private Button backupButton;
|
||||
private Button resetWorldButton;
|
||||
private Button switchMinigameButton;
|
||||
private boolean stateChanged;
|
||||
private int animTick;
|
||||
private int clicks;
|
||||
private final List<RealmsWorldSlotButton> slotButtonList = Lists.newArrayList();
|
||||
|
||||
public RealmsConfigureWorldScreen(RealmsMainScreen p_88411_, long p_88412_) {
|
||||
super(TITLE);
|
||||
this.lastScreen = p_88411_;
|
||||
this.serverId = p_88412_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (this.serverData == null) {
|
||||
this.fetchServerData(this.serverId);
|
||||
}
|
||||
|
||||
this.leftX = this.width / 2 - 187;
|
||||
this.rightX = this.width / 2 + 190;
|
||||
this.playersButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.players"), (p_280722_) -> {
|
||||
this.minecraft.setScreen(new RealmsPlayerScreen(this, this.serverData));
|
||||
}).bounds(this.centerButton(0, 3), row(0), 100, 20).build());
|
||||
this.settingsButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.settings"), (p_280716_) -> {
|
||||
this.minecraft.setScreen(new RealmsSettingsScreen(this, this.serverData.clone()));
|
||||
}).bounds(this.centerButton(1, 3), row(0), 100, 20).build());
|
||||
this.subscriptionButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.subscription"), (p_280725_) -> {
|
||||
this.minecraft.setScreen(new RealmsSubscriptionInfoScreen(this, this.serverData.clone(), this.lastScreen));
|
||||
}).bounds(this.centerButton(2, 3), row(0), 100, 20).build());
|
||||
this.slotButtonList.clear();
|
||||
|
||||
for(int i = 1; i < 5; ++i) {
|
||||
this.slotButtonList.add(this.addSlotButton(i));
|
||||
}
|
||||
|
||||
this.switchMinigameButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.switchminigame"), (p_280711_) -> {
|
||||
this.minecraft.setScreen(new RealmsSelectWorldTemplateScreen(Component.translatable("mco.template.title.minigame"), this::templateSelectionCallback, RealmsServer.WorldType.MINIGAME));
|
||||
}).bounds(this.leftButton(0), row(13) - 5, 100, 20).build());
|
||||
this.optionsButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.options"), (p_280720_) -> {
|
||||
this.minecraft.setScreen(new RealmsSlotOptionsScreen(this, this.serverData.slots.get(this.serverData.activeSlot).clone(), this.serverData.worldType, this.serverData.activeSlot));
|
||||
}).bounds(this.leftButton(0), row(13) - 5, 90, 20).build());
|
||||
this.backupButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.backup"), (p_280715_) -> {
|
||||
this.minecraft.setScreen(new RealmsBackupScreen(this, this.serverData.clone(), this.serverData.activeSlot));
|
||||
}).bounds(this.leftButton(1), row(13) - 5, 90, 20).build());
|
||||
this.resetWorldButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.resetworld"), (p_280724_) -> {
|
||||
this.minecraft.setScreen(new RealmsResetWorldScreen(this, this.serverData.clone(), () -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.minecraft.setScreen(this.getNewScreen());
|
||||
});
|
||||
}, () -> {
|
||||
this.minecraft.setScreen(this.getNewScreen());
|
||||
}));
|
||||
}).bounds(this.leftButton(2), row(13) - 5, 90, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_167407_) -> {
|
||||
this.backButtonClicked();
|
||||
}).bounds(this.rightX - 80 + 8, row(13) - 5, 70, 20).build());
|
||||
this.backupButton.active = true;
|
||||
if (this.serverData == null) {
|
||||
this.hideMinigameButtons();
|
||||
this.hideRegularButtons();
|
||||
this.playersButton.active = false;
|
||||
this.settingsButton.active = false;
|
||||
this.subscriptionButton.active = false;
|
||||
} else {
|
||||
this.disableButtons();
|
||||
if (this.isMinigame()) {
|
||||
this.hideRegularButtons();
|
||||
} else {
|
||||
this.hideMinigameButtons();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private RealmsWorldSlotButton addSlotButton(int p_167386_) {
|
||||
int i = this.frame(p_167386_);
|
||||
int j = row(5) + 5;
|
||||
RealmsWorldSlotButton realmsworldslotbutton = new RealmsWorldSlotButton(i, j, 80, 80, () -> {
|
||||
return this.serverData;
|
||||
}, (p_167399_) -> {
|
||||
this.toolTip = p_167399_;
|
||||
}, p_167386_, (p_167389_) -> {
|
||||
RealmsWorldSlotButton.State realmsworldslotbutton$state = ((RealmsWorldSlotButton)p_167389_).getState();
|
||||
if (realmsworldslotbutton$state != null) {
|
||||
switch (realmsworldslotbutton$state.action) {
|
||||
case NOTHING:
|
||||
break;
|
||||
case JOIN:
|
||||
this.joinRealm(this.serverData);
|
||||
break;
|
||||
case SWITCH_SLOT:
|
||||
if (realmsworldslotbutton$state.minigame) {
|
||||
this.switchToMinigame();
|
||||
} else if (realmsworldslotbutton$state.empty) {
|
||||
this.switchToEmptySlot(p_167386_, this.serverData);
|
||||
} else {
|
||||
this.switchToFullSlot(p_167386_, this.serverData);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown action " + realmsworldslotbutton$state.action);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
return this.addRenderableWidget(realmsworldslotbutton);
|
||||
}
|
||||
|
||||
private int leftButton(int p_88464_) {
|
||||
return this.leftX + p_88464_ * 95;
|
||||
}
|
||||
|
||||
private int centerButton(int p_88466_, int p_88467_) {
|
||||
return this.width / 2 - (p_88467_ * 105 - 5) / 2 + p_88466_ * 105;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
++this.animTick;
|
||||
--this.clicks;
|
||||
if (this.clicks < 0) {
|
||||
this.clicks = 0;
|
||||
}
|
||||
|
||||
this.slotButtonList.forEach(RealmsWorldSlotButton::tick);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282982_, int p_281739_, int p_283097_, float p_282528_) {
|
||||
this.toolTip = null;
|
||||
this.renderBackground(p_282982_);
|
||||
p_282982_.drawCenteredString(this.font, WORLD_LIST_TITLE, this.width / 2, row(4), 16777215);
|
||||
super.render(p_282982_, p_281739_, p_283097_, p_282528_);
|
||||
if (this.serverData == null) {
|
||||
p_282982_.drawCenteredString(this.font, this.title, this.width / 2, 17, 16777215);
|
||||
} else {
|
||||
String s = this.serverData.getName();
|
||||
int i = this.font.width(s);
|
||||
int j = this.serverData.state == RealmsServer.State.CLOSED ? 10526880 : 8388479;
|
||||
int k = this.font.width(this.title);
|
||||
p_282982_.drawCenteredString(this.font, this.title, this.width / 2, 12, 16777215);
|
||||
p_282982_.drawCenteredString(this.font, s, this.width / 2, 24, j);
|
||||
int l = Math.min(this.centerButton(2, 3) + 80 - 11, this.width / 2 + i / 2 + k / 2 + 10);
|
||||
this.drawServerStatus(p_282982_, l, 7, p_281739_, p_283097_);
|
||||
if (this.isMinigame()) {
|
||||
p_282982_.drawString(this.font, Component.translatable("mco.configure.world.minigame", this.serverData.getMinigameName()), this.leftX + 80 + 20 + 10, row(13), 16777215, false);
|
||||
}
|
||||
|
||||
if (this.toolTip != null) {
|
||||
this.renderMousehoverTooltip(p_282982_, this.toolTip, p_281739_, p_283097_);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private int frame(int p_88488_) {
|
||||
return this.leftX + (p_88488_ - 1) * 98;
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88417_, int p_88418_, int p_88419_) {
|
||||
if (p_88417_ == 256) {
|
||||
this.backButtonClicked();
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_88417_, p_88418_, p_88419_);
|
||||
}
|
||||
}
|
||||
|
||||
private void backButtonClicked() {
|
||||
if (this.stateChanged) {
|
||||
this.lastScreen.resetScreen();
|
||||
}
|
||||
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}
|
||||
|
||||
private void fetchServerData(long p_88427_) {
|
||||
(new Thread(() -> {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
RealmsServer realmsserver = realmsclient.getOwnWorld(p_88427_);
|
||||
this.minecraft.execute(() -> {
|
||||
this.serverData = realmsserver;
|
||||
this.disableButtons();
|
||||
if (this.isMinigame()) {
|
||||
this.show(this.switchMinigameButton);
|
||||
} else {
|
||||
this.show(this.optionsButton);
|
||||
this.show(this.backupButton);
|
||||
this.show(this.resetWorldButton);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't get own world");
|
||||
this.minecraft.execute(() -> {
|
||||
this.minecraft.setScreen(new RealmsGenericErrorScreen(Component.nullToEmpty(realmsserviceexception.getMessage()), this.lastScreen));
|
||||
});
|
||||
}
|
||||
|
||||
})).start();
|
||||
}
|
||||
|
||||
private void disableButtons() {
|
||||
this.playersButton.active = !this.serverData.expired;
|
||||
this.settingsButton.active = !this.serverData.expired;
|
||||
this.subscriptionButton.active = true;
|
||||
this.switchMinigameButton.active = !this.serverData.expired;
|
||||
this.optionsButton.active = !this.serverData.expired;
|
||||
this.resetWorldButton.active = !this.serverData.expired;
|
||||
}
|
||||
|
||||
private void joinRealm(RealmsServer p_88439_) {
|
||||
if (this.serverData.state == RealmsServer.State.OPEN) {
|
||||
this.lastScreen.play(p_88439_, new RealmsConfigureWorldScreen(this.lastScreen.newScreen(), this.serverId));
|
||||
} else {
|
||||
this.openTheWorld(true, new RealmsConfigureWorldScreen(this.lastScreen.newScreen(), this.serverId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void switchToMinigame() {
|
||||
RealmsSelectWorldTemplateScreen realmsselectworldtemplatescreen = new RealmsSelectWorldTemplateScreen(Component.translatable("mco.template.title.minigame"), this::templateSelectionCallback, RealmsServer.WorldType.MINIGAME);
|
||||
realmsselectworldtemplatescreen.setWarning(Component.translatable("mco.minigame.world.info.line1"), Component.translatable("mco.minigame.world.info.line2"));
|
||||
this.minecraft.setScreen(realmsselectworldtemplatescreen);
|
||||
}
|
||||
|
||||
private void switchToFullSlot(int p_88421_, RealmsServer p_88422_) {
|
||||
Component component = Component.translatable("mco.configure.world.slot.switch.question.line1");
|
||||
Component component1 = Component.translatable("mco.configure.world.slot.switch.question.line2");
|
||||
this.minecraft.setScreen(new RealmsLongConfirmationScreen((p_280714_) -> {
|
||||
if (p_280714_) {
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this.lastScreen, new SwitchSlotTask(p_88422_.id, p_88421_, () -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.minecraft.setScreen(this.getNewScreen());
|
||||
});
|
||||
})));
|
||||
} else {
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
}, RealmsLongConfirmationScreen.Type.INFO, component, component1, true));
|
||||
}
|
||||
|
||||
private void switchToEmptySlot(int p_88469_, RealmsServer p_88470_) {
|
||||
Component component = Component.translatable("mco.configure.world.slot.switch.question.line1");
|
||||
Component component1 = Component.translatable("mco.configure.world.slot.switch.question.line2");
|
||||
this.minecraft.setScreen(new RealmsLongConfirmationScreen((p_280719_) -> {
|
||||
if (p_280719_) {
|
||||
RealmsResetWorldScreen realmsresetworldscreen = new RealmsResetWorldScreen(this, p_88470_, Component.translatable("mco.configure.world.switch.slot"), Component.translatable("mco.configure.world.switch.slot.subtitle"), 10526880, CommonComponents.GUI_CANCEL, () -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.minecraft.setScreen(this.getNewScreen());
|
||||
});
|
||||
}, () -> {
|
||||
this.minecraft.setScreen(this.getNewScreen());
|
||||
});
|
||||
realmsresetworldscreen.setSlot(p_88469_);
|
||||
realmsresetworldscreen.setResetTitle(Component.translatable("mco.create.world.reset.title"));
|
||||
this.minecraft.setScreen(realmsresetworldscreen);
|
||||
} else {
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
}, RealmsLongConfirmationScreen.Type.INFO, component, component1, true));
|
||||
}
|
||||
|
||||
protected void renderMousehoverTooltip(GuiGraphics p_281972_, @Nullable Component p_282839_, int p_283007_, int p_283386_) {
|
||||
int i = p_283007_ + 12;
|
||||
int j = p_283386_ - 12;
|
||||
int k = this.font.width(p_282839_);
|
||||
if (i + k + 3 > this.rightX) {
|
||||
i = i - k - 20;
|
||||
}
|
||||
|
||||
p_281972_.fillGradient(i - 3, j - 3, i + k + 3, j + 8 + 3, -1073741824, -1073741824);
|
||||
p_281972_.drawString(this.font, p_282839_, i, j, 16777215);
|
||||
}
|
||||
|
||||
private void drawServerStatus(GuiGraphics p_281709_, int p_88491_, int p_88492_, int p_88493_, int p_88494_) {
|
||||
if (this.serverData.expired) {
|
||||
this.drawExpired(p_281709_, p_88491_, p_88492_, p_88493_, p_88494_);
|
||||
} else if (this.serverData.state == RealmsServer.State.CLOSED) {
|
||||
this.drawClose(p_281709_, p_88491_, p_88492_, p_88493_, p_88494_);
|
||||
} else if (this.serverData.state == RealmsServer.State.OPEN) {
|
||||
if (this.serverData.daysLeft < 7) {
|
||||
this.drawExpiring(p_281709_, p_88491_, p_88492_, p_88493_, p_88494_, this.serverData.daysLeft);
|
||||
} else {
|
||||
this.drawOpen(p_281709_, p_88491_, p_88492_, p_88493_, p_88494_);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawExpired(GuiGraphics p_283277_, int p_283238_, int p_282189_, int p_281748_, int p_282829_) {
|
||||
p_283277_.blit(EXPIRED_ICON_LOCATION, p_283238_, p_282189_, 0.0F, 0.0F, 10, 28, 10, 28);
|
||||
if (p_281748_ >= p_283238_ && p_281748_ <= p_283238_ + 9 && p_282829_ >= p_282189_ && p_282829_ <= p_282189_ + 27) {
|
||||
this.toolTip = SERVER_EXPIRED_TOOLTIP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawExpiring(GuiGraphics p_283478_, int p_281486_, int p_283460_, int p_282257_, int p_283127_, int p_282411_) {
|
||||
if (this.animTick % 20 < 10) {
|
||||
p_283478_.blit(EXPIRES_SOON_ICON_LOCATION, p_281486_, p_283460_, 0.0F, 0.0F, 10, 28, 20, 28);
|
||||
} else {
|
||||
p_283478_.blit(EXPIRES_SOON_ICON_LOCATION, p_281486_, p_283460_, 10.0F, 0.0F, 10, 28, 20, 28);
|
||||
}
|
||||
|
||||
if (p_282257_ >= p_281486_ && p_282257_ <= p_281486_ + 9 && p_283127_ >= p_283460_ && p_283127_ <= p_283460_ + 27) {
|
||||
if (p_282411_ <= 0) {
|
||||
this.toolTip = SERVER_EXPIRING_SOON_TOOLTIP;
|
||||
} else if (p_282411_ == 1) {
|
||||
this.toolTip = SERVER_EXPIRING_IN_DAY_TOOLTIP;
|
||||
} else {
|
||||
this.toolTip = Component.translatable("mco.selectServer.expires.days", p_282411_);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawOpen(GuiGraphics p_283165_, int p_283465_, int p_282847_, int p_281579_, int p_283400_) {
|
||||
p_283165_.blit(ON_ICON_LOCATION, p_283465_, p_282847_, 0.0F, 0.0F, 10, 28, 10, 28);
|
||||
if (p_281579_ >= p_283465_ && p_281579_ <= p_283465_ + 9 && p_283400_ >= p_282847_ && p_283400_ <= p_282847_ + 27) {
|
||||
this.toolTip = SERVER_OPEN_TOOLTIP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawClose(GuiGraphics p_282771_, int p_282927_, int p_282519_, int p_282695_, int p_282579_) {
|
||||
p_282771_.blit(OFF_ICON_LOCATION, p_282927_, p_282519_, 0.0F, 0.0F, 10, 28, 10, 28);
|
||||
if (p_282695_ >= p_282927_ && p_282695_ <= p_282927_ + 9 && p_282579_ >= p_282519_ && p_282579_ <= p_282519_ + 27) {
|
||||
this.toolTip = SERVER_CLOSED_TOOLTIP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isMinigame() {
|
||||
return this.serverData != null && this.serverData.worldType == RealmsServer.WorldType.MINIGAME;
|
||||
}
|
||||
|
||||
private void hideRegularButtons() {
|
||||
this.hide(this.optionsButton);
|
||||
this.hide(this.backupButton);
|
||||
this.hide(this.resetWorldButton);
|
||||
}
|
||||
|
||||
private void hide(Button p_88451_) {
|
||||
p_88451_.visible = false;
|
||||
this.removeWidget(p_88451_);
|
||||
}
|
||||
|
||||
private void show(Button p_88485_) {
|
||||
p_88485_.visible = true;
|
||||
this.addRenderableWidget(p_88485_);
|
||||
}
|
||||
|
||||
private void hideMinigameButtons() {
|
||||
this.hide(this.switchMinigameButton);
|
||||
}
|
||||
|
||||
public void saveSlotSettings(RealmsWorldOptions p_88445_) {
|
||||
RealmsWorldOptions realmsworldoptions = this.serverData.slots.get(this.serverData.activeSlot);
|
||||
p_88445_.templateId = realmsworldoptions.templateId;
|
||||
p_88445_.templateImage = realmsworldoptions.templateImage;
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
realmsclient.updateSlot(this.serverData.id, this.serverData.activeSlot, p_88445_);
|
||||
this.serverData.slots.put(this.serverData.activeSlot, p_88445_);
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't save slot settings");
|
||||
this.minecraft.setScreen(new RealmsGenericErrorScreen(realmsserviceexception, this));
|
||||
return;
|
||||
}
|
||||
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
public void saveSettings(String p_88455_, String p_88456_) {
|
||||
String s = p_88456_.trim().isEmpty() ? null : p_88456_;
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
realmsclient.update(this.serverData.id, p_88455_, s);
|
||||
this.serverData.setName(p_88455_);
|
||||
this.serverData.setDescription(s);
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't save settings");
|
||||
this.minecraft.setScreen(new RealmsGenericErrorScreen(realmsserviceexception, this));
|
||||
return;
|
||||
}
|
||||
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
public void openTheWorld(boolean p_88460_, Screen p_88461_) {
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(p_88461_, new OpenServerTask(this.serverData, this, this.lastScreen, p_88460_, this.minecraft)));
|
||||
}
|
||||
|
||||
public void closeTheWorld(Screen p_88453_) {
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(p_88453_, new CloseServerTask(this.serverData, this)));
|
||||
}
|
||||
|
||||
public void stateChanged() {
|
||||
this.stateChanged = true;
|
||||
}
|
||||
|
||||
private void templateSelectionCallback(@Nullable WorldTemplate p_167395_) {
|
||||
if (p_167395_ != null && WorldTemplate.WorldTemplateType.MINIGAME == p_167395_.type) {
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this.lastScreen, new SwitchMinigameTask(this.serverData.id, p_167395_, this.getNewScreen())));
|
||||
} else {
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public RealmsConfigureWorldScreen getNewScreen() {
|
||||
return new RealmsConfigureWorldScreen(this.lastScreen, this.serverId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsConfirmScreen extends RealmsScreen {
|
||||
protected BooleanConsumer callback;
|
||||
private final Component title1;
|
||||
private final Component title2;
|
||||
|
||||
public RealmsConfirmScreen(BooleanConsumer p_88550_, Component p_88551_, Component p_88552_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.callback = p_88550_;
|
||||
this.title1 = p_88551_;
|
||||
this.title2 = p_88552_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_YES, (p_88562_) -> {
|
||||
this.callback.accept(true);
|
||||
}).bounds(this.width / 2 - 105, row(9), 100, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_NO, (p_88559_) -> {
|
||||
this.callback.accept(false);
|
||||
}).bounds(this.width / 2 + 5, row(9), 100, 20).build());
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282610_, int p_282200_, int p_283480_, float p_281259_) {
|
||||
this.renderBackground(p_282610_);
|
||||
p_282610_.drawCenteredString(this.font, this.title1, this.width / 2, row(3), 16777215);
|
||||
p_282610_.drawCenteredString(this.font, this.title2, this.width / 2, row(5), 16777215);
|
||||
super.render(p_282610_, p_282200_, p_283480_, p_281259_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.realmsclient.RealmsMainScreen;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.util.task.WorldCreationTask;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsCreateRealmScreen extends RealmsScreen {
|
||||
private static final Component NAME_LABEL = Component.translatable("mco.configure.world.name");
|
||||
private static final Component DESCRIPTION_LABEL = Component.translatable("mco.configure.world.description");
|
||||
private final RealmsServer server;
|
||||
private final RealmsMainScreen lastScreen;
|
||||
private EditBox nameBox;
|
||||
private EditBox descriptionBox;
|
||||
private Button createButton;
|
||||
|
||||
public RealmsCreateRealmScreen(RealmsServer p_88574_, RealmsMainScreen p_88575_) {
|
||||
super(Component.translatable("mco.selectServer.create"));
|
||||
this.server = p_88574_;
|
||||
this.lastScreen = p_88575_;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (this.nameBox != null) {
|
||||
this.nameBox.tick();
|
||||
}
|
||||
|
||||
if (this.descriptionBox != null) {
|
||||
this.descriptionBox.tick();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.createButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.create.world"), (p_88592_) -> {
|
||||
this.createWorld();
|
||||
}).bounds(this.width / 2 - 100, this.height / 4 + 120 + 17, 97, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, (p_280726_) -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}).bounds(this.width / 2 + 5, this.height / 4 + 120 + 17, 95, 20).build());
|
||||
this.createButton.active = false;
|
||||
this.nameBox = new EditBox(this.minecraft.font, this.width / 2 - 100, 65, 200, 20, (EditBox)null, Component.translatable("mco.configure.world.name"));
|
||||
this.addWidget(this.nameBox);
|
||||
this.setInitialFocus(this.nameBox);
|
||||
this.descriptionBox = new EditBox(this.minecraft.font, this.width / 2 - 100, 115, 200, 20, (EditBox)null, Component.translatable("mco.configure.world.description"));
|
||||
this.addWidget(this.descriptionBox);
|
||||
}
|
||||
|
||||
public boolean charTyped(char p_88577_, int p_88578_) {
|
||||
boolean flag = super.charTyped(p_88577_, p_88578_);
|
||||
this.createButton.active = this.valid();
|
||||
return flag;
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88580_, int p_88581_, int p_88582_) {
|
||||
if (p_88580_ == 256) {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
return true;
|
||||
} else {
|
||||
boolean flag = super.keyPressed(p_88580_, p_88581_, p_88582_);
|
||||
this.createButton.active = this.valid();
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
|
||||
private void createWorld() {
|
||||
if (this.valid()) {
|
||||
RealmsResetWorldScreen realmsresetworldscreen = new RealmsResetWorldScreen(this.lastScreen, this.server, Component.translatable("mco.selectServer.create"), Component.translatable("mco.create.world.subtitle"), 10526880, Component.translatable("mco.create.world.skip"), () -> {
|
||||
this.minecraft.execute(() -> {
|
||||
this.minecraft.setScreen(this.lastScreen.newScreen());
|
||||
});
|
||||
}, () -> {
|
||||
this.minecraft.setScreen(this.lastScreen.newScreen());
|
||||
});
|
||||
realmsresetworldscreen.setResetTitle(Component.translatable("mco.create.world.reset.title"));
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this.lastScreen, new WorldCreationTask(this.server.id, this.nameBox.getValue(), this.descriptionBox.getValue(), realmsresetworldscreen)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean valid() {
|
||||
return !this.nameBox.getValue().trim().isEmpty();
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_283245_, int p_283409_, int p_282805_, float p_282071_) {
|
||||
this.renderBackground(p_283245_);
|
||||
p_283245_.drawCenteredString(this.font, this.title, this.width / 2, 11, 16777215);
|
||||
p_283245_.drawString(this.font, NAME_LABEL, this.width / 2 - 100, 52, 10526880, false);
|
||||
p_283245_.drawString(this.font, DESCRIPTION_LABEL, this.width / 2 - 100, 102, 10526880, false);
|
||||
if (this.nameBox != null) {
|
||||
this.nameBox.render(p_283245_, p_283409_, p_282805_, p_282071_);
|
||||
}
|
||||
|
||||
if (this.descriptionBox != null) {
|
||||
this.descriptionBox.render(p_283245_, p_283409_, p_282805_, p_282071_);
|
||||
}
|
||||
|
||||
super.render(p_283245_, p_283409_, p_282805_, p_282071_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.util.concurrent.RateLimiter;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.Unit;
|
||||
import com.mojang.realmsclient.client.FileDownload;
|
||||
import com.mojang.realmsclient.dto.WorldDownload;
|
||||
import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsDownloadLatestWorldScreen extends RealmsScreen {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final ReentrantLock DOWNLOAD_LOCK = new ReentrantLock();
|
||||
private static final int BAR_WIDTH = 200;
|
||||
private static final int BAR_TOP = 80;
|
||||
private static final int BAR_BOTTOM = 95;
|
||||
private static final int BAR_BORDER = 1;
|
||||
private final Screen lastScreen;
|
||||
private final WorldDownload worldDownload;
|
||||
private final Component downloadTitle;
|
||||
private final RateLimiter narrationRateLimiter;
|
||||
private Button cancelButton;
|
||||
private final String worldName;
|
||||
private final RealmsDownloadLatestWorldScreen.DownloadStatus downloadStatus;
|
||||
@Nullable
|
||||
private volatile Component errorMessage;
|
||||
private volatile Component status = Component.translatable("mco.download.preparing");
|
||||
@Nullable
|
||||
private volatile String progress;
|
||||
private volatile boolean cancelled;
|
||||
private volatile boolean showDots = true;
|
||||
private volatile boolean finished;
|
||||
private volatile boolean extracting;
|
||||
@Nullable
|
||||
private Long previousWrittenBytes;
|
||||
@Nullable
|
||||
private Long previousTimeSnapshot;
|
||||
private long bytesPersSecond;
|
||||
private int animTick;
|
||||
private static final String[] DOTS = new String[]{"", ".", ". .", ". . ."};
|
||||
private int dotIndex;
|
||||
private boolean checked;
|
||||
private final BooleanConsumer callback;
|
||||
|
||||
public RealmsDownloadLatestWorldScreen(Screen p_88625_, WorldDownload p_88626_, String p_88627_, BooleanConsumer p_88628_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.callback = p_88628_;
|
||||
this.lastScreen = p_88625_;
|
||||
this.worldName = p_88627_;
|
||||
this.worldDownload = p_88626_;
|
||||
this.downloadStatus = new RealmsDownloadLatestWorldScreen.DownloadStatus();
|
||||
this.downloadTitle = Component.translatable("mco.download.title");
|
||||
this.narrationRateLimiter = RateLimiter.create((double)0.1F);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.cancelButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, (p_88642_) -> {
|
||||
this.cancelled = true;
|
||||
this.backButtonClicked();
|
||||
}).bounds((this.width - 200) / 2, this.height - 42, 200, 20).build());
|
||||
this.checkDownloadSize();
|
||||
}
|
||||
|
||||
private void checkDownloadSize() {
|
||||
if (!this.finished) {
|
||||
if (!this.checked && this.getContentLength(this.worldDownload.downloadLink) >= 5368709120L) {
|
||||
Component component = Component.translatable("mco.download.confirmation.line1", Unit.humanReadable(5368709120L));
|
||||
Component component1 = Component.translatable("mco.download.confirmation.line2");
|
||||
this.minecraft.setScreen(new RealmsLongConfirmationScreen((p_280727_) -> {
|
||||
this.checked = true;
|
||||
this.minecraft.setScreen(this);
|
||||
this.downloadSave();
|
||||
}, RealmsLongConfirmationScreen.Type.WARNING, component, component1, false));
|
||||
} else {
|
||||
this.downloadSave();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private long getContentLength(String p_88647_) {
|
||||
FileDownload filedownload = new FileDownload();
|
||||
return filedownload.contentLength(p_88647_);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
++this.animTick;
|
||||
if (this.status != null && this.narrationRateLimiter.tryAcquire(1)) {
|
||||
Component component = this.createProgressNarrationMessage();
|
||||
this.minecraft.getNarrator().sayNow(component);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Component createProgressNarrationMessage() {
|
||||
List<Component> list = Lists.newArrayList();
|
||||
list.add(this.downloadTitle);
|
||||
list.add(this.status);
|
||||
if (this.progress != null) {
|
||||
list.add(Component.literal(this.progress + "%"));
|
||||
list.add(Component.literal(Unit.humanReadable(this.bytesPersSecond) + "/s"));
|
||||
}
|
||||
|
||||
if (this.errorMessage != null) {
|
||||
list.add(this.errorMessage);
|
||||
}
|
||||
|
||||
return CommonComponents.joinLines(list);
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88630_, int p_88631_, int p_88632_) {
|
||||
if (p_88630_ == 256) {
|
||||
this.cancelled = true;
|
||||
this.backButtonClicked();
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_88630_, p_88631_, p_88632_);
|
||||
}
|
||||
}
|
||||
|
||||
private void backButtonClicked() {
|
||||
if (this.finished && this.callback != null && this.errorMessage == null) {
|
||||
this.callback.accept(true);
|
||||
}
|
||||
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282124_, int p_88635_, int p_88636_, float p_88637_) {
|
||||
this.renderBackground(p_282124_);
|
||||
p_282124_.drawCenteredString(this.font, this.downloadTitle, this.width / 2, 20, 16777215);
|
||||
p_282124_.drawCenteredString(this.font, this.status, this.width / 2, 50, 16777215);
|
||||
if (this.showDots) {
|
||||
this.drawDots(p_282124_);
|
||||
}
|
||||
|
||||
if (this.downloadStatus.bytesWritten != 0L && !this.cancelled) {
|
||||
this.drawProgressBar(p_282124_);
|
||||
this.drawDownloadSpeed(p_282124_);
|
||||
}
|
||||
|
||||
if (this.errorMessage != null) {
|
||||
p_282124_.drawCenteredString(this.font, this.errorMessage, this.width / 2, 110, 16711680);
|
||||
}
|
||||
|
||||
super.render(p_282124_, p_88635_, p_88636_, p_88637_);
|
||||
}
|
||||
|
||||
private void drawDots(GuiGraphics p_281948_) {
|
||||
int i = this.font.width(this.status);
|
||||
if (this.animTick % 10 == 0) {
|
||||
++this.dotIndex;
|
||||
}
|
||||
|
||||
p_281948_.drawString(this.font, DOTS[this.dotIndex % DOTS.length], this.width / 2 + i / 2 + 5, 50, 16777215, false);
|
||||
}
|
||||
|
||||
private void drawProgressBar(GuiGraphics p_281556_) {
|
||||
double d0 = Math.min((double)this.downloadStatus.bytesWritten / (double)this.downloadStatus.totalBytes, 1.0D);
|
||||
this.progress = String.format(Locale.ROOT, "%.1f", d0 * 100.0D);
|
||||
int i = (this.width - 200) / 2;
|
||||
int j = i + (int)Math.round(200.0D * d0);
|
||||
p_281556_.fill(i - 1, 79, j + 1, 96, -2501934);
|
||||
p_281556_.fill(i, 80, j, 95, -8355712);
|
||||
p_281556_.drawCenteredString(this.font, Component.translatable("mco.download.percent", this.progress), this.width / 2, 84, 16777215);
|
||||
}
|
||||
|
||||
private void drawDownloadSpeed(GuiGraphics p_282236_) {
|
||||
if (this.animTick % 20 == 0) {
|
||||
if (this.previousWrittenBytes != null) {
|
||||
long i = Util.getMillis() - this.previousTimeSnapshot;
|
||||
if (i == 0L) {
|
||||
i = 1L;
|
||||
}
|
||||
|
||||
this.bytesPersSecond = 1000L * (this.downloadStatus.bytesWritten - this.previousWrittenBytes) / i;
|
||||
this.drawDownloadSpeed0(p_282236_, this.bytesPersSecond);
|
||||
}
|
||||
|
||||
this.previousWrittenBytes = this.downloadStatus.bytesWritten;
|
||||
this.previousTimeSnapshot = Util.getMillis();
|
||||
} else {
|
||||
this.drawDownloadSpeed0(p_282236_, this.bytesPersSecond);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawDownloadSpeed0(GuiGraphics p_283338_, long p_281931_) {
|
||||
if (p_281931_ > 0L) {
|
||||
int i = this.font.width(this.progress);
|
||||
p_283338_.drawString(this.font, Component.translatable("mco.download.speed", Unit.humanReadable(p_281931_)), this.width / 2 + i / 2 + 15, 84, 16777215, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void downloadSave() {
|
||||
(new Thread(() -> {
|
||||
try {
|
||||
if (DOWNLOAD_LOCK.tryLock(1L, TimeUnit.SECONDS)) {
|
||||
if (this.cancelled) {
|
||||
this.downloadCancelled();
|
||||
return;
|
||||
}
|
||||
|
||||
this.status = Component.translatable("mco.download.downloading", this.worldName);
|
||||
FileDownload filedownload = new FileDownload();
|
||||
filedownload.contentLength(this.worldDownload.downloadLink);
|
||||
filedownload.download(this.worldDownload, this.worldName, this.downloadStatus, this.minecraft.getLevelSource());
|
||||
|
||||
while(!filedownload.isFinished()) {
|
||||
if (filedownload.isError()) {
|
||||
filedownload.cancel();
|
||||
this.errorMessage = Component.translatable("mco.download.failed");
|
||||
this.cancelButton.setMessage(CommonComponents.GUI_DONE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (filedownload.isExtracting()) {
|
||||
if (!this.extracting) {
|
||||
this.status = Component.translatable("mco.download.extracting");
|
||||
}
|
||||
|
||||
this.extracting = true;
|
||||
}
|
||||
|
||||
if (this.cancelled) {
|
||||
filedownload.cancel();
|
||||
this.downloadCancelled();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(500L);
|
||||
} catch (InterruptedException interruptedexception) {
|
||||
LOGGER.error("Failed to check Realms backup download status");
|
||||
}
|
||||
}
|
||||
|
||||
this.finished = true;
|
||||
this.status = Component.translatable("mco.download.done");
|
||||
this.cancelButton.setMessage(CommonComponents.GUI_DONE);
|
||||
return;
|
||||
}
|
||||
|
||||
this.status = Component.translatable("mco.download.failed");
|
||||
} catch (InterruptedException interruptedexception1) {
|
||||
LOGGER.error("Could not acquire upload lock");
|
||||
return;
|
||||
} catch (Exception exception) {
|
||||
this.errorMessage = Component.translatable("mco.download.failed");
|
||||
exception.printStackTrace();
|
||||
return;
|
||||
} finally {
|
||||
if (!DOWNLOAD_LOCK.isHeldByCurrentThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DOWNLOAD_LOCK.unlock();
|
||||
this.showDots = false;
|
||||
this.finished = true;
|
||||
}
|
||||
|
||||
})).start();
|
||||
}
|
||||
|
||||
private void downloadCancelled() {
|
||||
this.status = Component.translatable("mco.download.cancelled");
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class DownloadStatus {
|
||||
public volatile long bytesWritten;
|
||||
public volatile long totalBytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.realmsclient.client.RealmsError;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.MultiLineLabel;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsGenericErrorScreen extends RealmsScreen {
|
||||
private final Screen nextScreen;
|
||||
private final RealmsGenericErrorScreen.ErrorMessage lines;
|
||||
private MultiLineLabel line2Split = MultiLineLabel.EMPTY;
|
||||
|
||||
public RealmsGenericErrorScreen(RealmsServiceException p_88669_, Screen p_88670_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.nextScreen = p_88670_;
|
||||
this.lines = errorMessage(p_88669_);
|
||||
}
|
||||
|
||||
public RealmsGenericErrorScreen(Component p_88672_, Screen p_88673_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.nextScreen = p_88673_;
|
||||
this.lines = errorMessage(p_88672_);
|
||||
}
|
||||
|
||||
public RealmsGenericErrorScreen(Component p_88675_, Component p_88676_, Screen p_88677_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.nextScreen = p_88677_;
|
||||
this.lines = errorMessage(p_88675_, p_88676_);
|
||||
}
|
||||
|
||||
private static RealmsGenericErrorScreen.ErrorMessage errorMessage(RealmsServiceException p_288965_) {
|
||||
RealmsError realmserror = p_288965_.realmsError;
|
||||
if (realmserror == null) {
|
||||
return errorMessage(Component.translatable("mco.errorMessage.realmsService", p_288965_.httpResultCode), Component.literal(p_288965_.rawResponse));
|
||||
} else {
|
||||
int i = realmserror.getErrorCode();
|
||||
String s = "mco.errorMessage." + i;
|
||||
return errorMessage(Component.translatable("mco.errorMessage.realmsService.realmsError", i), (Component)(I18n.exists(s) ? Component.translatable(s) : Component.nullToEmpty(realmserror.getErrorMessage())));
|
||||
}
|
||||
}
|
||||
|
||||
private static RealmsGenericErrorScreen.ErrorMessage errorMessage(Component p_289003_) {
|
||||
return errorMessage(Component.translatable("mco.errorMessage.generic"), p_289003_);
|
||||
}
|
||||
|
||||
private static RealmsGenericErrorScreen.ErrorMessage errorMessage(Component p_289010_, Component p_289015_) {
|
||||
return new RealmsGenericErrorScreen.ErrorMessage(p_289010_, p_289015_);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_OK, (p_280728_) -> {
|
||||
this.minecraft.setScreen(this.nextScreen);
|
||||
}).bounds(this.width / 2 - 100, this.height - 52, 200, 20).build());
|
||||
this.line2Split = MultiLineLabel.create(this.font, this.lines.detail, this.width * 3 / 4);
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return Component.empty().append(this.lines.title).append(": ").append(this.lines.detail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int key, int scanCode, int modifiers) {
|
||||
if (key == org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE) {
|
||||
minecraft.setScreen(this.nextScreen);
|
||||
return true;
|
||||
}
|
||||
return super.keyPressed(key, scanCode, modifiers);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_283497_, int p_88680_, int p_88681_, float p_88682_) {
|
||||
this.renderBackground(p_283497_);
|
||||
p_283497_.drawCenteredString(this.font, this.lines.title, this.width / 2, 80, 16777215);
|
||||
this.line2Split.renderCentered(p_283497_, this.width / 2, 100, 9, 16711680);
|
||||
super.render(p_283497_, p_88680_, p_88681_, p_88682_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static record ErrorMessage(Component title, Component detail) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsInviteScreen extends RealmsScreen {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Component NAME_LABEL = Component.translatable("mco.configure.world.invite.profile.name").withStyle((p_289621_) -> {
|
||||
return p_289621_.withColor(-6250336);
|
||||
});
|
||||
private static final Component INVITING_PLAYER_TEXT = Component.translatable("mco.configure.world.players.inviting").withStyle((p_289617_) -> {
|
||||
return p_289617_.withColor(-6250336);
|
||||
});
|
||||
private static final Component NO_SUCH_PLAYER_ERROR_TEXT = Component.translatable("mco.configure.world.players.error").withStyle((p_289622_) -> {
|
||||
return p_289622_.withColor(-65536);
|
||||
});
|
||||
private EditBox profileName;
|
||||
private Button inviteButton;
|
||||
private final RealmsServer serverData;
|
||||
private final RealmsConfigureWorldScreen configureScreen;
|
||||
private final Screen lastScreen;
|
||||
@Nullable
|
||||
private Component message;
|
||||
|
||||
public RealmsInviteScreen(RealmsConfigureWorldScreen p_88703_, Screen p_88704_, RealmsServer p_88705_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.configureScreen = p_88703_;
|
||||
this.lastScreen = p_88704_;
|
||||
this.serverData = p_88705_;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
this.profileName.tick();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.profileName = new EditBox(this.minecraft.font, this.width / 2 - 100, row(2), 200, 20, (EditBox)null, Component.translatable("mco.configure.world.invite.profile.name"));
|
||||
this.addWidget(this.profileName);
|
||||
this.setInitialFocus(this.profileName);
|
||||
this.inviteButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.invite"), (p_88721_) -> {
|
||||
this.onInvite();
|
||||
}).bounds(this.width / 2 - 100, row(10), 200, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, (p_280729_) -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}).bounds(this.width / 2 - 100, row(12), 200, 20).build());
|
||||
}
|
||||
|
||||
private void onInvite() {
|
||||
if (Util.isBlank(this.profileName.getValue())) {
|
||||
this.showMessage(NO_SUCH_PLAYER_ERROR_TEXT);
|
||||
} else {
|
||||
long i = this.serverData.id;
|
||||
String s = this.profileName.getValue().trim();
|
||||
this.inviteButton.active = false;
|
||||
this.profileName.setEditable(false);
|
||||
this.showMessage(INVITING_PLAYER_TEXT);
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return RealmsClient.create().invite(i, s);
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Couldn't invite user");
|
||||
return null;
|
||||
}
|
||||
}, Util.ioPool()).thenAcceptAsync((p_289618_) -> {
|
||||
if (p_289618_ != null) {
|
||||
this.serverData.players = p_289618_.players;
|
||||
this.minecraft.setScreen(new RealmsPlayerScreen(this.configureScreen, this.serverData));
|
||||
} else {
|
||||
this.showMessage(NO_SUCH_PLAYER_ERROR_TEXT);
|
||||
}
|
||||
|
||||
this.profileName.setEditable(true);
|
||||
this.inviteButton.active = true;
|
||||
}, this.screenExecutor);
|
||||
}
|
||||
}
|
||||
|
||||
private void showMessage(Component p_289685_) {
|
||||
this.message = p_289685_;
|
||||
this.minecraft.getNarrator().sayNow(p_289685_);
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88707_, int p_88708_, int p_88709_) {
|
||||
if (p_88707_ == 256) {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_88707_, p_88708_, p_88709_);
|
||||
}
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282206_, int p_283415_, int p_282016_, float p_283011_) {
|
||||
this.renderBackground(p_282206_);
|
||||
p_282206_.drawString(this.font, NAME_LABEL, this.width / 2 - 100, row(1), -1, false);
|
||||
if (this.message != null) {
|
||||
p_282206_.drawCenteredString(this.font, this.message, this.width / 2, row(5), -1);
|
||||
}
|
||||
|
||||
this.profileName.render(p_282206_, p_283415_, p_282016_, p_283011_);
|
||||
super.render(p_282206_, p_283415_, p_282016_, p_283011_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsLongConfirmationScreen extends RealmsScreen {
|
||||
static final Component WARNING = Component.translatable("mco.warning");
|
||||
static final Component INFO = Component.translatable("mco.info");
|
||||
private final RealmsLongConfirmationScreen.Type type;
|
||||
private final Component line2;
|
||||
private final Component line3;
|
||||
protected final BooleanConsumer callback;
|
||||
private final boolean yesNoQuestion;
|
||||
|
||||
public RealmsLongConfirmationScreen(BooleanConsumer p_88731_, RealmsLongConfirmationScreen.Type p_88732_, Component p_88733_, Component p_88734_, boolean p_88735_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.callback = p_88731_;
|
||||
this.type = p_88732_;
|
||||
this.line2 = p_88733_;
|
||||
this.line3 = p_88734_;
|
||||
this.yesNoQuestion = p_88735_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (this.yesNoQuestion) {
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_YES, (p_88751_) -> {
|
||||
this.callback.accept(true);
|
||||
}).bounds(this.width / 2 - 105, row(8), 100, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_NO, (p_88749_) -> {
|
||||
this.callback.accept(false);
|
||||
}).bounds(this.width / 2 + 5, row(8), 100, 20).build());
|
||||
} else {
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_OK, (p_88746_) -> {
|
||||
this.callback.accept(true);
|
||||
}).bounds(this.width / 2 - 50, row(8), 100, 20).build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return CommonComponents.joinLines(this.type.text, this.line2, this.line3);
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88737_, int p_88738_, int p_88739_) {
|
||||
if (p_88737_ == 256) {
|
||||
this.callback.accept(false);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_88737_, p_88738_, p_88739_);
|
||||
}
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282797_, int p_88742_, int p_88743_, float p_88744_) {
|
||||
this.renderBackground(p_282797_);
|
||||
p_282797_.drawCenteredString(this.font, this.type.text, this.width / 2, row(2), this.type.colorCode);
|
||||
p_282797_.drawCenteredString(this.font, this.line2, this.width / 2, row(4), 16777215);
|
||||
p_282797_.drawCenteredString(this.font, this.line3, this.width / 2, row(6), 16777215);
|
||||
super.render(p_282797_, p_88742_, p_88743_, p_88744_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static enum Type {
|
||||
WARNING(RealmsLongConfirmationScreen.WARNING, 16711680),
|
||||
INFO(RealmsLongConfirmationScreen.INFO, 8226750);
|
||||
|
||||
public final int colorCode;
|
||||
public final Component text;
|
||||
|
||||
private Type(Component p_287726_, int p_287605_) {
|
||||
this.text = p_287726_;
|
||||
this.colorCode = p_287605_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.exception.RealmsDefaultUncaughtExceptionHandler;
|
||||
import com.mojang.realmsclient.gui.ErrorCallback;
|
||||
import com.mojang.realmsclient.util.task.LongRunningTask;
|
||||
import java.time.Duration;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.realms.RepeatedNarrator;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsLongRunningMcoTaskScreen extends RealmsScreen implements ErrorCallback {
|
||||
private static final RepeatedNarrator REPEATED_NARRATOR = new RepeatedNarrator(Duration.ofSeconds(5L));
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final Screen lastScreen;
|
||||
private volatile Component title = CommonComponents.EMPTY;
|
||||
@Nullable
|
||||
private volatile Component errorMessage;
|
||||
private volatile boolean aborted;
|
||||
private int animTicks;
|
||||
private final LongRunningTask task;
|
||||
private final int buttonLength = 212;
|
||||
private Button cancelOrBackButton;
|
||||
public static final String[] SYMBOLS = new String[]{"\u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583", "_ \u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584", "_ _ \u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585", "_ _ _ \u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586", "_ _ _ _ \u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587", "_ _ _ _ _ \u2583 \u2584 \u2585 \u2586 \u2587 \u2588", "_ _ _ _ \u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587", "_ _ _ \u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586", "_ _ \u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585", "_ \u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584", "\u2583 \u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583", "\u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583 _", "\u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583 _ _", "\u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583 _ _ _", "\u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583 _ _ _ _", "\u2588 \u2587 \u2586 \u2585 \u2584 \u2583 _ _ _ _ _", "\u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583 _ _ _ _", "\u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583 _ _ _", "\u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583 _ _", "\u2584 \u2585 \u2586 \u2587 \u2588 \u2587 \u2586 \u2585 \u2584 \u2583 _"};
|
||||
|
||||
public RealmsLongRunningMcoTaskScreen(Screen p_88777_, LongRunningTask p_88778_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.lastScreen = p_88777_;
|
||||
this.task = p_88778_;
|
||||
p_88778_.setScreen(this);
|
||||
Thread thread = new Thread(p_88778_, "Realms-long-running-task");
|
||||
thread.setUncaughtExceptionHandler(new RealmsDefaultUncaughtExceptionHandler(LOGGER));
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
REPEATED_NARRATOR.narrate(this.minecraft.getNarrator(), this.title);
|
||||
++this.animTicks;
|
||||
this.task.tick();
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88781_, int p_88782_, int p_88783_) {
|
||||
if (p_88781_ == 256) {
|
||||
this.cancelOrBackButtonClicked();
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_88781_, p_88782_, p_88783_);
|
||||
}
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.task.init();
|
||||
this.cancelOrBackButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, (p_88795_) -> {
|
||||
this.cancelOrBackButtonClicked();
|
||||
}).bounds(this.width / 2 - 106, row(12), 212, 20).build());
|
||||
}
|
||||
|
||||
private void cancelOrBackButtonClicked() {
|
||||
this.aborted = true;
|
||||
this.task.abortTask();
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282789_, int p_88786_, int p_88787_, float p_88788_) {
|
||||
this.renderBackground(p_282789_);
|
||||
p_282789_.drawCenteredString(this.font, this.title, this.width / 2, row(3), 16777215);
|
||||
Component component = this.errorMessage;
|
||||
if (component == null) {
|
||||
p_282789_.drawCenteredString(this.font, SYMBOLS[this.animTicks % SYMBOLS.length], this.width / 2, row(8), 8421504);
|
||||
} else {
|
||||
p_282789_.drawCenteredString(this.font, component, this.width / 2, row(8), 16711680);
|
||||
}
|
||||
|
||||
super.render(p_282789_, p_88786_, p_88787_, p_88788_);
|
||||
}
|
||||
|
||||
public void error(Component p_88792_) {
|
||||
this.errorMessage = p_88792_;
|
||||
this.minecraft.getNarrator().sayNow(p_88792_);
|
||||
this.minecraft.execute(() -> {
|
||||
this.removeWidget(this.cancelOrBackButton);
|
||||
this.cancelOrBackButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_88790_) -> {
|
||||
this.cancelOrBackButtonClicked();
|
||||
}).bounds(this.width / 2 - 106, this.height / 4 + 120 + 12, 200, 20).build());
|
||||
});
|
||||
}
|
||||
|
||||
public void setTitle(Component p_88797_) {
|
||||
this.title = p_88797_;
|
||||
}
|
||||
|
||||
public boolean aborted() {
|
||||
return this.aborted;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsNotification;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.gui.RealmsDataFetcher;
|
||||
import com.mojang.realmsclient.gui.task.DataFetcher;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsNotificationsScreen extends RealmsScreen {
|
||||
private static final ResourceLocation INVITE_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/invite_icon.png");
|
||||
private static final ResourceLocation TRIAL_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/trial_icon.png");
|
||||
private static final ResourceLocation NEWS_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/news_notification_mainscreen.png");
|
||||
private static final ResourceLocation UNSEEN_NOTIFICATION_ICON_LOCATION = new ResourceLocation("minecraft", "textures/gui/unseen_notification.png");
|
||||
@Nullable
|
||||
private DataFetcher.Subscription realmsDataSubscription;
|
||||
@Nullable
|
||||
private RealmsNotificationsScreen.DataFetcherConfiguration currentConfiguration;
|
||||
private volatile int numberOfPendingInvites;
|
||||
static boolean checkedMcoAvailability;
|
||||
private static boolean trialAvailable;
|
||||
static boolean validClient;
|
||||
private static boolean hasUnreadNews;
|
||||
private static boolean hasUnseenNotifications;
|
||||
private final RealmsNotificationsScreen.DataFetcherConfiguration showAll = new RealmsNotificationsScreen.DataFetcherConfiguration() {
|
||||
public DataFetcher.Subscription initDataFetcher(RealmsDataFetcher p_275318_) {
|
||||
DataFetcher.Subscription datafetcher$subscription = p_275318_.dataFetcher.createSubscription();
|
||||
RealmsNotificationsScreen.this.addNewsAndInvitesSubscriptions(p_275318_, datafetcher$subscription);
|
||||
RealmsNotificationsScreen.this.addNotificationsSubscriptions(p_275318_, datafetcher$subscription);
|
||||
return datafetcher$subscription;
|
||||
}
|
||||
|
||||
public boolean showOldNotifications() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
private final RealmsNotificationsScreen.DataFetcherConfiguration onlyNotifications = new RealmsNotificationsScreen.DataFetcherConfiguration() {
|
||||
public DataFetcher.Subscription initDataFetcher(RealmsDataFetcher p_275318_) {
|
||||
DataFetcher.Subscription datafetcher$subscription = p_275318_.dataFetcher.createSubscription();
|
||||
RealmsNotificationsScreen.this.addNotificationsSubscriptions(p_275318_, datafetcher$subscription);
|
||||
return datafetcher$subscription;
|
||||
}
|
||||
|
||||
public boolean showOldNotifications() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public RealmsNotificationsScreen() {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.checkIfMcoEnabled();
|
||||
if (this.realmsDataSubscription != null) {
|
||||
this.realmsDataSubscription.forceUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void added() {
|
||||
super.added();
|
||||
this.minecraft.realmsDataFetcher().notificationsTask.reset();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private RealmsNotificationsScreen.DataFetcherConfiguration getConfiguration() {
|
||||
boolean flag = this.inTitleScreen() && validClient;
|
||||
if (!flag) {
|
||||
return null;
|
||||
} else {
|
||||
return this.getRealmsNotificationsEnabled() ? this.showAll : this.onlyNotifications;
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
RealmsNotificationsScreen.DataFetcherConfiguration realmsnotificationsscreen$datafetcherconfiguration = this.getConfiguration();
|
||||
if (!Objects.equals(this.currentConfiguration, realmsnotificationsscreen$datafetcherconfiguration)) {
|
||||
this.currentConfiguration = realmsnotificationsscreen$datafetcherconfiguration;
|
||||
if (this.currentConfiguration != null) {
|
||||
this.realmsDataSubscription = this.currentConfiguration.initDataFetcher(this.minecraft.realmsDataFetcher());
|
||||
} else {
|
||||
this.realmsDataSubscription = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.realmsDataSubscription != null) {
|
||||
this.realmsDataSubscription.tick();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean getRealmsNotificationsEnabled() {
|
||||
return this.minecraft.options.realmsNotifications().get();
|
||||
}
|
||||
|
||||
private boolean inTitleScreen() {
|
||||
return this.minecraft.screen instanceof TitleScreen;
|
||||
}
|
||||
|
||||
private void checkIfMcoEnabled() {
|
||||
if (!checkedMcoAvailability) {
|
||||
checkedMcoAvailability = true;
|
||||
(new Thread("Realms Notification Availability checker #1") {
|
||||
public void run() {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
RealmsClient.CompatibleVersionResponse realmsclient$compatibleversionresponse = realmsclient.clientCompatible();
|
||||
if (realmsclient$compatibleversionresponse != RealmsClient.CompatibleVersionResponse.COMPATIBLE) {
|
||||
return;
|
||||
}
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
if (realmsserviceexception.httpResultCode != 401) {
|
||||
RealmsNotificationsScreen.checkedMcoAvailability = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
RealmsNotificationsScreen.validClient = true;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282587_, int p_282992_, int p_283028_, float p_281605_) {
|
||||
if (validClient) {
|
||||
this.drawIcons(p_282587_);
|
||||
}
|
||||
|
||||
super.render(p_282587_, p_282992_, p_283028_, p_281605_);
|
||||
}
|
||||
|
||||
private void drawIcons(GuiGraphics p_282966_) {
|
||||
int i = this.numberOfPendingInvites;
|
||||
int j = 24;
|
||||
int k = this.height / 4 + 48;
|
||||
int l = this.width / 2 + 80;
|
||||
int i1 = k + 48 + 2;
|
||||
int j1 = 0;
|
||||
if (hasUnseenNotifications) {
|
||||
p_282966_.blit(UNSEEN_NOTIFICATION_ICON_LOCATION, l - j1 + 5, i1 + 3, 0.0F, 0.0F, 10, 10, 10, 10);
|
||||
j1 += 14;
|
||||
}
|
||||
|
||||
if (this.currentConfiguration != null && this.currentConfiguration.showOldNotifications()) {
|
||||
if (hasUnreadNews) {
|
||||
p_282966_.pose().pushPose();
|
||||
p_282966_.pose().scale(0.4F, 0.4F, 0.4F);
|
||||
p_282966_.blit(NEWS_ICON_LOCATION, (int)((double)(l + 2 - j1) * 2.5D), (int)((double)i1 * 2.5D), 0.0F, 0.0F, 40, 40, 40, 40);
|
||||
p_282966_.pose().popPose();
|
||||
j1 += 14;
|
||||
}
|
||||
|
||||
if (i != 0) {
|
||||
p_282966_.blit(INVITE_ICON_LOCATION, l - j1, i1, 0.0F, 0.0F, 18, 15, 18, 30);
|
||||
j1 += 16;
|
||||
}
|
||||
|
||||
if (trialAvailable) {
|
||||
int k1 = 0;
|
||||
if ((Util.getMillis() / 800L & 1L) == 1L) {
|
||||
k1 = 8;
|
||||
}
|
||||
|
||||
p_282966_.blit(TRIAL_ICON_LOCATION, l + 4 - j1, i1 + 4, 0.0F, (float)k1, 8, 8, 8, 16);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void addNewsAndInvitesSubscriptions(RealmsDataFetcher p_275490_, DataFetcher.Subscription p_275623_) {
|
||||
p_275623_.subscribe(p_275490_.pendingInvitesTask, (p_239521_) -> {
|
||||
this.numberOfPendingInvites = p_239521_;
|
||||
});
|
||||
p_275623_.subscribe(p_275490_.trialAvailabilityTask, (p_239494_) -> {
|
||||
trialAvailable = p_239494_;
|
||||
});
|
||||
p_275623_.subscribe(p_275490_.newsTask, (p_238946_) -> {
|
||||
p_275490_.newsManager.updateUnreadNews(p_238946_);
|
||||
hasUnreadNews = p_275490_.newsManager.hasUnreadNews();
|
||||
});
|
||||
}
|
||||
|
||||
void addNotificationsSubscriptions(RealmsDataFetcher p_275619_, DataFetcher.Subscription p_275628_) {
|
||||
p_275628_.subscribe(p_275619_.notificationsTask, (p_274637_) -> {
|
||||
hasUnseenNotifications = false;
|
||||
|
||||
for(RealmsNotification realmsnotification : p_274637_) {
|
||||
if (!realmsnotification.seen()) {
|
||||
hasUnseenNotifications = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
interface DataFetcherConfiguration {
|
||||
DataFetcher.Subscription initDataFetcher(RealmsDataFetcher p_275608_);
|
||||
|
||||
boolean showOldNotifications();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.MultiLineLabel;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsParentalConsentScreen extends RealmsScreen {
|
||||
private static final Component MESSAGE = Component.translatable("mco.account.privacyinfo");
|
||||
private final Screen nextScreen;
|
||||
private MultiLineLabel messageLines = MultiLineLabel.EMPTY;
|
||||
|
||||
public RealmsParentalConsentScreen(Screen p_88861_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.nextScreen = p_88861_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
Component component = Component.translatable("mco.account.update");
|
||||
Component component1 = CommonComponents.GUI_BACK;
|
||||
int i = Math.max(this.font.width(component), this.font.width(component1)) + 30;
|
||||
Component component2 = Component.translatable("mco.account.privacy.info");
|
||||
int j = (int)((double)this.font.width(component2) * 1.2D);
|
||||
this.addRenderableWidget(Button.builder(component2, (p_88873_) -> {
|
||||
Util.getPlatform().openUri("https://aka.ms/MinecraftGDPR");
|
||||
}).bounds(this.width / 2 - j / 2, row(11), j, 20).build());
|
||||
this.addRenderableWidget(Button.builder(component, (p_88871_) -> {
|
||||
Util.getPlatform().openUri("https://aka.ms/UpdateMojangAccount");
|
||||
}).bounds(this.width / 2 - (i + 5), row(13), i, 20).build());
|
||||
this.addRenderableWidget(Button.builder(component1, (p_280730_) -> {
|
||||
this.minecraft.setScreen(this.nextScreen);
|
||||
}).bounds(this.width / 2 + 5, row(13), i, 20).build());
|
||||
this.messageLines = MultiLineLabel.create(this.font, MESSAGE, (int)Math.round((double)this.width * 0.9D));
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return MESSAGE;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282593_, int p_282889_, int p_283522_, float p_281349_) {
|
||||
this.renderBackground(p_282593_);
|
||||
this.messageLines.renderCentered(p_282593_, this.width / 2, 15, 15, 16777215);
|
||||
super.render(p_282593_, p_282889_, p_283522_, p_281349_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.RealmsMainScreen;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.PendingInvite;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.gui.RowButton;
|
||||
import com.mojang.realmsclient.util.RealmsUtil;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.ObjectSelectionList;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsObjectSelectionList;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsPendingInvitesScreen extends RealmsScreen {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
static final ResourceLocation ACCEPT_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/accept_icon.png");
|
||||
static final ResourceLocation REJECT_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/reject_icon.png");
|
||||
private static final Component NO_PENDING_INVITES_TEXT = Component.translatable("mco.invites.nopending");
|
||||
static final Component ACCEPT_INVITE_TOOLTIP = Component.translatable("mco.invites.button.accept");
|
||||
static final Component REJECT_INVITE_TOOLTIP = Component.translatable("mco.invites.button.reject");
|
||||
private final Screen lastScreen;
|
||||
@Nullable
|
||||
Component toolTip;
|
||||
boolean loaded;
|
||||
RealmsPendingInvitesScreen.PendingInvitationSelectionList pendingInvitationSelectionList;
|
||||
int selectedInvite = -1;
|
||||
private Button acceptButton;
|
||||
private Button rejectButton;
|
||||
|
||||
public RealmsPendingInvitesScreen(Screen p_279260_, Component p_279122_) {
|
||||
super(p_279122_);
|
||||
this.lastScreen = p_279260_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.pendingInvitationSelectionList = new RealmsPendingInvitesScreen.PendingInvitationSelectionList();
|
||||
(new Thread("Realms-pending-invitations-fetcher") {
|
||||
public void run() {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
List<PendingInvite> list = realmsclient.pendingInvites().pendingInvites;
|
||||
List<RealmsPendingInvitesScreen.Entry> list1 = list.stream().map((p_88969_) -> {
|
||||
return RealmsPendingInvitesScreen.this.new Entry(p_88969_);
|
||||
}).collect(Collectors.toList());
|
||||
RealmsPendingInvitesScreen.this.minecraft.execute(() -> {
|
||||
RealmsPendingInvitesScreen.this.pendingInvitationSelectionList.replaceEntries(list1);
|
||||
});
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
RealmsPendingInvitesScreen.LOGGER.error("Couldn't list invites");
|
||||
} finally {
|
||||
RealmsPendingInvitesScreen.this.loaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
this.addWidget(this.pendingInvitationSelectionList);
|
||||
this.acceptButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.invites.button.accept"), (p_88940_) -> {
|
||||
this.accept(this.selectedInvite);
|
||||
this.selectedInvite = -1;
|
||||
this.updateButtonStates();
|
||||
}).bounds(this.width / 2 - 174, this.height - 32, 100, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, (p_280731_) -> {
|
||||
this.minecraft.setScreen(new RealmsMainScreen(this.lastScreen));
|
||||
}).bounds(this.width / 2 - 50, this.height - 32, 100, 20).build());
|
||||
this.rejectButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.invites.button.reject"), (p_88920_) -> {
|
||||
this.reject(this.selectedInvite);
|
||||
this.selectedInvite = -1;
|
||||
this.updateButtonStates();
|
||||
}).bounds(this.width / 2 + 74, this.height - 32, 100, 20).build());
|
||||
this.updateButtonStates();
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_88895_, int p_88896_, int p_88897_) {
|
||||
if (p_88895_ == 256) {
|
||||
this.minecraft.setScreen(new RealmsMainScreen(this.lastScreen));
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_88895_, p_88896_, p_88897_);
|
||||
}
|
||||
}
|
||||
|
||||
void updateList(int p_88893_) {
|
||||
this.pendingInvitationSelectionList.removeAtIndex(p_88893_);
|
||||
}
|
||||
|
||||
void reject(final int p_88923_) {
|
||||
if (p_88923_ < this.pendingInvitationSelectionList.getItemCount()) {
|
||||
(new Thread("Realms-reject-invitation") {
|
||||
public void run() {
|
||||
try {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
realmsclient.rejectInvitation((RealmsPendingInvitesScreen.this.pendingInvitationSelectionList.children().get(p_88923_)).pendingInvite.invitationId);
|
||||
RealmsPendingInvitesScreen.this.minecraft.execute(() -> {
|
||||
RealmsPendingInvitesScreen.this.updateList(p_88923_);
|
||||
});
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
RealmsPendingInvitesScreen.LOGGER.error("Couldn't reject invite");
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void accept(final int p_88933_) {
|
||||
if (p_88933_ < this.pendingInvitationSelectionList.getItemCount()) {
|
||||
(new Thread("Realms-accept-invitation") {
|
||||
public void run() {
|
||||
try {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
realmsclient.acceptInvitation((RealmsPendingInvitesScreen.this.pendingInvitationSelectionList.children().get(p_88933_)).pendingInvite.invitationId);
|
||||
RealmsPendingInvitesScreen.this.minecraft.execute(() -> {
|
||||
RealmsPendingInvitesScreen.this.updateList(p_88933_);
|
||||
});
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
RealmsPendingInvitesScreen.LOGGER.error("Couldn't accept invite");
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282787_, int p_88900_, int p_88901_, float p_88902_) {
|
||||
this.toolTip = null;
|
||||
this.renderBackground(p_282787_);
|
||||
this.pendingInvitationSelectionList.render(p_282787_, p_88900_, p_88901_, p_88902_);
|
||||
p_282787_.drawCenteredString(this.font, this.title, this.width / 2, 12, 16777215);
|
||||
if (this.toolTip != null) {
|
||||
this.renderMousehoverTooltip(p_282787_, this.toolTip, p_88900_, p_88901_);
|
||||
}
|
||||
|
||||
if (this.pendingInvitationSelectionList.getItemCount() == 0 && this.loaded) {
|
||||
p_282787_.drawCenteredString(this.font, NO_PENDING_INVITES_TEXT, this.width / 2, this.height / 2 - 20, 16777215);
|
||||
}
|
||||
|
||||
super.render(p_282787_, p_88900_, p_88901_, p_88902_);
|
||||
}
|
||||
|
||||
protected void renderMousehoverTooltip(GuiGraphics p_282344_, @Nullable Component p_283454_, int p_281609_, int p_283288_) {
|
||||
if (p_283454_ != null) {
|
||||
int i = p_281609_ + 12;
|
||||
int j = p_283288_ - 12;
|
||||
int k = this.font.width(p_283454_);
|
||||
p_282344_.fillGradient(i - 3, j - 3, i + k + 3, j + 8 + 3, -1073741824, -1073741824);
|
||||
p_282344_.drawString(this.font, p_283454_, i, j, 16777215);
|
||||
}
|
||||
}
|
||||
|
||||
void updateButtonStates() {
|
||||
this.acceptButton.visible = this.shouldAcceptAndRejectButtonBeVisible(this.selectedInvite);
|
||||
this.rejectButton.visible = this.shouldAcceptAndRejectButtonBeVisible(this.selectedInvite);
|
||||
}
|
||||
|
||||
private boolean shouldAcceptAndRejectButtonBeVisible(int p_88963_) {
|
||||
return p_88963_ != -1;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class Entry extends ObjectSelectionList.Entry<RealmsPendingInvitesScreen.Entry> {
|
||||
private static final int TEXT_LEFT = 38;
|
||||
final PendingInvite pendingInvite;
|
||||
private final List<RowButton> rowButtons;
|
||||
|
||||
Entry(PendingInvite p_88996_) {
|
||||
this.pendingInvite = p_88996_;
|
||||
this.rowButtons = Arrays.asList(new RealmsPendingInvitesScreen.Entry.AcceptRowButton(), new RealmsPendingInvitesScreen.Entry.RejectRowButton());
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281445_, int p_281806_, int p_283610_, int p_282909_, int p_281705_, int p_281977_, int p_282983_, int p_281655_, boolean p_282274_, float p_282862_) {
|
||||
this.renderPendingInvitationItem(p_281445_, this.pendingInvite, p_282909_, p_283610_, p_282983_, p_281655_);
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_88998_, double p_88999_, int p_89000_) {
|
||||
RowButton.rowButtonMouseClicked(RealmsPendingInvitesScreen.this.pendingInvitationSelectionList, this, this.rowButtons, p_89000_, p_88998_, p_88999_);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void renderPendingInvitationItem(GuiGraphics p_281764_, PendingInvite p_282748_, int p_282810_, int p_282994_, int p_283639_, int p_283659_) {
|
||||
p_281764_.drawString(RealmsPendingInvitesScreen.this.font, p_282748_.worldName, p_282810_ + 38, p_282994_ + 1, 16777215, false);
|
||||
p_281764_.drawString(RealmsPendingInvitesScreen.this.font, p_282748_.worldOwnerName, p_282810_ + 38, p_282994_ + 12, 7105644, false);
|
||||
p_281764_.drawString(RealmsPendingInvitesScreen.this.font, RealmsUtil.convertToAgePresentationFromInstant(p_282748_.date), p_282810_ + 38, p_282994_ + 24, 7105644, false);
|
||||
RowButton.drawButtonsInRow(p_281764_, this.rowButtons, RealmsPendingInvitesScreen.this.pendingInvitationSelectionList, p_282810_, p_282994_, p_283639_, p_283659_);
|
||||
RealmsUtil.renderPlayerFace(p_281764_, p_282810_, p_282994_, 32, p_282748_.worldOwnerUuid);
|
||||
}
|
||||
|
||||
public Component getNarration() {
|
||||
Component component = CommonComponents.joinLines(Component.literal(this.pendingInvite.worldName), Component.literal(this.pendingInvite.worldOwnerName), RealmsUtil.convertToAgePresentationFromInstant(this.pendingInvite.date));
|
||||
return Component.translatable("narrator.select", component);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class AcceptRowButton extends RowButton {
|
||||
AcceptRowButton() {
|
||||
super(15, 15, 215, 5);
|
||||
}
|
||||
|
||||
protected void draw(GuiGraphics p_282151_, int p_283695_, int p_282436_, boolean p_282168_) {
|
||||
float f = p_282168_ ? 19.0F : 0.0F;
|
||||
p_282151_.blit(RealmsPendingInvitesScreen.ACCEPT_ICON_LOCATION, p_283695_, p_282436_, f, 0.0F, 18, 18, 37, 18);
|
||||
if (p_282168_) {
|
||||
RealmsPendingInvitesScreen.this.toolTip = RealmsPendingInvitesScreen.ACCEPT_INVITE_TOOLTIP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onClick(int p_89029_) {
|
||||
RealmsPendingInvitesScreen.this.accept(p_89029_);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class RejectRowButton extends RowButton {
|
||||
RejectRowButton() {
|
||||
super(15, 15, 235, 5);
|
||||
}
|
||||
|
||||
protected void draw(GuiGraphics p_282457_, int p_281421_, int p_281260_, boolean p_281476_) {
|
||||
float f = p_281476_ ? 19.0F : 0.0F;
|
||||
p_282457_.blit(RealmsPendingInvitesScreen.REJECT_ICON_LOCATION, p_281421_, p_281260_, f, 0.0F, 18, 18, 37, 18);
|
||||
if (p_281476_) {
|
||||
RealmsPendingInvitesScreen.this.toolTip = RealmsPendingInvitesScreen.REJECT_INVITE_TOOLTIP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onClick(int p_89039_) {
|
||||
RealmsPendingInvitesScreen.this.reject(p_89039_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class PendingInvitationSelectionList extends RealmsObjectSelectionList<RealmsPendingInvitesScreen.Entry> {
|
||||
public PendingInvitationSelectionList() {
|
||||
super(RealmsPendingInvitesScreen.this.width, RealmsPendingInvitesScreen.this.height, 32, RealmsPendingInvitesScreen.this.height - 40, 36);
|
||||
}
|
||||
|
||||
public void removeAtIndex(int p_89058_) {
|
||||
this.remove(p_89058_);
|
||||
}
|
||||
|
||||
public int getMaxPosition() {
|
||||
return this.getItemCount() * 36;
|
||||
}
|
||||
|
||||
public int getRowWidth() {
|
||||
return 260;
|
||||
}
|
||||
|
||||
public void renderBackground(GuiGraphics p_282494_) {
|
||||
RealmsPendingInvitesScreen.this.renderBackground(p_282494_);
|
||||
}
|
||||
|
||||
public void selectItem(int p_89049_) {
|
||||
super.selectItem(p_89049_);
|
||||
this.selectInviteListItem(p_89049_);
|
||||
}
|
||||
|
||||
public void selectInviteListItem(int p_89061_) {
|
||||
RealmsPendingInvitesScreen.this.selectedInvite = p_89061_;
|
||||
RealmsPendingInvitesScreen.this.updateButtonStates();
|
||||
}
|
||||
|
||||
public void setSelected(@Nullable RealmsPendingInvitesScreen.Entry p_89053_) {
|
||||
super.setSelected(p_89053_);
|
||||
RealmsPendingInvitesScreen.this.selectedInvite = this.children().indexOf(p_89053_);
|
||||
RealmsPendingInvitesScreen.this.updateButtonStates();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.Ops;
|
||||
import com.mojang.realmsclient.dto.PlayerInfo;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.util.RealmsUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.ImageButton;
|
||||
import net.minecraft.client.gui.components.ObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.Tooltip;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsObjectSelectionList;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsPlayerScreen extends RealmsScreen {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
static final ResourceLocation OP_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/op_icon.png");
|
||||
static final ResourceLocation USER_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/user_icon.png");
|
||||
static final ResourceLocation CROSS_ICON_LOCATION = new ResourceLocation("realms", "textures/gui/realms/cross_player_icon.png");
|
||||
private static final ResourceLocation OPTIONS_BACKGROUND = new ResourceLocation("minecraft", "textures/gui/options_background.png");
|
||||
private static final Component QUESTION_TITLE = Component.translatable("mco.question");
|
||||
static final Component NORMAL_USER_TOOLTIP = Component.translatable("mco.configure.world.invites.normal.tooltip");
|
||||
static final Component OP_TOOLTIP = Component.translatable("mco.configure.world.invites.ops.tooltip");
|
||||
static final Component REMOVE_ENTRY_TOOLTIP = Component.translatable("mco.configure.world.invites.remove.tooltip");
|
||||
private static final int NO_ENTRY_SELECTED = -1;
|
||||
private final RealmsConfigureWorldScreen lastScreen;
|
||||
final RealmsServer serverData;
|
||||
RealmsPlayerScreen.InvitedObjectSelectionList invitedObjectSelectionList;
|
||||
int column1X;
|
||||
int columnWidth;
|
||||
private Button removeButton;
|
||||
private Button opdeopButton;
|
||||
int playerIndex = -1;
|
||||
private boolean stateChanged;
|
||||
|
||||
public RealmsPlayerScreen(RealmsConfigureWorldScreen p_89089_, RealmsServer p_89090_) {
|
||||
super(Component.translatable("mco.configure.world.players.title"));
|
||||
this.lastScreen = p_89089_;
|
||||
this.serverData = p_89090_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.column1X = this.width / 2 - 160;
|
||||
this.columnWidth = 150;
|
||||
int i = this.width / 2 + 12;
|
||||
this.invitedObjectSelectionList = new RealmsPlayerScreen.InvitedObjectSelectionList();
|
||||
this.invitedObjectSelectionList.setLeftPos(this.column1X);
|
||||
this.addWidget(this.invitedObjectSelectionList);
|
||||
|
||||
for(PlayerInfo playerinfo : this.serverData.players) {
|
||||
this.invitedObjectSelectionList.addEntry(playerinfo);
|
||||
}
|
||||
|
||||
this.playerIndex = -1;
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.invite"), (p_280732_) -> {
|
||||
this.minecraft.setScreen(new RealmsInviteScreen(this.lastScreen, this, this.serverData));
|
||||
}).bounds(i, row(1), this.columnWidth + 10, 20).build());
|
||||
this.removeButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.invites.remove.tooltip"), (p_278866_) -> {
|
||||
this.uninvite(this.playerIndex);
|
||||
}).bounds(i, row(7), this.columnWidth + 10, 20).build());
|
||||
this.opdeopButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.invites.ops.tooltip"), (p_278869_) -> {
|
||||
if (this.serverData.players.get(this.playerIndex).isOperator()) {
|
||||
this.deop(this.playerIndex);
|
||||
} else {
|
||||
this.op(this.playerIndex);
|
||||
}
|
||||
|
||||
}).bounds(i, row(9), this.columnWidth + 10, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_89122_) -> {
|
||||
this.backButtonClicked();
|
||||
}).bounds(i + this.columnWidth / 2 + 2, row(12), this.columnWidth / 2 + 10 - 2, 20).build());
|
||||
this.updateButtonStates();
|
||||
}
|
||||
|
||||
void updateButtonStates() {
|
||||
this.removeButton.visible = this.shouldRemoveAndOpdeopButtonBeVisible(this.playerIndex);
|
||||
this.opdeopButton.visible = this.shouldRemoveAndOpdeopButtonBeVisible(this.playerIndex);
|
||||
this.invitedObjectSelectionList.updateButtons();
|
||||
}
|
||||
|
||||
private boolean shouldRemoveAndOpdeopButtonBeVisible(int p_89191_) {
|
||||
return p_89191_ != -1;
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_89094_, int p_89095_, int p_89096_) {
|
||||
if (p_89094_ == 256) {
|
||||
this.backButtonClicked();
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_89094_, p_89095_, p_89096_);
|
||||
}
|
||||
}
|
||||
|
||||
private void backButtonClicked() {
|
||||
if (this.stateChanged) {
|
||||
this.minecraft.setScreen(this.lastScreen.getNewScreen());
|
||||
} else {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void op(int p_89193_) {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
String s = this.serverData.players.get(p_89193_).getUuid();
|
||||
|
||||
try {
|
||||
this.updateOps(realmsclient.op(this.serverData.id, s));
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't op the user");
|
||||
}
|
||||
|
||||
this.updateButtonStates();
|
||||
}
|
||||
|
||||
void deop(int p_89195_) {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
String s = this.serverData.players.get(p_89195_).getUuid();
|
||||
|
||||
try {
|
||||
this.updateOps(realmsclient.deop(this.serverData.id, s));
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't deop the user");
|
||||
}
|
||||
|
||||
this.updateButtonStates();
|
||||
}
|
||||
|
||||
private void updateOps(Ops p_89108_) {
|
||||
for(PlayerInfo playerinfo : this.serverData.players) {
|
||||
playerinfo.setOperator(p_89108_.ops.contains(playerinfo.getName()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void uninvite(int p_89197_) {
|
||||
this.updateButtonStates();
|
||||
if (p_89197_ >= 0 && p_89197_ < this.serverData.players.size()) {
|
||||
PlayerInfo playerinfo = this.serverData.players.get(p_89197_);
|
||||
RealmsConfirmScreen realmsconfirmscreen = new RealmsConfirmScreen((p_278868_) -> {
|
||||
if (p_278868_) {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
realmsclient.uninvite(this.serverData.id, playerinfo.getUuid());
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't uninvite user");
|
||||
}
|
||||
|
||||
this.serverData.players.remove(this.playerIndex);
|
||||
this.playerIndex = -1;
|
||||
this.updateButtonStates();
|
||||
}
|
||||
|
||||
this.stateChanged = true;
|
||||
this.minecraft.setScreen(this);
|
||||
}, QUESTION_TITLE, Component.translatable("mco.configure.world.uninvite.player", playerinfo.getName()));
|
||||
this.minecraft.setScreen(realmsconfirmscreen);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281762_, int p_282648_, int p_282676_, float p_281822_) {
|
||||
this.renderBackground(p_281762_);
|
||||
this.invitedObjectSelectionList.render(p_281762_, p_282648_, p_282676_, p_281822_);
|
||||
p_281762_.drawCenteredString(this.font, this.title, this.width / 2, 17, 16777215);
|
||||
int i = row(12) + 20;
|
||||
p_281762_.setColor(0.25F, 0.25F, 0.25F, 1.0F);
|
||||
p_281762_.blit(OPTIONS_BACKGROUND, 0, i, 0.0F, 0.0F, this.width, this.height - i, 32, 32);
|
||||
p_281762_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
String s = this.serverData.players != null ? Integer.toString(this.serverData.players.size()) : "0";
|
||||
p_281762_.drawString(this.font, Component.translatable("mco.configure.world.invited.number", s), this.column1X, row(0), 10526880, false);
|
||||
super.render(p_281762_, p_282648_, p_282676_, p_281822_);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class Entry extends ObjectSelectionList.Entry<RealmsPlayerScreen.Entry> {
|
||||
private static final int X_OFFSET = 3;
|
||||
private static final int Y_PADDING = 1;
|
||||
private static final int BUTTON_WIDTH = 8;
|
||||
private static final int BUTTON_HEIGHT = 7;
|
||||
private final PlayerInfo playerInfo;
|
||||
private final List<AbstractWidget> children = new ArrayList<>();
|
||||
private final ImageButton removeButton;
|
||||
private final ImageButton makeOpButton;
|
||||
private final ImageButton removeOpButton;
|
||||
|
||||
public Entry(PlayerInfo p_89204_) {
|
||||
this.playerInfo = p_89204_;
|
||||
int i = RealmsPlayerScreen.this.serverData.players.indexOf(this.playerInfo);
|
||||
int j = RealmsPlayerScreen.this.invitedObjectSelectionList.getRowRight() - 16 - 9;
|
||||
int k = RealmsPlayerScreen.this.invitedObjectSelectionList.getRowTop(i) + 1;
|
||||
this.removeButton = new ImageButton(j, k, 8, 7, 0, 0, 7, RealmsPlayerScreen.CROSS_ICON_LOCATION, 8, 14, (p_279099_) -> {
|
||||
RealmsPlayerScreen.this.uninvite(i);
|
||||
});
|
||||
this.removeButton.setTooltip(Tooltip.create(RealmsPlayerScreen.REMOVE_ENTRY_TOOLTIP));
|
||||
this.children.add(this.removeButton);
|
||||
j += 11;
|
||||
this.makeOpButton = new ImageButton(j, k, 8, 7, 0, 0, 7, RealmsPlayerScreen.USER_ICON_LOCATION, 8, 14, (p_279435_) -> {
|
||||
RealmsPlayerScreen.this.op(i);
|
||||
});
|
||||
this.makeOpButton.setTooltip(Tooltip.create(RealmsPlayerScreen.NORMAL_USER_TOOLTIP));
|
||||
this.children.add(this.makeOpButton);
|
||||
this.removeOpButton = new ImageButton(j, k, 8, 7, 0, 0, 7, RealmsPlayerScreen.OP_ICON_LOCATION, 8, 14, (p_279383_) -> {
|
||||
RealmsPlayerScreen.this.deop(i);
|
||||
});
|
||||
this.removeOpButton.setTooltip(Tooltip.create(RealmsPlayerScreen.OP_TOOLTIP));
|
||||
this.children.add(this.removeOpButton);
|
||||
this.updateButtons();
|
||||
}
|
||||
|
||||
public void updateButtons() {
|
||||
this.makeOpButton.visible = !this.playerInfo.isOperator();
|
||||
this.removeOpButton.visible = !this.makeOpButton.visible;
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_279264_, double p_279493_, int p_279168_) {
|
||||
if (!this.makeOpButton.mouseClicked(p_279264_, p_279493_, p_279168_)) {
|
||||
this.removeOpButton.mouseClicked(p_279264_, p_279493_, p_279168_);
|
||||
}
|
||||
|
||||
this.removeButton.mouseClicked(p_279264_, p_279493_, p_279168_);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282985_, int p_281343_, int p_283042_, int p_282863_, int p_281381_, int p_282692_, int p_283240_, int p_282706_, boolean p_283067_, float p_282230_) {
|
||||
int i;
|
||||
if (!this.playerInfo.getAccepted()) {
|
||||
i = 10526880;
|
||||
} else if (this.playerInfo.getOnline()) {
|
||||
i = 8388479;
|
||||
} else {
|
||||
i = 16777215;
|
||||
}
|
||||
|
||||
RealmsUtil.renderPlayerFace(p_282985_, RealmsPlayerScreen.this.column1X + 2 + 2, p_283042_ + 1, 8, this.playerInfo.getUuid());
|
||||
p_282985_.drawString(RealmsPlayerScreen.this.font, this.playerInfo.getName(), RealmsPlayerScreen.this.column1X + 3 + 12, p_283042_ + 1, i, false);
|
||||
this.children.forEach((p_280738_) -> {
|
||||
p_280738_.setY(p_283042_ + 1);
|
||||
p_280738_.render(p_282985_, p_283240_, p_282706_, p_282230_);
|
||||
});
|
||||
}
|
||||
|
||||
public Component getNarration() {
|
||||
return Component.translatable("narrator.select", this.playerInfo.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class InvitedObjectSelectionList extends RealmsObjectSelectionList<RealmsPlayerScreen.Entry> {
|
||||
public InvitedObjectSelectionList() {
|
||||
super(RealmsPlayerScreen.this.columnWidth + 10, RealmsPlayerScreen.row(12) + 20, RealmsPlayerScreen.row(1), RealmsPlayerScreen.row(12) + 20, 13);
|
||||
}
|
||||
|
||||
public void updateButtons() {
|
||||
if (RealmsPlayerScreen.this.playerIndex != -1) {
|
||||
this.getEntry(RealmsPlayerScreen.this.playerIndex).updateButtons();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addEntry(PlayerInfo p_89244_) {
|
||||
this.addEntry(RealmsPlayerScreen.this.new Entry(p_89244_));
|
||||
}
|
||||
|
||||
public int getRowWidth() {
|
||||
return (int)((double)this.width * 1.0D);
|
||||
}
|
||||
|
||||
public void selectItem(int p_89234_) {
|
||||
super.selectItem(p_89234_);
|
||||
this.selectInviteListItem(p_89234_);
|
||||
}
|
||||
|
||||
public void selectInviteListItem(int p_89251_) {
|
||||
RealmsPlayerScreen.this.playerIndex = p_89251_;
|
||||
RealmsPlayerScreen.this.updateButtonStates();
|
||||
}
|
||||
|
||||
public void setSelected(@Nullable RealmsPlayerScreen.Entry p_89246_) {
|
||||
super.setSelected(p_89246_);
|
||||
RealmsPlayerScreen.this.playerIndex = this.children().indexOf(p_89246_);
|
||||
RealmsPlayerScreen.this.updateButtonStates();
|
||||
}
|
||||
|
||||
public void renderBackground(GuiGraphics p_282559_) {
|
||||
RealmsPlayerScreen.this.renderBackground(p_282559_);
|
||||
}
|
||||
|
||||
public int getScrollbarPosition() {
|
||||
return RealmsPlayerScreen.this.column1X + this.width - 5;
|
||||
}
|
||||
|
||||
public int getMaxPosition() {
|
||||
return this.getItemCount() * 13;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.realmsclient.util.LevelType;
|
||||
import com.mojang.realmsclient.util.WorldGenerationInfo;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.CycleButton;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsResetNormalWorldScreen extends RealmsScreen {
|
||||
private static final Component SEED_LABEL = Component.translatable("mco.reset.world.seed");
|
||||
private final Consumer<WorldGenerationInfo> callback;
|
||||
private EditBox seedEdit;
|
||||
private LevelType levelType = LevelType.DEFAULT;
|
||||
private boolean generateStructures = true;
|
||||
private final Component buttonTitle;
|
||||
|
||||
public RealmsResetNormalWorldScreen(Consumer<WorldGenerationInfo> p_167438_, Component p_167439_) {
|
||||
super(Component.translatable("mco.reset.world.generate"));
|
||||
this.callback = p_167438_;
|
||||
this.buttonTitle = p_167439_;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
this.seedEdit.tick();
|
||||
super.tick();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.seedEdit = new EditBox(this.minecraft.font, this.width / 2 - 100, row(2), 200, 20, (EditBox)null, Component.translatable("mco.reset.world.seed"));
|
||||
this.seedEdit.setMaxLength(32);
|
||||
this.addWidget(this.seedEdit);
|
||||
this.setInitialFocus(this.seedEdit);
|
||||
this.addRenderableWidget(CycleButton.builder(LevelType::getName).withValues(LevelType.values()).withInitialValue(this.levelType).create(this.width / 2 - 102, row(4), 205, 20, Component.translatable("selectWorld.mapType"), (p_167441_, p_167442_) -> {
|
||||
this.levelType = p_167442_;
|
||||
}));
|
||||
this.addRenderableWidget(CycleButton.onOffBuilder(this.generateStructures).create(this.width / 2 - 102, row(6) - 2, 205, 20, Component.translatable("selectWorld.mapFeatures"), (p_167444_, p_167445_) -> {
|
||||
this.generateStructures = p_167445_;
|
||||
}));
|
||||
this.addRenderableWidget(Button.builder(this.buttonTitle, (p_89291_) -> {
|
||||
this.callback.accept(new WorldGenerationInfo(this.seedEdit.getValue(), this.levelType, this.generateStructures));
|
||||
}).bounds(this.width / 2 - 102, row(12), 97, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_89288_) -> {
|
||||
this.onClose();
|
||||
}).bounds(this.width / 2 + 8, row(12), 97, 20).build());
|
||||
}
|
||||
|
||||
public void onClose() {
|
||||
this.callback.accept((WorldGenerationInfo)null);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281862_, int p_282455_, int p_281572_, float p_282211_) {
|
||||
this.renderBackground(p_281862_);
|
||||
p_281862_.drawCenteredString(this.font, this.title, this.width / 2, 17, 16777215);
|
||||
p_281862_.drawString(this.font, SEED_LABEL, this.width / 2 - 100, row(1), 10526880, false);
|
||||
this.seedEdit.render(p_281862_, p_282455_, p_281572_, p_282211_);
|
||||
super.render(p_281862_, p_282455_, p_281572_, p_282211_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.WorldTemplate;
|
||||
import com.mojang.realmsclient.dto.WorldTemplatePaginatedList;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.util.WorldGenerationInfo;
|
||||
import com.mojang.realmsclient.util.task.LongRunningTask;
|
||||
import com.mojang.realmsclient.util.task.ResettingGeneratedWorldTask;
|
||||
import com.mojang.realmsclient.util.task.ResettingTemplateWorldTask;
|
||||
import com.mojang.realmsclient.util.task.SwitchSlotTask;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsLabel;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsResetWorldScreen extends RealmsScreen {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final Screen lastScreen;
|
||||
private final RealmsServer serverData;
|
||||
private Component subtitle = Component.translatable("mco.reset.world.warning");
|
||||
private Component buttonTitle = CommonComponents.GUI_CANCEL;
|
||||
private int subtitleColor = 16711680;
|
||||
private static final ResourceLocation SLOT_FRAME_LOCATION = new ResourceLocation("realms", "textures/gui/realms/slot_frame.png");
|
||||
private static final ResourceLocation UPLOAD_LOCATION = new ResourceLocation("realms", "textures/gui/realms/upload.png");
|
||||
private static final ResourceLocation ADVENTURE_MAP_LOCATION = new ResourceLocation("realms", "textures/gui/realms/adventure.png");
|
||||
private static final ResourceLocation SURVIVAL_SPAWN_LOCATION = new ResourceLocation("realms", "textures/gui/realms/survival_spawn.png");
|
||||
private static final ResourceLocation NEW_WORLD_LOCATION = new ResourceLocation("realms", "textures/gui/realms/new_world.png");
|
||||
private static final ResourceLocation EXPERIENCE_LOCATION = new ResourceLocation("realms", "textures/gui/realms/experience.png");
|
||||
private static final ResourceLocation INSPIRATION_LOCATION = new ResourceLocation("realms", "textures/gui/realms/inspiration.png");
|
||||
WorldTemplatePaginatedList templates;
|
||||
WorldTemplatePaginatedList adventuremaps;
|
||||
WorldTemplatePaginatedList experiences;
|
||||
WorldTemplatePaginatedList inspirations;
|
||||
public int slot = -1;
|
||||
private Component resetTitle = Component.translatable("mco.reset.world.resetting.screen.title");
|
||||
private final Runnable resetWorldRunnable;
|
||||
private final Runnable callback;
|
||||
|
||||
public RealmsResetWorldScreen(Screen p_167448_, RealmsServer p_167449_, Component p_167450_, Runnable p_167451_, Runnable p_167452_) {
|
||||
super(p_167450_);
|
||||
this.lastScreen = p_167448_;
|
||||
this.serverData = p_167449_;
|
||||
this.resetWorldRunnable = p_167451_;
|
||||
this.callback = p_167452_;
|
||||
}
|
||||
|
||||
public RealmsResetWorldScreen(Screen p_89329_, RealmsServer p_89330_, Runnable p_89331_, Runnable p_89332_) {
|
||||
this(p_89329_, p_89330_, Component.translatable("mco.reset.world.title"), p_89331_, p_89332_);
|
||||
}
|
||||
|
||||
public RealmsResetWorldScreen(Screen p_89334_, RealmsServer p_89335_, Component p_89336_, Component p_89337_, int p_89338_, Component p_89339_, Runnable p_89340_, Runnable p_89341_) {
|
||||
this(p_89334_, p_89335_, p_89336_, p_89340_, p_89341_);
|
||||
this.subtitle = p_89337_;
|
||||
this.subtitleColor = p_89338_;
|
||||
this.buttonTitle = p_89339_;
|
||||
}
|
||||
|
||||
public void setSlot(int p_89344_) {
|
||||
this.slot = p_89344_;
|
||||
}
|
||||
|
||||
public void setResetTitle(Component p_89390_) {
|
||||
this.resetTitle = p_89390_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.addRenderableWidget(Button.builder(this.buttonTitle, (p_280741_) -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}).bounds(this.width / 2 - 40, row(14) - 10, 80, 20).build());
|
||||
(new Thread("Realms-reset-world-fetcher") {
|
||||
public void run() {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
WorldTemplatePaginatedList worldtemplatepaginatedlist = realmsclient.fetchWorldTemplates(1, 10, RealmsServer.WorldType.NORMAL);
|
||||
WorldTemplatePaginatedList worldtemplatepaginatedlist1 = realmsclient.fetchWorldTemplates(1, 10, RealmsServer.WorldType.ADVENTUREMAP);
|
||||
WorldTemplatePaginatedList worldtemplatepaginatedlist2 = realmsclient.fetchWorldTemplates(1, 10, RealmsServer.WorldType.EXPERIENCE);
|
||||
WorldTemplatePaginatedList worldtemplatepaginatedlist3 = realmsclient.fetchWorldTemplates(1, 10, RealmsServer.WorldType.INSPIRATION);
|
||||
RealmsResetWorldScreen.this.minecraft.execute(() -> {
|
||||
RealmsResetWorldScreen.this.templates = worldtemplatepaginatedlist;
|
||||
RealmsResetWorldScreen.this.adventuremaps = worldtemplatepaginatedlist1;
|
||||
RealmsResetWorldScreen.this.experiences = worldtemplatepaginatedlist2;
|
||||
RealmsResetWorldScreen.this.inspirations = worldtemplatepaginatedlist3;
|
||||
});
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
RealmsResetWorldScreen.LOGGER.error("Couldn't fetch templates in reset world", (Throwable)realmsserviceexception);
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
this.addLabel(new RealmsLabel(this.subtitle, this.width / 2, 22, this.subtitleColor));
|
||||
this.addRenderableWidget(new RealmsResetWorldScreen.FrameButton(this.frame(1), row(0) + 10, Component.translatable("mco.reset.world.generate"), NEW_WORLD_LOCATION, (p_280746_) -> {
|
||||
this.minecraft.setScreen(new RealmsResetNormalWorldScreen(this::generationSelectionCallback, this.title));
|
||||
}));
|
||||
this.addRenderableWidget(new RealmsResetWorldScreen.FrameButton(this.frame(2), row(0) + 10, Component.translatable("mco.reset.world.upload"), UPLOAD_LOCATION, (p_280744_) -> {
|
||||
this.minecraft.setScreen(new RealmsSelectFileToUploadScreen(this.serverData.id, this.slot != -1 ? this.slot : this.serverData.activeSlot, this, this.callback));
|
||||
}));
|
||||
this.addRenderableWidget(new RealmsResetWorldScreen.FrameButton(this.frame(3), row(0) + 10, Component.translatable("mco.reset.world.template"), SURVIVAL_SPAWN_LOCATION, (p_280742_) -> {
|
||||
this.minecraft.setScreen(new RealmsSelectWorldTemplateScreen(Component.translatable("mco.reset.world.template"), this::templateSelectionCallback, RealmsServer.WorldType.NORMAL, this.templates));
|
||||
}));
|
||||
this.addRenderableWidget(new RealmsResetWorldScreen.FrameButton(this.frame(1), row(6) + 20, Component.translatable("mco.reset.world.adventure"), ADVENTURE_MAP_LOCATION, (p_280739_) -> {
|
||||
this.minecraft.setScreen(new RealmsSelectWorldTemplateScreen(Component.translatable("mco.reset.world.adventure"), this::templateSelectionCallback, RealmsServer.WorldType.ADVENTUREMAP, this.adventuremaps));
|
||||
}));
|
||||
this.addRenderableWidget(new RealmsResetWorldScreen.FrameButton(this.frame(2), row(6) + 20, Component.translatable("mco.reset.world.experience"), EXPERIENCE_LOCATION, (p_280745_) -> {
|
||||
this.minecraft.setScreen(new RealmsSelectWorldTemplateScreen(Component.translatable("mco.reset.world.experience"), this::templateSelectionCallback, RealmsServer.WorldType.EXPERIENCE, this.experiences));
|
||||
}));
|
||||
this.addRenderableWidget(new RealmsResetWorldScreen.FrameButton(this.frame(3), row(6) + 20, Component.translatable("mco.reset.world.inspiration"), INSPIRATION_LOCATION, (p_280740_) -> {
|
||||
this.minecraft.setScreen(new RealmsSelectWorldTemplateScreen(Component.translatable("mco.reset.world.inspiration"), this::templateSelectionCallback, RealmsServer.WorldType.INSPIRATION, this.inspirations));
|
||||
}));
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return CommonComponents.joinForNarration(this.getTitle(), this.createLabelNarration());
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_89346_, int p_89347_, int p_89348_) {
|
||||
if (p_89346_ == 256) {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_89346_, p_89347_, p_89348_);
|
||||
}
|
||||
}
|
||||
|
||||
private int frame(int p_89393_) {
|
||||
return this.width / 2 - 130 + (p_89393_ - 1) * 100;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282623_, int p_282142_, int p_281508_, float p_283104_) {
|
||||
this.renderBackground(p_282623_);
|
||||
p_282623_.drawCenteredString(this.font, this.title, this.width / 2, 7, 16777215);
|
||||
super.render(p_282623_, p_282142_, p_281508_, p_283104_);
|
||||
}
|
||||
|
||||
void drawFrame(GuiGraphics p_283049_, int p_282569_, int p_282343_, Component p_281871_, ResourceLocation p_281613_, boolean p_282720_, boolean p_282971_) {
|
||||
if (p_282720_) {
|
||||
p_283049_.setColor(0.56F, 0.56F, 0.56F, 1.0F);
|
||||
}
|
||||
|
||||
p_283049_.blit(p_281613_, p_282569_ + 2, p_282343_ + 14, 0.0F, 0.0F, 56, 56, 56, 56);
|
||||
p_283049_.blit(SLOT_FRAME_LOCATION, p_282569_, p_282343_ + 12, 0.0F, 0.0F, 60, 60, 60, 60);
|
||||
int i = p_282720_ ? 10526880 : 16777215;
|
||||
p_283049_.drawCenteredString(this.font, p_281871_, p_282569_ + 30, p_282343_, i);
|
||||
p_283049_.setColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
private void startTask(LongRunningTask p_167458_) {
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this.lastScreen, p_167458_));
|
||||
}
|
||||
|
||||
public void switchSlot(Runnable p_89383_) {
|
||||
this.startTask(new SwitchSlotTask(this.serverData.id, this.slot, () -> {
|
||||
this.minecraft.execute(p_89383_);
|
||||
}));
|
||||
}
|
||||
|
||||
private void templateSelectionCallback(@Nullable WorldTemplate p_167454_) {
|
||||
this.minecraft.setScreen(this);
|
||||
if (p_167454_ != null) {
|
||||
this.resetWorld(() -> {
|
||||
this.startTask(new ResettingTemplateWorldTask(p_167454_, this.serverData.id, this.resetTitle, this.resetWorldRunnable));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void generationSelectionCallback(@Nullable WorldGenerationInfo p_167456_) {
|
||||
this.minecraft.setScreen(this);
|
||||
if (p_167456_ != null) {
|
||||
this.resetWorld(() -> {
|
||||
this.startTask(new ResettingGeneratedWorldTask(p_167456_, this.serverData.id, this.resetTitle, this.resetWorldRunnable));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void resetWorld(Runnable p_167465_) {
|
||||
if (this.slot == -1) {
|
||||
p_167465_.run();
|
||||
} else {
|
||||
this.switchSlot(p_167465_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class FrameButton extends Button {
|
||||
private final ResourceLocation image;
|
||||
|
||||
public FrameButton(int p_89439_, int p_89440_, Component p_89441_, ResourceLocation p_89442_, Button.OnPress p_89443_) {
|
||||
super(p_89439_, p_89440_, 60, 72, p_89441_, p_89443_, DEFAULT_NARRATION);
|
||||
this.image = p_89442_;
|
||||
}
|
||||
|
||||
public void renderWidget(GuiGraphics p_282595_, int p_282741_, int p_283560_, float p_281923_) {
|
||||
RealmsResetWorldScreen.this.drawFrame(p_282595_, this.getX(), this.getY(), this.getMessage(), this.image, this.isHoveredOrFocused(), this.isMouseOver((double)p_282741_, (double)p_283560_));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.ObjectSelectionList;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsLabel;
|
||||
import net.minecraft.realms.RealmsObjectSelectionList;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.LevelSummary;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsSelectFileToUploadScreen extends RealmsScreen {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Component UNABLE_TO_LOAD_WORLD = Component.translatable("selectWorld.unable_to_load");
|
||||
static final Component WORLD_TEXT = Component.translatable("selectWorld.world");
|
||||
static final Component HARDCORE_TEXT = Component.translatable("mco.upload.hardcore").withStyle((p_264655_) -> {
|
||||
return p_264655_.withColor(-65536);
|
||||
});
|
||||
static final Component CHEATS_TEXT = Component.translatable("selectWorld.cheats");
|
||||
private static final DateFormat DATE_FORMAT = new SimpleDateFormat();
|
||||
private final RealmsResetWorldScreen lastScreen;
|
||||
private final long worldId;
|
||||
private final int slotId;
|
||||
Button uploadButton;
|
||||
List<LevelSummary> levelList = Lists.newArrayList();
|
||||
int selectedWorld = -1;
|
||||
RealmsSelectFileToUploadScreen.WorldSelectionList worldSelectionList;
|
||||
private final Runnable callback;
|
||||
|
||||
public RealmsSelectFileToUploadScreen(long p_89498_, int p_89499_, RealmsResetWorldScreen p_89500_, Runnable p_89501_) {
|
||||
super(Component.translatable("mco.upload.select.world.title"));
|
||||
this.lastScreen = p_89500_;
|
||||
this.worldId = p_89498_;
|
||||
this.slotId = p_89499_;
|
||||
this.callback = p_89501_;
|
||||
}
|
||||
|
||||
private void loadLevelList() throws Exception {
|
||||
LevelStorageSource.LevelCandidates levelstoragesource$levelcandidates = this.minecraft.getLevelSource().findLevelCandidates();
|
||||
this.levelList = this.minecraft.getLevelSource().loadLevelSummaries(levelstoragesource$levelcandidates).join().stream().filter((p_193517_) -> {
|
||||
return !p_193517_.requiresManualConversion() && !p_193517_.isLocked();
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
for(LevelSummary levelsummary : this.levelList) {
|
||||
this.worldSelectionList.addEntry(levelsummary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.worldSelectionList = new RealmsSelectFileToUploadScreen.WorldSelectionList();
|
||||
|
||||
try {
|
||||
this.loadLevelList();
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Couldn't load level list", (Throwable)exception);
|
||||
this.minecraft.setScreen(new RealmsGenericErrorScreen(UNABLE_TO_LOAD_WORLD, Component.nullToEmpty(exception.getMessage()), this.lastScreen));
|
||||
return;
|
||||
}
|
||||
|
||||
this.addWidget(this.worldSelectionList);
|
||||
this.uploadButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.upload.button.name"), (p_231307_) -> {
|
||||
this.upload();
|
||||
}).bounds(this.width / 2 - 154, this.height - 32, 153, 20).build());
|
||||
this.uploadButton.active = this.selectedWorld >= 0 && this.selectedWorld < this.levelList.size();
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_280747_) -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}).bounds(this.width / 2 + 6, this.height - 32, 153, 20).build());
|
||||
this.addLabel(new RealmsLabel(Component.translatable("mco.upload.select.world.subtitle"), this.width / 2, row(-1), 10526880));
|
||||
if (this.levelList.isEmpty()) {
|
||||
this.addLabel(new RealmsLabel(Component.translatable("mco.upload.select.world.none"), this.width / 2, this.height / 2 - 20, 16777215));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return CommonComponents.joinForNarration(this.getTitle(), this.createLabelNarration());
|
||||
}
|
||||
|
||||
private void upload() {
|
||||
if (this.selectedWorld != -1 && !this.levelList.get(this.selectedWorld).isHardcore()) {
|
||||
LevelSummary levelsummary = this.levelList.get(this.selectedWorld);
|
||||
this.minecraft.setScreen(new RealmsUploadScreen(this.worldId, this.slotId, this.lastScreen, levelsummary, this.callback));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281244_, int p_282772_, int p_281746_, float p_281757_) {
|
||||
this.renderBackground(p_281244_);
|
||||
this.worldSelectionList.render(p_281244_, p_282772_, p_281746_, p_281757_);
|
||||
p_281244_.drawCenteredString(this.font, this.title, this.width / 2, 13, 16777215);
|
||||
super.render(p_281244_, p_282772_, p_281746_, p_281757_);
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_89506_, int p_89507_, int p_89508_) {
|
||||
if (p_89506_ == 256) {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_89506_, p_89507_, p_89508_);
|
||||
}
|
||||
}
|
||||
|
||||
static Component gameModeName(LevelSummary p_89535_) {
|
||||
return p_89535_.getGameMode().getLongDisplayName();
|
||||
}
|
||||
|
||||
static String formatLastPlayed(LevelSummary p_89539_) {
|
||||
return DATE_FORMAT.format(new Date(p_89539_.getLastPlayed()));
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class Entry extends ObjectSelectionList.Entry<RealmsSelectFileToUploadScreen.Entry> {
|
||||
private final LevelSummary levelSummary;
|
||||
private final String name;
|
||||
private final Component id;
|
||||
private final Component info;
|
||||
|
||||
public Entry(LevelSummary p_89560_) {
|
||||
this.levelSummary = p_89560_;
|
||||
this.name = p_89560_.getLevelName();
|
||||
this.id = Component.translatable("mco.upload.entry.id", p_89560_.getLevelId(), RealmsSelectFileToUploadScreen.formatLastPlayed(p_89560_));
|
||||
Component component;
|
||||
if (p_89560_.isHardcore()) {
|
||||
component = RealmsSelectFileToUploadScreen.HARDCORE_TEXT;
|
||||
} else {
|
||||
component = RealmsSelectFileToUploadScreen.gameModeName(p_89560_);
|
||||
}
|
||||
|
||||
if (p_89560_.hasCheats()) {
|
||||
component = Component.translatable("mco.upload.entry.cheats", component.getString(), RealmsSelectFileToUploadScreen.CHEATS_TEXT);
|
||||
}
|
||||
|
||||
this.info = component;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282307_, int p_281918_, int p_281770_, int p_282954_, int p_281599_, int p_281852_, int p_283452_, int p_282531_, boolean p_283120_, float p_282082_) {
|
||||
this.renderItem(p_282307_, p_281918_, p_282954_, p_281770_);
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_89562_, double p_89563_, int p_89564_) {
|
||||
RealmsSelectFileToUploadScreen.this.worldSelectionList.selectItem(RealmsSelectFileToUploadScreen.this.levelList.indexOf(this.levelSummary));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void renderItem(GuiGraphics p_282872_, int p_283187_, int p_283611_, int p_282173_) {
|
||||
String s;
|
||||
if (this.name.isEmpty()) {
|
||||
s = RealmsSelectFileToUploadScreen.WORLD_TEXT + " " + (p_283187_ + 1);
|
||||
} else {
|
||||
s = this.name;
|
||||
}
|
||||
|
||||
p_282872_.drawString(RealmsSelectFileToUploadScreen.this.font, s, p_283611_ + 2, p_282173_ + 1, 16777215, false);
|
||||
p_282872_.drawString(RealmsSelectFileToUploadScreen.this.font, this.id, p_283611_ + 2, p_282173_ + 12, 8421504, false);
|
||||
p_282872_.drawString(RealmsSelectFileToUploadScreen.this.font, this.info, p_283611_ + 2, p_282173_ + 12 + 10, 8421504, false);
|
||||
}
|
||||
|
||||
public Component getNarration() {
|
||||
Component component = CommonComponents.joinLines(Component.literal(this.levelSummary.getLevelName()), Component.literal(RealmsSelectFileToUploadScreen.formatLastPlayed(this.levelSummary)), RealmsSelectFileToUploadScreen.gameModeName(this.levelSummary));
|
||||
return Component.translatable("narrator.select", component);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class WorldSelectionList extends RealmsObjectSelectionList<RealmsSelectFileToUploadScreen.Entry> {
|
||||
public WorldSelectionList() {
|
||||
super(RealmsSelectFileToUploadScreen.this.width, RealmsSelectFileToUploadScreen.this.height, RealmsSelectFileToUploadScreen.row(0), RealmsSelectFileToUploadScreen.this.height - 40, 36);
|
||||
}
|
||||
|
||||
public void addEntry(LevelSummary p_89588_) {
|
||||
this.addEntry(RealmsSelectFileToUploadScreen.this.new Entry(p_89588_));
|
||||
}
|
||||
|
||||
public int getMaxPosition() {
|
||||
return RealmsSelectFileToUploadScreen.this.levelList.size() * 36;
|
||||
}
|
||||
|
||||
public void renderBackground(GuiGraphics p_281249_) {
|
||||
RealmsSelectFileToUploadScreen.this.renderBackground(p_281249_);
|
||||
}
|
||||
|
||||
public void setSelected(@Nullable RealmsSelectFileToUploadScreen.Entry p_89592_) {
|
||||
super.setSelected(p_89592_);
|
||||
RealmsSelectFileToUploadScreen.this.selectedWorld = this.children().indexOf(p_89592_);
|
||||
RealmsSelectFileToUploadScreen.this.uploadButton.active = RealmsSelectFileToUploadScreen.this.selectedWorld >= 0 && RealmsSelectFileToUploadScreen.this.selectedWorld < this.getItemCount() && !RealmsSelectFileToUploadScreen.this.levelList.get(RealmsSelectFileToUploadScreen.this.selectedWorld).isHardcore();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,474 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.WorldTemplate;
|
||||
import com.mojang.realmsclient.dto.WorldTemplatePaginatedList;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.util.RealmsTextureManager;
|
||||
import com.mojang.realmsclient.util.TextRenderingUtils;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.ObjectSelectionList;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsObjectSelectionList;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsSelectWorldTemplateScreen extends RealmsScreen {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
static final ResourceLocation LINK_ICON = new ResourceLocation("realms", "textures/gui/realms/link_icons.png");
|
||||
static final ResourceLocation TRAILER_ICON = new ResourceLocation("realms", "textures/gui/realms/trailer_icons.png");
|
||||
static final ResourceLocation SLOT_FRAME_LOCATION = new ResourceLocation("realms", "textures/gui/realms/slot_frame.png");
|
||||
static final Component PUBLISHER_LINK_TOOLTIP = Component.translatable("mco.template.info.tooltip");
|
||||
static final Component TRAILER_LINK_TOOLTIP = Component.translatable("mco.template.trailer.tooltip");
|
||||
private final Consumer<WorldTemplate> callback;
|
||||
RealmsSelectWorldTemplateScreen.WorldTemplateObjectSelectionList worldTemplateObjectSelectionList;
|
||||
int selectedTemplate = -1;
|
||||
private Button selectButton;
|
||||
private Button trailerButton;
|
||||
private Button publisherButton;
|
||||
@Nullable
|
||||
Component toolTip;
|
||||
@Nullable
|
||||
String currentLink;
|
||||
private final RealmsServer.WorldType worldType;
|
||||
int clicks;
|
||||
@Nullable
|
||||
private Component[] warning;
|
||||
private String warningURL;
|
||||
boolean displayWarning;
|
||||
private boolean hoverWarning;
|
||||
@Nullable
|
||||
List<TextRenderingUtils.Line> noTemplatesMessage;
|
||||
|
||||
public RealmsSelectWorldTemplateScreen(Component p_167481_, Consumer<WorldTemplate> p_167482_, RealmsServer.WorldType p_167483_) {
|
||||
this(p_167481_, p_167482_, p_167483_, (WorldTemplatePaginatedList)null);
|
||||
}
|
||||
|
||||
public RealmsSelectWorldTemplateScreen(Component p_167485_, Consumer<WorldTemplate> p_167486_, RealmsServer.WorldType p_167487_, @Nullable WorldTemplatePaginatedList p_167488_) {
|
||||
super(p_167485_);
|
||||
this.callback = p_167486_;
|
||||
this.worldType = p_167487_;
|
||||
if (p_167488_ == null) {
|
||||
this.worldTemplateObjectSelectionList = new RealmsSelectWorldTemplateScreen.WorldTemplateObjectSelectionList();
|
||||
this.fetchTemplatesAsync(new WorldTemplatePaginatedList(10));
|
||||
} else {
|
||||
this.worldTemplateObjectSelectionList = new RealmsSelectWorldTemplateScreen.WorldTemplateObjectSelectionList(Lists.newArrayList(p_167488_.templates));
|
||||
this.fetchTemplatesAsync(p_167488_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setWarning(Component... p_89683_) {
|
||||
this.warning = p_89683_;
|
||||
this.displayWarning = true;
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_89629_, double p_89630_, int p_89631_) {
|
||||
if (this.hoverWarning && this.warningURL != null) {
|
||||
Util.getPlatform().openUri("https://www.minecraft.net/realms/adventure-maps-in-1-9");
|
||||
return true;
|
||||
} else {
|
||||
return super.mouseClicked(p_89629_, p_89630_, p_89631_);
|
||||
}
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.worldTemplateObjectSelectionList = new RealmsSelectWorldTemplateScreen.WorldTemplateObjectSelectionList(this.worldTemplateObjectSelectionList.getTemplates());
|
||||
this.trailerButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.template.button.trailer"), (p_89701_) -> {
|
||||
this.onTrailer();
|
||||
}).bounds(this.width / 2 - 206, this.height - 32, 100, 20).build());
|
||||
this.selectButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.template.button.select"), (p_89696_) -> {
|
||||
this.selectTemplate();
|
||||
}).bounds(this.width / 2 - 100, this.height - 32, 100, 20).build());
|
||||
Component component = this.worldType == RealmsServer.WorldType.MINIGAME ? CommonComponents.GUI_CANCEL : CommonComponents.GUI_BACK;
|
||||
Button button = Button.builder(component, (p_89691_) -> {
|
||||
this.onClose();
|
||||
}).bounds(this.width / 2 + 6, this.height - 32, 100, 20).build();
|
||||
this.addRenderableWidget(button);
|
||||
this.publisherButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.template.button.publisher"), (p_89679_) -> {
|
||||
this.onPublish();
|
||||
}).bounds(this.width / 2 + 112, this.height - 32, 100, 20).build());
|
||||
this.selectButton.active = false;
|
||||
this.trailerButton.visible = false;
|
||||
this.publisherButton.visible = false;
|
||||
this.addWidget(this.worldTemplateObjectSelectionList);
|
||||
this.magicalSpecialHackyFocus(this.worldTemplateObjectSelectionList);
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
List<Component> list = Lists.newArrayListWithCapacity(2);
|
||||
if (this.title != null) {
|
||||
list.add(this.title);
|
||||
}
|
||||
|
||||
if (this.warning != null) {
|
||||
list.addAll(Arrays.asList(this.warning));
|
||||
}
|
||||
|
||||
return CommonComponents.joinLines(list);
|
||||
}
|
||||
|
||||
void updateButtonStates() {
|
||||
this.publisherButton.visible = this.shouldPublisherBeVisible();
|
||||
this.trailerButton.visible = this.shouldTrailerBeVisible();
|
||||
this.selectButton.active = this.shouldSelectButtonBeActive();
|
||||
}
|
||||
|
||||
private boolean shouldSelectButtonBeActive() {
|
||||
return this.selectedTemplate != -1;
|
||||
}
|
||||
|
||||
private boolean shouldPublisherBeVisible() {
|
||||
return this.selectedTemplate != -1 && !this.getSelectedTemplate().link.isEmpty();
|
||||
}
|
||||
|
||||
private WorldTemplate getSelectedTemplate() {
|
||||
return this.worldTemplateObjectSelectionList.get(this.selectedTemplate);
|
||||
}
|
||||
|
||||
private boolean shouldTrailerBeVisible() {
|
||||
return this.selectedTemplate != -1 && !this.getSelectedTemplate().trailer.isEmpty();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
--this.clicks;
|
||||
if (this.clicks < 0) {
|
||||
this.clicks = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onClose() {
|
||||
this.callback.accept((WorldTemplate)null);
|
||||
}
|
||||
|
||||
void selectTemplate() {
|
||||
if (this.hasValidTemplate()) {
|
||||
this.callback.accept(this.getSelectedTemplate());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean hasValidTemplate() {
|
||||
return this.selectedTemplate >= 0 && this.selectedTemplate < this.worldTemplateObjectSelectionList.getItemCount();
|
||||
}
|
||||
|
||||
private void onTrailer() {
|
||||
if (this.hasValidTemplate()) {
|
||||
WorldTemplate worldtemplate = this.getSelectedTemplate();
|
||||
if (!"".equals(worldtemplate.trailer)) {
|
||||
Util.getPlatform().openUri(worldtemplate.trailer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onPublish() {
|
||||
if (this.hasValidTemplate()) {
|
||||
WorldTemplate worldtemplate = this.getSelectedTemplate();
|
||||
if (!"".equals(worldtemplate.link)) {
|
||||
Util.getPlatform().openUri(worldtemplate.link);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void fetchTemplatesAsync(final WorldTemplatePaginatedList p_89654_) {
|
||||
(new Thread("realms-template-fetcher") {
|
||||
public void run() {
|
||||
WorldTemplatePaginatedList worldtemplatepaginatedlist = p_89654_;
|
||||
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
while (worldtemplatepaginatedlist != null) {
|
||||
Either<WorldTemplatePaginatedList, String> either = RealmsSelectWorldTemplateScreen.this.fetchTemplates(worldtemplatepaginatedlist, realmsclient);
|
||||
worldtemplatepaginatedlist = RealmsSelectWorldTemplateScreen.this.minecraft.submit(() -> {
|
||||
if (either.right().isPresent()) {
|
||||
RealmsSelectWorldTemplateScreen.LOGGER.error("Couldn't fetch templates: {}", either.right().get());
|
||||
if (RealmsSelectWorldTemplateScreen.this.worldTemplateObjectSelectionList.isEmpty()) {
|
||||
RealmsSelectWorldTemplateScreen.this.noTemplatesMessage = TextRenderingUtils.decompose(I18n.get("mco.template.select.failure"));
|
||||
}
|
||||
|
||||
return null;
|
||||
} else {
|
||||
WorldTemplatePaginatedList worldtemplatepaginatedlist1 = either.left().get();
|
||||
|
||||
for(WorldTemplate worldtemplate : worldtemplatepaginatedlist1.templates) {
|
||||
RealmsSelectWorldTemplateScreen.this.worldTemplateObjectSelectionList.addEntry(worldtemplate);
|
||||
}
|
||||
|
||||
if (worldtemplatepaginatedlist1.templates.isEmpty()) {
|
||||
if (RealmsSelectWorldTemplateScreen.this.worldTemplateObjectSelectionList.isEmpty()) {
|
||||
String s = I18n.get("mco.template.select.none", "%link");
|
||||
TextRenderingUtils.LineSegment textrenderingutils$linesegment = TextRenderingUtils.LineSegment.link(I18n.get("mco.template.select.none.linkTitle"), "https://aka.ms/MinecraftRealmsContentCreator");
|
||||
RealmsSelectWorldTemplateScreen.this.noTemplatesMessage = TextRenderingUtils.decompose(s, textrenderingutils$linesegment);
|
||||
}
|
||||
|
||||
return null;
|
||||
} else {
|
||||
return worldtemplatepaginatedlist1;
|
||||
}
|
||||
}
|
||||
}).join();
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
Either<WorldTemplatePaginatedList, String> fetchTemplates(WorldTemplatePaginatedList p_89656_, RealmsClient p_89657_) {
|
||||
try {
|
||||
return Either.left(p_89657_.fetchWorldTemplates(p_89656_.page + 1, p_89656_.size, this.worldType));
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
return Either.right(realmsserviceexception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282162_, int p_89640_, int p_89641_, float p_89642_) {
|
||||
this.toolTip = null;
|
||||
this.currentLink = null;
|
||||
this.hoverWarning = false;
|
||||
this.renderBackground(p_282162_);
|
||||
this.worldTemplateObjectSelectionList.render(p_282162_, p_89640_, p_89641_, p_89642_);
|
||||
if (this.noTemplatesMessage != null) {
|
||||
this.renderMultilineMessage(p_282162_, p_89640_, p_89641_, this.noTemplatesMessage);
|
||||
}
|
||||
|
||||
p_282162_.drawCenteredString(this.font, this.title, this.width / 2, 13, 16777215);
|
||||
if (this.displayWarning) {
|
||||
Component[] acomponent = this.warning;
|
||||
|
||||
for(int i = 0; i < acomponent.length; ++i) {
|
||||
int j = this.font.width(acomponent[i]);
|
||||
int k = this.width / 2 - j / 2;
|
||||
int l = row(-1 + i);
|
||||
if (p_89640_ >= k && p_89640_ <= k + j && p_89641_ >= l && p_89641_ <= l + 9) {
|
||||
this.hoverWarning = true;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i1 = 0; i1 < acomponent.length; ++i1) {
|
||||
Component component = acomponent[i1];
|
||||
int j1 = 10526880;
|
||||
if (this.warningURL != null) {
|
||||
if (this.hoverWarning) {
|
||||
j1 = 7107012;
|
||||
component = component.copy().withStyle(ChatFormatting.STRIKETHROUGH);
|
||||
} else {
|
||||
j1 = 3368635;
|
||||
}
|
||||
}
|
||||
|
||||
p_282162_.drawCenteredString(this.font, component, this.width / 2, row(-1 + i1), j1);
|
||||
}
|
||||
}
|
||||
|
||||
super.render(p_282162_, p_89640_, p_89641_, p_89642_);
|
||||
this.renderMousehoverTooltip(p_282162_, this.toolTip, p_89640_, p_89641_);
|
||||
}
|
||||
|
||||
private void renderMultilineMessage(GuiGraphics p_282398_, int p_282163_, int p_282021_, List<TextRenderingUtils.Line> p_282203_) {
|
||||
for(int i = 0; i < p_282203_.size(); ++i) {
|
||||
TextRenderingUtils.Line textrenderingutils$line = p_282203_.get(i);
|
||||
int j = row(4 + i);
|
||||
int k = textrenderingutils$line.segments.stream().mapToInt((p_280748_) -> {
|
||||
return this.font.width(p_280748_.renderedText());
|
||||
}).sum();
|
||||
int l = this.width / 2 - k / 2;
|
||||
|
||||
for(TextRenderingUtils.LineSegment textrenderingutils$linesegment : textrenderingutils$line.segments) {
|
||||
int i1 = textrenderingutils$linesegment.isLink() ? 3368635 : 16777215;
|
||||
int j1 = p_282398_.drawString(this.font, textrenderingutils$linesegment.renderedText(), l, j, i1);
|
||||
if (textrenderingutils$linesegment.isLink() && p_282163_ > l && p_282163_ < j1 && p_282021_ > j - 3 && p_282021_ < j + 8) {
|
||||
this.toolTip = Component.literal(textrenderingutils$linesegment.getLinkUrl());
|
||||
this.currentLink = textrenderingutils$linesegment.getLinkUrl();
|
||||
}
|
||||
|
||||
l = j1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void renderMousehoverTooltip(GuiGraphics p_281524_, @Nullable Component p_281755_, int p_282387_, int p_281491_) {
|
||||
if (p_281755_ != null) {
|
||||
int i = p_282387_ + 12;
|
||||
int j = p_281491_ - 12;
|
||||
int k = this.font.width(p_281755_);
|
||||
p_281524_.fillGradient(i - 3, j - 3, i + k + 3, j + 8 + 3, -1073741824, -1073741824);
|
||||
p_281524_.drawString(this.font, p_281755_, i, j, 16777215);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class Entry extends ObjectSelectionList.Entry<RealmsSelectWorldTemplateScreen.Entry> {
|
||||
final WorldTemplate template;
|
||||
|
||||
public Entry(WorldTemplate p_89753_) {
|
||||
this.template = p_89753_;
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281796_, int p_282160_, int p_281759_, int p_282961_, int p_281497_, int p_282427_, int p_283550_, int p_282955_, boolean p_282866_, float p_281452_) {
|
||||
this.renderWorldTemplateItem(p_281796_, this.template, p_282961_, p_281759_, p_283550_, p_282955_);
|
||||
}
|
||||
|
||||
private void renderWorldTemplateItem(GuiGraphics p_282991_, WorldTemplate p_281775_, int p_281335_, int p_282289_, int p_281708_, int p_281391_) {
|
||||
int i = p_281335_ + 45 + 20;
|
||||
p_282991_.drawString(RealmsSelectWorldTemplateScreen.this.font, p_281775_.name, i, p_282289_ + 2, 16777215, false);
|
||||
p_282991_.drawString(RealmsSelectWorldTemplateScreen.this.font, p_281775_.author, i, p_282289_ + 15, 7105644, false);
|
||||
p_282991_.drawString(RealmsSelectWorldTemplateScreen.this.font, p_281775_.version, i + 227 - RealmsSelectWorldTemplateScreen.this.font.width(p_281775_.version), p_282289_ + 1, 7105644, false);
|
||||
if (!"".equals(p_281775_.link) || !"".equals(p_281775_.trailer) || !"".equals(p_281775_.recommendedPlayers)) {
|
||||
this.drawIcons(p_282991_, i - 1, p_282289_ + 25, p_281708_, p_281391_, p_281775_.link, p_281775_.trailer, p_281775_.recommendedPlayers);
|
||||
}
|
||||
|
||||
this.drawImage(p_282991_, p_281335_, p_282289_ + 1, p_281708_, p_281391_, p_281775_);
|
||||
}
|
||||
|
||||
private void drawImage(GuiGraphics p_282450_, int p_281877_, int p_282680_, int p_281921_, int p_283193_, WorldTemplate p_282405_) {
|
||||
p_282450_.blit(RealmsTextureManager.worldTemplate(p_282405_.id, p_282405_.image), p_281877_ + 1, p_282680_ + 1, 0.0F, 0.0F, 38, 38, 38, 38);
|
||||
p_282450_.blit(RealmsSelectWorldTemplateScreen.SLOT_FRAME_LOCATION, p_281877_, p_282680_, 0.0F, 0.0F, 40, 40, 40, 40);
|
||||
}
|
||||
|
||||
private void drawIcons(GuiGraphics p_281993_, int p_281797_, int p_281328_, int p_283015_, int p_281905_, String p_281390_, String p_281552_, String p_281807_) {
|
||||
if (!"".equals(p_281807_)) {
|
||||
p_281993_.drawString(RealmsSelectWorldTemplateScreen.this.font, p_281807_, p_281797_, p_281328_ + 4, 5000268, false);
|
||||
}
|
||||
|
||||
int i = "".equals(p_281807_) ? 0 : RealmsSelectWorldTemplateScreen.this.font.width(p_281807_) + 2;
|
||||
boolean flag = false;
|
||||
boolean flag1 = false;
|
||||
boolean flag2 = "".equals(p_281390_);
|
||||
if (p_283015_ >= p_281797_ + i && p_283015_ <= p_281797_ + i + 32 && p_281905_ >= p_281328_ && p_281905_ <= p_281328_ + 15 && p_281905_ < RealmsSelectWorldTemplateScreen.this.height - 15 && p_281905_ > 32) {
|
||||
if (p_283015_ <= p_281797_ + 15 + i && p_283015_ > i) {
|
||||
if (flag2) {
|
||||
flag1 = true;
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
} else if (!flag2) {
|
||||
flag1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag2) {
|
||||
float f = flag ? 15.0F : 0.0F;
|
||||
p_281993_.blit(RealmsSelectWorldTemplateScreen.LINK_ICON, p_281797_ + i, p_281328_, f, 0.0F, 15, 15, 30, 15);
|
||||
}
|
||||
|
||||
if (!"".equals(p_281552_)) {
|
||||
int j = p_281797_ + i + (flag2 ? 0 : 17);
|
||||
float f1 = flag1 ? 15.0F : 0.0F;
|
||||
p_281993_.blit(RealmsSelectWorldTemplateScreen.TRAILER_ICON, j, p_281328_, f1, 0.0F, 15, 15, 30, 15);
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
RealmsSelectWorldTemplateScreen.this.toolTip = RealmsSelectWorldTemplateScreen.PUBLISHER_LINK_TOOLTIP;
|
||||
RealmsSelectWorldTemplateScreen.this.currentLink = p_281390_;
|
||||
} else if (flag1 && !"".equals(p_281552_)) {
|
||||
RealmsSelectWorldTemplateScreen.this.toolTip = RealmsSelectWorldTemplateScreen.TRAILER_LINK_TOOLTIP;
|
||||
RealmsSelectWorldTemplateScreen.this.currentLink = p_281552_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Component getNarration() {
|
||||
Component component = CommonComponents.joinLines(Component.literal(this.template.name), Component.translatable("mco.template.select.narrate.authors", this.template.author), Component.literal(this.template.recommendedPlayers), Component.translatable("mco.template.select.narrate.version", this.template.version));
|
||||
return Component.translatable("narrator.select", component);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class WorldTemplateObjectSelectionList extends RealmsObjectSelectionList<RealmsSelectWorldTemplateScreen.Entry> {
|
||||
public WorldTemplateObjectSelectionList() {
|
||||
this(Collections.emptyList());
|
||||
}
|
||||
|
||||
public WorldTemplateObjectSelectionList(Iterable<WorldTemplate> p_89795_) {
|
||||
super(RealmsSelectWorldTemplateScreen.this.width, RealmsSelectWorldTemplateScreen.this.height, RealmsSelectWorldTemplateScreen.this.displayWarning ? RealmsSelectWorldTemplateScreen.row(1) : 32, RealmsSelectWorldTemplateScreen.this.height - 40, 46);
|
||||
p_89795_.forEach(this::addEntry);
|
||||
}
|
||||
|
||||
public void addEntry(WorldTemplate p_89805_) {
|
||||
this.addEntry(RealmsSelectWorldTemplateScreen.this.new Entry(p_89805_));
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_89797_, double p_89798_, int p_89799_) {
|
||||
if (p_89799_ == 0 && p_89798_ >= (double)this.y0 && p_89798_ <= (double)this.y1) {
|
||||
int i = this.width / 2 - 150;
|
||||
if (RealmsSelectWorldTemplateScreen.this.currentLink != null) {
|
||||
Util.getPlatform().openUri(RealmsSelectWorldTemplateScreen.this.currentLink);
|
||||
}
|
||||
|
||||
int j = (int)Math.floor(p_89798_ - (double)this.y0) - this.headerHeight + (int)this.getScrollAmount() - 4;
|
||||
int k = j / this.itemHeight;
|
||||
if (p_89797_ >= (double)i && p_89797_ < (double)this.getScrollbarPosition() && k >= 0 && j >= 0 && k < this.getItemCount()) {
|
||||
this.selectItem(k);
|
||||
this.itemClicked(j, k, p_89797_, p_89798_, this.width, p_89799_);
|
||||
if (k >= RealmsSelectWorldTemplateScreen.this.worldTemplateObjectSelectionList.getItemCount()) {
|
||||
return super.mouseClicked(p_89797_, p_89798_, p_89799_);
|
||||
}
|
||||
|
||||
RealmsSelectWorldTemplateScreen.this.clicks += 7;
|
||||
if (RealmsSelectWorldTemplateScreen.this.clicks >= 10) {
|
||||
RealmsSelectWorldTemplateScreen.this.selectTemplate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseClicked(p_89797_, p_89798_, p_89799_);
|
||||
}
|
||||
|
||||
public void setSelected(@Nullable RealmsSelectWorldTemplateScreen.Entry p_89807_) {
|
||||
super.setSelected(p_89807_);
|
||||
RealmsSelectWorldTemplateScreen.this.selectedTemplate = this.children().indexOf(p_89807_);
|
||||
RealmsSelectWorldTemplateScreen.this.updateButtonStates();
|
||||
}
|
||||
|
||||
public int getMaxPosition() {
|
||||
return this.getItemCount() * 46;
|
||||
}
|
||||
|
||||
public int getRowWidth() {
|
||||
return 300;
|
||||
}
|
||||
|
||||
public void renderBackground(GuiGraphics p_282384_) {
|
||||
RealmsSelectWorldTemplateScreen.this.renderBackground(p_282384_);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.getItemCount() == 0;
|
||||
}
|
||||
|
||||
public WorldTemplate get(int p_89812_) {
|
||||
return (this.children().get(p_89812_)).template;
|
||||
}
|
||||
|
||||
public List<WorldTemplate> getTemplates() {
|
||||
return this.children().stream().map((p_89814_) -> {
|
||||
return p_89814_.template;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsSettingsScreen extends RealmsScreen {
|
||||
private static final int COMPONENT_WIDTH = 212;
|
||||
private static final Component NAME_LABEL = Component.translatable("mco.configure.world.name");
|
||||
private static final Component DESCRIPTION_LABEL = Component.translatable("mco.configure.world.description");
|
||||
private final RealmsConfigureWorldScreen configureWorldScreen;
|
||||
private final RealmsServer serverData;
|
||||
private Button doneButton;
|
||||
private EditBox descEdit;
|
||||
private EditBox nameEdit;
|
||||
|
||||
public RealmsSettingsScreen(RealmsConfigureWorldScreen p_89829_, RealmsServer p_89830_) {
|
||||
super(Component.translatable("mco.configure.world.settings.title"));
|
||||
this.configureWorldScreen = p_89829_;
|
||||
this.serverData = p_89830_;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
this.nameEdit.tick();
|
||||
this.descEdit.tick();
|
||||
this.doneButton.active = !this.nameEdit.getValue().trim().isEmpty();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
int i = this.width / 2 - 106;
|
||||
this.doneButton = this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.done"), (p_89847_) -> {
|
||||
this.save();
|
||||
}).bounds(i - 2, row(12), 106, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, (p_280749_) -> {
|
||||
this.minecraft.setScreen(this.configureWorldScreen);
|
||||
}).bounds(this.width / 2 + 2, row(12), 106, 20).build());
|
||||
String s = this.serverData.state == RealmsServer.State.OPEN ? "mco.configure.world.buttons.close" : "mco.configure.world.buttons.open";
|
||||
Button button = Button.builder(Component.translatable(s), (p_287303_) -> {
|
||||
if (this.serverData.state == RealmsServer.State.OPEN) {
|
||||
Component component = Component.translatable("mco.configure.world.close.question.line1");
|
||||
Component component1 = Component.translatable("mco.configure.world.close.question.line2");
|
||||
this.minecraft.setScreen(new RealmsLongConfirmationScreen((p_280750_) -> {
|
||||
if (p_280750_) {
|
||||
this.configureWorldScreen.closeTheWorld(this);
|
||||
} else {
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
}, RealmsLongConfirmationScreen.Type.INFO, component, component1, true));
|
||||
} else {
|
||||
this.configureWorldScreen.openTheWorld(false, this);
|
||||
}
|
||||
|
||||
}).bounds(this.width / 2 - 53, row(0), 106, 20).build();
|
||||
this.addRenderableWidget(button);
|
||||
this.nameEdit = new EditBox(this.minecraft.font, i, row(4), 212, 20, (EditBox)null, Component.translatable("mco.configure.world.name"));
|
||||
this.nameEdit.setMaxLength(32);
|
||||
this.nameEdit.setValue(this.serverData.getName());
|
||||
this.addWidget(this.nameEdit);
|
||||
this.magicalSpecialHackyFocus(this.nameEdit);
|
||||
this.descEdit = new EditBox(this.minecraft.font, i, row(8), 212, 20, (EditBox)null, Component.translatable("mco.configure.world.description"));
|
||||
this.descEdit.setMaxLength(32);
|
||||
this.descEdit.setValue(this.serverData.getDescription());
|
||||
this.addWidget(this.descEdit);
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_89833_, int p_89834_, int p_89835_) {
|
||||
if (p_89833_ == 256) {
|
||||
this.minecraft.setScreen(this.configureWorldScreen);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_89833_, p_89834_, p_89835_);
|
||||
}
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_283580_, int p_281307_, int p_282074_, float p_282669_) {
|
||||
this.renderBackground(p_283580_);
|
||||
p_283580_.drawCenteredString(this.font, this.title, this.width / 2, 17, 16777215);
|
||||
p_283580_.drawString(this.font, NAME_LABEL, this.width / 2 - 106, row(3), 10526880, false);
|
||||
p_283580_.drawString(this.font, DESCRIPTION_LABEL, this.width / 2 - 106, row(7), 10526880, false);
|
||||
this.nameEdit.render(p_283580_, p_281307_, p_282074_, p_282669_);
|
||||
this.descEdit.render(p_283580_, p_281307_, p_282074_, p_282669_);
|
||||
super.render(p_283580_, p_281307_, p_282074_, p_282669_);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
this.configureWorldScreen.saveSettings(this.nameEdit.getValue(), this.descEdit.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.RealmsWorldOptions;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.AbstractSliderButton;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.CycleButton;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.screens.ConfirmScreen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsLabel;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.Difficulty;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsSlotOptionsScreen extends RealmsScreen {
|
||||
private static final int DEFAULT_DIFFICULTY = 2;
|
||||
public static final List<Difficulty> DIFFICULTIES = ImmutableList.of(Difficulty.PEACEFUL, Difficulty.EASY, Difficulty.NORMAL, Difficulty.HARD);
|
||||
private static final int DEFAULT_GAME_MODE = 0;
|
||||
public static final List<GameType> GAME_MODES = ImmutableList.of(GameType.SURVIVAL, GameType.CREATIVE, GameType.ADVENTURE);
|
||||
private static final Component NAME_LABEL = Component.translatable("mco.configure.world.edit.slot.name");
|
||||
static final Component SPAWN_PROTECTION_TEXT = Component.translatable("mco.configure.world.spawnProtection");
|
||||
private static final Component SPAWN_WARNING_TITLE = Component.translatable("mco.configure.world.spawn_toggle.title").withStyle(ChatFormatting.RED, ChatFormatting.BOLD);
|
||||
private EditBox nameEdit;
|
||||
protected final RealmsConfigureWorldScreen parent;
|
||||
private int column1X;
|
||||
private int columnWidth;
|
||||
private final RealmsWorldOptions options;
|
||||
private final RealmsServer.WorldType worldType;
|
||||
private Difficulty difficulty;
|
||||
private GameType gameMode;
|
||||
private final String defaultSlotName;
|
||||
private String worldName;
|
||||
private boolean pvp;
|
||||
private boolean spawnNPCs;
|
||||
private boolean spawnAnimals;
|
||||
private boolean spawnMonsters;
|
||||
int spawnProtection;
|
||||
private boolean commandBlocks;
|
||||
private boolean forceGameMode;
|
||||
RealmsSlotOptionsScreen.SettingsSlider spawnProtectionButton;
|
||||
|
||||
public RealmsSlotOptionsScreen(RealmsConfigureWorldScreen p_89886_, RealmsWorldOptions p_89887_, RealmsServer.WorldType p_89888_, int p_89889_) {
|
||||
super(Component.translatable("mco.configure.world.buttons.options"));
|
||||
this.parent = p_89886_;
|
||||
this.options = p_89887_;
|
||||
this.worldType = p_89888_;
|
||||
this.difficulty = findByIndex(DIFFICULTIES, p_89887_.difficulty, 2);
|
||||
this.gameMode = findByIndex(GAME_MODES, p_89887_.gameMode, 0);
|
||||
this.defaultSlotName = p_89887_.getDefaultSlotName(p_89889_);
|
||||
this.setWorldName(p_89887_.getSlotName(p_89889_));
|
||||
if (p_89888_ == RealmsServer.WorldType.NORMAL) {
|
||||
this.pvp = p_89887_.pvp;
|
||||
this.spawnProtection = p_89887_.spawnProtection;
|
||||
this.forceGameMode = p_89887_.forceGameMode;
|
||||
this.spawnAnimals = p_89887_.spawnAnimals;
|
||||
this.spawnMonsters = p_89887_.spawnMonsters;
|
||||
this.spawnNPCs = p_89887_.spawnNPCs;
|
||||
this.commandBlocks = p_89887_.commandBlocks;
|
||||
} else {
|
||||
this.pvp = true;
|
||||
this.spawnProtection = 0;
|
||||
this.forceGameMode = false;
|
||||
this.spawnAnimals = true;
|
||||
this.spawnMonsters = true;
|
||||
this.spawnNPCs = true;
|
||||
this.commandBlocks = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
this.nameEdit.tick();
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_89891_, int p_89892_, int p_89893_) {
|
||||
if (p_89891_ == 256) {
|
||||
this.minecraft.setScreen(this.parent);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_89891_, p_89892_, p_89893_);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T findByIndex(List<T> p_167525_, int p_167526_, int p_167527_) {
|
||||
try {
|
||||
return p_167525_.get(p_167526_);
|
||||
} catch (IndexOutOfBoundsException indexoutofboundsexception) {
|
||||
return p_167525_.get(p_167527_);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> int findIndex(List<T> p_167529_, T p_167530_, int p_167531_) {
|
||||
int i = p_167529_.indexOf(p_167530_);
|
||||
return i == -1 ? p_167531_ : i;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.columnWidth = 170;
|
||||
this.column1X = this.width / 2 - this.columnWidth;
|
||||
int i = this.width / 2 + 10;
|
||||
if (this.worldType != RealmsServer.WorldType.NORMAL) {
|
||||
Component component;
|
||||
if (this.worldType == RealmsServer.WorldType.ADVENTUREMAP) {
|
||||
component = Component.translatable("mco.configure.world.edit.subscreen.adventuremap");
|
||||
} else if (this.worldType == RealmsServer.WorldType.INSPIRATION) {
|
||||
component = Component.translatable("mco.configure.world.edit.subscreen.inspiration");
|
||||
} else {
|
||||
component = Component.translatable("mco.configure.world.edit.subscreen.experience");
|
||||
}
|
||||
|
||||
this.addLabel(new RealmsLabel(component, this.width / 2, 26, 16711680));
|
||||
}
|
||||
|
||||
this.nameEdit = new EditBox(this.minecraft.font, this.column1X + 2, row(1), this.columnWidth - 4, 20, (EditBox)null, Component.translatable("mco.configure.world.edit.slot.name"));
|
||||
this.nameEdit.setMaxLength(10);
|
||||
this.nameEdit.setValue(this.worldName);
|
||||
this.nameEdit.setResponder(this::setWorldName);
|
||||
this.magicalSpecialHackyFocus(this.nameEdit);
|
||||
CycleButton<Boolean> cyclebutton5 = this.addRenderableWidget(CycleButton.onOffBuilder(this.pvp).create(i, row(1), this.columnWidth, 20, Component.translatable("mco.configure.world.pvp"), (p_167546_, p_167547_) -> {
|
||||
this.pvp = p_167547_;
|
||||
}));
|
||||
this.addRenderableWidget(CycleButton.builder(GameType::getShortDisplayName).withValues(GAME_MODES).withInitialValue(this.gameMode).create(this.column1X, row(3), this.columnWidth, 20, Component.translatable("selectWorld.gameMode"), (p_167515_, p_167516_) -> {
|
||||
this.gameMode = p_167516_;
|
||||
}));
|
||||
Component component1 = Component.translatable("mco.configure.world.spawn_toggle.message");
|
||||
CycleButton<Boolean> cyclebutton = this.addRenderableWidget(CycleButton.onOffBuilder(this.spawnAnimals).create(i, row(3), this.columnWidth, 20, Component.translatable("mco.configure.world.spawnAnimals"), this.confirmDangerousOption(component1, (p_231329_) -> {
|
||||
this.spawnAnimals = p_231329_;
|
||||
})));
|
||||
CycleButton<Boolean> cyclebutton1 = CycleButton.onOffBuilder(this.difficulty != Difficulty.PEACEFUL && this.spawnMonsters).create(i, row(5), this.columnWidth, 20, Component.translatable("mco.configure.world.spawnMonsters"), this.confirmDangerousOption(component1, (p_231327_) -> {
|
||||
this.spawnMonsters = p_231327_;
|
||||
}));
|
||||
this.addRenderableWidget(CycleButton.builder(Difficulty::getDisplayName).withValues(DIFFICULTIES).withInitialValue(this.difficulty).create(this.column1X, row(5), this.columnWidth, 20, Component.translatable("options.difficulty"), (p_167519_, p_167520_) -> {
|
||||
this.difficulty = p_167520_;
|
||||
if (this.worldType == RealmsServer.WorldType.NORMAL) {
|
||||
boolean flag = this.difficulty != Difficulty.PEACEFUL;
|
||||
cyclebutton1.active = flag;
|
||||
cyclebutton1.setValue(flag && this.spawnMonsters);
|
||||
}
|
||||
|
||||
}));
|
||||
this.addRenderableWidget(cyclebutton1);
|
||||
this.spawnProtectionButton = this.addRenderableWidget(new RealmsSlotOptionsScreen.SettingsSlider(this.column1X, row(7), this.columnWidth, this.spawnProtection, 0.0F, 16.0F));
|
||||
CycleButton<Boolean> cyclebutton2 = this.addRenderableWidget(CycleButton.onOffBuilder(this.spawnNPCs).create(i, row(7), this.columnWidth, 20, Component.translatable("mco.configure.world.spawnNPCs"), this.confirmDangerousOption(Component.translatable("mco.configure.world.spawn_toggle.message.npc"), (p_231312_) -> {
|
||||
this.spawnNPCs = p_231312_;
|
||||
})));
|
||||
CycleButton<Boolean> cyclebutton3 = this.addRenderableWidget(CycleButton.onOffBuilder(this.forceGameMode).create(this.column1X, row(9), this.columnWidth, 20, Component.translatable("mco.configure.world.forceGameMode"), (p_167534_, p_167535_) -> {
|
||||
this.forceGameMode = p_167535_;
|
||||
}));
|
||||
CycleButton<Boolean> cyclebutton4 = this.addRenderableWidget(CycleButton.onOffBuilder(this.commandBlocks).create(i, row(9), this.columnWidth, 20, Component.translatable("mco.configure.world.commandBlocks"), (p_167522_, p_167523_) -> {
|
||||
this.commandBlocks = p_167523_;
|
||||
}));
|
||||
if (this.worldType != RealmsServer.WorldType.NORMAL) {
|
||||
cyclebutton5.active = false;
|
||||
cyclebutton.active = false;
|
||||
cyclebutton2.active = false;
|
||||
cyclebutton1.active = false;
|
||||
this.spawnProtectionButton.active = false;
|
||||
cyclebutton4.active = false;
|
||||
cyclebutton3.active = false;
|
||||
}
|
||||
|
||||
if (this.difficulty == Difficulty.PEACEFUL) {
|
||||
cyclebutton1.active = false;
|
||||
}
|
||||
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.buttons.done"), (p_89910_) -> {
|
||||
this.saveSettings();
|
||||
}).bounds(this.column1X, row(13), this.columnWidth, 20).build());
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, (p_280758_) -> {
|
||||
this.minecraft.setScreen(this.parent);
|
||||
}).bounds(i, row(13), this.columnWidth, 20).build());
|
||||
this.addWidget(this.nameEdit);
|
||||
}
|
||||
|
||||
private CycleButton.OnValueChange<Boolean> confirmDangerousOption(Component p_231324_, Consumer<Boolean> p_231325_) {
|
||||
return (p_280754_, p_280755_) -> {
|
||||
if (p_280755_) {
|
||||
p_231325_.accept(true);
|
||||
} else {
|
||||
this.minecraft.setScreen(new ConfirmScreen((p_280757_) -> {
|
||||
if (p_280757_) {
|
||||
p_231325_.accept(false);
|
||||
}
|
||||
|
||||
this.minecraft.setScreen(this);
|
||||
}, SPAWN_WARNING_TITLE, p_231324_, CommonComponents.GUI_PROCEED, CommonComponents.GUI_CANCEL));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return CommonComponents.joinForNarration(this.getTitle(), this.createLabelNarration());
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_283210_, int p_283172_, int p_281531_, float p_283191_) {
|
||||
this.renderBackground(p_283210_);
|
||||
p_283210_.drawCenteredString(this.font, this.title, this.width / 2, 17, 16777215);
|
||||
p_283210_.drawString(this.font, NAME_LABEL, this.column1X + this.columnWidth / 2 - this.font.width(NAME_LABEL) / 2, row(0) - 5, 16777215, false);
|
||||
this.nameEdit.render(p_283210_, p_283172_, p_281531_, p_283191_);
|
||||
super.render(p_283210_, p_283172_, p_281531_, p_283191_);
|
||||
}
|
||||
|
||||
private void setWorldName(String p_231314_) {
|
||||
if (p_231314_.equals(this.defaultSlotName)) {
|
||||
this.worldName = "";
|
||||
} else {
|
||||
this.worldName = p_231314_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void saveSettings() {
|
||||
int i = findIndex(DIFFICULTIES, this.difficulty, 2);
|
||||
int j = findIndex(GAME_MODES, this.gameMode, 0);
|
||||
if (this.worldType != RealmsServer.WorldType.ADVENTUREMAP && this.worldType != RealmsServer.WorldType.EXPERIENCE && this.worldType != RealmsServer.WorldType.INSPIRATION) {
|
||||
boolean flag = this.worldType == RealmsServer.WorldType.NORMAL && this.difficulty != Difficulty.PEACEFUL && this.spawnMonsters;
|
||||
this.parent.saveSlotSettings(new RealmsWorldOptions(this.pvp, this.spawnAnimals, flag, this.spawnNPCs, this.spawnProtection, this.commandBlocks, i, j, this.forceGameMode, this.worldName));
|
||||
} else {
|
||||
this.parent.saveSlotSettings(new RealmsWorldOptions(this.options.pvp, this.options.spawnAnimals, this.options.spawnMonsters, this.options.spawnNPCs, this.options.spawnProtection, this.options.commandBlocks, i, j, this.options.forceGameMode, this.worldName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class SettingsSlider extends AbstractSliderButton {
|
||||
private final double minValue;
|
||||
private final double maxValue;
|
||||
|
||||
public SettingsSlider(int p_89946_, int p_89947_, int p_89948_, int p_89949_, float p_89950_, float p_89951_) {
|
||||
super(p_89946_, p_89947_, p_89948_, 20, CommonComponents.EMPTY, 0.0D);
|
||||
this.minValue = (double)p_89950_;
|
||||
this.maxValue = (double)p_89951_;
|
||||
this.value = (double)((Mth.clamp((float)p_89949_, p_89950_, p_89951_) - p_89950_) / (p_89951_ - p_89950_));
|
||||
this.updateMessage();
|
||||
}
|
||||
|
||||
public void applyValue() {
|
||||
if (RealmsSlotOptionsScreen.this.spawnProtectionButton.active) {
|
||||
RealmsSlotOptionsScreen.this.spawnProtection = (int)Mth.lerp(Mth.clamp(this.value, 0.0D, 1.0D), this.minValue, this.maxValue);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateMessage() {
|
||||
this.setMessage(CommonComponents.optionNameValue(RealmsSlotOptionsScreen.SPAWN_PROTECTION_TEXT, (Component)(RealmsSlotOptionsScreen.this.spawnProtection == 0 ? CommonComponents.OPTION_OFF : Component.literal(String.valueOf(RealmsSlotOptionsScreen.this.spawnProtection)))));
|
||||
}
|
||||
|
||||
public void onClick(double p_89954_, double p_89955_) {
|
||||
}
|
||||
|
||||
public void onRelease(double p_89957_, double p_89958_) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.Subscription;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.FittingMultiLineTextWidget;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.util.CommonLinks;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsSubscriptionInfoScreen extends RealmsScreen {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Component SUBSCRIPTION_TITLE = Component.translatable("mco.configure.world.subscription.title");
|
||||
private static final Component SUBSCRIPTION_START_LABEL = Component.translatable("mco.configure.world.subscription.start");
|
||||
private static final Component TIME_LEFT_LABEL = Component.translatable("mco.configure.world.subscription.timeleft");
|
||||
private static final Component DAYS_LEFT_LABEL = Component.translatable("mco.configure.world.subscription.recurring.daysleft");
|
||||
private static final Component SUBSCRIPTION_EXPIRED_TEXT = Component.translatable("mco.configure.world.subscription.expired");
|
||||
private static final Component SUBSCRIPTION_LESS_THAN_A_DAY_TEXT = Component.translatable("mco.configure.world.subscription.less_than_a_day");
|
||||
private static final Component UNKNOWN = Component.translatable("mco.configure.world.subscription.unknown");
|
||||
private static final Component RECURRING_INFO = Component.translatable("mco.configure.world.subscription.recurring.info");
|
||||
private final Screen lastScreen;
|
||||
final RealmsServer serverData;
|
||||
final Screen mainScreen;
|
||||
private Component daysLeft = UNKNOWN;
|
||||
private Component startDate = UNKNOWN;
|
||||
@Nullable
|
||||
private Subscription.SubscriptionType type;
|
||||
|
||||
public RealmsSubscriptionInfoScreen(Screen p_89979_, RealmsServer p_89980_, Screen p_89981_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.lastScreen = p_89979_;
|
||||
this.serverData = p_89980_;
|
||||
this.mainScreen = p_89981_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.getSubscription(this.serverData.id);
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.subscription.extend"), (p_280761_) -> {
|
||||
String s = CommonLinks.extendRealms(this.serverData.remoteSubscriptionId, this.minecraft.getUser().getUuid());
|
||||
this.minecraft.keyboardHandler.setClipboard(s);
|
||||
Util.getPlatform().openUri(s);
|
||||
}).bounds(this.width / 2 - 100, row(6), 200, 20).build());
|
||||
if (this.serverData.expired) {
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("mco.configure.world.delete.button"), (p_287304_) -> {
|
||||
Component component = Component.translatable("mco.configure.world.delete.question.line1");
|
||||
Component component1 = Component.translatable("mco.configure.world.delete.question.line2");
|
||||
this.minecraft.setScreen(new RealmsLongConfirmationScreen(this::deleteRealm, RealmsLongConfirmationScreen.Type.WARNING, component, component1, true));
|
||||
}).bounds(this.width / 2 - 100, row(10), 200, 20).build());
|
||||
} else {
|
||||
this.addRenderableWidget((new FittingMultiLineTextWidget(this.width / 2 - 100, row(8), 200, 46, RECURRING_INFO, this.font)).setColor(10526880));
|
||||
}
|
||||
|
||||
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_280760_) -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}).bounds(this.width / 2 - 100, row(12), 200, 20).build());
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return CommonComponents.joinLines(SUBSCRIPTION_TITLE, SUBSCRIPTION_START_LABEL, this.startDate, TIME_LEFT_LABEL, this.daysLeft);
|
||||
}
|
||||
|
||||
private void deleteRealm(boolean p_90012_) {
|
||||
if (p_90012_) {
|
||||
(new Thread("Realms-delete-realm") {
|
||||
public void run() {
|
||||
try {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
realmsclient.deleteWorld(RealmsSubscriptionInfoScreen.this.serverData.id);
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
RealmsSubscriptionInfoScreen.LOGGER.error("Couldn't delete world", (Throwable)realmsserviceexception);
|
||||
}
|
||||
|
||||
RealmsSubscriptionInfoScreen.this.minecraft.execute(() -> {
|
||||
RealmsSubscriptionInfoScreen.this.minecraft.setScreen(RealmsSubscriptionInfoScreen.this.mainScreen);
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
this.minecraft.setScreen(this);
|
||||
}
|
||||
|
||||
private void getSubscription(long p_89990_) {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
Subscription subscription = realmsclient.subscriptionFor(p_89990_);
|
||||
this.daysLeft = this.daysLeftPresentation(subscription.daysLeft);
|
||||
this.startDate = localPresentation(subscription.startDate);
|
||||
this.type = subscription.type;
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't get subscription");
|
||||
this.minecraft.setScreen(new RealmsGenericErrorScreen(realmsserviceexception, this.lastScreen));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Component localPresentation(long p_182539_) {
|
||||
Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
|
||||
calendar.setTimeInMillis(p_182539_);
|
||||
return Component.literal(DateFormat.getDateTimeInstance().format(calendar.getTime()));
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_89986_, int p_89987_, int p_89988_) {
|
||||
if (p_89986_ == 256) {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_89986_, p_89987_, p_89988_);
|
||||
}
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282831_, int p_281266_, int p_281799_, float p_282330_) {
|
||||
this.renderBackground(p_282831_);
|
||||
int i = this.width / 2 - 100;
|
||||
p_282831_.drawCenteredString(this.font, SUBSCRIPTION_TITLE, this.width / 2, 17, 16777215);
|
||||
p_282831_.drawString(this.font, SUBSCRIPTION_START_LABEL, i, row(0), 10526880, false);
|
||||
p_282831_.drawString(this.font, this.startDate, i, row(1), 16777215, false);
|
||||
if (this.type == Subscription.SubscriptionType.NORMAL) {
|
||||
p_282831_.drawString(this.font, TIME_LEFT_LABEL, i, row(3), 10526880, false);
|
||||
} else if (this.type == Subscription.SubscriptionType.RECURRING) {
|
||||
p_282831_.drawString(this.font, DAYS_LEFT_LABEL, i, row(3), 10526880, false);
|
||||
}
|
||||
|
||||
p_282831_.drawString(this.font, this.daysLeft, i, row(4), 16777215, false);
|
||||
super.render(p_282831_, p_281266_, p_281799_, p_282330_);
|
||||
}
|
||||
|
||||
private Component daysLeftPresentation(int p_89984_) {
|
||||
if (p_89984_ < 0 && this.serverData.expired) {
|
||||
return SUBSCRIPTION_EXPIRED_TEXT;
|
||||
} else if (p_89984_ <= 1) {
|
||||
return SUBSCRIPTION_LESS_THAN_A_DAY_TEXT;
|
||||
} else {
|
||||
int i = p_89984_ / 30;
|
||||
int j = p_89984_ % 30;
|
||||
boolean flag = i > 0;
|
||||
boolean flag1 = j > 0;
|
||||
if (flag && flag1) {
|
||||
return Component.translatable("mco.configure.world.subscription.remaining.months.days", i, j);
|
||||
} else if (flag) {
|
||||
return Component.translatable("mco.configure.world.subscription.remaining.months", i);
|
||||
} else {
|
||||
return flag1 ? Component.translatable("mco.configure.world.subscription.remaining.days", j) : Component.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.RealmsMainScreen;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.util.task.GetServerDetailsTask;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsTermsScreen extends RealmsScreen {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Component TITLE = Component.translatable("mco.terms.title");
|
||||
private static final Component TERMS_STATIC_TEXT = Component.translatable("mco.terms.sentence.1");
|
||||
private static final Component TERMS_LINK_TEXT = CommonComponents.space().append(Component.translatable("mco.terms.sentence.2").withStyle(Style.EMPTY.withUnderlined(true)));
|
||||
private final Screen lastScreen;
|
||||
private final RealmsMainScreen mainScreen;
|
||||
private final RealmsServer realmsServer;
|
||||
private boolean onLink;
|
||||
|
||||
public RealmsTermsScreen(Screen p_90033_, RealmsMainScreen p_90034_, RealmsServer p_90035_) {
|
||||
super(TITLE);
|
||||
this.lastScreen = p_90033_;
|
||||
this.mainScreen = p_90034_;
|
||||
this.realmsServer = p_90035_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
int i = this.width / 4 - 2;
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("mco.terms.buttons.agree"), (p_90054_) -> {
|
||||
this.agreedToTos();
|
||||
}).bounds(this.width / 4, row(12), i, 20).build());
|
||||
this.addRenderableWidget(Button.builder(Component.translatable("mco.terms.buttons.disagree"), (p_280762_) -> {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}).bounds(this.width / 2 + 4, row(12), i, 20).build());
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_90041_, int p_90042_, int p_90043_) {
|
||||
if (p_90041_ == 256) {
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_90041_, p_90042_, p_90043_);
|
||||
}
|
||||
}
|
||||
|
||||
private void agreedToTos() {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
try {
|
||||
realmsclient.agreeToTos();
|
||||
this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this.lastScreen, new GetServerDetailsTask(this.mainScreen, this.lastScreen, this.realmsServer, new ReentrantLock())));
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
LOGGER.error("Couldn't agree to TOS");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double p_90037_, double p_90038_, int p_90039_) {
|
||||
if (this.onLink) {
|
||||
this.minecraft.keyboardHandler.setClipboard("https://aka.ms/MinecraftRealmsTerms");
|
||||
Util.getPlatform().openUri("https://aka.ms/MinecraftRealmsTerms");
|
||||
return true;
|
||||
} else {
|
||||
return super.mouseClicked(p_90037_, p_90038_, p_90039_);
|
||||
}
|
||||
}
|
||||
|
||||
public Component getNarrationMessage() {
|
||||
return CommonComponents.joinForNarration(super.getNarrationMessage(), TERMS_STATIC_TEXT).append(CommonComponents.SPACE).append(TERMS_LINK_TEXT);
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_281619_, int p_283526_, int p_282002_, float p_282536_) {
|
||||
this.renderBackground(p_281619_);
|
||||
p_281619_.drawCenteredString(this.font, this.title, this.width / 2, 17, 16777215);
|
||||
p_281619_.drawString(this.font, TERMS_STATIC_TEXT, this.width / 2 - 120, row(5), 16777215, false);
|
||||
int i = this.font.width(TERMS_STATIC_TEXT);
|
||||
int j = this.width / 2 - 121 + i;
|
||||
int k = row(5);
|
||||
int l = j + this.font.width(TERMS_LINK_TEXT) + 1;
|
||||
int i1 = k + 1 + 9;
|
||||
this.onLink = j <= p_283526_ && p_283526_ <= l && k <= p_282002_ && p_282002_ <= i1;
|
||||
p_281619_.drawString(this.font, TERMS_LINK_TEXT, this.width / 2 - 120 + i, row(5), this.onLink ? 7107012 : 3368635, false);
|
||||
super.render(p_281619_, p_283526_, p_282002_, p_282536_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.util.concurrent.RateLimiter;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.Unit;
|
||||
import com.mojang.realmsclient.client.FileUpload;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.client.UploadStatus;
|
||||
import com.mojang.realmsclient.dto.UploadInfo;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.exception.RetryCallException;
|
||||
import com.mojang.realmsclient.util.UploadTokenCache;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsScreen;
|
||||
import net.minecraft.world.level.storage.LevelSummary;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsUploadScreen extends RealmsScreen {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final ReentrantLock UPLOAD_LOCK = new ReentrantLock();
|
||||
private static final int BAR_WIDTH = 200;
|
||||
private static final int BAR_TOP = 80;
|
||||
private static final int BAR_BOTTOM = 95;
|
||||
private static final int BAR_BORDER = 1;
|
||||
private static final String[] DOTS = new String[]{"", ".", ". .", ". . ."};
|
||||
private static final Component VERIFYING_TEXT = Component.translatable("mco.upload.verifying");
|
||||
private final RealmsResetWorldScreen lastScreen;
|
||||
private final LevelSummary selectedLevel;
|
||||
private final long worldId;
|
||||
private final int slotId;
|
||||
private final UploadStatus uploadStatus;
|
||||
private final RateLimiter narrationRateLimiter;
|
||||
@Nullable
|
||||
private volatile Component[] errorMessage;
|
||||
private volatile Component status = Component.translatable("mco.upload.preparing");
|
||||
private volatile String progress;
|
||||
private volatile boolean cancelled;
|
||||
private volatile boolean uploadFinished;
|
||||
private volatile boolean showDots = true;
|
||||
private volatile boolean uploadStarted;
|
||||
private Button backButton;
|
||||
private Button cancelButton;
|
||||
private int tickCount;
|
||||
@Nullable
|
||||
private Long previousWrittenBytes;
|
||||
@Nullable
|
||||
private Long previousTimeSnapshot;
|
||||
private long bytesPersSecond;
|
||||
private final Runnable callback;
|
||||
|
||||
public RealmsUploadScreen(long p_90083_, int p_90084_, RealmsResetWorldScreen p_90085_, LevelSummary p_90086_, Runnable p_90087_) {
|
||||
super(GameNarrator.NO_TITLE);
|
||||
this.worldId = p_90083_;
|
||||
this.slotId = p_90084_;
|
||||
this.lastScreen = p_90085_;
|
||||
this.selectedLevel = p_90086_;
|
||||
this.uploadStatus = new UploadStatus();
|
||||
this.narrationRateLimiter = RateLimiter.create((double)0.1F);
|
||||
this.callback = p_90087_;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.backButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, (p_90118_) -> {
|
||||
this.onBack();
|
||||
}).bounds((this.width - 200) / 2, this.height - 42, 200, 20).build());
|
||||
this.backButton.visible = false;
|
||||
this.cancelButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, (p_90104_) -> {
|
||||
this.onCancel();
|
||||
}).bounds((this.width - 200) / 2, this.height - 42, 200, 20).build());
|
||||
if (!this.uploadStarted) {
|
||||
if (this.lastScreen.slot == -1) {
|
||||
this.upload();
|
||||
} else {
|
||||
this.lastScreen.switchSlot(() -> {
|
||||
if (!this.uploadStarted) {
|
||||
this.uploadStarted = true;
|
||||
this.minecraft.setScreen(this);
|
||||
this.upload();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onBack() {
|
||||
this.callback.run();
|
||||
}
|
||||
|
||||
private void onCancel() {
|
||||
this.cancelled = true;
|
||||
this.minecraft.setScreen(this.lastScreen);
|
||||
}
|
||||
|
||||
public boolean keyPressed(int p_90089_, int p_90090_, int p_90091_) {
|
||||
if (p_90089_ == 256) {
|
||||
if (this.showDots) {
|
||||
this.onCancel();
|
||||
} else {
|
||||
this.onBack();
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(p_90089_, p_90090_, p_90091_);
|
||||
}
|
||||
}
|
||||
|
||||
public void render(GuiGraphics p_282140_, int p_90097_, int p_90098_, float p_90099_) {
|
||||
this.renderBackground(p_282140_);
|
||||
if (!this.uploadFinished && this.uploadStatus.bytesWritten != 0L && this.uploadStatus.bytesWritten == this.uploadStatus.totalBytes) {
|
||||
this.status = VERIFYING_TEXT;
|
||||
this.cancelButton.active = false;
|
||||
}
|
||||
|
||||
p_282140_.drawCenteredString(this.font, this.status, this.width / 2, 50, 16777215);
|
||||
if (this.showDots) {
|
||||
this.drawDots(p_282140_);
|
||||
}
|
||||
|
||||
if (this.uploadStatus.bytesWritten != 0L && !this.cancelled) {
|
||||
this.drawProgressBar(p_282140_);
|
||||
this.drawUploadSpeed(p_282140_);
|
||||
}
|
||||
|
||||
if (this.errorMessage != null) {
|
||||
for(int i = 0; i < this.errorMessage.length; ++i) {
|
||||
p_282140_.drawCenteredString(this.font, this.errorMessage[i], this.width / 2, 110 + 12 * i, 16711680);
|
||||
}
|
||||
}
|
||||
|
||||
super.render(p_282140_, p_90097_, p_90098_, p_90099_);
|
||||
}
|
||||
|
||||
private void drawDots(GuiGraphics p_283121_) {
|
||||
int i = this.font.width(this.status);
|
||||
p_283121_.drawString(this.font, DOTS[this.tickCount / 10 % DOTS.length], this.width / 2 + i / 2 + 5, 50, 16777215, false);
|
||||
}
|
||||
|
||||
private void drawProgressBar(GuiGraphics p_282575_) {
|
||||
double d0 = Math.min((double)this.uploadStatus.bytesWritten / (double)this.uploadStatus.totalBytes, 1.0D);
|
||||
this.progress = String.format(Locale.ROOT, "%.1f", d0 * 100.0D);
|
||||
int i = (this.width - 200) / 2;
|
||||
int j = i + (int)Math.round(200.0D * d0);
|
||||
p_282575_.fill(i - 1, 79, j + 1, 96, -2501934);
|
||||
p_282575_.fill(i, 80, j, 95, -8355712);
|
||||
p_282575_.drawCenteredString(this.font, this.progress + " %", this.width / 2, 84, 16777215);
|
||||
}
|
||||
|
||||
private void drawUploadSpeed(GuiGraphics p_281884_) {
|
||||
if (this.tickCount % 20 == 0) {
|
||||
if (this.previousWrittenBytes != null) {
|
||||
long i = Util.getMillis() - this.previousTimeSnapshot;
|
||||
if (i == 0L) {
|
||||
i = 1L;
|
||||
}
|
||||
|
||||
this.bytesPersSecond = 1000L * (this.uploadStatus.bytesWritten - this.previousWrittenBytes) / i;
|
||||
this.drawUploadSpeed0(p_281884_, this.bytesPersSecond);
|
||||
}
|
||||
|
||||
this.previousWrittenBytes = this.uploadStatus.bytesWritten;
|
||||
this.previousTimeSnapshot = Util.getMillis();
|
||||
} else {
|
||||
this.drawUploadSpeed0(p_281884_, this.bytesPersSecond);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawUploadSpeed0(GuiGraphics p_282279_, long p_282827_) {
|
||||
if (p_282827_ > 0L) {
|
||||
int i = this.font.width(this.progress);
|
||||
String s = "(" + Unit.humanReadable(p_282827_) + "/s)";
|
||||
p_282279_.drawString(this.font, s, this.width / 2 + i / 2 + 15, 84, 16777215, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
++this.tickCount;
|
||||
if (this.status != null && this.narrationRateLimiter.tryAcquire(1)) {
|
||||
Component component = this.createProgressNarrationMessage();
|
||||
this.minecraft.getNarrator().sayNow(component);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Component createProgressNarrationMessage() {
|
||||
List<Component> list = Lists.newArrayList();
|
||||
list.add(this.status);
|
||||
if (this.progress != null) {
|
||||
list.add(Component.literal(this.progress + "%"));
|
||||
}
|
||||
|
||||
if (this.errorMessage != null) {
|
||||
list.addAll(Arrays.asList(this.errorMessage));
|
||||
}
|
||||
|
||||
return CommonComponents.joinLines(list);
|
||||
}
|
||||
|
||||
private void upload() {
|
||||
this.uploadStarted = true;
|
||||
(new Thread(() -> {
|
||||
File file1 = null;
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
long i = this.worldId;
|
||||
|
||||
try {
|
||||
if (UPLOAD_LOCK.tryLock(1L, TimeUnit.SECONDS)) {
|
||||
UploadInfo uploadinfo = null;
|
||||
|
||||
for(int j = 0; j < 20; ++j) {
|
||||
try {
|
||||
if (this.cancelled) {
|
||||
this.uploadCancelled();
|
||||
return;
|
||||
}
|
||||
|
||||
uploadinfo = realmsclient.requestUploadInfo(i, UploadTokenCache.get(i));
|
||||
if (uploadinfo != null) {
|
||||
break;
|
||||
}
|
||||
} catch (RetryCallException retrycallexception) {
|
||||
Thread.sleep((long)(retrycallexception.delaySeconds * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
if (uploadinfo == null) {
|
||||
this.status = Component.translatable("mco.upload.close.failure");
|
||||
return;
|
||||
}
|
||||
|
||||
UploadTokenCache.put(i, uploadinfo.getToken());
|
||||
if (!uploadinfo.isWorldClosed()) {
|
||||
this.status = Component.translatable("mco.upload.close.failure");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.cancelled) {
|
||||
this.uploadCancelled();
|
||||
return;
|
||||
}
|
||||
|
||||
File file2 = new File(this.minecraft.gameDirectory.getAbsolutePath(), "saves");
|
||||
file1 = this.tarGzipArchive(new File(file2, this.selectedLevel.getLevelId()));
|
||||
if (this.cancelled) {
|
||||
this.uploadCancelled();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.verify(file1)) {
|
||||
this.status = Component.translatable("mco.upload.uploading", this.selectedLevel.getLevelName());
|
||||
FileUpload fileupload = new FileUpload(file1, this.worldId, this.slotId, uploadinfo, this.minecraft.getUser(), SharedConstants.getCurrentVersion().getName(), this.uploadStatus);
|
||||
fileupload.upload((p_167557_) -> {
|
||||
if (p_167557_.statusCode >= 200 && p_167557_.statusCode < 300) {
|
||||
this.uploadFinished = true;
|
||||
this.status = Component.translatable("mco.upload.done");
|
||||
this.backButton.setMessage(CommonComponents.GUI_DONE);
|
||||
UploadTokenCache.invalidate(i);
|
||||
} else if (p_167557_.statusCode == 400 && p_167557_.errorMessage != null) {
|
||||
this.setErrorMessage(Component.translatable("mco.upload.failed", p_167557_.errorMessage));
|
||||
} else {
|
||||
this.setErrorMessage(Component.translatable("mco.upload.failed", p_167557_.statusCode));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
while(!fileupload.isFinished()) {
|
||||
if (this.cancelled) {
|
||||
fileupload.cancel();
|
||||
this.uploadCancelled();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(500L);
|
||||
} catch (InterruptedException interruptedexception) {
|
||||
LOGGER.error("Failed to check Realms file upload status");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
long k = file1.length();
|
||||
Unit unit = Unit.getLargest(k);
|
||||
Unit unit1 = Unit.getLargest(5368709120L);
|
||||
if (Unit.humanReadable(k, unit).equals(Unit.humanReadable(5368709120L, unit1)) && unit != Unit.B) {
|
||||
Unit unit2 = Unit.values()[unit.ordinal() - 1];
|
||||
this.setErrorMessage(Component.translatable("mco.upload.size.failure.line1", this.selectedLevel.getLevelName()), Component.translatable("mco.upload.size.failure.line2", Unit.humanReadable(k, unit2), Unit.humanReadable(5368709120L, unit2)));
|
||||
return;
|
||||
}
|
||||
|
||||
this.setErrorMessage(Component.translatable("mco.upload.size.failure.line1", this.selectedLevel.getLevelName()), Component.translatable("mco.upload.size.failure.line2", Unit.humanReadable(k, unit), Unit.humanReadable(5368709120L, unit1)));
|
||||
return;
|
||||
}
|
||||
|
||||
this.status = Component.translatable("mco.upload.close.failure");
|
||||
} catch (IOException ioexception) {
|
||||
this.setErrorMessage(Component.translatable("mco.upload.failed", ioexception.getMessage()));
|
||||
return;
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
this.setErrorMessage(Component.translatable("mco.upload.failed", realmsserviceexception.toString()));
|
||||
return;
|
||||
} catch (InterruptedException interruptedexception1) {
|
||||
LOGGER.error("Could not acquire upload lock");
|
||||
return;
|
||||
} finally {
|
||||
this.uploadFinished = true;
|
||||
if (UPLOAD_LOCK.isHeldByCurrentThread()) {
|
||||
UPLOAD_LOCK.unlock();
|
||||
this.showDots = false;
|
||||
this.backButton.visible = true;
|
||||
this.cancelButton.visible = false;
|
||||
if (file1 != null) {
|
||||
LOGGER.debug("Deleting file {}", (Object)file1.getAbsolutePath());
|
||||
file1.delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
})).start();
|
||||
}
|
||||
|
||||
private void setErrorMessage(Component... p_90113_) {
|
||||
this.errorMessage = p_90113_;
|
||||
}
|
||||
|
||||
private void uploadCancelled() {
|
||||
this.status = Component.translatable("mco.upload.cancelled");
|
||||
LOGGER.debug("Upload was cancelled");
|
||||
}
|
||||
|
||||
private boolean verify(File p_90106_) {
|
||||
return p_90106_.length() < 5368709120L;
|
||||
}
|
||||
|
||||
private File tarGzipArchive(File p_90120_) throws IOException {
|
||||
TarArchiveOutputStream tararchiveoutputstream = null;
|
||||
|
||||
File file2;
|
||||
try {
|
||||
File file1 = File.createTempFile("realms-upload-file", ".tar.gz");
|
||||
tararchiveoutputstream = new TarArchiveOutputStream(new GZIPOutputStream(new FileOutputStream(file1)));
|
||||
tararchiveoutputstream.setLongFileMode(3);
|
||||
this.addFileToTarGz(tararchiveoutputstream, p_90120_.getAbsolutePath(), "world", true);
|
||||
tararchiveoutputstream.finish();
|
||||
file2 = file1;
|
||||
} finally {
|
||||
if (tararchiveoutputstream != null) {
|
||||
tararchiveoutputstream.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return file2;
|
||||
}
|
||||
|
||||
private void addFileToTarGz(TarArchiveOutputStream p_90108_, String p_90109_, String p_90110_, boolean p_90111_) throws IOException {
|
||||
if (!this.cancelled) {
|
||||
File file1 = new File(p_90109_);
|
||||
String s = p_90111_ ? p_90110_ : p_90110_ + file1.getName();
|
||||
TarArchiveEntry tararchiveentry = new TarArchiveEntry(file1, s);
|
||||
p_90108_.putArchiveEntry(tararchiveentry);
|
||||
if (file1.isFile()) {
|
||||
IOUtils.copy(new FileInputStream(file1), p_90108_);
|
||||
p_90108_.closeArchiveEntry();
|
||||
} else {
|
||||
p_90108_.closeArchiveEntry();
|
||||
File[] afile = file1.listFiles();
|
||||
if (afile != null) {
|
||||
for(File file2 : afile) {
|
||||
this.addFileToTarGz(p_90108_, file2.getAbsolutePath(), s + "/", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class UploadResult {
|
||||
public final int statusCode;
|
||||
@Nullable
|
||||
public final String errorMessage;
|
||||
|
||||
UploadResult(int p_90136_, String p_90137_) {
|
||||
this.statusCode = p_90136_;
|
||||
this.errorMessage = p_90137_;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Builder {
|
||||
private int statusCode = -1;
|
||||
private String errorMessage;
|
||||
|
||||
public UploadResult.Builder withStatusCode(int p_90147_) {
|
||||
this.statusCode = p_90147_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UploadResult.Builder withErrorMessage(@Nullable String p_90149_) {
|
||||
this.errorMessage = p_90149_;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UploadResult build() {
|
||||
return new UploadResult(this.statusCode, this.errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.realmsclient.gui.screens;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,184 @@
|
||||
package com.mojang.realmsclient.gui.task;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.TimeSource;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class DataFetcher {
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
final Executor executor;
|
||||
final TimeUnit resolution;
|
||||
final TimeSource timeSource;
|
||||
|
||||
public DataFetcher(Executor p_239381_, TimeUnit p_239382_, TimeSource p_239383_) {
|
||||
this.executor = p_239381_;
|
||||
this.resolution = p_239382_;
|
||||
this.timeSource = p_239383_;
|
||||
}
|
||||
|
||||
public <T> DataFetcher.Task<T> createTask(String p_239623_, Callable<T> p_239624_, Duration p_239625_, RepeatedDelayStrategy p_239626_) {
|
||||
long i = this.resolution.convert(p_239625_);
|
||||
if (i == 0L) {
|
||||
throw new IllegalArgumentException("Period of " + p_239625_ + " too short for selected resolution of " + this.resolution);
|
||||
} else {
|
||||
return new DataFetcher.Task<>(p_239623_, p_239624_, i, p_239626_);
|
||||
}
|
||||
}
|
||||
|
||||
public DataFetcher.Subscription createSubscription() {
|
||||
return new DataFetcher.Subscription();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static record ComputationResult<T>(Either<T, Exception> value, long time) {
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class SubscribedTask<T> {
|
||||
private final DataFetcher.Task<T> task;
|
||||
private final Consumer<T> output;
|
||||
private long lastCheckTime = -1L;
|
||||
|
||||
SubscribedTask(DataFetcher.Task<T> p_239959_, Consumer<T> p_239960_) {
|
||||
this.task = p_239959_;
|
||||
this.output = p_239960_;
|
||||
}
|
||||
|
||||
void update(long p_239226_) {
|
||||
this.task.updateIfNeeded(p_239226_);
|
||||
this.runCallbackIfNeeded();
|
||||
}
|
||||
|
||||
void runCallbackIfNeeded() {
|
||||
DataFetcher.SuccessfulComputationResult<T> successfulcomputationresult = this.task.lastResult;
|
||||
if (successfulcomputationresult != null && this.lastCheckTime < successfulcomputationresult.time) {
|
||||
this.output.accept(successfulcomputationresult.value);
|
||||
this.lastCheckTime = successfulcomputationresult.time;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void runCallback() {
|
||||
DataFetcher.SuccessfulComputationResult<T> successfulcomputationresult = this.task.lastResult;
|
||||
if (successfulcomputationresult != null) {
|
||||
this.output.accept(successfulcomputationresult.value);
|
||||
this.lastCheckTime = successfulcomputationresult.time;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void reset() {
|
||||
this.task.reset();
|
||||
this.lastCheckTime = -1L;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Subscription {
|
||||
private final List<DataFetcher.SubscribedTask<?>> subscriptions = new ArrayList<>();
|
||||
|
||||
public <T> void subscribe(DataFetcher.Task<T> p_239442_, Consumer<T> p_239443_) {
|
||||
DataFetcher.SubscribedTask<T> subscribedtask = DataFetcher.this.new SubscribedTask<>(p_239442_, p_239443_);
|
||||
this.subscriptions.add(subscribedtask);
|
||||
subscribedtask.runCallbackIfNeeded();
|
||||
}
|
||||
|
||||
public void forceUpdate() {
|
||||
for(DataFetcher.SubscribedTask<?> subscribedtask : this.subscriptions) {
|
||||
subscribedtask.runCallback();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
for(DataFetcher.SubscribedTask<?> subscribedtask : this.subscriptions) {
|
||||
subscribedtask.update(DataFetcher.this.timeSource.get(DataFetcher.this.resolution));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
for(DataFetcher.SubscribedTask<?> subscribedtask : this.subscriptions) {
|
||||
subscribedtask.reset();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static record SuccessfulComputationResult<T>(T value, long time) {
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Task<T> {
|
||||
private final String id;
|
||||
private final Callable<T> updater;
|
||||
private final long period;
|
||||
private final RepeatedDelayStrategy repeatStrategy;
|
||||
@Nullable
|
||||
private CompletableFuture<DataFetcher.ComputationResult<T>> pendingTask;
|
||||
@Nullable
|
||||
DataFetcher.SuccessfulComputationResult<T> lastResult;
|
||||
private long nextUpdate = -1L;
|
||||
|
||||
Task(String p_239074_, Callable<T> p_239075_, long p_239076_, RepeatedDelayStrategy p_239077_) {
|
||||
this.id = p_239074_;
|
||||
this.updater = p_239075_;
|
||||
this.period = p_239076_;
|
||||
this.repeatStrategy = p_239077_;
|
||||
}
|
||||
|
||||
void updateIfNeeded(long p_239710_) {
|
||||
if (this.pendingTask != null) {
|
||||
DataFetcher.ComputationResult<T> computationresult = this.pendingTask.getNow((DataFetcher.ComputationResult<T>)null);
|
||||
if (computationresult == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.pendingTask = null;
|
||||
long i = computationresult.time;
|
||||
computationresult.value().ifLeft((p_239691_) -> {
|
||||
this.lastResult = new DataFetcher.SuccessfulComputationResult<>(p_239691_, i);
|
||||
this.nextUpdate = i + this.period * this.repeatStrategy.delayCyclesAfterSuccess();
|
||||
}).ifRight((p_239281_) -> {
|
||||
long j = this.repeatStrategy.delayCyclesAfterFailure();
|
||||
DataFetcher.LOGGER.warn("Failed to process task {}, will repeat after {} cycles", this.id, j, p_239281_);
|
||||
this.nextUpdate = i + this.period * j;
|
||||
});
|
||||
}
|
||||
|
||||
if (this.nextUpdate <= p_239710_) {
|
||||
this.pendingTask = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
T t = this.updater.call();
|
||||
long k = DataFetcher.this.timeSource.get(DataFetcher.this.resolution);
|
||||
return new DataFetcher.ComputationResult<>(Either.left(t), k);
|
||||
} catch (Exception exception) {
|
||||
long j = DataFetcher.this.timeSource.get(DataFetcher.this.resolution);
|
||||
return new DataFetcher.ComputationResult<>(Either.right(exception), j);
|
||||
}
|
||||
}, DataFetcher.this.executor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.pendingTask = null;
|
||||
this.lastResult = null;
|
||||
this.nextUpdate = -1L;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.mojang.realmsclient.gui.task;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public interface RepeatedDelayStrategy {
|
||||
RepeatedDelayStrategy CONSTANT = new RepeatedDelayStrategy() {
|
||||
public long delayCyclesAfterSuccess() {
|
||||
return 1L;
|
||||
}
|
||||
|
||||
public long delayCyclesAfterFailure() {
|
||||
return 1L;
|
||||
}
|
||||
};
|
||||
|
||||
long delayCyclesAfterSuccess();
|
||||
|
||||
long delayCyclesAfterFailure();
|
||||
|
||||
static RepeatedDelayStrategy exponentialBackoff(final int p_239256_) {
|
||||
return new RepeatedDelayStrategy() {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private int failureCount;
|
||||
|
||||
public long delayCyclesAfterSuccess() {
|
||||
this.failureCount = 0;
|
||||
return 1L;
|
||||
}
|
||||
|
||||
public long delayCyclesAfterFailure() {
|
||||
++this.failureCount;
|
||||
long i = Math.min(1L << this.failureCount, (long)p_239256_);
|
||||
LOGGER.debug("Skipping for {} extra cycles", (long)i);
|
||||
return i;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.realmsclient.gui.task;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.realmsclient;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.mojang.realmsclient.util;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class JsonUtils {
|
||||
public static <T> T getRequired(String p_275573_, JsonObject p_275650_, Function<JsonObject, T> p_275655_) {
|
||||
JsonElement jsonelement = p_275650_.get(p_275573_);
|
||||
if (jsonelement != null && !jsonelement.isJsonNull()) {
|
||||
if (!jsonelement.isJsonObject()) {
|
||||
throw new IllegalStateException("Required property " + p_275573_ + " was not a JsonObject as espected");
|
||||
} else {
|
||||
return p_275655_.apply(jsonelement.getAsJsonObject());
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Missing required property: " + p_275573_);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getRequiredString(String p_275692_, JsonObject p_275706_) {
|
||||
String s = getStringOr(p_275692_, p_275706_, (String)null);
|
||||
if (s == null) {
|
||||
throw new IllegalStateException("Missing required property: " + p_275692_);
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getStringOr(String p_90162_, JsonObject p_90163_, @Nullable String p_90164_) {
|
||||
JsonElement jsonelement = p_90163_.get(p_90162_);
|
||||
if (jsonelement != null) {
|
||||
return jsonelement.isJsonNull() ? p_90164_ : jsonelement.getAsString();
|
||||
} else {
|
||||
return p_90164_;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static UUID getUuidOr(String p_275342_, JsonObject p_275515_, @Nullable UUID p_275232_) {
|
||||
String s = getStringOr(p_275342_, p_275515_, (String)null);
|
||||
return s == null ? p_275232_ : UUID.fromString(s);
|
||||
}
|
||||
|
||||
public static int getIntOr(String p_90154_, JsonObject p_90155_, int p_90156_) {
|
||||
JsonElement jsonelement = p_90155_.get(p_90154_);
|
||||
if (jsonelement != null) {
|
||||
return jsonelement.isJsonNull() ? p_90156_ : jsonelement.getAsInt();
|
||||
} else {
|
||||
return p_90156_;
|
||||
}
|
||||
}
|
||||
|
||||
public static long getLongOr(String p_90158_, JsonObject p_90159_, long p_90160_) {
|
||||
JsonElement jsonelement = p_90159_.get(p_90158_);
|
||||
if (jsonelement != null) {
|
||||
return jsonelement.isJsonNull() ? p_90160_ : jsonelement.getAsLong();
|
||||
} else {
|
||||
return p_90160_;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean getBooleanOr(String p_90166_, JsonObject p_90167_, boolean p_90168_) {
|
||||
JsonElement jsonelement = p_90167_.get(p_90166_);
|
||||
if (jsonelement != null) {
|
||||
return jsonelement.isJsonNull() ? p_90168_ : jsonelement.getAsBoolean();
|
||||
} else {
|
||||
return p_90168_;
|
||||
}
|
||||
}
|
||||
|
||||
public static Date getDateOr(String p_90151_, JsonObject p_90152_) {
|
||||
JsonElement jsonelement = p_90152_.get(p_90151_);
|
||||
return jsonelement != null ? new Date(Long.parseLong(jsonelement.getAsString())) : new Date();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.mojang.realmsclient.util;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.levelgen.presets.WorldPreset;
|
||||
import net.minecraft.world.level.levelgen.presets.WorldPresets;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public enum LevelType {
|
||||
DEFAULT(0, WorldPresets.NORMAL),
|
||||
FLAT(1, WorldPresets.FLAT),
|
||||
LARGE_BIOMES(2, WorldPresets.LARGE_BIOMES),
|
||||
AMPLIFIED(3, WorldPresets.AMPLIFIED);
|
||||
|
||||
private final int index;
|
||||
private final Component name;
|
||||
|
||||
private LevelType(int p_239483_, ResourceKey<WorldPreset> p_239484_) {
|
||||
this.index = p_239483_;
|
||||
this.name = Component.translatable(p_239484_.location().toLanguageKey("generator"));
|
||||
}
|
||||
|
||||
public Component getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getDtoIndex() {
|
||||
return this.index;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.mojang.realmsclient.util;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.dto.GuardedSerializer;
|
||||
import com.mojang.realmsclient.dto.ReflectionBasedSerialization;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsPersistence {
|
||||
private static final String FILE_NAME = "realms_persistence.json";
|
||||
private static final GuardedSerializer GSON = new GuardedSerializer();
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public RealmsPersistence.RealmsPersistenceData read() {
|
||||
return readFile();
|
||||
}
|
||||
|
||||
public void save(RealmsPersistence.RealmsPersistenceData p_167617_) {
|
||||
writeFile(p_167617_);
|
||||
}
|
||||
|
||||
public static RealmsPersistence.RealmsPersistenceData readFile() {
|
||||
Path path = getPathToData();
|
||||
|
||||
try {
|
||||
String s = Files.readString(path, StandardCharsets.UTF_8);
|
||||
RealmsPersistence.RealmsPersistenceData realmspersistence$realmspersistencedata = GSON.fromJson(s, RealmsPersistence.RealmsPersistenceData.class);
|
||||
if (realmspersistence$realmspersistencedata != null) {
|
||||
return realmspersistence$realmspersistencedata;
|
||||
}
|
||||
} catch (NoSuchFileException nosuchfileexception) {
|
||||
} catch (Exception exception) {
|
||||
LOGGER.warn("Failed to read Realms storage {}", path, exception);
|
||||
}
|
||||
|
||||
return new RealmsPersistence.RealmsPersistenceData();
|
||||
}
|
||||
|
||||
public static void writeFile(RealmsPersistence.RealmsPersistenceData p_90173_) {
|
||||
Path path = getPathToData();
|
||||
|
||||
try {
|
||||
Files.writeString(path, GSON.toJson(p_90173_), StandardCharsets.UTF_8);
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Path getPathToData() {
|
||||
return Minecraft.getInstance().gameDirectory.toPath().resolve("realms_persistence.json");
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class RealmsPersistenceData implements ReflectionBasedSerialization {
|
||||
@SerializedName("newsLink")
|
||||
public String newsLink;
|
||||
@SerializedName("hasUnreadNews")
|
||||
public boolean hasUnreadNews;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.mojang.realmsclient.util;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsTextureManager {
|
||||
private static final Map<String, RealmsTextureManager.RealmsTexture> TEXTURES = Maps.newHashMap();
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final ResourceLocation TEMPLATE_ICON_LOCATION = new ResourceLocation("textures/gui/presets/isles.png");
|
||||
|
||||
public static ResourceLocation worldTemplate(String p_270945_, @Nullable String p_270612_) {
|
||||
return p_270612_ == null ? TEMPLATE_ICON_LOCATION : getTexture(p_270945_, p_270612_);
|
||||
}
|
||||
|
||||
private static ResourceLocation getTexture(String p_90197_, String p_90198_) {
|
||||
RealmsTextureManager.RealmsTexture realmstexturemanager$realmstexture = TEXTURES.get(p_90197_);
|
||||
if (realmstexturemanager$realmstexture != null && realmstexturemanager$realmstexture.image().equals(p_90198_)) {
|
||||
return realmstexturemanager$realmstexture.textureId;
|
||||
} else {
|
||||
NativeImage nativeimage = loadImage(p_90198_);
|
||||
if (nativeimage == null) {
|
||||
ResourceLocation resourcelocation1 = MissingTextureAtlasSprite.getLocation();
|
||||
TEXTURES.put(p_90197_, new RealmsTextureManager.RealmsTexture(p_90198_, resourcelocation1));
|
||||
return resourcelocation1;
|
||||
} else {
|
||||
ResourceLocation resourcelocation = new ResourceLocation("realms", "dynamic/" + p_90197_);
|
||||
Minecraft.getInstance().getTextureManager().register(resourcelocation, new DynamicTexture(nativeimage));
|
||||
TEXTURES.put(p_90197_, new RealmsTextureManager.RealmsTexture(p_90198_, resourcelocation));
|
||||
return resourcelocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static NativeImage loadImage(String p_270725_) {
|
||||
byte[] abyte = Base64.getDecoder().decode(p_270725_);
|
||||
ByteBuffer bytebuffer = MemoryUtil.memAlloc(abyte.length);
|
||||
|
||||
try {
|
||||
return NativeImage.read(bytebuffer.put(abyte).flip());
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.warn("Failed to load world image: {}", p_270725_, ioexception);
|
||||
} finally {
|
||||
MemoryUtil.memFree(bytebuffer);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static record RealmsTexture(String image, ResourceLocation textureId) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.mojang.realmsclient.util;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import com.mojang.util.UUIDTypeAdapter;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.PlayerFaceRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RealmsUtil {
|
||||
static final MinecraftSessionService SESSION_SERVICE = Minecraft.getInstance().getMinecraftSessionService();
|
||||
private static final Component RIGHT_NOW = Component.translatable("mco.util.time.now");
|
||||
private static final LoadingCache<String, GameProfile> GAME_PROFILE_CACHE = CacheBuilder.newBuilder().expireAfterWrite(60L, TimeUnit.MINUTES).build(new CacheLoader<String, GameProfile>() {
|
||||
public GameProfile load(String p_90229_) {
|
||||
return RealmsUtil.SESSION_SERVICE.fillProfileProperties(new GameProfile(UUIDTypeAdapter.fromString(p_90229_), (String)null), false);
|
||||
}
|
||||
});
|
||||
private static final int MINUTES = 60;
|
||||
private static final int HOURS = 3600;
|
||||
private static final int DAYS = 86400;
|
||||
|
||||
public static String uuidToName(String p_90222_) {
|
||||
return GAME_PROFILE_CACHE.getUnchecked(p_90222_).getName();
|
||||
}
|
||||
|
||||
public static GameProfile getGameProfile(String p_270932_) {
|
||||
return GAME_PROFILE_CACHE.getUnchecked(p_270932_);
|
||||
}
|
||||
|
||||
public static Component convertToAgePresentation(long p_287679_) {
|
||||
if (p_287679_ < 0L) {
|
||||
return RIGHT_NOW;
|
||||
} else {
|
||||
long i = p_287679_ / 1000L;
|
||||
if (i < 60L) {
|
||||
return Component.translatable("mco.time.secondsAgo", i);
|
||||
} else if (i < 3600L) {
|
||||
long l = i / 60L;
|
||||
return Component.translatable("mco.time.minutesAgo", l);
|
||||
} else if (i < 86400L) {
|
||||
long k = i / 3600L;
|
||||
return Component.translatable("mco.time.hoursAgo", k);
|
||||
} else {
|
||||
long j = i / 86400L;
|
||||
return Component.translatable("mco.time.daysAgo", j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Component convertToAgePresentationFromInstant(Date p_287698_) {
|
||||
return convertToAgePresentation(System.currentTimeMillis() - p_287698_.getTime());
|
||||
}
|
||||
|
||||
public static void renderPlayerFace(GuiGraphics p_281255_, int p_281818_, int p_281791_, int p_282088_, String p_282512_) {
|
||||
GameProfile gameprofile = getGameProfile(p_282512_);
|
||||
ResourceLocation resourcelocation = Minecraft.getInstance().getSkinManager().getInsecureSkinLocation(gameprofile);
|
||||
PlayerFaceRenderer.draw(p_281255_, resourcelocation, p_281818_, p_281791_, p_282088_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package com.mojang.realmsclient.util;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class TextRenderingUtils {
|
||||
private TextRenderingUtils() {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected static List<String> lineBreak(String p_90249_) {
|
||||
return Arrays.asList(p_90249_.split("\\n"));
|
||||
}
|
||||
|
||||
public static List<TextRenderingUtils.Line> decompose(String p_90257_, TextRenderingUtils.LineSegment... p_90258_) {
|
||||
return decompose(p_90257_, Arrays.asList(p_90258_));
|
||||
}
|
||||
|
||||
private static List<TextRenderingUtils.Line> decompose(String p_90254_, List<TextRenderingUtils.LineSegment> p_90255_) {
|
||||
List<String> list = lineBreak(p_90254_);
|
||||
return insertLinks(list, p_90255_);
|
||||
}
|
||||
|
||||
private static List<TextRenderingUtils.Line> insertLinks(List<String> p_90260_, List<TextRenderingUtils.LineSegment> p_90261_) {
|
||||
int i = 0;
|
||||
List<TextRenderingUtils.Line> list = Lists.newArrayList();
|
||||
|
||||
for(String s : p_90260_) {
|
||||
List<TextRenderingUtils.LineSegment> list1 = Lists.newArrayList();
|
||||
|
||||
for(String s1 : split(s, "%link")) {
|
||||
if ("%link".equals(s1)) {
|
||||
list1.add(p_90261_.get(i++));
|
||||
} else {
|
||||
list1.add(TextRenderingUtils.LineSegment.text(s1));
|
||||
}
|
||||
}
|
||||
|
||||
list.add(new TextRenderingUtils.Line(list1));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<String> split(String p_90251_, String p_90252_) {
|
||||
if (p_90252_.isEmpty()) {
|
||||
throw new IllegalArgumentException("Delimiter cannot be the empty string");
|
||||
} else {
|
||||
List<String> list = Lists.newArrayList();
|
||||
|
||||
int i;
|
||||
int j;
|
||||
for(i = 0; (j = p_90251_.indexOf(p_90252_, i)) != -1; i = j + p_90252_.length()) {
|
||||
if (j > i) {
|
||||
list.add(p_90251_.substring(i, j));
|
||||
}
|
||||
|
||||
list.add(p_90252_);
|
||||
}
|
||||
|
||||
if (i < p_90251_.length()) {
|
||||
list.add(p_90251_.substring(i));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class Line {
|
||||
public final List<TextRenderingUtils.LineSegment> segments;
|
||||
|
||||
Line(TextRenderingUtils.LineSegment... p_167625_) {
|
||||
this(Arrays.asList(p_167625_));
|
||||
}
|
||||
|
||||
Line(List<TextRenderingUtils.LineSegment> p_90264_) {
|
||||
this.segments = p_90264_;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Line{segments=" + this.segments + "}";
|
||||
}
|
||||
|
||||
public boolean equals(Object p_90266_) {
|
||||
if (this == p_90266_) {
|
||||
return true;
|
||||
} else if (p_90266_ != null && this.getClass() == p_90266_.getClass()) {
|
||||
TextRenderingUtils.Line textrenderingutils$line = (TextRenderingUtils.Line)p_90266_;
|
||||
return Objects.equals(this.segments, textrenderingutils$line.segments);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.segments);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class LineSegment {
|
||||
private final String fullText;
|
||||
@Nullable
|
||||
private final String linkTitle;
|
||||
@Nullable
|
||||
private final String linkUrl;
|
||||
|
||||
private LineSegment(String p_90273_) {
|
||||
this.fullText = p_90273_;
|
||||
this.linkTitle = null;
|
||||
this.linkUrl = null;
|
||||
}
|
||||
|
||||
private LineSegment(String p_90275_, @Nullable String p_90276_, @Nullable String p_90277_) {
|
||||
this.fullText = p_90275_;
|
||||
this.linkTitle = p_90276_;
|
||||
this.linkUrl = p_90277_;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_90287_) {
|
||||
if (this == p_90287_) {
|
||||
return true;
|
||||
} else if (p_90287_ != null && this.getClass() == p_90287_.getClass()) {
|
||||
TextRenderingUtils.LineSegment textrenderingutils$linesegment = (TextRenderingUtils.LineSegment)p_90287_;
|
||||
return Objects.equals(this.fullText, textrenderingutils$linesegment.fullText) && Objects.equals(this.linkTitle, textrenderingutils$linesegment.linkTitle) && Objects.equals(this.linkUrl, textrenderingutils$linesegment.linkUrl);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.fullText, this.linkTitle, this.linkUrl);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Segment{fullText='" + this.fullText + "', linkTitle='" + this.linkTitle + "', linkUrl='" + this.linkUrl + "'}";
|
||||
}
|
||||
|
||||
public String renderedText() {
|
||||
return this.isLink() ? this.linkTitle : this.fullText;
|
||||
}
|
||||
|
||||
public boolean isLink() {
|
||||
return this.linkTitle != null;
|
||||
}
|
||||
|
||||
public String getLinkUrl() {
|
||||
if (!this.isLink()) {
|
||||
throw new IllegalStateException("Not a link: " + this);
|
||||
} else {
|
||||
return this.linkUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public static TextRenderingUtils.LineSegment link(String p_90282_, String p_90283_) {
|
||||
return new TextRenderingUtils.LineSegment((String)null, p_90282_, p_90283_);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected static TextRenderingUtils.LineSegment text(String p_90280_) {
|
||||
return new TextRenderingUtils.LineSegment(p_90280_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.mojang.realmsclient.util;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class UploadTokenCache {
|
||||
private static final Long2ObjectMap<String> TOKEN_CACHE = new Long2ObjectOpenHashMap<>();
|
||||
|
||||
public static String get(long p_90293_) {
|
||||
return TOKEN_CACHE.get(p_90293_);
|
||||
}
|
||||
|
||||
public static void invalidate(long p_90298_) {
|
||||
TOKEN_CACHE.remove(p_90298_);
|
||||
}
|
||||
|
||||
public static void put(long p_90295_, String p_90296_) {
|
||||
TOKEN_CACHE.put(p_90295_, p_90296_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.mojang.realmsclient.util;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class WorldGenerationInfo {
|
||||
private final String seed;
|
||||
private final LevelType levelType;
|
||||
private final boolean generateStructures;
|
||||
|
||||
public WorldGenerationInfo(String p_167631_, LevelType p_167632_, boolean p_167633_) {
|
||||
this.seed = p_167631_;
|
||||
this.levelType = p_167632_;
|
||||
this.generateStructures = p_167633_;
|
||||
}
|
||||
|
||||
public String getSeed() {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
public LevelType getLevelType() {
|
||||
return this.levelType;
|
||||
}
|
||||
|
||||
public boolean shouldGenerateStructures() {
|
||||
return this.generateStructures;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@FieldsAreNonnullByDefault
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
package com.mojang.realmsclient.util;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.FieldsAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.mojang.realmsclient.util.task;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.exception.RetryCallException;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsConfigureWorldScreen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class CloseServerTask extends LongRunningTask {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final RealmsServer serverData;
|
||||
private final RealmsConfigureWorldScreen configureScreen;
|
||||
|
||||
public CloseServerTask(RealmsServer p_90302_, RealmsConfigureWorldScreen p_90303_) {
|
||||
this.serverData = p_90302_;
|
||||
this.configureScreen = p_90303_;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
this.setTitle(Component.translatable("mco.configure.world.closing"));
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
for(int i = 0; i < 25; ++i) {
|
||||
if (this.aborted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
boolean flag = realmsclient.close(this.serverData.id);
|
||||
if (flag) {
|
||||
this.configureScreen.stateChanged();
|
||||
this.serverData.state = RealmsServer.State.CLOSED;
|
||||
setScreen(this.configureScreen);
|
||||
break;
|
||||
}
|
||||
} catch (RetryCallException retrycallexception) {
|
||||
if (this.aborted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
pause((long)retrycallexception.delaySeconds);
|
||||
} catch (Exception exception) {
|
||||
if (this.aborted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.error("Failed to close server", (Throwable)exception);
|
||||
this.error("Failed to close the server");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.mojang.realmsclient.util.task;
|
||||
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.RealmsServerAddress;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.multiplayer.resolver.ServerAddress;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.realms.RealmsConnect;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class ConnectTask extends LongRunningTask {
|
||||
private final RealmsConnect realmsConnect;
|
||||
private final RealmsServer server;
|
||||
private final RealmsServerAddress address;
|
||||
|
||||
public ConnectTask(Screen p_90309_, RealmsServer p_90310_, RealmsServerAddress p_90311_) {
|
||||
this.server = p_90310_;
|
||||
this.address = p_90311_;
|
||||
this.realmsConnect = new RealmsConnect(p_90309_);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
this.setTitle(Component.translatable("mco.connect.connecting"));
|
||||
this.realmsConnect.connect(this.server, ServerAddress.parseString(this.address.address));
|
||||
}
|
||||
|
||||
public void abortTask() {
|
||||
this.realmsConnect.abort();
|
||||
Minecraft.getInstance().getDownloadedPackSource().clearServerPack();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
this.realmsConnect.tick();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.mojang.realmsclient.util.task;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.WorldDownload;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.exception.RetryCallException;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsDownloadLatestWorldScreen;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsGenericErrorScreen;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class DownloadTask extends LongRunningTask {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final long worldId;
|
||||
private final int slot;
|
||||
private final Screen lastScreen;
|
||||
private final String downloadName;
|
||||
|
||||
public DownloadTask(long p_90320_, int p_90321_, String p_90322_, Screen p_90323_) {
|
||||
this.worldId = p_90320_;
|
||||
this.slot = p_90321_;
|
||||
this.lastScreen = p_90323_;
|
||||
this.downloadName = p_90322_;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
this.setTitle(Component.translatable("mco.download.preparing"));
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
int i = 0;
|
||||
|
||||
while(i < 25) {
|
||||
try {
|
||||
if (this.aborted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
WorldDownload worlddownload = realmsclient.requestDownloadInfo(this.worldId, this.slot);
|
||||
pause(1L);
|
||||
if (this.aborted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
setScreen(new RealmsDownloadLatestWorldScreen(this.lastScreen, worlddownload, this.downloadName, (p_90325_) -> {
|
||||
}));
|
||||
return;
|
||||
} catch (RetryCallException retrycallexception) {
|
||||
if (this.aborted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
pause((long)retrycallexception.delaySeconds);
|
||||
++i;
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
if (this.aborted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.error("Couldn't download world data");
|
||||
setScreen(new RealmsGenericErrorScreen(realmsserviceexception, this.lastScreen));
|
||||
return;
|
||||
} catch (Exception exception) {
|
||||
if (this.aborted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.error("Couldn't download world data", (Throwable)exception);
|
||||
this.error(exception.getLocalizedMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package com.mojang.realmsclient.util.task;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.RealmsMainScreen;
|
||||
import com.mojang.realmsclient.client.RealmsClient;
|
||||
import com.mojang.realmsclient.dto.RealmsServer;
|
||||
import com.mojang.realmsclient.dto.RealmsServerAddress;
|
||||
import com.mojang.realmsclient.exception.RealmsServiceException;
|
||||
import com.mojang.realmsclient.exception.RetryCallException;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsBrokenWorldScreen;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsGenericErrorScreen;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsLongConfirmationScreen;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsLongRunningMcoTaskScreen;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsTermsScreen;
|
||||
import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class GetServerDetailsTask extends LongRunningTask {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final RealmsServer server;
|
||||
private final Screen lastScreen;
|
||||
private final RealmsMainScreen mainScreen;
|
||||
private final ReentrantLock connectLock;
|
||||
|
||||
public GetServerDetailsTask(RealmsMainScreen p_90332_, Screen p_90333_, RealmsServer p_90334_, ReentrantLock p_90335_) {
|
||||
this.lastScreen = p_90333_;
|
||||
this.mainScreen = p_90332_;
|
||||
this.server = p_90334_;
|
||||
this.connectLock = p_90335_;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
this.setTitle(Component.translatable("mco.connect.connecting"));
|
||||
|
||||
RealmsServerAddress realmsserveraddress;
|
||||
try {
|
||||
realmsserveraddress = this.fetchServerAddress();
|
||||
} catch (CancellationException cancellationexception) {
|
||||
LOGGER.info("User aborted connecting to realms");
|
||||
return;
|
||||
} catch (RealmsServiceException realmsserviceexception) {
|
||||
switch (realmsserviceexception.realmsErrorCodeOrDefault(-1)) {
|
||||
case 6002:
|
||||
setScreen(new RealmsTermsScreen(this.lastScreen, this.mainScreen, this.server));
|
||||
return;
|
||||
case 6006:
|
||||
boolean flag1 = this.server.ownerUUID.equals(Minecraft.getInstance().getUser().getUuid());
|
||||
setScreen((Screen)(flag1 ? new RealmsBrokenWorldScreen(this.lastScreen, this.mainScreen, this.server.id, this.server.worldType == RealmsServer.WorldType.MINIGAME) : new RealmsGenericErrorScreen(Component.translatable("mco.brokenworld.nonowner.title"), Component.translatable("mco.brokenworld.nonowner.error"), this.lastScreen)));
|
||||
return;
|
||||
default:
|
||||
this.error(realmsserviceexception.toString());
|
||||
LOGGER.error("Couldn't connect to world", (Throwable)realmsserviceexception);
|
||||
return;
|
||||
}
|
||||
} catch (TimeoutException timeoutexception) {
|
||||
this.error(Component.translatable("mco.errorMessage.connectionFailure"));
|
||||
return;
|
||||
} catch (Exception exception) {
|
||||
LOGGER.error("Couldn't connect to world", (Throwable)exception);
|
||||
this.error(exception.getLocalizedMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
boolean flag = realmsserveraddress.resourcePackUrl != null && realmsserveraddress.resourcePackHash != null;
|
||||
Screen screen = (Screen)(flag ? this.resourcePackDownloadConfirmationScreen(realmsserveraddress, this::connectScreen) : this.connectScreen(realmsserveraddress));
|
||||
setScreen(screen);
|
||||
}
|
||||
|
||||
private RealmsServerAddress fetchServerAddress() throws RealmsServiceException, TimeoutException, CancellationException {
|
||||
RealmsClient realmsclient = RealmsClient.create();
|
||||
|
||||
for(int i = 0; i < 40; ++i) {
|
||||
if (this.aborted()) {
|
||||
throw new CancellationException();
|
||||
}
|
||||
|
||||
try {
|
||||
return realmsclient.join(this.server.id);
|
||||
} catch (RetryCallException retrycallexception) {
|
||||
pause((long)retrycallexception.delaySeconds);
|
||||
}
|
||||
}
|
||||
|
||||
throw new TimeoutException();
|
||||
}
|
||||
|
||||
public RealmsLongRunningMcoTaskScreen connectScreen(RealmsServerAddress p_167638_) {
|
||||
return new RealmsLongRunningMcoTaskScreen(this.lastScreen, new ConnectTask(this.lastScreen, this.server, p_167638_));
|
||||
}
|
||||
|
||||
private RealmsLongConfirmationScreen resourcePackDownloadConfirmationScreen(RealmsServerAddress p_167640_, Function<RealmsServerAddress, Screen> p_167641_) {
|
||||
BooleanConsumer booleanconsumer = (p_167645_) -> {
|
||||
try {
|
||||
if (p_167645_) {
|
||||
this.scheduleResourcePackDownload(p_167640_).thenRun(() -> {
|
||||
setScreen(p_167641_.apply(p_167640_));
|
||||
}).exceptionally((p_287306_) -> {
|
||||
Minecraft.getInstance().getDownloadedPackSource().clearServerPack();
|
||||
LOGGER.error("Failed to download resource pack from {}", p_167640_, p_287306_);
|
||||
setScreen(new RealmsGenericErrorScreen(Component.translatable("mco.download.resourcePack.fail"), this.lastScreen));
|
||||
return null;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setScreen(this.lastScreen);
|
||||
} finally {
|
||||
if (this.connectLock.isHeldByCurrentThread()) {
|
||||
this.connectLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
return new RealmsLongConfirmationScreen(booleanconsumer, RealmsLongConfirmationScreen.Type.INFO, Component.translatable("mco.configure.world.resourcepack.question.line1"), Component.translatable("mco.configure.world.resourcepack.question.line2"), true);
|
||||
}
|
||||
|
||||
private CompletableFuture<?> scheduleResourcePackDownload(RealmsServerAddress p_167652_) {
|
||||
try {
|
||||
return Minecraft.getInstance().getDownloadedPackSource().downloadAndSelectResourcePack(new URL(p_167652_.resourcePackUrl), p_167652_.resourcePackHash, false);
|
||||
} catch (Exception exception) {
|
||||
CompletableFuture<Void> completablefuture = new CompletableFuture<>();
|
||||
completablefuture.completeExceptionally(exception);
|
||||
return completablefuture;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.mojang.realmsclient.util.task;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.realmsclient.gui.ErrorCallback;
|
||||
import com.mojang.realmsclient.gui.screens.RealmsLongRunningMcoTaskScreen;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class LongRunningTask implements ErrorCallback, Runnable {
|
||||
protected static final int NUMBER_OF_RETRIES = 25;
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
protected RealmsLongRunningMcoTaskScreen longRunningMcoTaskScreen;
|
||||
|
||||
protected static void pause(long p_167656_) {
|
||||
try {
|
||||
Thread.sleep(p_167656_ * 1000L);
|
||||
} catch (InterruptedException interruptedexception) {
|
||||
Thread.currentThread().interrupt();
|
||||
LOGGER.error("", (Throwable)interruptedexception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void setScreen(Screen p_90406_) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
minecraft.execute(() -> {
|
||||
minecraft.setScreen(p_90406_);
|
||||
});
|
||||
}
|
||||
|
||||
public void setScreen(RealmsLongRunningMcoTaskScreen p_90401_) {
|
||||
this.longRunningMcoTaskScreen = p_90401_;
|
||||
}
|
||||
|
||||
public void error(Component p_90408_) {
|
||||
this.longRunningMcoTaskScreen.error(p_90408_);
|
||||
}
|
||||
|
||||
public void setTitle(Component p_90410_) {
|
||||
this.longRunningMcoTaskScreen.setTitle(p_90410_);
|
||||
}
|
||||
|
||||
public boolean aborted() {
|
||||
return this.longRunningMcoTaskScreen.aborted();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public void abortTask() {
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user