Make YTTVs work properly

This commit is contained in:
Alejandro 2019-06-10 18:47:39 +03:00
parent b2d18e7486
commit f5a43cf451
15 changed files with 513 additions and 155 deletions

View File

@ -23,3 +23,49 @@ ADD COLUMN `can_swim` enum('1','0') NULL DEFAULT '0' AFTER `random_actions`;
UPDATE `pet_actions` SET `can_swim` = '1' WHERE `pet_type` = 9 OR `pet_type` = 14 OR `pet_type` = 23 OR `pet_type` = 24 OR `pet_type` = 25 OR `pet_type` = 28 OR `pet_type` = 29 OR `pet_type` = 30 OR `pet_type` = 32; UPDATE `pet_actions` SET `can_swim` = '1' WHERE `pet_type` = 9 OR `pet_type` = 14 OR `pet_type` = 23 OR `pet_type` = 24 OR `pet_type` = 25 OR `pet_type` = 28 OR `pet_type` = 29 OR `pet_type` = 30 OR `pet_type` = 32;
UPDATE `items_base` SET `customparams` = '30,60,120,180,300,600', `interaction_type` = 'game_timer', `interaction_modes_count` = 1 WHERE `item_name` IN ('fball_counter','bb_counter','es_counter'); UPDATE `items_base` SET `customparams` = '30,60,120,180,300,600', `interaction_type` = 'game_timer', `interaction_modes_count` = 1 WHERE `item_name` IN ('fball_counter','bb_counter','es_counter');
ALTER TABLE `youtube_playlists`
DROP COLUMN `order`,
CHANGE COLUMN `video_id` `playlist_id` varchar(255) NOT NULL COMMENT 'YouTube playlist ID' AFTER `item_id`;
DROP TABLE `youtube_items`;
TRUNCATE TABLE `youtube_playlists`;
DROP PROCEDURE IF EXISTS DEFAULT_YTTV_PLAYLISTS;
DELIMITER ;;
CREATE PROCEDURE DEFAULT_YTTV_PLAYLISTS()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE a INT DEFAULT 0;
DECLARE itemId INT default 0;
SELECT COUNT(*) FROM `items_base` WHERE `interaction_type` = 'youtube' INTO n;
SET i=0;
SET @defaultPlaylistIds = '["PL4YfV2mXS8WXOkxFly7YsGL8cKtqp873p","PL4F5KzcUTpEdux38c8CYunT9uNh_k2NPt","PL4F5KzcUTpEcO-1iw3P6gavJ_ALTxqNHn","PL4F5KzcUTpEfpHad_B7j_MulB3-cwtLFh","PL4F5KzcUTpEekJPbcVOaNYVV6VLSo9zRB","PL80F08DAE1B614BA9","PL4F5KzcUTpEfeS5t7EiEIYbpplZivDZTL","PL4ACB18CA629E650A","PL4F5KzcUTpEfyRBCOVKQ4qxlSoHsGDZ82","PL4F5KzcUTpEet7EMwhw0ge5n2oNMr7JY8","PL4F5KzcUTpEfTW4fkX9vrt497MEvWorwK","PL4F5KzcUTpEcit3i1q55-IFFndmo_dsR8","PL4F5KzcUTpEeJleVUhO1MWRJyYDWWp9Do","PL4F5KzcUTpEcFzCpH2_EXtwzKQH8mJGd9","PL4F5KzcUTpEcIiSOH2x3sg2jwACNbSIm9","PL4F5KzcUTpEfRxBiXwTBA7oiybPqoZD_j","PL4YfV2mXS8WUo09aevZX-b47k4PD08-i8","PL4F5KzcUTpEcFzCpH2_EXtwzKQH8mJGd9"]';
WHILE i < n DO
SET itemId = (SELECT id FROM `items_base` WHERE `interaction_type` = 'youtube' LIMIT i, 1);
WHILE a<JSON_LENGTH(@defaultPlaylistIds) DO
INSERT IGNORE INTO `youtube_playlists` (item_id, playlist_id) VALUES (itemId, TRIM(BOTH '"' FROM JSON_EXTRACT(@defaultPlaylistIds, CONCAT('$[',a,']'))));
SET a = a + 1;
END WHILE;
SET a = 0;
SET i = i + 1;
END WHILE;
END;
;;
DELIMITER ;
CALL DEFAULT_YTTV_PLAYLISTS();
DROP PROCEDURE IF EXISTS DEFAULT_YTTV_PLAYLISTS;
ALTER TABLE `permissions`
ADD COLUMN `cmd_update_youtube_playlists` enum('0','1') NOT NULL DEFAULT '0';
INSERT INTO `emulator_texts`(`key`, `value`) VALUES ('commands.keys.cmd_update_youtube_playlists', 'update_youtube;update_youtube_playlists')
INSERT INTO `emulator_texts`(`key`, `value`) VALUES ('commands.succes.cmd_update_youtube_playlists', 'YouTube playlists have been refreshed!')

View File

@ -0,0 +1,22 @@
package com.eu.habbo.habbohotel.commands;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
import com.eu.habbo.messages.outgoing.rooms.RoomRelativeMapComposer;
public class UpdateYoutubePlaylistsCommand extends Command {
public UpdateYoutubePlaylistsCommand() {
super("cmd_update_youtube_playlists", Emulator.getTexts().getValue("commands.keys.cmd_update_youtube_playlists").split(";"));
}
@Override
public boolean handle(GameClient gameClient, String[] params) throws Exception {
Emulator.getGameEnvironment().getItemManager().getYoutubeManager().load();
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_youtube_playlists"), RoomChatMessageBubbles.ALERT);
return true;
}
}

View File

@ -1,102 +1,173 @@
package com.eu.habbo.habbohotel.items; package com.eu.habbo.habbohotel.items;
import com.eu.habbo.Emulator; import com.eu.habbo.Emulator;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import gnu.trove.map.hash.THashMap; import gnu.trove.map.hash.THashMap;
import java.sql.Connection; import javax.net.ssl.HttpsURLConnection;
import java.sql.ResultSet; import java.io.BufferedReader;
import java.sql.SQLException; import java.io.InputStream;
import java.sql.Statement; import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class YoutubeManager { public class YoutubeManager {
public THashMap<Integer, ArrayList<YoutubeItem>> playLists = new THashMap<>(); public class YoutubeVideo {
public THashMap<Integer, YoutubeItem> videos = new THashMap<>(); private final String id;
private final int duration;
YoutubeVideo(String id, int duration) {
this.id = id;
this.duration = duration;
}
public String getId() {
return id;
}
public int getDuration() {
return duration;
}
}
public class YoutubePlaylist {
private final String id;
private final String name;
private final String description;
private final ArrayList<YoutubeVideo> videos;
YoutubePlaylist(String id, String name, String description, ArrayList<YoutubeVideo> videos) {
this.id = id;
this.name = name;
this.description = description;
this.videos = videos;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public ArrayList<YoutubeVideo> getVideos() {
return videos;
}
}
private THashMap<Integer, ArrayList<YoutubePlaylist>> playlists = new THashMap<>();
private THashMap<String, YoutubePlaylist> playlistCache = new THashMap<>();
public void load() { public void load() {
this.videos.clear(); this.playlists.clear();
this.playLists.clear(); this.playlistCache.clear();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { long millis = System.currentTimeMillis();
try (Statement statement = connection.createStatement()) {
try (ResultSet set = statement.executeQuery("SELECT * FROM youtube_items")) { ExecutorService youtubeDataLoaderPool = Executors.newFixedThreadPool(10);
Emulator.getLogging().logStart("YouTube Manager -> Loading...");
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM youtube_playlists")) {
try (ResultSet set = statement.executeQuery()) {
while (set.next()) { while (set.next()) {
this.videos.put(set.getInt("id"), new YoutubeItem(set)); final int itemId = set.getInt("item_id");
} final String playlistId = set.getString("playlist_id");
youtubeDataLoaderPool.submit(() -> {
ArrayList<YoutubePlaylist> playlists = this.playlists.getOrDefault(itemId, new ArrayList<>());
YoutubePlaylist playlist = this.playlistCache.containsKey(playlistId) ? this.playlistCache.get(playlistId) : this.getPlaylistDataById(playlistId);
if (playlist != null) {
playlists.add(playlist);
this.playlistCache.put(playlistId, playlist);
} else {
Emulator.getLogging().logErrorLine("Failed to load YouTube playlist: " + playlistId);
} }
try (ResultSet set = statement.executeQuery("SELECT * FROM youtube_playlists ORDER BY `order` ASC")) { this.playlists.put(itemId, playlists);
while (set.next()) { });
if (!this.playLists.containsKey(set.getInt("item_id"))) {
this.playLists.put(set.getInt("item_id"), new ArrayList<>());
}
YoutubeItem item = this.videos.get(set.getInt("video_id"));
if (item != null) {
this.playLists.get(set.getInt("item_id")).add(item);
}
}
} }
} }
} catch (SQLException e) { } catch (SQLException e) {
Emulator.getLogging().logSQLException(e); Emulator.getLogging().logSQLException(e);
} }
youtubeDataLoaderPool.shutdown();
try {
youtubeDataLoaderPool.awaitTermination(60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} }
public ArrayList<YoutubeItem> getPlaylist(Item item) { Emulator.getLogging().logStart("YouTube Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)");
if (this.playLists.containsKey(item.getId())) {
return this.playLists.get(item.getId());
} }
return new ArrayList<>(); private YoutubePlaylist getPlaylistDataById(String playlistId) {
try {
URL myUrl = new URL("https://www.youtube.com/playlist?list=" + playlistId);
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");
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
YoutubePlaylist 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<YoutubeVideo> 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())));
} }
public YoutubeItem getVideo(Item item, String video) { playlist = new YoutubePlaylist(playlistId, name, description, videos);
if (this.playLists.contains(item.getId())) {
for (YoutubeItem v : this.playLists.get(item.getId())) { break;
if (v.video.equalsIgnoreCase(video)) {
return v;
} }
} }
br.close();
return playlist;
} catch (java.io.IOException e) {
e.printStackTrace();
} }
return null; return null;
} }
public String getPreviewImage(Item item) { public ArrayList<YoutubePlaylist> getPlaylistsForItemId(int itemId) {
if (this.playLists.contains(item.getId())) { return this.playlists.get(itemId);
if (!this.playLists.get(item.getId()).isEmpty()) {
return this.playLists.get(item.getId()).get(0).video;
}
}
return "";
}
public YoutubeItem getVideo(Item item, int index) {
if (this.playLists.containsKey(item.getId())) {
return this.playLists.get(item.getId()).get(index);
}
return null;
}
public class YoutubeItem {
public final int id;
public final String video;
public final String title;
public final String description;
public final int startTime;
public final int endTime;
public YoutubeItem(ResultSet set) throws SQLException {
this.id = set.getInt("id");
this.video = set.getString("video");
this.title = set.getString("title");
this.description = set.getString("description");
this.startTime = set.getInt("start_time");
this.endTime = set.getInt("end_time");
}
} }
} }

View File

@ -1,16 +1,27 @@
package com.eu.habbo.habbohotel.items.interactions; package com.eu.habbo.habbohotel.items.interactions;
import com.eu.habbo.Emulator; import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.items.YoutubeManager;
import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.concurrent.ScheduledFuture;
public class InteractionYoutubeTV extends HabboItem { public class InteractionYoutubeTV extends HabboItem {
public YoutubeManager.YoutubePlaylist currentPlaylist = null;
public YoutubeManager.YoutubeVideo currentVideo = null;
public int startedWatchingAt = 0;
public int offset = 0;
public boolean playing = true;
public ScheduledFuture autoAdvance = null;
public InteractionYoutubeTV(ResultSet set, Item baseItem) throws SQLException { public InteractionYoutubeTV(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem); super(set, baseItem);
} }
@ -42,8 +53,44 @@ public class InteractionYoutubeTV extends HabboItem {
serverMessage.appendInt(1 + (this.isLimited() ? 256 : 0)); serverMessage.appendInt(1 + (this.isLimited() ? 256 : 0));
serverMessage.appendInt(1); serverMessage.appendInt(1);
serverMessage.appendString("THUMBNAIL_URL"); serverMessage.appendString("THUMBNAIL_URL");
serverMessage.appendString(Emulator.getConfig().getValue("imager.url.youtube").replace("%video%", Emulator.getGameEnvironment().getItemManager().getYoutubeManager().getPreviewImage(this.getBaseItem()))); if (this.currentVideo == null) {
serverMessage.appendString("");
} else {
serverMessage.appendString(Emulator.getConfig().getValue("imager.url.youtube").replace("%video%", this.currentVideo.getId()));
}
super.serializeExtradata(serverMessage); super.serializeExtradata(serverMessage);
} }
@Override
public void onPickUp(Room room) {
super.onPickUp(room);
if (this.autoAdvance != null) {
this.cancelAdvancement();
}
this.currentVideo = null;
this.currentPlaylist = null;
this.startedWatchingAt = 0;
this.offset = 0;
}
public void cancelAdvancement() {
if (this.autoAdvance == null) return;
this.autoAdvance.cancel(true);
this.autoAdvance = null;
}
@Override
public void onClick(GameClient client, Room room, Object[] objects) throws Exception {
super.onClick(client, room, objects);
if (this.currentVideo != null) {
int startTime = this.offset;
if (this.playing) startTime += Emulator.getIntUnixTimestamp() - this.startedWatchingAt;
client.sendResponse(new YoutubeVideoComposer(this.getId(), this.currentVideo, this.playing, startTime));
}
}
} }

View File

@ -52,9 +52,9 @@ import com.eu.habbo.messages.incoming.rooms.items.jukebox.*;
import com.eu.habbo.messages.incoming.rooms.items.lovelock.LoveLockStartConfirmEvent; import com.eu.habbo.messages.incoming.rooms.items.lovelock.LoveLockStartConfirmEvent;
import com.eu.habbo.messages.incoming.rooms.items.rentablespace.RentSpaceCancelEvent; import com.eu.habbo.messages.incoming.rooms.items.rentablespace.RentSpaceCancelEvent;
import com.eu.habbo.messages.incoming.rooms.items.rentablespace.RentSpaceEvent; import com.eu.habbo.messages.incoming.rooms.items.rentablespace.RentSpaceEvent;
import com.eu.habbo.messages.incoming.rooms.items.youtube.YoutubeRequestNextVideoEvent; import com.eu.habbo.messages.incoming.rooms.items.youtube.YoutubeRequestStateChange;
import com.eu.habbo.messages.incoming.rooms.items.youtube.YoutubeRequestPlayListEvent; import com.eu.habbo.messages.incoming.rooms.items.youtube.YoutubeRequestPlaylists;
import com.eu.habbo.messages.incoming.rooms.items.youtube.YoutubeRequestVideoDataEvent; import com.eu.habbo.messages.incoming.rooms.items.youtube.YoutubeRequestPlaylistChange;
import com.eu.habbo.messages.incoming.rooms.pets.*; import com.eu.habbo.messages.incoming.rooms.pets.*;
import com.eu.habbo.messages.incoming.rooms.promotions.BuyRoomPromotionEvent; import com.eu.habbo.messages.incoming.rooms.promotions.BuyRoomPromotionEvent;
import com.eu.habbo.messages.incoming.rooms.promotions.RequestPromotionRoomsEvent; import com.eu.habbo.messages.incoming.rooms.promotions.RequestPromotionRoomsEvent;
@ -424,9 +424,9 @@ public class PacketManager {
this.registerHandler(Incoming.RoomUserBanEvent, RoomUserBanEvent.class); this.registerHandler(Incoming.RoomUserBanEvent, RoomUserBanEvent.class);
this.registerHandler(Incoming.UnbanRoomUserEvent, UnbanRoomUserEvent.class); this.registerHandler(Incoming.UnbanRoomUserEvent, UnbanRoomUserEvent.class);
this.registerHandler(Incoming.RequestRoomUserTagsEvent, RequestRoomUserTagsEvent.class); this.registerHandler(Incoming.RequestRoomUserTagsEvent, RequestRoomUserTagsEvent.class);
this.registerHandler(Incoming.YoutubeRequestPlayListEvent, YoutubeRequestPlayListEvent.class); this.registerHandler(Incoming.YoutubeRequestPlaylists, YoutubeRequestPlaylists.class);
this.registerHandler(Incoming.YoutubeRequestNextVideoEvent, YoutubeRequestNextVideoEvent.class); this.registerHandler(Incoming.YoutubeRequestStateChange, YoutubeRequestStateChange.class);
this.registerHandler(Incoming.YoutubeRequestVideoDataEvent, YoutubeRequestVideoDataEvent.class); this.registerHandler(Incoming.YoutubeRequestPlaylistChange, YoutubeRequestPlaylistChange.class);
this.registerHandler(Incoming.RoomFavoriteEvent, RoomFavoriteEvent.class); this.registerHandler(Incoming.RoomFavoriteEvent, RoomFavoriteEvent.class);
this.registerHandler(Incoming.LoveLockStartConfirmEvent, LoveLockStartConfirmEvent.class); this.registerHandler(Incoming.LoveLockStartConfirmEvent, LoveLockStartConfirmEvent.class);
this.registerHandler(Incoming.RoomUnFavoriteEvent, RoomUnFavoriteEvent.class); this.registerHandler(Incoming.RoomUnFavoriteEvent, RoomUnFavoriteEvent.class);

View File

@ -305,9 +305,9 @@ public class Incoming {
public static final int RoomFavoriteEvent = 3817; public static final int RoomFavoriteEvent = 3817;
public static final int RoomUnFavoriteEvent = 309; public static final int RoomUnFavoriteEvent = 309;
public static final int YoutubeRequestPlayListEvent = 336; public static final int YoutubeRequestPlaylists = 336;
public static final int YoutubeRequestNextVideoEvent = 3005; public static final int YoutubeRequestStateChange = 3005;
public static final int YoutubeRequestVideoDataEvent = 2069; public static final int YoutubeRequestPlaylistChange = 2069;
public static final int EditRoomPromotionMessageEvent = 3707; public static final int EditRoomPromotionMessageEvent = 3707;
public static final int HotelViewRequestBadgeRewardEvent = 2318; public static final int HotelViewRequestBadgeRewardEvent = 2318;

View File

@ -1,28 +0,0 @@
package com.eu.habbo.messages.incoming.rooms.items.youtube;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.YoutubeManager;
import com.eu.habbo.habbohotel.items.interactions.InteractionYoutubeTV;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer;
public class YoutubeRequestNextVideoEvent extends MessageHandler {
@Override
public void handle() throws Exception {
int itemId = this.packet.readInt();
int next = this.packet.readInt();
if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) {
HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId);
if (item instanceof InteractionYoutubeTV) {
YoutubeManager.YoutubeItem video = Emulator.getGameEnvironment().getItemManager().getYoutubeManager().getVideo(item.getBaseItem(), next);
if (video != null) {
this.client.sendResponse(new YoutubeVideoComposer(itemId, video));
}
}
}
}
}

View File

@ -0,0 +1,55 @@
package com.eu.habbo.messages.incoming.rooms.items.youtube;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.YoutubeManager;
import com.eu.habbo.habbohotel.items.interactions.InteractionYoutubeTV;
import com.eu.habbo.habbohotel.permissions.Permission;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer;
import com.eu.habbo.threading.runnables.YoutubeAdvanceVideo;
import java.util.Optional;
public class YoutubeRequestPlaylistChange extends MessageHandler {
@Override
public void handle() throws Exception {
int itemId = this.packet.readInt();
String playlistId = this.packet.readString();
Habbo habbo = this.client.getHabbo();
if (habbo == null) return;
Room room = habbo.getHabboInfo().getCurrentRoom();
if (room == null) return;
if (!room.isOwner(habbo) && !habbo.hasPermission(Permission.ACC_ANYROOMOWNER)) return;
HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId);
if (item == null || !(item instanceof InteractionYoutubeTV)) return;
Optional<YoutubeManager.YoutubePlaylist> playlist = Emulator.getGameEnvironment().getItemManager().getYoutubeManager().getPlaylistsForItemId(item.getBaseItem().getId()).stream().filter(p -> p.getId().equals(playlistId)).findAny();
if (playlist.isPresent()) {
YoutubeManager.YoutubeVideo video = playlist.get().getVideos().get(0);
if (video == null) return;
((InteractionYoutubeTV) item).currentVideo = video;
((InteractionYoutubeTV) item).currentPlaylist = playlist.get();
((InteractionYoutubeTV) item).cancelAdvancement();
room.updateItem(item);
room.sendComposer(new YoutubeVideoComposer(itemId, video, true, 0).compose());
((InteractionYoutubeTV) item).autoAdvance = Emulator.getThreading().run(new YoutubeAdvanceVideo((InteractionYoutubeTV) item), video.getDuration() * 1000);
item.needsUpdate(true);
}
}
}

View File

@ -6,7 +6,7 @@ import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeDisplayListComposer; import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeDisplayListComposer;
public class YoutubeRequestPlayListEvent extends MessageHandler { public class YoutubeRequestPlaylists extends MessageHandler {
@Override @Override
public void handle() throws Exception { public void handle() throws Exception {
int itemId = this.packet.readInt(); int itemId = this.packet.readInt();
@ -15,7 +15,9 @@ public class YoutubeRequestPlayListEvent extends MessageHandler {
HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId);
if (item instanceof InteractionYoutubeTV) { if (item instanceof InteractionYoutubeTV) {
this.client.sendResponse(new YoutubeDisplayListComposer(itemId, Emulator.getGameEnvironment().getItemManager().getYoutubeManager().getPlaylist(item.getBaseItem()))); InteractionYoutubeTV tv = (InteractionYoutubeTV) item;
this.client.sendResponse(new YoutubeDisplayListComposer(itemId, Emulator.getGameEnvironment().getItemManager().getYoutubeManager().getPlaylistsForItemId(item.getBaseItem().getId()), tv.currentPlaylist));
} }
} }
} }

View File

@ -0,0 +1,108 @@
package com.eu.habbo.messages.incoming.rooms.items.youtube;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.YoutubeManager;
import com.eu.habbo.habbohotel.items.interactions.InteractionYoutubeTV;
import com.eu.habbo.habbohotel.permissions.Permission;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeStateChangeComposer;
import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer;
import com.eu.habbo.threading.runnables.YoutubeAdvanceVideo;
public class YoutubeRequestStateChange extends MessageHandler {
public enum YoutubeState {
PREVIOUS(0),
NEXT(1),
PAUSE(2),
RESUME(3);
private int state;
YoutubeState(int state) {
this.state = state;
}
public int getState() {
return state;
}
public static YoutubeState getByState(int state) {
switch (state) {
case 0:
return PREVIOUS;
case 1:
return NEXT;
case 2:
return PAUSE;
case 3:
return RESUME;
default:
return null;
}
}
}
@Override
public void handle() throws Exception {
int itemId = this.packet.readInt();
YoutubeState state = YoutubeState.getByState(this.packet.readInt());
if (state == null) return;
Habbo habbo = this.client.getHabbo();
if (habbo == null) return;
Room room = habbo.getHabboInfo().getCurrentRoom();
if (room == null) return;
if (!room.isOwner(habbo) && !habbo.hasPermission(Permission.ACC_ANYROOMOWNER)) return;
HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId);
if (item == null || !(item instanceof InteractionYoutubeTV)) return;
InteractionYoutubeTV tv = (InteractionYoutubeTV) item;
switch (state) {
case PAUSE:
tv.playing = false;
tv.offset += Emulator.getIntUnixTimestamp() - tv.startedWatchingAt;
if (tv.autoAdvance != null) tv.autoAdvance.cancel(true);
room.sendComposer(new YoutubeStateChangeComposer(tv.getId(), 2).compose());
break;
case RESUME:
tv.playing = true;
tv.startedWatchingAt = Emulator.getIntUnixTimestamp();
tv.autoAdvance = Emulator.getThreading().run(new YoutubeAdvanceVideo(tv), (tv.currentVideo.getDuration() - tv.offset) * 1000);
room.sendComposer(new YoutubeStateChangeComposer(tv.getId(), 1).compose());
break;
case PREVIOUS:
int previousIndex = tv.currentPlaylist.getVideos().indexOf(tv.currentVideo) - 1;
if (previousIndex < 0) previousIndex = tv.currentPlaylist.getVideos().size() - 1;
tv.currentVideo = tv.currentPlaylist.getVideos().get(previousIndex);
break;
case NEXT:
int nextIndex = tv.currentPlaylist.getVideos().indexOf(tv.currentVideo) + 1;
if (nextIndex >= tv.currentPlaylist.getVideos().size()) nextIndex = 0;
tv.currentVideo = tv.currentPlaylist.getVideos().get(nextIndex);
break;
}
if (state == YoutubeState.PREVIOUS || state == YoutubeState.NEXT) {
room.sendComposer(new YoutubeVideoComposer(tv.getId(), tv.currentVideo, true, 0).compose());
tv.cancelAdvancement();
tv.autoAdvance = Emulator.getThreading().run(new YoutubeAdvanceVideo(tv), tv.currentVideo.getDuration() * 1000);
tv.startedWatchingAt = Emulator.getIntUnixTimestamp();
tv.offset = 0;
tv.playing = true;
room.updateItem(tv);
}
}
}

View File

@ -1,28 +0,0 @@
package com.eu.habbo.messages.incoming.rooms.items.youtube;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.YoutubeManager;
import com.eu.habbo.habbohotel.items.interactions.InteractionYoutubeTV;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer;
public class YoutubeRequestVideoDataEvent extends MessageHandler {
@Override
public void handle() throws Exception {
int itemId = this.packet.readInt();
String videoId = this.packet.readString();
if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) {
HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId);
if (item instanceof InteractionYoutubeTV) {
YoutubeManager.YoutubeItem videoItem = Emulator.getGameEnvironment().getItemManager().getYoutubeManager().getVideo(item.getBaseItem(), videoId);
if (videoItem != null) {
this.client.sendResponse(new YoutubeVideoComposer(itemId, videoItem));
}
}
}
}
}

View File

@ -8,27 +8,29 @@ import com.eu.habbo.messages.outgoing.Outgoing;
import java.util.ArrayList; import java.util.ArrayList;
public class YoutubeDisplayListComposer extends MessageComposer { public class YoutubeDisplayListComposer extends MessageComposer {
public final int itemId; private final int itemId;
public final ArrayList<YoutubeManager.YoutubeItem> items; private final ArrayList<YoutubeManager.YoutubePlaylist> playlists;
private final YoutubeManager.YoutubePlaylist currentPlaylist;
public YoutubeDisplayListComposer(int itemId, ArrayList<YoutubeManager.YoutubeItem> items) { public YoutubeDisplayListComposer(int itemId, ArrayList<YoutubeManager.YoutubePlaylist> playlists, YoutubeManager.YoutubePlaylist currentPlaylist) {
this.itemId = itemId; this.itemId = itemId;
this.items = items; this.playlists = playlists;
this.currentPlaylist = currentPlaylist;
} }
@Override @Override
public ServerMessage compose() { public ServerMessage compose() {
this.response.init(Outgoing.YoutubeDisplayListComposer); this.response.init(Outgoing.YoutubeDisplayListComposer);
this.response.appendInt(this.itemId); this.response.appendInt(this.itemId);
this.response.appendInt(this.items.size()); this.response.appendInt(this.playlists.size());
for (YoutubeManager.YoutubeItem item : this.items) { for (YoutubeManager.YoutubePlaylist item : this.playlists) {
this.response.appendString(item.video); this.response.appendString(item.getId()); // playlist ID
this.response.appendString(item.title); this.response.appendString(item.getName()); // playlist title
this.response.appendString(item.description); this.response.appendString(item.getDescription()); // playlist description
} }
this.response.appendString(""); this.response.appendString(this.currentPlaylist == null ? "" : this.currentPlaylist.getId()); // current playlist ID
return this.response; return this.response;
} }
} }

View File

@ -0,0 +1,24 @@
package com.eu.habbo.messages.outgoing.rooms.items.youtube;
import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.outgoing.MessageComposer;
import com.eu.habbo.messages.outgoing.Outgoing;
public class YoutubeStateChangeComposer extends MessageComposer {
private final int furniId;
private final int state;
public YoutubeStateChangeComposer(int furniId, int state) {
this.furniId = furniId;
this.state = state;
}
@Override
public ServerMessage compose() {
this.response.init(Outgoing.YoutubeMessageComposer3);
this.response.appendInt(this.furniId);
this.response.appendInt(this.state);
return this.response;
}
}

View File

@ -6,22 +6,26 @@ import com.eu.habbo.messages.outgoing.MessageComposer;
import com.eu.habbo.messages.outgoing.Outgoing; import com.eu.habbo.messages.outgoing.Outgoing;
public class YoutubeVideoComposer extends MessageComposer { public class YoutubeVideoComposer extends MessageComposer {
public final int itemId; private final int itemId;
public final YoutubeManager.YoutubeItem item; private final YoutubeManager.YoutubeVideo video;
private final boolean playing;
private final int startTime;
public YoutubeVideoComposer(int itemId, YoutubeManager.YoutubeItem item) { public YoutubeVideoComposer(int itemId, YoutubeManager.YoutubeVideo video, boolean playing, int startTime) {
this.itemId = itemId; this.itemId = itemId;
this.item = item; this.video = video;
this.playing = playing;
this.startTime = startTime;
} }
@Override @Override
public ServerMessage compose() { public ServerMessage compose() {
this.response.init(Outgoing.YoutubeMessageComposer2); this.response.init(Outgoing.YoutubeMessageComposer2);
this.response.appendInt(this.itemId); this.response.appendInt(this.itemId);
this.response.appendString(this.item.video); this.response.appendString(this.video.getId());
this.response.appendInt(this.item.startTime); this.response.appendInt(this.startTime);
this.response.appendInt(this.item.endTime); this.response.appendInt(this.video.getDuration());
this.response.appendInt(0); this.response.appendInt(this.playing ? 1 : 2);
return this.response; return this.response;
} }
} }

View File

@ -0,0 +1,33 @@
package com.eu.habbo.threading.runnables;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.interactions.InteractionYoutubeTV;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer;
public class YoutubeAdvanceVideo implements Runnable {
private final InteractionYoutubeTV tv;
public YoutubeAdvanceVideo(InteractionYoutubeTV tv) {
this.tv = tv;
}
@Override
public void run() {
if (this.tv.autoAdvance == null) return;
Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.tv.getRoomId());
if (room == null) return;
int nextIndex = tv.currentPlaylist.getVideos().indexOf(tv.currentVideo) + 1;
if (nextIndex >= tv.currentPlaylist.getVideos().size()) nextIndex = 0;
tv.currentVideo = tv.currentPlaylist.getVideos().get(nextIndex);
tv.startedWatchingAt = Emulator.getIntUnixTimestamp();
tv.offset = 0;
room.updateItem(this.tv);
room.sendComposer(new YoutubeVideoComposer(tv.getId(), tv.currentVideo, true, 0).compose());
tv.autoAdvance = Emulator.getThreading().run(new YoutubeAdvanceVideo(this.tv), tv.currentVideo.getDuration() * 1000);
}
}