diff --git a/src/main/java/dev/ptnr/AyayaBot.java b/src/main/java/dev/ptnr/AyayaBot.java index 6995fca..9932bda 100644 --- a/src/main/java/dev/ptnr/AyayaBot.java +++ b/src/main/java/dev/ptnr/AyayaBot.java @@ -72,12 +72,17 @@ class BotListener extends ListenerAdapter { public void hitomi(SlashCommandInteractionEvent event, Integer id) { event.reply("작품을 로드합니다. 조금 기다려주세요...").setEphemeral(true).queue(); + HitomiDTO hitomiData = Hitomi.GetHitomiData(id); + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle(hitomiData.getTitle()); + eb.appendDescription("`품번: " + hitomiData.getId() + "`\n"); + eb.appendDescription("`작가: " + hitomiData.getArtistsAsString() + "`\n"); + eb.appendDescription("`종류: " + hitomiData.getType() + "`\n"); + eb.appendDescription("`태그: " + hitomiData.getTagsAsString() + "`"); - eb.setTitle("품번 : " + id); - eb.setTimestamp(Instant.now()); - - byte[] webpData = AyayaUtils.GetFileFromUrl(Hitomi.GetHitomiData(id)); + String coverUrl = Hitomi.getImageUrl(hitomiData.getImageHashList().get(0)); + byte[] webpData = AyayaUtils.GetFileFromUrl(coverUrl); if (webpData == null) { event.getHook().editOriginal("URL에서 이미지를 가져오지 못했습니다. URL이나 서버 상태를 확인해주세요.").queue(); return; @@ -91,6 +96,7 @@ class BotListener extends ListenerAdapter { eb.setImage("attachment://" + "1.png"); eb.setFooter("Uploader : " + event.getUser().getName()); + eb.setTimestamp(Instant.now()); FileUpload fileUpload = FileUpload.fromData(pngData, "1.png"); event.getChannel().sendFiles(fileUpload).setEmbeds(eb.build()).queue(); diff --git a/src/main/java/dev/ptnr/Hitomi.java b/src/main/java/dev/ptnr/Hitomi.java index 63e2f0b..346854d 100644 --- a/src/main/java/dev/ptnr/Hitomi.java +++ b/src/main/java/dev/ptnr/Hitomi.java @@ -1,5 +1,6 @@ package dev.ptnr; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -12,32 +13,74 @@ public class Hitomi { private static final String cdnUrl = ".gold-usergeneratedcontent.net"; private static final String baseCDNUrl = "https://ltn" + cdnUrl; - private static ArrayList getGalleryData(Integer galleryId) { + private static HitomiDTO getGalleryData(Integer galleryId) { String baseUrl = baseCDNUrl + "/galleries/" + galleryId + ".js"; + String rawJson; + + JsonNode rootNode; + ArrayList imageHashList = new ArrayList<>(); + ArrayList artists = new ArrayList<>(); + ArrayList femaleTag = new ArrayList<>(); + ArrayList maleTag = new ArrayList<>(); + ArrayList normalTag = new ArrayList<>(); + Map> tags = new HashMap>(); 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 = ", ""); + + try { + rawJson = new String(rawData, "UTF-8").replace("var galleryinfo = ", ""); + } catch (UnsupportedEncodingException e) { + System.out.println("[ERR > Hitomi.GetGalleryData()] Failed to Convert JSON"); + return null; + } - ArrayList galleryData = new ArrayList<>(); try { ObjectMapper objectMapper = new ObjectMapper(); - JsonNode rootNode = objectMapper.readTree(rawJson); - JsonNode files = rootNode.get("files"); - - for (JsonNode node : files) { - String fileHash = node.get("hash").asText(); - - galleryData.add(fileHash); - } + rootNode = objectMapper.readTree(rawJson); } catch (Exception e) { System.out.println("[ERR > Hitomi.GetGalleryData()] Failed to Parse JSON\n" + e.getMessage()); return null; } + for (JsonNode node : rootNode.get("files")) { + String fileHash = node.get("hash").asText(); + + imageHashList.add(fileHash); + } + + for (JsonNode node : rootNode.get("tags")) { + String tag = node.get("tag").asText(); + + if (node.get("female") == null) { + normalTag.add(tag); + continue; + } + + if (node.get("female").asInt() == 1) femaleTag.add(tag); + if (node.get("male").asInt() == 1) maleTag.add(tag); + } + tags.put("female", femaleTag); + tags.put("male", maleTag); + tags.put("tag", normalTag); + + for (JsonNode node : rootNode.get("artists")) { + String artist = node.get("artist").asText(); + + artists.add(artist); + } + + HitomiDTO galleryData = new HitomiDTO(rootNode.get("title").asText(), + galleryId, + artists, + rootNode.get("type").asText(), + rootNode.get("language").asText(), + imageHashList, + tags); + return galleryData; } @@ -68,44 +111,45 @@ public class Hitomi { return new String(rawJs); } - 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, offsetDomainKey); - int domainOffset = defaultDomainKey; + public static String getImageUrl(String hash) { + String ggData = getGGJS(); + if (ggData == null) { + System.err.println("[ERR > Hitomi.GetHitomiData()] Failed to Get gg.js"); + return null; + } // ex) hash == 415e8c1bfbac7cb6192b6f7c14768c196dde9029233126ca5f108d6aa99818de // 8de to slice hash[-1:] / hash[-3:-1] (e / 8d) // -> s == hash[-1:] + hash[-3:-1] == "e8d" // s to parseInt(s, 16) == 3725 == ImageId int imageId = Integer.parseInt(hash.substring(hash.length() - 1) + hash.substring(hash.length() - 3, hash.length() - 1), 16); + + int defaultDomainKey = getIdFromGG("var o = (\\d)", ggData) + 1; + int offsetDomainKey = getIdFromGG("o = (\\d); break;", ggData) + 1; + int commonKey = getIdFromGG("b: '(\\d+)\\/'", ggData); + + Map Offsets = getOffsetsFromGG("case (\\d+):", ggData, offsetDomainKey); + + int domainOffset = defaultDomainKey; if (Offsets.containsKey(imageId)) domainOffset = offsetDomainKey; // domain number (a1, a2 / w1, w2..) // webp = w1, w2 / avif = a1, a2 - return "https://w" + domainOffset + cdnUrl + "/" + commonKey + "/" + imageId + "/" + hash + ".webp"; } - public static String GetHitomiData(Integer galleryId) { - ArrayList galleryData = getGalleryData(galleryId); + public static HitomiDTO GetHitomiData(Integer galleryId) { + HitomiDTO 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; - } + return galleryData; + } - ArrayList images = new ArrayList<>(); - - galleryData.forEach((hash) -> images.add(getImageUrl(GGJS, hash))); - - return images.get(0); + public static void main(String[] args) { + HitomiDTO test = GetHitomiData(3392566); + System.out.println(test.getTagsAsString()); } } diff --git a/src/main/java/dev/ptnr/HitomiDTO.java b/src/main/java/dev/ptnr/HitomiDTO.java new file mode 100644 index 0000000..dbb637d --- /dev/null +++ b/src/main/java/dev/ptnr/HitomiDTO.java @@ -0,0 +1,105 @@ +package dev.ptnr; + +import java.util.ArrayList; +import java.util.Map; + +public class HitomiDTO { + private String title; + private int id; + private ArrayList artists; + private String type; + private String language; + private ArrayList imageHashList; + private Map> tags; + + public HitomiDTO() {} + + public HitomiDTO(String title, int id, ArrayList artists, String type, String language, ArrayList imageHashList, Map> tags) { + this.title = title; + this.id = id; + this.artists = artists; + this.type = type; + this.language = language; + this.imageHashList = imageHashList; + this.tags = tags; + } + + public String getTagsAsString() { + String tags = ""; + if (!this.tags.get("female").isEmpty()) { + for (String tag : this.tags.get("female")) tags += "female:" + tag + ", "; + } + if (!this.tags.get("male").isEmpty()) { + for (String tag : this.tags.get("male")) tags += "male:" + tag + ", "; + } + if (!this.tags.get("tag").isEmpty()) { + for (String tag : this.tags.get("tag")) tags += "tag:" + tag + ", "; + } + + return tags.substring(0, tags.length() - 2); + } + + public String getArtistsAsString() { + String artists = ""; + if (this.artists.size() == 1) return this.artists.get(0); + + for (String artist : this.artists) artists += artist + ", "; + return artists.substring(0, artists.length() - 2); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public ArrayList getArtists() { + return artists; + } + + public void setArtists(ArrayList artists) { + this.artists = artists; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public ArrayList getImageHashList() { + return imageHashList; + } + + public void setImageHashList(ArrayList imageHashList) { + this.imageHashList = imageHashList; + } + + public Map> getTags() { + return tags; + } + + public void setTags(Map> tags) { + this.tags = tags; + } +}