mirror of https://github.com/LOOHP/Limbo.git
Implemented Bossbar & Sounds Partially
This commit is contained in:
parent
8dd92345d4
commit
9193d907d1
12
pom.xml
12
pom.xml
|
|
@ -24,7 +24,7 @@
|
||||||
<groupId>com.loohp</groupId>
|
<groupId>com.loohp</groupId>
|
||||||
<artifactId>Limbo</artifactId>
|
<artifactId>Limbo</artifactId>
|
||||||
<name>Limbo</name>
|
<name>Limbo</name>
|
||||||
<version>0.6.19-ALPHA</version>
|
<version>0.6.20-ALPHA</version>
|
||||||
|
|
||||||
<description>Standalone Limbo Minecraft Server.</description>
|
<description>Standalone Limbo Minecraft Server.</description>
|
||||||
<url>https://github.com/LOOHP/Limbo</url>
|
<url>https://github.com/LOOHP/Limbo</url>
|
||||||
|
|
@ -256,31 +256,31 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>adventure-text-serializer-gson</artifactId>
|
<artifactId>adventure-text-serializer-gson</artifactId>
|
||||||
<version>4.10.1</version>
|
<version>4.12.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>adventure-text-serializer-legacy</artifactId>
|
<artifactId>adventure-text-serializer-legacy</artifactId>
|
||||||
<version>4.10.1</version>
|
<version>4.12.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>adventure-text-serializer-plain</artifactId>
|
<artifactId>adventure-text-serializer-plain</artifactId>
|
||||||
<version>4.10.1</version>
|
<version>4.12.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>adventure-api</artifactId>
|
<artifactId>adventure-api</artifactId>
|
||||||
<version>4.10.1</version>
|
<version>4.12.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>adventure-nbt</artifactId>
|
<artifactId>adventure-nbt</artifactId>
|
||||||
<version>4.10.1</version>
|
<version>4.12.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
||||||
|
|
@ -19,42 +19,9 @@
|
||||||
|
|
||||||
package com.loohp.limbo;
|
package com.loohp.limbo;
|
||||||
|
|
||||||
import java.awt.GraphicsEnvironment;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.json.simple.JSONArray;
|
|
||||||
import org.json.simple.JSONObject;
|
|
||||||
import org.json.simple.parser.JSONParser;
|
|
||||||
import org.json.simple.parser.ParseException;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.loohp.limbo.bossbar.KeyedBossBar;
|
||||||
import com.loohp.limbo.commands.CommandSender;
|
import com.loohp.limbo.commands.CommandSender;
|
||||||
import com.loohp.limbo.commands.DefaultCommands;
|
import com.loohp.limbo.commands.DefaultCommands;
|
||||||
import com.loohp.limbo.consolegui.GUI;
|
import com.loohp.limbo.consolegui.GUI;
|
||||||
|
|
@ -66,6 +33,7 @@ import com.loohp.limbo.network.ServerConnection;
|
||||||
import com.loohp.limbo.network.protocol.packets.Packet;
|
import com.loohp.limbo.network.protocol.packets.Packet;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketIn;
|
import com.loohp.limbo.network.protocol.packets.PacketIn;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketOut;
|
import com.loohp.limbo.network.protocol.packets.PacketOut;
|
||||||
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutBoss;
|
||||||
import com.loohp.limbo.permissions.PermissionsManager;
|
import com.loohp.limbo.permissions.PermissionsManager;
|
||||||
import com.loohp.limbo.player.Player;
|
import com.loohp.limbo.player.Player;
|
||||||
import com.loohp.limbo.plugins.LimboPlugin;
|
import com.loohp.limbo.plugins.LimboPlugin;
|
||||||
|
|
@ -74,21 +42,56 @@ import com.loohp.limbo.scheduler.LimboScheduler;
|
||||||
import com.loohp.limbo.scheduler.Tick;
|
import com.loohp.limbo.scheduler.Tick;
|
||||||
import com.loohp.limbo.utils.CustomStringUtils;
|
import com.loohp.limbo.utils.CustomStringUtils;
|
||||||
import com.loohp.limbo.utils.ImageUtils;
|
import com.loohp.limbo.utils.ImageUtils;
|
||||||
|
import com.loohp.limbo.utils.NamespacedKey;
|
||||||
import com.loohp.limbo.utils.NetworkUtils;
|
import com.loohp.limbo.utils.NetworkUtils;
|
||||||
import com.loohp.limbo.world.DimensionRegistry;
|
import com.loohp.limbo.world.DimensionRegistry;
|
||||||
import com.loohp.limbo.world.Environment;
|
import com.loohp.limbo.world.Environment;
|
||||||
import com.loohp.limbo.world.Schematic;
|
import com.loohp.limbo.world.Schematic;
|
||||||
import com.loohp.limbo.world.World;
|
import com.loohp.limbo.world.World;
|
||||||
|
import net.kyori.adventure.bossbar.BossBar;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
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 net.querz.nbt.io.NBTUtil;
|
import net.querz.nbt.io.NBTUtil;
|
||||||
import net.querz.nbt.tag.CompoundTag;
|
import net.querz.nbt.tag.CompoundTag;
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
|
||||||
import javax.swing.UnsupportedLookAndFeelException;
|
import javax.swing.UnsupportedLookAndFeelException;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class Limbo {
|
public final class Limbo {
|
||||||
|
|
||||||
public static final String LIMBO_BRAND = "Limbo";
|
public static final String LIMBO_BRAND = "Limbo";
|
||||||
|
|
||||||
|
|
@ -135,39 +138,41 @@ public class Limbo {
|
||||||
public final int SERVER_IMPLEMENTATION_PROTOCOL = 761;
|
public final int SERVER_IMPLEMENTATION_PROTOCOL = 761;
|
||||||
public final String LIMBO_IMPLEMENTATION_VERSION;
|
public final String LIMBO_IMPLEMENTATION_VERSION;
|
||||||
|
|
||||||
private AtomicBoolean isRunning;
|
private final AtomicBoolean isRunning;
|
||||||
|
|
||||||
private ServerConnection server;
|
private final ServerConnection server;
|
||||||
private Console console;
|
private final Console console;
|
||||||
|
|
||||||
private List<World> worlds = new ArrayList<>();
|
private final List<World> worlds = new CopyOnWriteArrayList<>();
|
||||||
private Map<String, Player> playersByName = new HashMap<>();
|
final Map<String, Player> playersByName = new ConcurrentHashMap<>();
|
||||||
private Map<UUID, Player> playersByUUID = new HashMap<>();
|
final Map<UUID, Player> playersByUUID = new ConcurrentHashMap<>();
|
||||||
|
private final Map<NamespacedKey, KeyedBossBar> bossBars = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private ServerProperties properties;
|
private final ServerProperties properties;
|
||||||
|
|
||||||
private PluginManager pluginManager;
|
private final PluginManager pluginManager;
|
||||||
private EventsManager eventsManager;
|
private final EventsManager eventsManager;
|
||||||
private PermissionsManager permissionManager;
|
private final PermissionsManager permissionManager;
|
||||||
private File pluginFolder;
|
private final File pluginFolder;
|
||||||
|
|
||||||
private File internalDataFolder;
|
private final File internalDataFolder;
|
||||||
|
|
||||||
private DimensionRegistry dimensionRegistry;
|
private final DimensionRegistry dimensionRegistry;
|
||||||
|
|
||||||
private Tick tick;
|
private final Tick tick;
|
||||||
private LimboScheduler scheduler;
|
private final LimboScheduler scheduler;
|
||||||
|
|
||||||
private Metrics metrics;
|
private final Metrics metrics;
|
||||||
|
|
||||||
public AtomicInteger entityIdCount = new AtomicInteger();
|
public final AtomicInteger entityIdCount = new AtomicInteger();
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private Unsafe unsafe = new Unsafe();
|
private Unsafe unsafe;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Limbo() throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException {
|
public Limbo() throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException {
|
||||||
instance = this;
|
instance = this;
|
||||||
|
unsafe = new Unsafe(this);
|
||||||
isRunning = new AtomicBoolean(true);
|
isRunning = new AtomicBoolean(true);
|
||||||
|
|
||||||
if (!noGui) {
|
if (!noGui) {
|
||||||
|
|
@ -429,6 +434,30 @@ public class Limbo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KeyedBossBar createBossBar(NamespacedKey namespacedKey, Component name, float progress, BossBar.Color color, BossBar.Overlay overlay, BossBar.Flag... flags) {
|
||||||
|
KeyedBossBar keyedBossBar = new KeyedBossBar(namespacedKey, BossBar.bossBar(name, progress, color, overlay, new HashSet<>(Arrays.asList(flags))));
|
||||||
|
bossBars.put(namespacedKey, keyedBossBar);
|
||||||
|
return keyedBossBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeBossBar(NamespacedKey namespacedKey) {
|
||||||
|
KeyedBossBar keyedBossBar = bossBars.remove(namespacedKey);
|
||||||
|
keyedBossBar.getProperties().removeListener(keyedBossBar.getUnsafe().getLimboListener());
|
||||||
|
keyedBossBar.getUnsafe().invalidate();
|
||||||
|
PacketPlayOutBoss packetPlayOutBoss = new PacketPlayOutBoss(keyedBossBar, PacketPlayOutBoss.BossBarAction.REMOVE);
|
||||||
|
for (Player player : keyedBossBar.getPlayers()) {
|
||||||
|
try {
|
||||||
|
player.clientConnection.sendPacket(packetPlayOutBoss);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<NamespacedKey, KeyedBossBar> getBossBars() {
|
||||||
|
return Collections.unmodifiableMap(bossBars);
|
||||||
|
}
|
||||||
|
|
||||||
public ServerProperties getServerProperties() {
|
public ServerProperties getServerProperties() {
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
@ -457,16 +486,6 @@ public class Limbo {
|
||||||
return playersByUUID.get(uuid);
|
return playersByUUID.get(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPlayer(Player player) {
|
|
||||||
playersByName.put(player.getName(), player);
|
|
||||||
playersByUUID.put(player.getUniqueId(), player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removePlayer(Player player) {
|
|
||||||
playersByName.remove(player.getName());
|
|
||||||
playersByUUID.remove(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<World> getWorlds() {
|
public List<World> getWorlds() {
|
||||||
return new ArrayList<>(worlds);
|
return new ArrayList<>(worlds);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,16 @@ import com.loohp.limbo.player.Player;
|
||||||
import com.loohp.limbo.utils.GameMode;
|
import com.loohp.limbo.utils.GameMode;
|
||||||
import com.loohp.limbo.world.World;
|
import com.loohp.limbo.world.World;
|
||||||
|
|
||||||
|
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public class Unsafe {
|
public class Unsafe {
|
||||||
|
|
||||||
|
private final Limbo instance;
|
||||||
private com.loohp.limbo.player.Unsafe playerUnsafe;
|
private com.loohp.limbo.player.Unsafe playerUnsafe;
|
||||||
private com.loohp.limbo.world.Unsafe worldUnsafe;
|
private com.loohp.limbo.world.Unsafe worldUnsafe;
|
||||||
|
|
||||||
protected Unsafe() {
|
protected Unsafe(Limbo instance) {
|
||||||
|
this.instance = instance;
|
||||||
try {
|
try {
|
||||||
Constructor<com.loohp.limbo.player.Unsafe> playerConstructor = com.loohp.limbo.player.Unsafe.class.getDeclaredConstructor();
|
Constructor<com.loohp.limbo.player.Unsafe> playerConstructor = com.loohp.limbo.player.Unsafe.class.getDeclaredConstructor();
|
||||||
playerConstructor.setAccessible(true);
|
playerConstructor.setAccessible(true);
|
||||||
|
|
@ -78,4 +81,17 @@ public class Unsafe {
|
||||||
playerUnsafe.a(player, location);
|
playerUnsafe.a(player, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void addPlayer(Player player) {
|
||||||
|
instance.playersByName.put(player.getName(), player);
|
||||||
|
instance.playersByUUID.put(player.getUniqueId(), player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void removePlayer(Player player) {
|
||||||
|
instance.getBossBars().values().forEach(each -> each.hidePlayer(player));
|
||||||
|
instance.playersByName.remove(player.getName());
|
||||||
|
instance.playersByUUID.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Limbo.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
|
||||||
|
* Copyright (C) 2022. Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.loohp.limbo.bossbar;
|
||||||
|
|
||||||
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutBoss;
|
||||||
|
import com.loohp.limbo.player.Player;
|
||||||
|
import com.loohp.limbo.utils.NamespacedKey;
|
||||||
|
import net.kyori.adventure.bossbar.BossBar;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public class KeyedBossBar {
|
||||||
|
|
||||||
|
private final UUID uuid;
|
||||||
|
private final NamespacedKey key;
|
||||||
|
private final BossBar properties;
|
||||||
|
private final Set<Player> players;
|
||||||
|
protected final LimboBossBarHandler listener;
|
||||||
|
protected final AtomicBoolean valid;
|
||||||
|
private final Unsafe unsafe;
|
||||||
|
|
||||||
|
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||||
|
@Deprecated
|
||||||
|
public KeyedBossBar(NamespacedKey key, BossBar properties) {
|
||||||
|
this.uuid = UUID.randomUUID();
|
||||||
|
this.key = key;
|
||||||
|
this.properties = properties;
|
||||||
|
this.players = ConcurrentHashMap.newKeySet();
|
||||||
|
this.listener = new LimboBossBarHandler(this);
|
||||||
|
this.properties.addListener(listener);
|
||||||
|
this.valid = new AtomicBoolean(true);
|
||||||
|
this.unsafe = new Unsafe(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUniqueId() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BossBar getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Player> getPlayers() {
|
||||||
|
return Collections.unmodifiableSet(players);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return valid.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public Unsafe getUnsafe() {
|
||||||
|
return unsafe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean showPlayer(Player player) {
|
||||||
|
PacketPlayOutBoss packetPlayOutBoss = new PacketPlayOutBoss(this, PacketPlayOutBoss.BossBarAction.ADD);
|
||||||
|
try {
|
||||||
|
player.clientConnection.sendPacket(packetPlayOutBoss);
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
}
|
||||||
|
return players.add(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hidePlayer(Player player) {
|
||||||
|
PacketPlayOutBoss packetPlayOutBoss = new PacketPlayOutBoss(this, PacketPlayOutBoss.BossBarAction.REMOVE);
|
||||||
|
try {
|
||||||
|
player.clientConnection.sendPacket(packetPlayOutBoss);
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
}
|
||||||
|
return players.remove(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LimboBossBarHandler implements BossBar.Listener {
|
||||||
|
|
||||||
|
private final KeyedBossBar parent;
|
||||||
|
|
||||||
|
private LimboBossBarHandler(KeyedBossBar parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bossBarNameChanged(@NotNull BossBar bar, @NotNull Component oldName, @NotNull Component newName) {
|
||||||
|
PacketPlayOutBoss packetPlayOutBoss = new PacketPlayOutBoss(parent, PacketPlayOutBoss.BossBarAction.UPDATE_NAME);
|
||||||
|
for (Player player : parent.getPlayers()) {
|
||||||
|
try {
|
||||||
|
player.clientConnection.sendPacket(packetPlayOutBoss);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bossBarProgressChanged(@NotNull BossBar bar, float oldProgress, float newProgress) {
|
||||||
|
PacketPlayOutBoss packetPlayOutBoss = new PacketPlayOutBoss(parent, PacketPlayOutBoss.BossBarAction.UPDATE_PROGRESS);
|
||||||
|
for (Player player : parent.getPlayers()) {
|
||||||
|
try {
|
||||||
|
player.clientConnection.sendPacket(packetPlayOutBoss);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bossBarColorChanged(@NotNull BossBar bar, BossBar.@NotNull Color oldColor, BossBar.@NotNull Color newColor) {
|
||||||
|
PacketPlayOutBoss packetPlayOutBoss = new PacketPlayOutBoss(parent, PacketPlayOutBoss.BossBarAction.UPDATE_STYLE);
|
||||||
|
for (Player player : parent.getPlayers()) {
|
||||||
|
try {
|
||||||
|
player.clientConnection.sendPacket(packetPlayOutBoss);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bossBarOverlayChanged(@NotNull BossBar bar, BossBar.@NotNull Overlay oldOverlay, BossBar.@NotNull Overlay newOverlay) {
|
||||||
|
PacketPlayOutBoss packetPlayOutBoss = new PacketPlayOutBoss(parent, PacketPlayOutBoss.BossBarAction.UPDATE_STYLE);
|
||||||
|
for (Player player : parent.getPlayers()) {
|
||||||
|
try {
|
||||||
|
player.clientConnection.sendPacket(packetPlayOutBoss);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bossBarFlagsChanged(@NotNull BossBar bar, @NotNull Set<BossBar.Flag> flagsAdded, @NotNull Set<BossBar.Flag> flagsRemoved) {
|
||||||
|
PacketPlayOutBoss packetPlayOutBoss = new PacketPlayOutBoss(parent, PacketPlayOutBoss.BossBarAction.UPDATE_PROPERTIES);
|
||||||
|
for (Player player : parent.getPlayers()) {
|
||||||
|
try {
|
||||||
|
player.clientConnection.sendPacket(packetPlayOutBoss);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Limbo.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
|
||||||
|
* Copyright (C) 2022. Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.loohp.limbo.bossbar;
|
||||||
|
|
||||||
|
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||||
|
@Deprecated
|
||||||
|
public class Unsafe {
|
||||||
|
|
||||||
|
private final KeyedBossBar instance;
|
||||||
|
|
||||||
|
protected Unsafe(KeyedBossBar instance) {
|
||||||
|
this.instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public KeyedBossBar.LimboBossBarHandler getLimboListener() {
|
||||||
|
return instance.listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void invalidate() {
|
||||||
|
instance.valid.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -34,46 +34,46 @@ import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
|
||||||
public interface CommandSender extends Audience {
|
public interface CommandSender extends Audience {
|
||||||
|
|
||||||
public void sendMessage(BaseComponent[] component, UUID uuid);
|
void sendMessage(BaseComponent[] component, UUID uuid);
|
||||||
|
|
||||||
public void sendMessage(BaseComponent component, UUID uuid);
|
void sendMessage(BaseComponent component, UUID uuid);
|
||||||
|
|
||||||
public void sendMessage(String message, UUID uuid);
|
void sendMessage(String message, UUID uuid);
|
||||||
|
|
||||||
public void sendMessage(BaseComponent[] component);
|
void sendMessage(BaseComponent[] component);
|
||||||
|
|
||||||
public void sendMessage(BaseComponent component);
|
void sendMessage(BaseComponent component);
|
||||||
|
|
||||||
public void sendMessage(String message);
|
void sendMessage(String message);
|
||||||
|
|
||||||
public boolean hasPermission(String permission);
|
boolean hasPermission(String permission);
|
||||||
|
|
||||||
public String getName();
|
String getName();
|
||||||
|
|
||||||
public void sendMessage(Identity source, Component message, MessageType type);
|
void sendMessage(Identity source, Component message, MessageType type);
|
||||||
|
|
||||||
public void openBook(Book book);
|
void openBook(Book book);
|
||||||
|
|
||||||
public void stopSound(SoundStop stop);
|
void stopSound(SoundStop stop);
|
||||||
|
|
||||||
public void playSound(Sound sound, Sound.Emitter emitter);
|
void playSound(Sound sound, Sound.Emitter emitter);
|
||||||
|
|
||||||
public void playSound(Sound sound, double x, double y, double z);
|
void playSound(Sound sound, double x, double y, double z);
|
||||||
|
|
||||||
public void playSound(Sound sound);
|
void playSound(Sound sound);
|
||||||
|
|
||||||
public void sendActionBar(Component message);
|
void sendActionBar(Component message);
|
||||||
|
|
||||||
public void sendPlayerListHeaderAndFooter(Component header, Component footer);
|
void sendPlayerListHeaderAndFooter(Component header, Component footer);
|
||||||
|
|
||||||
public <T> void sendTitlePart(TitlePart<T> part, T value);
|
<T> void sendTitlePart(TitlePart<T> part, T value);
|
||||||
|
|
||||||
public void clearTitle();
|
void clearTitle();
|
||||||
|
|
||||||
public void resetTitle();
|
void resetTitle();
|
||||||
|
|
||||||
public void showBossBar(BossBar bar);
|
void showBossBar(BossBar bar);
|
||||||
|
|
||||||
public void hideBossBar(BossBar bar);
|
void hideBossBar(BossBar bar);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,12 @@ import com.loohp.limbo.location.Location;
|
||||||
import com.loohp.limbo.utils.BungeecordAdventureConversionUtils;
|
import com.loohp.limbo.utils.BungeecordAdventureConversionUtils;
|
||||||
import com.loohp.limbo.world.World;
|
import com.loohp.limbo.world.World;
|
||||||
|
|
||||||
|
import net.kyori.adventure.sound.Sound;
|
||||||
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.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
|
||||||
public abstract class Entity {
|
public abstract class Entity implements Sound.Emitter {
|
||||||
|
|
||||||
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01)
|
@WatchableField(MetadataIndex = 0, WatchableObjectType = WatchableObjectType.BYTE, IsBitmask = true, Bitmask = 0x01)
|
||||||
protected boolean onFire = false;
|
protected boolean onFire = false;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ public class Channel implements AutoCloseable {
|
||||||
|
|
||||||
private void ensureOpen() {
|
private void ensureOpen() {
|
||||||
if (!valid.get()) {
|
if (!valid.get()) {
|
||||||
throw new IllegalStateException("Channel already closed!");
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,10 +106,13 @@ public class Channel implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void close() throws Exception {
|
public synchronized void close() {
|
||||||
if (valid.compareAndSet(true, false)) {
|
if (valid.compareAndSet(true, false)) {
|
||||||
|
try {
|
||||||
input.close();
|
input.close();
|
||||||
output.close();
|
output.close();
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -491,7 +491,7 @@ public class ClientConnection extends Thread {
|
||||||
|
|
||||||
player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
|
player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
|
||||||
player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
|
player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
|
||||||
Limbo.getInstance().addPlayer(player);
|
Limbo.getInstance().getUnsafe().addPlayer(player);
|
||||||
break;
|
break;
|
||||||
} else if (packetIn instanceof PacketLoginInPluginMessaging) {
|
} else if (packetIn instanceof PacketLoginInPluginMessaging) {
|
||||||
PacketLoginInPluginMessaging response = (PacketLoginInPluginMessaging) packetIn;
|
PacketLoginInPluginMessaging response = (PacketLoginInPluginMessaging) packetIn;
|
||||||
|
|
@ -519,7 +519,7 @@ public class ClientConnection extends Thread {
|
||||||
|
|
||||||
player = new Player(this, data.getUsername(), data.getUuid(), Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
|
player = new Player(this, data.getUsername(), data.getUuid(), Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
|
||||||
player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
|
player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
|
||||||
Limbo.getInstance().addPlayer(player);
|
Limbo.getInstance().getUnsafe().addPlayer(player);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -757,7 +757,7 @@ public class ClientConnection extends Thread {
|
||||||
state = ClientState.DISCONNECTED;
|
state = ClientState.DISCONNECTED;
|
||||||
|
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
Limbo.getInstance().removePlayer(player);
|
Limbo.getInstance().getUnsafe().removePlayer(player);
|
||||||
}
|
}
|
||||||
Limbo.getInstance().getServerConnection().getClients().remove(this);
|
Limbo.getInstance().getServerConnection().getClients().remove(this);
|
||||||
running = false;
|
running = false;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Limbo.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
|
||||||
|
* Copyright (C) 2022. Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.loohp.limbo.network.protocol.packets;
|
||||||
|
|
||||||
|
import com.loohp.limbo.utils.DataTypeIO;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class ClientboundSetActionBarTextPacket extends PacketOut {
|
||||||
|
|
||||||
|
private Component actionBar;
|
||||||
|
|
||||||
|
public ClientboundSetActionBarTextPacket(Component actionBar) {
|
||||||
|
this.actionBar = actionBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Component getActionBar() {
|
||||||
|
return actionBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] serializePacket() throws IOException {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
DataOutputStream output = new DataOutputStream(buffer);
|
||||||
|
output.writeByte(Packet.getPlayOut().get(getClass()));
|
||||||
|
DataTypeIO.writeString(output, GsonComponentSerializer.gson().serialize(actionBar), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
return buffer.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Limbo.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
|
||||||
|
* Copyright (C) 2022. Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.loohp.limbo.network.protocol.packets;
|
||||||
|
|
||||||
|
import com.loohp.limbo.bossbar.KeyedBossBar;
|
||||||
|
import com.loohp.limbo.utils.DataTypeIO;
|
||||||
|
import net.kyori.adventure.bossbar.BossBar;
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class PacketPlayOutBoss extends PacketOut {
|
||||||
|
|
||||||
|
public enum BossBarAction {
|
||||||
|
ADD,
|
||||||
|
REMOVE,
|
||||||
|
UPDATE_PROGRESS,
|
||||||
|
UPDATE_NAME,
|
||||||
|
UPDATE_STYLE,
|
||||||
|
UPDATE_PROPERTIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int encodeProperties(boolean darkenScreen, boolean playMusic, boolean createWorldFog) {
|
||||||
|
int i = 0;
|
||||||
|
if (darkenScreen) {
|
||||||
|
i |= 1;
|
||||||
|
}
|
||||||
|
if (playMusic) {
|
||||||
|
i |= 2;
|
||||||
|
}
|
||||||
|
if (createWorldFog) {
|
||||||
|
i |= 4;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyedBossBar bossBar;
|
||||||
|
private BossBarAction action;
|
||||||
|
|
||||||
|
public PacketPlayOutBoss(KeyedBossBar bossBar, BossBarAction action) {
|
||||||
|
this.bossBar = bossBar;
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyedBossBar getBossBar() {
|
||||||
|
return bossBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BossBarAction getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] serializePacket() throws IOException {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
DataOutputStream output = new DataOutputStream(buffer);
|
||||||
|
output.writeByte(Packet.getPlayOut().get(getClass()));
|
||||||
|
|
||||||
|
DataTypeIO.writeUUID(output, bossBar.getUniqueId());
|
||||||
|
DataTypeIO.writeVarInt(output, action.ordinal());
|
||||||
|
|
||||||
|
BossBar properties = bossBar.getProperties();
|
||||||
|
switch (action) {
|
||||||
|
case ADD: {
|
||||||
|
DataTypeIO.writeString(output, GsonComponentSerializer.gson().serialize(properties.name()), StandardCharsets.UTF_8);
|
||||||
|
output.writeFloat(properties.progress());
|
||||||
|
DataTypeIO.writeVarInt(output, properties.color().ordinal());
|
||||||
|
DataTypeIO.writeVarInt(output, properties.overlay().ordinal());
|
||||||
|
output.writeByte(encodeProperties(properties.hasFlag(BossBar.Flag.DARKEN_SCREEN), properties.hasFlag(BossBar.Flag.PLAY_BOSS_MUSIC), properties.hasFlag(BossBar.Flag.CREATE_WORLD_FOG)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case REMOVE: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case UPDATE_PROGRESS: {
|
||||||
|
output.writeFloat(properties.progress());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case UPDATE_NAME: {
|
||||||
|
DataTypeIO.writeString(output, GsonComponentSerializer.gson().serialize(properties.name()), StandardCharsets.UTF_8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case UPDATE_STYLE: {
|
||||||
|
DataTypeIO.writeVarInt(output, properties.color().ordinal());
|
||||||
|
DataTypeIO.writeVarInt(output, properties.overlay().ordinal());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case UPDATE_PROPERTIES: {
|
||||||
|
output.writeByte(encodeProperties(properties.hasFlag(BossBar.Flag.DARKEN_SCREEN), properties.hasFlag(BossBar.Flag.PLAY_BOSS_MUSIC), properties.hasFlag(BossBar.Flag.CREATE_WORLD_FOG)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Limbo.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
|
||||||
|
* Copyright (C) 2022. Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.loohp.limbo.network.protocol.packets;
|
||||||
|
|
||||||
|
import com.loohp.limbo.sounds.SoundEffect;
|
||||||
|
import com.loohp.limbo.utils.DataTypeIO;
|
||||||
|
import net.kyori.adventure.sound.Sound;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class PacketPlayOutNamedSoundEffect extends PacketOut {
|
||||||
|
|
||||||
|
private SoundEffect sound;
|
||||||
|
private Sound.Source source;
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
private int z;
|
||||||
|
private float volume;
|
||||||
|
private float pitch;
|
||||||
|
private long seed;
|
||||||
|
|
||||||
|
public PacketPlayOutNamedSoundEffect(SoundEffect sound, Sound.Source source, double x, double y, double z, float volume, float pitch, long seed) {
|
||||||
|
this.sound = sound;
|
||||||
|
this.source = source;
|
||||||
|
this.x = (int) (x * 8.0);
|
||||||
|
this.y = (int) (y * 8.0);
|
||||||
|
this.z = (int) (z * 8.0);
|
||||||
|
this.volume = volume;
|
||||||
|
this.pitch = pitch;
|
||||||
|
this.seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundEffect getSound() {
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Sound.Source getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getX() {
|
||||||
|
return (float) this.x / 8.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getY() {
|
||||||
|
return (float) this.y / 8.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getZ() {
|
||||||
|
return (float) this.z / 8.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getVolume() {
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPitch() {
|
||||||
|
return pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSeed() {
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] serializePacket() throws IOException {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
DataOutputStream output = new DataOutputStream(buffer);
|
||||||
|
output.writeByte(Packet.getPlayOut().get(getClass()));
|
||||||
|
|
||||||
|
DataTypeIO.writeVarInt(output, 0);
|
||||||
|
DataTypeIO.writeString(output, sound.getSound().toString(), StandardCharsets.UTF_8);
|
||||||
|
Optional<Float> fixedRange = sound.fixedRange();
|
||||||
|
if (fixedRange.isPresent()) {
|
||||||
|
output.writeBoolean(true);
|
||||||
|
output.writeFloat(fixedRange.get());
|
||||||
|
} else {
|
||||||
|
output.writeBoolean(false);
|
||||||
|
}
|
||||||
|
DataTypeIO.writeVarInt(output, source.ordinal());
|
||||||
|
output.writeInt(x);
|
||||||
|
output.writeInt(y);
|
||||||
|
output.writeInt(z);
|
||||||
|
output.writeFloat(volume);
|
||||||
|
output.writeFloat(pitch);
|
||||||
|
output.writeLong(seed);
|
||||||
|
|
||||||
|
return buffer.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Limbo.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
|
||||||
|
* Copyright (C) 2022. Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.loohp.limbo.network.protocol.packets;
|
||||||
|
|
||||||
|
import com.loohp.limbo.utils.DataTypeIO;
|
||||||
|
import com.loohp.limbo.utils.NamespacedKey;
|
||||||
|
import net.kyori.adventure.sound.Sound;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class PacketPlayOutStopSound extends PacketOut {
|
||||||
|
|
||||||
|
private NamespacedKey sound;
|
||||||
|
private Sound.Source source;
|
||||||
|
|
||||||
|
public PacketPlayOutStopSound(NamespacedKey sound, Sound.Source source) {
|
||||||
|
this.sound = sound;
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamespacedKey getSound() {
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Sound.Source getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] serializePacket() throws IOException {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
DataOutputStream output = new DataOutputStream(buffer);
|
||||||
|
output.writeByte(Packet.getPlayOut().get(getClass()));
|
||||||
|
|
||||||
|
if (source != null) {
|
||||||
|
if (sound != null) {
|
||||||
|
output.writeByte(3);
|
||||||
|
DataTypeIO.writeVarInt(output, source.ordinal());
|
||||||
|
DataTypeIO.writeString(output, sound.toString(), StandardCharsets.UTF_8);
|
||||||
|
} else {
|
||||||
|
output.writeByte(1);
|
||||||
|
DataTypeIO.writeVarInt(output, source.ordinal());
|
||||||
|
}
|
||||||
|
} else if (sound != null) {
|
||||||
|
output.writeByte(2);
|
||||||
|
DataTypeIO.writeString(output, sound.toString(), StandardCharsets.UTF_8);
|
||||||
|
} else {
|
||||||
|
output.writeByte(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,6 +31,7 @@ import com.loohp.limbo.events.player.PlayerTeleportEvent;
|
||||||
import com.loohp.limbo.location.Location;
|
import com.loohp.limbo.location.Location;
|
||||||
import com.loohp.limbo.network.ClientConnection;
|
import com.loohp.limbo.network.ClientConnection;
|
||||||
import com.loohp.limbo.network.protocol.packets.ClientboundClearTitlesPacket;
|
import com.loohp.limbo.network.protocol.packets.ClientboundClearTitlesPacket;
|
||||||
|
import com.loohp.limbo.network.protocol.packets.ClientboundSetActionBarTextPacket;
|
||||||
import com.loohp.limbo.network.protocol.packets.ClientboundSetSubtitleTextPacket;
|
import com.loohp.limbo.network.protocol.packets.ClientboundSetSubtitleTextPacket;
|
||||||
import com.loohp.limbo.network.protocol.packets.ClientboundSetTitleTextPacket;
|
import com.loohp.limbo.network.protocol.packets.ClientboundSetTitleTextPacket;
|
||||||
import com.loohp.limbo.network.protocol.packets.ClientboundSetTitlesAnimationPacket;
|
import com.loohp.limbo.network.protocol.packets.ClientboundSetTitlesAnimationPacket;
|
||||||
|
|
@ -38,10 +39,13 @@ import com.loohp.limbo.network.protocol.packets.ClientboundSystemChatPacket;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketOut;
|
import com.loohp.limbo.network.protocol.packets.PacketOut;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketPlayOutGameState;
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutGameState;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketPlayOutHeldItemChange;
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutHeldItemChange;
|
||||||
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutNamedSoundEffect;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerListHeaderFooter;
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutPlayerListHeaderFooter;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketPlayOutPositionAndLook;
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutPositionAndLook;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketPlayOutResourcePackSend;
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutResourcePackSend;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketPlayOutRespawn;
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutRespawn;
|
||||||
|
import com.loohp.limbo.network.protocol.packets.PacketPlayOutStopSound;
|
||||||
|
import com.loohp.limbo.sounds.SoundEffect;
|
||||||
import com.loohp.limbo.utils.BungeecordAdventureConversionUtils;
|
import com.loohp.limbo.utils.BungeecordAdventureConversionUtils;
|
||||||
import com.loohp.limbo.utils.GameMode;
|
import com.loohp.limbo.utils.GameMode;
|
||||||
import com.loohp.limbo.utils.MessageSignature;
|
import com.loohp.limbo.utils.MessageSignature;
|
||||||
|
|
@ -50,6 +54,7 @@ import net.kyori.adventure.audience.MessageType;
|
||||||
import net.kyori.adventure.bossbar.BossBar;
|
import net.kyori.adventure.bossbar.BossBar;
|
||||||
import net.kyori.adventure.identity.Identity;
|
import net.kyori.adventure.identity.Identity;
|
||||||
import net.kyori.adventure.inventory.Book;
|
import net.kyori.adventure.inventory.Book;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
import net.kyori.adventure.sound.Sound;
|
import net.kyori.adventure.sound.Sound;
|
||||||
import net.kyori.adventure.sound.Sound.Emitter;
|
import net.kyori.adventure.sound.Sound.Emitter;
|
||||||
import net.kyori.adventure.sound.SoundStop;
|
import net.kyori.adventure.sound.SoundStop;
|
||||||
|
|
@ -65,6 +70,7 @@ import java.io.IOException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public class Player extends LivingEntity implements CommandSender {
|
public class Player extends LivingEntity implements CommandSender {
|
||||||
|
|
||||||
|
|
@ -448,7 +454,13 @@ public class Player extends LivingEntity implements CommandSender {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopSound(SoundStop stop) {
|
public void stopSound(SoundStop stop) {
|
||||||
throw new UnsupportedOperationException("This function has not been implemented yet.");
|
Key sound = stop.sound();
|
||||||
|
PacketPlayOutStopSound stopSound = new PacketPlayOutStopSound(sound == null ? null : NamespacedKey.fromKey(sound), stop.source());
|
||||||
|
try {
|
||||||
|
clientConnection.sendPacket(stopSound);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -458,27 +470,37 @@ public class Player extends LivingEntity implements CommandSender {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playSound(Sound sound, double x, double y, double z) {
|
public void playSound(Sound sound, double x, double y, double z) {
|
||||||
throw new UnsupportedOperationException("This function has not been implemented yet.");
|
PacketPlayOutNamedSoundEffect namedSoundEffect = new PacketPlayOutNamedSoundEffect(
|
||||||
|
SoundEffect.createVariableRangeEvent(NamespacedKey.fromKey(sound.name())),
|
||||||
|
sound.source(), x, y, z, sound.volume(), sound.pitch(), sound.seed().orElse(ThreadLocalRandom.current().nextLong())
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
clientConnection.sendPacket(namedSoundEffect);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playSound(Sound sound) {
|
public void playSound(Sound sound) {
|
||||||
throw new UnsupportedOperationException("This function has not been implemented yet.");
|
playSound(sound, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendActionBar(Component message) {
|
public void sendActionBar(Component message) {
|
||||||
try {
|
try {
|
||||||
ClientboundSystemChatPacket chat = new ClientboundSystemChatPacket(message, true);
|
ClientboundSetActionBarTextPacket setActionBar = new ClientboundSetActionBarTextPacket(message);
|
||||||
clientConnection.sendPacket(chat);
|
clientConnection.sendPacket(setActionBar);
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendPlayerListHeaderAndFooter(Component header, Component footer) {
|
public void sendPlayerListHeaderAndFooter(Component header, Component footer) {
|
||||||
try {
|
try {
|
||||||
PacketPlayOutPlayerListHeaderFooter packsend = new PacketPlayOutPlayerListHeaderFooter(header, footer);
|
PacketPlayOutPlayerListHeaderFooter listHeaderFooter = new PacketPlayOutPlayerListHeaderFooter(header, footer);
|
||||||
clientConnection.sendPacket(packsend);
|
clientConnection.sendPacket(listHeaderFooter);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,15 +40,11 @@ public class Tick {
|
||||||
private Queue<LimboSchedulerTask> asyncTasksQueue = new ConcurrentLinkedQueue<>();
|
private Queue<LimboSchedulerTask> asyncTasksQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
public Tick(Limbo instance) {
|
public Tick(Limbo instance) {
|
||||||
new Thread(new Runnable() {
|
new Thread(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
tickingInterval = (int) Math.round(1000.0 / Limbo.getInstance().getServerProperties().getDefinedTicksPerSecond());
|
tickingInterval = (int) Math.round(1000.0 / Limbo.getInstance().getServerProperties().getDefinedTicksPerSecond());
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
Thread thread = new Thread(new Runnable() {
|
Thread thread = new Thread(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (instance.isRunning()) {
|
while (instance.isRunning()) {
|
||||||
LimboSchedulerTask task = asyncTasksQueue.poll();
|
LimboSchedulerTask task = asyncTasksQueue.poll();
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
|
|
@ -67,7 +63,6 @@ public class Tick {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
thread.start();
|
thread.start();
|
||||||
threads.add(thread);
|
threads.add(thread);
|
||||||
|
|
@ -122,7 +117,6 @@ public class Tick {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Limbo.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
|
||||||
|
* Copyright (C) 2022. Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.loohp.limbo.sounds;
|
||||||
|
|
||||||
|
import com.loohp.limbo.utils.NamespacedKey;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class SoundEffect {
|
||||||
|
|
||||||
|
public static SoundEffect createVariableRangeEvent(NamespacedKey namespacedKey) {
|
||||||
|
return new SoundEffect(namespacedKey, 16.0F, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SoundEffect createFixedRangeEvent(NamespacedKey namespacedKey, float range) {
|
||||||
|
return new SoundEffect(namespacedKey, range, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final NamespacedKey sound;
|
||||||
|
private final float range;
|
||||||
|
private final boolean newSystem;
|
||||||
|
|
||||||
|
private SoundEffect(NamespacedKey sound, float range, boolean newSystem) {
|
||||||
|
this.sound = sound;
|
||||||
|
this.range = range;
|
||||||
|
this.newSystem = newSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamespacedKey getSound() {
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRange() {
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNewSystem() {
|
||||||
|
return newSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Float> fixedRange() {
|
||||||
|
return this.newSystem ? Optional.of(this.range) : Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,12 +19,25 @@
|
||||||
|
|
||||||
package com.loohp.limbo.utils;
|
package com.loohp.limbo.utils;
|
||||||
|
|
||||||
|
import com.loohp.limbo.plugins.LimboPlugin;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class NamespacedKey {
|
public class NamespacedKey {
|
||||||
|
|
||||||
public static final String MINECRAFT_KEY = "minecraft";
|
public static final String MINECRAFT_KEY = "minecraft";
|
||||||
|
|
||||||
private String namespace;
|
public static NamespacedKey minecraft(String key) {
|
||||||
private String key;
|
return new NamespacedKey(MINECRAFT_KEY, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NamespacedKey fromKey(Key key) {
|
||||||
|
return new NamespacedKey(key.namespace(), key.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String namespace;
|
||||||
|
private final String key;
|
||||||
|
|
||||||
public NamespacedKey(String namespacedKey) {
|
public NamespacedKey(String namespacedKey) {
|
||||||
int index = namespacedKey.indexOf(":");
|
int index = namespacedKey.indexOf(":");
|
||||||
|
|
@ -37,15 +50,15 @@ public class NamespacedKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NamespacedKey(LimboPlugin plugin, String key) {
|
||||||
|
this(plugin.getName().toLowerCase().replace(" ", "_"), key);
|
||||||
|
}
|
||||||
|
|
||||||
public NamespacedKey(String namespace, String key) {
|
public NamespacedKey(String namespace, String key) {
|
||||||
this.namespace = namespace;
|
this.namespace = namespace;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NamespacedKey minecraft(String key) {
|
|
||||||
return new NamespacedKey(MINECRAFT_KEY, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNamespace() {
|
public String getNamespace() {
|
||||||
return namespace;
|
return namespace;
|
||||||
}
|
}
|
||||||
|
|
@ -54,40 +67,25 @@ public class NamespacedKey {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Key toKey() {
|
||||||
|
return Key.key(namespace, key);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return namespace + ":" + key;
|
return namespace + ":" + key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public boolean equals(Object o) {
|
||||||
final int prime = 31;
|
if (this == o) return true;
|
||||||
int result = 1;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
NamespacedKey that = (NamespacedKey) o;
|
||||||
result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
|
return namespace.equals(that.namespace) && key.equals(that.key);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public int hashCode() {
|
||||||
if (this == obj)
|
return Objects.hash(namespace, key);
|
||||||
return true;
|
|
||||||
if (obj == null)
|
|
||||||
return false;
|
|
||||||
if (getClass() != obj.getClass())
|
|
||||||
return false;
|
|
||||||
NamespacedKey other = (NamespacedKey) obj;
|
|
||||||
if (key == null) {
|
|
||||||
if (other.key != null)
|
|
||||||
return false;
|
|
||||||
} else if (!key.equals(other.key))
|
|
||||||
return false;
|
|
||||||
if (namespace == null) {
|
|
||||||
if (other.namespace != null)
|
|
||||||
return false;
|
|
||||||
} else if (!namespace.equals(other.namespace))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,11 @@
|
||||||
"ClientboundSetTitlesAnimationPacket": "0x5C",
|
"ClientboundSetTitlesAnimationPacket": "0x5C",
|
||||||
"ClientboundSetTitleTextPacket": "0x5B",
|
"ClientboundSetTitleTextPacket": "0x5B",
|
||||||
"ClientboundSetSubtitleTextPacket": "0x59",
|
"ClientboundSetSubtitleTextPacket": "0x59",
|
||||||
"ClientboundClearTitlesPacket": "0x0C"
|
"ClientboundSetActionBarTextPacket": "0x42",
|
||||||
|
"ClientboundClearTitlesPacket": "0x0C",
|
||||||
|
"PacketPlayOutBoss": "0x0A",
|
||||||
|
"PacketPlayOutNamedSoundEffect": "0x5E",
|
||||||
|
"PacketPlayOutStopSound": "0x5F"
|
||||||
},
|
},
|
||||||
"StatusIn": {
|
"StatusIn": {
|
||||||
"0x01": "PacketStatusInPing",
|
"0x01": "PacketStatusInPing",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue