Nerds !!
This commit is contained in:
commit
e0e00081a8
28
anticheat/pom.xml
Normal file
28
anticheat/pom.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>dustmc</artifactId>
|
||||
<groupId>com.br.guilhermematthew.nowly</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>anticheat</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.br.guilhermematthew.nowly</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>Project</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,26 @@
|
||||
package io.github.guilhermematthew.anticheat;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class AnticheatMain extends Constant {
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
|
||||
Bukkit.getConsoleSender().sendMessage(Fields.ENABLED);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
|
||||
Bukkit.getConsoleSender().sendMessage(Fields.DISABLED);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package io.github.guilhermematthew.anticheat;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public abstract class Constant extends JavaPlugin implements Listener
|
||||
{
|
||||
|
||||
//PLUGINS GETTERS
|
||||
private PluginManager pm = Bukkit.getPluginManager();
|
||||
|
||||
//PLUGIN GETTING SYSTEM
|
||||
private AnticheatMain plugin;
|
||||
public AnticheatMain getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
//SYSTEM ABSTRACT LOG MAIN
|
||||
public abstract void enable();
|
||||
public abstract void disable();
|
||||
public abstract void load();
|
||||
@Override
|
||||
public void onEnable() {
|
||||
this.enable();
|
||||
}
|
||||
@Override
|
||||
public void onDisable() {
|
||||
this.disable();
|
||||
}
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.load();
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package io.github.guilhermematthew.anticheat;
|
||||
|
||||
public class Fields {
|
||||
|
||||
public static final String
|
||||
|
||||
ENABLED = "§aThis is system AC has enabled sucessfuel!",
|
||||
DISABLED = "§cThis is system AC has disabled sucessfuel!";
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package io.github.guilhermematthew.anticheat.controller;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
public class PlayerController {
|
||||
|
||||
private int clicks;
|
||||
private long expireTime = System.currentTimeMillis() + 1000;
|
||||
public void addClicks() {
|
||||
clicks++;
|
||||
}
|
||||
|
||||
private long startTime = System.currentTimeMillis();
|
||||
private int click;
|
||||
private long lastClick;
|
||||
public void addClick() {
|
||||
this.click++;
|
||||
this.lastClick = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package io.github.guilhermematthew.anticheat.list;
|
||||
|
||||
import io.github.guilhermematthew.anticheat.controller.PlayerController;
|
||||
import io.github.guilhermematthew.anticheat.listeners.ConstantListeners;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Autoclicker extends ConstantListeners {
|
||||
|
||||
private Map<Player, PlayerController> clicksPerSecond;
|
||||
private Map<Player, Long> cooldownMap;
|
||||
|
||||
/* public Autoclicker() {
|
||||
clicksPerSecond = new HashMap<>();
|
||||
cooldownMap = new HashMap<>();
|
||||
|
||||
ProtocolLibrary.getProtocolManager()
|
||||
.addPacketListener(new PacketAdapter(BukkitMain.getInstance(), PacketType.Play.Client.ARM_ANIMATION) {
|
||||
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (player == null || ProtocolGetter.getPing(player) >= 100)
|
||||
return;
|
||||
|
||||
if (cooldownMap.containsKey(player) && cooldownMap.get(player) > System.currentTimeMillis())
|
||||
return;
|
||||
|
||||
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.ADVENTURE)
|
||||
return;
|
||||
|
||||
try {
|
||||
if (player.getTargetBlock((Set<Material>) null, 4).getType() != Material.AIR) {
|
||||
return;
|
||||
}
|
||||
} catch (IllegalStateException ex) {
|
||||
return;
|
||||
}
|
||||
|
||||
handle(player);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteract(BlockDamageEvent event) {
|
||||
clicksPerSecond.remove(event.getPlayer());
|
||||
cooldownMap.put(event.getPlayer(), System.currentTimeMillis() + 10000l);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
clicksPerSecond.remove(event.getPlayer());
|
||||
cooldownMap.remove(event.getPlayer());
|
||||
}
|
||||
|
||||
public void handle(Player player) {
|
||||
Clicks click = clicksPerSecond.computeIfAbsent(player, v -> new Clicks());
|
||||
|
||||
if (click.getExpireTime() < System.currentTimeMillis()) {
|
||||
if (click.getClicks() >= 20) {
|
||||
alert(player, click.getClicks());
|
||||
}
|
||||
|
||||
clicksPerSecond.remove(player);
|
||||
return;
|
||||
}
|
||||
|
||||
click.addClick();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onUpdate(UpdateEvent event) {
|
||||
if (event.getType() == UpdateType.SECOND) {
|
||||
Iterator<Entry<Player, Clicks>> iterator = clicksPerSecond.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Entry<Player, Clicks> entry = iterator.next();
|
||||
|
||||
if (entry.getValue().getExpireTime() < System.currentTimeMillis()) {
|
||||
if (entry.getValue().getClicks() >= 20) {
|
||||
alert(entry.getKey(), entry.getValue().getClicks());
|
||||
}
|
||||
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package io.github.guilhermematthew.anticheat.listeners;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsGeneral;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.account.BukkitPlayer;
|
||||
import com.br.guilhermematthew.nowly.commons.common.profile.GamingProfile;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Getter
|
||||
public class ConstantListeners implements Listener {
|
||||
|
||||
private String nameAt;
|
||||
@Setter
|
||||
private boolean alertCommon;
|
||||
@Setter
|
||||
private int maxAlerts = 10;
|
||||
|
||||
public ConstantListeners() {
|
||||
nameAt = getClass().getSimpleName().replace("ConstantListeners", "");
|
||||
}
|
||||
|
||||
public void alert(Player player) {
|
||||
alert(player, 0);
|
||||
}
|
||||
|
||||
public void alert(Player player, int cpsCount) {
|
||||
broadcast(gamingProfile -> gamingProfile.isStaffer(), "§9Anticheat> §fO jogador §d" + player.getName() + "§f está usando §c" + getNameAt()
|
||||
+ (cpsCount > 0 ? " §4(" + cpsCount + " cps)" : "") + " §7(" + 1 + "/" + maxAlerts + ")!");
|
||||
}
|
||||
|
||||
public void broadcast(Predicate<? super GamingProfile> filter, String message) {
|
||||
CommonsGeneral.getProfileManager().getGamingProfiles().stream()
|
||||
.filter(gamingProfile -> gamingProfile.isStaffer())
|
||||
.forEach(gamingProfile -> gamingProfile.sendMessage(message));
|
||||
}
|
||||
|
||||
|
||||
}
|
32
commons/.classpath
Normal file
32
commons/.classpath
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
23
commons/.project
Normal file
23
commons/.project
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>commons</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
8
commons/.settings/org.eclipse.jdt.core.prefs
Normal file
8
commons/.settings/org.eclipse.jdt.core.prefs
Normal file
@ -0,0 +1,8 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
4
commons/.settings/org.eclipse.m2e.core.prefs
Normal file
4
commons/.settings/org.eclipse.m2e.core.prefs
Normal file
@ -0,0 +1,4 @@
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
129
commons/dependency-reduced-pom.xml
Normal file
129
commons/dependency-reduced-pom.xml
Normal file
@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>dustmc</artifactId>
|
||||
<groupId>com.br.guilhermematthew.nowly</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>commons</artifactId>
|
||||
<build>
|
||||
<defaultGoal>clean install</defaultGoal>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>dmulloy2-repo</id>
|
||||
<url>https://repo.dmulloy2.net/repository/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>viaversion-repo</id>
|
||||
<url>https://repo.viaversion.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.github.paperspigot</groupId>
|
||||
<artifactId>paperspigot-api</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<groupId>commons-lang</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>json-simple</artifactId>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>guava</artifactId>
|
||||
<groupId>com.google.guava</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>ebean</artifactId>
|
||||
<groupId>org.avaje</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<groupId>org.yaml</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>bungeecord-chat</artifactId>
|
||||
<groupId>net.md-5</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>4.8.0</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>byte-buddy</artifactId>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.viaversion</groupId>
|
||||
<artifactId>viaversion-api</artifactId>
|
||||
<version>[4.0.0,5.0.0)</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.12</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.16-R0.4</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>D:/Users/zFros/Desktop/[SRC]/Dependencias/Zartema.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
</project>
|
||||
|
129
commons/pom.xml
Normal file
129
commons/pom.xml
Normal file
@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>dustmc</artifactId>
|
||||
<groupId>com.br.guilhermematthew.nowly</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>commons</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean install</defaultGoal>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>dmulloy2-repo</id>
|
||||
<url>https://repo.dmulloy2.net/repository/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>viaversion-repo</id>
|
||||
<url>https://repo.viaversion.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.16-R0.4</version>
|
||||
<systemPath>D:/Users/zFros/Desktop/[SRC]/Dependencias/Zartema.jar</systemPath>
|
||||
<scope>system</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.paperspigot</groupId>
|
||||
<artifactId>paperspigot-api</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>4.8.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.10</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
<version>2.11.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.viaversion</groupId>
|
||||
<artifactId>viaversion-api</artifactId>
|
||||
<version>[4.0.0,5.0.0)</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>4.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.dv8tion</groupId>
|
||||
<artifactId>JDA</artifactId>
|
||||
<version>5.0.0-beta.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,21 @@
|
||||
package com.br.guilhermematthew.nowly.commons;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class CommonsConst {
|
||||
|
||||
public static final String SERVER_NAME = "LEAGUE";
|
||||
public static final String DEFAULT_COLOR = "§2";
|
||||
public static final String PREFIX = DEFAULT_COLOR + "§l" + SERVER_NAME.toUpperCase();
|
||||
public static final String LOJA = "www.leaguemc.com.br";
|
||||
public static final String DISCORD = "discord.gg/leaguemc";
|
||||
public static final String DIR_CONFIG_NAME = "DustConfig";
|
||||
public static final String PERMISSION_PREFIX = "commons";
|
||||
|
||||
public static final Random RANDOM = new Random();
|
||||
public static final JsonParser PARSER = new JsonParser();
|
||||
public static final Gson GSON = new Gson();
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.br.guilhermematthew.nowly.commons;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.account.BukkitPlayer;
|
||||
import com.br.guilhermematthew.nowly.commons.bungee.BungeeMain;
|
||||
import com.br.guilhermematthew.nowly.commons.common.PluginInstance;
|
||||
import com.br.guilhermematthew.nowly.commons.common.connections.mysql.MySQL;
|
||||
import com.br.guilhermematthew.nowly.commons.common.profile.GamingProfile;
|
||||
import com.br.guilhermematthew.nowly.commons.common.profile.ProfileManager;
|
||||
import com.br.guilhermematthew.nowly.commons.common.serverinfo.ServersManager;
|
||||
import com.br.guilhermematthew.nowly.commons.common.utility.mojang.UUIDFetcher;
|
||||
|
||||
public class CommonsGeneral {
|
||||
|
||||
private static final ProfileManager profileManager = new ProfileManager();
|
||||
private static final UUIDFetcher uuidFetcher = new UUIDFetcher();
|
||||
private static final ServersManager serversManager = new ServersManager();
|
||||
private static final MySQL mySQL = new MySQL();
|
||||
|
||||
private static PluginInstance pluginInstance = PluginInstance.UNKNOWN;
|
||||
|
||||
public static boolean correctlyStarted() {
|
||||
if (!getMySQL().isConnected()) {
|
||||
error("A conexao com o MySQL nao teve exito, fechando servidor.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static ProfileManager getProfileManager() {
|
||||
return profileManager;
|
||||
}
|
||||
|
||||
public static UUIDFetcher getUUIDFetcher() {
|
||||
return uuidFetcher;
|
||||
}
|
||||
|
||||
public static PluginInstance getPluginInstance() {
|
||||
return pluginInstance;
|
||||
}
|
||||
|
||||
public static void setPluginInstance(PluginInstance pluginInstance) {
|
||||
CommonsGeneral.pluginInstance = pluginInstance;
|
||||
}
|
||||
|
||||
public static ServersManager getServersManager() {
|
||||
return serversManager;
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
if (pluginInstance == PluginInstance.BUNGEECORD) {
|
||||
BungeeMain.shutdown();
|
||||
} else {
|
||||
BukkitMain.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public static void error(String message) {
|
||||
console("§c[ERRO] " + message);
|
||||
}
|
||||
|
||||
public static void console(String message) {
|
||||
if (pluginInstance == PluginInstance.BUKKIT) {
|
||||
BukkitMain.console(message);
|
||||
} else {
|
||||
BungeeMain.console(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void runAsync(Runnable runnable) {
|
||||
if (pluginInstance == PluginInstance.BUKKIT) {
|
||||
BukkitMain.runAsync(runnable);
|
||||
} else {
|
||||
BungeeMain.runAsync(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
public static MySQL getMySQL() {
|
||||
return mySQL;
|
||||
}
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsGeneral;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.account.BukkitPlayer;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.BukkitServerAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.item.ActionItemListener;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.menu.MenuListener;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.commands.BukkitCommandFramework;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.server.ServerStatusUpdateEvent;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.scheduler.BukkitUpdateScheduler;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.listeners.CoreListener;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.listeners.WorldDListener;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.manager.BukkitManager;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.networking.BukkitPacketsHandler;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.utility.loader.BukkitListeners;
|
||||
import com.br.guilhermematthew.nowly.commons.common.PluginInstance;
|
||||
import com.br.guilhermematthew.nowly.commons.common.serverinfo.ServerType;
|
||||
import com.br.guilhermematthew.nowly.commons.custompackets.PacketType;
|
||||
import com.br.guilhermematthew.nowly.commons.custompackets.registry.CPacketCustomAction;
|
||||
import com.br.guilhermematthew.servercommunication.ServerCommunication;
|
||||
import com.br.guilhermematthew.servercommunication.client.Client;
|
||||
import com.br.guilhermematthew.servercommunication.server.Server;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitMain extends JavaPlugin {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private static BukkitMain instance;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private static int serverID;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private static ServerType serverType;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private static boolean loaded;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private static BukkitManager manager;
|
||||
|
||||
public static void console(String msg) {
|
||||
Bukkit.getConsoleSender().sendMessage("[Commons] " + msg);
|
||||
}
|
||||
|
||||
public static void runAsync(Runnable runnable) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(getInstance(), runnable);
|
||||
}
|
||||
|
||||
public static void runLater(Runnable runnable) {
|
||||
runLater(runnable, 5);
|
||||
}
|
||||
|
||||
public static void runLater(Runnable runnable, long ticks) {
|
||||
Bukkit.getScheduler().runTaskLater(getInstance(), runnable, ticks);
|
||||
}
|
||||
|
||||
public static void runSync(Runnable runnable) {
|
||||
if (getInstance().isEnabled() && !getInstance().getServer().isPrimaryThread()) {
|
||||
getInstance().getServer().getScheduler().runTask(getInstance(), runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public static BukkitPlayer getBukkitPlayer(final UUID uniqueId) {
|
||||
return (BukkitPlayer) CommonsGeneral.getProfileManager().getGamingProfile(uniqueId);
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
|
||||
public void onLoad() {
|
||||
saveDefaultConfig();
|
||||
|
||||
setLoaded(false);
|
||||
|
||||
setInstance(this);
|
||||
setManager(new BukkitManager());
|
||||
|
||||
// new BukkitLogFilter().registerFilter();
|
||||
|
||||
CommonsGeneral.setPluginInstance(PluginInstance.BUKKIT);
|
||||
|
||||
getManager().getConfigurationManager().init();
|
||||
getServer().getMessenger().registerOutgoingPluginChannel(this, "WDL|CONTROL");
|
||||
getServer().getMessenger().registerIncomingPluginChannel(this, "WDL|INIT", new WorldDListener());
|
||||
setServerType(ServerType.getServer(getConfig().getString("Servidor")));
|
||||
setServerID(getConfig().getInt("ServidorID"));
|
||||
|
||||
CommonsGeneral.getMySQL().openConnection();
|
||||
}
|
||||
|
||||
public void onEnable() {
|
||||
if (getServerType() != ServerType.UNKNOWN) {
|
||||
if (CommonsGeneral.correctlyStarted()) {
|
||||
CommonsGeneral.getMySQL().createTables();
|
||||
|
||||
ServerCommunication.startClient(getServerType().getName(), getServerID(), getConfig().getString("Socket.Host"));
|
||||
ServerCommunication.setPacketHandler(new BukkitPacketsHandler());
|
||||
|
||||
BukkitServerAPI.unregisterCommands("op", "deop", "kill", "about", "ver", "?", "scoreboard", "me", "say", "pl",
|
||||
"plugins", "reload", "rl", "stop", "ban", "ban-ip", "msg", "ban-list", "help", "pardon",
|
||||
"pardon-ip", "tp", "xp", "gamemode", "minecraft");
|
||||
|
||||
BukkitCommandFramework.INSTANCE.loadCommands(this, "com.br.guilhermematthew.nowly.commons.bukkit.commands.register");
|
||||
BukkitListeners.loadListeners(getInstance(), "com.br.guilhermematthew.nowly.commons.bukkit.listeners");
|
||||
|
||||
getServer().getMessenger().registerOutgoingPluginChannel(getInstance(), "BungeeCord");
|
||||
|
||||
if (getServerType().useMenuListener()) {
|
||||
MenuListener.registerListeners();
|
||||
}
|
||||
|
||||
if (getServerType().useActionItem()) {
|
||||
Bukkit.getServer().getPluginManager().registerEvents(new ActionItemListener(), getInstance());
|
||||
}
|
||||
|
||||
CoreListener.init();
|
||||
Bukkit.getServer().getScheduler().runTaskTimer(getInstance(), new BukkitUpdateScheduler(), 1, 1);
|
||||
|
||||
initialize();
|
||||
} else {
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
} else {
|
||||
console("§cTipo de servidor nao encontrado, mude na configuracao!");
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
Client.getInstance().getClientConnection().sendPacket(new CPacketCustomAction(BukkitMain.getServerType(), BukkitMain.getServerID())
|
||||
.type(PacketType.BUKKIT_SEND_INFO).field("bukkit-server-turn-off"));
|
||||
|
||||
CommonsGeneral.getMySQL().closeConnection();
|
||||
|
||||
if (Server.getInstance() != null) {
|
||||
try {
|
||||
Server.getInstance().getServerGeneral().disconnect();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
getServer().getScheduler().runTaskTimer(getInstance(), () -> {
|
||||
ServerStatusUpdateEvent event = new ServerStatusUpdateEvent(getServer().getOnlinePlayers().size(), true);
|
||||
|
||||
getServer().getPluginManager().callEvent(event);
|
||||
}, 0, 20L * getServerType().getSecondsUpdateStatus());
|
||||
}
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit;
|
||||
|
||||
public class BukkitMessages {
|
||||
|
||||
public static final String
|
||||
|
||||
SEU_TEMPO_DE_GRUPO_EXPIROU = "§cO rank %s §cque você possuia teve seu tempo esgotado!",
|
||||
VOCE_DESATIVOU_A_VISIBILIDADE_DOS_JOGADORES = "§cVocê desativou a opção de visibilidade dos jogadores.",
|
||||
VOCE_ATIVOU_A_VISIBILIDADE_DOS_JOGADORES = "§aVocê ativou a opção de visibilidade dos jogadores.",
|
||||
VOCE_ESTA_TENTANDO_EXECUTAR_COMANDOS_MUITO_RAPIDO = "§cVocê está tentando executar comandos muito rápido!",
|
||||
CONNECTING = "§aConectando...",
|
||||
SEU_SLOT_FOI_DADO_A_UM_JOGADOR_VIP = "§cO slot que você possuia foi liberado para um jogador VIP!",
|
||||
DEATH_MESSAGE_XP = "§c-%quantia% XP",
|
||||
KILL_MESSAGE_XP = "§a+%quantia% XP",
|
||||
KILL_MESSAGE_COINS = "§a+%quantia% coins",
|
||||
DEATH_MESSAGE_COINS = "§c-%quantia% coins",
|
||||
|
||||
ACABOU_OS_SLOTS_PARA_MEMBROS = "§cO servidor está lotado!",
|
||||
|
||||
//PREFERENCES
|
||||
CLAN_TAG_DISPLAY_ATIVADO = "§aAgora a TAG do seu Clan irá aparecer.",
|
||||
CLAN_TAG_DISPLAY_DESATIVADO = "§cAgora a TAG do seu Clan não irá aparecer.",
|
||||
|
||||
RANKS_PREFIX = "§eOs ranks são ligas ou patentes que Você pode upar ganhando XPs jogando, matando jogadores e ganhando partidas.",
|
||||
|
||||
SUAS_MEDALHAS = "§aSuas medalhas: ",
|
||||
TIROU_MEDALHA = "§cVocê removeu sua medalha.",
|
||||
MEDALHA_SELECIONADA = "§aVocê selecionou a medalha %medalha%§a com sucesso.",
|
||||
NAO_POSSUI_MEDALHA = "§cVocê não possui a medalha citada.",
|
||||
|
||||
|
||||
//TAGS START
|
||||
|
||||
SUAS_TAGS = "§aSuas tags:",
|
||||
VOCE_JA_ESTA_USANDO_ESTA_TAG = "§cVocê já está utilizando está tag.",
|
||||
TAG_SELECIONADA = "§aVocê está utilizando a tag %tag%",
|
||||
NAO_POSSUI_TAG = "§cVocê não possui esta TAG.",
|
||||
VOCE_NAO_PODE_TROCAR_A_TAG = "§cVocê não pode trocar sua tag.",
|
||||
|
||||
//TAGS END
|
||||
|
||||
//LEAGUE START
|
||||
|
||||
PLAYER_SUBIU_DE_LIGA = "§aParabéns! O jogador %nick% alcançou uma nova liga. Ela é %liga%",
|
||||
VOCE_SUBIU_DE_LIGA = "§aParabéns, Você subiu de liga! continue jogando e aprimorando suas habilidades.",
|
||||
|
||||
//LEAGUE END
|
||||
|
||||
VOCE_NAO_TEM_PERMISSãO_PARA_USAR_ESTE_COMANDO = "§cVocê não possui permissão para utilizar este comando.",
|
||||
THE_SERVER_IS_LOADING = "§cO servidor ainda não carregou.",
|
||||
THE_SERVER_NOT_RECEIVED_PLAYER_DATA = "§cA sala %s §cnão possui recebimentos de dados do mesmo.",
|
||||
THE_SERVER_WITH_WHITELIST = "§cEsta sala atualmente está liberada somente para equipe.",
|
||||
|
||||
STOP_PREFIX = "§cFechando servidor...",
|
||||
STOP_SENDING_PLAYERS_TO_LOBBY = "§aTentando enviar todos os jogadores locais para o Lobby.",
|
||||
PLAYER_SERVER_RESTARTING = "§cO Servidor atual irá reiniciar, Você será movido automaticamente para o Lobby.",
|
||||
|
||||
//FAKE START
|
||||
|
||||
FAKE_LIST_PREFIX = "§c",
|
||||
FAKE_LIST_LINHA = "§f- §e%nickFake% §f(§7%nickReal%§f)",
|
||||
FAKE_HELP = "§cUtilize o comando: /fake (nick/random/#/list)",
|
||||
NAO_ESTA_USANDO_FAKE = "§cVocê não está utilizando um Fake.",
|
||||
NAO_PODE_TIRAR_FAKE = "§cVocê não pode %action% o fake agora.",
|
||||
TIROU_FAKE = "§aFake removido com sucesso!",
|
||||
NENHUM_FAKE_RANDOM = "§cNenhum fake disponivel.",
|
||||
FAKE_INDISPONIVEL = "§cEste nick está associado a uma conta original.",
|
||||
FAKE_SUCESSO = "§aVocê alterou seu nick para: §e§l%nick%",
|
||||
NENHUM_JOGADOR_COM_FAKE = "§eNenhum jogador está utilizado fake!",
|
||||
VOCE_ENTROU_NO_SERVIDOR_COM_O_FAKE = "§aVocê entrou no servidor utilizando fake!",
|
||||
|
||||
//FAKE END;
|
||||
|
||||
COOLDOWN_MESSAGE = "§cAguarde %tempo% para usar novamente.",
|
||||
|
||||
//CHAT
|
||||
CHAT_COOLDOWN = "§cAguarde para digitar no chat novamente.",
|
||||
CHAT_ESTA_DESATIVADO = "§cO chat está desativado.",
|
||||
CHAT_DESATIVADO = "§cO chat foi desativado.",
|
||||
CHAT_ATIVADO = "§aO chat foi ativado.",
|
||||
CHAT_LIMPO = "§aO chat foi limpo.",
|
||||
COMANDO_BLOQUEADO = "§cEste comando está bloqueado em nosso servidor.",
|
||||
COMANDO_INEXISTENTE = "§cEste comando não existe.",
|
||||
|
||||
SYNC_TPALL_RUNNING = "§cJá existe um SyncTpall em andamento.",
|
||||
SYNC_TPALL_FINALIZED = "§aSyncTpall terminado!",
|
||||
TPALL = "§aTodos os jogadores foram teletransportado!",
|
||||
|
||||
BROADCAST_USAGE = "§cPara enviar um anúncio no seu servidor utilize: /bc (mensagem)",
|
||||
BROADCAST_PREFIX = "§2§lLEAGUE §8» §f",
|
||||
|
||||
CLEAR_DROPS = "§cForam removidos %quantia% itens do chão.",
|
||||
KILL_MOBS = "§cForam removidos %quantia% mobs.",
|
||||
|
||||
DANO_ATIVADO = "§aO DANO foi ativado!",
|
||||
DANO_DESATIVADO = "§cO DANO foi desativado!",
|
||||
|
||||
PVP_ATIVADO = "§aO PVP foi ativado!",
|
||||
PVP_DESATIVADO = "§cO PVP foi desativado",
|
||||
|
||||
JOGADOR_OFFLINE = "§cJogador offline!",
|
||||
|
||||
FLY_ATIVADO = "§aO modo voar foi ativado.",
|
||||
FLY_DESATIVADO = "§cO modo voar foi desativado.",
|
||||
|
||||
FLY_ATIVADO_PARA = "§eO modo voar foi ativado para §b%nick%",
|
||||
FLY_DESATIVADO_PARA = "§eO modo voar foi desativado para §b%nick%",
|
||||
|
||||
INVSEE = "§cUtilize: /invsee <Nick>",
|
||||
INVSEE_SUCESSO = "§aVocê abriu o inventário de %nick%",
|
||||
VOCE_NAO_PODE_ABRIR_SEU_INVENTARIO = "§cVocê não pode abrir o seu próprio inventário.",
|
||||
|
||||
SEU_PING = "§eSeu ping atual é: §b%quantia% ms",
|
||||
PING_OUTRO = "§eO ping do player %nick%§f é de: §b%quantia% ms",
|
||||
|
||||
GAMEMODE_CHANGE_FOR_SENDER = "§eVocê alterou o modo de jogo do(a) jogador(a) %nick% §apara o modo %gamemode%",
|
||||
VOCE_JA_ESTA_NESSE_GAMEMODE = "§cVocê ja está nesse modo de jogo!",
|
||||
GAMEMODE_CHANGED = "§aSeu modo de jogo foi alterado para %gamemode%",
|
||||
|
||||
TELEPORT_USAGE =
|
||||
"§cUtilize: /tp <Nick>\n" +
|
||||
"§cUtilize: /tp <Player1> <Player2>\n" +
|
||||
"§cUtilize: /tp <X> <Y> <Z>\n" +
|
||||
"§cUtilize: /tp <Nick> <X> <Y> <Z>",
|
||||
|
||||
TELEPORTED_TO_PLAYER = "§aVocê foi teleportado para §7§l%nick% §acom sucesso!",
|
||||
TELEPORTED_PLAYER_TO_PLAYER = "§cVocê teleportou §7%nick% §apara o §7%nick1%",
|
||||
TELEPORTED_TO_LOCATION = "§aVocê se teleportou para §7%coords%",
|
||||
TELEPORTED_PLAYER_TO_LOCATION = "§aVocê teleportou o §7%nick% §apara §7%coords%",
|
||||
|
||||
//SKIN START
|
||||
|
||||
SKIN_USAGE = "§cUtilize: /skin <Nick>",
|
||||
SKIN_MUDADA = "§aSua skin foi alterada com sucesso!",
|
||||
SKIN_ATUALIZADA = "§aSua skin foi atualizada com sucesso!",
|
||||
|
||||
ERROR_ON_UPDATE_SKIN = "§cOcorreu um erro ao tentar atualizar sua skin!",
|
||||
ERROR_ON_CHANGE_SKIN = "§cOcorreu um erro ao tentar trocar sua skin!",
|
||||
|
||||
SKIN_AGUARDE_PARA_TROCAR = "§cAguarde para trocar de skin novamente!",
|
||||
SKIN_DOWNLOADING = "§aSkin sendo baixada, aguarde...",
|
||||
VOCE_NAO_PODE_TROCAR_SUA_SKIN_AGORA = "§cVocê não pode trocar sua skin agora!",
|
||||
//SKIN END;
|
||||
|
||||
//TELL AND REPLY START
|
||||
|
||||
TELL_SPY = "§f[SPY] §8Mensagem de §6%nick% §8para §6%nick1%§8: §f%mensagem%",
|
||||
|
||||
COMMAND_REPLY_USAGE = "§cUtilize: /r <Mensagem>",
|
||||
VOCE_NAO_TEM_NENHUMA_CONVERSA_PARA_RESPONDER = "§cVocê não tem nenhuma conversa para responder.",
|
||||
|
||||
COMMAND_TELL_USAGE = "\n"
|
||||
+ "§cUtilize: /tell <Nick> <Mensagem>\n"
|
||||
+ "§cUtilize: /tell <On/Off>\n",
|
||||
|
||||
TELL_PARA_JOGADOR = "§8Mensagem para §6%nick%: §f%mensagem%",
|
||||
TELL_DE_JOGADOR = "§8Mensagem para §6%nick%: §f%mensagem%",
|
||||
|
||||
TELL_JA_ESTA_ATIVADO = "§aSuas mensagens privadas já estão ativas.",
|
||||
TELL_JA_ESTA_DESATIVADO = "§cSuas mensagens privadas já estão desativadas.",
|
||||
TELL_ATIVADO = "§aAgora você poderá receber mensagens privadas.",
|
||||
TELL_DESATIVADO = "§cVocê desativou o recebimento de mensagens privadas.",
|
||||
VOCE_NAO_PODE_ENVIAR_MENSAGEM_PARA_VOCE_MESMO = "§cVocê não pode enviar mensagem para si mesmo.",
|
||||
JOGADOR_COM_TELL_DESATIVADO = "§cO jogador não pode receber mensagens privadas.",
|
||||
//TELL AND REPLY END
|
||||
|
||||
NAO_TEM_CONTA = "§cO nickname citado não possuí um registro na rede.",
|
||||
|
||||
//ADMIN START
|
||||
|
||||
ADMIN_CANCELADO = "§cVocê não pode sair e/ou entrar no modo admin agora.",
|
||||
SAIU_DO_ADMIN = "§dVocê saiu do modo VANISH!",
|
||||
ENTROU_NO_ADMIN = "§dVocê entrou no modo VANISH!\n§dAgora você está visível somente para Moderação e Superiores.",
|
||||
PLAYER_SAIU_DO_ADMIN = "§c%nick% saiu do modo admin!",
|
||||
PLAYER_ENTROU_NO_ADMIN = "§a%nick% entrou no modo admin",
|
||||
PLAYER_FICOU_VISIVEL = "§aVocê está visível para todos os jogadores.",
|
||||
PLAYER_FICOU_INVISIVEL = "§cVocê está invisível para todos jogadores com cargo abaixo de %grupo%";
|
||||
|
||||
//ADMIN END
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class BukkitSettings {
|
||||
|
||||
@Getter
|
||||
public static boolean
|
||||
|
||||
CHAT_OPTION = true,
|
||||
PVP_OPTION = true,
|
||||
DANO_OPTION = true,
|
||||
DOUBLE_COINS_OPTION = false,
|
||||
DOUBLE_XP_OPTION = false,
|
||||
|
||||
LOGIN_OPTION = true;
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.account;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.account.permission.PlayerAttachment;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.player.PlayerChangeTagEvent;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.player.PlayerRequestEvent;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.scoreboard.tag.TagManager;
|
||||
import com.br.guilhermematthew.nowly.commons.common.data.category.DataCategory;
|
||||
import com.br.guilhermematthew.nowly.commons.common.data.type.DataType;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
import com.br.guilhermematthew.nowly.commons.common.profile.GamingProfile;
|
||||
import com.br.guilhermematthew.nowly.commons.common.profile.addons.League;
|
||||
import com.br.guilhermematthew.nowly.commons.common.tag.Tag;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class BukkitPlayer extends GamingProfile {
|
||||
|
||||
private String lastMessage;
|
||||
private Long lastChangeSkin;
|
||||
private Property lastSkin;
|
||||
private PlayerAttachment playerAttachment;
|
||||
private Tag actualTag;
|
||||
|
||||
public BukkitPlayer(String nick, String address, UUID uniqueId) {
|
||||
super(nick, address, uniqueId);
|
||||
this.lastMessage = "";
|
||||
this.lastChangeSkin = 0L;
|
||||
this.actualTag = Groups.MEMBRO.getTag();
|
||||
}
|
||||
|
||||
|
||||
public void addXP(final int amount) {
|
||||
League actualLeague = League.getRanking(getInt(DataType.XP)),
|
||||
newLeague = League.getRanking(getInt(DataType.XP) + amount);
|
||||
|
||||
getData(DataType.XP).add(amount);
|
||||
|
||||
if (actualLeague != newLeague) {
|
||||
Player player = getPlayer();
|
||||
|
||||
Bukkit.broadcastMessage(BukkitMessages.PLAYER_SUBIU_DE_LIGA.replace("%nick%", player.getName()).replace("%liga%", newLeague.getColor() +
|
||||
newLeague.getName().toUpperCase()));
|
||||
|
||||
player.sendMessage(BukkitMessages.VOCE_SUBIU_DE_LIGA);
|
||||
|
||||
TagManager.setTag(player, getActualTag(), this);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerRequestEvent(player, "update-scoreboard"));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeXP(final int amount) {
|
||||
League actualLeague = League.getRanking(getInt(DataType.XP));
|
||||
|
||||
getData(DataType.XP).remove(amount);
|
||||
|
||||
League newLeague = League.getRanking(getInt(DataType.XP));
|
||||
|
||||
if (actualLeague != newLeague) {
|
||||
Player player = getPlayer();
|
||||
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerRequestEvent(player, "update-scoreboard"));
|
||||
TagManager.setTag(player, getActualTag(), this);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTag(final Player player, final Tag newTag, boolean forced) {
|
||||
PlayerChangeTagEvent event = new PlayerChangeTagEvent(player, getActualTag(), newTag, forced);
|
||||
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) return;
|
||||
|
||||
if(actualTag != newTag) {
|
||||
set(DataType.TAG, newTag.getName());
|
||||
|
||||
BukkitMain.runAsync(() -> getDataHandler().saveCategory(DataCategory.ACCOUNT));
|
||||
}
|
||||
|
||||
this.actualTag = newTag;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return Bukkit.getPlayer(getUniqueId());
|
||||
}
|
||||
|
||||
public void setLastMessage(String name) {
|
||||
this.lastMessage = name;
|
||||
}
|
||||
|
||||
public boolean canChangeSkin() {
|
||||
return getLastChangeSkin() + TimeUnit.SECONDS.toMillis(40) < System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void injectPermissions(Player player) {
|
||||
if (playerAttachment == null) playerAttachment = new PlayerAttachment(player, BukkitMain.getInstance());
|
||||
|
||||
playerAttachment.removePermissions(playerAttachment.getPermissions());
|
||||
playerAttachment.addPermissions(getGroup().getPermissions());
|
||||
|
||||
val permissions = getData(DataType.PERMISSIONS).getList();
|
||||
playerAttachment.addPermissions(permissions);
|
||||
}
|
||||
|
||||
public void validateGroups() {
|
||||
Long groupTime = getLong(DataType.GROUP_TIME);
|
||||
|
||||
if (groupTime != 0L) {
|
||||
if (System.currentTimeMillis() > groupTime) {
|
||||
getData(DataType.GROUP_TIME).setValue(0L);
|
||||
getData(DataType.GROUP).setValue("Membro");
|
||||
getData(DataType.GROUP_CHANGED_BY).setValue("Console");
|
||||
|
||||
Groups groupExpired = getGroup();
|
||||
|
||||
if (getString(DataType.FAKE).isEmpty()) {
|
||||
setActualTag(getGroup().getTag());
|
||||
TagManager.setTag(getPlayer(), getGroup());
|
||||
} else {
|
||||
setActualTag(Groups.MEMBRO.getTag());
|
||||
TagManager.setTag(getPlayer(), Groups.MEMBRO);
|
||||
}
|
||||
|
||||
Player player = getPlayer();
|
||||
player.sendMessage(String.format(BukkitMessages.SEU_TEMPO_DE_GRUPO_EXPIROU, groupExpired.getColor() + groupExpired.getName()));
|
||||
|
||||
injectPermissions(player);
|
||||
|
||||
BukkitMain.runAsync(() -> getDataHandler().saveCategory(DataCategory.ACCOUNT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.account.permission;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerAttachment {
|
||||
|
||||
private final PermissionAttachment attachment;
|
||||
|
||||
public PlayerAttachment(Player player, Plugin plugin) {
|
||||
this.attachment = player.addAttachment(plugin);
|
||||
}
|
||||
|
||||
public void addPermission(String permission) {
|
||||
this.attachment.setPermission(permission, true);
|
||||
}
|
||||
|
||||
public void addPermissions(List<String> permissions) {
|
||||
if (permissions == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String permission : permissions) {
|
||||
this.attachment.setPermission(permission, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void removePermissions(List<String> permissions) {
|
||||
if (permissions == null) return;
|
||||
|
||||
for (String permission : permissions) this.attachment.setPermission(permission, false);
|
||||
}
|
||||
|
||||
public void resetPermissions() {
|
||||
if (getPermissions().size() != 0) {
|
||||
for (String permissions : getPermissions()) {
|
||||
this.attachment.setPermission(permissions, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removePermission(String permission) {
|
||||
this.attachment.setPermission(permission, false);
|
||||
}
|
||||
|
||||
public List<String> getPermissions() {
|
||||
return new ArrayList<>(attachment.getPermissions().keySet());
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsGeneral;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
import com.br.guilhermematthew.nowly.commons.common.profile.GamingProfile;
|
||||
import com.br.guilhermematthew.nowly.commons.custompackets.PacketType;
|
||||
import com.br.guilhermematthew.nowly.commons.custompackets.registry.CPacketCustomAction;
|
||||
import com.br.guilhermematthew.servercommunication.client.Client;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitServerAPI {
|
||||
|
||||
@Getter
|
||||
private static boolean registeredServer = false;
|
||||
|
||||
public static void registerServer() {
|
||||
registeredServer = true;
|
||||
|
||||
Client.getInstance().getClientConnection().sendPacket(new CPacketCustomAction(BukkitMain.getServerType(), BukkitMain.getServerID()).
|
||||
type(PacketType.BUKKIT_SEND_INFO).
|
||||
field("bukkit-register-server").
|
||||
fieldValue(Bukkit.getServer().getIp()).
|
||||
extraValue("" + Bukkit.getServer().getPort()));
|
||||
}
|
||||
|
||||
public static void redirectPlayer(final Player player, final String server) {
|
||||
redirectPlayer(player, server, false);
|
||||
}
|
||||
|
||||
public static boolean checkItem(ItemStack item, String display) {
|
||||
return (item != null && item.getType() != Material.AIR && item.hasItemMeta() && item.getItemMeta().hasDisplayName()
|
||||
&& item.getItemMeta().getDisplayName().startsWith(display));
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public static void redirectPlayer(final Player player, final String server, final boolean kick) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Connect");
|
||||
out.writeUTF(server);
|
||||
|
||||
player.sendPluginMessage(BukkitMain.getInstance(), "BungeeCord", out.toByteArray());
|
||||
|
||||
player.sendMessage(BukkitMessages.CONNECTING);
|
||||
|
||||
if (kick) {
|
||||
BukkitMain.runLater(() -> {
|
||||
if (player.isOnline()) {
|
||||
if (server.equalsIgnoreCase("LobbyPvP") || (server.equalsIgnoreCase("LobbyHardcoreGames"))) {
|
||||
player.sendMessage("§cOcorreu um erro ao tentar conectar-se ao Servidor: §7" + server);
|
||||
redirectPlayer(player, "Lobby", true);
|
||||
} else {
|
||||
player.kickPlayer("§cOcorreu um erro ao tentar conectar-se ao servidor: " + server);
|
||||
}
|
||||
}
|
||||
}, 40);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void unregisterCommands(String... commands) {
|
||||
try {
|
||||
Field firstField = Bukkit.getServer().getClass().getDeclaredField("commandMap");
|
||||
firstField.setAccessible(true);
|
||||
CommandMap commandMap = (CommandMap) firstField.get(Bukkit.getServer());
|
||||
Field secondField = commandMap.getClass().getDeclaredField("knownCommands");
|
||||
secondField.setAccessible(true);
|
||||
HashMap<String, Command> knownCommands = (HashMap<String, Command>) secondField.get(commandMap);
|
||||
for (String command : commands) {
|
||||
if (knownCommands.containsKey(command)) {
|
||||
knownCommands.remove(command);
|
||||
List<String> aliases = new ArrayList<>();
|
||||
for (String key : knownCommands.keySet()) {
|
||||
if (!key.contains(":"))
|
||||
continue;
|
||||
|
||||
String substr = key.substring(key.indexOf(":") + 1);
|
||||
if (substr.equalsIgnoreCase(command)) {
|
||||
aliases.add(key);
|
||||
}
|
||||
}
|
||||
for (String alias : aliases) {
|
||||
knownCommands.remove(alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void removePlayerFile(UUID uuid) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
File folder = new File(world.getWorldFolder(), "playerdata");
|
||||
|
||||
if (folder.exists() && folder.isDirectory()) {
|
||||
File file = new File(folder, uuid.toString() + ".dat");
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(BukkitMain.getInstance(), () -> {
|
||||
if (file.exists() && !file.delete()) {
|
||||
removePlayerFile(uuid);
|
||||
}
|
||||
}, 2L);
|
||||
}
|
||||
}
|
||||
|
||||
public static void warnStaff(String message, Groups tag) {
|
||||
for (GamingProfile profiles : CommonsGeneral.getProfileManager().getGamingProfiles()) {
|
||||
if (profiles.getGroup().getLevel() >= tag.getLevel()) {
|
||||
Player target = Bukkit.getPlayer(profiles.getUniqueId());
|
||||
|
||||
if (target != null) target.sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Player getExactPlayerByNick(String nick) {
|
||||
Player finded = null;
|
||||
|
||||
for (GamingProfile profiles : CommonsGeneral.getProfileManager().getGamingProfiles()) {
|
||||
if (profiles.getNick().equalsIgnoreCase(nick)) {
|
||||
finded = Bukkit.getPlayer(profiles.getUniqueId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return finded;
|
||||
}
|
||||
|
||||
public static String getRealNick(Player target) {
|
||||
return CommonsGeneral.getProfileManager().getGamingProfile(target.getUniqueId()).getNick();
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.actionbar;
|
||||
|
||||
import net.minecraft.server.v1_8_R3.IChatBaseComponent.ChatSerializer;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutChat;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ActionBarAPI {
|
||||
|
||||
public static void send(final Player player, final String message) {
|
||||
PacketPlayOutChat packet = new PacketPlayOutChat(ChatSerializer.a("{\"text\": \"" + message + "\"}"), (byte) 2);
|
||||
|
||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
|
||||
public static void broadcast(final String message) {
|
||||
PacketPlayOutChat packet = new PacketPlayOutChat(ChatSerializer.a("{\"text\": \"" + message + "\"}"), (byte) 2);
|
||||
|
||||
for (Player onlines : Bukkit.getOnlinePlayers())
|
||||
((CraftPlayer) onlines).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.bossbar;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.minecraft.server.v1_8_R3.EntityWither;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class BossBar {
|
||||
|
||||
private Player player;
|
||||
private EntityWither wither;
|
||||
private boolean cancelar, tempo;
|
||||
private int segundos;
|
||||
|
||||
public BossBar(final Player player, final String message, final boolean tempo) {
|
||||
setPlayer(player);
|
||||
setCancelar(false);
|
||||
setTempo(tempo);
|
||||
setSegundos(20);
|
||||
|
||||
setWither(new EntityWither(((CraftWorld) player.getWorld()).getHandle()));
|
||||
|
||||
getWither().setInvisible(true);
|
||||
getWither().setCustomName(message);
|
||||
getWither().getEffects().clear();
|
||||
getWither().setLocation(getViableLocation().getX(), getViableLocation().getY(), getViableLocation().getZ(), 0, 0);
|
||||
|
||||
((CraftPlayer) getPlayer()).getHandle().playerConnection.sendPacket(new PacketPlayOutSpawnEntityLiving(getWither()));
|
||||
}
|
||||
|
||||
public void onSecond() {
|
||||
if (isCancelar()) {
|
||||
destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getPlayer().isOnline()) {
|
||||
setCancelar(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isTempo()) {
|
||||
update();
|
||||
return;
|
||||
}
|
||||
|
||||
if (getSegundos() == 0) {
|
||||
destroy();
|
||||
setCancelar(true);
|
||||
return;
|
||||
}
|
||||
|
||||
segundos--;
|
||||
update();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (wither == null || player == null) return;
|
||||
|
||||
wither.setLocation(getViableLocation().getX(), getViableLocation().getY(), getViableLocation().getZ(), 0, 0);
|
||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutEntityTeleport(wither));
|
||||
}
|
||||
|
||||
public Location getViableLocation() {
|
||||
if (player == null)
|
||||
return new Location(Bukkit.getWorld("world"), 0, 0, 0);
|
||||
return player.getEyeLocation().add(player.getEyeLocation().getDirection().multiply(28));
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutEntityDestroy(wither.getId()));
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.bossbar;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.BukkitUpdateEvent;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.BukkitUpdateEvent.UpdateType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BossBarAPI {
|
||||
|
||||
private static final HashMap<UUID, BossBar> bossBars = new HashMap<>();
|
||||
private static boolean initialized = false;
|
||||
|
||||
private static void init() {
|
||||
if (initialized) return;
|
||||
|
||||
initialized = true;
|
||||
|
||||
Bukkit.getServer().getPluginManager().registerEvents(new Listener() {
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
if (getBossBars().containsKey(event.getPlayer().getUniqueId())) {
|
||||
getBossBars().get(event.getPlayer().getUniqueId()).destroy();
|
||||
getBossBars().remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent event) {
|
||||
if (getBossBars().containsKey(event.getEntity().getUniqueId())) {
|
||||
getBossBars().get(event.getEntity().getUniqueId()).destroy();
|
||||
getBossBars().remove(event.getEntity().getUniqueId());
|
||||
}
|
||||
|
||||
if (event.getEntity().getKiller() != null) {
|
||||
if (getBossBars().containsKey(event.getEntity().getKiller().getUniqueId())) {
|
||||
getBossBars().get(event.getEntity().getKiller().getUniqueId()).destroy();
|
||||
getBossBars().remove(event.getEntity().getKiller().getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onUpdate(BukkitUpdateEvent event) {
|
||||
if (event.getType() != UpdateType.SEGUNDO) return;
|
||||
|
||||
if (bossBars.size() > 0) {
|
||||
List<UUID> toRemove = new ArrayList<>();
|
||||
|
||||
for (BossBar boss : bossBars.values()) {
|
||||
if (boss.isCancelar()) {
|
||||
boss.destroy();
|
||||
toRemove.add(boss.getPlayer().getUniqueId());
|
||||
} else {
|
||||
boss.onSecond();
|
||||
}
|
||||
}
|
||||
|
||||
toRemove.forEach(uuids -> bossBars.remove(uuids));
|
||||
|
||||
toRemove.clear();
|
||||
toRemove = null;
|
||||
}
|
||||
}
|
||||
|
||||
}, BukkitMain.getInstance());
|
||||
}
|
||||
|
||||
public static void send(Player player, String name, int tempo) {
|
||||
if (!initialized) {
|
||||
init();
|
||||
send(player, name, tempo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (getBossBars().containsKey(player.getUniqueId())) {
|
||||
getBossBars().get(player.getUniqueId()).destroy();
|
||||
}
|
||||
|
||||
BossBar bossBar = new BossBar(player, name, true);
|
||||
bossBar.setSegundos(tempo);
|
||||
|
||||
getBossBars().put(player.getUniqueId(), bossBar);
|
||||
}
|
||||
|
||||
public static void send(Player player, String name) {
|
||||
if (!initialized) {
|
||||
init();
|
||||
send(player, name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (getBossBars().containsKey(player.getUniqueId())) {
|
||||
getBossBars().get(player.getUniqueId()).destroy();
|
||||
}
|
||||
|
||||
BossBar bossBar = new BossBar(player, name, false);
|
||||
getBossBars().put(player.getUniqueId(), bossBar);
|
||||
}
|
||||
|
||||
public static HashMap<UUID, BossBar> getBossBars() {
|
||||
return bossBars;
|
||||
}
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.cooldown;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.actionbar.ActionBarAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.cooldown.types.Cooldown;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.BukkitUpdateEvent;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.BukkitUpdateEvent.UpdateType;
|
||||
import com.br.guilhermematthew.nowly.commons.common.utility.string.StringUtility;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class CooldownAPI {
|
||||
|
||||
private static final Map<UUID, List<Cooldown>> map = new ConcurrentHashMap<>();
|
||||
private static boolean registred = false;
|
||||
|
||||
private static void registerListener() {
|
||||
if (registred) return;
|
||||
|
||||
registred = true;
|
||||
|
||||
Bukkit.getServer().getPluginManager().registerEvents(new Listener() {
|
||||
|
||||
@EventHandler
|
||||
public void onUpdate(BukkitUpdateEvent event) {
|
||||
if (event.getType() != UpdateType.TICK) return;
|
||||
if (event.getCurrentTick() % 2 > 0) return;
|
||||
|
||||
for (UUID uuid : map.keySet()) {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
|
||||
if (player != null) {
|
||||
List<Cooldown> list = map.get(uuid);
|
||||
Iterator<Cooldown> it = list.iterator();
|
||||
|
||||
Cooldown found = null;
|
||||
while (it.hasNext()) {
|
||||
Cooldown cooldown = it.next();
|
||||
if (!cooldown.expired()) {
|
||||
found = cooldown;
|
||||
continue;
|
||||
}
|
||||
it.remove();
|
||||
player.playSound(player.getLocation(), Sound.LEVEL_UP, 1F, 1F);
|
||||
}
|
||||
|
||||
if (found != null && found.isBarAPI()) {
|
||||
display(player, found);
|
||||
} else if (list.isEmpty()) {
|
||||
ActionBarAPI.send(player, "");
|
||||
map.remove(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, BukkitMain.getInstance());
|
||||
}
|
||||
|
||||
private static void display(Player player, Cooldown cooldown) {
|
||||
StringBuilder bar = new StringBuilder();
|
||||
double percentage = cooldown.getPercentage();
|
||||
double remaining = cooldown.getRemaining();
|
||||
double count = 20 - Math.max(percentage > 0D ? 1 : 0, percentage / 5);
|
||||
|
||||
for (int a = 0; a < count; a++)
|
||||
bar.append("§a" + ":");
|
||||
|
||||
for (int a = 0; a < 20 - count; a++)
|
||||
bar.append("§c" + ":");
|
||||
|
||||
String name = cooldown.getName();
|
||||
|
||||
ActionBarAPI.send(player, name + " " + bar + "§f " + String.format(Locale.US, "%.1fs", remaining));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void removeAllCooldowns(Player player) {
|
||||
if (map.containsKey(player.getUniqueId())) {
|
||||
List<Cooldown> list = map.get(player.getUniqueId());
|
||||
Iterator<Cooldown> it = list.iterator();
|
||||
while (it.hasNext()) {
|
||||
Cooldown cooldown = it.next();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendMessage(Player player, String name) {
|
||||
if (map.containsKey(player.getUniqueId())) {
|
||||
List<Cooldown> list = map.get(player.getUniqueId());
|
||||
for (Cooldown cooldown : list)
|
||||
if (cooldown.getName().equals(name)) {
|
||||
player.sendMessage(BukkitMessages.COOLDOWN_MESSAGE.replace("%tempo%", StringUtility.toMillis(cooldown.getRemaining())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addCooldown(Player player, Cooldown cooldown) {
|
||||
if (!registred) {
|
||||
registerListener();
|
||||
}
|
||||
|
||||
List<Cooldown> list = map.computeIfAbsent(player.getUniqueId(), v -> new ArrayList<>());
|
||||
list.add(cooldown);
|
||||
}
|
||||
|
||||
public static boolean removeCooldown(Player player, String name) {
|
||||
if (map.containsKey(player.getUniqueId())) {
|
||||
List<Cooldown> list = map.get(player.getUniqueId());
|
||||
Iterator<Cooldown> it = list.iterator();
|
||||
while (it.hasNext()) {
|
||||
Cooldown cooldown = it.next();
|
||||
if (cooldown.getName().equals(name)) {
|
||||
it.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasCooldown(Player player, String name) {
|
||||
if (map.containsKey(player.getUniqueId())) {
|
||||
List<Cooldown> list = map.get(player.getUniqueId());
|
||||
for (Cooldown cooldown : list)
|
||||
if (cooldown.getName().equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.cooldown.types;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Cooldown {
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final Long duration;
|
||||
private final long startTime = System.currentTimeMillis();
|
||||
|
||||
@Getter
|
||||
private final boolean barAPI;
|
||||
|
||||
public Cooldown(final String name, final Long duration, final boolean barAPI) {
|
||||
this.name = name;
|
||||
this.duration = duration;
|
||||
|
||||
this.barAPI = barAPI;
|
||||
}
|
||||
|
||||
public double getPercentage() {
|
||||
return (getRemaining() * 100) / duration;
|
||||
}
|
||||
|
||||
public double getRemaining() {
|
||||
long endTime = startTime + TimeUnit.SECONDS.toMillis(duration);
|
||||
return (-(System.currentTimeMillis() - endTime)) / 1000D;
|
||||
}
|
||||
|
||||
public boolean expired() {
|
||||
return getRemaining() < 0D;
|
||||
}
|
||||
}
|
@ -0,0 +1,207 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.fake;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.account.BukkitPlayer;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import lombok.val;
|
||||
import net.minecraft.server.v1_8_R3.*;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo.EnumPlayerInfoAction;
|
||||
import net.minecraft.server.v1_8_R3.WorldSettings.EnumGamemode;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class FakeAPI {
|
||||
|
||||
public static void changePlayerName(Player player, String name) {
|
||||
changePlayerName(player, name, true);
|
||||
}
|
||||
|
||||
public static void changePlayerName(Player player, String name, boolean respawn) {
|
||||
Collection<? extends Player> players = player.getWorld().getPlayers();
|
||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||
GameProfile playerProfile = entityPlayer.getProfile();
|
||||
|
||||
if (respawn) {
|
||||
removeFromTab(player, players);
|
||||
}
|
||||
|
||||
try {
|
||||
Field field = playerProfile.getClass().getDeclaredField("name");
|
||||
field.setAccessible(true);
|
||||
field.set(playerProfile, name);
|
||||
field.setAccessible(false);
|
||||
entityPlayer.getClass().getDeclaredField("displayName").set(entityPlayer, name);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (respawn) respawnPlayer(player);
|
||||
}
|
||||
|
||||
public static void removePlayerSkin(Player player) {
|
||||
removePlayerSkin(player, true);
|
||||
}
|
||||
|
||||
public static void removePlayerSkin(Player player, boolean respawn) {
|
||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||
GameProfile playerProfile = entityPlayer.getProfile();
|
||||
playerProfile.getProperties().removeAll("textures");
|
||||
|
||||
if (respawn) {
|
||||
respawnPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
public static void changePlayerSkin(Player player, String skinValue, String skinSignature) {
|
||||
changePlayerSkin(player, skinValue, skinSignature, true);
|
||||
}
|
||||
|
||||
public static void changePlayerSkin(Player player, String skinValue, String skinSignature, boolean respawn) {
|
||||
BukkitPlayer bPlayer = BukkitMain.getBukkitPlayer(player.getUniqueId());
|
||||
bPlayer.setLastSkin(new Property("textures", skinValue, skinSignature));
|
||||
|
||||
if (respawn) respawnPlayer(player);
|
||||
}
|
||||
|
||||
public static void removeFromTab(Player player, Collection<? extends Player> players) {
|
||||
PacketPlayOutPlayerInfo removePlayerInfo =
|
||||
new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, ((CraftPlayer) player).getHandle());
|
||||
|
||||
for (Player online : players) {
|
||||
if (online.canSee(player)) {
|
||||
((CraftPlayer) online).getHandle().playerConnection.sendPacket(removePlayerInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void respawnPlayer(Player p) {
|
||||
try {
|
||||
if (!p.isOnline()) return;
|
||||
|
||||
CraftPlayer cp = (CraftPlayer) p;
|
||||
EntityPlayer ep = cp.getHandle();
|
||||
int entId = ep.getId();
|
||||
Location l = p.getLocation();
|
||||
|
||||
val textures = BukkitMain.getBukkitPlayer(p.getUniqueId()).getLastSkin();
|
||||
if (textures != null) {
|
||||
ep.getProfile().getProperties().removeAll(textures.getName());
|
||||
ep.getProfile().getProperties().put(textures.getName(), textures);
|
||||
}
|
||||
|
||||
val actualPing = ep.ping;
|
||||
|
||||
PacketPlayOutPlayerInfo removeInfo =
|
||||
new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, ep);
|
||||
|
||||
PacketPlayOutEntityDestroy removeEntity =
|
||||
new PacketPlayOutEntityDestroy(entId);
|
||||
|
||||
PacketPlayOutNamedEntitySpawn addNamed =
|
||||
new PacketPlayOutNamedEntitySpawn(ep);
|
||||
|
||||
PacketPlayOutPlayerInfo addInfo =
|
||||
new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, ep);
|
||||
|
||||
PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(((WorldServer) ep.getWorld()).dimension,
|
||||
ep.world.getDifficulty(), ep.getWorld().worldData.getType(), EnumGamemode.getById(p.getGameMode().getValue()));
|
||||
|
||||
PacketPlayOutPosition pos =
|
||||
new PacketPlayOutPosition(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch(), new HashSet<>());
|
||||
|
||||
PacketPlayOutEntityEquipment itemhand =
|
||||
new PacketPlayOutEntityEquipment(entId, 0, CraftItemStack.asNMSCopy(p.getItemInHand()));
|
||||
|
||||
PacketPlayOutEntityEquipment helmet =
|
||||
new PacketPlayOutEntityEquipment(entId, 4, CraftItemStack.asNMSCopy(p.getInventory().getHelmet()));
|
||||
|
||||
PacketPlayOutEntityEquipment chestplate =
|
||||
new PacketPlayOutEntityEquipment(entId, 3, CraftItemStack.asNMSCopy(p.getInventory().getChestplate()));
|
||||
|
||||
PacketPlayOutEntityEquipment leggings =
|
||||
new PacketPlayOutEntityEquipment(entId, 2, CraftItemStack.asNMSCopy(p.getInventory().getLeggings()));
|
||||
|
||||
PacketPlayOutEntityEquipment boots =
|
||||
new PacketPlayOutEntityEquipment(entId, 1, CraftItemStack.asNMSCopy(p.getInventory().getBoots()));
|
||||
|
||||
PacketPlayOutHeldItemSlot slot =
|
||||
new PacketPlayOutHeldItemSlot(p.getInventory().getHeldItemSlot());
|
||||
|
||||
List<Player> toUpdate = new ArrayList<>();
|
||||
|
||||
for (Player pOnline : Bukkit.getServer().getOnlinePlayers()) {
|
||||
CraftPlayer craftOnline = (CraftPlayer) pOnline;
|
||||
PlayerConnection con = craftOnline.getHandle().playerConnection;
|
||||
|
||||
if (pOnline.equals(p)) {
|
||||
con.sendPacket(removeInfo);
|
||||
con.sendPacket(addInfo);
|
||||
con.sendPacket(respawn);
|
||||
con.sendPacket(pos);
|
||||
con.sendPacket(slot);
|
||||
|
||||
craftOnline.updateScaledHealth();
|
||||
craftOnline.getHandle().triggerHealthUpdate();
|
||||
craftOnline.updateInventory();
|
||||
|
||||
if (pOnline.isOp()) {
|
||||
pOnline.setOp(false);
|
||||
pOnline.setOp(true);
|
||||
}
|
||||
} else if ((pOnline.canSee(p)) && (pOnline.getWorld().equals(p.getWorld()))) {
|
||||
con.sendPacket(removeEntity);
|
||||
con.sendPacket(removeInfo);
|
||||
con.sendPacket(addInfo);
|
||||
con.sendPacket(addNamed);
|
||||
con.sendPacket(itemhand);
|
||||
con.sendPacket(helmet);
|
||||
con.sendPacket(chestplate);
|
||||
con.sendPacket(leggings);
|
||||
con.sendPacket(boots);
|
||||
|
||||
pOnline.hidePlayer(p);
|
||||
toUpdate.add(pOnline);
|
||||
} else {
|
||||
con.sendPacket(removeInfo);
|
||||
con.sendPacket(addInfo);
|
||||
}
|
||||
}
|
||||
|
||||
BukkitMain.runLater(() -> {
|
||||
if (!p.isOnline()) {
|
||||
return;
|
||||
}
|
||||
|
||||
toUpdate.forEach(players -> players.showPlayer(p));
|
||||
}, 10);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void addToTab(Player player, Collection<? extends Player> players) {
|
||||
PacketPlayOutPlayerInfo addPlayerInfo =
|
||||
new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, ((CraftPlayer) player).getHandle());
|
||||
|
||||
PacketPlayOutPlayerInfo updatePlayerInfo =
|
||||
new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.UPDATE_DISPLAY_NAME, ((CraftPlayer) player).getHandle());
|
||||
|
||||
for (Player online : players) {
|
||||
if (online.canSee(player)) {
|
||||
((CraftPlayer) online).getHandle().playerConnection.sendPacket(addPlayerInfo);
|
||||
((CraftPlayer) online).getHandle().playerConnection.sendPacket(updatePlayerInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,632 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.ClassBuilder;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.NMSClass;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.Reflection;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.DataWatcher;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.FieldResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.util.AccessUtil;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.protocol.ProtocolGetter;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
abstract class CraftHologram implements Hologram {
|
||||
|
||||
static final FieldResolver PacketPlayOutSpawnEntityLivingFieldResolver = new FieldResolver(NMSClass.PacketPlayOutSpawnEntityLiving);
|
||||
|
||||
protected int[] hologramIDs;
|
||||
protected int[] touchIDs;
|
||||
|
||||
protected boolean packetsBuilt;
|
||||
|
||||
/***
|
||||
* Packets
|
||||
***/
|
||||
/* Hologram */
|
||||
protected Object spawnPacketArmorStand;
|
||||
protected Object spawnPacketWitherSkull;
|
||||
protected Object spawnPacketHorse_1_7;
|
||||
protected Object spawnPacketHorse_1_8;
|
||||
protected Object attachPacket;
|
||||
protected Object teleportPacketArmorStand;
|
||||
protected Object teleportPacketSkull;
|
||||
protected Object teleportPacketHorse_1_7;
|
||||
protected Object teleportPacketHorse_1_8;
|
||||
protected Object destroyPacket;
|
||||
protected Object ridingAttachPacket;
|
||||
protected Object ridingEjectPacket;
|
||||
/* Touch */
|
||||
protected Object spawnPacketTouchSlime;
|
||||
protected Object spawnPacketTouchVehicle;
|
||||
protected Object attachPacketTouch;
|
||||
protected Object destroyPacketTouch;
|
||||
protected Object teleportPacketTouchSlime;
|
||||
protected Object teleportPacketTouchVehicle;
|
||||
|
||||
/***
|
||||
* DataWatchers
|
||||
***/
|
||||
/* Hologram */
|
||||
protected Object dataWatcherArmorStand;
|
||||
protected Object dataWatcherWitherSkull;
|
||||
protected Object dataWatcherHorse_1_7;
|
||||
protected Object dataWatcherHorse_1_8;
|
||||
/* Touch */
|
||||
protected Object dataWatcherTouchSlime;
|
||||
protected Object dataWatcherTouchVehicle;
|
||||
|
||||
protected boolean matchesTouchID(int id) {
|
||||
if (!this.isTouchable() || this.touchIDs == null) {
|
||||
return false;
|
||||
}
|
||||
for (int i : this.touchIDs) {
|
||||
if (i == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean matchesHologramID(int id) {
|
||||
if (!HologramAPI.packetsEnabled() || this.hologramIDs == null) {
|
||||
return false;
|
||||
}
|
||||
for (int i : this.hologramIDs) {
|
||||
if (i == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void buildPackets(boolean rebuild) throws Exception {
|
||||
if (!rebuild && this.packetsBuilt) {
|
||||
throw new IllegalStateException("packets already built");
|
||||
}
|
||||
if (rebuild && !this.packetsBuilt) {
|
||||
throw new IllegalStateException("cannot rebuild packets before building once");
|
||||
}
|
||||
Object world = Reflection.getHandle(this.getLocation().getWorld());
|
||||
|
||||
/* Hologram packets */
|
||||
if (HologramAPI.is1_8 && !HologramAPI.useProtocolSupport) {
|
||||
Object armorStand = ClassBuilder.buildEntityArmorStand(world, this.getLocation().add(0, HologramOffsets.ARMOR_STAND_DEFAULT, 0), this.getText());
|
||||
|
||||
ClassBuilder.setupArmorStand(armorStand);
|
||||
|
||||
if (rebuild) {
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).set(armorStand, this.hologramIDs[0]);
|
||||
} else {
|
||||
this.hologramIDs = new int[]{AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).getInt(armorStand)};
|
||||
}
|
||||
|
||||
this.spawnPacketArmorStand = ClassBuilder.buildArmorStandSpawnPacket(armorStand);
|
||||
this.dataWatcherArmorStand = AccessUtil.setAccessible(PacketPlayOutSpawnEntityLivingFieldResolver.resolveByFirstType(NMSClass.DataWatcher)).get(this.spawnPacketArmorStand);
|
||||
|
||||
this.teleportPacketArmorStand = ClassBuilder.buildTeleportPacket(this.hologramIDs[0], this.getLocation().add(0, HologramOffsets.ARMOR_STAND_DEFAULT, 0), true, false);
|
||||
} else {
|
||||
|
||||
// Spawn Horse
|
||||
Object horse_1_7 = ClassBuilder.buildEntityHorse_1_7(world, this.getLocation().add(0, HologramOffsets.WITHER_SKULL_HORSE, 0), this.getText());
|
||||
Object horse_1_8 = ClassBuilder.buildEntityHorse_1_8(world, this.getLocation().add(0, HologramOffsets.ARMOR_STAND_PACKET, 0), this.getText());
|
||||
|
||||
// Spawn WitherSkull
|
||||
Object witherSkull_1_7 = ClassBuilder.buildEntityWitherSkull(world, this.getLocation().add(0, HologramOffsets.WITHER_SKULL_HORSE, 0));
|
||||
this.dataWatcherWitherSkull = AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("datawatcher")).get(witherSkull_1_7);
|
||||
|
||||
if (rebuild) {
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).set(witherSkull_1_7, this.hologramIDs[0]);
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).set(horse_1_7, this.hologramIDs[1]);
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).set(horse_1_8, this.hologramIDs[2]);
|
||||
// Reset the entity count
|
||||
Field entityCountField = AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("entityCount"));
|
||||
entityCountField.set(null, (int) entityCountField.get(null) - 3);
|
||||
} else {
|
||||
this.hologramIDs = new int[]{
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).getInt(witherSkull_1_7),
|
||||
//
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).getInt(horse_1_7),
|
||||
//
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).getInt(horse_1_8)
|
||||
};
|
||||
}
|
||||
|
||||
/* Packets */
|
||||
|
||||
// 1.7 Horse
|
||||
this.spawnPacketHorse_1_7 = ClassBuilder.buildHorseSpawnPacket_1_7(horse_1_7, this.getText());
|
||||
this.dataWatcherHorse_1_7 = AccessUtil.setAccessible(PacketPlayOutSpawnEntityLivingFieldResolver.resolveByFirstType(NMSClass.DataWatcher)).get(this.spawnPacketHorse_1_7);
|
||||
|
||||
// Special 1.8 client packet which replaces the entity with an ArmorStand
|
||||
this.spawnPacketHorse_1_8 = ClassBuilder.buildHorseSpawnPacket_1_8(horse_1_8, this.getText());
|
||||
this.dataWatcherHorse_1_8 = AccessUtil.setAccessible(PacketPlayOutSpawnEntityLivingFieldResolver.resolveByFirstType(NMSClass.DataWatcher)).get(this.spawnPacketHorse_1_8);
|
||||
|
||||
// WitherSkull
|
||||
this.spawnPacketWitherSkull = ClassBuilder.buildWitherSkullSpawnPacket(witherSkull_1_7);
|
||||
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
this.attachPacket = NMSClass.PacketPlayOutAttachEntity.getConstructor(int.class, NMSClass.Entity, NMSClass.Entity).newInstance(0, horse_1_7, witherSkull_1_7);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("b")).set(this.attachPacket, this.hologramIDs[1]);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("c")).set(this.attachPacket, this.hologramIDs[0]);
|
||||
} else {
|
||||
this.attachPacket = NMSClass.PacketPlayOutAttachEntity.newInstance();
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("a")).set(this.attachPacket, this.hologramIDs[1]);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("b")).set(this.attachPacket, this.hologramIDs[0]);
|
||||
}
|
||||
|
||||
if (!HologramAPI.is1_8 || HologramAPI.useProtocolSupport) {
|
||||
this.teleportPacketSkull = ClassBuilder.buildTeleportPacket(this.hologramIDs[0], this.getLocation().add(0, HologramOffsets.WITHER_SKULL_HORSE, 0), true, false);
|
||||
this.teleportPacketHorse_1_7 = ClassBuilder.buildTeleportPacket(this.hologramIDs[1], this.getLocation().add(0, HologramOffsets.WITHER_SKULL_HORSE, 0), true, false);
|
||||
}
|
||||
this.teleportPacketHorse_1_8 = ClassBuilder.buildTeleportPacket(this.hologramIDs[2], this.getLocation().add(0, HologramOffsets.ARMOR_STAND_PACKET, 0), true, false);
|
||||
}
|
||||
|
||||
/* Touch packets */
|
||||
if (this.isTouchable()) {
|
||||
int size = this.getText() == null ? 1 : (this.getText().length() / 2 / 3);
|
||||
Object touchSlime = ClassBuilder.buildEntitySlime(world, this.getLocation().add(0, HologramOffsets.TOUCH_SLIME_SKULL, 0), size);
|
||||
this.dataWatcherTouchSlime = AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("datawatcher")).get(touchSlime);
|
||||
|
||||
Object touchVehicle = null;
|
||||
|
||||
if (HologramAPI.is1_8 && !HologramAPI.useProtocolSupport) {
|
||||
touchVehicle = ClassBuilder.buildEntityArmorStand(world, this.getLocation().add(0, HologramOffsets.ARMOR_STAND_PACKET + HologramOffsets.TOUCH_SLIME_ARMOR_STAND, 0), null);
|
||||
this.dataWatcherTouchVehicle = AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("datawatcher")).get(touchVehicle);
|
||||
|
||||
ClassBuilder.setupArmorStand(touchVehicle);
|
||||
} else {
|
||||
touchVehicle = ClassBuilder.buildEntityWitherSkull(world, this.getLocation().add(0, HologramOffsets.TOUCH_SLIME_SKULL, 0));
|
||||
this.dataWatcherTouchVehicle = AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("datawatcher")).get(touchVehicle);
|
||||
// ClassBuilder.setDataWatcherValue(this.dataWatcherTouchVehicle, 0, (byte) 32);
|
||||
DataWatcher.setValue(this.dataWatcherTouchVehicle, 0, DataWatcher.V1_9.ValueType.ENTITY_FLAG, (byte) 32);
|
||||
}
|
||||
|
||||
if (rebuild) {
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).set(touchSlime, this.touchIDs[0]);
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).set(touchVehicle, this.touchIDs[1]);
|
||||
// Reset the entity count
|
||||
Field entityCountField = AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("entityCount"));
|
||||
entityCountField.set(null, (int) entityCountField.get(null) - 2);
|
||||
} else {
|
||||
this.touchIDs = new int[]{
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).getInt(touchSlime),
|
||||
//
|
||||
AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("id")).getInt(touchVehicle)
|
||||
};
|
||||
}
|
||||
|
||||
this.spawnPacketTouchSlime = ClassBuilder.buildSlimeSpawnPacket(touchSlime);
|
||||
if (HologramAPI.is1_8 && !HologramAPI.useProtocolSupport) {
|
||||
this.spawnPacketTouchVehicle = ClassBuilder.buildArmorStandSpawnPacket(touchVehicle);
|
||||
} else {
|
||||
this.spawnPacketTouchVehicle = ClassBuilder.buildWitherSkullSpawnPacket(touchVehicle);
|
||||
}
|
||||
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
this.attachPacketTouch = NMSClass.PacketPlayOutAttachEntity.getConstructor(int.class, NMSClass.Entity, NMSClass.Entity).newInstance(0, touchSlime, touchVehicle);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("b")).set(this.attachPacketTouch, this.touchIDs[0]);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("c")).set(this.attachPacketTouch, this.touchIDs[1]);
|
||||
} else {
|
||||
this.attachPacketTouch = NMSClass.PacketPlayOutAttachEntity.newInstance();
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("a")).set(this.attachPacketTouch, this.touchIDs[0]);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("b")).set(this.attachPacketTouch, this.touchIDs[1]);
|
||||
}
|
||||
|
||||
this.teleportPacketTouchSlime = ClassBuilder.buildTeleportPacket(this.touchIDs[0], this.getLocation().add(0, HologramOffsets.TOUCH_SLIME_SKULL, 0), true, false);
|
||||
if (HologramAPI.is1_8 && !HologramAPI.useProtocolSupport) {
|
||||
this.teleportPacketTouchVehicle = ClassBuilder.buildTeleportPacket(this.touchIDs[1], this.getLocation().add(0, HologramOffsets.ARMOR_STAND_PACKET + HologramOffsets.TOUCH_SLIME_ARMOR_STAND, 0), true, false);
|
||||
} else {
|
||||
this.teleportPacketTouchVehicle = ClassBuilder.buildTeleportPacket(this.touchIDs[1], this.getLocation().add(0, HologramOffsets.TOUCH_SLIME_SKULL, 0), true, false);
|
||||
}
|
||||
|
||||
if (!rebuild) {
|
||||
this.destroyPacketTouch = NMSClass.PacketPlayOutEntityDestroy.getConstructor(int[].class).newInstance(this.touchIDs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
this.ridingAttachPacket = NMSClass.PacketPlayOutAttachEntity.newInstance();
|
||||
this.ridingEjectPacket = NMSClass.PacketPlayOutAttachEntity.newInstance();
|
||||
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("a")).set(this.ridingAttachPacket, 0);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("a")).set(this.ridingEjectPacket, 0);
|
||||
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("b")).set(this.ridingAttachPacket, this.hologramIDs[0]);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("b")).set(this.ridingEjectPacket, this.hologramIDs[0]);
|
||||
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("c")).set(this.ridingAttachPacket, this.getAttachedTo() != null ? this.getAttachedTo().getEntityId() : -1);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutAttachEntity.getDeclaredField("c")).set(this.ridingEjectPacket, -1);
|
||||
} else {
|
||||
this.ridingAttachPacket = NMSClass.PacketPlayOutMount.newInstance();
|
||||
this.ridingEjectPacket = NMSClass.PacketPlayOutMount.newInstance();
|
||||
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutMount.getDeclaredField("a")).set(this.ridingAttachPacket, ((DefaultHologram) this).isAttached() && this.getAttachedTo() != null ? this.getAttachedTo().getEntityId() : -1);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutMount.getDeclaredField("a")).set(this.ridingEjectPacket, ((DefaultHologram) this).isAttached() && this.getAttachedTo() != null ? this.getAttachedTo().getEntityId() : -1);
|
||||
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutMount.getDeclaredField("b")).set(this.ridingAttachPacket, new int[]{this.hologramIDs[0]});
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutMount.getDeclaredField("b")).set(this.ridingEjectPacket, new int[0]);
|
||||
}
|
||||
|
||||
if (!rebuild) {
|
||||
this.destroyPacket = NMSClass.PacketPlayOutEntityDestroy.getConstructor(int[].class).newInstance(this.hologramIDs);
|
||||
}
|
||||
}
|
||||
|
||||
protected void sendSpawnPackets(final Collection<? extends Player> receivers, final boolean holo, final boolean touch) {
|
||||
if (holo) {
|
||||
if (HologramAPI.is1_8 && !HologramAPI.useProtocolSupport) {
|
||||
for (Player p : receivers) {
|
||||
if (!isShown(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
HologramAPI.sendPacket(p, this.spawnPacketArmorStand);
|
||||
}
|
||||
} else {
|
||||
for (Player p : receivers) {
|
||||
if (!isShown(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ProtocolGetter.getVersion(p) > 5) {
|
||||
HologramAPI.sendPacket(p, this.spawnPacketHorse_1_8);
|
||||
} else {
|
||||
HologramAPI.sendPacket(p, this.spawnPacketHorse_1_7);
|
||||
HologramAPI.sendPacket(p, this.spawnPacketWitherSkull);
|
||||
HologramAPI.sendPacket(p, this.attachPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (touch && this.isTouchable()) {
|
||||
for (Player p : receivers) {
|
||||
if (!isShown(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
HologramAPI.sendPacket(p, this.spawnPacketTouchSlime);
|
||||
HologramAPI.sendPacket(p, this.spawnPacketTouchVehicle);
|
||||
HologramAPI.sendPacket(p, this.attachPacketTouch);
|
||||
}
|
||||
}
|
||||
if (holo || touch) {
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
CraftHologram.this.sendTeleportPackets(receivers, holo, touch);
|
||||
}
|
||||
}.runTaskLater(BukkitMain.getInstance(), 1L);
|
||||
}
|
||||
}
|
||||
|
||||
protected void sendTeleportPackets(final Collection<? extends Player> receivers, boolean holo, boolean touch) {
|
||||
if (!holo && !touch) {
|
||||
return;
|
||||
}
|
||||
for (Player p : receivers) {
|
||||
if (!isShown(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (holo) {
|
||||
if (!HologramAPI.is1_8 || HologramAPI.useProtocolSupport) {
|
||||
if (ProtocolGetter.getVersion(p) > 5) {
|
||||
HologramAPI.sendPacket(p, this.teleportPacketHorse_1_8);
|
||||
} else {
|
||||
HologramAPI.sendPacket(p, this.teleportPacketHorse_1_7);
|
||||
HologramAPI.sendPacket(p, this.teleportPacketSkull);
|
||||
}
|
||||
} else {
|
||||
HologramAPI.sendPacket(p, this.teleportPacketArmorStand);
|
||||
}
|
||||
}
|
||||
if (touch && this.isTouchable()) {
|
||||
HologramAPI.sendPacket(p, this.teleportPacketTouchSlime);
|
||||
HologramAPI.sendPacket(p, this.teleportPacketTouchVehicle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void sendNamePackets(Player p) {
|
||||
if (!isShown(p)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int id = HologramAPI.is1_8 && !HologramAPI.useProtocolSupport ? this.hologramIDs[0] : ProtocolGetter.getVersion(p) > 5 ? this.hologramIDs[2] : this.hologramIDs[1];
|
||||
Object dataWatcher = HologramAPI.is1_8 && !HologramAPI.useProtocolSupport ? this.dataWatcherArmorStand : ProtocolGetter.getVersion(p) > 5 ? this.dataWatcherHorse_1_8 : this.dataWatcherHorse_1_7;
|
||||
Object packet = ClassBuilder.buildNameMetadataPacket(id, dataWatcher, 2, 3, this.getText());
|
||||
HologramAPI.sendPacket(p, packet);
|
||||
if (ProtocolGetter.getVersion(p) <= 5) {
|
||||
if (this.hologramIDs.length > 1) {
|
||||
HologramAPI.sendPacket(p, ClassBuilder.buildNameMetadataPacket(this.hologramIDs[1], this.dataWatcherHorse_1_7, 10, 11, this.getText()));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void sendNamePackets(final Collection<? extends Player> receivers) {
|
||||
for (Player p : receivers) {
|
||||
if (!isShown(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
int id = HologramAPI.is1_8 && !HologramAPI.useProtocolSupport ? this.hologramIDs[0] : ProtocolGetter.getVersion(p) > 5 ? this.hologramIDs[2] : this.hologramIDs[1];
|
||||
Object dataWatcher = HologramAPI.is1_8 && !HologramAPI.useProtocolSupport ? this.dataWatcherArmorStand : ProtocolGetter.getVersion(p) > 5 ? this.dataWatcherHorse_1_8 : this.dataWatcherHorse_1_7;
|
||||
Object packet = ClassBuilder.buildNameMetadataPacket(id, dataWatcher, 2, 3, this.getText());
|
||||
HologramAPI.sendPacket(p, packet);
|
||||
if (ProtocolGetter.getVersion(p) <= 5) {
|
||||
if (this.hologramIDs.length > 1) {
|
||||
HologramAPI.sendPacket(p, ClassBuilder.buildNameMetadataPacket(this.hologramIDs[1], this.dataWatcherHorse_1_7, 10, 11, this.getText()));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void sendDestroyPackets(Collection<? extends Player> receivers) {
|
||||
for (Player p : receivers) {
|
||||
HologramAPI.sendPacket(p, this.destroyPacket);
|
||||
if (this.isTouchable()) {
|
||||
HologramAPI.sendPacket(p, this.destroyPacketTouch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void sendAttachPacket(Collection<? extends Player> receivers) {
|
||||
for (Player p : receivers) {
|
||||
if (!isShown(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!((DefaultHologram) this).isAttached()) {
|
||||
HologramAPI.sendPacket(p, this.ridingEjectPacket);
|
||||
} else {
|
||||
HologramAPI.sendPacket(p, this.ridingAttachPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Location getLocation();
|
||||
|
||||
@Override
|
||||
public abstract void setLocation(Location loc);
|
||||
|
||||
@Override
|
||||
public abstract String getText();
|
||||
|
||||
@Override
|
||||
public abstract void setText(String text);
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (this.attachPacket == null ? 0 : this.attachPacket.hashCode());
|
||||
result = prime * result + (this.attachPacketTouch == null ? 0 : this.attachPacketTouch.hashCode());
|
||||
result = prime * result + (this.dataWatcherArmorStand == null ? 0 : this.dataWatcherArmorStand.hashCode());
|
||||
result = prime * result + (this.dataWatcherHorse_1_7 == null ? 0 : this.dataWatcherHorse_1_7.hashCode());
|
||||
result = prime * result + (this.dataWatcherHorse_1_8 == null ? 0 : this.dataWatcherHorse_1_8.hashCode());
|
||||
result = prime * result + (this.dataWatcherTouchSlime == null ? 0 : this.dataWatcherTouchSlime.hashCode());
|
||||
result = prime * result + (this.dataWatcherTouchVehicle == null ? 0 : this.dataWatcherTouchVehicle.hashCode());
|
||||
result = prime * result + (this.dataWatcherWitherSkull == null ? 0 : this.dataWatcherWitherSkull.hashCode());
|
||||
result = prime * result + (this.destroyPacket == null ? 0 : this.destroyPacket.hashCode());
|
||||
result = prime * result + (this.destroyPacketTouch == null ? 0 : this.destroyPacketTouch.hashCode());
|
||||
result = prime * result + Arrays.hashCode(this.hologramIDs);
|
||||
result = prime * result + (this.packetsBuilt ? 1231 : 1237);
|
||||
result = prime * result + (this.spawnPacketArmorStand == null ? 0 : this.spawnPacketArmorStand.hashCode());
|
||||
result = prime * result + (this.spawnPacketHorse_1_7 == null ? 0 : this.spawnPacketHorse_1_7.hashCode());
|
||||
result = prime * result + (this.spawnPacketHorse_1_8 == null ? 0 : this.spawnPacketHorse_1_8.hashCode());
|
||||
result = prime * result + (this.spawnPacketTouchSlime == null ? 0 : this.spawnPacketTouchSlime.hashCode());
|
||||
result = prime * result + (this.spawnPacketTouchVehicle == null ? 0 : this.spawnPacketTouchVehicle.hashCode());
|
||||
result = prime * result + (this.spawnPacketWitherSkull == null ? 0 : this.spawnPacketWitherSkull.hashCode());
|
||||
result = prime * result + (this.teleportPacketArmorStand == null ? 0 : this.teleportPacketArmorStand.hashCode());
|
||||
result = prime * result + (this.teleportPacketHorse_1_7 == null ? 0 : this.teleportPacketHorse_1_7.hashCode());
|
||||
result = prime * result + (this.teleportPacketHorse_1_8 == null ? 0 : this.teleportPacketHorse_1_8.hashCode());
|
||||
result = prime * result + (this.teleportPacketSkull == null ? 0 : this.teleportPacketSkull.hashCode());
|
||||
result = prime * result + (this.teleportPacketTouchSlime == null ? 0 : this.teleportPacketTouchSlime.hashCode());
|
||||
result = prime * result + (this.teleportPacketTouchVehicle == null ? 0 : this.teleportPacketTouchVehicle.hashCode());
|
||||
result = prime * result + Arrays.hashCode(this.touchIDs);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
CraftHologram other = (CraftHologram) obj;
|
||||
if (this.attachPacket == null) {
|
||||
if (other.attachPacket != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.attachPacket.equals(other.attachPacket)) {
|
||||
return false;
|
||||
}
|
||||
if (this.attachPacketTouch == null) {
|
||||
if (other.attachPacketTouch != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.attachPacketTouch.equals(other.attachPacketTouch)) {
|
||||
return false;
|
||||
}
|
||||
if (this.dataWatcherArmorStand == null) {
|
||||
if (other.dataWatcherArmorStand != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.dataWatcherArmorStand.equals(other.dataWatcherArmorStand)) {
|
||||
return false;
|
||||
}
|
||||
if (this.dataWatcherHorse_1_7 == null) {
|
||||
if (other.dataWatcherHorse_1_7 != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.dataWatcherHorse_1_7.equals(other.dataWatcherHorse_1_7)) {
|
||||
return false;
|
||||
}
|
||||
if (this.dataWatcherHorse_1_8 == null) {
|
||||
if (other.dataWatcherHorse_1_8 != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.dataWatcherHorse_1_8.equals(other.dataWatcherHorse_1_8)) {
|
||||
return false;
|
||||
}
|
||||
if (this.dataWatcherTouchSlime == null) {
|
||||
if (other.dataWatcherTouchSlime != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.dataWatcherTouchSlime.equals(other.dataWatcherTouchSlime)) {
|
||||
return false;
|
||||
}
|
||||
if (this.dataWatcherTouchVehicle == null) {
|
||||
if (other.dataWatcherTouchVehicle != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.dataWatcherTouchVehicle.equals(other.dataWatcherTouchVehicle)) {
|
||||
return false;
|
||||
}
|
||||
if (this.dataWatcherWitherSkull == null) {
|
||||
if (other.dataWatcherWitherSkull != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.dataWatcherWitherSkull.equals(other.dataWatcherWitherSkull)) {
|
||||
return false;
|
||||
}
|
||||
if (this.destroyPacket == null) {
|
||||
if (other.destroyPacket != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.destroyPacket.equals(other.destroyPacket)) {
|
||||
return false;
|
||||
}
|
||||
if (this.destroyPacketTouch == null) {
|
||||
if (other.destroyPacketTouch != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.destroyPacketTouch.equals(other.destroyPacketTouch)) {
|
||||
return false;
|
||||
}
|
||||
if (!Arrays.equals(this.hologramIDs, other.hologramIDs)) {
|
||||
return false;
|
||||
}
|
||||
if (this.packetsBuilt != other.packetsBuilt) {
|
||||
return false;
|
||||
}
|
||||
if (this.spawnPacketArmorStand == null) {
|
||||
if (other.spawnPacketArmorStand != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.spawnPacketArmorStand.equals(other.spawnPacketArmorStand)) {
|
||||
return false;
|
||||
}
|
||||
if (this.spawnPacketHorse_1_7 == null) {
|
||||
if (other.spawnPacketHorse_1_7 != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.spawnPacketHorse_1_7.equals(other.spawnPacketHorse_1_7)) {
|
||||
return false;
|
||||
}
|
||||
if (this.spawnPacketHorse_1_8 == null) {
|
||||
if (other.spawnPacketHorse_1_8 != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.spawnPacketHorse_1_8.equals(other.spawnPacketHorse_1_8)) {
|
||||
return false;
|
||||
}
|
||||
if (this.spawnPacketTouchSlime == null) {
|
||||
if (other.spawnPacketTouchSlime != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.spawnPacketTouchSlime.equals(other.spawnPacketTouchSlime)) {
|
||||
return false;
|
||||
}
|
||||
if (this.spawnPacketTouchVehicle == null) {
|
||||
if (other.spawnPacketTouchVehicle != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.spawnPacketTouchVehicle.equals(other.spawnPacketTouchVehicle)) {
|
||||
return false;
|
||||
}
|
||||
if (this.spawnPacketWitherSkull == null) {
|
||||
if (other.spawnPacketWitherSkull != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.spawnPacketWitherSkull.equals(other.spawnPacketWitherSkull)) {
|
||||
return false;
|
||||
}
|
||||
if (this.teleportPacketArmorStand == null) {
|
||||
if (other.teleportPacketArmorStand != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.teleportPacketArmorStand.equals(other.teleportPacketArmorStand)) {
|
||||
return false;
|
||||
}
|
||||
if (this.teleportPacketHorse_1_7 == null) {
|
||||
if (other.teleportPacketHorse_1_7 != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.teleportPacketHorse_1_7.equals(other.teleportPacketHorse_1_7)) {
|
||||
return false;
|
||||
}
|
||||
if (this.teleportPacketHorse_1_8 == null) {
|
||||
if (other.teleportPacketHorse_1_8 != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.teleportPacketHorse_1_8.equals(other.teleportPacketHorse_1_8)) {
|
||||
return false;
|
||||
}
|
||||
if (this.teleportPacketSkull == null) {
|
||||
if (other.teleportPacketSkull != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.teleportPacketSkull.equals(other.teleportPacketSkull)) {
|
||||
return false;
|
||||
}
|
||||
if (this.teleportPacketTouchSlime == null) {
|
||||
if (other.teleportPacketTouchSlime != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.teleportPacketTouchSlime.equals(other.teleportPacketTouchSlime)) {
|
||||
return false;
|
||||
}
|
||||
if (this.teleportPacketTouchVehicle == null) {
|
||||
if (other.teleportPacketTouchVehicle != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.teleportPacketTouchVehicle.equals(other.teleportPacketTouchVehicle)) {
|
||||
return false;
|
||||
}
|
||||
return Arrays.equals(this.touchIDs, other.touchIDs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{\"hologramIDs\":\"" + Arrays.toString(this.hologramIDs) + "\",\"touchIDs\":\"" + Arrays
|
||||
.toString(this.touchIDs) + "\",\"packetsBuilt\":\"" + this.packetsBuilt + "\",\"spawnPacketArmorStand\":\"" + this.spawnPacketArmorStand + "\",\"spawnPacketWitherSkull\":\"" + this.spawnPacketWitherSkull + "\",\"spawnPacketHorse_1_7\":\"" + this.spawnPacketHorse_1_7 + "\",\"spawnPacketHorse_1_8\":\"" + this.spawnPacketHorse_1_8 + "\",\"attachPacket\":\"" + this.attachPacket
|
||||
+ "\",\"teleportPacketArmorStand\":\"" + this.teleportPacketArmorStand + "\",\"teleportPacketSkull\":\"" + this.teleportPacketSkull + "\",\"teleportPacketHorse_1_7\":\"" + this.teleportPacketHorse_1_7 + "\",\"teleportPacketHorse_1_8\":\"" + this.teleportPacketHorse_1_8 + "\",\"destroyPacket\":\"" + this.destroyPacket + "\",\"spawnPacketTouchSlime\":\"" + this.spawnPacketTouchSlime
|
||||
+ "\",\"spawnPacketTouchWitherSkull\":\"" + this.spawnPacketTouchVehicle + "\",\"attachPacketTouch\":\"" + this.attachPacketTouch + "\",\"destroyPacketTouch\":\"" + this.destroyPacketTouch + "\",\"teleportPacketTouchSlime\":\"" + this.teleportPacketTouchSlime + "\",\"teleportPacketTouchWitherSkull\":\"" + this.teleportPacketTouchVehicle + "\",\"dataWatcherArmorStand\":\""
|
||||
+ this.dataWatcherArmorStand + "\",\"dataWatcherWitherSkull\":\"" + this.dataWatcherWitherSkull + "\",\"dataWatcherHorse_1_7\":\"" + this.dataWatcherHorse_1_7 + "\",\"dataWatcherHorse_1_8\":\"" + this.dataWatcherHorse_1_8 + "\",\"dataWatcherTouchSlime\":\"" + this.dataWatcherTouchSlime + "\",\"dataWatcherTouchWitherSkull\":\"" + this.dataWatcherTouchVehicle + "\"}";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,489 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.touch.TouchHandler;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.view.ViewHandler;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.*;
|
||||
|
||||
public class DefaultHologram extends CraftHologram {
|
||||
|
||||
private final List<TouchHandler> touchHandlers = new ArrayList<>();
|
||||
private final List<ViewHandler> viewHandlers = new ArrayList<>();
|
||||
private Location location;
|
||||
private String text, name;
|
||||
private boolean touchable;
|
||||
private boolean spawned;
|
||||
private boolean isAttached;
|
||||
private Entity attachedTo;
|
||||
private Hologram lineBelow;
|
||||
private Hologram lineAbove;
|
||||
|
||||
private BukkitRunnable updater;
|
||||
|
||||
private final HashMap<UUID, Boolean> showns = new HashMap<>();
|
||||
|
||||
protected DefaultHologram(String name, @Nonnull Location loc, String text) {
|
||||
this.location = loc;
|
||||
this.text = text;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpawned() {
|
||||
return this.spawned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn(long ticks) {
|
||||
if (ticks < 1) {
|
||||
throw new IllegalArgumentException("ticks must be at least 1");
|
||||
}
|
||||
this.spawn();
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
DefaultHologram.this.despawn();
|
||||
}
|
||||
}.runTaskLater(BukkitMain.getInstance(), ticks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean spawn() {
|
||||
this.validateDespawned();
|
||||
if (!this.packetsBuilt) {
|
||||
try {
|
||||
this.buildPackets(false);
|
||||
this.packetsBuilt = true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
this.spawned = HologramAPI.spawn(this, this.getLocation().getWorld().getPlayers());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return this.spawned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean despawn() {
|
||||
this.validateSpawned();
|
||||
try {
|
||||
this.spawned = !HologramAPI.despawn(this, this.getLocation().getWorld().getPlayers());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return !this.spawned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return this.location.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(Location loc) {
|
||||
this.move(loc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
|
||||
if (this.isSpawned()) {
|
||||
try {
|
||||
this.buildPackets(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.sendNamePackets(this.getLocation().getWorld().getPlayers());
|
||||
}
|
||||
}
|
||||
|
||||
public void update(Player player) {
|
||||
if (this.isSpawned()) {
|
||||
try {
|
||||
this.buildPackets(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.sendNamePackets(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.setText(this.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long interval) {
|
||||
if (interval == -1) {
|
||||
if (this.updater == null) {
|
||||
throw new IllegalStateException("Not updating");
|
||||
}
|
||||
this.updater.cancel();
|
||||
this.updater = null;
|
||||
return;
|
||||
}
|
||||
if (this.updater != null) {
|
||||
throw new IllegalStateException("Already updating");
|
||||
}
|
||||
if (interval < 1) {
|
||||
throw new IllegalArgumentException("Interval must be at least 1");
|
||||
}
|
||||
this.updater = new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
DefaultHologram.this.update();
|
||||
}
|
||||
};
|
||||
this.updater.runTaskTimer(BukkitMain.getInstance(), interval, interval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(@Nonnull Location loc) {
|
||||
if (loc == null) {
|
||||
throw new IllegalArgumentException("location cannot be null");
|
||||
}
|
||||
if (this.location.equals(loc)) {
|
||||
return;
|
||||
}
|
||||
if (!this.location.getWorld().equals(loc.getWorld())) {
|
||||
throw new IllegalArgumentException("cannot move to different world");
|
||||
}
|
||||
this.location = loc;
|
||||
if (this.isSpawned()) {
|
||||
try {
|
||||
this.buildPackets(true);// Re-build the packets since the location is now different
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.sendTeleportPackets(this.getLocation().getWorld().getPlayers(), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTouchable() {
|
||||
return this.touchable && HologramAPI.packetsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTouchable(boolean flag) {
|
||||
this.validateTouchEnabled();
|
||||
if (flag == this.isTouchable()) {
|
||||
return;
|
||||
}
|
||||
this.touchable = flag;
|
||||
if (this.isSpawned()) {
|
||||
try {
|
||||
this.buildPackets(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.sendSpawnPackets(this.getLocation().getWorld().getPlayers(), false, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTouchHandler(TouchHandler handler) {
|
||||
this.validateTouchEnabled();
|
||||
if (!this.isTouchable()) {
|
||||
throw new IllegalStateException("Hologram is not touchable");
|
||||
}
|
||||
this.touchHandlers.add(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTouchHandler(TouchHandler handler) {
|
||||
this.validateTouchEnabled();
|
||||
if (!this.isTouchable()) {
|
||||
throw new IllegalStateException("Hologram is not touchable");
|
||||
}
|
||||
this.touchHandlers.remove(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<TouchHandler> getTouchHandlers() {
|
||||
return new ArrayList<>(this.touchHandlers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTouchHandlers() {
|
||||
for (TouchHandler handler : this.getTouchHandlers()) {
|
||||
this.removeTouchHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addViewHandler(ViewHandler handler) {
|
||||
this.validateViewsEnabled();
|
||||
this.viewHandlers.add(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViewHandler(ViewHandler handler) {
|
||||
this.validateViewsEnabled();
|
||||
this.viewHandlers.remove(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ViewHandler> getViewHandlers() {
|
||||
return new ArrayList<>(this.viewHandlers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearViewHandlers() {
|
||||
for (ViewHandler handler : this.getViewHandlers()) {
|
||||
this.removeViewHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hologram addLineBelow(String name, String text) {
|
||||
this.validateSpawned();
|
||||
Hologram hologram = HologramAPI.createHologram(name, this.getLocation().subtract(0, 0.25, 0), text);
|
||||
this.lineBelow = hologram;
|
||||
((DefaultHologram) hologram).lineAbove = this;
|
||||
|
||||
hologram.spawn();
|
||||
return hologram;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hologram getLineBelow() {
|
||||
this.validateSpawned();
|
||||
return this.lineBelow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLineBelow() {
|
||||
if (this.getLineBelow() != null) {
|
||||
if (this.getLineBelow().isSpawned()) {
|
||||
this.getLineBelow().despawn();
|
||||
}
|
||||
this.lineBelow = null;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Hologram> getLinesBelow() {
|
||||
List<Hologram> list = new ArrayList<>();
|
||||
|
||||
Hologram current = this;
|
||||
while ((current = ((DefaultHologram) current).lineBelow) != null) {
|
||||
list.add(current);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hologram addLineAbove(String name, String text) {
|
||||
this.validateSpawned();
|
||||
Hologram hologram = HologramAPI.createHologram(name, this.getLocation().add(0, 0.25, 0), text);
|
||||
this.lineAbove = hologram;
|
||||
((DefaultHologram) hologram).lineBelow = this;
|
||||
|
||||
hologram.spawn();
|
||||
return hologram;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hologram getLineAbove() {
|
||||
this.validateSpawned();
|
||||
return this.lineAbove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLineAbove() {
|
||||
if (this.getLineAbove() != null) {
|
||||
if (this.getLineAbove().isSpawned()) {
|
||||
this.getLineAbove().despawn();
|
||||
}
|
||||
this.lineAbove = null;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Hologram> getLinesAbove() {
|
||||
List<Hologram> list = new ArrayList<>();
|
||||
|
||||
Hologram current = this;
|
||||
while ((current = ((DefaultHologram) current).lineAbove) != null) {
|
||||
list.add(current);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Hologram> getLines() {
|
||||
List<Hologram> list = new ArrayList<>(this.getLinesAbove());
|
||||
list.add(this);
|
||||
list.addAll(this.getLinesBelow());
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getAttachedTo() {
|
||||
return attachedTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttachedTo(Entity attachedTo) {
|
||||
if (attachedTo == this.attachedTo) {
|
||||
return;
|
||||
}
|
||||
setAttached(attachedTo != null);
|
||||
if (attachedTo != null) {
|
||||
this.attachedTo = attachedTo;
|
||||
}
|
||||
if (this.isSpawned()) {
|
||||
try {
|
||||
this.buildPackets(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.sendAttachPacket(this.getLocation().getWorld().getPlayers());
|
||||
}
|
||||
//Wait for the packet to send (in 1.9), since it requires the attached's entity-id
|
||||
this.attachedTo = attachedTo;
|
||||
}
|
||||
|
||||
public boolean isAttached() {
|
||||
return isAttached;
|
||||
}
|
||||
|
||||
public void setAttached(boolean isAttached) {
|
||||
this.isAttached = isAttached;
|
||||
}
|
||||
|
||||
private void validateTouchEnabled() {
|
||||
if (!HologramAPI.packetsEnabled()) {
|
||||
throw new IllegalStateException("Touch-holograms are not enabled");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateViewsEnabled() {
|
||||
if (!HologramAPI.packetsEnabled()) {
|
||||
throw new IllegalStateException("ViewHandlers are not enabled");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateSpawned() {
|
||||
if (!this.spawned) {
|
||||
throw new IllegalStateException("Not spawned");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateDespawned() {
|
||||
if (this.spawned) {
|
||||
throw new IllegalStateException("Already spawned");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + (this.location == null ? 0 : this.location.hashCode());
|
||||
result = prime * result + (this.spawned ? 1231 : 1237);
|
||||
result = prime * result + (this.text == null ? 0 : this.text.hashCode());
|
||||
result = prime * result + (this.touchHandlers == null ? 0 : this.touchHandlers.hashCode());
|
||||
result = prime * result + (this.touchable ? 1231 : 1237);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
DefaultHologram other = (DefaultHologram) obj;
|
||||
if (this.location == null) {
|
||||
if (other.location != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.location.equals(other.location)) {
|
||||
return false;
|
||||
}
|
||||
if (this.spawned != other.spawned) {
|
||||
return false;
|
||||
}
|
||||
if (this.text == null) {
|
||||
if (other.text != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.text.equals(other.text)) {
|
||||
return false;
|
||||
}
|
||||
if (this.touchHandlers == null) {
|
||||
if (other.touchHandlers != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.touchHandlers.equals(other.touchHandlers)) {
|
||||
return false;
|
||||
}
|
||||
return this.touchable == other.touchable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{\"location\":\"" + this.location + "\",\"text\":\"" + this.text + "\",\"touchable\":\"" + this.touchable + "\",\"spawned\":\"" + this.spawned + "\",\"touchHandlers\":\"" + this.touchHandlers + "\"}";
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShown(Player player) {
|
||||
if (!showns.containsKey(player.getUniqueId())) {
|
||||
showns.put(player.getUniqueId(), false);
|
||||
return false;
|
||||
}
|
||||
return showns.get(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShown(Player player, boolean valor) {
|
||||
showns.put(player.getUniqueId(), valor);
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
showns.clear();
|
||||
}
|
||||
|
||||
public void clean(Player player) {
|
||||
showns.remove(player.getUniqueId());
|
||||
}
|
||||
}
|
@ -0,0 +1,232 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.touch.TouchHandler;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.view.ViewHandler;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.Nonnegative;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface Hologram {
|
||||
|
||||
String getName();
|
||||
|
||||
void setName(@Nullable String text);
|
||||
|
||||
boolean isSpawned();
|
||||
|
||||
boolean isShown(Player player);
|
||||
|
||||
/**
|
||||
* Spawns the hologram and despawns it after the specified timeout
|
||||
*
|
||||
* @param ticks timeout
|
||||
*/
|
||||
void spawn(@Nonnull @Nonnegative long ticks);
|
||||
|
||||
/**
|
||||
* Spawns the hologram
|
||||
*
|
||||
* @return <code>true</code> if the hologram has been spawned
|
||||
*/
|
||||
boolean spawn();
|
||||
|
||||
/**
|
||||
* Despawns the hologram
|
||||
*
|
||||
* @return <code>true</code> if the hologram has been despawned
|
||||
*/
|
||||
boolean despawn();
|
||||
|
||||
/**
|
||||
* @return The text content of the hologram
|
||||
*/
|
||||
String getText();
|
||||
|
||||
/**
|
||||
* @param text New text content of the hologram
|
||||
*/
|
||||
void setText(@Nullable String text);
|
||||
|
||||
/**
|
||||
* Updates the content of the hologram for player
|
||||
*/
|
||||
void update(Player player);
|
||||
|
||||
/**
|
||||
* Updates the content of the hologram
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Automatically updates the content of the hologram <code>-1</code> as the interval argument will stop the update
|
||||
*
|
||||
* @param interval Update interval in ticks, <code>-1</code> to stop updating
|
||||
*/
|
||||
void update(long interval);
|
||||
|
||||
/**
|
||||
* @return The {@link Location} of the hologram
|
||||
*/
|
||||
Location getLocation();
|
||||
|
||||
/**
|
||||
* @param loc changes the {@link Location} of the hologram
|
||||
* @see Hologram#move(Location)
|
||||
*/
|
||||
void setLocation(@Nonnull Location loc);
|
||||
|
||||
/**
|
||||
* Moves the hologram
|
||||
*
|
||||
* @param loc new {@link Location} of the hologram
|
||||
*/
|
||||
void move(@Nonnull Location loc);
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the hologram is touchable
|
||||
*/
|
||||
boolean isTouchable();
|
||||
|
||||
/**
|
||||
* Changes the touchability
|
||||
*
|
||||
* @param flag <code>true</code> if the hologram should be touchable,
|
||||
*/
|
||||
void setTouchable(boolean flag);
|
||||
|
||||
/**
|
||||
* Adds a touch handler to the hologram
|
||||
*
|
||||
* @param handler {@link TouchHandler} instance
|
||||
*/
|
||||
void addTouchHandler(@Nonnull TouchHandler handler);
|
||||
|
||||
/**
|
||||
* Removes a touch handler from the hologram
|
||||
*
|
||||
* @param handler {@link TouchHandler} instance
|
||||
*/
|
||||
void removeTouchHandler(@Nonnull TouchHandler handler);
|
||||
|
||||
/**
|
||||
* @return a {@link Collection} of registered {@link TouchHandler}s
|
||||
*/
|
||||
Collection<TouchHandler> getTouchHandlers();
|
||||
|
||||
/**
|
||||
* Removes all {@link TouchHandler}s from the hologram
|
||||
*/
|
||||
void clearTouchHandlers();
|
||||
|
||||
/**
|
||||
* Adds a view handler to the hologram
|
||||
*
|
||||
* @param handler {@link ViewHandler} instance
|
||||
*/
|
||||
void addViewHandler(@Nonnull ViewHandler handler);
|
||||
|
||||
/**
|
||||
* Removes a view handler from the hologram
|
||||
*
|
||||
* @param handler {@link ViewHandler} instance
|
||||
*/
|
||||
void removeViewHandler(@Nonnull ViewHandler handler);
|
||||
|
||||
/**
|
||||
* @return a {@link Collection} of registered {@link ViewHandler}s
|
||||
*/
|
||||
@Nonnull
|
||||
Collection<ViewHandler> getViewHandlers();
|
||||
|
||||
/**
|
||||
* Removes all {@link ViewHandler}s from the hologram
|
||||
*/
|
||||
void clearViewHandlers();
|
||||
|
||||
/**
|
||||
* Adds a {@link Hologram} line below this hologram
|
||||
*
|
||||
* @param text Text content of the hologram
|
||||
* @return A new {@link Hologram} instance
|
||||
*/
|
||||
@Nonnull
|
||||
Hologram addLineBelow(String name, String text);
|
||||
|
||||
/**
|
||||
* @return The {@link Hologram} line below this hologram
|
||||
*/
|
||||
@Nullable
|
||||
Hologram getLineBelow();
|
||||
|
||||
/**
|
||||
* Removes the line below this hologram
|
||||
*
|
||||
* @return <code>true</code> if the hologram has been removed
|
||||
*/
|
||||
boolean removeLineBelow();
|
||||
|
||||
/**
|
||||
* @return a {@link Collection} of all below {@link Hologram} lines
|
||||
*/
|
||||
@Nonnull
|
||||
Collection<Hologram> getLinesBelow();
|
||||
|
||||
/**
|
||||
* Adds a {@link Hologram} line above this hologram
|
||||
*
|
||||
* @param text Text content of the hologram
|
||||
* @return A new {@link Hologram} instance
|
||||
*/
|
||||
@Nonnull
|
||||
Hologram addLineAbove(String name, String text);
|
||||
|
||||
/**
|
||||
* @return The {@link Hologram} line above this hologram
|
||||
*/
|
||||
@Nullable
|
||||
Hologram getLineAbove();
|
||||
|
||||
/**
|
||||
* Removes the line above this hologram
|
||||
*
|
||||
* @return <code>true</code> if the hologram has been removed
|
||||
*/
|
||||
boolean removeLineAbove();
|
||||
|
||||
/**
|
||||
* @return a {@link Collection} of all above {@link Hologram} lines
|
||||
*/
|
||||
@Nonnull
|
||||
Collection<Hologram> getLinesAbove();
|
||||
|
||||
/**
|
||||
* @return a {@link Collection} of all below and above {@link Hologram} lines (Including this hologram)
|
||||
*/
|
||||
@Nonnull
|
||||
Collection<Hologram> getLines();
|
||||
|
||||
/**
|
||||
* @return The entity the hologram is attached to
|
||||
*/
|
||||
@Nullable
|
||||
Entity getAttachedTo();
|
||||
|
||||
/**
|
||||
* Attached the hologram to a entity
|
||||
*
|
||||
* @param entity Entity to attach the hologram to, or null to remove the attachment
|
||||
*/
|
||||
void setAttachedTo(@Nullable Entity entity);
|
||||
|
||||
void setShown(Player player, boolean valor);
|
||||
|
||||
void clean(Player player);
|
||||
|
||||
void clean();
|
||||
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.Reflection;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class HologramAPI {
|
||||
|
||||
protected static final List<Hologram> holograms = new ArrayList<>();
|
||||
public static boolean packetsEnabled = false;
|
||||
protected static final boolean is1_8/*Or 1.9*/ = Minecraft.VERSION.newerThan(Minecraft.Version.v1_8_R1);
|
||||
protected static final boolean useProtocolSupport = true;
|
||||
|
||||
//NEW
|
||||
|
||||
public static Hologram createHologramAndSpawn(final String name, final Location loc, String text) {
|
||||
Hologram hologram = new DefaultHologram(name, loc, text);
|
||||
hologram.spawn();
|
||||
holograms.add(hologram);
|
||||
return hologram;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link Hologram}
|
||||
*
|
||||
* @param loc {@link Location} to spawn the hologram at
|
||||
* @param text Initial text content of the hologram
|
||||
* @return a new {@link Hologram}
|
||||
*/
|
||||
|
||||
public static boolean spawnSingle(@Nonnull final Hologram hologram, final Player p) throws Exception {
|
||||
if (hologram == null) {
|
||||
throw new IllegalArgumentException("hologram cannot be null");
|
||||
}
|
||||
|
||||
if (!hologram.isShown(p)) {
|
||||
hologram.setShown(p, true);
|
||||
|
||||
spawn(hologram, new LinkedList<>(Collections.singletonList(p)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean despawnSingle(@Nonnull Hologram hologram, Player p) throws Exception {
|
||||
if (hologram == null) {
|
||||
throw new IllegalArgumentException("hologram cannot be null");
|
||||
}
|
||||
|
||||
if (hologram.isShown(p)) {
|
||||
hologram.setShown(p, false);
|
||||
|
||||
((CraftHologram) hologram).sendDestroyPackets(new LinkedList<>(Collections.singletonList(p)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Hologram createHologram(String name, Location loc, String text) {
|
||||
Hologram hologram = new DefaultHologram(name, loc, text);
|
||||
holograms.add(hologram);
|
||||
return hologram;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@link Hologram}
|
||||
*
|
||||
* @param loc {@link Location} of the hologram
|
||||
* @param text content of the hologram
|
||||
* @return <code>true</code> if a hologram was found and has been removed, <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean removeHologram(Location loc, String text) {
|
||||
Hologram toRemove = null;
|
||||
for (Hologram h : holograms) {
|
||||
if (h.getLocation().equals(loc) && h.getText().equals(text)) {
|
||||
toRemove = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
return removeHologram(toRemove);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@link Hologram}
|
||||
*
|
||||
* @param hologram {@link Hologram} to remove
|
||||
* @return <code>true</code> if the hologram has been removed
|
||||
*/
|
||||
public static boolean removeHologram(@Nonnull Hologram hologram) {
|
||||
if (hologram.isSpawned()) {
|
||||
hologram.despawn();
|
||||
hologram.clean();
|
||||
}
|
||||
return holograms.remove(hologram);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link Collection} of all registered {@link Hologram}s
|
||||
*/
|
||||
public static Collection<Hologram> getHolograms() {
|
||||
return new ArrayList<>(holograms);
|
||||
}
|
||||
|
||||
protected static boolean spawn(@Nonnull final Hologram hologram, final Collection<? extends Player> receivers) throws Exception {
|
||||
if (hologram == null) {
|
||||
throw new IllegalArgumentException("hologram cannot be null");
|
||||
}
|
||||
|
||||
checkReceiverWorld(hologram, receivers);
|
||||
|
||||
if (!receivers.isEmpty()) {
|
||||
((CraftHologram) hologram).sendSpawnPackets(receivers, true, true);
|
||||
((CraftHologram) hologram).sendTeleportPackets(receivers, true, true);
|
||||
((CraftHologram) hologram).sendNamePackets(receivers);
|
||||
((CraftHologram) hologram).sendAttachPacket(receivers);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static boolean despawn(@Nonnull Hologram hologram, Collection<? extends Player> receivers) throws Exception {
|
||||
if (hologram == null) {
|
||||
throw new IllegalArgumentException("hologram cannot be null");
|
||||
}
|
||||
if (receivers.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
((CraftHologram) hologram).sendDestroyPackets(receivers);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static void sendPacket(Player p, Object packet) {
|
||||
if (p == null || packet == null) {
|
||||
throw new IllegalArgumentException("player and packet cannot be null");
|
||||
}
|
||||
try {
|
||||
Object handle = Reflection.getHandle(p);
|
||||
Object connection = Reflection.getFieldWithException(handle.getClass(), "playerConnection").get(handle);
|
||||
Reflection.getMethod(connection.getClass(), "sendPacket", Reflection.getNMSClass("Packet")).invoke(connection, packet);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
protected static Collection<? extends Player> checkReceiverWorld(final Hologram hologram, final Collection<? extends Player> receivers) {
|
||||
for (Iterator<? extends Player> iterator = receivers.iterator(); iterator.hasNext(); ) {
|
||||
Player next = iterator.next();
|
||||
if (!next.getWorld().equals(hologram.getLocation().getWorld())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return receivers;
|
||||
}
|
||||
|
||||
public static boolean is1_8() {
|
||||
return is1_8;
|
||||
}
|
||||
|
||||
public static boolean packetsEnabled() {
|
||||
return packetsEnabled;
|
||||
}
|
||||
}
|
@ -0,0 +1,246 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.NMSClass;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.DataWatcher;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.FieldResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.util.AccessUtil;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.touch.TouchAction;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.touch.TouchHandler;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.view.ViewHandler;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.injector.PacketObject;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.injector.listener.PacketListener;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.injector.listener.PacketListenerAPI;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HologramInjector {
|
||||
|
||||
private static final FieldResolver DataWatcherFieldResolver = new FieldResolver(NMSClass.DataWatcher);
|
||||
|
||||
private static final String DELAY_TAG = "delay.hologram";
|
||||
|
||||
public static void inject(Plugin plugin) {
|
||||
PacketListenerAPI.addListener(new PacketListener() {
|
||||
|
||||
public void onPacketReceiving(PacketObject packetObject) {
|
||||
Object packet = packetObject.getPacket();
|
||||
|
||||
if (packet instanceof PacketPlayInUseEntity) {
|
||||
int id = (int) getPacketValue("a", packet);
|
||||
Object useAction = getPacketValue("action", packet);
|
||||
TouchAction action = TouchAction.fromUseAction(useAction);
|
||||
if (action == TouchAction.UNKNOWN) {
|
||||
return;// UNKNOWN means an invalid packet, so just ignore it
|
||||
}
|
||||
|
||||
if (hasDelay(packetObject.getPlayer())) {
|
||||
packetObject.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
addDelay(packetObject.getPlayer());
|
||||
|
||||
for (Hologram h : HologramAPI.getHolograms()) {
|
||||
if (((DefaultHologram) h).matchesTouchID(id)) {
|
||||
for (TouchHandler t : h.getTouchHandlers()) {
|
||||
t.onTouch(h, packetObject.getPlayer(), action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onPacketSending(PacketObject packetObject) {
|
||||
Object packet = packetObject.getPacket();
|
||||
|
||||
int type = -1;
|
||||
|
||||
if (packet instanceof PacketPlayOutSpawnEntityLiving) {
|
||||
type = 0;
|
||||
|
||||
}
|
||||
if (packet instanceof PacketPlayOutEntityMetadata) {
|
||||
type = 1;
|
||||
}
|
||||
|
||||
if (type == 0 || type == 1) {
|
||||
int a = (int) getPacketValue("a", packet);
|
||||
Object dataWatcher =
|
||||
type == 0 ?
|
||||
(Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1) ?
|
||||
getPacketValue("l", packet) : getPacketValue("m", packet)) : null;
|
||||
|
||||
if (dataWatcher != null) {
|
||||
try {
|
||||
dataWatcher = cloneDataWatcher(dataWatcher);// Clone the DataWatcher, we don't want to change the name values permanently
|
||||
AccessUtil.setAccessible(Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1) ? NMSClass.DataWatcher.getDeclaredField("a") : NMSClass.DataWatcher.getDeclaredField("b")).set(dataWatcher, null);
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
setPacketValue("l", dataWatcher, packet);
|
||||
} else {
|
||||
setPacketValue("m", dataWatcher, packet);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return;// Allowing further changes here would mess up the packet values
|
||||
}
|
||||
}
|
||||
|
||||
List list = (List) (type == 1 ? getPacketValue("b", packet) : null);
|
||||
int listIndex = -1;
|
||||
|
||||
String text = null;
|
||||
try {
|
||||
if (type == 0) {
|
||||
// text = (String) ClassBuilder.getWatchableObjectValue(ClassBuilder.getDataWatcherValue(dataWatcher, 2));
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
text = (String) DataWatcher.V1_8.getWatchableObjectValue(DataWatcher.V1_8.getValue(dataWatcher, 2));
|
||||
} else {
|
||||
Field dField = AccessUtil.setAccessible(NMSClass.DataWatcher.getDeclaredField("d"));
|
||||
Object dValue = dField.get(dataWatcher);
|
||||
if (dValue == null) {
|
||||
return;
|
||||
}
|
||||
if (Map.class.isAssignableFrom(dValue.getClass())) {
|
||||
if (((Map) dValue).isEmpty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
text = (String) DataWatcher.V1_9.getValue(dataWatcher, DataWatcher.V1_9.ValueType.ENTITY_NAME);
|
||||
}
|
||||
} else if (type == 1) {
|
||||
if (list != null) {
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
// int index = ClassBuilder.getWatchableObjectIndex(list.get(i));
|
||||
int index = DataWatcher.V1_8.getWatchableObjectIndex(list.get(i));
|
||||
if (index == 2) {
|
||||
// if (ClassBuilder.getWatchableObjectType(list.get(i)) == 4) {//Check if it is a string
|
||||
if (DataWatcher.V1_8.getWatchableObjectType(list.get(i)) == 4) {//Check if it is a string
|
||||
// text = (String) ClassBuilder.getWatchableObjectValue(list.get(i));
|
||||
text = (String) DataWatcher.V1_8.getWatchableObjectValue(list.get(i));
|
||||
listIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (list.size() > 2) {
|
||||
if (DataWatcher.V1_9.getItemType(list.get(2)) == String.class) {
|
||||
text = (String) DataWatcher.V1_9.getItemValue(list.get(2));
|
||||
listIndex = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (!HologramAPI.useProtocolSupport) {
|
||||
e.printStackTrace();//Ignore the exception(s) when using protocol support
|
||||
}
|
||||
}
|
||||
|
||||
if (text == null) {
|
||||
return;// The text will (or should) never be null
|
||||
}
|
||||
|
||||
for (Hologram h : HologramAPI.getHolograms()) {
|
||||
if (((CraftHologram) h).matchesHologramID(a)) {
|
||||
for (ViewHandler v : h.getViewHandlers()) {
|
||||
text = v.onView(h, packetObject.getPlayer(), text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (text == null) {
|
||||
packetObject.setCancelled(true);//Cancel the packet if the text is null after calling the view handlers
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (type == 0) {
|
||||
// ClassBuilder.setDataWatcherValue(dataWatcher, 2, text);
|
||||
DataWatcher.setValue(dataWatcher, 2, DataWatcher.V1_9.ValueType.ENTITY_NAME, text);
|
||||
} else if (type == 1) {
|
||||
if (list == null || listIndex == -1) {
|
||||
return;
|
||||
}
|
||||
// Object object = ClassBuilder.buildWatchableObject(2, text);
|
||||
Object object = Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1) ? DataWatcher.V1_8.newWatchableObject(2, text) : DataWatcher.V1_9.newDataWatcherItem(DataWatcher.V1_9.ValueType.ENTITY_NAME.getType(), text);
|
||||
list.set(listIndex, object);
|
||||
setPacketValue("b", list, packet);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setPacketValue(String field, Object value, Object packet) {
|
||||
FieldResolver fieldResolver = new FieldResolver(packet.getClass());
|
||||
try {
|
||||
fieldResolver.resolve(field).set(packet, value);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getPacketValue(String field, Object packet) {
|
||||
FieldResolver fieldResolver = new FieldResolver(packet.getClass());
|
||||
try {
|
||||
return fieldResolver.resolve(field).get(packet);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object cloneDataWatcher(Object original) throws Exception {
|
||||
if (original == null) {
|
||||
return null;
|
||||
}
|
||||
// Object clone = NMSClass.DataWatcher.getConstructor(new Class[] {
|
||||
// NMSClass.Entity }).newInstance(new Object[] { null });
|
||||
Object clone = DataWatcher.newDataWatcher(null);
|
||||
int index = 0;
|
||||
Object current = null;
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
// while ((current = ClassBuilder.getDataWatcherValue(original, index++)) !=
|
||||
// null) {
|
||||
// ClassBuilder.setDataWatcherValue(clone,
|
||||
// ClassBuilder.getWatchableObjectIndex(current),
|
||||
// ClassBuilder.getWatchableObjectValue(current));
|
||||
// }
|
||||
while ((current = DataWatcher.V1_8.getValue(original, index++)) != null) {
|
||||
DataWatcher.V1_8.setValue(clone, DataWatcher.V1_8.getWatchableObjectIndex(current),
|
||||
DataWatcher.V1_8.getWatchableObjectValue(current));
|
||||
}
|
||||
} else {
|
||||
Field mapField = DataWatcherFieldResolver.resolve("c");
|
||||
mapField.set(clone, mapField.get(original));
|
||||
// while ((current = DataWatcher.V1_9.getItem(original, index++)) != null) {
|
||||
// DataWatcher.V1_9.setItem(clone, index++, current);
|
||||
// }
|
||||
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
private static boolean hasDelay(Player player) {
|
||||
if (!player.hasMetadata(DELAY_TAG)) return false;
|
||||
return player.getMetadata(DELAY_TAG).get(0).asLong() > System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private static void addDelay(Player player) {
|
||||
player.setMetadata(DELAY_TAG, new FixedMetadataValue(BukkitMain.getInstance(), System.currentTimeMillis() + 600));
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.protocol.ProtocolGetter;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.utility.LocationUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
public class HologramListeners {
|
||||
|
||||
private final static String LOCKED_TAG = "LOCKED.HOLOGRAMS.TIME";
|
||||
private static Listener listener;
|
||||
|
||||
public static void registerListeners() {
|
||||
|
||||
listener = new Listener() {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
handleHolograms(event.getPlayer(), event.getPlayer().getLocation());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
for (Hologram hologram : HologramAPI.getHolograms()) {
|
||||
if (hologram.isSpawned()) {
|
||||
hologram.clean(event.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRealMovement(PlayerMoveEvent event) {
|
||||
if(!LocationUtil.isRealMovement(event.getFrom(), event.getTo())) return;
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (isLocked(player)) return;
|
||||
|
||||
handleHolograms(player, event.getTo());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onTeleport(PlayerTeleportEvent e) {
|
||||
Player player = e.getPlayer();
|
||||
if (isLocked(player)) return;
|
||||
|
||||
handleHolograms(player, e.getTo());
|
||||
}
|
||||
};
|
||||
|
||||
Bukkit.getServer().getPluginManager().registerEvents(listener, BukkitMain.getInstance());
|
||||
}
|
||||
|
||||
public static void unregisterListeners() {
|
||||
HandlerList.unregisterAll(listener);
|
||||
listener = null;
|
||||
}
|
||||
|
||||
public static void handleHolograms(Player player, Location location) {
|
||||
lock(player);
|
||||
|
||||
for (Hologram hologram : HologramAPI.getHolograms()) {
|
||||
if (!hologram.isSpawned()) continue;
|
||||
if (!hologram.getLocation().getWorld().getName().equals(location.getWorld().getName())) continue;
|
||||
|
||||
if (hologram.getLocation().distance(location) <= 80) {
|
||||
|
||||
boolean spawn = true;
|
||||
|
||||
if (hologram.getName().equalsIgnoreCase("name")) {
|
||||
if (ProtocolGetter.getVersion(player) < 6) spawn = false;
|
||||
}
|
||||
|
||||
if (spawn) {
|
||||
try {
|
||||
HologramAPI.spawnSingle(hologram, player);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
HologramAPI.despawnSingle(hologram, player);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeLock(player);
|
||||
}
|
||||
|
||||
public static void lock(Player player) {
|
||||
lock(player, 1500L);
|
||||
}
|
||||
|
||||
public static void removeLock(Player player) {
|
||||
player.removeMetadata(LOCKED_TAG, BukkitMain.getInstance());
|
||||
}
|
||||
|
||||
public static void lock(Player player, Long time) {
|
||||
player.setMetadata(LOCKED_TAG, new FixedMetadataValue(BukkitMain.getInstance(), System.currentTimeMillis() + time));
|
||||
}
|
||||
|
||||
private static boolean isLocked(final Player player) {
|
||||
if (!player.hasMetadata(LOCKED_TAG)) return false;
|
||||
return player.getMetadata(LOCKED_TAG).get(0).asLong() > System.currentTimeMillis();
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram;
|
||||
|
||||
class HologramOffsets {
|
||||
|
||||
protected static final double WITHER_SKULL_HORSE = 54.56;
|
||||
protected static final double ARMOR_STAND_PACKET = -2.25;
|
||||
protected static final double ARMOR_STAND_DEFAULT = -1.25;
|
||||
protected static final double TOUCH_SLIME_SKULL = -0.4;
|
||||
protected static final double TOUCH_SLIME_ARMOR_STAND = 0.4;
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
|
||||
@Getter
|
||||
public class PlayerTop implements Comparable<PlayerTop> {
|
||||
|
||||
private final String playerName;
|
||||
private final int value;
|
||||
|
||||
public PlayerTop(String playerName, int value) {
|
||||
this.playerName = playerName;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(PlayerTop o) {
|
||||
return o.getValue() - getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof PlayerTop)) return false;
|
||||
|
||||
val topObj = (PlayerTop) obj;
|
||||
|
||||
return topObj.getPlayerName().equals(playerName) && topObj.getValue() == value;
|
||||
}
|
||||
}
|
@ -0,0 +1,300 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.HologramAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.DataWatcher;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.FieldResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.minecraft.NMSClassResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.util.AccessUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.DataWatcher.V1_9.ValueType.*;
|
||||
|
||||
public abstract class ClassBuilder {
|
||||
|
||||
static NMSClassResolver nmsClassResolver = new NMSClassResolver();
|
||||
|
||||
static FieldResolver EntitySlimeFieldResolver = new FieldResolver(NMSClass.EntitySlime);
|
||||
static FieldResolver EntityFieldResolver = new FieldResolver(NMSClass.Entity);
|
||||
static final FieldResolver PacketPlayOutSpawnEntityLivingFieldResolver = new FieldResolver(NMSClass.PacketPlayOutSpawnEntityLiving);
|
||||
static final FieldResolver DataWatcherFieldResolver = new FieldResolver(NMSClass.DataWatcher);
|
||||
|
||||
public static Object buildEntityWitherSkull(Object world, Location loc) throws Exception {
|
||||
Object witherSkull = NMSClass.EntityWitherSkull.getConstructor(NMSClass.World).newInstance(world);
|
||||
updateEntityLocation(witherSkull, loc);
|
||||
|
||||
return witherSkull;
|
||||
}
|
||||
|
||||
public static Object buildEntityHorse_1_7(Object world, Location loc, String name) throws Exception {
|
||||
Object horse_1_7 = NMSClass.EntityHorse.getConstructor(NMSClass.World).newInstance(world);
|
||||
updateEntityLocation(horse_1_7, loc);
|
||||
if (HologramAPI.is1_8()) {
|
||||
if (name != null) {
|
||||
NMSClass.Entity.getDeclaredMethod("setCustomName", String.class).invoke(horse_1_7, name);
|
||||
}
|
||||
NMSClass.Entity.getDeclaredMethod("setCustomNameVisible", boolean.class).invoke(horse_1_7, name != null && !name.isEmpty());
|
||||
} else {
|
||||
if (name != null) {
|
||||
NMSClass.EntityInsentient.getDeclaredMethod("setCustomName", String.class).invoke(horse_1_7, name);
|
||||
}
|
||||
NMSClass.EntityInsentient.getDeclaredMethod("setCustomNameVisible", boolean.class).invoke(horse_1_7, name != null && !name.isEmpty());
|
||||
}
|
||||
Object horseDataWatcher = AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("datawatcher")).get(horse_1_7);
|
||||
NMSClass.EntityAgeable.getDeclaredMethod("setAge", int.class).invoke(horse_1_7, -1700000);
|
||||
// NMSClass.DataWatcher.getDeclaredMethod("watch", new Class[] {
|
||||
// int.class,
|
||||
// Object.class }).invoke(horseDataWatcher, new Object[] {
|
||||
// 12,
|
||||
// -1700000 });// Size
|
||||
DataWatcher.setValue(horseDataWatcher, 12, ENTITY_FLAG, (byte) -1700000);
|
||||
|
||||
return horse_1_7;
|
||||
}
|
||||
|
||||
public static Object buildEntityHorse_1_8(Object world, Location loc, String name) throws Exception {
|
||||
Object horse_1_8 = NMSClass.EntityHorse.getConstructor(NMSClass.World).newInstance(world);
|
||||
updateEntityLocation(horse_1_8, loc);
|
||||
if (HologramAPI.is1_8()) {
|
||||
if (name != null) {
|
||||
NMSClass.Entity.getDeclaredMethod("setCustomName", String.class).invoke(horse_1_8, name);
|
||||
}
|
||||
NMSClass.Entity.getDeclaredMethod("setCustomNameVisible", boolean.class).invoke(horse_1_8, true);
|
||||
} else {
|
||||
NMSClass.EntityInsentient.getDeclaredMethod("setCustomName", String.class).invoke(horse_1_8, name);
|
||||
NMSClass.EntityInsentient.getDeclaredMethod("setCustomNameVisible", boolean.class).invoke(horse_1_8, name != null && !name.isEmpty());
|
||||
}
|
||||
|
||||
return horse_1_8;
|
||||
}
|
||||
|
||||
public static Object buildEntityArmorStand(Object world, Location loc, String name) throws Exception {
|
||||
Object armorStand = NMSClass.EntityArmorStand.getConstructor(NMSClass.World).newInstance(world);
|
||||
updateEntityLocation(armorStand, loc);
|
||||
if (name != null) {
|
||||
NMSClass.Entity.getDeclaredMethod("setCustomName", String.class).invoke(armorStand, name);
|
||||
}
|
||||
NMSClass.Entity.getDeclaredMethod("setCustomNameVisible", boolean.class).invoke(armorStand, name != null && !name.isEmpty());
|
||||
|
||||
return armorStand;
|
||||
}
|
||||
|
||||
public static Object setupArmorStand(Object armorStand) throws Exception {
|
||||
NMSClass.EntityArmorStand.getDeclaredMethod("setInvisible", boolean.class).invoke(armorStand, true);
|
||||
NMSClass.EntityArmorStand.getDeclaredMethod("setSmall", boolean.class).invoke(armorStand, true);
|
||||
NMSClass.EntityArmorStand.getDeclaredMethod("setArms", boolean.class).invoke(armorStand, false);
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_10_R1)) {
|
||||
NMSClass.EntityArmorStand.getDeclaredMethod("setGravity", boolean.class).invoke(armorStand, false);
|
||||
} else {
|
||||
NMSClass.Entity.getDeclaredMethod("setNoGravity", boolean.class).invoke(armorStand, true);
|
||||
}
|
||||
NMSClass.EntityArmorStand.getDeclaredMethod("setBasePlate", boolean.class).invoke(armorStand, false);
|
||||
|
||||
return armorStand;
|
||||
}
|
||||
|
||||
public static Object buildEntitySlime(Object world, Location loc, int size) throws Exception {
|
||||
Object slime = NMSClass.EntitySlime.getConstructor(NMSClass.World).newInstance(world);
|
||||
updateEntityLocation(slime, loc);
|
||||
Object dataWatcher = AccessUtil.setAccessible(NMSClass.Entity.getDeclaredField("datawatcher")).get(slime);
|
||||
// setDataWatcherValue(dataWatcher, 0, (byte) 32);
|
||||
// setDataWatcherValue(dataWatcher, 16, (byte) (size < 1 ? 1 : size > 100 ? 100 : size));
|
||||
DataWatcher.setValue(dataWatcher, 0, ENTITY_FLAG, (byte) 32);
|
||||
DataWatcher.setValue(dataWatcher, 16, ENTITY_SLIME_SIZE, (size < 1 ? 1 : Math.min(size, 100)));//Size
|
||||
|
||||
return slime;
|
||||
}
|
||||
|
||||
public static Object buildWitherSkullSpawnPacket(Object skull) throws Exception {
|
||||
Object spawnPacketSkull = NMSClass.PacketPlayOutSpawnEntity.getConstructor(NMSClass.Entity, int.class).newInstance(skull, EntityType.WITHER_SKULL.getTypeId());
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutSpawnEntity.getDeclaredField("j")).set(spawnPacketSkull, 66);
|
||||
} else {
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutSpawnEntity.getDeclaredField("k")).set(spawnPacketSkull, 66);
|
||||
}
|
||||
|
||||
return spawnPacketSkull;
|
||||
}
|
||||
|
||||
public static Object buildSkullMetaPacket(int id, Object dataWatcher) throws Exception {
|
||||
// setDataWatcherValue(dataWatcher, 0, (byte) 32);
|
||||
DataWatcher.setValue(dataWatcher, 0, ENTITY_FLAG, (byte) 32);
|
||||
|
||||
return NMSClass.PacketPlayOutEntityMetadata.getConstructor(int.class, NMSClass.DataWatcher, boolean.class).newInstance(id, dataWatcher, true);
|
||||
}
|
||||
|
||||
public static Object buildHorseSpawnPacket_1_7(Object horse, String name) throws Exception {
|
||||
if (horse == null) {
|
||||
throw new IllegalArgumentException("horse cannot be null");
|
||||
}
|
||||
Object spawnPacketHorse_1_7 = NMSClass.PacketPlayOutSpawnEntityLiving.getConstructor(NMSClass.EntityLiving).newInstance(horse);
|
||||
Object dataWatcher_1_7 = AccessUtil.setAccessible(PacketPlayOutSpawnEntityLivingFieldResolver.resolveByFirstType(NMSClass.DataWatcher)).get(spawnPacketHorse_1_7);
|
||||
|
||||
if (name != null) {
|
||||
// setDataWatcherValue(dataWatcher_1_7, 10, name);
|
||||
DataWatcher.setValue(dataWatcher_1_7, 10, ENTITY_NAME, name);
|
||||
}
|
||||
// setDataWatcherValue(dataWatcher_1_7, 11, (byte) (name != null && !name.isEmpty() ? 1 : 0));
|
||||
DataWatcher.setValue(dataWatcher_1_7, 11, ENTITY_NAME_VISIBLE, (byte) (name != null && !name.isEmpty() ? 1 : 0));
|
||||
// NMUClass.gnu_trove_map_hash_TIntObjectHashMap.getDeclaredMethod("put", int.class, Object.class).invoke(map, 12, NMSClass.WatchableObject.getConstructor(int.class, int.class, Object.class).newInstance(2, 12, -1700000));
|
||||
DataWatcher.setValue(dataWatcher_1_7, 12, ENTITY_FLAG, -1700000);
|
||||
|
||||
return spawnPacketHorse_1_7;
|
||||
}
|
||||
|
||||
//No changes for 1.9 here - use ArmorStands
|
||||
public static Object buildHorseSpawnPacket_1_8(Object horse, String name) throws Exception {
|
||||
if (horse == null) {
|
||||
throw new IllegalArgumentException("horse cannot be null");
|
||||
}
|
||||
Object spawnPacketHorse_1_8 = NMSClass.PacketPlayOutSpawnEntityLiving.getConstructor(NMSClass.EntityLiving).newInstance(horse);
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutSpawnEntityLiving.getDeclaredField("b")).setInt(spawnPacketHorse_1_8, 30);
|
||||
Object dataWatcher_1_8 = AccessUtil.setAccessible(PacketPlayOutSpawnEntityLivingFieldResolver.resolveByFirstType(NMSClass.DataWatcher)).get(spawnPacketHorse_1_8);
|
||||
Map<Integer, Object> map_1_8 = (Map) DataWatcherFieldResolver.resolveByLastType(Map.class).get(dataWatcher_1_8);
|
||||
map_1_8.put(10, NMSClass.WatchableObject.getConstructor(int.class, int.class, Object.class).newInstance(0, 10, (byte) 1));
|
||||
|
||||
List<Integer> toRemove = new ArrayList<>();
|
||||
|
||||
for (Map.Entry entry : map_1_8.entrySet()) {// 100 is a random value, we just want to get all values
|
||||
Object current = entry.getValue();
|
||||
if (current == null) {
|
||||
continue;
|
||||
}
|
||||
int index = AccessUtil.setAccessible(NMSClass.WatchableObject.getDeclaredField("b")).getInt(current);
|
||||
if (index == 2) {
|
||||
AccessUtil.setAccessible(NMSClass.WatchableObject.getDeclaredField("c")).set(current, name);
|
||||
} else if (index != 3) {
|
||||
toRemove.add(Integer.valueOf(index));
|
||||
}
|
||||
}
|
||||
|
||||
for (Integer i : toRemove) {
|
||||
map_1_8.remove(i);
|
||||
}
|
||||
|
||||
map_1_8.put(0, NMSClass.WatchableObject.getConstructor(int.class, int.class, Object.class).newInstance(0, 0, (byte) 32));
|
||||
|
||||
return spawnPacketHorse_1_8;
|
||||
}
|
||||
|
||||
public static Object buildSlimeSpawnPacket(Object slime) throws Exception {
|
||||
|
||||
return NMSClass.PacketPlayOutSpawnEntityLiving.getConstructor(NMSClass.EntityLiving).newInstance(slime);
|
||||
}
|
||||
|
||||
public static Object buildNameMetadataPacket(int id, Object dataWatcher, int nameIndex, int visibilityIndex, String name) throws Exception {
|
||||
// dataWatcher = setDataWatcherValue(dataWatcher, nameIndex, name != null ? name : "");// Pass an empty string to avoid exceptions
|
||||
// dataWatcher = setDataWatcherValue(dataWatcher, visibilityIndex, (byte) (name != null && !name.isEmpty() ? 1 : 0));
|
||||
DataWatcher.setValue(dataWatcher, nameIndex, ENTITY_NAME, name != null ? name : "");// Pass an empty string to avoid exceptions
|
||||
DataWatcher.setValue(dataWatcher, visibilityIndex, ENTITY_NAME_VISIBLE, Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1) ? (byte) (name != null && !name.isEmpty() ? 1 : 0) : (name != null && !name.isEmpty()));//Byte < 1.9, Boolean >= 1.9
|
||||
|
||||
return NMSClass.PacketPlayOutEntityMetadata.getConstructor(int.class, NMSClass.DataWatcher, boolean.class).newInstance(id, dataWatcher, true);
|
||||
}
|
||||
|
||||
public static Object updateEntityLocation(Object entity, Location loc) throws Exception {
|
||||
NMSClass.Entity.getDeclaredField("locX").set(entity, loc.getX());
|
||||
NMSClass.Entity.getDeclaredField("locY").set(entity, loc.getY());
|
||||
NMSClass.Entity.getDeclaredField("locZ").set(entity, loc.getZ());
|
||||
return entity;
|
||||
}
|
||||
|
||||
// public static Object buildDataWatcher(@Nullable Object entity) throws Exception {
|
||||
// Object dataWatcher = NMSClass.DataWatcher.getConstructor(NMSClass.Entity).newInstance(entity);
|
||||
// return dataWatcher;
|
||||
// }
|
||||
//
|
||||
// public static Object buildWatchableObject(int index, Object value) throws Exception {
|
||||
// return buildWatchableObject(getDataWatcherValueType(value), index, value);
|
||||
// }
|
||||
//
|
||||
// public static Object buildWatchableObject(int type, int index, Object value) throws Exception {
|
||||
// return NMSClass.WatchableObject.getConstructor(int.class, int.class, Object.class).newInstance(type, index, value);
|
||||
// }
|
||||
//
|
||||
// public static Object setDataWatcherValue(Object dataWatcher, int index, Object value) throws Exception {
|
||||
// int type = getDataWatcherValueType(value);
|
||||
//
|
||||
// Object map = AccessUtil.setAccessible(NMSClass.DataWatcher.getDeclaredField("dataValues")).get(dataWatcher);
|
||||
// NMUClass.gnu_trove_map_hash_TIntObjectHashMap.getDeclaredMethod("put", int.class, Object.class).invoke(map, index, buildWatchableObject(type, index, value));
|
||||
//
|
||||
// return dataWatcher;
|
||||
// }
|
||||
//
|
||||
// public static Object getDataWatcherValue(Object dataWatcher, int index) throws Exception {
|
||||
// Object map = AccessUtil.setAccessible(NMSClass.DataWatcher.getDeclaredField("dataValues")).get(dataWatcher);
|
||||
// Object value = NMUClass.gnu_trove_map_hash_TIntObjectHashMap.getDeclaredMethod("get", int.class).invoke(map, index);
|
||||
//
|
||||
// return value;
|
||||
// }
|
||||
//
|
||||
// public static int getWatchableObjectIndex(Object object) throws Exception {
|
||||
// int index = AccessUtil.setAccessible(NMSClass.WatchableObject.getDeclaredField("b")).getInt(object);
|
||||
// return index;
|
||||
// }
|
||||
//
|
||||
// public static int getWatchableObjectType(Object object) throws Exception {
|
||||
// int type = AccessUtil.setAccessible(NMSClass.WatchableObject.getDeclaredField("a")).getInt(object);
|
||||
// return type;
|
||||
// }
|
||||
//
|
||||
// public static Object getWatchableObjectValue(Object object) throws Exception {
|
||||
// Object value = AccessUtil.setAccessible(NMSClass.WatchableObject.getDeclaredField("c")).get(object);
|
||||
// return value;
|
||||
// }
|
||||
//
|
||||
// public static int getDataWatcherValueType(Object value) {
|
||||
// int type = 0;
|
||||
// if (value instanceof Number) {
|
||||
// if (value instanceof Byte) {
|
||||
// type = 0;
|
||||
// } else if (value instanceof Short) {
|
||||
// type = 1;
|
||||
// } else if (value instanceof Integer) {
|
||||
// type = 2;
|
||||
// } else if (value instanceof Float) {
|
||||
// type = 3;
|
||||
// }
|
||||
// } else if (value instanceof String) {
|
||||
// type = 4;
|
||||
// } else if (value != null && value.getClass().equals(NMSClass.ItemStack)) {
|
||||
// type = 5;
|
||||
// } else if (value != null && (value.getClass().equals(NMSClass.ChunkCoordinates) || value.getClass().equals(NMSClass.BlockPosition))) {
|
||||
// type = 6;
|
||||
// } else if (value != null && value.getClass().equals(NMSClass.Vector3f)) {
|
||||
// type = 7;
|
||||
// }
|
||||
//
|
||||
// return type;
|
||||
// }
|
||||
|
||||
public static Object buildArmorStandSpawnPacket(Object armorStand) throws Exception {
|
||||
Object spawnPacket = NMSClass.PacketPlayOutSpawnEntityLiving.getConstructor(NMSClass.EntityLiving).newInstance(armorStand);
|
||||
AccessUtil.setAccessible(Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1) ? NMSClass.PacketPlayOutSpawnEntityLiving.getDeclaredField("b") : NMSClass.PacketPlayOutSpawnEntityLiving.getDeclaredField("c")).setInt(spawnPacket, 30);
|
||||
|
||||
return spawnPacket;
|
||||
}
|
||||
|
||||
public static Object buildTeleportPacket(int id, Location loc, boolean onGround, boolean heightCorrection) throws Exception {
|
||||
Object packet = NMSClass.PacketPlayOutEntityTeleport.newInstance();
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("a")).set(packet, id);
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("b")).set(packet, (int) (loc.getX() * 32D));
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("c")).set(packet, (int) (loc.getY() * 32D));
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("d")).set(packet, (int) (loc.getZ() * 32D));
|
||||
} else {
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("b")).set(packet, loc.getX());
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("c")).set(packet, loc.getY());
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("d")).set(packet, loc.getZ());
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("g")).set(packet, onGround);
|
||||
}
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("e")).set(packet, (byte) (int) (loc.getYaw() * 256F / 360F));
|
||||
AccessUtil.setAccessible(NMSClass.PacketPlayOutEntityTeleport.getDeclaredField("f")).set(packet, (byte) (int) (loc.getPitch() * 256F / 360F));
|
||||
|
||||
return packet;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection;
|
||||
|
||||
public abstract class MathUtil {
|
||||
|
||||
public static int floor(double d1) {
|
||||
int i = (int) d1;
|
||||
return d1 >= i ? i : i - 1;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public abstract class NMSClass {
|
||||
|
||||
public static Class<?> Entity;
|
||||
public static Class<?> EntityLiving;
|
||||
public static Class<?> EntityInsentient;
|
||||
public static Class<?> EntityAgeable;
|
||||
public static Class<?> EntityHorse;
|
||||
public static Class<?> EntityArmorStand;
|
||||
public static Class<?> EntityWitherSkull;
|
||||
public static Class<?> EntitySlime;
|
||||
public static Class<?> World;
|
||||
public static Class<?> PacketPlayOutSpawnEntityLiving;
|
||||
public static Class<?> PacketPlayOutSpawnEntity;
|
||||
public static Class<?> PacketPlayOutEntityDestroy;
|
||||
public static Class<?> PacketPlayOutAttachEntity;
|
||||
public static Class<?> PacketPlayOutMount;//1.9
|
||||
public static Class<?> PacketPlayOutEntityTeleport;
|
||||
public static Class<?> PacketPlayOutEntityMetadata;
|
||||
public static Class<?> DataWatcher;
|
||||
public static Class<?> WatchableObject;
|
||||
public static Class<?> ItemStack;
|
||||
public static Class<?> ChunkCoordinates;
|
||||
public static Class<?> BlockPosition;
|
||||
public static Class<?> Vector3f;
|
||||
public static Class<?> EnumEntityUseAction;
|
||||
private static boolean initialized = false;
|
||||
|
||||
static {
|
||||
if (!initialized) {
|
||||
for (Field f : NMSClass.class.getDeclaredFields()) {
|
||||
if (f.getType().equals(Class.class)) {
|
||||
try {
|
||||
f.set(null, Reflection.getNMSClassWithException(f.getName()));
|
||||
} catch (Exception e) {
|
||||
if (f.getName().equals("WatchableObject")) {
|
||||
try {
|
||||
f.set(null, Reflection.getNMSClassWithException("DataWatcher$WatchableObject"));
|
||||
} catch (Exception e1) {
|
||||
// e1.printStackTrace(); - Ignore for 1.9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public abstract class NMUClass {
|
||||
|
||||
public static Class<?> gnu_trove_map_TIntObjectMap;
|
||||
public static Class<?> gnu_trove_map_hash_TIntObjectHashMap;
|
||||
public static Class<?> gnu_trove_impl_hash_THash;
|
||||
public static Class<?> io_netty_channel_Channel;
|
||||
private static boolean initialized = false;
|
||||
|
||||
static {
|
||||
if (!initialized) {
|
||||
for (Field f : NMUClass.class.getDeclaredFields()) {
|
||||
if (f.getType().equals(Class.class)) {
|
||||
try {
|
||||
String name = f.getName().replace("_", ".");
|
||||
if (Reflection.getVersion().contains("1_8")) {
|
||||
f.set(null, Class.forName(name));
|
||||
} else {
|
||||
f.set(null, Class.forName("net.minecraft.util." + name));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public abstract class Reflection {
|
||||
|
||||
public static String getVersion() {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
return name.substring(name.lastIndexOf('.') + 1) + ".";
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClass(String className) {
|
||||
String fullName = "net.minecraft.server." + getVersion() + className;
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
clazz = Class.forName(fullName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClassWithException(String className) throws Exception {
|
||||
String fullName = "net.minecraft.server." + getVersion() + className;
|
||||
return Class.forName(fullName);
|
||||
}
|
||||
|
||||
public static Class<?> getOBCClass(String className) {
|
||||
String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
clazz = Class.forName(fullName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public static Object getHandle(Object obj) {
|
||||
try {
|
||||
return getMethod(obj.getClass(), "getHandle", new Class[0]).invoke(obj);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Field getField(Class<?> clazz, String name) {
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Field getFieldWithException(Class<?> clazz, String name) throws Exception {
|
||||
Field field = clazz.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name, Class<?>... args) {
|
||||
for (Method m : clazz.getMethods()) {
|
||||
if (m.getName().equals(name) && (args.length == 0 || ClassListEqual(args, m.getParameterTypes()))) {
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean ClassListEqual(Class<?>[] l1, Class<?>[] l2) {
|
||||
boolean equal = true;
|
||||
if (l1.length != l2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < l1.length; i++) {
|
||||
if (l1[i] != l2[i]) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.annotation;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Resolves the annotated {@link de.inventivegames.reflection.resolver.wrapper.ClassWrapper} or {@link java.lang.Class} field to the first matching class name.
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Class {
|
||||
|
||||
/**
|
||||
* Name of the class. Use <code>{nms}.MyClass</code> for NMS classes, or <code>{obc}.MyClass</code> for OBC classes. Use <code>></code> or <code><</code> as a name prefix in combination with {@link #versions()} to specify versions newer- or older-than.
|
||||
*
|
||||
* @return the class name
|
||||
*/
|
||||
String[] value();
|
||||
|
||||
/**
|
||||
* Specific versions for the names.
|
||||
*
|
||||
* @return Array of versions for the class names
|
||||
*/
|
||||
Minecraft.Version[] versions() default {};
|
||||
|
||||
/**
|
||||
* Whether to ignore any reflection exceptions thrown. Defaults to <code>true</code>
|
||||
*
|
||||
* @return whether to ignore exceptions
|
||||
*/
|
||||
boolean ignoreExceptions() default true;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.annotation;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Resolves the annotated {@link org.inventivegames.reflection.resolver.wrapper.FieldWrapper} or {@link java.lang.reflect.Field} field to the first matching field name.
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Field {
|
||||
|
||||
/**
|
||||
* Name of the class to load this field from
|
||||
*
|
||||
* @return name of the class
|
||||
*/
|
||||
String className();
|
||||
|
||||
/**
|
||||
* Possible names of the field. Use <code>></code> or <code><</code> as a name prefix in combination with {@link #versions()} to specify versions newer- or older-than.
|
||||
*
|
||||
* @return names of the field
|
||||
*/
|
||||
String[] value();
|
||||
|
||||
/**
|
||||
* Specific versions for the names.
|
||||
*
|
||||
* @return Array of versions for the class names
|
||||
*/
|
||||
Minecraft.Version[] versions() default {};
|
||||
|
||||
/**
|
||||
* Whether to ignore any reflection exceptions thrown. Defaults to <code>true</code>
|
||||
*
|
||||
* @return whether to ignore exceptions
|
||||
*/
|
||||
boolean ignoreExceptions() default true;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.annotation;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Resolves the annotated {@link org.inventivegames.reflection.resolver.wrapper.MethodWrapper} or {@link java.lang.reflect.Method} field to the first matching method name.
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Method {
|
||||
|
||||
/**
|
||||
* Name of the class to load this method from
|
||||
*
|
||||
* @return name of the class
|
||||
*/
|
||||
String className();
|
||||
|
||||
/**
|
||||
* Possible names of the method. Use <code>></code> or <code><</code> as a name prefix in combination with {@link #versions()} to specify versions newer- or older-than.
|
||||
*
|
||||
* @return method names
|
||||
*/
|
||||
String[] value();
|
||||
|
||||
/**
|
||||
* Specific versions for the names.
|
||||
*
|
||||
* @return Array of versions for the class names
|
||||
*/
|
||||
Minecraft.Version[] versions() default {};
|
||||
|
||||
/**
|
||||
* Whether to ignore any reflection exceptions thrown. Defaults to <code>true</code>
|
||||
*
|
||||
* @return whether to ignore exceptions
|
||||
*/
|
||||
boolean ignoreExceptions() default true;
|
||||
}
|
@ -0,0 +1,205 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.annotation;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.ClassResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.FieldResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.MethodResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper.ClassWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper.FieldWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper.MethodWrapper;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ReflectionAnnotations {
|
||||
|
||||
public static final ReflectionAnnotations INSTANCE = new ReflectionAnnotations();
|
||||
|
||||
static final Pattern classRefPattern = Pattern.compile("@Class\\((.*)\\)");
|
||||
|
||||
private ReflectionAnnotations() {
|
||||
}
|
||||
|
||||
public void load(Object toLoad) {
|
||||
if (toLoad == null) {
|
||||
throw new IllegalArgumentException("toLoad cannot be null");
|
||||
}
|
||||
|
||||
ClassResolver classResolver = new ClassResolver();
|
||||
|
||||
for (java.lang.reflect.Field field : toLoad.getClass().getDeclaredFields()) {
|
||||
Class classAnnotation = field.getAnnotation(Class.class);
|
||||
Field fieldAnnotation = field.getAnnotation(Field.class);
|
||||
Method methodAnnotation = field.getAnnotation(Method.class);
|
||||
|
||||
if (classAnnotation == null && fieldAnnotation == null && methodAnnotation == null) {
|
||||
continue;
|
||||
} else {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
|
||||
if (classAnnotation != null) {
|
||||
List<String> nameList = parseAnnotationVersions(Class.class, classAnnotation);
|
||||
if (nameList.isEmpty()) {
|
||||
throw new IllegalArgumentException("@Class names cannot be empty");
|
||||
}
|
||||
String[] names = nameList.toArray(new String[0]);
|
||||
for (int i = 0; i < names.length; i++) {// Replace NMS & OBC
|
||||
names[i] = names[i]
|
||||
.replace("{nms}", "net.minecraft.server." + Minecraft.VERSION.name())
|
||||
.replace("{obc}", "org.bukkit.craftbukkit." + Minecraft.VERSION.name());
|
||||
}
|
||||
try {
|
||||
if (ClassWrapper.class.isAssignableFrom(field.getType())) {
|
||||
field.set(toLoad, classResolver.resolveWrapper(names));
|
||||
} else if (java.lang.Class.class.isAssignableFrom(field.getType())) {
|
||||
field.set(toLoad, classResolver.resolve(names));
|
||||
} else {
|
||||
throwInvalidFieldType(field, toLoad, "Class or ClassWrapper");
|
||||
return;
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
if (!classAnnotation.ignoreExceptions()) {
|
||||
throwReflectionException("@Class", field, toLoad, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (fieldAnnotation != null) {
|
||||
List<String> nameList = parseAnnotationVersions(Field.class, fieldAnnotation);
|
||||
if (nameList.isEmpty()) {
|
||||
throw new IllegalArgumentException("@Field names cannot be empty");
|
||||
}
|
||||
String[] names = nameList.toArray(new String[0]);
|
||||
try {
|
||||
FieldResolver fieldResolver = new FieldResolver(parseClass(Field.class, fieldAnnotation, toLoad));
|
||||
if (FieldWrapper.class.isAssignableFrom(field.getType())) {
|
||||
field.set(toLoad, fieldResolver.resolveWrapper(names));
|
||||
} else if (java.lang.reflect.Field.class.isAssignableFrom(field.getType())) {
|
||||
field.set(toLoad, fieldResolver.resolve(names));
|
||||
} else {
|
||||
throwInvalidFieldType(field, toLoad, "Field or FieldWrapper");
|
||||
return;
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
if (!fieldAnnotation.ignoreExceptions()) {
|
||||
throwReflectionException("@Field", field, toLoad, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<String> nameList = parseAnnotationVersions(Method.class, methodAnnotation);
|
||||
if (nameList.isEmpty()) {
|
||||
throw new IllegalArgumentException("@Method names cannot be empty");
|
||||
}
|
||||
String[] names = nameList.toArray(new String[0]);
|
||||
|
||||
boolean isSignature = names[0].contains(" ");// Only signatures can contain spaces (e.g. "void aMethod()")
|
||||
for (String s : names) {
|
||||
if (s.contains(" ") != isSignature) {
|
||||
throw new IllegalArgumentException("Inconsistent method names: Cannot have mixed signatures/names");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
MethodResolver methodResolver = new MethodResolver(parseClass(Method.class, methodAnnotation, toLoad));
|
||||
if (MethodWrapper.class.isAssignableFrom(field.getType())) {
|
||||
if (isSignature) {
|
||||
field.set(toLoad, methodResolver.resolveSignatureWrapper(names));
|
||||
} else {
|
||||
field.set(toLoad, methodResolver.resolveWrapper(names));
|
||||
}
|
||||
} else if (java.lang.reflect.Method.class.isAssignableFrom(field.getType())) {
|
||||
if (isSignature) {
|
||||
field.set(toLoad, methodResolver.resolveSignature(names));
|
||||
} else {
|
||||
field.set(toLoad, methodResolver.resolve(names));
|
||||
}
|
||||
} else {
|
||||
throwInvalidFieldType(field, toLoad, "Method or MethodWrapper");
|
||||
return;
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
if (!methodAnnotation.ignoreExceptions()) {
|
||||
throwReflectionException("@Method", field, toLoad, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an annotation to the current server version. Removes all entries that don't match the version, but keeps the original order for matching names.
|
||||
*
|
||||
* @param clazz Class of the annotation
|
||||
* @param annotation annotation
|
||||
* @param <A> annotation type
|
||||
* @return a list of matching names
|
||||
*/
|
||||
<A extends Annotation> List<String> parseAnnotationVersions(java.lang.Class<A> clazz, A annotation) {
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
try {
|
||||
String[] names = (String[]) clazz.getMethod("value").invoke(annotation);
|
||||
Minecraft.Version[] versions = (Minecraft.Version[]) clazz.getMethod("versions").invoke(annotation);
|
||||
|
||||
if (versions.length == 0) {// No versions specified -> directly use the names
|
||||
list.addAll(Arrays.asList(names));
|
||||
} else {
|
||||
if (versions.length > names.length) {
|
||||
throw new RuntimeException("versions array cannot have more elements than the names (" + clazz + ")");
|
||||
}
|
||||
for (int i = 0; i < versions.length; i++) {
|
||||
if (Minecraft.VERSION == versions[i]) {// Wohoo, perfect match!
|
||||
list.add(names[i]);
|
||||
} else {
|
||||
if (names[i].startsWith(">") && Minecraft.VERSION.newerThan(versions[i])) {// Match if the current version is newer
|
||||
list.add(names[i].substring(1));
|
||||
} else if (names[i].startsWith("<") && Minecraft.VERSION.olderThan(versions[i])) {// Match if the current version is older
|
||||
list.add(names[i].substring(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
<A extends Annotation> String parseClass(java.lang.Class<A> clazz, A annotation, Object toLoad) {
|
||||
try {
|
||||
String className = (String) clazz.getMethod("className").invoke(annotation);
|
||||
Matcher matcher = classRefPattern.matcher(className);
|
||||
while (matcher.find()) {
|
||||
if (matcher.groupCount() != 1) {
|
||||
continue;
|
||||
}
|
||||
String fieldName = matcher.group(1);// It's a reference to a previously loaded class
|
||||
java.lang.reflect.Field field = toLoad.getClass().getField(fieldName);
|
||||
if (ClassWrapper.class.isAssignableFrom(field.getType())) {
|
||||
return ((ClassWrapper) field.get(toLoad)).getName();
|
||||
} else if (java.lang.Class.class.isAssignableFrom(field.getType())) {
|
||||
return ((java.lang.Class) field.get(toLoad)).getName();
|
||||
}
|
||||
}
|
||||
return className;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void throwInvalidFieldType(java.lang.reflect.Field field, Object toLoad, String expected) {
|
||||
throw new IllegalArgumentException("Field " + field.getName() + " in " + toLoad.getClass() + " is not of type " + expected + ", it's " + field.getType());
|
||||
}
|
||||
|
||||
void throwReflectionException(String annotation, java.lang.reflect.Field field, Object toLoad, ReflectiveOperationException exception) {
|
||||
throw new RuntimeException("Failed to set " + annotation + " field " + field.getName() + " in " + toLoad.getClass(), exception);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,425 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.ConstructorResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.FieldResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.MethodResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.ResolverQuery;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.minecraft.NMSClassResolver;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
public class DataWatcher {
|
||||
|
||||
static final NMSClassResolver nmsClassResolver = new NMSClassResolver();
|
||||
|
||||
static final Class<?> ItemStack = nmsClassResolver.resolveSilent("ItemStack");
|
||||
static final Class<?> ChunkCoordinates = nmsClassResolver.resolveSilent("ChunkCoordinates");
|
||||
static final Class<?> BlockPosition = nmsClassResolver.resolveSilent("BlockPosition");
|
||||
static final Class<?> Vector3f = nmsClassResolver.resolveSilent("Vector3f");
|
||||
static final Class<?> DataWatcher = nmsClassResolver.resolveSilent("DataWatcher");
|
||||
static final ConstructorResolver DataWacherConstructorResolver = new ConstructorResolver(DataWatcher);
|
||||
static final FieldResolver DataWatcherFieldResolver = new FieldResolver(DataWatcher);
|
||||
static final MethodResolver DataWatcherMethodResolver = new MethodResolver(DataWatcher);
|
||||
static final Class<?> Entity = nmsClassResolver.resolveSilent("Entity");
|
||||
|
||||
private DataWatcher() {
|
||||
}
|
||||
|
||||
public static Object newDataWatcher(Object entity) throws ReflectiveOperationException {
|
||||
return DataWacherConstructorResolver.resolve(new Class[]{Entity}).newInstance(entity);
|
||||
}
|
||||
|
||||
public static Object setValue(Object dataWatcher, int index, Object dataWatcherObject/*1.9*/, Object value) throws ReflectiveOperationException {
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
return V1_8.setValue(dataWatcher, index, value);
|
||||
} else {
|
||||
return V1_9.setValue(dataWatcher, dataWatcherObject, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object setValue(Object dataWatcher, int index, V1_9.ValueType type, Object value) throws ReflectiveOperationException {
|
||||
return setValue(dataWatcher, index, type.getType(), value);
|
||||
}
|
||||
|
||||
public static Object setValue(Object dataWatcher, int index, Object value, FieldResolver dataWatcherObjectFieldResolver/*1.9*/, String... dataWatcherObjectFieldNames/*1.9*/) throws ReflectiveOperationException {
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
return V1_8.setValue(dataWatcher, index, value);
|
||||
} else {
|
||||
Object dataWatcherObject = dataWatcherObjectFieldResolver.resolve(dataWatcherObjectFieldNames).get(null/*Should be a static field*/);
|
||||
return V1_9.setValue(dataWatcher, dataWatcherObject, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Object getValue(DataWatcher dataWatcher, int index) throws ReflectiveOperationException {
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
return V1_8.getValue(dataWatcher, index);
|
||||
} else {
|
||||
return V1_9.getValue(dataWatcher, index);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getValue(Object dataWatcher, int index, V1_9.ValueType type) throws ReflectiveOperationException {
|
||||
return getValue(dataWatcher, index, type.getType());
|
||||
}
|
||||
|
||||
public static Object getValue(Object dataWatcher, int index, Object dataWatcherObject/*1.9*/) throws ReflectiveOperationException {
|
||||
if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) {
|
||||
return V1_8.getWatchableObjectValue(V1_8.getValue(dataWatcher, index));
|
||||
} else {
|
||||
return V1_9.getValue(dataWatcher, dataWatcherObject);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: update type-ids to 1.9
|
||||
public static int getValueType(Object value) {
|
||||
int type = 0;
|
||||
if (value instanceof Number) {
|
||||
if (value instanceof Byte) {
|
||||
type = 0;
|
||||
} else if (value instanceof Short) {
|
||||
type = 1;
|
||||
} else if (value instanceof Integer) {
|
||||
type = 2;
|
||||
} else if (value instanceof Float) {
|
||||
type = 3;
|
||||
}
|
||||
} else if (value instanceof String) {
|
||||
type = 4;
|
||||
} else if (value != null && value.getClass().equals(ItemStack)) {
|
||||
type = 5;
|
||||
} else if (value != null && (value.getClass().equals(ChunkCoordinates) || value.getClass().equals(BlockPosition))) {
|
||||
type = 6;
|
||||
} else if (value != null && value.getClass().equals(Vector3f)) {
|
||||
type = 7;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for versions newer than 1.9
|
||||
*/
|
||||
public static class V1_9 {
|
||||
|
||||
static final Class<?> DataWatcherItem = nmsClassResolver.resolveSilent("DataWatcher$Item");//>= 1.9 only
|
||||
static final Class<?> DataWatcherObject = nmsClassResolver.resolveSilent("DataWatcherObject");//>= 1.9 only
|
||||
|
||||
static ConstructorResolver DataWatcherItemConstructorResolver;//>=1.9 only
|
||||
|
||||
static FieldResolver DataWatcherItemFieldResolver;//>=1.9 only
|
||||
static FieldResolver DataWatcherObjectFieldResolver;//>=1.9 only
|
||||
|
||||
public static Object newDataWatcherItem(Object dataWatcherObject, Object value) throws ReflectiveOperationException {
|
||||
if (DataWatcherItemConstructorResolver == null) {
|
||||
DataWatcherItemConstructorResolver = new ConstructorResolver(DataWatcherItem);
|
||||
}
|
||||
return DataWatcherItemConstructorResolver.resolveFirstConstructor().newInstance(dataWatcherObject, value);
|
||||
}
|
||||
|
||||
public static Object setItem(Object dataWatcher, int index, Object dataWatcherObject, Object value) throws ReflectiveOperationException {
|
||||
return setItem(dataWatcher, index, newDataWatcherItem(dataWatcherObject, value));
|
||||
}
|
||||
|
||||
public static Object setItem(Object dataWatcher, int index, Object dataWatcherItem) throws ReflectiveOperationException {
|
||||
Map<Integer, Object> map = (Map<Integer, Object>) DataWatcherFieldResolver.resolveByLastTypeSilent(Map.class).get(dataWatcher);
|
||||
map.put(index, dataWatcherItem);
|
||||
return dataWatcher;
|
||||
}
|
||||
|
||||
public static Object setValue(Object dataWatcher, Object dataWatcherObject, Object value) throws ReflectiveOperationException {
|
||||
DataWatcherMethodResolver.resolve("set").invoke(dataWatcher, dataWatcherObject, value);
|
||||
return dataWatcher;
|
||||
}
|
||||
|
||||
// public static Object getValue(Object dataWatcher, int index) throws ReflectiveOperationException {
|
||||
// Map<Integer, Object> map = (Map<Integer, Object>) DataWatcherFieldResolver.resolve("c").get(dataWatcher);
|
||||
// return map.get(index);
|
||||
// }
|
||||
|
||||
public static Object getItem(Object dataWatcher, Object dataWatcherObject) throws ReflectiveOperationException {
|
||||
return DataWatcherMethodResolver.resolve(new ResolverQuery("c", DataWatcherObject)).invoke(dataWatcher, dataWatcherObject);
|
||||
}
|
||||
|
||||
public static Object getValue(Object dataWatcher, Object dataWatcherObject) throws ReflectiveOperationException {
|
||||
return DataWatcherMethodResolver.resolve("get").invoke(dataWatcher, dataWatcherObject);
|
||||
}
|
||||
|
||||
public static Object getValue(Object dataWatcher, ValueType type) throws ReflectiveOperationException {
|
||||
return getValue(dataWatcher, type.getType());
|
||||
}
|
||||
|
||||
public static Object getItemObject(Object item) throws ReflectiveOperationException {
|
||||
if (DataWatcherItemFieldResolver == null) {
|
||||
DataWatcherItemFieldResolver = new FieldResolver(DataWatcherItem);
|
||||
}
|
||||
return DataWatcherItemFieldResolver.resolve("a").get(item);
|
||||
}
|
||||
|
||||
public static int getItemIndex(Object dataWatcher, Object item) throws ReflectiveOperationException {
|
||||
int index = -1;//Return -1 if the item is not in the DataWatcher
|
||||
Map<Integer, Object> map = (Map<Integer, Object>) DataWatcherFieldResolver.resolveByLastTypeSilent(Map.class).get(dataWatcher);
|
||||
for (Map.Entry<Integer, Object> entry : map.entrySet()) {
|
||||
if (entry.getValue().equals(item)) {
|
||||
index = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public static Type getItemType(Object item) throws ReflectiveOperationException {
|
||||
if (DataWatcherObjectFieldResolver == null) {
|
||||
DataWatcherObjectFieldResolver = new FieldResolver(DataWatcherObject);
|
||||
}
|
||||
Object object = getItemObject(item);
|
||||
Object serializer = DataWatcherObjectFieldResolver.resolve("b").get(object);
|
||||
Type[] genericInterfaces = serializer.getClass().getGenericInterfaces();
|
||||
if (genericInterfaces.length > 0) {
|
||||
Type type = genericInterfaces[0];
|
||||
if (type instanceof ParameterizedType) {
|
||||
Type[] actualTypes = ((ParameterizedType) type).getActualTypeArguments();
|
||||
if (actualTypes.length > 0) {
|
||||
return actualTypes[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getItemValue(Object item) throws ReflectiveOperationException {
|
||||
if (DataWatcherItemFieldResolver == null) {
|
||||
DataWatcherItemFieldResolver = new FieldResolver(DataWatcherItem);
|
||||
}
|
||||
return DataWatcherItemFieldResolver.resolve("b").get(item);
|
||||
}
|
||||
|
||||
public static void setItemValue(Object item, Object value) throws ReflectiveOperationException {
|
||||
DataWatcherItemFieldResolver.resolve("b").set(item, value);
|
||||
}
|
||||
|
||||
public enum ValueType {
|
||||
|
||||
/**
|
||||
* Byte
|
||||
*/
|
||||
ENTITY_FLAG("Entity", 57, 0 /*"ax", "ay"*/),
|
||||
/**
|
||||
* Integer
|
||||
*/
|
||||
ENTITY_AIR_TICKS("Entity", 58, 1/*"ay", "az"*/),
|
||||
/**
|
||||
* String
|
||||
*/
|
||||
ENTITY_NAME("Entity", 59, 2/*"az", "aA"*/),
|
||||
/**
|
||||
* Byte < 1.9 Boolean > 1.9
|
||||
*/
|
||||
ENTITY_NAME_VISIBLE("Entity", 60, 3/*"aA", "aB"*/),
|
||||
/**
|
||||
* Boolean
|
||||
*/
|
||||
ENTITY_SILENT("Entity", 61, 4/*"aB", "aC"*/),
|
||||
|
||||
//////////
|
||||
|
||||
//TODO: Add EntityLiving#as (Byte)
|
||||
ENTITY_as("EntityLiving", 2, 0/* "as", "at"*/),
|
||||
|
||||
/**
|
||||
* Float
|
||||
*/
|
||||
ENTITY_LIVING_HEALTH("EntityLiving", "HEALTH"),
|
||||
|
||||
//TODO: Add EntityLiving#f (Integer) - Maybe active potions?
|
||||
ENTITY_LIVING_f("EntityLiving", 4, 2/*"f"*/),
|
||||
|
||||
//TODO: Add EntityLiving#g (Boolean) - Maybe ambient potions?
|
||||
ENTITY_LIVING_g("EntityLiving", 5, 3/*"g"*/),
|
||||
|
||||
//TODO: Add EntityLiving#h (Integer)
|
||||
ENTITY_LIVING_h("EntityLiving", 6, 4/*"h"*/),
|
||||
|
||||
//////////
|
||||
|
||||
/**
|
||||
* Byte
|
||||
*/
|
||||
ENTITY_INSENTIENT_FLAG("EntityInsentient", 0, 0/* "a"*/),
|
||||
|
||||
///////////
|
||||
|
||||
/**
|
||||
* Integer
|
||||
*/
|
||||
ENTITY_SLIME_SIZE("EntitySlime", 0, 0/* "bt", "bu"*/),
|
||||
|
||||
/////////////
|
||||
|
||||
//TODO: Add EntityWither#a (Integer)
|
||||
ENTITY_WITHER_a("EntityWither", 0, 0/*"a"*/),
|
||||
|
||||
//TODO: Add EntityWither#b (Integer)
|
||||
ENTITY_WIHER_b("EntityWither", 1, 1/*"b"*/),
|
||||
|
||||
//TODO: Add EntityWither#c (Integer)
|
||||
ENTITY_WITHER_c("EntityWither", 2, 2/*"c"*/),
|
||||
|
||||
//TODO: Add EntityWither#bv (Integer) - (DataWatcherObject<Integer>[] bv, seems to be an array of {a, b, c})
|
||||
ENTITY_WITHER_bv("EntityWither", 3, 3/*"bv", "bw"*/),
|
||||
|
||||
//TODO: Add EntityWither#bw (Integer)
|
||||
ENTITY_WITHER_bw("EntityWither", 4, 4/*"bw", "bx"*/),
|
||||
|
||||
//////////
|
||||
|
||||
ENTITY_AGEABLE_CHILD("EntityAgeable", 0, 0),
|
||||
|
||||
///////////
|
||||
|
||||
ENTITY_HORSE_STATUS("EntityHorse", 3, 0),
|
||||
ENTITY_HORSE_HORSE_TYPE("EntityHorse", 4, 1),
|
||||
ENTITY_HORSE_HORSE_VARIANT("EntityHorse", 5, 2),
|
||||
ENTITY_HORSE_OWNER_UUID("EntityHorse", 6, 3),
|
||||
ENTITY_HORSE_HORSE_ARMOR("EntityHorse", 7, 4),
|
||||
|
||||
/////////
|
||||
|
||||
|
||||
/**
|
||||
* Float
|
||||
*/
|
||||
ENTITY_HUMAN_ABSORPTION_HEARTS("EntityHuman", 0, 0 /*"a"*/),
|
||||
|
||||
/**
|
||||
* Integer
|
||||
*/
|
||||
ENTITY_HUMAN_SCORE("EntityHuman", 1, 1 /*"b"*/),
|
||||
|
||||
/**
|
||||
* Byte
|
||||
*/
|
||||
ENTITY_HUMAN_SKIN_LAYERS("EntityHuman", 2, 2 /*"bp", "bq"*/),
|
||||
|
||||
/**
|
||||
* Byte (0 = left, 1 = right)
|
||||
*/
|
||||
ENTITY_HUMAN_MAIN_HAND("EntityHuman", 3, 3/*"bq", "br"*/);
|
||||
|
||||
private Object type;
|
||||
|
||||
ValueType(String className, String... fieldNames) {
|
||||
try {
|
||||
this.type = new FieldResolver(nmsClassResolver.resolve(className)).resolve(fieldNames).get(null);
|
||||
} catch (Exception e) {
|
||||
if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1)) {
|
||||
System.err.println("[ReflectionHelper] Failed to find DataWatcherObject for " + className + " " + Arrays.toString(fieldNames));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ValueType(String className, int index) {
|
||||
try {
|
||||
this.type = new FieldResolver(nmsClassResolver.resolve(className)).resolveIndex(index).get(null);
|
||||
} catch (Exception e) {
|
||||
if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1)) {
|
||||
System.err.println("[ReflectionHelper] Failed to find DataWatcherObject for " + className + " #" + index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ValueType(String className, int index, int offset) {
|
||||
int firstObject = 0;
|
||||
try {
|
||||
Class<?> clazz = nmsClassResolver.resolve(className);
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
if ("DataWatcherObject".equals(field.getType().getSimpleName())) {
|
||||
break;
|
||||
}
|
||||
firstObject++;
|
||||
}
|
||||
this.type = new FieldResolver(clazz).resolveIndex(firstObject + offset).get(null);
|
||||
} catch (Exception e) {
|
||||
if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1)) {
|
||||
System.err.println("[ReflectionHelper] Failed to find DataWatcherObject for " + className + " #" + index + " (" + firstObject + "+" + offset + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasType() {
|
||||
return getType() != null;
|
||||
}
|
||||
|
||||
public Object getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class for versions older than 1.8
|
||||
*/
|
||||
public static class V1_8 {
|
||||
|
||||
static final Class<?> WatchableObject = nmsClassResolver.resolveSilent("WatchableObject", "DataWatcher$WatchableObject");//<=1.8 only
|
||||
|
||||
static ConstructorResolver WatchableObjectConstructorResolver;//<=1.8 only
|
||||
|
||||
static FieldResolver WatchableObjectFieldResolver;//<=1.8 only
|
||||
|
||||
public static Object newWatchableObject(int index, Object value) throws ReflectiveOperationException {
|
||||
return newWatchableObject(getValueType(value), index, value);
|
||||
}
|
||||
|
||||
public static Object newWatchableObject(int type, int index, Object value) throws ReflectiveOperationException {
|
||||
if (WatchableObjectConstructorResolver == null) {
|
||||
WatchableObjectConstructorResolver = new ConstructorResolver(WatchableObject);
|
||||
}
|
||||
return WatchableObjectConstructorResolver.resolve(new Class[]{
|
||||
int.class,
|
||||
int.class,
|
||||
Object.class}).newInstance(type, index, value);
|
||||
}
|
||||
|
||||
public static Object setValue(Object dataWatcher, int index, Object value) throws ReflectiveOperationException {
|
||||
int type = getValueType(value);
|
||||
|
||||
Map map = (Map) DataWatcherFieldResolver.resolveByLastType(Map.class).get(dataWatcher);
|
||||
map.put(index, newWatchableObject(type, index, value));
|
||||
|
||||
return dataWatcher;
|
||||
}
|
||||
|
||||
public static Object getValue(Object dataWatcher, int index) throws ReflectiveOperationException {
|
||||
Map map = (Map) DataWatcherFieldResolver.resolveByLastType(Map.class).get(dataWatcher);
|
||||
|
||||
return map.get(index);
|
||||
}
|
||||
|
||||
public static int getWatchableObjectIndex(Object object) throws ReflectiveOperationException {
|
||||
if (WatchableObjectFieldResolver == null) {
|
||||
WatchableObjectFieldResolver = new FieldResolver(WatchableObject);
|
||||
}
|
||||
return WatchableObjectFieldResolver.resolve("b").getInt(object);
|
||||
}
|
||||
|
||||
public static int getWatchableObjectType(Object object) throws ReflectiveOperationException {
|
||||
if (WatchableObjectFieldResolver == null) {
|
||||
WatchableObjectFieldResolver = new FieldResolver(WatchableObject);
|
||||
}
|
||||
return WatchableObjectFieldResolver.resolve("a").getInt(object);
|
||||
}
|
||||
|
||||
public static Object getWatchableObjectValue(Object object) throws ReflectiveOperationException {
|
||||
if (WatchableObjectFieldResolver == null) {
|
||||
WatchableObjectFieldResolver = new FieldResolver(WatchableObject);
|
||||
}
|
||||
return WatchableObjectFieldResolver.resolve("c").get(object);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,228 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.ConstructorResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.FieldResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.MethodResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.minecraft.NMSClassResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.minecraft.OBCClassResolver;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.util.AccessUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import sun.reflect.ConstructorAccessor;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Helper class to access minecraft/bukkit specific objects
|
||||
*/
|
||||
public class Minecraft {
|
||||
public static final Version VERSION;
|
||||
static final Pattern NUMERIC_VERSION_PATTERN = Pattern.compile("v(\\d)_(\\d*)_R(\\d)");
|
||||
private static final NMSClassResolver nmsClassResolver = new NMSClassResolver();
|
||||
private static final OBCClassResolver obcClassResolver = new OBCClassResolver();
|
||||
private static final Class<?> NmsEntity;
|
||||
private static final Class<?> CraftEntity;
|
||||
|
||||
static {
|
||||
VERSION = Version.getVersion();
|
||||
try {
|
||||
NmsEntity = nmsClassResolver.resolve("Entity");
|
||||
CraftEntity = obcClassResolver.resolve("entity.CraftEntity");
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current NMS/OBC version (format <code><version>.</code>
|
||||
*/
|
||||
public static String getVersion() {
|
||||
return VERSION.name() + ".";
|
||||
}
|
||||
|
||||
public static Object getHandle(Object object) throws ReflectiveOperationException {
|
||||
Method method;
|
||||
try {
|
||||
method = AccessUtil.setAccessible(object.getClass().getDeclaredMethod("getHandle"));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
method = AccessUtil.setAccessible(CraftEntity.getDeclaredMethod("getHandle"));
|
||||
}
|
||||
return method.invoke(object);
|
||||
}
|
||||
|
||||
public static Entity getBukkitEntity(Object object) throws ReflectiveOperationException {
|
||||
Method method;
|
||||
try {
|
||||
method = AccessUtil.setAccessible(NmsEntity.getDeclaredMethod("getBukkitEntity"));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
method = AccessUtil.setAccessible(CraftEntity.getDeclaredMethod("getHandle"));
|
||||
}
|
||||
return (Entity) method.invoke(object);
|
||||
}
|
||||
|
||||
public static Object getHandleSilent(Object object) {
|
||||
try {
|
||||
return getHandle(object);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object newEnumInstance(Class clazz, Class[] types, Object[] values) throws ReflectiveOperationException {
|
||||
Constructor constructor = new ConstructorResolver(clazz).resolve(types);
|
||||
Field accessorField = new FieldResolver(Constructor.class).resolve("constructorAccessor");
|
||||
ConstructorAccessor constructorAccessor = (ConstructorAccessor) accessorField.get(constructor);
|
||||
if (constructorAccessor == null) {
|
||||
new MethodResolver(Constructor.class).resolve("acquireConstructorAccessor").invoke(constructor);
|
||||
constructorAccessor = (ConstructorAccessor) accessorField.get(constructor);
|
||||
}
|
||||
return constructorAccessor.newInstance(values);
|
||||
|
||||
}
|
||||
|
||||
public enum Version {
|
||||
UNKNOWN(-1) {
|
||||
@Override
|
||||
public boolean matchesPackageName(String packageName) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
v1_7_R1(10701),
|
||||
v1_7_R2(10702),
|
||||
v1_7_R3(10703),
|
||||
v1_7_R4(10704),
|
||||
|
||||
v1_8_R1(10801),
|
||||
v1_8_R2(10802),
|
||||
v1_8_R3(10803),
|
||||
//Does this even exists?
|
||||
v1_8_R4(10804),
|
||||
|
||||
v1_9_R1(10901),
|
||||
v1_9_R2(10902),
|
||||
|
||||
v1_10_R1(11001),
|
||||
|
||||
v1_11_R1(11101),
|
||||
|
||||
v1_12_R1(11201),
|
||||
|
||||
v1_13_R1(11301),
|
||||
v1_13_R2(11302),
|
||||
|
||||
v1_14_R1(11401);
|
||||
|
||||
private final int version;
|
||||
|
||||
Version(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public static Version getVersion() {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
String versionPackage = name.substring(name.lastIndexOf('.') + 1) + ".";
|
||||
for (Version version : values()) {
|
||||
if (version.matchesPackageName(versionPackage)) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
System.err.println("[ReflectionHelper] Failed to find version enum for '" + name + "'/'" + versionPackage + "'");
|
||||
|
||||
System.out.println("[ReflectionHelper] Generating dynamic constant...");
|
||||
Matcher matcher = NUMERIC_VERSION_PATTERN.matcher(versionPackage);
|
||||
while (matcher.find()) {
|
||||
if (matcher.groupCount() < 3) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String majorString = matcher.group(1);
|
||||
String minorString = matcher.group(2);
|
||||
if (minorString.length() == 1) {
|
||||
minorString = "0" + minorString;
|
||||
}
|
||||
String patchString = matcher.group(3);
|
||||
if (patchString.length() == 1) {
|
||||
patchString = "0" + patchString;
|
||||
}
|
||||
|
||||
String numVersionString = majorString + minorString + patchString;
|
||||
int numVersion = Integer.parseInt(numVersionString);
|
||||
String packge = versionPackage.substring(0, versionPackage.length() - 1);
|
||||
|
||||
try {
|
||||
// Add enum value
|
||||
Field valuesField = new FieldResolver(Version.class).resolve("$VALUES");
|
||||
Version[] oldValues = (Version[]) valuesField.get(null);
|
||||
Version[] newValues = new Version[oldValues.length + 1];
|
||||
System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
|
||||
Version dynamicVersion = (Version) newEnumInstance(Version.class, new Class[]{
|
||||
String.class,
|
||||
int.class,
|
||||
int.class
|
||||
}, new Object[]{
|
||||
packge,
|
||||
newValues.length - 1,
|
||||
numVersion
|
||||
});
|
||||
newValues[newValues.length - 1] = dynamicVersion;
|
||||
valuesField.set(null, newValues);
|
||||
|
||||
System.out.println("[ReflectionHelper] Injected dynamic version " + packge + " (#" + numVersion + ").");
|
||||
System.out.println("[ReflectionHelper] Please inform inventivegames about the outdated version, as this is not guaranteed to work.");
|
||||
return dynamicVersion;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the version-number
|
||||
*/
|
||||
public int version() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param version the version to check
|
||||
* @return <code>true</code> if this version is older than the specified version
|
||||
*/
|
||||
public boolean olderThan(Version version) {
|
||||
return version() < version.version();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param version the version to check
|
||||
* @return <code>true</code> if this version is newer than the specified version
|
||||
*/
|
||||
public boolean newerThan(Version version) {
|
||||
return version() >= version.version();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param oldVersion The older version to check
|
||||
* @param newVersion The newer version to check
|
||||
* @return <code>true</code> if this version is newer than the oldVersion and older that the newVersion
|
||||
*/
|
||||
public boolean inRange(Version oldVersion, Version newVersion) {
|
||||
return newerThan(oldVersion) && olderThan(newVersion);
|
||||
}
|
||||
|
||||
public boolean matchesPackageName(String packageName) {
|
||||
return packageName.toLowerCase().contains(name().toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name() + " (" + version() + ")";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper.ClassWrapper;
|
||||
|
||||
/**
|
||||
* Default {@link ClassResolver}
|
||||
*/
|
||||
public class ClassResolver extends ResolverAbstract<Class> {
|
||||
|
||||
public ClassWrapper resolveWrapper(String... names) {
|
||||
return new ClassWrapper<>(resolveSilent(names));
|
||||
}
|
||||
|
||||
public Class resolveSilent(String... names) {
|
||||
try {
|
||||
return resolve(names);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Class resolve(String... names) throws ClassNotFoundException {
|
||||
ResolverQuery.Builder builder = ResolverQuery.builder();
|
||||
for (String name : names)
|
||||
builder.with(name);
|
||||
try {
|
||||
return super.resolve(builder.build());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw (ClassNotFoundException) e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class resolveObject(ResolverQuery query) throws ReflectiveOperationException {
|
||||
return Class.forName(query.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassNotFoundException notFoundException(String joinedNames) {
|
||||
return new ClassNotFoundException("Could not resolve class for " + joinedNames);
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper.ConstructorWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.util.AccessUtil;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
/**
|
||||
* Resolver for constructors
|
||||
*/
|
||||
public class ConstructorResolver extends MemberResolver<Constructor> {
|
||||
|
||||
public ConstructorResolver(Class<?> clazz) {
|
||||
super(clazz);
|
||||
}
|
||||
|
||||
public ConstructorResolver(String className) throws ClassNotFoundException {
|
||||
super(className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Constructor resolveIndex(int index) throws IndexOutOfBoundsException, ReflectiveOperationException {
|
||||
return AccessUtil.setAccessible(this.clazz.getDeclaredConstructors()[index]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Constructor resolveIndexSilent(int index) {
|
||||
try {
|
||||
return resolveIndex(index);
|
||||
} catch (IndexOutOfBoundsException | ReflectiveOperationException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorWrapper resolveIndexWrapper(int index) {
|
||||
return new ConstructorWrapper<>(resolveIndexSilent(index));
|
||||
}
|
||||
|
||||
public ConstructorWrapper resolveWrapper(Class<?>[]... types) {
|
||||
return new ConstructorWrapper<>(resolveSilent(types));
|
||||
}
|
||||
|
||||
public Constructor resolveSilent(Class<?>[]... types) {
|
||||
try {
|
||||
return resolve(types);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Constructor resolve(Class<?>[]... types) throws NoSuchMethodException {
|
||||
ResolverQuery.Builder builder = ResolverQuery.builder();
|
||||
for (Class<?>[] type : types)
|
||||
builder.with(type);
|
||||
try {
|
||||
return super.resolve(builder.build());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw (NoSuchMethodException) e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Constructor resolveObject(ResolverQuery query) throws ReflectiveOperationException {
|
||||
return AccessUtil.setAccessible(this.clazz.getDeclaredConstructor(query.getTypes()));
|
||||
}
|
||||
|
||||
public Constructor resolveFirstConstructor() throws ReflectiveOperationException {
|
||||
for (Constructor constructor : this.clazz.getDeclaredConstructors()) {
|
||||
return AccessUtil.setAccessible(constructor);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Constructor resolveFirstConstructorSilent() {
|
||||
try {
|
||||
return resolveFirstConstructor();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Constructor resolveLastConstructor() throws ReflectiveOperationException {
|
||||
Constructor constructor = null;
|
||||
for (Constructor constructor1 : this.clazz.getDeclaredConstructors()) {
|
||||
constructor = constructor1;
|
||||
}
|
||||
if (constructor != null) {
|
||||
return AccessUtil.setAccessible(constructor);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Constructor resolveLastConstructorSilent() {
|
||||
try {
|
||||
return resolveLastConstructor();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NoSuchMethodException notFoundException(String joinedNames) {
|
||||
return new NoSuchMethodException("Could not resolve constructor for " + joinedNames + " in class " + this.clazz);
|
||||
}
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper.FieldWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.util.AccessUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Resolver for fields
|
||||
*/
|
||||
public class FieldResolver extends MemberResolver<Field> {
|
||||
|
||||
public FieldResolver(Class<?> clazz) {
|
||||
super(clazz);
|
||||
}
|
||||
|
||||
public FieldResolver(String className) throws ClassNotFoundException {
|
||||
super(className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field resolveIndex(int index) throws IndexOutOfBoundsException, ReflectiveOperationException {
|
||||
return AccessUtil.setAccessible(this.clazz.getDeclaredFields()[index]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field resolveIndexSilent(int index) {
|
||||
try {
|
||||
return resolveIndex(index);
|
||||
} catch (IndexOutOfBoundsException | ReflectiveOperationException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldWrapper resolveIndexWrapper(int index) {
|
||||
return new FieldWrapper<>(resolveIndexSilent(index));
|
||||
}
|
||||
|
||||
public FieldWrapper resolveWrapper(String... names) {
|
||||
return new FieldWrapper<>(resolveSilent(names));
|
||||
}
|
||||
|
||||
public Field resolveSilent(String... names) {
|
||||
try {
|
||||
return resolve(names);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Field resolve(String... names) throws NoSuchFieldException {
|
||||
ResolverQuery.Builder builder = ResolverQuery.builder();
|
||||
for (String name : names)
|
||||
builder.with(name);
|
||||
try {
|
||||
return super.resolve(builder.build());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw (NoSuchFieldException) e;
|
||||
}
|
||||
}
|
||||
|
||||
public Field resolveSilent(ResolverQuery... queries) {
|
||||
try {
|
||||
return resolve(queries);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Field resolve(ResolverQuery... queries) throws NoSuchFieldException {
|
||||
try {
|
||||
return super.resolve(queries);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw (NoSuchFieldException) e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Field resolveObject(ResolverQuery query) throws ReflectiveOperationException {
|
||||
if (query.getTypes() == null || query.getTypes().length == 0) {
|
||||
return AccessUtil.setAccessible(this.clazz.getDeclaredField(query.getName()));
|
||||
} else {
|
||||
for (Field field : this.clazz.getDeclaredFields()) {
|
||||
if (field.getName().equals(query.getName())) {
|
||||
for (Class type : query.getTypes()) {
|
||||
if (field.getType().equals(type)) {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find the first field of the specified type
|
||||
*
|
||||
* @param type Type to find
|
||||
* @return the Field
|
||||
* @throws ReflectiveOperationException (usually never)
|
||||
* @see #resolveByLastType(Class)
|
||||
*/
|
||||
public Field resolveByFirstType(Class<?> type) throws ReflectiveOperationException {
|
||||
for (Field field : this.clazz.getDeclaredFields()) {
|
||||
if (field.getType().equals(type)) {
|
||||
return AccessUtil.setAccessible(field);
|
||||
}
|
||||
}
|
||||
throw new NoSuchFieldException("Could not resolve field of type '" + type.toString() + "' in class " + this.clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find the first field of the specified type
|
||||
*
|
||||
* @param type Type to find
|
||||
* @return the Field
|
||||
* @see #resolveByLastTypeSilent(Class)
|
||||
*/
|
||||
public Field resolveByFirstTypeSilent(Class<?> type) {
|
||||
try {
|
||||
return resolveByFirstType(type);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find the last field of the specified type
|
||||
*
|
||||
* @param type Type to find
|
||||
* @return the Field
|
||||
* @throws ReflectiveOperationException (usually never)
|
||||
* @see #resolveByFirstType(Class)
|
||||
*/
|
||||
public Field resolveByLastType(Class<?> type) throws ReflectiveOperationException {
|
||||
Field field = null;
|
||||
for (Field field1 : this.clazz.getDeclaredFields()) {
|
||||
if (field1.getType().equals(type)) {
|
||||
field = field1;
|
||||
}
|
||||
}
|
||||
if (field == null) {
|
||||
throw new NoSuchFieldException("Could not resolve field of type '" + type.toString() + "' in class " + this.clazz);
|
||||
}
|
||||
return AccessUtil.setAccessible(field);
|
||||
}
|
||||
|
||||
public Field resolveByLastTypeSilent(Class<?> type) {
|
||||
try {
|
||||
return resolveByLastType(type);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NoSuchFieldException notFoundException(String joinedNames) {
|
||||
return new NoSuchFieldException("Could not resolve field for " + joinedNames + " in class " + this.clazz);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper.WrapperAbstract;
|
||||
|
||||
import java.lang.reflect.Member;
|
||||
|
||||
/**
|
||||
* abstract class to resolve members
|
||||
*
|
||||
* @param <T> member type
|
||||
* @see ConstructorResolver
|
||||
* @see FieldResolver
|
||||
* @see MethodResolver
|
||||
*/
|
||||
public abstract class MemberResolver<T extends Member> extends ResolverAbstract<T> {
|
||||
|
||||
protected Class<?> clazz;
|
||||
|
||||
public MemberResolver(Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
throw new IllegalArgumentException("class cannot be null");
|
||||
}
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public MemberResolver(String className) throws ClassNotFoundException {
|
||||
this(new ClassResolver().resolve(className));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a member by its index
|
||||
*
|
||||
* @param index index
|
||||
* @return the member
|
||||
* @throws IndexOutOfBoundsException if the specified index is out of the available member bounds
|
||||
* @throws ReflectiveOperationException if the object could not be set accessible
|
||||
*/
|
||||
public abstract T resolveIndex(int index) throws IndexOutOfBoundsException, ReflectiveOperationException;
|
||||
|
||||
/**
|
||||
* Resolve member by its index (without exceptions)
|
||||
*
|
||||
* @param index index
|
||||
* @return the member or <code>null</code>
|
||||
*/
|
||||
public abstract T resolveIndexSilent(int index);
|
||||
|
||||
/**
|
||||
* Resolce member wrapper by its index
|
||||
*
|
||||
* @param index index
|
||||
* @return the wrapped member
|
||||
*/
|
||||
public abstract WrapperAbstract resolveIndexWrapper(int index);
|
||||
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper.MethodWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.util.AccessUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Resolver for methods
|
||||
*/
|
||||
public class MethodResolver extends MemberResolver<Method> {
|
||||
|
||||
public MethodResolver(Class<?> clazz) {
|
||||
super(clazz);
|
||||
}
|
||||
|
||||
public MethodResolver(String className) throws ClassNotFoundException {
|
||||
super(className);
|
||||
}
|
||||
|
||||
static boolean ClassListEqual(Class<?>[] l1, Class<?>[] l2) {
|
||||
boolean equal = true;
|
||||
if (l1.length != l2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < l1.length; i++) {
|
||||
if (l1[i] != l2[i]) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
|
||||
public Method resolveSignature(String... signatures) throws ReflectiveOperationException {
|
||||
for (Method method : clazz.getDeclaredMethods()) {
|
||||
String methodSignature = MethodWrapper.getMethodSignature(method);
|
||||
for (String s : signatures) {
|
||||
if (s.equals(methodSignature)) {
|
||||
return AccessUtil.setAccessible(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Method resolveSignatureSilent(String... signatures) {
|
||||
try {
|
||||
return resolveSignature(signatures);
|
||||
} catch (ReflectiveOperationException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public MethodWrapper resolveSignatureWrapper(String... signatures) {
|
||||
return new MethodWrapper(resolveSignatureSilent(signatures));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method resolveIndex(int index) throws IndexOutOfBoundsException, ReflectiveOperationException {
|
||||
return AccessUtil.setAccessible(this.clazz.getDeclaredMethods()[index]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method resolveIndexSilent(int index) {
|
||||
try {
|
||||
return resolveIndex(index);
|
||||
} catch (IndexOutOfBoundsException | ReflectiveOperationException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodWrapper resolveIndexWrapper(int index) {
|
||||
return new MethodWrapper<>(resolveIndexSilent(index));
|
||||
}
|
||||
|
||||
public MethodWrapper resolveWrapper(String... names) {
|
||||
return new MethodWrapper<>(resolveSilent(names));
|
||||
}
|
||||
|
||||
public MethodWrapper resolveWrapper(ResolverQuery... queries) {
|
||||
return new MethodWrapper<>(resolveSilent(queries));
|
||||
}
|
||||
|
||||
public Method resolveSilent(String... names) {
|
||||
try {
|
||||
return resolve(names);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method resolveSilent(ResolverQuery... queries) {
|
||||
return super.resolveSilent(queries);
|
||||
}
|
||||
|
||||
public Method resolve(String... names) throws NoSuchMethodException {
|
||||
ResolverQuery.Builder builder = ResolverQuery.builder();
|
||||
for (String name : names) {
|
||||
builder.with(name);
|
||||
}
|
||||
return resolve(builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Method resolve(ResolverQuery... queries) throws NoSuchMethodException {
|
||||
try {
|
||||
return super.resolve(queries);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw (NoSuchMethodException) e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Method resolveObject(ResolverQuery query) throws ReflectiveOperationException {
|
||||
for (Method method : this.clazz.getDeclaredMethods()) {
|
||||
if (method.getName().equals(query.getName()) && (query.getTypes().length == 0 || ClassListEqual(query.getTypes(), method.getParameterTypes()))) {
|
||||
return AccessUtil.setAccessible(method);
|
||||
}
|
||||
}
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NoSuchMethodException notFoundException(String joinedNames) {
|
||||
return new NoSuchMethodException("Could not resolve method for " + joinedNames + " in class " + this.clazz);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Abstract resolver class
|
||||
*
|
||||
* @param <T> resolved type
|
||||
* @see ClassResolver
|
||||
* @see ConstructorResolver
|
||||
* @see FieldResolver
|
||||
* @see MethodResolver
|
||||
*/
|
||||
public abstract class ResolverAbstract<T> {
|
||||
|
||||
protected final Map<ResolverQuery, T> resolvedObjects = new ConcurrentHashMap<ResolverQuery, T>();
|
||||
|
||||
/**
|
||||
* Same as {@link #resolve(ResolverQuery...)} but throws no exceptions
|
||||
*
|
||||
* @param queries Array of possible queries
|
||||
* @return the resolved object if it was found, <code>null</code> otherwise
|
||||
*/
|
||||
protected T resolveSilent(ResolverQuery... queries) {
|
||||
try {
|
||||
return resolve(queries);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to resolve an array of possible queries to an object
|
||||
*
|
||||
* @param queries Array of possible queries
|
||||
* @return the resolved object (if it was found)
|
||||
* @throws ReflectiveOperationException if none of the possibilities could be resolved
|
||||
* @throws IllegalArgumentException if the given possibilities are empty
|
||||
*/
|
||||
protected T resolve(ResolverQuery... queries) throws ReflectiveOperationException {
|
||||
if (queries == null || queries.length <= 0) {
|
||||
throw new IllegalArgumentException("Given possibilities are empty");
|
||||
}
|
||||
for (ResolverQuery query : queries) {
|
||||
//Object is already resolved, return it directly
|
||||
if (resolvedObjects.containsKey(query)) {
|
||||
return resolvedObjects.get(query);
|
||||
}
|
||||
|
||||
//Object is not yet resolved, try to find it
|
||||
try {
|
||||
T resolved = resolveObject(query);
|
||||
//Store if it was found
|
||||
resolvedObjects.put(query, resolved);
|
||||
return resolved;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
//Not found, ignore the exception
|
||||
}
|
||||
}
|
||||
|
||||
//Couldn't find any of the possibilities
|
||||
throw notFoundException(Arrays.asList(queries).toString());
|
||||
}
|
||||
|
||||
protected abstract T resolveObject(ResolverQuery query) throws ReflectiveOperationException;
|
||||
|
||||
protected ReflectiveOperationException notFoundException(String joinedNames) {
|
||||
return new ReflectiveOperationException("Objects could not be resolved: " + joinedNames);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Container class for resolver-queries Used by {@link MethodResolver}
|
||||
*
|
||||
* @see org.inventivetalent.reflection.resolver.ResolverQuery.Builder
|
||||
*/
|
||||
public class ResolverQuery {
|
||||
|
||||
private String name;
|
||||
private final Class<?>[] types;
|
||||
|
||||
public ResolverQuery(String name, Class<?>... types) {
|
||||
this.name = name;
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public ResolverQuery(String name) {
|
||||
this.name = name;
|
||||
this.types = new Class[0];
|
||||
}
|
||||
|
||||
public ResolverQuery(Class<?>... types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Class<?>[] getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ResolverQuery that = (ResolverQuery) o;
|
||||
|
||||
if (name != null ? !name.equals(that.name) : that.name != null) {
|
||||
return false;
|
||||
}
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
return Arrays.equals(types, that.types);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = name != null ? name.hashCode() : 0;
|
||||
result = 31 * result + (types != null ? Arrays.hashCode(types) : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResolverQuery{" +
|
||||
"name='" + name + '\'' +
|
||||
", types=" + Arrays.toString(types) +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class for {@link ResolverQuery} Access using {@link ResolverQuery#builder()}
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private final List<ResolverQuery> queryList = new ArrayList<ResolverQuery>();
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
public Builder with(String name, Class<?>[] types) {
|
||||
queryList.add(new ResolverQuery(name, types));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder with(String name) {
|
||||
queryList.add(new ResolverQuery(name));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder with(Class<?>[] types) {
|
||||
queryList.add(new ResolverQuery(types));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResolverQuery[] build() {
|
||||
return queryList.toArray(new ResolverQuery[0]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.minecraft;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.ClassResolver;
|
||||
|
||||
/**
|
||||
* {@link ClassResolver} for <code>net.minecraft.server.*</code> classes
|
||||
*/
|
||||
public class NMSClassResolver extends ClassResolver {
|
||||
|
||||
@Override
|
||||
public Class resolve(String... names) throws ClassNotFoundException {
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
if (!names[i].startsWith("net.minecraft.server")) {
|
||||
names[i] = "net.minecraft.server." + Minecraft.getVersion() + names[i];
|
||||
}
|
||||
}
|
||||
return super.resolve(names);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.minecraft;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.minecraft.Minecraft;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.ClassResolver;
|
||||
|
||||
/**
|
||||
* {@link ClassResolver} for <code>org.bukkit.craftbukkit.*</code> classes
|
||||
*/
|
||||
public class OBCClassResolver extends ClassResolver {
|
||||
|
||||
@Override
|
||||
public Class resolve(String... names) throws ClassNotFoundException {
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
if (!names[i].startsWith("org.bukkit.craftbukkit")) {
|
||||
names[i] = "org.bukkit.craftbukkit." + Minecraft.getVersion() + names[i];
|
||||
}
|
||||
}
|
||||
return super.resolve(names);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper;
|
||||
|
||||
public class ClassWrapper<R> extends WrapperAbstract {
|
||||
|
||||
private final Class<R> clazz;
|
||||
|
||||
public ClassWrapper(Class<R> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return this.clazz != null;
|
||||
}
|
||||
|
||||
public Class<R> getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.clazz.getName();
|
||||
}
|
||||
|
||||
public R newInstance() {
|
||||
try {
|
||||
return this.clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public R newInstanceSilent() {
|
||||
try {
|
||||
return this.clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object == null || getClass() != object.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ClassWrapper<?> that = (ClassWrapper<?>) object;
|
||||
|
||||
return clazz != null ? clazz.equals(that.clazz) : that.clazz == null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return clazz != null ? clazz.hashCode() : 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
public class ConstructorWrapper<R> extends WrapperAbstract {
|
||||
|
||||
private final Constructor<R> constructor;
|
||||
|
||||
public ConstructorWrapper(Constructor<R> constructor) {
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return this.constructor != null;
|
||||
}
|
||||
|
||||
public R newInstance(Object... args) {
|
||||
try {
|
||||
return this.constructor.newInstance(args);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public R newInstanceSilent(Object... args) {
|
||||
try {
|
||||
return this.constructor.newInstance(args);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Class<?>[] getParameterTypes() {
|
||||
return this.constructor.getParameterTypes();
|
||||
}
|
||||
|
||||
public Constructor<R> getConstructor() {
|
||||
return constructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object == null || getClass() != object.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ConstructorWrapper<?> that = (ConstructorWrapper<?>) object;
|
||||
|
||||
return constructor != null ? constructor.equals(that.constructor) : that.constructor == null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return constructor != null ? constructor.hashCode() : 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class FieldWrapper<R> extends WrapperAbstract {
|
||||
|
||||
private final Field field;
|
||||
|
||||
public FieldWrapper(Field field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return this.field != null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.field.getName();
|
||||
}
|
||||
|
||||
public R get(Object object) {
|
||||
try {
|
||||
return (R) this.field.get(object);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public R getSilent(Object object) {
|
||||
try {
|
||||
return (R) this.field.get(object);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void set(Object object, R value) {
|
||||
try {
|
||||
this.field.set(object, value);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSilent(Object object, R value) {
|
||||
try {
|
||||
this.field.set(object, value);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public Field getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object == null || getClass() != object.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldWrapper<?> that = (FieldWrapper<?>) object;
|
||||
|
||||
return field != null ? field.equals(that.field) : that.field == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return field != null ? field.hashCode() : 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,292 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class MethodWrapper<R> extends WrapperAbstract {
|
||||
|
||||
private final Method method;
|
||||
|
||||
public MethodWrapper(Method method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a method's signature.
|
||||
*
|
||||
* @param method the method to get the signature for
|
||||
* @param fullClassNames whether to use the full class name
|
||||
* @return the method's signature
|
||||
*/
|
||||
public static String getMethodSignature(Method method, boolean fullClassNames) {
|
||||
// StringBuilder stringBuilder = new StringBuilder();
|
||||
//
|
||||
// Class<?> returnType = method.getReturnType();
|
||||
// if (returnType.isPrimitive()) {
|
||||
// stringBuilder.append(returnType);
|
||||
// } else {
|
||||
// stringBuilder.append(fullClassNames ? returnType.getName() : returnType.getSimpleName());
|
||||
// }
|
||||
// stringBuilder.append(" ");
|
||||
// stringBuilder.append(method.getName());
|
||||
//
|
||||
// stringBuilder.append("(");
|
||||
//
|
||||
// boolean first = true;
|
||||
// for (Class clazz : method.getParameterTypes()) {
|
||||
// if (!first) { stringBuilder.append(","); }
|
||||
// stringBuilder.append(fullClassNames ? clazz.getName() : clazz.getSimpleName());
|
||||
// first = false;
|
||||
// }
|
||||
// return stringBuilder.append(")").toString();
|
||||
|
||||
return MethodSignature.of(method, fullClassNames).getSignature();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param method Method to get the signature for
|
||||
* @return the signature
|
||||
* @see #getMethodSignature(Method, boolean)
|
||||
*/
|
||||
public static String getMethodSignature(Method method) {
|
||||
return getMethodSignature(method, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return this.method != null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.method.getName();
|
||||
}
|
||||
|
||||
public R invoke(Object object, Object... args) {
|
||||
try {
|
||||
return (R) this.method.invoke(object, args);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public R invokeSilent(Object object, Object... args) {
|
||||
try {
|
||||
return (R) this.method.invoke(object, args);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object == null || getClass() != object.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MethodWrapper<?> that = (MethodWrapper<?>) object;
|
||||
|
||||
return method != null ? method.equals(that.method) : that.method == null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return method != null ? method.hashCode() : 0;
|
||||
}
|
||||
|
||||
public static class MethodSignature {
|
||||
static final Pattern SIGNATURE_STRING_PATTERN = Pattern.compile("(.+) (.*)\\((.*)\\)");
|
||||
|
||||
private final String returnType;
|
||||
private final Pattern returnTypePattern;
|
||||
private final String name;
|
||||
private final Pattern namePattern;
|
||||
private final String[] parameterTypes;
|
||||
private final String signature;
|
||||
|
||||
public MethodSignature(String returnType, String name, String[] parameterTypes) {
|
||||
this.returnType = returnType;
|
||||
this.returnTypePattern = Pattern.compile(returnType
|
||||
.replace("?", "\\w")
|
||||
.replace("*", "\\w*")
|
||||
.replace("[", "\\[")
|
||||
.replace("]", "\\]"));
|
||||
this.name = name;
|
||||
this.namePattern = Pattern.compile(name.replace("?", "\\w").replace("*", "\\w*"));
|
||||
this.parameterTypes = parameterTypes;
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(returnType).append(" ").append(name).append("(");
|
||||
boolean first = true;
|
||||
for (String parameterType : parameterTypes) {
|
||||
if (!first) {
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append(parameterType);
|
||||
first = false;
|
||||
}
|
||||
this.signature = builder.append(")").toString();
|
||||
}
|
||||
|
||||
public static MethodSignature of(Method method, boolean fullClassNames) {
|
||||
Class<?> returnType = method.getReturnType();
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
|
||||
String returnTypeString;
|
||||
if (returnType.isPrimitive()) {
|
||||
returnTypeString = returnType.toString();
|
||||
} else {
|
||||
returnTypeString = fullClassNames ? returnType.getName() : returnType.getSimpleName();
|
||||
}
|
||||
String methodName = method.getName();
|
||||
String[] parameterTypeStrings = new String[parameterTypes.length];
|
||||
for (int i = 0; i < parameterTypeStrings.length; i++) {
|
||||
if (parameterTypes[i].isPrimitive()) {
|
||||
parameterTypeStrings[i] = parameterTypes[i].toString();
|
||||
} else {
|
||||
parameterTypeStrings[i] = fullClassNames ? parameterTypes[i].getName() : parameterTypes[i].getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
return new MethodSignature(returnTypeString, methodName, parameterTypeStrings);
|
||||
}
|
||||
|
||||
public static MethodSignature fromString(String signatureString) {
|
||||
if (signatureString == null) {
|
||||
return null;
|
||||
}
|
||||
Matcher matcher = SIGNATURE_STRING_PATTERN.matcher(signatureString);
|
||||
if (matcher.find()) {
|
||||
if (matcher.groupCount() != 3) {
|
||||
throw new IllegalArgumentException("invalid signature");
|
||||
}
|
||||
return new MethodSignature(matcher.group(1), matcher.group(2), matcher.group(3).split(","));
|
||||
} else {
|
||||
throw new IllegalArgumentException("invalid signature");
|
||||
}
|
||||
}
|
||||
|
||||
public String getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public boolean isReturnTypeWildcard() {
|
||||
return "?".equals(returnType) || "*".equals(returnType);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isNameWildcard() {
|
||||
return "?".equals(name) || "*".equals(name);
|
||||
}
|
||||
|
||||
public String[] getParameterTypes() {
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
public String getParameterType(int index) throws IndexOutOfBoundsException {
|
||||
return parameterTypes[index];
|
||||
}
|
||||
|
||||
public boolean isParameterWildcard(int index) throws IndexOutOfBoundsException {
|
||||
return "?".equals(getParameterType(index)) || "*".equals(getParameterType(index));
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this signature matches another signature. Wildcards are checked in this signature, but not the other signature.
|
||||
*
|
||||
* @param other signature to check
|
||||
* @return whether the signatures match
|
||||
*/
|
||||
public boolean matches(MethodSignature other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (!returnType.equals(other.returnType)) {
|
||||
// if (!isReturnTypeWildcard()) { return false; }
|
||||
// }
|
||||
// if (!name.equals(other.name)) {
|
||||
// if (!isNameWildcard()) { return false; }
|
||||
// }
|
||||
// if (parameterTypes.length != other.parameterTypes.length) { return false; }
|
||||
// for (int i = 0; i < parameterTypes.length; i++) {
|
||||
// if (!getParameterType(i).equals(other.getParameterType(i))) {
|
||||
// if (!isParameterWildcard(i)) { return false; }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!returnTypePattern.matcher(other.returnType).matches()) {
|
||||
return false;
|
||||
}
|
||||
if (!namePattern.matcher(other.name).matches()) {
|
||||
return false;
|
||||
}
|
||||
if (parameterTypes.length != other.parameterTypes.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
if (!Pattern.compile(getParameterType(i).replace("?", "\\w").replace("*", "\\w*")).matcher(other.getParameterType(i)).matches()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MethodSignature signature1 = (MethodSignature) o;
|
||||
|
||||
if (!returnType.equals(signature1.returnType)) {
|
||||
return false;
|
||||
}
|
||||
if (!name.equals(signature1.name)) {
|
||||
return false;
|
||||
}
|
||||
// Probably incorrect - comparing Object[] arrays with Arrays.equals
|
||||
if (!Arrays.equals(parameterTypes, signature1.parameterTypes)) {
|
||||
return false;
|
||||
}
|
||||
return signature.equals(signature1.signature);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = returnType.hashCode();
|
||||
result = 31 * result + name.hashCode();
|
||||
result = 31 * result + Arrays.hashCode(parameterTypes);
|
||||
result = 31 * result + signature.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSignature();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.resolver.wrapper;
|
||||
|
||||
public abstract class WrapperAbstract {
|
||||
|
||||
/**
|
||||
* Check whether the wrapped object exists (i.e. is not null)
|
||||
*
|
||||
* @return <code>true</code> if the wrapped object exists
|
||||
*/
|
||||
public abstract boolean exists();
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.reflection.util;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Helper class to set fields, methods & constructors accessible
|
||||
*/
|
||||
public abstract class AccessUtil {
|
||||
|
||||
/**
|
||||
* Sets the field accessible and removes final modifiers
|
||||
*
|
||||
* @param field Field to set accessible
|
||||
* @return the Field
|
||||
* @throws ReflectiveOperationException (usually never)
|
||||
*/
|
||||
public static Field setAccessible(Field field) throws ReflectiveOperationException {
|
||||
field.setAccessible(true);
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, field.getModifiers() & 0xFFFFFFEF);
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the method accessible
|
||||
*
|
||||
* @param method Method to set accessible
|
||||
* @return the Method
|
||||
* @throws ReflectiveOperationException (usually never)
|
||||
*/
|
||||
public static Method setAccessible(Method method) throws ReflectiveOperationException {
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the constructor accessible
|
||||
*
|
||||
* @param constructor Constructor to set accessible
|
||||
* @return the Constructor
|
||||
* @throws ReflectiveOperationException (usually never)
|
||||
*/
|
||||
public static Constructor setAccessible(Constructor constructor) throws ReflectiveOperationException {
|
||||
constructor.setAccessible(true);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.touch;
|
||||
|
||||
public enum TouchAction {
|
||||
|
||||
RIGHT_CLICK,
|
||||
LEFT_CLICK,
|
||||
UNKNOWN;
|
||||
|
||||
public static TouchAction fromUseAction(Object useAction) {
|
||||
if (useAction == null) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
int i = ((Enum) useAction).ordinal();
|
||||
switch (i) {
|
||||
case 0:
|
||||
return RIGHT_CLICK;
|
||||
case 1:
|
||||
return LEFT_CLICK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.touch;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.Hologram;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface TouchHandler {
|
||||
|
||||
void onTouch(@Nonnull Hologram hologram, @Nonnull Player player, @Nonnull TouchAction action);
|
||||
|
||||
}
|
@ -0,0 +1,232 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.types;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsGeneral;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.Hologram;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.HologramAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.PlayerTop;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.view.ViewHandler;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.manager.configuration.PluginConfiguration;
|
||||
import com.br.guilhermematthew.nowly.commons.common.data.category.DataCategory;
|
||||
import com.br.guilhermematthew.nowly.commons.common.data.type.DataType;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
import com.br.guilhermematthew.nowly.commons.common.profile.GamingProfile;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class SimpleHologram {
|
||||
|
||||
private String name, display;
|
||||
private DataCategory dataCategory;
|
||||
private DataType dataType;
|
||||
private List<PlayerTop> topList;
|
||||
private final ViewHandler defaultViewHandler = (hologram, player, string) -> {
|
||||
int topId = Integer.parseInt(hologram.getName().replace("top", "").replace("-", "").replace(getName(), ""));
|
||||
|
||||
PlayerTop playerTop = getTopList().get(topId - 1);
|
||||
|
||||
return string.replace("%position%", "" + topId).replace("%playerName%", playerTop.getPlayerName()).replace("%value%", "" + playerTop.getValue());
|
||||
};
|
||||
private boolean created, updating;
|
||||
private Plugin instance;
|
||||
|
||||
public SimpleHologram(String name, String display, DataCategory dataCategory, DataType dataType, Plugin instance) {
|
||||
this.name = name;
|
||||
this.display = display;
|
||||
this.dataCategory = dataCategory;
|
||||
this.dataType = dataType;
|
||||
this.instance = instance;
|
||||
this.created = false;
|
||||
this.updating = false;
|
||||
this.topList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void create() {
|
||||
create("world");
|
||||
}
|
||||
|
||||
public void recreate() {
|
||||
if (isCreated()) {
|
||||
for (Hologram holograms : HologramAPI.getHolograms()) {
|
||||
String holoName = holograms.getName().toLowerCase();
|
||||
|
||||
if (holoName.equalsIgnoreCase("titulo-" + getName().toLowerCase())) {
|
||||
holograms.update();
|
||||
} else if ((holoName.startsWith("top")) && (holoName.contains(getName().toLowerCase())) && (holoName.contains("-"))) {
|
||||
holograms.update();
|
||||
} else if (holoName.contains("blank") && holoName.contains(getName().toLowerCase())) {
|
||||
holograms.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create();
|
||||
}
|
||||
|
||||
public void create(final String worldName) {
|
||||
if (isCreated()) return;
|
||||
|
||||
PluginConfiguration.createLocation(getInstance(), "hologramas." + getName().toLowerCase(), worldName);
|
||||
|
||||
Location location = PluginConfiguration.getLocation(getInstance(), "hologramas." + getName().toLowerCase());
|
||||
assert location != null;
|
||||
|
||||
World world = location.getWorld();
|
||||
|
||||
double y = location.getY();
|
||||
|
||||
Hologram title = HologramAPI.createHologram("titulo-" + getName().toLowerCase(), location,
|
||||
"§e§lTOP 10 §b§l" + getDisplay().toUpperCase() + "§7(1/1)");
|
||||
y = y -= 0.25;
|
||||
|
||||
title.spawn();
|
||||
|
||||
title.addLineBelow("blank-" + getName().toLowerCase(), "");
|
||||
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top1 =
|
||||
HologramAPI.createHologram("top1-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top1.addViewHandler(defaultViewHandler);
|
||||
|
||||
top1.spawn();
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top2 =
|
||||
HologramAPI.createHologram("top2-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top2.addViewHandler(defaultViewHandler);
|
||||
top2.spawn();
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top3 =
|
||||
HologramAPI.createHologram("top3-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top3.addViewHandler(defaultViewHandler);
|
||||
top3.spawn();
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top4 =
|
||||
HologramAPI.createHologram("top4-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top4.addViewHandler(defaultViewHandler);
|
||||
top4.spawn();
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top5 =
|
||||
HologramAPI.createHologram("top5-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top5.addViewHandler(defaultViewHandler);
|
||||
top5.spawn();
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top6 =
|
||||
HologramAPI.createHologram("top6-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top6.addViewHandler(defaultViewHandler);
|
||||
top6.spawn();
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top7 =
|
||||
HologramAPI.createHologram("top7-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top7.addViewHandler(defaultViewHandler);
|
||||
top7.spawn();
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top8 =
|
||||
HologramAPI.createHologram("top8-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top8.addViewHandler(defaultViewHandler);
|
||||
top8.spawn();
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top9 =
|
||||
HologramAPI.createHologram("top9-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top9.addViewHandler(defaultViewHandler);
|
||||
top9.spawn();
|
||||
y = y -= 0.25;
|
||||
|
||||
Hologram top10 =
|
||||
HologramAPI.createHologram("top10-" + getName(), new Location(world, location.getX(), y, location.getZ()), "§e%position%. %playerName% §7- §e%value%");
|
||||
top10.addViewHandler(defaultViewHandler);
|
||||
top10.spawn();
|
||||
|
||||
setCreated(true);
|
||||
}
|
||||
|
||||
public void updateValues() {
|
||||
this.updating = true;
|
||||
|
||||
new Thread(() -> {
|
||||
List<PlayerTop> updated = new ArrayList<>();
|
||||
|
||||
String fieldReference = "data>'$.\"" + getDataType().getField() + "\"" + "'";
|
||||
|
||||
try (Connection connection = CommonsGeneral.getMySQL().getConnection()) {
|
||||
PreparedStatement preparedStatament = connection.prepareStatement(
|
||||
"SELECT nick,data" + " FROM " + getDataCategory().getTableName() + " ORDER BY " + fieldReference + " DESC");
|
||||
|
||||
ResultSet result = preparedStatament.executeQuery();
|
||||
|
||||
int id = 0;
|
||||
|
||||
while (result.next()) {
|
||||
id++;
|
||||
|
||||
String playerName = result.getString("nick");
|
||||
|
||||
UUID uniqueId = CommonsGeneral.getUUIDFetcher().getOfflineUUID(playerName);
|
||||
|
||||
GamingProfile profile = CommonsGeneral.getProfileManager().getGamingProfile(uniqueId);
|
||||
|
||||
if (profile == null) {
|
||||
profile = new GamingProfile(playerName, uniqueId);
|
||||
|
||||
if (getDataCategory() != DataCategory.ACCOUNT) {
|
||||
if (!profile.getDataHandler().isCategoryLoaded(DataCategory.ACCOUNT)) {
|
||||
profile.getDataHandler().load(DataCategory.ACCOUNT);
|
||||
}
|
||||
}
|
||||
|
||||
profile.getDataHandler().loadFromJSONString(getDataCategory(), result.getString("data"));
|
||||
}
|
||||
|
||||
Groups group = profile.getGroup();
|
||||
val top = new PlayerTop(group.getTag().getColor() + playerName, profile.getInt(getDataType()));
|
||||
|
||||
if(updated.isEmpty()) updated.add(top);
|
||||
else if(!updated.get(updated.size() - 1).getPlayerName().equals(top.getPlayerName())) updated.add(top);
|
||||
}
|
||||
|
||||
result.close();
|
||||
preparedStatament.close();
|
||||
|
||||
while (id < 10) {
|
||||
id++;
|
||||
updated.add(new PlayerTop("§7Ninguém", 0));
|
||||
}
|
||||
|
||||
topList.clear();
|
||||
|
||||
updated.sort(PlayerTop::compareTo);
|
||||
topList.addAll(updated.subList(0, 10));
|
||||
recreate();
|
||||
|
||||
updated.clear();
|
||||
|
||||
this.updating = false;
|
||||
} catch (SQLException ex) {
|
||||
BukkitMain.console("§cOcorreu um erro ao tentar atualizar o TOP 10 '" + getName().toUpperCase() + "' -> " + ex.getLocalizedMessage());
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.view;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.Hologram;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface ViewHandler {
|
||||
|
||||
/**
|
||||
* Called when a {@link Hologram} is viewed by a player
|
||||
*
|
||||
* @param hologram viewed {@link Hologram}
|
||||
* @param player viewer
|
||||
* @param string content of the hologram
|
||||
* @return The new/modified content of the hologram
|
||||
*/
|
||||
String onView(@Nonnull Hologram hologram, @Nonnull Player player, @Nonnull String string);
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.item;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.item.ActionItemStack.InteractHandler;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.listeners.CoreListener;
|
||||
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.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ActionItemListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onInteract(PlayerInteractEvent event) {
|
||||
if (event.getItem() == null)
|
||||
return;
|
||||
|
||||
ItemStack itemStack = event.getItem();
|
||||
|
||||
try {
|
||||
if (itemStack == null || itemStack.getType() == Material.AIR)
|
||||
throw new Exception();
|
||||
|
||||
Player player = event.getPlayer();
|
||||
Action action = event.getAction();
|
||||
|
||||
if (itemStack.getType() == Material.MUSHROOM_SOUP && action.name().contains("RIGHT")) {
|
||||
event.setCancelled(CoreListener.handleSoup(player));
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
|
||||
if (!itemStack.hasItemMeta()) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
final String displayName = itemStack.getItemMeta().getDisplayName();
|
||||
InteractHandler handler = ActionItemStack.getHandler(itemStack.getItemMeta().getDisplayName());
|
||||
|
||||
if (handler == null) {
|
||||
throw new NullPointerException("Handler com o nome " + displayName + " com InteractHandler nulo!");
|
||||
}
|
||||
event.setCancelled(handler.onInteract(player, itemStack, action, event.getClickedBlock()));
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.item;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ActionItemStack {
|
||||
|
||||
private static HashMap<String, InteractHandler> handlers = null;
|
||||
|
||||
public static void register(final ItemStack itemStack, final InteractHandler handler) {
|
||||
register(itemStack.getItemMeta().getDisplayName(), handler);
|
||||
}
|
||||
|
||||
public static void register(final String itemName, final InteractHandler handler) {
|
||||
if (handlers == null)
|
||||
handlers = new HashMap<>();
|
||||
|
||||
handlers.put(itemName, handler);
|
||||
}
|
||||
|
||||
public static void unregister(final String itemName) {
|
||||
handlers.remove(itemName);
|
||||
}
|
||||
|
||||
public static InteractHandler getHandler(final String itemName) {
|
||||
return handlers.get(itemName);
|
||||
}
|
||||
|
||||
public interface InteractHandler {
|
||||
|
||||
boolean onInteract(Player player, ItemStack itemStack, Action action, Block clickedBlock);
|
||||
}
|
||||
}
|
@ -0,0 +1,314 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.item;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagCompound;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagList;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class ItemBuilder {
|
||||
|
||||
private Material material;
|
||||
private int amount;
|
||||
private short durability;
|
||||
private boolean useMeta;
|
||||
private boolean glow;
|
||||
private String displayName;
|
||||
private HashMap<Enchantment, Integer> enchantments;
|
||||
private List<String> lore;
|
||||
|
||||
private Color color;
|
||||
private String skinOwner;
|
||||
private String skinUrl;
|
||||
|
||||
private boolean hideAttributes;
|
||||
private boolean unbreakable;
|
||||
|
||||
private NBTTagCompound basicNBT;
|
||||
private NBTTagList enchNBT;
|
||||
|
||||
public ItemBuilder() {
|
||||
material = Material.STONE;
|
||||
amount = 1;
|
||||
durability = 0;
|
||||
hideAttributes = false;
|
||||
unbreakable = false;
|
||||
useMeta = false;
|
||||
glow = false;
|
||||
}
|
||||
|
||||
public static ItemBuilder fromStack(ItemStack stack) {
|
||||
ItemBuilder builder = new ItemBuilder().type(stack.getType()).amount(stack.getAmount())
|
||||
.durability(stack.getDurability());
|
||||
|
||||
if (stack.hasItemMeta()) {
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
|
||||
if (meta.hasDisplayName())
|
||||
builder.name(meta.getDisplayName());
|
||||
|
||||
if (meta.hasLore())
|
||||
builder.lore(meta.getLore());
|
||||
|
||||
if (meta instanceof LeatherArmorMeta) {
|
||||
Color color = ((LeatherArmorMeta) meta).getColor();
|
||||
if (color != null)
|
||||
builder.color(color);
|
||||
}
|
||||
|
||||
if (meta instanceof SkullMeta) {
|
||||
SkullMeta sm = (SkullMeta) meta;
|
||||
if (sm.hasOwner())
|
||||
builder.skin(sm.getOwner());
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public ItemBuilder type(Material material) {
|
||||
this.material = material;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder material(Material material) {
|
||||
this.material = material;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder amount(int amount) {
|
||||
if (amount > material.getMaxStackSize())
|
||||
amount = material.getMaxStackSize();
|
||||
if (amount <= 0)
|
||||
amount = 1;
|
||||
this.amount = amount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder durability(short durability) {
|
||||
this.durability = durability;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder durability(int durability) {
|
||||
this.durability = (short) durability;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder name(String text) {
|
||||
if (!useMeta) {
|
||||
useMeta = true;
|
||||
}
|
||||
this.displayName = text.replace("&", "§");
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder enchantment(Enchantment enchantment) {
|
||||
return enchantment(enchantment, 1);
|
||||
}
|
||||
|
||||
public ItemBuilder enchantment(Enchantment enchantment, Integer level) {
|
||||
if (enchantments == null) {
|
||||
enchantments = new HashMap<>();
|
||||
}
|
||||
|
||||
if (level == 0)
|
||||
return this;
|
||||
|
||||
enchantments.put(enchantment, level);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder lore(String... lore) {
|
||||
return lore(Arrays.asList(lore));
|
||||
}
|
||||
|
||||
public ItemBuilder lore(List<String> text) {
|
||||
if (!this.useMeta) this.useMeta = true;
|
||||
if (this.lore == null) this.lore = new ArrayList<>();
|
||||
|
||||
for (String str : text) {
|
||||
if (str.contains("\n")) {
|
||||
this.lore.add(str.replace("\n", ""));
|
||||
|
||||
this.lore.add("");
|
||||
} else {
|
||||
this.lore.add(str);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder color(Color color) {
|
||||
this.useMeta = true;
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder skin(String skin) {
|
||||
this.useMeta = true;
|
||||
this.skinOwner = skin;
|
||||
this.durability = 3;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder skinURL(String skinURL) {
|
||||
this.useMeta = true;
|
||||
this.skinUrl = skinURL;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder hideAttributes() {
|
||||
this.useMeta = true;
|
||||
this.hideAttributes = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder showAttributes() {
|
||||
this.useMeta = true;
|
||||
this.hideAttributes = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder unbreakable() {
|
||||
this.unbreakable = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemStack build() {
|
||||
ItemStack stack = new ItemStack(material, amount, durability);
|
||||
|
||||
if (enchantments != null && !enchantments.isEmpty()) {
|
||||
for (Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||
stack.addUnsafeEnchantment(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (useMeta) {
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
|
||||
if (displayName != null) {
|
||||
meta.setDisplayName(displayName.replace("&", "§"));
|
||||
}
|
||||
|
||||
if (lore != null && !lore.isEmpty()) {
|
||||
meta.setLore(lore);
|
||||
}
|
||||
|
||||
/** Colored Leather Armor */
|
||||
if (color != null) {
|
||||
if (meta instanceof LeatherArmorMeta) {
|
||||
((LeatherArmorMeta) meta).setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
/** Skull Heads */
|
||||
if (meta instanceof SkullMeta) {
|
||||
SkullMeta skullMeta = (SkullMeta) meta;
|
||||
if (skinUrl != null) {
|
||||
GameProfile profile = new GameProfile(UUID.randomUUID(), null);
|
||||
profile.getProperties().put("textures",
|
||||
new Property("textures",
|
||||
Base64.getEncoder()
|
||||
.encodeToString(String.format("{textures:{SKIN:{url:\"%s\"}}}", skinUrl)
|
||||
.getBytes(StandardCharsets.UTF_8))));
|
||||
try {
|
||||
Field field = skullMeta.getClass().getDeclaredField("profile");
|
||||
field.setAccessible(true);
|
||||
field.set(skullMeta, profile);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (skinOwner != null) {
|
||||
skullMeta.setOwner(skinOwner);
|
||||
}
|
||||
}
|
||||
|
||||
meta.spigot().setUnbreakable(unbreakable);
|
||||
|
||||
/** Item Flags */
|
||||
if (hideAttributes) {
|
||||
meta.addItemFlags(ItemFlag.values());
|
||||
} else {
|
||||
meta.removeItemFlags(ItemFlag.values());
|
||||
}
|
||||
|
||||
stack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
if (glow && (enchantments == null || enchantments.isEmpty())) {
|
||||
net.minecraft.server.v1_8_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack);
|
||||
if (nmsStack.hasTag()) {
|
||||
nmsStack.getTag().set("ench", this.enchNBT);
|
||||
} else {
|
||||
nmsStack.setTag(this.basicNBT);
|
||||
}
|
||||
stack = CraftItemStack.asCraftMirror(nmsStack);
|
||||
}
|
||||
|
||||
material = Material.STONE;
|
||||
amount = 1;
|
||||
durability = 0;
|
||||
|
||||
if (useMeta) {
|
||||
useMeta = false;
|
||||
}
|
||||
|
||||
if (glow) {
|
||||
glow = false;
|
||||
}
|
||||
|
||||
if (hideAttributes) {
|
||||
hideAttributes = false;
|
||||
}
|
||||
|
||||
if (unbreakable) {
|
||||
unbreakable = false;
|
||||
}
|
||||
|
||||
if (displayName != null) {
|
||||
displayName = null;
|
||||
}
|
||||
|
||||
if (enchantments != null) {
|
||||
enchantments.clear();
|
||||
enchantments = null;
|
||||
}
|
||||
|
||||
if (lore != null) {
|
||||
lore.clear();
|
||||
lore = null;
|
||||
}
|
||||
|
||||
skinOwner = null;
|
||||
skinUrl = null;
|
||||
color = null;
|
||||
this.basicNBT = null;
|
||||
this.enchNBT = null;
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public ItemBuilder glow() {
|
||||
this.glow = true;
|
||||
|
||||
this.basicNBT = new NBTTagCompound();
|
||||
this.enchNBT = new NBTTagList();
|
||||
this.basicNBT.set("ench", this.enchNBT);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.item;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsConst;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ItemChance {
|
||||
|
||||
private int chance;
|
||||
private ItemStack item;
|
||||
private int randomStack;
|
||||
|
||||
public ItemChance(ItemStack item, int chance, int randomStack) {
|
||||
this.item = item;
|
||||
this.chance = chance;
|
||||
this.randomStack = randomStack;
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
if (randomStack != 0)
|
||||
return new ItemBuilder().type(item.getType()).durability(item.getDurability()).
|
||||
amount(CommonsConst.RANDOM.nextInt(randomStack) + 1).build();
|
||||
return item;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.menu;
|
||||
|
||||
public enum ClickType {
|
||||
LEFT, RIGHT
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.menu;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public interface MenuClickHandler {
|
||||
|
||||
void onClick(Player player, Inventory inventory, ClickType type, ItemStack itemStack, int slot);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.menu;
|
||||
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
class MenuHolder implements InventoryHolder {
|
||||
|
||||
private MenuInventory menu;
|
||||
|
||||
public MenuHolder(MenuInventory menuInventory) {
|
||||
this.menu = menuInventory;
|
||||
}
|
||||
|
||||
public MenuInventory getMenu() {
|
||||
return menu;
|
||||
}
|
||||
|
||||
public void setMenu(MenuInventory menu) {
|
||||
this.menu = menu;
|
||||
}
|
||||
|
||||
public boolean isOnePerPlayer() {
|
||||
return menu.isOnePerPlayer();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
menu = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
if (isOnePerPlayer()) {
|
||||
return null;
|
||||
} else {
|
||||
return menu.getInventory();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.menu;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class MenuInventory {
|
||||
|
||||
private final HashMap<Integer, MenuItem> slotItem;
|
||||
private final int rows;
|
||||
private String title;
|
||||
private Inventory inv;
|
||||
private final boolean onePerPlayer;
|
||||
|
||||
public MenuInventory(String title, int rows) {
|
||||
this(title, rows, false);
|
||||
}
|
||||
|
||||
public MenuInventory(String title, int rows, boolean onePerPlayer) {
|
||||
this.slotItem = new HashMap<>();
|
||||
this.rows = rows;
|
||||
this.title = title;
|
||||
this.onePerPlayer = onePerPlayer;
|
||||
if (!onePerPlayer) {
|
||||
this.inv = Bukkit.createInventory(new MenuHolder(this), rows * 9, this.title);
|
||||
}
|
||||
}
|
||||
|
||||
public void addItem(MenuItem item) {
|
||||
setItem(firstEmpty(), item);
|
||||
}
|
||||
|
||||
public void addItem(ItemStack item) {
|
||||
setItem(firstEmpty(), item);
|
||||
}
|
||||
|
||||
public void setItem(ItemStack item, int slot) {
|
||||
setItem(slot, new MenuItem(item));
|
||||
}
|
||||
|
||||
public void setItem(int slot, ItemStack item) {
|
||||
setItem(slot, new MenuItem(item));
|
||||
}
|
||||
|
||||
public void setItem(int slot, ItemStack item, MenuClickHandler handler) {
|
||||
setItem(slot, new MenuItem(item, handler));
|
||||
}
|
||||
|
||||
public void setItem(MenuItem item, int slot) {
|
||||
setItem(slot, item);
|
||||
}
|
||||
|
||||
public void setItem(int slot, MenuItem item) {
|
||||
this.slotItem.put(slot, item);
|
||||
if (!onePerPlayer) {
|
||||
inv.setItem(slot, item.getStack());
|
||||
}
|
||||
}
|
||||
|
||||
public int firstEmpty() {
|
||||
if (!onePerPlayer) {
|
||||
return inv.firstEmpty();
|
||||
} else {
|
||||
for (int i = 0; i < rows * 9; i++) {
|
||||
if (!slotItem.containsKey(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasItem(int slot) {
|
||||
return this.slotItem.containsKey(slot);
|
||||
}
|
||||
|
||||
public MenuItem getItem(int slot) {
|
||||
return this.slotItem.get(slot);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
slotItem.clear();
|
||||
if (!onePerPlayer) {
|
||||
inv.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void open(Player p) {
|
||||
if (!onePerPlayer) {
|
||||
p.openInventory(inv);
|
||||
} else {
|
||||
if (p.getOpenInventory() == null//
|
||||
|| p.getOpenInventory().getTopInventory().getType() != InventoryType.CHEST//
|
||||
|| p.getOpenInventory().getTopInventory().getSize() != rows * 9
|
||||
|| p.getOpenInventory().getTopInventory().getHolder() == null//
|
||||
|| !(p.getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder)//
|
||||
|| !(((MenuHolder) p.getOpenInventory().getTopInventory().getHolder()).isOnePerPlayer())) {
|
||||
createAndOpenInventory(p);
|
||||
} else {
|
||||
// Update the current inventory of player
|
||||
for (int i = 0; i < rows * 9; i++) {
|
||||
if (slotItem.containsKey(i)) {
|
||||
p.getOpenInventory().getTopInventory().setItem(i, slotItem.get(i).getStack());
|
||||
} else {
|
||||
p.getOpenInventory().getTopInventory().setItem(i, null);
|
||||
}
|
||||
}
|
||||
p.updateInventory();
|
||||
}
|
||||
((MenuHolder) p.getOpenInventory().getTopInventory().getHolder()).setMenu(this);
|
||||
}
|
||||
|
||||
p = null;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public void createAndOpenInventory(Player p) {
|
||||
Inventory playerInventory = Bukkit.createInventory(new MenuHolder(this), rows * 9, this.title);
|
||||
|
||||
slotItem.entrySet().forEach(entry -> playerInventory.setItem(entry.getKey(), entry.getValue().getStack()));
|
||||
|
||||
p.openInventory(playerInventory);
|
||||
p = null;
|
||||
}
|
||||
|
||||
public void close(Player p) {
|
||||
if (onePerPlayer) {
|
||||
destroy(p);
|
||||
p = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy(Player p) {
|
||||
if (p.getOpenInventory().getTopInventory().getHolder() != null
|
||||
&& p.getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder) {
|
||||
((MenuHolder) p.getOpenInventory().getTopInventory().getHolder()).destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOnePerPlayer() {
|
||||
return onePerPlayer;
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
return inv;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.menu;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class MenuItem {
|
||||
|
||||
private ItemStack stack;
|
||||
private MenuClickHandler handler;
|
||||
|
||||
public MenuItem(ItemStack itemstack) {
|
||||
this.stack = itemstack;
|
||||
|
||||
this.handler = new MenuClickHandler() {
|
||||
@Override
|
||||
public void onClick(Player p, Inventory inv, ClickType type, ItemStack stack, int slot) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public MenuItem(ItemStack itemstack, MenuClickHandler clickHandler) {
|
||||
this.stack = itemstack;
|
||||
this.handler = clickHandler;
|
||||
}
|
||||
|
||||
public ItemStack getStack() {
|
||||
return stack;
|
||||
}
|
||||
|
||||
public MenuClickHandler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
stack = null;
|
||||
handler = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.menu;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public class MenuListener implements Listener {
|
||||
|
||||
private static Listener listener;
|
||||
|
||||
@Getter
|
||||
private static boolean openMenus;
|
||||
|
||||
public static void registerListeners() {
|
||||
if (openMenus) return;
|
||||
|
||||
openMenus = true;
|
||||
|
||||
listener = new Listener() {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onInventoryClickListener(InventoryClickEvent event) {
|
||||
if (event.getInventory() == null)
|
||||
return;
|
||||
|
||||
Inventory inv = event.getInventory();
|
||||
if (inv.getType() != InventoryType.CHEST)
|
||||
return;
|
||||
|
||||
if (inv.getHolder() == null)
|
||||
return;
|
||||
|
||||
if (!(inv.getHolder() instanceof MenuHolder))
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
if (event.getClickedInventory() != inv)
|
||||
return;
|
||||
|
||||
if (!(event.getWhoClicked() instanceof Player))
|
||||
return;
|
||||
|
||||
if (event.getSlot() < 0)
|
||||
return;
|
||||
|
||||
MenuHolder holder = (MenuHolder) inv.getHolder();
|
||||
MenuInventory menu = holder.getMenu();
|
||||
|
||||
if (menu.hasItem(event.getSlot())) {
|
||||
Player p = (Player) event.getWhoClicked();
|
||||
MenuItem item = menu.getItem(event.getSlot());
|
||||
|
||||
item.getHandler().onClick(p, inv,
|
||||
((event.getAction() == InventoryAction.PICKUP_HALF) ? ClickType.RIGHT : ClickType.LEFT),
|
||||
event.getCurrentItem(), event.getSlot());
|
||||
|
||||
p = null;
|
||||
item = null;
|
||||
}
|
||||
|
||||
holder = null;
|
||||
menu = null;
|
||||
inv = null;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onClose(InventoryCloseEvent event) {
|
||||
if (event.getInventory() == null)
|
||||
return;
|
||||
|
||||
Inventory inv = event.getInventory();
|
||||
if (inv.getType() != InventoryType.CHEST)
|
||||
return;
|
||||
|
||||
if (inv.getHolder() == null)
|
||||
return;
|
||||
|
||||
if (!(inv.getHolder() instanceof MenuHolder))
|
||||
return;
|
||||
|
||||
if (!(event.getPlayer() instanceof Player))
|
||||
return;
|
||||
|
||||
MenuHolder holder = (MenuHolder) inv.getHolder();
|
||||
if (holder.isOnePerPlayer()) {
|
||||
holder.destroy();
|
||||
|
||||
holder = null;
|
||||
}
|
||||
|
||||
inv = null;
|
||||
}
|
||||
};
|
||||
|
||||
Bukkit.getServer().getPluginManager().registerEvents(listener, BukkitMain.getInstance());
|
||||
}
|
||||
|
||||
public static void unregisterListeners() {
|
||||
openMenus = false;
|
||||
|
||||
HandlerList.unregisterAll(listener);
|
||||
|
||||
listener = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api.NPC;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets.NPC_v1_8_R3;
|
||||
import com.br.guilhermematthew.nowly.commons.common.utility.skin.Skin;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class NPCLib {
|
||||
|
||||
public static NPC createNPC(String customName, String color, String name, Skin skin, int itemStackID) {
|
||||
return new NPC_v1_8_R3(BukkitMain.getInstance(), customName, color, name, skin, itemStackID);
|
||||
}
|
||||
|
||||
public static NPC createNPC(String customName, String color, String name, Skin skin) {
|
||||
return createNPC(customName, color, name, skin, 20);
|
||||
}
|
||||
|
||||
public static NPC createNPC(String customName, String color, String name) {
|
||||
return createNPC(customName, color, name, null, 20);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api.NPC;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.listener.NPCListener;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public final class NPCManager {
|
||||
|
||||
private static Set<NPC> npcs;
|
||||
|
||||
private static boolean registred = false;
|
||||
|
||||
private NPCManager() {
|
||||
throw new SecurityException("You cannot initialize this class.");
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
if (registred) return;
|
||||
|
||||
registred = true;
|
||||
npcs = new HashSet<>();
|
||||
|
||||
Bukkit.getServer().getPluginManager().registerEvents(new NPCListener(), BukkitMain.getInstance());
|
||||
|
||||
BukkitMain.console("§a[NPCS] has been registred!");
|
||||
}
|
||||
|
||||
public static Set<NPC> getAllNPCs() {
|
||||
return npcs;
|
||||
}
|
||||
|
||||
public static void add(NPC npc) {
|
||||
npcs.add(npc);
|
||||
}
|
||||
|
||||
public static void remove(NPC npc) {
|
||||
npcs.remove(npc);
|
||||
}
|
||||
|
||||
public static NPC getNPCByName(String name) {
|
||||
NPC finded = null;
|
||||
|
||||
for (NPC npc : npcs) {
|
||||
if (npc.getCustomName().equalsIgnoreCase(name)) {
|
||||
finded = npc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return finded;
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.Hologram;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.hologram.HologramAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.NPCManager;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api.wrapper.GameProfileWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.common.utility.skin.Skin;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class NPC implements PacketHandler {
|
||||
|
||||
protected final UUID uuid = UUID.randomUUID();
|
||||
// Below was previously = (int) Math.ceil(Math.random() * 100000) + 100000 (new is experimental).
|
||||
protected final int entityId = Integer.MAX_VALUE - NPCManager.getAllNPCs().size();
|
||||
protected final Skin skin;
|
||||
private final Set<UUID> shown = new HashSet<>();
|
||||
protected int itemStackID = 0;
|
||||
protected final String customName;
|
||||
protected final String color;
|
||||
protected final String name;
|
||||
protected final JavaPlugin plugin;
|
||||
protected GameProfileWrapper gameProfile;
|
||||
protected Location location;
|
||||
|
||||
//for players 1.8
|
||||
@Getter
|
||||
protected Hologram nameHologram;
|
||||
|
||||
public NPC(JavaPlugin plugin, String customName, String color, String name, Skin skin, int itemStackID) {
|
||||
this.plugin = plugin;
|
||||
this.skin = skin;
|
||||
this.name = name;
|
||||
this.customName = customName;
|
||||
this.color = color;
|
||||
|
||||
this.itemStackID = itemStackID;
|
||||
|
||||
NPCManager.add(this);
|
||||
}
|
||||
|
||||
protected GameProfileWrapper generateGameProfile(UUID uuid, String name) {
|
||||
GameProfileWrapper gameProfile = new GameProfileWrapper(uuid, name);
|
||||
|
||||
if (skin != null) {
|
||||
gameProfile.addSkin(skin);
|
||||
}
|
||||
|
||||
return gameProfile;
|
||||
}
|
||||
|
||||
public String getCustomName() {
|
||||
return customName;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
NPCManager.remove(this);
|
||||
|
||||
// Destroy NPC for every player that is still seeing it.
|
||||
for (UUID uuid : shown) {
|
||||
hide(Bukkit.getPlayer(uuid));
|
||||
}
|
||||
|
||||
nameHologram.despawn();
|
||||
}
|
||||
|
||||
public void hideAll() {
|
||||
for (UUID uuid : shown) {
|
||||
hide(Bukkit.getPlayer(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
public Set<UUID> getShown() {
|
||||
return shown;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public void create(Location location) {
|
||||
this.location = location;
|
||||
|
||||
nameHologram = HologramAPI.createHologram("name",
|
||||
location.clone().add(0, 2.095, 0), null);
|
||||
nameHologram.spawn();
|
||||
|
||||
createPackets();
|
||||
}
|
||||
|
||||
public Location getLocationForHologram() {
|
||||
return location.clone().add(0, 2.05, 0);
|
||||
}
|
||||
|
||||
public void show(Player player) {
|
||||
if (shown.contains(player.getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
sendShowPackets(player);
|
||||
}
|
||||
|
||||
public void hide(Player player) {
|
||||
if (!shown.contains(player.getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
sendHidePackets(player, false);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
interface PacketHandler {
|
||||
|
||||
void createPackets();
|
||||
|
||||
void sendShowPackets(Player player);
|
||||
|
||||
void sendHidePackets(Player player, boolean scheduler);
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api.wrapper;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.utility.Reflection;
|
||||
import com.br.guilhermematthew.nowly.commons.common.utility.skin.Skin;
|
||||
import com.google.common.collect.ForwardingMultimap;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class GameProfileWrapper {
|
||||
|
||||
// Written because of issue#10 (https://github.com/JitseB/NPCLib/issues/10).
|
||||
// This class acts as an NMS reflection wrapper for the GameProfileWrapper class.
|
||||
|
||||
// TODO: As of 1.4.2 1.7 support was removed, refactor this class.
|
||||
|
||||
// TODO: This doesn't seem to work well with modified versions of Spigot (see issue #12).
|
||||
private final boolean is1_7 = Bukkit.getBukkitVersion().contains("1.7");
|
||||
private final Class<?> gameProfileClazz = Reflection.getClass((is1_7 ? "net.minecraft.util." : "") + "com.mojang.authlib.GameProfile");
|
||||
|
||||
final Object gameProfile;
|
||||
|
||||
public GameProfileWrapper(UUID uuid, String name) {
|
||||
// Only need to check if the version is 1.7, as NPCLib doesn't support any version below this version.
|
||||
this.gameProfile = Reflection.getConstructor(gameProfileClazz, UUID.class, String.class).invoke(uuid, name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void addSkin(Skin skin) {
|
||||
// Create a new property with the skin data.
|
||||
Class<?> propertyClazz = Reflection.getClass((is1_7 ? "net.minecraft.util." : "") + "com.mojang.authlib.properties.Property");
|
||||
Object property = Reflection.getConstructor(propertyClazz,
|
||||
String.class, String.class, String.class).invoke("textures", skin.getValue(), skin.getSignature());
|
||||
|
||||
// Get the property map from the GameProfileWrapper object.
|
||||
Class<?> propertyMapClazz = Reflection.getClass((is1_7 ? "net.minecraft.util." : "") + "com.mojang.authlib.properties.PropertyMap");
|
||||
Reflection.FieldAccessor propertyMapGetter = Reflection.getField(gameProfileClazz, "properties",
|
||||
propertyMapClazz);
|
||||
Object propertyMap = propertyMapGetter.get(gameProfile);
|
||||
|
||||
// TODO: Won't work on 1.7.10 (as Guava also changed package location).
|
||||
// Add our new property to the property map.
|
||||
Reflection.getMethod(ForwardingMultimap.class, "put", Object.class, Object.class)
|
||||
.invoke(propertyMap, "textures", property);
|
||||
|
||||
// Finally set the property map back in the GameProfileWrapper object.
|
||||
propertyMapGetter.set(gameProfile, propertyMap);
|
||||
}
|
||||
|
||||
public Object getGameProfile() {
|
||||
return gameProfile;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.events;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api.NPC;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.events.click.ClickType;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
@Getter
|
||||
public class NPCInteractEvent extends Event {
|
||||
|
||||
private final Player player;
|
||||
private final ClickType clickType;
|
||||
private final NPC npc;
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
public NPCInteractEvent(Player player, ClickType clickType, NPC npc) {
|
||||
this.player = player;
|
||||
this.clickType = clickType;
|
||||
this.npc = npc;
|
||||
}
|
||||
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.events.click;
|
||||
|
||||
public enum ClickType {
|
||||
|
||||
LEFT_CLICK, RIGHT_CLICK
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.listener;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.NPCManager;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api.NPC;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.utility.LocationUtil;
|
||||
import org.bukkit.Location;
|
||||
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.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
public class NPCListener implements Listener {
|
||||
|
||||
private static final String LOCKED_TAG = "LOCKED.NPCS.TIME";
|
||||
|
||||
public static void lock(Player player) {
|
||||
lock(player, 2000L);
|
||||
}
|
||||
|
||||
public static void lock(Player player, Long time) {
|
||||
player.setMetadata(LOCKED_TAG, new FixedMetadataValue(BukkitMain.getInstance(), System.currentTimeMillis() + time));
|
||||
}
|
||||
|
||||
public static void removeLock(Player player) {
|
||||
player.removeMetadata(LOCKED_TAG, BukkitMain.getInstance());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
handleNPC(event.getPlayer(), event.getPlayer().getLocation());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
for (NPC npc : NPCManager.getAllNPCs()) {
|
||||
npc.getShown().remove(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRealMovement(PlayerMoveEvent event) {
|
||||
if(!LocationUtil.isRealMovement(event.getFrom(), event.getTo())) return;
|
||||
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (isLocked(player)) return;
|
||||
|
||||
handleNPC(player, event.getTo());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onTeleport(PlayerTeleportEvent e) {
|
||||
Player player = e.getPlayer();
|
||||
|
||||
if (isLocked(player)) return;
|
||||
handleNPC(player, e.getTo());
|
||||
}
|
||||
|
||||
public void handleNPC(Player player, Location to) {
|
||||
lock(player);
|
||||
|
||||
for (NPC npc : NPCManager.getAllNPCs()) {
|
||||
Location location = npc.getLocation();
|
||||
|
||||
if (location.getWorld() != to.getWorld()) continue;
|
||||
|
||||
double distancia = location.distance(to);
|
||||
|
||||
if (distancia <= 80) {
|
||||
if (!npc.getShown().contains(player.getUniqueId())) {
|
||||
npc.show(player);
|
||||
npc.getShown().add(player.getUniqueId());
|
||||
}
|
||||
} else {
|
||||
if (npc.getShown().contains(player.getUniqueId())) {
|
||||
npc.hide(player);
|
||||
npc.getShown().remove(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeLock(player);
|
||||
}
|
||||
|
||||
private boolean isLocked(Player player) {
|
||||
if (!player.hasMetadata(LOCKED_TAG)) return false;
|
||||
return player.getMetadata(LOCKED_TAG).get(0).asLong() > System.currentTimeMillis();
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api.NPC;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets.packets.PacketPlayOutEntityHeadRotationWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets.packets.PacketPlayOutNamedEntitySpawnWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets.packets.PacketPlayOutPlayerInfoWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets.packets.PacketPlayOutScoreboardTeamWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.common.utility.skin.Skin;
|
||||
import net.minecraft.server.v1_8_R3.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class NPC_v1_8_R3 extends NPC {
|
||||
|
||||
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
|
||||
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister, packetPlayOutScoreboardTeamUnregister;
|
||||
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
|
||||
private PacketPlayOutEntityHeadRotation packetPlayOutEntityHeadRotation;
|
||||
private PacketPlayOutEntityDestroy packetPlayOutEntityDestroy;
|
||||
|
||||
public NPC_v1_8_R3(JavaPlugin plugin, String customName, String color, String name, Skin skin, int itemStackID) {
|
||||
super(plugin, customName, color, name, skin, itemStackID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPackets() {
|
||||
this.gameProfile = generateGameProfile(uuid, name);
|
||||
|
||||
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();
|
||||
|
||||
// Packets for spawning the NPC:
|
||||
this.packetPlayOutScoreboardTeamRegister = new PacketPlayOutScoreboardTeamWrapper()
|
||||
.createRegisterTeam(name, color); // First packet to send.
|
||||
|
||||
this.packetPlayOutPlayerInfoAdd = packetPlayOutPlayerInfoWrapper
|
||||
.create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, gameProfile, name); // Second packet to send.
|
||||
|
||||
this.packetPlayOutNamedEntitySpawn = new PacketPlayOutNamedEntitySpawnWrapper()
|
||||
.create(uuid, location, entityId, itemStackID); // Third packet to send.
|
||||
|
||||
this.packetPlayOutEntityHeadRotation = new PacketPlayOutEntityHeadRotationWrapper()
|
||||
.create(location, entityId); // Fourth packet to send.
|
||||
|
||||
this.packetPlayOutPlayerInfoRemove = packetPlayOutPlayerInfoWrapper
|
||||
.create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, gameProfile, name); // Fifth packet to send (delayed).
|
||||
|
||||
// Packet for destroying the NPC:
|
||||
this.packetPlayOutEntityDestroy = new PacketPlayOutEntityDestroy(entityId); // First packet to send.
|
||||
|
||||
// Second packet to send is "packetPlayOutPlayerInfoRemove".
|
||||
|
||||
this.packetPlayOutScoreboardTeamUnregister = new PacketPlayOutScoreboardTeamWrapper()
|
||||
.createUnregisterTeam(name, color); // Third packet to send.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendShowPackets(Player player) {
|
||||
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
|
||||
playerConnection.sendPacket(packetPlayOutScoreboardTeamRegister);
|
||||
|
||||
playerConnection.sendPacket(packetPlayOutPlayerInfoAdd);
|
||||
playerConnection.sendPacket(packetPlayOutNamedEntitySpawn);
|
||||
playerConnection.sendPacket(packetPlayOutEntityHeadRotation);
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () ->
|
||||
playerConnection.sendPacket(packetPlayOutPlayerInfoRemove), 40);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendHidePackets(Player player, boolean scheduler) {
|
||||
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
|
||||
playerConnection.sendPacket(packetPlayOutEntityDestroy);
|
||||
playerConnection.sendPacket(packetPlayOutPlayerInfoRemove);
|
||||
|
||||
if (scheduler) {
|
||||
// Sending this a bit later so the player doesn't see the name (for that split second).
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () ->
|
||||
playerConnection.sendPacket(packetPlayOutScoreboardTeamUnregister), 5);
|
||||
} else {
|
||||
playerConnection.sendPacket(packetPlayOutScoreboardTeamUnregister);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets.packets;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.utility.Reflection;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityHeadRotation;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class PacketPlayOutEntityHeadRotationWrapper {
|
||||
|
||||
public PacketPlayOutEntityHeadRotation create(Location location, int entityId) {
|
||||
PacketPlayOutEntityHeadRotation packetPlayOutEntityHeadRotation = new PacketPlayOutEntityHeadRotation();
|
||||
|
||||
Reflection.getField(packetPlayOutEntityHeadRotation.getClass(), "a", int.class).
|
||||
set(packetPlayOutEntityHeadRotation, entityId);
|
||||
Reflection.getField(packetPlayOutEntityHeadRotation.getClass(), "b", byte.class)
|
||||
.set(packetPlayOutEntityHeadRotation, (byte) ((int) location.getYaw() * 256.0F / 360.0F));
|
||||
|
||||
return packetPlayOutEntityHeadRotation;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets.packets;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.utility.Reflection;
|
||||
import net.minecraft.server.v1_8_R3.DataWatcher;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutNamedEntitySpawn;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PacketPlayOutNamedEntitySpawnWrapper {
|
||||
|
||||
public PacketPlayOutNamedEntitySpawn create(UUID uuid, Location location, int entityId, int itemStackID) {
|
||||
PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn = new PacketPlayOutNamedEntitySpawn();
|
||||
|
||||
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "a", int.class)
|
||||
.set(packetPlayOutNamedEntitySpawn, entityId);
|
||||
|
||||
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "b", UUID.class)
|
||||
.set(packetPlayOutNamedEntitySpawn, uuid);
|
||||
|
||||
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "c", int.class)
|
||||
.set(packetPlayOutNamedEntitySpawn, (int) Math.floor(location.getX() * 32.0D));
|
||||
|
||||
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "d", int.class)
|
||||
.set(packetPlayOutNamedEntitySpawn, (int) Math.floor(location.getY() * 32.0D));
|
||||
|
||||
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "e", int.class)
|
||||
.set(packetPlayOutNamedEntitySpawn, (int) Math.floor(location.getZ() * 32.0D));
|
||||
|
||||
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "f", byte.class)
|
||||
.set(packetPlayOutNamedEntitySpawn, (byte) ((int) (location.getYaw() * 256.0F / 360.0F)));
|
||||
|
||||
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "g", byte.class)
|
||||
.set(packetPlayOutNamedEntitySpawn, (byte) ((int) (location.getPitch() * 256.0F / 360.0F)));
|
||||
|
||||
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "h", int.class)
|
||||
.set(packetPlayOutNamedEntitySpawn, itemStackID);
|
||||
|
||||
DataWatcher dataWatcher = new DataWatcher(null);
|
||||
dataWatcher.a(10, (byte) 127);
|
||||
|
||||
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "i", DataWatcher.class)
|
||||
.set(packetPlayOutNamedEntitySpawn, dataWatcher);
|
||||
|
||||
return packetPlayOutNamedEntitySpawn;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets.packets;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.npc.api.wrapper.GameProfileWrapper;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.utility.Reflection;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.server.v1_8_R3.IChatBaseComponent;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo;
|
||||
import net.minecraft.server.v1_8_R3.WorldSettings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PacketPlayOutPlayerInfoWrapper {
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public PacketPlayOutPlayerInfo create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction action, GameProfileWrapper gameProfileWrapper, String name) {
|
||||
GameProfile gameProfile = (GameProfile) gameProfileWrapper.getGameProfile();
|
||||
|
||||
PacketPlayOutPlayerInfo packetPlayOutPlayerInfo = new PacketPlayOutPlayerInfo();
|
||||
Reflection.getField(packetPlayOutPlayerInfo.getClass(), "a", PacketPlayOutPlayerInfo.EnumPlayerInfoAction.class)
|
||||
.set(packetPlayOutPlayerInfo, action);
|
||||
|
||||
PacketPlayOutPlayerInfo.PlayerInfoData playerInfoData = packetPlayOutPlayerInfo.new PlayerInfoData(gameProfile, 1,
|
||||
WorldSettings.EnumGamemode.NOT_SET, IChatBaseComponent.ChatSerializer.a(name));
|
||||
|
||||
Reflection.FieldAccessor<List> fieldAccessor = Reflection.getField(packetPlayOutPlayerInfo.getClass(),
|
||||
"b", List.class);
|
||||
|
||||
List<PacketPlayOutPlayerInfo.PlayerInfoData> list = fieldAccessor.get(packetPlayOutPlayerInfo);
|
||||
list.add(playerInfoData);
|
||||
fieldAccessor.set(packetPlayOutPlayerInfo, list);
|
||||
|
||||
return packetPlayOutPlayerInfo;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.npc.packets.packets;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.utility.Reflection;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutScoreboardTeam;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class PacketPlayOutScoreboardTeamWrapper {
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public PacketPlayOutScoreboardTeam createRegisterTeam(String name, String color) {
|
||||
PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = new PacketPlayOutScoreboardTeam();
|
||||
|
||||
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "h", int.class)
|
||||
.set(packetPlayOutScoreboardTeam, 0);
|
||||
|
||||
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "b", String.class)
|
||||
.set(packetPlayOutScoreboardTeam, color + name);
|
||||
|
||||
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "a", String.class)
|
||||
.set(packetPlayOutScoreboardTeam, color + name);
|
||||
|
||||
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "e", String.class)
|
||||
.set(packetPlayOutScoreboardTeam, "never");
|
||||
|
||||
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "i", int.class)
|
||||
.set(packetPlayOutScoreboardTeam, 1);
|
||||
// Could not get this working in the PacketPlayOutPlayerInfoWrapper class.
|
||||
|
||||
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "c", String.class)
|
||||
.set(packetPlayOutScoreboardTeam, "" + color);
|
||||
|
||||
Reflection.FieldAccessor<Collection> collectionFieldAccessor = Reflection.getField(
|
||||
packetPlayOutScoreboardTeam.getClass(), "g", Collection.class);
|
||||
|
||||
Collection collection = collectionFieldAccessor.get(packetPlayOutScoreboardTeam);
|
||||
collection.add(name);
|
||||
collectionFieldAccessor.set(packetPlayOutScoreboardTeam, collection);
|
||||
|
||||
return packetPlayOutScoreboardTeam;
|
||||
}
|
||||
|
||||
public PacketPlayOutScoreboardTeam createUnregisterTeam(String name, String color) {
|
||||
PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = new PacketPlayOutScoreboardTeam();
|
||||
|
||||
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "h", int.class)
|
||||
.set(packetPlayOutScoreboardTeam, 1);
|
||||
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "a", String.class)
|
||||
.set(packetPlayOutScoreboardTeam, color + name);
|
||||
|
||||
return packetPlayOutScoreboardTeam;
|
||||
}
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.player;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsConst;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitSettings;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.player.PlayerUpdateTabEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerAPI {
|
||||
|
||||
public static boolean isRealMovement(final PlayerMoveEvent event) {
|
||||
return (event.getFrom().getBlockX() != event.getTo().getBlockX()) || (event.getFrom().getBlockZ() != event.getTo().getBlockZ());
|
||||
}
|
||||
|
||||
public static int getXPKill(final Player player, long doubleXPTime) {
|
||||
boolean doubleActive = doubleXPTime > System.currentTimeMillis();
|
||||
|
||||
if (BukkitSettings.DOUBLE_XP_OPTION)
|
||||
doubleActive = true;
|
||||
|
||||
int xp = CommonsConst.RANDOM.nextInt(16);
|
||||
|
||||
if (xp < 12)
|
||||
xp = 12;
|
||||
|
||||
if (doubleActive) {
|
||||
xp = xp * 2;
|
||||
player.sendMessage(BukkitMessages.KILL_MESSAGE_XP.replace("%quantia%", "" + xp) + " (2x)");
|
||||
} else {
|
||||
player.sendMessage(BukkitMessages.KILL_MESSAGE_XP.replace("%quantia%", "" + xp));
|
||||
}
|
||||
|
||||
return xp;
|
||||
}
|
||||
|
||||
public static int getCoinsKill(final Player player, long doubleCoinsTime) {
|
||||
boolean doubleActive = doubleCoinsTime > System.currentTimeMillis();
|
||||
|
||||
if (BukkitSettings.DOUBLE_COINS_OPTION)
|
||||
doubleActive = true;
|
||||
|
||||
int coins = CommonsConst.RANDOM.nextInt(100);
|
||||
|
||||
if (coins < 80)
|
||||
coins = 80;
|
||||
|
||||
if (doubleActive) {
|
||||
coins = coins * 2;
|
||||
player.sendMessage(BukkitMessages.KILL_MESSAGE_COINS.replace("%quantia%", "" + coins) + " (2x)");
|
||||
} else {
|
||||
player.sendMessage(BukkitMessages.KILL_MESSAGE_COINS.replace("%quantia%", "" + coins));
|
||||
}
|
||||
|
||||
return coins;
|
||||
}
|
||||
|
||||
public static int getPing(final Player player) {
|
||||
return ((CraftPlayer) player).getHandle().ping;
|
||||
}
|
||||
|
||||
public static String getHealth(Player player) {
|
||||
return getHealth(player.getHealth());
|
||||
}
|
||||
|
||||
public static String getHealth(double health) {
|
||||
return NumberFormat.getCurrencyInstance().format(health / 2).replace("$", "").replace("R", "")
|
||||
.replace(",", ".");
|
||||
}
|
||||
|
||||
public static String getAddress(final Player player) {
|
||||
return player.getAddress().getAddress().getHostAddress();
|
||||
}
|
||||
|
||||
public static void dropItems(final Player p, final Location l) {
|
||||
ArrayList<ItemStack> itens = new ArrayList<>();
|
||||
|
||||
for (ItemStack item : p.getPlayer().getInventory().getContents()) {
|
||||
if ((item != null) && (item.getType() != Material.AIR)) {
|
||||
if (item.hasItemMeta()) {
|
||||
if ((item.getItemMeta().hasDisplayName()) && (item.getItemMeta().getDisplayName().contains("Kit"))) {
|
||||
continue;
|
||||
}
|
||||
itens.add(item.clone());
|
||||
} else {
|
||||
itens.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemStack item : p.getPlayer().getInventory().getArmorContents()) {
|
||||
if ((item != null) && (item.getType() != Material.AIR)) {
|
||||
itens.add(item.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if ((p.getPlayer().getItemOnCursor() != null) && (p.getPlayer().getItemOnCursor().getType() != Material.AIR)) {
|
||||
itens.add(p.getPlayer().getItemOnCursor().clone());
|
||||
}
|
||||
|
||||
dropItems(p, itens, l);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void dropItems(Player player, List<ItemStack> itens, final Location location) {
|
||||
World world = location.getWorld();
|
||||
|
||||
for (ItemStack item : itens) {
|
||||
if ((item != null) && (item.getType() != Material.AIR)) {
|
||||
if (item.hasItemMeta()) {
|
||||
world.dropItemNaturally(location, item.clone()).getItemStack().setItemMeta(item.getItemMeta());
|
||||
} else {
|
||||
world.dropItemNaturally(location, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player.getPlayer().getInventory().setArmorContents(new ItemStack[4]);
|
||||
player.getPlayer().getInventory().clear();
|
||||
player.getPlayer().setItemOnCursor(new ItemStack(0));
|
||||
|
||||
itens.clear();
|
||||
}
|
||||
|
||||
public static void clearEffects(Player player) {
|
||||
for (PotionEffect effect : player.getActivePotionEffects()) {
|
||||
player.removePotionEffect(effect.getType());
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFull(final Inventory inventory) {
|
||||
return inventory.firstEmpty() == -1;
|
||||
}
|
||||
|
||||
public static void updateTab(final Player player) {
|
||||
Bukkit.getPluginManager().callEvent(new PlayerUpdateTabEvent(player));
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.protocol;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class ProtocolGetter {
|
||||
|
||||
//Protocol Support
|
||||
static Class<?> ProtocolSupportAPI;
|
||||
static Class<?> ProtocolVersion;
|
||||
static Method ProtocolSupportAPI_getProtocolVersion;
|
||||
static Method ProtocolVersion_getId;
|
||||
|
||||
static {
|
||||
try {
|
||||
ProtocolSupportAPI = Class.forName("protocolsupport.api.ProtocolSupportAPI");
|
||||
ProtocolVersion = Class.forName("protocolsupport.api.ProtocolVersion");
|
||||
|
||||
ProtocolSupportAPI_getProtocolVersion = getMethod(ProtocolSupportAPI, "getProtocolVersion", Player.class);
|
||||
ProtocolVersion_getId = getMethod(ProtocolVersion, "getId");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getVersion(Player p) {
|
||||
try {
|
||||
Object protocolVersion = ProtocolSupportAPI_getProtocolVersion.invoke(null, p);
|
||||
return (int) ProtocolVersion_getId.invoke(protocolVersion);
|
||||
} catch (Exception ex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String name, Class<?>... args) {
|
||||
for (Method m : clazz.getMethods()) {
|
||||
if (m.getName().equals(name) && (args.length == 0 || ClassListEqual(args, m.getParameterTypes()))) {
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean ClassListEqual(Class<?>[] l1, Class<?>[] l2) {
|
||||
boolean equal = true;
|
||||
if (l1.length != l2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < l1.length; i++) {
|
||||
if (l1[i] != l2[i]) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.title;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class TitleAPI {
|
||||
|
||||
public static void sendTitles(final Player player, final String... titles) {
|
||||
for (int i = 0; i < titles.length; i++) {
|
||||
String line = titles[i];
|
||||
|
||||
String title = line.split(";")[0],
|
||||
subtitle = line.split(";")[1];
|
||||
|
||||
BukkitMain.runLater(() -> {
|
||||
sendTitle(player, title, subtitle, 0, 0, 2);
|
||||
}, i == 0 ? 30 : i * 60);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendTitle(Player player,
|
||||
String titulo, String subtitulo, int fadeInTime, int stayTime, int fadeOutTime) {
|
||||
sendTitle(player, fadeInTime * 20, stayTime * 20, fadeOutTime * 20, titulo, subtitulo);
|
||||
}
|
||||
|
||||
public static void sendTitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String message) {
|
||||
sendTitle(player, fadeIn, stay, fadeOut, message, null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void sendSubtitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String message) {
|
||||
sendTitle(player, fadeIn, stay, fadeOut, null, message);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void sendFullTitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String title, String subtitle) {
|
||||
sendTitle(player, fadeIn, stay, fadeOut, title, subtitle);
|
||||
}
|
||||
|
||||
public static void sendPacket(Player player, Object packet) {
|
||||
try {
|
||||
Object handle = player.getClass().getMethod("getHandle").invoke(player);
|
||||
Object playerConnection = handle.getClass().getField("playerConnection").get(handle);
|
||||
playerConnection.getClass().getMethod("sendPacket", getNMSClass("Packet")).invoke(playerConnection, packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClass(String name) {
|
||||
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
try {
|
||||
return Class.forName("net.minecraft.server." + version + "." + name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static void sendTitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String title, String subtitle) {
|
||||
try {
|
||||
Object e;
|
||||
Object chatTitle;
|
||||
Object chatSubtitle;
|
||||
Constructor subtitleConstructor;
|
||||
Object titlePacket;
|
||||
Object subtitlePacket;
|
||||
|
||||
if (title != null) {
|
||||
title = ChatColor.translateAlternateColorCodes('&', title);
|
||||
title = title.replaceAll("%player%", player.getDisplayName());
|
||||
// Times packets
|
||||
e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TIMES").get(null);
|
||||
chatTitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[]{String.class}).invoke(null, "{\"text\":\"" + title + "\"}");
|
||||
subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE);
|
||||
titlePacket = subtitleConstructor.newInstance(e, chatTitle, fadeIn, stay, fadeOut);
|
||||
sendPacket(player, titlePacket);
|
||||
|
||||
e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TITLE").get(null);
|
||||
chatTitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[]{String.class}).invoke(null, "{\"text\":\"" + title + "\"}");
|
||||
subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"));
|
||||
titlePacket = subtitleConstructor.newInstance(e, chatTitle);
|
||||
sendPacket(player, titlePacket);
|
||||
}
|
||||
|
||||
if (subtitle != null) {
|
||||
subtitle = ChatColor.translateAlternateColorCodes('&', subtitle);
|
||||
subtitle = subtitle.replaceAll("%player%", player.getDisplayName());
|
||||
// Times packets
|
||||
e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TIMES").get(null);
|
||||
chatSubtitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[]{String.class}).invoke(null, "{\"text\":\"" + title + "\"}");
|
||||
subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE);
|
||||
subtitlePacket = subtitleConstructor.newInstance(e, chatSubtitle, fadeIn, stay, fadeOut);
|
||||
sendPacket(player, subtitlePacket);
|
||||
|
||||
e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("SUBTITLE").get(null);
|
||||
chatSubtitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[]{String.class}).invoke(null, "{\"text\":\"" + subtitle + "\"}");
|
||||
subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE);
|
||||
subtitlePacket = subtitleConstructor.newInstance(e, chatSubtitle, fadeIn, stay, fadeOut);
|
||||
sendPacket(player, subtitlePacket);
|
||||
}
|
||||
} catch (Exception var11) {
|
||||
var11.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearTitle(Player player) {
|
||||
sendTitle(player, 0, 0, 0, "", "");
|
||||
}
|
||||
|
||||
public static void setHeaderAndFooter(Player player, String header, String footer) {
|
||||
if (header == null) header = "";
|
||||
header = ChatColor.translateAlternateColorCodes('&', header);
|
||||
|
||||
if (footer == null) footer = "";
|
||||
footer = ChatColor.translateAlternateColorCodes('&', footer);
|
||||
|
||||
header = header.replaceAll("%player%", player.getDisplayName());
|
||||
footer = footer.replaceAll("%player%", player.getDisplayName());
|
||||
|
||||
try {
|
||||
Object tabHeader =
|
||||
getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + header + "\"}");
|
||||
|
||||
Object tabFooter =
|
||||
getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + footer + "\"}");
|
||||
|
||||
Constructor<?> titleConstructor = getNMSClass("PacketPlayOutPlayerListHeaderFooter").getConstructor();
|
||||
Object packet = titleConstructor.newInstance();
|
||||
try {
|
||||
Field aField = packet.getClass().getDeclaredField("a");
|
||||
aField.setAccessible(true);
|
||||
aField.set(packet, tabHeader);
|
||||
Field bField = packet.getClass().getDeclaredField("b");
|
||||
bField.setAccessible(true);
|
||||
bField.set(packet, tabFooter);
|
||||
} catch (Exception e) {
|
||||
Field aField = packet.getClass().getDeclaredField("header");
|
||||
aField.setAccessible(true);
|
||||
aField.set(packet, tabHeader);
|
||||
Field bField = packet.getClass().getDeclaredField("footer");
|
||||
bField.setAccessible(true);
|
||||
bField.set(packet, tabFooter);
|
||||
}
|
||||
sendPacket(player, packet);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.api.vanish;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.player.PlayerAdminChangeEvent;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.custom.events.player.PlayerAdminChangeEvent.AdminChangeType;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.scoreboard.tag.TagManager;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
import com.br.guilhermematthew.nowly.commons.common.tag.Tag;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class VanishAPI {
|
||||
|
||||
private static final List<Player> invisiveis = new ArrayList<>();
|
||||
private static final List<Player> admin = new ArrayList<>();
|
||||
|
||||
/*
|
||||
private static final HashMap<UUID, ItemStack[]> itens = new HashMap<>();
|
||||
private static final HashMap<UUID, ItemStack[]> armadura = new HashMap<>();*/
|
||||
|
||||
public static void hide(Player player) {
|
||||
if (invisiveis.contains(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
invisiveis.add(player);
|
||||
|
||||
Tag tag =
|
||||
BukkitMain.getBukkitPlayer(player.getUniqueId()).getGroup().getTag();
|
||||
|
||||
for (Player onlines : Bukkit.getOnlinePlayers()) {
|
||||
if (!TagManager.hasPermission(onlines, tag)) {
|
||||
onlines.hidePlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
player.sendMessage(BukkitMessages.PLAYER_FICOU_INVISIVEL.replace("%grupo%", tag.getColor() + "§l" + tag.getName()));
|
||||
}
|
||||
|
||||
public static void show(Player player) {
|
||||
if (!invisiveis.contains(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
invisiveis.remove(player);
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach(onlines -> onlines.showPlayer(player));
|
||||
|
||||
player.sendMessage(BukkitMessages.PLAYER_FICOU_VISIVEL);
|
||||
}
|
||||
|
||||
public static void updateInvisibles(Player player) {
|
||||
for (Player invisible : invisiveis) {
|
||||
|
||||
if (invisible != null && invisible.isOnline()) {
|
||||
Tag tag = BukkitMain.getBukkitPlayer(invisible.getUniqueId()).getGroup().getTag();
|
||||
|
||||
if (TagManager.hasPermission(player, tag)) {
|
||||
player.showPlayer(invisible);
|
||||
} else {
|
||||
player.hidePlayer(invisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void changeAdmin(Player player) {
|
||||
changeAdmin(player, true);
|
||||
}
|
||||
|
||||
public static void changeAdmin(Player player, boolean callEvent) {
|
||||
boolean inAdmin = admin.contains(player);
|
||||
|
||||
Groups playerGroup = BukkitMain.getBukkitPlayer(player.getUniqueId()).getGroup();
|
||||
|
||||
if (inAdmin) {
|
||||
//saiu do admin
|
||||
/* player.getInventory().clear();
|
||||
player.getInventory().setArmorContents(null);
|
||||
|
||||
player.getInventory().setContents(itens.get(player.getUniqueId()));
|
||||
player.getInventory().setArmorContents(armadura.get(player.getUniqueId()));
|
||||
|
||||
armadura.remove(player.getUniqueId());
|
||||
itens.remove(player.getUniqueId());*/
|
||||
admin.remove(player);
|
||||
|
||||
invisiveis.remove(player);
|
||||
} else {
|
||||
if (!admin.contains(player)) {
|
||||
admin.add(player);
|
||||
}
|
||||
|
||||
if (!invisiveis.contains(player)) {
|
||||
invisiveis.add(player);
|
||||
}
|
||||
|
||||
/*
|
||||
itens.put(player.getUniqueId(), player.getInventory().getContents());
|
||||
armadura.put(player.getUniqueId(), player.getInventory().getArmorContents());
|
||||
|
||||
player.getInventory().clear();
|
||||
player.getInventory().setArmorContents(null);*/
|
||||
}
|
||||
|
||||
for (Player onlines : Bukkit.getOnlinePlayers()) {
|
||||
if (player == onlines) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inAdmin) {
|
||||
onlines.showPlayer(player);
|
||||
}
|
||||
|
||||
if (TagManager.hasPermission(onlines, playerGroup)) {
|
||||
onlines.sendMessage(inAdmin ? BukkitMessages.PLAYER_SAIU_DO_ADMIN.replace("%nick%", player.getName()) :
|
||||
BukkitMessages.PLAYER_ENTROU_NO_ADMIN.replace("%nick%", player.getName()));
|
||||
} else {
|
||||
if (!inAdmin) {
|
||||
onlines.hidePlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (callEvent) {
|
||||
Bukkit.getPluginManager().callEvent(new PlayerAdminChangeEvent(player, inAdmin ? AdminChangeType.SAIU : AdminChangeType.ENTROU));
|
||||
}
|
||||
|
||||
player.setGameMode(inAdmin ? GameMode.SURVIVAL : GameMode.CREATIVE);
|
||||
|
||||
player.sendMessage(inAdmin ? BukkitMessages.SAIU_DO_ADMIN : BukkitMessages.ENTROU_NO_ADMIN);
|
||||
}
|
||||
|
||||
public static void remove(Player player) {
|
||||
admin.remove(player);
|
||||
invisiveis.remove(player);
|
||||
/*itens.remove(uniqueId);
|
||||
armadura.remove(uniqueId);*/
|
||||
}
|
||||
|
||||
public static boolean inAdmin(Player player) {
|
||||
return admin.contains(player);
|
||||
}
|
||||
|
||||
public static boolean isInvisible(Player player) {
|
||||
return invisiveis.contains(player);
|
||||
}
|
||||
}
|
@ -0,0 +1,356 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.commands;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsConst;
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsGeneral;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMain;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandClass;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandFramework;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
import com.br.guilhermematthew.nowly.commons.common.profile.GamingProfile;
|
||||
import com.br.guilhermematthew.nowly.commons.common.serverinfo.ServerType;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.help.GenericCommandHelpTopic;
|
||||
import org.bukkit.help.HelpTopic;
|
||||
import org.bukkit.help.HelpTopicComparator;
|
||||
import org.bukkit.help.IndexHelpTopic;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.SimplePluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class BukkitCommandFramework implements CommandFramework {
|
||||
|
||||
public static final BukkitCommandFramework INSTANCE = new BukkitCommandFramework(BukkitMain.getInstance());
|
||||
|
||||
private final Map<String, Entry<Method, Object>> commandMap = new HashMap<>();
|
||||
private final JavaPlugin plugin;
|
||||
private CommandMap map;
|
||||
|
||||
public BukkitCommandFramework(JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
if (plugin.getServer().getPluginManager() instanceof SimplePluginManager) {
|
||||
SimplePluginManager manager = (SimplePluginManager) plugin.getServer().getPluginManager();
|
||||
try {
|
||||
Field field = SimplePluginManager.class.getDeclaredField("commandMap");
|
||||
field.setAccessible(true);
|
||||
map = (CommandMap) field.get(manager);
|
||||
} catch (IllegalArgumentException | NoSuchFieldException | IllegalAccessException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JavaPlugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public boolean handleCommand(org.bukkit.command.CommandSender sender, String label, org.bukkit.command.Command cmd, String[] args) {
|
||||
StringBuilder line = new StringBuilder();
|
||||
|
||||
line.append(label);
|
||||
|
||||
for (String arg : args) {
|
||||
line.append(" ").append(arg);
|
||||
}
|
||||
|
||||
for (int i = args.length; i >= 0; i--) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append(label.toLowerCase());
|
||||
|
||||
for (int x = 0; x < i; x++) {
|
||||
buffer.append(".").append(args[x].toLowerCase());
|
||||
}
|
||||
|
||||
String cmdLabel = buffer.toString();
|
||||
|
||||
if (commandMap.containsKey(cmdLabel)) {
|
||||
Entry<Method, Object> entry = commandMap.get(cmdLabel);
|
||||
Command command = entry.getKey().getAnnotation(Command.class);
|
||||
|
||||
if (sender instanceof Player) {
|
||||
Player p = (Player) sender;
|
||||
|
||||
if (BukkitMain.getServerType() == ServerType.LOGIN) {
|
||||
if ((command.name().equalsIgnoreCase("login")) || (command.name().equalsIgnoreCase("logar"))
|
||||
|| (command.name().equalsIgnoreCase("register")) || (command.name().equalsIgnoreCase("registrar"))) {
|
||||
try {
|
||||
entry.getKey().invoke(entry.getValue(), new BukkitCommandSender(sender), label, args);
|
||||
} catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
p.sendMessage("§cEste comando não pode ser executado aqui.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
GamingProfile profile = CommonsGeneral.getProfileManager().getGamingProfile(p.getUniqueId());
|
||||
|
||||
final String groupName = profile.getGroup().getName();
|
||||
|
||||
if (command.groupsToUse().length == 1 && command.groupsToUse()[0] == Groups.MEMBRO) {
|
||||
|
||||
} else {
|
||||
Groups tagPlayer = Groups.getGroup(groupName);
|
||||
|
||||
boolean semPermissao = true;
|
||||
for (int uses = 0; uses < command.groupsToUse().length; uses++) {
|
||||
Groups tag = command.groupsToUse()[uses];
|
||||
if (tagPlayer.getLevel() >= tag.getLevel()) {
|
||||
semPermissao = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (semPermissao) {
|
||||
if (hasCommand(p, command.name().toLowerCase())) {
|
||||
semPermissao = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (semPermissao) {
|
||||
p.sendMessage(BukkitMessages.VOCE_NAO_TEM_PERMISSãO_PARA_USAR_ESTE_COMANDO);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (command.runAsync()) {
|
||||
BukkitMain.runAsync(() -> {
|
||||
try {
|
||||
entry.getKey().invoke(entry.getValue(), new BukkitCommandSender(sender), label, args);
|
||||
} catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
try {
|
||||
entry.getKey().invoke(entry.getValue(), new BukkitCommandSender(sender), label, args);
|
||||
} catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasCommand(Player player, String command) {
|
||||
if (player.hasPermission(CommonsConst.PERMISSION_PREFIX + ".cmd.all")) return true;
|
||||
|
||||
return player.hasPermission(CommonsConst.PERMISSION_PREFIX + ".cmd." + command);
|
||||
}
|
||||
|
||||
public void registerCommands(CommandClass commandClass) {
|
||||
for (Method m : commandClass.getClass().getMethods()) {
|
||||
if (m.getAnnotation(Command.class) != null) {
|
||||
Command command = m.getAnnotation(Command.class);
|
||||
if (m.getParameterTypes().length != 3
|
||||
|| !BukkitCommandSender.class.isAssignableFrom(m.getParameterTypes()[0])
|
||||
&& !String.class.isAssignableFrom(m.getParameterTypes()[1])
|
||||
&& !String[].class.isAssignableFrom(m.getParameterTypes()[2])) {
|
||||
System.out.println("Unable to register command " + m.getName() + ". Unexpected method arguments");
|
||||
continue;
|
||||
}
|
||||
registerCommand(command, command.name(), m, commandClass);
|
||||
for (String alias : command.aliases()) {
|
||||
registerCommand(command, alias, m, commandClass);
|
||||
}
|
||||
} else if (m.getAnnotation(Completer.class) != null) {
|
||||
Completer comp = m.getAnnotation(Completer.class);
|
||||
if (m.getParameterTypes().length != 3
|
||||
|| m.getParameterTypes()[0] != BukkitCommandSender.class
|
||||
&& m.getParameterTypes()[1] != String.class
|
||||
&& m.getParameterTypes()[2] != String[].class) {
|
||||
System.out.println(
|
||||
"Unable to register tab completer " + m.getName() + ". Unexpected method arguments");
|
||||
continue;
|
||||
}
|
||||
if (m.getReturnType() != List.class) {
|
||||
System.out.println("Unable to register tab completer " + m.getName() + ". Unexpected return type");
|
||||
continue;
|
||||
}
|
||||
registerCompleter(comp.name(), m, commandClass);
|
||||
for (String alias : comp.aliases()) {
|
||||
registerCompleter(alias, m, commandClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerHelp() {
|
||||
Set<HelpTopic> help = new TreeSet<HelpTopic>(HelpTopicComparator.helpTopicComparatorInstance());
|
||||
for (String s : commandMap.keySet()) {
|
||||
if (!s.contains(".")) {
|
||||
org.bukkit.command.Command cmd = map.getCommand(s);
|
||||
HelpTopic topic = new GenericCommandHelpTopic(cmd);
|
||||
help.add(topic);
|
||||
}
|
||||
}
|
||||
IndexHelpTopic topic = new IndexHelpTopic(plugin.getName(), "All commands for " + plugin.getName(), null, help,
|
||||
"Below is a list of all " + plugin.getName() + " commands:");
|
||||
Bukkit.getServer().getHelpMap().addTopic(topic);
|
||||
}
|
||||
|
||||
private void registerCommand(Command command, String label, Method m, Object obj) {
|
||||
Entry<Method, Object> entry = new AbstractMap.SimpleEntry<>(m, obj);
|
||||
commandMap.put(label.toLowerCase(), entry);
|
||||
String cmdLabel = label.replace(".", ",").split(",")[0].toLowerCase();
|
||||
if (map.getCommand(cmdLabel) == null) {
|
||||
org.bukkit.command.Command cmd = new BukkitCommand(cmdLabel, plugin);
|
||||
map.register(plugin.getName(), cmd);
|
||||
}
|
||||
if (!command.description().equalsIgnoreCase("") && cmdLabel.equals(label)) {
|
||||
map.getCommand(cmdLabel).setDescription(command.description());
|
||||
}
|
||||
if (!command.usage().equalsIgnoreCase("") && cmdLabel.equals(label)) {
|
||||
map.getCommand(cmdLabel).setUsage(command.usage());
|
||||
}
|
||||
}
|
||||
|
||||
private void registerCompleter(String label, Method m, Object obj) {
|
||||
String cmdLabel = label.replace(".", ",").split(",")[0].toLowerCase();
|
||||
if (map.getCommand(cmdLabel) == null) {
|
||||
org.bukkit.command.Command command = new BukkitCommand(cmdLabel, plugin);
|
||||
map.register(plugin.getName(), command);
|
||||
}
|
||||
if (map.getCommand(cmdLabel) instanceof BukkitCommand) {
|
||||
BukkitCommand command = (BukkitCommand) map.getCommand(cmdLabel);
|
||||
if (command.completer == null) {
|
||||
command.completer = new BukkitCompleter();
|
||||
}
|
||||
command.completer.addCompleter(label, m, obj);
|
||||
} else if (map.getCommand(cmdLabel) instanceof PluginCommand) {
|
||||
try {
|
||||
Object command = map.getCommand(cmdLabel);
|
||||
Field field = command.getClass().getDeclaredField("completer");
|
||||
field.setAccessible(true);
|
||||
if (field.get(command) == null) {
|
||||
BukkitCompleter completer = new BukkitCompleter();
|
||||
completer.addCompleter(label, m, obj);
|
||||
field.set(command, completer);
|
||||
} else if (field.get(command) instanceof BukkitCompleter) {
|
||||
BukkitCompleter completer = (BukkitCompleter) field.get(command);
|
||||
completer.addCompleter(label, m, obj);
|
||||
} else {
|
||||
System.out.println("Unable to register tab completer " + m.getName()
|
||||
+ ". A tab completer is already registered for that command!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BukkitCommand extends org.bukkit.command.Command {
|
||||
|
||||
private final Plugin owningPlugin;
|
||||
private final CommandExecutor executor;
|
||||
protected BukkitCompleter completer;
|
||||
|
||||
protected BukkitCommand(String label, Plugin owner) {
|
||||
super(label);
|
||||
this.executor = owner;
|
||||
this.owningPlugin = owner;
|
||||
this.usageMessage = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(org.bukkit.command.CommandSender sender, String commandLabel, String[] args) {
|
||||
boolean success;
|
||||
|
||||
if (!owningPlugin.isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
success = handleCommand(sender, commandLabel, this, args);
|
||||
} catch (Throwable ex) {
|
||||
throw new CommandException("Unhandled exception executing command '" + commandLabel + "' in plugin "
|
||||
+ owningPlugin.getDescription().getFullName(), ex);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(org.bukkit.command.CommandSender sender, String alias, String[] args)
|
||||
throws CommandException, IllegalArgumentException {
|
||||
Validate.notNull(sender, "Sender cannot be null");
|
||||
Validate.notNull(args, "Arguments cannot be null");
|
||||
Validate.notNull(alias, "Alias cannot be null");
|
||||
|
||||
List<String> completions = null;
|
||||
try {
|
||||
if (completer != null) {
|
||||
completions = completer.onTabComplete(sender, this, alias, args);
|
||||
}
|
||||
if (completions == null && executor instanceof TabCompleter) {
|
||||
completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append("Unhandled exception during tab completion for command '/").append(alias).append(' ');
|
||||
for (String arg : args) {
|
||||
message.append(arg).append(' ');
|
||||
}
|
||||
message.deleteCharAt(message.length() - 1).append("' in plugin ")
|
||||
.append(owningPlugin.getDescription().getFullName());
|
||||
throw new CommandException(message.toString(), ex);
|
||||
}
|
||||
|
||||
if (completions == null) {
|
||||
return super.tabComplete(sender, alias, args);
|
||||
}
|
||||
return completions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class BukkitCompleter implements TabCompleter {
|
||||
|
||||
private final Map<String, Entry<Method, Object>> completers = new HashMap<>();
|
||||
|
||||
public void addCompleter(String label, Method m, Object obj) {
|
||||
completers.put(label, new AbstractMap.SimpleEntry<>(m, obj));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<String> onTabComplete(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command,
|
||||
String label, String[] args) {
|
||||
for (int i = args.length; i >= 0; i--) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append(label.toLowerCase());
|
||||
for (int x = 0; x < i; x++) {
|
||||
if (!args[x].equals("") && !args[x].equals(" ")) {
|
||||
buffer.append(".").append(args[x].toLowerCase());
|
||||
}
|
||||
}
|
||||
String cmdLabel = buffer.toString();
|
||||
if (completers.containsKey(cmdLabel)) {
|
||||
Entry<Method, Object> entry = completers.get(cmdLabel);
|
||||
try {
|
||||
return (List<String>) entry.getKey().invoke(entry.getValue(), new BukkitCommandSender(sender),
|
||||
label, args);
|
||||
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,160 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.commands;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsConst;
|
||||
import com.br.guilhermematthew.nowly.commons.CommonsGeneral;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandSender;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BukkitCommandSender implements CommandSender, org.bukkit.command.CommandSender {
|
||||
|
||||
@NonNull
|
||||
private org.bukkit.command.CommandSender commandSender;
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
if (commandSender instanceof Player)
|
||||
return ((Player) commandSender).getUniqueId();
|
||||
return UUID.randomUUID();
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return (Player) commandSender;
|
||||
}
|
||||
|
||||
public String getNick() {
|
||||
if (commandSender instanceof Player) {
|
||||
return commandSender.getName();
|
||||
}
|
||||
return "CONSOLE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayer() {
|
||||
if (commandSender instanceof Player) {
|
||||
return true;
|
||||
}
|
||||
commandSender.sendMessage("§cComando disponível apenas para Jogadores.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getRealNick() {
|
||||
if (commandSender instanceof Player) {
|
||||
return CommonsGeneral.getProfileManager().getGamingProfile(((Player) commandSender).getUniqueId()).getNick();
|
||||
}
|
||||
return "CONSOLE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(Plugin arg0) {
|
||||
return commandSender.addAttachment(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(Plugin arg0, int arg1) {
|
||||
return commandSender.addAttachment(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(Plugin arg0, String arg1, boolean arg2) {
|
||||
return commandSender.addAttachment(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionAttachment addAttachment(Plugin arg0, String arg1, boolean arg2, int arg3) {
|
||||
return commandSender.addAttachment(arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
return commandSender.getEffectivePermissions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String arg0) {
|
||||
if (commandSender.hasPermission(CommonsConst.PERMISSION_PREFIX + ".cmd.all")) {
|
||||
return true;
|
||||
}
|
||||
if (commandSender.hasPermission(CommonsConst.PERMISSION_PREFIX + ".cmd." + arg0)) {
|
||||
return true;
|
||||
}
|
||||
commandSender.sendMessage(BukkitMessages.VOCE_NAO_TEM_PERMISSãO_PARA_USAR_ESTE_COMANDO);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Permission arg0) {
|
||||
return commandSender.hasPermission(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(String arg0) {
|
||||
return commandSender.isPermissionSet(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(Permission arg0) {
|
||||
return commandSender.isPermissionSet(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculatePermissions() {
|
||||
commandSender.recalculatePermissions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttachment(PermissionAttachment arg0) {
|
||||
commandSender.removeAttachment(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOp() {
|
||||
return commandSender.isOp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOp(boolean arg0) {
|
||||
commandSender.setOp(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return commandSender.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Server getServer() {
|
||||
return commandSender.getServer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String arg0) {
|
||||
commandSender.sendMessage(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String[] arg0) {
|
||||
commandSender.sendMessage(arg0);
|
||||
}
|
||||
|
||||
public String getArgs(String[] args, int começo) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
for (int i = começo; i < args.length; i++) {
|
||||
stringBuilder.append(args[i]).append(" ");
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.commands.register;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.BukkitServerAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.menu.MenuListener;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.commands.BukkitCommandSender;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.menu.AccountInventory;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandClass;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandFramework.Command;
|
||||
import com.br.guilhermematthew.nowly.commons.common.connections.mysql.MySQLManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class AccountCommand implements CommandClass {
|
||||
|
||||
@Command(name = "account", aliases = {"acc", "perfil", "conta", "stats", "info"}, runAsync = true)
|
||||
public void account(BukkitCommandSender commandSender, String label, String[] args) {
|
||||
if (!commandSender.isPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MenuListener.isOpenMenus()) {
|
||||
commandSender.sendMessage("§cVocê não pode abrir menus agora.");
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = commandSender.getPlayer();
|
||||
|
||||
final String nickViewer = BukkitServerAPI.getRealNick(player);
|
||||
|
||||
if (args.length == 1) {
|
||||
if (!commandSender.hasPermission("account")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String nick = MySQLManager.getString("accounts", "nick", args[0], "nick");
|
||||
if (nick.equalsIgnoreCase("N/A")) {
|
||||
commandSender.sendMessage(BukkitMessages.NAO_TEM_CONTA);
|
||||
return;
|
||||
}
|
||||
new AccountInventory(nickViewer, nick).open(player);
|
||||
} else {
|
||||
new AccountInventory(nickViewer, nickViewer).open(player);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.commands.register;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.vanish.VanishAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.commands.BukkitCommandSender;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandClass;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandFramework.Command;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
|
||||
public class AdminCommand implements CommandClass {
|
||||
|
||||
@Command(name = "admin", aliases = {"adm", "v"}, groupsToUse = Groups.PRIME)
|
||||
public void admin(BukkitCommandSender commandSender, String label, String[] args) {
|
||||
if (!commandSender.isPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
VanishAPI.changeAdmin(commandSender.getPlayer());
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.commands.register;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.BukkitServerAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.commands.BukkitCommandSender;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandClass;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandFramework.Command;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
import com.br.guilhermematthew.nowly.commons.common.utility.string.StringUtility;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class BroadCastCommand implements CommandClass {
|
||||
|
||||
@Command(name = "broadcast", aliases = {"bc"}, groupsToUse = {Groups.MOD})
|
||||
public void broadcast(BukkitCommandSender commandSender, String label, String[] args) {
|
||||
if (args.length == 0) {
|
||||
commandSender.sendMessage(BukkitMessages.BROADCAST_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.broadcastMessage(BukkitMessages.BROADCAST_PREFIX + StringUtility.createArgs(0, args).replaceAll("&", "§"));
|
||||
if (!commandSender.getNick().equalsIgnoreCase("CONSOLE")) {
|
||||
BukkitServerAPI.warnStaff("§7[" + BukkitServerAPI.getRealNick(commandSender.getPlayer()) + " utilizou o BroadCast!]", Groups.ADMIN);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.commands.register;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitSettings;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.BukkitServerAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.commands.BukkitCommandSender;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandClass;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandFramework.Command;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ChatCommand implements CommandClass {
|
||||
|
||||
@Command(name = "chat", groupsToUse = {Groups.MOD})
|
||||
public void chat(BukkitCommandSender commandSender, String label, String[] args) {
|
||||
if (BukkitSettings.CHAT_OPTION) {
|
||||
BukkitSettings.CHAT_OPTION = false;
|
||||
|
||||
Bukkit.broadcastMessage(BukkitMessages.CHAT_DESATIVADO);
|
||||
|
||||
if (!commandSender.getNick().equalsIgnoreCase("CONSOLE")) {
|
||||
BukkitServerAPI.warnStaff("§7[" + BukkitServerAPI.getRealNick(commandSender.getPlayer()) + " desativou o Chat!]", Groups.ADMIN);
|
||||
}
|
||||
} else {
|
||||
BukkitSettings.CHAT_OPTION = true;
|
||||
Bukkit.broadcastMessage(BukkitMessages.CHAT_ATIVADO);
|
||||
|
||||
if (!commandSender.getNick().equalsIgnoreCase("CONSOLE")) {
|
||||
BukkitServerAPI.warnStaff("§7[" + BukkitServerAPI.getRealNick(commandSender.getPlayer()) + " ativou o Chat!]", Groups.ADMIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(name = "clearchat", aliases = {"cc"}, groupsToUse = {Groups.MOD})
|
||||
public void clearChat(BukkitCommandSender commandSender, String label, String[] args) {
|
||||
for (Player on : Bukkit.getOnlinePlayers()) {
|
||||
for (int i = 0; i <= 100; i++) {
|
||||
on.sendMessage("");
|
||||
}
|
||||
}
|
||||
Bukkit.broadcastMessage(BukkitMessages.CHAT_LIMPO);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.commands.register;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.BukkitServerAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.commands.BukkitCommandSender;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandClass;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandFramework.Command;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClearDropsCommand implements CommandClass {
|
||||
|
||||
@Command(name = "cleardrops", aliases = {"cd"}, groupsToUse = {Groups.MOD})
|
||||
public void clearDrops(BukkitCommandSender commandSender, String label, String[] args) {
|
||||
int removidos = 0;
|
||||
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
List<Entity> items = world.getEntities();
|
||||
|
||||
for (Entity item : items) {
|
||||
if (item instanceof Item) {
|
||||
item.remove();
|
||||
removidos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
commandSender.sendMessage(BukkitMessages.CLEAR_DROPS.replace("%quantia%", "" + removidos));
|
||||
|
||||
if (!commandSender.getNick().equalsIgnoreCase("CONSOLE")) {
|
||||
BukkitServerAPI.warnStaff("§7[" + BukkitServerAPI.getRealNick(commandSender.getPlayer()) + " limpou o chão!]", Groups.ADMIN);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.br.guilhermematthew.nowly.commons.bukkit.commands.register;
|
||||
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitMessages;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.BukkitSettings;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.api.BukkitServerAPI;
|
||||
import com.br.guilhermematthew.nowly.commons.bukkit.commands.BukkitCommandSender;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandClass;
|
||||
import com.br.guilhermematthew.nowly.commons.common.command.CommandFramework.Command;
|
||||
import com.br.guilhermematthew.nowly.commons.common.group.Groups;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class DanoCommand implements CommandClass {
|
||||
|
||||
@Command(name = "dano", groupsToUse = {Groups.MOD})
|
||||
public void dano(BukkitCommandSender commandSender, String label, String[] args) {
|
||||
if (BukkitSettings.DANO_OPTION) {
|
||||
BukkitSettings.DANO_OPTION = false;
|
||||
Bukkit.broadcastMessage(BukkitMessages.DANO_DESATIVADO);
|
||||
} else {
|
||||
BukkitSettings.DANO_OPTION = true;
|
||||
Bukkit.broadcastMessage(BukkitMessages.DANO_ATIVADO);
|
||||
}
|
||||
|
||||
if (!commandSender.getNick().equalsIgnoreCase("CONSOLE")) {
|
||||
BukkitServerAPI.warnStaff("§7[" + BukkitServerAPI.getRealNick(commandSender.getPlayer()) + " "
|
||||
+ (BukkitSettings.DANO_OPTION ? "ativou" : "desativou") + " o Dano!]", Groups.ADMIN);
|
||||
}
|
||||
}
|
||||
|
||||
@Command(name = "pvp", groupsToUse = {Groups.MOD})
|
||||
public void pvp(BukkitCommandSender commandSender, String label, String[] args) {
|
||||
if (BukkitSettings.PVP_OPTION) {
|
||||
BukkitSettings.PVP_OPTION = false;
|
||||
Bukkit.broadcastMessage(BukkitMessages.PVP_DESATIVADO);
|
||||
} else {
|
||||
BukkitSettings.PVP_OPTION = true;
|
||||
Bukkit.broadcastMessage(BukkitMessages.PVP_ATIVADO);
|
||||
}
|
||||
|
||||
if (!commandSender.getNick().equalsIgnoreCase("CONSOLE")) {
|
||||
BukkitServerAPI.warnStaff("§7[" + BukkitServerAPI.getRealNick(commandSender.getPlayer()) + " "
|
||||
+ (BukkitSettings.PVP_OPTION ? "ativou" : "desativou") + " o PvP!]", Groups.ADMIN);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user