mirror of
https://github.com/SPAWNRYS-ban/FUCK-CustomDiscs.git
synced 2025-12-10 05:19:43 +05:00
New upcoming release 5.0 - Reintroducing the custom Goat horns, but also add the custom player heads !
Too many changes to be listed, but require a PaperMC server 1.21.7-9 at minimum.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id "com.gradleup.shadow" version "8.3.6"
|
id "com.gradleup.shadow" version "8.3.8"
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
org.gradle.jvmargs=-Xmx2G
|
org.gradle.jvmargs=-Xmx2G
|
||||||
|
|
||||||
java_version=21
|
|
||||||
|
|
||||||
mp3spi_version=1.9.5.4
|
mp3spi_version=1.9.5.4
|
||||||
|
|
||||||
bukkit_api_version=1.21
|
bukkit_api_version=1.21
|
||||||
bukkit_version=1.21.7-R0.1-SNAPSHOT
|
bukkit_version=1.21.8-R0.1-SNAPSHOT
|
||||||
mod_id=customdiscsplugin
|
mod_id=customdiscsplugin
|
||||||
|
|
||||||
# Target an older API to make it compatible with older versions of Simple Voice Chat
|
# Target an older API to make it compatible with older versions of Simple Voice Chat
|
||||||
voicechat_api_version=2.3.3
|
voicechat_api_version=2.5.31
|
||||||
command_api_version=10.1.1
|
command_api_version=10.1.1
|
||||||
|
|
||||||
plugin_version=4.5
|
plugin_version=5.0
|
||||||
maven_group=me.Navoei.customdiscsplugin
|
maven_group=me.Navoei.customdiscsplugin
|
||||||
archives_base_name=custom-discs
|
archives_base_name=custom-discs
|
||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
#Sun Aug 11 17:52:06 EDT 2024
|
#Sun Aug 11 17:52:06 EDT 2024
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
122
readme.md
122
readme.md
@@ -1,7 +1,17 @@
|
|||||||
# Custom Discs v4.5 for Paper 1.21.6 and 1.21.7
|
# Custom Discs v5.0 for Paper 1.21.7 / 1.21.8
|
||||||
|
|
||||||
|
> ### ⚠️⚠️⚠️ READ THIS SECTION CAREFULLY! ⚠️⚠️⚠️
|
||||||
|
> ### This version introduce some breaking changes and *require at least the build 9 of PaperMC 1.21.7*.
|
||||||
|
> ### Any earlier version of PaperMC is not guaranteed to function and new features may not function at all!
|
||||||
|
> ### ⚠️⚠️⚠️ Please also note that this new release requires you to delete the ```config.yml``` and ```lang.yml``` files (or update them with the new options).
|
||||||
|
> ### ⚠️⚠️⚠️ Without this being done, you could experience issues with this plugin.
|
||||||
|
|
||||||
|
|
||||||
|
## 🆘 NEW : You can now ask for support on this Discord server ➡️ https://discord.gg/YJpqruvZ97 (but you can still use the "[Issues](https://github.com/Navoei/CustomDiscs/issues)" report section of GitHub)
|
||||||
|
|
||||||
|
|
||||||
A Paper fork of henkelmax's Audio Player. Special thanks to Athar42 for maintaining this plugin.
|
A Paper fork of henkelmax's Audio Player. Special thanks to Athar42 for maintaining this plugin.
|
||||||
- Play custom music discs using the Simple Voice Chat API. (The voice chat mod is required on the client and server.)
|
- Play custom music discs, goat horns and player's head using the Simple Voice Chat API. (The voice chat mod is required on the client and server.)
|
||||||
- Use ```/customdisc``` or ```/cd``` to view available commands.
|
- Use ```/customdisc``` or ```/cd``` to view available commands.
|
||||||
- Music files should go into ```plugins/CustomDiscs/musicdata/```
|
- Music files should go into ```plugins/CustomDiscs/musicdata/```
|
||||||
- Music files must be in the ```.wav```, ```.flac```, or ```.mp3``` format.
|
- Music files must be in the ```.wav```, ```.flac```, or ```.mp3``` format.
|
||||||
@@ -19,16 +29,34 @@ Permission Nodes (Required to run the commands. Playing discs does not require a
|
|||||||
- ```customdiscs.create``` to create a disc
|
- ```customdiscs.create``` to create a disc
|
||||||
- ```customdiscs.download``` to download a file
|
- ```customdiscs.download``` to download a file
|
||||||
- ```customdiscs.range``` to set the range of the disc
|
- ```customdiscs.range``` to set the range of the disc
|
||||||
|
- ```customdiscs.horncooldown``` to set the cooldown (in ticks) for using the modified goat horn
|
||||||
|
|
||||||
Dependencies:
|
Dependencies:
|
||||||
- This plugin depends on the latest version of ProtocolLib available for your Paper version and SimpleVoiceChatBukkit (2.5.33 is recommended).
|
- This plugin depends on the latest version of ProtocolLib available for your Paper version and SimpleVoiceChatBukkit (latest is recommended - at least version 2.5.31 required).
|
||||||
|
|
||||||
|
|
||||||
https://user-images.githubusercontent.com/64107368/178426026-c454ac66-5133-4f3a-9af9-7f674e022423.mp4
|
https://user-images.githubusercontent.com/64107368/178426026-c454ac66-5133-4f3a-9af9-7f674e022423.mp4
|
||||||
|
|
||||||
Default Config.yml:
|
Default Config.yml:
|
||||||
```
|
```
|
||||||
# [Music Disc Config]
|
# [General CustomDiscs Config]
|
||||||
|
|
||||||
|
# The maximum download size in megabytes.
|
||||||
|
max-download-size: 50
|
||||||
|
|
||||||
|
# The master volume of music discs from 0-1. (You can set values like 0.5 for 50% volume).
|
||||||
|
music-disc-volume: 1
|
||||||
|
|
||||||
|
# Debug Mode - To display some more logging information and Stack Trace informations
|
||||||
|
debugMode: false
|
||||||
|
|
||||||
|
# [Music Discs Config]
|
||||||
|
|
||||||
|
# Enable custom music discs.
|
||||||
|
music-disc-enable: true
|
||||||
|
|
||||||
|
# Enable "Now playing" message for custom music discs.
|
||||||
|
music-disc-playing-enable: true
|
||||||
|
|
||||||
# The distance from which music discs can be heard in blocks.
|
# The distance from which music discs can be heard in blocks.
|
||||||
music-disc-distance: 16
|
music-disc-distance: 16
|
||||||
@@ -36,41 +64,75 @@ music-disc-distance: 16
|
|||||||
# The max distance from which music discs can be heard in blocks.
|
# The max distance from which music discs can be heard in blocks.
|
||||||
music-disc-max-distance: 256
|
music-disc-max-distance: 256
|
||||||
|
|
||||||
# The master volume of music discs from 0-1. (You can set values like 0.5 for 50% volume).
|
# [Goat Horns Config]
|
||||||
music-disc-volume: 1
|
|
||||||
|
|
||||||
# The maximum download size in megabytes.
|
# Enable custom goat horns.
|
||||||
max-download-size: 50
|
custom-horn-enable: true
|
||||||
|
|
||||||
#Custom Discs Help Page
|
# Enable "Now playing" message for custom horns.
|
||||||
|
custom-horn-playing-enable: true
|
||||||
|
|
||||||
|
# The distance from which custom horns can be heard in blocks.
|
||||||
|
custom-horn-distance: 16
|
||||||
|
|
||||||
|
# The max distance from which custom horns can be heard in blocks.
|
||||||
|
custom-horn-max-distance: 256
|
||||||
|
|
||||||
|
# The default cooldown time for horns in ticks from 1 to the max value of horn-max-cooldown (1 second is 20 ticks).
|
||||||
|
horn-cooldown: 140
|
||||||
|
|
||||||
|
# The default max cooldown time for horns in ticks (1 second is 20 ticks).
|
||||||
|
horn-max-cooldown: 6000
|
||||||
|
|
||||||
|
# [Player Heads Config]
|
||||||
|
|
||||||
|
# Enable custom player heads.
|
||||||
|
custom-head-enable: true
|
||||||
|
|
||||||
|
# Enable "Now playing" message for player heads.
|
||||||
|
custom-head-playing-enable: true
|
||||||
|
|
||||||
|
# The distance from which music discs can be heard in blocks.
|
||||||
|
custom-head-distance: 16
|
||||||
|
|
||||||
|
# The max distance from which music discs can be heard in blocks.
|
||||||
|
custom-head-max-distance: 256
|
||||||
|
|
||||||
|
|
||||||
|
# [DO NOT EDIT BELOW THIS LINE - Help configuration]
|
||||||
|
# Custom Discs Help Page
|
||||||
help:
|
help:
|
||||||
- "&8-[&6CustomDiscs Help Page&8]-"
|
- "&8-[&6CustomDiscs v5.0 - Help Page&8]-"
|
||||||
- "&aAuthor&7: &6Navoei"
|
- "&aAuthor&7: &6Navoei"
|
||||||
- "&aContributors&7: &6alfw / &6Athar42"
|
- "&aContributors&7: &6Athar42 / &6alfw"
|
||||||
- "&fGit&0Hub&7: &9&ohttps://github.com/Navoei/CustomDiscs"
|
- "&fGit&0Hub&7: &9&ohttps://github.com/Navoei/CustomDiscs"
|
||||||
|
- "&aDiscord&7: &9&ohttps://discord.gg/YJpqruvZ97"
|
||||||
```
|
```
|
||||||
|
|
||||||
Default Lang.yml:
|
Default Lang.yml:
|
||||||
```
|
```
|
||||||
prefix: "&8[&6CustomDiscs&8]&r"
|
prefix: '&8[&6CustomDiscs&8]&r'
|
||||||
no-permission: "&cYou do not have permission to execute this command."
|
invalid-filename: '&cThis is an invalid filename!'
|
||||||
invalid-filename: "&cThis is an invalid filename!"
|
invalid-format: '&cFile must be in wav, flac, or mp3 format!'
|
||||||
no-disc-name-provided: "&cYou must provide a name for your disc."
|
file-not-found: '&cFile not found!'
|
||||||
invalid-format: "&cFile must be in wav, flac, or mp3 format!"
|
not-holding-correct-item: '&cYou must either hold a disc, goat horn or player head in your main hand.'
|
||||||
file-not-found: "&cFile not found!"
|
create-filename: '&7Your filename is: &a"%filename%".'
|
||||||
invalid-arguments: "&cInvalid arguments. &7(&a%command_syntax%&7)"
|
create-custom-name: '&7Your custom name is: &a"%custom_name%".'
|
||||||
not-holding-disc: "&cYou must hold a disc in your main hand."
|
downloading-file: '&7Downloading file...'
|
||||||
create-filename: "&7Your filename is: &a\"%filename%\"."
|
file-too-large: '&cThe file is larger than %max_download_size%MB.'
|
||||||
create-custom-name: "&7Your custom name is: &a\"%custom_name%\"."
|
successful-download: '&aFile successfully downloaded to &7%file_path%&a.'
|
||||||
downloading-file: "&7Downloading file..."
|
create-disc: '&aCreate a disc by doing &7/cd create %filename% "Custom Lore"&a.'
|
||||||
file-too-large: "&cThe file is larger than %max_download_size%MB."
|
download-error: '&cAn error has occurred while downloading.'
|
||||||
successful-download: "&aFile successfully downloaded to &7%file_path%&a."
|
now-playing: '&6Now playing: %song_name%'
|
||||||
create-disc: "&aCreate a disc by doing &7/cd create %filename% \"Custom Lore\"&a."
|
disc-converted: '&aConverted disc to new format! &fThis is due to changes in newer Minecraft versions which introduced &7ToolTipDisplay&f.'
|
||||||
download-error: "&cAn error has occurred while downloading."
|
invalid-range: '&cYou need to chose a range between 1 and %range_value%'
|
||||||
now-playing: "&6Now playing: %song_name%"
|
create-custom-range: '&7Your range is set to: &a"%custom_range%".'
|
||||||
disc-converted: "&aConverted disc to new format! &fThis is due to changes in newer Minecraft versions which introduced &7JukeboxPlayableComponent&f."
|
not-holding-modified-goathorn: '&cYou must hold a modified goat horn in your main hand.'
|
||||||
invalid-range: "&cYou need to chose a range between 1 and %range_value%"
|
invalid-cooldown: '&cYou need to chose a cooldown between 1 and %cooldown_value% (in ticks)'
|
||||||
create-custom-range: "&7Your range is set to: &a\"%custom_range%\"."
|
create-custom-goat-cooldown: '&7Your goat horn cooldown is set to: &a"%custom_goat_cooldown%".'
|
||||||
|
custom-music-disabled: '&7Custom music discs are disabled in the configuration.'
|
||||||
|
custom-head-disabled: '&7Custom player heads are disabled in the configuration.'
|
||||||
|
custom-horn-disabled: '&7Custom goat horns are disabled in the configuration.'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
package me.Navoei.customdiscsplugin;
|
package me.Navoei.customdiscsplugin;
|
||||||
|
|
||||||
|
import me.Navoei.customdiscsplugin.command.CustomDiscCommand;
|
||||||
|
import me.Navoei.customdiscsplugin.event.JukeBox;
|
||||||
|
import me.Navoei.customdiscsplugin.event.HeadPlay;
|
||||||
|
import me.Navoei.customdiscsplugin.event.HornPlay;
|
||||||
|
import me.Navoei.customdiscsplugin.language.Lang;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.protocol.PacketType;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
import com.comphenix.protocol.ProtocolManager;
|
import com.comphenix.protocol.ProtocolManager;
|
||||||
@@ -7,12 +13,12 @@ import com.comphenix.protocol.events.ListenerPriority;
|
|||||||
import com.comphenix.protocol.events.PacketAdapter;
|
import com.comphenix.protocol.events.PacketAdapter;
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
|
|
||||||
import de.maxhenkel.voicechat.api.BukkitVoicechatService;
|
import de.maxhenkel.voicechat.api.BukkitVoicechatService;
|
||||||
|
|
||||||
import dev.jorel.commandapi.CommandAPI;
|
import dev.jorel.commandapi.CommandAPI;
|
||||||
import dev.jorel.commandapi.CommandAPIBukkitConfig;
|
import dev.jorel.commandapi.CommandAPIBukkitConfig;
|
||||||
import me.Navoei.customdiscsplugin.command.CustomDiscCommand;
|
|
||||||
import me.Navoei.customdiscsplugin.event.JukeBox;
|
|
||||||
import me.Navoei.customdiscsplugin.language.Lang;
|
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.block.Jukebox;
|
import org.bukkit.block.Jukebox;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
@@ -30,23 +36,36 @@ public final class CustomDiscs extends JavaPlugin {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private VoicePlugin voicechatPlugin;
|
private VoicePlugin voicechatPlugin;
|
||||||
private Logger log;
|
private Logger pluginLogger;
|
||||||
|
private static boolean debugMode = false;
|
||||||
public static YamlConfiguration LANG;
|
public static YamlConfiguration LANG;
|
||||||
public static File LANG_FILE;
|
public static File LANG_FILE;
|
||||||
|
public static boolean musicDiscEnable = true;
|
||||||
|
public static boolean musicDiscPlayingEnable = true;
|
||||||
public float musicDiscDistance;
|
public float musicDiscDistance;
|
||||||
public float musicDiscMaxDistance;
|
public float musicDiscMaxDistance;
|
||||||
public float musicDiscVolume;
|
public float musicDiscVolume;
|
||||||
|
public static boolean customHornEnable = true;
|
||||||
|
public static boolean customHornPlayingEnable = true;
|
||||||
|
public float customHornDistance;
|
||||||
|
public float customHornMaxDistance;
|
||||||
|
public int hornCooldown;
|
||||||
|
public int hornMaxCooldown;
|
||||||
|
public static boolean customHeadEnable = true;
|
||||||
|
public static boolean customHeadPlayingEnable = true;
|
||||||
|
public float customHeadDistance;
|
||||||
|
public float customHeadMaxDistance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
CustomDiscs.instance = this;
|
CustomDiscs.instance = this;
|
||||||
CommandAPI.onLoad(new CommandAPIBukkitConfig(this).verboseOutput(true));
|
CommandAPI.onLoad(new CommandAPIBukkitConfig(this).verboseOutput(true).beLenientForMinorVersions(true));
|
||||||
new CustomDiscCommand(this).register("customdiscs");
|
new CustomDiscCommand(this).register("customdiscs");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
log = getLogger();
|
pluginLogger = getLogger();
|
||||||
|
|
||||||
CommandAPI.onEnable();
|
CommandAPI.onEnable();
|
||||||
|
|
||||||
@@ -55,6 +74,28 @@ public final class CustomDiscs extends JavaPlugin {
|
|||||||
this.saveDefaultConfig();
|
this.saveDefaultConfig();
|
||||||
loadLang();
|
loadLang();
|
||||||
|
|
||||||
|
// Config initializer section
|
||||||
|
debugMode = getConfig().getBoolean("debugMode", false);
|
||||||
|
musicDiscEnable = getConfig().getBoolean("music-disc-enable");
|
||||||
|
musicDiscPlayingEnable = getConfig().getBoolean("music-disc-playing-enable");
|
||||||
|
musicDiscDistance = getConfig().getInt("music-disc-distance");
|
||||||
|
musicDiscMaxDistance = getConfig().getInt("music-disc-max-distance");
|
||||||
|
musicDiscVolume = Float.parseFloat(Objects.requireNonNull(getConfig().getString("music-disc-volume")));
|
||||||
|
customHornEnable = getConfig().getBoolean("custom-horn-enable");
|
||||||
|
customHornPlayingEnable = getConfig().getBoolean("custom-horn-playing-enable");
|
||||||
|
customHornDistance = getConfig().getInt("custom-horn-distance");
|
||||||
|
customHornMaxDistance = getConfig().getInt("custom-horn-max-distance");
|
||||||
|
hornCooldown = getConfig().getInt("horn-cooldown");
|
||||||
|
hornMaxCooldown = getConfig().getInt("horn-max-cooldown");
|
||||||
|
customHeadEnable = getConfig().getBoolean("custom-head-enable");
|
||||||
|
customHeadPlayingEnable = getConfig().getBoolean("custom-head-playing-enable");
|
||||||
|
customHeadDistance = getConfig().getInt("custom-head-distance");
|
||||||
|
customHeadMaxDistance = getConfig().getInt("custom-head-max-distance");
|
||||||
|
|
||||||
|
// Checking server version and display console message in case the server is not supported
|
||||||
|
ServerVersionChecker serverVersionChecker = new ServerVersionChecker(this);
|
||||||
|
serverVersionChecker.checkVersion();
|
||||||
|
|
||||||
File musicData = new File(this.getDataFolder(), "musicdata");
|
File musicData = new File(this.getDataFolder(), "musicdata");
|
||||||
if (!(musicData.exists())) {
|
if (!(musicData.exists())) {
|
||||||
musicData.mkdirs();
|
musicData.mkdirs();
|
||||||
@@ -63,17 +104,26 @@ public final class CustomDiscs extends JavaPlugin {
|
|||||||
if (service != null) {
|
if (service != null) {
|
||||||
voicechatPlugin = new VoicePlugin();
|
voicechatPlugin = new VoicePlugin();
|
||||||
service.registerPlugin(voicechatPlugin);
|
service.registerPlugin(voicechatPlugin);
|
||||||
log.info("Successfully registered CustomDiscs plugin");
|
pluginLogger.info("Successfully registered CustomDiscs plugin");
|
||||||
} else {
|
} else {
|
||||||
log.info("Failed to register CustomDiscs plugin");
|
pluginLogger.info("Failed to register CustomDiscs plugin");
|
||||||
}
|
}
|
||||||
|
|
||||||
getServer().getPluginManager().registerEvents(new JukeBox(), this);
|
if (isMusicDiscEnable()) {
|
||||||
getServer().getPluginManager().registerEvents(new HopperManager(), this);
|
getServer().getPluginManager().registerEvents(new JukeBox(), this);
|
||||||
|
getServer().getPluginManager().registerEvents(new HopperManager(), this);
|
||||||
|
}
|
||||||
|
if (isCustomHeadEnable()) { getServer().getPluginManager().registerEvents(new HeadPlay(), this); }
|
||||||
|
if (isCustomHornEnable()) { getServer().getPluginManager().registerEvents(new HornPlay(), this); }
|
||||||
|
|
||||||
|
// To avoid any "0" values, set it to 1.
|
||||||
|
if (hornCooldown <= 0) {
|
||||||
|
hornCooldown = 1;
|
||||||
|
}
|
||||||
|
if (hornMaxCooldown <= 0) {
|
||||||
|
hornMaxCooldown = 1;
|
||||||
|
}
|
||||||
|
|
||||||
musicDiscDistance = Objects.requireNonNull(getConfig().getInt("music-disc-distance"));
|
|
||||||
musicDiscMaxDistance = Objects.requireNonNull(getConfig().getInt("music-disc-max-distance"));
|
|
||||||
musicDiscVolume = Float.parseFloat(Objects.requireNonNull(getConfig().getString("music-disc-volume")));
|
|
||||||
|
|
||||||
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
||||||
|
|
||||||
@@ -83,6 +133,7 @@ public final class CustomDiscs extends JavaPlugin {
|
|||||||
PacketContainer packet = event.getPacket();
|
PacketContainer packet = event.getPacket();
|
||||||
|
|
||||||
if (packet.getIntegers().read(0).toString().equals("1010")) {
|
if (packet.getIntegers().read(0).toString().equals("1010")) {
|
||||||
|
if (!isMusicDiscEnable()) { return; }
|
||||||
Jukebox jukebox = (Jukebox) packet.getBlockPositionModifier().read(0).toLocation(event.getPlayer().getWorld()).getBlock().getState();
|
Jukebox jukebox = (Jukebox) packet.getBlockPositionModifier().read(0).toLocation(event.getPlayer().getWorld()).getBlock().getState();
|
||||||
|
|
||||||
if (!jukebox.getRecord().hasItemMeta()) return;
|
if (!jukebox.getRecord().hasItemMeta()) return;
|
||||||
@@ -106,7 +157,7 @@ public final class CustomDiscs extends JavaPlugin {
|
|||||||
CommandAPI.onDisable();
|
CommandAPI.onDisable();
|
||||||
if (voicechatPlugin != null) {
|
if (voicechatPlugin != null) {
|
||||||
getServer().getServicesManager().unregister(voicechatPlugin);
|
getServer().getServicesManager().unregister(voicechatPlugin);
|
||||||
log.info("Successfully unregistered CustomDiscs plugin");
|
pluginLogger.info("Successfully unregistered CustomDiscs plugin");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,8 +167,6 @@ public final class CustomDiscs extends JavaPlugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the lang.yml file.
|
* Load the lang.yml file.
|
||||||
*
|
|
||||||
* @return The lang.yml config.
|
|
||||||
*/
|
*/
|
||||||
public void loadLang() {
|
public void loadLang() {
|
||||||
File lang = new File(getDataFolder(), "lang.yml");
|
File lang = new File(getDataFolder(), "lang.yml");
|
||||||
@@ -133,10 +182,12 @@ public final class CustomDiscs extends JavaPlugin {
|
|||||||
Lang.setFile(defConfig);
|
Lang.setFile(defConfig);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace(); // So they notice
|
pluginLogger.severe("Failed to create lang.yml for CustomDiscs.");
|
||||||
log.severe("Failed to create lang.yml for CustomDiscs.");
|
pluginLogger.severe("Now disabling...");
|
||||||
log.severe("Now disabling...");
|
|
||||||
this.setEnabled(false); // Without it loaded, we can't send them messages
|
this.setEnabled(false); // Without it loaded, we can't send them messages
|
||||||
|
if (isDebugMode()) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
YamlConfiguration conf = YamlConfiguration.loadConfiguration(lang);
|
YamlConfiguration conf = YamlConfiguration.loadConfiguration(lang);
|
||||||
@@ -151,9 +202,11 @@ public final class CustomDiscs extends JavaPlugin {
|
|||||||
try {
|
try {
|
||||||
conf.save(getLangFile());
|
conf.save(getLangFile());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.log(Level.WARNING, "Failed to save lang.yml for CustomDiscs");
|
pluginLogger.warning("Failed to save lang.yml for CustomDiscs");
|
||||||
log.log(Level.WARNING, "Now disabling...");
|
pluginLogger.warning("Now disabling...");
|
||||||
e.printStackTrace();
|
if (isDebugMode()) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,8 +233,59 @@ public final class CustomDiscs extends JavaPlugin {
|
|||||||
try (OutputStream output = new FileOutputStream(file)) {
|
try (OutputStream output = new FileOutputStream(file)) {
|
||||||
input.transferTo(output);
|
input.transferTo(output);
|
||||||
} catch (IOException ioException) {
|
} catch (IOException ioException) {
|
||||||
ioException.printStackTrace();
|
if (isDebugMode()) {
|
||||||
|
CustomDiscs.getInstance().getLogger().log(Level.SEVERE, "Exception output: ", ioException);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the debugMode configuration.
|
||||||
|
*
|
||||||
|
* @return The boolean value of debugMode.
|
||||||
|
*/
|
||||||
|
public static boolean isDebugMode() { return debugMode; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the musicDiscPlayingEnable configuration.
|
||||||
|
*
|
||||||
|
* @return The boolean value of musicDiscPlayingEnable.
|
||||||
|
*/
|
||||||
|
public static boolean isMusicDiscEnable() { return musicDiscEnable; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the customHornPlayingEnable configuration.
|
||||||
|
*
|
||||||
|
* @return The boolean value of customHornPlayingEnable.
|
||||||
|
*/
|
||||||
|
public static boolean isCustomHornEnable() { return customHornEnable; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the customHeadPlayingEnable configuration.
|
||||||
|
*
|
||||||
|
* @return The boolean value of customHeadPlayingEnable.
|
||||||
|
*/
|
||||||
|
public static boolean isCustomHeadEnable() { return customHeadEnable; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the musicDiscPlayingEnable configuration.
|
||||||
|
*
|
||||||
|
* @return The boolean value of musicDiscPlayingEnable.
|
||||||
|
*/
|
||||||
|
public static boolean isMusicDiscPlayingEnable() { return musicDiscPlayingEnable; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the customHornPlayingEnable configuration.
|
||||||
|
*
|
||||||
|
* @return The boolean value of customHornPlayingEnable.
|
||||||
|
*/
|
||||||
|
public static boolean isCustomHornPlayingEnable() { return customHornPlayingEnable; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the customHeadPlayingEnable configuration.
|
||||||
|
*
|
||||||
|
* @return The boolean value of customHeadPlayingEnable.
|
||||||
|
*/
|
||||||
|
public static boolean isCustomHeadPlayingEnable() { return customHeadPlayingEnable; }
|
||||||
}
|
}
|
||||||
@@ -1,54 +1,49 @@
|
|||||||
package me.Navoei.customdiscsplugin;
|
package me.Navoei.customdiscsplugin;
|
||||||
|
|
||||||
|
import me.Navoei.customdiscsplugin.language.Lang;
|
||||||
|
|
||||||
import io.papermc.paper.datacomponent.DataComponentTypes;
|
import io.papermc.paper.datacomponent.DataComponentTypes;
|
||||||
import io.papermc.paper.datacomponent.item.TooltipDisplay;
|
import io.papermc.paper.datacomponent.item.TooltipDisplay;
|
||||||
import me.Navoei.customdiscsplugin.language.Lang;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.NamespacedKey;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
//import org.bukkit.block.Container;
|
|
||||||
import org.bukkit.block.Jukebox;
|
import org.bukkit.block.Jukebox;
|
||||||
|
import org.bukkit.entity.minecart.HopperMinecart;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
import org.bukkit.event.world.ChunkLoadEvent;
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.persistence.PersistentDataContainer;
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.inventory.meta.components.JukeboxPlayableComponent;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import org.bukkit.entity.minecart.HopperMinecart;
|
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
|
||||||
|
|
||||||
// Used only if logger is needed
|
|
||||||
//import java.util.logging.Logger;
|
|
||||||
//import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
public class HopperManager implements Listener {
|
public class HopperManager implements Listener {
|
||||||
|
|
||||||
CustomDiscs customDiscs = CustomDiscs.getInstance();
|
CustomDiscs customDiscs = CustomDiscs.getInstance();
|
||||||
|
|
||||||
PlayerManager playerManager = PlayerManager.instance();
|
PlayerManager playerManager = PlayerManager.instance();
|
||||||
|
private final Logger pluginLogger = customDiscs.getLogger();
|
||||||
//private static final Logger logger = Bukkit.getLogger(); // or Logger.getLogger("Minecraft");
|
private final boolean debugModeResult = CustomDiscs.isDebugMode();
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onJukeboxInsertFromHopper(InventoryMoveItemEvent event) {
|
public void onJukeboxInsertFromHopper(InventoryMoveItemEvent event) {
|
||||||
//logger.warning("Enter : onJukeboxInsertFromHopper");
|
if (debugModeResult) {
|
||||||
|
pluginLogger.info("DEBUG - HopperManager -> Enter : onJukeboxInsertFromHopper");
|
||||||
|
}
|
||||||
if (event.getDestination().getLocation() == null) return;
|
if (event.getDestination().getLocation() == null) return;
|
||||||
if (!event.getDestination().getType().equals(InventoryType.JUKEBOX)) return;
|
if (!event.getDestination().getType().equals(InventoryType.JUKEBOX)) return;
|
||||||
if (!isCustomMusicDisc(event.getItem())) return;
|
if (!TypeChecker.isCustomMusicDisc(event.getItem())) return;
|
||||||
|
|
||||||
Component songNameComponent = Objects.requireNonNull(event.getItem().getItemMeta().lore()).get(0).asComponent();
|
Component songNameComponent = Objects.requireNonNull(event.getItem().getItemMeta().lore()).get(0).asComponent();
|
||||||
String songName = PlainTextComponentSerializer.plainText().serialize(songNameComponent);
|
String songName = PlainTextComponentSerializer.plainText().serialize(songNameComponent);
|
||||||
@@ -78,7 +73,9 @@ public class HopperManager implements Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onJukeboxEjectToHopperMinecart(InventoryMoveItemEvent event) {
|
public void onJukeboxEjectToHopperMinecart(InventoryMoveItemEvent event) {
|
||||||
//logger.warning("Enter : onJukeboxEjectToHopper");
|
if (debugModeResult) {
|
||||||
|
pluginLogger.info("DEBUG - HopperManager -> Enter : onJukeboxEjectToHopper");
|
||||||
|
}
|
||||||
|
|
||||||
InventoryHolder holderSource = event.getSource().getHolder();
|
InventoryHolder holderSource = event.getSource().getHolder();
|
||||||
InventoryHolder holderDestination = event.getDestination().getHolder();
|
InventoryHolder holderDestination = event.getDestination().getHolder();
|
||||||
@@ -86,55 +83,39 @@ public class HopperManager implements Listener {
|
|||||||
if (event.getSource().getLocation() == null) return;
|
if (event.getSource().getLocation() == null) return;
|
||||||
if (!event.getSource().getType().equals(InventoryType.JUKEBOX)) return;
|
if (!event.getSource().getType().equals(InventoryType.JUKEBOX)) return;
|
||||||
if (event.getItem().getItemMeta() == null) return;
|
if (event.getItem().getItemMeta() == null) return;
|
||||||
if (!isCustomMusicDisc(event.getItem())) return;
|
if (!TypeChecker.isCustomMusicDisc(event.getItem())) return;
|
||||||
|
|
||||||
if (holderDestination instanceof HopperMinecart) {
|
if (holderDestination instanceof HopperMinecart) {
|
||||||
stopDisc(((BlockState) holderSource).getBlock());
|
playerManager.stopDisc(((BlockState) holderSource).getBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onChunkLoad(ChunkLoadEvent event) {
|
public void onChunkLoad(ChunkLoadEvent event) {
|
||||||
//logger.warning("Enter : onChunkLoad");
|
if (debugModeResult) {
|
||||||
|
pluginLogger.info("DEBUG - HopperManager -> Enter : onChunkLoad");
|
||||||
|
}
|
||||||
for (BlockState blockState : event.getChunk().getTileEntities()) {
|
for (BlockState blockState : event.getChunk().getTileEntities()) {
|
||||||
if (blockState instanceof Jukebox jukebox) {
|
if (blockState instanceof Jukebox jukebox) {
|
||||||
if (!jukebox.hasRecord()) return;
|
if (!jukebox.hasRecord()) return;
|
||||||
if (!PlayerManager.instance().isAudioPlayerPlaying(blockState.getLocation()) && isCustomMusicDisc(jukebox.getRecord())) {
|
if (!PlayerManager.instance().isAudioPlayerPlaying(blockState.getLocation()) && TypeChecker.isCustomMusicDisc(jukebox.getRecord())) {
|
||||||
//Set the block type to force an update.
|
|
||||||
jukebox.stopPlaying();
|
jukebox.stopPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void discToHopper(Block block) {
|
|
||||||
if (block == null) return;
|
|
||||||
if (!block.getLocation().getChunk().isLoaded()) return;
|
|
||||||
if (!block.getType().equals(Material.JUKEBOX)) return;
|
|
||||||
|
|
||||||
Jukebox jukebox = (Jukebox) block.getState();
|
|
||||||
jukebox.stopPlaying();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isCustomMusicDisc(ItemStack item) {
|
|
||||||
//logger.warning("Enter : isCustomMusicDisc");
|
|
||||||
return item.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customdisc"), PersistentDataType.STRING);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopDisc(Block block) {
|
|
||||||
playerManager.stopLocationalAudio(block.getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HopperManager instance;
|
private static HopperManager instance;
|
||||||
|
|
||||||
public static HopperManager instance() {
|
public static HopperManager instance() {
|
||||||
//logger.warning("Enter : HopperManager Instance");
|
if (CustomDiscs.isDebugMode()) {
|
||||||
|
CustomDiscs.getInstance().getLogger().info("DEBUG - HopperManager -> Enter : HopperManager Instance");
|
||||||
|
}
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new HopperManager();
|
instance = new HopperManager();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,29 @@
|
|||||||
package me.Navoei.customdiscsplugin;
|
package me.Navoei.customdiscsplugin;
|
||||||
|
|
||||||
import de.maxhenkel.voicechat.api.ServerPlayer;
|
import de.maxhenkel.voicechat.api.ServerPlayer;
|
||||||
import de.maxhenkel.voicechat.api.VoicechatConnection;
|
|
||||||
import de.maxhenkel.voicechat.api.VoicechatServerApi;
|
import de.maxhenkel.voicechat.api.VoicechatServerApi;
|
||||||
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
|
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
|
||||||
import de.maxhenkel.voicechat.api.audiochannel.AudioPlayer;
|
import de.maxhenkel.voicechat.api.audiochannel.AudioPlayer;
|
||||||
import de.maxhenkel.voicechat.api.audiochannel.LocationalAudioChannel;
|
import de.maxhenkel.voicechat.api.audiochannel.LocationalAudioChannel;
|
||||||
|
|
||||||
import javazoom.spi.mpeg.sampled.convert.MpegFormatConversionProvider;
|
import javazoom.spi.mpeg.sampled.convert.MpegFormatConversionProvider;
|
||||||
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;
|
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.TextComponent;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import org.jflac.sound.spi.Flac2PcmAudioInputStream;
|
import org.jflac.sound.spi.Flac2PcmAudioInputStream;
|
||||||
import org.jflac.sound.spi.FlacAudioFileReader;
|
import org.jflac.sound.spi.FlacAudioFileReader;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.sound.sampled.*;
|
import javax.sound.sampled.*;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -31,6 +32,8 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class PlayerManager {
|
public class PlayerManager {
|
||||||
|
|
||||||
@@ -38,6 +41,11 @@ public class PlayerManager {
|
|||||||
private final Map<UUID, PlayerReference> playerMap;
|
private final Map<UUID, PlayerReference> playerMap;
|
||||||
private final ExecutorService executorService;
|
private final ExecutorService executorService;
|
||||||
private static final AudioFormat FORMAT = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 48000F, 16, 1, 2, 48000F, false);
|
private static final AudioFormat FORMAT = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 48000F, 16, 1, 2, 48000F, false);
|
||||||
|
private final Logger pluginLogger = plugin.getLogger();
|
||||||
|
private final boolean debugModeResult = CustomDiscs.isDebugMode();
|
||||||
|
private final boolean musicDiscPlayingEnableResult = CustomDiscs.isMusicDiscPlayingEnable();
|
||||||
|
private final boolean customHornPlayingEnableResult = CustomDiscs.isCustomHornPlayingEnable();
|
||||||
|
private final boolean customHeadPlayingEnableResult = CustomDiscs.isCustomHeadPlayingEnable();
|
||||||
|
|
||||||
public PlayerManager() {
|
public PlayerManager() {
|
||||||
this.playerMap = new ConcurrentHashMap<>();
|
this.playerMap = new ConcurrentHashMap<>();
|
||||||
@@ -60,9 +68,11 @@ public class PlayerManager {
|
|||||||
|
|
||||||
Collection<ServerPlayer> playersInRange = api.getPlayersInRange(api.fromServerLevel(block.getWorld()), audioChannel.getLocation(), range);
|
Collection<ServerPlayer> playersInRange = api.getPlayersInRange(api.fromServerLevel(block.getWorld()), audioChannel.getLocation(), range);
|
||||||
|
|
||||||
for (ServerPlayer serverPlayer : playersInRange) {
|
if (musicDiscPlayingEnableResult) {
|
||||||
Player bukkitPlayer = (Player) serverPlayer.getPlayer();
|
for (ServerPlayer serverPlayer : playersInRange) {
|
||||||
bukkitPlayer.sendActionBar(actionbarComponent);
|
Player bukkitPlayer = (Player) serverPlayer.getPlayer();
|
||||||
|
bukkitPlayer.sendActionBar(actionbarComponent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AtomicBoolean stopped = new AtomicBoolean();
|
AtomicBoolean stopped = new AtomicBoolean();
|
||||||
@@ -99,7 +109,142 @@ public class PlayerManager {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
//plugin.getServer().getRegionScheduler().run(plugin, block.getLocation(), scheduledTask -> HopperManager.instance().discToHopper(block));
|
if (playerMap.containsValue(playerReference)) {
|
||||||
|
playerMap.remove(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
synchronized (stopped) {
|
||||||
|
if (!stopped.get()) {
|
||||||
|
player.set(audioPlayer);
|
||||||
|
} else {
|
||||||
|
audioPlayer.stopPlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playAudioHorn(VoicechatServerApi api, Path soundFilePath, Player block, Component actionbarComponent, float range) {
|
||||||
|
UUID id = UUID.nameUUIDFromBytes(block.getLocation().toString().getBytes());
|
||||||
|
|
||||||
|
LocationalAudioChannel audioChannel = api.createLocationalAudioChannel(id, api.fromServerLevel(block.getWorld()), api.createPosition(block.getLocation().getX() + 0.5d, block.getLocation().getY() + 0.5d, block.getLocation().getZ() + 0.5d));
|
||||||
|
|
||||||
|
if (audioChannel == null) return;
|
||||||
|
|
||||||
|
audioChannel.setCategory(VoicePlugin.GOAT_HORN_CATEGORY);
|
||||||
|
audioChannel.setDistance(range);
|
||||||
|
|
||||||
|
Collection<ServerPlayer> playersInRange = api.getPlayersInRange(api.fromServerLevel(block.getWorld()), audioChannel.getLocation(), range);
|
||||||
|
|
||||||
|
if (customHornPlayingEnableResult) {
|
||||||
|
for (ServerPlayer serverPlayer : playersInRange) {
|
||||||
|
Player bukkitPlayer = (Player) serverPlayer.getPlayer();
|
||||||
|
bukkitPlayer.sendActionBar(actionbarComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AtomicBoolean stopped = new AtomicBoolean();
|
||||||
|
AtomicReference<de.maxhenkel.voicechat.api.audiochannel.AudioPlayer> player = new AtomicReference<>();
|
||||||
|
PlayerReference playerReference = new PlayerReference(() -> {
|
||||||
|
synchronized (stopped) {
|
||||||
|
stopped.set(true);
|
||||||
|
de.maxhenkel.voicechat.api.audiochannel.AudioPlayer audioPlayer = player.get();
|
||||||
|
if (audioPlayer != null) {
|
||||||
|
audioPlayer.stopPlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, player, soundFilePath);
|
||||||
|
|
||||||
|
playerMap.put(id, playerReference);
|
||||||
|
|
||||||
|
executorService.execute(() -> {
|
||||||
|
AudioPlayer audioPlayer = null;
|
||||||
|
AudioInputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
inputStream = getAudioInputStream(soundFilePath, FORMAT);
|
||||||
|
audioPlayer = playChannelHorn(api, audioChannel, block, inputStream, playersInRange);
|
||||||
|
} catch (UnsupportedAudioFileException | IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
if (audioPlayer == null) {
|
||||||
|
playerMap.remove(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AudioInputStream finalInputStream = inputStream;
|
||||||
|
audioPlayer.setOnStopped(() -> {
|
||||||
|
try {
|
||||||
|
finalInputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
if (playerMap.containsValue(playerReference)) {
|
||||||
|
playerMap.remove(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
synchronized (stopped) {
|
||||||
|
if (!stopped.get()) {
|
||||||
|
player.set(audioPlayer);
|
||||||
|
} else {
|
||||||
|
audioPlayer.stopPlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playAudioHead(VoicechatServerApi api, Path soundFilePath, Block block, Component actionbarComponent, float range) {
|
||||||
|
UUID id = UUID.nameUUIDFromBytes(block.getLocation().toString().getBytes());
|
||||||
|
|
||||||
|
LocationalAudioChannel audioChannel = api.createLocationalAudioChannel(id, api.fromServerLevel(block.getWorld()), api.createPosition(block.getLocation().getX() + 0.5d, block.getLocation().getY() + 0.5d, block.getLocation().getZ() + 0.5d));
|
||||||
|
|
||||||
|
if (audioChannel == null) return;
|
||||||
|
|
||||||
|
audioChannel.setCategory(VoicePlugin.PLAYER_HEAD_CATEGORY);
|
||||||
|
audioChannel.setDistance(range);
|
||||||
|
|
||||||
|
Collection<ServerPlayer> playersInRange = api.getPlayersInRange(api.fromServerLevel(block.getWorld()), audioChannel.getLocation(), range);
|
||||||
|
|
||||||
|
if (customHeadPlayingEnableResult) {
|
||||||
|
for (ServerPlayer serverPlayer : playersInRange) {
|
||||||
|
Player bukkitPlayer = (Player) serverPlayer.getPlayer();
|
||||||
|
bukkitPlayer.sendActionBar(actionbarComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AtomicBoolean stopped = new AtomicBoolean();
|
||||||
|
AtomicReference<de.maxhenkel.voicechat.api.audiochannel.AudioPlayer> player = new AtomicReference<>();
|
||||||
|
PlayerReference playerReference = new PlayerReference(() -> {
|
||||||
|
synchronized (stopped) {
|
||||||
|
stopped.set(true);
|
||||||
|
de.maxhenkel.voicechat.api.audiochannel.AudioPlayer audioPlayer = player.get();
|
||||||
|
if (audioPlayer != null) {
|
||||||
|
audioPlayer.stopPlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, player, soundFilePath);
|
||||||
|
|
||||||
|
playerMap.put(id, playerReference);
|
||||||
|
|
||||||
|
executorService.execute(() -> {
|
||||||
|
AudioPlayer audioPlayer = null;
|
||||||
|
AudioInputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
inputStream = getAudioInputStream(soundFilePath, FORMAT);
|
||||||
|
audioPlayer = playChannelHead(api, audioChannel, block, inputStream, playersInRange);
|
||||||
|
} catch (UnsupportedAudioFileException | IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
if (audioPlayer == null) {
|
||||||
|
playerMap.remove(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AudioInputStream finalInputStream = inputStream;
|
||||||
|
audioPlayer.setOnStopped(() -> {
|
||||||
|
try {
|
||||||
|
finalInputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
if (playerMap.containsValue(playerReference)) {
|
if (playerMap.containsValue(playerReference)) {
|
||||||
playerMap.remove(id);
|
playerMap.remove(id);
|
||||||
}
|
}
|
||||||
@@ -117,18 +262,66 @@ public class PlayerManager {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private de.maxhenkel.voicechat.api.audiochannel.AudioPlayer playChannel(VoicechatServerApi api, AudioChannel audioChannel, Block block, AudioInputStream inputStream, Collection<ServerPlayer> playersInRange) throws UnsupportedAudioFileException, IOException {
|
private de.maxhenkel.voicechat.api.audiochannel.AudioPlayer playChannel(VoicechatServerApi api, AudioChannel audioChannel, Block block, AudioInputStream inputStream, Collection<ServerPlayer> playersInRange) throws UnsupportedAudioFileException, IOException {
|
||||||
//short[] audio = readSoundFile(soundFilePath);
|
|
||||||
AudioPlayer audioPlayer = api.createAudioPlayer(audioChannel, api.createEncoder(), () -> {
|
AudioPlayer audioPlayer = api.createAudioPlayer(audioChannel, api.createEncoder(), () -> {
|
||||||
try {
|
try {
|
||||||
return readSoundFile(inputStream);
|
return readSoundFile(inputStream);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
plugin.getLogger().info("Error Occurred At: " + block.getLocation());
|
pluginLogger.severe("An error did occur while trying to play a music disc!");
|
||||||
|
pluginLogger.info("Error Occurred At: " + block.getLocation());
|
||||||
for (ServerPlayer serverPlayer : playersInRange) {
|
for (ServerPlayer serverPlayer : playersInRange) {
|
||||||
Player bukkitPlayer = (Player) serverPlayer.getPlayer();
|
Player bukkitPlayer = (Player) serverPlayer.getPlayer();
|
||||||
TextComponent textComponent = Component.text("An error has occurred while trying to play this disc.").color(NamedTextColor.RED);
|
TextComponent textComponent = Component.text("An error has occurred while trying to play this disc.").color(NamedTextColor.RED);
|
||||||
bukkitPlayer.sendMessage(textComponent);
|
bukkitPlayer.sendMessage(textComponent);
|
||||||
}
|
}
|
||||||
e.printStackTrace();
|
if(debugModeResult) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
audioPlayer.startPlaying();
|
||||||
|
return audioPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private de.maxhenkel.voicechat.api.audiochannel.AudioPlayer playChannelHorn(VoicechatServerApi api, AudioChannel audioChannel, Player block, AudioInputStream inputStream, Collection<ServerPlayer> playersInRange) throws UnsupportedAudioFileException, IOException {
|
||||||
|
AudioPlayer audioPlayer = api.createAudioPlayer(audioChannel, api.createEncoder(), () -> {
|
||||||
|
try {
|
||||||
|
return readSoundFile(inputStream);
|
||||||
|
} catch (Exception e) {
|
||||||
|
pluginLogger.severe("An error did occur while trying to play a goat horn!");
|
||||||
|
pluginLogger.info("Error Occurred At: " + block.getLocation());
|
||||||
|
for (ServerPlayer serverPlayer : playersInRange) {
|
||||||
|
Player bukkitPlayer = (Player) serverPlayer.getPlayer();
|
||||||
|
TextComponent textComponent = Component.text("An error has occurred while trying to play this goat horn.").color(NamedTextColor.RED);
|
||||||
|
bukkitPlayer.sendMessage(textComponent);
|
||||||
|
}
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
audioPlayer.startPlaying();
|
||||||
|
return audioPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private de.maxhenkel.voicechat.api.audiochannel.AudioPlayer playChannelHead(VoicechatServerApi api, AudioChannel audioChannel, Block block, AudioInputStream inputStream, Collection<ServerPlayer> playersInRange) throws UnsupportedAudioFileException, IOException {
|
||||||
|
AudioPlayer audioPlayer = api.createAudioPlayer(audioChannel, api.createEncoder(), () -> {
|
||||||
|
try {
|
||||||
|
return readSoundFile(inputStream);
|
||||||
|
} catch (Exception e) {
|
||||||
|
pluginLogger.severe("An error did occur while trying to play a player head!");
|
||||||
|
pluginLogger.info("Error Occurred At: " + block.getLocation());
|
||||||
|
for (ServerPlayer serverPlayer : playersInRange) {
|
||||||
|
Player bukkitPlayer = (Player) serverPlayer.getPlayer();
|
||||||
|
TextComponent textComponent = Component.text("An error has occurred while trying to play this player head.").color(NamedTextColor.RED);
|
||||||
|
bukkitPlayer.sendMessage(textComponent);
|
||||||
|
}
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -222,10 +415,11 @@ public class PlayerManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//public static float getLengthSeconds(Path file) throws UnsupportedAudioFileException, IOException {
|
// DISABLED FOR NOW, MAY BE REUSED LATER IF WE DECIDE TO IMPLEMENT IT
|
||||||
// short[] audio = readSoundFile(file);
|
/*public static float getLengthSeconds(Path file) throws UnsupportedAudioFileException, IOException {
|
||||||
// return (float) audio.length / FORMAT.getSampleRate();
|
short[] audio = readSoundFile(file);
|
||||||
//}
|
return (float) audio.length / FORMAT.getSampleRate();
|
||||||
|
}*/
|
||||||
|
|
||||||
public boolean isAudioPlayerPlaying(Location blockLocation) {
|
public boolean isAudioPlayerPlaying(Location blockLocation) {
|
||||||
UUID id = UUID.nameUUIDFromBytes(blockLocation.toString().getBytes());
|
UUID id = UUID.nameUUIDFromBytes(blockLocation.toString().getBytes());
|
||||||
@@ -241,6 +435,10 @@ public class PlayerManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stopDisc(Block block) {
|
||||||
|
this.stopLocationalAudio(block.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
private static PlayerManager instance;
|
private static PlayerManager instance;
|
||||||
|
|
||||||
public static PlayerManager instance() {
|
public static PlayerManager instance() {
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package me.Navoei.customdiscsplugin;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ServerVersionChecker {
|
||||||
|
private static final String REQUIRED_VERSION = "1.21.7-9"; // Set the PaperMC required version
|
||||||
|
private final Logger pluginLogger;
|
||||||
|
private final boolean debugModeResult = CustomDiscs.isDebugMode();
|
||||||
|
|
||||||
|
public ServerVersionChecker(JavaPlugin plugin) {
|
||||||
|
this.pluginLogger = plugin.getLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkVersion() {
|
||||||
|
// Get the full server version message output
|
||||||
|
String versionMessage = Bukkit.getVersionMessage();
|
||||||
|
|
||||||
|
if (versionMessage == null) {
|
||||||
|
pluginLogger.severe("Unable to detect the running server version. Is this a supported PaperMC release?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract server type and version
|
||||||
|
Matcher serverInfoExtracted = Pattern.compile("This server is running (\\S+) version (\\S+)").matcher(versionMessage);
|
||||||
|
|
||||||
|
if (serverInfoExtracted.find()) {
|
||||||
|
String serverType = serverInfoExtracted.group(1); // Extract the server type (Should be "Paper", but can be forks like "Purpur", "Spigot", ...)
|
||||||
|
String buildVersion = serverInfoExtracted.group(2); // Extract the full version info (For example : 1.21.7-9-main@5661fbb)
|
||||||
|
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.info("DEBUG - Detected Server Type: " + serverType);
|
||||||
|
pluginLogger.info("DEBUG - Server Full Version: " + versionMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// As we only officially support Paper, we look up for it specifically
|
||||||
|
if ("paper".equalsIgnoreCase(serverType)) {
|
||||||
|
String cleanVersion = cleanBuildVersion(buildVersion);
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.info("DEBUG - Extracted Version: " + cleanVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We then perform a version comparison
|
||||||
|
if (compareVersions(cleanVersion) < 0) {
|
||||||
|
pluginLogger.severe("This Paper server version is unsupported. Please update to at least Paper " + REQUIRED_VERSION);
|
||||||
|
} else {
|
||||||
|
pluginLogger.info("Paper server version is supported.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// For Paper forks servers (mostly), log a severe message about non-support
|
||||||
|
pluginLogger.severe(serverType + " server detected. No support will be made in case of issues!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pluginLogger.severe("Unable to read the server version. Is this a supported PaperMC release?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up the version string to remove the non usefull part after the build number (like '-main@5661fbb').
|
||||||
|
* The result is only the main version part (like '1.21.7-9').
|
||||||
|
*/
|
||||||
|
private static String cleanBuildVersion(String version) {
|
||||||
|
String[] versionParts = version.split("-");
|
||||||
|
return versionParts.length >= 2 ? versionParts[0] + "-" + versionParts[1] : version;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int compareVersions(String runningVersion) {
|
||||||
|
// We first start by separating the main version number from the build number
|
||||||
|
String[] currentVersion = runningVersion.split("-");
|
||||||
|
String[] requiredVersion = REQUIRED_VERSION.split("-");
|
||||||
|
|
||||||
|
// Then we compare the base version (sub-function to handle it)
|
||||||
|
// If we are in the same main version, we pass to the next check, else we exit (-1 = older release ; 1 = newer release)
|
||||||
|
int result = compareVersionParts(currentVersion[0], requiredVersion[0]);
|
||||||
|
if (result != 0) return result;
|
||||||
|
|
||||||
|
// And finally, we compare the build number (only if we are at the same main base version, to ensure we get the minimal build)
|
||||||
|
return Integer.compare(Integer.parseInt(currentVersion[1]), Integer.parseInt(requiredVersion[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int compareVersionParts(String currentVersionPart, String requiredVersionPart) {
|
||||||
|
// We split each numbers into individual components (major (1), minor (21), and patch versions (7), so we can compare it one by one)
|
||||||
|
String[] currentVersionArray = currentVersionPart.split("\\.");
|
||||||
|
String[] requiredVersionArray = requiredVersionPart.split("\\.");
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
int currentVersion = Integer.parseInt(currentVersionArray[i]);
|
||||||
|
int requiredVersion = Integer.parseInt(requiredVersionArray[i]);
|
||||||
|
|
||||||
|
if (currentVersion < requiredVersion) return -1;
|
||||||
|
if (currentVersion > requiredVersion) return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
73
src/main/java/me/Navoei/customdiscsplugin/TypeChecker.java
Normal file
73
src/main/java/me/Navoei/customdiscsplugin/TypeChecker.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package me.Navoei.customdiscsplugin;
|
||||||
|
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
|
public class TypeChecker {
|
||||||
|
static CustomDiscs customDiscs = CustomDiscs.getInstance();
|
||||||
|
|
||||||
|
// Commented methods are kept for possible future checks usage.
|
||||||
|
|
||||||
|
// MUSIC DISCS
|
||||||
|
|
||||||
|
public static boolean isMusicDisc(ItemStack item) {
|
||||||
|
return item.getType().toString().contains("MUSIC_DISC");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public static boolean isMusicDiscPlayer(Player p) {
|
||||||
|
return p.getInventory().getItemInMainHand().getType().toString().contains("MUSIC_DISC");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public static boolean isCustomMusicDisc(ItemStack itemStack) {
|
||||||
|
if (itemStack == null) return false;
|
||||||
|
if (itemStack.getItemMeta() == null) return false;
|
||||||
|
return itemStack.getType().toString().contains("MUSIC_DISC") && itemStack.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customdisc"), PersistentDataType.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public static boolean isCustomMusicDiscPlayer(Player p) {
|
||||||
|
return p.getInventory().getItemInMainHand().getType().toString().contains("MUSIC_DISC") && p.getInventory().getItemInMainHand().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customdisc"), PersistentDataType.STRING);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// GOAT HORNS
|
||||||
|
|
||||||
|
/*public static boolean isGoatHorn(ItemStack item) {
|
||||||
|
return item.getType().toString().contains("GOAT_HORN");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public static boolean isGoatHornPlayer(Player p) {
|
||||||
|
return p.getInventory().getItemInMainHand().getType().toString().contains("GOAT_HORN");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCustomGoatHorn(PlayerInteractEvent e) {
|
||||||
|
if (e.getItem()==null) return false;
|
||||||
|
return e.getItem().getType().toString().contains("GOAT_HORN") && e.getItem().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customhorn"), PersistentDataType.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCustomGoatHornPlayer(Player p) {
|
||||||
|
return p.getInventory().getItemInMainHand().getType().toString().contains("GOAT_HORN") && p.getInventory().getItemInMainHand().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customhorn"), PersistentDataType.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PLAYER HEADS
|
||||||
|
|
||||||
|
/*public static boolean isHead(ItemStack item) {
|
||||||
|
return item.getType().toString().contains("PLAYER_HEAD");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public static boolean isHeadPlayer(Player p) {
|
||||||
|
return p.getInventory().getItemInMainHand().getType().toString().contains("PLAYER_HEAD");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public static boolean isCustomHead(ItemStack itemStack) {
|
||||||
|
if (itemStack == null) return false;
|
||||||
|
if (itemStack.getItemMeta() == null) return false;
|
||||||
|
return itemStack.getType().toString().contains("PLAYER_HEAD") && itemStack.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customhead"), PersistentDataType.STRING);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public static boolean isCustomHeadPlayer(Player p) {
|
||||||
|
return p.getInventory().getItemInMainHand().getType().toString().contains("PLAYER_HEAD") && p.getInventory().getItemInMainHand().getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customhead"), PersistentDataType.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,6 +12,8 @@ import javax.imageio.ImageIO;
|
|||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class VoicePlugin implements VoicechatPlugin {
|
public class VoicePlugin implements VoicechatPlugin {
|
||||||
|
|
||||||
@@ -31,6 +33,9 @@ public class VoicePlugin implements VoicechatPlugin {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static VolumeCategory playerHeads;
|
public static VolumeCategory playerHeads;
|
||||||
|
|
||||||
|
private final Logger pluginLogger = CustomDiscs.getInstance().getLogger();
|
||||||
|
private final boolean debugModeResult = CustomDiscs.isDebugMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the unique ID for this voice chat plugin
|
* @return the unique ID for this voice chat plugin
|
||||||
*/
|
*/
|
||||||
@@ -70,6 +75,22 @@ public class VoicePlugin implements VoicechatPlugin {
|
|||||||
.build();
|
.build();
|
||||||
voicechatServerApi.registerVolumeCategory(musicDiscs);
|
voicechatServerApi.registerVolumeCategory(musicDiscs);
|
||||||
|
|
||||||
|
goatHorns = voicechatServerApi.volumeCategoryBuilder()
|
||||||
|
.setId(GOAT_HORN_CATEGORY)
|
||||||
|
.setName("Goat Horns")
|
||||||
|
.setDescription("The volume of goat horns")
|
||||||
|
.setIcon(getGoatHornsIcon())
|
||||||
|
.build();
|
||||||
|
voicechatServerApi.registerVolumeCategory(goatHorns);
|
||||||
|
|
||||||
|
playerHeads = voicechatServerApi.volumeCategoryBuilder()
|
||||||
|
.setId(PLAYER_HEAD_CATEGORY)
|
||||||
|
.setName("Player Heads")
|
||||||
|
.setDescription("The volume of player heads (on noteblock)")
|
||||||
|
.setIcon(getPlayerHeadIcon())
|
||||||
|
.build();
|
||||||
|
voicechatServerApi.registerVolumeCategory(playerHeads);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[][] getMusicDiscIcon() {
|
private int[][] getMusicDiscIcon() {
|
||||||
@@ -94,7 +115,70 @@ public class VoicePlugin implements VoicechatPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
pluginLogger.severe("An error occurred while trying to set the Music Disc icon category.");
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[][] getGoatHornsIcon() {
|
||||||
|
try {
|
||||||
|
Enumeration<URL> resources = CustomDiscs.getInstance().getClass().getClassLoader().getResources("goat_horn_category.png");
|
||||||
|
|
||||||
|
while (resources.hasMoreElements()) {
|
||||||
|
BufferedImage bufferedImage = ImageIO.read(resources.nextElement().openStream());
|
||||||
|
if (bufferedImage.getWidth() != 16) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (bufferedImage.getHeight() != 16) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int[][] image = new int[16][16];
|
||||||
|
for (int x = 0; x < bufferedImage.getWidth(); x++) {
|
||||||
|
for (int y = 0; y < bufferedImage.getHeight(); y++) {
|
||||||
|
image[x][y] = bufferedImage.getRGB(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
pluginLogger.severe("An error occurred while trying to set the Goat Horn icon category.");
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[][] getPlayerHeadIcon() {
|
||||||
|
try {
|
||||||
|
Enumeration<URL> resources = CustomDiscs.getInstance().getClass().getClassLoader().getResources("player_head_category.png");
|
||||||
|
|
||||||
|
while (resources.hasMoreElements()) {
|
||||||
|
BufferedImage bufferedImage = ImageIO.read(resources.nextElement().openStream());
|
||||||
|
if (bufferedImage.getWidth() != 16) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (bufferedImage.getHeight() != 16) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int[][] image = new int[16][16];
|
||||||
|
for (int x = 0; x < bufferedImage.getWidth(); x++) {
|
||||||
|
for (int y = 0; y < bufferedImage.getHeight(); y++) {
|
||||||
|
image[x][y] = bufferedImage.getRGB(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
pluginLogger.severe("An error occurred while trying to set the Player Head icon category.");
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
package me.Navoei.customdiscsplugin.command;
|
package me.Navoei.customdiscsplugin.command;
|
||||||
|
|
||||||
import dev.jorel.commandapi.CommandAPICommand;
|
|
||||||
import dev.jorel.commandapi.executors.CommandArguments;
|
|
||||||
import me.Navoei.customdiscsplugin.CustomDiscs;
|
import me.Navoei.customdiscsplugin.CustomDiscs;
|
||||||
import me.Navoei.customdiscsplugin.command.SubCommands.CreateSubCommand;
|
import me.Navoei.customdiscsplugin.command.SubCommands.CreateSubCommand;
|
||||||
import me.Navoei.customdiscsplugin.command.SubCommands.DownloadSubCommand;
|
import me.Navoei.customdiscsplugin.command.SubCommands.DownloadSubCommand;
|
||||||
|
import me.Navoei.customdiscsplugin.command.SubCommands.SetHornCooldownSubCommand;
|
||||||
import me.Navoei.customdiscsplugin.command.SubCommands.SetRangeSubCommand;
|
import me.Navoei.customdiscsplugin.command.SubCommands.SetRangeSubCommand;
|
||||||
|
|
||||||
|
import dev.jorel.commandapi.CommandAPICommand;
|
||||||
|
import dev.jorel.commandapi.CommandPermission;
|
||||||
|
import dev.jorel.commandapi.executors.CommandArguments;
|
||||||
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -21,10 +26,12 @@ public class CustomDiscCommand extends CommandAPICommand {
|
|||||||
|
|
||||||
this.withAliases("cd");
|
this.withAliases("cd");
|
||||||
this.withFullDescription("The custom discs command.");
|
this.withFullDescription("The custom discs command.");
|
||||||
|
this.withPermission(CommandPermission.NONE);
|
||||||
|
|
||||||
this.withSubcommand(new CreateSubCommand(plugin));
|
this.withSubcommand(new CreateSubCommand(plugin));
|
||||||
this.withSubcommand(new DownloadSubCommand(plugin));
|
this.withSubcommand(new DownloadSubCommand(plugin));
|
||||||
this.withSubcommand(new SetRangeSubCommand(plugin));
|
this.withSubcommand(new SetRangeSubCommand(plugin));
|
||||||
|
this.withSubcommand(new SetHornCooldownSubCommand(plugin));
|
||||||
|
|
||||||
this.executesPlayer(this::onCommandPlayer);
|
this.executesPlayer(this::onCommandPlayer);
|
||||||
this.executesConsole(this::onCommandConsole);
|
this.executesConsole(this::onCommandConsole);
|
||||||
@@ -43,4 +50,5 @@ public class CustomDiscCommand extends CommandAPICommand {
|
|||||||
executor.sendMessage(NamedTextColor.RED + "Only players can use this command : '"+arguments+"'!");
|
executor.sendMessage(NamedTextColor.RED + "Only players can use this command : '"+arguments+"'!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,29 @@
|
|||||||
package me.Navoei.customdiscsplugin.command.SubCommands;
|
package me.Navoei.customdiscsplugin.command.SubCommands;
|
||||||
|
|
||||||
|
import me.Navoei.customdiscsplugin.CustomDiscs;
|
||||||
|
import me.Navoei.customdiscsplugin.TypeChecker;
|
||||||
|
import me.Navoei.customdiscsplugin.language.Lang;
|
||||||
|
|
||||||
import dev.jorel.commandapi.CommandAPICommand;
|
import dev.jorel.commandapi.CommandAPICommand;
|
||||||
import dev.jorel.commandapi.arguments.ArgumentSuggestions;
|
import dev.jorel.commandapi.arguments.ArgumentSuggestions;
|
||||||
import dev.jorel.commandapi.arguments.StringArgument;
|
import dev.jorel.commandapi.arguments.StringArgument;
|
||||||
import dev.jorel.commandapi.arguments.TextArgument;
|
import dev.jorel.commandapi.arguments.TextArgument;
|
||||||
import dev.jorel.commandapi.executors.CommandArguments;
|
import dev.jorel.commandapi.executors.CommandArguments;
|
||||||
|
|
||||||
import io.papermc.paper.datacomponent.DataComponentTypes;
|
import io.papermc.paper.datacomponent.DataComponentTypes;
|
||||||
import io.papermc.paper.datacomponent.item.TooltipDisplay;
|
import io.papermc.paper.datacomponent.item.TooltipDisplay;
|
||||||
import me.Navoei.customdiscsplugin.CustomDiscs;
|
import io.papermc.paper.registry.RegistryKey;
|
||||||
import me.Navoei.customdiscsplugin.language.Lang;
|
import io.papermc.paper.registry.TypedKey;
|
||||||
|
import io.papermc.paper.registry.keys.InstrumentKeys;
|
||||||
|
import io.papermc.paper.registry.keys.SoundEventKeys;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.TextComponent;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.format.TextDecoration;
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -38,6 +48,7 @@ public class CreateSubCommand extends CommandAPICommand {
|
|||||||
|
|
||||||
this.withFullDescription(NamedTextColor.GRAY + "Creates a custom music disc.");
|
this.withFullDescription(NamedTextColor.GRAY + "Creates a custom music disc.");
|
||||||
this.withUsage("/customdisc create <filename> \"Custom Lore\"");
|
this.withUsage("/customdisc create <filename> \"Custom Lore\"");
|
||||||
|
this.withPermission("customdiscs.create");
|
||||||
|
|
||||||
this.withArguments(new StringArgument("filename").replaceSuggestions(ArgumentSuggestions.stringCollection((sender) -> {
|
this.withArguments(new StringArgument("filename").replaceSuggestions(ArgumentSuggestions.stringCollection((sender) -> {
|
||||||
File musicDataFolder = new File(this.plugin.getDataFolder(), "musicdata");
|
File musicDataFolder = new File(this.plugin.getDataFolder(), "musicdata");
|
||||||
@@ -62,18 +73,17 @@ public class CreateSubCommand extends CommandAPICommand {
|
|||||||
private int onCommandPlayer(Player player, CommandArguments arguments) {
|
private int onCommandPlayer(Player player, CommandArguments arguments) {
|
||||||
|
|
||||||
ItemStack item = player.getInventory().getItemInMainHand();
|
ItemStack item = player.getInventory().getItemInMainHand();
|
||||||
|
boolean resultIsMusicDisc = TypeChecker.isMusicDisc(item);
|
||||||
|
boolean resultIsHorn = TypeChecker.isGoatHornPlayer(player);
|
||||||
|
boolean resultIsHead = TypeChecker.isHeadPlayer(player);
|
||||||
|
|
||||||
if (!isMusicDisc(item)) {
|
if (!resultIsMusicDisc && !resultIsHorn && !resultIsHead) {
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_DISC.toString()));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_CORRECT_ITEM.toString()));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!player.hasPermission("customdiscs.create")) {
|
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_PERMISSION.toString()));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find file, if file not there then say "file not there"
|
|
||||||
String filename = Objects.requireNonNull(arguments.getByClass("filename", String.class));
|
String filename = Objects.requireNonNull(arguments.getByClass("filename", String.class));
|
||||||
if (filename.contains("../")) {
|
if (filename.contains("../")) {
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FILENAME.toString()));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FILENAME.toString()));
|
||||||
@@ -94,17 +104,60 @@ public class CreateSubCommand extends CommandAPICommand {
|
|||||||
|
|
||||||
String song_name = Objects.requireNonNull(arguments.getByClass("song_name", String.class));
|
String song_name = Objects.requireNonNull(arguments.getByClass("song_name", String.class));
|
||||||
|
|
||||||
ItemStack disc = new ItemStack(player.getInventory().getItemInMainHand());
|
if (resultIsMusicDisc) {
|
||||||
disc.setData(DataComponentTypes.TOOLTIP_DISPLAY, TooltipDisplay.tooltipDisplay().addHiddenComponents(DataComponentTypes.JUKEBOX_PLAYABLE).build());
|
if (!CustomDiscs.isMusicDiscEnable()) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CUSTOM_MUSIC_DISABLED.toString())); return 1; }
|
||||||
ItemMeta meta = disc.getItemMeta();
|
ItemStack disc = new ItemStack(player.getInventory().getItemInMainHand());
|
||||||
@Nullable List<Component> itemLore = new ArrayList<>();
|
disc.setData(DataComponentTypes.TOOLTIP_DISPLAY, TooltipDisplay.tooltipDisplay().addHiddenComponents(DataComponentTypes.JUKEBOX_PLAYABLE).build());
|
||||||
final TextComponent customLoreSong = Component.text().decoration(TextDecoration.ITALIC, false).content(song_name).color(NamedTextColor.GRAY).build();
|
ItemMeta meta = disc.getItemMeta();
|
||||||
itemLore.add(customLoreSong);
|
@Nullable List<Component> itemLore = new ArrayList<>();
|
||||||
meta.lore(itemLore);
|
final TextComponent customLoreSong = Component.text().decoration(TextDecoration.ITALIC, false).content(song_name).color(NamedTextColor.GRAY).build();
|
||||||
|
itemLore.add(customLoreSong);
|
||||||
|
meta.lore(itemLore);
|
||||||
|
|
||||||
|
PersistentDataContainer data = meta.getPersistentDataContainer();
|
||||||
|
data.set(new NamespacedKey(this.plugin, "customdisc"), PersistentDataType.STRING, filename);
|
||||||
|
player.getInventory().getItemInMainHand().setItemMeta(meta);
|
||||||
|
} else if (resultIsHorn) {
|
||||||
|
if (!CustomDiscs.isCustomHornEnable()) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CUSTOM_HORN_DISABLED.toString())); return 1; }
|
||||||
|
final TextComponent customLoreSong = Component.text().decoration(TextDecoration.ITALIC, false).content(song_name).color(NamedTextColor.GRAY).build();
|
||||||
|
MusicInstrument customInstrument = MusicInstrument.create(builder -> {
|
||||||
|
builder.copyFrom(InstrumentKeys.ADMIRE_GOAT_HORN)
|
||||||
|
.description(customLoreSong)
|
||||||
|
.range(256.0f)
|
||||||
|
.duration(1.0f)
|
||||||
|
.soundEvent(TypedKey.create(
|
||||||
|
RegistryKey.SOUND_EVENT,
|
||||||
|
SoundEventKeys.INTENTIONALLY_EMPTY
|
||||||
|
));
|
||||||
|
});
|
||||||
|
item.setData(DataComponentTypes.INSTRUMENT, customInstrument);
|
||||||
|
|
||||||
|
ItemStack disc = new ItemStack(player.getInventory().getItemInMainHand());
|
||||||
|
disc.setData(DataComponentTypes.TOOLTIP_DISPLAY, TooltipDisplay.tooltipDisplay().addHiddenComponents(DataComponentTypes.JUKEBOX_PLAYABLE).build());
|
||||||
|
ItemMeta meta = disc.getItemMeta();
|
||||||
|
PersistentDataContainer data = meta.getPersistentDataContainer();
|
||||||
|
data.set(new NamespacedKey(this.plugin, "customhorn"), PersistentDataType.STRING, filename);
|
||||||
|
player.getInventory().getItemInMainHand().setItemMeta(meta);
|
||||||
|
} else if (resultIsHead) {
|
||||||
|
if (!CustomDiscs.isCustomHeadEnable()) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CUSTOM_HEAD_DISABLED.toString())); return 1; }
|
||||||
|
final Component customLoreHead = Component.text().decoration(TextDecoration.ITALIC, false).content(song_name).color(NamedTextColor.GRAY).build();
|
||||||
|
String serialized = GsonComponentSerializer.gson().serialize(customLoreHead);
|
||||||
|
|
||||||
|
ItemStack disc = new ItemStack(player.getInventory().getItemInMainHand());
|
||||||
|
ItemMeta meta = disc.getItemMeta();
|
||||||
|
@Nullable List<Component> itemLore = new ArrayList<>();
|
||||||
|
final TextComponent customLoreSong = Component.text().decoration(TextDecoration.ITALIC, false).content(song_name).color(NamedTextColor.GRAY).build();
|
||||||
|
itemLore.add(customLoreSong);
|
||||||
|
meta.lore(itemLore);
|
||||||
|
|
||||||
|
PersistentDataContainer data = meta.getPersistentDataContainer();
|
||||||
|
data.set(new NamespacedKey(this.plugin, "customhead"), PersistentDataType.STRING, filename);
|
||||||
|
data.set(new NamespacedKey(this.plugin, "headlore"), PersistentDataType.STRING, serialized);
|
||||||
|
player.getInventory().getItemInMainHand().setItemMeta(meta);
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
PersistentDataContainer data = meta.getPersistentDataContainer();
|
|
||||||
data.set(new NamespacedKey(this.plugin, "customdisc"), PersistentDataType.STRING, filename);
|
|
||||||
player.getInventory().getItemInMainHand().setItemMeta(meta);
|
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_FILENAME.toString().replace("%filename%", filename)));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_FILENAME.toString().replace("%filename%", filename)));
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_CUSTOM_NAME.toString().replace("%custom_name%", song_name)));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_CUSTOM_NAME.toString().replace("%custom_name%", song_name)));
|
||||||
return 1;
|
return 1;
|
||||||
@@ -124,8 +177,4 @@ public class CreateSubCommand extends CommandAPICommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isMusicDisc(ItemStack item) {
|
|
||||||
return item.getType().toString().contains("MUSIC_DISC");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,20 @@
|
|||||||
package me.Navoei.customdiscsplugin.command.SubCommands;
|
package me.Navoei.customdiscsplugin.command.SubCommands;
|
||||||
|
|
||||||
|
import me.Navoei.customdiscsplugin.CustomDiscs;
|
||||||
|
import me.Navoei.customdiscsplugin.language.Lang;
|
||||||
|
|
||||||
import dev.jorel.commandapi.CommandAPICommand;
|
import dev.jorel.commandapi.CommandAPICommand;
|
||||||
import dev.jorel.commandapi.arguments.StringArgument;
|
import dev.jorel.commandapi.arguments.StringArgument;
|
||||||
import dev.jorel.commandapi.arguments.TextArgument;
|
import dev.jorel.commandapi.arguments.TextArgument;
|
||||||
import dev.jorel.commandapi.executors.CommandArguments;
|
import dev.jorel.commandapi.executors.CommandArguments;
|
||||||
import me.Navoei.customdiscsplugin.CustomDiscs;
|
|
||||||
import me.Navoei.customdiscsplugin.language.Lang;
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import org.codehaus.plexus.util.FileUtils;
|
import org.codehaus.plexus.util.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -22,9 +26,12 @@ import java.net.URLConnection;
|
|||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class DownloadSubCommand extends CommandAPICommand {
|
public class DownloadSubCommand extends CommandAPICommand {
|
||||||
private final CustomDiscs plugin;
|
private final CustomDiscs plugin;
|
||||||
|
private final boolean debugModeResult = CustomDiscs.isDebugMode();
|
||||||
|
|
||||||
public DownloadSubCommand(CustomDiscs plugin) {
|
public DownloadSubCommand(CustomDiscs plugin) {
|
||||||
super("download");
|
super("download");
|
||||||
@@ -32,6 +39,7 @@ public class DownloadSubCommand extends CommandAPICommand {
|
|||||||
|
|
||||||
this.withFullDescription(NamedTextColor.GRAY + "Downloads a file from a given URL.");
|
this.withFullDescription(NamedTextColor.GRAY + "Downloads a file from a given URL.");
|
||||||
this.withUsage("/customdisc download <url> <filename.extension>");
|
this.withUsage("/customdisc download <url> <filename.extension>");
|
||||||
|
this.withPermission("customdiscs.download");
|
||||||
|
|
||||||
this.withArguments(new TextArgument("url"));
|
this.withArguments(new TextArgument("url"));
|
||||||
this.withArguments(new StringArgument("filename"));
|
this.withArguments(new StringArgument("filename"));
|
||||||
@@ -41,10 +49,7 @@ public class DownloadSubCommand extends CommandAPICommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int onCommandPlayer(Player player, CommandArguments arguments) {
|
private int onCommandPlayer(Player player, CommandArguments arguments) {
|
||||||
if (!player.hasPermission("customdiscs.download")) {
|
final Logger pluginLogger = plugin.getLogger();
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_PERMISSION.toString()));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
||||||
try {
|
try {
|
||||||
@@ -52,14 +57,17 @@ public class DownloadSubCommand extends CommandAPICommand {
|
|||||||
URI uri = new URI(Objects.requireNonNull(arguments.getByClass("url", String.class)));
|
URI uri = new URI(Objects.requireNonNull(arguments.getByClass("url", String.class)));
|
||||||
URL fileURL = uri.toURL();
|
URL fileURL = uri.toURL();
|
||||||
String filename = Objects.requireNonNull(arguments.getByClass("filename", String.class));
|
String filename = Objects.requireNonNull(arguments.getByClass("filename", String.class));
|
||||||
|
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.info("DEBUG - Download File URL: " + fileURL);
|
||||||
|
pluginLogger.info("DEBUG - File name: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
if (filename.contains("../")) {
|
if (filename.contains("../")) {
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FILENAME.toString()));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FILENAME.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//DEBUG
|
|
||||||
//System.out.println(filename);
|
|
||||||
|
|
||||||
String fileExtension = getFileExtension(filename);
|
String fileExtension = getFileExtension(filename);
|
||||||
if (!fileExtension.equals("wav") && !fileExtension.equals("mp3") && !fileExtension.equals("flac")) {
|
if (!fileExtension.equals("wav") && !fileExtension.equals("mp3") && !fileExtension.equals("flac")) {
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FORMAT.toString()));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_FORMAT.toString()));
|
||||||
@@ -85,11 +93,17 @@ public class DownloadSubCommand extends CommandAPICommand {
|
|||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_DISC.toString().replace("%filename%", filename)));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_DISC.toString().replace("%filename%", filename)));
|
||||||
} catch (URISyntaxException | MalformedURLException e) {
|
} catch (URISyntaxException | MalformedURLException e) {
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.DOWNLOAD_ERROR.toString()));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.DOWNLOAD_ERROR.toString()));
|
||||||
e.printStackTrace();
|
pluginLogger.warning("A download error occurred.");
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.DOWNLOAD_ERROR.toString()));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.DOWNLOAD_ERROR.toString()));
|
||||||
e.printStackTrace();
|
pluginLogger.warning("A download error occurred.");
|
||||||
|
if(debugModeResult) {
|
||||||
|
pluginLogger.log(Level.SEVERE, "Exception output: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -109,4 +123,5 @@ public class DownloadSubCommand extends CommandAPICommand {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package me.Navoei.customdiscsplugin.command.SubCommands;
|
||||||
|
|
||||||
|
import me.Navoei.customdiscsplugin.CustomDiscs;
|
||||||
|
import me.Navoei.customdiscsplugin.TypeChecker;
|
||||||
|
import me.Navoei.customdiscsplugin.language.Lang;
|
||||||
|
|
||||||
|
import dev.jorel.commandapi.CommandAPICommand;
|
||||||
|
import dev.jorel.commandapi.arguments.IntegerArgument;
|
||||||
|
import dev.jorel.commandapi.executors.CommandArguments;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class SetHornCooldownSubCommand extends CommandAPICommand {
|
||||||
|
private final CustomDiscs plugin;
|
||||||
|
|
||||||
|
public SetHornCooldownSubCommand(CustomDiscs plugin) {
|
||||||
|
super("goatcooldown");
|
||||||
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
this.withFullDescription(NamedTextColor.GRAY + "Set the cooldown for a modified goat horn (range from 1 to "+ this.plugin.hornMaxCooldown +" in ticks).");
|
||||||
|
this.withUsage("/cd goatcooldown <range>");
|
||||||
|
this.withPermission("customdiscs.horncooldown");
|
||||||
|
|
||||||
|
this.withArguments(new IntegerArgument("goatcooldown"));
|
||||||
|
|
||||||
|
this.executesPlayer(this::onCommandPlayer);
|
||||||
|
this.executesConsole(this::onCommandConsole);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int onCommandPlayer(Player player, CommandArguments arguments) {
|
||||||
|
if (!TypeChecker.isCustomGoatHornPlayer(player)) {
|
||||||
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_MODIFIED_GOATHORN.toString()));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TypeChecker.isCustomGoatHornPlayer(player)) {
|
||||||
|
if (!CustomDiscs.isMusicDiscEnable()) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CUSTOM_HORN_DISABLED.toString())); return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
int goatcooldown = Objects.requireNonNull(arguments.getByClass("goatcooldown", Integer.class));
|
||||||
|
|
||||||
|
if (goatcooldown <= 0 || goatcooldown > this.plugin.hornMaxCooldown) {
|
||||||
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_COOLDOWN.toString().replace("%cooldown_value%", Integer.toString(this.plugin.hornMaxCooldown))));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack disc = new ItemStack(player.getInventory().getItemInMainHand());
|
||||||
|
ItemMeta meta = disc.getItemMeta();
|
||||||
|
PersistentDataContainer data = meta.getPersistentDataContainer();
|
||||||
|
|
||||||
|
data.set(new NamespacedKey(this.plugin, "customhorncoolodwn"), PersistentDataType.INTEGER, Math.min(goatcooldown, CustomDiscs.getInstance().hornMaxCooldown));
|
||||||
|
player.getInventory().getItemInMainHand().setItemMeta(meta);
|
||||||
|
|
||||||
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_CUSTOM_GOAT_COOLDOWN.toString().replace("%custom_goat_cooldown%", Integer.toString(goatcooldown))));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int onCommandConsole(ConsoleCommandSender executor, CommandArguments arguments) {
|
||||||
|
executor.sendMessage(NamedTextColor.RED + "Only players can use this command : '"+arguments+"'!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,26 +1,25 @@
|
|||||||
package me.Navoei.customdiscsplugin.command.SubCommands;
|
package me.Navoei.customdiscsplugin.command.SubCommands;
|
||||||
|
|
||||||
|
import me.Navoei.customdiscsplugin.CustomDiscs;
|
||||||
|
import me.Navoei.customdiscsplugin.TypeChecker;
|
||||||
|
import me.Navoei.customdiscsplugin.language.Lang;
|
||||||
|
|
||||||
import dev.jorel.commandapi.CommandAPICommand;
|
import dev.jorel.commandapi.CommandAPICommand;
|
||||||
import dev.jorel.commandapi.arguments.FloatArgument;
|
import dev.jorel.commandapi.arguments.FloatArgument;
|
||||||
import dev.jorel.commandapi.executors.CommandArguments;
|
import dev.jorel.commandapi.executors.CommandArguments;
|
||||||
import me.Navoei.customdiscsplugin.CustomDiscs;
|
|
||||||
import me.Navoei.customdiscsplugin.language.Lang;
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
//import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
//import org.bukkit.Material;
|
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
//import org.bukkit.inventory.ItemFlag;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.persistence.PersistentDataContainer;
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
public class SetRangeSubCommand extends CommandAPICommand {
|
public class SetRangeSubCommand extends CommandAPICommand {
|
||||||
private final CustomDiscs plugin;
|
private final CustomDiscs plugin;
|
||||||
@@ -31,6 +30,7 @@ public class SetRangeSubCommand extends CommandAPICommand {
|
|||||||
|
|
||||||
this.withFullDescription(NamedTextColor.GRAY + "Set the range of a disc to the defined value (range from 1 to "+ this.plugin.musicDiscMaxDistance +").");
|
this.withFullDescription(NamedTextColor.GRAY + "Set the range of a disc to the defined value (range from 1 to "+ this.plugin.musicDiscMaxDistance +").");
|
||||||
this.withUsage("/cd range <range>");
|
this.withUsage("/cd range <range>");
|
||||||
|
this.withPermission("customdiscs.range");
|
||||||
|
|
||||||
this.withArguments(new FloatArgument("range"));
|
this.withArguments(new FloatArgument("range"));
|
||||||
|
|
||||||
@@ -41,28 +41,40 @@ public class SetRangeSubCommand extends CommandAPICommand {
|
|||||||
private int onCommandPlayer(Player player, CommandArguments arguments) {
|
private int onCommandPlayer(Player player, CommandArguments arguments) {
|
||||||
|
|
||||||
ItemStack item = player.getInventory().getItemInMainHand();
|
ItemStack item = player.getInventory().getItemInMainHand();
|
||||||
|
boolean resultIsCustomDisc = TypeChecker.isCustomMusicDisc(item);
|
||||||
|
boolean resultIsCustomHorn = TypeChecker.isCustomGoatHornPlayer(player);
|
||||||
|
boolean resultIsCustomHead = TypeChecker.isCustomHeadPlayer(player);
|
||||||
|
|
||||||
if (!isCustomDisc(item)) {
|
if (!resultIsCustomDisc && !resultIsCustomHorn && !resultIsCustomHead) {
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_DISC.toString()));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NOT_HOLDING_CORRECT_ITEM.toString()));
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!player.hasPermission("customdiscs.range")) {
|
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.NO_PERMISSION.toString()));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float range = Objects.requireNonNull(arguments.getByClass("range", Float.class));
|
Float range = Objects.requireNonNull(arguments.getByClass("range", Float.class));
|
||||||
|
|
||||||
if ( range < 1 || range > this.plugin.musicDiscMaxDistance) {
|
Float configMusicDiscMaxDistance;
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_RANGE.toString().replace("%range_value%", Float.toString(this.plugin.musicDiscMaxDistance))));
|
if (resultIsCustomHorn) {
|
||||||
|
if (!CustomDiscs.isCustomHornEnable()) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CUSTOM_HORN_DISABLED.toString())); return 1; }
|
||||||
|
configMusicDiscMaxDistance = this.plugin.customHornMaxDistance;
|
||||||
|
} else if (resultIsCustomHead) {
|
||||||
|
if (!CustomDiscs.isCustomHeadEnable()) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CUSTOM_HEAD_DISABLED.toString())); return 1; }
|
||||||
|
configMusicDiscMaxDistance = this.plugin.customHeadMaxDistance;
|
||||||
|
} else {
|
||||||
|
if (!CustomDiscs.isMusicDiscEnable()) { player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CUSTOM_MUSIC_DISABLED.toString())); return 1; }
|
||||||
|
configMusicDiscMaxDistance = this.plugin.musicDiscMaxDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( range < 1 || range > configMusicDiscMaxDistance) {
|
||||||
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.INVALID_RANGE.toString().replace("%range_value%", Float.toString(configMusicDiscMaxDistance))));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemMeta meta = item.getItemMeta();
|
ItemMeta meta = item.getItemMeta();
|
||||||
PersistentDataContainer data = meta.getPersistentDataContainer();
|
PersistentDataContainer data = meta.getPersistentDataContainer();
|
||||||
data.set(new NamespacedKey(this.plugin, "range"), PersistentDataType.FLOAT, range);
|
data.set(new NamespacedKey(this.plugin, "range"), PersistentDataType.FLOAT, range);
|
||||||
player.getInventory().getItemInMainHand().setItemMeta(meta);
|
player.getInventory().getItemInMainHand().setItemMeta(meta);
|
||||||
|
|
||||||
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_CUSTOM_RANGE.toString().replace("%custom_range%", Float.toString(range))));
|
player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.PREFIX + Lang.CREATE_CUSTOM_RANGE.toString().replace("%custom_range%", Float.toString(range))));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -73,9 +85,4 @@ public class SetRangeSubCommand extends CommandAPICommand {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCustomDisc(ItemStack item) {
|
|
||||||
if (item==null) return false;
|
|
||||||
return item.getType().toString().contains("MUSIC_DISC") && item.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(plugin, "customdisc"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
127
src/main/java/me/Navoei/customdiscsplugin/event/HeadPlay.java
Normal file
127
src/main/java/me/Navoei/customdiscsplugin/event/HeadPlay.java
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
package me.Navoei.customdiscsplugin.event;
|
||||||
|
|
||||||
|
import me.Navoei.customdiscsplugin.CustomDiscs;
|
||||||
|
import me.Navoei.customdiscsplugin.PlayerManager;
|
||||||
|
import me.Navoei.customdiscsplugin.VoicePlugin;
|
||||||
|
import me.Navoei.customdiscsplugin.language.Lang;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.Skull;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.event.block.NotePlayEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class HeadPlay implements Listener{
|
||||||
|
|
||||||
|
CustomDiscs customDiscs = CustomDiscs.getInstance();
|
||||||
|
PlayerManager playerManager = PlayerManager.instance();
|
||||||
|
|
||||||
|
// Triggered on every noteblock interaction.
|
||||||
|
// Most of the function will only be executed if a custom player head is found on top of the noteblock.
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onNotePlay(NotePlayEvent event) throws IOException {
|
||||||
|
Block noteBlock = event.getBlock();
|
||||||
|
|
||||||
|
if (noteBlock.getType() != Material.NOTE_BLOCK) return;
|
||||||
|
|
||||||
|
if (PlayerManager.instance().isAudioPlayerPlaying(noteBlock.getLocation())) return;
|
||||||
|
|
||||||
|
Block headBlock = noteBlock.getRelative(BlockFace.UP);
|
||||||
|
if (headBlock.getType() != Material.PLAYER_HEAD) return;
|
||||||
|
|
||||||
|
Skull skull = (Skull) headBlock.getState();
|
||||||
|
PersistentDataContainer persistentDataContainer = skull.getPersistentDataContainer();
|
||||||
|
|
||||||
|
if (persistentDataContainer.has(new NamespacedKey(customDiscs, "customhead"), PersistentDataType.STRING)) {
|
||||||
|
|
||||||
|
String soundFileName = persistentDataContainer.get(new NamespacedKey(customDiscs, "customhead"), PersistentDataType.STRING);
|
||||||
|
|
||||||
|
float range = CustomDiscs.getInstance().customHeadDistance;
|
||||||
|
NamespacedKey customSoundRangeKey = new NamespacedKey(customDiscs, "range");
|
||||||
|
NamespacedKey customLore = new NamespacedKey(customDiscs, "headlore");
|
||||||
|
|
||||||
|
if(persistentDataContainer.has(customSoundRangeKey, PersistentDataType.FLOAT)) {
|
||||||
|
float soundRange = Optional.ofNullable(persistentDataContainer.get(customSoundRangeKey, PersistentDataType.FLOAT)).orElse(0f);
|
||||||
|
range = Math.min(soundRange, CustomDiscs.getInstance().customHeadMaxDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
Path soundFilePath = Path.of(customDiscs.getDataFolder().getPath(), "musicdata", soundFileName);
|
||||||
|
|
||||||
|
if (soundFilePath.toFile().exists()) {
|
||||||
|
Component songNameComponent = Optional.ofNullable(persistentDataContainer.get(customLore, PersistentDataType.STRING)).map(GsonComponentSerializer.gson()::deserialize).orElse(Component.text("Unknown Song", NamedTextColor.GRAY));
|
||||||
|
String songName = PlainTextComponentSerializer.plainText().serialize(songNameComponent);
|
||||||
|
Component customActionBarSongPlaying = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.NOW_PLAYING.toString().replace("%song_name%", songName));
|
||||||
|
|
||||||
|
assert VoicePlugin.voicechatServerApi != null;
|
||||||
|
playerManager.playAudioHead(VoicePlugin.voicechatServerApi, soundFilePath, noteBlock, customActionBarSongPlaying, range);
|
||||||
|
} else {
|
||||||
|
event.setCancelled(true);
|
||||||
|
throw new FileNotFoundException("Sound file is missing!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event to delay by 1 tick after a player head had been placed
|
||||||
|
// Delay will only be triggered on custom player head created with this plugin
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onHeadPlace(BlockPlaceEvent event) {
|
||||||
|
ItemStack item = event.getItemInHand();
|
||||||
|
|
||||||
|
if (item.getType() != Material.PLAYER_HEAD) return;
|
||||||
|
if (!(item.getItemMeta() instanceof SkullMeta meta)) return;
|
||||||
|
|
||||||
|
PersistentDataContainer itemPDC = meta.getPersistentDataContainer();
|
||||||
|
if (!itemPDC.has(new NamespacedKey(customDiscs, "customhead"), PersistentDataType.STRING)) return;
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskLater(customDiscs, () -> {
|
||||||
|
Block block = event.getBlockPlaced();
|
||||||
|
if (block.getType() != Material.PLAYER_HEAD && block.getType() != Material.PLAYER_WALL_HEAD) return;
|
||||||
|
|
||||||
|
Skull skull = (Skull) block.getState();
|
||||||
|
PersistentDataContainer blockPDC = skull.getPersistentDataContainer();
|
||||||
|
|
||||||
|
NamespacedKey headKey = new NamespacedKey(customDiscs, "customhead");
|
||||||
|
NamespacedKey loreKey = new NamespacedKey(customDiscs, "headlore");
|
||||||
|
NamespacedKey rangeKey = new NamespacedKey(customDiscs, "range");
|
||||||
|
|
||||||
|
if (itemPDC.has(headKey, PersistentDataType.STRING)) {
|
||||||
|
String customheadValue = itemPDC.get(headKey, PersistentDataType.STRING);
|
||||||
|
blockPDC.set(headKey, PersistentDataType.STRING, customheadValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPDC.has(loreKey, PersistentDataType.STRING)) {
|
||||||
|
String headloreValue = itemPDC.get(loreKey, PersistentDataType.STRING);
|
||||||
|
blockPDC.set(loreKey, PersistentDataType.STRING, headloreValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPDC.has(rangeKey, PersistentDataType.FLOAT)) {
|
||||||
|
Float rangeValue = itemPDC.get(rangeKey, PersistentDataType.FLOAT);
|
||||||
|
blockPDC.set(rangeKey, PersistentDataType.FLOAT, rangeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
skull.update(true, true);
|
||||||
|
}, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
145
src/main/java/me/Navoei/customdiscsplugin/event/HornPlay.java
Normal file
145
src/main/java/me/Navoei/customdiscsplugin/event/HornPlay.java
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
package me.Navoei.customdiscsplugin.event;
|
||||||
|
|
||||||
|
import me.Navoei.customdiscsplugin.CustomDiscs;
|
||||||
|
import me.Navoei.customdiscsplugin.PlayerManager;
|
||||||
|
import me.Navoei.customdiscsplugin.TypeChecker;
|
||||||
|
import me.Navoei.customdiscsplugin.VoicePlugin;
|
||||||
|
|
||||||
|
import io.papermc.paper.datacomponent.DataComponentTypes;
|
||||||
|
|
||||||
|
import me.Navoei.customdiscsplugin.language.Lang;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.MusicInstrument;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class HornPlay implements Listener{
|
||||||
|
|
||||||
|
CustomDiscs customDiscs = CustomDiscs.getInstance();
|
||||||
|
PlayerManager playerManager = PlayerManager.instance();
|
||||||
|
|
||||||
|
private final List<Material> goatHornNotInteractable = Arrays.asList(
|
||||||
|
Material.ANVIL,
|
||||||
|
Material.ARMOR_STAND,
|
||||||
|
Material.BARREL,
|
||||||
|
Material.BEACON,
|
||||||
|
Material.BLAST_FURNACE,
|
||||||
|
Material.BREWING_STAND,
|
||||||
|
Material.CARTOGRAPHY_TABLE,
|
||||||
|
Material.CHIPPED_ANVIL,
|
||||||
|
Material.CHISELED_BOOKSHELF,
|
||||||
|
Material.COMMAND_BLOCK,
|
||||||
|
Material.COMPARATOR,
|
||||||
|
Material.CRAFTER,
|
||||||
|
Material.CRAFTING_TABLE,
|
||||||
|
Material.DAMAGED_ANVIL,
|
||||||
|
Material.DAYLIGHT_DETECTOR,
|
||||||
|
Material.DECORATED_POT,
|
||||||
|
Material.DISPENSER,
|
||||||
|
Material.DROPPER,
|
||||||
|
Material.ENCHANTING_TABLE,
|
||||||
|
Material.FLOWER_POT,
|
||||||
|
Material.FURNACE,
|
||||||
|
Material.GRINDSTONE,
|
||||||
|
Material.HOPPER,
|
||||||
|
Material.ITEM_FRAME,
|
||||||
|
Material.LECTERN,
|
||||||
|
Material.LEVER,
|
||||||
|
Material.LOOM,
|
||||||
|
Material.NOTE_BLOCK,
|
||||||
|
Material.REPEATER,
|
||||||
|
Material.SMITHING_TABLE,
|
||||||
|
Material.SMOKER,
|
||||||
|
Material.STONECUTTER,
|
||||||
|
Material.STRUCTURE_BLOCK
|
||||||
|
);
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) throws IOException {
|
||||||
|
ItemStack item = event.getItem();
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
if (item == null) return;
|
||||||
|
if (item.getType() != Material.GOAT_HORN) return;
|
||||||
|
|
||||||
|
Block block = event.getClickedBlock();
|
||||||
|
if (player.hasCooldown(Material.GOAT_HORN)) return;
|
||||||
|
|
||||||
|
if (TypeChecker.isCustomGoatHorn(event) && ((event.getAction() == Action.RIGHT_CLICK_BLOCK) || (event.getAction() == Action.RIGHT_CLICK_AIR))) {
|
||||||
|
|
||||||
|
if (!player.isSneaking() && block != null) {
|
||||||
|
Material targetBlockType = block.getType();
|
||||||
|
if (goatHornNotInteractable.contains(targetBlockType)) return;
|
||||||
|
if (targetBlockType.name().contains("_BED") || targetBlockType.name().contains("_BOAT") || targetBlockType.name().contains("_BUTTON") || targetBlockType.name().contains("CHEST") || targetBlockType.name().contains("_DOOR") /*|| targetBlockType.name().contains("_FENCE_GATE") */|| targetBlockType.name().contains("_GATE") || targetBlockType.name().contains("MINECART") || targetBlockType.name().contains("POTTED_") || targetBlockType.name().contains("_SIGN") || targetBlockType.name().contains("_TRAPDOOR")) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String soundFileName = event.getItem().getItemMeta().getPersistentDataContainer().get(new NamespacedKey(customDiscs, "customhorn"), PersistentDataType.STRING);
|
||||||
|
|
||||||
|
@Nonnull PersistentDataContainer persistentDataContainer = event.getItem().getItemMeta().getPersistentDataContainer();
|
||||||
|
|
||||||
|
float range = CustomDiscs.getInstance().customHornDistance;
|
||||||
|
NamespacedKey customSoundRangeKey = new NamespacedKey(customDiscs, "range");
|
||||||
|
|
||||||
|
if(persistentDataContainer.has(customSoundRangeKey, PersistentDataType.FLOAT)) {
|
||||||
|
float soundRange = Optional.ofNullable(persistentDataContainer.get(customSoundRangeKey, PersistentDataType.FLOAT)).orElse(0f);
|
||||||
|
range = Math.min(soundRange, CustomDiscs.getInstance().customHornMaxDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hornCooldown;
|
||||||
|
NamespacedKey hornCooldownKey = new NamespacedKey(customDiscs, "customhorncoolodwn");
|
||||||
|
if(persistentDataContainer.has(hornCooldownKey, PersistentDataType.INTEGER)) {
|
||||||
|
hornCooldown = Math.min(persistentDataContainer.get(hornCooldownKey, PersistentDataType.INTEGER), CustomDiscs.getInstance().hornMaxCooldown);
|
||||||
|
} else {
|
||||||
|
hornCooldown = Math.min(CustomDiscs.getInstance().hornCooldown, CustomDiscs.getInstance().hornMaxCooldown);
|
||||||
|
}
|
||||||
|
|
||||||
|
Path soundFilePath = Path.of(customDiscs.getDataFolder().getPath(), "musicdata", soundFileName);
|
||||||
|
|
||||||
|
if (soundFilePath.toFile().exists()) {
|
||||||
|
|
||||||
|
String songName = "Unknown sound";
|
||||||
|
|
||||||
|
MusicInstrument instrument = item.getDataOrDefault(DataComponentTypes.INSTRUMENT, null);
|
||||||
|
if (instrument != null) {
|
||||||
|
Component songNameComponent = instrument.description(); // This is the one you're asking for
|
||||||
|
songName = PlainTextComponentSerializer.plainText().serialize(songNameComponent);
|
||||||
|
} else {
|
||||||
|
songName = "Unknown sound";
|
||||||
|
}
|
||||||
|
|
||||||
|
Component customActionBarSongPlaying = LegacyComponentSerializer.legacyAmpersand().deserialize(Lang.NOW_PLAYING.toString().replace("%song_name%", songName));
|
||||||
|
|
||||||
|
assert VoicePlugin.voicechatServerApi != null;
|
||||||
|
playerManager.playAudioHorn(VoicePlugin.voicechatServerApi, soundFilePath, player, customActionBarSongPlaying.asComponent(), range);
|
||||||
|
player.setCooldown(Material.GOAT_HORN, hornCooldown);
|
||||||
|
} else {
|
||||||
|
player.sendMessage(NamedTextColor.RED + "Sound file not found.");
|
||||||
|
event.setCancelled(true);
|
||||||
|
throw new FileNotFoundException("Sound file is missing!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,15 +1,18 @@
|
|||||||
package me.Navoei.customdiscsplugin.event;
|
package me.Navoei.customdiscsplugin.event;
|
||||||
|
|
||||||
import io.papermc.paper.datacomponent.DataComponentTypes;
|
|
||||||
import io.papermc.paper.datacomponent.item.TooltipDisplay;
|
|
||||||
import me.Navoei.customdiscsplugin.CustomDiscs;
|
import me.Navoei.customdiscsplugin.CustomDiscs;
|
||||||
import me.Navoei.customdiscsplugin.PlayerManager;
|
import me.Navoei.customdiscsplugin.PlayerManager;
|
||||||
import me.Navoei.customdiscsplugin.VoicePlugin;
|
import me.Navoei.customdiscsplugin.VoicePlugin;
|
||||||
import me.Navoei.customdiscsplugin.language.Lang;
|
import me.Navoei.customdiscsplugin.language.Lang;
|
||||||
|
|
||||||
|
import io.papermc.paper.datacomponent.DataComponentTypes;
|
||||||
|
import io.papermc.paper.datacomponent.item.TooltipDisplay;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@@ -24,7 +27,6 @@ import org.bukkit.event.entity.EntityExplodeEvent;
|
|||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.inventory.meta.components.JukeboxPlayableComponent;
|
|
||||||
import org.bukkit.persistence.PersistentDataContainer;
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
@@ -112,7 +114,7 @@ public class JukeBox implements Listener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (player.isSneaking() && !itemInvolvedInEvent.getType().equals(Material.AIR)) return;
|
if (player.isSneaking() && !itemInvolvedInEvent.getType().equals(Material.AIR)) return;
|
||||||
stopDisc(block);
|
playerManager.stopDisc(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +127,7 @@ public class JukeBox implements Listener{
|
|||||||
Jukebox jukebox = (Jukebox) block.getState();
|
Jukebox jukebox = (Jukebox) block.getState();
|
||||||
if (!isCustomMusicDisc(jukebox.getRecord())) return;
|
if (!isCustomMusicDisc(jukebox.getRecord())) return;
|
||||||
|
|
||||||
stopDisc(block);
|
playerManager.stopDisc(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
@@ -135,7 +137,7 @@ public class JukeBox implements Listener{
|
|||||||
if (explodedBlock.getType() == Material.JUKEBOX) {
|
if (explodedBlock.getType() == Material.JUKEBOX) {
|
||||||
Jukebox jukebox = (Jukebox) explodedBlock.getState();
|
Jukebox jukebox = (Jukebox) explodedBlock.getState();
|
||||||
if (!isCustomMusicDisc(jukebox.getRecord())) return;
|
if (!isCustomMusicDisc(jukebox.getRecord())) return;
|
||||||
stopDisc(explodedBlock);
|
playerManager.stopDisc(explodedBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,8 +154,4 @@ public class JukeBox implements Listener{
|
|||||||
return itemStack.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customdisc"));
|
return itemStack.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(customDiscs, "customdisc"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopDisc(Block block) {
|
|
||||||
playerManager.stopLocationalAudio(block.getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,10 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
|
|
||||||
public enum Lang {
|
public enum Lang {
|
||||||
PREFIX("prefix", "&8[&6CustomDiscs&8]&r"),
|
PREFIX("prefix", "&8[&6CustomDiscs&8]&r"),
|
||||||
NO_PERMISSION("no-permission", "&rYou do not have permission to execute this command."),
|
|
||||||
INVALID_FILENAME("invalid-filename", "&rThis is an invalid filename!"),
|
INVALID_FILENAME("invalid-filename", "&rThis is an invalid filename!"),
|
||||||
INVALID_FORMAT("invalid-format", "&rFile must be in wav, flac, or mp3 format!"),
|
INVALID_FORMAT("invalid-format", "&rFile must be in wav, flac, or mp3 format!"),
|
||||||
FILE_NOT_FOUND("file-not-found", "&rFile not found!"),
|
FILE_NOT_FOUND("file-not-found", "&rFile not found!"),
|
||||||
INVALID_ARGUMENTS("invalid-arguments", "&rInsufficient arguments. &7(&a%command_syntax%&7)"),
|
NOT_HOLDING_CORRECT_ITEM("not-holding-correct-item", "&rYou must either hold a disc, goat horn or player head in your main hand."),
|
||||||
NOT_HOLDING_DISC("not-holding-disc", "&rYou must hold a disc in your main hand."),
|
|
||||||
CREATE_FILENAME("create-filename", "&7Your filename is: &a\"%filename%\"."),
|
CREATE_FILENAME("create-filename", "&7Your filename is: &a\"%filename%\"."),
|
||||||
CREATE_CUSTOM_NAME("create-custom-name", "&7Your custom name is: &a\"%custom_name%\"."),
|
CREATE_CUSTOM_NAME("create-custom-name", "&7Your custom name is: &a\"%custom_name%\"."),
|
||||||
DOWNLOADING_FILE("downloading-file", "&7Downloading file..."),
|
DOWNLOADING_FILE("downloading-file", "&7Downloading file..."),
|
||||||
@@ -18,9 +16,15 @@ public enum Lang {
|
|||||||
CREATE_DISC("create-disc", "&aCreate a disc by doing &7/cd create filename.extension \"Custom Lore\"&a."),
|
CREATE_DISC("create-disc", "&aCreate a disc by doing &7/cd create filename.extension \"Custom Lore\"&a."),
|
||||||
DOWNLOAD_ERROR("download-error", "&rAn error has occurred while downloading."),
|
DOWNLOAD_ERROR("download-error", "&rAn error has occurred while downloading."),
|
||||||
NOW_PLAYING("now-playing","&6Now playing: %song_name%"),
|
NOW_PLAYING("now-playing","&6Now playing: %song_name%"),
|
||||||
DISC_CONVERTED("disc-converted", "&aConverted disc to new format! &fThis is due to changes in newer Minecraft versions which introduced &7JukeboxPlayableComponent&f."),
|
DISC_CONVERTED("disc-converted", "&aConverted disc to new format! &fThis is due to changes in newer Minecraft versions which introduced &ToolTipDisplay&f."),
|
||||||
INVALID_RANGE("invalid-range","&rYou need to chose a range between 1 and %range_value%"),
|
INVALID_RANGE("invalid-range","&rYou need to chose a range between 1 and %range_value%"),
|
||||||
CREATE_CUSTOM_RANGE("create-custom-range", "&7Your range is set to: &a\"%custom_range%\".");
|
CREATE_CUSTOM_RANGE("create-custom-range", "&7Your range is set to: &a\"%custom_range%\"."),
|
||||||
|
NOT_HOLDING_MODIFIED_GOATHORN("not-holding-modified-goathorn", "&cYou must hold a modified goat horn in your main hand."),
|
||||||
|
INVALID_COOLDOWN("invalid-cooldown","&cYou need to chose a cooldown between 1 and %cooldown_value% (in ticks)"),
|
||||||
|
CREATE_CUSTOM_GOAT_COOLDOWN("create-custom-goat-cooldown", "&7Your goat horn cooldown is set to: &a\"%custom_goat_cooldown%\"."),
|
||||||
|
CUSTOM_MUSIC_DISABLED("custom-music-disabled", "&7Custom music discs are disabled in the configuration."),
|
||||||
|
CUSTOM_HEAD_DISABLED("custom-head-disabled", "&7Custom player heads are disabled in the configuration."),
|
||||||
|
CUSTOM_HORN_DISABLED("custom-horn-disabled", "&7Custom goat horns are disabled in the configuration.");
|
||||||
|
|
||||||
private final String path;
|
private final String path;
|
||||||
private final String def;
|
private final String def;
|
||||||
@@ -67,6 +71,4 @@ public enum Lang {
|
|||||||
return this.path;
|
return this.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Component textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(PlaceholderAPI.setPlaceholders(player, Lang.PREFIX + Lang.COMBAT.toString()));
|
|
||||||
//player.sendMessage(textComponent);
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,21 @@
|
|||||||
# [Music Disc Config]
|
# [General CustomDiscs Config]
|
||||||
|
|
||||||
|
# The maximum download size in megabytes.
|
||||||
|
max-download-size: 50
|
||||||
|
|
||||||
|
# The master volume of music discs from 0-1. (You can set values like 0.5 for 50% volume).
|
||||||
|
music-disc-volume: 1
|
||||||
|
|
||||||
|
# Debug Mode - To display some more logging information and Stack Trace informations
|
||||||
|
debugMode: false
|
||||||
|
|
||||||
|
# [Music Discs Config]
|
||||||
|
|
||||||
|
# Enable custom music discs.
|
||||||
|
music-disc-enable: true
|
||||||
|
|
||||||
|
# Enable "Now playing" message for custom music discs.
|
||||||
|
music-disc-playing-enable: true
|
||||||
|
|
||||||
# The distance from which music discs can be heard in blocks.
|
# The distance from which music discs can be heard in blocks.
|
||||||
music-disc-distance: 16
|
music-disc-distance: 16
|
||||||
@@ -6,15 +23,46 @@ music-disc-distance: 16
|
|||||||
# The max distance from which music discs can be heard in blocks.
|
# The max distance from which music discs can be heard in blocks.
|
||||||
music-disc-max-distance: 256
|
music-disc-max-distance: 256
|
||||||
|
|
||||||
# The master volume of music discs from 0-1. (You can set values like 0.5 for 50% volume).
|
# [Goat Horns Config]
|
||||||
music-disc-volume: 1
|
|
||||||
|
|
||||||
# The maximum download size in megabytes.
|
# Enable custom goat horns.
|
||||||
max-download-size: 50
|
custom-horn-enable: true
|
||||||
|
|
||||||
#Custom Discs Help Page
|
# Enable "Now playing" message for custom horns.
|
||||||
|
custom-horn-playing-enable: true
|
||||||
|
|
||||||
|
# The distance from which custom horns can be heard in blocks.
|
||||||
|
custom-horn-distance: 16
|
||||||
|
|
||||||
|
# The max distance from which custom horns can be heard in blocks.
|
||||||
|
custom-horn-max-distance: 256
|
||||||
|
|
||||||
|
# The default cooldown time for horns in ticks from 1 to the max value of horn-max-cooldown (1 second is 20 ticks).
|
||||||
|
horn-cooldown: 140
|
||||||
|
|
||||||
|
# The default max cooldown time for horns in ticks (1 second is 20 ticks).
|
||||||
|
horn-max-cooldown: 6000
|
||||||
|
|
||||||
|
# [Player Heads Config]
|
||||||
|
|
||||||
|
# Enable custom player heads.
|
||||||
|
custom-head-enable: true
|
||||||
|
|
||||||
|
# Enable "Now playing" message for player heads.
|
||||||
|
custom-head-playing-enable: true
|
||||||
|
|
||||||
|
# The distance from which music discs can be heard in blocks.
|
||||||
|
custom-head-distance: 16
|
||||||
|
|
||||||
|
# The max distance from which music discs can be heard in blocks.
|
||||||
|
custom-head-max-distance: 256
|
||||||
|
|
||||||
|
|
||||||
|
# [DO NOT EDIT BELOW THIS LINE - Help configuration]
|
||||||
|
# Custom Discs Help Page
|
||||||
help:
|
help:
|
||||||
- "&8-[&6CustomDiscs Help Page&8]-"
|
- "&8-[&6CustomDiscs v5.0 - Help Page&8]-"
|
||||||
- "&aAuthor&7: &6Navoei"
|
- "&aAuthor&7: &6Navoei"
|
||||||
- "&aContributors&7: &6alfw / &6Athar42"
|
- "&aContributors&7: &6Athar42 / &6alfw"
|
||||||
- "&fGit&0Hub&7: &9&ohttps://github.com/Navoei/CustomDiscs"
|
- "&fGit&0Hub&7: &9&ohttps://github.com/Navoei/CustomDiscs"
|
||||||
|
- "&aDiscord&7: &9&ohttps://discord.gg/YJpqruvZ97"
|
||||||
BIN
src/main/resources/goat_horn_category.png
Normal file
BIN
src/main/resources/goat_horn_category.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 197 B |
@@ -1,19 +1,22 @@
|
|||||||
prefix: "&8[&6CustomDiscs&8]&r"
|
prefix: '&8[&6CustomDiscs&8]&r'
|
||||||
no-permission: "&cYou do not have permission to execute this command."
|
invalid-filename: '&cThis is an invalid filename!'
|
||||||
invalid-filename: "&cThis is an invalid filename!"
|
invalid-format: '&cFile must be in wav, flac, or mp3 format!'
|
||||||
no-disc-name-provided: "&cYou must provide a name for your disc."
|
file-not-found: '&cFile not found!'
|
||||||
invalid-format: "&cFile must be in wav, flac, or mp3 format!"
|
not-holding-correct-item: '&cYou must either hold a disc, goat horn or player head in your main hand.'
|
||||||
file-not-found: "&cFile not found!"
|
create-filename: '&7Your filename is: &a"%filename%".'
|
||||||
invalid-arguments: "&cInvalid arguments. &7(&a%command_syntax%&7)"
|
create-custom-name: '&7Your custom name is: &a"%custom_name%".'
|
||||||
not-holding-disc: "&cYou must hold a disc in your main hand."
|
downloading-file: '&7Downloading file...'
|
||||||
create-filename: "&7Your filename is: &a\"%filename%\"."
|
file-too-large: '&cThe file is larger than %max_download_size%MB.'
|
||||||
create-custom-name: "&7Your custom name is: &a\"%custom_name%\"."
|
successful-download: '&aFile successfully downloaded to &7%file_path%&a.'
|
||||||
downloading-file: "&7Downloading file..."
|
create-disc: '&aCreate a disc by doing &7/cd create %filename% "Custom Lore"&a.'
|
||||||
file-too-large: "&cThe file is larger than %max_download_size%MB."
|
download-error: '&cAn error has occurred while downloading.'
|
||||||
successful-download: "&aFile successfully downloaded to &7%file_path%&a."
|
now-playing: '&6Now playing: %song_name%'
|
||||||
create-disc: "&aCreate a disc by doing &7/cd create %filename% \"Custom Lore\"&a."
|
disc-converted: '&aConverted disc to new format! &fThis is due to changes in newer Minecraft versions which introduced &7ToolTipDisplay&f.'
|
||||||
download-error: "&cAn error has occurred while downloading."
|
invalid-range: '&cYou need to chose a range between 1 and %range_value%'
|
||||||
now-playing: "&6Now playing: %song_name%"
|
create-custom-range: '&7Your range is set to: &a"%custom_range%".'
|
||||||
disc-converted: "&aConverted disc to new format! &fThis is due to changes in newer Minecraft versions which introduced &7ToolTipDisplay&f."
|
not-holding-modified-goathorn: '&cYou must hold a modified goat horn in your main hand.'
|
||||||
invalid-range: "&cYou need to chose a range between 1 and %range_value%"
|
invalid-cooldown: '&cYou need to chose a cooldown between 1 and %cooldown_value% (in ticks)'
|
||||||
create-custom-range: "&7Your range is set to: &a\"%custom_range%\"."
|
create-custom-goat-cooldown: '&7Your goat horn cooldown is set to: &a"%custom_goat_cooldown%".'
|
||||||
|
custom-music-disabled: '&7Custom music discs are disabled in the configuration.'
|
||||||
|
custom-head-disabled: '&7Custom player heads are disabled in the configuration.'
|
||||||
|
custom-horn-disabled: '&7Custom goat horns are disabled in the configuration.'
|
||||||
BIN
src/main/resources/player_head_category.png
Normal file
BIN
src/main/resources/player_head_category.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
@@ -4,7 +4,7 @@ main: me.Navoei.customdiscsplugin.CustomDiscs
|
|||||||
api-version: '${bukkit_api_version}'
|
api-version: '${bukkit_api_version}'
|
||||||
prefix: CustomDiscs
|
prefix: CustomDiscs
|
||||||
authors: [ "Navoei", "Athar42", "alfw" ]
|
authors: [ "Navoei", "Athar42", "alfw" ]
|
||||||
description: A plugin which uses the Simple Voice Chat API to add custom music discs.
|
description: A plugin which uses the Simple Voice Chat API to add custom music discs, goat horns and player's head.
|
||||||
depend: [ "voicechat", "ProtocolLib" ]
|
depend: [ "voicechat", "ProtocolLib" ]
|
||||||
dependencies:
|
dependencies:
|
||||||
server:
|
server:
|
||||||
|
|||||||
Reference in New Issue
Block a user