From f022c31f3d336dd7aa0aab1d3d9530ea75c81102 Mon Sep 17 00:00:00 2001 From: brenoepics <59066707+brenoepics@users.noreply.github.com> Date: Mon, 21 Feb 2022 17:49:03 -0300 Subject: [PATCH 1/4] Update ModToolManager.java --- .../java/com/eu/habbo/habbohotel/modtool/ModToolManager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java b/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java index 2a65ba4a..3b8e5b3b 100644 --- a/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java @@ -184,8 +184,6 @@ public class ModToolManager { public void quickTicket(Habbo reported, String reason, String message) { ModToolIssue issue = new ModToolIssue(0, reason, reported.getHabboInfo().getId(), reported.getHabboInfo().getUsername(), 0, message, ModToolTicketType.AUTOMATIC); - if (Emulator.getPluginManager().fireEvent(new SupportTicketEvent(null, issue)).isCancelled()) - return; Emulator.getGameEnvironment().getModToolManager().addTicket(issue); Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); From c865bb23829bceb24dae27265e3dd3a1b209b728 Mon Sep 17 00:00:00 2001 From: skeletor Date: Wed, 2 Mar 2022 21:44:53 +0000 Subject: [PATCH 2/4] Addresses #889: update mysql connector --- pom.xml | 2 +- src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 50967e7b..4cfb2d74 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ mysql mysql-connector-java - 5.1.49 + 8.0.22 runtime diff --git a/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java b/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java index 603e9b9e..144dd93f 100644 --- a/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java +++ b/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java @@ -257,7 +257,7 @@ public class HabboStats implements Runnable { try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_settings WHERE user_id = ? LIMIT 1")) { statement.setInt(1, habboInfo.getId()); try (ResultSet set = statement.executeQuery()) { - set.first(); + set.next(); if (set.getRow() != 0) { stats = new HabboStats(set, habboInfo); } else { From 662befaeb33803f30c05c90b6d5b616e7f543739 Mon Sep 17 00:00:00 2001 From: brenoepic Date: Wed, 2 Mar 2022 22:13:56 +0000 Subject: [PATCH 3/4] Fix YoutubeTV --- sqlupdates/3_0_0 to 3_0_1.sql | 3 + .../habbohotel/items/YoutubeManager.java | 153 ++++++++++++------ .../youtube/YoutubeRequestStateChange.java | 6 +- 3 files changed, 110 insertions(+), 52 deletions(-) diff --git a/sqlupdates/3_0_0 to 3_0_1.sql b/sqlupdates/3_0_0 to 3_0_1.sql index 4a1d34e7..9cbec636 100644 --- a/sqlupdates/3_0_0 to 3_0_1.sql +++ b/sqlupdates/3_0_0 to 3_0_1.sql @@ -5,3 +5,6 @@ INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.error.cmd_stalk. -- Enable or Disable TTY in console (Default is enabled) INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('console.mode', '1'); + +-- Youtube Api v3 key to YoutubeManager +INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('youtube.apikey', ''); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java b/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java index 3be71726..a383541a 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java @@ -11,10 +11,12 @@ import org.slf4j.LoggerFactory; import javax.net.ssl.HttpsURLConnection; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.sql.*; +import java.time.Duration; import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -23,7 +25,7 @@ import java.util.concurrent.TimeUnit; public class YoutubeManager { private static final Logger LOGGER = LoggerFactory.getLogger(YoutubeManager.class); - public class YoutubeVideo { + public static class YoutubeVideo { private final String id; private final int duration; @@ -41,7 +43,7 @@ public class YoutubeManager { } } - public class YoutubePlaylist { + public static class YoutubePlaylist { private final String id; private final String name; private final String description; @@ -71,8 +73,9 @@ public class YoutubeManager { } } - private THashMap> playlists = new THashMap<>(); - private THashMap playlistCache = new THashMap<>(); + private final THashMap> playlists = new THashMap<>(); + private final THashMap playlistCache = new THashMap<>(); + private final String apiKey = Emulator.getConfig().getValue("youtube.apikey"); public void load() { this.playlists.clear(); @@ -94,11 +97,15 @@ public class YoutubeManager { youtubeDataLoaderPool.submit(() -> { ArrayList playlists = this.playlists.getOrDefault(itemId, new ArrayList<>()); - YoutubePlaylist playlist = this.getPlaylistDataById(playlistId); - if (playlist != null) { - playlists.add(playlist); - } else { - LOGGER.error("Failed to load YouTube playlist: " + playlistId); + YoutubePlaylist playlist; + + try { + playlist = this.getPlaylistDataById(playlistId); + if (playlist != null) { + playlists.add(playlist); + } + } catch (IOException e) { + LOGGER.error("Failed to load YouTube playlist {} ERROR: {}", playlistId, e); } this.playlists.put(itemId, playlists); @@ -120,56 +127,102 @@ public class YoutubeManager { }); } - public YoutubePlaylist getPlaylistDataById(String playlistId) { + public YoutubePlaylist getPlaylistDataById(String playlistId) throws IOException { if (this.playlistCache.containsKey(playlistId)) return this.playlistCache.get(playlistId); + if(apiKey.isEmpty()) return null; - try { - URL myUrl = new URL("https://www.youtube.com/playlist?list=" + playlistId); + YoutubePlaylist playlist; + URL playlistInfo = new URL("https://youtube.googleapis.com/youtube/v3/playlists?part=snippet&id=" + playlistId + "&maxResults=1&key=" + apiKey); + HttpsURLConnection playlistCon = (HttpsURLConnection) playlistInfo.openConnection(); + if (playlistCon.getResponseCode() != 200) { + InputStream errorInputStream = playlistCon.getErrorStream(); + InputStreamReader playlistISR = new InputStreamReader(errorInputStream); + BufferedReader playlistBR = new BufferedReader(playlistISR); + JsonObject errorObj = JsonParser.parseReader(playlistBR).getAsJsonObject(); + String message = errorObj.get("error").getAsJsonObject().get("message").getAsString(); + LOGGER.error("Failed to load YouTube playlist {} ERROR: {}", playlistId, message); + return null; + } + InputStream playlistInputStream = playlistCon.getInputStream(); + InputStreamReader playlistISR = new InputStreamReader(playlistInputStream); + BufferedReader playlistBR = new BufferedReader(playlistISR); - HttpsURLConnection conn = (HttpsURLConnection) myUrl.openConnection(); - conn.setRequestProperty("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"); - conn.setRequestProperty("accept-language", "en-GB,en-US;q=0.9,en;q=0.8"); - conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3731.0 Safari/537.36"); + JsonObject playlistData = JsonParser.parseReader(playlistBR).getAsJsonObject(); - InputStream is = conn.getInputStream(); - InputStreamReader isr = new InputStreamReader(is); - YoutubePlaylist playlist; - try (BufferedReader br = new BufferedReader(isr)) { - playlist = null; - String inputLine; - while ((inputLine = br.readLine()) != null) { - if (inputLine.contains("window[\"ytInitialData\"]")) { - JsonObject obj = new JsonParser().parse(inputLine.substring(inputLine.indexOf("{")).replace(";", "")).getAsJsonObject(); - - JsonObject meta = obj.get("microformat").getAsJsonObject().get("microformatDataRenderer").getAsJsonObject(); - String name = meta.get("title").getAsString(); - String description = meta.get("description").getAsString(); - - ArrayList videos = new ArrayList<>(); - - JsonArray rawVideos = obj.get("contents").getAsJsonObject().get("twoColumnBrowseResultsRenderer").getAsJsonObject().get("tabs").getAsJsonArray().get(0).getAsJsonObject().get("tabRenderer").getAsJsonObject().get("content").getAsJsonObject().get("sectionListRenderer").getAsJsonObject().get("contents").getAsJsonArray().get(0).getAsJsonObject().get("itemSectionRenderer").getAsJsonObject().get("contents").getAsJsonArray().get(0).getAsJsonObject().get("playlistVideoListRenderer").getAsJsonObject().get("contents").getAsJsonArray(); - - for (JsonElement rawVideo : rawVideos) { - JsonObject videoData = rawVideo.getAsJsonObject().get("playlistVideoRenderer").getAsJsonObject(); - if (!videoData.has("lengthSeconds")) continue; // removed videos - videos.add(new YoutubeVideo(videoData.get("videoId").getAsString(), Integer.valueOf(videoData.get("lengthSeconds").getAsString()))); - } - - playlist = new YoutubePlaylist(playlistId, name, description, videos); - - break; - } - } + JsonArray playlists = playlistData.get("items").getAsJsonArray(); + if (playlists.size() == 0) { + LOGGER.error("Playlist {} not found!", playlistId); + return null; + } + JsonObject playlistItem = playlists.get(0).getAsJsonObject().get("snippet").getAsJsonObject(); + + String name = playlistItem.get("title").getAsString(); + String description = playlistItem.get("description").getAsString(); + + ArrayList < YoutubeVideo > videos = new ArrayList < > (); + String nextPageToken = ""; + do { + ArrayList < String > videoIds = new ArrayList < > (); + URL playlistItems; + + if (nextPageToken.isEmpty()) { + playlistItems = new URL("https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet%2Cstatus&playlistId=" + playlistId + "&maxResults=50&key=" + apiKey); + } else { + playlistItems = new URL("https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet%2Cstatus&playlistId=" + playlistId + "&pageToken=" + nextPageToken + "&maxResults=50&key=" + apiKey); } - this.playlistCache.put(playlistId, playlist); + HttpsURLConnection con = (HttpsURLConnection) playlistItems.openConnection(); - return playlist; - } catch (java.io.IOException e) { - e.printStackTrace(); + InputStream is = con.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + JsonObject object = JsonParser.parseReader(br).getAsJsonObject(); + + JsonArray rawV = object.get("items").getAsJsonArray(); + for (JsonElement rawVideo: rawV) { + JsonObject videoData = rawVideo.getAsJsonObject().get("snippet").getAsJsonObject(); + JsonObject videoStatus = rawVideo.getAsJsonObject().get("status").getAsJsonObject(); + if (!videoStatus.get("privacyStatus").getAsString().equals("public")) + continue; // removed videos + videoIds.add(videoData.get("resourceId").getAsJsonObject().get("videoId").getAsString()); + } + + if (!videoIds.isEmpty()) { + URL VideoItems; + + String commaSeparatedVideos = String.join(",", videoIds); + + VideoItems = new URL("https://youtube.googleapis.com/youtube/v3/videos?part=contentDetails&id=" + commaSeparatedVideos + "&maxResults=50&key=" + apiKey); + HttpsURLConnection con1 = (HttpsURLConnection) VideoItems.openConnection(); + InputStream is1 = con1.getInputStream(); + InputStreamReader isr1 = new InputStreamReader(is1); + BufferedReader br1 = new BufferedReader(isr1); + JsonObject object1 = JsonParser.parseReader(br1).getAsJsonObject(); + JsonArray Vds = object1.get("items").getAsJsonArray(); + for (JsonElement rawVideo: Vds) { + JsonObject contentDetails = rawVideo.getAsJsonObject().get("contentDetails").getAsJsonObject(); + int duration = (int) Duration.parse(contentDetails.get("duration").getAsString()).getSeconds(); + if (duration < 1) continue; + videos.add(new YoutubeVideo(rawVideo.getAsJsonObject().get("id").getAsString(), duration)); + } + } + if (object.has("nextPageToken")) { + nextPageToken = object.get("nextPageToken").getAsString(); + } else { + nextPageToken = null; + } + } while (nextPageToken != null); + + if (videos.isEmpty()) { + LOGGER.warn("Playlist {} has no videos!", playlistId); + return null; } + playlist = new YoutubePlaylist(playlistId, name, description, videos); + + this.playlistCache.put(playlistId, playlist); + + return playlist; - return null; } public ArrayList getPlaylistsForItemId(int itemId) { diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java index f212e698..b9010e5a 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java +++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java @@ -64,10 +64,12 @@ public class YoutubeRequestStateChange extends MessageHandler { HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); - if (item == null || !(item instanceof InteractionYoutubeTV)) return; + if (!(item instanceof InteractionYoutubeTV)) return; InteractionYoutubeTV tv = (InteractionYoutubeTV) item; + if(tv.currentPlaylist == null || tv.currentPlaylist.getVideos().isEmpty()) return; + switch (state) { case PAUSE: tv.playing = false; @@ -104,4 +106,4 @@ public class YoutubeRequestStateChange extends MessageHandler { room.updateItem(tv); } } -} \ No newline at end of file +} From 3b8caee5de97f5961622dab9fd21fb23bae7be08 Mon Sep 17 00:00:00 2001 From: Snaiker Date: Wed, 2 Mar 2022 22:20:16 +0000 Subject: [PATCH 4/4] Cleanup redeem voucher --- .../habbohotel/catalog/CatalogManager.java | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java index 5058b78c..6eb01a77 100644 --- a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java @@ -523,7 +523,6 @@ public class CatalogManager { return null; } - public Voucher getVoucher(String code) { synchronized (this.vouchers) { for (Voucher voucher : this.vouchers) { @@ -535,22 +534,20 @@ public class CatalogManager { return null; } - public void redeemVoucher(GameClient client, String voucherCode) { - Voucher voucher = Emulator.getGameEnvironment().getCatalogManager().getVoucher(voucherCode); + Habbo habbo = client.getHabbo(); + if (habbo == null) + return; + Voucher voucher = Emulator.getGameEnvironment().getCatalogManager().getVoucher(voucherCode); if (voucher == null) { client.sendResponse(new RedeemVoucherErrorComposer(RedeemVoucherErrorComposer.INVALID_CODE)); return; } - Habbo habbo = client.getHabbo(); - if (habbo == null) return; - if (voucher.isExhausted()) { - if (!Emulator.getGameEnvironment().getCatalogManager().deleteVoucher(voucher)) { - client.sendResponse(new RedeemVoucherErrorComposer(RedeemVoucherErrorComposer.TECHNICAL_ERROR)); - } + client.sendResponse(new RedeemVoucherErrorComposer(Emulator.getGameEnvironment().getCatalogManager().deleteVoucher(voucher) ? RedeemVoucherErrorComposer.INVALID_CODE : RedeemVoucherErrorComposer.TECHNICAL_ERROR)); + return; } if (voucher.hasUserExhausted(habbo.getHabboInfo().getId())) { @@ -560,12 +557,6 @@ public class CatalogManager { voucher.addHistoryEntry(habbo.getHabboInfo().getId()); - if (voucher.isExhausted()) { - if (!Emulator.getGameEnvironment().getCatalogManager().deleteVoucher(voucher)) { - client.sendResponse(new RedeemVoucherErrorComposer(RedeemVoucherErrorComposer.TECHNICAL_ERROR)); - } - } - if (voucher.points > 0) { client.getHabbo().getHabboInfo().addCurrencyAmount(voucher.pointsType, voucher.points); client.sendResponse(new UserPointsComposer(client.getHabbo().getHabboInfo().getCurrencyAmount(voucher.pointsType), voucher.points, voucher.pointsType)); @@ -578,7 +569,6 @@ public class CatalogManager { if (voucher.catalogItemId > 0) { CatalogItem item = this.getCatalogItem(voucher.catalogItemId); - if (item != null) { this.purchaseItem(null, item, client.getHabbo(), 1, "", true); } @@ -587,7 +577,6 @@ public class CatalogManager { client.sendResponse(new RedeemVoucherOKComposer()); } - public boolean deleteVoucher(Voucher voucher) { try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM vouchers WHERE code = ?")) { statement.setString(1, voucher.code);