diff --git a/pom.xml b/pom.xml
index 4dcac6d..8bb2cb6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,11 +47,6 @@
config
1.3.2
-
- com.jagrosh
- Vortex-Pro
- 0.2
-
diff --git a/src/main/java/com/jagrosh/vortex/Vortex.java b/src/main/java/com/jagrosh/vortex/Vortex.java
index 38591d1..c2d9b7e 100644
--- a/src/main/java/com/jagrosh/vortex/Vortex.java
+++ b/src/main/java/com/jagrosh/vortex/Vortex.java
@@ -22,8 +22,6 @@
import com.jagrosh.vortex.commands.tools.*;
import com.jagrosh.vortex.commands.owner.*;
import com.jagrosh.vortex.commands.settings.*;
-import java.nio.file.*;
-import java.util.List;
import java.util.concurrent.Executors;
import com.jagrosh.jdautilities.command.CommandClient;
import com.jagrosh.jdautilities.command.CommandClientBuilder;
@@ -84,10 +82,10 @@
config.getString("database.password"));
uploader = new TextUploader(this, config.getLong("uploader.guild"), config.getLong("uploader.category"));
modlog = new ModLogger(this);
- basiclog = new BasicLogger(this);
+ basiclog = new BasicLogger(this, config);
messages = new MessageCache();
logwebhook = new WebhookClientBuilder(config.getString("webhook-url")).build();
- automod = new AutoMod(this, config.getString("url-resolver.url"), config.getString("url-resolver.secret"));
+ automod = new AutoMod(this, config);
strikehandler = new StrikeHandler(this);
CommandClient client = new CommandClientBuilder()
.setPrefix(Constants.PREFIX)
diff --git a/src/main/java/com/jagrosh/vortex/automod/AutoMod.java b/src/main/java/com/jagrosh/vortex/automod/AutoMod.java
index ad1154c..ab5f8d7 100644
--- a/src/main/java/com/jagrosh/vortex/automod/AutoMod.java
+++ b/src/main/java/com/jagrosh/vortex/automod/AutoMod.java
@@ -20,9 +20,11 @@
import com.jagrosh.vortex.database.managers.AutomodManager;
import com.jagrosh.vortex.database.managers.AutomodManager.AutomodSettings;
import com.jagrosh.vortex.logging.MessageCache.CachedMessage;
-import com.jagrosh.vortex.pro.URLResolver;
+import com.jagrosh.vortex.logging.URLResolver;
+import com.jagrosh.vortex.logging.URLResolver.*;
import com.jagrosh.vortex.utils.FixedCache;
import com.jagrosh.vortex.utils.OtherUtil;
+import com.typesafe.config.Config;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
@@ -50,7 +52,6 @@
private static final Pattern INVITES = Pattern.compile("discord\\s?(?:(?:\\.|dot|\\(\\.\\)|\\(dot\\))\\s?gg|app\\s?\\.\\s?com\\s?\\/\\s?invite)\\s?\\/\\s?([A-Z0-9-]{2,18})",
Pattern.CASE_INSENSITIVE);
-
private static final Pattern REF = Pattern.compile("https?:\\/\\/\\S+(?:\\/ref\\/|[?]ref(?:errer|erral)?=)\\S+", Pattern.CASE_INSENSITIVE);
private static final Pattern BASE_URL = Pattern.compile("https?:\\/\\/(?:[^?&:\\/\\s]+\\.)?([^?&:\\/\\s]+\\.\\w+)(?:\\W|$)", Pattern.CASE_INSENSITIVE);
@@ -70,10 +71,10 @@
private final FixedCache spams = new FixedCache<>(3000);
private final HashMap latestGuildJoin = new HashMap<>();
- public AutoMod(Vortex vortex, String url, String secret)
+ public AutoMod(Vortex vortex, Config config)
{
this.vortex = vortex;
- urlResolver = new URLResolver(url, secret);
+ urlResolver = config.getBoolean("url-resolver.active") ? new ActiveURLResolver(config) : new DummyURLResolver();
loadCopypastas();
loadReferralDomains();
}
diff --git a/src/main/java/com/jagrosh/vortex/logging/AvatarSaver.java b/src/main/java/com/jagrosh/vortex/logging/AvatarSaver.java
new file mode 100644
index 0000000..f3aae14
--- /dev/null
+++ b/src/main/java/com/jagrosh/vortex/logging/AvatarSaver.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2018 John Grosh (john.a.grosh@gmail.com).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jagrosh.vortex.logging;
+
+import com.typesafe.config.Config;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import javax.imageio.ImageIO;
+import net.dv8tion.jda.core.entities.User;
+
+/**
+ *
+ * @author John Grosh (john.a.grosh@gmail.com)
+ */
+public class AvatarSaver
+{
+ private final static BufferedImage NOAVATAR = loadNoAvatar();
+
+ private final String userAgent;
+
+ public AvatarSaver(Config config)
+ {
+ userAgent = config.getString("avatar-saver.user-agent");
+ }
+
+ public byte[] makeAvatarImage(User user, String oldAvatarUrl, String oldAvatarId)
+ {
+ BufferedImage oldimg;
+ if(oldAvatarUrl==null)
+ oldimg = imageFromUrl(user.getDefaultAvatarUrl());
+ else
+ {
+ oldimg = imageFromId(user.getIdLong(), oldAvatarId);
+ if(oldimg==null)
+ oldimg = imageFromUrl(oldAvatarUrl);
+ }
+ if(oldimg==null)
+ oldimg = NOAVATAR;
+ BufferedImage newimg = imageFromUrl(user.getEffectiveAvatarUrl());
+ if(newimg == null)
+ newimg = NOAVATAR;
+ else if(user.getAvatarId()!=null)
+ saveImageWithId(newimg, user.getIdLong(), user.getAvatarId());
+ BufferedImage combo = new BufferedImage(256,128,BufferedImage.TYPE_INT_ARGB_PRE);
+ Graphics2D g2d = combo.createGraphics();
+ g2d.setColor(Color.BLACK);
+ if(oldimg!=null)
+ {
+ g2d.drawImage(oldimg, 0, 0, 128, 128, null);
+ }
+ if(newimg!=null)
+ {
+ g2d.drawImage(newimg, 128, 0, 128, 128, null);
+ }
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream())
+ {
+ ImageIO.write(combo, "png", baos );
+ baos.flush();
+ return baos.toByteArray();
+ }
+ catch(IOException ex)
+ {
+ return null;
+ }
+ finally
+ {
+ g2d.dispose();
+ }
+ }
+
+ public BufferedImage imageFromUrl(String url)
+ {
+ if(url==null)
+ return null;
+ try
+ {
+ URL u = new URL(url.replace(".gif", ".png"));
+ URLConnection urlConnection = u.openConnection();
+ urlConnection.setRequestProperty("user-agent", userAgent);
+ return ImageIO.read(urlConnection.getInputStream());
+ }
+ catch(IOException|IllegalArgumentException e)
+ {
+ return null;
+ }
+ }
+
+ private BufferedImage imageFromId(long id, String avyId)
+ {
+ try
+ {
+ return ImageIO.read(location(id, avyId));
+ }
+ catch(IOException ex)
+ {
+ return null;
+ }
+ }
+
+ private void saveImageWithId(BufferedImage img, long id, String avyId)
+ {
+ try
+ {
+ BufferedImage buf = new BufferedImage(64, 64, BufferedImage.TYPE_INT_RGB);
+ buf.getGraphics().drawImage(img, 0, 0, 64, 64, null);
+ ImageIO.write(buf, "jpg", location(id, avyId));
+ buf.getGraphics().dispose();
+ }
+ catch(IOException ex) {}
+ }
+
+ private File location(long id, String avyId)
+ {
+ String dir = "avatars" + File.separator;
+ long remainder = id;
+ for(int i=16; i>=0; i-=2)
+ {
+ dir += (remainder / (long)Math.pow(10, i)) + File.separator;
+ remainder %= (long)Math.pow(10, i);
+ File directory = new File(dir);
+ if(!directory.exists())
+ directory.mkdir();
+ }
+ return new File(dir + avyId + ".jpg");
+ }
+
+ private static BufferedImage loadNoAvatar()
+ {
+ try
+ {
+ return ImageIO.read(new File("images"+File.separator+"NoAvatar.png"));
+ }
+ catch(IOException ex)
+ {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/jagrosh/vortex/logging/BasicLogger.java b/src/main/java/com/jagrosh/vortex/logging/BasicLogger.java
index 5d9842f..a4b48c6 100644
--- a/src/main/java/com/jagrosh/vortex/logging/BasicLogger.java
+++ b/src/main/java/com/jagrosh/vortex/logging/BasicLogger.java
@@ -15,11 +15,11 @@
*/
package com.jagrosh.vortex.logging;
-import com.jagrosh.vortex.pro.AvatarUtil;
import com.jagrosh.vortex.Vortex;
import com.jagrosh.vortex.logging.MessageCache.CachedMessage;
import com.jagrosh.vortex.utils.FormatUtil;
import com.jagrosh.vortex.utils.LogUtil;
+import com.typesafe.config.Config;
import java.awt.Color;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
@@ -61,10 +61,12 @@
private final static String AVATAR = "\uD83D\uDDBC"; // 🖼
private final Vortex vortex;
+ private final AvatarSaver avatarSaver;
- public BasicLogger(Vortex vortex)
+ public BasicLogger(Vortex vortex, Config config)
{
this.vortex = vortex;
+ this.avatarSaver = new AvatarSaver(config);
}
private void log(OffsetDateTime now, TextChannel tc, String emote, String message, MessageEmbed embed)
@@ -300,7 +302,7 @@
OffsetDateTime now = OffsetDateTime.now();
vortex.getThreadpool().execute(() ->
{
- byte[] im = AvatarUtil.makeAvatarImage(event.getUser(), event.getOldAvatarUrl(), event.getOldAvatarId());
+ byte[] im = avatarSaver.makeAvatarImage(event.getUser(), event.getOldAvatarUrl(), event.getOldAvatarId());
if(im!=null)
logs.forEach(tc -> logFile(now, tc, AVATAR, FormatUtil.formatFullUser(event.getUser())+" has changed avatars"
+(event.getUser().getAvatarId()!=null && event.getUser().getAvatarId().startsWith("a_") ? " <:gif:314068430624129039>" : "")
diff --git a/src/main/java/com/jagrosh/vortex/logging/URLResolver.java b/src/main/java/com/jagrosh/vortex/logging/URLResolver.java
new file mode 100644
index 0000000..2fb2ad4
--- /dev/null
+++ b/src/main/java/com/jagrosh/vortex/logging/URLResolver.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2018 John Grosh (john.a.grosh@gmail.com).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jagrosh.vortex.logging;
+
+import com.jagrosh.vortex.utils.FixedCache;
+import com.jagrosh.vortex.utils.OtherUtil;
+import com.typesafe.config.Config;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import okhttp3.FormBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+
+/**
+ *
+ * @author John Grosh (john.a.grosh@gmail.com)
+ */
+public interface URLResolver
+{
+ public List findRedirects(String url);
+ public void loadSafeDomains();
+
+ public static class DummyURLResolver implements URLResolver
+ {
+ @Override
+ public List findRedirects(String url)
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ @Override
+ public void loadSafeDomains() {}
+ }
+
+ public static class ActiveURLResolver implements URLResolver
+ {
+ private final String prefix, suffix, form;
+ private final OkHttpClient client = new OkHttpClient.Builder().build();
+ private final Request.Builder request;
+
+ private final FixedCache> cache = new FixedCache<>(1000);
+
+ public ActiveURLResolver(Config config)
+ {
+ prefix = config.getString("url-resolver.prefix");
+ suffix = config.getString("url-resolver.suffix");
+ form = config.getString("url-resolver.form");
+ request = new Request.Builder().url(config.getString("url-resolver.url"))
+ .header("Content-Type", "application/x-www-form-urlencoded")
+ .header(config.getString("url-resolver.key"), config.getString("url-resolver.value"));
+ }
+
+ @Override
+ public synchronized List findRedirects(String url)
+ {
+ if(isSafeDomain(url))
+ return Collections.EMPTY_LIST;
+ if(cache.contains(url))
+ return cache.get(url);
+ try
+ {
+ List resolved = resolve(client
+ .newCall(request.post(new FormBody.Builder().add(form, url).build()).build())
+ .execute().body().string());
+ cache.put(url, resolved);
+ System.out.println("Link Resolving: "+url+" -> "+resolved);
+ return resolved;
+ }
+ catch(Exception ex)
+ {
+ return Collections.EMPTY_LIST;
+ }
+ }
+
+ private List resolve(String text)
+ {
+ List list = new LinkedList<>();
+ boolean skip = true; // first link is always the link we gave
+ for(int i=0; i