parent
					
						
							
								4503f15d6c
							
						
					
				
			
			
				commit
				
					
						621c006590
					
				
			
		
					 15 changed files with 233 additions and 51 deletions
				
			
		
							
								
								
									
										19
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					# tweaks724
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Dependencies: ProtocolLib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Caveats
 | 
				
			||||||
 | 
					Disable "secure chat"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Chatrooms
 | 
				
			||||||
 | 
					- `/c` to see info about current chatroom
 | 
				
			||||||
 | 
					- `/c <name>` to join a chatroom
 | 
				
			||||||
 | 
					- `/cm create <name>` to create a chatroom
 | 
				
			||||||
 | 
					- `/cm set* <name>` to change a setting (for owners)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Commands
 | 
				
			||||||
 | 
					- `/dkick` - discreet kick. The player will be kicked with a cryptic error message, and those smarter will think it's a plugin bug.[^1] Brilliant!
 | 
				
			||||||
 | 
					- `/ping` - checks ping. Ping is checked using a more accurate[^2] method
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[^1]: or, better, client bug, if they don't trust their client
 | 
				
			||||||
 | 
					[^2]: not
 | 
				
			||||||
							
								
								
									
										36
									
								
								pom.xml
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								pom.xml
									
										
									
									
									
								
							| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
    <modelVersion>4.0.0</modelVersion>
 | 
					    <modelVersion>4.0.0</modelVersion>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <groupId>eu.m724</groupId>
 | 
					    <groupId>eu.m724</groupId>
 | 
				
			||||||
    <artifactId>mutils</artifactId>
 | 
					    <artifactId>tweaks</artifactId>
 | 
				
			||||||
    <version>1.0-SNAPSHOT</version>
 | 
					    <version>1.0-SNAPSHOT</version>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <properties>
 | 
					    <properties>
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,40 @@
 | 
				
			||||||
                <filtering>true</filtering>
 | 
					                <filtering>true</filtering>
 | 
				
			||||||
            </resource>
 | 
					            </resource>
 | 
				
			||||||
        </resources>
 | 
					        </resources>
 | 
				
			||||||
 | 
					        <plugins>
 | 
				
			||||||
 | 
					            <!-- this is to reduce jar size by 1 or 2 kb -->
 | 
				
			||||||
 | 
					            <plugin>
 | 
				
			||||||
 | 
					                <groupId>org.apache.maven.plugins</groupId>
 | 
				
			||||||
 | 
					                <artifactId>maven-shade-plugin</artifactId>
 | 
				
			||||||
 | 
					                <version>3.6.0</version>
 | 
				
			||||||
 | 
					                <configuration>
 | 
				
			||||||
 | 
					                    <createDependencyReducedPom>false</createDependencyReducedPom>
 | 
				
			||||||
 | 
					                    <minimizeJar>true</minimizeJar>
 | 
				
			||||||
 | 
					                    <artifactSet>
 | 
				
			||||||
 | 
					                        <includes>
 | 
				
			||||||
 | 
					                            <include>eu.m724:tweaks</include>
 | 
				
			||||||
 | 
					                        </includes>
 | 
				
			||||||
 | 
					                    </artifactSet>
 | 
				
			||||||
 | 
					                    <filters>
 | 
				
			||||||
 | 
					                        <filter>
 | 
				
			||||||
 | 
					                            <artifact>*</artifact>
 | 
				
			||||||
 | 
					                            <excludes>
 | 
				
			||||||
 | 
					                                <exclude>META-INF/**</exclude>
 | 
				
			||||||
 | 
					                            </excludes>
 | 
				
			||||||
 | 
					                        </filter>
 | 
				
			||||||
 | 
					                    </filters>
 | 
				
			||||||
 | 
					                </configuration>
 | 
				
			||||||
 | 
					                <executions>
 | 
				
			||||||
 | 
					                    <execution>
 | 
				
			||||||
 | 
					                        <phase>package</phase>
 | 
				
			||||||
 | 
					                        <goals>
 | 
				
			||||||
 | 
					                            <goal>shade</goal>
 | 
				
			||||||
 | 
					                        </goals>
 | 
				
			||||||
 | 
					                    </execution>
 | 
				
			||||||
 | 
					                </executions>
 | 
				
			||||||
 | 
					            </plugin>
 | 
				
			||||||
 | 
					            <!-- end of this -->
 | 
				
			||||||
 | 
					        </plugins>
 | 
				
			||||||
    </build>
 | 
					    </build>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <repositories>
 | 
					    <repositories>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,5 +25,6 @@ public class TweaksPlugin extends JavaPlugin {
 | 
				
			||||||
        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());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,17 +30,12 @@ public class ChatCommands implements CommandExecutor {
 | 
				
			||||||
            ChatRoom chatRoom = manager.getPlayerChatRoom(player);
 | 
					            ChatRoom chatRoom = manager.getPlayerChatRoom(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (args.length == 0) { // show room
 | 
					            if (args.length == 0) { // show room
 | 
				
			||||||
                BaseComponent[] component = new ComponentBuilder("Active chat room: ").color(ChatColor.GOLD)
 | 
					                player.spigot().sendMessage(chatRoom.getInfoComponent());
 | 
				
			||||||
                        .append(chatRoom.id).color(chatRoom.color)
 | 
					 | 
				
			||||||
                        .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(chatRoom.getInfoComponent())))
 | 
					 | 
				
			||||||
                        .create();
 | 
					 | 
				
			||||||
                player.spigot().sendMessage(component);
 | 
					 | 
				
			||||||
            } else { // join room
 | 
					            } else { // join room
 | 
				
			||||||
                // TODO move joining logic
 | 
					 | 
				
			||||||
                String id = args[0];
 | 
					                String id = args[0];
 | 
				
			||||||
                String password = null;
 | 
					                String password = null;
 | 
				
			||||||
                if (args.length > 1) {
 | 
					                if (args.length > 1) {
 | 
				
			||||||
                    password = Arrays.stream(args).skip(1).collect(Collectors.joining(" ")).strip();
 | 
					                    password = Arrays.stream(args).skip(1).collect(Collectors.joining(" "));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                boolean authenticated = false;
 | 
					                boolean authenticated = false;
 | 
				
			||||||
| 
						 | 
					@ -105,7 +100,8 @@ public class ChatCommands implements CommandExecutor {
 | 
				
			||||||
                    case "delete" -> {
 | 
					                    case "delete" -> {
 | 
				
			||||||
                        if (argument.equals(chatRoom.id)) {
 | 
					                        if (argument.equals(chatRoom.id)) {
 | 
				
			||||||
                            if (isOwner) {
 | 
					                            if (isOwner) {
 | 
				
			||||||
                                // TODO
 | 
					                                manager.deleteChatRoom(chatRoom);
 | 
				
			||||||
 | 
					                                sender.sendMessage("Room %s deleted".formatted(chatRoom.id));
 | 
				
			||||||
                            } else {
 | 
					                            } else {
 | 
				
			||||||
                                sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
 | 
					                                sender.sendMessage("You're not the owner of %s, please enter the room you want to make changes in".formatted(chatRoom.id));
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
| 
						 | 
					@ -134,7 +130,7 @@ public class ChatCommands implements CommandExecutor {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    case "setpassword" -> {
 | 
					                    case "setpassword" -> {
 | 
				
			||||||
                        if (isOwner) {
 | 
					                        if (isOwner) {
 | 
				
			||||||
                            chatRoom.password = Arrays.stream(args).skip(1).collect(Collectors.joining(" ")).strip();
 | 
					                            chatRoom.password = Arrays.stream(args).skip(1).collect(Collectors.joining(" "));
 | 
				
			||||||
                            try {
 | 
					                            try {
 | 
				
			||||||
                                manager.saveChatRoom(chatRoom);
 | 
					                                manager.saveChatRoom(chatRoom);
 | 
				
			||||||
                                sender.sendMessage("Password changed");
 | 
					                                sender.sendMessage("Password changed");
 | 
				
			||||||
| 
						 | 
					@ -174,13 +170,13 @@ public class ChatCommands implements CommandExecutor {
 | 
				
			||||||
                    case "create" ->
 | 
					                    case "create" ->
 | 
				
			||||||
                            sender.sendMessage("Please pass a room name as an argument. The room name must be of characters and digits.");
 | 
					                            sender.sendMessage("Please pass a room name as an argument. The room name must be of characters and digits.");
 | 
				
			||||||
                    case "delete" ->
 | 
					                    case "delete" ->
 | 
				
			||||||
                            sender.sendMessage("You want to delete room %s. Confirm by passing its name as an argument for this action.".formatted(chatRoom));
 | 
					                            sender.sendMessage("You want to delete room %s. Confirm by passing its name as an argument for this action.".formatted(chatRoom.id));
 | 
				
			||||||
                    case "setowner" ->
 | 
					                    case "setowner" ->
 | 
				
			||||||
                            sender.sendMessage("To transfer ownership of room %s, pass the new owner name as an argument for this action.".formatted(chatRoom));
 | 
					                            sender.sendMessage("To transfer ownership of room %s, pass the new owner name as an argument for this action.".formatted(chatRoom.id));
 | 
				
			||||||
                    case "setpassword" ->
 | 
					                    case "setpassword" ->
 | 
				
			||||||
                            sender.sendMessage("To change the password of room %s, pass the new password as an argument for this action.".formatted(chatRoom));
 | 
					                            sender.sendMessage("To change the password of room %s, pass the new password as an argument for this action.".formatted(chatRoom.id));
 | 
				
			||||||
                    case "setcolor" ->
 | 
					                    case "setcolor" ->
 | 
				
			||||||
                            sender.sendMessage("To change the message color of room %s, pass the new color as an argument for this action. #hex or color name.".formatted(chatRoom));
 | 
					                            sender.sendMessage("To change the message color of room %s, pass the new color as an argument for this action. #hex or color name.".formatted(chatRoom.id));
 | 
				
			||||||
                    default ->
 | 
					                    default ->
 | 
				
			||||||
                            sender.sendMessage("Actions: create, delete, setowner, setpassword, setcolor");
 | 
					                            sender.sendMessage("Actions: create, delete, setowner, setpassword, setcolor");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										39
									
								
								src/main/java/eu/m724/tweaks/chat/ChatFormatUtils.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/main/java/eu/m724/tweaks/chat/ChatFormatUtils.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,39 @@
 | 
				
			||||||
 | 
					package eu.m724.tweaks.chat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.md_5.bungee.api.ChatColor;
 | 
				
			||||||
 | 
					import net.md_5.bungee.api.chat.BaseComponent;
 | 
				
			||||||
 | 
					import net.md_5.bungee.api.chat.ComponentBuilder;
 | 
				
			||||||
 | 
					import net.md_5.bungee.api.chat.HoverEvent;
 | 
				
			||||||
 | 
					import net.md_5.bungee.api.chat.hover.content.Text;
 | 
				
			||||||
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ChatFormatUtils {
 | 
				
			||||||
 | 
					    public static BaseComponent[] formatPlayer(Player player) {
 | 
				
			||||||
 | 
					        ChatColor nameColor = ChatColor.of("#" + Integer.toHexString(player.getName().hashCode()).substring(0, 6));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (player.getCustomName() != null) {
 | 
				
			||||||
 | 
					            return new ComponentBuilder()
 | 
				
			||||||
 | 
					                    .append("~" + player.getCustomName()).color(nameColor)
 | 
				
			||||||
 | 
					                    .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(player.getName())))
 | 
				
			||||||
 | 
					                    .create();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return new ComponentBuilder()
 | 
				
			||||||
 | 
					                    .append(player.getName()).color(nameColor)
 | 
				
			||||||
 | 
					                    .create();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static BaseComponent[] chatRoomPrefixShort(ChatRoom chatRoom) {
 | 
				
			||||||
 | 
					        ChatColor prefixColor = ChatColor.of(chatRoom.color.getColor().darker());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new ComponentBuilder(chatRoom.id.charAt(0) + " ").color(prefixColor)
 | 
				
			||||||
 | 
					                .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(chatRoom.getInfoComponent())))
 | 
				
			||||||
 | 
					                .create();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static BaseComponent[] formatChatRoom(ChatRoom chatRoom) {
 | 
				
			||||||
 | 
					        return new ComponentBuilder(chatRoom.id).color(chatRoom.color)
 | 
				
			||||||
 | 
					                .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(chatRoom.getInfoComponent())))
 | 
				
			||||||
 | 
					                .create();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3,13 +3,12 @@ package eu.m724.tweaks.chat;
 | 
				
			||||||
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 net.md_5.bungee.api.chat.HoverEvent;
 | 
					 | 
				
			||||||
import net.md_5.bungee.api.chat.hover.content.Text;
 | 
					 | 
				
			||||||
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.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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ChatListener implements Listener {
 | 
					public class ChatListener implements Listener {
 | 
				
			||||||
    private final ChatManager chatManager;
 | 
					    private final ChatManager chatManager;
 | 
				
			||||||
| 
						 | 
					@ -24,12 +23,37 @@ public class ChatListener implements Listener {
 | 
				
			||||||
        ChatRoom chatRoom = chatManager.getPlayerChatRoom(player);
 | 
					        ChatRoom chatRoom = chatManager.getPlayerChatRoom(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        BaseComponent[] component = new ComponentBuilder("Chat room: ").color(ChatColor.GOLD)
 | 
					        BaseComponent[] component = new ComponentBuilder("Chat room: ").color(ChatColor.GOLD)
 | 
				
			||||||
                .append(chatRoom.id).color(ChatColor.AQUA)
 | 
					                .append(ChatFormatUtils.formatChatRoom(chatRoom))
 | 
				
			||||||
                .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(chatRoom.getInfoComponent())))
 | 
					 | 
				
			||||||
                .create();
 | 
					                .create();
 | 
				
			||||||
        player.spigot().sendMessage(component);
 | 
					        player.spigot().sendMessage(component);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event.setJoinMessage(null); // TODO room messages
 | 
					        chatRoom.broadcast(
 | 
				
			||||||
 | 
					                new ComponentBuilder()
 | 
				
			||||||
 | 
					                        .append(ChatFormatUtils.chatRoomPrefixShort(chatRoom))
 | 
				
			||||||
 | 
					                        .append(ChatFormatUtils.formatPlayer(player))
 | 
				
			||||||
 | 
					                        .append(" has joined the server").color(ChatColor.GREEN)
 | 
				
			||||||
 | 
					                        .create()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // remove Minecraft join message
 | 
				
			||||||
 | 
					        event.setJoinMessage(null);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @EventHandler
 | 
				
			||||||
 | 
					    public void onPlayerQuit(PlayerQuitEvent event) {
 | 
				
			||||||
 | 
					        Player player = event.getPlayer();
 | 
				
			||||||
 | 
					        ChatRoom chatRoom = chatManager.removePlayer(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        chatRoom.broadcast(
 | 
				
			||||||
 | 
					                new ComponentBuilder()
 | 
				
			||||||
 | 
					                        .append(ChatFormatUtils.chatRoomPrefixShort(chatRoom))
 | 
				
			||||||
 | 
					                        .append(ChatFormatUtils.formatPlayer(player))
 | 
				
			||||||
 | 
					                        .append(" has left the server").color(ChatColor.RED)
 | 
				
			||||||
 | 
					                        .create()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // remove Minecraft quit message
 | 
				
			||||||
 | 
					        event.setQuitMessage(null);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
| 
						 | 
					@ -38,24 +62,14 @@ public class ChatListener implements Listener {
 | 
				
			||||||
        ChatRoom chatRoom = chatManager.getPlayerChatRoom(player);
 | 
					        ChatRoom chatRoom = chatManager.getPlayerChatRoom(player);
 | 
				
			||||||
        String message = event.getMessage();
 | 
					        String message = event.getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO move sending logic
 | 
					        ComponentBuilder builder = new ComponentBuilder();
 | 
				
			||||||
        ChatColor prefixColor = ChatColor.of(chatRoom.color.getColor().darker());
 | 
					        builder.append(ChatFormatUtils.chatRoomPrefixShort(chatRoom));
 | 
				
			||||||
        ChatColor nameColor = ChatColor.of("#" + Integer.toHexString(player.getName().hashCode()).substring(0, 6));
 | 
					        builder.append(ChatFormatUtils.formatPlayer(player)).append(": ");
 | 
				
			||||||
 | 
					        builder.append(message).color(chatRoom.color);
 | 
				
			||||||
        ComponentBuilder builder = new ComponentBuilder(chatRoom.id.charAt(0) + " ").color(prefixColor)
 | 
					 | 
				
			||||||
                .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(chatRoom.getInfoComponent())));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (player.getCustomName() != null) {
 | 
					 | 
				
			||||||
            builder = builder.append("~" + player.getCustomName() + ": ").color(nameColor)
 | 
					 | 
				
			||||||
                    .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(chatRoom.getInfoComponent())));
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            builder = builder.append(player.getName() + ": ").color(nameColor);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        builder = builder.append(message).color(chatRoom.color);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        chatRoom.broadcast(builder.create());
 | 
					        chatRoom.broadcast(builder.create());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // remove the original message
 | 
				
			||||||
        event.setCancelled(true);
 | 
					        event.setCancelled(true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,7 @@
 | 
				
			||||||
package eu.m724.tweaks.chat;
 | 
					package eu.m724.tweaks.chat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import net.md_5.bungee.api.ChatColor;
 | 
				
			||||||
 | 
					import net.md_5.bungee.api.chat.ComponentBuilder;
 | 
				
			||||||
import org.bukkit.NamespacedKey;
 | 
					import org.bukkit.NamespacedKey;
 | 
				
			||||||
import org.bukkit.OfflinePlayer;
 | 
					import org.bukkit.OfflinePlayer;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
| 
						 | 
					@ -27,6 +29,18 @@ public class ChatManager {
 | 
				
			||||||
        plugin.getServer().getPluginManager().registerEvents(new ChatListener(this), plugin);
 | 
					        plugin.getServer().getPluginManager().registerEvents(new ChatListener(this), plugin);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * removes player from the server and their chatroom
 | 
				
			||||||
 | 
					     * @param player the player
 | 
				
			||||||
 | 
					     * @return the chatroom the player was removed from
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public ChatRoom removePlayer(Player player) {
 | 
				
			||||||
 | 
					        ChatRoom chatRoom = playerMap.remove(player);
 | 
				
			||||||
 | 
					        chatRoom.players.remove(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return chatRoom;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get a chat room by id.<br>
 | 
					     * Get a chat room by id.<br>
 | 
				
			||||||
     * If the chat room is not loaded, it's loaded.
 | 
					     * If the chat room is not loaded, it's loaded.
 | 
				
			||||||
| 
						 | 
					@ -59,6 +73,22 @@ public class ChatManager {
 | 
				
			||||||
        player.getPersistentDataContainer().set(chatRoomKey, PersistentDataType.STRING, chatRoom.id);
 | 
					        player.getPersistentDataContainer().set(chatRoomKey, PersistentDataType.STRING, chatRoom.id);
 | 
				
			||||||
        playerMap.put(player, chatRoom);
 | 
					        playerMap.put(player, chatRoom);
 | 
				
			||||||
        chatRoom.players.add(player);
 | 
					        chatRoom.players.add(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        chatRoom.broadcast(
 | 
				
			||||||
 | 
					                new ComponentBuilder()
 | 
				
			||||||
 | 
					                        .append(ChatFormatUtils.chatRoomPrefixShort(chatRoom))
 | 
				
			||||||
 | 
					                        .append(ChatFormatUtils.formatPlayer(player))
 | 
				
			||||||
 | 
					                        .append(" has left the chat room").color(ChatColor.RED)
 | 
				
			||||||
 | 
					                        .create()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        chatRoom.broadcast(
 | 
				
			||||||
 | 
					                new ComponentBuilder()
 | 
				
			||||||
 | 
					                        .append(ChatFormatUtils.chatRoomPrefixShort(chatRoom))
 | 
				
			||||||
 | 
					                        .append(ChatFormatUtils.formatPlayer(player))
 | 
				
			||||||
 | 
					                        .append(" has joined the chat room").color(ChatColor.GREEN)
 | 
				
			||||||
 | 
					                        .create()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					@ -123,6 +153,14 @@ public class ChatManager {
 | 
				
			||||||
        ChatRoomLoader.save(plugin, chatRoom);
 | 
					        ChatRoomLoader.save(plugin, chatRoom);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void deleteChatRoom(ChatRoom chatRoom) {
 | 
				
			||||||
 | 
					        roomIdMap.remove(chatRoom.id);
 | 
				
			||||||
 | 
					        ChatRoomLoader.getFile(plugin, chatRoom.id).delete();
 | 
				
			||||||
 | 
					        chatRoom.players.forEach(player -> {
 | 
				
			||||||
 | 
					            setPlayerChatRoom(getById("global"), player);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * If an ID is too short, too long, wrong composition, etc.
 | 
					     * If an ID is too short, too long, wrong composition, etc.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,6 @@ public class ChatRoom {
 | 
				
			||||||
        this.owner = owner;
 | 
					        this.owner = owner;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO not recompute every time
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @return A nicely formatted text block with info such as room id, owner, online, etc.
 | 
					     * @return A nicely formatted text block with info such as room id, owner, online, etc.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
| 
						 | 
					@ -46,7 +45,7 @@ public class ChatRoom {
 | 
				
			||||||
            builder = builder.append(playersList.removeFirst().getName()).color(ChatColor.GRAY);
 | 
					            builder = builder.append(playersList.removeFirst().getName()).color(ChatColor.GRAY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (Player player : playersList) {
 | 
					            for (Player player : playersList) {
 | 
				
			||||||
                builder = builder.append(", ").color(ChatColor.GRAY)
 | 
					                builder = builder.append(", ").color(ChatColor.GREEN)
 | 
				
			||||||
                        .append(player.getName()).color(ChatColor.AQUA);
 | 
					                        .append(player.getName()).color(ChatColor.AQUA);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,13 +12,18 @@ import java.nio.file.Paths;
 | 
				
			||||||
import java.util.UUID;
 | 
					import java.util.UUID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ChatRoomLoader {
 | 
					public class ChatRoomLoader {
 | 
				
			||||||
    private static File getFile(Plugin plugin, String id) {
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the file of persistent storage of a chat room
 | 
				
			||||||
 | 
					     * @return the file or null if ID is invalid
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static File getFile(Plugin plugin, String id) {
 | 
				
			||||||
        Path chatRoomsPath = Paths.get(plugin.getDataFolder().getPath(), "rooms");
 | 
					        Path chatRoomsPath = Paths.get(plugin.getDataFolder().getPath(), "rooms");
 | 
				
			||||||
        chatRoomsPath.toFile().mkdirs();
 | 
					        chatRoomsPath.toFile().mkdirs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO sanitize
 | 
					        if (validateId(id) != 0)
 | 
				
			||||||
        File chatRoomFile = Paths.get(chatRoomsPath.toFile().getPath(), id + ".yml").toFile();
 | 
					            throw new RuntimeException("Invalid id: " + id);
 | 
				
			||||||
        return chatRoomFile;
 | 
					
 | 
				
			||||||
 | 
					        return Paths.get(chatRoomsPath.toFile().getPath(), id + ".yml").toFile();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@ public class DoorListener implements Listener {
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
    public void onBlockDamage(BlockDamageEvent event) {
 | 
					    public void onBlockDamage(BlockDamageEvent event) {
 | 
				
			||||||
        Block block = event.getBlock();
 | 
					        Block block = event.getBlock();
 | 
				
			||||||
        if (!(block.getBlockData() instanceof Door door)) return;
 | 
					        if (!(block.getBlockData() instanceof Door)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        World world = block.getLocation().getWorld();
 | 
					        World world = block.getLocation().getWorld();
 | 
				
			||||||
        Player player = event.getPlayer();
 | 
					        Player player = event.getPlayer();
 | 
				
			||||||
| 
						 | 
					@ -41,11 +41,10 @@ public class DoorListener implements Listener {
 | 
				
			||||||
            pitch = ThreadLocalRandom.current().nextFloat(0.5f, 0.7f);
 | 
					            pitch = ThreadLocalRandom.current().nextFloat(0.5f, 0.7f);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        PotionEffect weakness = player.getPotionEffect(PotionEffectType.WEAKNESS);
 | 
					 | 
				
			||||||
        PotionEffect fatigue = player.getPotionEffect(PotionEffectType.MINING_FATIGUE);
 | 
					        PotionEffect fatigue = player.getPotionEffect(PotionEffectType.MINING_FATIGUE);
 | 
				
			||||||
        int level = (weakness != null ? weakness.getAmplifier() : 0) + (fatigue != null ? fatigue.getAmplifier() : 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (weakness != null || fatigue != null) {
 | 
					        if (fatigue != null) {
 | 
				
			||||||
 | 
					            int level = fatigue.getAmplifier();
 | 
				
			||||||
            volume /= level / 3f;
 | 
					            volume /= level / 3f;
 | 
				
			||||||
            pitch /= level;
 | 
					            pitch /= level;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -53,7 +52,7 @@ public class DoorListener implements Listener {
 | 
				
			||||||
        volume *= (float) ((10.0 - Math.min(distance - 2, 10.0)) / 10.0);
 | 
					        volume *= (float) ((10.0 - Math.min(distance - 2, 10.0)) / 10.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        world.playSound(hitLocation, sound, volume, pitch);
 | 
					        world.playSound(hitLocation, sound, volume, pitch);
 | 
				
			||||||
        world.spawnParticle(Particle.BLOCK, hitLocation, (int) (10 * volume), door);
 | 
					        //world.spawnParticle(Particle.BLOCK, hitLocation, (int) (10 * volume), door);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,6 @@ public class MsptChecker extends BukkitRunnable {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void init(Plugin plugin) {
 | 
					    public void init(Plugin plugin) {
 | 
				
			||||||
        this.runTaskTimerAsynchronously(plugin, 0, 100); // 5 secs
 | 
					        this.runTaskTimer(plugin, 0, 100); // 5 secs
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,6 @@ import java.util.concurrent.ConcurrentHashMap;
 | 
				
			||||||
public class PingChecker extends BukkitRunnable {
 | 
					public class PingChecker extends BukkitRunnable {
 | 
				
			||||||
    private final Plugin plugin;
 | 
					    private final Plugin plugin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO concurrnet too?
 | 
					 | 
				
			||||||
    // this is in nanoseconds
 | 
					    // this is in nanoseconds
 | 
				
			||||||
    private final Map<Player, Long> pending = new ConcurrentHashMap<>();
 | 
					    private final Map<Player, Long> pending = new ConcurrentHashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,8 +38,13 @@ public class PingChecker extends BukkitRunnable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    long start = pending.remove(player);
 | 
					                    long start = pending.remove(player);
 | 
				
			||||||
                    PlayerPing.pings.put(player, System.nanoTime() - start);
 | 
					                    PlayerPing.pings.put(player, System.nanoTime() - start);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // gotta cancel because the server will kick
 | 
					                    // gotta cancel because the server will kick
 | 
				
			||||||
 | 
					                    if (!PlayerPing.kickQueue.contains(player)) {
 | 
				
			||||||
                        event.setCancelled(true);
 | 
					                        event.setCancelled(true);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        PlayerPing.kickQueue.remove(player);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
| 
						 | 
					@ -52,7 +56,8 @@ public class PingChecker extends BukkitRunnable {
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void run() {
 | 
					    public void run() {
 | 
				
			||||||
        plugin.getServer().getOnlinePlayers().forEach(player -> {
 | 
					        plugin.getServer().getOnlinePlayers().forEach(player -> {
 | 
				
			||||||
            if (pending.containsKey(player)) return;
 | 
					            // 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
 | 
					            pending.put(player, System.nanoTime()); // here or at the bottom? probably doesn't matter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PacketContainer packet = new PacketContainer(PacketType.Play.Server.COOKIE_REQUEST);
 | 
					            PacketContainer packet = new PacketContainer(PacketType.Play.Server.COOKIE_REQUEST);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@ package eu.m724.tweaks.ping;
 | 
				
			||||||
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.Bukkit;
 | 
				
			||||||
import org.bukkit.command.Command;
 | 
					import org.bukkit.command.Command;
 | 
				
			||||||
import org.bukkit.command.CommandExecutor;
 | 
					import org.bukkit.command.CommandExecutor;
 | 
				
			||||||
import org.bukkit.command.CommandSender;
 | 
					import org.bukkit.command.CommandSender;
 | 
				
			||||||
| 
						 | 
					@ -18,6 +19,25 @@ public class PingCommands implements CommandExecutor {
 | 
				
			||||||
                    .append("%.2fms".formatted(PlayerPing.getPingMillis(player))).color(ChatColor.AQUA)
 | 
					                    .append("%.2fms".formatted(PlayerPing.getPingMillis(player))).color(ChatColor.AQUA)
 | 
				
			||||||
                    .create();
 | 
					                    .create();
 | 
				
			||||||
            player.spigot().sendMessage(component);
 | 
					            player.spigot().sendMessage(component);
 | 
				
			||||||
 | 
					        } else if (command.getName().equals("dkick")) {
 | 
				
			||||||
 | 
					            if (args.length == 0) {
 | 
				
			||||||
 | 
					                sender.sendMessage("Include one or more player names");
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                for (String name : args) {
 | 
				
			||||||
 | 
					                    Player player = Bukkit.getPlayer(name);
 | 
				
			||||||
 | 
					                    if (player == null) {
 | 
				
			||||||
 | 
					                        sender.sendMessage("Player %s is not online".formatted(name));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (PlayerPing.kick(player)) {
 | 
				
			||||||
 | 
					                        if (player.getName().equals(sender.getName())) {
 | 
				
			||||||
 | 
					                            sender.sendMessage("Kicking yourself? Very well");
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        sender.sendMessage("Player %s will be kicked shortly".formatted(name));
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        sender.sendMessage("Player %s is already queued".formatted(name));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,14 +3,16 @@ package eu.m724.tweaks.ping;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					import java.util.Set;
 | 
				
			||||||
import java.util.concurrent.ConcurrentHashMap;
 | 
					import java.util.concurrent.ConcurrentHashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class PlayerPing {
 | 
					public class PlayerPing {
 | 
				
			||||||
    // TODO concurrnet?
 | 
					 | 
				
			||||||
    // in nanos
 | 
					    // in nanos
 | 
				
			||||||
    static final Map<Player, Long> pings = new ConcurrentHashMap<>();
 | 
					    static final Map<Player, Long> pings = new ConcurrentHashMap<>();
 | 
				
			||||||
    // nanos per tick
 | 
					    // nanos per tick
 | 
				
			||||||
    static long nspt = 0L;
 | 
					    static volatile long nspt = 0L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static final Set<Player> kickQueue = ConcurrentHashMap.newKeySet();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static long getPingNanos(Player player) {
 | 
					    public static long getPingNanos(Player player) {
 | 
				
			||||||
        return pings.getOrDefault(player, -1L);
 | 
					        return pings.getOrDefault(player, -1L);
 | 
				
			||||||
| 
						 | 
					@ -27,4 +29,8 @@ public class PlayerPing {
 | 
				
			||||||
    public static double getMillisPerTick() {
 | 
					    public static double getMillisPerTick() {
 | 
				
			||||||
        return nspt / 1000000.0; // a mil ns in ms
 | 
					        return nspt / 1000000.0; // a mil ns in ms
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static boolean kick(Player player) {
 | 
				
			||||||
 | 
					        return kickQueue.add(player);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,4 +15,11 @@ commands:
 | 
				
			||||||
    aliases: [cm, crm]
 | 
					    aliases: [cm, crm]
 | 
				
			||||||
  ping:
 | 
					  ping:
 | 
				
			||||||
    description: Your ping
 | 
					    description: Your ping
 | 
				
			||||||
 | 
					  dkick:
 | 
				
			||||||
 | 
					    description: Kick a player discreetly
 | 
				
			||||||
 | 
					    permission: tweaks724.dkick
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					permissions:
 | 
				
			||||||
 | 
					  tweaks724.dkick:
 | 
				
			||||||
 | 
					    default: op
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue