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