Stefatorus
4 years ago
commit
fd8c45bd7b
34 changed files with 2256 additions and 0 deletions
@ -0,0 +1,20 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<classpath> |
|||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"> |
|||
<attributes> |
|||
<attribute name="maven.pomderived" value="true"/> |
|||
</attributes> |
|||
</classpathentry> |
|||
<classpathentry kind="src" path="src"/> |
|||
<classpathentry excluding="**" kind="src" output="target/classes" path="resources"> |
|||
<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> |
@ -0,0 +1,2 @@ |
|||
target/ |
|||
bin/ |
@ -0,0 +1,23 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<projectDescription> |
|||
<name>AFKGuard</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.m2e.core.maven2Nature</nature> |
|||
<nature>org.eclipse.jdt.core.javanature</nature> |
|||
</natures> |
|||
</projectDescription> |
@ -0,0 +1,3 @@ |
|||
eclipse.preferences.version=1 |
|||
encoding/<project>=UTF-8 |
|||
encoding/resources=UTF-8 |
@ -0,0 +1,14 @@ |
|||
eclipse.preferences.version=1 |
|||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled |
|||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate |
|||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 |
|||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve |
|||
org.eclipse.jdt.core.compiler.compliance=1.8 |
|||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate |
|||
org.eclipse.jdt.core.compiler.debug.localVariable=generate |
|||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate |
|||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error |
|||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error |
|||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning |
|||
org.eclipse.jdt.core.compiler.release=disabled |
|||
org.eclipse.jdt.core.compiler.source=1.8 |
@ -0,0 +1,4 @@ |
|||
activeProfiles= |
|||
eclipse.preferences.version=1 |
|||
resolveWorkspaceProjects=true |
|||
version=1 |
@ -0,0 +1,88 @@ |
|||
<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"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
|
|||
<groupId>com.entryrise</groupId> |
|||
<artifactId>afkguard</artifactId> |
|||
<version>0.2</version> |
|||
<packaging>jar</packaging> |
|||
|
|||
<name>AFKGuard</name> |
|||
<url>http://maven.apache.org</url> |
|||
|
|||
<properties> |
|||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
|||
<plugin.description>Guard against AFKers</plugin.description> |
|||
</properties> |
|||
|
|||
<build> |
|||
<finalName>${project.name}</finalName> |
|||
<directory>target</directory> |
|||
<sourceDirectory>src</sourceDirectory> |
|||
<resources> |
|||
<resource> |
|||
<directory>resources</directory> |
|||
<filtering>true</filtering> |
|||
<includes> |
|||
<include>*</include> |
|||
</includes> |
|||
</resource> |
|||
</resources> |
|||
<plugins> |
|||
<!-- Set a compiler level --> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-compiler-plugin</artifactId> |
|||
<version>2.3.2</version> |
|||
<configuration> |
|||
<source>1.8</source> |
|||
<target>1.8</target> |
|||
</configuration> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
|
|||
<repositories> |
|||
<repository> |
|||
<id>spigot-repo</id> |
|||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url> |
|||
</repository> |
|||
<repository> |
|||
<id>mikeprimm-repo</id> |
|||
<url>http://repo.mikeprimm.com/</url> |
|||
</repository> |
|||
<repository> |
|||
<id>jitpack.io</id> |
|||
<url>https://jitpack.io</url> |
|||
</repository> |
|||
</repositories> |
|||
|
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.spigotmc</groupId> |
|||
<artifactId>spigot-api</artifactId> |
|||
<!-- Peasants don't update or use new features :D --> |
|||
<version>1.8.8-R0.1-SNAPSHOT</version> |
|||
<scope>provided</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.mojang</groupId> |
|||
<artifactId>authlib</artifactId> |
|||
<version>1.5.13</version> |
|||
<scope>provided</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
<version>1.18.20</version> |
|||
<scope>provided</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.github.MilkBowl</groupId> |
|||
<artifactId>VaultAPI</artifactId> |
|||
<version>1.7</version> |
|||
<scope>provided</scope> |
|||
</dependency> |
|||
</dependencies> |
|||
</project> |
@ -0,0 +1,11 @@ |
|||
name: ${project.name} |
|||
author: Stefatorus |
|||
version: ${project.version} |
|||
api-version: 1.13 |
|||
description: ${plugin.description} |
|||
main: ${project.groupId}.${project.artifactId}.Main |
|||
depend: [Vault] |
|||
commands: |
|||
${project.name}: |
|||
description: command reserved for plugin |
|||
|
@ -0,0 +1,190 @@ |
|||
# Plugin config |
|||
# ______ _ _______ _ |
|||
# /\ | ____| |/ / ____| | | |
|||
# / \ | |__ | ' / | __ _ _ __ _ _ __ __| | |
|||
# / /\ \ | __| | <| | |_ | | | |/ _` | '__/ _` | |
|||
# / ____ \| | | . \ |__| | |_| | (_| | | | (_| | |
|||
# /_/ \_\_| |_|\_\_____|\__,_|\__,_|_| \__,_| |
|||
# |
|||
# By EntryRise S.R.L - https://www.entryrise.com |
|||
# |
|||
# Support at: |
|||
# - https://www.entryrise.com/discord |
|||
# - Stefatorus#9382 |
|||
# |
|||
|
|||
settings: |
|||
# The AFK detection system of AFKGuard uses a score system |
|||
# to allow you to have complete control on the way AFKGuard |
|||
# checks if players are actually AFK or just less active. |
|||
# |
|||
# (!) We recommend testing once you change settings here, |
|||
# as not to affect normal players. |
|||
afk-detection: |
|||
# The punishment table allows you to run actions when a player is found to be afk-ing. |
|||
# |
|||
# This allows you to discourage AFK-ing without outright kicking players. |
|||
# |
|||
# Current actions: |
|||
# cmd:<COMMAND TO RUN>:<COUNTER TO RESET TO> - Run a command |
|||
# payment:<MONEY>:<COUNTER TO RESET TO> - Force player to pay money to stay AFK. If he pays, the punishment value will not increment. Useful for charging for chunk loading bots. |
|||
# captcha:<COUNTER TO RESET TO> - Send the player a captcha he will need to complete to reset his punishment value. |
|||
# |
|||
# If there are multiple counters, it will reset to the last counter in the action chain. |
|||
punishment-table: |
|||
5: |
|||
# The player will have to run a captcha. If he does, the counter will reset to 3. If not, the counter will keep ticking. |
|||
- "captcha:3" |
|||
6: |
|||
# Force player to pay 3000 if he wants the counter not to increment. Useful for regulating AFK farms. |
|||
- "payment:3000:5" |
|||
# If the player fails to complete the captcha or pay, kick the player out, and set his counter to 0. |
|||
10: |
|||
- "cmd:kick %player% AFK-ing too much!:0" |
|||
# |
|||
# The counter is based on scores to allow better management of what is considered AFK or just low activity from the player. |
|||
# The calculation is done the following way: |
|||
# |
|||
# Each counter cycle (configurable timer), the score will reset to the starting score you configure. Each action they do will |
|||
# slowly reduce the score, until it reaches 0. If the score is above 0, the player is considered to be AFK at that minute. |
|||
# If the player is AFK, we increase counter by one. Otherwise, we decrease by one. |
|||
counter: |
|||
# 1200 ticks = 1 minute |
|||
timer: 1200 |
|||
# What should be the starting score. Larger = easier to get flagged as AFK. |
|||
start-score: 100 |
|||
# How much should we decrease the afk score when player proves not to be AFK? |
|||
# |
|||
# (!) Setting it to a smaller amount (eg: 1) will allow for activity checkup, meaning |
|||
# even small amounts of inactivity will get punished. |
|||
decrease-amount: 5 |
|||
# What actions should reduce the score. Larger values here = harder to get flagged as AFK. |
|||
actions: |
|||
# What should we reduce the score by each chat message |
|||
chat: 15 |
|||
# People can afk and block break, but for sanity purposes, we gave block breaking a minimal value. |
|||
# This should allow people to mine normally, but not AFK at generators. |
|||
block-break: 1 |
|||
# Placing blocks is harder to do while AFK, so we give it a higher value. |
|||
block-place: 5 |
|||
# The movement check multiplies blocks moved by the value underlined here. I recommend as smaller value, as |
|||
# people can AFK in minecarts to move larger distances. |
|||
# |
|||
# (!) This also accounts for teleportation, which will almost never be done by AFK bots. |
|||
# Please note this uses the movement*movement, so for 10 blocks moved, the value will actually be 100 blocks * location-movement. |
|||
location-movement: 0.07 |
|||
# Movement riding something. This should be set low to account for minecart afk machines. |
|||
riding-movement: 0.01 |
|||
# Mouse movement multiplies by the angle difference between player's current looking angle, and his previous |
|||
# angle. |
|||
# |
|||
# (!) Non-hacking afk farms will have this always equal to 0, as the mouse is not moved. |
|||
# |
|||
# Example: Looking the opposite way, your movement would be 180 * 0.2 = 36 (YAW) + 30 * 0.2 = 6 (PITCH) |
|||
mouse-movement: 0.01 |
|||
# World change is rarely done by AFK actors, meaning that we can assign a high value to it. |
|||
world-movement: 75 |
|||
# Picking up items can be done by bots, so we will actually reduce the score by a slight amount on item pickup. |
|||
# |
|||
# Example: Picking 5 stacks = -5 |
|||
pickup-item: -1.0 |
|||
# Generally, players will sprint when they need to move around. We can reduce the score when player toggles sprinting on. |
|||
toggle-sprint: 5.0 |
|||
# Flight is rarely implemented by cheats, so it can be a good check for creative servers. |
|||
toggle-flight: 15.0 |
|||
# Bots are often used for fishing. Penalize players when they are fishing. |
|||
fishing: -5.0 |
|||
# |
|||
# The captcha tool is used to verify if people are AFK-ing or if they are properly in game. It is intrusive, so players will definetly see |
|||
# it and have time to react. |
|||
captcha: |
|||
# What should we do on failed attempt. |
|||
fail-command: "kick %player% You failed the AFK Captcha" |
|||
# What should we run on success attempt. |
|||
success-command: "bc %player% You sucessfully finished the afk captcha" |
|||
# The categories for validating if player is afk. |
|||
# |
|||
# (!) THESE ARE VERSION DEPENDANT. USING INVALID VALUES WILL LEAD TO ERRORS. |
|||
gui: |
|||
title: "&0&lCaptcha: &8&l%category%" |
|||
glass-pane: |
|||
material: "LIME_STAINED_GLASS_PANE" |
|||
name: "&7" |
|||
lore: |
|||
- "" |
|||
shiny: false |
|||
example: |
|||
# Material will get replaced during execution. |
|||
material: "PAPER" |
|||
name: "&e&lAnswer Example" |
|||
lore: |
|||
- "" |
|||
- "&7This is an example of a" |
|||
- "&7correct answer" |
|||
- "" |
|||
shiny: false |
|||
item: |
|||
# Material will get replaced during execution. |
|||
material: "PAPER" |
|||
name: "&c&lChoose Answer" |
|||
lore: |
|||
- "" |
|||
- "&7Click here if you feel" |
|||
- "&7this is the correct answer" |
|||
- "" |
|||
shiny: false |
|||
|
|||
categories: |
|||
Stairs: |
|||
- "PURPUR_STAIRS" |
|||
- "OAK_STAIRS" |
|||
- "COBBLESTONE_STAIRS" |
|||
- "BRICK_STAIRS" |
|||
- "STONE_BRICK_STAIRS" |
|||
- "SANDSTONE_STAIRS" |
|||
Fence: |
|||
- "OAK_FENCE" |
|||
- "SPRUCE_FENCE" |
|||
- "BIRCH_FENCE" |
|||
- "JUNGLE_FENCE" |
|||
- "ACACIA_FENCE" |
|||
- "DARK_OAK_FENCE" |
|||
Log: |
|||
- "OAK_LOG" |
|||
- "SPRUCE_LOG" |
|||
- "BIRCH_LOG" |
|||
- "JUNGLE_LOG" |
|||
- "ACACIA_LOG" |
|||
- "DARK_OAK_LOG" |
|||
Sapling: |
|||
- "OAK_SAPLING" |
|||
- "SPRUCE_SAPLING" |
|||
- "BIRCH_SAPLING" |
|||
- "JUNGLE_SAPLING" |
|||
- "ACACIA_SAPLING" |
|||
- "DARK_OAK_SAPLING" |
|||
Wool: |
|||
- "WHITE_WOOL" |
|||
- "ORANGE_WOOL" |
|||
- "MAGENTA_WOOL" |
|||
- "LIGHT_BLUE_WOOL" |
|||
- "YELLOW_WOOL" |
|||
- "LIME_WOOL" |
|||
- "PINK_WOOL" |
|||
- "GRAY_WOOL" |
|||
- "LIGHT_GRAY_WOOL" |
|||
- "CYAN_WOOL" |
|||
Spawnegg: |
|||
- "BAT_SPAWN_EGG" |
|||
- "BLAZE_SPAWN_EGG" |
|||
- "CHICKEN_SPAWN_EGG" |
|||
- "COD_SPAWN_EGG" |
|||
- "COW_SPAWN_EGG" |
|||
- "CREEPER_SPAWN_EGG" |
|||
- "DOLPHIN_SPAWN_EGG" |
|||
- "DONKEY_SPAWN_EGG" |
|||
- "DROWNED_SPAWN_EGG" |
|||
|
|||
|
|||
# Version is used for future updates |
|||
version: 1 |
@ -0,0 +1,133 @@ |
|||
package com.entryrise.afkguard; |
|||
|
|||
import java.io.File; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.Material; |
|||
import org.bukkit.OfflinePlayer; |
|||
import org.bukkit.command.CommandSender; |
|||
import org.bukkit.configuration.file.FileConfiguration; |
|||
import org.bukkit.configuration.file.YamlConfiguration; |
|||
import org.bukkit.entity.Player; |
|||
import org.bukkit.event.Listener; |
|||
import org.bukkit.plugin.RegisteredServiceProvider; |
|||
import org.bukkit.plugin.java.JavaPlugin; |
|||
|
|||
import com.entryrise.afkguard.antiafk.AFKManager; |
|||
import com.entryrise.afkguard.antiafk.captcha.CaptchaCategory; |
|||
import com.entryrise.afkguard.antiafk.captcha.CaptchaGUI; |
|||
import com.entryrise.afkguard.antiafk.captcha.CaptchaGUI.CaptchaData; |
|||
import com.entryrise.afkguard.cmd.CommandListener; |
|||
import com.entryrise.afkguard.cmd.CommandTabListener; |
|||
import com.entryrise.afkguard.listeners.ListenersMain; |
|||
import com.entryrise.afkguard.utils.Others; |
|||
import com.entryrise.afkguard.utils.VersionMgr; |
|||
|
|||
import net.milkbowl.vault.economy.Economy; |
|||
|
|||
public class Main extends JavaPlugin implements Listener { |
|||
|
|||
public static String USER = "%%__USER__%%"; |
|||
public static final String PREFIX = "§2§lAFK§f§lGuard §e» §f"; |
|||
|
|||
public static JavaPlugin p; |
|||
public static boolean paper = false; |
|||
|
|||
private static File file; |
|||
public static FileConfiguration config = new YamlConfiguration(); |
|||
|
|||
public static Economy econ; |
|||
|
|||
public void onEnable() { |
|||
p = this; |
|||
|
|||
file = new File(getDataFolder(), "server.yml"); |
|||
config = Others.getConfig(file, 1); |
|||
|
|||
paper = VersionMgr.isPaper(); |
|||
|
|||
Bukkit.getLogger().info(PREFIX + "Enabling Systems:"); |
|||
|
|||
setupEconomy(); |
|||
EnableClasses(false); |
|||
|
|||
getServer().getPluginManager().registerEvents(this, this); |
|||
getCommand("afkguard").setExecutor(new CommandListener()); |
|||
getCommand("afkguard").setTabCompleter(new CommandTabListener()); |
|||
} |
|||
|
|||
private boolean setupEconomy() { |
|||
if (getServer().getPluginManager().getPlugin("Vault") == null) { |
|||
return false; |
|||
} |
|||
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class); |
|||
if (rsp == null) { |
|||
return false; |
|||
} |
|||
econ = rsp.getProvider(); |
|||
return econ != null; |
|||
} |
|||
|
|||
|
|||
private static void EnableClasses(boolean reload) { |
|||
ListenersMain.Enabler(reload); |
|||
CaptchaCategory.Enabler(reload); |
|||
AFKManager.Enabler(reload); |
|||
} |
|||
|
|||
public static void ReloadPlugin(CommandSender s) { |
|||
config = Others.getConfig(file, 1); |
|||
|
|||
Bukkit.getLogger().info(PREFIX + "Reloading Systems:"); |
|||
EnableClasses(true); |
|||
|
|||
s.sendMessage(PREFIX + "Reloaded the config successfully."); |
|||
} |
|||
|
|||
@Override |
|||
public void onDisable() { |
|||
// PacketInjector.Disabler(); <- SEEMS UNIMPORTANT AND GLITCHY
|
|||
} |
|||
|
|||
public static void failedAttempt(Player p) { |
|||
CaptchaGUI.invs.remove(p.getUniqueId()); |
|||
p.closeInventory(); |
|||
// p.kickPlayer(getKickMsg());
|
|||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), Main.config.getString("settings.captcha.fail-command").replace("%player%", p.getName())); |
|||
} |
|||
|
|||
public static void goodAttempt(Player p, int target) { |
|||
CaptchaGUI.invs.remove(p.getUniqueId()); |
|||
p.closeInventory(); |
|||
// p.sendMessage(getSuccessfulsg());
|
|||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), Main.config.getString("settings.captcha.success-command").replace("%player%", p.getName())); |
|||
AFKManager.setScore(p, target); |
|||
} |
|||
|
|||
public static void captchaResult(Player p, Material mat) { |
|||
CaptchaData cd = CaptchaGUI.invs.get(p.getUniqueId()); |
|||
if (!cd.category.getAllowed().contains(mat)) { |
|||
failedAttempt(p); |
|||
return; |
|||
} |
|||
|
|||
goodAttempt(p, cd.counter); |
|||
} |
|||
|
|||
public static void openCapcha(Player p, int resetcounter) { |
|||
Bukkit.getScheduler().runTaskLater(Main.p, () -> p.openInventory(CaptchaGUI.getInventory(p, resetcounter)), 20); |
|||
} |
|||
|
|||
|
|||
public static void penalizePlayer(Player p, double payment, int reset) { |
|||
OfflinePlayer op = Bukkit.getOfflinePlayer(p.getUniqueId()); |
|||
|
|||
if (!econ.has(op, payment)) { |
|||
return; |
|||
} |
|||
|
|||
econ.withdrawPlayer(op, payment); |
|||
AFKManager.setScore(p, reset); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,74 @@ |
|||
package com.entryrise.afkguard.antiafk; |
|||
|
|||
import java.util.Map; |
|||
import java.util.WeakHashMap; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.entity.Player; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
|
|||
import lombok.Getter; |
|||
|
|||
public class AFKManager { |
|||
|
|||
/* |
|||
* Using a weak hashmap allows the values to disappear on player quit. May be |
|||
* changed to UUID if we notice bots use this to bypass checks by constantly |
|||
* rejoining. |
|||
*/ |
|||
@Getter |
|||
private static Map<Player, AFKPlayer> players = new WeakHashMap<>(); |
|||
|
|||
/* |
|||
* Increment player score in the hashmap. |
|||
*/ |
|||
|
|||
public static void Enabler(boolean reload) { |
|||
if (!reload) { |
|||
runTask(); |
|||
} |
|||
|
|||
Bukkit.getLogger().info(" §e[§a✔§e] §fAFK Manager"); |
|||
} |
|||
|
|||
private static void runTask() { |
|||
int timer = Main.config.getInt("settings.afk-detection.counter.timer"); |
|||
Bukkit.getScheduler().runTaskTimer(Main.p, () -> { |
|||
for(Player p : Bukkit.getOnlinePlayers()) { |
|||
|
|||
if (p.hasPermission("afkguard.bypass.admin")) { |
|||
continue; |
|||
} |
|||
|
|||
players.getOrDefault(p, new AFKPlayer()).isAfk(p); |
|||
} |
|||
}, timer, timer); |
|||
} |
|||
|
|||
public static void incrementPlayer(Player p, double d) { |
|||
players.compute(p, (k, v) -> { |
|||
v = v == null ? new AFKPlayer() : v; |
|||
v.addScore(d); |
|||
return v; |
|||
}); |
|||
} |
|||
|
|||
public static void setScore(Player p, int score) { |
|||
if (score < 0) { |
|||
return; |
|||
} |
|||
|
|||
players.compute(p, (k, v) -> { |
|||
v = v == null ? new AFKPlayer() : v; |
|||
|
|||
v.setAfkcycles(score); |
|||
|
|||
return v; |
|||
}); |
|||
} |
|||
|
|||
public static int getScore(Player p) { |
|||
return players.getOrDefault(p, new AFKPlayer()).getAfkcycles(); |
|||
} |
|||
} |
@ -0,0 +1,68 @@ |
|||
package com.entryrise.afkguard.antiafk; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.entity.Player; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
import com.entryrise.afkguard.utils.MathUtils; |
|||
|
|||
import lombok.Getter; |
|||
import lombok.Setter; |
|||
|
|||
public class AFKPlayer { |
|||
|
|||
private double score; |
|||
|
|||
@Getter |
|||
@Setter |
|||
private int afkcycles; |
|||
|
|||
public AFKPlayer() { |
|||
score = Main.config.getInt("settings.afk-detection.counter.start-score"); |
|||
afkcycles = 0; |
|||
} |
|||
|
|||
/* |
|||
* Returns -1 = Decrease Returns +1 = Increase Returns 0 = Stays still. (No |
|||
* usage yet) |
|||
* |
|||
* It also sets the afkcycles and makes sure it doesn't go under 0. |
|||
*/ |
|||
private int calculateCycles(Player p) { |
|||
afkcycles = score > 0 ? afkcycles + 1 : Math.max(0, afkcycles - Main.config.getInt("settings.afk-detection.counter.decrease-amount")); |
|||
return score > 0 ? 1 : -1; |
|||
} |
|||
|
|||
public void addScore(double increment) { |
|||
score -= increment; |
|||
} |
|||
|
|||
public boolean isAfk(Player p) { |
|||
|
|||
// If the player was found to be AFK, it means there was a change in cyclecount.
|
|||
//
|
|||
// This means we should check for actions to run.
|
|||
if (calculateCycles(p) == 1) { |
|||
for (String stg : Main.config.getStringList("settings.afk-detection.punishment-table." + afkcycles)) { |
|||
String[] result = stg.split(":"); |
|||
|
|||
int reset = MathUtils.isInt(result[result.length - 1]) ? Integer.valueOf(result[result.length - 1]) |
|||
: -1; |
|||
|
|||
if (result[0].equalsIgnoreCase("cmd") && result.length >= 2 && !p.hasPermission("afkguard.bypass.cmd")) { |
|||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), result[1].replace("%player%", p.getName())); |
|||
AFKManager.setScore(p, reset); |
|||
} else if (result[0].equalsIgnoreCase("payment") && !p.hasPermission("afkguard.bypass.payment")) { |
|||
double payment = MathUtils.isInt(result[1]) ? Integer.valueOf(result[1]) : 0; |
|||
Main.penalizePlayer(p, payment, reset); |
|||
} else if (result[0].equalsIgnoreCase("captcha") && !p.hasPermission("afkguard.bypass.captcha")) { |
|||
Main.openCapcha(p, reset); |
|||
} |
|||
} |
|||
} |
|||
|
|||
score = Main.config.getDouble("settings.afk-detection.counter.start-score"); |
|||
|
|||
return false; |
|||
} |
|||
} |
@ -0,0 +1,90 @@ |
|||
package com.entryrise.afkguard.antiafk.captcha; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Collections; |
|||
import java.util.List; |
|||
import java.util.SplittableRandom; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.Material; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
|
|||
public class CaptchaCategory { |
|||
|
|||
private static SplittableRandom sr = new SplittableRandom(); |
|||
private static List<CaptchaCategory> categories = new ArrayList<CaptchaCategory>(); |
|||
|
|||
public static void Enabler(boolean reload) { |
|||
if (!reload) { |
|||
Main.p.getServer().getPluginManager().registerEvents(new CaptchaGUI(), Main.p); |
|||
} |
|||
for (String stg : Main.config.getConfigurationSection("settings.captcha.categories").getKeys(false)) { |
|||
categories.add(new CaptchaCategory(stg)); |
|||
|
|||
} |
|||
Bukkit.getLogger().info(" §e[§a✔§e] §fCategories Added"); |
|||
} |
|||
|
|||
public static CaptchaCategory getCategory(CaptchaCategory exception) { |
|||
// For safety if the random randomly breaks out of some reason or another.
|
|||
// Will render plugin kind of unsafe but still usable and won't crash server.
|
|||
int i = 50; |
|||
CaptchaCategory categ; |
|||
do { |
|||
categ = categories.get(sr.nextInt(categories.size())); |
|||
} while (categ.equals(exception) && --i > 0); |
|||
|
|||
return categ; |
|||
} |
|||
|
|||
public List<Material> getShuffledFiller() { |
|||
List<Material> raw = new ArrayList<Material>(); |
|||
for (CaptchaCategory cat : categories) { |
|||
if (cat.equals(this)) { |
|||
continue; |
|||
} |
|||
for (int i = 0; i < 5; i++) { |
|||
raw.addAll(cat.members); |
|||
} |
|||
} |
|||
|
|||
Collections.shuffle(raw); |
|||
return raw; |
|||
} |
|||
|
|||
// This is where objective stuff starts and no more statics roam the land.
|
|||
|
|||
private List<Material> members = new ArrayList<Material>(); |
|||
private String name; |
|||
|
|||
private CaptchaCategory(String name) { |
|||
String loc = "settings.captcha.categories." + name; |
|||
|
|||
this.name = name; |
|||
for (String stg : Main.config.getStringList(loc)) { |
|||
members.add(Material.getMaterial(stg)); |
|||
} |
|||
} |
|||
|
|||
public Material getRandom(Material exception) { |
|||
// For safety if the random randomly breaks out of some reason or another.
|
|||
// Will render plugin kind of unsafe but still usable and won't crash server.
|
|||
int i = 50; |
|||
Material mat; |
|||
do { |
|||
mat = members.get(sr.nextInt(members.size())); |
|||
} while (mat.equals(exception) && --i > 0); |
|||
|
|||
return mat; |
|||
} |
|||
|
|||
public String getName() { |
|||
return name; |
|||
} |
|||
|
|||
public List<Material> getAllowed() { |
|||
return members; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,216 @@ |
|||
package com.entryrise.afkguard.antiafk.captcha; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.SplittableRandom; |
|||
import java.util.UUID; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.ChatColor; |
|||
import org.bukkit.Material; |
|||
import org.bukkit.entity.HumanEntity; |
|||
import org.bukkit.entity.Player; |
|||
import org.bukkit.event.EventHandler; |
|||
import org.bukkit.event.Listener; |
|||
import org.bukkit.event.inventory.InventoryClickEvent; |
|||
import org.bukkit.event.inventory.InventoryCloseEvent; |
|||
import org.bukkit.inventory.Inventory; |
|||
import org.bukkit.inventory.ItemStack; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
import com.entryrise.afkguard.mineutils.ItemBuilder; |
|||
|
|||
|
|||
public class CaptchaGUI implements Listener { |
|||
|
|||
public static List<Integer> filler = new ArrayList<Integer>(); |
|||
private static SplittableRandom sr = new SplittableRandom(); |
|||
|
|||
// Fillers where selector items can stay;
|
|||
static { |
|||
for (int i = 19; i < 26; i++) { |
|||
filler.add(i); |
|||
} |
|||
for (int i = 28; i < 35; i++) { |
|||
filler.add(i); |
|||
} |
|||
for (int i = 37; i < 44; i++) { |
|||
filler.add(i); |
|||
} |
|||
|
|||
filler.add(10); |
|||
filler.add(11); |
|||
filler.add(15); |
|||
filler.add(16); |
|||
} |
|||
|
|||
public static class CaptchaData { |
|||
|
|||
public CaptchaCategory category; |
|||
public Material example; |
|||
public Inventory inv; |
|||
|
|||
public int counter; |
|||
|
|||
public CaptchaData() { |
|||
this.category = CaptchaCategory.getCategory(null); |
|||
this.example = category.getRandom(null); |
|||
} |
|||
|
|||
} |
|||
|
|||
public static Map<UUID, CaptchaData> invs = new HashMap<UUID, CaptchaData>(); |
|||
|
|||
public static Inventory getInventory(Player p, int counter) { |
|||
return getInventory(p.getUniqueId(), counter); |
|||
} |
|||
|
|||
public static boolean existsAlready(Player p) { |
|||
return existsAlready(p.getUniqueId()); |
|||
} |
|||
|
|||
public static boolean existsAlready(UUID u) { |
|||
|
|||
return invs.containsKey(u); |
|||
} |
|||
|
|||
public static Inventory getInventory(UUID u, int counter) { |
|||
if (existsAlready(u)) { |
|||
return invs.get(u).inv; |
|||
} else if (counter != -1) { |
|||
return createInventory(u, counter); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
private static Inventory createInventory(UUID u, int counter) { |
|||
CaptchaData cd = new CaptchaData(); |
|||
|
|||
Inventory inv = Bukkit.createInventory(null, 54, getTitle(cd.category.getName())); |
|||
|
|||
setBorders(inv); |
|||
setRandomExample(inv, cd); |
|||
setRandomAnswers(inv, cd); |
|||
|
|||
cd.inv = inv; |
|||
cd.counter = counter; |
|||
|
|||
invs.put(u, cd); |
|||
|
|||
return inv; |
|||
} |
|||
|
|||
public static String getTitle(String categoryname) { |
|||
return ChatColor.translateAlternateColorCodes('&', Main.config.getString("settings.captcha.gui.title")) |
|||
.replace("%category%", categoryname); |
|||
} |
|||
|
|||
@EventHandler |
|||
public void onInventoryClick(InventoryClickEvent e) { |
|||
|
|||
HumanEntity hm = e.getWhoClicked(); |
|||
|
|||
if (!(hm instanceof Player)) { |
|||
return; |
|||
} |
|||
|
|||
Player p = (Player) hm; |
|||
|
|||
Inventory invent = e.getInventory(); |
|||
|
|||
ItemStack itm = e.getCurrentItem(); |
|||
|
|||
if (itm == null) { |
|||
return; |
|||
} |
|||
|
|||
if (!invs.containsKey(p.getUniqueId())) { |
|||
return; |
|||
} |
|||
|
|||
if (!invent.equals(invs.get(p.getUniqueId()).inv)) { |
|||
return; |
|||
} |
|||
|
|||
// Done checks to make sure it's a verify gui. We can now do the work required.
|
|||
int slot = e.getSlot(); |
|||
|
|||
// Make sure you're not clicking anywhere except verify items.
|
|||
e.setCancelled(true); |
|||
|
|||
if (!filler.contains(slot)) { |
|||
return; |
|||
} |
|||
|
|||
Main.captchaResult(p, itm.getType()); |
|||
|
|||
} |
|||
|
|||
@EventHandler |
|||
public void onInventoryClose(InventoryCloseEvent e) { |
|||
HumanEntity hm = e.getPlayer(); |
|||
|
|||
if (!(hm instanceof Player)) { |
|||
return; |
|||
} |
|||
|
|||
Player p = (Player) hm; |
|||
|
|||
Inventory invent = e.getInventory(); |
|||
|
|||
if (!invs.containsKey(p.getUniqueId())) { |
|||
return; |
|||
} |
|||
|
|||
if (!invent.equals(invs.get(p.getUniqueId()).inv)) { |
|||
return; |
|||
} |
|||
|
|||
Bukkit.getScheduler().runTaskLater(Main.p, () -> p.openInventory(CaptchaGUI.getInventory(p, -1)), 5); |
|||
} |
|||
|
|||
public static void setBorders(Inventory inv) { |
|||
ItemStack pane = new ItemBuilder(Main.config, "settings.captcha.gui.glass-pane").build(); |
|||
for (int i = 4; i <= 49; i += 9) { |
|||
inv.setItem(i - 4, pane); |
|||
inv.setItem(i + 4, pane); |
|||
} |
|||
|
|||
for (int i = 1; i <= 7; i++) { |
|||
inv.setItem(i, pane); |
|||
inv.setItem(i + 45, pane); |
|||
} |
|||
|
|||
inv.setItem(12, pane); |
|||
inv.setItem(13, pane); |
|||
inv.setItem(14, pane); |
|||
} |
|||
|
|||
public static void setRandomExample(Inventory inv, CaptchaData cd) { |
|||
ItemStack itm = new ItemBuilder(Main.config, "settings.captcha.gui.example").setType(cd.example.name()).build(); |
|||
inv.setItem(4, itm); |
|||
} |
|||
|
|||
public static void setRandomAnswers(Inventory inv, CaptchaData cd) { |
|||
List<Material> mats = cd.category.getShuffledFiller(); |
|||
|
|||
for (int i = 0; i < filler.size(); i++) { |
|||
Material mat = mats.get(i); |
|||
int slot = filler.get(i); |
|||
|
|||
ItemStack itm = prepareItemStack(mat); |
|||
inv.setItem(slot, itm); |
|||
} |
|||
|
|||
inv.setItem(filler.get(sr.nextInt(filler.size())), prepareItemStack(cd.category.getRandom(cd.example))); |
|||
} |
|||
|
|||
private static ItemStack prepareItemStack(Material mat) { |
|||
ItemStack itm = new ItemBuilder(Main.config, "settings.captcha.gui.item").setType(mat.name()).build(); |
|||
return itm; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,59 @@ |
|||
package com.entryrise.afkguard.cmd; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.command.Command; |
|||
import org.bukkit.command.CommandExecutor; |
|||
import org.bukkit.command.CommandSender; |
|||
import org.bukkit.entity.Player; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
import com.entryrise.afkguard.antiafk.AFKManager; |
|||
import com.entryrise.afkguard.utils.MathUtils; |
|||
|
|||
public class CommandListener implements CommandExecutor { |
|||
|
|||
private static Set<Player> debug |
|||
|
|||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { |
|||
Player p = sender instanceof Player ? (Player) sender : null; |
|||
|
|||
if (p == null) { |
|||
sender.sendMessage(Main.PREFIX + "Can't run from console"); |
|||
return true; |
|||
} |
|||
|
|||
if(args.length >= 2 && args[0].equalsIgnoreCase("captcha")) { |
|||
Player pl = Bukkit.getPlayer(args[1]); |
|||
|
|||
if (pl == null) { |
|||
p.sendMessage(Main.PREFIX + "That player doesn't exist"); |
|||
return true; |
|||
} |
|||
|
|||
Main.openCapcha(pl, args.length >= 3 && MathUtils.isInt(args[2]) ? Integer.valueOf(args[2]) : 0); |
|||
} else if (args.length >= 3 && args[0].equalsIgnoreCase("setscore")) { |
|||
Player pl = Bukkit.getPlayer(args[1]); |
|||
|
|||
if (pl == null) { |
|||
p.sendMessage(Main.PREFIX + "That player doesn't exist"); |
|||
return true; |
|||
} |
|||
|
|||
AFKManager.setScore(pl, MathUtils.isInt(args[2]) ? Integer.valueOf(args[2]) : 0); |
|||
} else if (args.length >= 2 && args[0].equalsIgnoreCase("getscore")) { |
|||
Player pl = Bukkit.getPlayer(args[1]); |
|||
|
|||
if (pl == null) { |
|||
p.sendMessage(Main.PREFIX + "That player doesn't exist"); |
|||
return true; |
|||
} |
|||
|
|||
p.sendMessage(Main.PREFIX + "Player " + pl.getName() + " has score " + AFKManager.getScore(pl)); |
|||
} else |
|||
|
|||
sender.sendMessage(Main.PREFIX + "Valid args: captcha [Player] [Reset Counter], setscore [Player] [Score]"); |
|||
return true; |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,19 @@ |
|||
package com.entryrise.afkguard.cmd; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import org.bukkit.command.Command; |
|||
import org.bukkit.command.CommandSender; |
|||
import org.bukkit.command.TabCompleter; |
|||
|
|||
public class CommandTabListener implements TabCompleter { |
|||
|
|||
|
|||
public List<String> onTabComplete(CommandSender sender, Command cmd, String alias, String[] args) { |
|||
return new ArrayList<String>(); |
|||
|
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,154 @@ |
|||
package com.entryrise.afkguard.gui; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
import java.util.UUID; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.entity.Player; |
|||
import org.bukkit.event.EventHandler; |
|||
import org.bukkit.event.Listener; |
|||
import org.bukkit.event.inventory.InventoryClickEvent; |
|||
import org.bukkit.event.inventory.InventoryCloseEvent; |
|||
import org.bukkit.inventory.Inventory; |
|||
import org.bukkit.inventory.ItemStack; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
|
|||
|
|||
public abstract class GUI implements Listener { |
|||
|
|||
private int size; |
|||
private String title; |
|||
private boolean persistent; |
|||
|
|||
public Map<UUID, GUIInventory> invs = null; |
|||
|
|||
// Decorate inventory (Borders, blabla)
|
|||
public abstract void decorateInventory(Inventory inv); |
|||
|
|||
public abstract void setGUIItems(GUIInventory ginv, UUID u); |
|||
|
|||
protected boolean isPersistent() { |
|||
return persistent; |
|||
} |
|||
|
|||
public GUI getCurrentInstance() { |
|||
return this; |
|||
} |
|||
|
|||
public GUI(String title, int size, boolean persistent) { |
|||
this.title = title; |
|||
this.size = size; |
|||
this.persistent = persistent; |
|||
|
|||
invs = new HashMap<UUID, GUIInventory>(); |
|||
|
|||
Bukkit.getPluginManager().registerEvents(this, Main.p); |
|||
} |
|||
|
|||
public void openInventory(Player p) { |
|||
p.openInventory(getInventory(p)); |
|||
} |
|||
|
|||
public Inventory getInventory(Player p) { |
|||
UUID u = p.getUniqueId(); |
|||
|
|||
if (invs.containsKey(u)) { |
|||
return invs.get(u).inv; |
|||
} |
|||
|
|||
return createInventory(u); |
|||
} |
|||
|
|||
private Inventory createInventory(UUID u) { |
|||
Inventory inv = Bukkit.createInventory(null, size, title); |
|||
|
|||
decorateInventory(inv); |
|||
|
|||
GUIInventory ginv = new GUIInventory(inv); |
|||
|
|||
invs.put(u, ginv); |
|||
|
|||
setGUIItems(ginv, u); |
|||
|
|||
return inv; |
|||
} |
|||
|
|||
public void refreshInventory(UUID u) { |
|||
GUIInventory ginv = invs.get(u); |
|||
|
|||
if (ginv == null) { |
|||
return; |
|||
} |
|||
|
|||
ginv.reset(); |
|||
|
|||
decorateInventory(ginv.inv); |
|||
setGUIItems(ginv, u); |
|||
} |
|||
|
|||
@EventHandler |
|||
public void onClick(InventoryClickEvent e) { |
|||
if (e.isCancelled()) { |
|||
return; |
|||
} |
|||
|
|||
Player p = (Player) e.getWhoClicked(); |
|||
Inventory inv = e.getClickedInventory(); |
|||
ItemStack hand = e.getCursor(); |
|||
|
|||
UUID u = p.getUniqueId(); |
|||
|
|||
if (!invs.containsKey(u)) { |
|||
return; |
|||
} |
|||
|
|||
GUIInventory ginv = invs.get(u); |
|||
|
|||
if (!ginv.inv.equals(inv)) { |
|||
return; |
|||
} |
|||
|
|||
// CANCEL ANYTHING
|
|||
e.setCancelled(true); |
|||
|
|||
GUIItem gitem = ginv.getGUIItem(e.getSlot()); |
|||
|
|||
if (gitem == null) { |
|||
return; |
|||
} |
|||
|
|||
if (e.isRightClick()) { |
|||
gitem.onRightClick(p, inv, hand); |
|||
} |
|||
if (e.isLeftClick()) { |
|||
gitem.onLeftClick(p, inv, hand); |
|||
} |
|||
} |
|||
|
|||
@EventHandler |
|||
public void onClose(InventoryCloseEvent e) { |
|||
Player p = (Player) e.getPlayer(); |
|||
Inventory inv = e.getInventory(); |
|||
|
|||
UUID u = p.getUniqueId(); |
|||
|
|||
if (!invs.containsKey(u)) { |
|||
return; |
|||
} |
|||
|
|||
GUIInventory ginv = invs.get(u); |
|||
|
|||
if (!ginv.inv.equals(inv)) { |
|||
return; |
|||
} |
|||
|
|||
if (isPersistent()) { |
|||
return; |
|||
} |
|||
|
|||
invs.remove(u); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,45 @@ |
|||
package com.entryrise.afkguard.gui; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import org.bukkit.inventory.Inventory; |
|||
|
|||
public class GUIInventory { |
|||
|
|||
public Inventory inv; |
|||
public List<GUIItem> items = new ArrayList<GUIItem>(); |
|||
|
|||
public GUIItem getGUIItem(int slot) { |
|||
for (GUIItem itm : items) { |
|||
if (itm.getSlot() == slot) { |
|||
return itm; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public void addGUIItem(GUIItem itm) { |
|||
items.add(itm); |
|||
|
|||
inv.setItem(itm.getSlot(), itm.getItm().clone()); |
|||
} |
|||
|
|||
public void reset() { |
|||
items.clear(); |
|||
} |
|||
|
|||
public GUIInventory(Inventory inv) { |
|||
this.inv = inv; |
|||
|
|||
} |
|||
|
|||
public GUIInventory(Inventory inv, List<GUIItem> items) { |
|||
this.inv = inv; |
|||
for (GUIItem itm : items) { |
|||
addGUIItem(itm); |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,45 @@ |
|||
package com.entryrise.afkguard.gui; |
|||
|
|||
import org.bukkit.entity.Player; |
|||
import org.bukkit.inventory.Inventory; |
|||
import org.bukkit.inventory.ItemStack; |
|||
|
|||
public abstract class GUIItem { |
|||
|
|||
private ItemStack itm; |
|||
private int slot; |
|||
|
|||
public ItemStack getItm() { |
|||
return itm; |
|||
} |
|||
|
|||
public void setItm(ItemStack itm) { |
|||
this.itm = itm; |
|||
} |
|||
|
|||
public int getSlot() { |
|||
return slot; |
|||
} |
|||
|
|||
public void setSlot(int slot) { |
|||
this.slot = slot; |
|||
} |
|||
|
|||
public GUIItem(ItemStack itm, int slot) { |
|||
this.setSlot(slot); |
|||
this.setItm(itm); |
|||
} |
|||
|
|||
public void onLeftClick(Player p, Inventory inv, ItemStack hand) { |
|||
|
|||
} |
|||
|
|||
public void onRightClick(Player p, Inventory inv, ItemStack hand) { |
|||
|
|||
} |
|||
|
|||
public void onMiddleClick(Player p, Inventory inv, ItemStack hand) { |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,20 @@ |
|||
package com.entryrise.afkguard.gui; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
|
|||
|
|||
public class GUIManager { |
|||
|
|||
// public static TestGUI TestGUI;
|
|||
|
|||
public static void Enabler(boolean reload) { |
|||
if (!reload) { |
|||
registerGUIs(); |
|||
} |
|||
Bukkit.getLogger().info(" §e[§a✔§e] §fGUIs loaded"); |
|||
} |
|||
|
|||
private static void registerGUIs() { |
|||
} |
|||
|
|||
} |
@ -0,0 +1,82 @@ |
|||
package com.entryrise.afkguard.gui.inputs; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.HashSet; |
|||
import java.util.List; |
|||
import java.util.Set; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.entity.HumanEntity; |
|||
import org.bukkit.entity.Player; |
|||
import org.bukkit.event.EventHandler; |
|||
import org.bukkit.event.EventPriority; |
|||
import org.bukkit.event.HandlerList; |
|||
import org.bukkit.event.player.PlayerEditBookEvent; |
|||
import org.bukkit.inventory.Inventory; |
|||
import org.bukkit.inventory.ItemStack; |
|||
import org.bukkit.inventory.meta.BookMeta; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
import com.entryrise.afkguard.utils.VersionMgr; |
|||
|
|||
public abstract class GUIBookInput extends GUIInput<List<String>> { |
|||
|
|||
private static ItemStack editbook; |
|||
|
|||
private Inventory inv; |
|||
private Set<HumanEntity> ents = new HashSet<HumanEntity>(); |
|||
|
|||
static { |
|||
editbook = new ItemStack(VersionMgr.getWritableBook()); |
|||
BookMeta bmeta = (BookMeta) editbook.getItemMeta(); |
|||
bmeta.setDisplayName("§d§4EdItB00k"); |
|||
} |
|||
|
|||
public Inventory getInv() { |
|||
return inv; |
|||
} |
|||
|
|||
public void setInv(Inventory inv) { |
|||
this.inv = inv; |
|||
} |
|||
|
|||
@EventHandler(priority = EventPriority.LOW) |
|||
public void onChat(PlayerEditBookEvent e) { |
|||
if (e.isCancelled()) { |
|||
return; |
|||
} |
|||
|
|||
Player p = e.getPlayer(); |
|||
|
|||
if (!ents.contains(p)) { |
|||
return; |
|||
} |
|||
|
|||
e.setCancelled(true); |
|||
|
|||
for (HumanEntity ent : ents) { |
|||
ent.openInventory(inv); |
|||
} |
|||
|
|||
HandlerList.unregisterAll(this); |
|||
|
|||
onResult(Arrays.asList(e.getNewBookMeta().getPage(0).split("\n"))); |
|||
|
|||
} |
|||
|
|||
public GUIBookInput(Inventory inv) { |
|||
this.setInv(inv); |
|||
|
|||
for (HumanEntity ent : inv.getViewers()) { |
|||
ents.add(ent); |
|||
ent.closeInventory(); |
|||
|
|||
Player p = (Player) ent; |
|||
|
|||
VersionMgr.openBook(p, editbook); |
|||
} |
|||
|
|||
Bukkit.getPluginManager().registerEvents(this, Main.p); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,83 @@ |
|||
package com.entryrise.afkguard.gui.inputs; |
|||
|
|||
import java.util.HashSet; |
|||
import java.util.Set; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.entity.HumanEntity; |
|||
import org.bukkit.entity.Player; |
|||
import org.bukkit.event.EventHandler; |
|||
import org.bukkit.event.EventPriority; |
|||
import org.bukkit.event.HandlerList; |
|||
import org.bukkit.event.player.AsyncPlayerChatEvent; |
|||
import org.bukkit.event.player.PlayerCommandPreprocessEvent; |
|||
import org.bukkit.inventory.Inventory; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
|
|||
public abstract class GUIChatInput extends GUIInput<String> { |
|||
|
|||
private Inventory inv; |
|||
private Set<HumanEntity> ents = new HashSet<HumanEntity>(); |
|||
|
|||
public Inventory getInv() { |
|||
return inv; |
|||
} |
|||
|
|||
public void setInv(Inventory inv) { |
|||
this.inv = inv; |
|||
} |
|||
|
|||
@EventHandler(priority = EventPriority.LOW) |
|||
public void onCommand(PlayerCommandPreprocessEvent e) { |
|||
if (e.isCancelled()) { |
|||
return; |
|||
} |
|||
|
|||
Player p = e.getPlayer(); |
|||
|
|||
if (!ents.contains(p)) { |
|||
return; |
|||
} |
|||
|
|||
e.setCancelled(true); |
|||
p.sendMessage("You can't execute commands while inputting in a GUI."); |
|||
} |
|||
|
|||
@EventHandler(priority = EventPriority.LOW) |
|||
public void onChat(AsyncPlayerChatEvent e) { |
|||
if (e.isCancelled()) { |
|||
return; |
|||
} |
|||
|
|||
Player p = e.getPlayer(); |
|||
|
|||
if (!ents.contains(p)) { |
|||
return; |
|||
} |
|||
|
|||
String chat = e.getMessage(); |
|||
e.setCancelled(true); |
|||
|
|||
for (HumanEntity ent : ents) { |
|||
ent.openInventory(inv); |
|||
} |
|||
|
|||
HandlerList.unregisterAll(this); |
|||
|
|||
onResult(chat); |
|||
|
|||
} |
|||
|
|||
public GUIChatInput(Inventory inv) { |
|||
this.setInv(inv); |
|||
|
|||
for (HumanEntity ent : inv.getViewers()) { |
|||
ents.add(ent); |
|||
ent.closeInventory(); |
|||
} |
|||
|
|||
Bukkit.getPluginManager().registerEvents(this, Main.p); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,11 @@ |
|||
package com.entryrise.afkguard.gui.inputs; |
|||
|
|||
import org.bukkit.event.Listener; |
|||
|
|||
public abstract class GUIInput<E> implements Listener { |
|||
|
|||
public abstract void onResult(E result); |
|||
|
|||
|
|||
|
|||
} |
@ -0,0 +1,119 @@ |
|||
package com.entryrise.afkguard.listeners; |
|||
|
|||
import java.util.Map; |
|||
import java.util.WeakHashMap; |
|||
|
|||
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.Listener; |
|||
import org.bukkit.event.block.BlockBreakEvent; |
|||
import org.bukkit.event.block.BlockPlaceEvent; |
|||
import org.bukkit.event.entity.EntityPickupItemEvent; |
|||
import org.bukkit.event.player.AsyncPlayerChatEvent; |
|||
import org.bukkit.event.player.PlayerFishEvent; |
|||
import org.bukkit.event.player.PlayerToggleFlightEvent; |
|||
import org.bukkit.event.player.PlayerToggleSprintEvent; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
import com.entryrise.afkguard.antiafk.AFKManager; |
|||
|
|||
public class AFKListener implements Listener { |
|||
|
|||
private Map<Player, Location> oldlocations = new WeakHashMap<>(); |
|||
|
|||
public AFKListener() { |
|||
Bukkit.getScheduler().runTaskTimer(Main.p, () -> { |
|||
|
|||
for (Player p : Bukkit.getOnlinePlayers()) { |
|||
oldlocations.compute(p, (k, oldloc) -> { |
|||
|
|||
Location newloc = p.getLocation(); |
|||
|
|||
if (oldloc == null) { |
|||
return newloc; |
|||
} |
|||
|
|||
double multiplier = Main.config |
|||
.getDouble("settings.afk-detection.counter.actions.location-movement"); |
|||
|
|||
double value = 0; |
|||
|
|||
if (!p.isInsideVehicle()) { |
|||
if (oldloc.getWorld() == newloc.getWorld()) { |
|||
value += multiplier * oldloc.distanceSquared(newloc); |
|||
} else { |
|||
value += Main.config.getDouble("settings.afk-detection.counter.actions.world-movement"); |
|||
} |
|||
} else { |
|||
value += Main.config.getDouble("settings.afk-detection.counter.actions.riding-movement"); |
|||
} |
|||
|
|||
value += (Math.abs(newloc.getYaw() - oldloc.getYaw()) |
|||
+ Math.abs((newloc.getPitch() - oldloc.getPitch())) |
|||
* Main.config.getDouble("settings.afk-detection.counter.actions.mouse-movement")); |
|||
|
|||
AFKManager.incrementPlayer(p, value); |
|||
|
|||
return newloc; |
|||
}); |
|||
} |
|||
|
|||
}, 100, 100); |
|||
} |
|||
|
|||
/* |
|||
* The plugin uses monitor as it's the intended priority for monitoring tasks. |
|||
* |
|||
* Since afkguard doesn't do anything directly in the event, it is the ideal |
|||
* choice for this usecase. |
|||
*/ |
|||
|
|||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) |
|||
public void onChat(AsyncPlayerChatEvent e) { |
|||
AFKManager.incrementPlayer(e.getPlayer(), Main.config.getDouble("settings.afk-detection.counter.actions.chat")); |
|||
} |
|||
|
|||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) |
|||
public void onBlockBreak(BlockBreakEvent e) { |
|||
AFKManager.incrementPlayer(e.getPlayer(), |
|||
Main.config.getDouble("settings.afk-detection.counter.actions.block-break")); |
|||
} |
|||
|
|||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) |
|||
public void onBlockPlace(BlockPlaceEvent e) { |
|||
AFKManager.incrementPlayer(e.getPlayer(), |
|||
Main.config.getDouble("settings.afk-detection.counter.actions.block-place")); |
|||
} |
|||
|
|||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) |
|||
public void onToggleSprint(PlayerToggleSprintEvent e) { |
|||
AFKManager.incrementPlayer(e.getPlayer(), |
|||
Main.config.getDouble("settings.afk-detection.counter.actions.toggle-sprint")); |
|||
} |
|||
|
|||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) |
|||
public void onToggleSprint(PlayerToggleFlightEvent e) { |
|||
AFKManager.incrementPlayer(e.getPlayer(), |
|||
Main.config.getDouble("settings.afk-detection.counter.actions.toggle-flight")); |
|||
} |
|||
|
|||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) |
|||
public void onBlockPlace(PlayerFishEvent e) { |
|||
AFKManager.incrementPlayer(e.getPlayer(), |
|||
Main.config.getDouble("settings.afk-detection.counter.actions.fishing")); |
|||
} |
|||
|
|||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) |
|||
public void onItemPickup(EntityPickupItemEvent e) { |
|||
Player p = e.getEntity() instanceof Player ? (Player) e.getEntity() : null; |
|||
|
|||
if (p == null) { |
|||
return; |
|||
} |
|||
AFKManager.incrementPlayer(p, Main.config.getDouble("settings.afk-detection.counter.actions.pickup-item")); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,20 @@ |
|||
package com.entryrise.afkguard.listeners; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
|
|||
public class ListenersMain { |
|||
|
|||
public static void Enabler(boolean reload) { |
|||
if (!reload) { |
|||
registerEvents(); |
|||
} |
|||
Bukkit.getLogger().info(" §e[§a✔§e] §fEvent-Listeners loaded"); |
|||
} |
|||
|
|||
private static void registerEvents() { |
|||
Bukkit.getServer().getPluginManager().registerEvents(new AFKListener(), Main.p); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,62 @@ |
|||
package com.entryrise.afkguard.mineutils; |
|||
|
|||
import java.lang.reflect.Field; |
|||
import java.util.Base64; |
|||
import java.util.UUID; |
|||
|
|||
import org.bukkit.Material; |
|||
import org.bukkit.inventory.ItemStack; |
|||
import org.bukkit.inventory.meta.ItemMeta; |
|||
import org.bukkit.inventory.meta.SkullMeta; |
|||
|
|||
import com.mojang.authlib.GameProfile; |
|||
import com.mojang.authlib.properties.Property; |
|||
|
|||
public class HeadUtils { |
|||
|
|||
public static ItemStack getSkull(String skinURL) { |
|||
ItemStack head = getSkullItem(); |
|||
if(skinURL.isEmpty())return head; |
|||
|
|||
|
|||
ItemMeta headMeta = head.getItemMeta(); |
|||
GameProfile profile = new GameProfile(UUID.randomUUID(), null); |
|||
byte[] encodedData = Base64.getEncoder().encode(String.format("{textures:{SKIN:{url:\"%s\"}}}", skinURL).getBytes()); |
|||
profile.getProperties().put("textures", new Property("textures", new String(encodedData))); |
|||
Field profileField = null; |
|||
try { |
|||
profileField = headMeta.getClass().getDeclaredField("profile"); |
|||
} catch (NoSuchFieldException | SecurityException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
profileField.setAccessible(true); |
|||
try { |
|||
profileField.set(headMeta, profile); |
|||
} catch (IllegalArgumentException | IllegalAccessException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
head.setItemMeta(headMeta); |
|||
return head; |
|||
} |
|||
|
|||
public static ItemStack getPlayerSkull(String username) { |
|||
ItemStack head = getSkullItem(); |
|||
ItemMeta imeta = head.getItemMeta(); |
|||
|
|||
SkullMeta smeta = (SkullMeta) imeta; |
|||
|
|||
smeta.setOwner(username); |
|||
head.setItemMeta(smeta); |
|||
return head; |
|||
} |
|||
|
|||
public static Material getSkull() { |
|||
Material mat = Material.getMaterial("SKULL_ITEM"); |
|||
|
|||
return (mat != null) ? mat : Material.getMaterial("PLAYER_HEAD"); |
|||
} |
|||
|
|||
public static ItemStack getSkullItem() { |
|||
return new ItemStack(getSkull(), 1, (short) 3); |
|||
} |
|||
} |
@ -0,0 +1,95 @@ |
|||
package com.entryrise.afkguard.mineutils; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import org.bukkit.enchantments.Enchantment; |
|||
import org.bukkit.inventory.Inventory; |
|||
import org.bukkit.inventory.ItemFlag; |
|||
import org.bukkit.inventory.ItemStack; |
|||
import org.bukkit.inventory.meta.ItemMeta; |
|||
|
|||
public class InventoryUtils { |
|||
|
|||
public static List<Integer> filledSquare(Inventory inv, ItemStack filler, int from, int to) { |
|||
int row1 = from%9; |
|||
int line1 = from/9; |
|||
|
|||
int row2 = to%9; |
|||
int line2 = to/9; |
|||
|
|||
List<Integer> filled = new ArrayList<Integer>(); |
|||
|
|||
for (int i = line1; i<=line2; i++) { |
|||
for (int j = row1; j<=row2; j++) { |
|||
int slot = i*9+j; |
|||
filled.add(slot); |
|||
inv.setItem(slot, filler); |
|||
} |
|||
} |
|||
|
|||
return filled; |
|||
} |
|||
|
|||
public static List<Integer> outlineSquare(Inventory inv, ItemStack filler, int from, int to) { |
|||
int row1 = from%9; |
|||
int line1 = from/9; |
|||
|
|||
int row2 = to%9; |
|||
int line2 = to/9; |
|||
|
|||
List<Integer> filled = new ArrayList<Integer>(); |
|||
|
|||
for (int i=row1; i<=row2; i++) { |
|||
filled.add(line1*9+i); |
|||
filled.add(line2*9+i); |
|||
} |
|||
|
|||
for (int i=line1; i<=line2; i++) { |
|||
filled.add(i*9+row1); |
|||
filled.add(i*9+row2); |
|||
} |
|||
|
|||
for (int slot : filled) { |
|||
inv.setItem(slot, filler); |
|||
} |
|||
|
|||
return filled; |
|||
} |
|||
|
|||
public static List<Integer> centeredCross(Inventory inv, ItemStack filler, int center, int size) { |
|||
int row = center%9; |
|||
int line = center/9; |
|||
|
|||
List<Integer> filled = new ArrayList<Integer>(); |
|||
|
|||
for (int i = Math.max(0, line-size); i<=Math.min(8, line+size); i++) { |
|||
int slot = i*9+row; |
|||
filled.add(slot); |
|||
inv.setItem(slot, filler); |
|||
} |
|||
|
|||
for (int i = Math.max(0, row-size); i<=Math.min(8, row+size); i++) { |
|||
int slot = line*9+i; |
|||
filled.add(slot); |
|||
inv.setItem(slot, filler); |
|||
} |
|||
|
|||
return filled; |
|||
} |
|||
|
|||
public static ItemStack setName(ItemStack itm, String name) { |
|||
ItemMeta imeta = itm.getItemMeta(); |
|||
imeta.setDisplayName(name); |
|||
itm.setItemMeta(imeta); |
|||
return itm; |
|||
} |
|||
|
|||
public static ItemStack setShiny(ItemStack itm) { |
|||
ItemMeta imeta = itm.getItemMeta(); |
|||
imeta.addEnchant(Enchantment.DURABILITY, 10, true); |
|||
imeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); |
|||
itm.setItemMeta(imeta); |
|||
return itm; |
|||
} |
|||
} |
@ -0,0 +1,190 @@ |
|||
package com.entryrise.afkguard.mineutils; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Set; |
|||
|
|||
import org.bukkit.ChatColor; |
|||
import org.bukkit.Material; |
|||
import org.bukkit.configuration.file.FileConfiguration; |
|||
import org.bukkit.enchantments.Enchantment; |
|||
import org.bukkit.inventory.ItemFlag; |
|||
import org.bukkit.inventory.ItemStack; |
|||
import org.bukkit.inventory.meta.ItemMeta; |
|||
|
|||
public class ItemBuilder { |
|||
|
|||
private ItemStack itm; |
|||
|
|||
public ItemBuilder(Material mat) { |
|||
this.itm = new ItemStack(mat); |
|||
} |
|||
|
|||
public ItemBuilder(ItemStack itm) { |
|||
this.itm = itm; |
|||
} |
|||
|
|||
public ItemBuilder(FileConfiguration config, String location, String... placeholders) { |
|||
if (!config.contains(location)) { |
|||
return; |
|||
} |
|||
|
|||
this.setType(config.getString(location + ".material")); |
|||
this.setName(config.getString(location + ".name")); |
|||
|
|||
List<String> stgs = config.getStringList(location + ".lore"); |
|||
|
|||
if (stgs != null && !stgs.isEmpty()) { |
|||
this.setLore(stgs.toArray(new String[stgs.size()])); |
|||
setLorePlaceholders(placeholders); |
|||
} |
|||
|
|||
if (config.getBoolean(location + ".shiny")) { |
|||
this.setShiny(); |
|||
} |
|||
|
|||
setNamePlaceholders(placeholders); |
|||
|
|||
} |
|||
|
|||
public ItemBuilder setType(String material) { |
|||
if (material == null) { |
|||
material = "BARRIER"; |
|||
} |
|||
ItemMeta imeta = (itm == null) ? null : itm.getItemMeta().clone(); |
|||
|
|||
String displayname = null; |
|||
List<String> lore = null; |
|||
Set<ItemFlag> flags = null; |
|||
Map<Enchantment, Integer> enchants = null; |
|||
|
|||
if (imeta != null) { |
|||
displayname = imeta.hasDisplayName() ? imeta.getDisplayName() : null; |
|||
lore = imeta.hasLore() ? imeta.getLore() : null; |
|||
enchants = imeta.hasEnchants() ? imeta.getEnchants() : null; |
|||
flags = imeta.getItemFlags(); |
|||
} |
|||
|
|||
// Bukkit.getPlayer("Stefytorus").getInventory().addItem(itm);
|
|||
|
|||
String[] split = material.split(":"); |
|||
|
|||
if (material.startsWith("head:")) { |
|||
itm = HeadUtils.getPlayerSkull(material.replace("head:", "")); |
|||
} else if (material.startsWith("urlhead:")) { |
|||
itm = HeadUtils.getSkull(material.replace("urlhead:", "")); |
|||
} else if (split.length == 2) { |
|||
Material mat = Material.getMaterial(split[0]); |
|||
if (mat == null) { |
|||
mat = Material.getMaterial("BARRIER"); |
|||
} |
|||
itm = new ItemStack(mat, 1, Short.valueOf(split[1])); |
|||
} else { |
|||
Material mat = Material.getMaterial(material); |
|||
if (mat == null) { |
|||
mat = Material.getMaterial("BARRIER"); |
|||
} |
|||
itm = new ItemStack(mat); |
|||
} |
|||
|
|||
imeta = itm.getItemMeta(); |
|||
if (lore != null) { |
|||
imeta.setLore(lore); |
|||
} |
|||
if (displayname != null) { |
|||
imeta.setDisplayName(displayname); |
|||
} |
|||
if (enchants != null) { |
|||
for (Enchantment ench : enchants.keySet()) { |
|||
imeta.addEnchant(ench, enchants.get(ench), true); |
|||
} |
|||
} |
|||
if (flags != null) { |
|||
imeta.addItemFlags(flags.toArray(new ItemFlag[flags.size()])); |
|||
} |
|||
itm.setItemMeta(imeta); |
|||
|
|||
return this; |
|||
} |
|||
|
|||
public ItemBuilder setName(String name) { |
|||
ItemMeta imeta = itm.getItemMeta(); |
|||
imeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); |
|||
itm.setItemMeta(imeta); |
|||
return this; |
|||
} |
|||
|
|||
public ItemBuilder setShiny() { |
|||
ItemMeta imeta = itm.getItemMeta(); |
|||
imeta.addEnchant(Enchantment.DURABILITY, 10, true); |
|||
imeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); |
|||
itm.setItemMeta(imeta); |
|||
return this; |
|||
} |
|||
|
|||
public ItemBuilder setLore(String... lore) { |
|||
List<String> solved = new ArrayList<String>(); |
|||
for (String stg : lore) { |
|||
solved.add(ChatColor.translateAlternateColorCodes('&', stg)); |
|||
} |
|||
ItemMeta imeta = itm.getItemMeta(); |
|||
imeta.setLore(solved); |
|||
itm.setItemMeta(imeta); |
|||
return this; |
|||
} |
|||
|
|||
public ItemBuilder setLorePlaceholders(String... placeholders) { |
|||
ItemMeta imeta = itm.getItemMeta(); |
|||
List<String> lore = imeta.getLore(); |
|||
|
|||
for (int i = 0; i < lore.size(); i++) { |
|||
String val = lore.get(i); |
|||
for (int j = 0; j < placeholders.length; j += 2) { |
|||
val = val.replace(placeholders[j], placeholders[j + 1]); |
|||
} |
|||
lore.set(i, val); |
|||
} |
|||
imeta.setLore(lore); |
|||
itm.setItemMeta(imeta); |
|||
return this; |
|||
} |
|||
|
|||
public ItemBuilder setLorePlaceholders(String placeholder, List<String> placement) { |
|||
ItemMeta imeta = itm.getItemMeta(); |
|||
List<String> lore = imeta.getLore(); |
|||
List<String> newlore = new ArrayList<String>(); |
|||
for (int i = 0; i < lore.size(); i++) { |
|||
String val = lore.get(i); |
|||
if (val.contains(placeholder)) { |
|||
val = val.replace(placeholder, ""); |
|||
newlore.add(val); |
|||
for (String stg : placement) { |
|||
newlore.add(stg); |
|||
} |
|||
continue; |
|||
} |
|||
newlore.add(val); |
|||
} |
|||
imeta.setLore(newlore); |
|||
itm.setItemMeta(imeta); |
|||
return this; |
|||
} |
|||
|
|||
public ItemBuilder setNamePlaceholders(String... placeholders) { |
|||
ItemMeta imeta = itm.getItemMeta(); |
|||
String name = imeta.getDisplayName(); |
|||
|
|||
for (int j = 0; j < placeholders.length; j += 2) { |
|||
name = name.replace(placeholders[j], placeholders[j + 1]); |
|||
} |
|||
imeta.setDisplayName(name); |
|||
itm.setItemMeta(imeta); |
|||
return this; |
|||
} |
|||
|
|||
public ItemStack build() { |
|||
return itm; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,9 @@ |
|||
package com.entryrise.afkguard.mineutils; |
|||
|
|||
public class ValidationUtils { |
|||
|
|||
public static boolean isAlphanumeric(String stg) { |
|||
return stg.matches("^([A-Za-z]|[0-9]|_)+$"); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,72 @@ |
|||
package com.entryrise.afkguard.utils; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.HashSet; |
|||
import java.util.Map; |
|||
import java.util.Set; |
|||
|
|||
public class Cache<S, T> { |
|||
|
|||
protected class Cachebox { |
|||
|
|||
protected T cached; |
|||
protected int time; |
|||
|
|||
protected Cachebox(T cached, int time) { |
|||
this.cached = cached; |
|||
this.time = time; |
|||
} |
|||
|
|||
protected boolean tick() { |
|||
time--; |
|||
return time <= 0; |
|||
} |
|||
} |
|||
|
|||
private int cachetime; |
|||
private Map<S, Cachebox> cachestorage = new HashMap<S, Cachebox>(); |
|||
|
|||
public Cache(int cachetime) { |
|||
this.cachetime = cachetime; |
|||
} |
|||
|
|||
public void putCached(S key, T cached) { |
|||
cachestorage.put(key, new Cachebox(cached, cachetime)); |
|||
} |
|||
|
|||
public boolean isCached(S key) { |
|||
return cachestorage.containsKey(key); |
|||
} |
|||
|
|||
public T getCached(S key) { |
|||
if (isCached(key)) { |
|||
return cachestorage.get(key).cached; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public void tick() { |
|||
Set<S> removables = new HashSet<S>(); |
|||
|
|||
for (S key : cachestorage.keySet()) { |
|||
Cachebox box = cachestorage.get(key); |
|||
|
|||
if (!box.tick()) { |
|||
continue; |
|||
} |
|||
|
|||
removables.add(key); |
|||
} |
|||
|
|||
cachestorage.keySet().removeAll(removables); |
|||
} |
|||
|
|||
public void clear() { |
|||
cachestorage.clear(); |
|||
} |
|||
|
|||
public boolean remove(S key) { |
|||
return cachestorage.remove(key) != null; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,30 @@ |
|||
package com.entryrise.afkguard.utils; |
|||
|
|||
import net.md_5.bungee.api.chat.ClickEvent; |
|||
import net.md_5.bungee.api.chat.ComponentBuilder; |
|||
import net.md_5.bungee.api.chat.HoverEvent; |
|||
import net.md_5.bungee.api.chat.TextComponent; |
|||
|
|||
public class Chat { |
|||
|
|||
public static TextComponent genHoverAndSuggestTextComponent(String show, String hover, String click) { |
|||
TextComponent msg = new TextComponent(show); |
|||
msg.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hover).create())); |
|||
msg.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + click)); |
|||
return msg; |
|||
} |
|||
|
|||
public static TextComponent genHoverAndRunCommandTextComponent(String show, String hover, String click) { |
|||
TextComponent msg = new TextComponent(show); |
|||
msg.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hover).create())); |
|||
msg.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/" + click)); |
|||
return msg; |
|||
} |
|||
|
|||
public static TextComponent genHoverTextComponent(String show, String hover) { |
|||
TextComponent msg = new TextComponent(show); |
|||
msg.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hover).create())); |
|||
return msg; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,19 @@ |
|||
package com.entryrise.afkguard.utils; |
|||
|
|||
public class MathUtils { |
|||
|
|||
public static int toMegaByte(long bytes) { |
|||
return (int) (bytes / 1048576); |
|||
} |
|||
|
|||
public static boolean isInt(String str) { |
|||
try { |
|||
int d = Integer.parseInt(str); |
|||
d = d + 1; |
|||
} catch (NumberFormatException nfe) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,75 @@ |
|||
package com.entryrise.afkguard.utils; |
|||
|
|||
import java.io.File; |
|||
|
|||
import org.apache.commons.lang.RandomStringUtils; |
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.Location; |
|||
import org.bukkit.WorldBorder; |
|||
import org.bukkit.configuration.file.YamlConfiguration; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
|
|||
|
|||
public class Others { |
|||
|
|||
public static boolean isInsideBorder(Location loc) { |
|||
WorldBorder border = loc.getWorld().getWorldBorder(); |
|||
double radius = border.getSize() / 2; |
|||
Location location = loc, center = border.getCenter(); |
|||
|
|||
return center.distanceSquared(location) < (radius * radius); |
|||
} |
|||
|
|||
public static YamlConfiguration getConfig(File f, int version) { |
|||
YamlConfiguration fc = new YamlConfiguration(); |
|||
|
|||
if (!f.exists()) { |
|||
f.getParentFile().mkdirs(); |
|||
Main.p.saveResource(f.getName(), false); |
|||
} |
|||
|
|||
try { |
|||
fc.load(f); |
|||
|
|||
if (fc.contains("version")) { |
|||
if (fc.getInt("version") != version) { |
|||
Bukkit.getLogger().info(Main.PREFIX + "Updating " + f.getName() + " file!"); |
|||
f.renameTo(getOldFile(f)); |
|||
Main.p.saveResource(f.getName(), false); |
|||
fc.load(f); |
|||
|
|||
} |
|||
} else { |
|||
Bukkit.getLogger().info(Main.PREFIX + "Updating " + f.getName() + " file!"); |
|||
f.renameTo(getOldFile(f)); |
|||
Main.p.saveResource(f.getName(), false); |
|||
fc.load(f); |
|||
} |
|||
|
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
|
|||
return fc; |
|||
|
|||
} |
|||
|
|||
private static File getOldFile(File f) { |
|||
return new File(f.getParentFile(), f.getName() + "." + RandomStringUtils.randomAlphanumeric(3) + ".old"); |
|||
} |
|||
|
|||
public static String serializeLocation(Location loc) { |
|||
if (loc.getWorld() == null) { |
|||
System.out.println("world doesn't exist man!"); |
|||
} |
|||
return loc.getWorld().getName() + ";" + loc.getX() + ";" + loc.getY() + ";" + loc.getZ() + ";" + loc.getYaw() + ";" |
|||
+ loc.getPitch(); |
|||
} |
|||
|
|||
public static Location deserializeLocation(String loc) { |
|||
String[] rawloc = loc.split(";"); |
|||
return new Location(Bukkit.getWorld(rawloc[0]), Double.valueOf(rawloc[1]), Double.valueOf(rawloc[2]), |
|||
Double.valueOf(rawloc[3]), Float.valueOf(rawloc[4]), Float.valueOf(rawloc[5])); |
|||
} |
|||
} |
@ -0,0 +1,111 @@ |
|||
package com.entryrise.afkguard.utils; |
|||
|
|||
import org.bukkit.Bukkit; |
|||
import org.bukkit.Material; |
|||
import org.bukkit.entity.Player; |
|||
import org.bukkit.inventory.ItemStack; |
|||
|
|||
import com.entryrise.afkguard.Main; |
|||
|
|||
public class VersionMgr { |
|||
|
|||
public static boolean isV1_8() { |
|||
return Bukkit.getVersion().contains("1.8"); |
|||
} |
|||
|
|||
public static boolean isV1_9() { |
|||
return Bukkit.getVersion().contains("1.9"); |
|||
} |
|||
|
|||
public static boolean isV1_10() { |
|||
return Bukkit.getVersion().contains("1.10"); |
|||
} |
|||
|
|||
public static boolean isV1_13() { |
|||
return Bukkit.getVersion().contains("1.13"); |
|||
} |
|||
|
|||
public static boolean isV1_11() { |
|||
if (Bukkit.getVersion().contains("1.8")) { |
|||
return false; |
|||
} |
|||
if (Bukkit.getVersion().contains("1.9")) { |
|||
return false; |
|||
} |
|||
if (Bukkit.getVersion().contains("1.10")) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
public static boolean isV1_12() { |
|||
if (Bukkit.getVersion().contains("1.8")) { |
|||
return false; |
|||
} |
|||
if (Bukkit.getVersion().contains("1.9")) { |
|||
return false; |
|||
} |
|||
if (Bukkit.getVersion().contains("1.10")) { |
|||
return false; |
|||
} |
|||
if (Bukkit.getVersion().contains("1.11")) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
public static boolean isNewMaterials() { |
|||
if (isV1_8()) { |
|||
return false; |
|||
} |
|||
|
|||
if (isV1_9()) { |
|||
return false; |
|||
} |
|||
|
|||
if (isV1_10()) { |
|||
return false; |
|||
} |
|||
|
|||
if (isV1_11()) { |
|||
return false; |
|||
} |
|||
|
|||
if (isV1_12()) { |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
|
|||
} |
|||
|
|||
public static boolean isPaper() { |
|||
try { |
|||
Class.forName("com.destroystokyo.paper.PaperConfig"); |
|||
} catch (ClassNotFoundException e) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
public static String ChunkExistsName() { |
|||
return isV1_13() ? "f" : "e"; |
|||
} |
|||
|
|||
public static Material getWritableBook() { |
|||
return Material.getMaterial(isNewMaterials() ? "WRITABLE_BOOK" : "BOOK_AND_QUILL"); |
|||
} |
|||
|
|||
public static void openBook(Player p, ItemStack book) { |
|||
ItemStack itm = p.getInventory().getItemInHand(); |
|||
p.getInventory().setItemInHand(book); |
|||
|
|||
String channel = isNewMaterials() ? "minecraft:book_open" : "MC|BOpen"; |
|||
|
|||
// Main hand = 0 | Off hand = 1
|
|||
p.sendPluginMessage(Main.p, channel, new byte[0]); |
|||
|
|||
p.getInventory().setItemInHand(itm); |
|||
} |
|||
|
|||
} |
Loading…
Reference in new issue