AWT is forbidden on 1.13+ (this includes BufferedImage)

Instead use NativeImage on 1.13+ via newly introduced Image class.
See Image docs for details.

Also fixes an issue with thumbnail taking on 1.13+: The original
ScreenshotHelper method is now async, luckily there's a sync
variant and as a bonus it directly returns a NativeImage so we can
skip having to read the screenshot from disk.
This commit is contained in:
Jonas Herzig
2019-06-30 11:11:02 +02:00
parent 732e1ab32e
commit 7241036e61
14 changed files with 132 additions and 134 deletions

View File

@@ -11,13 +11,12 @@ import com.replaymod.online.AuthenticationHash;
import com.replaymod.online.api.replay.ReplayModApiMethods;
import com.replaymod.online.api.replay.SearchQuery;
import com.replaymod.online.api.replay.holders.*;
import de.johni0702.minecraft.gui.versions.Image;
import net.minecraft.client.MinecraftClient;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import javax.imageio.ImageIO;
import javax.net.ssl.HttpsURLConnection;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
@@ -133,14 +132,14 @@ public class ApiClient {
return SimpleApiClient.invokeUrl(builder.toString());
}
public BufferedImage downloadThumbnail(int file) throws IOException {
public Image downloadThumbnail(int file) throws IOException {
QueryBuilder builder = new QueryBuilder(ReplayModApiMethods.get_thumbnail);
builder.put("id", file);
URL url = new URL(builder.toString());
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(SSL_SOCKET_FACTORY);
try (InputStream in = connection.getInputStream()) {
return ImageIO.read(in);
return Image.read(in);
}
}

View File

@@ -39,10 +39,10 @@ import de.johni0702.minecraft.gui.utils.Colors;
import de.johni0702.minecraft.gui.utils.Consumer;
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
import de.johni0702.minecraft.gui.versions.Image;
import org.apache.commons.lang3.StringUtils;
import net.minecraft.util.Formatting;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collections;
@@ -311,19 +311,9 @@ public class GuiReplayCenter extends GuiScreen {
if (Thread.interrupted()) return;
try {
// Make sure that to int[] conversion doesn't have to occur in main thread
final BufferedImage theThumb;
final Image theThumb;
if (fileInfo.hasThumbnail()) {
BufferedImage buf = apiClient.downloadThumbnail(fileInfo.getId());
// This is the same way minecraft calls this method, we cache the result and hand
// minecraft a BufferedImage with way simpler logic using the precomputed values
final int[] theIntArray = buf.getRGB(0, 0, buf.getWidth(), buf.getHeight(), null, 0, buf.getWidth());
theThumb = new BufferedImage(buf.getWidth(), buf.getHeight(), BufferedImage.TYPE_INT_ARGB) {
@Override
public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) {
System.arraycopy(theIntArray, 0, rgbArray, 0, theIntArray.length);
return null; // Minecraft doesn't use the return value
}
};
theThumb = apiClient.downloadThumbnail(fileInfo.getId());
} else {
theThumb = null;
}
@@ -412,7 +402,7 @@ public class GuiReplayCenter extends GuiScreen {
private final boolean downloaded;
private final boolean incompatible;
public GuiReplayEntry(FileInfo fileInfo, BufferedImage thumbImage, int sortId, boolean downloaded) {
public GuiReplayEntry(FileInfo fileInfo, Image thumbImage, int sortId, boolean downloaded) {
this.fileInfo = fileInfo;
this.sortId = sortId;
this.downloaded = downloaded;

View File

@@ -1,6 +1,5 @@
package com.replaymod.online.gui;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.replaymod.core.KeyBindingRegistry;
@@ -32,6 +31,7 @@ import de.johni0702.minecraft.gui.layout.VerticalLayout;
import de.johni0702.minecraft.gui.popup.AbstractGuiPopup;
import de.johni0702.minecraft.gui.popup.GuiYesNoPopup;
import de.johni0702.minecraft.gui.utils.Colors;
import de.johni0702.minecraft.gui.versions.Image;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.util.crash.CrashReport;
@@ -45,9 +45,10 @@ import org.apache.commons.lang3.StringUtils;
//#endif
import javax.annotation.Nullable;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -127,12 +128,24 @@ public class GuiUploadReplay extends GuiScreen {
this.uploader = new FileUploader(mod.getApiClient());
ReplayMetaData metaData;
Optional<BufferedImage> optThumbnail;
Optional<Image> optThumbnail;
// Read from replay file
try (ReplayFile replayFile = new ZipReplayFile(new ReplayStudio(), file)) {
metaData = replayFile.getMetaData();
optThumbnail = replayFile.getThumb();
// TODO add a getThumbBytes method to ReplayStudio
optThumbnail = Optional.ofNullable(replayFile.get("thumb").orNull()).flatMap(stream -> {
try (InputStream in = stream) {
int i = 7;
while (i > 0) {
i -= in.skip(i);
}
return Optional.of(Image.read(in));
} catch (IOException e) {
e.printStackTrace();
return Optional.empty();
}
});
} catch (IOException e) {
throw new CrashException(CrashReport.create(e, "Read replay file " + file.getName()));
}