Change playlist system, and some other fixes

This commit is contained in:
stijnb1234 2020-06-23 14:16:20 +02:00
parent bc109013f3
commit 4b9c5d3a59
13 changed files with 950 additions and 65 deletions

View file

@ -4,6 +4,7 @@
<root id="archive" name="MCTPAudio.jar">
<element id="module-output" name="MCTPAudio" />
<element id="extracted-dir" path="$USER_HOME$/Downloads/Java-WebSocket-1.3.8.jar" path-in-jar="/" />
<element id="extracted-dir" path="$USER_HOME$/Downloads/mp3agic-0.9.1.jar" path-in-jar="/" />
</root>
</artifact>
</component>

124
.idea/uiDesigner.xml generated Normal file
View file

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View file

@ -16,20 +16,9 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library" scope="PROVIDED">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/Documents/Minecarft Test Server 1.14.4/server.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/Documents/Minecarft Test Server 1.14.4/server.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="library" scope="PROVIDED" name="spigot-1.14.4" level="project" />
<orderEntry type="library" name="Java-WebSocket-1.3.8" level="project" />
<orderEntry type="module-library">
<orderEntry type="library" scope="PROVIDED" name="Java-WebSocket-1.3.8" level="project" />
<orderEntry type="module-library" scope="PROVIDED">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/Downloads/WorldGuardEvents.jar!/" />
@ -38,7 +27,7 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<orderEntry type="module-library" scope="PROVIDED">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/Downloads/worldedit-bukkit-7.1.0.jar!/" />
@ -47,7 +36,7 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<orderEntry type="module-library" scope="PROVIDED">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/Downloads/worldguard-bukkit-7.0.2.jar!/" />
@ -56,5 +45,14 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$USER_HOME$/Downloads/mp3agic-0.9.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

View file

@ -1,8 +1,11 @@
package me.mctp;
import me.mctp.commands.MCTPAudioCMD;
import me.mctp.commands.MCTPShowCMD;
import me.mctp.listener.LogoutListener;
import me.mctp.listener.WGListener;
import me.mctp.managers.WGManager;
import me.mctp.radio.Playlist;
import me.mctp.socket.Client;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -14,6 +17,7 @@ public class Main extends JavaPlugin implements Listener {
private static Plugin pl;
private static Client client;
private static Playlist playlist;
public static String prefix = (ChatColor.GOLD + "[" + ChatColor.YELLOW + "MCTP" + ChatColor.GOLD + "] " + ChatColor.GRAY);
@ -29,6 +33,7 @@ public class Main extends JavaPlugin implements Listener {
}
getConfig().addDefault("Regions.demosound", "https://audiopagina.mcthemeparks.eu/gallery/voletarium.mp3");
getConfig().addDefault("HueRegions.demosound", "255_0_0_254");
getConfig().options().copyDefaults(true);
saveConfig();
@ -37,12 +42,15 @@ public class Main extends JavaPlugin implements Listener {
client = new Client("ws://144.91.100.169:30217");
client.connect();
getCommand("audio").setExecutor(new MCTPAudioCmd());
getCommand("mctpaudio").setExecutor(new MCTPAudioCmd());
getCommand("audio").setExecutor(new MCTPAudioCMD());
getCommand("mctpaudio").setExecutor(new MCTPAudioCMD());
getCommand("mctpshow").setExecutor(new MCTPShowCMD());
Bukkit.getPluginManager().registerEvents(new WGListener(), this);
Bukkit.getPluginManager().registerEvents(new LogoutListener(), this);
playlist = new Playlist();
Bukkit.getLogger().info(prefix + " __ __ ____ _____ ____ _ _ _ ");
Bukkit.getLogger().info(prefix + " | \\/ |/ ___|_ _| _ \\ / \\ _ _ __| (_) ___ ");
Bukkit.getLogger().info(prefix + " | |\\/| | | | | | |_) / _ \\| | | |/ _` | |/ _ \\ ");
@ -75,4 +83,8 @@ public class Main extends JavaPlugin implements Listener {
public static Client getClient() {
return client;
}
public static Playlist getPlaylist() {
return playlist;
}
}

View file

@ -0,0 +1,28 @@
package me.mctp.api.maps;
import java.util.*;
public class Playlist<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

@ -1,8 +1,10 @@
package me.mctp;
package me.mctp.commands;
import me.mctp.Main;
import me.mctp.api.AudioType;
import me.mctp.api.HueType;
import me.mctp.managers.PinManager;
import me.mctp.utils.HeadUtil;
import me.mctp.utils.SpigotPlayerSelector;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
@ -15,11 +17,13 @@ import org.bukkit.entity.Player;
import org.json.simple.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class MCTPAudioCmd implements CommandExecutor {
public class MCTPAudioCMD implements CommandExecutor {
public static String prefix = (ChatColor.GOLD + "[" + ChatColor.YELLOW + "MCTP" + ChatColor.GOLD + "] " + ChatColor.GRAY);
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandlabel, String[] args) {
if (cmd.getName().equalsIgnoreCase("mctpaudio")) {
if (!sender.hasPermission("mctp.audio")) {
@ -27,9 +31,24 @@ public class MCTPAudioCmd implements CommandExecutor {
return true;
}
// /mctpaudio play SELECTOR TYPE URL
// /mctpaudio stop SELECTOR TYPE
if (args.length == 4 && args[0].equalsIgnoreCase("play")) {
if (args.length == 1 && args[0].equalsIgnoreCase("toggleradio")) {
if (Main.getPlaylist().isRunning()) {
Main.getPlaylist().stop();
sender.sendMessage(prefix + "De auto radio is stopgezet. Zodra het huidige nummer is afgelopen, gebeurt er niks meer.");
} else {
Main.getPlaylist().init();
sender.sendMessage(prefix + "De auto radio is weer gestart.");
}
return true;
} else if (args.length == 2 && args[0].equalsIgnoreCase("addsong")) {
List<String> urls = Main.getPlugin().getConfig().getStringList("RadioSongs");
urls.add(args[1]);
Main.getPlugin().getConfig().set("RadioSongs", urls);
Main.getPlugin().saveConfig();
Main.getPlaylist().addSong(args[1]);
sender.sendMessage(prefix + "Nummer toegevoegd aan de lijst.");
return true;
} else if (args.length == 4 && args[0].equalsIgnoreCase("play")) {
AudioType type;
try {
type = AudioType.valueOf(args[2].toUpperCase());
@ -116,6 +135,16 @@ public class MCTPAudioCmd implements CommandExecutor {
players.addAll(selector.getPlayers(sender));
}
//CHECK FOR THE REGION SELECTOR -> Then save
if (args[1].startsWith("@a") && HeadUtil.getArgument(args[1], "region").length() != 0) {
String regionID = HeadUtil.getArgument(args[1], "region");
String data = r + "_" + g + "_" + b + "_" + type.name();
if (brightness != null) data += "_" + brightness;
Main.getPlugin().getConfig().set("HueRegions." + regionID, data);
Main.getPlugin().saveConfig();
}
JSONObject data;
for (Player p : players) {
data = new JSONObject();

View file

@ -0,0 +1,81 @@
package me.mctp.commands;
import me.mctp.Main;
import me.mctp.utils.Laser;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashMap;
import java.util.Map;
public class MCTPShowCMD implements CommandExecutor {
public static String prefix = (ChatColor.GOLD + "[" + ChatColor.YELLOW + "MCTP" + ChatColor.GOLD + "] " + ChatColor.GRAY);
private Map<Player, LaserRunnable> lasers =new HashMap<>();
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandlabel, String[] args) {
if (cmd.getName().equalsIgnoreCase("mctpshow")) {
if (!sender.hasPermission("mctp.show")) {
sender.sendMessage(prefix + "You don't have the permission to do this.");
return true;
}
if (args.length == 1 && args[0].equalsIgnoreCase("demo")) {
Player p = (Player) sender;
if (lasers.containsKey(p)){
lasers.get(p).cancel();
}else {
try{
lasers.put(p, new LaserRunnable(p));
lasers.get(p).runTaskTimer(Main.getPlugin(), 5, 1);
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
}
}
}
return true;
}
public class LaserRunnable extends BukkitRunnable {
public static final byte LOADING_TIME = 30;
public static final byte RANGE = 10;
private final Laser laser;
private final Player p;
public byte loading = 0;
public LaserRunnable(Player p) throws ReflectiveOperationException{
this.p = p;
this.laser = new Laser(p.getLocation(), p.getLocation().add(0, 1, 0), -1, 50);
this.laser.start(Main.getPlugin());
}
public void run(){
if (loading != LOADING_TIME){
loading++;
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 0.7f, loading == LOADING_TIME ? 1.5f : 0.2f);
}
try{
laser.moveStart(p.getLocation().add(0, 0.8, 0));
laser.moveEnd(p.getLocation().add(0, 1.2, 0).add(p.getLocation().getDirection().multiply(loading == LOADING_TIME ? RANGE : loading / (LOADING_TIME / RANGE * 1.3))));
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
}
public synchronized void cancel() throws IllegalStateException{
laser.stop();
lasers.remove(p);
super.cancel();
}
}
}

View file

@ -1,69 +1,105 @@
package me.mctp.listener;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.mctp.Main;
import me.mctp.managers.PinManager;
import me.mctp.managers.WGManager;
import net.raidstone.wgevents.events.RegionsEnteredEvent;
import net.raidstone.wgevents.events.RegionsLeftEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.json.simple.JSONObject;
import java.util.Collections;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
public class WGListener implements Listener {
/** Music detection */
@EventHandler
public void onRegionEnter(RegionsEnteredEvent e) {
Set<String> list = Main.getPlugin().getConfig().getConfigurationSection("Regions").getKeys(false);
Set<String> list2 = Main.getPlugin().getConfig().getConfigurationSection("HueRegions").getKeys(false);
public void onMove(PlayerMoveEvent e) {
if (e.getTo() == null || e.getFrom().getWorld() == null || e.getTo().getWorld() == null) return;
if (!Collections.disjoint(list, e.getRegionsNames())) {
//One element is the same -> In a region
Optional<String> name = e.getRegionsNames().stream().filter(list::contains).findFirst();
if (!name.isPresent()) return;
String regionURL = Main.getPlugin().getConfig().getString("Regions." + name.get());
JSONObject data = new JSONObject();
if (e.getFrom().getBlockX() != e.getTo().getBlockX() || e.getFrom().getBlockY() != e.getTo().getBlockY() || e.getFrom().getBlockZ() != e.getTo().getBlockZ()) {
Set<String> list = Main.getPlugin().getConfig().getConfigurationSection("Regions").getKeys(false);
if (!PinManager.hasPin(Objects.requireNonNull(e.getPlayer()).getUniqueId())) return;
data.put("task", "MUSIC");
data.put("path", regionURL);
data.put("uuid", e.getPlayer().getUniqueId().toString().replace("-", ""));
Main.getClient().sendData(data);
}
List<ProtectedRegion> regions = WGManager.getRegionsIn(e.getFrom());
List<String> regionNames = regions.stream().map(ProtectedRegion::getId).collect(Collectors.toList());
List<ProtectedRegion> regions2 = WGManager.getRegionsIn(e.getTo());
List<String> regionNames2 = regions2.stream().map(ProtectedRegion::getId).collect(Collectors.toList());
if (!Collections.disjoint(list2, e.getRegionsNames())) {
//One element is the same -> In a region
if ((Collections.disjoint(list, regionNames) && !Collections.disjoint(list, regionNames2)) || (!Collections.disjoint(list, regionNames) && !Collections.disjoint(list, regionNames2))) {
//Walked in a region
//TODO Add hue support
if (!Collections.disjoint(list, regionNames) && !Collections.disjoint(list, regionNames2)) {
Optional<String> name = regionNames.stream().filter(list::contains).findFirst();
Optional<String> name2 = regionNames2.stream().filter(list::contains).findFirst();
if (name.isPresent() && name2.isPresent() && name.get().equals(name2.get())) {
return;
}
if (name.isPresent() && name2.isPresent()) {
String regionURL = Main.getPlugin().getConfig().getString("Regions." + name.get());
String regionURL2 = Main.getPlugin().getConfig().getString("Regions." + name2.get());
if (regionURL.equals(regionURL2)) {
return;
}
}
}
Optional<String> name = regionNames2.stream().filter(list::contains).findFirst();
if (!name.isPresent()) return;
String regionURL = Main.getPlugin().getConfig().getString("Regions." + name.get());
JSONObject data = new JSONObject();
data.put("task", "MUSIC");
data.put("path", regionURL);
data.put("uuid", e.getPlayer().getUniqueId().toString().replace("-", ""));
Main.getClient().sendData(data);
} else if (!Collections.disjoint(list, regionNames) && Collections.disjoint(list, regionNames2)) {
//Not in a region, stop...
JSONObject data = new JSONObject();
data.put("task", "MUSIC");
data.put("path", "");
data.put("uuid", e.getPlayer().getUniqueId().toString().replace("-", ""));
Main.getClient().sendData(data);
}
}
}
/** Hue detection */
@EventHandler
public void onRegionExit(RegionsLeftEvent e) {
Set<String> list = Main.getPlugin().getConfig().getConfigurationSection("Regions").getKeys(false);
public void onRegionEnter(RegionsEnteredEvent e) {
Set<String> list2 = Main.getPlugin().getConfig().getConfigurationSection("HueRegions").getKeys(false);
if (!Collections.disjoint(list, e.getRegionsNames())) {
//One element is the same -> In a region
JSONObject data = new JSONObject();
if (!PinManager.hasPin(Objects.requireNonNull(e.getPlayer()).getUniqueId())) return;
data.put("task", "MUSIC");
data.put("path", "");
data.put("uuid", e.getPlayer().getUniqueId().toString().replace("-", ""));
Main.getClient().sendData(data);
}
if (!Collections.disjoint(list2, e.getRegionsNames())) {
//One element is the same -> In a region
//TODO Add hue support
Optional<String> name = e.getRegionsNames().stream().filter(list2::contains).findFirst();
if (!name.isPresent()) return;
String configData = Main.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(Objects.requireNonNull(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("-", ""));
Main.getClient().sendData(data);
}
}
}

View file

@ -0,0 +1,114 @@
package me.mctp.radio;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.UnsupportedTagException;
import me.mctp.Main;
import me.mctp.managers.PinManager;
import me.mctp.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;
public class Playlist {
private me.mctp.api.maps.Playlist<String> songList = new me.mctp.api.maps.Playlist<>();
private boolean running = false;
private BukkitTask currentTimer;
/**
* Init, load all the songs from the data and start first
*/
public Playlist() {
init();
}
/**
* Load the songs into the system and start
*/
public void init() {
for (String URL : Main.getPlugin().getConfig().getStringList("RadioSongs")) {
addSong(URL);
}
Bukkit.getScheduler().runTaskAsynchronously(Main.getPlugin(), this::nextSong);
running = true;
}
/**
* Stop the playlist (clears the queue)
*/
public void stop() {
songList.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) {
songList.add(url);
songList.shuffle();
}
/**
* Go to the next song
*/
public void nextSong() {
if (currentTimer != null) return;
//Get song
String nextURL = songList.getRandom();
if (nextURL == null) return;
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("-", ""));
Main.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(Main.getPlugin(), () -> {
currentTimer = null;
nextSong();
}, ticks);
//Shuffle playlist again
songList.shuffle();
}
public boolean isRunning() {
return running;
}
}

View file

@ -1,6 +1,6 @@
package me.mctp.socket;
import me.mctp.MCTPAudioCmd;
import me.mctp.commands.MCTPAudioCMD;
import me.mctp.Main;
import me.mctp.managers.PinManager;
import org.bukkit.Bukkit;
@ -73,7 +73,7 @@ public class Client {
Player p = Bukkit.getPlayer(pUUID);
if (p != null && p.isOnline()) {
p.sendMessage(MCTPAudioCmd.prefix + "You are now connected with the audioclient.");
p.sendMessage(MCTPAudioCMD.prefix + "You are now connected with the audioclient.");
}
JSONObject reply = new JSONObject();
@ -88,7 +88,7 @@ public class Client {
UUID pUUID = JSONUtil.formatFromInput(uuid);
Player p = Bukkit.getPlayer(pUUID);
if (p != null && p.isOnline()) {
p.sendMessage(MCTPAudioCmd.prefix + "You are now disconnected from the audioclient.");
p.sendMessage(MCTPAudioCMD.prefix + "You are now disconnected from the audioclient.");
}
}
}

View file

@ -0,0 +1,84 @@
package me.mctp.utils;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.Mp3File;
import com.mpatric.mp3agic.UnsupportedTagException;
import org.bukkit.craftbukkit.libs.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;
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,376 @@
package me.mctp.utils;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.UUID;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
/**
* A whole class to create Guardian Beams by reflection </br>
* Inspired by the API <a href="https://www.spigotmc.org/resources/guardianbeamapi.18329">GuardianBeamAPI</a></br>
* <b>1.9 -> 1.15</b>
*
* @see <a href="https://github.com/SkytAsul/GuardianBeam">GitHub page</a>
* @author SkytAsul
*/
public class Laser {
private final int duration;
private final int distanceSquared;
private Location start;
private Location end;
private final Object createGuardianPacket;
private final Object createSquidPacket;
private final Object teamAddPacket;
private final Object destroyPacket;
private final Object metadataPacketGuardian;
private final Object metadataPacketSquid;
private final Object fakeGuardianDataWatcher;
private final int squid;
private final UUID squidUUID;
private final int guardian;
private final UUID guardianUUID;
private BukkitRunnable run;
private HashSet<Player> show = new HashSet<>();
/**
* Create a Laser instance
* @param start Location where laser will starts
* @param end Location where laser will ends
* @param duration Duration of laser in seconds (<i>-1 if infinite</i>)
* @param distance Distance where laser will be visible
*/
public Laser(Location start, Location end, int duration, int distance) throws ReflectiveOperationException {
this.start = start;
this.end = end;
this.duration = duration;
distanceSquared = distance * distance;
createSquidPacket = Packets.createPacketSquidSpawn(end);
squid = (int) Packets.getField(Packets.packetSpawn, "a", createSquidPacket);
squidUUID = (UUID) Packets.getField(Packets.packetSpawn, "b", createSquidPacket);
metadataPacketSquid = Packets.createPacketMetadata(squid, Packets.fakeSquidWatcher);
Packets.setDirtyWatcher(Packets.fakeSquidWatcher);
fakeGuardianDataWatcher = Packets.createFakeDataWatcher();
createGuardianPacket = Packets.createPacketGuardianSpawn(start, fakeGuardianDataWatcher, squid);
guardian = (int) Packets.getField(Packets.packetSpawn, "a", createGuardianPacket);
guardianUUID = (UUID) Packets.getField(Packets.packetSpawn, "b", createGuardianPacket);
metadataPacketGuardian = Packets.createPacketMetadata(guardian, fakeGuardianDataWatcher);
teamAddPacket = Packets.createPacketTeamAddEntities(squidUUID, guardianUUID);
destroyPacket = Packets.createPacketRemoveEntities(squid, guardian);
}
public void start(Plugin plugin) {
Validate.isTrue(run == null, "Task already started");
run = new BukkitRunnable() {
int time = duration;
@Override
public void run() {
try {
if (time == 0) {
cancel();
return;
}
for (Player p : start.getWorld().getPlayers()) {
if (isCloseEnough(p.getLocation())) {
if (!show.contains(p)) {
sendStartPackets(p);
show.add(p);
}
}else if (show.contains(p)) {
Packets.sendPacket(p, destroyPacket);
show.remove(p);
}
}
if (time != -1) time--;
}catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}
@Override
public synchronized void cancel() throws IllegalStateException {
super.cancel();
try {
for (Player p : show) {
Packets.sendPacket(p, destroyPacket);
}
}catch (ReflectiveOperationException e) {
e.printStackTrace();
}
run = null;
}
};
run.runTaskTimerAsynchronously(plugin, 0L, 20L);
}
public void stop() {
Validate.isTrue(run != null, "Task not started");
run.cancel();
}
public void moveStart(Location location) throws ReflectiveOperationException {
this.start = location;
Object packet = Packets.createPacketMoveEntity(start, guardian);
for (Player p : show) {
Packets.sendPacket(p, packet);
}
}
public Location getStart() {
return start;
}
public void moveEnd(Location location) throws ReflectiveOperationException {
this.end = location;
Object packet = Packets.createPacketMoveEntity(end, squid);
for (Player p : show) {
Packets.sendPacket(p, packet);
}
}
public Location getEnd() {
return end;
}
public void callColorChange() throws ReflectiveOperationException{
for (Player p : show) {
Packets.sendPacket(p, metadataPacketGuardian);
}
}
public boolean isStarted() {
return run != null;
}
private void sendStartPackets(Player p) throws ReflectiveOperationException {
Packets.sendPacket(p, createSquidPacket);
Packets.sendPacket(p, createGuardianPacket);
if (Packets.version > 14) {
Packets.sendPacket(p, metadataPacketSquid);
Packets.sendPacket(p, metadataPacketGuardian);
}
Packets.sendPacket(p, Packets.packetTeamCreate);
Packets.sendPacket(p, teamAddPacket);
}
private boolean isCloseEnough(Location location) {
return start.distanceSquared(location) <= distanceSquared ||
end.distanceSquared(location) <= distanceSquared;
}
private static class Packets {
private static int lastIssuedEID = 2000000000;
static int generateEID() {
return lastIssuedEID++;
}
private static int version = Integer.parseInt(Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3].substring(1).split("_")[1]);
private static String npack = "net.minecraft.server." + Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";
private static String cpack = Bukkit.getServer().getClass().getPackage().getName() + ".";
private static Object packetTeamCreate;
private static Constructor<?> watcherConstructor;
private static Method watcherSet;
private static Method watcherRegister;
private static Method watcherDirty;
private static Class<?> packetSpawn;
private static Class<?> packetRemove;
private static Class<?> packetTeleport;
private static Class<?> packetTeam;
private static Class<?> packetMetadata;
private static Object watcherObject1; // invisilibity
private static Object watcherObject2; // spikes
private static Object watcherObject3; // attack id
private static int squidID;
private static int guardianID;
private static Object fakeSquid;
private static Object fakeSquidWatcher;
static {
try {
String watcherName1 = null, watcherName2 = null, watcherName3 = null;
if (version < 13) {
watcherName1 = "Z";
watcherName2 = "bA";
watcherName3 = "bB";
squidID = 94;
guardianID = 68;
}else if (version == 13) {
watcherName1 = "ac";
watcherName2 = "bF";
watcherName3 = "bG";
squidID = 70;
guardianID = 28;
}else if (version == 14) {
watcherName1 = "W";
watcherName2 = "b";
watcherName3 = "bD";
squidID = 73;
guardianID = 30;
}else if (version > 14) {
watcherName1 = "T";
watcherName2 = "b";
watcherName3 = "bA";
squidID = 74;
guardianID = 31;
}
watcherObject1 = getField(Class.forName(npack + "Entity"), watcherName1, null);
watcherObject2 = getField(Class.forName(npack + "EntityGuardian"), watcherName2, null);
watcherObject3 = getField(Class.forName(npack + "EntityGuardian"), watcherName3, null);
watcherConstructor = Class.forName(npack + "DataWatcher").getDeclaredConstructor(Class.forName(npack + "Entity"));
watcherSet = getMethod(Class.forName(npack + "DataWatcher"), "set");
watcherRegister = getMethod(Class.forName(npack + "DataWatcher"), "register");
if (version >= 15) watcherDirty = getMethod(Class.forName(npack + "DataWatcher"), "markDirty");
packetSpawn = Class.forName(npack + "PacketPlayOutSpawnEntityLiving");
packetRemove = Class.forName(npack + "PacketPlayOutEntityDestroy");
packetTeleport = Class.forName(npack + "PacketPlayOutEntityTeleport");
packetTeam = Class.forName(npack + "PacketPlayOutScoreboardTeam");
packetMetadata = Class.forName(npack + "PacketPlayOutEntityMetadata");
packetTeamCreate = packetTeam.newInstance();
setField(packetTeamCreate, "a", "noclip");
setField(packetTeamCreate, "i", 0);
setField(packetTeamCreate, "f", "never");
Object world = Class.forName(cpack + "CraftWorld").getDeclaredMethod("getHandle").invoke(Bukkit.getWorlds().get(0));
Object[] entityConstructorParams = version < 14 ? new Object[] { world } : new Object[] { Class.forName(npack + "EntityTypes").getDeclaredField("SQUID").get(null), world };
fakeSquid = getMethod(Class.forName(cpack + "entity.CraftSquid"), "getHandle").invoke(Class.forName(cpack + "entity.CraftSquid").getDeclaredConstructors()[0].newInstance(
null, Class.forName(npack + "EntitySquid").getDeclaredConstructors()[0].newInstance(
entityConstructorParams)));
fakeSquidWatcher = createFakeDataWatcher();
tryWatcherSet(fakeSquidWatcher, watcherObject1, (byte) 32);
}catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}
public static void sendPacket(Player p, Object packet) throws ReflectiveOperationException {
Object entityPlayer = Class.forName(cpack + "entity.CraftPlayer").getDeclaredMethod("getHandle").invoke(p);
Object playerConnection = entityPlayer.getClass().getDeclaredField("playerConnection").get(entityPlayer);
playerConnection.getClass().getDeclaredMethod("sendPacket", Class.forName(npack + "Packet")).invoke(playerConnection, packet);
}
public static Object createFakeDataWatcher() throws ReflectiveOperationException {
Object watcher = watcherConstructor.newInstance(fakeSquid);
if (version > 13) setField(watcher, "registrationLocked", false);
return watcher;
}
public static void setDirtyWatcher(Object watcher) throws ReflectiveOperationException {
if (version >= 15) watcherDirty.invoke(watcher, watcherObject1);
}
public static Object createPacketSquidSpawn(Location location) throws ReflectiveOperationException {
Object packet = packetSpawn.newInstance();
setField(packet, "a", generateEID());
setField(packet, "b", UUID.randomUUID());
setField(packet, "c", squidID);
setField(packet, "d", location.getX());
setField(packet, "e", location.getY());
setField(packet, "f", location.getZ());
setField(packet, "j", (byte) (location.getYaw() * 256.0F / 360.0F));
setField(packet, "k", (byte) (location.getPitch() * 256.0F / 360.0F));
if (version <= 14) setField(packet, "m", fakeSquidWatcher);
return packet;
}
public static Object createPacketGuardianSpawn(Location location, Object watcher, int squidId) throws ReflectiveOperationException {
Object packet = packetSpawn.newInstance();
setField(packet, "a", generateEID());
setField(packet, "b", UUID.randomUUID());
setField(packet, "c", guardianID);
setField(packet, "d", location.getX());
setField(packet, "e", location.getY());
setField(packet, "f", location.getZ());
setField(packet, "j", (byte) (location.getYaw() * 256.0F / 360.0F));
setField(packet, "k", (byte) (location.getPitch() * 256.0F / 360.0F));
tryWatcherSet(watcher, watcherObject1, (byte) 32);
tryWatcherSet(watcher, watcherObject2, false);
tryWatcherSet(watcher, watcherObject3, squidId);
if (version <= 14) setField(packet, "m", watcher);
return packet;
}
public static Object createPacketRemoveEntities(int squidId, int guardianId) throws ReflectiveOperationException {
Object packet = packetRemove.newInstance();
setField(packet, "a", new int[] { squidId, guardianId });
return packet;
}
public static Object createPacketMoveEntity(Location location, int entityId) throws ReflectiveOperationException {
Object packet = packetTeleport.newInstance();
setField(packet, "a", entityId);
setField(packet, "b", location.getX());
setField(packet, "c", location.getY());
setField(packet, "d", location.getZ());
setField(packet, "e", (byte) (location.getYaw() * 256.0F / 360.0F));
setField(packet, "f", (byte) (location.getPitch() * 256.0F / 360.0F));
setField(packet, "g", true);
return packet;
}
public static Object createPacketTeamAddEntities(UUID squidUUID, UUID guardianUUID) throws ReflectiveOperationException {
Object packet = packetTeam.newInstance();
setField(packet, "a", "noclip");
setField(packet, "i", 3);
Collection<String> players = (Collection<String>) getField(packetTeam, "h", packet);
players.add(squidUUID.toString());
players.add(guardianUUID.toString());
return packet;
}
private static Object createPacketMetadata(int entityId, Object watcher) throws ReflectiveOperationException {
return packetMetadata.getConstructor(int.class, watcher.getClass(), boolean.class).newInstance(entityId, watcher, false);
}
private static void tryWatcherSet(Object watcher, Object watcherObject, Object watcherData) throws ReflectiveOperationException {
try {
watcherSet.invoke(watcher, watcherObject, watcherData);
}catch (InvocationTargetException ex) {
watcherRegister.invoke(watcher, watcherObject, watcherData);
if (version >= 15) watcherDirty.invoke(watcher, watcherObject);
}
}
/* Reflection utils */
private static Method getMethod(Class<?> clazz, String name) {
for (Method m : clazz.getDeclaredMethods()) {
if (m.getName().equals(name)) return m;
}
return null;
}
private static void setField(Object instance, String name, Object value) throws ReflectiveOperationException {
Validate.notNull(instance);
Field field = instance.getClass().getDeclaredField(name);
field.setAccessible(true);
field.set(instance, value);
}
private static Object getField(Class<?> clazz, String name, Object instance) throws ReflectiveOperationException {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field.get(instance);
}
}
}

View file

@ -1,6 +1,6 @@
main: me.mctp.Main
name: MCTPAudio
version: 1.0
version: 1.2
api-version: 1.14
author: MaybeFromNL_SBDeveloper
description: Copyright MaybeFromNL & SBDeveloper
@ -9,6 +9,8 @@ depend: ['WorldGuard']
commands:
mctpaudio:
description: Main command
mctpshow:
description: Show command
audio:
description: Connect command