diff --git a/src/main/java/dev/ptnr/AyayaBot.java b/src/main/java/dev/ptnr/AyayaBot.java index 8d8e5b0..ffaec62 100644 --- a/src/main/java/dev/ptnr/AyayaBot.java +++ b/src/main/java/dev/ptnr/AyayaBot.java @@ -5,7 +5,6 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.session.ReadyEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; @@ -30,7 +29,7 @@ public class AyayaBot { try { jda.awaitReady(); } catch (InterruptedException e) { - System.err.println("[ERR] In AyayaBot.main() > " + e.getMessage()); + System.err.println("[ERR > AyayaBot.main()] Failed to Init\n" + e.getMessage()); } } @@ -55,7 +54,6 @@ class BotListener extends ListenerAdapter { List guildList = jda.getGuilds(); for (Guild guild : guildList) { System.out.println("Contain Guild : " + guild.getName()); - // System.out.println("ID: " + guild.get); } System.out.println(jda.getSelfUser().getName() + " is Ready."); @@ -73,34 +71,30 @@ class BotListener extends ListenerAdapter { } public void hitomi(SlashCommandInteractionEvent event, Integer id) { + event.reply("작품을 로드합니다. 조금 기다려주세요...").setEphemeral(true).queue(); + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("품번 : " + id); eb.setTimestamp(Instant.now()); - // eb.setDescription("This image has been added to the bot."); - // eb.addBlankField(false); - byte[] webpData = AyayaUtils.GetFileFromUrl(Hitomi.GetHitomiData(id)); if (webpData == null) { - event.reply("URL에서 이미지를 가져오지 못했습니다. URL이나 서버 상태를 확인해주세요.") - .setEphemeral(true) - .queue(); + event.getHook().editOriginal("URL에서 이미지를 가져오지 못했습니다. URL이나 서버 상태를 확인해주세요.").queue(); return; } byte[] pngData = AyayaUtils.ConvertWebpToPng(webpData); if (pngData == null) { - event.reply("이미지를 PNG로 변환하는 데 실패했습니다. 파일이 올바른 WebP 형식이 아닐 수 있습니다.") - .setEphemeral(true).queue(); + event.getHook().editOriginal("이미지를 PNG로 변환하는 데 실패했습니다. 파일이 올바른 WebP 형식이 아닐 수 있습니다.").queue(); return; } eb.setImage("attachment://" + "1.png"); eb.setFooter("Uploader : " + event.getUser().getName()); - event.reply("작품을 로드합니다. 조금 기다려주세요...").setEphemeral(true).queue(); FileUpload fileUpload = FileUpload.fromData(pngData, "1.png"); event.getChannel().sendFiles(fileUpload).setEmbeds(eb.build()).queue(); - event.getHook().sendMessage("작품을 받아오는 데에 성공하였습니다!").setEphemeral(true).queue(); + event.getHook().editOriginal("작품을 받아오는 데에 성공하였습니다!").queue(); } } diff --git a/src/main/java/dev/ptnr/AyayaUtils.java b/src/main/java/dev/ptnr/AyayaUtils.java index 37641ac..49f6cef 100644 --- a/src/main/java/dev/ptnr/AyayaUtils.java +++ b/src/main/java/dev/ptnr/AyayaUtils.java @@ -30,7 +30,7 @@ public class AyayaUtils { return out.toByteArray(); } } catch (IOException e) { - e.printStackTrace(); + System.out.println("[ERR > AyayaUtils.GetFileFromUrl()] Failed to Get Data\n" + e.getMessage()); return null; } finally { if (conn != null) { @@ -47,7 +47,7 @@ public class AyayaUtils { ImageIO.write(image, "png", baos); return baos.toByteArray(); } catch (IOException e) { - e.printStackTrace(); + System.out.println("[ERR > AyayaUtils.ConvertWebpToPng()] Failed to Convert Webp\n" + e.getMessage()); return null; } } diff --git a/src/main/java/dev/ptnr/Hitomi.java b/src/main/java/dev/ptnr/Hitomi.java index 723fb86..5b9545f 100644 --- a/src/main/java/dev/ptnr/Hitomi.java +++ b/src/main/java/dev/ptnr/Hitomi.java @@ -2,134 +2,111 @@ package dev.ptnr; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.*; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; public class Hitomi { - private static String cdnUrl = ".gold-usergeneratedcontent.net"; - private static String baseCDNUrl = "https://ltn" + cdnUrl; - - private static Map getGalleryData(Integer galleryId) throws Exception { - Map galleryData = new LinkedHashMap<>(); + private static final String cdnUrl = ".gold-usergeneratedcontent.net"; + private static final String baseCDNUrl = "https://ltn" + cdnUrl; + private static ArrayList getGalleryData(Integer galleryId) { String baseUrl = baseCDNUrl + "/galleries/" + galleryId + ".js"; - String rawData = new String(AyayaUtils.GetFileFromUrl(baseUrl)); - if (rawData.length() == 3) { - throw new Exception("Failed to Get JS (code " + rawData + ")"); + byte[] rawData = AyayaUtils.GetFileFromUrl(baseUrl); + if (rawData == null) { + System.out.println("[ERR > Hitomi.GetGalleryData()] Failed to Get " + galleryId + ".js"); + return null; } + String rawJson = new String(rawData).replace("var galleryinfo = ", ""); - rawData = rawData.replace("var galleryinfo = ", ""); - - ObjectMapper objectMapper = new ObjectMapper(); - + ArrayList galleryData = new ArrayList<>(); try { - JsonNode rootNode = objectMapper.readTree(rawData); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode rootNode = objectMapper.readTree(rawJson); JsonNode files = rootNode.get("files"); for (JsonNode node : files) { String fileHash = node.get("hash").asText(); - Boolean hasAvif = node.get("hasavif").asBoolean(); + // Boolean hasAvif = node.get("hasavif").asBoolean(); - galleryData.put(fileHash, hasAvif); + galleryData.add(fileHash); } - } catch (JsonProcessingException e) { - System.out.println("[ERR] In Hitomi.getGalleryData() > " + e.getMessage()); - throw e; + } catch (Exception e) { + System.out.println("[ERR > Hitomi.GetGalleryData()] Failed to Parse JSON\n" + e.getMessage()); + return null; } return galleryData; } - private static String getIdFromGG(String regex, String data) { + private static Integer getIdFromGG(String regex, String data) { Matcher matcher = Pattern.compile(regex).matcher(data); - String regexData = ""; + int regexData; matcher.find(); - regexData = matcher.group(1); + regexData = Integer.parseInt(matcher.group(1)); return regexData; } - private static Map getOffsetsFromGG(String regex, String data, Integer key) { + private static Map getOffsetsFromGG(String regex, String data, Integer key) { Matcher matcher = Pattern.compile(regex).matcher(data); - Map offsets = new HashMap<>(); + Map offsets = new HashMap<>(); while (matcher.find()) { - offsets.put(matcher.group(1), key); + offsets.put(Integer.parseInt(matcher.group(1)), key); } return offsets; } private static String getGGJS() { String baseUrl = baseCDNUrl + "/gg.js"; - - try { - return new String(AyayaUtils.GetFileFromUrl(baseUrl)); - } catch (Exception e) { - System.out.println("[ERR] In Hitomi.GetGGJS() > " + e.getMessage()); - return ""; + byte[] rawJs = AyayaUtils.GetFileFromUrl(baseUrl); + if (rawJs == null) { + System.out.println("[ERR > Hitomi.GetGGJS()] Failed to Get gg.js"); + return null; } + return new String(rawJs); } - private static String getImageUrl(String rawGG, String hash, Boolean hasAvif) { - String DefaultSubdomainKey = getIdFromGG("var o = (\\d)", rawGG); - String SubdomainKey = getIdFromGG("o = (\\d); break;", rawGG); - String CommonImagePath = getIdFromGG("b: '(.+)'", rawGG); + private static String getImageUrl(String rawGG, String hash) { + int defaultDomainKey = getIdFromGG("var o = (\\d)", rawGG) + 1; + int offsetDomainKey = getIdFromGG("o = (\\d); break;", rawGG) + 1; + int commonKey = getIdFromGG("b: '(\\d+)\\/'", rawGG); - Map Offsets = getOffsetsFromGG("case (\\d+):", rawGG, Integer.parseInt(SubdomainKey)); - - String ImageUrl = ""; - Integer SubdomainOffset = Integer.parseInt(DefaultSubdomainKey) + 1; + Map Offsets = getOffsetsFromGG("case (\\d+):", rawGG, offsetDomainKey); + int domainOffset = defaultDomainKey; // ex) hash == 415e8c1bfbac7cb6192b6f7c14768c196dde9029233126ca5f108d6aa99818de // 8de to slice hash[-1:] / hash[-3:-1] (e / 8d) // -> s == hash[-1:] + hash[-3:-1] == "e8d" - String SubKey = hash.substring(hash.length() - 1, hash.length()) + hash.substring(hash.length() - 3, hash.length() - 1); - // s to parseInt(s, 16) == 3725 == ImageId - Integer ImageId = Integer.parseInt(SubKey, 16); + int imageId = Integer.parseInt(hash.substring(hash.length() - 1) + hash.substring(hash.length() - 3, hash.length() - 1), 16); + if (Offsets.containsKey(imageId)) domainOffset = offsetDomainKey; - if (Offsets.containsKey(ImageId.toString())) SubdomainOffset = Integer.parseInt(SubdomainKey) + 1; - - // a{key}.gold-usergeneratedcontent.net/1749488401/3725/415e8c1bfbac7cb6192b6f7c14768c196dde9029233126ca5f108d6aa99818de.avif // domain number (a1, a2 / w1, w2..) // webp = w1, w2 / avif = a1, a2 - // in gg.js case -> o(SubdomainKey) + 1 == 1, out of ggjs case -> o(DefaultSubdomainKey) + 1 == 2 - // hasavif flag 1 -> a1, a2 / flag 0 -> w1, w2 - // if (hasAvif) ImageUrl = "https://a" + SubdomainOffset + cdnUrl + "/" + CommonImagePath + ImageId + "/" + hash + ".avif"; - // else ImageUrl = "https://w" + SubdomainOffset + cdnUrl + "/" + CommonImagePath + ImageId + "/" + hash + ".webp"; - ImageUrl = "https://w" + SubdomainOffset + cdnUrl + "/" + CommonImagePath + ImageId + "/" + hash + ".webp"; - - // System.out.println("ImageUrl: " + ImageUrl); - - return ImageUrl; + return "https://w" + domainOffset + cdnUrl + "/" + commonKey + "/" + imageId + "/" + hash + ".webp"; } public static String GetHitomiData(Integer galleryId) { - Map galleryData = new LinkedHashMap<>(); - ArrayList images = new ArrayList<>(); - - try { - galleryData = getGalleryData(galleryId); - } catch (Exception e) { - System.err.println("In Hitomi.main() > " + e.getMessage()); - return ""; + ArrayList galleryData = getGalleryData(galleryId); + if (galleryData == null) { + System.err.println("[ERR > Hitomi.GetHitomiData()] Failed to Get Gallery Data"); + return null; } String GGJS = getGGJS(); + if (GGJS == null) { + System.err.println("[ERR > Hitomi.GetHitomiData()] Failed to Get gg.js"); + return null; + } - galleryData.forEach((hash, hasAvif) -> { - images.add(getImageUrl(GGJS, hash, hasAvif)); - }); + ArrayList images = new ArrayList<>(); + + galleryData.forEach((hash) -> images.add(getImageUrl(GGJS, hash))); return images.get(0); } - - public static void main(String[] args) { - // GetHitomiData(3390541); - } }