mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-08 09:27:58 +01:00
Implement playSound and openBook methods
This commit is contained in:
parent
52831e7091
commit
2c2f1b6cee
@ -0,0 +1,29 @@
|
||||
package net.minestom.server.adventure;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minestom.server.sound.Sound;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Adventure related utilities.
|
||||
*/
|
||||
public class AdventureUtils {
|
||||
private static final Map<String, Sound> SOUND_MAP =
|
||||
Arrays.stream(Sound.values()).collect(Collectors.toMap(Sound::getNamespaceID, sound -> sound));
|
||||
|
||||
/**
|
||||
* Attempts to get an NMS sound from an Adventure key.
|
||||
*
|
||||
* @param name the key
|
||||
*
|
||||
* @return the sound, if found
|
||||
*/
|
||||
public static @Nullable Sound asSound(@NotNull Key name) {
|
||||
return SOUND_MAP.get(name.asString());
|
||||
}
|
||||
}
|
@ -5,14 +5,13 @@ import net.kyori.adventure.audience.MessageType;
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.inventory.Book;
|
||||
import net.kyori.adventure.sound.SoundStop;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.title.Title;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.advancements.AdvancementTab;
|
||||
import net.minestom.server.attribute.Attribute;
|
||||
import net.minestom.server.adventure.AdventureUtils;
|
||||
import net.minestom.server.attribute.AttributeInstance;
|
||||
import net.minestom.server.bossbar.BossBar;
|
||||
import net.minestom.server.chat.ChatParser;
|
||||
@ -845,12 +844,13 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* @param z the effect Z
|
||||
* @param volume the volume of the sound (1 is 100%)
|
||||
* @param pitch the pitch of the sound, between 0.5 and 2.0
|
||||
* @deprecated Use {@link #playSound(net.kyori.adventure.sound.Sound, double, double, double)}
|
||||
*/
|
||||
public void playSound(@NotNull Sound sound, @NotNull SoundCategory soundCategory,
|
||||
int x, int y, int z, float volume, float pitch) {
|
||||
@Deprecated
|
||||
public void playSound(@NotNull Sound sound, @NotNull SoundCategory soundCategory, int x, int y, int z, float volume, float pitch) {
|
||||
SoundEffectPacket soundEffectPacket = new SoundEffectPacket();
|
||||
soundEffectPacket.soundId = sound.getId();
|
||||
soundEffectPacket.soundCategory = soundCategory;
|
||||
soundEffectPacket.soundCategory = soundCategory.ordinal();
|
||||
soundEffectPacket.x = x;
|
||||
soundEffectPacket.y = y;
|
||||
soundEffectPacket.z = z;
|
||||
@ -863,9 +863,10 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* Plays a sound from the {@link Sound} enum.
|
||||
*
|
||||
* @see #playSound(Sound, SoundCategory, int, int, int, float, float)
|
||||
* @deprecated Use {@link #playSound(net.kyori.adventure.sound.Sound, double, double, double)}
|
||||
*/
|
||||
public void playSound(@NotNull Sound sound, @NotNull SoundCategory soundCategory,
|
||||
BlockPosition position, float volume, float pitch) {
|
||||
@Deprecated
|
||||
public void playSound(@NotNull Sound sound, @NotNull SoundCategory soundCategory, BlockPosition position, float volume, float pitch) {
|
||||
playSound(sound, soundCategory, position.getX(), position.getY(), position.getZ(), volume, pitch);
|
||||
}
|
||||
|
||||
@ -879,12 +880,13 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* @param z the effect Z
|
||||
* @param volume the volume of the sound (1 is 100%)
|
||||
* @param pitch the pitch of the sound, between 0.5 and 2.0
|
||||
* @deprecated Use {@link #playSound(net.kyori.adventure.sound.Sound, double, double, double)}
|
||||
*/
|
||||
public void playSound(@NotNull String identifier, @NotNull SoundCategory soundCategory,
|
||||
int x, int y, int z, float volume, float pitch) {
|
||||
@Deprecated
|
||||
public void playSound(@NotNull String identifier, @NotNull SoundCategory soundCategory, int x, int y, int z, float volume, float pitch) {
|
||||
NamedSoundEffectPacket namedSoundEffectPacket = new NamedSoundEffectPacket();
|
||||
namedSoundEffectPacket.soundName = identifier;
|
||||
namedSoundEffectPacket.soundCategory = soundCategory;
|
||||
namedSoundEffectPacket.soundCategory = soundCategory.ordinal();
|
||||
namedSoundEffectPacket.x = x;
|
||||
namedSoundEffectPacket.y = y;
|
||||
namedSoundEffectPacket.z = z;
|
||||
@ -897,7 +899,9 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* Plays a sound from an identifier (represents a custom sound in a resource pack).
|
||||
*
|
||||
* @see #playSound(String, SoundCategory, int, int, int, float, float)
|
||||
* @deprecated Use {@link #playSound(net.kyori.adventure.sound.Sound, double, double, double)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void playSound(@NotNull String identifier, @NotNull SoundCategory soundCategory, BlockPosition position, float volume, float pitch) {
|
||||
playSound(identifier, soundCategory, position.getX(), position.getY(), position.getZ(), volume, pitch);
|
||||
}
|
||||
@ -909,7 +913,9 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* @param soundCategory the sound category
|
||||
* @param volume the volume of the sound (1 is 100%)
|
||||
* @param pitch the pitch of the sound, between 0.5 and 2.0
|
||||
* @deprecated Use {@link #playSound(net.kyori.adventure.sound.Sound)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void playSound(@NotNull Sound sound, @NotNull SoundCategory soundCategory, float volume, float pitch) {
|
||||
EntitySoundEffectPacket entitySoundEffectPacket = new EntitySoundEffectPacket();
|
||||
entitySoundEffectPacket.entityId = getEntityId();
|
||||
@ -920,6 +926,56 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
playerConnection.sendPacket(entitySoundEffectPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(net.kyori.adventure.sound.@NonNull Sound sound) {
|
||||
this.playSound(sound, this.position.getX(), this.position.getY(), this.position.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(net.kyori.adventure.sound.@NonNull Sound sound, double x, double y, double z) {
|
||||
Sound minestomSound = AdventureUtils.asSound(sound.name());
|
||||
|
||||
if (minestomSound == null) {
|
||||
NamedSoundEffectPacket packet = new NamedSoundEffectPacket();
|
||||
packet.soundName = sound.name().asString();
|
||||
packet.soundCategory = sound.source().ordinal();
|
||||
packet.x = (int) x;
|
||||
packet.y = (int) y;
|
||||
packet.z = (int) z;
|
||||
packet.volume = sound.volume();
|
||||
packet.pitch = sound.pitch();
|
||||
playerConnection.sendPacket(packet);
|
||||
} else {
|
||||
SoundEffectPacket packet = new SoundEffectPacket();
|
||||
packet.soundId = minestomSound.getId();
|
||||
packet.soundCategory = sound.source().ordinal();
|
||||
packet.x = (int) x;
|
||||
packet.y = (int) y;
|
||||
packet.z = (int) z;
|
||||
packet.volume = sound.volume();
|
||||
packet.pitch = sound.pitch();
|
||||
playerConnection.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopSound(@NonNull SoundStop stop) {
|
||||
StopSoundPacket packet = new StopSoundPacket();
|
||||
packet.flags = 0x0;
|
||||
|
||||
if (stop.source() != null) {
|
||||
packet.flags |= 0x1;
|
||||
packet.source = stop.source().ordinal();
|
||||
}
|
||||
|
||||
if (stop.sound() != null) {
|
||||
packet.flags |= 0x2;
|
||||
packet.sound = stop.sound().asString();
|
||||
}
|
||||
|
||||
this.playerConnection.sendPacket(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays a given effect at the given position for this player.
|
||||
*
|
||||
@ -941,7 +997,9 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
/**
|
||||
* Sends a {@link StopSoundPacket} packet.
|
||||
* @deprecated Use {@link #stopSound(SoundStop)} with {@link SoundStop#all()}
|
||||
*/
|
||||
@Deprecated
|
||||
public void stopSound() {
|
||||
StopSoundPacket stopSoundPacket = new StopSoundPacket();
|
||||
stopSoundPacket.flags = 0x00;
|
||||
@ -1129,7 +1187,28 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
@Override
|
||||
public void openBook(@NonNull Book book) {
|
||||
// TODO write the book
|
||||
// make the book
|
||||
ItemStack writtenBook = new ItemStack(Material.WRITTEN_BOOK, (byte) 1);
|
||||
writtenBook.setItemMeta(WrittenBookMeta.fromAdventure(book));
|
||||
|
||||
// Set book in offhand
|
||||
SetSlotPacket setBookPacket = new SetSlotPacket();
|
||||
setBookPacket.windowId = 0;
|
||||
setBookPacket.slot = 45;
|
||||
setBookPacket.itemStack = writtenBook;
|
||||
playerConnection.sendPacket(setBookPacket);
|
||||
|
||||
// Open the book
|
||||
OpenBookPacket openBookPacket = new OpenBookPacket();
|
||||
openBookPacket.hand = Hand.OFF;
|
||||
playerConnection.sendPacket(openBookPacket);
|
||||
|
||||
// Restore the item in offhand
|
||||
SetSlotPacket restoreItemPacket = new SetSlotPacket();
|
||||
restoreItemPacket.windowId = 0;
|
||||
restoreItemPacket.slot = 45;
|
||||
restoreItemPacket.itemStack = getItemInOffHand();
|
||||
playerConnection.sendPacket(restoreItemPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,8 @@
|
||||
package net.minestom.server.item.metadata;
|
||||
|
||||
import net.kyori.adventure.inventory.Book;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.chat.ChatParser;
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
@ -18,7 +21,7 @@ public class WrittenBookMeta extends ItemMeta {
|
||||
private WrittenBookGeneration generation;
|
||||
private String author;
|
||||
private String title;
|
||||
private List<JsonMessage> pages = new ArrayList<>();
|
||||
private List<String> pages = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Gets if the book is resolved.
|
||||
@ -100,7 +103,7 @@ public class WrittenBookMeta extends ItemMeta {
|
||||
*
|
||||
* @return a modifiable {@link ArrayList} with the pages of the book
|
||||
*/
|
||||
public List<JsonMessage> getPages() {
|
||||
public List<String> getPages() {
|
||||
return pages;
|
||||
}
|
||||
|
||||
@ -109,7 +112,7 @@ public class WrittenBookMeta extends ItemMeta {
|
||||
*
|
||||
* @param pages the array list containing the book pages
|
||||
*/
|
||||
public void setPages(List<JsonMessage> pages) {
|
||||
public void setPages(List<String> pages) {
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
@ -149,9 +152,7 @@ public class WrittenBookMeta extends ItemMeta {
|
||||
if (compound.containsKey("pages")) {
|
||||
final NBTList<NBTString> list = compound.getList("pages");
|
||||
for (NBTString page : list) {
|
||||
final String jsonPage = page.getValue();
|
||||
final ColoredText coloredText = ChatParser.toColoredText(jsonPage);
|
||||
this.pages.add(coloredText);
|
||||
this.pages.add(page.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,8 +173,8 @@ public class WrittenBookMeta extends ItemMeta {
|
||||
}
|
||||
if (!pages.isEmpty()) {
|
||||
NBTList<NBTString> list = new NBTList<>(NBTTypes.TAG_String);
|
||||
for (JsonMessage page : pages) {
|
||||
list.add(new NBTString(page.toString()));
|
||||
for (String page : pages) {
|
||||
list.add(new NBTString(page));
|
||||
}
|
||||
compound.set("pages", list);
|
||||
}
|
||||
@ -196,4 +197,26 @@ public class WrittenBookMeta extends ItemMeta {
|
||||
ORIGINAL, COPY_OF_ORIGINAL, COPY_OF_COPY, TATTERED
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a written book meta from an Adventure book. This meta will not be
|
||||
* resolved and the generation will default to {@link WrittenBookGeneration#ORIGINAL}.
|
||||
*
|
||||
* @param book the book
|
||||
*
|
||||
* @return the meta
|
||||
*/
|
||||
public static @NotNull WrittenBookMeta fromAdventure(@NotNull Book book) {
|
||||
WrittenBookMeta meta = new WrittenBookMeta();
|
||||
meta.resolved = false;
|
||||
meta.generation = WrittenBookGeneration.ORIGINAL;
|
||||
meta.author = MinecraftServer.getSerializationManager().serialize(book.author());
|
||||
meta.title = MinecraftServer.getSerializationManager().serialize(book.title());
|
||||
meta.pages = new ArrayList<>();
|
||||
|
||||
for (Component page : book.pages()) {
|
||||
meta.pages.add(MinecraftServer.getSerializationManager().serialize(page));
|
||||
}
|
||||
|
||||
return meta;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class NamedSoundEffectPacket implements ServerPacket {
|
||||
|
||||
public String soundName;
|
||||
public SoundCategory soundCategory;
|
||||
public int soundCategory;
|
||||
public int x, y, z;
|
||||
public float volume;
|
||||
public float pitch;
|
||||
@ -17,7 +17,7 @@ public class NamedSoundEffectPacket implements ServerPacket {
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeSizedString(soundName);
|
||||
writer.writeVarInt(soundCategory.ordinal());
|
||||
writer.writeVarInt(soundCategory);
|
||||
writer.writeInt(x * 8);
|
||||
writer.writeInt(y * 8);
|
||||
writer.writeInt(z * 8);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.sound.Sound.Source;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.sound.Sound;
|
||||
@ -11,15 +12,19 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class SoundEffectPacket implements ServerPacket {
|
||||
|
||||
public int soundId;
|
||||
public SoundCategory soundCategory;
|
||||
public int soundCategory;
|
||||
public int x, y, z;
|
||||
public float volume;
|
||||
public float pitch;
|
||||
|
||||
/**
|
||||
* @deprecated Use variables
|
||||
*/
|
||||
@Deprecated
|
||||
public static SoundEffectPacket create(SoundCategory category, Sound sound, Position position, float volume, float pitch) {
|
||||
SoundEffectPacket packet = new SoundEffectPacket();
|
||||
packet.soundId = sound.getId();
|
||||
packet.soundCategory = category;
|
||||
packet.soundCategory = category.ordinal();
|
||||
// *8 converts to fixed-point representation with 3 bits for fractional part
|
||||
packet.x = (int) position.getX();
|
||||
packet.y = (int) position.getY();
|
||||
@ -32,7 +37,7 @@ public class SoundEffectPacket implements ServerPacket {
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeVarInt(soundId);
|
||||
writer.writeVarInt(soundCategory.ordinal());
|
||||
writer.writeVarInt(soundCategory);
|
||||
writer.writeInt(x * 8);
|
||||
writer.writeInt(y * 8);
|
||||
writer.writeInt(z * 8);
|
||||
|
@ -1,5 +1,9 @@
|
||||
package net.minestom.server.sound;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link net.kyori.adventure.sound.Sound.Source}
|
||||
*/
|
||||
@Deprecated
|
||||
public enum SoundCategory {
|
||||
MASTER,
|
||||
MUSIC,
|
||||
|
Loading…
Reference in New Issue
Block a user