Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
769dfc3f8e | ||
|
|
8c061a057c | ||
|
|
e41a8e3db5 | ||
|
|
1fc0538ff4 | ||
|
|
fff868cf25 | ||
|
|
51b91b3c3d | ||
|
|
a20ed832f4 | ||
|
|
4ebbdc1c64 | ||
|
|
f0eb998f23 | ||
|
|
f1590c5098 | ||
|
|
30aeb8882b | ||
|
|
8b2803d752 | ||
|
|
6d2c5907c1 | ||
|
|
a5a81f2360 | ||
|
|
f14a1660b5 | ||
|
|
f07f3edc3b | ||
|
|
c18118f846 | ||
|
|
f1e6291e76 | ||
|
|
97d28fe0f0 | ||
|
|
7093fa2761 | ||
|
|
ce68890877 | ||
|
|
3a71045feb | ||
|
|
4db713d93b | ||
|
|
910179326a | ||
|
|
856c6decb2 | ||
|
|
d4c8b36ac6 | ||
|
|
0318246403 | ||
|
|
b38e62b138 | ||
|
|
bd62322adf | ||
|
|
803b49c2ac | ||
|
|
68c749c9d2 | ||
|
|
27def17f8a | ||
|
|
2b27cbbf64 | ||
|
|
39a5fdb611 | ||
|
|
7e961dc8ee | ||
|
|
ccbe90f7ee | ||
|
|
ce6da93c57 | ||
|
|
2e8379dec9 |
No files matched your search
@@ -1,38 +0,0 @@
|
||||
name: Build v2
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ v2 ]
|
||||
pull_request:
|
||||
branches: [ v2 ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
name: Checkout repo
|
||||
|
||||
- name: Set up JDK 17 (LTS)
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'adopt'
|
||||
cache: maven
|
||||
|
||||
- name: Build with Maven
|
||||
run: mvn install --file pom.xml
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
name: Upload Artifact
|
||||
with:
|
||||
name: ChatItem.jar
|
||||
path: target/ChatItem-*.jar
|
||||
- name: Send file README.md to discord channel
|
||||
uses: sinshutu/upload-to-discord@master
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
with:
|
||||
args: target/ChatItem-*.jar
|
||||
@@ -1,9 +1,4 @@
|
||||
.idea/
|
||||
src/test/
|
||||
bin/
|
||||
target/
|
||||
*.iml
|
||||
dependency-reduced-pom.xml
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
+1
-2
@@ -1,2 +1 @@
|
||||
language: java
|
||||
script: "mvn clean package -DskipTests"
|
||||
language: java
|
||||
@@ -1,4 +1,4 @@
|
||||
# ChatItem [](https://travis-ci.org/dadus33/ChatItem) [](https://discord.gg/eQJbVJt)
|
||||
# ChatItem [](https://travis-ci.org/dadus33/ChatItem)
|
||||
The official repository of the ChatItem Spigot/Bukkit plugin.
|
||||
# Building
|
||||
Building this is simple as we use Maven.
|
||||
|
||||
@@ -5,126 +5,72 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>me.dadus33</groupId>
|
||||
<artifactId>chatitem</artifactId>
|
||||
<version>2.2</version>
|
||||
<artifactId>ChatItem</artifactId>
|
||||
<version>1.2.2</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>Bungeecord</id>
|
||||
<url>https://repo.md-5.net/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
<id>dmulloy2-repo</id>
|
||||
<url>http://repo.dmulloy2.net/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>lang-utils-repo</id>
|
||||
<url>https://raw.github.com/MascusJeoraly/LanguageUtils/mvn-repo/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>protocollib-repo</id>
|
||||
<url>https://repo.dmulloy2.net/nexus/repository/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>viaversion-repo</id>
|
||||
<url>https://repo.viaversion.com</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>elikill-repo</id>
|
||||
<url>https://repo.eliapp.fr:8081/repository/internal/</url>
|
||||
<id>Plugin Metrics</id>
|
||||
<url>http://repo.mcstats.org/content/repositories/public</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.17-R0.1-SNAPSHOT</version>
|
||||
<version>1.10-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>minecraft-server</artifactId>
|
||||
<version>1.7.10</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.10-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mcstats.bukkit</groupId>
|
||||
<artifactId>metrics-lite</artifactId>
|
||||
<version>R8-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.meowj</groupId>
|
||||
<artifactId>LangUtils</artifactId>
|
||||
<version>1.9</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>4.7.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ProtocolSupport</groupId>
|
||||
<artifactId>ProtocolSupport</artifactId>
|
||||
<version>f34959c331</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.53.Final</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.GeyserMC</groupId>
|
||||
<artifactId>opennbt</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.majek</groupId>
|
||||
<artifactId>HexNicks</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-api</artifactId>
|
||||
<version>4.9.3</version>
|
||||
<version>2.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>ChatItem-${project.version}</finalName>
|
||||
<directory>./target</directory>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -144,8 +90,8 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
@@ -159,7 +105,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<version>2.4.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
@@ -167,20 +113,17 @@
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>com.google.gson</pattern>
|
||||
<shadedPattern>me.dadus33.gson</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<outputDirectory>${export_dir}</outputDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
@@ -1,186 +1,117 @@
|
||||
package me.dadus33.chatitem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import me.dadus33.chatitem.chatmanager.ChatManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
|
||||
import me.dadus33.chatitem.chatmanager.v2.ChatListenerChatManager;
|
||||
import me.dadus33.chatitem.commands.CIReloadCommand;
|
||||
import me.dadus33.chatitem.commands.ChatItemCommand;
|
||||
import com.comphenix.protocol.AsynchronousManager;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.async.AsyncListenerHandler;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import me.dadus33.chatitem.commands.CIReload;
|
||||
import me.dadus33.chatitem.filters.Log4jFilter;
|
||||
import me.dadus33.chatitem.itemnamer.NamerManager;
|
||||
import me.dadus33.chatitem.listeners.InventoryListener;
|
||||
import me.dadus33.chatitem.listeners.JoinListener;
|
||||
import me.dadus33.chatitem.playernamer.PlayerNamerManager;
|
||||
import me.dadus33.chatitem.utils.SemVer;
|
||||
import me.dadus33.chatitem.json.JSONManipulator;
|
||||
import me.dadus33.chatitem.json.JSONManipulatorCurrent;
|
||||
import me.dadus33.chatitem.listeners.ChatEventListener;
|
||||
import me.dadus33.chatitem.listeners.ChatPacketListener;
|
||||
import me.dadus33.chatitem.utils.General;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
import me.dadus33.chatitem.utils.Utils;
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.mcstats.MetricsLite;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ChatItem extends JavaPlugin {
|
||||
|
||||
public final static int CFG_VER = 13;
|
||||
public final static int CFG_VER = 4;
|
||||
private static ChatItem instance;
|
||||
private ChatEventListener chatEventListener;
|
||||
private Log4jFilter filter;
|
||||
private Storage storage;
|
||||
private boolean hasNewVersion = false;
|
||||
private List<ChatManager> chatManager = new ArrayList<>();
|
||||
private ProtocolManager pm;
|
||||
private ChatPacketListener listener;
|
||||
private static JSONManipulator manip;
|
||||
public static boolean post17 = false;
|
||||
|
||||
private void chooseManagers() {
|
||||
this.chatManager.forEach((cm) -> cm.unload(this));
|
||||
this.chatManager.clear();
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
String managerName = getStorage().MANAGER;
|
||||
if(managerName.equalsIgnoreCase("both")) {
|
||||
this.chatManager.add(new PacketEditingChatManager(this));
|
||||
this.chatManager.add(new ChatListenerChatManager(this));
|
||||
getLogger().info("Manager automatically choosed: " + getVisualChatManagers());
|
||||
} else if(managerName.equalsIgnoreCase("auto")) {
|
||||
if(getPluginThatRequirePacket().stream().map(pm::getPlugin).filter(Objects::nonNull).count() > 0 && Version.getVersion().isNewerThan(Version.V1_7))
|
||||
this.chatManager.add(new PacketEditingChatManager(this));
|
||||
else
|
||||
this.chatManager.add(new ChatListenerChatManager(this));
|
||||
getLogger().info("Manager automatically choosed: " + getVisualChatManagers());
|
||||
} else {
|
||||
if(managerName.equalsIgnoreCase("packet")) {
|
||||
this.chatManager.add(new PacketEditingChatManager(this));
|
||||
getLogger().info("Manager choosed: " + getVisualChatManagers());
|
||||
} else if(managerName.equalsIgnoreCase("chat")) {
|
||||
this.chatManager.add(new ChatListenerChatManager(this));
|
||||
getLogger().info("Manager choosed: " + getVisualChatManagers());
|
||||
} else {
|
||||
getLogger().severe("----- WARN -----");
|
||||
getLogger().severe("Failed to find manager: " + managerName + ".");
|
||||
getLogger().severe("Please reset your config and/or check wiki for more informations");
|
||||
getLogger().severe("Using default manager: chat.");
|
||||
getLogger().severe("----- WARN -----");
|
||||
this.chatManager.add(new ChatListenerChatManager(this));
|
||||
}
|
||||
}
|
||||
this.chatManager.forEach((cm) -> cm.load(this, getStorage()));
|
||||
|
||||
NamerManager.load(this);
|
||||
PlayerNamerManager.load(this);
|
||||
}
|
||||
|
||||
private List<String> getPluginThatRequirePacket(){
|
||||
return Arrays.asList("DeluxeChat", "HexNicks", "VentureChat");
|
||||
}
|
||||
|
||||
public static void reload(CommandSender sender) {
|
||||
ChatItem pl = getInstance();
|
||||
if(pl.getConfig() == null || pl.getConfig().getKeys(false).isEmpty())
|
||||
pl.saveDefaultConfig();
|
||||
pl.reloadConfig();
|
||||
String oldChatManager = pl.storage.MANAGER;
|
||||
pl.storage = new Storage(pl.getConfig());
|
||||
pl.chooseManagers();
|
||||
pl.filter.setStorage(pl.storage);
|
||||
if (!pl.storage.RELOAD_MESSAGE.isEmpty())
|
||||
sender.sendMessage(pl.storage.RELOAD_MESSAGE);
|
||||
if(!oldChatManager.equalsIgnoreCase(pl.storage.MANAGER))
|
||||
sender.sendMessage(ChatColor.GOLD + "Changing the manager with command reloading CAN produce issue. It's mostly suggested to restart after finding the better manager for you.");
|
||||
ChatItem obj = getInstance();
|
||||
obj.pm = ProtocolLibrary.getProtocolManager();
|
||||
obj.saveDefaultConfig();
|
||||
obj.reloadConfig();
|
||||
obj.storage = new Storage(obj.getConfig());
|
||||
General.init(obj.storage);
|
||||
General.checkConfigVersion();
|
||||
obj.listener.setStorage(obj.storage);
|
||||
obj.chatEventListener.setStorage(obj.storage);
|
||||
obj.filter.setStorage(obj.storage);
|
||||
if (!obj.storage.RELOAD_MESSAGE.isEmpty())
|
||||
sender.sendMessage(obj.storage.RELOAD_MESSAGE);
|
||||
}
|
||||
|
||||
public static ChatItem getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
//Save the instance (we're basically a singleton)
|
||||
instance = this;
|
||||
|
||||
//Load ProtocolManager
|
||||
//pm = ProtocolLibrary.getProtocolManager();
|
||||
|
||||
//Load config
|
||||
pm = ProtocolLibrary.getProtocolManager();
|
||||
saveDefaultConfig();
|
||||
storage = new Storage(getConfig());
|
||||
|
||||
//We halt the use of this system for now, until we can solve the infamous getProtocolVersion issue
|
||||
//Till then, users of both ViaVersion and ProtocolSupport should do just fine
|
||||
/*if(!protocolSupport && !viaVersion) {
|
||||
//We only implement our own way of getting protocol versions if we have no other choice
|
||||
pm.addPacketListener(new HandshakeListener(this, ListenerPriority.MONITOR, PacketType.Handshake.Client.SET_PROTOCOL));
|
||||
}*/
|
||||
General.init(storage);
|
||||
General.checkConfigVersion();
|
||||
listener = new ChatPacketListener(this, ListenerPriority.HIGHEST, storage, PacketType.Play.Server.CHAT);
|
||||
AsynchronousManager am = pm.getAsynchronousManager();
|
||||
AsyncListenerHandler packetListenerAsyncThread = am.registerAsyncHandler(listener);
|
||||
packetListenerAsyncThread.start();
|
||||
CIReload rld = new CIReload();
|
||||
Bukkit.getPluginCommand("cireload").setExecutor(rld);
|
||||
chatEventListener = new ChatEventListener(storage);
|
||||
Bukkit.getPluginManager().registerEvents(chatEventListener, this);
|
||||
if(isMc18OrLater()) {
|
||||
post17 = true;
|
||||
}
|
||||
manip = new JSONManipulatorCurrent();
|
||||
|
||||
//Commands
|
||||
loadCommand(getCommand("cireload"), new CIReloadCommand());
|
||||
loadCommand(getCommand("chatitem"), new ChatItemCommand());
|
||||
|
||||
// events
|
||||
getServer().getPluginManager().registerEvents(new JoinListener(), this);
|
||||
getServer().getPluginManager().registerEvents(new InventoryListener(), this);
|
||||
|
||||
chooseManagers();
|
||||
|
||||
//Initialize Log4J filter (remove ugly console messages)
|
||||
try {
|
||||
MetricsLite metrics = new MetricsLite(this);
|
||||
metrics.start();
|
||||
} catch (IOException e) {
|
||||
getLogger().log(Level.WARNING, ChatColor.RED + "Couldn't start metrics!");
|
||||
}
|
||||
filter = new Log4jFilter(storage);
|
||||
|
||||
if(storage.CHECK_UPDATE) {
|
||||
getServer().getScheduler().runTaskAsynchronously(this, () -> {
|
||||
String urlName = "https://api.spigotmc.org/legacy/update.php?resource=19064";
|
||||
String content = Utils.getFromURL(urlName);
|
||||
if(Strings.isNullOrEmpty(content))
|
||||
return;
|
||||
SemVer currentVersion = SemVer.parse(getDescription().getVersion());
|
||||
if (currentVersion == null)
|
||||
return;
|
||||
SemVer latestVersion = SemVer.parse(content);
|
||||
if (latestVersion != null && latestVersion.isNewerThan(currentVersion)) {
|
||||
hasNewVersion = !content.equalsIgnoreCase(getDescription().getVersion());
|
||||
if(hasNewVersion) {
|
||||
getLogger().info(storage.JOIN_UPDATE_MESSAGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void onDisable() {
|
||||
instance = null;
|
||||
post17 = false;
|
||||
}
|
||||
|
||||
private boolean isMc18OrLater(){
|
||||
switch(getVersion(Bukkit.getServer())){
|
||||
case "v1_8_R1": return true;
|
||||
case "v1_8_R2": return true;
|
||||
case "v1_8_R3": return true;
|
||||
case "v1_9_R1": return true;
|
||||
case "v1_9_R2": return true;
|
||||
case "v1_10_R1": return true;
|
||||
case "v1_10_R2": return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void loadCommand(PluginCommand cmd, Object obj) {
|
||||
if(obj instanceof CommandExecutor)
|
||||
cmd.setExecutor((CommandExecutor) obj);
|
||||
if(obj instanceof TabCompleter)
|
||||
cmd.setTabCompleter((TabCompleter) obj);
|
||||
}
|
||||
|
||||
public Storage getStorage() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
public List<ChatManager> getChatManager() {
|
||||
return chatManager;
|
||||
}
|
||||
|
||||
public String getVisualChatManagers() {
|
||||
StringJoiner sj = new StringJoiner(", ");
|
||||
for(ChatManager cm : chatManager) {
|
||||
sj.add(cm.getName() + " (" + cm.getId() + ")");
|
||||
}
|
||||
return sj.toString();
|
||||
|
||||
|
||||
private static String getVersion(Server server) {
|
||||
final String packageName = server.getClass().getPackage().getName();
|
||||
|
||||
return packageName.substring(packageName.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
public boolean isHasNewVersion() {
|
||||
return hasNewVersion;
|
||||
}
|
||||
|
||||
public static void debug(String msg) {
|
||||
if(getInstance().getConfig().getBoolean("debug", false))
|
||||
getInstance().getLogger().info("[Debug] " + msg);
|
||||
|
||||
|
||||
public static JSONManipulator getManipulator(){
|
||||
return manip;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public abstract class ChatManager {
|
||||
|
||||
public final static char SEPARATOR = ((char) 0x0007);
|
||||
public final static String SEPARATOR_STR = "\\u0007";
|
||||
|
||||
protected Storage s;
|
||||
|
||||
public ChatManager() {
|
||||
|
||||
}
|
||||
|
||||
public abstract String getName();
|
||||
|
||||
public abstract String getId();
|
||||
|
||||
public Storage getStorage() {
|
||||
return s;
|
||||
}
|
||||
|
||||
public void load(ChatItem pl, Storage s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public abstract void unload(ChatItem pl);
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.ChatManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulator;
|
||||
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulatorCurrent;
|
||||
import me.dadus33.chatitem.chatmanager.v1.listeners.ChatEventListener;
|
||||
import me.dadus33.chatitem.chatmanager.v1.listeners.ChatPacketManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacketManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.IPlayerVersion;
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.hooks.DefaultVersionHook;
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.hooks.ProtocolSupportHook;
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.hooks.ViaVersionHook;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public class PacketEditingChatManager extends ChatManager {
|
||||
|
||||
private final JSONManipulatorCurrent jsonManipulator;
|
||||
private boolean baseComponentAvailable = true;
|
||||
private final ChatItemPacketManager packetManager;
|
||||
private final ChatEventListener chatEventListener;
|
||||
private final ChatPacketManager chatPacketManager;
|
||||
private IPlayerVersion playerVersionAdapter;
|
||||
|
||||
public PacketEditingChatManager(ChatItem pl) {
|
||||
jsonManipulator = new JSONManipulatorCurrent();
|
||||
packetManager = new ChatItemPacketManager(pl);
|
||||
chatEventListener = new ChatEventListener(this);
|
||||
chatPacketManager = new ChatPacketManager(this);
|
||||
|
||||
//Check for existence of BaseComponent class (only on spigot)
|
||||
try {
|
||||
Class.forName("net.md_5.bungee.api.chat.BaseComponent");
|
||||
} catch (ClassNotFoundException e) {
|
||||
baseComponentAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "PacketEditing";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "packet";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ChatItem pl, Storage s) {
|
||||
super.load(pl, s);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(chatEventListener, pl);
|
||||
packetManager.getPacketManager().addHandler(chatPacketManager);
|
||||
|
||||
if(Bukkit.getPluginManager().getPlugin("ViaVersion") != null){
|
||||
playerVersionAdapter = new ViaVersionHook();
|
||||
pl.getLogger().info("Loading ViaVersion support ...");
|
||||
} else if(Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null){
|
||||
playerVersionAdapter = new ProtocolSupportHook();
|
||||
pl.getLogger().info("Loading ProtocolSupport support ...");
|
||||
} else {
|
||||
playerVersionAdapter = new DefaultVersionHook();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(ChatItem pl) {
|
||||
HandlerList.unregisterAll(chatEventListener);
|
||||
packetManager.getPacketManager().removeHandler(chatPacketManager);
|
||||
packetManager.getPacketManager().stop();
|
||||
}
|
||||
|
||||
public JSONManipulator getManipulator(){
|
||||
/*
|
||||
We used to have 2 kinds of JSONManipulators because of my bad understanding of the 1.7 way of parsing JSON chat
|
||||
The interface should however stay as there might be great changes in future versions in JSON parsing (most likely 1.13)
|
||||
*/
|
||||
return jsonManipulator;
|
||||
//We just return a new one whenever requested for the moment, should implement a cache of some sort some time though
|
||||
}
|
||||
|
||||
public IPlayerVersion getPlayerVersionAdapter() {
|
||||
return playerVersionAdapter;
|
||||
}
|
||||
|
||||
public boolean supportsChatComponentApi(){
|
||||
return baseComponentAvailable;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.json;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
|
||||
public interface JSONManipulator {
|
||||
|
||||
String parse(String json, List<String> replacements, ItemStack item, String repl, int protocol) throws Exception;
|
||||
String parseEmpty(String json, List<String> replacements, String repl, List<String> tooltip, Player sender);
|
||||
|
||||
}
|
||||
@@ -1,947 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.json;
|
||||
|
||||
import static me.dadus33.chatitem.utils.PacketUtils.getNmsClass;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.DoubleTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.FloatTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.LongTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ShortTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.v1.utils.Item;
|
||||
import me.dadus33.chatitem.chatmanager.v1.utils.ItemRewriter;
|
||||
import me.dadus33.chatitem.utils.PacketUtils;
|
||||
import me.dadus33.chatitem.utils.Reflect;
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class JSONManipulatorCurrent implements JSONManipulator {
|
||||
|
||||
private static final Class<?> CRAFT_ITEM_STACK_CLASS = PacketUtils.getObcClass("inventory.CraftItemStack");
|
||||
private static final Class<?> NBT_STRING = getNmsClass("NBTTagString", "nbt.");
|
||||
private static final Class<?> NBT_LIST = getNmsClass("NBTTagList", "nbt.");
|
||||
private static final Map<Class<?>, BiFunction<String, Object, Tag>> TYPES_TO_MC_NBT_TAGS = new HashMap<>();
|
||||
private static final Map<Class<?>, Function<String, Tag>> TYPES_TO_OPEN_NBT_TAGS = new HashMap<>();
|
||||
private static final List<Class<?>> NBT_BASE_CLASSES = new ArrayList<>();
|
||||
private static final List<Field> NBT_BASE_DATA_FIELD = new ArrayList<>();
|
||||
private static final Class<?> NMS_ITEM_STACK_CLASS = getNmsClass("ItemStack", "world.item.");
|
||||
private static final Method AS_NMS_COPY = Reflect.getMethod(CRAFT_ITEM_STACK_CLASS, "asNMSCopy", ItemStack.class);
|
||||
private static final Class<?> NBT_TAG_COMPOUND = getNmsClass("NBTTagCompound", "nbt.");
|
||||
private static final Method SAVE_NMS_ITEM_STACK_METHOD = Reflect.getMethod(NMS_ITEM_STACK_CLASS, NBT_TAG_COMPOUND,
|
||||
NBT_TAG_COMPOUND);
|
||||
private static final Field MAP = Reflect.getField(NBT_TAG_COMPOUND, "map", "x");
|
||||
private static final Field LIST_FIELD = Reflect.getField(NBT_LIST, "list", "c");
|
||||
|
||||
// Tags to be ignored. Currently it only contains tags from PortableHorses, but
|
||||
// feel free to submit a pull request to add tags from your plugins
|
||||
private static final List<String> IGNORED = Arrays.asList("horsetag", "phorse", "iscnameviz", "cname");
|
||||
|
||||
private static final ConcurrentHashMap<Map.Entry<Version, ItemStack>, JsonObject> STACKS = new ConcurrentHashMap<>();
|
||||
|
||||
static {
|
||||
NBT_BASE_CLASSES.add(getNmsClass("NBTTagByte", "nbt."));
|
||||
NBT_BASE_CLASSES.add(getNmsClass("NBTTagByteArray", "nbt."));
|
||||
NBT_BASE_CLASSES.add(getNmsClass("NBTTagDouble", "nbt."));
|
||||
NBT_BASE_CLASSES.add(getNmsClass("NBTTagFloat", "nbt."));
|
||||
NBT_BASE_CLASSES.add(getNmsClass("NBTTagInt", "nbt."));
|
||||
NBT_BASE_CLASSES.add(getNmsClass("NBTTagIntArray", "nbt."));
|
||||
NBT_BASE_CLASSES.add(getNmsClass("NBTTagLong", "nbt."));
|
||||
NBT_BASE_CLASSES.add(getNmsClass("NBTTagShort", "nbt."));
|
||||
|
||||
for (Class<?> NBT_BASE_CLASS : NBT_BASE_CLASSES) {
|
||||
NBT_BASE_DATA_FIELD.add(Reflect.getField(NBT_BASE_CLASS, "data", "c", "x"));
|
||||
}
|
||||
|
||||
// include NBT tags
|
||||
TYPES_TO_MC_NBT_TAGS.put(getNmsClass("NBTTagByte", "nbt."), (name, obj) -> new ByteTag(name, get(obj, "h")));
|
||||
TYPES_TO_MC_NBT_TAGS.put(getNmsClass("NBTTagByteArray", "nbt."), (name, obj) -> new ByteArrayTag(name, get(obj, "d")));
|
||||
TYPES_TO_MC_NBT_TAGS.put(getNmsClass("NBTTagDouble", "nbt."), (name, obj) -> new DoubleTag(name, get(obj, "i")));
|
||||
TYPES_TO_MC_NBT_TAGS.put(getNmsClass("NBTTagFloat", "nbt."), (name, obj) -> new FloatTag(name, get(obj, "j")));
|
||||
TYPES_TO_MC_NBT_TAGS.put(getNmsClass("NBTTagInt", "nbt."), (name, obj) -> new IntTag(name, get(obj, "f")));
|
||||
TYPES_TO_MC_NBT_TAGS.put(getNmsClass("NBTTagIntArray", "nbt."), (name, obj) -> new IntArrayTag(name, get(obj, "c")));
|
||||
TYPES_TO_MC_NBT_TAGS.put(getNmsClass("NBTTagLong", "nbt."), (name, obj) -> new LongTag(name, get(obj, "e")));
|
||||
TYPES_TO_MC_NBT_TAGS.put(getNmsClass("NBTTagShort", "nbt."), (name, obj) -> new ShortTag(name, get(obj, "g")));
|
||||
// now basic types
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(Byte.class, ByteTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(Byte[].class, ByteArrayTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(Double.class, DoubleTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(Float.class, FloatTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(Integer.class, IntTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(Integer[].class, IntArrayTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(Long.class, LongTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(Short.class, ShortTag::new);
|
||||
// Add the primitive types too, just in case
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(byte.class, ByteTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(byte[].class, ByteArrayTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(double.class, DoubleTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(float.class, FloatTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(int.class, IntTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(int[].class, IntArrayTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(long.class, LongTag::new);
|
||||
TYPES_TO_OPEN_NBT_TAGS.put(short.class, ShortTag::new);
|
||||
|
||||
}
|
||||
|
||||
public static <T> T get(Object obj, String methodName){
|
||||
try {
|
||||
return (T) obj.getClass().getDeclaredMethod(methodName).invoke(obj);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<String> replaces;
|
||||
private String rgx;
|
||||
private Version protocolVersion;
|
||||
private JsonObject itemTooltip;
|
||||
private JsonArray classicTooltip;
|
||||
private final JsonParser PARSER = new JsonParser();
|
||||
|
||||
public String parse(String json, List<String> replacements, ItemStack item, String replacement, int protocol)
|
||||
throws Exception {
|
||||
JsonObject obj = PARSER.parse(json).getAsJsonObject();
|
||||
JsonArray array = obj.getAsJsonArray("extra");
|
||||
replaces = replacements;
|
||||
String regex = "";
|
||||
for (int i = 0; i < replacements.size(); ++i) {
|
||||
if (replacements.size() == 1) {
|
||||
regex = Pattern.quote(replacements.get(0));
|
||||
break;
|
||||
}
|
||||
if (i == 0 || i + 1 == replacements.size()) {
|
||||
if (i == 0) {
|
||||
regex = "(" + Pattern.quote(replacements.get(i));
|
||||
} else {
|
||||
regex = regex.concat("|").concat(Pattern.quote(replacements.get(i))).concat(")");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
regex = regex.concat("|").concat(Pattern.quote(replacements.get(i)));
|
||||
}
|
||||
rgx = regex;
|
||||
JsonArray rep = new JsonArray();
|
||||
final AbstractMap.SimpleEntry<Version, ItemStack> p = new AbstractMap.SimpleEntry<>(
|
||||
protocolVersion = Version.getVersion(protocol), item);
|
||||
|
||||
if ((itemTooltip = STACKS.get(p)) == null) {
|
||||
JsonArray use = Translator.toJson(replacement); // We get the json representation of the old color
|
||||
// formatting method
|
||||
// There's no public clone method for JSONObjects so we need to parse them every time
|
||||
JsonObject hover = PARSER.parse("{\"action\":\"show_item\", \"value\": \"\"}").getAsJsonObject();
|
||||
|
||||
String jsonRep = stringifyItem(item); // Get the JSON representation of the item (well, not really JSON, but
|
||||
// rather a string representation of NBT data)
|
||||
hover.addProperty("value", jsonRep);
|
||||
|
||||
JsonObject wrapper = new JsonObject(); // Create a wrapper object for the whole array
|
||||
wrapper.addProperty("text", ""); // The text field is compulsory, even if it's empty
|
||||
wrapper.add("extra", use);
|
||||
wrapper.add("hoverEvent", hover);
|
||||
|
||||
itemTooltip = wrapper; // Save the tooltip for later use when we encounter a placeholder
|
||||
STACKS.put(p, itemTooltip); // Save it in the cache too so when parsing other packets with the same item
|
||||
// (and client version) we no longer have to create it again
|
||||
// We remove it later when no longer needed to save memory
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(ChatItem.getInstance(), () -> STACKS.remove(p), 100L);
|
||||
}
|
||||
|
||||
for (int i = 0; i < array.size(); ++i) {
|
||||
if (array.get(i).isJsonObject()) {
|
||||
JsonObject o = array.get(i).getAsJsonObject();
|
||||
boolean inside = false;
|
||||
for (String replace : replacements)
|
||||
if (o.toString().contains(replace)) {
|
||||
if (inside) {
|
||||
break;
|
||||
}
|
||||
inside = true;
|
||||
}
|
||||
JsonElement text = o.get("text");
|
||||
if (text == null) {
|
||||
JsonElement el = o.get("extra");
|
||||
if (el != null) {
|
||||
JsonArray jar = el.getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseArray(jar);
|
||||
o.add("extra", jar);
|
||||
} else {
|
||||
o.remove("extra");
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
if (text.getAsString().isEmpty()) {
|
||||
JsonElement el = o.get("extra");
|
||||
if (el != null) {
|
||||
JsonArray jar = el.getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseArray(jar);
|
||||
o.add("extra", jar);
|
||||
} else {
|
||||
o.remove("extra");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String msg = text.getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replacements) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(regex);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
String st = o.toString();
|
||||
JsonObject fix = PARSER.parse(st).getAsJsonObject();
|
||||
fix.addProperty("text", splits[j]);
|
||||
rep.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
rep.add(itemTooltip);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
rep.add(o);
|
||||
}
|
||||
} else {
|
||||
if (array.get(i).isJsonNull()) {
|
||||
continue;
|
||||
} else {
|
||||
if (array.get(i).isJsonArray()) {
|
||||
JsonArray jar = array.get(i).getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseArray(array.get(i).getAsJsonArray());
|
||||
rep.set(i, jar);
|
||||
}
|
||||
} else {
|
||||
|
||||
String msg = array.get(i).getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replacements) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(regex);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
JsonElement fix = new JsonPrimitive(splits[j]);
|
||||
rep.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
rep.add(itemTooltip);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
rep.add(array.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
obj.add("extra", rep);
|
||||
if (!obj.has("text")) {
|
||||
obj.addProperty("text", "");
|
||||
}
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseEmpty(String json, List<String> replacements, String repl, List<String> tooltip, Player sender) {
|
||||
JsonObject obj = PARSER.parse(json).getAsJsonObject();
|
||||
JsonArray array = obj.getAsJsonArray("extra");
|
||||
replaces = replacements;
|
||||
String regex = "";
|
||||
for (int i = 0; i < replacements.size(); ++i) {
|
||||
if (replacements.size() == 1) {
|
||||
regex = Pattern.quote(replacements.get(0));
|
||||
break;
|
||||
}
|
||||
if (i == 0 || i + 1 == replacements.size()) {
|
||||
if (i == 0) {
|
||||
regex = "(" + Pattern.quote(replacements.get(i));
|
||||
} else {
|
||||
regex = regex.concat("|").concat(Pattern.quote(replacements.get(i))).concat(")");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
regex = regex.concat("|").concat(Pattern.quote(replacements.get(i)));
|
||||
}
|
||||
rgx = regex;
|
||||
JsonArray rep = new JsonArray();
|
||||
JsonArray use = Translator
|
||||
.toJson(repl.replace("{name}", sender.getName()).replace("{display-name}", sender.getDisplayName()));
|
||||
JsonObject hover = PARSER.parse("{\"action\":\"show_text\", \"value\": \"\"}").getAsJsonObject();
|
||||
|
||||
StringBuilder oneLineTooltip = new StringBuilder("");
|
||||
int index = 0;
|
||||
for (String m : tooltip) {
|
||||
oneLineTooltip
|
||||
.append(m.replace("{name}", sender.getName()).replace("{display-name}", sender.getDisplayName()));
|
||||
++index;
|
||||
if (index != tooltip.size()) {
|
||||
oneLineTooltip.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
hover.add("value", new JsonPrimitive(oneLineTooltip.toString()));
|
||||
for (JsonElement ob : use)
|
||||
ob.getAsJsonObject().add("hoverEvent", hover);
|
||||
|
||||
classicTooltip = use;
|
||||
|
||||
for (int i = 0; i < array.size(); ++i) {
|
||||
if (array.get(i).isJsonObject()) {
|
||||
JsonObject o = array.get(i).getAsJsonObject();
|
||||
boolean inside = false;
|
||||
for (String replace : replacements)
|
||||
if (o.toString().contains(replace)) {
|
||||
if (inside) {
|
||||
break;
|
||||
}
|
||||
inside = true;
|
||||
}
|
||||
JsonElement text = o.get("text");
|
||||
if (text == null) {
|
||||
JsonElement el = o.get("extra");
|
||||
if (el != null) {
|
||||
JsonArray jar = el.getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseNoItemArray(jar);
|
||||
o.add("extra", jar);
|
||||
} else {
|
||||
o.remove("extra");
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
if (text.getAsString().isEmpty()) {
|
||||
JsonElement el = o.get("extra");
|
||||
if (el != null) {
|
||||
JsonArray jar = el.getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseNoItemArray(jar);
|
||||
o.add("extra", jar);
|
||||
} else {
|
||||
o.remove("extra");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String msg = text.getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replacements) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(regex);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
String st = o.toString();
|
||||
JsonObject fix = PARSER.parse(st).getAsJsonObject();
|
||||
fix.addProperty("text", splits[j]);
|
||||
rep.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
rep.addAll(use);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
rep.add(o);
|
||||
}
|
||||
} else {
|
||||
if (array.get(i).isJsonNull()) {
|
||||
continue;
|
||||
} else {
|
||||
if (array.get(i).isJsonArray()) {
|
||||
JsonArray jar = array.get(i).getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseNoItemArray(array.get(i).getAsJsonArray());
|
||||
rep.set(i, jar);
|
||||
}
|
||||
} else {
|
||||
|
||||
String msg = array.get(i).getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replacements) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(regex);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
JsonElement fix = new JsonPrimitive(splits[j]);
|
||||
rep.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
rep.addAll(use);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
rep.add(array.get(i));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
obj.add("extra", rep);
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
private JsonArray parseNoItemArray(JsonArray arr) {
|
||||
JsonArray replacer = new JsonArray();
|
||||
for (int i = 0; i < arr.size(); ++i) {
|
||||
if (arr.get(i).isJsonObject()) {
|
||||
JsonObject o = arr.get(i).getAsJsonObject();
|
||||
boolean inside = false;
|
||||
for (String replacement : replaces)
|
||||
if (o.toString().contains(replacement)) {
|
||||
if (inside) {
|
||||
break;
|
||||
}
|
||||
inside = true;
|
||||
}
|
||||
if (!inside) { // the placeholder we're looking for is not inside this element, so we continue
|
||||
// searching
|
||||
replacer.add(o);
|
||||
continue;
|
||||
}
|
||||
JsonElement text = o.get("text");
|
||||
if (text == null) {
|
||||
continue;
|
||||
}
|
||||
if (text.getAsString().isEmpty()) {
|
||||
JsonElement el = o.get("extra");
|
||||
if (el == null) {
|
||||
continue;
|
||||
}
|
||||
JsonArray jar = el.getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseNoItemArray(jar);
|
||||
o.add("extra", jar);
|
||||
} else {
|
||||
o.remove("extra");
|
||||
}
|
||||
}
|
||||
|
||||
String msg = text.getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replaces) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(rgx);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
String st = o.toString();
|
||||
JsonObject fix = PARSER.parse(st).getAsJsonObject();
|
||||
fix.addProperty("text", splits[j]);
|
||||
replacer.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
replacer.addAll(classicTooltip);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
replacer.add(o);
|
||||
}
|
||||
} else {
|
||||
if (arr.get(i).isJsonNull()) {
|
||||
continue;
|
||||
} else {
|
||||
if (arr.get(i).isJsonArray()) {
|
||||
JsonArray jar = arr.get(i).getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseNoItemArray(arr.get(i).getAsJsonArray());
|
||||
replacer.set(i, jar);
|
||||
}
|
||||
} else {
|
||||
String msg = arr.get(i).getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replaces) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(rgx);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
JsonElement fix = new JsonPrimitive(splits[j]);
|
||||
replacer.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
replacer.addAll(classicTooltip);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
replacer.add(arr.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return replacer;
|
||||
}
|
||||
|
||||
private JsonArray parseArray(JsonArray arr) {
|
||||
JsonArray replacer = new JsonArray();
|
||||
for (int i = 0; i < arr.size(); ++i) {
|
||||
if (arr.get(i).isJsonObject()) {
|
||||
JsonObject o = arr.get(i).getAsJsonObject();
|
||||
boolean inside = false;
|
||||
for (String replacement : replaces)
|
||||
if (o.toString().contains(replacement)) {
|
||||
if (inside) {
|
||||
break;
|
||||
}
|
||||
inside = true;
|
||||
}
|
||||
if (!inside) { // the placeholder we're looking for is not inside this element, so we continue
|
||||
// searching
|
||||
replacer.add(o);
|
||||
continue;
|
||||
}
|
||||
JsonElement text = o.get("text");
|
||||
if (text == null) {
|
||||
continue;
|
||||
}
|
||||
if (text.getAsString().isEmpty()) {
|
||||
JsonElement el = o.get("extra");
|
||||
if (el == null) {
|
||||
continue;
|
||||
}
|
||||
JsonArray jar = el.getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseArray(jar);
|
||||
o.add("extra", jar);
|
||||
} else {
|
||||
o.remove("extra");
|
||||
}
|
||||
}
|
||||
|
||||
String msg = text.getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replaces) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(rgx);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
String st = o.toString();
|
||||
JsonObject fix = PARSER.parse(st).getAsJsonObject();
|
||||
fix.addProperty("text", splits[j]);
|
||||
replacer.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
replacer.add(itemTooltip);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
replacer.add(o);
|
||||
}
|
||||
} else {
|
||||
if (arr.get(i).isJsonNull()) {
|
||||
continue;
|
||||
} else {
|
||||
if (arr.get(i).isJsonArray()) {
|
||||
JsonArray jar = arr.get(i).getAsJsonArray();
|
||||
if (jar.size() != 0) {
|
||||
jar = parseArray(arr.get(i).getAsJsonArray());
|
||||
replacer.set(i, jar);
|
||||
}
|
||||
} else {
|
||||
String msg = arr.get(i).getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replaces) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(rgx);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
JsonElement fix = new JsonPrimitive(splits[j]);
|
||||
replacer.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
replacer.add(itemTooltip);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
replacer.add(arr.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return replacer;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private Item toItem(ItemStack is) throws Exception {
|
||||
CompoundTag tag = new CompoundTag("tag");
|
||||
|
||||
Object nmsStack = AS_NMS_COPY.invoke(null, is);
|
||||
Object nmsTag = NBT_TAG_COMPOUND.newInstance();
|
||||
SAVE_NMS_ITEM_STACK_METHOD.invoke(nmsStack, nmsTag);
|
||||
Map<String, Object> nmsMap = (Map<String, Object>) MAP.get(nmsTag);
|
||||
String id = nmsMap.get("id").toString().replace("\"", "");
|
||||
Object realTag = nmsMap.get("tag");
|
||||
if (NBT_TAG_COMPOUND.isInstance(realTag)) { // We need to make sure this is indeed an NBTTagCompound
|
||||
Map<String, Object> realMap = (Map<String, Object>) MAP.get(realTag);
|
||||
Set<Map.Entry<String, Object>> entrySet = realMap.entrySet();
|
||||
Map<String, Tag> map = tag.getValue();
|
||||
for (Map.Entry<String, Object> entry : entrySet) {
|
||||
map.put(entry.getKey(), toOpenTag(entry.getValue(), entry.getKey()));
|
||||
}
|
||||
tag.setValue(map);
|
||||
}
|
||||
|
||||
Item item = new Item();
|
||||
item.setAmount((byte) is.getAmount());
|
||||
item.setData(is.getDurability());
|
||||
item.setId(id);
|
||||
item.setTag(tag);
|
||||
return item;
|
||||
}
|
||||
|
||||
private Tag toOpenTag(Object nmsTag, String name) throws Exception {
|
||||
if (NBT_TAG_COMPOUND.isInstance(nmsTag)) {
|
||||
CompoundTag tag = new CompoundTag(name);
|
||||
Map<String, Tag> tagMap = tag.getValue();
|
||||
|
||||
Map<String, Object> nmsMap = (Map<String, Object>) MAP.get(nmsTag);
|
||||
Set<Map.Entry<String, Object>> entrySet = nmsMap.entrySet();
|
||||
for (Map.Entry<String, Object> entry : entrySet) {
|
||||
Tag value = toOpenTag(entry.getValue(), entry.getKey());
|
||||
tagMap.put(entry.getKey(), value);
|
||||
}
|
||||
tag.setValue(tagMap);
|
||||
return tag;
|
||||
} else {
|
||||
// Strings are a special case as they need proper escaping
|
||||
if (NBT_STRING.isInstance(nmsTag)) {
|
||||
String toString = nmsTag.toString();
|
||||
if (toString.startsWith("\"") && toString.endsWith("\"")) {
|
||||
toString = toString.substring(1, toString.length() - 1);
|
||||
// toString = escapeSpecials(toString);
|
||||
return new StringTag(name, toString);
|
||||
}
|
||||
}
|
||||
|
||||
// NBTTag Lists are also special, as they are a sort of compound themselves and
|
||||
// need to be parsed recursively
|
||||
if (NBT_LIST.isInstance(nmsTag)) {
|
||||
List<Object> nmsNBTBaseList = (List<Object>) LIST_FIELD.get(nmsTag);
|
||||
List<Tag> list = new ArrayList<>();
|
||||
//int i = 0;
|
||||
for (Object baseTag : nmsNBTBaseList) {
|
||||
list.add(toOpenTag(baseTag, ""));
|
||||
//++i;
|
||||
}
|
||||
return new ListTag(name, list);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NBT_BASE_CLASSES.size(); ++i) {
|
||||
Class<?> c = NBT_BASE_CLASSES.get(i);
|
||||
if (c.isInstance(nmsTag)) {
|
||||
Object value = NBT_BASE_DATA_FIELD.get(i).get(nmsTag);
|
||||
if(value.getClass().getSimpleName().startsWith("NBTTag")) {
|
||||
if(!TYPES_TO_MC_NBT_TAGS.containsKey(value.getClass())) {
|
||||
ChatItem.getInstance().getLogger().warning("Failed to find NBT tag for class: " + value.getClass().getSimpleName());
|
||||
continue;
|
||||
}
|
||||
return TYPES_TO_MC_NBT_TAGS.get(value.getClass()).apply(name, value);
|
||||
} else {
|
||||
Tag t = TYPES_TO_OPEN_NBT_TAGS.get(value.getClass()).apply(name);
|
||||
if (t instanceof ByteTag) {
|
||||
((ByteTag) t).setValue((byte) value);
|
||||
((ByteTag) t).setValue((byte) value);
|
||||
} else if (t instanceof ByteArrayTag)
|
||||
((ByteArrayTag) t).setValue((byte[]) value);
|
||||
else if (t instanceof DoubleTag)
|
||||
((DoubleTag) t).setValue((double) value);
|
||||
else if (t instanceof FloatTag)
|
||||
((FloatTag) t).setValue((float) value);
|
||||
else if (t instanceof IntTag)
|
||||
((IntTag) t).setValue((int) value);
|
||||
else if (t instanceof IntArrayTag)
|
||||
((IntArrayTag) t).setValue((int[]) value);
|
||||
else if (t instanceof LongTag)
|
||||
((LongTag) t).setValue((long) value);
|
||||
else if (t instanceof ShortTag)
|
||||
((ShortTag) t).setValue((short) value);
|
||||
else
|
||||
ChatItem.getInstance().getLogger().warning("Failed to find Open tag for class: " + t.getClass().getSimpleName());
|
||||
return t; // Should never happen
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // Should never happen
|
||||
}
|
||||
}
|
||||
|
||||
private String stringifyItem(ItemStack stack) throws Exception {
|
||||
Item item = toItem(stack);
|
||||
ItemRewriter.remapIds(Version.getVersion().MAX_VER, protocolVersion.MAX_VER, item);
|
||||
StringBuilder sb = new StringBuilder("{id:");
|
||||
sb.append("\"").append(item.getId()).append("\"").append(","); // Append the id
|
||||
sb.append("Count:").append(item.getAmount()).append("b,"); // Append the amount
|
||||
sb.append("Damage:").append(item.getData()).append("s"); // Append the durability data
|
||||
|
||||
Map<String, Tag> tagMap = item.getTag().getValue();
|
||||
if (tagMap.isEmpty()) {
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
Set<Map.Entry<String, Tag>> entrySet = tagMap.entrySet();
|
||||
boolean first = true;
|
||||
sb.append(",tag:{"); // Start of the tag
|
||||
for (Map.Entry<String, Tag> entry : entrySet) {
|
||||
String key = entry.getKey();
|
||||
if (IGNORED.contains(key)) {
|
||||
continue;
|
||||
}
|
||||
Pattern pattern = Pattern.compile("[{}\\[\\],\":\\\\/]");
|
||||
Matcher matcher = pattern.matcher(key);
|
||||
if (matcher.find()) {
|
||||
continue; // Skip invalid keys, as they can cause exceptions client-side
|
||||
}
|
||||
String value = stringifyTag(entry.getValue());
|
||||
if (!first) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(key).append(":").append(value);
|
||||
first = false;
|
||||
}
|
||||
sb.append("}}"); // End of tag and end of item
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String stringifyTag(Tag normalTag) {
|
||||
if (normalTag instanceof CompoundTag) {
|
||||
StringBuilder sb = new StringBuilder("{");
|
||||
CompoundTag tagCompound = (CompoundTag) normalTag;
|
||||
Map<String, Tag> tagMap = tagCompound.getValue();
|
||||
Set<Map.Entry<String, Tag>> entrySet = tagMap.entrySet();
|
||||
for (Map.Entry<String, Tag> entry : entrySet) {
|
||||
String value = stringifyTag(entry.getValue());
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
if (sb.length() > 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(entry.getKey()).append(":").append(value);
|
||||
}
|
||||
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
} else {
|
||||
if (normalTag instanceof StringTag) {
|
||||
return "\"" + ((StringTag) normalTag).getValue() + "\""; // Should be already escaped
|
||||
}
|
||||
|
||||
if (normalTag instanceof ListTag) {
|
||||
List<Tag> list = ((ListTag) normalTag).getValue();
|
||||
StringBuilder sb = new StringBuilder("[");
|
||||
boolean first = true;
|
||||
for (Tag tag : list) {
|
||||
String index = tag.getName();
|
||||
String value = stringifyTag(tag);
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
if (!first) {
|
||||
sb.append(",");
|
||||
}
|
||||
if (protocolVersion.MAX_VER <= Version.V1_11.MAX_VER) { // it's before 1.12
|
||||
sb.append(index).append(":").append(value);
|
||||
} else {
|
||||
sb.append(value);
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
if (normalTag instanceof ByteTag) {
|
||||
return normalTag.getValue() + "b";
|
||||
}
|
||||
if (normalTag instanceof ByteArrayTag) {
|
||||
return "[" + ((byte[]) normalTag.getValue()).length + " bytes]";
|
||||
}
|
||||
if (normalTag instanceof DoubleTag) {
|
||||
return (double) normalTag.getValue() + "d";
|
||||
}
|
||||
if (normalTag instanceof FloatTag) {
|
||||
return (float) normalTag.getValue() + "f";
|
||||
}
|
||||
if (normalTag instanceof IntTag) {
|
||||
return String.valueOf((int) normalTag.getValue());
|
||||
}
|
||||
if (normalTag instanceof IntArrayTag) {
|
||||
int[] array = (int[]) normalTag.getValue();
|
||||
if (array.length == 0) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder("[");
|
||||
boolean first = true;
|
||||
for (int i : array) {
|
||||
if (!first) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(i);
|
||||
first = false;
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
if (normalTag instanceof LongTag) {
|
||||
return (long) normalTag.getValue() + "L";
|
||||
}
|
||||
if (normalTag instanceof ShortTag) {
|
||||
return (short) normalTag.getValue() + "s";
|
||||
}
|
||||
return null; // Should never happen
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.json;
|
||||
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
//Based on DarkSeraphim's system, but using Gson and supporting some more edge cases
|
||||
public class Translator {
|
||||
|
||||
private static final String STYLES = "klmnor"; //All style codes
|
||||
|
||||
public static JsonArray toJson(String old){
|
||||
if(old.lastIndexOf(ChatColor.COLOR_CHAR) == -1){
|
||||
JsonArray arr = new JsonArray();
|
||||
JsonObject obj = new JsonObject();
|
||||
obj.addProperty("text", old);
|
||||
arr.add(obj);
|
||||
return arr;
|
||||
}
|
||||
boolean startsWithCode = old.startsWith(Character.toString(ChatColor.COLOR_CHAR));
|
||||
JsonArray message = new JsonArray();
|
||||
String[] parts = old.split(Character.toString(ChatColor.COLOR_CHAR));
|
||||
JsonObject next = null; //refers to the object we created before (in time) but next in the message, as we're going from end to start
|
||||
for(int i = parts.length-1; i >= 0; --i){ //We go in reverse order
|
||||
String part = parts[i];
|
||||
|
||||
if(part.isEmpty()){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i == 0 && !startsWithCode){
|
||||
JsonObject toAdd = new JsonObject();
|
||||
toAdd.addProperty("text", part);
|
||||
message.add(toAdd);
|
||||
break;
|
||||
}
|
||||
|
||||
char code = Character.toLowerCase(part.charAt(0));
|
||||
|
||||
if(!isColorOrStyle(code)){
|
||||
if(next != null){
|
||||
String text = next.get("text").getAsString();
|
||||
text = ChatColor.COLOR_CHAR + part + text;
|
||||
next.addProperty("text", text);
|
||||
}else{
|
||||
JsonObject added = new JsonObject();
|
||||
added.addProperty("text", ChatColor.COLOR_CHAR + part);
|
||||
message.add(added);
|
||||
next = added;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(part.length() == 1){ //If it's just format and no text, we try to format the next element, if it wasn't formatted already (and it's not null)
|
||||
if(next == null){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isStyle(code)){
|
||||
next.addProperty(getStyleName(code), true);
|
||||
}else{ //it's a color
|
||||
if(isAlreadyColored(next)){
|
||||
continue;
|
||||
}
|
||||
next.addProperty("color", getColorName(code));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
//Last possibility that remains is that we have a normal color/format + text situation
|
||||
JsonObject added = new JsonObject();
|
||||
added.addProperty("text", part.substring(1));
|
||||
if(isStyle(code)){
|
||||
added.addProperty(getStyleName(code), true);
|
||||
message.add(added);
|
||||
next = added;
|
||||
continue;
|
||||
}
|
||||
//else it can only be a color
|
||||
added.addProperty("color", getColorName(code));
|
||||
//also try to color the next element if not colored already
|
||||
if(next != null){
|
||||
if(!isAlreadyColored(next)){
|
||||
next.addProperty("color", getColorName(code));
|
||||
}
|
||||
}
|
||||
message.add(added);
|
||||
next = added;
|
||||
}
|
||||
|
||||
int i = message.size()-1;
|
||||
JsonArray orderedMessage = new JsonArray();//This is where we'll store the reverted message (in proper order for being sent to the client)
|
||||
//First we have to copy all elements
|
||||
for(JsonElement el : message){
|
||||
orderedMessage.add(el);
|
||||
}
|
||||
for(JsonElement element : message){
|
||||
JsonObject obj = (JsonObject) element;
|
||||
orderedMessage.set(i, obj); //And then we add the object to the properly ordered array
|
||||
--i;
|
||||
}
|
||||
|
||||
return orderedMessage;
|
||||
}
|
||||
|
||||
private static String getColorName(char code){
|
||||
return ChatColor.getByChar(code).name().toLowerCase();
|
||||
}
|
||||
|
||||
private static String getStyleName(char code){
|
||||
switch(code){
|
||||
case 'k': return "obfuscated";
|
||||
case 'l': return "bold";
|
||||
case 'm': return "strikethrough";
|
||||
case 'n': return "underlined";
|
||||
case 'o': return "italic";
|
||||
case 'r': return "reset";
|
||||
default: return null; //Should never happen. Made it return null to throw errors if a new format pops up and it really happens
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isColorOrStyle(char code){
|
||||
return ChatColor.getByChar(code) != null;
|
||||
}
|
||||
|
||||
private static boolean isStyle(char c){
|
||||
return STYLES.indexOf(c) != -1;
|
||||
}
|
||||
|
||||
private static boolean isAlreadyColored(JsonObject obj){
|
||||
return obj.has("color");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.listeners;
|
||||
|
||||
import static me.dadus33.chatitem.chatmanager.ChatManager.SEPARATOR;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public class ChatEventListener implements Listener {
|
||||
|
||||
private final static String LEFT = "{remaining}";
|
||||
private final HashMap<String, Long> COOLDOWNS = new HashMap<>();
|
||||
private final PacketEditingChatManager manage;
|
||||
|
||||
public ChatEventListener(PacketEditingChatManager manage) {
|
||||
this.manage = manage;
|
||||
}
|
||||
|
||||
public Storage getStorage() {
|
||||
return this.manage.getStorage();
|
||||
}
|
||||
|
||||
private String calculateTime(long seconds) {
|
||||
if (seconds < 60) {
|
||||
return seconds + getStorage().SECONDS;
|
||||
}
|
||||
if (seconds < 3600) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int minutes = (int) seconds / 60;
|
||||
builder.append(minutes).append(getStorage().MINUTES);
|
||||
int secs = (int) seconds - minutes * 60;
|
||||
if (secs != 0) {
|
||||
builder.append(" ").append(secs).append(getStorage().SECONDS);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int hours = (int) seconds / 3600;
|
||||
builder.append(hours).append(getStorage().HOURS);
|
||||
int minutes = (int) (seconds / 60) - (hours * 60);
|
||||
if (minutes != 0) {
|
||||
builder.append(" ").append(minutes).append(getStorage().MINUTES);
|
||||
}
|
||||
int secs = (int) (seconds - ((seconds / 60) * 60));
|
||||
if (secs != 0) {
|
||||
builder.append(" ").append(secs).append(getStorage().SECONDS);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private int countOccurrences(String findStr, String str) {
|
||||
int lastIndex = 0;
|
||||
int count = 0;
|
||||
while (lastIndex != -1) {
|
||||
|
||||
lastIndex = str.indexOf(findStr, lastIndex);
|
||||
|
||||
if (lastIndex != -1) {
|
||||
count++;
|
||||
lastIndex += findStr.length();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) // We need to have lowest priority in order
|
||||
// to get to the event before DeluxeChat or
|
||||
// other plugins do
|
||||
public void onChat(AsyncPlayerChatEvent e) {
|
||||
ChatItem.debug("(v1) Check for v1 system. Cancelled: " + e.isCancelled());
|
||||
if (e.getMessage().indexOf(SEPARATOR) != -1) { // If the BELL character is found, we have to remove it
|
||||
String msg = e.getMessage().replace(Character.toString(SEPARATOR), "");
|
||||
ChatItem.debug("Already bell in message: " + e.getMessage());
|
||||
e.setMessage(msg);
|
||||
}
|
||||
boolean found = false;
|
||||
final String oldMsg = e.getMessage();
|
||||
for (String rep : getStorage().PLACEHOLDERS)
|
||||
if (oldMsg.contains(rep)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ChatItem.debug("(v1) not found placeholders in: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
Player p = e.getPlayer();
|
||||
|
||||
if (getStorage().PERMISSION_ENABLED && !p.hasPermission(getStorage().PERMISSION_NAME)) {
|
||||
if (!getStorage().LET_MESSAGE_THROUGH) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
if (!getStorage().NO_PERMISSION_MESSAGE.isEmpty() && getStorage().SHOW_NO_PERM_NORMAL) {
|
||||
p.sendMessage(getStorage().NO_PERMISSION_MESSAGE);
|
||||
}
|
||||
ChatItem.debug("(v1) Don't have permission");
|
||||
return;
|
||||
}
|
||||
if (p.getItemInHand().getType().equals(Material.AIR)) {
|
||||
if (getStorage().DENY_IF_NO_ITEM) {
|
||||
e.setCancelled(true);
|
||||
if (!getStorage().DENY_MESSAGE.isEmpty())
|
||||
e.getPlayer().sendMessage(getStorage().DENY_MESSAGE);
|
||||
ChatItem.debug("(v1) No item and must deny");
|
||||
return;
|
||||
}
|
||||
if (getStorage().HAND_DISABLED) {
|
||||
ChatItem.debug("(v1) Hand disabled");
|
||||
return;
|
||||
}
|
||||
}
|
||||
ChatItem.debug("(v1) Checking cooldown " + e.getMessage());
|
||||
if (getStorage().COOLDOWN > 0 && !p.hasPermission("chatitem.ignore-cooldown")) {
|
||||
if (COOLDOWNS.containsKey(p.getName())) {
|
||||
long start = COOLDOWNS.get(p.getName());
|
||||
long current = System.currentTimeMillis() / 1000;
|
||||
long elapsed = current - start;
|
||||
if (elapsed >= getStorage().COOLDOWN) {
|
||||
COOLDOWNS.remove(p.getName());
|
||||
} else {
|
||||
if (!getStorage().LET_MESSAGE_THROUGH) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
if (!getStorage().COOLDOWN_MESSAGE.isEmpty()) {
|
||||
long left = (start + getStorage().COOLDOWN) - current;
|
||||
p.sendMessage(getStorage().COOLDOWN_MESSAGE.replace(LEFT, calculateTime(left)));
|
||||
}
|
||||
ChatItem.debug("(v1) Cooldown");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
String s = e.getMessage(), firstPlaceholder = getStorage().PLACEHOLDERS.get(0);
|
||||
for (String placeholder : getStorage().PLACEHOLDERS) {
|
||||
s = s.replace(placeholder, firstPlaceholder);
|
||||
}
|
||||
int occurrences = countOccurrences(firstPlaceholder, s);
|
||||
|
||||
if (occurrences > getStorage().LIMIT) {
|
||||
e.setCancelled(true);
|
||||
ChatItem.debug("(v1) Reach message limit");
|
||||
if (getStorage().LIMIT_MESSAGE.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
e.getPlayer().sendMessage(getStorage().LIMIT_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
ChatItem.debug("(v1) Set placeholder: " + e.getMessage());
|
||||
try {
|
||||
StringJoiner msg = new StringJoiner(" ");
|
||||
for(String part : e.getMessage().split(" ")) {
|
||||
if(part.equalsIgnoreCase(firstPlaceholder)) {
|
||||
msg.add(firstPlaceholder + SEPARATOR + p.getName());
|
||||
} else {
|
||||
msg.add(part);
|
||||
}
|
||||
}
|
||||
e.setMessage(msg.toString());
|
||||
e.setFormat(e.getFormat().replace(oldMsg, e.getMessage())); // set own message for plugin that already put the message into the format
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
if (!p.hasPermission("chatitem.ignore-cooldown")) {
|
||||
COOLDOWNS.put(p.getName(), System.currentTimeMillis() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onCommand(final PlayerCommandPreprocessEvent e) {
|
||||
if (e.getMessage().indexOf(SEPARATOR) != -1) { // If the BELL character is found, we have to remove it
|
||||
String msg = e.getMessage().replace(Character.toString(SEPARATOR), "");
|
||||
e.setMessage(msg);
|
||||
}
|
||||
String commandString = e.getMessage().split(" ")[0].replaceAll("^/+", ""); // First part of the command, without
|
||||
// leading slashes and without
|
||||
// arguments
|
||||
Command cmd = Bukkit.getPluginCommand(commandString);
|
||||
if (cmd == null) { // not a plugin command
|
||||
if (!getStorage().ALLOWED_DEFAULT_COMMANDS.contains(commandString)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!getStorage().ALLOWED_PLUGIN_COMMANDS.contains(cmd)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Player p = e.getPlayer();
|
||||
boolean found = false;
|
||||
|
||||
for (String rep : getStorage().PLACEHOLDERS) {
|
||||
if (e.getMessage().contains(rep)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!p.hasPermission("chatitem.use")) {
|
||||
if (!getStorage().NO_PERMISSION_MESSAGE.isEmpty() && getStorage().SHOW_NO_PERM_COMMAND) {
|
||||
p.sendMessage(getStorage().NO_PERMISSION_MESSAGE);
|
||||
}
|
||||
e.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.getPlayer().getItemInHand().getType().equals(Material.AIR)) {
|
||||
if (getStorage().DENY_IF_NO_ITEM) {
|
||||
e.setCancelled(true);
|
||||
if (!getStorage().DENY_MESSAGE.isEmpty()) {
|
||||
e.getPlayer().sendMessage(getStorage().DENY_MESSAGE);
|
||||
}
|
||||
}
|
||||
if (getStorage().HAND_DISABLED) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (getStorage().COOLDOWN > 0 && !p.hasPermission("chatitem.ignore-cooldown")) {
|
||||
if (COOLDOWNS.containsKey(p.getName())) {
|
||||
long start = COOLDOWNS.get(p.getName());
|
||||
long current = System.currentTimeMillis() / 1000;
|
||||
long elapsed = current - start;
|
||||
if (elapsed >= getStorage().COOLDOWN) {
|
||||
COOLDOWNS.remove(p.getName());
|
||||
} else {
|
||||
if (!getStorage().LET_MESSAGE_THROUGH) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
if (!getStorage().COOLDOWN_MESSAGE.isEmpty()) {
|
||||
long left = (start + getStorage().COOLDOWN) - current;
|
||||
p.sendMessage(getStorage().COOLDOWN_MESSAGE.replace(LEFT, calculateTime(left)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String s = e.getMessage();
|
||||
for (String placeholder : getStorage().PLACEHOLDERS) {
|
||||
s = s.replace(placeholder, getStorage().PLACEHOLDERS.get(0));
|
||||
}
|
||||
int occurrences = countOccurrences(getStorage().PLACEHOLDERS.get(0), s);
|
||||
|
||||
if (occurrences > getStorage().LIMIT) {
|
||||
e.setCancelled(true);
|
||||
if (getStorage().LIMIT_MESSAGE.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
e.getPlayer().sendMessage(getStorage().LIMIT_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(e.getMessage());
|
||||
sb.append(SEPARATOR).append(e.getPlayer().getName());
|
||||
e.setMessage(sb.toString());
|
||||
if (!p.hasPermission("chatitem.ignore-cooldown")) {
|
||||
COOLDOWNS.put(p.getName(), System.currentTimeMillis() / 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,299 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.listeners;
|
||||
|
||||
import static me.dadus33.chatitem.chatmanager.ChatManager.SEPARATOR;
|
||||
import static me.dadus33.chatitem.chatmanager.ChatManager.SEPARATOR_STR;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.ShulkerBox;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.BlockStateMeta;
|
||||
import org.bukkit.inventory.meta.BookMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketHandler;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
|
||||
import me.dadus33.chatitem.utils.PacketUtils;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
public class ChatPacketManager extends PacketHandler {
|
||||
|
||||
private final static String NAME = "{name}";
|
||||
private final static String AMOUNT = "{amount}";
|
||||
private final static String TIMES = "{times}";
|
||||
|
||||
private Method serializerGetJson;
|
||||
private PacketEditingChatManager manager;
|
||||
|
||||
public ChatPacketManager(PacketEditingChatManager manager) {
|
||||
this.manager = manager;
|
||||
try {
|
||||
for (Method m : PacketUtils.CHAT_SERIALIZER.getDeclaredMethods()) {
|
||||
if (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(PacketUtils.COMPONENT_CLASS)
|
||||
&& m.getReturnType().equals(String.class)) {
|
||||
serializerGetJson = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (serializerGetJson == null)
|
||||
ChatItem.getInstance().getLogger().warning(
|
||||
"Failed to find JSON serializer in class: " + PacketUtils.CHAT_SERIALIZER.getCanonicalName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onSend(ChatItemPacket e) {
|
||||
if (!e.hasPlayer() || !e.getPacketType().equals(PacketType.Server.CHAT)) {
|
||||
return;
|
||||
}
|
||||
Version version = Version.getVersion();
|
||||
if (version.isNewerOrEquals(Version.V1_8)) { // only if action bar messages are supported in this
|
||||
// version of minecraft
|
||||
if (version.isNewerOrEquals(Version.V1_12)) {
|
||||
try {
|
||||
if (((Enum<?>) e.getContent()
|
||||
.getSpecificModifier(PacketUtils.getNmsClass("ChatMessageType", "network.chat.")).read(0))
|
||||
.name().equals("GAME_INFO")) {
|
||||
return; // It means it's an actionbar message, and we ain't intercepting those
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
} else if (e.getContent().getBytes().readSafely(0) == (byte) 2) {
|
||||
return; // It means it's an actionbar message, and we ain't intercepting those
|
||||
}
|
||||
}
|
||||
ChatItem.debug("UUID: " + e.getContent().getSpecificModifier(UUID.class).readSafely(0, null));
|
||||
boolean usesBaseComponents = false;
|
||||
PacketContent packet = e.getContent();
|
||||
String json;
|
||||
if (packet.getChatComponents().readSafely(0) == null) { // null check for some cases of messages sent using
|
||||
// spigot's Chat Component API or other means
|
||||
if (!manager.supportsChatComponentApi()) // only if the API is supported in this server distribution
|
||||
return;// We don't know how to deal with anything else. Most probably some mod message
|
||||
// we shouldn't mess with anyways
|
||||
BaseComponent[] components = packet.getSpecificModifier(BaseComponent[].class).readSafely(0);
|
||||
if (components == null) {
|
||||
ChatItem.debug("No base components");
|
||||
return;
|
||||
}
|
||||
json = ComponentSerializer.toString(components);
|
||||
usesBaseComponents = true;
|
||||
} else {
|
||||
try {
|
||||
json = (String) serializerGetJson.invoke(null, packet.getChatComponents().readSafely(0));
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
json = "{}";
|
||||
}
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
for (String rep : getStorage().PLACEHOLDERS) {
|
||||
if (json.contains(rep)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
ChatItem.debug("No placeholders founded");
|
||||
return; // then it's just a normal message without placeholders, so we leave it alone
|
||||
}
|
||||
Object toReplace = null;
|
||||
if(json.lastIndexOf(SEPARATOR) != -1)
|
||||
toReplace = SEPARATOR;
|
||||
if(json.lastIndexOf(SEPARATOR_STR) != -1)
|
||||
toReplace = SEPARATOR_STR;
|
||||
if (toReplace == null) { // if the message doesn't contain the BELL separator, then it's certainly NOT a message we want to parse
|
||||
ChatItem.debug("Not contains bell " + json);
|
||||
return;
|
||||
}
|
||||
ChatItem.debug("Add packet meta");
|
||||
String fjson = json, toReplaceStr = toReplace.toString();
|
||||
boolean bUsesBaseComponents = usesBaseComponents;
|
||||
e.setCancelled(true); // We cancel the packet as we're going to resend it anyways (ignoring listeners
|
||||
// this time)
|
||||
Bukkit.getScheduler().runTaskAsynchronously(ChatItem.getInstance(), () -> {
|
||||
|
||||
int topIndex = -1;
|
||||
String name = null;
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
String pname = toReplaceStr + p.getName();
|
||||
if (!fjson.contains(pname)) {
|
||||
continue;
|
||||
}
|
||||
int index = fjson.lastIndexOf(pname) + pname.length();
|
||||
if (index > topIndex) {
|
||||
topIndex = index;
|
||||
name = pname.replace(toReplaceStr, "");
|
||||
}
|
||||
}
|
||||
if (name == null) { // something went really bad, so we run away and hide (AKA the player left or is
|
||||
// on another server)
|
||||
ChatItem.debug("Name null for " + fjson);
|
||||
return;
|
||||
}
|
||||
|
||||
Player p = Bukkit.getPlayer(name);
|
||||
StringBuilder builder = new StringBuilder(fjson);
|
||||
builder.replace(topIndex - (name.length() + 6), topIndex, ""); // we remove both the name and the separator
|
||||
// from the json string
|
||||
String localJson = builder.toString();
|
||||
|
||||
String message = null;
|
||||
try {
|
||||
if (!p.getItemInHand().getType().equals(Material.AIR)) {
|
||||
ItemStack copy = p.getItemInHand().clone();
|
||||
if (copy.getType().name().contains("_BOOK")) { // filtering written books
|
||||
BookMeta bm = (BookMeta) copy.getItemMeta();
|
||||
bm.setPages(Collections.emptyList());
|
||||
copy.setItemMeta(bm);
|
||||
} else {
|
||||
if (copy.getType().name().contains("SHULKER_BOX")) { // if it's shulker
|
||||
if (copy.hasItemMeta()) {
|
||||
BlockStateMeta bsm = (BlockStateMeta) copy.getItemMeta();
|
||||
if (bsm.hasBlockState()) {
|
||||
ShulkerBox sb = (ShulkerBox) bsm.getBlockState();
|
||||
for (ItemStack item : sb.getInventory()) {
|
||||
stripData(item);
|
||||
}
|
||||
bsm.setBlockState(sb);
|
||||
}
|
||||
copy.setItemMeta(bsm);
|
||||
}
|
||||
}
|
||||
}
|
||||
message = manager.getManipulator().parse(localJson, getStorage().PLACEHOLDERS, copy,
|
||||
styleItem(copy, getStorage()), manager.getPlayerVersionAdapter().getProtocolVersion(p));
|
||||
} else {
|
||||
if (!getStorage().HAND_DISABLED) {
|
||||
message = manager.getManipulator().parseEmpty(localJson, getStorage().PLACEHOLDERS,
|
||||
getStorage().HAND_NAME, getStorage().HAND_TOOLTIP, p);
|
||||
}
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
if (message != null) {
|
||||
if (!bUsesBaseComponents) {
|
||||
packet.getChatComponents().write(0, jsonToChatComponent(message));
|
||||
} else {
|
||||
packet.getSpecificModifier(BaseComponent[].class).write(0, ComponentSerializer.parse(message));
|
||||
}
|
||||
}
|
||||
PacketUtils.sendPacket(e.getPlayer(), e.getPacket());
|
||||
});
|
||||
}
|
||||
private Object jsonToChatComponent(String json) {
|
||||
try {
|
||||
return PacketUtils.CHAT_SERIALIZER.getMethod("a", String.class).invoke(null, json);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String styleItem(ItemStack item, Storage c) {
|
||||
String replacer = c.NAME_FORMAT;
|
||||
String amount = c.AMOUNT_FORMAT;
|
||||
boolean dname = item.hasItemMeta() ? item.getItemMeta().hasDisplayName() : false;
|
||||
|
||||
if (item.getAmount() == 1) {
|
||||
if (c.FORCE_ADD_AMOUNT) {
|
||||
amount = amount.replace(TIMES, "1");
|
||||
replacer = replacer.replace(AMOUNT, amount);
|
||||
} else {
|
||||
replacer = replacer.replace(AMOUNT, "");
|
||||
}
|
||||
} else {
|
||||
amount = amount.replace(TIMES, String.valueOf(item.getAmount()));
|
||||
replacer = replacer.replace(AMOUNT, amount);
|
||||
}
|
||||
if (dname) {
|
||||
String trp = item.getItemMeta().getDisplayName();
|
||||
if (c.COLOR_IF_ALREADY_COLORED) {
|
||||
replacer = replacer.replace(NAME, ChatColor.stripColor(trp));
|
||||
} else {
|
||||
replacer = replacer.replace(NAME, trp);
|
||||
}
|
||||
} else {
|
||||
HashMap<Short, String> translationSection = c.TRANSLATIONS.get(item.getType().name());
|
||||
if (translationSection == null) {
|
||||
String trp = materialToName(item.getType());
|
||||
replacer = replacer.replace(NAME, trp);
|
||||
} else {
|
||||
@SuppressWarnings("deprecation")
|
||||
String translated = translationSection.get(item.getDurability());
|
||||
if (translated != null) {
|
||||
replacer = replacer.replace(NAME, translated);
|
||||
} else {
|
||||
replacer = replacer.replace(NAME, materialToName(item.getType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return replacer;
|
||||
}
|
||||
|
||||
private static String materialToName(Material m) {
|
||||
if (m.equals(Material.TNT)) {
|
||||
return "TNT";
|
||||
}
|
||||
String orig = m.toString().toLowerCase();
|
||||
String[] splits = orig.split("_");
|
||||
StringBuilder sb = new StringBuilder(orig.length());
|
||||
int pos = 0;
|
||||
for (String split : splits) {
|
||||
sb.append(split);
|
||||
int loc = sb.lastIndexOf(split);
|
||||
char charLoc = sb.charAt(loc);
|
||||
if (!(split.equalsIgnoreCase("of") || split.equalsIgnoreCase("and") || split.equalsIgnoreCase("with")
|
||||
|| split.equalsIgnoreCase("on")))
|
||||
sb.setCharAt(loc, Character.toUpperCase(charLoc));
|
||||
if (pos != splits.length - 1)
|
||||
sb.append(' ');
|
||||
++pos;
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void stripData(ItemStack i) {
|
||||
if (i == null) {
|
||||
return;
|
||||
}
|
||||
if (i.getType().equals(Material.AIR)) {
|
||||
return;
|
||||
}
|
||||
if (!i.hasItemMeta()) {
|
||||
return;
|
||||
}
|
||||
ItemMeta im = Bukkit.getItemFactory().getItemMeta(i.getType());
|
||||
ItemMeta original = i.getItemMeta();
|
||||
if (original.hasDisplayName()) {
|
||||
im.setDisplayName(original.getDisplayName());
|
||||
}
|
||||
i.setItemMeta(im);
|
||||
}
|
||||
|
||||
|
||||
public Storage getStorage() {
|
||||
return manager.getStorage();
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.listeners;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.hooks.DefaultVersionHook;
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
|
||||
public class HandshakeListener extends PacketAdapter {
|
||||
|
||||
public HandshakeListener(ChatItem pl) {
|
||||
super(pl, ListenerPriority.MONITOR, PacketType.Handshake.Client.SET_PROTOCOL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceiving(final PacketEvent e){
|
||||
if(e.isPlayerTemporary() || e.getPlayer() == null)
|
||||
return;
|
||||
PacketType.Protocol p = e.getPacket().getProtocols().read(0);
|
||||
if(p == PacketType.Protocol.STATUS || p == PacketType.Protocol.LEGACY){
|
||||
return;
|
||||
}
|
||||
final int version = e.getPacket().getIntegers().readSafely(0);
|
||||
//Delay the mapping to make sure the true address of the player was received when using bungeecord or other types of proxies
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), () ->
|
||||
DefaultVersionHook.PROTOCOL_PER_ADDRESS.put(Version.stringifyAdress(e.getPlayer().getAddress()), version), 10L);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ChatItemPacket {
|
||||
|
||||
protected Player player;
|
||||
protected Object packet;
|
||||
protected PacketType type;
|
||||
protected boolean cancel = false;
|
||||
protected PacketMetadata metaData = new PacketMetadata();
|
||||
|
||||
public ChatItemPacket(PacketType type, Object packet, Player player) {
|
||||
this.player = player;
|
||||
this.packet = packet;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public boolean hasPlayer() {
|
||||
return player != null;
|
||||
}
|
||||
|
||||
public String getPlayername() {
|
||||
return getPlayer().getName();
|
||||
}
|
||||
|
||||
public Object getPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
public String getPacketName() {
|
||||
return packet.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
public PacketType getPacketType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
public PacketContent getContent() {
|
||||
return new PacketContent(this);
|
||||
}
|
||||
|
||||
public PacketMetadata getMetaData() {
|
||||
return metaData;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.protocollib.ProtocollibPacketManager;
|
||||
|
||||
public class ChatItemPacketManager {
|
||||
|
||||
private PacketManager packetManager;
|
||||
|
||||
public ChatItemPacketManager(ChatItem pl) {
|
||||
Plugin protocolLibPlugin = Bukkit.getPluginManager().getPlugin("ProtocolLib");
|
||||
if (protocolLibPlugin != null) {
|
||||
if(checkProtocollibConditions()) {
|
||||
pl.getLogger().info("The plugin ProtocolLib has been detected. Loading Protocollib support ...");
|
||||
packetManager = new ProtocollibPacketManager(pl);
|
||||
} else {
|
||||
pl.getLogger().warning("The plugin ProtocolLib has been detected but you have an OLD version, so we cannot use it.");
|
||||
pl.getLogger().warning("Fallback to default Packet system ...");
|
||||
packetManager = new CustomPacketManager(pl);
|
||||
}
|
||||
} else {
|
||||
pl.getLogger().info("Loading own packet system.");
|
||||
packetManager = new CustomPacketManager(pl);
|
||||
}
|
||||
}
|
||||
|
||||
public PacketManager getPacketManager() {
|
||||
return packetManager;
|
||||
}
|
||||
|
||||
private boolean checkProtocollibConditions() {
|
||||
try {
|
||||
Class.forName("com.comphenix.protocol.injector.server.TemporaryPlayer");
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
|
||||
import me.dadus33.chatitem.utils.PacketUtils;
|
||||
|
||||
public class PacketContent {
|
||||
|
||||
|
||||
private final ChatItemPacket packet;
|
||||
private final Object obj;
|
||||
|
||||
/**
|
||||
* Create a PacketContent to easily read and write value in it
|
||||
*
|
||||
* @param packet the Negativity's packet
|
||||
*/
|
||||
public PacketContent(ChatItemPacket packet) {
|
||||
this.packet = packet;
|
||||
this.obj = packet.getPacket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PacketContent to easily read and write to the specified object
|
||||
*
|
||||
* @param obj the object that will be read or edit
|
||||
*/
|
||||
public PacketContent(Object obj) {
|
||||
this.packet = null;
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
public ChatItemPacket getPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
public <T> ContentModifier<T> getSpecificModifier(T type){
|
||||
return new ContentModifier<T>(obj, type.getClass());
|
||||
}
|
||||
|
||||
public <T> ContentModifier<T> getSpecificModifier(Class<T> clazz){
|
||||
return new ContentModifier<T>(obj, clazz);
|
||||
}
|
||||
|
||||
public ContentModifier<String> getStrings(){
|
||||
return new ContentModifier<String>(obj, String.class);
|
||||
}
|
||||
|
||||
public ContentModifier<Byte> getBytes(){
|
||||
return new ContentModifier<Byte>(obj, byte.class);
|
||||
}
|
||||
|
||||
public ContentModifier<Boolean> getBooleans(){
|
||||
return new ContentModifier<Boolean>(obj, boolean.class);
|
||||
}
|
||||
|
||||
public ContentModifier<Integer> getIntegers(){
|
||||
return new ContentModifier<Integer>(obj, int.class);
|
||||
}
|
||||
|
||||
public ContentModifier<byte[]> getByteArrays(){
|
||||
return new ContentModifier<byte[]>(obj, byte[].class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ContentModifier<Object> getChatComponents() {
|
||||
return (ContentModifier<Object>) getSpecificModifier(PacketUtils.COMPONENT_CLASS);
|
||||
}
|
||||
|
||||
public static class ContentModifier<T> {
|
||||
|
||||
private Object obj;
|
||||
private HashMap<Field, T> content = new HashMap<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ContentModifier(Object obj, Class<?> clazz) {
|
||||
this.obj = obj;
|
||||
|
||||
for(Field f : obj.getClass().getDeclaredFields()) {
|
||||
try {
|
||||
if(f.getType().isAssignableFrom(clazz)) {
|
||||
f.setAccessible(true);
|
||||
content.put(f, (T) f.get(obj));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(!obj.getClass().getSuperclass().equals(Object.class)) {
|
||||
for(Field f : obj.getClass().getSuperclass().getDeclaredFields()) {
|
||||
try {
|
||||
if(f.getType().isAssignableFrom(clazz)) {
|
||||
f.setAccessible(true);
|
||||
content.put(f, (T) f.get(obj));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the Map of content
|
||||
*
|
||||
* @return the number of content
|
||||
*/
|
||||
public int size() {
|
||||
return content.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the field which is named by the given one
|
||||
*
|
||||
* @param fieldName the name of the needed field
|
||||
* @return the value of the field
|
||||
*/
|
||||
public T read(String fieldName) {
|
||||
for(Field field : content.keySet())
|
||||
if(field.getName().equalsIgnoreCase(fieldName))
|
||||
return content.get(field);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the field which is named by the given one
|
||||
*
|
||||
* @param fieldName the name of the needed field
|
||||
* @param defaultValue the returned value if there is no value
|
||||
* @return the value of the field
|
||||
*/
|
||||
public T read(String fieldName, T defaultValue) {
|
||||
for(Field field : content.keySet())
|
||||
if(field.getName().equalsIgnoreCase(fieldName))
|
||||
return content.get(field);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the specified value.
|
||||
*
|
||||
* @param i the number of the value to get getted. Start at 0.
|
||||
* @return the requested value.
|
||||
*
|
||||
* @throws NoSuchElementException if the value doesn't exist
|
||||
*/
|
||||
public T read(int i) {
|
||||
return content.values().stream().filter(Objects::nonNull).findFirst().get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the specified value.
|
||||
*
|
||||
* @param i the number of the value to get getted. Start at 0.
|
||||
* @return the requested value, or null if it doesn't exist.
|
||||
*/
|
||||
public T readSafely(int i) {
|
||||
return readSafely(i, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the specified value.
|
||||
*
|
||||
* @param i the number of the value to get getted. Start at 0.
|
||||
* @param defaultValue the value which is return if the key doesn't exist
|
||||
* @return the requested value.
|
||||
*/
|
||||
public T readSafely(int i, T defaultValue) {
|
||||
return content.values().stream().filter(Objects::nonNull).findFirst().orElse(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value in the specified object.
|
||||
*
|
||||
* @param i the key of the value to set
|
||||
* @param value the new value which will be set
|
||||
*/
|
||||
public void write(int i, T value) {
|
||||
Field key = content.keySet().toArray(new Field[] {})[i];
|
||||
if(key == null) {
|
||||
new NoSuchFieldException("Not enough value in " + obj.getClass() + ".").printStackTrace();
|
||||
} else {
|
||||
content.put(key, value);
|
||||
try {
|
||||
key.set(obj, value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field which her value
|
||||
*
|
||||
* @return all content
|
||||
*/
|
||||
public HashMap<Field, T> getContent(){
|
||||
return content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets;
|
||||
|
||||
public abstract class PacketHandler {
|
||||
|
||||
public void onReceive(ChatItemPacket packet) {}
|
||||
public void onSend(ChatItemPacket packet) {}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class PacketManager {
|
||||
|
||||
public void addPlayer(Player p) {}
|
||||
public void removePlayer(Player p) {}
|
||||
public abstract void stop();
|
||||
|
||||
private final ArrayList<PacketHandler> handlers = new ArrayList<>();
|
||||
public boolean addHandler(PacketHandler handler) {
|
||||
return !handlers.add(handler);
|
||||
}
|
||||
|
||||
public boolean removeHandler(PacketHandler handler) {
|
||||
return handlers.remove(handler);
|
||||
}
|
||||
|
||||
public void notifyHandlersSent(ChatItemPacket packet) {
|
||||
handlers.forEach((handler) -> handler.onSend(packet));
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PacketMetadata {
|
||||
|
||||
private final HashMap<String, Object> metas = new HashMap<>();
|
||||
|
||||
public void setMeta(String key, Object obj) {
|
||||
this.metas.put(key, obj);
|
||||
}
|
||||
|
||||
public boolean hasMeta(String key) {
|
||||
return metas.containsKey(key);
|
||||
}
|
||||
|
||||
public void removeMeta(String key) {
|
||||
metas.remove(key);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getMeta(String key, T def) {
|
||||
return (T) metas.getOrDefault(key, def);
|
||||
}
|
||||
|
||||
public HashMap<String, Object> getMetas() {
|
||||
return metas;
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public interface PacketType {
|
||||
|
||||
String name();
|
||||
String getPacketName();
|
||||
String getFullName();
|
||||
List<String> getAlias();
|
||||
|
||||
static final String SERVER_PREFIX = "PacketPlayOut", HANDSHAKE_PREFIX = "PacketHandshaking";
|
||||
|
||||
public static PacketType getType(String packetName) {
|
||||
if(packetName.startsWith(SERVER_PREFIX)) {
|
||||
return getPacketTypeFor(packetName, Server.values(), Server.UNSET);
|
||||
} else if(packetName.startsWith(HANDSHAKE_PREFIX)) {
|
||||
return getPacketTypeFor(packetName, Handshake.values(), Handshake.UNSET);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static PacketType getPacketTypeFor(String packetName, PacketType[] types, PacketType unset) {
|
||||
for(PacketType packet : types)
|
||||
if(packet.getFullName().equalsIgnoreCase(packetName) || packet.getPacketName().equalsIgnoreCase(packetName) || packet.getAlias().contains(packetName))
|
||||
return packet;
|
||||
return unset;
|
||||
}
|
||||
|
||||
public static enum Server implements PacketType {
|
||||
|
||||
CHAT("Chat"),
|
||||
UNSET("Unset");
|
||||
|
||||
private final String packetName, fullName;
|
||||
private List<String> alias = new ArrayList<>();
|
||||
|
||||
private Server(String packetName, String... alias) {
|
||||
this.packetName = packetName;
|
||||
this.fullName = SERVER_PREFIX + packetName;
|
||||
for(String al : alias)
|
||||
this.alias.add(SERVER_PREFIX + al);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPacketName() {
|
||||
return packetName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAlias() {
|
||||
return alias;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Handshake implements PacketType {
|
||||
|
||||
IS_SET_PROTOCOL("InSetProtocol"),
|
||||
UNSET("Unset");
|
||||
|
||||
private final String packetName, fullName;
|
||||
private List<String> alias = new ArrayList<>();
|
||||
|
||||
private Handshake(String packetName, String... alias) {
|
||||
this.packetName = packetName;
|
||||
for(String al : alias)
|
||||
this.alias.add(HANDSHAKE_PREFIX + al);
|
||||
this.fullName = HANDSHAKE_PREFIX + packetName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPacketName() {
|
||||
return packetName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets.custom;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.channel.ChannelAbstract;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.channel.INC2Channel;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.channel.INCChannel;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.channel.NMUChannel;
|
||||
import me.dadus33.chatitem.utils.Utils;
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
|
||||
public class CustomPacketManager extends PacketManager implements Listener {
|
||||
|
||||
private ChannelAbstract channel;
|
||||
private Plugin pl;
|
||||
public HashMap<Object, Integer> protocolVersionPerChannel = new HashMap<>();
|
||||
private boolean isStarted = false;
|
||||
|
||||
public CustomPacketManager(Plugin pl) {
|
||||
this.pl = pl;
|
||||
Version version = Version.getVersion();
|
||||
if (version.isNewerOrEquals(Version.V1_17))
|
||||
channel = new INC2Channel(this);
|
||||
else if (version.equals(Version.V1_7))
|
||||
channel = new NMUChannel(this);
|
||||
else
|
||||
channel = new INCChannel(this);
|
||||
pl.getServer().getPluginManager().registerEvents(this, pl);
|
||||
|
||||
// we wait the start server
|
||||
Bukkit.getScheduler().runTaskLater(pl, () -> {
|
||||
isStarted = true;
|
||||
for(Player p : Utils.getOnlinePlayers())
|
||||
addPlayer(p);
|
||||
}, 20);
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return pl;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
addPlayer(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
removePlayer(e.getPlayer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlayer(Player p) {
|
||||
if(isStarted)
|
||||
channel.addPlayer(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePlayer(Player p) {
|
||||
channel.removePlayer(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
for(Player player : Utils.getOnlinePlayers())
|
||||
removePlayer(player);
|
||||
if(channel.getAddChannelExecutor() != null)
|
||||
channel.getAddChannelExecutor().shutdownNow();
|
||||
if(channel.getRemoveChannelExecutor() != null)
|
||||
channel.getRemoveChannelExecutor().shutdownNow();
|
||||
}
|
||||
|
||||
public ChatItemPacket onPacketSent(PacketType type, Player sender, Object packet) {
|
||||
if(type == null) {
|
||||
//ChatItem.debug("Failed to find packet type for " + packet.getClass().getSimpleName());
|
||||
return null;
|
||||
}
|
||||
ChatItemPacket customPacket = new ChatItemPacket(type, packet, sender);
|
||||
notifyHandlersSent(customPacket);
|
||||
return customPacket;
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.hooks.DefaultVersionHook;
|
||||
|
||||
public abstract class ChannelAbstract {
|
||||
|
||||
private ExecutorService addChannelExecutor, removeChannelExecutor;
|
||||
static final String KEY_HANDSHAKE = "packet_handshake_chatitem", KEY_HANDLER_SERVER = "packet_handler", KEY_SERVER = "packet_server_chatitem";
|
||||
|
||||
private CustomPacketManager customPacketManager;
|
||||
private HashSet<UUID> players = new HashSet<>();
|
||||
|
||||
protected ChannelAbstract(CustomPacketManager customPacketManager) {
|
||||
this.customPacketManager = customPacketManager;
|
||||
}
|
||||
|
||||
public CustomPacketManager getPacketManager() {
|
||||
return customPacketManager;
|
||||
}
|
||||
|
||||
public ExecutorService getAddChannelExecutor() {
|
||||
return addChannelExecutor;
|
||||
}
|
||||
|
||||
public ExecutorService getOrCreateAddChannelExecutor() {
|
||||
if(addChannelExecutor == null || addChannelExecutor.isTerminated())
|
||||
addChannelExecutor = Executors.newSingleThreadExecutor();
|
||||
return addChannelExecutor;
|
||||
}
|
||||
|
||||
public ExecutorService getRemoveChannelExecutor() {
|
||||
return removeChannelExecutor;
|
||||
}
|
||||
|
||||
public ExecutorService getOrCreateRemoveChannelExecutor() {
|
||||
if(removeChannelExecutor == null || removeChannelExecutor.isTerminated())
|
||||
removeChannelExecutor = Executors.newSingleThreadExecutor();
|
||||
return removeChannelExecutor;
|
||||
}
|
||||
|
||||
public void addPlayer(Player p) {
|
||||
if(players.add(p.getUniqueId())) {
|
||||
addChannel(p, p.getUniqueId().toString());
|
||||
try {
|
||||
Integer protocol = customPacketManager.protocolVersionPerChannel.remove(getChannel(p));
|
||||
if(protocol != null)
|
||||
DefaultVersionHook.PROTOCOL_PER_UUID.put(p.getUniqueId(), protocol);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removePlayer(Player p) {
|
||||
if(players.remove(p.getUniqueId()))
|
||||
removeChannel(p, p.getUniqueId().toString());
|
||||
}
|
||||
|
||||
public void removeAllPlayers() {
|
||||
new ArrayList<>(players).forEach((uuid) -> {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if(p != null) // player don't left
|
||||
removeChannel(Bukkit.getPlayer(uuid), uuid.toString());
|
||||
});
|
||||
players.clear();
|
||||
}
|
||||
|
||||
protected abstract void stopPipelines();
|
||||
|
||||
public abstract void addChannel(Player player, String endChannelName);
|
||||
|
||||
public abstract void removeChannel(Player player, String endChannelName);
|
||||
|
||||
public abstract Object getChannel(Player p) throws Exception;
|
||||
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
|
||||
|
||||
public class ChannelInboundHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
public static final HashMap<Channel, ChatItemPacket> TMP = new HashMap<>();
|
||||
private CustomPacketManager packetManager;
|
||||
private List<ChannelPipeline> pipelines = new ArrayList<>();
|
||||
|
||||
public ChannelInboundHandler(CustomPacketManager packetManager) {
|
||||
this.packetManager = packetManager;
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
pipelines.forEach(ChannelPipeline::removeFirst);
|
||||
pipelines.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
ctx.fireChannelRead(msg);
|
||||
ChannelPipeline pipe = ((Channel) msg).pipeline();
|
||||
pipelines.add(pipe);
|
||||
pipe.addFirst(new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) {
|
||||
try {
|
||||
channel.eventLoop().submit(() -> {
|
||||
try {
|
||||
ChannelHandler interceptor = channel.pipeline().get(ChannelAbstract.KEY_HANDSHAKE);
|
||||
// Inject our packet interceptor
|
||||
if (interceptor == null) {
|
||||
interceptor = new ChannelHandlerHandshakeReceive(channel);
|
||||
channel.pipeline().addBefore("packet_handler", ChannelAbstract.KEY_HANDSHAKE, interceptor);
|
||||
}
|
||||
return interceptor;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Try again
|
||||
return channel.pipeline().get(ChannelAbstract.KEY_HANDSHAKE);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
packetManager.getPlugin().getLogger().log(Level.SEVERE, "Cannot inject incoming channel " + channel, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public class ChannelHandlerHandshakeReceive extends ChannelInboundHandlerAdapter {
|
||||
|
||||
private Channel channel;
|
||||
|
||||
public ChannelHandlerHandshakeReceive(Channel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object packet) {
|
||||
try {
|
||||
PacketType packetType = PacketType.getType(packet.getClass().getSimpleName());
|
||||
if(packetType != null && packetType == PacketType.Handshake.IS_SET_PROTOCOL) {
|
||||
packetManager.protocolVersionPerChannel.put(channel, new PacketContent(packet).getIntegers().readSafely(0, 0));
|
||||
}
|
||||
super.channelRead(ctx, packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
|
||||
|
||||
import static me.dadus33.chatitem.utils.PacketUtils.getPlayerConnection;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.hooks.DefaultVersionHook;
|
||||
import me.dadus33.chatitem.utils.PacketUtils;
|
||||
import me.dadus33.chatitem.utils.ReflectionUtils;
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
|
||||
public class INC2Channel extends ChannelAbstract {
|
||||
|
||||
private final ChannelInboundHandler boundHandler;
|
||||
private ChannelPipeline pipeline;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public INC2Channel(CustomPacketManager customPacketManager) {
|
||||
super(customPacketManager);
|
||||
boundHandler = new ChannelInboundHandler(customPacketManager);
|
||||
try {
|
||||
Object mcServer = ReflectionUtils.callMethod(PacketUtils.getCraftServer(), Version.getVersion().equals(Version.V1_17) ? "getServer" : "b");
|
||||
Object co = ReflectionUtils.getFirstWith(mcServer, PacketUtils.getNmsClass("MinecraftServer", "server."), PacketUtils.getNmsClass("ServerConnection", "server.network."));
|
||||
((List<ChannelFuture>) ReflectionUtils.getField(co, "f")).forEach((channelFuture) -> {
|
||||
pipeline = channelFuture.channel().pipeline();
|
||||
pipeline.addFirst(boundHandler);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopPipelines() {
|
||||
pipeline.remove(boundHandler);
|
||||
boundHandler.clean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChannel(final Player player, String endChannelName) {
|
||||
getOrCreateAddChannelExecutor().execute(() -> {
|
||||
if(!player.isOnline())
|
||||
return;
|
||||
try {
|
||||
Channel channel = getChannel(player);
|
||||
// Managing outgoing packet (to the player)
|
||||
channel.pipeline().addAfter(KEY_HANDLER_SERVER, KEY_SERVER + endChannelName, new ChannelHandlerSent(player));
|
||||
|
||||
ChatItemPacket pa = ChannelInboundHandler.TMP.remove(channel);
|
||||
if(pa != null)
|
||||
DefaultVersionHook.PROTOCOL_PER_UUID.put(player.getUniqueId(), pa.getContent().getIntegers().readSafely(0, Version.getVersion().MAX_VER));
|
||||
} catch (NoSuchElementException e) {
|
||||
// appear when the player's channel isn't accessible because of reload.
|
||||
getPacketManager().getPlugin().getLogger().warning("Please, don't use reload, this can produce some problem. Currently, " + player.getName() + " isn't fully checked because of that. More details: " + e.getMessage() + " (NoSuchElementException)");
|
||||
} catch (IllegalArgumentException e) {
|
||||
if(e.getMessage().contains("Duplicate handler")) {
|
||||
removeChannel(player, endChannelName);
|
||||
addChannel(player, endChannelName);
|
||||
} else
|
||||
getPacketManager().getPlugin().getLogger().severe("Error while loading Packet channel. " + e.getMessage() + ". Please, prefer restart than reload.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChannel(Player player, String endChannelName) {
|
||||
getOrCreateRemoveChannelExecutor().execute(() -> {
|
||||
try {
|
||||
final Channel channel = getChannel(player);
|
||||
if(channel.pipeline().get(KEY_SERVER + endChannelName) != null)
|
||||
channel.pipeline().remove(KEY_SERVER + endChannelName);
|
||||
} catch (Exception e) {
|
||||
ChatItem.getInstance().getLogger().warning("Failed to remove channel for " + player.getName() + ". Reason: " + e.getMessage() + " (" + e.getStackTrace()[0].toString() + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel getChannel(Player p) throws Exception {
|
||||
Object playerConnection = getPlayerConnection(p);
|
||||
Object networkManager = playerConnection.getClass().getField("a").get(playerConnection);
|
||||
return (Channel) networkManager.getClass().getDeclaredField("k").get(networkManager);//(Channel) networkManager.getClass().getDeclaredField("channel").get(networkManager);
|
||||
}
|
||||
|
||||
private class ChannelHandlerSent extends ChannelOutboundHandlerAdapter {
|
||||
|
||||
private final Player owner;
|
||||
|
||||
public ChannelHandlerSent(Player player) {
|
||||
this.owner = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception {
|
||||
ChatItemPacket nextPacket = getPacketManager().onPacketSent(PacketType.getType(packet.getClass().getSimpleName()), owner, packet);
|
||||
if(nextPacket != null && nextPacket.isCancelled())
|
||||
return;
|
||||
super.write(ctx, packet, promise);
|
||||
}
|
||||
}
|
||||
}
|
||||
-129
@@ -1,129 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
|
||||
|
||||
import static me.dadus33.chatitem.utils.PacketUtils.getPlayerConnection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.hooks.DefaultVersionHook;
|
||||
import me.dadus33.chatitem.utils.PacketUtils;
|
||||
import me.dadus33.chatitem.utils.ReflectionUtils;
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class INCChannel extends ChannelAbstract {
|
||||
|
||||
private final ChannelInboundHandler boundHandler;
|
||||
private ChannelPipeline pipeline;
|
||||
|
||||
public INCChannel(CustomPacketManager customPacketManager) {
|
||||
super(customPacketManager);
|
||||
boundHandler = new ChannelInboundHandler(customPacketManager);
|
||||
getFuturChannel().forEach((channelFuture) -> {
|
||||
pipeline = channelFuture.channel().pipeline();
|
||||
pipeline.addFirst(boundHandler);
|
||||
});
|
||||
}
|
||||
|
||||
public List<ChannelFuture> getFuturChannel() {
|
||||
try {
|
||||
Object dedicatedSrv = PacketUtils.getCraftServer();
|
||||
Object mcServer = dedicatedSrv.getClass().getMethod("getServer").invoke(dedicatedSrv);
|
||||
Object co = ReflectionUtils.getFirstWith(mcServer, PacketUtils.getNmsClass("MinecraftServer", "server."), PacketUtils.getNmsClass("ServerConnection", "network."));
|
||||
try {
|
||||
return (List<ChannelFuture>) ReflectionUtils.getPrivateField(co, "g");
|
||||
} catch (NoSuchFieldException e) {
|
||||
return (List<ChannelFuture>) ReflectionUtils.getPrivateField(co, "listeningChannels");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopPipelines() {
|
||||
pipeline.remove(boundHandler);
|
||||
boundHandler.clean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChannel(final Player player, String endChannelName) {
|
||||
getOrCreateAddChannelExecutor().execute(() -> {
|
||||
if(!player.isOnline())
|
||||
return;
|
||||
try {
|
||||
Channel channel = getChannel(player);
|
||||
// Managing outgoing packet (to the player)
|
||||
channel.pipeline().addAfter(KEY_HANDLER_SERVER, KEY_SERVER + endChannelName, new ChannelHandlerSent(player));
|
||||
|
||||
ChatItemPacket pa = ChannelInboundHandler.TMP.remove(channel);
|
||||
if(pa != null)
|
||||
DefaultVersionHook.PROTOCOL_PER_UUID.put(player.getUniqueId(), pa.getContent().getIntegers().readSafely(0, Version.getVersion().MAX_VER));
|
||||
} catch (NoSuchElementException e) {
|
||||
// appear when the player's channel isn't accessible because of reload.
|
||||
getPacketManager().getPlugin().getLogger().warning("Please, don't use reload, this can produce some problem. Currently, " + player.getName() + " isn't fully checked because of that. More details: " + e.getMessage() + " (NoSuchElementException)");
|
||||
} catch (IllegalArgumentException e) {
|
||||
if(e.getMessage().contains("Duplicate handler")) {
|
||||
removeChannel(player, endChannelName);
|
||||
addChannel(player, endChannelName);
|
||||
} else
|
||||
getPacketManager().getPlugin().getLogger().severe("Error while loading Packet channel. " + e.getMessage() + ". Please, prefer restart than reload.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChannel(Player player, String endChannelName) {
|
||||
getOrCreateRemoveChannelExecutor().execute(() -> {
|
||||
try {
|
||||
final Channel channel = getChannel(player);
|
||||
|
||||
if(channel.pipeline().get(KEY_SERVER + endChannelName) != null)
|
||||
channel.pipeline().remove(KEY_SERVER + endChannelName);
|
||||
} catch (Exception e) {
|
||||
ChatItem.getInstance().getLogger().warning("Failed to remove channel for " + player.getName() + ". Reason: " + e.getMessage() + " (" + e.getStackTrace()[0].toString() + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel getChannel(Player p) throws Exception {
|
||||
Object playerConnection = getPlayerConnection(p);
|
||||
Object networkManager = playerConnection.getClass().getField("networkManager").get(playerConnection);
|
||||
return new PacketContent(networkManager).getSpecificModifier(Channel.class).readSafely(0);//(Channel) networkManager.getClass().getDeclaredField("channel").get(networkManager);
|
||||
}
|
||||
|
||||
private class ChannelHandlerSent extends ChannelOutboundHandlerAdapter {
|
||||
|
||||
private final Player owner;
|
||||
|
||||
public ChannelHandlerSent(Player player) {
|
||||
this.owner = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception {
|
||||
ChatItemPacket nextPacket = getPacketManager().onPacketSent(PacketType.getType(packet.getClass().getSimpleName()), owner, packet);
|
||||
if(nextPacket != null && nextPacket.isCancelled())
|
||||
return;
|
||||
super.write(ctx, packet, promise);
|
||||
}
|
||||
}
|
||||
}
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
|
||||
|
||||
import static me.dadus33.chatitem.utils.PacketUtils.getPlayerConnection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
|
||||
import me.dadus33.chatitem.utils.PacketUtils;
|
||||
import me.dadus33.chatitem.utils.ReflectionUtils;
|
||||
import net.minecraft.util.io.netty.channel.Channel;
|
||||
import net.minecraft.util.io.netty.channel.ChannelFuture;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandler;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.util.io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import net.minecraft.util.io.netty.channel.ChannelInitializer;
|
||||
import net.minecraft.util.io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPipeline;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPromise;
|
||||
|
||||
public class NMUChannel extends ChannelAbstract {
|
||||
|
||||
private ChannelInboundHandlerAdapter boundHandler;
|
||||
private ChannelPipeline pipeline;
|
||||
|
||||
public NMUChannel(CustomPacketManager customPacketManager) {
|
||||
super(customPacketManager);
|
||||
try {
|
||||
Object dedicatedSrv = PacketUtils.getCraftServer();
|
||||
Object mcServer = dedicatedSrv.getClass().getMethod("getServer").invoke(dedicatedSrv);
|
||||
Object co = ReflectionUtils.getFirstWith(mcServer, PacketUtils.getNmsClass("MinecraftServer", "server."), PacketUtils.getNmsClass("ServerConnection", "network."));
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ChannelFuture> g = (List<ChannelFuture>) ReflectionUtils.getField(co, "g");
|
||||
g.forEach((channelFuture) -> {
|
||||
pipeline = channelFuture.channel().pipeline();
|
||||
pipeline.addFirst(boundHandler = new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
((Channel) msg).pipeline().addFirst(new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) {
|
||||
try {
|
||||
channel.eventLoop().submit(() -> {
|
||||
try {
|
||||
ChannelHandler interceptor = channel.pipeline().get(KEY_HANDSHAKE);
|
||||
// Inject our packet interceptor
|
||||
if (interceptor == null) {
|
||||
interceptor = new ChannelHandlerHandshakeReceive(channel);
|
||||
channel.pipeline().addBefore("packet_handler", KEY_HANDSHAKE, interceptor);
|
||||
}
|
||||
return interceptor;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Try again
|
||||
return channel.pipeline().get(KEY_HANDSHAKE);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
getPacketManager().getPlugin().getLogger().log(Level.SEVERE, "Cannot inject incomming channel " + channel, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopPipelines() {
|
||||
pipeline.remove(boundHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChannel(final Player player, String endChannelName) {
|
||||
getOrCreateAddChannelExecutor().execute(() -> {
|
||||
try {
|
||||
Channel channel = getChannel(player);
|
||||
// Managing outgoing packet (to the player)
|
||||
channel.pipeline().addAfter(KEY_HANDLER_SERVER, KEY_SERVER + endChannelName, new ChannelHandlerSent(player));
|
||||
} catch (NoSuchElementException e) {
|
||||
// appear when the player's channel isn't accessible because of reload.
|
||||
getPacketManager().getPlugin().getLogger().warning("Please, don't use reload, this can produce some problem. Currently, " + player.getName() + " isn't fully checked because of that. More details: " + e.getMessage() + " (NoSuchElementException)");
|
||||
} catch (IllegalArgumentException e) {
|
||||
if(e.getMessage().contains("Duplicate")) {
|
||||
removeChannel(player, endChannelName);
|
||||
addChannel(player, endChannelName);
|
||||
} else
|
||||
getPacketManager().getPlugin().getLogger().severe("Error while loading Packet channel. " + e.getMessage() + ". Please, prefer restart than reload.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChannel(Player player, String endChannelName) {
|
||||
getOrCreateRemoveChannelExecutor().execute(() -> {
|
||||
try {
|
||||
final Channel channel = getChannel(player);
|
||||
if(channel.pipeline().get(KEY_SERVER + endChannelName) != null)
|
||||
channel.pipeline().remove(KEY_SERVER + endChannelName);
|
||||
} catch (Exception e) {}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel getChannel(Player p) throws Exception {
|
||||
Object playerConnection = getPlayerConnection(p);
|
||||
Object networkManager = playerConnection.getClass().getField("networkManager").get(playerConnection);
|
||||
|
||||
for (Field field : networkManager.getClass().getDeclaredFields())
|
||||
if (field.getType().equals(Channel.class)) {
|
||||
field.setAccessible(true);
|
||||
return (Channel) field.get(networkManager);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class ChannelHandlerSent extends ChannelOutboundHandlerAdapter {
|
||||
|
||||
private final Player owner;
|
||||
|
||||
public ChannelHandlerSent(Player player) {
|
||||
this.owner = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception {
|
||||
ChatItemPacket nextPacket = getPacketManager().onPacketSent(PacketType.getType(packet.getClass().getSimpleName()), owner, packet);
|
||||
if(nextPacket != null && nextPacket.isCancelled())
|
||||
return;
|
||||
super.write(ctx, packet, promise);
|
||||
}
|
||||
}
|
||||
|
||||
private class ChannelHandlerHandshakeReceive extends ChannelInboundHandlerAdapter {
|
||||
|
||||
private final Channel channel;
|
||||
|
||||
public ChannelHandlerHandshakeReceive(Channel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object packet) {
|
||||
try {
|
||||
PacketType packetType = PacketType.getType(packet.getClass().getSimpleName());
|
||||
if(packetType != null && packetType == PacketType.Handshake.IS_SET_PROTOCOL) {
|
||||
getPacketManager().protocolVersionPerChannel.put(channel, new PacketContent(packet).getIntegers().readSafely(0, 0));
|
||||
}
|
||||
super.channelRead(ctx, packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.packets.protocollib;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.comphenix.protocol.PacketType.Play;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.v1.listeners.HandshakeListener;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
|
||||
|
||||
public class ProtocollibPacketManager extends PacketManager {
|
||||
|
||||
private final ProtocolManager protocolManager;
|
||||
|
||||
public ProtocollibPacketManager(ChatItem pl) {
|
||||
protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
protocolManager.addPacketListener(new PacketAdapter(pl, ListenerPriority.LOWEST, Arrays.asList(Play.Server.CHAT)) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if (p == null || e.isPlayerTemporary())
|
||||
return;
|
||||
ChatItemPacket packet = onPacketSent(PacketType.getType(e.getPacket().getHandle().getClass().getSimpleName()),
|
||||
p, e.getPacket().getHandle());
|
||||
if(packet == null)
|
||||
return;
|
||||
if(!e.isCancelled())
|
||||
e.setCancelled(packet.isCancelled());
|
||||
}
|
||||
});
|
||||
protocolManager.addPacketListener(new HandshakeListener(pl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
protocolManager.removePacketListeners(ChatItem.getInstance());
|
||||
}
|
||||
|
||||
public ChatItemPacket onPacketSent(PacketType type, Player sender, Object packet) {
|
||||
if(type == null)
|
||||
return null;
|
||||
ChatItemPacket customPacket = new ChatItemPacket(type, packet, sender);
|
||||
notifyHandlersSent(customPacket);
|
||||
return customPacket;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.playerversion;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
|
||||
public interface IPlayerVersion {
|
||||
|
||||
public int getProtocolVersion(Player p);
|
||||
|
||||
default Version getPlayerVersion(Player p) {
|
||||
return Version.getVersion(getProtocolVersion(p));
|
||||
}
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.playerversion.hooks;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.IPlayerVersion;
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
|
||||
public class DefaultVersionHook implements IPlayerVersion {
|
||||
|
||||
public static final HashMap<String, Integer> PROTOCOL_PER_ADDRESS = new HashMap<>();
|
||||
public static final HashMap<UUID, Integer> PROTOCOL_PER_UUID = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public int getProtocolVersion(Player p) {
|
||||
if(PROTOCOL_PER_UUID.containsKey(p.getUniqueId()))
|
||||
return PROTOCOL_PER_UUID.get(p.getUniqueId());
|
||||
return PROTOCOL_PER_ADDRESS.getOrDefault(Version.stringifyAdress(p.getAddress()), Version.getVersion().MAX_VER);
|
||||
}
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.playerversion.hooks;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.IPlayerVersion;
|
||||
import protocolsupport.api.ProtocolSupportAPI;
|
||||
|
||||
public class ProtocolSupportHook implements IPlayerVersion {
|
||||
|
||||
@Override
|
||||
public int getProtocolVersion(Player p) {
|
||||
return ProtocolSupportAPI.getProtocolVersion(p).getId();
|
||||
}
|
||||
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.playerversion.hooks;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.chatmanager.v1.playerversion.IPlayerVersion;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
public class ViaVersionHook implements IPlayerVersion {
|
||||
|
||||
@Override
|
||||
public int getProtocolVersion(Player p) {
|
||||
return Via.getAPI().getPlayerVersion(p.getUniqueId());
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.utils;
|
||||
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
|
||||
public class Item {
|
||||
private String id;
|
||||
private byte amount;
|
||||
private short data;
|
||||
private CompoundTag tag;
|
||||
|
||||
public CompoundTag getTag(){
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(CompoundTag newTag){
|
||||
this.tag = newTag;
|
||||
}
|
||||
|
||||
public void setId(String newId){
|
||||
this.id = newId;
|
||||
}
|
||||
|
||||
public void setData(short newData){
|
||||
data = newData;
|
||||
}
|
||||
|
||||
public String getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public short getData(){
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setAmount(byte newAmount){
|
||||
this.amount = newAmount;
|
||||
}
|
||||
|
||||
public byte getAmount(){
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.utils;
|
||||
|
||||
import static me.dadus33.chatitem.utils.Version.V1_10;
|
||||
import static me.dadus33.chatitem.utils.Version.V1_11;
|
||||
import static me.dadus33.chatitem.utils.Version.V1_8;
|
||||
import static me.dadus33.chatitem.utils.Version.V1_9;
|
||||
|
||||
public class ItemRewriter {
|
||||
|
||||
public static void remapIds(int server, int player, Item item) {
|
||||
if (areIdsCompatible(server, player)) {
|
||||
return;
|
||||
}
|
||||
if ((server >= V1_9.MIN_VER && player <= V1_8.MAX_VER) || (player >= V1_9.MIN_VER && server <= V1_8.MAX_VER)) {
|
||||
if ((server >= V1_9.MIN_VER && player <= V1_8.MAX_VER)) {
|
||||
ItemRewriter_1_9_TO_1_8.reversedToClient(item);
|
||||
return;
|
||||
}
|
||||
ItemRewriter_1_9_TO_1_8.toClient(item);
|
||||
return;
|
||||
}
|
||||
if ((server <= V1_10.MAX_VER && player >= V1_11.MIN_VER)
|
||||
|| (player <= V1_10.MAX_VER && server >= V1_11.MIN_VER)) {
|
||||
if (server <= V1_10.MAX_VER && player >= V1_11.MIN_VER) {
|
||||
ItemRewriter_1_11_TO_1_10.toClient(item);
|
||||
} else {
|
||||
ItemRewriter_1_11_TO_1_10.reverseToClient(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean areIdsCompatible(int version1, int version2) {
|
||||
if ((version1 >= V1_9.MIN_VER && version2 <= V1_8.MAX_VER)
|
||||
|| (version2 >= V1_9.MIN_VER && version1 <= V1_8.MAX_VER)) {
|
||||
return false;
|
||||
}
|
||||
if ((version1 <= V1_10.MAX_VER && version2 >= V1_11.MIN_VER)
|
||||
|| (version1 <= V1_10.MAX_VER && version2 >= V1_11.MIN_VER)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.utils;
|
||||
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
|
||||
|
||||
/**
|
||||
* Thanks to the developers of ViaVersion for this!
|
||||
*/
|
||||
public class ItemRewriter_1_11_TO_1_10 {
|
||||
private static BiMap<String, String> oldToNewNames = HashBiMap.create();
|
||||
|
||||
static {
|
||||
oldToNewNames.put("AreaEffectCloud", "minecraft:area_effect_cloud");
|
||||
oldToNewNames.put("ArmorStand", "minecraft:armor_stand");
|
||||
oldToNewNames.put("Arrow", "minecraft:arrow");
|
||||
oldToNewNames.put("Bat", "minecraft:bat");
|
||||
oldToNewNames.put("Blaze", "minecraft:blaze");
|
||||
oldToNewNames.put("Boat", "minecraft:boat");
|
||||
oldToNewNames.put("CaveSpider", "minecraft:cave_spider");
|
||||
oldToNewNames.put("Chicken", "minecraft:chicken");
|
||||
oldToNewNames.put("Cow", "minecraft:cow");
|
||||
oldToNewNames.put("Creeper", "minecraft:creeper");
|
||||
oldToNewNames.put("Donkey", "minecraft:donkey");
|
||||
oldToNewNames.put("DragonFireball", "minecraft:dragon_fireball");
|
||||
oldToNewNames.put("ElderGuardian", "minecraft:elder_guardian");
|
||||
oldToNewNames.put("EnderCrystal", "minecraft:ender_crystal");
|
||||
oldToNewNames.put("EnderDragon", "minecraft:ender_dragon");
|
||||
oldToNewNames.put("Enderman", "minecraft:enderman");
|
||||
oldToNewNames.put("Endermite", "minecraft:endermite");
|
||||
oldToNewNames.put("EntityHorse", "minecraft:horse");
|
||||
oldToNewNames.put("EyeOfEnderSignal", "minecraft:eye_of_ender_signal");
|
||||
oldToNewNames.put("FallingSand", "minecraft:falling_block");
|
||||
oldToNewNames.put("Fireball", "minecraft:fireball");
|
||||
oldToNewNames.put("FireworksRocketEntity", "minecraft:fireworks_rocket");
|
||||
oldToNewNames.put("Ghast", "minecraft:ghast");
|
||||
oldToNewNames.put("Giant", "minecraft:giant");
|
||||
oldToNewNames.put("Guardian", "minecraft:guardian");
|
||||
oldToNewNames.put("Husk", "minecraft:husk");
|
||||
oldToNewNames.put("Item", "minecraft:item");
|
||||
oldToNewNames.put("ItemFrame", "minecraft:item_frame");
|
||||
oldToNewNames.put("LavaSlime", "minecraft:magma_cube");
|
||||
oldToNewNames.put("LeashKnot", "minecraft:leash_knot");
|
||||
oldToNewNames.put("MinecartChest", "minecraft:chest_minecart");
|
||||
oldToNewNames.put("MinecartCommandBlock", "minecraft:commandblock_minecart");
|
||||
oldToNewNames.put("MinecartFurnace", "minecraft:furnace_minecart");
|
||||
oldToNewNames.put("MinecartHopper", "minecraft:hopper_minecart");
|
||||
oldToNewNames.put("MinecartRideable", "minecraft:minecart");
|
||||
oldToNewNames.put("MinecartSpawner", "minecraft:spawner_minecart");
|
||||
oldToNewNames.put("MinecartTNT", "minecraft:tnt_minecart");
|
||||
oldToNewNames.put("Mule", "minecraft:mule");
|
||||
oldToNewNames.put("MushroomCow", "minecraft:mooshroom");
|
||||
oldToNewNames.put("Ozelot", "minecraft:ocelot");
|
||||
oldToNewNames.put("Painting", "minecraft:painting");
|
||||
oldToNewNames.put("Pig", "minecraft:pig");
|
||||
oldToNewNames.put("PigZombie", "minecraft:zombie_pigman");
|
||||
oldToNewNames.put("PolarBear", "minecraft:polar_bear");
|
||||
oldToNewNames.put("PrimedTnt", "minecraft:tnt");
|
||||
oldToNewNames.put("Rabbit", "minecraft:rabbit");
|
||||
oldToNewNames.put("Sheep", "minecraft:sheep");
|
||||
oldToNewNames.put("Shulker", "minecraft:shulker");
|
||||
oldToNewNames.put("ShulkerBullet", "minecraft:shulker_bullet");
|
||||
oldToNewNames.put("Silverfish", "minecraft:silverfish");
|
||||
oldToNewNames.put("Skeleton", "minecraft:skeleton");
|
||||
oldToNewNames.put("SkeletonHorse", "minecraft:skeleton_horse");
|
||||
oldToNewNames.put("Slime", "minecraft:slime");
|
||||
oldToNewNames.put("SmallFireball", "minecraft:small_fireball");
|
||||
oldToNewNames.put("Snowball", "minecraft:snowball");
|
||||
oldToNewNames.put("SnowMan", "minecraft:snowman");
|
||||
oldToNewNames.put("SpectralArrow", "minecraft:spectral_arrow");
|
||||
oldToNewNames.put("Spider", "minecraft:spider");
|
||||
oldToNewNames.put("Squid", "minecraft:squid");
|
||||
oldToNewNames.put("Stray", "minecraft:stray");
|
||||
oldToNewNames.put("ThrownEgg", "minecraft:egg");
|
||||
oldToNewNames.put("ThrownEnderpearl", "minecraft:ender_pearl");
|
||||
oldToNewNames.put("ThrownExpBottle", "minecraft:xp_bottle");
|
||||
oldToNewNames.put("ThrownPotion", "minecraft:potion");
|
||||
oldToNewNames.put("Villager", "minecraft:villager");
|
||||
oldToNewNames.put("VillagerGolem", "minecraft:villager_golem");
|
||||
oldToNewNames.put("Witch", "minecraft:witch");
|
||||
oldToNewNames.put("WitherBoss", "minecraft:wither");
|
||||
oldToNewNames.put("WitherSkeleton", "minecraft:wither_skeleton");
|
||||
oldToNewNames.put("WitherSkull", "minecraft:wither_skull");
|
||||
oldToNewNames.put("Wolf", "minecraft:wolf");
|
||||
oldToNewNames.put("XPOrb", "minecraft:xp_orb");
|
||||
oldToNewNames.put("Zombie", "minecraft:zombie");
|
||||
oldToNewNames.put("ZombieHorse", "minecraft:zombie_horse");
|
||||
oldToNewNames.put("ZombieVillager", "minecraft:zombie_villager");
|
||||
}
|
||||
|
||||
static void toClient(Item item) {
|
||||
if (hasEntityTag(item)) {
|
||||
CompoundTag entityTag = item.getTag().get("EntityTag");
|
||||
if (entityTag.get("id") instanceof StringTag) {
|
||||
StringTag id = entityTag.get("id");
|
||||
if (oldToNewNames.containsKey(id.getValue())) {
|
||||
id.setValue(oldToNewNames.get(id.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void reverseToClient(Item item) {
|
||||
if (hasEntityTag(item)) {
|
||||
CompoundTag entityTag = item.getTag().get("EntityTag");
|
||||
if (entityTag.get("id") instanceof StringTag) {
|
||||
StringTag id = entityTag.get("id");
|
||||
if (oldToNewNames.containsKey(id.getValue())) {
|
||||
id.setValue(oldToNewNames.get(id.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static boolean hasEntityTag(Item item) {
|
||||
if (item != null && item.getId().equals("minecraft:spawn_egg")) { // Monster Egg
|
||||
CompoundTag tag = item.getTag();
|
||||
if (tag != null && tag.contains("EntityTag") && tag.get("EntityTag") instanceof CompoundTag) {
|
||||
if (((CompoundTag) tag.get("EntityTag")).get("id") instanceof StringTag) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,341 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v1.utils;
|
||||
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
/**
|
||||
* Thanks to the developers of ViaVersion for this!
|
||||
*/
|
||||
public class ItemRewriter_1_9_TO_1_8 {
|
||||
|
||||
private static final Map<String, Integer> ENTTIY_NAME_TO_ID = new HashMap<>();
|
||||
private static final Map<Integer, String> ENTTIY_ID_TO_NAME = new HashMap<>();
|
||||
private static final Map<String, Integer> POTION_NAME_TO_ID = new HashMap<>();
|
||||
private static final Map<Integer, String> POTION_ID_TO_NAME = new HashMap<>();
|
||||
|
||||
private static final Map<Integer, Integer> POTION_INDEX = new HashMap<>();
|
||||
|
||||
static {
|
||||
/* Entities */
|
||||
registerEntity(1, "Item");
|
||||
registerEntity(2, "XPOrb");
|
||||
registerEntity(7, "ThrownEgg");
|
||||
registerEntity(8, "LeashKnot");
|
||||
registerEntity(9, "Painting");
|
||||
registerEntity(10, "Arrow");
|
||||
registerEntity(11, "Snowball");
|
||||
registerEntity(12, "Fireball");
|
||||
registerEntity(13, "SmallFireball");
|
||||
registerEntity(14, "ThrownEnderpearl");
|
||||
registerEntity(15, "EyeOfEnderSignal");
|
||||
registerEntity(16, "ThrownPotion");
|
||||
registerEntity(17, "ThrownExpBottle");
|
||||
registerEntity(18, "ItemFrame");
|
||||
registerEntity(19, "WitherSkull");
|
||||
registerEntity(20, "PrimedTnt");
|
||||
registerEntity(21, "FallingSand");
|
||||
registerEntity(22, "FireworksRocketEntity");
|
||||
registerEntity(30, "ArmorStand");
|
||||
registerEntity(40, "MinecartCommandBlock");
|
||||
registerEntity(41, "Boat");
|
||||
registerEntity(42, "MinecartRideable");
|
||||
registerEntity(43, "MinecartChest");
|
||||
registerEntity(44, "MinecartFurnace");
|
||||
registerEntity(45, "MinecartTNT");
|
||||
registerEntity(46, "MinecartHopper");
|
||||
registerEntity(47, "MinecartSpawner");
|
||||
registerEntity(48, "Mob");
|
||||
registerEntity(49, "Monster");
|
||||
registerEntity(50, "Creeper");
|
||||
registerEntity(51, "Skeleton");
|
||||
registerEntity(52, "Spider");
|
||||
registerEntity(53, "Giant");
|
||||
registerEntity(54, "Zombie");
|
||||
registerEntity(55, "Slime");
|
||||
registerEntity(56, "Ghast");
|
||||
registerEntity(57, "PigZombie");
|
||||
registerEntity(58, "Enderman");
|
||||
registerEntity(59, "CaveSpider");
|
||||
registerEntity(60, "Silverfish");
|
||||
registerEntity(61, "Blaze");
|
||||
registerEntity(62, "LavaSlime");
|
||||
registerEntity(63, "EnderDragon");
|
||||
registerEntity(64, "WitherBoss");
|
||||
registerEntity(65, "Bat");
|
||||
registerEntity(66, "Witch");
|
||||
registerEntity(67, "Endermite");
|
||||
registerEntity(68, "Guardian");
|
||||
registerEntity(90, "Pig");
|
||||
registerEntity(91, "Sheep");
|
||||
registerEntity(92, "Cow");
|
||||
registerEntity(93, "Chicken");
|
||||
registerEntity(94, "Squid");
|
||||
registerEntity(95, "Wolf");
|
||||
registerEntity(96, "MushroomCow");
|
||||
registerEntity(97, "SnowMan");
|
||||
registerEntity(98, "Ozelot");
|
||||
registerEntity(99, "VillagerGolem");
|
||||
registerEntity(100, "EntityHorse");
|
||||
registerEntity(101, "Rabbit");
|
||||
registerEntity(120, "Villager");
|
||||
registerEntity(200, "EnderCrystal");
|
||||
|
||||
/* Potions */
|
||||
registerPotion(-1, "empty");
|
||||
registerPotion(0, "water");
|
||||
registerPotion(64, "mundane");
|
||||
registerPotion(32, "thick");
|
||||
registerPotion(16, "awkward");
|
||||
|
||||
registerPotion(8198, "night_vision");
|
||||
registerPotion(8262, "long_night_vision");
|
||||
|
||||
registerPotion(8206, "invisibility");
|
||||
registerPotion(8270, "long_invisibility");
|
||||
|
||||
registerPotion(8203, "leaping");
|
||||
registerPotion(8267, "long_leaping");
|
||||
registerPotion(8235, "strong_leaping");
|
||||
|
||||
registerPotion(8195, "fire_resistance");
|
||||
registerPotion(8259, "long_fire_resistance");
|
||||
|
||||
registerPotion(8194, "swiftness");
|
||||
registerPotion(8258, "long_swiftness");
|
||||
registerPotion(8226, "strong_swiftness");
|
||||
|
||||
registerPotion(8202, "slowness");
|
||||
registerPotion(8266, "long_slowness");
|
||||
|
||||
registerPotion(8205, "water_breathing");
|
||||
registerPotion(8269, "long_water_breathing");
|
||||
|
||||
registerPotion(8261, "healing");
|
||||
registerPotion(8229, "strong_healing");
|
||||
|
||||
registerPotion(8204, "harming");
|
||||
registerPotion(8236, "strong_harming");
|
||||
|
||||
registerPotion(8196, "poison");
|
||||
registerPotion(8260, "long_poison");
|
||||
registerPotion(8228, "strong_poison");
|
||||
|
||||
registerPotion(8193, "regeneration");
|
||||
registerPotion(8257, "long_regeneration");
|
||||
registerPotion(8225, "strong_regeneration");
|
||||
|
||||
registerPotion(8201, "strength");
|
||||
registerPotion(8265, "long_strength");
|
||||
registerPotion(8233, "strong_strength");
|
||||
|
||||
registerPotion(8200, "weakness");
|
||||
registerPotion(8264, "long_weakness");
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void toClient(Item item) {
|
||||
if (item != null) {
|
||||
if (item.getId().equals("minecraft:spawn_egg") && item.getData() != 0) { // Monster Egg
|
||||
CompoundTag tag = item.getTag();
|
||||
if (tag == null) {
|
||||
tag = new CompoundTag("tag");
|
||||
}
|
||||
CompoundTag entityTag = new CompoundTag("EntityTag");
|
||||
if (ENTTIY_ID_TO_NAME.containsKey((int) item.getData())) {
|
||||
StringTag id = new StringTag("id", ENTTIY_ID_TO_NAME.get((int) item.getData()));
|
||||
entityTag.put(id);
|
||||
tag.put(entityTag);
|
||||
}
|
||||
item.setTag(tag);
|
||||
item.setData((short) 0);
|
||||
}
|
||||
if (item.getId().equals("minecraft:potion")) { // Potion
|
||||
CompoundTag tag = item.getTag();
|
||||
if (tag == null) {
|
||||
tag = new CompoundTag("tag");
|
||||
}
|
||||
if (item.getData() >= 16384) {
|
||||
item.setId("minecraft:splash_potion"); // splash id
|
||||
item.setData((short) (item.getData() - 8192));
|
||||
}
|
||||
String name = potionNameFromDamage(item.getData());
|
||||
StringTag potion = new StringTag("Potion", "minecraft:" + name);
|
||||
tag.put(potion);
|
||||
item.setTag(tag);
|
||||
item.setData((short) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void reversedToClient(Item item) {
|
||||
if (item != null) {
|
||||
if (item.getId().equals("minecraft:spawn_egg") && item.getData() == 0) { // Monster Egg
|
||||
CompoundTag tag = item.getTag();
|
||||
int data = 0;
|
||||
if(tag != null) {
|
||||
if (tag.get("EntityTag") instanceof CompoundTag) {
|
||||
CompoundTag entityTag = tag.get("EntityTag");
|
||||
if (entityTag.get("id") instanceof StringTag) {
|
||||
StringTag id = entityTag.get("id");
|
||||
if (ENTTIY_NAME_TO_ID.containsKey(id.getValue()))
|
||||
data = ENTTIY_NAME_TO_ID.get(id.getValue());
|
||||
}
|
||||
tag.remove("EntityTag");
|
||||
}
|
||||
}
|
||||
item.setTag(tag);
|
||||
item.setData((short) data);
|
||||
}
|
||||
if (item.getId().equals("minecraft:potion")) { // Potion
|
||||
CompoundTag tag = item.getTag();
|
||||
int data = 0;
|
||||
if(tag != null) {
|
||||
if (tag.get("Potion") instanceof StringTag) {
|
||||
StringTag potion = tag.get("Potion");
|
||||
String potionName = potion.getValue().replace("minecraft:", "");
|
||||
if (POTION_NAME_TO_ID.containsKey(potionName)) {
|
||||
data = POTION_NAME_TO_ID.get(potionName);
|
||||
}
|
||||
tag.remove("Potion");
|
||||
}
|
||||
}
|
||||
item.setTag(tag);
|
||||
item.setData((short) data);
|
||||
}
|
||||
// Splash potion
|
||||
if (item.getId().equals("minecraft:splash_potion")) {
|
||||
CompoundTag tag = item.getTag();
|
||||
int data = 0;
|
||||
item.setId("minecraft:potion"); // Potion
|
||||
if(tag != null) {
|
||||
if (tag.get("Potion") instanceof StringTag) {
|
||||
StringTag potion = tag.get("Potion");
|
||||
String potionName = potion.getValue().replace("minecraft:", "");
|
||||
if (POTION_NAME_TO_ID.containsKey(potionName)) {
|
||||
data = POTION_NAME_TO_ID.get(potionName) + 8192;
|
||||
}
|
||||
tag.remove("Potion");
|
||||
}
|
||||
}
|
||||
item.setTag(tag);
|
||||
item.setData((short) data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String potionNameFromDamage(short damage) {
|
||||
String cached = POTION_ID_TO_NAME.get((int) damage);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
if (damage == 0) {
|
||||
return "water";
|
||||
}
|
||||
|
||||
int effect = damage & 0xF;
|
||||
int name = damage & 0x3F;
|
||||
boolean enhanced = (damage & 0x20) > 0;
|
||||
boolean extended = (damage & 0x40) > 0;
|
||||
|
||||
boolean canEnhance = true;
|
||||
boolean canExtend = true;
|
||||
|
||||
String id;
|
||||
switch (effect) {
|
||||
case 1:
|
||||
id = "regeneration";
|
||||
break;
|
||||
case 2:
|
||||
id = "swiftness";
|
||||
break;
|
||||
case 3:
|
||||
id = "fire_resistance";
|
||||
canEnhance = false;
|
||||
break;
|
||||
case 4:
|
||||
id = "poison";
|
||||
break;
|
||||
case 5:
|
||||
id = "healing";
|
||||
canExtend = false;
|
||||
break;
|
||||
case 6:
|
||||
id = "night_vision";
|
||||
canEnhance = false;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
id = "weakness";
|
||||
canEnhance = false;
|
||||
break;
|
||||
case 9:
|
||||
id = "strength";
|
||||
break;
|
||||
case 10:
|
||||
id = "slowness";
|
||||
canEnhance = false;
|
||||
break;
|
||||
case 11:
|
||||
id = "leaping";
|
||||
break;
|
||||
case 12:
|
||||
id = "harming";
|
||||
canExtend = false;
|
||||
break;
|
||||
case 13:
|
||||
id = "water_breathing";
|
||||
canEnhance = false;
|
||||
break;
|
||||
case 14:
|
||||
id = "invisibility";
|
||||
canEnhance = false;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
canEnhance = false;
|
||||
canExtend = false;
|
||||
switch (name) {
|
||||
case 0:
|
||||
id = "mundane";
|
||||
break;
|
||||
case 16:
|
||||
id = "awkward";
|
||||
break;
|
||||
case 32:
|
||||
id = "thick";
|
||||
break;
|
||||
default:
|
||||
id = "empty";
|
||||
}
|
||||
}
|
||||
|
||||
if (effect > 0) {
|
||||
if (canEnhance && enhanced) {
|
||||
id = "strong_" + id;
|
||||
} else if (canExtend && extended) {
|
||||
id = "long_" + id;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private static void registerEntity(Integer id, String name) {
|
||||
ENTTIY_ID_TO_NAME.put(id, name);
|
||||
ENTTIY_NAME_TO_ID.put(name, id);
|
||||
}
|
||||
|
||||
private static void registerPotion(Integer id, String name) {
|
||||
POTION_INDEX.put(id, POTION_ID_TO_NAME.size());
|
||||
POTION_ID_TO_NAME.put(id, name);
|
||||
POTION_NAME_TO_ID.put(name, id);
|
||||
}
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v2;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.ChatManager;
|
||||
import me.dadus33.chatitem.itemnamer.NamerManager;
|
||||
import me.dadus33.chatitem.playernamer.PlayerNamerManager;
|
||||
import me.dadus33.chatitem.utils.ColorManager;
|
||||
import me.dadus33.chatitem.utils.PacketUtils;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
import me.dadus33.chatitem.utils.Version;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.HoverEvent.Action;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ChatListener implements Listener {
|
||||
|
||||
public final static char SEPARATOR = ((char) 0x0007);
|
||||
private final static String NAME = "{name}";
|
||||
private final static String AMOUNT = "{amount}";
|
||||
private final static String TIMES = "{times}";
|
||||
private final static String LEFT = "{remaining}";
|
||||
private final HashMap<String, Long> COOLDOWNS = new HashMap<>();
|
||||
private ChatListenerChatManager manage;
|
||||
private Method saveMethod;
|
||||
|
||||
public ChatListener(ChatListenerChatManager manage) {
|
||||
this.manage = manage;
|
||||
|
||||
try {
|
||||
Class<?> nbtTag = PacketUtils.getNmsClass("NBTTagCompound", "nbt.");
|
||||
Class<?> itemClass = PacketUtils.getNmsClass("ItemStack", "world.item.");
|
||||
for (Method m : itemClass.getDeclaredMethods()) {
|
||||
if (m.getParameterTypes().length == 1) {
|
||||
if (m.getParameterTypes()[0].equals(nbtTag) && m.getReturnType().equals(nbtTag)) {
|
||||
saveMethod = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
if (saveMethod == null)
|
||||
ChatItem.getInstance().getLogger().info("Failed to find save method. Using default system...");
|
||||
else
|
||||
ChatItem.getInstance().getLogger().info("Save method founded: " + saveMethod.getName() + ".");
|
||||
}
|
||||
|
||||
public Storage getStorage() {
|
||||
return manage.getStorage();
|
||||
}
|
||||
|
||||
private String calculateTime(long seconds) {
|
||||
if (seconds < 60) {
|
||||
return seconds + getStorage().SECONDS;
|
||||
}
|
||||
if (seconds < 3600) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int minutes = (int) seconds / 60;
|
||||
builder.append(minutes).append(getStorage().MINUTES);
|
||||
int secs = (int) seconds - minutes * 60;
|
||||
if (secs != 0) {
|
||||
builder.append(" ").append(secs).append(getStorage().SECONDS);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int hours = (int) seconds / 3600;
|
||||
builder.append(hours).append(getStorage().HOURS);
|
||||
int minutes = (int) (seconds / 60) - (hours * 60);
|
||||
if (minutes != 0) {
|
||||
builder.append(" ").append(minutes).append(getStorage().MINUTES);
|
||||
}
|
||||
int secs = (int) (seconds - ((seconds / 60) * 60));
|
||||
if (secs != 0) {
|
||||
builder.append(" ").append(secs).append(getStorage().SECONDS);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onChat(AsyncPlayerChatEvent e) {
|
||||
if (e.isCancelled()) {
|
||||
if (ChatItem.getInstance().getChatManager().size() == 1) { // only chat
|
||||
String msg = e.getMessage().toLowerCase();
|
||||
for (String rep : getStorage().PLACEHOLDERS) {
|
||||
if (msg.contains(rep)) {
|
||||
ChatItem.debug(
|
||||
"You choose 'chat' manager but it seems to don't be the good choice. More informations here: https://github.com/dadus33-plugins/ChatItem/wiki");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ChatItem.debug("Chat cancelled for " + e.getPlayer().getName());
|
||||
return;
|
||||
}
|
||||
Player p = e.getPlayer();
|
||||
for (String rep : getStorage().PLACEHOLDERS) {
|
||||
if (e.getMessage().contains(rep + ChatManager.SEPARATOR + p.getName())) { // already managed by v1
|
||||
return;
|
||||
}
|
||||
}
|
||||
boolean found = false;
|
||||
|
||||
for (String key : e.getMessage().split(" ")) {
|
||||
if (found)
|
||||
break;
|
||||
for (String rep : getStorage().PLACEHOLDERS) {
|
||||
if (key.equalsIgnoreCase(rep)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
if (getStorage().PERMISSION_ENABLED && !p.hasPermission(getStorage().PERMISSION_NAME)) {
|
||||
if (!getStorage().LET_MESSAGE_THROUGH) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
if (!getStorage().NO_PERMISSION_MESSAGE.isEmpty() && getStorage().SHOW_NO_PERM_NORMAL) {
|
||||
p.sendMessage(getStorage().NO_PERMISSION_MESSAGE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (p.getItemInHand().getType().equals(Material.AIR)) {
|
||||
if (getStorage().DENY_IF_NO_ITEM) {
|
||||
e.setCancelled(true);
|
||||
if (!getStorage().DENY_MESSAGE.isEmpty())
|
||||
e.getPlayer().sendMessage(getStorage().DENY_MESSAGE);
|
||||
return;
|
||||
}
|
||||
if (getStorage().HAND_DISABLED) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (getStorage().COOLDOWN > 0 && !p.hasPermission("chatitem.ignore-cooldown")) {
|
||||
if (COOLDOWNS.containsKey(p.getName())) {
|
||||
long start = COOLDOWNS.get(p.getName());
|
||||
long current = System.currentTimeMillis() / 1000;
|
||||
long elapsed = current - start;
|
||||
if (elapsed >= getStorage().COOLDOWN) {
|
||||
COOLDOWNS.remove(p.getName());
|
||||
} else {
|
||||
if (!getStorage().LET_MESSAGE_THROUGH) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
if (!getStorage().COOLDOWN_MESSAGE.isEmpty()) {
|
||||
long left = (start + getStorage().COOLDOWN) - current;
|
||||
p.sendMessage(getStorage().COOLDOWN_MESSAGE.replace(LEFT, calculateTime(left)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
e.setCancelled(true);
|
||||
String format = e.getFormat(), defMsg = e.getMessage();
|
||||
Bukkit.getConsoleSender().sendMessage(String.format(e.getFormat(), e.getPlayer().getDisplayName(), defMsg)); // show
|
||||
// in
|
||||
// log
|
||||
boolean isAlreadyParsed = false;
|
||||
if (format.contains("%1$s") && format.contains("%2$s")) // message not parsed but not default way
|
||||
isAlreadyParsed = false;
|
||||
if (format.equalsIgnoreCase(defMsg)) // is message already parsed
|
||||
isAlreadyParsed = true;
|
||||
if (format.equalsIgnoreCase("<%1$s> %2$s")) // default MC message
|
||||
isAlreadyParsed = false;
|
||||
String msg = isAlreadyParsed ? format : String.format(format, p.getDisplayName(), defMsg);
|
||||
ItemStack item = p.getItemInHand();
|
||||
ItemMeta meta = item == null ? null : item.getItemMeta();
|
||||
if(Version.getVersion().isNewerOrEquals(Version.V1_16))
|
||||
e.getRecipients().forEach((pl) -> showWithHex(pl, p, item, meta, format, msg));
|
||||
else
|
||||
e.getRecipients().forEach((pl) -> showWithoutHex(pl, p, item, meta, format, msg));
|
||||
}
|
||||
|
||||
private void showWithoutHex(Player to, Player origin, ItemStack item, ItemMeta meta, String format, String msg) {
|
||||
ComponentBuilder component = new ComponentBuilder();
|
||||
ChatColor color = ChatColor.getByChar(getColorChat(format));
|
||||
for (String args : msg.split(" ")) {
|
||||
if (getStorage().PLACEHOLDERS.contains(args)) {
|
||||
if (meta != null) {
|
||||
ComponentBuilder itemComponent = new ComponentBuilder(
|
||||
ChatListener.styleItem(to, item, getStorage()));
|
||||
String itemJson = convertItemStackToJson(item);
|
||||
itemComponent.event(new HoverEvent(Action.SHOW_ITEM, new ComponentBuilder(itemJson).create()));
|
||||
component.append(itemComponent.create());
|
||||
} else {
|
||||
if (getStorage().HAND_DISABLED)
|
||||
component.append(color + args);
|
||||
else {
|
||||
String handName = getStorage().HAND_NAME;
|
||||
ComponentBuilder handComp = new ComponentBuilder();
|
||||
ComponentBuilder handTooltip = new ComponentBuilder();
|
||||
int stay = getStorage().HAND_TOOLTIP.size();
|
||||
for (String line : getStorage().HAND_TOOLTIP) {
|
||||
stay--;
|
||||
handTooltip.append(line.replace("{name}", origin.getName()).replace("{display-name}",
|
||||
origin.getDisplayName()));
|
||||
if (stay > 0)
|
||||
handTooltip.append("\n");
|
||||
}
|
||||
handComp.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, handTooltip.create()));
|
||||
if (handName.contains("{name}")) {
|
||||
String[] splitted = handName.split("{name}");
|
||||
for (int i = 0; i < (splitted.length - 1); i++) {
|
||||
handComp.append(new ComponentBuilder(splitted[i]).create());
|
||||
handComp.append(PlayerNamerManager.getPlayerNamer().getName(origin));
|
||||
}
|
||||
handComp.append(new ComponentBuilder(splitted[splitted.length - 1]).create());
|
||||
} else
|
||||
handComp.append(handName.replace("{display-name}", origin.getDisplayName()));
|
||||
component.append(handComp.create());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
component.append(color + args);
|
||||
}
|
||||
component.append(" ");
|
||||
char maybeNextCode = getColorChat(args);
|
||||
if (maybeNextCode != 'r') {
|
||||
color = ChatColor.getByChar(maybeNextCode);
|
||||
}
|
||||
}
|
||||
to.spigot().sendMessage(component.create());
|
||||
}
|
||||
|
||||
private void showWithHex(Player to, Player origin, ItemStack item, ItemMeta meta, String format, String msg) {
|
||||
ComponentBuilder component = new ComponentBuilder();
|
||||
for (String args : msg.split(" ")) {
|
||||
if (getStorage().PLACEHOLDERS.contains(args)) {
|
||||
if (meta != null) {
|
||||
ComponentBuilder itemComponent = new ComponentBuilder(
|
||||
ChatListener.styleItem(to, item, getStorage()));
|
||||
String itemJson = convertItemStackToJson(item);
|
||||
itemComponent.event(new HoverEvent(Action.SHOW_ITEM, new ComponentBuilder(itemJson).create()));
|
||||
component.append(itemComponent.create());
|
||||
} else {
|
||||
if (getStorage().HAND_DISABLED)
|
||||
component.append(ColorManager.getChatWithHex(args));
|
||||
else {
|
||||
String handName = getStorage().HAND_NAME;
|
||||
ComponentBuilder handComp = new ComponentBuilder();
|
||||
ComponentBuilder handTooltip = new ComponentBuilder();
|
||||
int stay = getStorage().HAND_TOOLTIP.size();
|
||||
for (String line : getStorage().HAND_TOOLTIP) {
|
||||
stay--;
|
||||
handTooltip.append(line.replace("{name}", origin.getName()).replace("{display-name}",
|
||||
origin.getDisplayName()));
|
||||
if (stay > 0)
|
||||
handTooltip.append("\n");
|
||||
}
|
||||
handComp.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, handTooltip.create()));
|
||||
if (handName.contains("{name}")) {
|
||||
String[] splitted = handName.split("{name}");
|
||||
for (int i = 0; i < (splitted.length - 1); i++) {
|
||||
handComp.append(new ComponentBuilder(splitted[i]).create());
|
||||
handComp.append(PlayerNamerManager.getPlayerNamer().getName(origin));
|
||||
}
|
||||
handComp.append(new ComponentBuilder(splitted[splitted.length - 1]).create());
|
||||
} else
|
||||
handComp.append(handName.replace("{display-name}", origin.getDisplayName()));
|
||||
component.append(handComp.create());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
component.append(ColorManager.getChatWithHex(args));
|
||||
}
|
||||
component.append(" ");
|
||||
}
|
||||
to.spigot().sendMessage(component.create());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an {@link org.bukkit.inventory.ItemStack} to a Json string for
|
||||
* sending with {@link net.md_5.bungee.api.chat.BaseComponent}'s.
|
||||
*
|
||||
* @param itemStack the item to convert
|
||||
* @return the Json string representation of the item
|
||||
*/
|
||||
public String convertItemStackToJson(ItemStack itemStack) {
|
||||
try {
|
||||
Class<?> nbtTag = PacketUtils.getNmsClass("NBTTagCompound", "nbt.");
|
||||
Class<?> craftItemClass = PacketUtils.getObcClass("inventory.CraftItemStack");
|
||||
Object nmsNbtTagCompoundObj = nbtTag.newInstance();
|
||||
if (saveMethod == null) {
|
||||
Object nmsItemStackObj = craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, itemStack);
|
||||
return nmsItemStackObj.getClass().getMethod("save", nbtTag)
|
||||
.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString();
|
||||
} else {
|
||||
Object nmsItemStackObj = craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, itemStack);
|
||||
return saveMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest color chat
|
||||
*
|
||||
* @param msg the message that contains color
|
||||
* @return the char of the color or 'r' if nothing found
|
||||
*/
|
||||
private char getColorChat(String msg) {
|
||||
if (msg.length() < 2)
|
||||
return 'r';
|
||||
for (int i = msg.length() - 2; i > 0; i--) {
|
||||
char s = msg.charAt(i);
|
||||
if (ChatColor.COLOR_CHAR == s) {
|
||||
return msg.charAt(i + 1);
|
||||
}
|
||||
}
|
||||
return 'r';
|
||||
}
|
||||
|
||||
public static String styleItem(Player p, ItemStack item, Storage c) {
|
||||
String replacer = c.NAME_FORMAT;
|
||||
String amount = c.AMOUNT_FORMAT;
|
||||
|
||||
if (item.getAmount() == 1) {
|
||||
if (c.FORCE_ADD_AMOUNT) {
|
||||
amount = amount.replace(TIMES, "1");
|
||||
replacer = replacer.replace(AMOUNT, amount);
|
||||
} else {
|
||||
replacer = replacer.replace(AMOUNT, "");
|
||||
}
|
||||
} else {
|
||||
amount = amount.replace(TIMES, String.valueOf(item.getAmount()));
|
||||
replacer = replacer.replace(AMOUNT, amount);
|
||||
}
|
||||
replacer = replacer.replace(NAME, NamerManager.getName(p, item, c));
|
||||
return replacer;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package me.dadus33.chatitem.chatmanager.v2;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.chatmanager.ChatManager;
|
||||
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulator;
|
||||
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulatorCurrent;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public class ChatListenerChatManager extends ChatManager {
|
||||
|
||||
private final JSONManipulatorCurrent jsonManipulator;
|
||||
private final ChatListener chatListener;
|
||||
private boolean baseComponentAvailable = true;
|
||||
|
||||
public ChatListenerChatManager(ChatItem pl) {
|
||||
jsonManipulator = new JSONManipulatorCurrent();
|
||||
chatListener = new ChatListener(this);
|
||||
|
||||
//Check for existence of BaseComponent class (only on spigot)
|
||||
try {
|
||||
Class.forName("net.md_5.bungee.api.chat.BaseComponent");
|
||||
} catch (ClassNotFoundException e) {
|
||||
baseComponentAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "ChatListener";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "chat";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(ChatItem pl, Storage s) {
|
||||
super.load(pl, s);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(chatListener, pl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(ChatItem pl) {
|
||||
HandlerList.unregisterAll(chatListener);
|
||||
}
|
||||
|
||||
public JSONManipulator getManipulator(){
|
||||
/*
|
||||
We used to have 2 kinds of JSONManipulators because of my bad understanding of the 1.7 way of parsing JSON chat
|
||||
The interface should however stay as there might be great changes in future versions in JSON parsing (most likely 1.13)
|
||||
*/
|
||||
return jsonManipulator;
|
||||
//We just return a new one whenever requested for the moment, should implement a cache of some sort some time though
|
||||
}
|
||||
|
||||
public boolean supportsChatComponentApi(){
|
||||
return baseComponentAvailable;
|
||||
}
|
||||
}
|
||||
+6
-4
@@ -1,16 +1,18 @@
|
||||
package me.dadus33.chatitem.commands;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
|
||||
public class CIReloadCommand implements CommandExecutor {
|
||||
/**
|
||||
* Created by Vlad on 30.09.2016.
|
||||
*/
|
||||
public class CIReload implements CommandExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
||||
ChatItem.reload(sender);
|
||||
ChatItem.reload(sender);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package me.dadus33.chatitem.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.listeners.InventoryListener;
|
||||
import me.dadus33.chatitem.utils.Messages;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
|
||||
public class ChatItemCommand implements CommandExecutor, TabExecutor {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
||||
if(!(sender instanceof Player)) {
|
||||
Messages.sendMessage(sender, "only-players");
|
||||
return false;
|
||||
}
|
||||
Player p = (Player) sender;
|
||||
if(args.length == 0) {
|
||||
Messages.sendMessage(p, "chatitem-cmd.help");
|
||||
} else if(args[0].equalsIgnoreCase("admin")) {
|
||||
InventoryListener.open(p);
|
||||
} else if(args[0].equalsIgnoreCase("reload")) {
|
||||
ChatItem.reload(sender);
|
||||
} else if(args[0].equalsIgnoreCase("link") || args[0].equalsIgnoreCase("links")) {
|
||||
ConfigurationSection config = ChatItem.getInstance().getConfig().getConfigurationSection("messages.chatitem-cmd.links");
|
||||
TextComponent text = new TextComponent(Storage.color(config.getString("begin")));
|
||||
for(String key : config.getConfigurationSection("list").getKeys(false)) {
|
||||
ConfigurationSection linkConfig = config.getConfigurationSection("list." + key);
|
||||
TextComponent linkComp = new TextComponent(Storage.color(linkConfig.getString("message")));
|
||||
String hover = Storage.color(linkConfig.getString("hover"));
|
||||
if(hover != null)
|
||||
linkComp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hover).create()));
|
||||
String link = linkConfig.getString("link");
|
||||
if(link != null)
|
||||
linkComp.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, link));
|
||||
text.addExtra(linkComp);
|
||||
}
|
||||
p.spigot().sendMessage(text);
|
||||
} else {
|
||||
Messages.sendMessage(p, "chatitem-cmd.help");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] arg) {
|
||||
List<String> list = new ArrayList<>();
|
||||
String prefix = arg[arg.length - 1].toLowerCase(Locale.ROOT);
|
||||
for(String s : Arrays.asList("help", "admin", "reload"))
|
||||
if(prefix.isEmpty() || s.startsWith(prefix))
|
||||
list.add(s);
|
||||
return list.isEmpty() ? null : list;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package me.dadus33.chatitem.filters;
|
||||
|
||||
import static org.apache.logging.log4j.core.Filter.Result.NEUTRAL;
|
||||
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Marker;
|
||||
@@ -12,13 +11,16 @@ import org.apache.logging.log4j.message.Message;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.chatmanager.v2.ChatListener;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static org.apache.logging.log4j.core.Filter.Result.NEUTRAL;
|
||||
|
||||
|
||||
public class Log4jFilter implements Filter {
|
||||
|
||||
private Storage c;
|
||||
private boolean stopped;
|
||||
private final static CopyOnWriteArrayList<String> ls = new CopyOnWriteArrayList<>();
|
||||
public Storage c;
|
||||
|
||||
public Log4jFilter(Storage st){
|
||||
c = st;
|
||||
@@ -55,26 +57,43 @@ public class Log4jFilter implements Filter {
|
||||
public Result filter(LogEvent logEvent) {
|
||||
return checkMessage(logEvent.getMessage().getFormattedMessage());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
stopped = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
// seems to be required
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
return !this.stopped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStopped() {
|
||||
return this.stopped;
|
||||
}
|
||||
|
||||
private Result checkMessage(String msg){
|
||||
if(msg==null){
|
||||
return Result.NEUTRAL;
|
||||
}
|
||||
for(String placeholder : c.PLACEHOLDERS){
|
||||
if(msg.contains(placeholder)){
|
||||
ls.add(msg);
|
||||
for(Player p : Bukkit.getOnlinePlayers()){
|
||||
if(msg.contains(ChatListener.SEPARATOR +p.getName())){
|
||||
msg = msg.replaceAll("\\p{C}", "");
|
||||
if(msg.endsWith(p.getName()) || msg.lastIndexOf(p.getName())+2+p.getName().length()>=msg.length()){
|
||||
return Result.DENY;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return Result.NEUTRAL;
|
||||
|
||||
}
|
||||
|
||||
public void setStorage(Storage nst){
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package me.dadus33.chatitem.itemnamer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public interface INamer {
|
||||
|
||||
/**
|
||||
* Get priority of this namer.<br>
|
||||
* Get first name that is not null, with this order:
|
||||
* - MAJOR
|
||||
*
|
||||
*
|
||||
* @return priority
|
||||
*/
|
||||
Priority getPriority();
|
||||
|
||||
/**
|
||||
* Get the name of the item thanks to this namer.
|
||||
*
|
||||
* @param item the item to get the name
|
||||
* @param storage the actual config
|
||||
* @return the name or null if can't find a name
|
||||
*/
|
||||
String getName(Player p, ItemStack item, Storage storage);
|
||||
|
||||
public static enum Priority {
|
||||
MAJOR(4),
|
||||
IMPORTANT(3),
|
||||
MEDIUM(2),
|
||||
SMALL(1),
|
||||
MINOR(0);
|
||||
|
||||
private final int priority;
|
||||
|
||||
private Priority(int priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public int getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public static List<Priority> getOrderedPriorities() {
|
||||
return Arrays.asList(values()).stream().sorted((p1, p2) -> p2.getPriority() - p1.getPriority()).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package me.dadus33.chatitem.itemnamer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.itemnamer.INamer.Priority;
|
||||
import me.dadus33.chatitem.itemnamer.hook.ChatItemTranslationNamer;
|
||||
import me.dadus33.chatitem.itemnamer.hook.DefaultNamer;
|
||||
import me.dadus33.chatitem.itemnamer.hook.ItemDisplayNamer;
|
||||
import me.dadus33.chatitem.itemnamer.hook.LangUtilsNamer;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public class NamerManager {
|
||||
|
||||
private static final HashMap<Priority, List<INamer>> NAMER_PER_PRIORITY = new HashMap<>();
|
||||
|
||||
public static void load(ChatItem pl) {
|
||||
NAMER_PER_PRIORITY.clear();
|
||||
|
||||
StringJoiner sj = new StringJoiner(", ");
|
||||
PluginManager pm = Bukkit.getPluginManager();
|
||||
if(pm.getPlugin("LangUtils") != null) {
|
||||
addNamer(new LangUtilsNamer());
|
||||
sj.add("LangUtils");
|
||||
}
|
||||
if(sj.length() > 0)
|
||||
pl.getLogger().info("Loaded namer for plugin " + sj.toString() + ".");
|
||||
|
||||
addNamer(new ChatItemTranslationNamer());
|
||||
addNamer(new ItemDisplayNamer());
|
||||
addNamer(new DefaultNamer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add namer according to his {@link INamer#getPriority()}'s value
|
||||
*
|
||||
* @param namer the namer to add
|
||||
*/
|
||||
public static void addNamer(INamer namer) {
|
||||
List<INamer> namers = getOrCreate(namer.getPriority());
|
||||
namers.add(namer);
|
||||
}
|
||||
|
||||
private static List<INamer> getOrCreate(Priority p){
|
||||
return NAMER_PER_PRIORITY.computeIfAbsent(p, (a) -> new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of this item, according to this storage.
|
||||
*
|
||||
* @param item
|
||||
* @param storage
|
||||
* @return the name (should NOT return null)
|
||||
*/
|
||||
public static String getName(Player p, ItemStack item, Storage storage) {
|
||||
for(Priority pr : Priority.getOrderedPriorities()) {
|
||||
List<INamer> allNamers = NAMER_PER_PRIORITY.get(pr);
|
||||
if(allNamers == null || allNamers.isEmpty())
|
||||
continue;
|
||||
for(INamer namer : allNamers) {
|
||||
String tmpName = namer.getName(p, item, storage);
|
||||
if(tmpName != null)
|
||||
return tmpName;
|
||||
}
|
||||
}
|
||||
return null; // this should NEVER append
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package me.dadus33.chatitem.itemnamer.hook;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import me.dadus33.chatitem.itemnamer.INamer;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public class ChatItemTranslationNamer implements INamer {
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.SMALL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(Player p, ItemStack item, Storage storage) {
|
||||
HashMap<Short, String> translationSection = storage.TRANSLATIONS.get(item.getType().name());
|
||||
if (translationSection != null) {
|
||||
@SuppressWarnings("deprecation")
|
||||
String translated = translationSection.get(item.getDurability());
|
||||
if (translated != null) {
|
||||
return translated;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package me.dadus33.chatitem.itemnamer.hook;
|
||||
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import me.dadus33.chatitem.itemnamer.INamer;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public class DefaultNamer implements INamer {
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.MINOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(Player p, ItemStack item, Storage storage) {
|
||||
Material m = item.getType();
|
||||
return m.equals(Material.TNT) ? "TNT" : WordUtils.capitalize(m.name().replaceAll("_", " ").toLowerCase());
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package me.dadus33.chatitem.itemnamer.hook;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import me.dadus33.chatitem.itemnamer.INamer;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public class ItemDisplayNamer implements INamer {
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.MEDIUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(Player p, ItemStack item, Storage storage) {
|
||||
if(item.hasItemMeta() && item.getItemMeta().hasDisplayName()) {
|
||||
String name = item.getItemMeta().getDisplayName();
|
||||
return storage.COLOR_IF_ALREADY_COLORED ? ChatColor.stripColor(name) : name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package me.dadus33.chatitem.itemnamer.hook;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.meowj.langutils.lang.LanguageHelper;
|
||||
|
||||
import me.dadus33.chatitem.itemnamer.INamer;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public class LangUtilsNamer implements INamer {
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.IMPORTANT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(Player p, ItemStack item, Storage storage) {
|
||||
return LanguageHelper.getItemName(item, p);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package me.dadus33.chatitem.json;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
|
||||
public interface JSONManipulator {
|
||||
String parse(String json, String[] replacements, ItemStack item, String repl) throws InvocationTargetException, IllegalAccessException, InstantiationException;
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
package me.dadus33.chatitem.json;
|
||||
|
||||
|
||||
import com.google.gson.*;
|
||||
import me.dadus33.chatitem.utils.Reflect;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class JSONManipulatorCurrent implements JSONManipulator{
|
||||
|
||||
private static Class<?> craftItemStackClass = Reflect.getOBCClass("inventory.CraftItemStack");
|
||||
private static Class<?> nmsItemStackClass = Reflect.getNMSClass("ItemStack");
|
||||
private static Method asNMSCopy = Reflect.getMethod(craftItemStackClass, "asNMSCopy", ItemStack.class);
|
||||
private static Class<?> nbtTagCompoundClass = Reflect.getNMSClass("NBTTagCompound");
|
||||
private static Method saveNmsItemStackMethod = Reflect.getMethod(nmsItemStackClass, "save", nbtTagCompoundClass);
|
||||
|
||||
private static String[] replaces;
|
||||
private static String rgx;
|
||||
private static JsonArray toUse;
|
||||
private static JsonParser parser = new JsonParser();
|
||||
|
||||
|
||||
public String parse(String json, String[] replacements, ItemStack item, String repl) throws InvocationTargetException, IllegalAccessException, InstantiationException {
|
||||
JsonObject obj = parser.parse(json).getAsJsonObject();
|
||||
JsonArray array = obj.getAsJsonArray("extra");
|
||||
replaces = replacements;
|
||||
String regex = "";
|
||||
for (int i = 0; i < replacements.length; ++i) {
|
||||
if (replacements.length == 1) {
|
||||
regex = Pattern.quote(replacements[0]);
|
||||
break;
|
||||
}
|
||||
if (i == 0 || i + 1 == replacements.length) {
|
||||
if (i == 0) {
|
||||
regex = "(" + Pattern.quote(replacements[i]);
|
||||
} else {
|
||||
regex = regex.concat("|").concat(Pattern.quote(replacements[i])).concat(")");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
regex = regex.concat("|").concat(Pattern.quote(replacements[i]));
|
||||
}
|
||||
rgx = regex;
|
||||
JsonArray rep = new JsonArray();
|
||||
repl = escapeBackslash(repl);
|
||||
JsonArray use = parser.parse(Translator.toJSON(repl)).getAsJsonArray();
|
||||
|
||||
JsonObject hover = parser.parse("{\"action\":\"show_item\", \"value\": \"\"}").getAsJsonObject();
|
||||
Object nmsStack = asNMSCopy.invoke(null, item);
|
||||
Object tag = nbtTagCompoundClass.newInstance();
|
||||
tag = saveNmsItemStackMethod.invoke(nmsStack, tag);
|
||||
String jsonRep = escapeBackslash(tag.toString());
|
||||
hover.addProperty("value", jsonRep);
|
||||
for (JsonElement ob : use)
|
||||
ob.getAsJsonObject().add("hoverEvent", hover);
|
||||
|
||||
toUse = use;
|
||||
|
||||
for (int i = 0; i < array.size(); ++i) {
|
||||
if (array.get(i).isJsonObject()){
|
||||
JsonObject o = array.get(i).getAsJsonObject();
|
||||
boolean inside = false;
|
||||
for (String replacement : replacements)
|
||||
if (o.toString().contains(replacement)) {
|
||||
if (inside) {
|
||||
break;
|
||||
}
|
||||
inside = true;
|
||||
}
|
||||
JsonElement text = o.get("text");
|
||||
if (text == null) {
|
||||
JsonElement el = o.get("extra");
|
||||
if (el != null) {
|
||||
JsonArray jar = el.getAsJsonArray();
|
||||
jar = parseArray(jar);
|
||||
o.add("extra", jar);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
if (text.getAsString().isEmpty()) {
|
||||
JsonElement el = o.get("extra");
|
||||
if (el != null) {
|
||||
JsonArray jar = el.getAsJsonArray();
|
||||
jar = parseArray(jar);
|
||||
o.add("extra", jar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String msg = text.getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replacements) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(regex);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
String st = o.toString();
|
||||
JsonObject fix = parser.parse(st).getAsJsonObject();
|
||||
fix.addProperty("text", splits[j]);
|
||||
rep.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
rep.addAll(use);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
rep.add(o);
|
||||
}
|
||||
}else{
|
||||
if(array.get(i).isJsonNull()){
|
||||
continue;
|
||||
}else{
|
||||
if(array.get(i).isJsonArray()){
|
||||
JsonArray jar = parseArray(array.get(i).getAsJsonArray());
|
||||
rep.set(i, jar);
|
||||
}else{
|
||||
|
||||
|
||||
String msg = array.get(i).getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replacements) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(regex);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
JsonElement fix = new JsonPrimitive(splits[j]);
|
||||
rep.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
rep.addAll(use);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
rep.add(array.get(i));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
obj.add("extra", rep);
|
||||
return obj.toString();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static JsonArray parseArray(JsonArray arr) {
|
||||
JsonArray replacer = new JsonArray();
|
||||
for (int i = 0; i < arr.size(); ++i) {
|
||||
if (arr.get(i).isJsonObject()){
|
||||
JsonObject o = arr.get(i).getAsJsonObject();
|
||||
boolean inside = false;
|
||||
for (String replacement : replaces)
|
||||
if (o.toString().contains(replacement)) {
|
||||
if (inside) {
|
||||
break;
|
||||
}
|
||||
inside = true;
|
||||
}
|
||||
if (!inside) { //the placeholder we're looking for is not inside this element, so we continue searching
|
||||
continue;
|
||||
}
|
||||
JsonElement text = o.get("text");
|
||||
if (text == null) {
|
||||
continue;
|
||||
}
|
||||
if (text.getAsString().isEmpty()) {
|
||||
JsonElement el = o.get("extra");
|
||||
if (el == null) {
|
||||
continue;
|
||||
}
|
||||
JsonArray jar = el.getAsJsonArray();
|
||||
jar = parseArray(jar);
|
||||
o.add("extra", jar);
|
||||
}
|
||||
|
||||
String msg = text.getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replaces) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(rgx);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
String st = o.toString();
|
||||
JsonObject fix = parser.parse(st).getAsJsonObject();
|
||||
fix.addProperty("text", splits[j]);
|
||||
replacer.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
replacer.addAll(toUse);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
replacer.add(o);
|
||||
}
|
||||
}else{
|
||||
if(arr.get(i).isJsonNull()){
|
||||
continue;
|
||||
}else{
|
||||
if(arr.get(i).isJsonArray()){
|
||||
JsonArray jar = parseArray(arr.get(i).getAsJsonArray());
|
||||
replacer.set(i, jar);
|
||||
}else{
|
||||
String msg = arr.get(i).getAsString();
|
||||
boolean isLast = false;
|
||||
boolean done = false;
|
||||
boolean fnd;
|
||||
String[] splits;
|
||||
for (String repls : replaces) {
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
isLast = msg.endsWith(repls);
|
||||
if (isLast) {
|
||||
done = true;
|
||||
msg = msg.concat(".");
|
||||
}
|
||||
}
|
||||
splits = msg.split(rgx);
|
||||
fnd = splits.length != 1;
|
||||
if (fnd)
|
||||
for (int j = 0; j < splits.length; ++j) {
|
||||
boolean endDot = (j == splits.length - 1) && isLast;
|
||||
if (!splits[j].isEmpty() && !endDot) {
|
||||
JsonElement fix = new JsonPrimitive(splits[j]);
|
||||
replacer.add(fix);
|
||||
}
|
||||
if (j != splits.length - 1) {
|
||||
replacer.addAll(toUse);
|
||||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
replacer.add(arr.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return replacer;
|
||||
}
|
||||
|
||||
|
||||
private static String escapeBackslash(String json){
|
||||
json = json.replace("\\", "\\\\");
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package me.dadus33.chatitem.json;
|
||||
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
/*
|
||||
Many thanks to @DarkSeraphim for this!
|
||||
I only modified his work to make it compatible with what I was building.
|
||||
*/
|
||||
public class Translator {
|
||||
private static final StringBuilder BUILDER = new StringBuilder("");
|
||||
private static final StringBuilder STYLE = new StringBuilder();
|
||||
|
||||
static String toJSON(String message) {
|
||||
if (message == null || message.isEmpty())
|
||||
return null;
|
||||
String[] parts = message.split(Character.toString(ChatColor.COLOR_CHAR));
|
||||
boolean first = true;
|
||||
String colour = null;
|
||||
String format = null;
|
||||
BUILDER.setLength(0);
|
||||
BUILDER.append("[");
|
||||
boolean ignoreFirst = !parts[0].isEmpty() && ChatColor.getByChar(parts[0].charAt(0)) != null;
|
||||
for (String part : parts) {
|
||||
if (part.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String newStyle = null;
|
||||
if (!ignoreFirst) {
|
||||
newStyle = getStyle(part.charAt(0));
|
||||
} else {
|
||||
ignoreFirst = false;
|
||||
}
|
||||
|
||||
if (newStyle != null) {
|
||||
part = part.substring(1);
|
||||
if (newStyle.startsWith("\"c"))
|
||||
colour = newStyle;
|
||||
else
|
||||
format = newStyle;
|
||||
}
|
||||
if (!part.isEmpty()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else {
|
||||
BUILDER.append(", ");
|
||||
}
|
||||
BUILDER.append("{");
|
||||
if (colour != null) {
|
||||
BUILDER.append(colour);
|
||||
colour = null;
|
||||
}
|
||||
if (format != null) {
|
||||
BUILDER.append(format);
|
||||
format = null;
|
||||
}
|
||||
BUILDER.append(String.format("\"text\":\"%s\"", part));
|
||||
BUILDER.append("}");
|
||||
}
|
||||
}
|
||||
BUILDER.append("]");
|
||||
return BUILDER.toString();
|
||||
}
|
||||
|
||||
private static String getStyle(char colour) {
|
||||
if (STYLE.length() > 0)
|
||||
STYLE.delete(0, STYLE.length());
|
||||
switch (colour) {
|
||||
case 'k':
|
||||
return "\"obfuscated\": true,";
|
||||
case 'l':
|
||||
return "\"bold\": true,";
|
||||
case 'm':
|
||||
return "\"strikethrough\": true,";
|
||||
case 'n':
|
||||
return "\"underlined\": true,";
|
||||
case 'o':
|
||||
return "\"italic\": true,";
|
||||
case 'r':
|
||||
return "\"reset\": true,";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ChatColor cc = ChatColor.getByChar(colour);
|
||||
if (cc == null)
|
||||
return null;
|
||||
return STYLE.append("\"color\":\"").append(cc.name().toLowerCase()).append("\", ").toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package me.dadus33.chatitem.listeners;
|
||||
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
|
||||
public class ChatEventListener implements Listener {
|
||||
|
||||
private Storage c;
|
||||
|
||||
public ChatEventListener(Storage storage) {
|
||||
c = storage;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onChat(AsyncPlayerChatEvent e) {
|
||||
boolean found = false;
|
||||
|
||||
for (String rep : c.PLACEHOLDERS)
|
||||
if (e.getMessage().contains(rep)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
if (!e.getPlayer().hasPermission("chatitem.use")) {
|
||||
e.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (e.getPlayer().getItemInHand().getType().equals(Material.AIR)) {
|
||||
if (c.DENY_IF_NO_ITEM) {
|
||||
e.setCancelled(true);
|
||||
if (!c.DENY_MESSAGE.isEmpty())
|
||||
e.getPlayer().sendMessage(c.DENY_MESSAGE);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
String s = e.getMessage();
|
||||
for(String placeholder : c.PLACEHOLDERS){
|
||||
s = s.replace(placeholder, c.PLACEHOLDERS.get(0));
|
||||
}
|
||||
int occurrences = countOccurrences(c.PLACEHOLDERS.get(0), s);
|
||||
if(occurrences>c.MAX_OCCURRENCES){
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
String oldmsg = e.getMessage();
|
||||
e.setMessage(e.getMessage().concat(e.getPlayer().getName()));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onCommand(PlayerCommandPreprocessEvent e){
|
||||
boolean found = false;
|
||||
|
||||
for (String rep : c.PLACEHOLDERS)
|
||||
if (e.getMessage().contains(rep)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found) {
|
||||
return;
|
||||
}
|
||||
if (!e.getPlayer().hasPermission("chatitem.use")) {
|
||||
e.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (e.getPlayer().getItemInHand().getType().equals(Material.AIR)) {
|
||||
if (c.DENY_IF_NO_ITEM) {
|
||||
e.setCancelled(true);
|
||||
if (!c.DENY_MESSAGE.isEmpty())
|
||||
e.getPlayer().sendMessage(c.DENY_MESSAGE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
String s = e.getMessage();
|
||||
for(String placeholder : c.PLACEHOLDERS){
|
||||
s = s.replace(placeholder, c.PLACEHOLDERS.get(0));
|
||||
}
|
||||
int occurrences = countOccurrences(c.PLACEHOLDERS.get(0), s);
|
||||
if(occurrences>c.MAX_OCCURRENCES){
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
e.setMessage(e.getMessage().concat(e.getPlayer().getName()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void setStorage(Storage st) {
|
||||
c = st;
|
||||
}
|
||||
|
||||
private int countOccurrences(String findStr, String str){
|
||||
int lastIndex = 0;
|
||||
int count = 0;
|
||||
while(lastIndex != -1){
|
||||
|
||||
lastIndex = str.indexOf(findStr,lastIndex);
|
||||
|
||||
if(lastIndex != -1){
|
||||
count ++;
|
||||
lastIndex += findStr.length();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package me.dadus33.chatitem.listeners;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
public class ChatItemAdminHolder implements InventoryHolder {
|
||||
|
||||
public final HashMap<Integer, String> keyBySlot = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
package me.dadus33.chatitem.listeners;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
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.WrappedChatComponent;
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class ChatPacketListener extends PacketAdapter {
|
||||
|
||||
private final static String NAME = "{name}";
|
||||
private final static String AMOUNT = "{amount}";
|
||||
private final static String TIMES = "{times}";
|
||||
private ChatItem instance;
|
||||
private Storage c;
|
||||
|
||||
public ChatPacketListener(Plugin plugin, ListenerPriority listenerPriority, Storage s, PacketType... types) {
|
||||
super(plugin, listenerPriority, types);
|
||||
this.instance = (ChatItem) plugin;
|
||||
c = s;
|
||||
}
|
||||
|
||||
private static String materialToName(Material m) {
|
||||
if (m.equals(Material.TNT)) {
|
||||
return "TNT";
|
||||
}
|
||||
String orig = m.toString().toLowerCase();
|
||||
String[] splits = orig.split("_");
|
||||
StringBuilder sb = new StringBuilder(orig.length());
|
||||
int pos = 0;
|
||||
for (String split : splits) {
|
||||
sb.append(split);
|
||||
int loc = sb.lastIndexOf(split);
|
||||
char charLoc = sb.charAt(loc);
|
||||
if (!(split.equalsIgnoreCase("of") || split.equalsIgnoreCase("and") ||
|
||||
split.equalsIgnoreCase("with") || split.equalsIgnoreCase("on")))
|
||||
sb.setCharAt(loc, Character.toUpperCase(charLoc));
|
||||
if (pos != splits.length - 1)
|
||||
sb.append(' ');
|
||||
++pos;
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent e) {
|
||||
if(ChatItem.post17)
|
||||
if (e.getPacket().getBytes().readSafely(0) == (byte) 2) {
|
||||
return; //It means it's an actionbar message, and we ain't intercepting those
|
||||
}
|
||||
|
||||
PacketContainer packet = e.getPacket();
|
||||
|
||||
if(packet.getChatComponents().readSafely(0)==null){ // null check for some cases of messages from other plugins
|
||||
return;
|
||||
}
|
||||
String json = packet.getChatComponents().readSafely(0).getJson();
|
||||
|
||||
boolean found = false;
|
||||
for (String rep : c.PLACEHOLDERS)
|
||||
if (json.contains(rep)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found) {
|
||||
return; //then it's just a normal message without placeholders, so we leave it alone
|
||||
}
|
||||
int topIndex = -1;
|
||||
String name = null;
|
||||
for(Player p : Bukkit.getOnlinePlayers()){
|
||||
String pname = p.getName();
|
||||
if(!json.contains(pname)){
|
||||
continue;
|
||||
}
|
||||
int index = json.lastIndexOf(pname)+pname.length();
|
||||
if(index>topIndex){
|
||||
topIndex = index;
|
||||
name = pname;
|
||||
}
|
||||
}
|
||||
if(name==null){ //something went really bad, so we run away and hide
|
||||
return;
|
||||
}
|
||||
Player p = Bukkit.getPlayer(name);
|
||||
StringBuilder buff = new StringBuilder(json);
|
||||
buff.replace(topIndex-name.length(), topIndex, "");
|
||||
json = buff.toString();
|
||||
|
||||
|
||||
//STYLE BEGIN
|
||||
|
||||
ItemStack inHand = p.getItemInHand();
|
||||
String replacer = c.NAME_FORMAT;
|
||||
String amount = c.AMOUNT_FORMAT;
|
||||
boolean dname = false;
|
||||
if (!c.COLOR_IF_ALREADY_COLORED && inHand.hasItemMeta()) {
|
||||
if (inHand.getItemMeta().hasDisplayName()) {
|
||||
replacer = ChatColor.stripColor(replacer);
|
||||
dname = true;
|
||||
}
|
||||
} else {
|
||||
if (inHand.hasItemMeta()) {
|
||||
if (inHand.getItemMeta().hasDisplayName()) {
|
||||
dname = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inHand.getAmount() == 1) {
|
||||
if (c.FORCE_ADD_AMOUNT) {
|
||||
amount = amount.replace(TIMES, "1");
|
||||
replacer = replacer.replace(AMOUNT, amount);
|
||||
} else {
|
||||
replacer = replacer.replace(AMOUNT, "");
|
||||
}
|
||||
} else {
|
||||
amount = amount.replace(TIMES, String.valueOf(inHand.getAmount()));
|
||||
replacer = replacer.replace(AMOUNT, amount);
|
||||
}
|
||||
if (dname) {
|
||||
String trp = inHand.getItemMeta().getDisplayName();
|
||||
replacer = replacer.replace(NAME, trp);
|
||||
} else {
|
||||
HashMap<Short, String> translationSection = c.TRANSLATIONS.get(inHand.getType().name());
|
||||
if(translationSection==null){
|
||||
String trp = materialToName(inHand.getType());
|
||||
replacer = replacer.replace(NAME, trp);
|
||||
}else {
|
||||
String translated = translationSection.get(inHand.getDurability());
|
||||
if (translated != null) {
|
||||
replacer = replacer.replace(NAME, translated);
|
||||
} else {
|
||||
replacer = replacer.replace(NAME, materialToName(inHand.getType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//STYLE END
|
||||
|
||||
String[] reps = new String[c.PLACEHOLDERS.size()];
|
||||
c.PLACEHOLDERS.toArray(reps);
|
||||
String message = null;
|
||||
try {
|
||||
if(!p.getItemInHand().getType().equals(Material.AIR))
|
||||
message = ChatItem.getManipulator().parse(json, reps, p.getItemInHand(), replacer);
|
||||
} catch (InvocationTargetException | IllegalAccessException | InstantiationException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
if(message!=null)
|
||||
packet.getChatComponents().writeSafely(0, WrappedChatComponent.fromJson(message));
|
||||
else
|
||||
e.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
public void setStorage(Storage st) {
|
||||
c = st;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package me.dadus33.chatitem.listeners;
|
||||
|
||||
import static me.dadus33.chatitem.utils.ItemUtils.createItem;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.utils.ItemUtils;
|
||||
import me.dadus33.chatitem.utils.Messages;
|
||||
import me.dadus33.chatitem.utils.Storage;
|
||||
|
||||
public class InventoryListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onClick(InventoryClickEvent e) {
|
||||
if(e.getClickedInventory() == null || !(e.getWhoClicked() instanceof Player) || e.getCurrentItem() == null
|
||||
|| !(e.getClickedInventory().getHolder() instanceof ChatItemAdminHolder))
|
||||
return;
|
||||
e.setCancelled(true);
|
||||
Player p = (Player) e.getWhoClicked();
|
||||
ItemStack item = e.getCurrentItem();
|
||||
Material type = item.getType();
|
||||
Storage c = ChatItem.getInstance().getStorage();
|
||||
if(type.equals(ItemUtils.MATERIAL_CLOSE)) {
|
||||
p.closeInventory();
|
||||
} else if(type.equals(Material.PAPER)) {
|
||||
ChatItemAdminHolder holder = (ChatItemAdminHolder) e.getClickedInventory().getHolder();
|
||||
String key = holder.keyBySlot.get(e.getSlot());
|
||||
if(key != null) {
|
||||
setInConfig("manager", key);
|
||||
p.closeInventory();
|
||||
ChatItem.reload(p);
|
||||
}
|
||||
} else if(type.equals(ItemUtils.INK_SAC)) {
|
||||
setInConfig("general.color-if-already-colored", c.COLOR_IF_ALREADY_COLORED = !c.COLOR_IF_ALREADY_COLORED);
|
||||
open(p);
|
||||
} else if(type.equals(Material.REDSTONE)) {
|
||||
setInConfig("general.deny-if-no-item", c.DENY_IF_NO_ITEM = !c.DENY_IF_NO_ITEM);
|
||||
open(p);
|
||||
} else if(type.equals(Material.STICK)) {
|
||||
setInConfig("general.hand.disabled", c.HAND_DISABLED = !c.HAND_DISABLED);
|
||||
open(p);
|
||||
} else if(type.equals(Material.IRON_DOOR)) {
|
||||
if(e.getClick().equals(ClickType.RIGHT))
|
||||
c.LIMIT--;
|
||||
else if(e.getClick().equals(ClickType.LEFT))
|
||||
c.LIMIT++;
|
||||
setInConfig("general.limit-per-message", c.LIMIT);
|
||||
open(p);
|
||||
} else if(type.equals(Material.APPLE)) {
|
||||
if(e.getClick().equals(ClickType.RIGHT))
|
||||
c.COOLDOWN--;
|
||||
else if(e.getClick().equals(ClickType.LEFT))
|
||||
c.COOLDOWN++;
|
||||
setInConfig("general.cooldown", c.COOLDOWN);
|
||||
open(p);
|
||||
}
|
||||
}
|
||||
|
||||
private void setInConfig(String key, Object val) {
|
||||
ChatItem pl = ChatItem.getInstance();
|
||||
pl.getConfig().set(key, val);
|
||||
pl.saveConfig();
|
||||
}
|
||||
|
||||
public static void open(Player p) {
|
||||
ChatItemAdminHolder holder = new ChatItemAdminHolder();
|
||||
Storage c = ChatItem.getInstance().getStorage();
|
||||
Inventory inv = Bukkit.createInventory(holder, 27, Messages.getMessage("admin-inv.name"));
|
||||
for(int i = 0; i < inv.getSize(); i ++)
|
||||
inv.setItem(i, createItem(ItemUtils.WHITE_STAINED_GLASS, "-"));
|
||||
|
||||
int slot = 0;
|
||||
for(String manager : Arrays.asList("both", "auto", "packet", "chat")) {
|
||||
holder.keyBySlot.put(slot, manager);
|
||||
inv.setItem(slot++, getManagerItem(manager));
|
||||
}
|
||||
inv.setItem(slot + 1, getManagerItem("actual", "%manager%", Messages.getMessage("admin-inv.manager." + c.MANAGER + ".name")));
|
||||
|
||||
inv.setItem(18, getBoolChangeItem(ItemUtils.INK_SAC, "color-if-already-colored", c.COLOR_IF_ALREADY_COLORED));
|
||||
inv.setItem(19, getBoolChangeItem(Material.REDSTONE, "deny-no-item", c.DENY_IF_NO_ITEM));
|
||||
inv.setItem(20, getBoolChangeItem(Material.STICK, "hand-disabled", c.HAND_DISABLED));
|
||||
inv.setItem(21, getAmountChangeItem(Material.IRON_DOOR, "limit-per-message", c.LIMIT));
|
||||
inv.setItem(22, getAmountChangeItem(Material.APPLE, "cooldown", c.COOLDOWN));
|
||||
|
||||
inv.setItem(26, createItem(ItemUtils.MATERIAL_CLOSE, Messages.getMessage("admin-inv.close")));
|
||||
p.openInventory(inv);
|
||||
}
|
||||
|
||||
private static ItemStack getBoolChangeItem(Material type, String key, boolean b) {
|
||||
return createItem(type, Messages.getMessage("admin-inv." + key, "%state%", Messages.getMessage(b ? "enabled" : "disabled")), Messages.getMessageList("admin-inv.bool-lore"));
|
||||
}
|
||||
|
||||
private static ItemStack getAmountChangeItem(Material type, String key, int amount) {
|
||||
return createItem(type, Messages.getMessage("admin-inv." + key, "%state%", amount), Messages.getMessageList("admin-inv.amount-lore"));
|
||||
}
|
||||
|
||||
private static ItemStack getManagerItem(String manager, Object... placeholders) {
|
||||
return createItem(Material.PAPER, Messages.getMessage("admin-inv.manager." + manager + ".name", placeholders),
|
||||
Messages.getMessageList("admin-inv.manager." + manager + ".lore", placeholders));
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package me.dadus33.chatitem.listeners;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
|
||||
public class JoinListener implements Listener {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
if(!p.isOp())
|
||||
return;
|
||||
ChatItem pl = ChatItem.getInstance();
|
||||
if(pl.isHasNewVersion()) {
|
||||
TextComponent text = new TextComponent(pl.getStorage().JOIN_UPDATE_MESSAGE);
|
||||
text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(pl.getStorage().JOIN_UPDATE_HOVER).create()));
|
||||
text.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.spigotmc.org/resources/19064/"));
|
||||
p.spigot().sendMessage(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package me.dadus33.chatitem.playernamer;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
|
||||
public interface IPlayerNamer {
|
||||
|
||||
public BaseComponent[] getName(Player p);
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package me.dadus33.chatitem.playernamer;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import me.dadus33.chatitem.playernamer.hook.DefaultPlayerNamer;
|
||||
import me.dadus33.chatitem.playernamer.hook.HexNicksPlayerNamer;
|
||||
|
||||
public class PlayerNamerManager {
|
||||
|
||||
private static IPlayerNamer playerNamer;
|
||||
public static IPlayerNamer getPlayerNamer() {
|
||||
return playerNamer;
|
||||
}
|
||||
public static void setPlayerNamer(IPlayerNamer playerNamer) {
|
||||
PlayerNamerManager.playerNamer = playerNamer;
|
||||
}
|
||||
|
||||
public static void load(ChatItem pl) {
|
||||
if(Bukkit.getPluginManager().getPlugin("HexNicks") != null) {
|
||||
setPlayerNamer(new HexNicksPlayerNamer());
|
||||
pl.getLogger().info("Enable support for HexNicks plugin !");
|
||||
} else {
|
||||
setPlayerNamer(new DefaultPlayerNamer());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package me.dadus33.chatitem.playernamer.hook;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.playernamer.IPlayerNamer;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
|
||||
public class DefaultPlayerNamer implements IPlayerNamer {
|
||||
|
||||
@Override
|
||||
public BaseComponent[] getName(Player p) {
|
||||
return new ComponentBuilder(p.getName()).create();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package me.dadus33.chatitem.playernamer.hook;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import dev.majek.hexnicks.Nicks;
|
||||
import me.dadus33.chatitem.playernamer.IPlayerNamer;
|
||||
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
|
||||
public class HexNicksPlayerNamer implements IPlayerNamer {
|
||||
|
||||
@Override
|
||||
public BaseComponent[] getName(Player p) {
|
||||
return BungeeComponentSerializer.get().serialize(Nicks.api().getStoredNick(p).join());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
|
||||
public class ColorManager {
|
||||
|
||||
public static BaseComponent[] getChatWithHex(String msg) {
|
||||
ChatItem.debug("Converting " + msg);
|
||||
ComponentBuilder builder = new ComponentBuilder();
|
||||
ChatColor color = ChatColor.WHITE;
|
||||
String colorCode = "", text = "";
|
||||
boolean waiting = false;
|
||||
for(char c : msg.toCharArray()) {
|
||||
if(c == '§') { // begin of color
|
||||
if(colorCode.isEmpty() && !text.isEmpty()) { // text before this char
|
||||
ChatItem.debug("Append " + text);
|
||||
builder.append(new ComponentBuilder(text).color(color).create());
|
||||
text = "";
|
||||
}
|
||||
|
||||
waiting = true; // waiting for color code
|
||||
} else if(waiting) { // if waiting for code and valid str
|
||||
if(String.valueOf(c).matches("-?[0-9a-fA-F]+") && colorCode.length() <= 5) { // if it's hexademical value and with enough space for full color
|
||||
colorCode += c; // add char to it
|
||||
waiting = false;
|
||||
} else {
|
||||
color = ChatColor.getByChar(c); // a color by itself
|
||||
colorCode = ""; // clean actual code, it's only to prevent some kind of issue
|
||||
waiting = false;
|
||||
}
|
||||
} else {
|
||||
if(!colorCode.isEmpty()) {
|
||||
color = getColor(colorCode);
|
||||
}
|
||||
// basic text, not waiting for code after '§'
|
||||
text += c;
|
||||
colorCode = ""; // clean actual code
|
||||
waiting = false;
|
||||
}
|
||||
}
|
||||
if(!text.isEmpty())
|
||||
builder.append(new ComponentBuilder(text).color(color).create()); // add last char
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private static ChatColor getColor(String input) {
|
||||
return input.isEmpty() ? ChatColor.WHITE : (input.length() == 1 ? ChatColor.getByChar(input.charAt(0)) : ChatColor.of("#" + input));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class General {
|
||||
|
||||
private static Storage c;
|
||||
|
||||
public static void checkConfigVersion() {
|
||||
int latestVersion = ChatItem.CFG_VER;
|
||||
if (latestVersion != c.CONFIG_VERSION) {
|
||||
Bukkit.getLogger().log(Level.WARNING, ChatColor.RED + "ChatItem detected an older or invalid configuration file. Replacing it with the default config...");
|
||||
c.performOverwrite();
|
||||
Bukkit.getLogger().log(Level.WARNING, ChatColor.RED + "Replacement complete!");
|
||||
}
|
||||
}
|
||||
|
||||
public static void init(Storage st) {
|
||||
c = st;
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class ItemUtils {
|
||||
|
||||
public static final Material MATERIAL_CLOSE = getMaterialWithCompatibility("BARRIER", "REDSTONE_BLOCK");
|
||||
|
||||
// items
|
||||
public static final Material EMPTY_MAP = getMaterialWithCompatibility("EMPTY_MAP", "MAP");
|
||||
public static final Material BOOK_AND_QUILL = getMaterialWithCompatibility("BOOK_AND_QUILL", "WRITTEN_BOOK");
|
||||
public static final Material WEB = getMaterialWithCompatibility("WEB", "COBWEB");
|
||||
public static final Material FIREBALL = getMaterialWithCompatibility("FIREBALL", "FIRE_CHARGE");
|
||||
public static final Material INK_SAC = getMaterialWithCompatibility("INK_SAC", "INK_SACK", "DYE", "GRAY_DYE");
|
||||
|
||||
public static final Material BIRCH_WOOD_STAIRS = getMaterialWithCompatibility("BIRCH_WOOD_STAIRS", "BIRCH_STAIRS");
|
||||
|
||||
// colored items
|
||||
public static final Material GRAY_STAINED_GLASS_PANE = getMaterialWithCompatibility("STAINED_GLASS_PANE", "GRAY_STAINED_GLASS_PANE");
|
||||
public static final Material WHITE_STAINED_GLASS = getMaterialWithCompatibility("STAINED_GLASS_PANE", "WHITE_STAINED_GLASS_PANE");
|
||||
|
||||
public static Material getMaterialWithCompatibility(String... tempMat) {
|
||||
for(String s : tempMat) {
|
||||
try {
|
||||
Material m = (Material) Material.class.getField(s).get(Material.class);
|
||||
if(m != null)
|
||||
return m;
|
||||
} catch (IllegalArgumentException | IllegalAccessException | SecurityException e2) {
|
||||
e2.printStackTrace();
|
||||
} catch (NoSuchFieldException e) {}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack createItem(Material m, String name, String... lore) {
|
||||
return createItem(m, name, 1, lore);
|
||||
}
|
||||
|
||||
public static ItemStack createItem(Material m, String name, int quantite, String... lore) {
|
||||
ItemStack item = new ItemStack(m, quantite);
|
||||
ItemMeta meta = (ItemMeta) item.getItemMeta();
|
||||
meta.setDisplayName(ChatColor.RESET + name);
|
||||
meta.setLore(Arrays.asList(lore));
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createItem(Material m, String name, List<String> lore) {
|
||||
return createItem(m, name, 1, lore);
|
||||
}
|
||||
|
||||
public static ItemStack createItem(Material m, String name, int quantite, List<String> lore) {
|
||||
ItemStack item = new ItemStack(m, quantite);
|
||||
ItemMeta meta = (ItemMeta) item.getItemMeta();
|
||||
meta.setDisplayName(ChatColor.RESET + name);
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static ItemStack createItem(Material m, String name, int amount, byte b, String... lore) {
|
||||
ItemStack item = new ItemStack(m, amount, b);
|
||||
ItemMeta meta = (ItemMeta) item.getItemMeta();
|
||||
meta.setDisplayName(ChatColor.RESET + name);
|
||||
meta.setLore(Arrays.asList(lore));
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack hideAttributes(ItemStack stack) {
|
||||
if (Version.getVersion().isNewerThan(Version.V1_7)) {
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
// All ItemFlags are used to hide attributes, their javadoc says so too.
|
||||
meta.addItemFlags(ItemFlag.values());
|
||||
stack.setItemMeta(meta);
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
|
||||
public class Messages {
|
||||
|
||||
public static void sendMessage(CommandSender p, String key, Object... placeholders) {
|
||||
getMessageList(key, placeholders).forEach(p::sendMessage);
|
||||
}
|
||||
|
||||
public static String getMessage(String key, Object... placeholders) {
|
||||
return colorAndPlaceholders(ChatItem.getInstance().getConfig().getString("messages." + key, key), placeholders);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<String> getMessageList(String key, Object... placeholders) {
|
||||
Object obj = ChatItem.getInstance().getConfig().get("messages." + key);
|
||||
if(obj == null)
|
||||
return Arrays.asList(key);
|
||||
if(obj instanceof List) {
|
||||
return ((List<String>) obj).stream().map((s) -> colorAndPlaceholders(s, placeholders)).collect(Collectors.toList());
|
||||
} else if(obj instanceof String)
|
||||
return Arrays.asList(colorAndPlaceholders((String) obj, placeholders));
|
||||
else
|
||||
return Arrays.asList(colorAndPlaceholders(obj.toString(), placeholders));
|
||||
}
|
||||
|
||||
private static String colorAndPlaceholders(String msg, Object... placeholders) {
|
||||
if(msg == null)
|
||||
return "";
|
||||
for (int index = 0; index <= placeholders.length - 1; index += 2) {
|
||||
msg = msg.replace(String.valueOf(placeholders[index]), String.valueOf(placeholders[index + 1]));
|
||||
}
|
||||
return Storage.color(msg);
|
||||
}
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PacketUtils {
|
||||
|
||||
public static final String VERSION = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",")
|
||||
.split(",")[3];
|
||||
public static final String NMS_PREFIX;
|
||||
public static final String OBC_PREFIX;
|
||||
public static final boolean IS_THERMOS;
|
||||
public static final Class<?> CRAFT_PLAYER_CLASS, CRAFT_SERVER_CLASS, CHAT_SERIALIZER, COMPONENT_CLASS;
|
||||
|
||||
/**
|
||||
* This Map is to reduce Reflection action which take more resources than just RAM action
|
||||
*/
|
||||
private static final Map<String, Class<?>> ALL_CLASS = Collections.synchronizedMap(new HashMap<String, Class<?>>());
|
||||
|
||||
static {
|
||||
IS_THERMOS = isClassExist("thermos.Thermos");
|
||||
NMS_PREFIX = Version.getVersion().isNewerOrEquals(Version.V1_17) || IS_THERMOS ? "net.minecraft." : "net.minecraft.server." + VERSION + ".";
|
||||
OBC_PREFIX = "org.bukkit.craftbukkit." + VERSION + ".";
|
||||
CRAFT_PLAYER_CLASS = getObcClass("entity.CraftPlayer");
|
||||
CHAT_SERIALIZER = getNmsClass("IChatBaseComponent$ChatSerializer", "network.chat.", "ChatSerializer");
|
||||
COMPONENT_CLASS = getNmsClass("IChatBaseComponent", "network.chat.");
|
||||
CRAFT_SERVER_CLASS = getObcClass("CraftServer");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Class in NMS, with a processing reducer
|
||||
*
|
||||
* @param name of the NMS class (in net.minecraft.server package ONLY, because it's NMS)
|
||||
* @return clazz the searched class
|
||||
*/
|
||||
public static Class<?> getNmsClass(String name, String packagePrefix, String... alias){
|
||||
return ALL_CLASS.computeIfAbsent(name, (a) -> {
|
||||
String fullPrefix = NMS_PREFIX + (Version.getVersion().isNewerOrEquals(Version.V1_17) || IS_THERMOS ? packagePrefix : "");
|
||||
try {
|
||||
Class<?> clazz = Class.forName(fullPrefix + name);
|
||||
if(clazz != null)
|
||||
return clazz;
|
||||
} catch (ClassNotFoundException e) {
|
||||
if(alias.length == 0)
|
||||
e.printStackTrace(); // no alias, print error
|
||||
// else ignore and go check for alias
|
||||
}
|
||||
|
||||
for(String className : alias) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(fullPrefix + className);
|
||||
if(clazz != null)
|
||||
return clazz;
|
||||
} catch (ClassNotFoundException e) {
|
||||
if(className == alias[alias.length - 1]) // if it's last alias, print error
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Class in NMS, with a processing reducer
|
||||
*
|
||||
* @param name of the NMS class (in net.minecraft.server package ONLY, because it's NMS)
|
||||
* @return clazz the searched class
|
||||
*/
|
||||
public static Class<?> getObcClass(String name, String... alias){
|
||||
return ALL_CLASS.computeIfAbsent(name, (a) -> {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(OBC_PREFIX + name);
|
||||
if(clazz != null)
|
||||
return clazz;
|
||||
} catch (ClassNotFoundException e) {
|
||||
if(alias.length == 0)
|
||||
e.printStackTrace(); // no alias, print error
|
||||
// else ignore and go check for alias
|
||||
}
|
||||
|
||||
for(String className : alias) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(OBC_PREFIX + className);
|
||||
if(clazz != null)
|
||||
return clazz;
|
||||
} catch (ClassNotFoundException e) {
|
||||
if(className == alias[alias.length - 1]) // if it's last alias, print error
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get NMS entity player of specified one
|
||||
*
|
||||
* @param p the player that we want the NMS entity player
|
||||
* @return the entity player
|
||||
*/
|
||||
public static Object getEntityPlayer(Player p) {
|
||||
try {
|
||||
Object craftPlayer = CRAFT_PLAYER_CLASS.cast(p);
|
||||
return craftPlayer.getClass().getMethod("getHandle").invoke(craftPlayer);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isClassExist(String name) {
|
||||
try {
|
||||
Class.forName(name);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get NMS player connection of specified player
|
||||
*
|
||||
* @param p Player of which we want to get the player connection
|
||||
* @return the NMS player connection
|
||||
*/
|
||||
public static Object getPlayerConnection(Player p) {
|
||||
try {
|
||||
Object entityPlayer = getEntityPlayer(p);
|
||||
if(Version.getVersion().isNewerOrEquals(Version.V1_17))
|
||||
return entityPlayer.getClass().getField("b").get(entityPlayer);
|
||||
else
|
||||
return entityPlayer.getClass().getField("playerConnection").get(entityPlayer);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get NMS entity player of specified one
|
||||
*
|
||||
* @param p the player that we want the NMS entity player
|
||||
* @return the entity player
|
||||
*/
|
||||
public static Object getCraftServer() {
|
||||
try {
|
||||
Object craftServer = CRAFT_SERVER_CLASS.cast(Bukkit.getServer());
|
||||
return craftServer.getClass().getMethod("getHandle").invoke(craftServer);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the packet to the specified player
|
||||
*
|
||||
* @param p which will receive the packet
|
||||
* @param packet the packet to sent
|
||||
*/
|
||||
public static void sendPacket(Player p, Object packet) {
|
||||
try {
|
||||
Object playerConnection = getPlayerConnection(p);
|
||||
playerConnection.getClass().getMethod(Version.getVersion().isNewerOrEquals(Version.V1_18) ? "a" : "sendPacket", getNmsClass("Packet", "network.protocol.")).invoke(playerConnection, packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,56 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class Reflect {
|
||||
|
||||
|
||||
private static String versionString;
|
||||
|
||||
|
||||
private static String getVersion() {
|
||||
if (versionString == null) {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
versionString = name.substring(name.lastIndexOf('.') + 1) + ".";
|
||||
}
|
||||
|
||||
return versionString;
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClass(String nmsClassName) {
|
||||
|
||||
String clazzName = "net.minecraft.server." + getVersion() + nmsClassName;
|
||||
Class<?> clazz;
|
||||
|
||||
try {
|
||||
clazz = Class.forName(clazzName);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
|
||||
public static Class<?> getOBCClass(String obcClassName) {
|
||||
|
||||
String clazzName = "org.bukkit.craftbukkit." + getVersion() + obcClassName;
|
||||
Class<?> clazz;
|
||||
|
||||
try {
|
||||
clazz = Class.forName(clazzName);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... params) {
|
||||
try {
|
||||
return clazz.getMethod(methodName, params);
|
||||
@@ -16,41 +59,5 @@ public class Reflect {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, Class<?> returned, Class<?>... params) {
|
||||
try {
|
||||
for(Method m : clazz.getDeclaredMethods()) {
|
||||
if(returned.equals(m.getReturnType()) && areParamsEquals(m.getParameterTypes(), params))
|
||||
return m;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean areParamsEquals(Class<?>[] p1, Class<?>[] p2) {
|
||||
if(p1.length != p2.length)
|
||||
return false;
|
||||
for(int i = 0; i < p1.length; i++) {
|
||||
if(!p1[i].equals(p2[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Field getField(Class<?> clazz, String... fieldNames){
|
||||
for(String field : fieldNames) {
|
||||
try{
|
||||
Field f = clazz.getDeclaredField(field);
|
||||
f.setAccessible(true);
|
||||
return f;
|
||||
} catch (NoSuchFieldException e) {
|
||||
// go to next
|
||||
}
|
||||
}
|
||||
ChatItem.getInstance().getLogger().severe("Failed to find field: " + Arrays.asList(fieldNames) + " in class: " + clazz.getCanonicalName());
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class ReflectionUtils {
|
||||
|
||||
public static Object getPrivateField(Object object, String field)
|
||||
throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
|
||||
Field objectField = object.getClass().getDeclaredField(field);
|
||||
objectField.setAccessible(true);
|
||||
return objectField.get(object);
|
||||
}
|
||||
|
||||
public static void setField(Object src, String fieldName, Object value) {
|
||||
try {
|
||||
Field field = src.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(src, value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specified field name in the object source
|
||||
*
|
||||
* @param source where we will find the field
|
||||
* @param field the name of the field
|
||||
* @return the requested field
|
||||
*/
|
||||
public static Object getField(Object source, String field) {
|
||||
try {
|
||||
Field f = source.getClass().getDeclaredField(field);
|
||||
f.setAccessible(true);
|
||||
return f.get(source);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call method. Return the method return.
|
||||
*
|
||||
* @param source the object where we want to run the method
|
||||
* @param method the name of the method to call
|
||||
* @return the return of the method called
|
||||
*/
|
||||
public static Object callMethod(Object source, String method) {
|
||||
try {
|
||||
return source.getClass().getDeclaredMethod(method).invoke(source);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first field which have the searching for class type
|
||||
*
|
||||
* @param from the object where we will try to find the field
|
||||
* @param clazz the class that have to define the field
|
||||
* @param searchingFor the class of the required field
|
||||
* @return the field (or null if not found)
|
||||
* @throws Exception if something gone wrong
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getFirstWith(Object from, Class<?> clazz, Class<T> searchingFor) throws Exception {
|
||||
for (Field f : clazz.getDeclaredFields()) {
|
||||
if (f.getType().equals(searchingFor)) {
|
||||
f.setAccessible(true);
|
||||
return (T) f.get(from);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents the simplified SemVer schema Negativity uses for its plugin versions.
|
||||
*/
|
||||
public final class SemVer implements Comparable<SemVer> {
|
||||
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int patch;
|
||||
|
||||
private final @Nullable Suffix suffix;
|
||||
|
||||
public SemVer(int major, int minor, int patch, @Nullable Suffix suffix) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public boolean isNewerThan(SemVer other) {
|
||||
return this.compareTo(other) > 0;
|
||||
}
|
||||
|
||||
public boolean isOlderThan(SemVer other) {
|
||||
return this.compareTo(other) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Slightly different from {@link #equals} in that this method will return
|
||||
* true if the suffix has the same {@link Suffix#getWeight() weight}
|
||||
* but not the same {@link Suffix#getText()} text
|
||||
*/
|
||||
public boolean isEquivalentTo(SemVer other) {
|
||||
return this.compareTo(other) == 0;
|
||||
}
|
||||
|
||||
public int getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
public int getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
public int getPatch() {
|
||||
return patch;
|
||||
}
|
||||
|
||||
public @Nullable Suffix getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(SemVer o) {
|
||||
int majorDelta = Integer.compare(this.major, o.major);
|
||||
if (majorDelta != 0) {
|
||||
return majorDelta;
|
||||
}
|
||||
int minorDelta = Integer.compare(this.minor, o.minor);
|
||||
if (minorDelta != 0) {
|
||||
return minorDelta;
|
||||
}
|
||||
int patchDelta = Integer.compare(this.patch, o.patch);
|
||||
if (patchDelta != 0) {
|
||||
return patchDelta;
|
||||
}
|
||||
if (this.suffix != null) {
|
||||
return o.suffix != null ? this.suffix.compareTo(o.suffix) : -1;
|
||||
}
|
||||
if (o.suffix != null) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SemVer semVer = (SemVer) o;
|
||||
return major == semVer.major && minor == semVer.minor && patch == semVer.patch && Objects.equals(suffix, semVer.suffix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(major, minor, patch, suffix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SemVer{major=" + major + ", minor=" + minor + ", patch=" + patch + ", suffix=" + suffix + '}';
|
||||
}
|
||||
|
||||
public String toFormattedString() {
|
||||
if (suffix == null) {
|
||||
if(patch > 0)
|
||||
return major + "." + minor + (patch > 0 ? "." + patch : "");
|
||||
}
|
||||
return major + "." + minor + (patch > 0 ? "." + patch : "") + (suffix == null ? "" : "-" + suffix.getText());
|
||||
}
|
||||
|
||||
public static @Nullable SemVer parse(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] suffixSplit = text.split("-", 2);
|
||||
Suffix suffix = null;
|
||||
if (suffixSplit.length > 1) {
|
||||
suffix = Suffix.of(suffixSplit[1]);
|
||||
}
|
||||
|
||||
String[] parts = suffixSplit[0].split("\\.");
|
||||
int major;
|
||||
try {
|
||||
major = Integer.parseInt(parts[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
int minor = 0;
|
||||
if (parts.length > 1) {
|
||||
try {
|
||||
minor = Integer.parseInt(parts[1]);
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
}
|
||||
int patch = 0;
|
||||
if (parts.length > 2) {
|
||||
try {
|
||||
patch = Integer.parseInt(parts[2]);
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
}
|
||||
return new SemVer(major, minor, patch, suffix);
|
||||
}
|
||||
|
||||
public static final class Suffix implements Comparable<Suffix> {
|
||||
|
||||
public static final Suffix SNAPSHOT = new Suffix(0, "SNAPSHOT");
|
||||
public static final Suffix ALPHA = new Suffix(1, "ALPHA");
|
||||
public static final Suffix BETA = new Suffix(2, "BETA");
|
||||
public static final Suffix GAMMA = new Suffix(3, "GAMMA");
|
||||
public static final Suffix DELTA = new Suffix(4, "DELTA");
|
||||
|
||||
private final int weight;
|
||||
private final String text;
|
||||
|
||||
public Suffix(int weight, String text) {
|
||||
this.weight = weight;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Suffix o) {
|
||||
return Integer.compare(this.weight, o.weight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Suffix suffix = (Suffix) o;
|
||||
return weight == suffix.weight && text.equals(suffix.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(weight, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Suffix{weight=" + weight + ", text='" + text + "'}";
|
||||
}
|
||||
|
||||
public static Suffix of(String text) {
|
||||
String uppercaseText = text.toUpperCase(Locale.ROOT);
|
||||
switch (uppercaseText) {
|
||||
case "SNAPSHOT":
|
||||
return SNAPSHOT;
|
||||
case "ALPHA":
|
||||
return ALPHA;
|
||||
case "BETA":
|
||||
return BETA;
|
||||
case "GAMMA":
|
||||
return GAMMA;
|
||||
case "DELTA":
|
||||
return DELTA;
|
||||
default:
|
||||
return new Suffix(-1, uppercaseText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,120 +1,63 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
|
||||
public class Storage {
|
||||
|
||||
private FileConfiguration conf;
|
||||
public final HashMap<String, HashMap<Short, String>> TRANSLATIONS = new HashMap<>();
|
||||
public boolean COLOR_IF_ALREADY_COLORED, FORCE_ADD_AMOUNT, LET_MESSAGE_THROUGH, DENY_IF_NO_ITEM,
|
||||
HAND_DISABLED, SHOW_NO_PERM_NORMAL, CHECK_UPDATE, SHOW_NO_PERM_COMMAND, PERMISSION_ENABLED;
|
||||
public final String HAND_NAME, NAME_FORMAT, AMOUNT_FORMAT, MANAGER, PERMISSION_NAME;
|
||||
public final String NO_PERMISSION_MESSAGE, DENY_MESSAGE, RELOAD_MESSAGE, COOLDOWN_MESSAGE, LIMIT_MESSAGE;
|
||||
public final String SECONDS, MINUTES, HOURS;
|
||||
public final String JOIN_UPDATE_MESSAGE, JOIN_UPDATE_HOVER;
|
||||
public int CONFIG_VERSION, LIMIT, COOLDOWN;
|
||||
public final List<Command> ALLOWED_PLUGIN_COMMANDS = new ArrayList<>();
|
||||
public final List<String> ALLOWED_DEFAULT_COMMANDS = new ArrayList<>();
|
||||
public final List<String> PLACEHOLDERS, HAND_TOOLTIP;
|
||||
public final HashMap<String, HashMap<Short, String>> TRANSLATIONS = new HashMap<>();
|
||||
public final List<String> PLACEHOLDERS;
|
||||
public final String NAME_FORMAT;
|
||||
public final String AMOUNT_FORMAT;
|
||||
public final Boolean COLOR_IF_ALREADY_COLORED;
|
||||
public final Boolean FORCE_ADD_AMOUNT;
|
||||
public final Boolean DENY_IF_NO_ITEM;
|
||||
public final String DENY_MESSAGE;
|
||||
public final String RELOAD_MESSAGE;
|
||||
final Integer CONFIG_VERSION;
|
||||
public final Integer MAX_OCCURRENCES;
|
||||
|
||||
public Storage(FileConfiguration cnf) {
|
||||
this.conf = cnf;
|
||||
CONFIG_VERSION = conf.getInt("config-version", 13);
|
||||
checkConfigVersion();
|
||||
this.MANAGER = conf.getString("manager", "auto");
|
||||
Set<String> keys = conf.getConfigurationSection("translations").getKeys(false);
|
||||
for (String key : keys) {
|
||||
HashMap<Short, String> entry = new HashMap<>();
|
||||
Set<String> subKeys = conf.getConfigurationSection("translations.".concat(key)).getKeys(false);
|
||||
for (String subKey : subKeys) {
|
||||
entry.put(Short.parseShort(subKey),
|
||||
color(conf.getString("translations.".concat(key).concat(".").concat(subKey))));
|
||||
}
|
||||
public Storage(FileConfiguration conf) {
|
||||
Set<String> keys = conf.getConfigurationSection("Translations").getKeys(false);
|
||||
for (String key : keys) {
|
||||
HashMap<Short, String> entry = new HashMap<>();
|
||||
Set<String> subKeys = conf.getConfigurationSection("Translations.".concat(key)).getKeys(false);
|
||||
for (String subKey : subKeys) {
|
||||
entry.put(Short.parseShort(subKey), color(conf.getString("Translations.".concat(key).concat(".")
|
||||
.concat(subKey))));
|
||||
}
|
||||
|
||||
TRANSLATIONS.put(key, entry);
|
||||
}
|
||||
PLACEHOLDERS = ImmutableList.copyOf(conf.getStringList("general.placeholders"));
|
||||
NAME_FORMAT = color(conf.getString("general.name-format", "&b&l&o{name} {amount}&r"));
|
||||
AMOUNT_FORMAT = color(conf.getString("general.amount-format", "x{times}"));
|
||||
COLOR_IF_ALREADY_COLORED = conf.getBoolean("general.color-if-already-colored", true);
|
||||
LET_MESSAGE_THROUGH = conf.getBoolean("general.let-message-through", true);
|
||||
FORCE_ADD_AMOUNT = conf.getBoolean("general.force-add-amount", true);
|
||||
DENY_IF_NO_ITEM = conf.getBoolean("general.deny-if-no-item", false);
|
||||
LIMIT = conf.getInt("general.limit", 8);
|
||||
COOLDOWN = conf.getInt("general.cooldown", 60);
|
||||
SHOW_NO_PERM_NORMAL = conf.getBoolean("general.show-no-permission-message.normal", true);
|
||||
SHOW_NO_PERM_COMMAND = conf.getBoolean("general.show-no-permission-message.command", false);
|
||||
PERMISSION_ENABLED = conf.getBoolean("general.permission.enabled", false);
|
||||
PERMISSION_NAME = conf.getString("general.permission.name", "chatitem.use");
|
||||
HAND_DISABLED = conf.getBoolean("general.hand.disabled", false);
|
||||
HAND_NAME = color(conf.getString("general.hand.name", "&b&l&o{display-name}&b&l&o's hand"));
|
||||
HAND_TOOLTIP = conf.getStringList("general.hand.tooltip");
|
||||
CHECK_UPDATE = conf.getBoolean("general.check-update", true);
|
||||
DENY_MESSAGE = color(conf.getString("messages.deny-message", "&c&lYou have no item in hand!"));
|
||||
RELOAD_MESSAGE = color(conf.getString("messages.reload-success", "&b&lSuccessful reload!"));
|
||||
NO_PERMISSION_MESSAGE = color(conf.getString("messages.no-permission",
|
||||
"&c&lI'm sorry, but you are not allowed to use the placeholder in chat!"));
|
||||
COOLDOWN_MESSAGE = color(conf.getString("messages.cooldown-message",
|
||||
"&c&lYou can only use items in chat once a minute! You have {remaining} left!"));
|
||||
JOIN_UPDATE_MESSAGE = color(conf.getString("messages.join-update.message",
|
||||
"&cA new version of ChatItem is available. &aClick here to download."));
|
||||
JOIN_UPDATE_HOVER = color(conf.getString("messages.join-update.hover", "&6Click to go to spigot page !"));
|
||||
LIMIT_MESSAGE = color(conf.getString("messages.limit-message", "&c&lYou can only add 8 item placeholders per message!"));
|
||||
|
||||
SECONDS = color(conf.getString("messages.seconds", " seconds"));
|
||||
MINUTES = color(conf.getString("messages.minutes", " minutes"));
|
||||
HOURS = color(conf.getString("messages.hours", " hours"));
|
||||
colorStringList(HAND_TOOLTIP);
|
||||
final List<String> cmds = conf.getStringList("general.commands");
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(ChatItem.getInstance(), () -> {
|
||||
for (String s : cmds) {
|
||||
Command c = Bukkit.getPluginCommand(s);
|
||||
if (c != null) {
|
||||
ALLOWED_PLUGIN_COMMANDS.add(c);
|
||||
} else {
|
||||
ALLOWED_DEFAULT_COMMANDS.add(s);
|
||||
}
|
||||
}
|
||||
}, 100L);
|
||||
TRANSLATIONS.put(key, entry);
|
||||
}
|
||||
CONFIG_VERSION = conf.getInt("config-version");
|
||||
List<String> added = conf.getStringList("placeholders");
|
||||
PLACEHOLDERS = ImmutableList.copyOf(added);
|
||||
NAME_FORMAT = color(conf.getString("name-format"));
|
||||
AMOUNT_FORMAT = color(conf.getString("amount-format"));
|
||||
COLOR_IF_ALREADY_COLORED = conf.getBoolean("color-if-already-colored");
|
||||
FORCE_ADD_AMOUNT = conf.getBoolean("force-add-amount");
|
||||
DENY_IF_NO_ITEM = conf.getBoolean("deny-if-no-item");
|
||||
DENY_MESSAGE = color(conf.getString("deny-message"));
|
||||
RELOAD_MESSAGE = color(conf.getString("reload-success"));
|
||||
MAX_OCCURRENCES = conf.getInt("max-occurrences");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static String color(String s) {
|
||||
return s == null || s.isEmpty() ? s : ChatColor.translateAlternateColorCodes('&', s);
|
||||
}
|
||||
|
||||
private void checkConfigVersion() {
|
||||
int latestVersion = ChatItem.CFG_VER;
|
||||
if (latestVersion != CONFIG_VERSION) {
|
||||
ChatItem pl = ChatItem.getInstance();
|
||||
pl.getLogger().warning(ChatColor.RED
|
||||
+ "ChatItem detected an older or invalid configuration file. Replacing it with the default config...");
|
||||
performOverwrite();
|
||||
conf = pl.getConfig();
|
||||
pl.getLogger().warning(ChatColor.RED + "Replacement complete!");
|
||||
}
|
||||
}
|
||||
private static String color(String s) {
|
||||
return ChatColor.translateAlternateColorCodes('&', s);
|
||||
}
|
||||
|
||||
private void performOverwrite() {
|
||||
ChatItem.getInstance().saveResource("config.yml", true);
|
||||
}
|
||||
|
||||
private static void colorStringList(List<String> input) {
|
||||
for (int i = 0; i < input.size(); ++i) {
|
||||
input.set(i, color(input.get(i)));
|
||||
}
|
||||
}
|
||||
void performOverwrite() {
|
||||
ChatItem.getInstance().saveResource("config.yml", true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ConnectException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import me.dadus33.chatitem.ChatItem;
|
||||
|
||||
public class Utils {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Player> getOnlinePlayers() {
|
||||
Object players = Bukkit.getOnlinePlayers();
|
||||
if(players instanceof Player[])
|
||||
return Arrays.asList((Player[]) players);
|
||||
return new ArrayList<>((Collection<Player>) players);
|
||||
}
|
||||
|
||||
public static String getFromURL(String urlName) {
|
||||
ChatItem pl = ChatItem.getInstance();
|
||||
try {
|
||||
URL url = new URL(urlName);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setUseCaches(true);
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setReadTimeout(5000);
|
||||
connection.setRequestProperty("User-Agent", "ChatItem " + pl.getDescription().getVersion());
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("GET");
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String content = "";
|
||||
String input;
|
||||
while ((input = br.readLine()) != null)
|
||||
content = content + input;
|
||||
br.close();
|
||||
return content;
|
||||
} catch (SocketTimeoutException e) {
|
||||
pl.getLogger().info("Failed to access to " + urlName + " (Reason: timed out).");
|
||||
} catch (UnknownHostException | MalformedURLException e) {
|
||||
pl.getLogger().info("Could not use the internet connection to check for update or send stats");
|
||||
} catch (ConnectException e) {
|
||||
pl.getLogger().warning("Cannot connect to " + urlName + " (Reason: " + e.getMessage() + ").");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package me.dadus33.chatitem.utils;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public enum Version {
|
||||
|
||||
// http://wiki.vg/Protocol_version_numbers
|
||||
V1_7(0, 5, 0),
|
||||
V1_8(6, 47, 1),
|
||||
V1_9(49, 110, 2), // 1.9.X - Starts with 49 as 48 was an april fools update
|
||||
V1_10(201, 210, 3), // 1.10.X - Starts with 201 because why not.
|
||||
V1_11(301, 316, 4),
|
||||
V1_12(317, 340, 5),
|
||||
V1_13(341, 440, 6),
|
||||
V1_14(100, 441, 500),
|
||||
V1_15(100, 550, 578),
|
||||
V1_16(100, 700, 754),
|
||||
V1_17(100, 755, 756),
|
||||
V1_18(100, 757, 800),
|
||||
V1_19(100, 801, 1000),
|
||||
HIGHER(Integer.MAX_VALUE, -1, Integer.MAX_VALUE);
|
||||
|
||||
// Latest version should always have the upper limit set to Integer.MAX_VALUE so
|
||||
// I don't have to update the plugin for every minor protocol change
|
||||
|
||||
public final int MIN_VER;
|
||||
public final int MAX_VER;
|
||||
public final int index; // Represents how new the version is (0 - extremely old)
|
||||
|
||||
private static final Version SERVER_VERSION;
|
||||
public static final String BUKKIT_VERSION;
|
||||
|
||||
static {
|
||||
BUKKIT_VERSION = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
SERVER_VERSION = getVersionByName(BUKKIT_VERSION);
|
||||
}
|
||||
|
||||
Version(int min, int max, int index) {
|
||||
this.MIN_VER = min;
|
||||
this.MAX_VER = max;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public boolean isNewerOrEquals(Version other) {
|
||||
return index >= other.index;
|
||||
}
|
||||
|
||||
public boolean isNewerThan(Version other) {
|
||||
return index > other.index;
|
||||
}
|
||||
|
||||
public static Version getVersionByName(String name) {
|
||||
for (Version v : Version.values())
|
||||
if (name.toLowerCase().startsWith(v.name().toLowerCase()))
|
||||
return v;
|
||||
return HIGHER;
|
||||
}
|
||||
|
||||
public static Version getVersion(int protocolVersion) {
|
||||
for (Version ver : Version.values()) {
|
||||
if (protocolVersion >= ver.MIN_VER && protocolVersion <= ver.MAX_VER) {
|
||||
return ver;
|
||||
}
|
||||
}
|
||||
return HIGHER;
|
||||
}
|
||||
|
||||
public static Version getVersion() {
|
||||
return SERVER_VERSION;
|
||||
}
|
||||
|
||||
public static String stringifyAdress(InetSocketAddress address) {
|
||||
String port = String.valueOf(address.getPort());
|
||||
String ip = address.getAddress().getHostAddress();
|
||||
return ip + ":" + port;
|
||||
}
|
||||
}
|
||||
+67
-1301
File diff suppressed because it is too large.
Load diff
@@ -1,26 +1,17 @@
|
||||
name: ChatItem
|
||||
main: me.dadus33.chatitem.ChatItem
|
||||
version: ${project.version}
|
||||
|
||||
softdepend: [ViaVersion, ProtocolSupport, ProtocolLib, LangUtils, HexNicks]
|
||||
authors: [dadus33, WOLFI3654, Elikill58]
|
||||
api-version: 1.13
|
||||
|
||||
depend: [ProtocolLib]
|
||||
author: dadus33
|
||||
commands:
|
||||
cireload:
|
||||
description: Reload the ChatItem config.
|
||||
aliases: [chatitemreload, citemreload, cir]
|
||||
permission: chatitem.reload
|
||||
chatitem:
|
||||
description: See and edit ChatItem informations
|
||||
permission: chatitem.reload
|
||||
permissions:
|
||||
chatitem.reload:
|
||||
description: Allows reloading the config
|
||||
default: op
|
||||
chatitem.use:
|
||||
description: Allows your messages to be parsed by the plugin
|
||||
default: op
|
||||
chatitem.ignore-cooldown:
|
||||
description: Allows you to ignore cooldowns (if enabled)
|
||||
default: op
|
||||
default: true
|
||||
Reference in new issue
Block a user