♻️ Refactored MCTPAudio, moved to ACF, removed unneeded things, and more.

This commit is contained in:
stijnb1234 2021-01-28 20:30:21 +01:00
parent 435007a502
commit d523a31310
22 changed files with 652 additions and 525 deletions

View file

@ -0,0 +1,88 @@
package nl.sbdeveloper.mctpaudio;
import co.aikar.commands.PaperCommandManager;
import nl.sbdeveloper.mctpaudio.commands.MCTPAudioCMD;
import nl.sbdeveloper.mctpaudio.listener.LogoutListener;
import nl.sbdeveloper.mctpaudio.listener.WGListener;
import nl.sbdeveloper.mctpaudio.managers.WGManager;
import nl.sbdeveloper.mctpaudio.radio.Playlist;
import nl.sbdeveloper.mctpaudio.socket.Client;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public final class MCTPAudio extends JavaPlugin {
private static Plugin instance;
private static PaperCommandManager commandManager;
private static Client client;
private static Playlist playlist;
public void onEnable() {
Bukkit.getLogger().info("[MCTPAudio] Loading...");
if (!setupPlugins()) {
Bukkit.getLogger().severe("[MCTPAudio] WorldGuard not found! Disabling...");
getServer().getPluginManager().disablePlugin(this);
return;
}
instance = this;
getConfig().addDefault("Regions.demosound", "https://audiopagina.mcthemeparks.eu/gallery/voletarium.mp3");
getConfig().addDefault("HueRegions.demosound", "255_0_0_254");
getConfig().options().copyDefaults(true);
saveConfig();
Bukkit.getLogger().info("[MCTPAudio] Connecting with socket...");
client = new Client("ws://173.249.31.58:8166");
client.connect();
Bukkit.getLogger().info("[MCTPAudio] Loading commands and events...");
commandManager = new PaperCommandManager(this);
commandManager.enableUnstableAPI("help");
commandManager.registerCommand(new MCTPAudioCMD());
Bukkit.getPluginManager().registerEvents(new WGListener(), this);
Bukkit.getPluginManager().registerEvents(new LogoutListener(), this);
Bukkit.getLogger().info("[MCTPAudio] Loading playlist...");
playlist = new Playlist();
Bukkit.getLogger().info("[MCTPAudio] Plugin is enabled!");
}
public void onDisable() {
client.disconnect();
instance = null;
Bukkit.getLogger().info("[MCTPAudio] Plugin is disabled!");
}
private boolean setupPlugins() {
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) {
WGManager.setWorldGuard(getServer().getPluginManager().getPlugin("WorldGuard"));
return true;
}
return false;
}
public static Plugin getPlugin() {
return instance;
}
public static Client getClient() {
return client;
}
public static Playlist getPlaylist() {
return playlist;
}
}

View file

@ -0,0 +1,11 @@
package nl.sbdeveloper.mctpaudio.api;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public enum AudioType {
MUSIC, SFX, RADIO
}

View file

@ -0,0 +1,11 @@
package nl.sbdeveloper.mctpaudio.api;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public enum HueType {
LEFT, MID, RIGHT, ALL
}

View file

@ -0,0 +1,43 @@
package nl.sbdeveloper.mctpaudio.api.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public class AudioConnectionUpdateEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private final Player player;
private final boolean connected;
public AudioConnectionUpdateEvent(@NotNull Player who, boolean connected) {
super(true);
this.player = who;
this.connected = connected;
}
public Player getPlayer() {
return player;
}
public boolean isConnected() {
return connected;
}
@NotNull
@Override
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View file

@ -0,0 +1,40 @@
package nl.sbdeveloper.mctpaudio.api.maps;
import java.util.ArrayList;
import java.util.Random;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
/**
* An {@link ArrayList} with shuffle support.
*
* @param <E> The type you want to store
*/
public class SongList<E> extends ArrayList<E> {
public void shuffle() {
Random random = new Random();
for (int index = 0; index < this.size(); index++) {
int secondIndex = random.nextInt(this.size());
swap(index, secondIndex);
}
}
public E getRandom() {
Random random = new Random();
return this.get(random.nextInt(this.size()));
}
private void swap(int firstIndex, int secondIndex) {
E first = this.get(firstIndex);
E second = this.get(secondIndex);
this.set(secondIndex, first);
this.set(firstIndex, second);
}
}

View file

@ -0,0 +1,188 @@
package nl.sbdeveloper.mctpaudio.commands;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.CommandHelp;
import co.aikar.commands.annotation.*;
import nl.sbdeveloper.mctpaudio.MCTPAudio;
import nl.sbdeveloper.mctpaudio.api.AudioType;
import nl.sbdeveloper.mctpaudio.api.HueType;
import nl.sbdeveloper.mctpaudio.managers.PinManager;
import nl.sbdeveloper.mctpaudio.utils.HeadUtil;
import nl.sbdeveloper.mctpaudio.utils.SpigotPlayerSelector;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.json.simple.JSONObject;
import java.util.ArrayList;
import java.util.List;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
@CommandAlias("mctpaudio")
@CommandPermission("mctp.audio")
public class MCTPAudioCMD extends BaseCommand {
@Default
@HelpCommand
public void onHelp(CommandSender sender, CommandHelp help) {
help.showHelp();
}
@Subcommand("toggleradio")
@Description("")
public void toggleRadio(CommandSender sender) {
if (MCTPAudio.getPlaylist().isRunning()) {
MCTPAudio.getPlaylist().stop();
sender.sendMessage(ChatColor.GRAY + "De auto radio is stopgezet. Zodra het huidige nummer is afgelopen, gebeurt er niks meer.");
} else {
MCTPAudio.getPlaylist().start();
sender.sendMessage(ChatColor.GRAY + "De auto radio is weer gestart.");
}
}
@Subcommand("addsong")
@Description("")
public void onAddSong(CommandSender sender, String url) {
List<String> urls = MCTPAudio.getPlugin().getConfig().getStringList("RadioSongs");
urls.add(url);
MCTPAudio.getPlugin().getConfig().set("RadioSongs", urls);
MCTPAudio.getPlugin().saveConfig();
MCTPAudio.getPlaylist().addSong(url);
sender.sendMessage(ChatColor.GRAY + "Nummer toegevoegd aan de lijst.");
}
@Subcommand("play")
@Description("")
public void onPlay(CommandSender sender, String selector, AudioType type, String url) {
ArrayList<Player> players = new ArrayList<>();
Player target = Bukkit.getPlayer(selector);
if (target != null) {
if (!PinManager.hasPin(target.getUniqueId())) {
sender.sendMessage(ChatColor.GRAY + "Die speler is niet verbonden met de client.");
return;
}
players.add(target);
} else {
SpigotPlayerSelector sel = new SpigotPlayerSelector(selector);
players.addAll(sel.getPlayers(sender));
}
JSONObject data;
for (Player p : players) {
data = new JSONObject();
if (!PinManager.hasPin(p.getUniqueId())) continue;
data.put("task", type.name());
data.put("path", url);
data.put("uuid", p.getUniqueId().toString().replace("-", ""));
MCTPAudio.getClient().sendData(data);
}
sender.sendMessage(ChatColor.GRAY + "Gestart met afspelen!");
}
@Subcommand("hue")
@Description("")
public void onHue(CommandSender sender, String selector, int r, int g, int b, HueType type, @Optional Integer brightness) {
if (brightness != null && (brightness < 0 || brightness > 254)) {
sender.sendMessage(ChatColor.GRAY.toString() + brightness + " is geen correcte brightness.");
return;
}
ArrayList<Player> players = new ArrayList<>();
Player target = Bukkit.getPlayer(selector);
if (target != null) {
if (!PinManager.hasPin(target.getUniqueId())) {
sender.sendMessage(ChatColor.GRAY + "Die speler is niet verbonden met de client.");
return;
}
players.add(target);
} else {
SpigotPlayerSelector sel = new SpigotPlayerSelector(selector);
players.addAll(sel.getPlayers(sender));
}
//CHECK FOR THE REGION SELECTOR -> Then save
if (selector.startsWith("@a") && HeadUtil.getArgument(selector, "region").length() != 0) {
String regionID = HeadUtil.getArgument(selector, "region");
String data = r + "_" + g + "_" + b + "_" + type.name();
if (brightness != null) data += "_" + brightness;
MCTPAudio.getPlugin().getConfig().set("HueRegions." + regionID, data);
MCTPAudio.getPlugin().saveConfig();
}
JSONObject data;
for (Player p : players) {
data = new JSONObject();
if (!PinManager.hasPin(p.getUniqueId())) continue;
data.put("task", "HUE");
data.put("rgb", r + ":" + g + ":" + b);
data.put("type", type.name());
if (brightness != null) data.put("brightness", brightness);
data.put("uuid", p.getUniqueId().toString().replace("-", ""));
MCTPAudio.getClient().sendData(data);
}
sender.sendMessage(ChatColor.GRAY + "Indien de speler(s) is/zijn verbonden met Philips Hue, is de kleur veranderd.");
}
@Subcommand("setregion")
@Description("")
public void onSetRegion(CommandSender sender, String regionName, String url) {
MCTPAudio.getPlugin().getConfig().set("Regions." + regionName, url);
MCTPAudio.getPlugin().saveConfig();
sender.sendMessage(ChatColor.GRAY + "De region zal vanaf nu muziek afspelen.");
}
// @Subcommand("sethueregion")
// @Description("")
// public void onSetHueRegion(CommandSender sender, String regionName, String url) {
// MCTPAudio.getPlugin().getConfig().set("HueRegions." + regionName, url);
// MCTPAudio.getPlugin().saveConfig();
//
// sender.sendMessage(ChatColor.GRAY + "De region zal vanaf nu licht aanpassen.");
// }
@Subcommand("stop")
@Description("")
public void onStop(CommandSender sender, String selector) {
ArrayList<Player> players = new ArrayList<>();
Player target = Bukkit.getPlayer(selector);
if (target != null) {
if (!PinManager.hasPin(target.getUniqueId())) {
sender.sendMessage(ChatColor.GRAY + "Die speler is niet verbonden met de client.");
return;
}
players.add(target);
} else {
SpigotPlayerSelector sel = new SpigotPlayerSelector(selector);
players.addAll(sel.getPlayers(sender));
}
JSONObject data;
for (Player p : players) {
data = new JSONObject();
if (!PinManager.hasPin(p.getUniqueId())) continue;
data.put("task", "STOP");
data.put("uuid", p.getUniqueId().toString().replace("-", ""));
MCTPAudio.getClient().sendData(data);
}
sender.sendMessage(ChatColor.GRAY + "Gestopt met afspelen!");
}
}

View file

@ -0,0 +1,23 @@
package nl.sbdeveloper.mctpaudio.listener;
import nl.sbdeveloper.mctpaudio.MCTPAudio;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.json.simple.JSONObject;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public class LogoutListener implements Listener {
@EventHandler
public void onDisconnect(PlayerQuitEvent e) {
JSONObject data = new JSONObject();
data.put("task", "LOGOUT");
data.put("uuid", e.getPlayer().getUniqueId().toString().replace("-", ""));
MCTPAudio.getClient().sendData(data);
}
}

View file

@ -0,0 +1,126 @@
package nl.sbdeveloper.mctpaudio.listener;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import nl.sbdeveloper.mctpaudio.MCTPAudio;
import nl.sbdeveloper.mctpaudio.managers.PinManager;
import nl.sbdeveloper.mctpaudio.managers.WGManager;
import net.raidstone.wgevents.events.RegionsEnteredEvent;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.json.simple.JSONObject;
import java.util.*;
import java.util.stream.Collectors;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public class WGListener implements Listener {
/**
* Music detection
*/
@EventHandler
public void onMove(PlayerMoveEvent e) {
handlePlayerMovement(e.getPlayer(), e.getFrom(), e.getTo());
}
@EventHandler
public void onTeleport(PlayerTeleportEvent e) {
handlePlayerMovement(e.getPlayer(), e.getFrom(), e.getTo());
}
private void handlePlayerMovement(Player player, Location from, Location to) {
if (to == null || from.getWorld() == null || to.getWorld() == null) return;
if (from.getBlockX() != to.getBlockX() || from.getBlockY() != to.getBlockY() || from.getBlockZ() != to.getBlockZ()) {
Set<String> list = MCTPAudio.getPlugin().getConfig().getConfigurationSection("Regions").getKeys(false);
if (!PinManager.hasPin(Objects.requireNonNull(player).getUniqueId())) return;
List<String> fromRegions = WGManager.getRegionsIn(from).stream().map(ProtectedRegion::getId).collect(Collectors.toList());
List<String> toRegions = WGManager.getRegionsIn(to).stream().map(ProtectedRegion::getId).collect(Collectors.toList());
if ((Collections.disjoint(list, fromRegions) && !Collections.disjoint(list, toRegions)) || (!Collections.disjoint(list, fromRegions) && !Collections.disjoint(list, toRegions))) {
//Walked in a region
if (!Collections.disjoint(list, fromRegions) && !Collections.disjoint(list, toRegions)) {
Optional<String> name = fromRegions.stream().filter(list::contains).findFirst();
Optional<String> name2 = toRegions.stream().filter(list::contains).findFirst();
if (name.isPresent() && name2.isPresent() && name.get().equals(name2.get()))
return; //Beide heeft een region, en dat is dezelfde.
if (name.isPresent() && name2.isPresent()) {
String regionURL = MCTPAudio.getPlugin().getConfig().getString("Regions." + name.get());
String regionURL2 = MCTPAudio.getPlugin().getConfig().getString("Regions." + name2.get());
if (regionURL.equals(regionURL2))
return; //Beide heeft een region, niet dezelfde, maar wel met dezelfde muziek.
}
}
Optional<String> name = toRegions.stream().filter(list::contains).findFirst();
if (!name.isPresent()) return;
String regionURL = MCTPAudio.getPlugin().getConfig().getString("Regions." + name.get());
JSONObject data = new JSONObject();
data.put("task", "MUSIC");
data.put("path", regionURL);
data.put("uuid", player.getUniqueId().toString().replace("-", ""));
MCTPAudio.getClient().sendData(data);
} else if (!Collections.disjoint(list, fromRegions) && Collections.disjoint(list, toRegions)) {
//Not in a region, stop...
JSONObject data = new JSONObject();
data.put("task", "MUSIC");
data.put("path", "");
data.put("uuid", player.getUniqueId().toString().replace("-", ""));
MCTPAudio.getClient().sendData(data);
}
}
}
/**
* Hue detection
*/
@EventHandler
public void onRegionEnter(RegionsEnteredEvent e) {
if (e.getPlayer() == null) return;
Set<String> list2 = MCTPAudio.getPlugin().getConfig().getConfigurationSection("HueRegions").getKeys(false);
if (!Collections.disjoint(list2, e.getRegionsNames())) {
//One element is the same -> In a region
Optional<String> name = e.getRegionsNames().stream().filter(list2::contains).findFirst();
if (!name.isPresent()) return;
String configData = MCTPAudio.getPlugin().getConfig().getString("HueRegions." + name.get());
if (configData == null) return;
String[] configDataSplit = configData.split("_");
int r = Integer.parseInt(configDataSplit[0]);
int g = Integer.parseInt(configDataSplit[1]);
int b = Integer.parseInt(configDataSplit[2]);
String type = configDataSplit[3];
Integer brightness = null;
if (configDataSplit.length == 5) brightness = Integer.parseInt(configDataSplit[4]);
if (!PinManager.hasPin(e.getPlayer().getUniqueId())) return;
JSONObject data = new JSONObject();
data.put("task", "HUE");
data.put("rgb", r + ":" + g + ":" + b);
data.put("type", type);
if (brightness != null) data.put("brightness", brightness);
data.put("uuid", e.getPlayer().getUniqueId().toString().replace("-", ""));
MCTPAudio.getClient().sendData(data);
}
}
}

View file

@ -0,0 +1,75 @@
package nl.sbdeveloper.mctpaudio.managers;
import java.security.SecureRandom;
import java.util.UUID;
import java.util.WeakHashMap;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public class PinManager {
private static final WeakHashMap<UUID, String> pins = new WeakHashMap<>();
/**
* Get the pin of a player
*
* @param pUUID The player UUID
* @return The pin
*/
public static String getPIN(UUID pUUID) {
if (pUUID == null) return null;
if (!pins.containsKey(pUUID)) {
StringBuilder builder = new StringBuilder();
SecureRandom random = new SecureRandom();
for (int i = 0; i < 9; ++i) {
builder.append(random.nextInt(9));
}
String pin = builder.toString();
pins.put(pUUID, pin);
return pin;
} else {
return pins.get(pUUID);
}
}
/**
* Check if a player has a pin
*
* @param pUUID The player UUID
* @return The pin
*/
public static boolean hasPin(UUID pUUID) {
return pUUID != null && pins.containsKey(pUUID);
}
/**
* Check if the pin is correct
*
* @param pUUID The player UUID
* @param pin The pin
* @return true/false
*/
public static boolean checkPin(UUID pUUID, String pin) {
if (pUUID == null || pin == null || pin.isEmpty()) {
return false;
}
return pins.containsKey(pUUID) && pin.equals(pins.get(pUUID));
}
/**
* Remove the pin
*
* @param pUUID The player UUID
*/
public static void removePin(UUID pUUID) {
if (pUUID != null) {
pins.remove(pUUID);
}
}
}

View file

@ -0,0 +1,297 @@
package nl.sbdeveloper.mctpaudio.managers;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.regions.Polygonal2DRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.managers.storage.StorageException;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
/**
* WorldGuard class to make the usage of WorldGuard easy. This is the 1.14.x version!
*
* <i>Note that if you do use this in one of your projects, leave this notice.</i>
* <i>Please do credit me if you do use this in one of your projects.</i>
*
* @author SBDeveloper [Fixed 1.13+ support]
*/
public class WGManager {
public static WorldGuardPlugin wgp;
public static WorldEditPlugin wep;
public static boolean hasWorldGuard() {
return wgp != null;
}
public static boolean hasWorldEdit() {
return wep != null;
}
public static boolean setWorldGuard(Plugin plugin) {
wgp = (WorldGuardPlugin) plugin;
return true;
}
public static boolean setWorldEdit(Plugin plugin) {
wep = (WorldEditPlugin) plugin;
return true;
}
public static ProtectedRegion createRegion(Player p, String id) throws StorageException {
LocalSession l = WorldEdit.getInstance().getSessionManager().get(BukkitAdapter.adapt(p));
Region s;
try {
s = l.getSelection(l.getSelectionWorld());
} catch (IncompleteRegionException e) {
return null;
}
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(p.getWorld()));
rm.removeRegion(id);
ProtectedRegion region;
// Detect the type of region from WorldEdit
if (s instanceof Polygonal2DRegion) {
Polygonal2DRegion polySel = (Polygonal2DRegion) s;
int minY = polySel.getMinimumY();
int maxY = polySel.getMaximumY();
region = new ProtectedPolygonalRegion(id, polySel.getPoints(), minY, maxY);
} else { /// default everything to cuboid
region = new ProtectedCuboidRegion(id,
s.getMinimumPoint(),
s.getMaximumPoint());
}
region.setPriority(11); /// some relatively high priority
region.setFlag(Flags.INTERACT, State.DENY);
region.setFlag(Flags.INTERACT.getRegionGroupFlag(), RegionGroup.NON_MEMBERS);
rm.addRegion(region);
rm.save();
return region;
}
public static ArrayList<ProtectedRegion> getRegionsIn(Location loc) {
ArrayList<ProtectedRegion> inRegions = new ArrayList<>();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(loc.getWorld()));
for (ProtectedRegion protectedRegion : rm.getApplicableRegions(BukkitAdapter.asBlockVector(loc)))
inRegions.add(protectedRegion);
return inRegions;
}
public static ProtectedRegion getRegionfromStringList(List<String> str, Location loc) {
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(loc.getWorld()));
ApplicableRegionSet mogreg = rm.getApplicableRegions(BukkitAdapter.asBlockVector(loc));
for (ProtectedRegion mogregion : mogreg) {
for (String strgo : str) {
if (strgo.equalsIgnoreCase(mogregion.getId())) {
return mogregion;
}
}
}
//Niks gevonden!
return null;
}
public static ProtectedRegion getRegionfromString(String str, Location loc) {
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(loc.getWorld()));
ApplicableRegionSet mogreg = rm.getApplicableRegions(BukkitAdapter.asBlockVector(loc));
for (ProtectedRegion mogregion : mogreg) {
if (str.equalsIgnoreCase(mogregion.getId())) {
return mogregion;
}
}
//Niks gevonden!
return null;
}
public static ProtectedRegion getRegionfromStringListInWorld(List<String> str, Location loc) {
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(loc.getWorld()));
Map<String, ProtectedRegion> mp = rm.getRegions();
for (Entry<String, ProtectedRegion> pair : mp.entrySet()) {
for (String string : str) {
if (pair.getValue().getId().equals(string)) {
return pair.getValue();
}
}
}
//Niks gevonden!
return null;
}
public static ProtectedRegion getRegionfromStringInWorld(String str, Location loc) {
String strgood = str.toLowerCase();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(loc.getWorld()));
Map<String, ProtectedRegion> mp = rm.getRegions();
return mp.get(strgood);
}
public static boolean isMember(Player p, ProtectedRegion region, OfflinePlayer target) {
World w = p.getWorld();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
ProtectedRegion currentRegion = rm.getRegion(region.getId());
DefaultDomain currentMembers = currentRegion.getMembers();
return currentMembers.contains(target.getUniqueId());
}
public static boolean isOwner(Player p, ProtectedRegion region, OfflinePlayer target) {
World w = p.getWorld();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
ProtectedRegion currentRegion = rm.getRegion(region.getId());
DefaultDomain currentOwners = currentRegion.getOwners();
return currentOwners.contains(target.getUniqueId());
}
public static boolean addMember(Player p, ProtectedRegion region, OfflinePlayer newmember) {
try {
World w = p.getWorld();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
ProtectedRegion currentRegion = rm.getRegion(region.getId());
DefaultDomain currentMembers = currentRegion.getMembers();
currentMembers.addPlayer(UUID.fromString(newmember.getUniqueId().toString()));
rm.save();
return true;
} catch (StorageException e) {
return false;
}
}
public static boolean addOwner(Player p, ProtectedRegion region, OfflinePlayer newowner) {
try {
World w = p.getWorld();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
ProtectedRegion currentRegion = rm.getRegion(region.getId());
DefaultDomain currentOwners = currentRegion.getOwners();
currentOwners.addPlayer(UUID.fromString(newowner.getUniqueId().toString()));
rm.save();
return true;
} catch (StorageException e) {
return false;
}
}
public static boolean removeMember(Player p, ProtectedRegion region, OfflinePlayer newmember) {
try {
World w = p.getWorld();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
ProtectedRegion currentRegion = rm.getRegion(region.getId());
DefaultDomain currentMembers = currentRegion.getMembers();
currentMembers.removePlayer(UUID.fromString(newmember.getUniqueId().toString()));
rm.save();
return true;
} catch (StorageException e) {
return false;
}
}
public static boolean removeOwner(Player p, ProtectedRegion region, UUID newowner) {
try {
World w = p.getWorld();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
ProtectedRegion currentRegion = rm.getRegion(region.getId());
DefaultDomain currentOwners = currentRegion.getOwners();
currentOwners.removePlayer(newowner);
rm.save();
return true;
} catch (StorageException e) {
return false;
}
}
public static ArrayList<String> getMembers(Player p, ProtectedRegion region) {
World w = p.getWorld();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
ProtectedRegion currentRegion = rm.getRegion(region.getId());
DefaultDomain currentMembers = currentRegion.getMembers();
ArrayList<String> members = new ArrayList<>();
for (UUID uuid : currentMembers.getUniqueIds()) {
OfflinePlayer member = Bukkit.getServer().getOfflinePlayer(uuid);
members.add(member.getName());
}
return members;
}
public static ArrayList<String> getOwners(Player p, ProtectedRegion region) {
World w = p.getWorld();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
ProtectedRegion currentRegion = rm.getRegion(region.getId());
DefaultDomain currentOwners = currentRegion.getOwners();
ArrayList<String> owners = new ArrayList<>();
for (UUID uuid : currentOwners.getUniqueIds()) {
OfflinePlayer owner = Bukkit.getServer().getOfflinePlayer(uuid);
owners.add(owner.getName());
}
return owners;
}
public static boolean removeRegion(Player p, String name) {
try {
World w = p.getWorld();
RegionManager rm = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
ProtectedRegion currentRegion = rm.getRegion(name);
if (currentRegion == null) {
return false;
}
rm.removeRegion(name);
rm.save();
return true;
} catch (StorageException e) {
return false;
}
}
}

View file

@ -0,0 +1,139 @@
package nl.sbdeveloper.mctpaudio.radio;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.UnsupportedTagException;
import nl.sbdeveloper.mctpaudio.MCTPAudio;
import nl.sbdeveloper.mctpaudio.api.maps.SongList;
import nl.sbdeveloper.mctpaudio.managers.PinManager;
import nl.sbdeveloper.mctpaudio.utils.HeadUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import org.json.simple.JSONObject;
import java.io.IOException;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public class Playlist {
private SongList<String> playList = new SongList<>();
private final SongList<String> playedList = new SongList<>();
private boolean running = false;
private BukkitTask currentTimer;
/**
* Create a new PlayList object
* Starts the playlist
*/
public Playlist() {
start();
}
/**
* Start this playlist
*/
public void start() {
for (String URL : MCTPAudio.getPlugin().getConfig().getStringList("RadioSongs")) {
addSong(URL);
}
Bukkit.getScheduler().runTaskAsynchronously(MCTPAudio.getPlugin(), this::nextSong);
running = true;
}
/**
* Stop the playlist
*/
public void stop() {
playList.clear();
if (currentTimer != null) {
currentTimer.cancel();
currentTimer = null;
}
running = false;
}
/**
* Add a song by the url
*
* @param url The song url (mp3)
*/
public void addSong(String url) {
playList.add(url);
playList.shuffle();
}
/**
* Go to the next song
*/
public void nextSong() {
if (currentTimer != null) return;
if (playList.isEmpty()) {
//All numbers played
playList = (SongList<String>) playedList.clone(); //Copy a clone.
playedList.clear();
}
//Get song
String nextURL = playList.getRandom();
if (nextURL == null) return;
playList.remove(nextURL);
playedList.add(nextURL);
JSONObject data;
for (Player p : Bukkit.getOnlinePlayers()) {
data = new JSONObject();
if (!PinManager.hasPin(p.getUniqueId())) continue;
data.put("task", "RADIO");
data.put("path", nextURL);
data.put("uuid", p.getUniqueId().toString().replace("-", ""));
MCTPAudio.getClient().sendData(data);
}
int ticks;
try {
ticks = HeadUtil.getTicksOfFile(nextURL);
} catch (IOException | InvalidDataException | UnsupportedTagException e) {
e.printStackTrace();
nextSong();
return;
}
if (ticks == 0) {
Bukkit.getLogger().info("0 ticks");
nextSong();
return;
}
Bukkit.getLogger().info("Started song with duration: " + ticks / 20 + " sec.");
currentTimer = Bukkit.getScheduler().runTaskLaterAsynchronously(MCTPAudio.getPlugin(), () -> {
currentTimer = null;
nextSong();
}, ticks);
//Shuffle playlist again
playList.shuffle();
}
/**
* Check if the playlist is running
*
* @return true if running
*/
public boolean isRunning() {
return running;
}
}

View file

@ -0,0 +1,199 @@
package nl.sbdeveloper.mctpaudio.socket;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import nl.sbdeveloper.mctpaudio.MCTPAudio;
import nl.sbdeveloper.mctpaudio.api.events.AudioConnectionUpdateEvent;
import nl.sbdeveloper.mctpaudio.managers.PinManager;
import nl.sbdeveloper.mctpaudio.managers.WGManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.simple.JSONObject;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public class Client {
private final String url;
private int taskID = 0;
private int controlID = 0;
private WebSocketClient wsc;
private boolean connected = false;
/**
* Construct a new client
*
* @param url The URL to connect to
*/
public Client(String url) {
this.url = url;
}
/**
* Connect to the websocket
*/
public void connect() {
if (!this.connected) {
this.connected = true;
this.controlID = Bukkit.getScheduler().runTaskTimer(MCTPAudio.getPlugin(), () -> {
if (!this.connected) {
Bukkit.getScheduler().cancelTask(this.controlID);
this.controlID = 0;
} else if (this.wsc == null || !this.wsc.isOpen()) {
if (this.wsc != null) {
this.wsc.closeConnection(404, "Disconnected from socket");
this.wsc = null;
}
this.connect();
}
}, 600L, 600L).getTaskId();
}
if (this.url != null && this.wsc == null) {
try {
URI uri = new URI(this.url + "?type=SERVER&");
this.wsc = new WebSocketClient(uri) {
@Override
public void onOpen(ServerHandshake serverHandshake) {
}
@Override
public void onMessage(String s) {
JSONObject json = JSONUtil.parse(s);
if (json == null) return;
String str = JSONUtil.getValue(json, "task");
if (str == null || str.isEmpty()) return;
if (str.equals("VERIFY")) {
String uuid = JSONUtil.getValue(json, "uuid");
if (uuid == null || uuid.isEmpty()) return;
String pin = JSONUtil.getValue(json, "pin");
if (pin == null || pin.isEmpty()) return;
UUID pUUID = JSONUtil.formatFromInput(uuid);
boolean verified = false;
if (Bukkit.getPlayer(pUUID) != null) {
verified = PinManager.checkPin(pUUID, pin);
}
Player p = Bukkit.getPlayer(pUUID);
if (p != null && p.isOnline()) {
AudioConnectionUpdateEvent event = new AudioConnectionUpdateEvent(p, true);
Bukkit.getPluginManager().callEvent(event);
List<String> regions = WGManager.getRegionsIn(p.getLocation()).stream().map(ProtectedRegion::getId).collect(Collectors.toList());
Set<String> list = MCTPAudio.getPlugin().getConfig().getConfigurationSection("Regions").getKeys(false);
Optional<String> regionName = regions.stream().filter(list::contains).findFirst();
regionName.ifPresent(name -> {
String regionURL = MCTPAudio.getPlugin().getConfig().getString("Regions." + name);
JSONObject data = new JSONObject();
data.put("task", "MUSIC");
data.put("path", regionURL);
data.put("uuid", p.getUniqueId().toString().replace("-", ""));
MCTPAudio.getClient().sendData(data);
});
}
JSONObject reply = new JSONObject();
reply.put("task", "AUTHENTICATION");
reply.put("verified", verified);
reply.put("uuid", uuid);
this.send(reply.toJSONString());
} else if (str.equals("DISCONNECTED")) {
String uuid = JSONUtil.getValue(json, "uuid");
if (uuid == null || uuid.isEmpty()) return;
UUID pUUID = JSONUtil.formatFromInput(uuid);
Player p = Bukkit.getPlayer(pUUID);
if (p != null && p.isOnline()) {
AudioConnectionUpdateEvent event = new AudioConnectionUpdateEvent(p, false);
Bukkit.getPluginManager().callEvent(event);
}
}
}
@Override
public void onClose(int i, String s, boolean b) {
Client.this.wsc = null;
Bukkit.getScheduler().cancelTask(Client.this.taskID);
Client.this.taskID = 0;
}
@Override
public void onError(Exception e) {
e.printStackTrace();
}
};
this.wsc.connect();
if (this.taskID == 0) {
this.taskID = Bukkit.getScheduler().runTaskTimerAsynchronously(MCTPAudio.getPlugin(), () -> {
if (Client.this.wsc != null && Client.this.wsc.isOpen()) {
Client.this.wsc.send("__PING__");
} else {
if (Client.this.wsc != null) {
Client.this.wsc.closeConnection(404, "Disconnected from socket");
Client.this.wsc = null;
}
Bukkit.getScheduler().cancelTask(Client.this.taskID);
Client.this.taskID = 0;
}
}, 200L, 200L).getTaskId();
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
/**
* Disconnect from socket
*/
public void disconnect() {
if (this.wsc != null) {
this.wsc.closeConnection(404, "Disconnected from socket");
}
this.wsc = null;
if (this.taskID != 0) {
Bukkit.getScheduler().cancelTask(this.taskID);
this.taskID = 0;
}
this.connected = false;
if (this.controlID != 0) {
Bukkit.getScheduler().cancelTask(this.controlID);
this.controlID = 0;
}
}
public void sendData(JSONObject object) {
if (this.wsc != null && this.wsc.isOpen() && object != null && object.toJSONString() != null) {
this.wsc.send(object.toJSONString());
}
}
}

View file

@ -0,0 +1,56 @@
package nl.sbdeveloper.mctpaudio.socket;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.UUID;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public class JSONUtil {
public static JSONObject parse(String string) {
try {
JSONParser parser = new JSONParser();
return (JSONObject) parser.parse(string);
} catch (ParseException ignored) {
}
return null;
}
public static String getValue(JSONObject object, String string) {
if (object != null && !object.isEmpty()) {
Object obj = object.get(string);
String str = null;
if (obj != null) str = String.valueOf(obj);
return str;
}
return null;
}
public static UUID formatFromInput(String uuid) throws IllegalArgumentException {
if (uuid == null) throw new IllegalArgumentException();
uuid = uuid.trim();
return uuid.length() == 32 ? fromTrimmed(uuid.replaceAll("-", "")) : UUID.fromString(uuid);
}
public static UUID fromTrimmed(String trimmedUUID) throws IllegalArgumentException {
if (trimmedUUID == null) throw new IllegalArgumentException();
StringBuilder builder = new StringBuilder(trimmedUUID.trim());
/* Backwards adding to avoid index adjustments */
try {
builder.insert(20, "-");
builder.insert(16, "-");
builder.insert(12, "-");
builder.insert(8, "-");
} catch (StringIndexOutOfBoundsException e) {
throw new IllegalArgumentException();
}
return UUID.fromString(builder.toString());
}
}

View file

@ -0,0 +1,93 @@
package nl.sbdeveloper.mctpaudio.utils;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.Mp3File;
import com.mpatric.mp3agic.UnsupportedTagException;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
/**
* Read the head of a MP3 file.
*/
public class HeadUtil {
public static String getArgument(String selector, String key) {
StringBuilder result = new StringBuilder();
String[] arguments = selector.split(key + "=");
if (arguments.length == 1) return "";
for (byte type : arguments[1].getBytes()) {
char element = (char) type;
if (element == ',' || element == ']') {
return result.toString();
} else {
result.append(element);
}
}
return result.toString().replaceAll("\\.", "");
}
private static String downloadFromUrl(URL url, String localFilename) throws IOException {
InputStream is = null;
FileOutputStream fos = null;
String tempDir = System.getProperty("java.io.tmpdir");
String outputPath = tempDir + "/" + localFilename;
try {
//connect
URLConnection urlConn = url.openConnection();
//get inputstream from connection
is = urlConn.getInputStream();
fos = new FileOutputStream(outputPath);
// 4KB buffer
byte[] buffer = new byte[4096];
int length;
// read from source and write into local file
while ((length = is.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
return outputPath;
} finally {
try {
if (is != null) {
is.close();
}
} finally {
if (fos != null) {
fos.close();
}
}
}
}
public static int getTicksOfFile(String input) throws IOException, InvalidDataException, UnsupportedTagException {
URL url = new URL(input);
String result = downloadFromUrl(url, FilenameUtils.getName(url.getPath()));
File file = new File(result);
if (!file.exists()) return 0;
Mp3File mp3File = new Mp3File(file);
long sec = mp3File.getLengthInSeconds();
file.delete();
return (int) (sec * 20);
}
}

View file

@ -0,0 +1,154 @@
package nl.sbdeveloper.mctpaudio.utils;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import nl.sbdeveloper.mctpaudio.managers.WGManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/* Copyright (C) McThemeParks - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Stijn Bannink <stijnbannink23@gmail.com>, July 2020
*/
public class SpigotPlayerSelector {
private final String selector;
public SpigotPlayerSelector(String selector) {
this.selector = selector;
}
/**
* this turns selectors like @a[r=5] into a usable list, since
* 1.13 spigot removed this feature, FOR SOME REASON.. thanks guys..
*
* @param commandSender the sender
* @return players following the selector
*/
public List<Player> getPlayers(CommandSender commandSender) {
List<Player> players = new ArrayList<>();
if (selector.startsWith("@p")) {
//get Location
Location standPoint = getLocation(commandSender);
if (getArgument("r").length() != 0) {
int radius = Integer.parseInt(getArgument("r"));
Player nearest = Bukkit.getOnlinePlayers().stream()
.filter(player -> player.getLocation().getWorld().getName().equals(standPoint.getWorld().getName()))
.min(Comparator.comparing(player -> player.getLocation().distance(standPoint)))
.filter(player -> radius > player.getLocation().distance(standPoint))
.get();
players.add(nearest);
}
if (getArgument("distance").length() != 0) {
int distance = Integer.parseInt(getArgument("distance"));
Player nearest = Bukkit.getOnlinePlayers().stream()
.filter(player -> player.getLocation().getWorld().getName().equals(standPoint.getWorld().getName()))
.min(Comparator.comparing(player -> player.getLocation().distance(standPoint)))
.filter(player -> distance > player.getLocation().distance(standPoint))
.get();
players.add(nearest);
} else {
Bukkit.getOnlinePlayers().stream()
.filter(player -> player.getLocation().getWorld().getName().equals(standPoint.getWorld().getName()))
.min(Comparator.comparing(player -> player.getLocation().distance(standPoint)))
.ifPresent(players::add);
}
} else if (selector.startsWith("@a")) {
//everyone
Location standPoint = getLocation(commandSender);
if (getArgument("region").length() != 0) {
String regionID = getArgument("region");
for (Player p : Bukkit.getOnlinePlayers()) {
ArrayList<ProtectedRegion> regions = WGManager.getRegionsIn(p.getLocation());
if (regions.stream().anyMatch(region -> region.getId().equalsIgnoreCase(regionID))) {
players.add(p);
}
}
} else if (getArgument("r").length() != 0) {
int radius = Integer.parseInt(getArgument("r"));
players.addAll(Bukkit.getOnlinePlayers().stream()
.filter(player -> player.getLocation().getWorld().getName().equals(standPoint.getWorld().getName()))
.filter(player -> radius > player.getLocation().distance(standPoint))
.collect(Collectors.toList()));
} else if (getArgument("distance").length() != 0) {
int distance = Integer.parseInt(getArgument("distance"));
players.addAll(Bukkit.getOnlinePlayers().stream()
.filter(player -> player.getLocation().getWorld().getName().equals(standPoint.getWorld().getName()))
.filter(player -> distance > player.getLocation().distance(standPoint))
.collect(Collectors.toList()));
} else {
players.addAll(Bukkit.getOnlinePlayers().stream()
.filter(player -> player.getLocation().getWorld().getName().equals(standPoint.getWorld().getName()))
.collect(Collectors.toList()));
}
} else if (selector.length() <= 16) {
//player
Player player = Bukkit.getPlayer(selector);
if (player != null) players.add(player);
} else {
//you fucked it
commandSender.sendMessage("Invalid player query. Try something like @a, @p, username or other arguments.");
}
return players;
}
/**
* attempt to parse the location
*
* @param commandSender the sender
* @return the location or null
*/
private Location getLocation(CommandSender commandSender) {
Location initialLocation = new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
if (commandSender instanceof Player) {
initialLocation = ((Player) commandSender).getLocation();
} else if (commandSender instanceof BlockCommandSender) {
initialLocation = ((BlockCommandSender) commandSender).getBlock().getLocation();
}
if (!getArgument("x").equals("") && !getArgument("y").equals("") && !getArgument("z").equals("")) {
try {
int x = Integer.parseInt(getArgument("x"));
int y = Integer.parseInt(getArgument("y"));
int z = Integer.parseInt(getArgument("z"));
return new Location(initialLocation.getWorld(), x, y, z);
} catch (Exception e) {
commandSender.sendMessage("An error occurred when parsing the location as an Integer");
return initialLocation;
}
}
return initialLocation;
}
private String getArgument(String key) {
StringBuilder result = new StringBuilder();
String[] arguments = selector.split(key + "=");
if (arguments.length == 1) return "";
for (byte type : arguments[1].getBytes()) {
char element = (char) type;
if (element == ',' || element == ']') {
return result.toString();
} else {
result.append(element);
}
}
return result.toString().replaceAll("\\.", "");
}
}