mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 10:58:15 -05:00
Update #51 - Protocol and FPS improvements, better workspace
This commit is contained in:
@ -40,17 +40,17 @@ public class GuiScreenPhishingWarning extends GuiScreen {
|
||||
|
||||
public void initGui() {
|
||||
this.buttonList.clear();
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 6 + 134, I18n.format("webviewPhishingWaring.continue")));
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 6 + 134, I18n.format("webviewPhishingWarning.continue")));
|
||||
}
|
||||
|
||||
public void drawScreen(int mx, int my, float pt) {
|
||||
this.drawDefaultBackground();
|
||||
this.drawCenteredString(fontRendererObj, EnumChatFormatting.BOLD + I18n.format("webviewPhishingWaring.title"), this.width / 2, 70, 0xFF4444);
|
||||
this.drawCenteredString(fontRendererObj, I18n.format("webviewPhishingWaring.text0"), this.width / 2, 90, 16777215);
|
||||
this.drawCenteredString(fontRendererObj, I18n.format("webviewPhishingWaring.text1"), this.width / 2, 102, 16777215);
|
||||
this.drawCenteredString(fontRendererObj, I18n.format("webviewPhishingWaring.text2"), this.width / 2, 114, 16777215);
|
||||
this.drawCenteredString(fontRendererObj, EnumChatFormatting.BOLD + I18n.format("webviewPhishingWarning.title"), this.width / 2, 70, 0xFF4444);
|
||||
this.drawCenteredString(fontRendererObj, I18n.format("webviewPhishingWarning.text0"), this.width / 2, 90, 16777215);
|
||||
this.drawCenteredString(fontRendererObj, I18n.format("webviewPhishingWarning.text1"), this.width / 2, 102, 16777215);
|
||||
this.drawCenteredString(fontRendererObj, I18n.format("webviewPhishingWarning.text2"), this.width / 2, 114, 16777215);
|
||||
|
||||
String dontShowAgain = I18n.format("webviewPhishingWaring.dontShowAgain");
|
||||
String dontShowAgain = I18n.format("webviewPhishingWarning.dontShowAgain");
|
||||
int w = fontRendererObj.getStringWidth(dontShowAgain) + 20;
|
||||
int ww = (this.width - w) / 2;
|
||||
this.drawString(fontRendererObj, dontShowAgain, ww + 20, 137, 0xCCCCCC);
|
||||
|
@ -23,6 +23,7 @@ import java.util.Arrays;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglerZLIB;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.IOUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.crypto.SHA1Digest;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.WebViewOptions;
|
||||
@ -34,6 +35,7 @@ import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.client.CPacketRequestServerInfoV4EAG;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
@ -44,13 +46,25 @@ public class GuiScreenRecieveServerInfo extends GuiScreen {
|
||||
|
||||
protected final GuiScreen parent;
|
||||
protected final byte[] expectHash;
|
||||
protected final IDisplayWebviewProc proc;
|
||||
protected int timer;
|
||||
protected int timer2;
|
||||
protected String statusString = "recieveServerInfo.checkingCache";
|
||||
|
||||
public static interface IDisplayWebviewProc {
|
||||
GuiScreen display(GuiScreen parent, byte[] blob, EaglercraftUUID permissionsOriginUUID);
|
||||
}
|
||||
|
||||
public GuiScreenRecieveServerInfo(GuiScreen parent, byte[] expectHash) {
|
||||
this.parent = parent;
|
||||
this.expectHash = expectHash;
|
||||
this.proc = GuiScreenServerInfo::createForCurrentState;
|
||||
}
|
||||
|
||||
public GuiScreenRecieveServerInfo(GuiScreen parent, byte[] expectHash, IDisplayWebviewProc proc) {
|
||||
this.parent = parent;
|
||||
this.expectHash = expectHash;
|
||||
this.proc = proc;
|
||||
}
|
||||
|
||||
public void initGui() {
|
||||
@ -105,28 +119,26 @@ public class GuiScreenRecieveServerInfo extends GuiScreen {
|
||||
mc.displayGuiScreen(parent);
|
||||
return;
|
||||
}
|
||||
NetHandlerPlayClient sendQueue = mc.thePlayer.sendQueue;
|
||||
++timer;
|
||||
if(timer == 1) {
|
||||
byte[] data = ServerInfoCache.loadFromCache(expectHash);
|
||||
if(data != null) {
|
||||
mc.displayGuiScreen(GuiScreenServerInfo.createForCurrentState(parent, data, WebViewOptions.getEmbedOriginUUID(expectHash)));
|
||||
mc.displayGuiScreen(proc.display(parent, data, WebViewOptions.getEmbedOriginUUID(expectHash)));
|
||||
}else {
|
||||
byte[] b = mc.thePlayer.sendQueue.cachedServerInfoData;
|
||||
if(b != null) {
|
||||
byte[] b = sendQueue.cachedServerInfoData;
|
||||
if(b != null && Arrays.equals(expectHash, sendQueue.cachedServerInfoHash)) {
|
||||
if(b.length == 0) {
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("serverInfoFailure.title", "serverInfoFailure.desc", parent));
|
||||
}else {
|
||||
ServerInfoCache.storeInCache(expectHash, b);
|
||||
mc.displayGuiScreen(GuiScreenServerInfo.createForCurrentState(parent, b, WebViewOptions.getEmbedOriginUUID(expectHash)));
|
||||
mc.displayGuiScreen(proc.display(parent, b, WebViewOptions.getEmbedOriginUUID(expectHash)));
|
||||
}
|
||||
}else {
|
||||
statusString = "recieveServerInfo.contactingServer";
|
||||
if(!mc.thePlayer.sendQueue.hasRequestedServerInfo) {
|
||||
if(!ServerInfoCache.hasLastChunk || !Arrays.equals(ServerInfoCache.chunkRecieveHash, expectHash)) {
|
||||
ServerInfoCache.clearDownload();
|
||||
mc.thePlayer.sendQueue.sendEaglerMessage(new CPacketRequestServerInfoV4EAG(expectHash));
|
||||
mc.thePlayer.sendQueue.hasRequestedServerInfo = true;
|
||||
}
|
||||
if(!ServerInfoCache.hasLastChunk || !Arrays.equals(ServerInfoCache.chunkRecieveHash, expectHash)) {
|
||||
ServerInfoCache.clearDownload();
|
||||
sendQueue.sendEaglerMessage(new CPacketRequestServerInfoV4EAG(expectHash));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,7 +156,8 @@ public class GuiScreenRecieveServerInfo extends GuiScreen {
|
||||
}
|
||||
if(i != ServerInfoCache.chunkCurrentSize) {
|
||||
logger.error("An unknown error occured!");
|
||||
mc.thePlayer.sendQueue.cachedServerInfoData = new byte[0];
|
||||
sendQueue.cachedServerInfoHash = expectHash;
|
||||
sendQueue.cachedServerInfoData = new byte[0];
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("serverInfoFailure.title", "serverInfoFailure.desc", parent));
|
||||
return;
|
||||
}
|
||||
@ -154,14 +167,16 @@ public class GuiScreenRecieveServerInfo extends GuiScreen {
|
||||
int finalSize = (new DataInputStream(bis)).readInt();
|
||||
if(finalSize < 0) {
|
||||
logger.error("The response data was corrupt, decompressed size is negative!");
|
||||
mc.thePlayer.sendQueue.cachedServerInfoData = new byte[0];
|
||||
sendQueue.cachedServerInfoHash = expectHash;
|
||||
sendQueue.cachedServerInfoData = new byte[0];
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("serverInfoFailure.title", "serverInfoFailure.desc", parent));
|
||||
return;
|
||||
}
|
||||
if(finalSize > ServerInfoCache.CACHE_MAX_SIZE * 2) {
|
||||
logger.error("Failed to decompress/verify server info response! Size is massive, {} " + finalSize + " bytes reported!");
|
||||
logger.error("Failed to decompress/verify server info response! Size is massive, {} bytes reported!", finalSize);
|
||||
logger.error("Aborting decompression. Rejoin the server to try again.");
|
||||
mc.thePlayer.sendQueue.cachedServerInfoData = new byte[0];
|
||||
sendQueue.cachedServerInfoHash = expectHash;
|
||||
sendQueue.cachedServerInfoData = new byte[0];
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("serverInfoFailure.title", "serverInfoFailure.desc", parent));
|
||||
return;
|
||||
}
|
||||
@ -175,17 +190,20 @@ public class GuiScreenRecieveServerInfo extends GuiScreen {
|
||||
digest.doFinal(csum, 0);
|
||||
if(Arrays.equals(csum, expectHash)) {
|
||||
ServerInfoCache.storeInCache(csum, decompressed);
|
||||
mc.thePlayer.sendQueue.cachedServerInfoData = decompressed;
|
||||
mc.displayGuiScreen(GuiScreenServerInfo.createForCurrentState(parent, decompressed, WebViewOptions.getEmbedOriginUUID(expectHash)));
|
||||
sendQueue.cachedServerInfoHash = expectHash;
|
||||
sendQueue.cachedServerInfoData = decompressed;
|
||||
mc.displayGuiScreen(proc.display(parent, decompressed, WebViewOptions.getEmbedOriginUUID(expectHash)));
|
||||
}else {
|
||||
logger.error("The data recieved from the server did not have the correct SHA1 checksum! Rejoin the server to try again.");
|
||||
mc.thePlayer.sendQueue.cachedServerInfoData = new byte[0];
|
||||
sendQueue.cachedServerInfoHash = expectHash;
|
||||
sendQueue.cachedServerInfoData = new byte[0];
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("serverInfoFailure.title", "serverInfoFailure.desc", parent));
|
||||
}
|
||||
}catch(IOException ex) {
|
||||
logger.error("Failed to decompress/verify server info response! Rejoin the server to try again.");
|
||||
logger.error(ex);
|
||||
mc.thePlayer.sendQueue.cachedServerInfoData = new byte[0];
|
||||
sendQueue.cachedServerInfoHash = expectHash;
|
||||
sendQueue.cachedServerInfoData = new byte[0];
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("serverInfoFailure.title", "serverInfoFailure.desc", parent));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.lax1dude.eaglercraft.v1_8.webview;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class GuiScreenRequestDisplay extends GuiScreen {
|
||||
|
||||
private static final ResourceLocation beaconGuiTexture = new ResourceLocation("textures/gui/container/beacon.png");
|
||||
|
||||
private GuiScreen cont;
|
||||
private GuiScreen back;
|
||||
private NetHandlerPlayClient netHandler;
|
||||
private boolean mouseOverCheck;
|
||||
private boolean hasCheckedBox;
|
||||
|
||||
public GuiScreenRequestDisplay(GuiScreen cont, GuiScreen back, NetHandlerPlayClient netHandler) {
|
||||
this.cont = cont;
|
||||
this.back = back;
|
||||
this.netHandler = netHandler;
|
||||
}
|
||||
|
||||
public void initGui() {
|
||||
this.buttonList.clear();
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 + 2, this.height / 6 + 122, 148, 20, I18n.format("webviewPhishingWarning.continue")));
|
||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 150, this.height / 6 + 122, 148, 20, I18n.format("gui.cancel")));
|
||||
}
|
||||
|
||||
public void drawScreen(int mx, int my, float pt) {
|
||||
this.drawDefaultBackground();
|
||||
this.drawCenteredString(fontRendererObj, EnumChatFormatting.BOLD + I18n.format("webviewDisplayWarning.title"), this.width / 2, 70, 0xFF4444);
|
||||
this.drawCenteredString(fontRendererObj, I18n.format("webviewDisplayWarning.text0"), this.width / 2, 90, 16777215);
|
||||
this.drawCenteredString(fontRendererObj, I18n.format("webviewDisplayWarning.text1"), this.width / 2, 102, 16777215);
|
||||
|
||||
String dontShowAgain = I18n.format("webviewPhishingWarning.dontShowAgain");
|
||||
int w = fontRendererObj.getStringWidth(dontShowAgain) + 20;
|
||||
int ww = (this.width - w) / 2;
|
||||
this.drawString(fontRendererObj, dontShowAgain, ww + 20, 125, 0xCCCCCC);
|
||||
|
||||
mouseOverCheck = ww < mx && ww + 17 > mx && 121 < my && 138 > my;
|
||||
|
||||
if(mouseOverCheck) {
|
||||
GlStateManager.color(0.7f, 0.7f, 1.0f, 1.0f);
|
||||
}else {
|
||||
GlStateManager.color(0.6f, 0.6f, 0.6f, 1.0f);
|
||||
}
|
||||
|
||||
mc.getTextureManager().bindTexture(beaconGuiTexture);
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
drawTexturedModalRect(ww * 4 / 3, 121 * 4 / 3, 22, 219, 22, 22);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if(hasCheckedBox) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.color(1.1f, 1.1f, 1.1f, 1.0f);
|
||||
GlStateManager.translate(0.5f, 0.5f, 0.0f);
|
||||
drawTexturedModalRect(ww, 121, 90, 222, 16, 16);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
super.drawScreen(mx, my, pt);
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton par1GuiButton) {
|
||||
if(par1GuiButton.id == 0) {
|
||||
if(hasCheckedBox) {
|
||||
netHandler.allowedDisplayWebview = true;
|
||||
netHandler.allowedDisplayWebviewYes = true;
|
||||
}
|
||||
mc.displayGuiScreen(cont);
|
||||
}else if (par1GuiButton.id == 1) {
|
||||
if(hasCheckedBox) {
|
||||
netHandler.allowedDisplayWebview = true;
|
||||
netHandler.allowedDisplayWebviewYes = false;
|
||||
}
|
||||
mc.displayGuiScreen(back);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int mx, int my, int btn) {
|
||||
if(btn == 0 && mouseOverCheck) {
|
||||
hasCheckedBox = !hasCheckedBox;
|
||||
mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
return;
|
||||
}
|
||||
super.mouseClicked(mx, my, btn);
|
||||
}
|
||||
|
||||
}
|
@ -26,6 +26,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.WebViewOptions;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.minecraft.GuiScreenGenericErrorMessage;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.server.SPacketDisplayWebViewURLV5EAG;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
@ -91,6 +92,54 @@ public class GuiScreenServerInfo extends GuiScreen {
|
||||
opts.fallbackTitle = PauseMenuCustomizeState.serverInfoEmbedTitle;
|
||||
}
|
||||
|
||||
public static GuiScreen createForDisplayRequest(GuiScreen parent, int perms, String title, String url) {
|
||||
URI urlObj;
|
||||
try {
|
||||
urlObj = new URI(url);
|
||||
}catch(URISyntaxException ex) {
|
||||
logger.error("Refusing to iframe an invalid URL: {}", url);
|
||||
logger.error(ex);
|
||||
return new GuiScreenGenericErrorMessage("webviewInvalidURL.title", "webviewInvalidURL.desc", parent);
|
||||
}
|
||||
return createForDisplayRequest(parent, perms, title, urlObj);
|
||||
}
|
||||
|
||||
public static GuiScreen createForDisplayRequest(GuiScreen parent, int perms, String title, URI url) {
|
||||
boolean support = WebViewOverlayController.supported();
|
||||
boolean fallbackSupport = WebViewOverlayController.fallbackSupported();
|
||||
if(!support && !fallbackSupport) {
|
||||
return new GuiScreenGenericErrorMessage("webviewNotSupported.title", "webviewNotSupported.desc", parent);
|
||||
}
|
||||
WebViewOptions opts = new WebViewOptions();
|
||||
opts.contentMode = EnumWebViewContentMode.URL_BASED;
|
||||
opts.url = url;
|
||||
setupState(opts, perms, title);
|
||||
opts.permissionsOriginUUID = WebViewOptions.getURLOriginUUID(url);
|
||||
return support ? new GuiScreenServerInfo(parent, opts) : new GuiScreenServerInfoDesktop(parent, opts);
|
||||
}
|
||||
|
||||
public static GuiScreen createForDisplayRequest(GuiScreen parent, int perms, String title, byte[] blob,
|
||||
EaglercraftUUID permissionsOriginUUID) {
|
||||
boolean support = WebViewOverlayController.supported();
|
||||
boolean fallbackSupport = WebViewOverlayController.fallbackSupported();
|
||||
if(!support && !fallbackSupport) {
|
||||
return new GuiScreenGenericErrorMessage("webviewNotSupported.title", "webviewNotSupported.desc", parent);
|
||||
}
|
||||
WebViewOptions opts = new WebViewOptions();
|
||||
opts.contentMode = EnumWebViewContentMode.BLOB_BASED;
|
||||
opts.blob = blob;
|
||||
setupState(opts, perms, title);
|
||||
opts.permissionsOriginUUID = permissionsOriginUUID;
|
||||
return support ? new GuiScreenServerInfo(parent, opts) : new GuiScreenServerInfoDesktop(parent, opts);
|
||||
}
|
||||
|
||||
public static void setupState(WebViewOptions opts, int perms, String title) {
|
||||
opts.scriptEnabled = (perms & SPacketDisplayWebViewURLV5EAG.FLAG_PERMS_JAVASCRIPT) != 0;
|
||||
opts.strictCSPEnable = (perms & SPacketDisplayWebViewURLV5EAG.FLAG_PERMS_STRICT_CSP) != 0;
|
||||
opts.serverMessageAPIEnabled = (perms & SPacketDisplayWebViewURLV5EAG.FLAG_PERMS_MESSAGE_API) != 0;
|
||||
opts.fallbackTitle = title;
|
||||
}
|
||||
|
||||
public void initGui() {
|
||||
ScaledResolution res = mc.scaledResolution;
|
||||
if(!isShowing) {
|
||||
@ -118,8 +167,7 @@ public class GuiScreenServerInfo extends GuiScreen {
|
||||
|
||||
public void drawScreen(int mx, int my, float pt) {
|
||||
drawDefaultBackground();
|
||||
drawCenteredString(fontRendererObj, PauseMenuCustomizeState.serverInfoEmbedTitle == null ? "Server Info"
|
||||
: PauseMenuCustomizeState.serverInfoEmbedTitle, width / 2, 13, 0xFFFFFF);
|
||||
drawCenteredString(fontRendererObj, opts.fallbackTitle == null ? "Server Info" : opts.fallbackTitle, width / 2, 13, 0xFFFFFF);
|
||||
super.drawScreen(mx, my, pt);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.webview;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.PauseMenuCustomizeState;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.WebViewOptions;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
@ -77,7 +76,8 @@ public class GuiScreenServerInfoDesktop extends GuiScreen {
|
||||
|
||||
public void drawScreen(int mx, int my, float pt) {
|
||||
drawDefaultBackground();
|
||||
drawCenteredString(fontRendererObj, PauseMenuCustomizeState.serverInfoEmbedTitle, this.width / 2, 70, 16777215);
|
||||
drawCenteredString(fontRendererObj, opts.fallbackTitle == null ? "Server Info" : opts.fallbackTitle,
|
||||
this.width / 2, 70, 16777215);
|
||||
drawCenteredString(fontRendererObj, I18n.format("fallbackWebViewScreen.text0"), this.width / 2, 90, 11184810);
|
||||
String link = WebViewOverlayController.fallbackRunning() ? WebViewOverlayController.getFallbackURL()
|
||||
: I18n.format(hasStarted ? "fallbackWebViewScreen.exited" : "fallbackWebViewScreen.startingUp");
|
||||
|
Reference in New Issue
Block a user