RealmsDownloadLatestWorldScreen.java
com.mojang.realmsclient.gui.screens.RealmsDownloadLatestWorldScreen
信息
- 全限定名:com.mojang.realmsclient.gui.screens.RealmsDownloadLatestWorldScreen
- 类型:public class
- 包:com.mojang.realmsclient.gui.screens
- 源码路径:src/main/java/com/mojang/realmsclient/gui/screens/RealmsDownloadLatestWorldScreen.java
- 起始行号:L28
- 继承:RealmsScreen
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L29 - 说明:
TODO
- 类型:
-
DOWNLOAD_LOCK- 类型:
ReentrantLock - 修饰符:
private static final - 源码定位:
L30 - 说明:
TODO
- 类型:
-
BAR_WIDTH- 类型:
int - 修饰符:
private static final - 源码定位:
L31 - 说明:
TODO
- 类型:
-
BAR_TOP- 类型:
int - 修饰符:
private static final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
BAR_BOTTOM- 类型:
int - 修饰符:
private static final - 源码定位:
L33 - 说明:
TODO
- 类型:
-
BAR_BORDER- 类型:
int - 修饰符:
private static final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
lastScreen- 类型:
Screen - 修饰符:
private final - 源码定位:
L35 - 说明:
TODO
- 类型:
-
worldDownload- 类型:
WorldDownload - 修饰符:
private final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
downloadTitle- 类型:
Component - 修饰符:
private final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
narrationRateLimiter- 类型:
RateLimiter - 修饰符:
private final - 源码定位:
L38 - 说明:
TODO
- 类型:
-
cancelButton- 类型:
Button - 修饰符:
private - 源码定位:
L39 - 说明:
TODO
- 类型:
-
worldName- 类型:
String - 修饰符:
private final - 源码定位:
L40 - 说明:
TODO
- 类型:
-
downloadStatus- 类型:
RealmsDownloadLatestWorldScreen.DownloadStatus - 修饰符:
private final - 源码定位:
L41 - 说明:
TODO
- 类型:
-
errorMessage- 类型:
Component - 修饰符:
private volatile - 源码定位:
L42 - 说明:
TODO
- 类型:
-
status- 类型:
Component - 修饰符:
private volatile - 源码定位:
L43 - 说明:
TODO
- 类型:
-
progress- 类型:
String - 修饰符:
private volatile - 源码定位:
L44 - 说明:
TODO
- 类型:
-
cancelled- 类型:
boolean - 修饰符:
private volatile - 源码定位:
L45 - 说明:
TODO
- 类型:
-
showDots- 类型:
boolean - 修饰符:
private volatile - 源码定位:
L46 - 说明:
TODO
- 类型:
-
finished- 类型:
boolean - 修饰符:
private volatile - 源码定位:
L47 - 说明:
TODO
- 类型:
-
extracting- 类型:
boolean - 修饰符:
private volatile - 源码定位:
L48 - 说明:
TODO
- 类型:
-
previousWrittenBytes- 类型:
Long - 修饰符:
private - 源码定位:
L49 - 说明:
TODO
- 类型:
-
previousTimeSnapshot- 类型:
Long - 修饰符:
private - 源码定位:
L50 - 说明:
TODO
- 类型:
-
bytesPersSecond- 类型:
long - 修饰符:
private - 源码定位:
L51 - 说明:
TODO
- 类型:
-
animTick- 类型:
int - 修饰符:
private - 源码定位:
L52 - 说明:
TODO
- 类型:
-
DOTS- 类型:
String[] - 修饰符:
private static final - 源码定位:
L53 - 说明:
TODO
- 类型:
-
dotIndex- 类型:
int - 修饰符:
private - 源码定位:
L54 - 说明:
TODO
- 类型:
-
checked- 类型:
boolean - 修饰符:
private - 源码定位:
L55 - 说明:
TODO
- 类型:
-
callback- 类型:
BooleanConsumer - 修饰符:
private final - 源码定位:
L56 - 说明:
TODO
- 类型:
内部类/嵌套类型
com.mojang.realmsclient.gui.screens.RealmsDownloadLatestWorldScreen.DownloadStatus- 类型:
class - 修饰符:
public static - 源码定位:
L272 - 说明:
TODO
- 类型:
构造器
public RealmsDownloadLatestWorldScreen(Screen lastScreen, WorldDownload worldDownload, String worldName, BooleanConsumer callback) @ L58
- 构造器名:RealmsDownloadLatestWorldScreen
- 源码定位:L58
- 修饰符:public
参数:
- lastScreen: Screen
- worldDownload: WorldDownload
- worldName: String
- callback: BooleanConsumer
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void init() @ L69
- 方法名:init
- 源码定位:L69
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private void checkDownloadSize() @ L77
- 方法名:checkDownloadSize
- 源码定位:L77
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private long getContentLength(String downloadLink) @ L92
- 方法名:getContentLength
- 源码定位:L92
- 返回类型:long
- 修饰符:private
参数:
- downloadLink: String
说明:
TODO
public void tick() @ L96
- 方法名:tick
- 源码定位:L96
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private Component createProgressNarrationMessage() @ L106
- 方法名:createProgressNarrationMessage
- 源码定位:L106
- 返回类型:Component
- 修饰符:private
参数:
- 无
说明:
TODO
public void onClose() @ L122
- 方法名:onClose
- 源码定位:L122
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void extractRenderState(GuiGraphicsExtractor graphics, int xm, int ym, float a) @ L132
- 方法名:extractRenderState
- 源码定位:L132
- 返回类型:void
- 修饰符:public
参数:
- graphics: GuiGraphicsExtractor
- xm: int
- ym: int
- a: float
说明:
TODO
private void extractDots(GuiGraphicsExtractor graphics) @ L151
- 方法名:extractDots
- 源码定位:L151
- 返回类型:void
- 修饰符:private
参数:
- graphics: GuiGraphicsExtractor
说明:
TODO
private void extractProgressBar(GuiGraphicsExtractor graphics) @ L160
- 方法名:extractProgressBar
- 源码定位:L160
- 返回类型:void
- 修饰符:private
参数:
- graphics: GuiGraphicsExtractor
说明:
TODO
private void extractDownloadSpeed(GuiGraphicsExtractor graphics) @ L170
- 方法名:extractDownloadSpeed
- 源码定位:L170
- 返回类型:void
- 修饰符:private
参数:
- graphics: GuiGraphicsExtractor
说明:
TODO
private void extractDownloadSpeed0(GuiGraphicsExtractor graphics, long bytesPerSecond) @ L189
- 方法名:extractDownloadSpeed0
- 源码定位:L189
- 返回类型:void
- 修饰符:private
参数:
- graphics: GuiGraphicsExtractor
- bytesPerSecond: long
说明:
TODO
private void downloadSave() @ L198
- 方法名:downloadSave
- 源码定位:L198
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void downloadCancelled() @ L267
- 方法名:downloadCancelled
- 源码定位:L267
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
代码
@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;
private volatile @Nullable Component errorMessage;
private volatile Component status = Component.translatable("mco.download.preparing");
private volatile @Nullable String progress;
private volatile boolean cancelled;
private volatile boolean showDots = true;
private volatile boolean finished;
private volatile boolean extracting;
private @Nullable Long previousWrittenBytes;
private @Nullable 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 lastScreen, WorldDownload worldDownload, String worldName, BooleanConsumer callback) {
super(GameNarrator.NO_TITLE);
this.callback = callback;
this.lastScreen = lastScreen;
this.worldName = worldName;
this.worldDownload = worldDownload;
this.downloadStatus = new RealmsDownloadLatestWorldScreen.DownloadStatus();
this.downloadTitle = Component.translatable("mco.download.title");
this.narrationRateLimiter = RateLimiter.create(0.1F);
}
@Override
public void init() {
this.cancelButton = this.addRenderableWidget(
Button.builder(CommonComponents.GUI_CANCEL, button -> this.onClose()).bounds((this.width - 200) / 2, this.height - 42, 200, 20).build()
);
this.checkDownloadSize();
}
private void checkDownloadSize() {
if (!this.finished && !this.checked) {
this.checked = true;
if (this.getContentLength(this.worldDownload.downloadLink()) >= 5368709120L) {
Component popupMessage = Component.translatable("mco.download.confirmation.oversized", Unit.humanReadable(5368709120L));
this.minecraft.setScreen(RealmsPopups.warningAcknowledgePopupScreen(this, popupMessage, popupScreen -> {
this.minecraft.setScreen(this);
this.downloadSave();
}));
} else {
this.downloadSave();
}
}
}
private long getContentLength(String downloadLink) {
return FileDownload.contentLength(downloadLink).orElse(0L);
}
@Override
public void tick() {
super.tick();
this.animTick++;
if (this.status != null && this.narrationRateLimiter.tryAcquire(1)) {
Component message = this.createProgressNarrationMessage();
this.minecraft.getNarrator().saySystemNow(message);
}
}
private Component createProgressNarrationMessage() {
List<Component> elements = Lists.newArrayList();
elements.add(this.downloadTitle);
elements.add(this.status);
if (this.progress != null) {
elements.add(Component.translatable("mco.download.percent", this.progress));
elements.add(Component.translatable("mco.download.speed.narration", Unit.humanReadable(this.bytesPersSecond)));
}
if (this.errorMessage != null) {
elements.add(this.errorMessage);
}
return CommonComponents.joinLines(elements);
}
@Override
public void onClose() {
this.cancelled = true;
if (this.finished && this.callback != null && this.errorMessage == null) {
this.callback.accept(true);
}
this.minecraft.setScreen(this.lastScreen);
}
@Override
public void extractRenderState(GuiGraphicsExtractor graphics, int xm, int ym, float a) {
super.extractRenderState(graphics, xm, ym, a);
graphics.centeredText(this.font, this.downloadTitle, this.width / 2, 20, -1);
graphics.centeredText(this.font, this.status, this.width / 2, 50, -1);
if (this.showDots) {
this.extractDots(graphics);
}
if (this.downloadStatus.bytesWritten != 0L && !this.cancelled) {
this.extractProgressBar(graphics);
this.extractDownloadSpeed(graphics);
}
if (this.errorMessage != null) {
graphics.centeredText(this.font, this.errorMessage, this.width / 2, 110, -65536);
}
}
private void extractDots(GuiGraphicsExtractor graphics) {
int statusWidth = this.font.width(this.status);
if (this.animTick != 0 && this.animTick % 10 == 0) {
this.dotIndex++;
}
graphics.text(this.font, DOTS[this.dotIndex % DOTS.length], this.width / 2 + statusWidth / 2 + 5, 50, -1);
}
private void extractProgressBar(GuiGraphicsExtractor graphics) {
double percentage = Math.min((double)this.downloadStatus.bytesWritten / this.downloadStatus.totalBytes, 1.0);
this.progress = String.format(Locale.ROOT, "%.1f", percentage * 100.0);
int left = (this.width - 200) / 2;
int right = left + (int)Math.round(200.0 * percentage);
graphics.fill(left - 1, 79, right + 1, 96, -1);
graphics.fill(left, 80, right, 95, -8355712);
graphics.centeredText(this.font, Component.translatable("mco.download.percent", this.progress), this.width / 2, 84, -1);
}
private void extractDownloadSpeed(GuiGraphicsExtractor graphics) {
if (this.animTick % 20 == 0) {
if (this.previousWrittenBytes != null) {
long timeElapsed = Util.getMillis() - this.previousTimeSnapshot;
if (timeElapsed == 0L) {
timeElapsed = 1L;
}
this.bytesPersSecond = 1000L * (this.downloadStatus.bytesWritten - this.previousWrittenBytes) / timeElapsed;
this.extractDownloadSpeed0(graphics, this.bytesPersSecond);
}
this.previousWrittenBytes = this.downloadStatus.bytesWritten;
this.previousTimeSnapshot = Util.getMillis();
} else {
this.extractDownloadSpeed0(graphics, this.bytesPersSecond);
}
}
private void extractDownloadSpeed0(GuiGraphicsExtractor graphics, long bytesPerSecond) {
if (bytesPerSecond > 0L) {
int progressLength = this.font.width(this.progress);
graphics.text(
this.font, Component.translatable("mco.download.speed", Unit.humanReadable(bytesPerSecond)), this.width / 2 + progressLength / 2 + 15, 84, -1
);
}
}
private void downloadSave() {
new Thread(() -> {
try {
try {
if (!DOWNLOAD_LOCK.tryLock(1L, TimeUnit.SECONDS)) {
this.status = Component.translatable("mco.download.failed");
return;
}
if (this.cancelled) {
this.downloadCancelled();
return;
}
this.status = Component.translatable("mco.download.downloading", this.worldName);
FileDownload fileDownload = new FileDownload();
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 var8) {
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;
} catch (InterruptedException var9) {
LOGGER.error("Could not acquire upload lock");
} catch (Exception var10) {
this.errorMessage = Component.translatable("mco.download.failed");
LOGGER.info("Exception while downloading world", (Throwable)var10);
}
} finally {
if (!DOWNLOAD_LOCK.isHeldByCurrentThread()) {
return;
} else {
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;
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
Unit.humanReadable()
- 引用位置:
-
- 引用位置:
方法调用/构造调用 - 关联成员:
FileDownload(), FileDownload.contentLength()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RealmsPopups.warningAcknowledgePopupScreen()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Button.builder()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
CommonComponents.joinLines()
- 引用位置:
-
- 引用位置:
字段/方法调用/返回值 - 关联成员:
Component.translatable()
- 引用位置:
-
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.getMillis()
- 引用位置: