parent
ddd100f493
commit
282bebdcdb
22 changed files with 706 additions and 192 deletions
3
pom.xml
3
pom.xml
|
@ -25,7 +25,6 @@
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
<plugins>
|
<plugins>
|
||||||
<!-- this is to reduce jar size by 1 or 2 kb -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
@ -56,7 +55,7 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- end of this -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>specialsource-maven-plugin</artifactId>
|
<artifactId>specialsource-maven-plugin</artifactId>
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
usage of:
|
modules that require nms / reflections / protocollib:
|
||||||
|
- MOTD
|
||||||
reflections:
|
- brand
|
||||||
- ping/F3NameListener net.minecraft.network.protocol.common.custom.BrandPayload
|
- worldborder
|
||||||
|
|
||||||
protocollib:
|
|
||||||
- ping/F3NameListener sending and intercepting CUSTOM_PAYLOADs to modify brand
|
|
||||||
- ping/PingChecker sending and intercepting COOKIE_RESPONSEs to measure ping
|
|
88
src/main/java/eu/m724/tweaks/TweaksConfig.java
Normal file
88
src/main/java/eu/m724/tweaks/TweaksConfig.java
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
package eu.m724.tweaks;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
public record TweaksConfig(
|
||||||
|
boolean isProtocolLib,
|
||||||
|
|
||||||
|
boolean worldborderHide,
|
||||||
|
|
||||||
|
boolean brandEnabled,
|
||||||
|
String brandText,
|
||||||
|
boolean brandShowPing,
|
||||||
|
boolean brandShowMspt,
|
||||||
|
|
||||||
|
boolean doorEnabled,
|
||||||
|
boolean doorDoubleOpen,
|
||||||
|
boolean doorKnocking,
|
||||||
|
|
||||||
|
boolean motdEnabled,
|
||||||
|
String motdSet,
|
||||||
|
|
||||||
|
boolean chatEnabled,
|
||||||
|
boolean chatLocalEvents,
|
||||||
|
String chatDefaultName,
|
||||||
|
|
||||||
|
boolean compassEnabled,
|
||||||
|
int compassWidth,
|
||||||
|
int compassPrecision
|
||||||
|
) {
|
||||||
|
public static final int CONFIG_VERSION = 1;
|
||||||
|
private static TweaksConfig config;
|
||||||
|
|
||||||
|
public static TweaksConfig getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TweaksConfig load(Plugin plugin) {
|
||||||
|
plugin.saveDefaultConfig();
|
||||||
|
FileConfiguration config = plugin.getConfig();
|
||||||
|
|
||||||
|
boolean isProtocolLib = plugin.getServer().getPluginManager().getPlugin("ProtocolLib") != null;
|
||||||
|
|
||||||
|
int configVersion = config.getInt("magic number dont modify this", 0);
|
||||||
|
RuntimeException exception = new RuntimeException("Config version is %d, expected %d".formatted(configVersion, CONFIG_VERSION));
|
||||||
|
if (configVersion == 0) {
|
||||||
|
throw exception;
|
||||||
|
} else if (configVersion > CONFIG_VERSION) {
|
||||||
|
throw new RuntimeException("Please follow update instructions", exception);
|
||||||
|
} else if (configVersion < CONFIG_VERSION) {
|
||||||
|
throw new RuntimeException("Did you downgrade the plugin? Remove config.yml and let the plugin re-create it", exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hideWorldBorder = config.getBoolean("worldborder.hide");
|
||||||
|
|
||||||
|
boolean brandEnabled = config.getBoolean("brand.enabled");
|
||||||
|
String brandText = config.getString("brand.text");
|
||||||
|
boolean brandShowPing = config.getBoolean("brand.showPing");
|
||||||
|
boolean brandShowMspt = config.getBoolean("brand.showMspt");
|
||||||
|
|
||||||
|
boolean doorDoubleOpen = config.getBoolean("doors.doubleOpen");
|
||||||
|
boolean doorKnocking = config.getBoolean("doors.knocking");
|
||||||
|
boolean doorEnabled = doorDoubleOpen || doorKnocking;
|
||||||
|
|
||||||
|
String motdSet = config.getString("motd.set");
|
||||||
|
boolean motdEnabled = !(motdSet.equals("false") || motdSet.isBlank());
|
||||||
|
|
||||||
|
boolean chatEnabled = config.getBoolean("chat.enabled");
|
||||||
|
boolean chatLocalEvents = config.getBoolean("chat.localEvents");
|
||||||
|
String chatDefaultName = config.getString("chat.defaultName");
|
||||||
|
|
||||||
|
boolean compassEnabled = config.getBoolean("compass.enabled");
|
||||||
|
int compassWidth = config.getInt("compass.width");
|
||||||
|
int compassPrecision = config.getInt("compass.precision");
|
||||||
|
|
||||||
|
TweaksConfig.config = new TweaksConfig(
|
||||||
|
isProtocolLib,
|
||||||
|
hideWorldBorder,
|
||||||
|
brandEnabled, brandText, brandShowPing, brandShowMspt,
|
||||||
|
doorEnabled, doorDoubleOpen, doorKnocking,
|
||||||
|
motdEnabled, motdSet,
|
||||||
|
chatEnabled, chatLocalEvents, chatDefaultName,
|
||||||
|
compassEnabled, compassWidth, compassPrecision
|
||||||
|
);
|
||||||
|
|
||||||
|
return TweaksConfig.config;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,12 +2,12 @@ package eu.m724.tweaks;
|
||||||
|
|
||||||
import eu.m724.tweaks.chat.ChatCommands;
|
import eu.m724.tweaks.chat.ChatCommands;
|
||||||
import eu.m724.tweaks.chat.ChatManager;
|
import eu.m724.tweaks.chat.ChatManager;
|
||||||
import eu.m724.tweaks.door.DoorListener;
|
import eu.m724.tweaks.compass.CompassManager;
|
||||||
|
import eu.m724.tweaks.door.DoorManager;
|
||||||
import eu.m724.tweaks.motd.MotdListener;
|
import eu.m724.tweaks.motd.MotdListener;
|
||||||
import eu.m724.tweaks.ping.F3NameListener;
|
import eu.m724.tweaks.ping.F3NameListener;
|
||||||
import eu.m724.tweaks.ping.PingChecker;
|
import eu.m724.tweaks.ping.PingChecker;
|
||||||
import eu.m724.tweaks.ping.PingCommands;
|
import eu.m724.tweaks.ping.PingCommands;
|
||||||
import eu.m724.tweaks.player.MusicPlayer;
|
|
||||||
import eu.m724.tweaks.worldborder.WorldBorderManager;
|
import eu.m724.tweaks.worldborder.WorldBorderManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
@ -17,33 +17,48 @@ import java.util.Objects;
|
||||||
public class TweaksPlugin extends JavaPlugin {
|
public class TweaksPlugin extends JavaPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
TweaksConfig config = TweaksConfig.load(this);
|
||||||
|
|
||||||
|
new CompassManager(this).init();
|
||||||
|
|
||||||
|
if (config.chatEnabled()) {
|
||||||
ChatManager chatManager = new ChatManager(this);
|
ChatManager chatManager = new ChatManager(this);
|
||||||
chatManager.init();
|
chatManager.init();
|
||||||
|
|
||||||
ChatCommands chatCommands = new ChatCommands(chatManager);
|
ChatCommands chatCommands = new ChatCommands(chatManager);
|
||||||
Objects.requireNonNull(getCommand("chat")).setExecutor(chatCommands);
|
Objects.requireNonNull(getCommand("chat")).setExecutor(chatCommands);
|
||||||
Objects.requireNonNull(getCommand("chatmanage")).setExecutor(chatCommands);
|
Objects.requireNonNull(getCommand("chatmanage")).setExecutor(chatCommands);
|
||||||
|
}
|
||||||
|
|
||||||
getServer().getPluginManager().registerEvents(new DoorListener(), this);
|
if (config.doorEnabled()) {
|
||||||
|
new DoorManager().init(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.brandEnabled()) {
|
||||||
new F3NameListener(this).init();
|
new F3NameListener(this).init();
|
||||||
|
}
|
||||||
|
|
||||||
new PingChecker(this).init();
|
new PingChecker(this).init();
|
||||||
Objects.requireNonNull(getCommand("ping")).setExecutor(new PingCommands());
|
Objects.requireNonNull(getCommand("ping")).setExecutor(new PingCommands());
|
||||||
Objects.requireNonNull(getCommand("dkick")).setExecutor(new PingCommands());
|
Objects.requireNonNull(getCommand("dkick")).setExecutor(new PingCommands());
|
||||||
|
|
||||||
if (getServer().getPluginManager().getPlugin("voicechat") != null) {
|
/*if (getServer().getPluginManager().getPlugin("voicechat") != null) {
|
||||||
new MusicPlayer(this).init();
|
new MusicPlayer(this).init();
|
||||||
} else {
|
} else {
|
||||||
getLogger().warning("To use voice extensions, install \"Simple Voice Chat\"");
|
getLogger().warning("To use voice extensions, install \"Simple Voice Chat\"");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
if (config.motdEnabled()) {
|
||||||
try {
|
try {
|
||||||
new MotdListener("example").init(this);
|
new MotdListener(this).init();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
getLogger().severe("Failed to initialize MOTD extension");
|
getLogger().severe("Failed to initialize MOTD extension");
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.worldborderHide()) {
|
||||||
new WorldBorderManager().init(this);
|
new WorldBorderManager().init(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
package eu.m724.tweaks.chat;
|
package eu.m724.tweaks.chat;
|
||||||
|
|
||||||
|
import eu.m724.tweaks.TweaksConfig;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
public class ChatListener implements Listener {
|
public class ChatListener implements Listener {
|
||||||
private final ChatManager chatManager;
|
private final ChatManager chatManager;
|
||||||
|
private final boolean localEvents;
|
||||||
|
|
||||||
public ChatListener(ChatManager chatManager) {
|
public ChatListener(ChatManager chatManager) {
|
||||||
this.chatManager = chatManager;
|
this.chatManager = chatManager;
|
||||||
|
this.localEvents = TweaksConfig.getConfig().chatLocalEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
@ -27,6 +31,7 @@ public class ChatListener implements Listener {
|
||||||
.create();
|
.create();
|
||||||
player.spigot().sendMessage(component);
|
player.spigot().sendMessage(component);
|
||||||
|
|
||||||
|
if (localEvents) {
|
||||||
chatRoom.broadcast(
|
chatRoom.broadcast(
|
||||||
new ComponentBuilder()
|
new ComponentBuilder()
|
||||||
.append(ChatFormatUtils.chatRoomPrefixShort(chatRoom))
|
.append(ChatFormatUtils.chatRoomPrefixShort(chatRoom))
|
||||||
|
@ -38,12 +43,14 @@ public class ChatListener implements Listener {
|
||||||
// remove Minecraft join message
|
// remove Minecraft join message
|
||||||
event.setJoinMessage(null);
|
event.setJoinMessage(null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
ChatRoom chatRoom = chatManager.removePlayer(player);
|
ChatRoom chatRoom = chatManager.removePlayer(player);
|
||||||
|
|
||||||
|
if (localEvents) {
|
||||||
chatRoom.broadcast(
|
chatRoom.broadcast(
|
||||||
new ComponentBuilder()
|
new ComponentBuilder()
|
||||||
.append(ChatFormatUtils.chatRoomPrefixShort(chatRoom))
|
.append(ChatFormatUtils.chatRoomPrefixShort(chatRoom))
|
||||||
|
@ -55,6 +62,25 @@ public class ChatListener implements Listener {
|
||||||
// remove Minecraft quit message
|
// remove Minecraft quit message
|
||||||
event.setQuitMessage(null);
|
event.setQuitMessage(null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||||
|
if (localEvents) {
|
||||||
|
Player player = event.getEntity();
|
||||||
|
ChatRoom chatRoom = chatManager.getPlayerChatRoom(player);
|
||||||
|
|
||||||
|
chatRoom.broadcast(
|
||||||
|
new ComponentBuilder()
|
||||||
|
.append(ChatFormatUtils.chatRoomPrefixShort(chatRoom))
|
||||||
|
.append(event.getDeathMessage())
|
||||||
|
.create()
|
||||||
|
);
|
||||||
|
|
||||||
|
// remove Minecraft death message
|
||||||
|
event.setDeathMessage(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onAsyncPlayerChat(AsyncPlayerChatEvent event) {
|
public void onAsyncPlayerChat(AsyncPlayerChatEvent event) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.m724.tweaks.chat;
|
package eu.m724.tweaks.chat;
|
||||||
|
|
||||||
|
import eu.m724.tweaks.TweaksConfig;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
|
@ -15,6 +16,7 @@ import java.util.Map;
|
||||||
public class ChatManager {
|
public class ChatManager {
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
private final NamespacedKey chatRoomKey;
|
private final NamespacedKey chatRoomKey;
|
||||||
|
private final String defaultRoom;
|
||||||
|
|
||||||
private final Map<Player, ChatRoom> playerMap = new HashMap<>();
|
private final Map<Player, ChatRoom> playerMap = new HashMap<>();
|
||||||
private final Map<String, ChatRoom> roomIdMap = new HashMap<>();
|
private final Map<String, ChatRoom> roomIdMap = new HashMap<>();
|
||||||
|
@ -22,10 +24,11 @@ public class ChatManager {
|
||||||
public ChatManager(Plugin plugin) {
|
public ChatManager(Plugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.chatRoomKey = new NamespacedKey(plugin, "chatRoom");
|
this.chatRoomKey = new NamespacedKey(plugin, "chatRoom");
|
||||||
|
this.defaultRoom = TweaksConfig.getConfig().chatDefaultName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
getById("global");
|
getById(defaultRoom);
|
||||||
plugin.getServer().getPluginManager().registerEvents(new ChatListener(this), plugin);
|
plugin.getServer().getPluginManager().registerEvents(new ChatListener(this), plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,10 +56,15 @@ public class ChatManager {
|
||||||
ChatRoom chatRoom = roomIdMap.get(id);
|
ChatRoom chatRoom = roomIdMap.get(id);
|
||||||
|
|
||||||
if (chatRoom == null) {
|
if (chatRoom == null) {
|
||||||
|
if (id.equals(defaultRoom)) {
|
||||||
|
return new ChatRoom(defaultRoom, null, null);
|
||||||
|
} else {
|
||||||
chatRoom = ChatRoomLoader.load(plugin, id);
|
chatRoom = ChatRoomLoader.load(plugin, id);
|
||||||
|
}
|
||||||
roomIdMap.put(id, chatRoom);
|
roomIdMap.put(id, chatRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return chatRoom;
|
return chatRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,9 +112,9 @@ public class ChatManager {
|
||||||
if (chatRoom == null) {
|
if (chatRoom == null) {
|
||||||
String id = player.getPersistentDataContainer().get(chatRoomKey, PersistentDataType.STRING);
|
String id = player.getPersistentDataContainer().get(chatRoomKey, PersistentDataType.STRING);
|
||||||
|
|
||||||
if (id == null) id = "global";
|
if (id == null) id = defaultRoom;
|
||||||
chatRoom = getById(id);
|
chatRoom = getById(id);
|
||||||
if (chatRoom == null) chatRoom = getById("global");
|
if (chatRoom == null) chatRoom = getById(defaultRoom);
|
||||||
|
|
||||||
chatRoom.players.add(player);
|
chatRoom.players.add(player);
|
||||||
playerMap.put(player, chatRoom);
|
playerMap.put(player, chatRoom);
|
||||||
|
@ -157,7 +165,7 @@ public class ChatManager {
|
||||||
roomIdMap.remove(chatRoom.id);
|
roomIdMap.remove(chatRoom.id);
|
||||||
ChatRoomLoader.getFile(plugin, chatRoom.id).delete();
|
ChatRoomLoader.getFile(plugin, chatRoom.id).delete();
|
||||||
chatRoom.players.forEach(player -> {
|
chatRoom.players.forEach(player -> {
|
||||||
setPlayerChatRoom(getById("global"), player);
|
setPlayerChatRoom(getById(defaultRoom), player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,6 @@ public class ChatRoomLoader {
|
||||||
* @return the chat room or null if no such chat room
|
* @return the chat room or null if no such chat room
|
||||||
*/
|
*/
|
||||||
static ChatRoom load(Plugin plugin, String id) {
|
static ChatRoom load(Plugin plugin, String id) {
|
||||||
if (id.equals("global")) {
|
|
||||||
return new ChatRoom("global", null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
File chatRoomFile = getFile(plugin, id);
|
File chatRoomFile = getFile(plugin, id);
|
||||||
if (!chatRoomFile.exists()) return null;
|
if (!chatRoomFile.exists()) return null;
|
||||||
|
|
||||||
|
|
133
src/main/java/eu/m724/tweaks/compass/CompassListener.java
Normal file
133
src/main/java/eu/m724/tweaks/compass/CompassListener.java
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
package eu.m724.tweaks.compass;
|
||||||
|
|
||||||
|
import eu.m724.tweaks.TweaksConfig;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||||
|
import org.bukkit.inventory.meta.CompassMeta;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
// TODO dimension check
|
||||||
|
public class CompassListener implements Listener {
|
||||||
|
private final int precision = TweaksConfig.getConfig().compassPrecision(); // degrees every point
|
||||||
|
private final int width = TweaksConfig.getConfig().compassWidth(); // points left to right
|
||||||
|
|
||||||
|
private final Map<Integer, String> points = Map.of(
|
||||||
|
0, ChatColor.DARK_GRAY + "S",
|
||||||
|
90, ChatColor.DARK_GRAY + "W",
|
||||||
|
180, ChatColor.DARK_GRAY + "N",
|
||||||
|
270, ChatColor.DARK_GRAY + "E"
|
||||||
|
);
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
|
||||||
|
if (event.getMainHandItem().getType() == Material.COMPASS || event.getOffHandItem().getType() == Material.COMPASS) {
|
||||||
|
event.getPlayer().resetTitle();
|
||||||
|
event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
CompassPlayerPreferences preferences = CompassPlayerPreferences.get(player);
|
||||||
|
|
||||||
|
boolean mainHand = event.getPlayer().getInventory().getItemInMainHand().getType() == Material.COMPASS;
|
||||||
|
boolean offHand = event.getPlayer().getInventory().getItemInOffHand().getType() == Material.COMPASS;
|
||||||
|
boolean holding = mainHand || offHand;
|
||||||
|
|
||||||
|
if (holding) {
|
||||||
|
preferences.visible = true;
|
||||||
|
} else {
|
||||||
|
if (preferences.visible) {
|
||||||
|
preferences.visible = false;
|
||||||
|
event.getPlayer().resetTitle();
|
||||||
|
event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double yaw = wrapMod(event.getTo().getYaw(), 360.0);
|
||||||
|
|
||||||
|
String[] visiblePoints = new String[width];
|
||||||
|
Arrays.fill(visiblePoints, ChatColor.DARK_GRAY + "-");
|
||||||
|
|
||||||
|
Map<Integer, String> currentPoints = new LinkedHashMap<>(points);
|
||||||
|
currentPoints.putAll(preferences.customPoints);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
// TODO optimzie, caluclate that when needed
|
||||||
|
if (player.getBedSpawnLocation() != null) {
|
||||||
|
if (player.getBedSpawnLocation().getWorld().equals(player.getWorld())) {
|
||||||
|
double respawnYaw = calculateYaw(player.getLocation(), player.getBedSpawnLocation());
|
||||||
|
System.out.println(respawnYaw);
|
||||||
|
currentPoints.put((int) respawnYaw, ChatColor.GREEN + "r");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainHand) {
|
||||||
|
CompassMeta meta = (CompassMeta) player.getInventory().getItemInMainHand().getItemMeta();
|
||||||
|
if (meta.isLodestoneTracked()) {
|
||||||
|
double lodeYaw = calculateYaw(player.getLocation(), meta.getLodestone());
|
||||||
|
currentPoints.put((int) lodeYaw, ChatColor.GRAY + "L");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offHand) {
|
||||||
|
CompassMeta meta = (CompassMeta) player.getInventory().getItemInOffHand().getItemMeta();
|
||||||
|
if (meta.isLodestoneTracked()) {
|
||||||
|
double lodeYaw = calculateYaw(player.getLocation(), meta.getLodestone());
|
||||||
|
currentPoints.put((int) lodeYaw, ChatColor.GRAY + "L");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
for (Map.Entry<Integer, String> entry : currentPoints.entrySet()) {
|
||||||
|
double distance = -wrapModRange(yaw - entry.getKey(), -180, 180);
|
||||||
|
int index = (int) (distance / precision + width / 2.0);
|
||||||
|
|
||||||
|
if (index >= 0 && index < width) {
|
||||||
|
visiblePoints[index] = entry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentBuilder builder = new ComponentBuilder();
|
||||||
|
for (String point : visiblePoints) {
|
||||||
|
builder.append(point + ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainHand) {
|
||||||
|
event.getPlayer().sendTitle("", builder.build().toLegacyText(), 0, 70, 20);
|
||||||
|
} else {
|
||||||
|
event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, builder.create());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double wrapModRange(double value, double start, double stop) {
|
||||||
|
double range = stop - start;
|
||||||
|
double result = start + (value - start - Math.floor((value - start) / range) * range);
|
||||||
|
return result == stop ? start : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double wrapMod(double value, double stop) {
|
||||||
|
double result = (value - Math.floor(value / stop) * stop);
|
||||||
|
return result == stop ? 0 : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calculateYaw(Location source, Location target) {
|
||||||
|
return wrapMod(Math.atan2(source.getX() - target.getX(), target.getZ() - source.getZ()) * (180 / Math.PI), 360);
|
||||||
|
}
|
||||||
|
}
|
15
src/main/java/eu/m724/tweaks/compass/CompassManager.java
Normal file
15
src/main/java/eu/m724/tweaks/compass/CompassManager.java
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package eu.m724.tweaks.compass;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
public class CompassManager {
|
||||||
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
public CompassManager(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
plugin.getServer().getPluginManager().registerEvents(new CompassListener(), plugin);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package eu.m724.tweaks.compass;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CompassPlayerPreferences {
|
||||||
|
static Map<Player, CompassPlayerPreferences> playerMap = new HashMap<>();
|
||||||
|
|
||||||
|
boolean visible = false;
|
||||||
|
Map<Integer, String> customPoints = new HashMap<>();
|
||||||
|
|
||||||
|
static CompassPlayerPreferences get(Player player) {
|
||||||
|
return CompassPlayerPreferences.playerMap.computeIfAbsent(player, (k) -> new CompassPlayerPreferences());
|
||||||
|
}
|
||||||
|
}
|
57
src/main/java/eu/m724/tweaks/door/DoorKnockListener.java
Normal file
57
src/main/java/eu/m724/tweaks/door/DoorKnockListener.java
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package eu.m724.tweaks.door;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.data.type.Door;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockDamageAbortEvent;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
import org.bukkit.util.RayTraceResult;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
public class DoorKnockListener implements Listener {
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockDamageAbort(BlockDamageAbortEvent event) {
|
||||||
|
Block block = event.getBlock();
|
||||||
|
if (!(block.getBlockData() instanceof Door)) return;
|
||||||
|
|
||||||
|
World world = block.getLocation().getWorld();
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
// TODO maybe it would be faster to check just player and the door
|
||||||
|
RayTraceResult result = player.rayTraceBlocks(5);
|
||||||
|
if (result == null) return;
|
||||||
|
|
||||||
|
Location hitLocation = result.getHitPosition().toLocation(world);
|
||||||
|
double distance = player.getEyeLocation().distanceSquared(hitLocation);
|
||||||
|
if (distance > 12) return;
|
||||||
|
|
||||||
|
Sound sound = block.getType() == Material.IRON_DOOR ? Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR : Sound.ENTITY_ZOMBIE_ATTACK_WOODEN_DOOR;
|
||||||
|
float volume = player.isSneaking() ? 0.4f : 1f;
|
||||||
|
float pitch = player.getFallDistance() > 0 ? 1f : 1.5f;
|
||||||
|
|
||||||
|
if (player.hasPotionEffect(PotionEffectType.NAUSEA)) {
|
||||||
|
pitch = ThreadLocalRandom.current().nextFloat(0.5f, 0.7f);
|
||||||
|
}
|
||||||
|
|
||||||
|
PotionEffect fatigue = player.getPotionEffect(PotionEffectType.MINING_FATIGUE);
|
||||||
|
|
||||||
|
if (fatigue != null) {
|
||||||
|
int level = fatigue.getAmplifier();
|
||||||
|
volume /= level / 3f;
|
||||||
|
pitch /= level;
|
||||||
|
}
|
||||||
|
|
||||||
|
volume *= (float) ((10.0 - Math.min(distance - 2, 10.0)) / 10.0);
|
||||||
|
|
||||||
|
world.playSound(hitLocation, sound, volume, pitch);
|
||||||
|
//world.spawnParticle(Particle.BLOCK, hitLocation, (int) (10 * volume), door);
|
||||||
|
}
|
||||||
|
}
|
18
src/main/java/eu/m724/tweaks/door/DoorManager.java
Normal file
18
src/main/java/eu/m724/tweaks/door/DoorManager.java
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package eu.m724.tweaks.door;
|
||||||
|
|
||||||
|
import eu.m724.tweaks.TweaksConfig;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
public class DoorManager {
|
||||||
|
|
||||||
|
public void init(Plugin plugin) {
|
||||||
|
if (TweaksConfig.getConfig().doorKnocking()) {
|
||||||
|
plugin.getServer().getPluginManager().registerEvents(new DoorKnockListener(), plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TweaksConfig.getConfig().doorDoubleOpen()) {
|
||||||
|
plugin.getServer().getPluginManager().registerEvents(new DoorOpenListener(), plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,56 +4,12 @@ import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.data.type.Door;
|
import org.bukkit.block.data.type.Door;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.block.BlockDamageEvent;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
import org.bukkit.util.RayTraceResult;
|
|
||||||
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
public class DoorOpenListener implements Listener {
|
||||||
|
|
||||||
public class DoorListener implements Listener {
|
|
||||||
@EventHandler
|
|
||||||
public void onBlockDamage(BlockDamageEvent event) {
|
|
||||||
Block block = event.getBlock();
|
|
||||||
if (!(block.getBlockData() instanceof Door)) return;
|
|
||||||
|
|
||||||
World world = block.getLocation().getWorld();
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
// TODO maybe it would be faster to check just player and the door
|
|
||||||
RayTraceResult result = player.rayTraceBlocks(5);
|
|
||||||
if (result == null) return;
|
|
||||||
|
|
||||||
Location hitLocation = result.getHitPosition().toLocation(world);
|
|
||||||
double distance = player.getEyeLocation().distanceSquared(hitLocation);
|
|
||||||
if (distance > 12) return;
|
|
||||||
|
|
||||||
Sound sound = block.getType() == Material.IRON_DOOR ? Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR : Sound.ENTITY_ZOMBIE_ATTACK_WOODEN_DOOR;
|
|
||||||
float volume = player.isSneaking() ? 0.4f : 1f;
|
|
||||||
float pitch = player.getFallDistance() > 0 ? 1f : 1.5f;
|
|
||||||
|
|
||||||
if (player.hasPotionEffect(PotionEffectType.NAUSEA)) {
|
|
||||||
pitch = ThreadLocalRandom.current().nextFloat(0.5f, 0.7f);
|
|
||||||
}
|
|
||||||
|
|
||||||
PotionEffect fatigue = player.getPotionEffect(PotionEffectType.MINING_FATIGUE);
|
|
||||||
|
|
||||||
if (fatigue != null) {
|
|
||||||
int level = fatigue.getAmplifier();
|
|
||||||
volume /= level / 3f;
|
|
||||||
pitch /= level;
|
|
||||||
}
|
|
||||||
|
|
||||||
volume *= (float) ((10.0 - Math.min(distance - 2, 10.0)) / 10.0);
|
|
||||||
|
|
||||||
world.playSound(hitLocation, sound, volume, pitch);
|
|
||||||
//world.spawnParticle(Particle.BLOCK, hitLocation, (int) (10 * volume), door);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
@ -109,4 +65,5 @@ public class DoorListener implements Listener {
|
||||||
location.getBlock().setBlockData(nextDoor);
|
location.getBlock().setBlockData(nextDoor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ import com.comphenix.protocol.ProtocolLibrary;
|
||||||
import com.comphenix.protocol.events.*;
|
import com.comphenix.protocol.events.*;
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
import com.comphenix.protocol.reflect.StructureModifier;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
import eu.m724.tweaks.TweaksConfig;
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
import net.md_5.bungee.chat.ComponentSerializer;
|
import net.md_5.bungee.chat.ComponentSerializer;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
|
@ -21,15 +22,18 @@ import java.util.Optional;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public class MotdListener {
|
public class MotdListener {
|
||||||
private final String motdSetName;
|
private final Plugin plugin;
|
||||||
|
|
||||||
private Component[] motds;
|
private Component[] motds;
|
||||||
|
|
||||||
public MotdListener(String motdSetName) {
|
public MotdListener(Plugin plugin) {
|
||||||
this.motdSetName = motdSetName;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(Plugin plugin) throws IOException {
|
public void init() throws IOException {
|
||||||
|
// TODO adding more MOTD features would require checking whether to enable set
|
||||||
|
|
||||||
|
String motdSetName = TweaksConfig.getConfig().motdSet();
|
||||||
File motdSetsFile = new File(plugin.getDataFolder() + "/motd sets/" + motdSetName + ".txt");
|
File motdSetsFile = new File(plugin.getDataFolder() + "/motd sets/" + motdSetName + ".txt");
|
||||||
|
|
||||||
// if the directory didn't exist create example motd sets
|
// if the directory didn't exist create example motd sets
|
||||||
|
@ -46,8 +50,6 @@ public class MotdListener {
|
||||||
})
|
})
|
||||||
.toArray(Component[]::new);
|
.toArray(Component[]::new);
|
||||||
|
|
||||||
plugin.getLogger().info("Loaded %d MOTDs".formatted(motds.length));
|
|
||||||
|
|
||||||
registerListener(plugin);
|
registerListener(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.comphenix.protocol.PacketType;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
import com.comphenix.protocol.events.*;
|
import com.comphenix.protocol.events.*;
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
import com.comphenix.protocol.reflect.StructureModifier;
|
||||||
|
import eu.m724.tweaks.TweaksConfig;
|
||||||
import net.minecraft.network.protocol.common.custom.BrandPayload;
|
import net.minecraft.network.protocol.common.custom.BrandPayload;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
@ -12,34 +13,35 @@ import org.bukkit.scheduler.BukkitRunnable;
|
||||||
public class F3NameListener {
|
public class F3NameListener {
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
private boolean showPing, showMspt;
|
||||||
|
private String text;
|
||||||
|
|
||||||
public F3NameListener(Plugin plugin) {
|
public F3NameListener(Plugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
|
showPing = TweaksConfig.getConfig().brandShowPing();
|
||||||
|
showMspt = TweaksConfig.getConfig().brandShowMspt();
|
||||||
|
text = TweaksConfig.getConfig().brandText();
|
||||||
|
|
||||||
new BukkitRunnable() {
|
new BukkitRunnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
double mspt = PlayerPing.getMillisPerTick();
|
if (showPing) {
|
||||||
boolean showMspt = mspt > 50.05; // mspt is at least like 50.01 because of some measuring overheads (I think)
|
|
||||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||||
double ping = PlayerPing.getPingMillis(player);
|
String text = getBrandText(player);
|
||||||
String brand;
|
changeBrandFor(player, text);
|
||||||
if (ping == 0) {
|
|
||||||
brand = "wait";
|
|
||||||
} else {
|
|
||||||
if (showMspt) {
|
|
||||||
brand = "%.2f mspt | Ping: %.2f ms".formatted(mspt, PlayerPing.getPingMillis(player));
|
|
||||||
} else {
|
|
||||||
brand = "Ping: %.2f ms".formatted(PlayerPing.getPingMillis(player));
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
changeBrand(player, brand);
|
String text = getBrandText(null);
|
||||||
|
changeBrandAll(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.runTaskTimerAsynchronously(plugin, 0, 200); // 10 sec
|
}.runTaskTimerAsynchronously(plugin, 0, 200); // 10 sec
|
||||||
|
|
||||||
// this is just to make the server not send a brand on login, it doesn't ever run after login
|
// this is just to make the server not send a brand on login, it doesn't ever run after login
|
||||||
|
// TODO is there much difference if we create a packet instead of modifying?
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(
|
||||||
plugin,
|
plugin,
|
||||||
ListenerPriority.NORMAL,
|
ListenerPriority.NORMAL,
|
||||||
|
@ -50,7 +52,7 @@ public class F3NameListener {
|
||||||
PacketContainer packet = event.getPacket();
|
PacketContainer packet = event.getPacket();
|
||||||
|
|
||||||
InternalStructure structure = new InternalStructure(
|
InternalStructure structure = new InternalStructure(
|
||||||
new BrandPayload("wait"),
|
new BrandPayload(text),
|
||||||
new StructureModifier<>(BrandPayload.class)
|
new StructureModifier<>(BrandPayload.class)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -59,7 +61,29 @@ public class F3NameListener {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeBrand(Player player, String brand) {
|
/**
|
||||||
|
* Composes a brand name
|
||||||
|
* @param player player or null if server wide
|
||||||
|
* @return the brand name
|
||||||
|
*/
|
||||||
|
private String getBrandText(Player player) {
|
||||||
|
String _text = text;
|
||||||
|
|
||||||
|
if (showMspt) {
|
||||||
|
double mspt = PlayerPing.getMillisPerTick();
|
||||||
|
if (mspt > 50.05) { // mspt is at least like 50.01 because of some measuring overheads (I think)
|
||||||
|
_text += " | %.2f mspt".formatted(mspt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showPing) {
|
||||||
|
_text += " | %.2f ms".formatted(PlayerPing.getPingMillis(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
return _text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PacketContainer composeBrandPacket(String brand) {
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.CUSTOM_PAYLOAD);
|
PacketContainer packet = new PacketContainer(PacketType.Play.Server.CUSTOM_PAYLOAD);
|
||||||
|
|
||||||
InternalStructure structure = new InternalStructure(
|
InternalStructure structure = new InternalStructure(
|
||||||
|
@ -68,6 +92,21 @@ public class F3NameListener {
|
||||||
);
|
);
|
||||||
|
|
||||||
packet.getStructures().write(0, structure);
|
packet.getStructures().write(0, structure);
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes server brand for all players on the server
|
||||||
|
*/
|
||||||
|
private void changeBrandAll(String brand) {
|
||||||
|
ProtocolLibrary.getProtocolManager().broadcastServerPacket(composeBrandPacket(brand));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes server brand for a player
|
||||||
|
*/
|
||||||
|
private void changeBrandFor(Player player, String brand) {
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, composeBrandPacket(brand));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +1,24 @@
|
||||||
package eu.m724.tweaks.ping;
|
package eu.m724.tweaks.ping;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import eu.m724.tweaks.TweaksConfig;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
|
||||||
import com.comphenix.protocol.events.ListenerPriority;
|
|
||||||
import com.comphenix.protocol.events.PacketAdapter;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
|
||||||
import com.comphenix.protocol.wrappers.MinecraftKey;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import java.util.Map;
|
public class PingChecker {
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
public class PingChecker extends BukkitRunnable {
|
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
|
|
||||||
// this is in nanoseconds
|
|
||||||
private final Map<Player, Long> pending = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public PingChecker(Plugin plugin) {
|
public PingChecker(Plugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(
|
|
||||||
plugin,
|
|
||||||
ListenerPriority.NORMAL,
|
|
||||||
PacketType.Play.Client.COOKIE_RESPONSE
|
|
||||||
) {
|
|
||||||
@Override
|
|
||||||
public void onPacketReceiving(PacketEvent event) {
|
|
||||||
// below line checks, whether the first (and sole) identifier field in the packet is minecraft:chk_ping
|
|
||||||
if (event.getPacket().getMinecraftKeys().read(0).getKey().equals("chk_ping")) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
long start = pending.remove(player);
|
if (TweaksConfig.getConfig().isProtocolLib()) {
|
||||||
PlayerPing.pings.put(player, System.nanoTime() - start);
|
plugin.getLogger().info("Using ProtocolLib for checking ping");
|
||||||
|
new ProtocolPingChecker(plugin).start();
|
||||||
// gotta cancel because the server will kick
|
|
||||||
if (!PlayerPing.kickQueue.contains(player)) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
} else {
|
} else {
|
||||||
PlayerPing.kickQueue.remove(player);
|
plugin.getLogger().info("Using Spigot for checking ping");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.runTaskTimerAsynchronously(plugin, 0, 200); // 10 secs
|
|
||||||
new MsptChecker().init(plugin); // TODO should this be here
|
new MsptChecker().init(plugin); // TODO should this be here
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
plugin.getServer().getOnlinePlayers().forEach(player -> {
|
|
||||||
// dropped packets happen so timing out a request after 30 seconds
|
|
||||||
if (System.nanoTime() - pending.getOrDefault(player, 0L) < 30000000000L) return;
|
|
||||||
pending.put(player, System.nanoTime()); // here or at the bottom? probably doesn't matter
|
|
||||||
|
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.COOKIE_REQUEST);
|
|
||||||
packet.getMinecraftKeys().write(0, new MinecraftKey("chk_ping"));
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.m724.tweaks.ping;
|
package eu.m724.tweaks.ping;
|
||||||
|
|
||||||
|
import eu.m724.tweaks.TweaksConfig;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||||
|
@ -20,6 +21,11 @@ public class PingCommands implements CommandExecutor {
|
||||||
.create();
|
.create();
|
||||||
player.spigot().sendMessage(component);
|
player.spigot().sendMessage(component);
|
||||||
} else if (command.getName().equals("dkick")) {
|
} else if (command.getName().equals("dkick")) {
|
||||||
|
if (!TweaksConfig.getConfig().isProtocolLib()) {
|
||||||
|
sender.sendMessage("This feature is not available");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
sender.sendMessage("Include one or more player names");
|
sender.sendMessage("Include one or more player names");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.m724.tweaks.ping;
|
package eu.m724.tweaks.ping;
|
||||||
|
|
||||||
|
import eu.m724.tweaks.TweaksConfig;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -7,16 +8,24 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class PlayerPing {
|
public class PlayerPing {
|
||||||
// in nanos
|
// if protocol lib is installed we use our own checker
|
||||||
static final Map<Player, Long> pings = new ConcurrentHashMap<>();
|
private static final boolean external = TweaksConfig.getConfig().isProtocolLib();
|
||||||
// nanos per tick
|
|
||||||
static volatile long nspt = 0L;
|
|
||||||
|
|
||||||
|
// TODO remove this feature because why
|
||||||
static final Set<Player> kickQueue = ConcurrentHashMap.newKeySet();
|
static final Set<Player> kickQueue = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
|
// current player latencies, in nanos
|
||||||
|
static final Map<Player, Long> pings = new ConcurrentHashMap<>();
|
||||||
|
// nanoseconds per tick
|
||||||
|
static volatile long nspt = 0L;
|
||||||
|
|
||||||
public static long getPingNanos(Player player) {
|
public static long getPingNanos(Player player) {
|
||||||
|
if (!external) {
|
||||||
|
return (long) player.getPing() * 1000000;
|
||||||
|
} else {
|
||||||
return pings.getOrDefault(player, -1L);
|
return pings.getOrDefault(player, -1L);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static double getPingMillis(Player player) {
|
public static double getPingMillis(Player player) {
|
||||||
return getPingNanos(player) / 1000000.0; // a mil ns in ms
|
return getPingNanos(player) / 1000000.0; // a mil ns in ms
|
||||||
|
|
66
src/main/java/eu/m724/tweaks/ping/ProtocolPingChecker.java
Normal file
66
src/main/java/eu/m724/tweaks/ping/ProtocolPingChecker.java
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package eu.m724.tweaks.ping;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.events.ListenerPriority;
|
||||||
|
import com.comphenix.protocol.events.PacketAdapter;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
|
import com.comphenix.protocol.wrappers.MinecraftKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class ProtocolPingChecker extends BukkitRunnable {
|
||||||
|
// this is in nanoseconds
|
||||||
|
private final Map<Player, Long> pending = new ConcurrentHashMap<>();
|
||||||
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
ProtocolPingChecker(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(
|
||||||
|
plugin,
|
||||||
|
ListenerPriority.NORMAL,
|
||||||
|
PacketType.Play.Client.COOKIE_RESPONSE
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void onPacketReceiving(PacketEvent event) {
|
||||||
|
// below line checks, whether the first (and sole) identifier field in the packet is minecraft:chk_ping
|
||||||
|
if (event.getPacket().getMinecraftKeys().read(0).getKey().equals("chk_ping")) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
long start = pending.remove(player);
|
||||||
|
PlayerPing.pings.put(player, System.nanoTime() - start);
|
||||||
|
|
||||||
|
// gotta cancel because the server will kick
|
||||||
|
if (!PlayerPing.kickQueue.contains(player)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
} else {
|
||||||
|
PlayerPing.kickQueue.remove(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.runTaskTimerAsynchronously(plugin, 0, 200); // 10 secs
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
plugin.getServer().getOnlinePlayers().forEach(player -> {
|
||||||
|
// dropped packets happen so timing out a request after 30 seconds
|
||||||
|
if (System.nanoTime() - pending.getOrDefault(player, 0L) < 30000000000L) return;
|
||||||
|
pending.put(player, System.nanoTime()); // here or at the bottom? probably doesn't matter
|
||||||
|
|
||||||
|
PacketContainer packet = new PacketContainer(PacketType.Play.Server.COOKIE_REQUEST);
|
||||||
|
packet.getMinecraftKeys().write(0, new MinecraftKey("chk_ping"));
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package eu.m724.tweaks.worldborder;
|
||||||
|
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
// TODO I could do this with API but yeah I'm more comfortable with this
|
||||||
|
|
||||||
|
public record WorldBorderInfoPayload(int extensionRadius) implements CustomPacketPayload {
|
||||||
|
private static final Type<WorldBorderInfoPayload> TYPE =
|
||||||
|
new Type<>(ResourceLocation.tryBuild("tweaks724", "worldborder"));
|
||||||
|
|
||||||
|
public static final StreamCodec<FriendlyByteBuf, WorldBorderInfoPayload> STREAM_CODEC =
|
||||||
|
CustomPacketPayload.codec(WorldBorderInfoPayload::write, WorldBorderInfoPayload::new);
|
||||||
|
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WorldBorderInfoPayload(FriendlyByteBuf byteBuf) {
|
||||||
|
this(byteBuf.readVarInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void write(FriendlyByteBuf byteBuf) {
|
||||||
|
byteBuf.writeVarInt(extensionRadius);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,19 +2,21 @@ package eu.m724.tweaks.worldborder;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.protocol.PacketType;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
import com.comphenix.protocol.events.*;
|
import com.comphenix.protocol.events.ListenerPriority;
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
import com.comphenix.protocol.events.PacketAdapter;
|
||||||
import net.minecraft.SharedConstants;
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
import net.minecraft.network.chat.Component;
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
import net.minecraft.network.protocol.game.ClientboundInitializeBorderPacket;
|
|
||||||
import net.minecraft.network.protocol.status.ServerStatus;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
|
||||||
|
|
||||||
public class WorldBorderManager {
|
public class WorldBorderManager {
|
||||||
|
private static final int EXTENSION_RADIUS = 512;
|
||||||
|
|
||||||
public void init(Plugin plugin) {
|
public void init(Plugin plugin) {
|
||||||
|
plugin.getServer().getMessenger().registerOutgoingPluginChannel(plugin, "tweaks724:worldborder");
|
||||||
|
byte[] infoArray = ByteBuffer.allocate(4).putInt(EXTENSION_RADIUS).array();
|
||||||
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(
|
||||||
plugin,
|
plugin,
|
||||||
ListenerPriority.NORMAL,
|
ListenerPriority.NORMAL,
|
||||||
|
@ -23,12 +25,43 @@ public class WorldBorderManager {
|
||||||
@Override
|
@Override
|
||||||
public void onPacketSending(PacketEvent event) {
|
public void onPacketSending(PacketEvent event) {
|
||||||
PacketContainer packet = event.getPacket();
|
PacketContainer packet = event.getPacket();
|
||||||
event.getPacket().getDoubles().write(2, 60000000.0);
|
// old diameter
|
||||||
event.getPacket().getDoubles().write(3, 60000000.0);
|
packet.getDoubles().write(2, packet.getDoubles().read(2) + EXTENSION_RADIUS * 2);
|
||||||
|
// new diameter
|
||||||
|
packet.getDoubles().write(3, packet.getDoubles().read(3) + EXTENSION_RADIUS * 2);
|
||||||
|
|
||||||
System.out.println(
|
// border radius
|
||||||
packet
|
// packet.getIntegers().write(0, packet.getIntegers().read(0) + EXTENSION_RADIUS);
|
||||||
);
|
// warning distance
|
||||||
|
packet.getIntegers().write(1, packet.getIntegers().read(1) + EXTENSION_RADIUS);
|
||||||
|
|
||||||
|
event.getPlayer().sendPluginMessage(plugin, "tweaks724:worldborder", infoArray);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(
|
||||||
|
plugin,
|
||||||
|
ListenerPriority.NORMAL,
|
||||||
|
PacketType.Play.Server.SET_BORDER_SIZE
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void onPacketSending(PacketEvent event) {
|
||||||
|
PacketContainer packet = event.getPacket();
|
||||||
|
// diameter
|
||||||
|
packet.getDoubles().write(0, packet.getDoubles().read(0) + EXTENSION_RADIUS * 2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(
|
||||||
|
plugin,
|
||||||
|
ListenerPriority.NORMAL,
|
||||||
|
PacketType.Play.Server.SET_BORDER_WARNING_DISTANCE
|
||||||
|
) {
|
||||||
|
@Override
|
||||||
|
public void onPacketSending(PacketEvent event) {
|
||||||
|
PacketContainer packet = event.getPacket();
|
||||||
|
// warning distance
|
||||||
|
packet.getIntegers().write(0, packet.getIntegers().read(0) + EXTENSION_RADIUS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
50
src/main/resources/config.yml
Normal file
50
src/main/resources/config.yml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
worldborder:
|
||||||
|
# Hides the world border at 30 mil
|
||||||
|
# Client side so it won't make the world bigger or anything
|
||||||
|
# Warning: Don't use /worldborder while this is on
|
||||||
|
hide: true
|
||||||
|
|
||||||
|
# "Server brand" (second line of F3)
|
||||||
|
brand:
|
||||||
|
enabled: true
|
||||||
|
# Custom text, "" to not use
|
||||||
|
text: "My server"
|
||||||
|
# Show a player's ping
|
||||||
|
showPing: true
|
||||||
|
# Show mspt (millis per tick) if server is lagging
|
||||||
|
showMspt: true
|
||||||
|
|
||||||
|
doors:
|
||||||
|
# Opening one door also opens the adjacent one
|
||||||
|
doubleOpen: true
|
||||||
|
# Make a sound on left-clicking
|
||||||
|
knocking: true
|
||||||
|
|
||||||
|
motd:
|
||||||
|
# Name of the set containing the MOTDs
|
||||||
|
# (random displayed every ping)
|
||||||
|
# "" or false to disable
|
||||||
|
set: "example"
|
||||||
|
|
||||||
|
chat:
|
||||||
|
# Enable chatrooms
|
||||||
|
enabled: true
|
||||||
|
# Whether event messages like join, quit, death (I think that's all needed)
|
||||||
|
# are only within the player's chatroom
|
||||||
|
localEvents: true
|
||||||
|
# Name of the default / global chatroom
|
||||||
|
defaultName: "global"
|
||||||
|
|
||||||
|
compass:
|
||||||
|
# Compass will be shown in a text form
|
||||||
|
enabled: true
|
||||||
|
# How much points (each point is separated with a space)
|
||||||
|
# I suggest making this uneven to make center... in center
|
||||||
|
width: 9
|
||||||
|
# How many degrees every point
|
||||||
|
precision: 10
|
||||||
|
|
||||||
|
# Finally, thank you for downloading Tweaks724, I hope you enjoy!
|
||||||
|
|
||||||
|
# Don't modify unless told to
|
||||||
|
magic number dont modify this: 1
|
Loading…
Reference in a new issue