diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java b/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java
index 6408be3522..83e30cbfc7 100644
--- a/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java
+++ b/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java
@@ -48,6 +48,7 @@ public class RuneLiteProperties
private static final String JAV_CONFIG_BACKUP = "runelite.jav_config_backup";
private static final String PLUGINHUB_BASE = "runelite.pluginhub.url";
private static final String PLUGINHUB_VERSION = "runelite.pluginhub.version";
+ private static final String IMGUR_CLIENT_ID = "runelite.imgur.client.id";
private static final Properties properties = new Properties();
@@ -139,4 +140,9 @@ public class RuneLiteProperties
String version = System.getProperty(PLUGINHUB_VERSION, properties.getProperty(PLUGINHUB_VERSION));
return HttpUrl.parse(properties.get(PLUGINHUB_BASE) + "/" + version);
}
+
+ public static String getImgurClientId()
+ {
+ return properties.getProperty(IMGUR_CLIENT_ID);
+ }
}
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotConfig.java
index 2158de75e3..314af4ab07 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotConfig.java
@@ -28,6 +28,7 @@ import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Keybind;
+import net.runelite.client.util.ImageUploadStyle;
@ConfigGroup("screenshot")
public interface ScreenshotConfig extends Config
@@ -115,9 +116,9 @@ public interface ScreenshotConfig extends Config
description = "Configures whether or not screenshots are uploaded to Imgur, or placed on your clipboard",
position = 7
)
- default UploadStyle uploadScreenshot()
+ default ImageUploadStyle uploadScreenshot()
{
- return UploadStyle.NEITHER;
+ return ImageUploadStyle.NEITHER;
}
@ConfigItem(
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java
index 2867e4d9f6..e5bdce4414 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java
@@ -31,26 +31,14 @@ import com.google.inject.Provides;
import java.awt.Desktop;
import java.awt.Graphics;
import java.awt.Image;
-import java.awt.Toolkit;
-import java.awt.TrayIcon;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.StringSelection;
import java.awt.image.BufferedImage;
-import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
import java.time.LocalDate;
-import java.util.Date;
-import java.util.EnumSet;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.imageio.ImageIO;
import javax.inject.Inject;
import javax.swing.SwingUtilities;
import lombok.AccessLevel;
@@ -62,7 +50,6 @@ import net.runelite.api.GameState;
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.api.SpriteID;
-import net.runelite.api.WorldType;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.PlayerDeath;
@@ -86,24 +73,15 @@ import net.runelite.client.game.SpriteManager;
import net.runelite.client.input.KeyManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
-import net.runelite.client.plugins.screenshot.imgur.ImageUploadRequest;
-import net.runelite.client.plugins.screenshot.imgur.ImageUploadResponse;
import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.HotkeyListener;
+import net.runelite.client.util.ImageCapture;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.Text;
-import net.runelite.http.api.RuneLiteAPI;
-import okhttp3.Call;
-import okhttp3.Callback;
-import okhttp3.HttpUrl;
-import okhttp3.MediaType;
-import okhttp3.Request;
-import okhttp3.RequestBody;
-import okhttp3.Response;
@PluginDescriptor(
name = "Screenshot",
@@ -113,12 +91,6 @@ import okhttp3.Response;
@Slf4j
public class ScreenshotPlugin extends Plugin
{
- private static final String IMGUR_CLIENT_ID = "30d71e5f6860809";
- private static final HttpUrl IMGUR_IMAGE_UPLOAD_URL = HttpUrl.parse("https://api.imgur.com/3/image");
- private static final MediaType JSON = MediaType.parse("application/json");
-
- private static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
-
private static final Pattern NUMBER_PATTERN = Pattern.compile("([0-9]+)");
private static final Pattern LEVEL_UP_PATTERN = Pattern.compile(".*Your ([a-zA-Z]+) (?:level is|are)? now (\\d+)\\.");
private static final Pattern BOSSKILL_MESSAGE_PATTERN = Pattern.compile("Your (.+) kill count is:
(\\d+).");
@@ -129,14 +101,6 @@ public class ScreenshotPlugin extends Plugin
"You feel something weird sneaking into your backpack",
"You have a funny feeling like you would have been followed");
- static String format(Date date)
- {
- synchronized (TIME_FORMAT)
- {
- return TIME_FORMAT.format(date);
- }
- }
-
private String clueType;
private Integer clueNumber;
@@ -183,6 +147,9 @@ public class ScreenshotPlugin extends Plugin
@Inject
private SpriteManager spriteManager;
+ @Inject
+ private ImageCapture imageCapture;
+
@Getter(AccessLevel.PACKAGE)
private BufferedImage reportButton;
@@ -193,7 +160,7 @@ public class ScreenshotPlugin extends Plugin
@Override
public void hotkeyPressed()
{
- takeScreenshot(format(new Date()));
+ takeScreenshot("");
}
};
@@ -216,7 +183,7 @@ public class ScreenshotPlugin extends Plugin
.tab(false)
.tooltip("Take screenshot")
.icon(iconImage)
- .onClick(() -> takeScreenshot(format(new Date())))
+ .onClick(() -> takeScreenshot(""))
.popup(ImmutableMap
.builder()
.put("Open screenshot folder...", () ->
@@ -284,11 +251,11 @@ public class ScreenshotPlugin extends Plugin
Player player = playerDeath.getPlayer();
if (player == client.getLocalPlayer() && config.screenshotPlayerDeath())
{
- takeScreenshot("Death " + format(new Date()));
+ takeScreenshot("Death");
}
else if ((player.isClanMember() || player.isFriend()) && config.screenshotFriendDeath() && player.getCanvasTilePoly() != null)
{
- takeScreenshot("Death " + player.getName() + " " + format(new Date()));
+ takeScreenshot("Death " + player.getName());
}
}
@@ -299,7 +266,7 @@ public class ScreenshotPlugin extends Plugin
{
final Player player = playerLootReceived.getPlayer();
final String name = player.getName();
- String fileName = "Kill " + name + " " + format(new Date());
+ String fileName = "Kill " + name;
takeScreenshot(fileName);
}
}
@@ -367,7 +334,7 @@ public class ScreenshotPlugin extends Plugin
if (config.screenshotPet() && PET_MESSAGES.stream().anyMatch(chatMessage::contains))
{
- String fileName = "Pet " + format(new Date());
+ String fileName = "Pet";
takeScreenshot(fileName);
}
@@ -389,7 +356,7 @@ public class ScreenshotPlugin extends Plugin
if (m.matches())
{
String valuableDropName = m.group(1);
- String fileName = "Valuable drop " + valuableDropName + " " + format(new Date());
+ String fileName = "Valuable drop " + valuableDropName;
takeScreenshot(fileName);
}
}
@@ -400,7 +367,7 @@ public class ScreenshotPlugin extends Plugin
if (m.matches())
{
String untradeableDropName = m.group(1);
- String fileName = "Untradeable drop " + untradeableDropName + " " + format(new Date());
+ String fileName = "Untradeable drop " + untradeableDropName;
takeScreenshot(fileName);
}
}
@@ -615,120 +582,7 @@ public class ScreenshotPlugin extends Plugin
// Draw the game onto the screenshot
graphics.drawImage(image, gameOffsetX, gameOffsetY, null);
-
- File playerFolder;
- if (client.getLocalPlayer() != null && client.getLocalPlayer().getName() != null)
- {
- final EnumSet worldTypes = client.getWorldType();
-
- String playerDir = client.getLocalPlayer().getName();
- if (worldTypes.contains(WorldType.DEADMAN))
- {
- playerDir += "-Deadman";
- }
- else if (worldTypes.contains(WorldType.LEAGUE))
- {
- playerDir += "-League";
- }
- playerFolder = new File(SCREENSHOT_DIR, playerDir);
- }
- else
- {
- playerFolder = SCREENSHOT_DIR;
- }
-
- playerFolder.mkdirs();
-
- try
- {
- File screenshotFile = new File(playerFolder, fileName + ".png");
-
- // To make sure that screenshots don't get overwritten, check if file exists,
- // and if it does create file with same name and suffix.
- int i = 1;
- while (screenshotFile.exists())
- {
- screenshotFile = new File(playerFolder, fileName + String.format("(%d)", i++) + ".png");
- }
-
- ImageIO.write(screenshot, "PNG", screenshotFile);
- UploadStyle uploadStyle = config.uploadScreenshot();
-
- if (uploadStyle == UploadStyle.IMGUR)
- {
- uploadScreenshot(screenshotFile);
- }
- else if (uploadStyle == UploadStyle.CLIPBOARD)
- {
- Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- TransferableBufferedImage transferableBufferedImage = new TransferableBufferedImage(screenshot);
- clipboard.setContents(transferableBufferedImage, null);
-
- if (config.notifyWhenTaken())
- {
- notifier.notify("A screenshot was saved and inserted into your clipboard!", TrayIcon.MessageType.INFO);
- }
- }
- else if (config.notifyWhenTaken())
- {
- notifier.notify("A screenshot was saved to " + screenshotFile, TrayIcon.MessageType.INFO);
- }
- }
- catch (IOException ex)
- {
- log.warn("error writing screenshot", ex);
- }
- }
-
- /**
- * Uploads a screenshot to the Imgur image-hosting service,
- * and copies the image link to the clipboard.
- *
- * @param screenshotFile Image file to upload.
- * @throws IOException Thrown if the file cannot be read.
- */
- private void uploadScreenshot(File screenshotFile) throws IOException
- {
- String json = RuneLiteAPI.GSON.toJson(new ImageUploadRequest(screenshotFile));
-
- Request request = new Request.Builder()
- .url(IMGUR_IMAGE_UPLOAD_URL)
- .addHeader("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
- .post(RequestBody.create(JSON, json))
- .build();
-
- RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback()
- {
- @Override
- public void onFailure(Call call, IOException ex)
- {
- log.warn("error uploading screenshot", ex);
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException
- {
- try (InputStream in = response.body().byteStream())
- {
- ImageUploadResponse imageUploadResponse = RuneLiteAPI.GSON
- .fromJson(new InputStreamReader(in), ImageUploadResponse.class);
-
- if (imageUploadResponse.isSuccess())
- {
- String link = imageUploadResponse.getData().getLink();
-
- StringSelection selection = new StringSelection(link);
- Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- clipboard.setContents(selection, selection);
-
- if (config.notifyWhenTaken())
- {
- notifier.notify("A screenshot was uploaded and inserted into your clipboard!", TrayIcon.MessageType.INFO);
- }
- }
- }
- }
- });
+ imageCapture.takeScreenshot(screenshot, fileName, config.notifyWhenTaken(), config.uploadScreenshot());
}
@VisibleForTesting
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/imgur/ImageUploadRequest.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/imgur/ImageUploadRequest.java
deleted file mode 100644
index 28c8d4f2f3..0000000000
--- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/imgur/ImageUploadRequest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2018, Lotto
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 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 OWNER 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.runelite.client.plugins.screenshot.imgur;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.Base64;
-import lombok.Data;
-
-@Data
-public class ImageUploadRequest
-{
- private final String image;
- private final String type;
-
- public ImageUploadRequest(File imageFile) throws IOException
- {
- this.image = Base64.getEncoder().encodeToString(Files.readAllBytes(imageFile.toPath()));
- this.type = "base64";
- }
-}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/imgur/ImageUploadResponse.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/imgur/ImageUploadResponse.java
deleted file mode 100644
index 820ed2aded..0000000000
--- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/imgur/ImageUploadResponse.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2018, Lotto
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 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 OWNER 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.runelite.client.plugins.screenshot.imgur;
-
-import lombok.Data;
-
-@Data
-public class ImageUploadResponse
-{
- private Data data;
- private boolean success;
-
- @lombok.Data
- public static class Data
- {
- private String link;
- }
-}
diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java
new file mode 100644
index 0000000000..0331d6a50e
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2018, Lotto
+ * Copyright (c) 2019, Alexsuperfly
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 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 OWNER 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.runelite.client.util;
+
+import java.awt.Toolkit;
+import java.awt.TrayIcon;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Base64;
+import java.util.Date;
+import java.util.EnumSet;
+import javax.imageio.ImageIO;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import net.runelite.api.Client;
+import net.runelite.api.GameState;
+import net.runelite.api.WorldType;
+import net.runelite.client.Notifier;
+import static net.runelite.client.RuneLite.SCREENSHOT_DIR;
+import net.runelite.client.RuneLiteProperties;
+import net.runelite.http.api.RuneLiteAPI;
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.HttpUrl;
+import okhttp3.MediaType;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+@Slf4j
+@Singleton
+public class ImageCapture
+{
+ private static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
+ private static final HttpUrl IMGUR_IMAGE_UPLOAD_URL = HttpUrl.parse("https://api.imgur.com/3/image");
+ private static final MediaType JSON = MediaType.parse("application/json");
+
+ @Inject
+ private Client client;
+
+ @Inject
+ private Notifier notifier;
+
+ /**
+ * Saves a screenshot of the client window to the screenshot folder as a PNG,
+ * and optionally uploads it to an image-hosting service.
+ *
+ * @param screenshot BufferedImage to capture.
+ * @param fileName Filename to use, without file extension.
+ * @param notify Send a notification to the system tray when the image is captured.
+ * @param imageUploadStyle which method to use to upload the screenshot (Imgur or directly to clipboard).
+ */
+ public void takeScreenshot(BufferedImage screenshot, String fileName, boolean notify, ImageUploadStyle imageUploadStyle)
+ {
+ if (client.getGameState() == GameState.LOGIN_SCREEN)
+ {
+ // Prevent the screenshot from being captured
+ log.info("Login screenshot prevented");
+ return;
+ }
+
+ File playerFolder;
+ if (client.getLocalPlayer() != null && client.getLocalPlayer().getName() != null)
+ {
+ final EnumSet worldTypes = client.getWorldType();
+
+ String playerDir = client.getLocalPlayer().getName();
+ if (worldTypes.contains(WorldType.DEADMAN))
+ {
+ playerDir += "-Deadman";
+ }
+ else if (worldTypes.contains(WorldType.LEAGUE))
+ {
+ playerDir += "-League";
+ }
+ playerFolder = new File(SCREENSHOT_DIR, playerDir);
+ }
+ else
+ {
+ playerFolder = SCREENSHOT_DIR;
+ }
+
+ playerFolder.mkdirs();
+
+ fileName += " " + format(new Date());
+
+ try
+ {
+ File screenshotFile = new File(playerFolder, fileName + ".png");
+
+ // To make sure that screenshots don't get overwritten, check if file exists,
+ // and if it does create file with same name and suffix.
+ int i = 1;
+ while (screenshotFile.exists())
+ {
+ screenshotFile = new File(playerFolder, fileName + String.format("(%d)", i++) + ".png");
+ }
+
+ ImageIO.write(screenshot, "PNG", screenshotFile);
+
+ if (imageUploadStyle == ImageUploadStyle.IMGUR)
+ {
+ uploadScreenshot(screenshotFile, notify);
+ }
+ else if (imageUploadStyle == ImageUploadStyle.CLIPBOARD)
+ {
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ TransferableBufferedImage transferableBufferedImage = new TransferableBufferedImage(screenshot);
+ clipboard.setContents(transferableBufferedImage, null);
+
+ if (notify)
+ {
+ notifier.notify("A screenshot was saved and inserted into your clipboard!", TrayIcon.MessageType.INFO);
+ }
+ }
+ else if (notify)
+ {
+ notifier.notify("A screenshot was saved to " + screenshotFile, TrayIcon.MessageType.INFO);
+ }
+ }
+ catch (IOException ex)
+ {
+ log.warn("error writing screenshot", ex);
+ }
+ }
+
+ /**
+ * Uploads a screenshot to the Imgur image-hosting service,
+ * and copies the image link to the clipboard.
+ *
+ * @param screenshotFile Image file to upload.
+ * @throws IOException Thrown if the file cannot be read.
+ */
+ private void uploadScreenshot(File screenshotFile, boolean notify) throws IOException
+ {
+ String json = RuneLiteAPI.GSON.toJson(new ImageUploadRequest(screenshotFile));
+
+ Request request = new Request.Builder()
+ .url(IMGUR_IMAGE_UPLOAD_URL)
+ .addHeader("Authorization", "Client-ID " + RuneLiteProperties.getImgurClientId())
+ .post(RequestBody.create(JSON, json))
+ .build();
+
+ RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback()
+ {
+ @Override
+ public void onFailure(Call call, IOException ex)
+ {
+ log.warn("error uploading screenshot", ex);
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException
+ {
+ try (InputStream in = response.body().byteStream())
+ {
+ ImageUploadResponse imageUploadResponse = RuneLiteAPI.GSON
+ .fromJson(new InputStreamReader(in), ImageUploadResponse.class);
+
+ if (imageUploadResponse.isSuccess())
+ {
+ String link = imageUploadResponse.getData().getLink();
+
+ StringSelection selection = new StringSelection(link);
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ clipboard.setContents(selection, selection);
+
+ if (notify)
+ {
+ notifier.notify("A screenshot was uploaded and inserted into your clipboard!", TrayIcon.MessageType.INFO);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ private static String format(Date date)
+ {
+ synchronized (TIME_FORMAT)
+ {
+ return TIME_FORMAT.format(date);
+ }
+ }
+
+ @Data
+ private static class ImageUploadResponse
+ {
+ private Data data;
+ private boolean success;
+
+ @lombok.Data
+ private static class Data
+ {
+ private String link;
+ }
+ }
+
+ @Data
+ private static class ImageUploadRequest
+ {
+ private final String image;
+ private final String type;
+
+ ImageUploadRequest(File imageFile) throws IOException
+ {
+ this.image = Base64.getEncoder().encodeToString(Files.readAllBytes(imageFile.toPath()));
+ this.type = "base64";
+ }
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/UploadStyle.java b/runelite-client/src/main/java/net/runelite/client/util/ImageUploadStyle.java
similarity index 95%
rename from runelite-client/src/main/java/net/runelite/client/plugins/screenshot/UploadStyle.java
rename to runelite-client/src/main/java/net/runelite/client/util/ImageUploadStyle.java
index fd0594e7ba..95c75536a4 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/UploadStyle.java
+++ b/runelite-client/src/main/java/net/runelite/client/util/ImageUploadStyle.java
@@ -23,9 +23,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-package net.runelite.client.plugins.screenshot;
+package net.runelite.client.util;
-public enum UploadStyle
+public enum ImageUploadStyle
{
NEITHER,
IMGUR,
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/TransferableBufferedImage.java b/runelite-client/src/main/java/net/runelite/client/util/TransferableBufferedImage.java
similarity index 97%
rename from runelite-client/src/main/java/net/runelite/client/plugins/screenshot/TransferableBufferedImage.java
rename to runelite-client/src/main/java/net/runelite/client/util/TransferableBufferedImage.java
index 27b4ddd154..f87e52564b 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/TransferableBufferedImage.java
+++ b/runelite-client/src/main/java/net/runelite/client/util/TransferableBufferedImage.java
@@ -24,7 +24,7 @@
* 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.runelite.client.plugins.screenshot;
+package net.runelite.client.util;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
diff --git a/runelite-client/src/main/resources/net/runelite/client/runelite.properties b/runelite-client/src/main/resources/net/runelite/client/runelite.properties
index e6ad242cdf..801f0cc406 100644
--- a/runelite-client/src/main/resources/net/runelite/client/runelite.properties
+++ b/runelite-client/src/main/resources/net/runelite/client/runelite.properties
@@ -12,4 +12,5 @@ runelite.dnschange.link=https://1.1.1.1/dns/
runelite.jav_config=http://oldschool.runescape.com/jav_config.ws
runelite.jav_config_backup=http://static.runelite.net/jav_config.ws
runelite.pluginhub.url=https://repo.runelite.net/plugins
-runelite.pluginhub.version=${project.version}
\ No newline at end of file
+runelite.pluginhub.version=${project.version}
+runelite.imgur.client.id=30d71e5f6860809
\ No newline at end of file