diff --git a/Plugins/Javascript-Plugin/.idea/compiler.xml b/Plugins/Javascript-Plugin/.idea/compiler.xml
new file mode 100644
index 0000000..4ce0013
--- /dev/null
+++ b/Plugins/Javascript-Plugin/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/Javascript-Plugin/.idea/jarRepositories.xml b/Plugins/Javascript-Plugin/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/Plugins/Javascript-Plugin/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/Javascript-Plugin/.idea/misc.xml b/Plugins/Javascript-Plugin/.idea/misc.xml
new file mode 100644
index 0000000..44185bb
--- /dev/null
+++ b/Plugins/Javascript-Plugin/.idea/misc.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/Javascript-Plugin/.idea/workspace.xml b/Plugins/Javascript-Plugin/.idea/workspace.xml
new file mode 100644
index 0000000..b1aedd9
--- /dev/null
+++ b/Plugins/Javascript-Plugin/.idea/workspace.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1712556687432
+
+
+ 1712556687432
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/Javascript-Plugin/compiled/Javascript-Plugin-1.0-SNAPSHOT.jar b/Plugins/Javascript-Plugin/compiled/Javascript-Plugin-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..32259b2
Binary files /dev/null and b/Plugins/Javascript-Plugin/compiled/Javascript-Plugin-1.0-SNAPSHOT.jar differ
diff --git a/Plugins/Javascript-Plugin/pom.xml b/Plugins/Javascript-Plugin/pom.xml
new file mode 100644
index 0000000..f697bf8
--- /dev/null
+++ b/Plugins/Javascript-Plugin/pom.xml
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+
+ com.skeletor
+ Javascript-Plugin
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+ 8
+
+
+
+
+
+
+
+ com.eu.habbo
+ Habbo
+ 3.0.0
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/audio/RoomAudioManager.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/audio/RoomAudioManager.java
new file mode 100644
index 0000000..6714f3b
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/audio/RoomAudioManager.java
@@ -0,0 +1,36 @@
+package com.skeletor.plugin.javascript.audio;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+public class RoomAudioManager {
+ private static RoomAudioManager _instance;
+
+ private ConcurrentHashMap roomAudio = new ConcurrentHashMap<>();
+
+ public RoomPlaylist getPlaylistForRoom(int roomId) {
+ if (this.roomAudio.containsKey(Integer.valueOf(roomId)))
+ return this.roomAudio.get(Integer.valueOf(roomId));
+ RoomPlaylist newPlaylist = new RoomPlaylist();
+ this.roomAudio.put(Integer.valueOf(roomId), newPlaylist);
+ return newPlaylist;
+ }
+
+ public void dispose(int roomId) {
+ this.roomAudio.remove(Integer.valueOf(roomId));
+ }
+
+ public static void Init() {
+ _instance = new RoomAudioManager();
+ }
+
+ public void Dispose() {
+ this.roomAudio.clear();
+ _instance = null;
+ }
+
+ public static RoomAudioManager getInstance() {
+ if (_instance == null)
+ _instance = new RoomAudioManager();
+ return _instance;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/audio/RoomPlaylist.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/audio/RoomPlaylist.java
new file mode 100644
index 0000000..d5b3b59
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/audio/RoomPlaylist.java
@@ -0,0 +1,90 @@
+package com.skeletor.plugin.javascript.audio;
+
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer;
+import gnu.trove.map.hash.THashMap;
+import java.util.ArrayList;
+
+public class RoomPlaylist {
+ private ArrayList playlist = new ArrayList<>();
+
+ private int current = 0;
+
+ private boolean playing = false;
+
+ public YoutubeVideo nextSong() {
+ if (this.current < this.playlist.size() - 1) {
+ this.current++;
+ } else {
+ this.current = 0;
+ }
+ return this.playlist.get(this.current);
+ }
+
+ public YoutubeVideo prevSong() {
+ if (this.current > 0)
+ this.current--;
+ return this.playlist.get(this.current);
+ }
+
+ public boolean isPlaying() {
+ return this.playing;
+ }
+
+ public void setPlaying(boolean playing) {
+ this.playing = playing;
+ }
+
+ public void addSong(YoutubeVideo song) {
+ this.playlist.add(song);
+ }
+
+ public YoutubeVideo removeSong(int index) {
+ YoutubeVideo res = null;
+ if (this.playlist.size() - 1 >= index)
+ res = this.playlist.remove(index);
+ if (this.playlist.size() == 0)
+ setPlaying(false);
+ if (index == getCurrentIndex()) {
+ if (index > this.playlist.size() - 1 && this.playlist.size() > 0)
+ this.current = this.playlist.size() - 1;
+ } else if (index < getCurrentIndex() && getCurrentIndex() > 0) {
+ this.current--;
+ }
+ return res;
+ }
+
+ public YoutubeVideo getCurrentSong() {
+ return this.playlist.get(this.current);
+ }
+
+ public int getCurrentIndex() {
+ return this.current;
+ }
+
+ public ArrayList getPlaylist() {
+ return this.playlist;
+ }
+
+ public static class YoutubeVideo {
+ public String name;
+
+ public String videoId;
+
+ public String channel;
+
+ public YoutubeVideo(String name, String videoId, String channel) {
+ this.name = name;
+ this.videoId = videoId;
+ this.channel = channel;
+ }
+ }
+
+ public MessageComposer getNowPlayingBubbleAlert() {
+ THashMap keys = new THashMap();
+ keys.put("display", "BUBBLE");
+ keys.put("image", "${image.library.url}notifications/music.png");
+ keys.put("message", "Now playing " + (getCurrentSong()).name);
+ return (MessageComposer)new BubbleAlertComposer("", keys);
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/categories/Category.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/categories/Category.java
new file mode 100644
index 0000000..0629cf5
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/categories/Category.java
@@ -0,0 +1,37 @@
+package com.skeletor.plugin.javascript.categories;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Category {
+ private int id;
+
+ private String name;
+
+ private List permissions;
+
+ public Category(ResultSet set) throws SQLException {
+ this.id = set.getInt("id");
+ this.name = set.getString("name");
+ this.permissions = new ArrayList<>();
+ }
+
+ public void addPermission(String permission) {
+ if (!this.permissions.contains(permission))
+ this.permissions.add(permission);
+ }
+
+ public int getId() {
+ return this.id;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public List getPermissions() {
+ return this.permissions;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/categories/CommandManager.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/categories/CommandManager.java
new file mode 100644
index 0000000..e45ecf9
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/categories/CommandManager.java
@@ -0,0 +1,72 @@
+package com.skeletor.plugin.javascript.categories;
+
+import com.eu.habbo.Emulator;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CommandManager {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CommandManager.class);
+
+ private final List commandCategories;
+
+ public CommandManager() {
+ this.commandCategories = new ArrayList<>();
+ reload();
+ }
+
+ public void reload() {
+ dispose();
+ try(Connection connection = Emulator.getDatabase().getDataSource().getConnection();
+ PreparedStatement statement = connection.prepareStatement("SELECT * FROM `command_categories` ORDER BY `order`");
+ ResultSet set = statement.executeQuery()) {
+ while (set.next()) {
+ Category category = new Category(set);
+ this.commandCategories.add(category);
+ }
+ } catch (SQLException e) {
+ LOGGER.error("Caught SQL exception", e);
+ }
+ try(Connection connection = Emulator.getDatabase().getDataSource().getConnection();
+ PreparedStatement statement = connection.prepareStatement("SELECT * FROM `command_category_permissions` ORDER BY `order`");
+ ResultSet set = statement.executeQuery()) {
+ while (set.next()) {
+ if (hasCommandCategory(Integer.valueOf(set.getInt("category_id")))) {
+ Category category = getCommandCategory(Integer.valueOf(set.getInt("category_id")));
+ ((Category)this.commandCategories.get(this.commandCategories.indexOf(category))).addPermission(set.getString("permission"));
+ }
+ }
+ } catch (SQLException e) {
+ LOGGER.error("Caught SQL exception", e);
+ }
+ }
+
+ public void dispose() {
+ this.commandCategories.clear();
+ }
+
+ public boolean hasCommandCategory(Integer id) {
+ return
+
+ (((List)this.commandCategories.stream().filter(p -> (p.getId() == id.intValue())).collect(Collectors.toList())).size() > 0);
+ }
+
+ public Category getCommandCategory(Integer id) {
+ if (hasCommandCategory(id))
+ return ((List)this.commandCategories
+ .stream()
+ .filter(p -> (p.getId() == id.intValue()))
+ .collect(Collectors.toList())).get(0);
+ return null;
+ }
+
+ public List getCommandCategories() {
+ return this.commandCategories;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/CmdCommand.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/CmdCommand.java
new file mode 100644
index 0000000..21e2968
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/CmdCommand.java
@@ -0,0 +1,23 @@
+package com.skeletor.plugin.javascript.commands;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.habbohotel.commands.Command;
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.common.CommandsComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+import java.util.List;
+
+public class CmdCommand extends Command {
+ public CmdCommand() {
+ super("cmd_commands", Emulator.getTexts().getValue("jscommands.keys.cmd_commands").split(";"));
+ }
+
+ public boolean handle(GameClient gameClient, String[] strings) throws Exception {
+ List commands = Emulator.getGameEnvironment().getCommandHandler().getCommandsForRank(gameClient.getHabbo().getHabboInfo().getRank().getId());
+ CommandsComposer commandsComposer = new CommandsComposer(commands);
+ gameClient.sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)commandsComposer));
+ return true;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/TwitchCommand.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/TwitchCommand.java
new file mode 100644
index 0000000..0cdd209
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/TwitchCommand.java
@@ -0,0 +1,33 @@
+package com.skeletor.plugin.javascript.commands;
+
+import com.eu.habbo.habbohotel.commands.Command;
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.common.TwitchVideoComposer;
+import com.skeletor.plugin.javascript.main;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class TwitchCommand extends Command {
+ public TwitchCommand() {
+ super("cmd_twitch", new String[] { "twitch" });
+ }
+
+ public boolean handle(GameClient gameClient, String[] strings) throws Exception {
+ Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom();
+ if ((room.hasRights(gameClient.getHabbo()) || gameClient.getHabbo().getHabboInfo().getRank().getName().equals("VIP")) &&
+ strings.length > 1) {
+ String videoId = strings[1];
+ if (videoId.isEmpty()) {
+ gameClient.getHabbo().whisper("You must supply the twitch channel/video");
+ return true;
+ }
+ main.addTwitchRoom(room.getId(), videoId);
+ TwitchVideoComposer twitchVideoComposer = new TwitchVideoComposer(videoId);
+ room.sendComposer((new JavascriptCallbackComposer((OutgoingWebMessage)twitchVideoComposer)).compose());
+ return true;
+ }
+ gameClient.getHabbo().whisper("You do not have permission to use this command in this room");
+ return true;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/UpdateCategoriesCommand.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/UpdateCategoriesCommand.java
new file mode 100644
index 0000000..f44bf3a
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/UpdateCategoriesCommand.java
@@ -0,0 +1,19 @@
+package com.skeletor.plugin.javascript.commands;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.habbohotel.commands.Command;
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.plugin.EventListener;
+import com.skeletor.plugin.javascript.main;
+
+public class UpdateCategoriesCommand extends Command implements EventListener {
+ public UpdateCategoriesCommand(String permission, String[] keys) {
+ super(permission, keys);
+ }
+
+ public boolean handle(GameClient gameClient, String[] strings) throws Exception {
+ main.getCommandManager().reload();
+ gameClient.getHabbo().whisper(Emulator.getTexts().getValue("categories.cmd_update_categories.success"));
+ return true;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/YoutubeCommand.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/YoutubeCommand.java
new file mode 100644
index 0000000..d509ab5
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/commands/YoutubeCommand.java
@@ -0,0 +1,45 @@
+package com.skeletor.plugin.javascript.commands;
+
+import com.eu.habbo.habbohotel.commands.Command;
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.common.YoutubeTVComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+import com.skeletor.plugin.javascript.utils.RegexUtility;
+
+public class YoutubeCommand extends Command {
+ public YoutubeCommand() {
+ super("cmd_youtube", new String[] { "youtube" });
+ }
+
+ public boolean handle(GameClient gameClient, String[] strings) throws Exception {
+ Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom();
+ if (strings.length > 1) {
+ String videoId = RegexUtility.getYouTubeId(strings[1]);
+ int time = 0;
+ if (videoId.isEmpty()) {
+ gameClient.getHabbo().whisper("Invalid youtube url", RoomChatMessageBubbles.ALERT);
+ return true;
+ }
+ if (strings[1].contains("t="))
+ try {
+ String[] realParams = strings[1].split("\\?");
+ if (realParams.length > 1) {
+ String[] params = realParams[1].split("&");
+ for (String param : params) {
+ String[] split = param.split("=");
+ if (split.length > 1 &&
+ split[0].equals("t"))
+ time = Integer.parseInt(split[1].replace("s", ""));
+ }
+ }
+ } catch (Exception exception) {}
+ YoutubeTVComposer youtubeTVComposer = new YoutubeTVComposer(videoId, Integer.valueOf(time));
+ room.sendComposer((new JavascriptCallbackComposer((OutgoingWebMessage)youtubeTVComposer)).compose());
+ return true;
+ }
+ return true;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/CommunicationManager.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/CommunicationManager.java
new file mode 100644
index 0000000..77772c6
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/CommunicationManager.java
@@ -0,0 +1,85 @@
+package com.skeletor.plugin.javascript.communication;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.incoming.audio.AddSongEvent;
+import com.skeletor.plugin.javascript.communication.incoming.audio.NextSongEvent;
+import com.skeletor.plugin.javascript.communication.incoming.audio.PlayStopEvent;
+import com.skeletor.plugin.javascript.communication.incoming.audio.PreviousSongEvent;
+import com.skeletor.plugin.javascript.communication.incoming.audio.RemoveSongEvent;
+import com.skeletor.plugin.javascript.communication.incoming.audio.SongEndedEvent;
+import com.skeletor.plugin.javascript.communication.incoming.common.MoveAvatarEvent;
+import com.skeletor.plugin.javascript.communication.incoming.common.RequestCommandsEvent;
+import com.skeletor.plugin.javascript.communication.incoming.common.RequestCreditsEvent;
+import com.skeletor.plugin.javascript.communication.incoming.common.RequestSpinSlotMachineEvent;
+import com.skeletor.plugin.javascript.communication.incoming.loaded.LoadedEvent;
+import com.skeletor.plugin.javascript.utils.JsonFactory;
+import gnu.trove.map.hash.THashMap;
+
+public class CommunicationManager {
+ private static CommunicationManager instance;
+
+ private final THashMap> _incomingMessages;
+
+ static {
+ try {
+ instance = new CommunicationManager();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public CommunicationManager() {
+ this._incomingMessages = new THashMap();
+ initializeMessages();
+ }
+
+ public void initializeMessages() {
+ registerMessage("move_avatar", (Class)MoveAvatarEvent.class);
+ registerMessage("request_credits", (Class)RequestCreditsEvent.class);
+ registerMessage("spin_slot_machine", (Class)RequestSpinSlotMachineEvent.class);
+ registerMessage("add_song", (Class)AddSongEvent.class);
+ registerMessage("next_song", (Class)NextSongEvent.class);
+ registerMessage("prev_song", (Class)PreviousSongEvent.class);
+ registerMessage("play_stop", (Class)PlayStopEvent.class);
+ registerMessage("remove_song", (Class)RemoveSongEvent.class);
+ registerMessage("song_ended", (Class)SongEndedEvent.class);
+ registerMessage("request_commands", (Class)RequestCommandsEvent.class);
+ registerMessage("js_loaded", (Class)LoadedEvent.class);
+ }
+
+ public void registerMessage(String key, Class extends IncomingWebMessage> message) {
+ this._incomingMessages.put(key, message);
+ }
+
+ public THashMap> getIncomingMessages() {
+ return this._incomingMessages;
+ }
+
+ public static CommunicationManager getInstance() {
+ if (instance == null)
+ try {
+ instance = new CommunicationManager();
+ } catch (Exception e) {
+ Emulator.getLogging().logErrorLine(e.getMessage());
+ }
+ return instance;
+ }
+
+ public void OnMessage(String jsonPayload, GameClient sender) {
+ try {
+ IncomingWebMessage.JSONIncomingEvent heading = (IncomingWebMessage.JSONIncomingEvent)JsonFactory.getInstance().fromJson(jsonPayload, IncomingWebMessage.JSONIncomingEvent.class);
+ Class extends IncomingWebMessage> message = (Class extends IncomingWebMessage>)getInstance().getIncomingMessages().get(heading.header);
+ IncomingWebMessage webEvent = message.getDeclaredConstructor(new Class[0]).newInstance(new Object[0]);
+ webEvent.handle(sender, JsonFactory.getInstance().fromJson(heading.data.toString(), webEvent.type));
+ } catch (Exception e) {
+ Emulator.getLogging().logUndefinedPacketLine("unknown message: " + jsonPayload);
+ }
+ }
+
+ public void Dispose() {
+ this._incomingMessages.clear();
+ instance = null;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/IncomingWebMessage.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/IncomingWebMessage.java
new file mode 100644
index 0000000..add0095
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/IncomingWebMessage.java
@@ -0,0 +1,20 @@
+package com.skeletor.plugin.javascript.communication.incoming;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.google.gson.JsonObject;
+
+public abstract class IncomingWebMessage {
+ public final Class type;
+
+ public IncomingWebMessage(Class type) {
+ this.type = type;
+ }
+
+ public abstract void handle(GameClient paramGameClient, T paramT);
+
+ public static class JSONIncomingEvent {
+ public String header;
+
+ public JsonObject data;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/AddSongEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/AddSongEvent.java
new file mode 100644
index 0000000..0890434
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/AddSongEvent.java
@@ -0,0 +1,37 @@
+package com.skeletor.plugin.javascript.communication.incoming.audio;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.skeletor.plugin.javascript.audio.RoomAudioManager;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.AddSongComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class AddSongEvent extends IncomingWebMessage {
+ public AddSongEvent() {
+ super(JSONAddSong.class);
+ }
+
+ public void handle(GameClient client, JSONAddSong message) {
+ Room currentRoom = client.getHabbo().getHabboInfo().getCurrentRoom();
+ if (currentRoom == null)
+ return;
+ if (currentRoom.hasRights(client.getHabbo())) {
+ RoomPlaylist playlist = RoomAudioManager.getInstance().getPlaylistForRoom(currentRoom.getId());
+ RoomPlaylist.YoutubeVideo song = new RoomPlaylist.YoutubeVideo(message.name, message.videoId, message.channel);
+ playlist.addSong(song);
+ AddSongComposer addSongComposer = new AddSongComposer(song);
+ currentRoom.sendComposer((new JavascriptCallbackComposer((OutgoingWebMessage)addSongComposer)).compose());
+ }
+ }
+
+ public static class JSONAddSong {
+ public String name;
+
+ public String videoId;
+
+ public String channel;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/NextSongEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/NextSongEvent.java
new file mode 100644
index 0000000..c6b5c41
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/NextSongEvent.java
@@ -0,0 +1,34 @@
+package com.skeletor.plugin.javascript.communication.incoming.audio;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.skeletor.plugin.javascript.audio.RoomAudioManager;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.PlaySongComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class NextSongEvent extends IncomingWebMessage {
+ public NextSongEvent() {
+ super(JSONNextSongEvent.class);
+ }
+
+ public void handle(GameClient client, JSONNextSongEvent message) {
+ Room currentRoom = client.getHabbo().getHabboInfo().getCurrentRoom();
+ if (currentRoom == null)
+ return;
+ if (currentRoom.hasRights(client.getHabbo())) {
+ RoomPlaylist playlist = RoomAudioManager.getInstance().getPlaylistForRoom(currentRoom.getId());
+ playlist.nextSong();
+ playlist.setPlaying(true);
+ PlaySongComposer playSongComposer = new PlaySongComposer(playlist.getCurrentIndex());
+ currentRoom.sendComposer((new JavascriptCallbackComposer((OutgoingWebMessage)playSongComposer)).compose());
+ currentRoom.sendComposer(playlist.getNowPlayingBubbleAlert().compose());
+ }
+ }
+
+ public static class JSONNextSongEvent {
+ public int currentIndex;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/PlayStopEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/PlayStopEvent.java
new file mode 100644
index 0000000..646a749
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/PlayStopEvent.java
@@ -0,0 +1,33 @@
+package com.skeletor.plugin.javascript.communication.incoming.audio;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.skeletor.plugin.javascript.audio.RoomAudioManager;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.PlayStopComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class PlayStopEvent extends IncomingWebMessage {
+ public PlayStopEvent() {
+ super(JSONPlayStopEvent.class);
+ }
+
+ public void handle(GameClient client, JSONPlayStopEvent message) {
+ Room room = client.getHabbo().getHabboInfo().getCurrentRoom();
+ if (room == null)
+ return;
+ if (room.hasRights(client.getHabbo())) {
+ RoomPlaylist roomPlaylist = RoomAudioManager.getInstance().getPlaylistForRoom(room.getId());
+ roomPlaylist.setPlaying(message.play);
+ room.sendComposer((new JavascriptCallbackComposer((OutgoingWebMessage)new PlayStopComposer(message.play))).compose());
+ if (message.play)
+ room.sendComposer(roomPlaylist.getNowPlayingBubbleAlert().compose());
+ }
+ }
+
+ public static class JSONPlayStopEvent {
+ public boolean play;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/PreviousSongEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/PreviousSongEvent.java
new file mode 100644
index 0000000..b443c47
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/PreviousSongEvent.java
@@ -0,0 +1,34 @@
+package com.skeletor.plugin.javascript.communication.incoming.audio;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.skeletor.plugin.javascript.audio.RoomAudioManager;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.PlaySongComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class PreviousSongEvent extends IncomingWebMessage {
+ public PreviousSongEvent() {
+ super(JSONPreviousSongEvent.class);
+ }
+
+ public void handle(GameClient client, JSONPreviousSongEvent message) {
+ Room currentRoom = client.getHabbo().getHabboInfo().getCurrentRoom();
+ if (currentRoom == null)
+ return;
+ if (currentRoom.hasRights(client.getHabbo())) {
+ RoomPlaylist playlist = RoomAudioManager.getInstance().getPlaylistForRoom(currentRoom.getId());
+ playlist.prevSong();
+ playlist.setPlaying(true);
+ PlaySongComposer playSongComposer = new PlaySongComposer(playlist.getCurrentIndex());
+ currentRoom.sendComposer((new JavascriptCallbackComposer((OutgoingWebMessage)playSongComposer)).compose());
+ currentRoom.sendComposer(playlist.getNowPlayingBubbleAlert().compose());
+ }
+ }
+
+ public static class JSONPreviousSongEvent {
+ public int currentIndex;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/RemoveSongEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/RemoveSongEvent.java
new file mode 100644
index 0000000..4dde4ee
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/RemoveSongEvent.java
@@ -0,0 +1,31 @@
+package com.skeletor.plugin.javascript.communication.incoming.audio;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.skeletor.plugin.javascript.audio.RoomAudioManager;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.RemoveSongComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class RemoveSongEvent extends IncomingWebMessage {
+ public RemoveSongEvent() {
+ super(JSONRemoveSongEvent.class);
+ }
+
+ public void handle(GameClient client, JSONRemoveSongEvent message) {
+ Room room = client.getHabbo().getHabboInfo().getCurrentRoom();
+ if (room == null)
+ return;
+ if (room.hasRights(client.getHabbo())) {
+ RoomPlaylist roomPlaylist = RoomAudioManager.getInstance().getPlaylistForRoom(room.getId());
+ roomPlaylist.removeSong(message.index);
+ room.sendComposer((new JavascriptCallbackComposer((OutgoingWebMessage)new RemoveSongComposer(message.index))).compose());
+ }
+ }
+
+ public static class JSONRemoveSongEvent {
+ public int index;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/SongEndedEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/SongEndedEvent.java
new file mode 100644
index 0000000..499e1de
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/audio/SongEndedEvent.java
@@ -0,0 +1,36 @@
+package com.skeletor.plugin.javascript.communication.incoming.audio;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.skeletor.plugin.javascript.audio.RoomAudioManager;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.PlaySongComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class SongEndedEvent extends IncomingWebMessage {
+ public SongEndedEvent() {
+ super(JSONSongEndedEvent.class);
+ }
+
+ public void handle(GameClient client, JSONSongEndedEvent message) {
+ Room room = client.getHabbo().getHabboInfo().getCurrentRoom();
+ if (room == null)
+ return;
+ if (room.hasRights(client.getHabbo())) {
+ RoomPlaylist playlist = RoomAudioManager.getInstance().getPlaylistForRoom(room.getId());
+ if (playlist.getCurrentIndex() == message.currentIndex) {
+ playlist.nextSong();
+ playlist.setPlaying(true);
+ PlaySongComposer playSongComposer = new PlaySongComposer(playlist.getCurrentIndex());
+ room.sendComposer((new JavascriptCallbackComposer((OutgoingWebMessage)playSongComposer)).compose());
+ room.sendComposer(playlist.getNowPlayingBubbleAlert().compose());
+ }
+ }
+ }
+
+ class JSONSongEndedEvent {
+ public int currentIndex;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/MoveAvatarEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/MoveAvatarEvent.java
new file mode 100644
index 0000000..8db59e4
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/MoveAvatarEvent.java
@@ -0,0 +1,54 @@
+package com.skeletor.plugin.javascript.communication.incoming.common;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.eu.habbo.habbohotel.rooms.RoomTile;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+
+public class MoveAvatarEvent extends IncomingWebMessage {
+ private static final short DEFAULT_WALK_AMOUNT = 1;
+
+ public MoveAvatarEvent() {
+ super(JSONMoveAvatarEvent.class);
+ }
+
+ public void handle(GameClient client, JSONMoveAvatarEvent message) {
+ Room room = client.getHabbo().getRoomUnit().getRoom();
+ if (room == null)
+ return;
+ short x = (client.getHabbo().getRoomUnit().getGoal()).x;
+ short y = (client.getHabbo().getRoomUnit().getGoal()).y;
+ switch (message.direction) {
+ case "stop":
+ return;
+ case "left":
+ y = (short)(y + 1);
+ break;
+ case "right":
+ y = (short)(y - 1);
+ break;
+ case "up":
+ x = (short)(x - 1);
+ break;
+ case "down":
+ x = (short)(x + 1);
+ break;
+ default:
+ return;
+ }
+ try {
+ RoomTile goal = room.getLayout().getTile(x, y);
+ if (goal == null)
+ return;
+ if (goal.isWalkable() || client.getHabbo().getHabboInfo().getCurrentRoom().canSitOrLayAt(goal.x, goal.y)) {
+ if (client.getHabbo().getRoomUnit().getMoveBlockingTask() != null)
+ client.getHabbo().getRoomUnit().getMoveBlockingTask().get();
+ client.getHabbo().getRoomUnit().setGoalLocation(goal);
+ }
+ } catch (Exception exception) {}
+ }
+
+ static class JSONMoveAvatarEvent {
+ String direction;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/RequestCommandsEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/RequestCommandsEvent.java
new file mode 100644
index 0000000..c67ea48
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/RequestCommandsEvent.java
@@ -0,0 +1,27 @@
+package com.skeletor.plugin.javascript.communication.incoming.common;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.habbohotel.commands.Command;
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.common.CommandsComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+import java.util.List;
+
+public class RequestCommandsEvent extends IncomingWebMessage {
+ public RequestCommandsEvent() {
+ super(JSONRequestCommandsEvent.class);
+ }
+
+ public void handle(GameClient client, JSONRequestCommandsEvent message) {
+ List commands = Emulator.getGameEnvironment().getCommandHandler().getCommandsForRank(client.getHabbo().getHabboInfo().getRank().getId());
+ CommandsComposer commandsComposer = new CommandsComposer(commands);
+ client.sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)commandsComposer));
+ }
+
+ static class JSONRequestCommandsEvent {
+ boolean idk;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/RequestCreditsEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/RequestCreditsEvent.java
new file mode 100644
index 0000000..9c8452a
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/RequestCreditsEvent.java
@@ -0,0 +1,25 @@
+package com.skeletor.plugin.javascript.communication.incoming.common;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.eu.habbo.messages.outgoing.users.UserCreditsComposer;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.common.UpdateCreditsComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class RequestCreditsEvent extends IncomingWebMessage {
+ public RequestCreditsEvent() {
+ super(JSONRequestCreditsEvent.class);
+ }
+
+ public void handle(GameClient client, JSONRequestCreditsEvent message) {
+ client.sendResponse((MessageComposer)new UserCreditsComposer(client.getHabbo()));
+ UpdateCreditsComposer creditsComposer = new UpdateCreditsComposer(client.getHabbo().getHabboInfo().getCredits());
+ client.sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)creditsComposer));
+ }
+
+ static class JSONRequestCreditsEvent {
+ boolean idk;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/RequestSpinSlotMachineEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/RequestSpinSlotMachineEvent.java
new file mode 100644
index 0000000..58ea5a8
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/common/RequestSpinSlotMachineEvent.java
@@ -0,0 +1,91 @@
+package com.skeletor.plugin.javascript.communication.incoming.common;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
+import com.eu.habbo.habbohotel.users.HabboItem;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.eu.habbo.messages.outgoing.users.UserCreditsComposer;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.common.UpdateCreditsComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.slotmachine.SpinResultComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class RequestSpinSlotMachineEvent extends IncomingWebMessage {
+ private static final int maxNumber = 5;
+
+ private static final int LEMON = 0;
+
+ private static final int MELON = 1;
+
+ private static final int GRAPES = 2;
+
+ private static final int CHERRY = 3;
+
+ private static final int BAR = 4;
+
+ public RequestSpinSlotMachineEvent() {
+ super(JSONRequestSpinSlotMachineEvent.class);
+ }
+
+ public void handle(GameClient client, JSONRequestSpinSlotMachineEvent message) {
+ HabboItem item = client.getHabbo().getRoomUnit().getRoom().getHabboItem(message.itemId);
+ if (item == null)
+ return;
+ if (message.bet <= 0 || message.bet > client.getHabbo().getHabboInfo().getCredits())
+ return;
+ client.getHabbo().getHabboInfo().addCredits(-message.bet);
+ client.sendResponse((MessageComposer)new UserCreditsComposer(client.getHabbo()));
+ client.getHabbo().talk(Emulator.getTexts().getValue("slot.machines.spin", "* Bets %amount% on Slots Machine *").replace("%amount%", message.bet + ""), RoomChatMessageBubbles.ALERT);
+ client.sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new UpdateCreditsComposer(client.getHabbo().getHabboInfo().getCredits())));
+ int result1 = Emulator.getRandom().nextInt(5);
+ int result2 = Emulator.getRandom().nextInt(5);
+ int result3 = Emulator.getRandom().nextInt(5);
+ int amountWon = 0;
+ boolean won = false;
+ if (result1 == result2 && result2 == result3) {
+ won = true;
+ switch (result1) {
+ case 0:
+ amountWon = 5 * message.bet;
+ break;
+ case 1:
+ amountWon = 6 * message.bet;
+ break;
+ case 2:
+ amountWon = 10 * message.bet;
+ break;
+ case 3:
+ amountWon = 15 * message.bet;
+ break;
+ case 4:
+ amountWon = 20 * message.bet;
+ break;
+ }
+ client.getHabbo().getHabboInfo().addCredits(amountWon);
+ } else if (result1 == 4 && result2 == 4) {
+ won = true;
+ amountWon = 4 * message.bet;
+ client.getHabbo().getHabboInfo().addCredits(amountWon);
+ } else if (result1 == 3 && result2 == 3) {
+ won = true;
+ amountWon = 3 * message.bet;
+ client.getHabbo().getHabboInfo().addCredits(amountWon);
+ } else if (result1 == 3) {
+ won = true;
+ amountWon = 2 * message.bet;
+ client.getHabbo().getHabboInfo().addCredits(amountWon);
+ }
+ SpinResultComposer resultComposer = new SpinResultComposer(result1, result2, result3, won, amountWon);
+ client.sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)resultComposer));
+ int finalAmount = amountWon;
+ Emulator.getThreading().run(() -> client.getHabbo().talk(Emulator.getTexts().getValue("slot.machines.won", "* Won %amount% in Slots Machine *").replace("%amount%", finalAmount + ""), RoomChatMessageBubbles.ALERT), 5000L);
+ }
+
+ static class JSONRequestSpinSlotMachineEvent {
+ int itemId;
+
+ int bet;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/loaded/LoadedEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/loaded/LoadedEvent.java
new file mode 100644
index 0000000..ffb4768
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/incoming/loaded/LoadedEvent.java
@@ -0,0 +1,33 @@
+package com.skeletor.plugin.javascript.communication.incoming.loaded;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.habbohotel.commands.Command;
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.users.Habbo;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.skeletor.plugin.javascript.communication.incoming.IncomingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.commands.CommandsPopUpComposer;
+import com.skeletor.plugin.javascript.main;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+import java.util.List;
+
+public class LoadedEvent extends IncomingWebMessage {
+ public LoadedEvent() {
+ super(JSONLoadedEvent.class);
+ }
+
+ public void handle(GameClient client, JSONLoadedEvent message) {
+ Habbo habbo = client.getHabbo();
+ if (habbo == null)
+ return;
+ (habbo.getHabboStats()).cache.put(main.USER_LOADED_EVENT, Boolean.valueOf(true));
+ List commands = Emulator.getGameEnvironment().getCommandHandler().getCommandsForRank(client.getHabbo().getHabboInfo().getRank().getId());
+ CommandsPopUpComposer commandsPopUpComposer = new CommandsPopUpComposer(commands, (habbo.getHabboInfo().getRank().getLevel() >= 5));
+ client.sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)commandsPopUpComposer));
+ }
+
+ static class JSONLoadedEvent {
+ boolean idk;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/OutgoingWebMessage.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/OutgoingWebMessage.java
new file mode 100644
index 0000000..ce70c59
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/OutgoingWebMessage.java
@@ -0,0 +1,14 @@
+package com.skeletor.plugin.javascript.communication.outgoing;
+
+import com.google.gson.JsonObject;
+
+public abstract class OutgoingWebMessage {
+ public String header;
+
+ public JsonObject data;
+
+ public OutgoingWebMessage(String name) {
+ this.header = name;
+ this.data = new JsonObject();
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/AddSongComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/AddSongComposer.java
new file mode 100644
index 0000000..7da77f8
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/AddSongComposer.java
@@ -0,0 +1,18 @@
+package com.skeletor.plugin.javascript.communication.outgoing.audio;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class AddSongComposer extends OutgoingWebMessage {
+ public AddSongComposer(RoomPlaylist.YoutubeVideo video) {
+ super("add_song");
+ JsonObject song = new JsonObject();
+ song.add("name", (JsonElement)new JsonPrimitive(video.name));
+ song.add("videoId", (JsonElement)new JsonPrimitive(video.videoId));
+ song.add("channel", (JsonElement)new JsonPrimitive(video.channel));
+ this.data.add("song", (JsonElement)song);
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/ChangeVolumeComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/ChangeVolumeComposer.java
new file mode 100644
index 0000000..a2080ec
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/ChangeVolumeComposer.java
@@ -0,0 +1,12 @@
+package com.skeletor.plugin.javascript.communication.outgoing.audio;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class ChangeVolumeComposer extends OutgoingWebMessage {
+ public ChangeVolumeComposer(int volume) {
+ super("change_volume");
+ this.data.add("volume", (JsonElement)new JsonPrimitive(Integer.valueOf(volume)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/DisposePlaylistComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/DisposePlaylistComposer.java
new file mode 100644
index 0000000..3b1b7ea
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/DisposePlaylistComposer.java
@@ -0,0 +1,9 @@
+package com.skeletor.plugin.javascript.communication.outgoing.audio;
+
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class DisposePlaylistComposer extends OutgoingWebMessage {
+ public DisposePlaylistComposer() {
+ super("dispose_playlist");
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/JukeboxComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/JukeboxComposer.java
new file mode 100644
index 0000000..15f7fbf
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/JukeboxComposer.java
@@ -0,0 +1,23 @@
+package com.skeletor.plugin.javascript.communication.outgoing.audio;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class JukeboxComposer extends OutgoingWebMessage {
+ public JukeboxComposer(RoomPlaylist playlist) {
+ super("jukebox_player");
+ JsonArray playlistJson = new JsonArray();
+ for (RoomPlaylist.YoutubeVideo video : playlist.getPlaylist()) {
+ JsonObject song = new JsonObject();
+ song.add("name", (JsonElement)new JsonPrimitive(video.name));
+ song.add("videoId", (JsonElement)new JsonPrimitive(video.videoId));
+ song.add("channel", (JsonElement)new JsonPrimitive(video.channel));
+ playlistJson.add((JsonElement)song);
+ }
+ this.data.add("playlist", (JsonElement)playlistJson);
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/PlaySongComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/PlaySongComposer.java
new file mode 100644
index 0000000..85ab1db
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/PlaySongComposer.java
@@ -0,0 +1,12 @@
+package com.skeletor.plugin.javascript.communication.outgoing.audio;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class PlaySongComposer extends OutgoingWebMessage {
+ public PlaySongComposer(int index) {
+ super("play_song");
+ this.data.add("index", (JsonElement)new JsonPrimitive(Integer.valueOf(index)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/PlayStopComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/PlayStopComposer.java
new file mode 100644
index 0000000..bfce7e0
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/PlayStopComposer.java
@@ -0,0 +1,12 @@
+package com.skeletor.plugin.javascript.communication.outgoing.audio;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class PlayStopComposer extends OutgoingWebMessage {
+ public PlayStopComposer(boolean isPlaying) {
+ super("play_stop");
+ this.data.add("playing", (JsonElement)new JsonPrimitive(Boolean.valueOf(isPlaying)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/PlaylistComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/PlaylistComposer.java
new file mode 100644
index 0000000..3169255
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/PlaylistComposer.java
@@ -0,0 +1,23 @@
+package com.skeletor.plugin.javascript.communication.outgoing.audio;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class PlaylistComposer extends OutgoingWebMessage {
+ public PlaylistComposer(RoomPlaylist playlist) {
+ super("playlist");
+ JsonArray playlistJson = new JsonArray();
+ for (RoomPlaylist.YoutubeVideo video : playlist.getPlaylist()) {
+ JsonObject song = new JsonObject();
+ song.add("name", (JsonElement)new JsonPrimitive(video.name));
+ song.add("videoId", (JsonElement)new JsonPrimitive(video.videoId));
+ song.add("channel", (JsonElement)new JsonPrimitive(video.channel));
+ playlistJson.add((JsonElement)song);
+ }
+ this.data.add("playlist", (JsonElement)playlistJson);
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/RemoveSongComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/RemoveSongComposer.java
new file mode 100644
index 0000000..28db242
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/audio/RemoveSongComposer.java
@@ -0,0 +1,12 @@
+package com.skeletor.plugin.javascript.communication.outgoing.audio;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class RemoveSongComposer extends OutgoingWebMessage {
+ public RemoveSongComposer(int index) {
+ super("remove_song");
+ this.data.add("index", (JsonElement)new JsonPrimitive(Integer.valueOf(index)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/commands/CommandsPopUpComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/commands/CommandsPopUpComposer.java
new file mode 100644
index 0000000..7a5ac1b
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/commands/CommandsPopUpComposer.java
@@ -0,0 +1,27 @@
+package com.skeletor.plugin.javascript.communication.outgoing.commands;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.habbohotel.commands.Command;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class CommandsPopUpComposer extends OutgoingWebMessage {
+ public CommandsPopUpComposer(List commands, boolean mod) {
+ super("commands_pop_up");
+ JsonArray json_cmd = new JsonArray();
+ Collections.sort(commands, new Comparator() {
+ public int compare(Command command2, Command command1) {
+ return Emulator.getTexts().getValue("commands.description." + command2.permission, "commands.description." + command2.permission).compareTo(Emulator.getTexts().getValue("commands.description." + command1.permission, "commands.description." + command1.permission));
+ }
+ });
+ for (Command c : commands)
+ json_cmd.add(Emulator.getTexts().getValue("commands.description." + c.permission, "commands.description." + c.permission));
+ this.data.add("commands", (JsonElement)json_cmd);
+ this.data.add("mod", (JsonElement)new JsonPrimitive(Boolean.valueOf(mod)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/CommandsComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/CommandsComposer.java
new file mode 100644
index 0000000..eb48958
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/CommandsComposer.java
@@ -0,0 +1,77 @@
+package com.skeletor.plugin.javascript.communication.outgoing.common;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.habbohotel.commands.Command;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.skeletor.plugin.javascript.categories.Category;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.main;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class CommandsComposer extends OutgoingWebMessage {
+ public CommandsComposer(List commands) {
+ super("commands");
+ JsonArray json_cmd = new JsonArray();
+ Collections.sort(commands, new Comparator() {
+ public int compare(Command command2, Command command1) {
+ return Emulator.getTexts().getValue("commands.description." + command2.permission, "commands.description." + command2.permission).compareTo(Emulator.getTexts().getValue("commands.description." + command1.permission, "commands.description." + command1.permission));
+ }
+ });
+ List duplicateCommands = new ArrayList<>(commands);
+ List tempList = new ArrayList<>();
+ boolean hasPermission = false;
+ for (Category category : main.getCommandManager().getCommandCategories()) {
+ tempList = new ArrayList<>();
+ hasPermission = false;
+ if (category.getPermissions().size() > 0) {
+ for (String permission : category.getPermissions()) {
+ for (Command command : commands) {
+ if (command.permission.equals(permission)) {
+ duplicateCommands.remove(command);
+ String keys = "";
+ if (Emulator.getConfig().getBoolean("categories.cmd_commandsc.show_keys")) {
+ for (String key : command.keys) {
+ if (keys.equals("")) {
+ keys = "(" + key;
+ } else {
+ keys = keys + " " + key;
+ }
+ }
+ keys = keys + ")";
+ }
+ tempList.add(Emulator.getTexts().getValue("commands.description." + command.permission, "commands.description." + command.permission + " " + keys));
+ hasPermission = true;
+ }
+ }
+ }
+ if (hasPermission) {
+ json_cmd.add(category.getName());
+ for (String temp : tempList)
+ json_cmd.add(temp);
+ }
+ }
+ }
+ if (duplicateCommands.size() > 0 && Emulator.getConfig().getBoolean("categories.cmd_commandsc.show_others")) {
+ json_cmd.add(Emulator.getTexts().getValue("commands.generic.cmd_commandsc.others"));
+ for (Command command : duplicateCommands) {
+ String keys = "";
+ if (Emulator.getConfig().getBoolean("categories.cmd_commandsc.show_keys")) {
+ for (String key : command.keys) {
+ if (keys.equals("")) {
+ keys = "(" + key;
+ } else {
+ keys = keys + " " + key;
+ }
+ }
+ keys = keys + ")";
+ }
+ json_cmd.add(Emulator.getTexts().getValue("commands.description." + command.permission, "commands.description." + command.permission) + " " + keys);
+ }
+ }
+ this.data.add("commands", (JsonElement)json_cmd);
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/OnlineCountComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/OnlineCountComposer.java
new file mode 100644
index 0000000..8252864
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/OnlineCountComposer.java
@@ -0,0 +1,12 @@
+package com.skeletor.plugin.javascript.communication.outgoing.common;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class OnlineCountComposer extends OutgoingWebMessage {
+ public OnlineCountComposer(int count) {
+ super("online_count");
+ this.data.add("count", (JsonElement)new JsonPrimitive(Integer.valueOf(count)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/SessionDataComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/SessionDataComposer.java
new file mode 100644
index 0000000..43ed4ec
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/SessionDataComposer.java
@@ -0,0 +1,15 @@
+package com.skeletor.plugin.javascript.communication.outgoing.common;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class SessionDataComposer extends OutgoingWebMessage {
+ public SessionDataComposer(int id, String username, String look, int credits) {
+ super("session_data");
+ this.data.add("id", (JsonElement)new JsonPrimitive(Integer.valueOf(id)));
+ this.data.add("username", (JsonElement)new JsonPrimitive(username));
+ this.data.add("look", (JsonElement)new JsonPrimitive(look));
+ this.data.add("credits", (JsonElement)new JsonPrimitive(Integer.valueOf(credits)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/TwitchVideoComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/TwitchVideoComposer.java
new file mode 100644
index 0000000..a596c05
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/TwitchVideoComposer.java
@@ -0,0 +1,12 @@
+package com.skeletor.plugin.javascript.communication.outgoing.common;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class TwitchVideoComposer extends OutgoingWebMessage {
+ public TwitchVideoComposer(String videoId) {
+ super("twitch");
+ this.data.add("videoId", (JsonElement)new JsonPrimitive(videoId));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/UpdateCreditsComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/UpdateCreditsComposer.java
new file mode 100644
index 0000000..f79bfa3
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/UpdateCreditsComposer.java
@@ -0,0 +1,12 @@
+package com.skeletor.plugin.javascript.communication.outgoing.common;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class UpdateCreditsComposer extends OutgoingWebMessage {
+ public UpdateCreditsComposer(int credits) {
+ super("update_credits");
+ this.data.add("credits", (JsonElement)new JsonPrimitive(Integer.valueOf(credits)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/YoutubeTVComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/YoutubeTVComposer.java
new file mode 100644
index 0000000..69f4e82
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/common/YoutubeTVComposer.java
@@ -0,0 +1,14 @@
+package com.skeletor.plugin.javascript.communication.outgoing.common;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class YoutubeTVComposer extends OutgoingWebMessage {
+ public YoutubeTVComposer(String videoId, Integer time) {
+ super("youtube_tv");
+ this.data.add("videoId", (JsonElement)new JsonPrimitive(videoId));
+ this.data.add("time", (JsonElement)new JsonPrimitive(time));
+ this.data.add("itemId", (JsonElement)new JsonPrimitive(Integer.valueOf(0)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/slotmachine/SlotMachineComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/slotmachine/SlotMachineComposer.java
new file mode 100644
index 0000000..c24da4c
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/slotmachine/SlotMachineComposer.java
@@ -0,0 +1,13 @@
+package com.skeletor.plugin.javascript.communication.outgoing.slotmachine;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class SlotMachineComposer extends OutgoingWebMessage {
+ public SlotMachineComposer(int itemId, int credits) {
+ super("slot_machine");
+ this.data.add("itemId", (JsonElement)new JsonPrimitive(Integer.valueOf(itemId)));
+ this.data.add("credits", (JsonElement)new JsonPrimitive(Integer.valueOf(credits)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/slotmachine/SpinResultComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/slotmachine/SpinResultComposer.java
new file mode 100644
index 0000000..54cbc9a
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/communication/outgoing/slotmachine/SpinResultComposer.java
@@ -0,0 +1,16 @@
+package com.skeletor.plugin.javascript.communication.outgoing.slotmachine;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+
+public class SpinResultComposer extends OutgoingWebMessage {
+ public SpinResultComposer(int result1, int result2, int result3, boolean won, int payout) {
+ super("slot_result");
+ this.data.add("result1", (JsonElement)new JsonPrimitive(Integer.valueOf(result1)));
+ this.data.add("result2", (JsonElement)new JsonPrimitive(Integer.valueOf(result2)));
+ this.data.add("result3", (JsonElement)new JsonPrimitive(Integer.valueOf(result3)));
+ this.data.add("won", (JsonElement)new JsonPrimitive(Boolean.valueOf(won)));
+ this.data.add("payout", (JsonElement)new JsonPrimitive(Integer.valueOf(payout)));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/interactions/InteractionSlotMachine.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/interactions/InteractionSlotMachine.java
new file mode 100644
index 0000000..37321b5
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/interactions/InteractionSlotMachine.java
@@ -0,0 +1,39 @@
+package com.skeletor.plugin.javascript.interactions;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.items.Item;
+import com.eu.habbo.habbohotel.items.interactions.InteractionDefault;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.eu.habbo.habbohotel.rooms.RoomUnit;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.slotmachine.SlotMachineComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class InteractionSlotMachine extends InteractionDefault {
+ public InteractionSlotMachine(ResultSet set, Item baseItem) throws SQLException {
+ super(set, baseItem);
+ }
+
+ public InteractionSlotMachine(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
+ super(id, userId, item, extradata, limitedStack, limitedSells);
+ }
+
+ public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) {
+ return false;
+ }
+
+ public boolean isWalkable() {
+ return false;
+ }
+
+ public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception {}
+
+ public void onClick(GameClient client, Room room, Object[] objects) throws Exception {
+ super.onClick(client, room, objects);
+ SlotMachineComposer webComposer = new SlotMachineComposer(getId(), client.getHabbo().getHabboInfo().getCredits());
+ client.sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)webComposer));
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/interactions/InteractionYoutubeJukebox.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/interactions/InteractionYoutubeJukebox.java
new file mode 100644
index 0000000..c28706b
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/interactions/InteractionYoutubeJukebox.java
@@ -0,0 +1,44 @@
+package com.skeletor.plugin.javascript.interactions;
+
+import com.eu.habbo.habbohotel.gameclients.GameClient;
+import com.eu.habbo.habbohotel.items.Item;
+import com.eu.habbo.habbohotel.items.interactions.InteractionDefault;
+import com.eu.habbo.habbohotel.rooms.Room;
+import com.eu.habbo.habbohotel.rooms.RoomUnit;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.skeletor.plugin.javascript.audio.RoomAudioManager;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.JukeboxComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class InteractionYoutubeJukebox extends InteractionDefault {
+ public InteractionYoutubeJukebox(ResultSet set, Item baseItem) throws SQLException {
+ super(set, baseItem);
+ }
+
+ public InteractionYoutubeJukebox(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
+ super(id, userId, item, extradata, limitedStack, limitedSells);
+ }
+
+ public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) {
+ return false;
+ }
+
+ public boolean isWalkable() {
+ return false;
+ }
+
+ public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception {}
+
+ public void onClick(GameClient client, Room room, Object[] objects) throws Exception {
+ super.onClick(client, room, objects);
+ if (room.hasRights(client.getHabbo())) {
+ RoomPlaylist roomPlaylist = RoomAudioManager.getInstance().getPlaylistForRoom(room.getId());
+ JukeboxComposer webComposer = new JukeboxComposer(roomPlaylist);
+ client.sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)webComposer));
+ }
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/main.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/main.java
new file mode 100644
index 0000000..53a101a
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/main.java
@@ -0,0 +1,197 @@
+package com.skeletor.plugin.javascript;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.habbohotel.commands.Command;
+import com.eu.habbo.habbohotel.commands.CommandHandler;
+import com.eu.habbo.habbohotel.items.ItemInteraction;
+import com.eu.habbo.habbohotel.users.Habbo;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.eu.habbo.plugin.EventHandler;
+import com.eu.habbo.plugin.EventListener;
+import com.eu.habbo.plugin.HabboPlugin;
+import com.eu.habbo.plugin.events.emulator.EmulatorLoadItemsManagerEvent;
+import com.eu.habbo.plugin.events.emulator.EmulatorLoadedEvent;
+import com.eu.habbo.plugin.events.rooms.RoomUncachedEvent;
+import com.eu.habbo.plugin.events.users.UserCreditsEvent;
+import com.eu.habbo.plugin.events.users.UserEnterRoomEvent;
+import com.eu.habbo.plugin.events.users.UserExitRoomEvent;
+import com.eu.habbo.plugin.events.users.UserLoginEvent;
+import com.eu.habbo.plugin.events.users.UserSavedSettingsEvent;
+import com.skeletor.plugin.javascript.audio.RoomAudioManager;
+import com.skeletor.plugin.javascript.audio.RoomPlaylist;
+import com.skeletor.plugin.javascript.categories.CommandManager;
+import com.skeletor.plugin.javascript.commands.CmdCommand;
+import com.skeletor.plugin.javascript.commands.TwitchCommand;
+import com.skeletor.plugin.javascript.commands.UpdateCategoriesCommand;
+import com.skeletor.plugin.javascript.commands.YoutubeCommand;
+import com.skeletor.plugin.javascript.communication.CommunicationManager;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.ChangeVolumeComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.DisposePlaylistComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.PlaySongComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.PlayStopComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.audio.PlaylistComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.common.OnlineCountComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.common.SessionDataComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.common.TwitchVideoComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.common.UpdateCreditsComposer;
+import com.skeletor.plugin.javascript.interactions.InteractionSlotMachine;
+import com.skeletor.plugin.javascript.interactions.InteractionYoutubeJukebox;
+import com.skeletor.plugin.javascript.override_packets.incoming.JavascriptCallbackEvent;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+import com.skeletor.plugin.javascript.runnables.OnlineCountRunnable;
+import com.skeletor.plugin.javascript.scheduler.CheckLoadedScheduler;
+import gnu.trove.map.hash.THashMap;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+public class main extends HabboPlugin implements EventListener {
+ public static final int JSCALLBACKEVENTHEADER = 314;
+
+ private static CommandManager commandManager;
+
+ private static THashMap twitchRooms;
+
+ public static String USER_LOADED_EVENT = "user.loaded.event.key";
+
+ public static String STARTED_LOADING_EVENT = "user.loading.event.key";
+
+ public void onEnable() throws Exception {
+ Emulator.getPluginManager().registerEvents(this, this);
+ if (Emulator.isReady && !Emulator.isShuttingDown)
+ onEmulatorLoadedEvent(null);
+ }
+
+ @EventHandler
+ public void onEmulatorLoadedEvent(EmulatorLoadedEvent e) throws Exception {
+ Emulator.getGameServer().getPacketManager().registerHandler(Integer.valueOf(314), JavascriptCallbackEvent.class);
+ Emulator.getTexts().register("jscommands.keys.cmd_commands", "commands");
+ Emulator.getTexts().register("commands.description.cmd_commandsc", ":commandsc");
+ Emulator.getTexts().register("categories.cmd_commandsc.keys", "commandsc");
+ Emulator.getTexts().register("commands.generic.cmd_commandsc.text", "Your Commands");
+ Emulator.getTexts().register("commands.generic.cmd_commandsc.others", "Others");
+ Emulator.getTexts().register("commands.description.cmd_update_categories", ":update_categories");
+ Emulator.getTexts().register("categories.cmd_update_categories.keys", "update_categories");
+ Emulator.getTexts().register("categories.cmd_update_categories.success", "Successfully updated command categories");
+ Emulator.getConfig().register("categories.cmd_commandsc.show_keys", "1");
+ Emulator.getConfig().register("categories.cmd_commandsc.show_others", "1");
+ boolean reloadPermissions = false;
+ reloadPermissions = registerPermission("cmd_commandsc", "'0', '1'", "1", reloadPermissions);
+ reloadPermissions = registerPermission("cmd_update_categories", "'0', '1'", "0", reloadPermissions);
+ if (reloadPermissions)
+ Emulator.getGameEnvironment().getPermissionsManager().reload();
+ CommandHandler.addCommand((Command)new YoutubeCommand());
+ CommandHandler.addCommand((Command)new CmdCommand());
+ CommandHandler.addCommand((Command)new TwitchCommand());
+ CommandHandler.addCommand((Command)new UpdateCategoriesCommand("cmd_update_categories", Emulator.getTexts().getValue("categories.cmd_update_categories.keys").split(";")));
+ RoomAudioManager.Init();
+ OnlineCountRunnable.getInstance().start();
+ commandManager = new CommandManager();
+ twitchRooms = new THashMap();
+ new CheckLoadedScheduler();
+ }
+
+ private boolean registerPermission(String name, String options, String defaultValue, boolean defaultReturn) {
+ try(Connection connection = Emulator.getDatabase().getDataSource().getConnection();
+
+ PreparedStatement statement = connection.prepareStatement("ALTER TABLE `permissions` ADD `" + name + "` ENUM( " + options + " ) NOT NULL DEFAULT '" + defaultValue + "'")) {
+ statement.execute();
+ return true;
+ } catch (SQLException sQLException) {
+ return defaultReturn;
+ }
+ }
+
+ @EventHandler
+ public void onLoadItemsManager(EmulatorLoadItemsManagerEvent e) {
+ Emulator.getGameEnvironment().getItemManager().addItemInteraction(new ItemInteraction("slots_machine", InteractionSlotMachine.class));
+ Emulator.getGameEnvironment().getItemManager().addItemInteraction(new ItemInteraction("yt_jukebox", InteractionYoutubeJukebox.class));
+ }
+
+ @EventHandler
+ public void onUserEnterRoomEvent(UserEnterRoomEvent e) {
+ RoomPlaylist playlist = RoomAudioManager.getInstance().getPlaylistForRoom(e.room.getId());
+ if (playlist.getPlaylist().size() > 0) {
+ e.habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new PlaylistComposer(playlist)));
+ if (playlist.isPlaying()) {
+ e.habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new PlaySongComposer(playlist.getCurrentIndex())));
+ e.habbo.getClient().sendResponse(playlist.getNowPlayingBubbleAlert());
+ }
+ }
+ if (e.room.getHabbos() == null || e.room.getHabbos().size() == 0)
+ twitchRooms.remove(Integer.valueOf(e.room.getId()));
+ if (twitchRooms.containsKey(Integer.valueOf(e.room.getId()))) {
+ TwitchVideoComposer twitchVideoComposer = new TwitchVideoComposer((String)twitchRooms.get(Integer.valueOf(e.room.getId())));
+ e.habbo.getClient().sendResponse((new JavascriptCallbackComposer((OutgoingWebMessage)twitchVideoComposer)).compose());
+ }
+ }
+
+ @EventHandler
+ public void onUserExitRoomEvent(UserExitRoomEvent e) {
+ e.habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new PlayStopComposer(false)));
+ e.habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new DisposePlaylistComposer()));
+ }
+
+ @EventHandler
+ public void onRoomUncachedEvent(RoomUncachedEvent e) {
+ RoomAudioManager.getInstance().dispose(e.room.getId());
+ }
+
+ @EventHandler
+ public void onUserLoginEvent(UserLoginEvent e) {
+ if (e.habbo == null || e.habbo.getClient() == null)
+ return;
+ Habbo habbo = e.habbo;
+ (e.habbo.getHabboStats()).cache.put(USER_LOADED_EVENT, Boolean.valueOf(false));
+ (e.habbo.getHabboStats()).cache.put(STARTED_LOADING_EVENT, Integer.valueOf(Emulator.getIntUnixTimestamp()));
+ SessionDataComposer sessionDataComposer = new SessionDataComposer(e.habbo.getHabboInfo().getId(), e.habbo.getHabboInfo().getUsername(), e.habbo.getHabboInfo().getLook(), e.habbo.getHabboInfo().getCredits());
+ e.habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)sessionDataComposer));
+ e.habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new ChangeVolumeComposer((e.habbo.getHabboStats()).volumeTrax)));
+ e.habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new OnlineCountComposer(Emulator.getGameEnvironment().getHabboManager().getOnlineCount())));
+ Emulator.getThreading().run(() -> userCheckLoaded(habbo), 500L);
+ }
+
+ public void userCheckLoaded(Habbo habbo) {
+ if (habbo == null || habbo.getClient() == null || !habbo.isOnline())
+ return;
+ if (((Boolean)(habbo.getHabboStats()).cache.get(USER_LOADED_EVENT)).booleanValue())
+ return;
+ if (Emulator.getIntUnixTimestamp() - ((Integer)(habbo.getHabboStats()).cache.get(STARTED_LOADING_EVENT)).intValue() > 15)
+ return;
+ SessionDataComposer sessionDataComposer = new SessionDataComposer(habbo.getHabboInfo().getId(), habbo.getHabboInfo().getUsername(), habbo.getHabboInfo().getLook(), habbo.getHabboInfo().getCredits());
+ habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)sessionDataComposer));
+ habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new ChangeVolumeComposer((habbo.getHabboStats()).volumeTrax)));
+ habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new OnlineCountComposer(Emulator.getGameEnvironment().getHabboManager().getOnlineCount())));
+ Emulator.getThreading().run(() -> userCheckLoaded(habbo), 500L);
+ }
+
+ @EventHandler
+ public void onUserCreditsEvent(UserCreditsEvent e) {
+ UpdateCreditsComposer creditsComposer = new UpdateCreditsComposer(e.habbo.getHabboInfo().getCredits());
+ e.habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)creditsComposer));
+ }
+
+ @EventHandler
+ public void onUserSavedSettingsEvent(UserSavedSettingsEvent e) {
+ e.habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new ChangeVolumeComposer((e.habbo.getHabboStats()).volumeTrax)));
+ }
+
+ public void onDisable() throws Exception {
+ CommunicationManager.getInstance().Dispose();
+ RoomAudioManager.getInstance().Dispose();
+ OnlineCountRunnable.getInstance().stop();
+ }
+
+ public static CommandManager getCommandManager() {
+ return commandManager;
+ }
+
+ public static void addTwitchRoom(int roomId, String twitch) {
+ twitchRooms.put(Integer.valueOf(roomId), twitch);
+ }
+
+ public boolean hasPermission(Habbo habbo, String s) {
+ return false;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/override_packets/incoming/JavascriptCallbackEvent.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/override_packets/incoming/JavascriptCallbackEvent.java
new file mode 100644
index 0000000..ddda642
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/override_packets/incoming/JavascriptCallbackEvent.java
@@ -0,0 +1,11 @@
+package com.skeletor.plugin.javascript.override_packets.incoming;
+
+import com.eu.habbo.messages.incoming.MessageHandler;
+import com.skeletor.plugin.javascript.communication.CommunicationManager;
+
+public class JavascriptCallbackEvent extends MessageHandler {
+ public void handle() {
+ String payload = this.packet.readString();
+ CommunicationManager.getInstance().OnMessage(payload, this.client);
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/override_packets/outgoing/JavascriptCallbackComposer.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/override_packets/outgoing/JavascriptCallbackComposer.java
new file mode 100644
index 0000000..61178ab
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/override_packets/outgoing/JavascriptCallbackComposer.java
@@ -0,0 +1,21 @@
+package com.skeletor.plugin.javascript.override_packets.outgoing;
+
+import com.eu.habbo.messages.ServerMessage;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.utils.JsonFactory;
+
+public class JavascriptCallbackComposer extends MessageComposer {
+ private OutgoingWebMessage webMessage;
+
+ public JavascriptCallbackComposer(OutgoingWebMessage message) {
+ this.webMessage = message;
+ }
+
+ public ServerMessage composeInternal() {
+ this.response.init(2023);
+ String jsonMessage = JsonFactory.getInstance().toJson(this.webMessage).replace("/", "/");
+ this.response.appendString("habblet/open/" + jsonMessage);
+ return this.response;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/runnables/OnlineCountRunnable.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/runnables/OnlineCountRunnable.java
new file mode 100644
index 0000000..5455839
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/runnables/OnlineCountRunnable.java
@@ -0,0 +1,36 @@
+package com.skeletor.plugin.javascript.runnables;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.common.OnlineCountComposer;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+
+public class OnlineCountRunnable implements Runnable {
+ private static final OnlineCountRunnable instance = new OnlineCountRunnable();
+
+ private volatile boolean running = false;
+
+ public void run() {
+ if (this.running) {
+ int count = Emulator.getGameEnvironment().getHabboManager().getOnlineCount();
+ Emulator.getGameServer().getGameClientManager().sendBroadcastResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)new OnlineCountComposer(count)));
+ Emulator.getThreading().run(this, 30000L);
+ }
+ }
+
+ public static OnlineCountRunnable getInstance() {
+ return instance;
+ }
+
+ public void start() {
+ if (!this.running) {
+ this.running = true;
+ Emulator.getThreading().run(this);
+ }
+ }
+
+ public void stop() {
+ this.running = false;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/scheduler/CheckLoadedScheduler.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/scheduler/CheckLoadedScheduler.java
new file mode 100644
index 0000000..030bca3
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/scheduler/CheckLoadedScheduler.java
@@ -0,0 +1,34 @@
+package com.skeletor.plugin.javascript.scheduler;
+
+import com.eu.habbo.Emulator;
+import com.eu.habbo.core.Scheduler;
+import com.eu.habbo.habbohotel.users.Habbo;
+import com.eu.habbo.messages.outgoing.MessageComposer;
+import com.skeletor.plugin.javascript.communication.outgoing.OutgoingWebMessage;
+import com.skeletor.plugin.javascript.communication.outgoing.common.SessionDataComposer;
+import com.skeletor.plugin.javascript.main;
+import com.skeletor.plugin.javascript.override_packets.outgoing.JavascriptCallbackComposer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CheckLoadedScheduler extends Scheduler {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CheckLoadedScheduler.class);
+
+ public CheckLoadedScheduler() {
+ super(60);
+ run();
+ }
+
+ public void run() {
+ super.run();
+ if (Emulator.getConfig().getBoolean("pop.up.enabled", true))
+ for (Habbo habbo : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().values()) {
+ if (!(habbo.getHabboStats()).cache.containsKey(main.USER_LOADED_EVENT))
+ continue;
+ if (((Boolean)(habbo.getHabboStats()).cache.get(main.USER_LOADED_EVENT)).booleanValue())
+ continue;
+ SessionDataComposer sessionDataComposer = new SessionDataComposer(habbo.getHabboInfo().getId(), habbo.getHabboInfo().getUsername(), habbo.getHabboInfo().getLook(), habbo.getHabboInfo().getCredits());
+ habbo.getClient().sendResponse((MessageComposer)new JavascriptCallbackComposer((OutgoingWebMessage)sessionDataComposer));
+ }
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/utils/JsonFactory.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/utils/JsonFactory.java
new file mode 100644
index 0000000..fa3e5ab
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/utils/JsonFactory.java
@@ -0,0 +1,11 @@
+package com.skeletor.plugin.javascript.utils;
+
+import com.google.gson.Gson;
+
+public class JsonFactory {
+ private static final Gson gson = new Gson();
+
+ public static Gson getInstance() {
+ return gson;
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/utils/RegexUtility.java b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/utils/RegexUtility.java
new file mode 100644
index 0000000..29bd810
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/java/com/skeletor/plugin/javascript/utils/RegexUtility.java
@@ -0,0 +1,15 @@
+package com.skeletor.plugin.javascript.utils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class RegexUtility {
+ public static String getYouTubeId(String youTubeUrl) {
+ String pattern = "(?<=youtu.be/|watch\\?v=|/videos/|embed\\/)[^#\\&\\?]*";
+ Pattern compiledPattern = Pattern.compile(pattern);
+ Matcher matcher = compiledPattern.matcher(youTubeUrl);
+ if (matcher.find())
+ return matcher.group();
+ return "";
+ }
+}
diff --git a/Plugins/Javascript-Plugin/src/main/resources/plugin.json b/Plugins/Javascript-Plugin/src/main/resources/plugin.json
new file mode 100644
index 0000000..64adabf
--- /dev/null
+++ b/Plugins/Javascript-Plugin/src/main/resources/plugin.json
@@ -0,0 +1,5 @@
+{
+ "main" : "com.skeletor.plugin.javascript.main",
+ "name" : "Javascript Plugin",
+ "author" : "skeletor"
+}
\ No newline at end of file