Change playlist system, and some other fixes
This commit is contained in:
parent
bc109013f3
commit
4b9c5d3a59
13 changed files with 950 additions and 65 deletions
1
.idea/artifacts/MCTPAudio_jar.xml
generated
1
.idea/artifacts/MCTPAudio_jar.xml
generated
|
@ -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
124
.idea/uiDesigner.xml
generated
Normal 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>
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
28
src/me/mctp/api/maps/Playlist.java
Normal file
28
src/me/mctp/api/maps/Playlist.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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();
|
81
src/me/mctp/commands/MCTPShowCMD.java
Normal file
81
src/me/mctp/commands/MCTPShowCMD.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
114
src/me/mctp/radio/Playlist.java
Normal file
114
src/me/mctp/radio/Playlist.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
84
src/me/mctp/utils/HeadUtil.java
Normal file
84
src/me/mctp/utils/HeadUtil.java
Normal 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);
|
||||
}
|
||||
}
|
376
src/me/mctp/utils/Laser.java
Normal file
376
src/me/mctp/utils/Laser.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue