├── .gitignore ├── README.md ├── jitpack.yml ├── pom.xml └── src └── main ├── java └── fi │ └── septicuss │ └── tooltips │ ├── Tooltips.java │ ├── api │ └── TooltipsAPI.java │ ├── commands │ ├── TooltipsCommand.java │ ├── TooltipsSubCommand.java │ └── subcommands │ │ ├── DebugCommand.java │ │ ├── EvalCommand.java │ │ ├── ListVarsCommand.java │ │ ├── ReloadCommand.java │ │ ├── SendPresetCommand.java │ │ ├── SendThemeCommand.java │ │ └── VarsCommand.java │ ├── listener │ ├── PlayerConnectionListener.java │ ├── PlayerInteractListener.java │ └── PlayerMovementListener.java │ ├── managers │ ├── condition │ │ ├── Condition.java │ │ ├── ConditionManager.java │ │ ├── Context.java │ │ ├── Statement.java │ │ ├── StatementHolder.java │ │ ├── argument │ │ │ ├── Argument.java │ │ │ └── Arguments.java │ │ ├── composite │ │ │ ├── CompositeCondition.java │ │ │ └── CompositeConditionBuilder.java │ │ ├── impl │ │ │ ├── Compare.java │ │ │ ├── equals │ │ │ │ ├── BlockNbtEquals.java │ │ │ │ ├── BlockStateEquals.java │ │ │ │ ├── EntityNbtEquals.java │ │ │ │ ├── ItemNbtEquals.java │ │ │ │ └── TileEntityNbtEquals.java │ │ │ ├── lookingat │ │ │ │ ├── LookingAtBlock.java │ │ │ │ ├── LookingAtCitizen.java │ │ │ │ ├── LookingAtEntity.java │ │ │ │ ├── LookingAtFurniture.java │ │ │ │ └── LookingAtMythicMob.java │ │ │ ├── player │ │ │ │ ├── Equipped.java │ │ │ │ ├── Gamemode.java │ │ │ │ ├── Op.java │ │ │ │ ├── Permission.java │ │ │ │ ├── Sneaking.java │ │ │ │ └── StandingOn.java │ │ │ └── world │ │ │ │ ├── Day.java │ │ │ │ ├── InCuboid.java │ │ │ │ ├── Location.java │ │ │ │ ├── Night.java │ │ │ │ ├── Region.java │ │ │ │ ├── Time.java │ │ │ │ └── World.java │ │ ├── parser │ │ │ ├── ArgumentParser.java │ │ │ ├── CompositeConditionParser.java │ │ │ ├── ConditionParser.java │ │ │ ├── ParsedCondition.java │ │ │ ├── Parser.java │ │ │ └── StatementParser.java │ │ └── type │ │ │ ├── EnumOptions.java │ │ │ ├── LocationArgument.java │ │ │ ├── MultiLocation.java │ │ │ ├── MultiString.java │ │ │ └── Operation.java │ ├── icon │ │ ├── Icon.java │ │ └── IconManager.java │ ├── integration │ │ ├── IntegrationManager.java │ │ ├── impl │ │ │ ├── axgens │ │ │ │ ├── AxGensCache.java │ │ │ │ └── LookingAtAxGen.java │ │ │ ├── betonquest │ │ │ │ ├── BetonQuestCondition.java │ │ │ │ ├── actions │ │ │ │ │ ├── EndConversationCommand.java │ │ │ │ │ ├── NextOptionCommand.java │ │ │ │ │ └── SelectOptionCommand.java │ │ │ │ └── conversation │ │ │ │ │ ├── TooltipsConversationData.java │ │ │ │ │ └── TooltipsConversationIO.java │ │ │ ├── crucible │ │ │ │ └── CrucibleFurnitureProvider.java │ │ │ ├── itemsadder │ │ │ │ └── ItemsAdderFurnitureProvider.java │ │ │ ├── nbtapi │ │ │ │ ├── NBTBlockWrapper.java │ │ │ │ ├── NBTEntityWrapper.java │ │ │ │ ├── NBTItemWrapper.java │ │ │ │ ├── NBTTileEntityWrapper.java │ │ │ │ └── NBTWrapper.java │ │ │ ├── nexo │ │ │ │ └── NexoFurnitureProvider.java │ │ │ ├── oraxen │ │ │ │ └── OraxenFurnitureProvider.java │ │ │ ├── packetevents │ │ │ │ ├── PacketEventsPacketProvider.java │ │ │ │ └── PacketEventsTitle.java │ │ │ ├── papi │ │ │ │ ├── PAPI.java │ │ │ │ └── TooltipsExpansion.java │ │ │ ├── protocollib │ │ │ │ ├── ProtocolLibPacketProvider.java │ │ │ │ └── ProtocolLibTitle.java │ │ │ └── worldguard │ │ │ │ └── WorldGuardAreaProvider.java │ │ ├── providers │ │ │ ├── AreaProvider.java │ │ │ ├── FurnitureProvider.java │ │ │ ├── PacketProvider.java │ │ │ └── Provider.java │ │ └── wrappers │ │ │ └── FurnitureWrapper.java │ ├── preset │ │ ├── Preset.java │ │ ├── PresetManager.java │ │ ├── actions │ │ │ ├── ActionProperties.java │ │ │ ├── DefaultTooltipAction.java │ │ │ └── command │ │ │ │ ├── ActionCommand.java │ │ │ │ ├── ActionCommands.java │ │ │ │ └── impl │ │ │ │ ├── DelayCommand.java │ │ │ │ ├── MessageCommand.java │ │ │ │ ├── RedisplayCommand.java │ │ │ │ ├── SkipCommand.java │ │ │ │ ├── SoundCommand.java │ │ │ │ └── vars │ │ │ │ ├── ClearVarCommand.java │ │ │ │ ├── ClearVarsCommand.java │ │ │ │ ├── SavePersistentVarsCommand.java │ │ │ │ ├── SetVarCommand.java │ │ │ │ └── VarCommand.java │ │ ├── animation │ │ │ ├── Animation.java │ │ │ ├── AnimationProvider.java │ │ │ ├── Animations.java │ │ │ ├── ParsedAnimation.java │ │ │ └── impl │ │ │ │ └── TypewriterAnimationProvider.java │ │ ├── functions │ │ │ ├── Function.java │ │ │ ├── FunctionContext.java │ │ │ ├── Functions.java │ │ │ └── impl │ │ │ │ ├── AnimationFunction.java │ │ │ │ ├── CapitalizeFunction.java │ │ │ │ ├── ContextFunction.java │ │ │ │ ├── DataFunction.java │ │ │ │ ├── HasContextFunction.java │ │ │ │ ├── HasDataFunction.java │ │ │ │ ├── IfFunction.java │ │ │ │ ├── LowercaseFunction.java │ │ │ │ ├── ParseFunction.java │ │ │ │ ├── PreprocessFunction.java │ │ │ │ ├── StaticFunction.java │ │ │ │ ├── StripFunction.java │ │ │ │ ├── UppercaseFunction.java │ │ │ │ └── variable │ │ │ │ ├── HasPVarFunction.java │ │ │ │ ├── HasVarFunction.java │ │ │ │ ├── PVarFunction.java │ │ │ │ └── VarFunction.java │ │ └── show │ │ │ └── ShowProperties.java │ ├── schema │ │ ├── SchemaManager.java │ │ └── SchemaPart.java │ ├── theme │ │ ├── Theme.java │ │ └── ThemeManager.java │ ├── title │ │ ├── Title.java │ │ ├── TitleBuilder.java │ │ └── TitleManager.java │ └── tooltip │ │ ├── Tooltip.java │ │ ├── TooltipManager.java │ │ ├── build │ │ ├── TooltipBuilder.java │ │ ├── TooltipProperties.java │ │ ├── element │ │ │ ├── BackgroundElement.java │ │ │ ├── TextLineElement.java │ │ │ └── TooltipElement.java │ │ └── text │ │ │ └── TextLine.java │ │ └── tasks │ │ ├── CacheTask.java │ │ ├── ConditionTask.java │ │ ├── TooltipTask.java │ │ └── data │ │ ├── CooldownType.java │ │ └── PlayerTooltipData.java │ ├── pack │ ├── Generator.java │ ├── PackData.java │ ├── PackGenerator.java │ └── impl │ │ ├── IconGenerator.java │ │ ├── LineGenerator.java │ │ ├── SpaceGenerator.java │ │ ├── TextureGenerator.java │ │ └── ThemeGenerator.java │ └── utils │ ├── AdventureUtils.java │ ├── Colors.java │ ├── Cuboid.java │ ├── Expr.java │ ├── FileSetup.java │ ├── FileUtils.java │ ├── NamespacedPath.java │ ├── Placeholders.java │ ├── PrioritySet.java │ ├── Text.java │ ├── Utils.java │ ├── cache │ ├── area │ │ └── CurrentAreaCache.java │ ├── furniture │ │ └── FurnitureCache.java │ ├── player │ │ └── LookingAtCache.java │ └── tooltip │ │ └── TooltipCache.java │ ├── font │ ├── Spaces.java │ └── Widths.java │ ├── rays │ └── Rays.java │ ├── validation │ ├── Validatable.java │ └── Validity.java │ └── variable │ └── Variables.java └── resources ├── default ├── .data │ ├── schemas │ │ ├── fonts.yml │ │ └── textures │ │ │ ├── accented.png │ │ │ ├── ascii.png │ │ │ ├── nonlatin_european.png │ │ │ └── space.png │ └── widths.yml ├── config │ ├── config.yml │ ├── icons │ │ └── default.yml │ ├── presets │ │ └── default.yml │ └── themes │ │ └── default.yml └── pack │ └── assets │ └── tooltips │ └── textures │ ├── example-icons │ ├── box.png │ ├── gem.png │ └── right-click.png │ ├── space.png │ └── tooltips │ └── default │ ├── five-line.png │ ├── four-line.png │ ├── one-line.png │ ├── three-line.png │ └── two-line.png └── plugin.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .metadata 2 | bin/ 3 | tmp/ 4 | *.tmp 5 | *.bak 6 | *.swp 7 | *~.nib 8 | local.properties 9 | .settings/ 10 | .loadpath 11 | .recommenders 12 | 13 | # External tool builders 14 | .externalToolBuilders/ 15 | 16 | # Locally stored "Eclipse launch configurations" 17 | *.launch 18 | 19 | # PyDev specific (Python IDE for Eclipse) 20 | *.pydevproject 21 | 22 | # CDT-specific (C/C++ Development Tooling) 23 | .cproject 24 | 25 | # CDT- autotools 26 | .autotools 27 | 28 | # Java annotation processor (APT) 29 | .factorypath 30 | 31 | # PDT-specific (PHP Development Tools) 32 | .buildpath 33 | 34 | # sbteclipse plugin 35 | .target 36 | 37 | # Tern plugin 38 | .tern-project 39 | 40 | # TeXlipse plugin 41 | .texlipse 42 | 43 | # STS (Spring Tool Suite) 44 | .springBeans 45 | 46 | # Code Recommenders 47 | .recommenders/ 48 | 49 | # Annotation Processing 50 | .apt_generated/ 51 | .apt_generated_test/ 52 | 53 | # Scala IDE specific (Scala & Java development for Eclipse) 54 | .cache-main 55 | .scala_dependencies 56 | .worksheet 57 | 58 | # Uncomment this line if you wish to ignore the project description file. 59 | # Typically, this file would be tracked if it contains build/dependency configurations: 60 | #.project 61 | *.properties 62 | *.lst 63 | /target/ 64 | .classpath 65 | .project 66 | /.idea 67 | *.iml 68 | /.run 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tooltips 2 | 🖼 A fancy tooltips plugin 3 | 4 | Currently, the license is All Rights Reserved 5 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | jdk: 2 | - openjdk21 3 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/commands/TooltipsSubCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.commands; 2 | 3 | import org.bukkit.command.Command; 4 | import org.bukkit.command.CommandSender; 5 | 6 | import java.util.List; 7 | 8 | public interface TooltipsSubCommand { 9 | 10 | void onCommand(CommandSender sender, Command command, String label, String[] args); 11 | 12 | /** 13 | * @param sender 14 | * @param command 15 | * @param label 16 | * @param relativeArgs Inside brackets = /tt vars [arg arg] 17 | * @return 18 | */ 19 | List onTabComplete(CommandSender sender, Command command, String label, String[] relativeArgs); 20 | 21 | String getPermission(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/commands/subcommands/EvalCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.commands.subcommands; 2 | 3 | import com.google.common.collect.Lists; 4 | import fi.septicuss.tooltips.Tooltips; 5 | import fi.septicuss.tooltips.commands.TooltipsSubCommand; 6 | import fi.septicuss.tooltips.utils.AdventureUtils; 7 | import fi.septicuss.tooltips.utils.Colors; 8 | import org.bukkit.command.Command; 9 | import org.bukkit.command.CommandSender; 10 | import org.bukkit.entity.Player; 11 | 12 | import java.util.List; 13 | 14 | public class EvalCommand implements TooltipsSubCommand { 15 | 16 | private Tooltips plugin; 17 | 18 | public EvalCommand(Tooltips plugin) { 19 | this.plugin = plugin; 20 | } 21 | 22 | @Override 23 | public void onCommand(CommandSender sender, Command command, String label, String[] args) { 24 | 25 | if (!(sender instanceof Player player)) { 26 | AdventureUtils.sendMessage(sender, Colors.WARN + "[!] Must be a player to use this command."); 27 | return; 28 | } 29 | 30 | if (args.length < 2) { 31 | AdventureUtils.sendMessage(sender, Colors.WARN + "[!] Missing condition"); 32 | return; 33 | } 34 | 35 | StringBuilder builder = new StringBuilder(); 36 | 37 | for (int i = 1; i < args.length; i++) { 38 | builder.append(args[i] + " "); 39 | } 40 | 41 | String conditionStr = builder.toString(); 42 | var parser = plugin.getConditionManager().getStatementParser(); 43 | var statement = parser.parse("eval", conditionStr); 44 | 45 | if (statement == null) { 46 | AdventureUtils.sendMessage(sender, Colors.WARN + "[!] An error occured while trying to parse condition"); 47 | return; 48 | } 49 | 50 | boolean result = statement.getCompositeCondition().check(player); 51 | 52 | AdventureUtils.sendMessage(sender, 53 | "Condition result: " + (result ? Colors.PLUGIN : Colors.WARN) + result); 54 | 55 | if (statement.hasOutcome()) 56 | AdventureUtils.sendMessage(sender, 57 | " Outcome: " + (statement.getOutcome().asBoolean() ? Colors.PLUGIN : Colors.WARN) 58 | + statement.getOutcome().toString()); 59 | 60 | } 61 | 62 | @Override 63 | public List onTabComplete(CommandSender sender, Command command, String label, String[] relativeArgs) { 64 | return Lists.newArrayList(); 65 | } 66 | 67 | @Override 68 | public String getPermission() { 69 | return "tooltips.command.eval"; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/commands/subcommands/ReloadCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.commands.subcommands; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.commands.TooltipsSubCommand; 5 | import fi.septicuss.tooltips.utils.AdventureUtils; 6 | import fi.septicuss.tooltips.utils.Colors; 7 | import org.bukkit.command.Command; 8 | import org.bukkit.command.CommandSender; 9 | 10 | import java.util.List; 11 | 12 | public class ReloadCommand implements TooltipsSubCommand { 13 | 14 | private Tooltips plugin; 15 | 16 | public ReloadCommand(Tooltips plugin) { 17 | this.plugin = plugin; 18 | } 19 | 20 | @Override 21 | public void onCommand(CommandSender sender, Command command, String label, String[] args) { 22 | AdventureUtils.sendMessage(sender, Colors.PLUGIN + "Reloading plugin..."); 23 | plugin.reload(); 24 | AdventureUtils.sendMessage(sender, Colors.PLUGIN + "Reloaded!"); 25 | } 26 | 27 | @Override 28 | public List onTabComplete(CommandSender sender, Command command, String label, String[] relativeArgs) { 29 | return null; 30 | } 31 | 32 | @Override 33 | public String getPermission() { 34 | return "tooltips.command.reload"; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/listener/PlayerConnectionListener.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.listener; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.utils.cache.player.LookingAtCache; 5 | import fi.septicuss.tooltips.utils.cache.tooltip.TooltipCache; 6 | import org.bukkit.event.EventHandler; 7 | import org.bukkit.event.Listener; 8 | import org.bukkit.event.player.PlayerQuitEvent; 9 | 10 | public class PlayerConnectionListener implements Listener { 11 | 12 | @EventHandler 13 | public void on(PlayerQuitEvent event) { 14 | TooltipCache.remove(event.getPlayer()); 15 | LookingAtCache.remove(event.getPlayer()); 16 | Tooltips.get().getTooltipManager().removePlayerTooltipData(event.getPlayer()); 17 | } 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/listener/PlayerMovementListener.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.listener; 2 | 3 | import fi.septicuss.tooltips.managers.integration.IntegrationManager; 4 | import fi.septicuss.tooltips.managers.integration.providers.AreaProvider; 5 | import fi.septicuss.tooltips.utils.cache.area.CurrentAreaCache; 6 | import org.bukkit.Location; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.event.EventHandler; 9 | import org.bukkit.event.Listener; 10 | import org.bukkit.event.player.PlayerMoveEvent; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | public class PlayerMovementListener implements Listener { 16 | 17 | private final IntegrationManager integrationManager; 18 | 19 | public PlayerMovementListener(IntegrationManager integrationManager) { 20 | this.integrationManager = integrationManager; 21 | } 22 | 23 | @EventHandler 24 | public void on(PlayerMoveEvent event) { 25 | 26 | var from = event.getFrom(); 27 | var to = event.getTo(); 28 | 29 | if (!hasBlockChanged(from, to)) { 30 | return; 31 | } 32 | 33 | if (!integrationManager.getAreaProviders().isEmpty()) { 34 | cacheApplicableAreas(event.getPlayer(), to); 35 | } 36 | 37 | } 38 | 39 | private void cacheApplicableAreas(Player player, Location location) { 40 | List applicable = new ArrayList<>(); 41 | 42 | for (AreaProvider provider : integrationManager.getAreaProviders().values()) { 43 | final List providerAreas = provider.getApplicableAreas(location); 44 | 45 | if (providerAreas == null) { 46 | continue; 47 | } 48 | 49 | applicable.addAll(providerAreas); 50 | } 51 | 52 | CurrentAreaCache.put(player, applicable); 53 | } 54 | 55 | private boolean hasBlockChanged(Location from, Location to) { 56 | return !(from.getBlockX() == to.getBlockX() && from.getBlockY() == to.getBlockY() 57 | && from.getBlockZ() == to.getBlockZ()); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/Condition.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.utils.Utils; 5 | import fi.septicuss.tooltips.utils.validation.Validity; 6 | import org.bukkit.entity.Player; 7 | 8 | public interface Condition { 9 | 10 | default boolean check(Player player, Arguments args) { 11 | return false; 12 | } 13 | 14 | default void writeContext(Player player, Arguments args, Context context) { } 15 | 16 | Validity valid(Arguments args); 17 | 18 | String id(); 19 | 20 | default String quote(String message) { 21 | return Utils.quote(message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/ConditionManager.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition; 2 | 3 | import fi.septicuss.tooltips.managers.condition.parser.ArgumentParser; 4 | import fi.septicuss.tooltips.managers.condition.parser.CompositeConditionParser; 5 | import fi.septicuss.tooltips.managers.condition.parser.ConditionParser; 6 | import fi.septicuss.tooltips.managers.condition.parser.StatementParser; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Set; 11 | 12 | public class ConditionManager { 13 | 14 | private final Map registeredConditions; 15 | 16 | private final ArgumentParser argumentParser; 17 | private final ConditionParser conditionParser; 18 | private final CompositeConditionParser compositeParser; 19 | private final StatementParser statementParser; 20 | 21 | public ConditionManager() { 22 | 23 | this.registeredConditions = new HashMap<>(); 24 | 25 | this.argumentParser = new ArgumentParser(); 26 | this.conditionParser = new ConditionParser(this, argumentParser); 27 | this.compositeParser = new CompositeConditionParser(conditionParser); 28 | this.statementParser = new StatementParser(compositeParser); 29 | 30 | } 31 | 32 | public void register(Condition condition) { 33 | registeredConditions.put(condition.id(), condition); 34 | } 35 | 36 | public void register(Condition... conditions) { 37 | for (var condition : conditions) 38 | this.register(condition); 39 | } 40 | 41 | public void unregister(String name) { 42 | registeredConditions.remove(name); 43 | } 44 | 45 | public Set getConditions() { 46 | return this.registeredConditions.keySet(); 47 | } 48 | 49 | public boolean exists(String name) { 50 | return registeredConditions.containsKey(name); 51 | } 52 | 53 | public Condition get(String name) { 54 | return registeredConditions.get(name); 55 | } 56 | 57 | public ArgumentParser getArgumentParser() { 58 | return argumentParser; 59 | } 60 | 61 | public ConditionParser getConditionParser() { 62 | return conditionParser; 63 | } 64 | 65 | public CompositeConditionParser getCompositeParser() { 66 | return compositeParser; 67 | } 68 | 69 | public StatementParser getStatementParser() { 70 | return statementParser; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/Context.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition; 2 | 3 | import javax.annotation.Nullable; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | public class Context implements Cloneable{ 8 | 9 | private final Map context; 10 | 11 | public Context() { 12 | this.context = new HashMap<>(); 13 | } 14 | 15 | public Context(Map context) { 16 | this.context = context; 17 | } 18 | 19 | public @Nullable Object get(String key) { 20 | return this.context.get(key); 21 | } 22 | 23 | public boolean has(String key) { 24 | return this.context.containsKey(key); 25 | } 26 | 27 | public void put(String key, Object context) { 28 | this.context.put(key, context); 29 | } 30 | 31 | public void put(Context otherContext) { 32 | this.context.putAll(otherContext.contextMap()); 33 | } 34 | 35 | public void remove(String key) { 36 | this.context.remove(key); 37 | } 38 | 39 | public void merge(Context otherContext) { 40 | this.context.putAll(otherContext.contextMap()); 41 | } 42 | 43 | public Map contextMap() { 44 | return this.context; 45 | } 46 | 47 | @Override 48 | public Context clone() { 49 | return new Context(this.context); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/Statement.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition; 2 | 3 | import fi.septicuss.tooltips.managers.condition.composite.CompositeCondition; 4 | 5 | public class Statement { 6 | 7 | private Outcome outcome; 8 | private CompositeCondition condition; 9 | 10 | public Statement(CompositeCondition condition, Outcome outcome) { 11 | this.condition = condition; 12 | this.outcome = outcome; 13 | } 14 | 15 | public Statement(CompositeCondition condition) { 16 | this(condition, null); 17 | } 18 | 19 | public Outcome getOutcome() { 20 | return outcome; 21 | } 22 | 23 | public boolean hasOutcome() { 24 | return (outcome != null); 25 | } 26 | 27 | public CompositeCondition getCompositeCondition() { 28 | return condition; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return "Statement [" + condition.toString() + ", " + outcome.toString() + "]"; 34 | } 35 | 36 | public enum Outcome { 37 | 38 | REQUIRED(true), CANCEL(false), SKIP(true); 39 | 40 | private boolean bool; 41 | 42 | private Outcome(boolean bool) { 43 | this.bool = bool; 44 | } 45 | 46 | public boolean asBoolean() { 47 | return bool; 48 | } 49 | 50 | public static Outcome parseOutcome(String value) { 51 | for (var outcome : values()) { 52 | if (String.valueOf(outcome.asBoolean()).equalsIgnoreCase(value) || outcome.toString().equalsIgnoreCase(value)) 53 | return outcome; 54 | } 55 | 56 | return null; 57 | } 58 | 59 | public static boolean isOutcome(String value) { 60 | if (value == null) 61 | return false; 62 | if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) 63 | return true; 64 | 65 | for (var outcome : values()) 66 | if (outcome.toString().equalsIgnoreCase(value)) 67 | return true; 68 | 69 | return false; 70 | } 71 | 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/StatementHolder.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition; 2 | 3 | import fi.septicuss.tooltips.managers.condition.composite.CompositeCondition; 4 | import fi.septicuss.tooltips.managers.condition.parser.ParsedCondition; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class StatementHolder { 12 | 13 | private List statements; 14 | 15 | public StatementHolder() { 16 | this.statements = new ArrayList<>(); 17 | } 18 | 19 | public StatementHolder(List statements) { 20 | this.statements = statements; 21 | } 22 | 23 | public void addStatement(Statement statement) { 24 | statements.add(statement); 25 | } 26 | 27 | public boolean evaluate(Player player, Context context) { 28 | 29 | for (var statement : statements) { 30 | if (statement == null || statement.getCompositeCondition() == null) 31 | continue; 32 | 33 | boolean conditionResult = statement.getCompositeCondition().check(player, context); 34 | 35 | if (statement.hasOutcome()) { 36 | final var outcome = statement.getOutcome(); 37 | 38 | if (outcome == Statement.Outcome.SKIP) { 39 | this.writeSkippedContext(player, context, statement); 40 | continue; 41 | } 42 | 43 | final boolean required = statement.getOutcome().asBoolean(); 44 | 45 | if (required) { 46 | if (!conditionResult) return false; 47 | } else { 48 | if (conditionResult) return false; 49 | else continue; 50 | } 51 | 52 | } 53 | 54 | 55 | if (!conditionResult) return false; 56 | 57 | } 58 | 59 | return true; 60 | 61 | } 62 | 63 | public List getStatements() { 64 | return Collections.unmodifiableList(statements); 65 | } 66 | 67 | private void writeSkippedContext(Player player, Context context, Statement statement) { 68 | 69 | final CompositeCondition compositeCondition = statement.getCompositeCondition(); 70 | if (compositeCondition == null) return; 71 | 72 | writeSkippedContext(player, context, compositeCondition); 73 | 74 | } 75 | 76 | private void writeSkippedContext(Player player, Context context, CompositeCondition compositeCondition) { 77 | 78 | if (compositeCondition.hasLeft()) 79 | writeSkippedContext(player, context, compositeCondition.getLeft()); 80 | 81 | if (compositeCondition.hasRight()) 82 | writeSkippedContext(player, context, compositeCondition.getRight()); 83 | 84 | if (compositeCondition.hasCondition()) { 85 | final ParsedCondition parsedCondition = compositeCondition.getParsedCondition(); 86 | if (parsedCondition == null) return; 87 | 88 | final Condition condition = parsedCondition.getCondition(); 89 | if (condition == null) return; 90 | 91 | condition.writeContext(player, parsedCondition.getArgs(), context); 92 | } 93 | 94 | } 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/argument/Argument.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.argument; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Context; 4 | import fi.septicuss.tooltips.managers.condition.type.EnumOptions; 5 | import fi.septicuss.tooltips.managers.condition.type.LocationArgument; 6 | import fi.septicuss.tooltips.utils.Text; 7 | import org.bukkit.entity.Player; 8 | 9 | public class Argument { 10 | 11 | private String value; 12 | 13 | public Argument(String value) { 14 | this.value = value; 15 | } 16 | 17 | public Argument process(Player player) { 18 | if (player == null) return this; 19 | return new Argument(Text.processText(player, value)); 20 | } 21 | 22 | public Argument process(Player player, Context context) { 23 | if (player == null) return this; 24 | return new Argument(Text.processTextWithContext(player, this.value, context)); 25 | } 26 | 27 | public String getAsString() { 28 | return value; 29 | } 30 | 31 | public boolean getAsBool() { 32 | return Boolean.parseBoolean(value); 33 | } 34 | 35 | public int getAsInt() { 36 | return Integer.parseInt(value); 37 | } 38 | 39 | public double getAsDouble() { 40 | return Double.parseDouble(value); 41 | } 42 | 43 | public long getAsLong() { 44 | return Long.parseLong(value); 45 | } 46 | 47 | public float getAsFloat() { 48 | try { 49 | return Float.parseFloat(value); 50 | } catch (NumberFormatException e) { 51 | return 0f; 52 | } 53 | } 54 | 55 | public > EnumOptions getAsEnumOptions(Class enumType) { 56 | return EnumOptions.of(enumType, value); 57 | } 58 | 59 | public LocationArgument getAsLocationArgument(Player player) { 60 | return LocationArgument.of(player, value); 61 | } 62 | 63 | public boolean isNumber() { 64 | try { 65 | Double.parseDouble(value); 66 | return true; 67 | } catch (NumberFormatException e) { 68 | return false; 69 | } 70 | } 71 | 72 | public boolean isBoolean() { 73 | if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) 74 | return true; 75 | return false; 76 | } 77 | 78 | @Override 79 | public String toString() { 80 | return "Argument{value=" + value + "}"; 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/argument/Arguments.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.argument; 2 | 3 | import java.util.HashMap; 4 | import java.util.Set; 5 | 6 | public class Arguments { 7 | 8 | private HashMap argumentMap = new HashMap<>(); 9 | 10 | public Arguments() { 11 | argumentMap = new HashMap<>(); 12 | } 13 | 14 | public void add(String name, Argument argument) { 15 | argumentMap.put(name, argument); 16 | } 17 | 18 | public Argument get(String... aliases) { 19 | for (var alias : aliases) { 20 | if (alias == null) continue; 21 | if (argumentMap.containsKey(alias)) { 22 | return argumentMap.get(alias); 23 | } 24 | } 25 | return null; 26 | } 27 | 28 | public boolean has(String... aliases) { 29 | for (var alias : aliases) 30 | if (argumentMap.containsKey(alias)) 31 | return true; 32 | 33 | return false; 34 | } 35 | 36 | public boolean isNumber(String... aliases) { 37 | if (!has(aliases)) 38 | return false; 39 | try { 40 | Double.parseDouble(get(aliases).getAsString()); 41 | return true; 42 | } catch (NumberFormatException e) { 43 | return false; 44 | } 45 | } 46 | 47 | public boolean isBoolean(String... aliases) { 48 | if (!has(aliases)) { 49 | return false; 50 | } 51 | String value = get(aliases).getAsString(); 52 | if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) 53 | return true; 54 | return false; 55 | } 56 | 57 | public void remove(String... aliases) { 58 | for (var alias : aliases) 59 | argumentMap.remove(alias); 60 | } 61 | 62 | public Set keys() { 63 | return argumentMap.keySet(); 64 | } 65 | 66 | public boolean areEmpty() { 67 | return argumentMap.isEmpty(); 68 | } 69 | 70 | public int size() { 71 | return argumentMap.size(); 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return "Arguments{" + argumentMap.toString() + "}"; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/composite/CompositeConditionBuilder.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.composite; 2 | 3 | import fi.septicuss.tooltips.managers.condition.composite.CompositeCondition.Operator; 4 | import fi.septicuss.tooltips.managers.condition.parser.ParsedCondition; 5 | 6 | public class CompositeConditionBuilder { 7 | 8 | private CompositeCondition root; 9 | 10 | /*-* 11 | // meow AND meow 12 | // null 13 | // / \ 14 | // / AND \ 15 | // meow meow 16 | // 17 | 18 | // meow AND meow OR meow OR meow 19 | // null 20 | // / \ 21 | // / AND \ 22 | // meow null 23 | // / \ 24 | // / OR \ 25 | // meow null 26 | // / \ 27 | // / OR \ 28 | // meow meow 29 | // 30 | 31 | // (meow AND meow) OR (meow OR meow) 32 | // null 33 | // / \ 34 | // / OR \ 35 | // null null 36 | // / \ / \ 37 | // / AND\ / OR \ 38 | // meow meow meow meow 39 | // 40 | **/ 41 | public CompositeConditionBuilder() { 42 | this.root = new CompositeCondition(null); 43 | } 44 | 45 | public CompositeConditionBuilder with(ParsedCondition condition) { 46 | var left = new CompositeCondition(condition); 47 | root.setLeft(left); 48 | return this; 49 | } 50 | 51 | public CompositeConditionBuilder with(CompositeCondition composite) { 52 | root.setLeft(composite); 53 | return this; 54 | } 55 | 56 | public CompositeConditionBuilder append(Operator operator, ParsedCondition condition) { 57 | root.setOperator(operator); 58 | root.setRight(new CompositeCondition(condition)); 59 | return this; 60 | } 61 | 62 | public CompositeConditionBuilder append(Operator operator, CompositeCondition composite) { 63 | root.setOperator(operator); 64 | root.setRight(composite); 65 | return this; 66 | } 67 | 68 | public CompositeCondition build() { 69 | return root; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/equals/BlockNbtEquals.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.equals; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.integration.impl.nbtapi.NBTBlockWrapper; 7 | import fi.septicuss.tooltips.utils.Utils; 8 | import fi.septicuss.tooltips.utils.validation.Validity; 9 | import org.bukkit.Bukkit; 10 | import org.bukkit.block.Block; 11 | import org.bukkit.entity.Player; 12 | 13 | public class BlockNbtEquals implements Condition { 14 | 15 | private static final String[] DISTANCE = { "d", "dist", "distance" }; 16 | private static final String[] KEY = { "key", "k" }; 17 | private static final String[] VALUE = { "nbtval", "value", "nbtvalue", "val", "v" }; 18 | 19 | @Override 20 | public boolean check(Player player, Arguments args) { 21 | int distance = 3; 22 | 23 | if (args.has(DISTANCE)) 24 | distance = args.get(DISTANCE).getAsInt(); 25 | 26 | var rayTrace = Utils.getRayTraceResult(player, distance); 27 | 28 | if (rayTrace == null || rayTrace.getHitBlock() == null) 29 | return false; 30 | 31 | Block block = rayTrace.getHitBlock(); 32 | 33 | String key = args.get(KEY).getAsString(); 34 | var compound = new NBTBlockWrapper(block).getCompound(); 35 | 36 | Argument valueArg = args.get(VALUE); 37 | 38 | if (key.contains(".")) { 39 | String[] split = key.split("\\."); 40 | for (int i = 0; i < split.length; i++) { 41 | if (i == split.length - 1) { 42 | key = split[i]; 43 | continue; 44 | } 45 | compound = compound.getCompound(split[i]); 46 | if (compound == null) 47 | return false; 48 | } 49 | } 50 | 51 | if (valueArg.isNumber()) { 52 | int num = valueArg.getAsInt(); 53 | return compound.getInteger(key) == num; 54 | } 55 | 56 | if (valueArg.isBoolean()) { 57 | boolean bool = valueArg.getAsBool(); 58 | return compound.getBoolean(key) == bool; 59 | } 60 | 61 | String str = valueArg.getAsString(); 62 | return compound.getString(key).equals(str); 63 | } 64 | 65 | @Override 66 | public Validity valid(Arguments args) { 67 | if (Bukkit.getPluginManager().isPluginEnabled("NBTAPI")) { 68 | return Validity.of(false, "Cannot use blocknbtequals because NBTAPI is not installed"); 69 | } 70 | 71 | if (!args.has(KEY)) { 72 | return Validity.of(false, "Key argument is missing"); 73 | } 74 | 75 | if (!args.has(VALUE)) { 76 | return Validity.of(false, "Value argument is missing"); 77 | } 78 | 79 | return Validity.TRUE; 80 | } 81 | 82 | @Override 83 | public String id() { 84 | return "blocknbtequals"; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/equals/BlockStateEquals.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.equals; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.utils.Utils; 6 | import fi.septicuss.tooltips.utils.validation.Validity; 7 | import org.bukkit.block.Block; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | public class BlockStateEquals implements Condition { 14 | 15 | private static final String[] DISTANCE = {"distance", "dist", "d"}; 16 | private static final String[] KEY = {"key", "k", "id"}; 17 | private static final String[] VALUE = {"value", "val", "v"}; 18 | 19 | @Override 20 | public boolean check(Player player, Arguments args) { 21 | int distance = 3; 22 | 23 | if (args.has(DISTANCE)) 24 | distance = args.get(DISTANCE).getAsInt(); 25 | 26 | var rayTrace = Utils.getRayTraceResult(player, distance); 27 | 28 | if (rayTrace == null || rayTrace.getHitBlock() == null) { 29 | return false; 30 | } 31 | 32 | Block hit = rayTrace.getHitBlock(); 33 | 34 | if (hit.getBlockData() == null) { 35 | return false; 36 | } 37 | 38 | String blockDataString = hit.getBlockData().getAsString(); 39 | Map stateMap = getBlockStateMap(blockDataString); 40 | 41 | String key = args.get(KEY).getAsString(); 42 | String comparableValue = args.get(VALUE).getAsString(); 43 | 44 | if (!stateMap.containsKey(key)) { 45 | return false; 46 | } 47 | 48 | String value = stateMap.get(key); 49 | return (value.equals(comparableValue)); 50 | } 51 | 52 | @Override 53 | public Validity valid(Arguments args) { 54 | 55 | if (args.has(DISTANCE) && !args.isNumber(DISTANCE)) 56 | return Validity.of(false, "Distance must be a number"); 57 | 58 | if (!args.has(KEY)) 59 | return Validity.of(false, "Key argument is required"); 60 | 61 | if (!args.has(VALUE)) 62 | return Validity.of(false, "Value argument is required"); 63 | 64 | return Validity.TRUE; 65 | } 66 | 67 | @Override 68 | public String id() { 69 | return "blockstateequals"; 70 | } 71 | 72 | private Map getBlockStateMap(String blockDataString) { 73 | // blockDataString is of the following format: 74 | // minecraft:chest[waterlogged=false] 75 | 76 | Map map = new HashMap<>(); 77 | 78 | int firstSquareBracket = blockDataString.indexOf("["); 79 | 80 | if (firstSquareBracket == -1) { 81 | return map; 82 | } 83 | 84 | String states = blockDataString.substring(firstSquareBracket + 1, blockDataString.length() - 1); 85 | 86 | for (var state : states.split(",")) { 87 | var keyValue = state.split("="); 88 | var key = keyValue[0]; 89 | var value = keyValue[1]; 90 | map.put(key, value); 91 | } 92 | 93 | return map; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/equals/ItemNbtEquals.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.equals; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.integration.impl.nbtapi.NBTItemWrapper; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.EquipmentSlot; 11 | import org.bukkit.inventory.ItemStack; 12 | 13 | public class ItemNbtEquals implements Condition { 14 | 15 | private static final String[] KEY = { "key", "k" }; 16 | private static final String[] VALUE = { "nbtval", "value", "nbtvalue", "val", "v" }; 17 | private static final String[] SLOT = { "slot", "s" }; 18 | 19 | public boolean check(Player player, Arguments args) { 20 | EquipmentSlot slot = EquipmentSlot.HAND; 21 | if (args.has(SLOT)) 22 | slot = EquipmentSlot.valueOf(args.get(SLOT).getAsString().strip().toUpperCase()); 23 | 24 | ItemStack item = player.getInventory().getItem(slot); 25 | 26 | if (item == null || item.getType().isAir()) 27 | return false; 28 | 29 | String key = args.get(KEY).getAsString(); 30 | var nbti = new NBTItemWrapper(item).getCompound(); 31 | 32 | if (key.contains(".")) { 33 | String[] split = key.split("\\."); 34 | for (int i = 0; i < split.length; i++) { 35 | if (i == split.length - 1) { 36 | key = split[i]; 37 | } else { 38 | nbti = nbti.getCompound(split[i]); 39 | if (nbti == null) 40 | return false; 41 | } 42 | } 43 | } 44 | 45 | Argument valueArg = args.get(VALUE); 46 | 47 | if (valueArg.isNumber()) { 48 | int i = valueArg.getAsInt(); 49 | return (nbti.getInteger(key).intValue() == i); 50 | } 51 | if (valueArg.isBoolean()) { 52 | boolean bool = valueArg.getAsBool(); 53 | return (nbti.getBoolean(key).booleanValue() == bool); 54 | } 55 | 56 | String value = valueArg.getAsString(); 57 | return nbti.getString(key).equals(value); 58 | } 59 | 60 | public Validity valid(Arguments args) { 61 | if (!Bukkit.getPluginManager().isPluginEnabled("NBTAPI")) { 62 | return Validity.of(false, "Cannot use itemnbtequals because NBTAPI is not installed"); 63 | } 64 | 65 | if (!args.has(KEY)) { 66 | return Validity.of(false, "Key argument is missing"); 67 | } 68 | 69 | if (!args.has(VALUE)) { 70 | return Validity.of(false, "Value argument is missing"); 71 | } 72 | 73 | if (args.has(SLOT)) { 74 | String slot = args.get(SLOT).getAsString(); 75 | try { 76 | return Validity.of(false, "Unknown slot " + quote(slot)); 77 | } catch (IllegalArgumentException e) { 78 | return Validity.of(false, null); 79 | } 80 | } 81 | 82 | return Validity.TRUE; 83 | } 84 | 85 | @Override 86 | public String id() { 87 | return "itemnbtequals"; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/equals/TileEntityNbtEquals.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.equals; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.integration.impl.nbtapi.NBTTileEntityWrapper; 7 | import fi.septicuss.tooltips.utils.Utils; 8 | import fi.septicuss.tooltips.utils.validation.Validity; 9 | import org.bukkit.Bukkit; 10 | import org.bukkit.block.Block; 11 | import org.bukkit.entity.Player; 12 | 13 | public class TileEntityNbtEquals implements Condition { 14 | 15 | private static final String[] DISTANCE = { "d", "dist", "distance" }; 16 | private static final String[] KEY = { "key", "k" }; 17 | private static final String[] VALUE = { "nbtval", "value", "nbtvalue", "val", "v" }; 18 | 19 | @Override 20 | public boolean check(Player player, Arguments args) { 21 | int distance = 3; 22 | 23 | if (args.has(DISTANCE)) 24 | distance = args.get(DISTANCE).getAsInt(); 25 | 26 | var rayTrace = Utils.getRayTraceResult(player, distance); 27 | 28 | if (rayTrace == null || rayTrace.getHitBlock() == null) 29 | return false; 30 | 31 | Block block = rayTrace.getHitBlock(); 32 | 33 | String key = args.get(KEY).getAsString(); 34 | var compound = new NBTTileEntityWrapper(block.getState()).getCompound(); 35 | 36 | Argument valueArg = args.get(VALUE); 37 | 38 | if (key.contains(".")) { 39 | String[] split = key.split("\\."); 40 | for (int i = 0; i < split.length; i++) { 41 | if (i == split.length - 1) { 42 | key = split[i]; 43 | continue; 44 | } 45 | compound = compound.getCompound(split[i]); 46 | if (compound == null) { 47 | return false; 48 | } 49 | } 50 | } 51 | 52 | if (valueArg.isNumber()) { 53 | int num = valueArg.getAsInt(); 54 | return compound.getInteger(key) == num; 55 | } 56 | 57 | if (valueArg.isBoolean()) { 58 | boolean bool = valueArg.getAsBool(); 59 | return compound.getBoolean(key) == bool; 60 | } 61 | 62 | String str = valueArg.getAsString(); 63 | return compound.getString(key).equals(str); 64 | } 65 | 66 | @Override 67 | public Validity valid(Arguments args) { 68 | if (!Bukkit.getPluginManager().isPluginEnabled("NBTAPI")) { 69 | return Validity.of(false, "Cannot use entitynbtequals because NBTAPI is not installed"); 70 | } 71 | 72 | if (!args.has(KEY)) { 73 | return Validity.of(false, "Key argument is missing"); 74 | } 75 | 76 | if (!args.has(VALUE)) { 77 | return Validity.of(false, "Value argument is missing"); 78 | } 79 | 80 | return Validity.TRUE; 81 | } 82 | 83 | @Override 84 | public String id() { 85 | return "tileentitynbtequals"; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/lookingat/LookingAtBlock.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.lookingat; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.condition.type.EnumOptions; 7 | import fi.septicuss.tooltips.managers.condition.type.MultiLocation; 8 | import fi.septicuss.tooltips.utils.Utils; 9 | import fi.septicuss.tooltips.utils.validation.Validity; 10 | import org.bukkit.Material; 11 | import org.bukkit.block.Block; 12 | import org.bukkit.entity.Player; 13 | 14 | public class LookingAtBlock implements Condition { 15 | 16 | private static final String[] MATERIAL_ALIASES = { "type", "m", "mat", "material" }; 17 | private static final String[] DISTANCE_ALIASES = { "distance", "d" }; 18 | private static final String[] LOCATION_ALIASES = { "l", "loc", "location" }; 19 | 20 | @Override 21 | public boolean check(Player player, Arguments args) { 22 | EnumOptions materials = null; 23 | MultiLocation locations = null; 24 | int distance = 3; 25 | 26 | if (args.isNumber(DISTANCE_ALIASES)) 27 | distance = args.get(DISTANCE_ALIASES).getAsInt(); 28 | 29 | if (args.has(MATERIAL_ALIASES)) 30 | materials = args.get(MATERIAL_ALIASES).getAsEnumOptions(Material.class); 31 | 32 | if (args.has(LOCATION_ALIASES)) 33 | locations = MultiLocation.of(player, args.get(LOCATION_ALIASES).getAsString()); 34 | 35 | var rayTrace = Utils.getRayTraceResult(player, distance); 36 | 37 | if (rayTrace == null) 38 | return false; 39 | 40 | Block target = rayTrace.getHitBlock(); 41 | 42 | if (target == null) { 43 | if (materials == null) 44 | return false; 45 | return materials.contains(Material.AIR); 46 | } 47 | 48 | boolean validMaterial = (materials == null ? true : materials.contains(target.getType())); 49 | boolean validLocation = (locations == null ? true : locations.contains(target.getLocation())); 50 | 51 | return (validMaterial && validLocation); 52 | } 53 | 54 | @Override 55 | public Validity valid(Arguments args) { 56 | 57 | if (!args.has(MATERIAL_ALIASES) && !args.has(LOCATION_ALIASES)) 58 | return Validity.of(false, "A material and/or location argument is required"); 59 | 60 | if (args.has(MATERIAL_ALIASES)) { 61 | Argument materialArg = args.get(MATERIAL_ALIASES); 62 | Validity optionValidity = EnumOptions.validity(Material.class, materialArg.getAsString()); 63 | 64 | if (!optionValidity.isValid()) { 65 | return optionValidity; 66 | } 67 | } 68 | 69 | if (args.has(LOCATION_ALIASES)) { 70 | Argument locationArg = args.get(LOCATION_ALIASES); 71 | Validity multiLocationValidity = MultiLocation.validityOf(locationArg.getAsString()); 72 | 73 | if (!multiLocationValidity.isValid()) { 74 | return multiLocationValidity; 75 | } 76 | } 77 | 78 | return Validity.TRUE; 79 | } 80 | 81 | @Override 82 | public String id() { 83 | return "lookingatblock"; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/lookingat/LookingAtCitizen.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.lookingat; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.condition.type.MultiString; 7 | import fi.septicuss.tooltips.utils.Utils; 8 | import fi.septicuss.tooltips.utils.validation.Validity; 9 | import net.citizensnpcs.api.CitizensAPI; 10 | import net.citizensnpcs.api.npc.NPC; 11 | import net.citizensnpcs.api.npc.NPCRegistry; 12 | import org.bukkit.Bukkit; 13 | import org.bukkit.entity.Entity; 14 | import org.bukkit.entity.Player; 15 | 16 | public class LookingAtCitizen implements Condition { 17 | 18 | private static final String[] DISTANCE = { "distance", "dist", "d" }; 19 | private static final String[] ID = { "id" }; 20 | 21 | @Override 22 | public boolean check(Player player, Arguments args) { 23 | 24 | MultiString ids = null; 25 | 26 | if (args.has(ID)) 27 | ids = MultiString.of(args.get(ID).getAsString()); 28 | 29 | final NPC citizen = this.getCitizen(player, args); 30 | 31 | if (citizen == null) { 32 | return false; 33 | } 34 | 35 | // Any citizen 36 | if (ids == null) { 37 | return true; 38 | } 39 | 40 | // Specific ID citizen 41 | final String id = String.valueOf(citizen.getId()); 42 | return ids.contains(id); 43 | } 44 | 45 | @Override 46 | public void writeContext(Player player, Arguments args, Context context) { 47 | final NPC citizen = this.getCitizen(player, args); 48 | 49 | if (citizen == null) { 50 | return; 51 | } 52 | 53 | context.put("citizen.id", citizen.getId()); 54 | } 55 | 56 | private NPC getCitizen(Player player, Arguments args) { 57 | int distance = 3; 58 | 59 | if (args.has(DISTANCE)) 60 | distance = args.get(DISTANCE).getAsInt(); 61 | 62 | var rayTrace = Utils.getRayTraceResult(player, distance); 63 | 64 | if (rayTrace == null || rayTrace.getHitEntity() == null) 65 | return null; 66 | 67 | Entity entity = rayTrace.getHitEntity(); 68 | 69 | NPCRegistry registry = CitizensAPI.getNPCRegistry(); 70 | 71 | if (!registry.isNPC(entity)) 72 | return null; 73 | 74 | return registry.getNPC(entity); 75 | } 76 | 77 | @Override 78 | public Validity valid(Arguments args) { 79 | if (!Bukkit.getPluginManager().isPluginEnabled("Citizens")) 80 | return Validity.of(false, "Citizens is required for this condition."); 81 | 82 | if (CitizensAPI.getNPCRegistry() == null) 83 | return Validity.of(false, "Citizens is required for this condition."); 84 | 85 | if (args.has(DISTANCE) && !args.isNumber(DISTANCE)) 86 | return Validity.of(false, "Distance must be a number"); 87 | 88 | return Validity.TRUE; 89 | } 90 | 91 | @Override 92 | public String id() { 93 | return "lookingatcitizen"; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/lookingat/LookingAtEntity.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.lookingat; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.condition.type.EnumOptions; 7 | import fi.septicuss.tooltips.utils.Utils; 8 | import fi.septicuss.tooltips.utils.validation.Validity; 9 | import org.bukkit.entity.Entity; 10 | import org.bukkit.entity.EntityType; 11 | import org.bukkit.entity.Player; 12 | 13 | public class LookingAtEntity implements Condition { 14 | 15 | private static final String[] DISTANCE = {"d", "dist", "distance"}; 16 | private static final String[] TYPE = {"entity", "type", "t"}; 17 | 18 | @Override 19 | public boolean check(Player player, Arguments args) { 20 | return this.entity(player, args) != null; 21 | } 22 | 23 | @Override 24 | public void writeContext(Player player, Arguments args, Context context) { 25 | Entity entity = this.entity(player, args); 26 | if (entity != null) 27 | context.put("lookingatentity.name", entity.getName()); 28 | } 29 | 30 | @Override 31 | public Validity valid(Arguments args) { 32 | 33 | if (args.has(DISTANCE) && !args.isNumber(DISTANCE)) { 34 | return Validity.of(false, "Distance integer must be present"); 35 | } 36 | 37 | if (args.has(TYPE)) { 38 | String type = args.get(TYPE).getAsString(); 39 | Validity typeValidity = EnumOptions.validity(EntityType.class, type); 40 | 41 | if (!typeValidity.isValid()) 42 | return typeValidity; 43 | } 44 | 45 | return Validity.TRUE; 46 | } 47 | 48 | private Entity entity(Player player, Arguments args) { 49 | int distance = 3; 50 | EnumOptions entities = null; 51 | 52 | if (args.has(DISTANCE)) 53 | distance = args.get(DISTANCE).getAsInt(); 54 | 55 | if (args.has(TYPE)) 56 | entities = args.get(TYPE).getAsEnumOptions(EntityType.class); 57 | 58 | var rayTrace = Utils.getRayTraceResult(player, distance); 59 | 60 | if (rayTrace == null || rayTrace.getHitEntity() == null) 61 | return null; 62 | 63 | if (entities == null) 64 | return null; 65 | 66 | Entity entity = rayTrace.getHitEntity(); 67 | 68 | if (entity == null) return null; 69 | return entities.contains(entity.getType()) ? entity : null; 70 | } 71 | 72 | @Override 73 | public String id() { 74 | return "lookingatentity"; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/lookingat/LookingAtMythicMob.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.lookingat; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.managers.condition.type.MultiString; 6 | import fi.septicuss.tooltips.utils.Utils; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import io.lumine.mythic.bukkit.MythicBukkit; 9 | import org.bukkit.Bukkit; 10 | import org.bukkit.entity.Entity; 11 | import org.bukkit.entity.Player; 12 | 13 | public class LookingAtMythicMob implements Condition { 14 | 15 | // lookingatmythicmob{id=meow, meow1; dist=2} 16 | 17 | private static final String[] DISTANCE = { "distance", "dist", "d" }; 18 | private static final String[] ID = { "id", "ids" }; 19 | 20 | @Override 21 | public boolean check(Player player, Arguments args) { 22 | 23 | int distance = 3; 24 | 25 | if (args.has(DISTANCE)) 26 | distance = args.get(DISTANCE).getAsInt(); 27 | 28 | var rayTrace = Utils.getRayTraceResult(player, distance); 29 | 30 | if (rayTrace == null || rayTrace.getHitEntity() == null) 31 | return false; 32 | 33 | Entity entity = rayTrace.getHitEntity(); 34 | MultiString ids = null; 35 | 36 | if (args.has(ID)) 37 | ids = MultiString.of(args.get(ID).getAsString()); 38 | 39 | var mob = MythicBukkit.inst().getMobManager().getActiveMob(entity.getUniqueId()).orElse(null); 40 | 41 | if (mob == null) 42 | return false; 43 | 44 | if (ids == null) 45 | return true; 46 | 47 | String type = String.valueOf(mob.getMobType()); 48 | return ids.contains(type); 49 | } 50 | 51 | @Override 52 | public Validity valid(Arguments args) { 53 | if (!Bukkit.getPluginManager().isPluginEnabled("MythicMobs")) 54 | return Validity.of(false, "MythicMobs plugin is required for this condition."); 55 | 56 | return Validity.TRUE; 57 | } 58 | 59 | @Override 60 | public String id() { 61 | return "lookingatmythicmob"; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/player/Equipped.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.player; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.condition.type.EnumOptions; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.Material; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.EquipmentSlot; 11 | import org.bukkit.inventory.ItemStack; 12 | 13 | public class Equipped implements Condition { 14 | 15 | private static final String[] SLOT = { "slot", "s" }; 16 | private static final String[] MATERIAL = { "type", "m", "mat", "material" }; 17 | 18 | @Override 19 | public boolean check(Player player, Arguments args) { 20 | EnumOptions materials = args.get(MATERIAL).getAsEnumOptions(Material.class); 21 | EquipmentSlot slot = EquipmentSlot.HAND; 22 | 23 | if (args.has(SLOT)) { 24 | slot = EquipmentSlot.valueOf(args.get(SLOT).getAsString().strip().toUpperCase()); 25 | } 26 | 27 | ItemStack item = player.getInventory().getItem(slot); 28 | 29 | if (item == null || item.getType().isAir()) { 30 | return materials.contains(Material.AIR); 31 | } 32 | 33 | return (materials.contains(item.getType())); 34 | } 35 | 36 | @Override 37 | public Validity valid(Arguments args) { 38 | 39 | if (!args.has(MATERIAL)) { 40 | return Validity.of(false, "Type argument is required"); 41 | } 42 | 43 | if (args.has(MATERIAL)) { 44 | Argument materialArg = args.get(MATERIAL); 45 | Validity optionValidity = EnumOptions.validity(Material.class, materialArg.getAsString()); 46 | 47 | if (!optionValidity.isValid()) { 48 | return optionValidity; 49 | } 50 | } 51 | 52 | if (args.has(SLOT)) { 53 | String slot = args.get(SLOT).getAsString(); 54 | try { 55 | return Validity.of(false, "Unknown slot " + quote(slot)); 56 | } catch (IllegalArgumentException e) { 57 | return Validity.of(false, null); 58 | } 59 | } 60 | 61 | return Validity.TRUE; 62 | } 63 | 64 | @Override 65 | public String id() { 66 | return "equipped"; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/player/Gamemode.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.player; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 6 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 7 | import fi.septicuss.tooltips.managers.condition.type.EnumOptions; 8 | import fi.septicuss.tooltips.utils.validation.Validity; 9 | import org.bukkit.GameMode; 10 | import org.bukkit.entity.Player; 11 | 12 | public class Gamemode implements Condition { 13 | 14 | private static final String[] GAMEMODE_ALIASES = { "gamemode", "gm" }; 15 | 16 | @Override 17 | public boolean check(Player player, Arguments args) { 18 | EnumOptions options = args.get(GAMEMODE_ALIASES).getAsEnumOptions(GameMode.class); 19 | return options.contains(player.getGameMode()); 20 | } 21 | 22 | @Override 23 | public void writeContext(Player player, Arguments args, Context context) { 24 | context.put("gamemode", player.getGameMode().toString()); 25 | } 26 | 27 | @Override 28 | public Validity valid(Arguments args) { 29 | if (!args.has(GAMEMODE_ALIASES)) { 30 | return Validity.of(false, "Missing gamemode argument"); 31 | } 32 | 33 | Argument arg = args.get(GAMEMODE_ALIASES); 34 | Validity optionValidity = EnumOptions.validity(GameMode.class, arg.getAsString()); 35 | 36 | if (!optionValidity.isValid()) { 37 | return optionValidity; 38 | } 39 | 40 | return Validity.of(true); 41 | } 42 | 43 | @Override 44 | public String id() { 45 | return "gamemode"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/player/Op.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.player; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.utils.validation.Validity; 7 | import org.bukkit.entity.Player; 8 | 9 | public class Op implements Condition { 10 | 11 | @Override 12 | public boolean check(Player player, Arguments args) { 13 | return player.isOp(); 14 | } 15 | 16 | @Override 17 | public void writeContext(Player player, Arguments args, Context context) { 18 | context.put("op", player.isOp()); 19 | } 20 | 21 | @Override 22 | public Validity valid(Arguments args) { 23 | return Validity.TRUE; 24 | } 25 | 26 | @Override 27 | public String id() { 28 | return "op"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/player/Permission.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.player; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.managers.condition.type.MultiString; 6 | import fi.septicuss.tooltips.utils.Text; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.entity.Player; 9 | 10 | public class Permission implements Condition { 11 | 12 | private static final String[] PERMISSION = { "p", "perm", "permission" }; 13 | 14 | @Override 15 | public boolean check(Player player, Arguments args) { 16 | MultiString permissions = MultiString.of(args.get(PERMISSION).getAsString()); 17 | for (var permission : permissions.getStrings()) 18 | if (player.hasPermission(Text.processText(player, permission))) 19 | return true; 20 | return false; 21 | } 22 | 23 | @Override 24 | public Validity valid(Arguments args) { 25 | if (!args.has(PERMISSION)) { 26 | return Validity.of(false, "Permission argument is required"); 27 | } 28 | 29 | return Validity.TRUE; 30 | } 31 | 32 | @Override 33 | public String id() { 34 | return "permission"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/player/Sneaking.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.player; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.utils.validation.Validity; 7 | import org.bukkit.entity.Player; 8 | 9 | public class Sneaking implements Condition { 10 | 11 | @Override 12 | public boolean check(Player player, Arguments args) { 13 | return player.isSneaking(); 14 | } 15 | 16 | @Override 17 | public void writeContext(Player player, Arguments args, Context context) { 18 | context.put("sneaking", player.isSneaking()); 19 | } 20 | 21 | @Override 22 | public Validity valid(Arguments args) { 23 | return Validity.TRUE; 24 | } 25 | 26 | @Override 27 | public String id() { 28 | return "sneaking"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/player/StandingOn.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.player; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 6 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 7 | import fi.septicuss.tooltips.managers.condition.type.EnumOptions; 8 | import fi.septicuss.tooltips.utils.validation.Validity; 9 | import org.bukkit.Material; 10 | import org.bukkit.block.Block; 11 | import org.bukkit.block.BlockFace; 12 | import org.bukkit.entity.Player; 13 | 14 | public class StandingOn implements Condition { 15 | 16 | private static final String[] TYPE_ALIASES = { "type", "m", "mat", "material" }; 17 | 18 | @Override 19 | public boolean check(Player player, Arguments args) { 20 | Argument typeArg = args.get(TYPE_ALIASES); 21 | String typeStr = typeArg.getAsString(); 22 | 23 | EnumOptions materials = EnumOptions.of(Material.class, typeStr); 24 | Block under = player.getLocation().getBlock().getRelative(BlockFace.DOWN); 25 | 26 | return materials.contains(under.getType()); 27 | } 28 | 29 | @Override 30 | public void writeContext(Player player, Arguments args, Context context) { 31 | context.put("standingon.type", player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType().toString()); 32 | } 33 | 34 | @Override 35 | public Validity valid(Arguments args) { 36 | if (!args.has(TYPE_ALIASES)) 37 | return Validity.of(false, quote("type") + " argument is required"); 38 | 39 | String multiMaterialString = args.get(TYPE_ALIASES).getAsString(); 40 | Validity materialValidity = EnumOptions.validity(Material.class, multiMaterialString); 41 | 42 | if (!materialValidity.isValid()) 43 | return materialValidity; 44 | 45 | return Validity.of(true); 46 | } 47 | 48 | @Override 49 | public String id() { 50 | return "standingon"; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/world/Day.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.world; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.utils.validation.Validity; 6 | import org.bukkit.entity.Player; 7 | 8 | public class Day implements Condition { 9 | 10 | @Override 11 | public boolean check(Player player, Arguments args) { 12 | long worldTime = player.getWorld().getTime(); 13 | 14 | return (worldTime >= 0 && worldTime < 13000); 15 | } 16 | 17 | @Override 18 | public Validity valid(Arguments args) { 19 | return Validity.of(true); 20 | } 21 | 22 | @Override 23 | public String id() { 24 | return "day"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/world/InCuboid.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.world; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.managers.condition.type.LocationArgument; 6 | import fi.septicuss.tooltips.utils.Cuboid; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.entity.Player; 9 | 10 | public class InCuboid implements Condition { 11 | 12 | public static final String[] FIRST = { "first", "1", "firstpoint" }; 13 | public static final String[] SECOND = { "second", "2", "secondpoint" }; 14 | 15 | @Override 16 | public boolean check(Player player, Arguments args) { 17 | org.bukkit.Location first = args.get(FIRST).getAsLocationArgument(player).getLocation(); 18 | org.bukkit.Location second = args.get(SECOND).getAsLocationArgument(player).getLocation(); 19 | org.bukkit.Location current = player.getLocation(); 20 | 21 | Cuboid cuboid = new Cuboid(first, second); 22 | return cuboid.isIn(current); 23 | } 24 | 25 | @Override 26 | public Validity valid(Arguments args) { 27 | 28 | if (!args.has(FIRST)) 29 | return Validity.of(false, "First point is missing"); 30 | 31 | Validity firstValidity = LocationArgument.validityOf(args.get(FIRST).getAsString()); 32 | 33 | if (!firstValidity.isValid()) 34 | return firstValidity; 35 | 36 | if (!args.has(SECOND)) 37 | return Validity.of(false, "Second point is missing"); 38 | 39 | Validity secondValidity = LocationArgument.validityOf(args.get(SECOND).getAsString()); 40 | 41 | if (!secondValidity.isValid()) 42 | return secondValidity; 43 | 44 | return Validity.TRUE; 45 | } 46 | 47 | @Override 48 | public String id() { 49 | return "incuboid"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/world/Location.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.world; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.managers.condition.type.MultiLocation; 6 | import fi.septicuss.tooltips.utils.validation.Validity; 7 | import org.bukkit.entity.Player; 8 | 9 | public class Location implements Condition { 10 | 11 | private static final String[] LOCATION = { "l", "loc", "location" }; 12 | 13 | @Override 14 | public boolean check(Player player, Arguments args) { 15 | MultiLocation locations = MultiLocation.of(player, args.get(LOCATION).getAsString()); 16 | org.bukkit.Location playerLocation = player.getLocation(); 17 | 18 | for (org.bukkit.Location location : locations.getLocations()) { 19 | if (playerLocation.getBlockX() == location.getBlockX() && 20 | playerLocation.getBlockY() == location.getBlockY() && 21 | playerLocation.getBlockZ() == location.getBlockZ()) { 22 | return true; 23 | } 24 | } 25 | 26 | return false; 27 | } 28 | 29 | @Override 30 | public Validity valid(Arguments args) { 31 | if (!args.has(LOCATION)) { 32 | return Validity.of(false, "Location argument is required"); 33 | } 34 | 35 | Validity validity = MultiLocation.validityOf(args.get(LOCATION).getAsString()); 36 | 37 | if (!validity.isValid()) { 38 | return validity; 39 | } 40 | 41 | return Validity.TRUE; 42 | } 43 | 44 | @Override 45 | public String id() { 46 | return "location"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/world/Night.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.world; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.utils.validation.Validity; 6 | import org.bukkit.entity.Player; 7 | 8 | public class Night implements Condition { 9 | 10 | @Override 11 | public boolean check(Player player, Arguments args) { 12 | long worldTime = player.getWorld().getTime(); 13 | 14 | return (worldTime >= 13000); 15 | } 16 | 17 | @Override 18 | public Validity valid(Arguments args) { 19 | return Validity.of(true); 20 | } 21 | 22 | @Override 23 | public String id() { 24 | return "night"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/world/Region.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.world; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.condition.type.MultiString; 7 | import fi.septicuss.tooltips.utils.cache.area.CurrentAreaCache; 8 | import fi.septicuss.tooltips.utils.validation.Validity; 9 | import org.bukkit.entity.Player; 10 | 11 | public class Region implements Condition { 12 | 13 | private static final String[] REGION = { "r", "reg", "region", "name", "id" }; 14 | 15 | @Override 16 | public boolean check(Player player, Arguments args) { 17 | MultiString region = null; 18 | 19 | if (args.has(REGION)) 20 | region = MultiString.of(args.get(REGION).process(player).getAsString()); 21 | 22 | if (region == null) { 23 | return CurrentAreaCache.has(player); 24 | } 25 | 26 | if (!CurrentAreaCache.has(player)) 27 | return false; 28 | 29 | for (var applicableRegion : CurrentAreaCache.get(player)) 30 | if (region.contains(applicableRegion)) 31 | return true; 32 | 33 | return false; 34 | } 35 | 36 | @Override 37 | public void writeContext(Player player, Arguments args, Context context) { 38 | MultiString region = null; 39 | 40 | if (args.has(REGION)) 41 | region = MultiString.of(args.get(REGION).getAsString()); 42 | 43 | if (region == null) { 44 | return; 45 | } 46 | 47 | if (!CurrentAreaCache.has(player)) 48 | return; 49 | 50 | for (var applicableRegion : CurrentAreaCache.get(player)) 51 | if (region.contains(applicableRegion)) { 52 | context.put("region", applicableRegion); 53 | return; 54 | } 55 | 56 | } 57 | 58 | @Override 59 | public Validity valid(Arguments args) { 60 | return Validity.TRUE; 61 | } 62 | 63 | @Override 64 | public String id() { 65 | return "region"; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/world/Time.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.world; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.condition.type.Operation; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.entity.Player; 9 | 10 | public class Time implements Condition { 11 | 12 | private static final String[] TIME = { "time", "t" }; 13 | private static final String[] OPERATION = { "o", "oper", "operation" }; 14 | 15 | @Override 16 | public boolean check(Player player, Arguments args) { 17 | 18 | Operation operation = Operation.EQUAL; 19 | int time = args.get(TIME).getAsInt(); 20 | long worldTime = player.getWorld().getTime(); 21 | 22 | if (args.has(OPERATION)) 23 | operation = Operation.parseOperation(args.get(OPERATION).getAsString()); 24 | 25 | switch (operation) { 26 | case EQUAL: 27 | return time == worldTime; 28 | case GREATER_THAN: 29 | return time > worldTime; 30 | case GREATER_THAN_OR_EQUAL: 31 | return time >= worldTime; 32 | case LESS_THAN: 33 | return time < worldTime; 34 | case LESS_THAN_OR_EQUAL: 35 | return time <= worldTime; 36 | default: 37 | return false; 38 | } 39 | 40 | } 41 | 42 | @Override 43 | public void writeContext(Player player, Arguments args, Context context) { 44 | context.put("time", player.getWorld().getTime()); 45 | } 46 | 47 | @Override 48 | public Validity valid(Arguments args) { 49 | 50 | if (!args.has(TIME)) { 51 | return Validity.of(false, "Time argument is missing"); 52 | } 53 | 54 | if (!args.isNumber(TIME)) { 55 | return Validity.of(false, "Time must be an integer"); 56 | } 57 | 58 | if (args.has(OPERATION)) { 59 | String operation = args.get(OPERATION).getAsString(); 60 | if (Operation.parseOperation(operation) == null) { 61 | return Validity.of(false, "Unknown operation " + quote(operation)); 62 | } 63 | } 64 | 65 | return Validity.TRUE; 66 | } 67 | 68 | @Override 69 | public String id() { 70 | return "time"; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/impl/world/World.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.impl.world; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.condition.type.MultiString; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.entity.Player; 9 | 10 | public class World implements Condition { 11 | 12 | private static final String[] WORLD = { "name" }; 13 | 14 | @Override 15 | public boolean check(Player player, Arguments args) { 16 | MultiString multi = MultiString.of(args.get(WORLD).getAsString()); 17 | return multi.contains(player.getWorld().getName()); 18 | } 19 | 20 | @Override 21 | public void writeContext(Player player, Arguments args, Context context) { 22 | context.put("world", player.getWorld().getName()); 23 | } 24 | 25 | @Override 26 | public Validity valid(Arguments args) { 27 | if (!args.has(WORLD)) { 28 | return Validity.of(false, "Must have the world name argument"); 29 | } 30 | 31 | return Validity.TRUE; 32 | } 33 | 34 | @Override 35 | public String id() { 36 | return "world"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/parser/ArgumentParser.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.parser; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.utils.Utils; 6 | 7 | public class ArgumentParser implements Parser { 8 | 9 | @Override 10 | public Arguments parse(String presetName, String from) { 11 | if (from.isBlank()) 12 | return new Arguments(); 13 | 14 | final Arguments arguments = new Arguments(); 15 | 16 | final String[] strArguments = Utils.splitStringQuotations(from, ';'); 17 | 18 | for (var strArg : strArguments) { 19 | int indexOfEquals = strArg.indexOf('='); 20 | 21 | if (indexOfEquals == -1) { 22 | warn("Failed to parse argument " + quote(strArg) + " in preset " + quote(presetName)); 23 | warn(" (Full line = " + quote(from) + ")"); 24 | continue; 25 | } 26 | 27 | String key = strArg.substring(0, indexOfEquals); 28 | String value = strArg.substring(indexOfEquals + 1); 29 | 30 | if (Utils.isSurroundedByQuotes(value)) { 31 | value = Utils.removeQuotes(value); 32 | } 33 | 34 | arguments.add(key.strip(), new Argument(value.strip())); 35 | } 36 | 37 | return arguments; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/parser/ConditionParser.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.parser; 2 | 3 | import fi.septicuss.tooltips.managers.condition.ConditionManager; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | 6 | public class ConditionParser implements Parser { 7 | 8 | private ConditionManager conditionManager; 9 | private ArgumentParser argumentParser; 10 | 11 | public ConditionParser(ConditionManager conditionManager, ArgumentParser argumentParser) { 12 | this.conditionManager = conditionManager; 13 | this.argumentParser = argumentParser; 14 | } 15 | 16 | @Override 17 | public ParsedCondition parse(String presetName, String from) { 18 | // Just for sure 19 | from = from.strip(); 20 | 21 | int firstBracket = from.indexOf("{"); 22 | 23 | boolean hasOpeningBracket = (firstBracket != -1); 24 | boolean endsWithBracket = from.endsWith("}"); 25 | 26 | // Brackets missing / misplaced 27 | if (!endsWithBracket || !hasOpeningBracket) { 28 | final Arguments args = new Arguments(); 29 | return new ParsedCondition(this.conditionManager, presetName, from, args); 30 | } 31 | 32 | String name = from.substring(0, firstBracket).strip(); 33 | String argLine = from.substring(firstBracket + 1, from.length() - 1); 34 | 35 | if (!conditionManager.exists(name)) { 36 | warn("condition-" + name + "-" + presetName, "Failed to parse unknown condition " + quote(name) + " in preset " + quote(presetName) + " (2)"); 37 | return null; 38 | } 39 | 40 | final Arguments args = argumentParser.parse(presetName, argLine); 41 | return new ParsedCondition(this.conditionManager, presetName, name, args); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/parser/ParsedCondition.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.parser; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.managers.condition.Condition; 5 | import fi.septicuss.tooltips.managers.condition.ConditionManager; 6 | import fi.septicuss.tooltips.managers.condition.Context; 7 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 8 | import fi.septicuss.tooltips.utils.Utils; 9 | import fi.septicuss.tooltips.utils.validation.Validity; 10 | import org.bukkit.entity.Player; 11 | 12 | public class ParsedCondition { 13 | 14 | private final ConditionManager conditionManager; 15 | private final String presetName; 16 | private final String conditionName; 17 | private final Arguments args; 18 | 19 | public ParsedCondition(ConditionManager conditionManager, String presetName, String conditionName, Arguments args) { 20 | this.conditionManager = conditionManager; 21 | this.conditionName = conditionName; 22 | this.presetName = presetName; 23 | this.args = args; 24 | } 25 | 26 | public boolean check(Player player, Context context) { 27 | final Condition condition = this.getCondition(); 28 | 29 | if (condition == null) { 30 | Tooltips.warn("condition-" + conditionName + "-" + presetName, "Tried to run an unknown condition " + Utils.quote(conditionName) + " in preset " + Utils.quote(presetName)); 31 | return false; 32 | } 33 | 34 | final Validity validity = condition.valid(args); 35 | 36 | if (!validity.isValid()) { 37 | Tooltips.warn("condition-" + conditionName + "-" + presetName, "Failed to parse condition " + Utils.quote(conditionName) + " in preset " + Utils.quote(presetName) + ""); 38 | if (validity.hasReason()) { 39 | Tooltips.warn("condition-" + conditionName + "-" + presetName, " -> " + validity.getReason()); 40 | } 41 | return false; 42 | } 43 | 44 | final boolean result = condition.check(player, args); 45 | 46 | if (result) { 47 | condition.writeContext(player, args, context); 48 | } 49 | 50 | context.put("condition." + condition.id(), result); 51 | 52 | return result; 53 | } 54 | 55 | public Condition getCondition() { 56 | return this.conditionManager.get(this.conditionName); 57 | } 58 | 59 | public Arguments getArgs() { 60 | return args; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return "ParsedCondition [condition=" + conditionName + ", args=" + args + "]"; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/parser/Parser.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.parser; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.utils.Utils; 5 | 6 | public interface Parser { 7 | 8 | public T parse(String presetName, String from); 9 | 10 | default void warn(String message) { 11 | Tooltips.warn(message); 12 | } 13 | 14 | default void warn(String key, String message) { 15 | Tooltips.warn(key, message); 16 | } 17 | 18 | default String quote(String message) { 19 | return Utils.quote(message); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/parser/StatementParser.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.parser; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Statement; 4 | import fi.septicuss.tooltips.managers.condition.Statement.Outcome; 5 | 6 | public class StatementParser implements Parser { 7 | 8 | private CompositeConditionParser compositeParser; 9 | 10 | public StatementParser(CompositeConditionParser compositeParser) { 11 | this.compositeParser = compositeParser; 12 | } 13 | 14 | @Override 15 | public Statement parse(String presetName, String from) { 16 | 17 | // Does not have outcome 18 | if (from.endsWith(")")) { 19 | var compositeCondition = compositeParser.parse(presetName, from); 20 | return new Statement(compositeCondition); 21 | } 22 | 23 | String[] split = from.split(" "); 24 | Outcome outcome = null; 25 | 26 | String last = split[split.length - 1]; 27 | 28 | if (Outcome.isOutcome(last)) { 29 | outcome = Outcome.parseOutcome(last); 30 | from = from.substring(0, from.length() - last.length() - 1); 31 | } 32 | 33 | var compositeCondition = compositeParser.parse(presetName, from); 34 | 35 | if (compositeCondition == null) 36 | return null; 37 | 38 | return new Statement(compositeCondition, outcome); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/type/EnumOptions.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.type; 2 | 3 | import fi.septicuss.tooltips.utils.Utils; 4 | import fi.septicuss.tooltips.utils.validation.Validity; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class EnumOptions> { 11 | 12 | private List options; 13 | 14 | public EnumOptions(List options) { 15 | this.options = options; 16 | } 17 | 18 | public boolean contains(E other) { 19 | return options.contains(other); 20 | } 21 | 22 | public List getOptions() { 23 | return Collections.unmodifiableList(options); 24 | } 25 | 26 | public static > EnumOptions of(Class enumType, String line) { 27 | final String[] split = line.split(","); 28 | final List list = new ArrayList<>(); 29 | 30 | for (int i = 0; i < split.length; i++) { 31 | var str = split[i].strip().toUpperCase(); 32 | list.add(Enum.valueOf(enumType, str)); 33 | } 34 | 35 | return new EnumOptions<>(list); 36 | } 37 | 38 | public static > Validity validity(Class enumType, String optionString) { 39 | final String[] split = optionString.split(","); 40 | 41 | for (int i = 0; i < split.length; i++) { 42 | var str = split[i].strip().toUpperCase(); 43 | 44 | try { 45 | Enum.valueOf(enumType, str); 46 | } catch (IllegalArgumentException e) { 47 | return Validity.of(false, 48 | "Enum " + Utils.quote(str) + " is not specified for type " + Utils.quote(enumType.getName())); 49 | } 50 | } 51 | 52 | return Validity.of(true); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/type/LocationArgument.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.type; 2 | 3 | import fi.septicuss.tooltips.utils.Utils; 4 | import fi.septicuss.tooltips.utils.validation.Validity; 5 | import org.bukkit.Location; 6 | import org.bukkit.entity.Player; 7 | 8 | public class LocationArgument { 9 | 10 | private Location location; 11 | private String world; 12 | private double x; 13 | private double y; 14 | private double z; 15 | 16 | public LocationArgument(Location location) { 17 | this.location = location; 18 | this.world = location.getWorld().getName(); 19 | this.x = location.getX(); 20 | this.y = location.getY(); 21 | this.z = location.getZ(); 22 | } 23 | 24 | public String getWorld() { 25 | return world; 26 | } 27 | 28 | public double getX() { 29 | return x; 30 | } 31 | 32 | public double getY() { 33 | return y; 34 | } 35 | 36 | public double getZ() { 37 | return z; 38 | } 39 | 40 | public Location getLocation() { 41 | return location; 42 | } 43 | 44 | /** 45 | * 46 | * @param player 47 | * @param string In format [x, y, z] 48 | * @return 49 | */ 50 | public static LocationArgument of(Player player, String string) { 51 | if (string.startsWith("[") && string.endsWith("]")) { 52 | string = string.substring(1, string.length() - 1); 53 | } 54 | 55 | double x = 0; 56 | double y = 0; 57 | double z = 0; 58 | 59 | String[] split = string.split(","); 60 | 61 | for (int i = 0; i < split.length; i++) { 62 | var str = split[i].strip(); 63 | 64 | double value = Double.parseDouble(str); 65 | 66 | if (i == 0) 67 | x = value; 68 | if (i == 1) 69 | y = value; 70 | if (i == 2) 71 | z = value; 72 | } 73 | 74 | Location location = new Location(player.getWorld(), x, y, z); 75 | return new LocationArgument(location); 76 | } 77 | 78 | /** 79 | * Checks the validity of a location argument string 80 | * 81 | * @param string In format [x, y, z] 82 | * @return 83 | */ 84 | public static Validity validityOf(String string) { 85 | 86 | if (!string.startsWith("[") || !string.endsWith("]")) { 87 | return Validity.of(false, "Location argument must be within square brackets [x, y, z]"); 88 | } 89 | 90 | string = string.substring(1, string.length() - 1); 91 | String[] split = string.split(","); 92 | 93 | if (split.length != 3) { 94 | return Validity.of(false, "Invalid location format. Must be [x, y, z]"); 95 | } 96 | 97 | for (var str : split) { 98 | try { 99 | Double.parseDouble(str); 100 | } catch (IllegalArgumentException e) { 101 | return Validity.of(false, Utils.quote(str) + " is not a number"); 102 | } 103 | } 104 | 105 | return Validity.TRUE; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/type/MultiString.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.type; 2 | 3 | import com.google.common.collect.Lists; 4 | 5 | import java.util.List; 6 | 7 | public class MultiString { 8 | 9 | private List strings; 10 | 11 | public MultiString(List strings) { 12 | this.strings = strings; 13 | } 14 | 15 | public boolean contains(String other) { 16 | if (other == null) return false; 17 | return strings.contains(other); 18 | } 19 | 20 | public List getStrings() { 21 | return strings; 22 | } 23 | 24 | public static MultiString of(String line) { 25 | List strings = Lists.newArrayList(); 26 | for (var string : line.split(",")) 27 | strings.add(string.strip()); 28 | return new MultiString(strings); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/condition/type/Operation.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.condition.type; 2 | 3 | public enum Operation { 4 | 5 | GREATER_THAN(">"), 6 | GREATER_THAN_OR_EQUAL(">=", "=>"), 7 | LESS_THAN("<"), 8 | LESS_THAN_OR_EQUAL("<=", "=<"), 9 | EQUAL("=", "=="); 10 | 11 | private String[] aliases; 12 | 13 | private Operation(String... aliases) { 14 | this.aliases = aliases; 15 | } 16 | 17 | public String[] getAliases() { 18 | return aliases; 19 | } 20 | 21 | public static Operation parseOperation(String arg0) { 22 | for (var operation : values()) 23 | for (var alias : operation.getAliases()) 24 | if (arg0.equalsIgnoreCase(alias)) 25 | return operation; 26 | return null; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/icon/Icon.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.icon; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.utils.NamespacedPath; 5 | import fi.septicuss.tooltips.utils.Utils; 6 | import fi.septicuss.tooltips.utils.validation.Validatable; 7 | import org.bukkit.configuration.ConfigurationSection; 8 | 9 | import java.io.File; 10 | 11 | public class Icon implements Validatable { 12 | 13 | private String path; 14 | private String file; 15 | private NamespacedPath texturePath; 16 | private int ascent; 17 | private int height; 18 | private double overridingWidth; 19 | 20 | private char unicode = ' '; 21 | private boolean valid = false; 22 | 23 | public Icon(String path, String file, ConfigurationSection iconSection) { 24 | this.path = path; 25 | this.file = file; 26 | this.ascent = iconSection.getInt("ascent"); 27 | this.height = iconSection.getInt("height"); 28 | this.overridingWidth = iconSection.getDouble("width", 0); 29 | 30 | String pathStr = iconSection.getString("path"); 31 | 32 | if (pathStr == null) { 33 | Tooltips.warn(String.format("Icon " + Utils.quote(path) + " does not define a path to the texture.")); 34 | return; 35 | } 36 | 37 | this.texturePath = new NamespacedPath(pathStr, "textures"); 38 | 39 | var textureFile = new File(Tooltips.getPackAssetsFolder(), texturePath.getFullPath()); 40 | var fileExists = (textureFile.exists()); 41 | 42 | if (!fileExists) { 43 | Tooltips.warn("Icon " + Utils.quote(path) + " uses an invalid texture " + Utils.quote(texturePath.getNamespacedPath())); 44 | return; 45 | } 46 | 47 | this.valid = true; 48 | } 49 | 50 | public String getPath() { 51 | return path; 52 | } 53 | 54 | public NamespacedPath getTexturePath() { 55 | return texturePath; 56 | } 57 | 58 | public int getAscent() { 59 | return ascent; 60 | } 61 | 62 | public int getHeight() { 63 | return height; 64 | } 65 | 66 | public char getUnicode() { 67 | return unicode; 68 | } 69 | 70 | public void setUnicode(char unicode) { 71 | this.unicode = unicode; 72 | } 73 | 74 | public double getOverridingWidth() { 75 | return overridingWidth; 76 | } 77 | 78 | public boolean hasUnicode() { 79 | return (unicode != ' '); 80 | } 81 | 82 | @Override 83 | public boolean isValid() { 84 | return this.valid; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/axgens/LookingAtAxGen.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.axgens; 2 | 3 | import com.artillexstudios.axgens.generators.Generator; 4 | import com.artillexstudios.axgens.generators.GeneratorArea; 5 | import fi.septicuss.tooltips.managers.condition.Condition; 6 | import fi.septicuss.tooltips.managers.condition.Context; 7 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 8 | import fi.septicuss.tooltips.utils.Utils; 9 | import fi.septicuss.tooltips.utils.validation.Validity; 10 | import org.bukkit.Bukkit; 11 | import org.bukkit.Location; 12 | import org.bukkit.block.Block; 13 | import org.bukkit.entity.Player; 14 | 15 | public class LookingAtAxGen implements Condition { 16 | 17 | private static final String[] DISTANCE_ALIASES = { "distance", "d" }; 18 | 19 | @Override 20 | public boolean check(Player player, Arguments args) { 21 | int distance = 3; 22 | 23 | if (args.isNumber(DISTANCE_ALIASES)) 24 | distance = args.get(DISTANCE_ALIASES).getAsInt(); 25 | 26 | var rayTrace = Utils.getRayTraceResult(player, distance); 27 | 28 | if (rayTrace == null) { 29 | return false; 30 | } 31 | 32 | final Block target = rayTrace.getHitBlock(); 33 | 34 | if (target == null) { 35 | return false; 36 | } 37 | 38 | final Location blockLocation = target.getLocation(); 39 | final Generator generator = GeneratorArea.getGeneratorAt(blockLocation); 40 | 41 | if (generator == null) { 42 | return false; 43 | } 44 | 45 | AxGensCache.cache(player, generator); 46 | return true; 47 | } 48 | 49 | @Override 50 | public void writeContext(Player player, Arguments args, Context context) { 51 | final AxGensCache.AxGen axGen = AxGensCache.get(player); 52 | 53 | context.put("axgens.id", axGen.id()); 54 | context.put("axgens.name", axGen.name()); 55 | context.put("axgens.tier", axGen.tier()); 56 | context.put("axgens.speed", axGen.speed()); 57 | context.put("axgens.drops", axGen.drops()); 58 | context.put("axgens.drops.price", axGen.dropPrice()); 59 | context.put("axgens.next.name", axGen.name()); 60 | context.put("axgens.next.price", axGen.nextPrice()); 61 | context.put("axgens.next.level", axGen.nextLevel()); 62 | context.put("axgens.next.tier", axGen.nextTier()); 63 | context.put("axgens.next.speed", axGen.nextSpeed()); 64 | context.put("axgens.next.drops", axGen.nextDrops()); 65 | context.put("axgens.next.drops.price", axGen.nextDropPrice()); 66 | 67 | } 68 | 69 | @Override 70 | public Validity valid(Arguments args) { 71 | if (!Bukkit.getPluginManager().isPluginEnabled("AxGens")) { 72 | return Validity.of(false, "AxGens is required for this condition"); 73 | } 74 | 75 | return Validity.TRUE; 76 | } 77 | 78 | @Override 79 | public String id() { 80 | return "lookingataxgen"; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/betonquest/BetonQuestCondition.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.betonquest; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Condition; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.integration.impl.betonquest.conversation.TooltipsConversationData; 7 | import fi.septicuss.tooltips.managers.integration.impl.betonquest.conversation.TooltipsConversationIO; 8 | import fi.septicuss.tooltips.utils.validation.Validity; 9 | import org.bukkit.entity.Player; 10 | 11 | public class BetonQuestCondition implements Condition { 12 | 13 | @Override 14 | public boolean check(Player player, Arguments args) { 15 | return TooltipsConversationIO.isInConversation(player); 16 | } 17 | 18 | @Override 19 | public void writeContext(Player player, Arguments args, Context context) { 20 | if (!TooltipsConversationIO.isInConversation(player)) return; 21 | final TooltipsConversationData data = TooltipsConversationIO.getData(player); 22 | if (data == null) return; 23 | 24 | context.put("betonquest.npc", data.getNPCName()); 25 | context.put("betonquest.text", data.getText()); 26 | context.put("betonquest.options", data.getOptions()); 27 | context.put("betonquest.selected", data.getSelectedOption()); 28 | } 29 | 30 | @Override 31 | public Validity valid(Arguments args) { 32 | return Validity.TRUE; 33 | } 34 | 35 | @Override 36 | public String id() { 37 | return "betonquest"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/betonquest/actions/EndConversationCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.betonquest.actions; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.managers.integration.impl.betonquest.conversation.TooltipsConversationData; 5 | import fi.septicuss.tooltips.managers.integration.impl.betonquest.conversation.TooltipsConversationIO; 6 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.betonquest.betonquest.conversation.Conversation; 9 | import org.betonquest.betonquest.utils.PlayerConverter; 10 | import org.bukkit.entity.Player; 11 | 12 | public class EndConversationCommand implements ActionCommand { 13 | 14 | @Override 15 | public void run(Player player, Arguments arguments) { 16 | 17 | Conversation conversation = Conversation.getConversation(PlayerConverter.getID(player)); 18 | 19 | if (conversation != null) { 20 | conversation.endConversation(); 21 | } 22 | 23 | if (!TooltipsConversationIO.isInConversation(player)) { 24 | return; 25 | } 26 | final TooltipsConversationData conversationData = TooltipsConversationIO.getData(player); 27 | if (conversationData == null) return; 28 | 29 | conversationData.end(); 30 | conversationData.getConversation().endConversation(); 31 | 32 | } 33 | 34 | @Override 35 | public Validity validity(Arguments arguments) { 36 | return Validity.TRUE; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/betonquest/actions/NextOptionCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.betonquest.actions; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.managers.integration.impl.betonquest.conversation.TooltipsConversationData; 5 | import fi.septicuss.tooltips.managers.integration.impl.betonquest.conversation.TooltipsConversationIO; 6 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.entity.Player; 9 | 10 | public class NextOptionCommand implements ActionCommand { 11 | 12 | @Override 13 | public void run(Player player, Arguments arguments) { 14 | if (!TooltipsConversationIO.isInConversation(player)) { 15 | return; 16 | } 17 | 18 | final TooltipsConversationData data = TooltipsConversationIO.getData(player); 19 | 20 | if (!data.isReady()) { 21 | return; 22 | } 23 | 24 | data.nextOption(); 25 | 26 | } 27 | 28 | @Override 29 | public Validity validity(Arguments arguments) { 30 | return Validity.TRUE; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/betonquest/actions/SelectOptionCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.betonquest.actions; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.managers.integration.impl.betonquest.conversation.TooltipsConversationData; 5 | import fi.septicuss.tooltips.managers.integration.impl.betonquest.conversation.TooltipsConversationIO; 6 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.entity.Player; 9 | 10 | public class SelectOptionCommand implements ActionCommand { 11 | 12 | @Override 13 | public void run(Player player, Arguments arguments) { 14 | if (!TooltipsConversationIO.isInConversation(player)) { 15 | return; 16 | } 17 | 18 | final TooltipsConversationData conversationData = TooltipsConversationIO.getData(player); 19 | 20 | if (!conversationData.isReady()) { 21 | return; 22 | } 23 | 24 | int answer = 1; 25 | 26 | if (arguments.has("1")) { 27 | answer = arguments.get("1").getAsInt() + 1; 28 | } 29 | 30 | if (conversationData.getOptions().isEmpty()) { 31 | conversationData.end(); 32 | conversationData.getConversation().endConversation(); 33 | return; 34 | } 35 | 36 | if (answer > conversationData.getOptions().size() - 1) { 37 | answer = Math.max(answer, conversationData.getOptions().size()); 38 | } 39 | 40 | conversationData.getConversation().passPlayerAnswer(answer); 41 | 42 | } 43 | 44 | @Override 45 | public Validity validity(Arguments arguments) { 46 | if (arguments.has("1")) { 47 | if (!arguments.get("1").isNumber()) { 48 | return Validity.of(false, "Selected option must be a number"); 49 | } 50 | } 51 | 52 | 53 | return Validity.TRUE; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/betonquest/conversation/TooltipsConversationData.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.betonquest.conversation; 2 | 3 | import org.betonquest.betonquest.conversation.Conversation; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class TooltipsConversationData { 9 | 10 | private final Conversation conversation; 11 | 12 | // Conversation data 13 | private String npcName; 14 | private String text; 15 | private final List options = new ArrayList<>(); 16 | private int selectedOption; 17 | 18 | // Conversation state 19 | /** Whether all necessary data has been received from BQ. */ 20 | private boolean ready; 21 | /** Controls whether to end this conversation */ 22 | private boolean end; 23 | 24 | public TooltipsConversationData(Conversation conversation) { 25 | this.conversation = conversation; 26 | } 27 | 28 | public Conversation getConversation() { 29 | return conversation; 30 | } 31 | 32 | public String getNPCName() { 33 | return npcName; 34 | } 35 | 36 | public void setNPCName(String npcName) { 37 | this.npcName = npcName; 38 | } 39 | 40 | public String getText() { 41 | return text; 42 | } 43 | 44 | public void setText(String text) { 45 | this.text = text; 46 | } 47 | 48 | public boolean isReady() { 49 | return ready; 50 | } 51 | 52 | public void setReady(boolean ready) { 53 | this.ready = ready; 54 | } 55 | 56 | public void end() { 57 | this.end = true; 58 | } 59 | 60 | public boolean shouldEnd() { 61 | return this.end; 62 | } 63 | 64 | public List getOptions() { 65 | return options; 66 | } 67 | 68 | public void addOption(String option) { 69 | this.options.add(option); 70 | } 71 | 72 | public void clearOptions() { 73 | this.options.clear(); 74 | this.selectedOption = 0; 75 | } 76 | 77 | public void nextOption() { 78 | int size = this.options.size(); 79 | if (size > 0) { 80 | this.selectedOption = (this.selectedOption + 1) % size; 81 | } else { 82 | this.selectedOption = 0; 83 | } 84 | } 85 | 86 | public int getSelectedOption() { 87 | return this.selectedOption; 88 | } 89 | 90 | public boolean isLast() { 91 | return this.conversation.isEnded(); 92 | } 93 | 94 | public void reset() { 95 | this.npcName = null; 96 | this.text = null; 97 | this.options.clear(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/crucible/CrucibleFurnitureProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.crucible; 2 | 3 | import fi.septicuss.tooltips.managers.integration.providers.FurnitureProvider; 4 | import fi.septicuss.tooltips.managers.integration.wrappers.FurnitureWrapper; 5 | import io.lumine.mythiccrucible.MythicCrucible; 6 | import io.lumine.mythiccrucible.items.CrucibleItem; 7 | import io.lumine.mythiccrucible.items.furniture.FurnitureDataKeys; 8 | import io.lumine.mythiccrucible.utils.CustomBlockData; 9 | import org.bukkit.block.Block; 10 | import org.bukkit.entity.Entity; 11 | import org.bukkit.persistence.PersistentDataType; 12 | 13 | import java.util.Optional; 14 | 15 | public class CrucibleFurnitureProvider implements FurnitureProvider { 16 | 17 | 18 | @Override 19 | public FurnitureWrapper getFurniture(Entity entity) { 20 | if (entity == null) { 21 | return null; 22 | } 23 | 24 | final String id = entity.getPersistentDataContainer().get(FurnitureDataKeys.FURNITURE_TYPE, PersistentDataType.STRING); 25 | return this.getWrapperFromId(id); 26 | } 27 | 28 | @Override 29 | public FurnitureWrapper getFurniture(Block block) { 30 | if (block == null) { 31 | return null; 32 | } 33 | 34 | final CustomBlockData data = new CustomBlockData(block, MythicCrucible.inst()); 35 | final String id = data.get(FurnitureDataKeys.FURNITURE_TYPE, PersistentDataType.STRING); 36 | 37 | return this.getWrapperFromId(id); 38 | } 39 | 40 | private FurnitureWrapper getWrapperFromId(final String id) { 41 | if (id == null) { 42 | return null; 43 | } 44 | 45 | final Optional optionalItem = MythicCrucible.inst().getItemManager().getItem(id); 46 | 47 | if (optionalItem.isEmpty()) { 48 | return null; 49 | } 50 | 51 | final CrucibleItem item = optionalItem.get(); 52 | final String name = item.getDisplayName(); 53 | final String itemId = item.getInternalName(); 54 | 55 | return new FurnitureWrapper(this.identifier(), itemId, name); 56 | } 57 | 58 | @Override 59 | public String identifier() { 60 | return "Crucible"; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/itemsadder/ItemsAdderFurnitureProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.itemsadder; 2 | 3 | import dev.lone.itemsadder.api.CustomFurniture; 4 | import fi.septicuss.tooltips.managers.integration.providers.FurnitureProvider; 5 | import fi.septicuss.tooltips.managers.integration.wrappers.FurnitureWrapper; 6 | import org.bukkit.block.Block; 7 | import org.bukkit.entity.Entity; 8 | 9 | public class ItemsAdderFurnitureProvider implements FurnitureProvider { 10 | 11 | @Override 12 | public FurnitureWrapper getFurniture(Block block) { 13 | if (block == null) { 14 | return null; 15 | } 16 | 17 | try { 18 | final CustomFurniture furniture = CustomFurniture.byAlreadySpawned(block); 19 | return this.getWrapperFromFurniture(furniture); 20 | } catch (RuntimeException exception) { 21 | return null; 22 | } 23 | } 24 | 25 | @Override 26 | public FurnitureWrapper getFurniture(Entity entity) { 27 | if (entity == null) { 28 | return null; 29 | } 30 | 31 | try { 32 | final CustomFurniture furniture = CustomFurniture.byAlreadySpawned(entity); 33 | return this.getWrapperFromFurniture(furniture); 34 | } catch (RuntimeException exception) { 35 | return null; 36 | } 37 | } 38 | 39 | private FurnitureWrapper getWrapperFromFurniture(final CustomFurniture furniture) { 40 | if (furniture == null) { 41 | return null; 42 | } 43 | 44 | final String id = furniture.getNamespacedID(); 45 | final String name = furniture.getDisplayName(); 46 | 47 | return new FurnitureWrapper(this.identifier(), id, name); 48 | } 49 | 50 | @Override 51 | public String identifier() { 52 | return "ItemsAdder"; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/nbtapi/NBTBlockWrapper.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.nbtapi; 2 | 3 | import de.tr7zw.nbtapi.NBTBlock; 4 | import de.tr7zw.nbtapi.NBTCompound; 5 | import org.bukkit.block.Block; 6 | 7 | public class NBTBlockWrapper extends NBTWrapper { 8 | 9 | private NBTCompound compound; 10 | 11 | public NBTBlockWrapper(Block block) { 12 | super(block); 13 | 14 | if (hasNBTAPI()) 15 | this.compound = new NBTBlock(block).getData(); 16 | } 17 | 18 | public NBTCompound getCompound() { 19 | return compound; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/nbtapi/NBTEntityWrapper.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.nbtapi; 2 | 3 | import de.tr7zw.nbtapi.NBTCompound; 4 | import de.tr7zw.nbtapi.NBTEntity; 5 | import org.bukkit.entity.Entity; 6 | 7 | public class NBTEntityWrapper extends NBTWrapper { 8 | 9 | private NBTCompound compound; 10 | 11 | public NBTEntityWrapper(Entity entity) { 12 | super(entity); 13 | 14 | if (hasNBTAPI()) 15 | this.compound = new NBTEntity(entity); 16 | } 17 | 18 | @Override 19 | public NBTCompound getCompound() { 20 | return compound; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/nbtapi/NBTItemWrapper.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.nbtapi; 2 | 3 | import de.tr7zw.nbtapi.NBTCompound; 4 | import de.tr7zw.nbtapi.NBTItem; 5 | import org.bukkit.inventory.ItemStack; 6 | 7 | public class NBTItemWrapper extends NBTWrapper { 8 | 9 | private NBTCompound compound; 10 | 11 | public NBTItemWrapper(ItemStack item) { 12 | super(item); 13 | 14 | if (hasNBTAPI()) 15 | this.compound = new NBTItem(item); 16 | } 17 | 18 | public NBTCompound getCompound() { 19 | return compound; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/nbtapi/NBTTileEntityWrapper.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.nbtapi; 2 | 3 | import de.tr7zw.nbtapi.NBTCompound; 4 | import de.tr7zw.nbtapi.NBTTileEntity; 5 | import org.bukkit.block.BlockState; 6 | 7 | public class NBTTileEntityWrapper extends NBTWrapper { 8 | 9 | private NBTCompound compound; 10 | 11 | public NBTTileEntityWrapper(BlockState state) { 12 | super(state); 13 | 14 | if (hasNBTAPI()) 15 | this.compound = new NBTTileEntity(state); 16 | } 17 | 18 | public NBTCompound getCompound() { 19 | return compound; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/nbtapi/NBTWrapper.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.nbtapi; 2 | 3 | import de.tr7zw.nbtapi.NBTCompound; 4 | import org.bukkit.Bukkit; 5 | 6 | public abstract class NBTWrapper { 7 | 8 | public NBTWrapper(T object) { 9 | } 10 | 11 | public abstract NBTCompound getCompound(); 12 | 13 | public boolean hasNBTAPI() { 14 | return Bukkit.getPluginManager().isPluginEnabled("NBTAPI"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/nexo/NexoFurnitureProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.nexo; 2 | 3 | import com.nexomc.nexo.api.NexoFurniture; 4 | import com.nexomc.nexo.api.NexoItems; 5 | import com.nexomc.nexo.items.ItemBuilder; 6 | import com.nexomc.nexo.mechanics.furniture.FurnitureMechanic; 7 | import fi.septicuss.tooltips.managers.integration.providers.FurnitureProvider; 8 | import fi.septicuss.tooltips.managers.integration.wrappers.FurnitureWrapper; 9 | import net.kyori.adventure.text.TextComponent; 10 | import org.bukkit.Location; 11 | import org.bukkit.block.Block; 12 | import org.bukkit.entity.Entity; 13 | import org.bukkit.entity.Player; 14 | import org.jetbrains.annotations.Nullable; 15 | 16 | 17 | public class NexoFurnitureProvider implements FurnitureProvider { 18 | 19 | @Nullable 20 | @Override 21 | public FurnitureWrapper getFurniture(Entity entity) { 22 | if (!NexoFurniture.isFurniture(entity)) { 23 | return null; 24 | } 25 | 26 | final FurnitureMechanic mechanic = NexoFurniture.furnitureMechanic(entity); 27 | if (mechanic == null) return null; 28 | 29 | return this.getWrapperFromMechanic(mechanic); 30 | } 31 | 32 | @Nullable 33 | @Override 34 | public FurnitureWrapper getFurniture(Block block) { 35 | final Location location = block.getLocation(); 36 | if (!NexoFurniture.isFurniture(location)) { 37 | return null; 38 | } 39 | 40 | final FurnitureMechanic mechanic = NexoFurniture.furnitureMechanic(location); 41 | if (mechanic == null) return null; 42 | 43 | return this.getWrapperFromMechanic(mechanic); 44 | } 45 | 46 | @Override 47 | public boolean hasCustomRaytrace() { 48 | try { 49 | NexoFurniture.class.getMethod("findTargetFurniture", Player.class); 50 | return true; 51 | } catch (NoSuchMethodException e) { 52 | return false; 53 | } 54 | } 55 | 56 | @Override 57 | public FurnitureWrapper getTargetFurniture(Player player) { 58 | return this.getFurniture(NexoFurniture.findTargetFurniture(player)); 59 | } 60 | 61 | private FurnitureWrapper getWrapperFromMechanic(final FurnitureMechanic mechanic) { 62 | final String id = mechanic.getItemID(); 63 | final String name = this.getFurnitureName(id); 64 | 65 | if (name == null) { 66 | return null; 67 | } 68 | 69 | return new FurnitureWrapper(this.identifier(), id, name); 70 | } 71 | 72 | private String getFurnitureName(final String itemId) { 73 | final ItemBuilder builder = NexoItems.itemFromId(itemId); 74 | 75 | if (builder == null) { 76 | return null; 77 | } 78 | 79 | final boolean hasName = builder.hasItemName(); 80 | return (hasName ? ((TextComponent) builder.getItemName()).content() : builder.getType().toString()); 81 | } 82 | 83 | @Override 84 | public String identifier() { 85 | return "Nexo"; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/oraxen/OraxenFurnitureProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.oraxen; 2 | 3 | import fi.septicuss.tooltips.managers.integration.providers.FurnitureProvider; 4 | import fi.septicuss.tooltips.managers.integration.wrappers.FurnitureWrapper; 5 | import io.th0rgal.oraxen.api.OraxenFurniture; 6 | import io.th0rgal.oraxen.api.OraxenItems; 7 | import io.th0rgal.oraxen.items.ItemBuilder; 8 | import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic; 9 | import org.bukkit.block.Block; 10 | import org.bukkit.entity.Entity; 11 | 12 | public class OraxenFurnitureProvider implements FurnitureProvider { 13 | 14 | @Override 15 | public FurnitureWrapper getFurniture(Entity entity) { 16 | if (!OraxenFurniture.isFurniture(entity)) { 17 | return null; 18 | } 19 | 20 | final FurnitureMechanic mechanic = OraxenFurniture.getFurnitureMechanic(entity); 21 | if (mechanic == null) return null; 22 | 23 | return this.getWrapperFromMechanic(mechanic); 24 | } 25 | 26 | @Override 27 | public FurnitureWrapper getFurniture(Block block) { 28 | if (!OraxenFurniture.isFurniture(block)) { 29 | return null; 30 | } 31 | 32 | final FurnitureMechanic mechanic = OraxenFurniture.getFurnitureMechanic(block); 33 | if (mechanic == null) return null; 34 | 35 | return this.getWrapperFromMechanic(mechanic); 36 | } 37 | 38 | private FurnitureWrapper getWrapperFromMechanic(final FurnitureMechanic mechanic) { 39 | final String id = mechanic.getItemID(); 40 | final String name = this.getFurnitureName(id); 41 | 42 | if (name == null) { 43 | return null; 44 | } 45 | 46 | return new FurnitureWrapper(this.identifier(), id, name); 47 | } 48 | 49 | 50 | private String getFurnitureName(final String itemId) { 51 | final ItemBuilder builder = OraxenItems.getItemById(itemId); 52 | 53 | if (builder == null) { 54 | return null; 55 | } 56 | 57 | final boolean hasName = builder.hasItemName(); 58 | return (hasName ? builder.getItemName() : builder.getType().toString()); 59 | } 60 | 61 | @Override 62 | public String identifier() { 63 | return "Oraxen"; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/packetevents/PacketEventsPacketProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.packetevents; 2 | 3 | import fi.septicuss.tooltips.managers.integration.providers.PacketProvider; 4 | import fi.septicuss.tooltips.managers.title.Title; 5 | 6 | import javax.annotation.Nonnull; 7 | import java.util.Optional; 8 | 9 | public class PacketEventsPacketProvider implements PacketProvider { 10 | 11 | public PacketEventsPacketProvider() { 12 | 13 | } 14 | 15 | @Override 16 | public @Nonnull Optional> createTitle(String titleJson, String subtitleJson, int fadeIn, int stay, int fadeOut) { 17 | return Optional.of(new PacketEventsTitle(this, titleJson, subtitleJson, fadeIn, stay, fadeOut)); 18 | } 19 | 20 | @Override 21 | public String identifier() { 22 | return "packetevents"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/packetevents/PacketEventsTitle.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.packetevents; 2 | 3 | import com.github.retrooper.packetevents.PacketEvents; 4 | import com.github.retrooper.packetevents.wrapper.PacketWrapper; 5 | import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetTitleSubtitle; 6 | import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetTitleText; 7 | import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetTitleTimes; 8 | import fi.septicuss.tooltips.managers.title.Title; 9 | import fi.septicuss.tooltips.utils.AdventureUtils; 10 | import org.bukkit.entity.Player; 11 | 12 | import java.util.ArrayList; 13 | 14 | public class PacketEventsTitle extends Title { 15 | 16 | private final ArrayList> packets = new ArrayList<>(); 17 | 18 | public PacketEventsTitle(PacketEventsPacketProvider packetProvider, String titleJson, String subtitleJson, int fadeIn, int stay, int fadeOut) { 19 | super(packetProvider, titleJson, subtitleJson, fadeIn, stay, fadeOut); 20 | } 21 | 22 | @Override 23 | public void preparePackets() { 24 | packets.clear(); 25 | packets.add(new WrapperPlayServerSetTitleTimes(getFadeIn(), getStay(), getFadeOut())); 26 | packets.add(new WrapperPlayServerSetTitleText(AdventureUtils.GSONSERIALIZER.deserialize(getTitleJson()))); 27 | packets.add(new WrapperPlayServerSetTitleSubtitle(AdventureUtils.GSONSERIALIZER.deserialize(getSubtitleJson()))); 28 | } 29 | 30 | @Override 31 | public void send(Player player) { 32 | final var user = PacketEvents.getAPI().getPlayerManager().getUser(player); 33 | if (user == null) { 34 | return; 35 | } 36 | for (var packet : this.packets) { 37 | user.sendPacket(packet); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/papi/PAPI.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.papi; 2 | 3 | import me.clip.placeholderapi.PlaceholderAPI; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.util.List; 8 | 9 | public class PAPI { 10 | 11 | public static List replacePlaceholders(Player player, List text) { 12 | if (!Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { 13 | return text; 14 | } 15 | 16 | return PlaceholderAPI.setPlaceholders(player, text); 17 | } 18 | 19 | public static String replacePlaceholders(Player player, String text) { 20 | if (!Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { 21 | return text; 22 | } 23 | 24 | return PlaceholderAPI.setPlaceholders(player, text); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/papi/TooltipsExpansion.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.papi; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.utils.variable.Variables; 5 | import me.clip.placeholderapi.expansion.PlaceholderExpansion; 6 | import org.bukkit.OfflinePlayer; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public class TooltipsExpansion extends PlaceholderExpansion { 11 | 12 | @Override 13 | public @NotNull String getIdentifier() { 14 | return "tooltips"; 15 | } 16 | 17 | @Override 18 | public @NotNull String getAuthor() { 19 | return "Septicuss"; 20 | } 21 | 22 | @Override 23 | public @NotNull String getVersion() { 24 | return "1.1"; 25 | } 26 | 27 | @Override 28 | public boolean persist() { 29 | return true; 30 | } 31 | 32 | @Override 33 | public @Nullable String onRequest(OfflinePlayer player, @NotNull String params) { 34 | 35 | String[] paramArgs = params.split("_"); 36 | String firstParam = paramArgs[0]; 37 | 38 | boolean variable = false; 39 | boolean persistent = false; 40 | boolean global = false; 41 | 42 | char[] chars = firstParam.toCharArray(); 43 | int length = chars.length; 44 | 45 | if (length > 3) { 46 | return null; 47 | } 48 | 49 | for (char c : firstParam.toCharArray()) { 50 | if (c == 'v') { 51 | variable = true; 52 | continue; 53 | } 54 | 55 | if (c == 'p') { 56 | persistent = true; 57 | continue; 58 | } 59 | 60 | if (c == 'g') { 61 | global = true; 62 | continue; 63 | } 64 | 65 | return null; 66 | } 67 | 68 | if (!variable) { 69 | return null; 70 | } 71 | 72 | if (params.length() < length + 1) { 73 | return null; 74 | } 75 | 76 | String variableName = params.substring(length + 1); 77 | 78 | if (variableName.isBlank()) { 79 | return null; 80 | } 81 | 82 | Argument argument = null; 83 | 84 | if (persistent) { 85 | if (global) { 86 | argument = Variables.PERSISTENT.getVar(variableName); 87 | } else { 88 | argument = Variables.PERSISTENT.getVar(player, variableName); 89 | } 90 | } else { 91 | if (global) { 92 | argument = Variables.LOCAL.getVar(variableName); 93 | } else { 94 | argument = Variables.LOCAL.getVar(player, variableName); 95 | } 96 | } 97 | 98 | if (argument == null || argument.getAsString() == null) { 99 | return null; 100 | } 101 | 102 | return argument.getAsString(); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/protocollib/ProtocolLibPacketProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.protocollib; 2 | 3 | import com.comphenix.protocol.ProtocolLibrary; 4 | import com.comphenix.protocol.ProtocolManager; 5 | import fi.septicuss.tooltips.managers.integration.providers.PacketProvider; 6 | import fi.septicuss.tooltips.managers.title.Title; 7 | 8 | import javax.annotation.Nonnull; 9 | import java.util.Optional; 10 | 11 | public class ProtocolLibPacketProvider implements PacketProvider { 12 | 13 | private final ProtocolManager protocolManager; 14 | 15 | public ProtocolLibPacketProvider() { 16 | this.protocolManager = ProtocolLibrary.getProtocolManager(); 17 | } 18 | 19 | public ProtocolManager getProtocolManager() { 20 | return this.protocolManager; 21 | } 22 | 23 | @Override 24 | public @Nonnull Optional> createTitle(String titleJson, String subtitleJson, int fadeIn, int stay, int fadeOut) { 25 | return Optional.of(new ProtocolLibTitle(this, titleJson, subtitleJson, fadeIn, stay, fadeOut)); 26 | } 27 | 28 | @Override 29 | public String identifier() { 30 | return "ProtocolLib"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/protocollib/ProtocolLibTitle.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.protocollib; 2 | 3 | import com.comphenix.protocol.PacketType; 4 | import com.comphenix.protocol.ProtocolManager; 5 | import com.comphenix.protocol.events.PacketContainer; 6 | import com.comphenix.protocol.wrappers.WrappedChatComponent; 7 | import fi.septicuss.tooltips.Tooltips; 8 | import fi.septicuss.tooltips.managers.title.Title; 9 | import org.bukkit.Bukkit; 10 | import org.bukkit.entity.Player; 11 | 12 | import java.lang.reflect.InvocationTargetException; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | public class ProtocolLibTitle extends Title { 17 | 18 | private final ProtocolManager protocolManager; 19 | private final List packets = new ArrayList<>(); 20 | private boolean setup = false; 21 | 22 | public ProtocolLibTitle(ProtocolLibPacketProvider packetProvider, String titleJson, String subtitleJson, int fadeIn, int stay, int fadeOut) { 23 | super(packetProvider, titleJson, subtitleJson, fadeIn, stay, fadeOut); 24 | 25 | this.protocolManager = packetProvider.getProtocolManager(); 26 | } 27 | 28 | @Override 29 | public void preparePackets() { 30 | var titlePacket = new PacketContainer(PacketType.Play.Server.SET_TITLE_TEXT); 31 | titlePacket.getChatComponents().write(0, WrappedChatComponent.fromJson(getTitleJson())); 32 | 33 | var subtitlePacket = new PacketContainer(PacketType.Play.Server.SET_SUBTITLE_TEXT); 34 | subtitlePacket.getChatComponents().write(0, WrappedChatComponent.fromJson(getSubtitleJson())); 35 | 36 | var timePacket = new PacketContainer(PacketType.Play.Server.SET_TITLES_ANIMATION); 37 | timePacket.getIntegers().write(0, getFadeIn()).write(1, getStay()).write(2, getFadeOut()); 38 | 39 | packets.add(timePacket); 40 | packets.add(titlePacket); 41 | packets.add(subtitlePacket); 42 | 43 | this.setup = true; 44 | } 45 | 46 | @Override 47 | public void send(Player player) { 48 | if (!setup) { 49 | return; 50 | } 51 | 52 | Bukkit.getScheduler().runTaskAsynchronously(Tooltips.get(), () -> { 53 | if (player == null || !player.isOnline()) 54 | return; 55 | 56 | try { 57 | for (PacketContainer packet : this.packets) { 58 | protocolManager.sendServerPacket(player, packet); 59 | } 60 | } catch (InvocationTargetException e) { 61 | Tooltips.warn("Failed to send title packets"); 62 | e.printStackTrace(); 63 | } 64 | }); 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/impl/worldguard/WorldGuardAreaProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.impl.worldguard; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.sk89q.worldedit.bukkit.BukkitAdapter; 5 | import com.sk89q.worldedit.math.BlockVector3; 6 | import com.sk89q.worldedit.world.World; 7 | import com.sk89q.worldguard.WorldGuard; 8 | import com.sk89q.worldguard.protection.ApplicableRegionSet; 9 | import com.sk89q.worldguard.protection.managers.RegionManager; 10 | import com.sk89q.worldguard.protection.regions.RegionContainer; 11 | import fi.septicuss.tooltips.managers.integration.providers.AreaProvider; 12 | import org.bukkit.Location; 13 | 14 | import java.util.List; 15 | 16 | public class WorldGuardAreaProvider implements AreaProvider { 17 | 18 | private RegionContainer container; 19 | 20 | public WorldGuardAreaProvider() { 21 | container = WorldGuard.getInstance().getPlatform().getRegionContainer(); 22 | } 23 | 24 | @Override 25 | public List getApplicableAreas(Location location) { 26 | if (location == null) return null; 27 | if (location.getWorld() == null) return null; 28 | 29 | final World world = BukkitAdapter.adapt(location.getWorld()); 30 | final RegionManager regions = container.get(world); 31 | 32 | if (regions == null) return null; 33 | 34 | final BlockVector3 vector = BukkitAdapter.asBlockVector(location); 35 | 36 | if (vector == null) return null; 37 | 38 | ApplicableRegionSet applicable = regions.getApplicableRegions(vector); 39 | 40 | if (applicable.size() == 0) { 41 | return null; 42 | } 43 | 44 | List regionIds = Lists.newArrayList(); 45 | applicable.forEach(region -> regionIds.add(region.getId())); 46 | 47 | return regionIds; 48 | } 49 | 50 | @Override 51 | public String identifier() { 52 | return "WorldGuard"; 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/providers/AreaProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.providers; 2 | 3 | import org.bukkit.Location; 4 | 5 | import java.util.List; 6 | 7 | public interface AreaProvider extends Provider { 8 | 9 | /** 10 | * Given a location, return a list which contains identifiers of all areas 11 | * applicable to the location. 12 | * 13 | * @param location Location to check 14 | * @return A list of area identifiers 15 | */ 16 | List getApplicableAreas(Location location); 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/providers/FurnitureProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.providers; 2 | 3 | import fi.septicuss.tooltips.managers.integration.wrappers.FurnitureWrapper; 4 | import org.bukkit.block.Block; 5 | import org.bukkit.entity.Entity; 6 | import org.bukkit.entity.Player; 7 | 8 | import javax.annotation.Nullable; 9 | 10 | public interface FurnitureProvider extends Provider { 11 | 12 | @Nullable FurnitureWrapper getFurniture(Entity entity); 13 | 14 | @Nullable FurnitureWrapper getFurniture(Block block); 15 | 16 | default boolean hasCustomRaytrace() { 17 | return false; 18 | } 19 | 20 | default FurnitureWrapper getTargetFurniture(Player player) { 21 | return null; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/providers/PacketProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.providers; 2 | 3 | import fi.septicuss.tooltips.managers.title.Title; 4 | 5 | import javax.annotation.Nonnull; 6 | import java.util.Optional; 7 | 8 | public interface PacketProvider extends Provider { 9 | 10 | @Nonnull Optional> createTitle(String titleJson, String subtitleJson, int fadeIn, int stay, int fadeOut); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/providers/Provider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.providers; 2 | 3 | public interface Provider { 4 | 5 | /** 6 | * Identifier for this provider. 7 | * 8 | * @return Identifier for this provider 9 | */ 10 | String identifier(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/integration/wrappers/FurnitureWrapper.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.integration.wrappers; 2 | 3 | public record FurnitureWrapper(String plugin, String id, String displayName) {} 4 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/ActionProperties.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions; 2 | 3 | import org.bukkit.configuration.ConfigurationSection; 4 | 5 | import java.util.Collections; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public class ActionProperties { 11 | 12 | private final Map> actionCommands; 13 | 14 | private ActionProperties(ConfigurationSection actionsSection) { 15 | 16 | this.actionCommands = new HashMap<>(); 17 | 18 | if (actionsSection == null) { 19 | return; 20 | } 21 | 22 | 23 | for (String key : actionsSection.getKeys(false)) { 24 | this.actionCommands.put(key, actionsSection.getStringList(key)); 25 | } 26 | 27 | } 28 | 29 | public boolean hasAnyActions() { 30 | return !actionCommands.isEmpty(); 31 | } 32 | 33 | public boolean hasAction(String action) { 34 | return actionCommands.containsKey(action); 35 | } 36 | 37 | public List getCommandsForAction(String action) { 38 | return Collections.unmodifiableList(actionCommands.get(action)); 39 | } 40 | 41 | public static ActionProperties of(ConfigurationSection actionsSection) { 42 | return new ActionProperties(actionsSection); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/DefaultTooltipAction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions; 2 | 3 | public class DefaultTooltipAction { 4 | public static String LEFT_CLICK = "left-click"; 5 | public static String LEFT_CLICK_BLOCK = "left-click-block"; 6 | public static String LEFT_CLICK_AIR = "left-click-air"; 7 | public static String LEFT_CLICK_ENTITY = "left-click-entity"; 8 | public static String RIGHT_CLICK = "right-click"; 9 | public static String RIGHT_CLICK_BLOCK = "right-click-block"; 10 | public static String RIGHT_CLICK_AIR = "right-click-air"; 11 | public static String RIGHT_CLICK_ENTITY = "right-click-entity"; 12 | public static String ON_SHOW = "on-show"; 13 | public static String ON_STOP_SHOWING = "on-stop-showing"; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/ActionCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.utils.validation.Validity; 5 | import org.bukkit.entity.Player; 6 | 7 | public interface ActionCommand { 8 | 9 | void run(Player player, Arguments arguments); 10 | 11 | Validity validity(Arguments arguments); 12 | 13 | default String[] convertArgumentsToArray(Arguments arguments) { 14 | String[] args = new String[arguments.size()]; 15 | for (int i = 1; i <= arguments.size(); i++) { 16 | args[i - 1] = arguments.get(String.valueOf(i)).getAsString(); 17 | } 18 | return args; 19 | } 20 | 21 | default String appendFrom(String[] args, int startIndex) { 22 | StringBuilder builder = new StringBuilder(); 23 | for (int i = startIndex; i < args.length; i++) 24 | builder.append(args[i] + " "); 25 | return builder.toString().strip(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/impl/DelayCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command.impl; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 5 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 6 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 7 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommands; 8 | import fi.septicuss.tooltips.utils.Text; 9 | import fi.septicuss.tooltips.utils.validation.Validity; 10 | import org.bukkit.Bukkit; 11 | import org.bukkit.entity.Player; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | public class DelayCommand implements ActionCommand { 17 | 18 | @Override 19 | public void run(Player player, Arguments arguments) { 20 | 21 | int ticks = arguments.get("1").getAsInt(); 22 | String commandString = appendFrom(convertArgumentsToArray(arguments), 1); 23 | 24 | List commandList = new ArrayList<>(); 25 | 26 | for (var command : commandString.split(";")) { 27 | commandList.add(Text.processText(player, command.strip())); 28 | } 29 | 30 | Bukkit.getScheduler().runTaskLater(Tooltips.get(), () -> { 31 | for (var command : commandList) { 32 | 33 | if (ActionCommands.isValidCommand(command)) { 34 | ActionCommands.runCommand(player, "none", command); 35 | continue; 36 | } 37 | 38 | Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); 39 | } 40 | }, ticks); 41 | 42 | 43 | 44 | } 45 | 46 | @Override 47 | public Validity validity(Arguments arguments) { 48 | if (!arguments.has("2")) { 49 | return Validity.of(false, "Not enough arguments: delay (ticks) (command);(other command)"); 50 | } 51 | 52 | Argument timeArg = arguments.get("1"); 53 | 54 | if (!timeArg.isNumber()) { 55 | return Validity.of(false, "Ticks must be a number"); 56 | } 57 | 58 | return Validity.TRUE; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/impl/MessageCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 5 | import fi.septicuss.tooltips.utils.AdventureUtils; 6 | import fi.septicuss.tooltips.utils.validation.Validity; 7 | import org.bukkit.entity.Player; 8 | 9 | public class MessageCommand implements ActionCommand { 10 | 11 | @Override 12 | public void run(Player player, Arguments arguments) { 13 | 14 | String message = appendFrom(convertArgumentsToArray(arguments), 0); 15 | AdventureUtils.sendMessage(player, message); 16 | 17 | } 18 | 19 | @Override 20 | public Validity validity(Arguments arguments) { 21 | return Validity.TRUE; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/impl/RedisplayCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command.impl; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 6 | import fi.septicuss.tooltips.managers.tooltip.tasks.data.PlayerTooltipData; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.entity.Player; 9 | 10 | public class RedisplayCommand implements ActionCommand { 11 | 12 | @Override 13 | public void run(Player player, Arguments arguments) { 14 | 15 | PlayerTooltipData tooltipData = Tooltips.get().getTooltipManager().getPlayerTooltipData(player); 16 | tooltipData.setRedisplayQueued(true); 17 | 18 | } 19 | 20 | @Override 21 | public Validity validity(Arguments arguments) { 22 | return Validity.TRUE; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/impl/SkipCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command.impl; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 6 | import fi.septicuss.tooltips.managers.tooltip.tasks.data.PlayerTooltipData; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import org.bukkit.entity.Player; 9 | 10 | public class SkipCommand implements ActionCommand { 11 | 12 | @Override 13 | public void run(Player player, Arguments arguments) { 14 | 15 | boolean skipAll = true; 16 | 17 | if (arguments.has("1")) { 18 | final String firstArg = arguments.get("1").getAsString(); 19 | if (firstArg.equalsIgnoreCase("current") || firstArg.equalsIgnoreCase("curr")) { 20 | skipAll = false; 21 | } 22 | 23 | } 24 | 25 | final PlayerTooltipData data = Tooltips.get().getTooltipManager().getPlayerTooltipData(player); 26 | 27 | if (skipAll) { 28 | data.skipAllAnimations(); 29 | return; 30 | } 31 | 32 | data.skipCurrentAnimation(); 33 | 34 | } 35 | 36 | @Override 37 | public Validity validity(Arguments arguments) { 38 | return Validity.TRUE; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/impl/SoundCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 5 | import fi.septicuss.tooltips.utils.Utils; 6 | import fi.septicuss.tooltips.utils.validation.Validity; 7 | import org.bukkit.SoundCategory; 8 | import org.bukkit.entity.Player; 9 | 10 | public class SoundCommand implements ActionCommand { 11 | 12 | @Override 13 | public void run(Player player, Arguments arguments) { 14 | String sound = arguments.get("1").getAsString().toLowerCase(); 15 | SoundCategory category = SoundCategory.valueOf(arguments.get("2").getAsString().toUpperCase()); 16 | float volume = arguments.get("3").getAsFloat(); 17 | float pitch = arguments.get("4").getAsFloat(); 18 | 19 | player.playSound(player.getLocation(), sound, category, volume, pitch); 20 | } 21 | 22 | @Override 23 | public Validity validity(Arguments arguments) { 24 | 25 | if (!arguments.has("4")) 26 | return Validity.of(false, "Not enough arguments: sound (sound) (category) (volume) (pitch)"); 27 | 28 | String category = arguments.get("2").getAsString(); 29 | 30 | if (!Utils.enumExists(SoundCategory.class, category)) 31 | return Validity.of(false, "Unknown sound category " + Utils.quote(category)); 32 | 33 | if (!arguments.isNumber("3") || !arguments.isNumber("4")) 34 | return Validity.of(false, "Volume and pitch must be floats"); 35 | 36 | return Validity.TRUE; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/impl/vars/ClearVarCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command.impl.vars; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 5 | import fi.septicuss.tooltips.utils.Placeholders; 6 | import fi.septicuss.tooltips.utils.Utils; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import fi.septicuss.tooltips.utils.variable.Variables; 9 | import fi.septicuss.tooltips.utils.variable.Variables.VariableProvider; 10 | import org.bukkit.Bukkit; 11 | import org.bukkit.entity.Player; 12 | 13 | public class ClearVarCommand extends VarCommand implements ActionCommand { 14 | 15 | private boolean persistent = false; 16 | private String commandName = "clearvar"; 17 | 18 | public ClearVarCommand(boolean persistent) { 19 | this.persistent = persistent; 20 | this.commandName = persistent ? "clearpersistentvar" : "clearvar"; 21 | } 22 | 23 | @Override 24 | public void run(Player player, Arguments arguments) { 25 | String[] args = convertArgumentsToArray(arguments); 26 | 27 | // Determine scope & name 28 | final String scopeArgument = args[0]; 29 | 30 | final boolean global = isGlobal(scopeArgument); 31 | Player target = getTarget(scopeArgument); 32 | 33 | if (target == null) 34 | target = player; 35 | 36 | final String variableName = Placeholders.replacePlaceholders(target, args[1]); 37 | 38 | // Clearing the variable 39 | VariableProvider provider = (persistent ? Variables.PERSISTENT : Variables.LOCAL); 40 | 41 | if (global) { 42 | provider.clearVar(variableName); 43 | return; 44 | } 45 | 46 | provider.clearVar(target, variableName); 47 | } 48 | 49 | @Override 50 | public Validity validity(Arguments arguments) { 51 | String[] args = convertArgumentsToArray(arguments); 52 | 53 | if (args.length < 2) 54 | return Validity.of(false, "Not enough arguments; " + commandName + " (player/global) name"); 55 | 56 | String target = args[0]; 57 | Player targetPlayer = Bukkit.getPlayerExact(target); 58 | 59 | if (!target.equalsIgnoreCase("global") && !target.equalsIgnoreCase("player") && targetPlayer == null) 60 | return Validity.of(false, 61 | "Scope must either be a players name, 'player' or 'global'. Now was " + Utils.quote(args[0])); 62 | 63 | return Validity.TRUE; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/impl/vars/ClearVarsCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command.impl.vars; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 5 | import fi.septicuss.tooltips.utils.Placeholders; 6 | import fi.septicuss.tooltips.utils.Utils; 7 | import fi.septicuss.tooltips.utils.validation.Validity; 8 | import fi.septicuss.tooltips.utils.variable.Variables; 9 | import fi.septicuss.tooltips.utils.variable.Variables.VariableProvider; 10 | import org.bukkit.Bukkit; 11 | import org.bukkit.entity.Player; 12 | 13 | public class ClearVarsCommand extends VarCommand implements ActionCommand { 14 | 15 | private boolean persistent; 16 | private String commandName; 17 | 18 | public ClearVarsCommand(boolean persistent) { 19 | this.persistent = persistent; 20 | this.commandName = (persistent ? "clearpersistentvars" : "clearvars"); 21 | } 22 | 23 | @Override 24 | public void run(Player player, Arguments arguments) { 25 | String[] args = convertArgumentsToArray(arguments); 26 | 27 | final String scopeArgument = Placeholders.replacePlaceholders(player, args[0]); 28 | final boolean global = isGlobal(scopeArgument); 29 | 30 | Player target = getTarget(scopeArgument); 31 | 32 | if (target == null) 33 | target = player; 34 | 35 | // Clearing vars 36 | VariableProvider provider = (persistent ? Variables.PERSISTENT : Variables.LOCAL); 37 | 38 | if (global) { 39 | provider.clearAllVars(); 40 | return; 41 | } 42 | 43 | provider.clearAllVars(target); 44 | } 45 | 46 | @Override 47 | public Validity validity(Arguments arguments) { 48 | String[] args = convertArgumentsToArray(arguments); 49 | 50 | if (args.length < 1) 51 | return Validity.of(false, "Not enough arguments; " + commandName + " (player/global)"); 52 | 53 | String target = args[0]; 54 | Player targetPlayer = Bukkit.getPlayerExact(target); 55 | 56 | if (!target.equalsIgnoreCase("global") && !target.equalsIgnoreCase("player") && targetPlayer == null) 57 | return Validity.of(false, 58 | "Scope must either be a players name, 'player' or 'global'. Now was " + Utils.quote(args[0])); 59 | 60 | return Validity.TRUE; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/impl/vars/SavePersistentVarsCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command.impl.vars; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | import fi.septicuss.tooltips.managers.preset.actions.command.ActionCommand; 5 | import fi.septicuss.tooltips.utils.validation.Validity; 6 | import fi.septicuss.tooltips.utils.variable.Variables; 7 | import org.bukkit.entity.Player; 8 | 9 | public class SavePersistentVarsCommand extends VarCommand implements ActionCommand { 10 | 11 | @Override 12 | public void run(Player player, Arguments arguments) { 13 | Variables.PERSISTENT.save(); 14 | } 15 | 16 | @Override 17 | public Validity validity(Arguments arguments) { 18 | return Validity.TRUE; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/actions/command/impl/vars/VarCommand.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.actions.command.impl.vars; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | 6 | public abstract class VarCommand { 7 | 8 | public Player getTarget(String scopeArgument) { 9 | return Bukkit.getPlayerExact(scopeArgument); 10 | } 11 | 12 | public boolean isGlobal(String scopeArgument) { 13 | return (scopeArgument.equalsIgnoreCase("global")); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/animation/Animation.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.animation; 2 | 3 | 4 | import org.bukkit.entity.Player; 5 | 6 | public interface Animation { 7 | 8 | void tick(Player player); 9 | 10 | void skip(); 11 | 12 | boolean finished(); 13 | 14 | String text(); 15 | 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/animation/AnimationProvider.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.animation; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 4 | 5 | public interface AnimationProvider { 6 | 7 | Animation create(String text, Arguments arguments); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/animation/ParsedAnimation.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.animation; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.condition.argument.Arguments; 5 | import org.bukkit.entity.Player; 6 | 7 | public record ParsedAnimation(Animation animation, String text, Arguments arguments) { 8 | 9 | public int id() { 10 | final Argument idArgument = this.arguments().get("id"); 11 | if (idArgument == null || !idArgument.isNumber()) 12 | return -1; 13 | return idArgument.getAsInt(); 14 | } 15 | 16 | 17 | public void tick(Player player) { 18 | this.animation().tick(player); 19 | } 20 | 21 | public void skip() { 22 | this.animation().skip(); 23 | } 24 | 25 | public boolean finished() { 26 | return this.animation().finished(); 27 | } 28 | 29 | public String text() { 30 | return this.animation().text(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/Function.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions; 2 | 3 | 4 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.util.List; 8 | 9 | public interface Function { 10 | 11 | String handle(Player player, FunctionContext context, List args); 12 | 13 | default boolean isAcceptRawInput() { 14 | return false; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/FunctionContext.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions; 2 | 3 | import fi.septicuss.tooltips.managers.condition.Context; 4 | 5 | public record FunctionContext(String preset, Context context) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/AnimationFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.animation.Animations; 5 | import fi.septicuss.tooltips.managers.preset.animation.ParsedAnimation; 6 | import fi.septicuss.tooltips.managers.preset.functions.Function; 7 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.List; 11 | import java.util.UUID; 12 | 13 | public class AnimationFunction implements Function { 14 | 15 | @Override 16 | public String handle(Player player, FunctionContext context, List args) { 17 | if (args.isEmpty()) return ""; 18 | final UUID uuid = UUID.fromString(args.get(0).getAsString()); 19 | final ParsedAnimation animation = Animations.get(uuid); 20 | 21 | if (animation == null) return ""; 22 | return animation.text(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/CapitalizeFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import org.bukkit.entity.Player; 7 | 8 | import java.util.List; 9 | 10 | public class CapitalizeFunction implements Function { 11 | 12 | @Override 13 | public String handle(Player player, FunctionContext context, List args) { 14 | if (args.isEmpty()) return ""; 15 | final String str = args.get(0).process(player, context.context()).getAsString(); 16 | return str.isEmpty() ? str : str.substring(0, 1).toUpperCase() + str.substring(1); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/ContextFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | 4 | import fi.septicuss.tooltips.Tooltips; 5 | import fi.septicuss.tooltips.managers.condition.Context; 6 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 7 | import fi.septicuss.tooltips.managers.preset.functions.Function; 8 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 9 | import fi.septicuss.tooltips.managers.tooltip.tasks.data.PlayerTooltipData; 10 | import fi.septicuss.tooltips.utils.Utils; 11 | import org.bukkit.entity.Player; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * $context(key) 17 | */ 18 | public class ContextFunction implements Function { 19 | 20 | private final Tooltips plugin; 21 | 22 | public ContextFunction(Tooltips plugin) { 23 | this.plugin = plugin; 24 | } 25 | 26 | @Override 27 | public String handle(Player player, FunctionContext context, List args) { 28 | if (args.isEmpty()) return ""; 29 | 30 | final String path = args.get(0).process(player, context.context()).getAsString(); 31 | final String queryPath = Utils.stripQueryPath(path); 32 | 33 | final Context tooltipContext = context.context(); 34 | if (!tooltipContext.has(queryPath)) return ""; 35 | 36 | final Object value = tooltipContext.get(queryPath); 37 | if (value == null) return ""; 38 | 39 | final Object result = Utils.queryObject(path, value); 40 | 41 | return result.toString(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/DataFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 5 | import fi.septicuss.tooltips.managers.preset.Preset; 6 | import fi.septicuss.tooltips.managers.preset.functions.Function; 7 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 8 | import fi.septicuss.tooltips.utils.Utils; 9 | import org.bukkit.configuration.ConfigurationSection; 10 | import org.bukkit.entity.Player; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * $data("path.to.yml.data") 16 | */ 17 | public class DataFunction implements Function { 18 | 19 | private final Tooltips plugin; 20 | 21 | public DataFunction(final Tooltips plugin) { 22 | this.plugin = plugin; 23 | } 24 | 25 | @Override 26 | public String handle(Player player, FunctionContext context, List args) { 27 | final String preset = context.preset(); 28 | if (preset == null) return ""; 29 | if (args.isEmpty()) return ""; 30 | 31 | final ConfigurationSection data = getPresetDataSection(preset); 32 | if (data == null) return ""; 33 | 34 | final String path = args.get(0).process(player, context.context()).getAsString(); 35 | final String queryPath = Utils.stripQueryPath(path); 36 | 37 | if (path.endsWith(".")) return ""; 38 | 39 | final Object object = data.get(queryPath); 40 | if (object == null) return ""; 41 | 42 | final Object result = Utils.queryObject(path, object); 43 | if (result == null) return ""; 44 | 45 | return result.toString(); 46 | } 47 | 48 | private ConfigurationSection getPresetDataSection(final String presetPath) { 49 | final Preset preset = plugin.getPresetManager().getPreset(presetPath); 50 | if (preset == null || !preset.isValid()) return null; 51 | 52 | final ConfigurationSection section = preset.getSection().getParent(); 53 | if (section == null) return null; 54 | if (!section.isSet("data")) return null; 55 | 56 | return section.getConfigurationSection("data"); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/HasContextFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 6 | import fi.septicuss.tooltips.managers.preset.functions.Function; 7 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 8 | import fi.septicuss.tooltips.managers.tooltip.tasks.data.PlayerTooltipData; 9 | import org.bukkit.entity.Player; 10 | 11 | import java.util.List; 12 | 13 | public class HasContextFunction implements Function { 14 | 15 | private final Tooltips plugin; 16 | 17 | public HasContextFunction(Tooltips plugin) { 18 | this.plugin = plugin; 19 | } 20 | 21 | @Override 22 | public String handle(Player player, FunctionContext context, List args) { 23 | if (args.isEmpty()) return ""; 24 | final String key = args.get(0).process(player, context.context()).getAsString(); 25 | final PlayerTooltipData tooltipData = plugin.getTooltipManager().getPlayerTooltipData(player); 26 | 27 | final Context tooltipContext = tooltipData.getActiveContext(); 28 | return (tooltipContext.has(key) && tooltipContext.get(key) != null ? "true" : "false"); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/HasDataFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 5 | import fi.septicuss.tooltips.managers.preset.Preset; 6 | import fi.septicuss.tooltips.managers.preset.functions.Function; 7 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 8 | import org.bukkit.configuration.ConfigurationSection; 9 | import org.bukkit.entity.Player; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * $hasdata("path.to.yml.data") 15 | */ 16 | public class HasDataFunction implements Function { 17 | 18 | private static final String FALSE = "false"; 19 | private static final String TRUE = "true"; 20 | private final Tooltips plugin; 21 | 22 | public HasDataFunction(final Tooltips plugin) { 23 | this.plugin = plugin; 24 | } 25 | 26 | @Override 27 | public String handle(Player player, FunctionContext context, List args) { 28 | final String preset = context.preset(); 29 | if (preset == null) return FALSE; 30 | if (args.isEmpty()) return FALSE; 31 | 32 | final ConfigurationSection data = getPresetDataSection(preset); 33 | if (data == null) return FALSE; 34 | 35 | String path = args.get(0).process(player, context.context()).getAsString(); 36 | int index = -1; 37 | 38 | // ...[x] used for indexing lists 39 | if (path.length() > 3 && path.endsWith("]") && path.charAt(path.length() - 3) == '[') { 40 | index = Character.digit(path.charAt(path.length() - 2), 10); 41 | path = path.substring(0, path.length() - 3); 42 | } 43 | 44 | final Object result = data.get(path); 45 | if (result == null) return FALSE; 46 | 47 | if (result instanceof List) { 48 | final List list = data.getList(path); 49 | final boolean hasIndex = index != -1; 50 | final boolean indexInBounds = list.size() > index; 51 | 52 | return (hasIndex && indexInBounds) ? TRUE : FALSE; 53 | } 54 | 55 | return TRUE; 56 | } 57 | 58 | private ConfigurationSection getPresetDataSection(final String presetPath) { 59 | final Preset preset = plugin.getPresetManager().getPreset(presetPath); 60 | if (preset == null || !preset.isValid()) return null; 61 | 62 | final ConfigurationSection section = preset.getSection().getParent(); 63 | if (section == null) return null; 64 | if (!section.isSet("data")) return null; 65 | 66 | return section.getConfigurationSection("data"); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/IfFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import fi.septicuss.tooltips.utils.Expr; 7 | import fi.septicuss.tooltips.utils.Utils; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.List; 11 | 12 | public class IfFunction implements Function { 13 | 14 | @Override 15 | public String handle(Player player, FunctionContext context, List args) { 16 | if (args.isEmpty() || args.size() < 3) return ""; 17 | 18 | final Argument conditionArgument = args.get(0).process(player, context.context()); 19 | final String string = conditionArgument.getAsString(); 20 | 21 | final Expr.Builder expressionBuilder = new Expr.Builder(); 22 | boolean result = true; 23 | 24 | if (this.needsParsing(expressionBuilder, string)) { 25 | float evaluated = parse(expressionBuilder, string); 26 | result = evaluated == 1; 27 | } else { 28 | result = Boolean.parseBoolean(conditionArgument.getAsString()); 29 | } 30 | 31 | if (result) { 32 | return args.get(1).process(player, context.context()).getAsString(); 33 | } 34 | 35 | return args.get(2).process(player, context.context()).getAsString(); 36 | } 37 | 38 | private boolean needsParsing(Expr.Builder expressionBuilder, String value) { 39 | final List tokens = expressionBuilder.tokenize(value); 40 | final Expr expression = expressionBuilder.parse(value, null, null); 41 | 42 | boolean fullyNumeric = true; 43 | 44 | if (tokens != null) 45 | for (var token : tokens) { 46 | if (Expr.Builder.OPS.containsKey(token)) 47 | continue; 48 | if (!Utils.isNumeric(token)) { 49 | fullyNumeric = false; 50 | break; 51 | } 52 | } 53 | 54 | if (tokens == null || expression == null || !fullyNumeric) { 55 | return false; 56 | } 57 | 58 | return true; 59 | } 60 | 61 | private float parse(Expr.Builder expressionBuilder, String value) { 62 | return expressionBuilder.parse(value, null, null).eval(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/LowercaseFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import org.bukkit.entity.Player; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * $lowercase(str) 12 | */ 13 | public class LowercaseFunction implements Function { 14 | 15 | @Override 16 | public String handle(Player player, FunctionContext context, List args) { 17 | if (args.isEmpty()) return ""; 18 | final String str = args.get(0).process(player, context.context()).getAsString(); 19 | return str.isEmpty() ? str : str.toLowerCase(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/ParseFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import fi.septicuss.tooltips.utils.Text; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.List; 11 | 12 | public class ParseFunction implements Function { 13 | 14 | @Override 15 | public String handle(Player player, FunctionContext context, List args) { 16 | if (args.isEmpty()) return ""; 17 | if (args.size() < 2) return ""; 18 | 19 | final String targetName = args.get(0).getAsString(); 20 | final String string = args.get(1).getAsString(); 21 | 22 | final Player target = Bukkit.getPlayerExact(targetName); 23 | if (target == null) return ""; 24 | 25 | return Text.processTextWithContext(target, string, context.context()); 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/PreprocessFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import fi.septicuss.tooltips.managers.preset.functions.Functions; 7 | import org.bukkit.entity.Player; 8 | 9 | import java.util.List; 10 | 11 | public class PreprocessFunction implements Function { 12 | 13 | @Override 14 | public String handle(Player player, FunctionContext context, List args) { 15 | if (args.isEmpty()) return ""; 16 | 17 | final Argument argument = args.get(0); 18 | return Functions.parseSingleLineWithContext(player, context.preset(), argument.getAsString(), context.context()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/StaticFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import fi.septicuss.tooltips.managers.preset.functions.Functions; 7 | import fi.septicuss.tooltips.utils.Utils; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class StaticFunction implements Function { 14 | 15 | @Override 16 | public String handle(Player player, FunctionContext context, List args) { 17 | if (args.isEmpty()) return ""; 18 | final List list = new ArrayList<>(); 19 | for (Argument arg : args) { 20 | list.add(arg.getAsString()); 21 | } 22 | 23 | String joined = String.join(",", list); 24 | 25 | if (Utils.isSurroundedByQuotes(joined)) { 26 | joined = Utils.removeQuotes(joined); 27 | } 28 | 29 | return Functions.parseSingleLineWithContext(player, context.preset(), joined, context.context()); 30 | } 31 | 32 | @Override 33 | public boolean isAcceptRawInput() { 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/StripFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.animation.Animations; 5 | import fi.septicuss.tooltips.managers.preset.functions.Function; 6 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 7 | import fi.septicuss.tooltips.managers.preset.functions.Functions; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.List; 11 | 12 | public class StripFunction implements Function { 13 | 14 | @Override 15 | public String handle(Player player, FunctionContext context, List args) { 16 | if (args.isEmpty()) return ""; 17 | return Animations.stripAnimations(Functions.parseSingleLineWithContext(player, context.preset(), args.get(0).getAsString(), context.context())); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/UppercaseFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import org.bukkit.entity.Player; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * $uppercase(str) 12 | */ 13 | public class UppercaseFunction implements Function { 14 | 15 | @Override 16 | public String handle(Player player, FunctionContext context, List args) { 17 | if (args.isEmpty()) return ""; 18 | final String str = args.get(0).process(player, context.context()).getAsString(); 19 | return str.isEmpty() ? str : str.toLowerCase(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/variable/HasPVarFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl.variable; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import fi.septicuss.tooltips.managers.preset.functions.Functions; 7 | import fi.septicuss.tooltips.utils.variable.Variables; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.List; 11 | 12 | public class HasPVarFunction implements Function { 13 | 14 | @Override 15 | public String handle(Player player, FunctionContext context, List args) { 16 | if (args.isEmpty()) return "false"; 17 | 18 | final String first = args.get(0).getAsString(); 19 | boolean global = first.equalsIgnoreCase("global"); 20 | 21 | String variableName = (args.size() == 1 ? args.get(0).getAsString() : args.get(1).getAsString()); 22 | variableName = Functions.parse(player, context.preset(), variableName); 23 | 24 | Argument returnArgument = null; 25 | 26 | if (global) { 27 | returnArgument = Variables.PERSISTENT.getVar(variableName); 28 | } else { 29 | returnArgument = Variables.PERSISTENT.getVar(player, variableName); 30 | } 31 | 32 | if (returnArgument == null || returnArgument.getAsString() == null) { 33 | return "false"; 34 | } 35 | 36 | return "true"; 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/variable/HasVarFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl.variable; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import fi.septicuss.tooltips.managers.preset.functions.Functions; 7 | import fi.septicuss.tooltips.utils.variable.Variables; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.List; 11 | 12 | public class HasVarFunction implements Function { 13 | 14 | @Override 15 | public String handle(Player player, FunctionContext context, List args) { 16 | if (args.isEmpty()) return "false"; 17 | 18 | final String first = args.get(0).getAsString(); 19 | boolean global = first.equalsIgnoreCase("global"); 20 | 21 | String variableName = (args.size() == 1 ? args.get(0).getAsString() : args.get(1).getAsString()); 22 | variableName = Functions.parse(player, context.preset(), variableName); 23 | 24 | Argument returnArgument = null; 25 | 26 | if (global) { 27 | returnArgument = Variables.LOCAL.getVar(variableName); 28 | } else { 29 | returnArgument = Variables.LOCAL.getVar(player, variableName); 30 | } 31 | 32 | if (returnArgument == null || returnArgument.getAsString() == null) { 33 | return "false"; 34 | } 35 | 36 | return "true"; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/variable/PVarFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl.variable; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import fi.septicuss.tooltips.managers.preset.functions.Functions; 7 | import fi.septicuss.tooltips.utils.variable.Variables; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.List; 11 | 12 | public class PVarFunction implements Function { 13 | 14 | @Override 15 | public String handle(Player player, FunctionContext context, List args) { 16 | if (args.isEmpty()) return ""; 17 | 18 | final String first = args.get(0).getAsString(); 19 | boolean global = first.equalsIgnoreCase("global"); 20 | 21 | String variableName = (args.size() == 1 ? args.get(0).getAsString() : args.get(1).getAsString()); 22 | variableName = Functions.parse(player, context.preset(), variableName); 23 | 24 | Argument returnArgument = null; 25 | 26 | if (global) { 27 | returnArgument = Variables.PERSISTENT.getVar(variableName); 28 | } else { 29 | returnArgument = Variables.PERSISTENT.getVar(player, variableName); 30 | } 31 | 32 | if (returnArgument == null || returnArgument.getAsString() == null) { 33 | return ""; 34 | } 35 | 36 | return returnArgument.getAsString(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/functions/impl/variable/VarFunction.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.functions.impl.variable; 2 | 3 | import fi.septicuss.tooltips.managers.condition.argument.Argument; 4 | import fi.septicuss.tooltips.managers.preset.functions.Function; 5 | import fi.septicuss.tooltips.managers.preset.functions.FunctionContext; 6 | import fi.septicuss.tooltips.managers.preset.functions.Functions; 7 | import fi.septicuss.tooltips.utils.variable.Variables; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.List; 11 | 12 | public class VarFunction implements Function { 13 | 14 | @Override 15 | public String handle(Player player, FunctionContext context, List args) { 16 | if (args.isEmpty()) return ""; 17 | 18 | final String first = args.get(0).getAsString(); 19 | boolean global = first.equalsIgnoreCase("global"); 20 | 21 | String variableName = (args.size() == 1 ? args.get(0).getAsString() : args.get(1).getAsString()); 22 | variableName = Functions.parse(player, context.preset(), variableName); 23 | 24 | Argument returnArgument = null; 25 | 26 | if (global) { 27 | returnArgument = Variables.LOCAL.getVar(variableName); 28 | } else { 29 | returnArgument = Variables.LOCAL.getVar(player, variableName); 30 | } 31 | 32 | if (returnArgument == null || returnArgument.getAsString() == null) { 33 | return ""; 34 | } 35 | 36 | return returnArgument.getAsString(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/preset/show/ShowProperties.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.preset.show; 2 | 3 | import org.bukkit.configuration.ConfigurationSection; 4 | 5 | public class ShowProperties { 6 | 7 | private final boolean active; 8 | private final boolean reshowOnChange; 9 | private final int limit; 10 | private final int cooldown; 11 | 12 | public ShowProperties(boolean active, boolean reshowOnChange, int limit, int cooldown) { 13 | this.active = active; 14 | this.reshowOnChange = reshowOnChange; 15 | this.limit = limit; 16 | this.cooldown = cooldown; 17 | } 18 | 19 | public boolean isActive() { 20 | return active; 21 | } 22 | 23 | public int getLimit() { 24 | return limit; 25 | } 26 | 27 | public boolean hasLimit() { 28 | return (limit != 0); 29 | } 30 | 31 | public int getCooldown() { 32 | return cooldown; 33 | } 34 | 35 | public boolean hasCooldown() { 36 | return (cooldown != 0); 37 | } 38 | 39 | public boolean shouldRefreshOnChange() { 40 | return this.reshowOnChange; 41 | } 42 | 43 | public static ShowProperties of(ConfigurationSection showSection) { 44 | if (showSection == null) 45 | return new ShowProperties(true, false, 0, 0); 46 | 47 | boolean active; 48 | boolean refreshOnChange; 49 | int limit; 50 | int cooldown; 51 | 52 | active = showSection.getBoolean("active", true); 53 | refreshOnChange = showSection.getBoolean("reshow-on-change", showSection.getBoolean("reshow", false)); 54 | limit = showSection.getInt("limit", 0); 55 | cooldown = showSection.getInt("cooldown", 0); 56 | return new ShowProperties(active, refreshOnChange, limit, cooldown); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/schema/SchemaPart.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.schema; 2 | 3 | import com.google.gson.JsonObject; 4 | import org.bukkit.configuration.ConfigurationSection; 5 | 6 | public record SchemaPart(ConfigurationSection schemaConfig, JsonObject schemaProvider) { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/theme/ThemeManager.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.theme; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.utils.FileUtils; 5 | import net.md_5.bungee.api.ChatColor; 6 | import org.bukkit.configuration.ConfigurationSection; 7 | import org.bukkit.configuration.file.YamlConfiguration; 8 | 9 | import java.io.File; 10 | import java.util.Collections; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | public class ThemeManager { 16 | 17 | public static final char OFFSET = '\uE000'; 18 | public static final char LEFT = '\uF101'; 19 | public static final char CENTER = '\uF102'; 20 | public static final char RIGHT = '\uF103'; 21 | 22 | private Map themes; 23 | 24 | public ThemeManager() { 25 | this.themes = new HashMap<>(); 26 | } 27 | 28 | public void loadFrom(final File themeDirectory) { 29 | Tooltips.log("Loading themes..."); 30 | 31 | int total = 0; 32 | int valid = 0; 33 | themes.clear(); 34 | 35 | final List themeFiles = FileUtils.getAllYamlFilesFromDirectory(themeDirectory); 36 | 37 | if (!themeFiles.isEmpty()) { 38 | for (File file : themeFiles) { 39 | final String relativeName = FileUtils.getRelativeFileName(themeDirectory, file); 40 | 41 | var config = YamlConfiguration.loadConfiguration(file); 42 | var root = config.getRoot(); 43 | 44 | for (String name : root.getKeys(false)) { 45 | final String themePath = relativeName + "/" + name; 46 | 47 | final ConfigurationSection section = root.getConfigurationSection(name); 48 | final Theme theme = new Theme(themePath, section); 49 | 50 | total++; 51 | 52 | if (!theme.isValid()) continue; 53 | 54 | registerTheme(themePath, theme); 55 | valid++; 56 | 57 | } 58 | 59 | } 60 | } 61 | 62 | final int invalid = total - valid; 63 | final String loadedAmount = valid + ((invalid > 0) ? (" (out of " + total + ")") : ("")); 64 | final String message = String.format("Loaded " + loadedAmount + " themes."); 65 | 66 | Tooltips.log(ChatColor.GREEN + message); 67 | 68 | } 69 | 70 | public Map getThemes() { 71 | return Collections.unmodifiableMap(themes); 72 | } 73 | 74 | public Theme getTheme(String name) { 75 | return themes.get(name); 76 | } 77 | 78 | public boolean doesThemeExist(String name) { 79 | return themes.containsKey(name); 80 | } 81 | 82 | public void registerTheme(String name, Theme theme) { 83 | this.themes.put(name, theme); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/title/Title.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.title; 2 | 3 | import fi.septicuss.tooltips.managers.integration.providers.PacketProvider; 4 | import org.bukkit.entity.Player; 5 | 6 | public abstract class Title { 7 | 8 | private final T packetProvider; 9 | private final String titleJson; 10 | private final String subtitleJson; 11 | private final int fadeIn; 12 | private final int stay; 13 | private final int fadeOut; 14 | 15 | public Title(T packetProvider, String titleJson, String subtitleJson, int fadeIn, int stay, int fadeOut) { 16 | this.packetProvider = packetProvider; 17 | this.titleJson = titleJson; 18 | this.subtitleJson = subtitleJson; 19 | this.fadeIn = fadeIn; 20 | this.stay = stay; 21 | this.fadeOut = fadeOut; 22 | } 23 | 24 | public T getPacketProvider() { 25 | return packetProvider; 26 | } 27 | 28 | public String getTitleJson() { 29 | return titleJson; 30 | } 31 | 32 | public String getSubtitleJson() { 33 | return subtitleJson; 34 | } 35 | 36 | public int getFadeIn() { 37 | return fadeIn; 38 | } 39 | 40 | public int getStay() { 41 | return stay; 42 | } 43 | 44 | public int getFadeOut() { 45 | return fadeOut; 46 | } 47 | 48 | public abstract void preparePackets(); 49 | 50 | public abstract void send(Player player); 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/title/TitleBuilder.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.title; 2 | 3 | import fi.septicuss.tooltips.managers.integration.providers.PacketProvider; 4 | import fi.septicuss.tooltips.utils.AdventureUtils; 5 | import net.kyori.adventure.text.Component; 6 | 7 | import java.util.Optional; 8 | 9 | public class TitleBuilder { 10 | 11 | private final TitleManager titleManager; 12 | 13 | private String titleJson = "\"\""; 14 | private String subtitleJson = "\"\""; 15 | 16 | private int fadeIn = 0; 17 | private int stay = 0; 18 | private int fadeOut = 0; 19 | 20 | public TitleBuilder(TitleManager titleManager) { 21 | this.titleManager = titleManager; 22 | } 23 | 24 | public Optional> build() { 25 | return titleManager.newTitle(titleJson, subtitleJson, fadeIn, stay, fadeOut); 26 | } 27 | 28 | public TitleBuilder clone() { 29 | TitleBuilder clone = new TitleBuilder(titleManager); 30 | clone.setTitleJson(titleJson); 31 | clone.setSubtitleJson(subtitleJson); 32 | clone.setFadeIn(fadeIn); 33 | clone.setStay(stay); 34 | clone.setFadeOut(fadeOut); 35 | return clone; 36 | } 37 | 38 | public TitleBuilder setTitle(Component title) { 39 | this.titleJson = AdventureUtils.GSONSERIALIZER.serialize(title); 40 | return this; 41 | } 42 | 43 | public TitleBuilder setSubtitle(Component subtitle) { 44 | this.subtitleJson = AdventureUtils.GSONSERIALIZER.serialize(subtitle); 45 | return this; 46 | } 47 | 48 | public TitleBuilder setTitleJson(String titleJson) { 49 | this.titleJson = titleJson; 50 | return this; 51 | } 52 | 53 | public TitleBuilder setSubtitleJson(String subtitleJson) { 54 | this.subtitleJson = subtitleJson; 55 | return this; 56 | } 57 | 58 | public TitleBuilder setFadeIn(int fadeIn) { 59 | this.fadeIn = fadeIn; 60 | return this; 61 | } 62 | 63 | public TitleBuilder setStay(int stay) { 64 | this.stay = stay; 65 | return this; 66 | } 67 | 68 | public TitleBuilder setFadeOut(int fadeOut) { 69 | this.fadeOut = fadeOut; 70 | return this; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/title/TitleManager.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.title; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.managers.integration.providers.PacketProvider; 5 | import fi.septicuss.tooltips.utils.AdventureUtils; 6 | import net.kyori.adventure.text.Component; 7 | 8 | import java.util.Optional; 9 | 10 | public class TitleManager { 11 | 12 | private final Tooltips plugin; 13 | 14 | public TitleManager(Tooltips plugin) { 15 | this.plugin = plugin; 16 | } 17 | 18 | public Optional> newTitle(String titleJson, String subtitleJson, int fadeIn, int stay, int fadeOut) { 19 | final PacketProvider packetProvider = plugin.getIntegrationManager().getPacketProvider(); 20 | 21 | if (packetProvider == null) { 22 | return Optional.empty(); 23 | } 24 | 25 | final Optional> optionalTitle = packetProvider.createTitle(titleJson, subtitleJson, fadeIn, stay, fadeOut); 26 | optionalTitle.ifPresent(Title::preparePackets); 27 | 28 | return optionalTitle; 29 | } 30 | 31 | public Optional> newTitle(Component title, Component subtitle, int fadeIn, int stay, int fadeOut) { 32 | return this.newTitle(AdventureUtils.GSONSERIALIZER.serialize(title), AdventureUtils.GSONSERIALIZER.serialize(subtitle), fadeIn, stay, fadeOut); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/tooltip/Tooltip.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.tooltip; 2 | 3 | import net.kyori.adventure.text.Component; 4 | 5 | public class Tooltip { 6 | 7 | private Component component; 8 | 9 | public Tooltip(Component component) { 10 | this.component = component; 11 | } 12 | 13 | public Component getComponent() { 14 | return component; 15 | } 16 | 17 | @Override 18 | public int hashCode() { 19 | return component.hashCode(); 20 | } 21 | 22 | @Override 23 | public boolean equals(Object obj) { 24 | return component.equals(obj); 25 | } 26 | 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/tooltip/build/TooltipProperties.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.tooltip.build; 2 | 3 | import fi.septicuss.tooltips.managers.preset.Preset; 4 | import fi.septicuss.tooltips.managers.theme.Theme; 5 | 6 | public class TooltipProperties { 7 | 8 | private Theme theme; 9 | private String color; 10 | private boolean shadow; 11 | private int horizontalShift; 12 | 13 | protected TooltipProperties() { 14 | 15 | } 16 | 17 | protected TooltipProperties(Theme theme, String color, boolean shadow, int horizontalShift) { 18 | this.theme = theme; 19 | this.color = color; 20 | this.shadow = shadow; 21 | this.horizontalShift = horizontalShift; 22 | } 23 | 24 | public Theme getTheme() { 25 | return theme; 26 | } 27 | 28 | public String getColor() { 29 | return color; 30 | } 31 | 32 | public boolean hasShadow() { 33 | return shadow; 34 | } 35 | 36 | public int getHorizontalShift() { 37 | return horizontalShift; 38 | } 39 | 40 | public static TooltipProperties from(Preset preset) { 41 | return new TooltipProperties(preset.getTheme(), preset.getColor(), preset.hasShadow(), preset.getHorizontalShift()); 42 | } 43 | 44 | public static TooltipProperties from(Theme theme) { 45 | return new TooltipProperties(theme, "#ffffff", true, 0); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/tooltip/build/element/BackgroundElement.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.tooltip.build.element; 2 | 3 | import fi.septicuss.tooltips.managers.theme.Theme; 4 | import fi.septicuss.tooltips.managers.theme.ThemeManager; 5 | import fi.septicuss.tooltips.utils.AdventureUtils; 6 | import net.kyori.adventure.text.Component; 7 | 8 | public class BackgroundElement implements TooltipElement { 9 | 10 | private static final int SIDE_PARTS = 2; 11 | 12 | private final Theme theme; 13 | private final String color; 14 | private final boolean gradient; 15 | private final int requiredWidth; 16 | private int width; 17 | 18 | private Component component; 19 | 20 | public BackgroundElement(Theme theme, String color, int requiredWidth) { 21 | this.theme = theme; 22 | this.color = color.replace('-', ':'); 23 | this.gradient = color.contains(":"); 24 | this.requiredWidth = requiredWidth; 25 | } 26 | 27 | @Override 28 | public Component getComponent() { 29 | if (this.component != null) 30 | return this.component; 31 | 32 | final int middleParts = (int) (((double)requiredWidth / (double)theme.getWidth()) + SIDE_PARTS); 33 | final int totalParts = middleParts + SIDE_PARTS; 34 | 35 | double width = theme.getWidth() * (double)totalParts; 36 | this.width = (int) (width); 37 | 38 | final String backgroundString = constructBackgroundString(middleParts); 39 | String toFormat; 40 | 41 | if (gradient) { 42 | toFormat = String.format("%s", color, backgroundString); 43 | } else { 44 | toFormat = String.format("%s", color, backgroundString); 45 | } 46 | 47 | this.component = AdventureUtils.MINIMESSAGE.deserialize(toFormat).font(theme.getFontKey()); 48 | return this.component; 49 | } 50 | 51 | private String constructBackgroundString(int middleParts) { 52 | final StringBuilder backgroundBuilder = new StringBuilder(); 53 | 54 | backgroundBuilder.append(ThemeManager.LEFT); 55 | 56 | for (int i = 0; i < middleParts; i++) { 57 | backgroundBuilder.append(ThemeManager.OFFSET); 58 | backgroundBuilder.append(ThemeManager.CENTER); 59 | } 60 | 61 | backgroundBuilder.append(ThemeManager.OFFSET); 62 | backgroundBuilder.append(ThemeManager.RIGHT); 63 | return backgroundBuilder.toString(); 64 | } 65 | 66 | @Override 67 | public int getWidth() { 68 | return width; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/tooltip/build/element/TooltipElement.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.tooltip.build.element; 2 | 3 | import net.kyori.adventure.text.Component; 4 | 5 | public interface TooltipElement { 6 | 7 | Component getComponent(); 8 | 9 | int getWidth(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/tooltip/tasks/CacheTask.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.tooltip.tasks; 2 | 3 | import fi.septicuss.tooltips.managers.integration.impl.axgens.AxGensCache; 4 | import fi.septicuss.tooltips.utils.cache.furniture.FurnitureCache; 5 | import fi.septicuss.tooltips.utils.cache.tooltip.TooltipCache; 6 | import fi.septicuss.tooltips.utils.rays.Rays; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.scheduler.BukkitRunnable; 9 | 10 | /** 11 | * Task responsible for periodically clearing the caches 12 | */ 13 | public class CacheTask extends BukkitRunnable { 14 | 15 | @Override 16 | public void run() { 17 | 18 | Rays.clearCache(); 19 | TooltipCache.clear(); 20 | FurnitureCache.clear(); 21 | 22 | if (Bukkit.getPluginManager().isPluginEnabled("AxGens")) { 23 | AxGensCache.clear(); 24 | } 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/tooltip/tasks/ConditionTask.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.tooltip.tasks; 2 | 3 | import fi.septicuss.tooltips.managers.tooltip.TooltipManager; 4 | import fi.septicuss.tooltips.managers.tooltip.tasks.data.PlayerTooltipData; 5 | import org.bukkit.Bukkit; 6 | import org.bukkit.entity.Player; 7 | import org.bukkit.scheduler.BukkitRunnable; 8 | 9 | /** 10 | * Manages: 11 | * - checking which preset should be shown to a given player based on conditions 12 | * - saving the data provided by conditions (context) 13 | */ 14 | public class ConditionTask extends BukkitRunnable { 15 | 16 | private final TooltipManager manager; 17 | 18 | public ConditionTask(final TooltipManager tooltipManager) { 19 | this.manager = tooltipManager; 20 | } 21 | 22 | @Override 23 | public void run() { 24 | 25 | var onlinePlayers = Bukkit.getOnlinePlayers(); 26 | if (onlinePlayers.isEmpty()) 27 | return; 28 | 29 | for (Player player : onlinePlayers) { 30 | 31 | final PlayerTooltipData data = manager.getPlayerTooltipData(player); 32 | 33 | for (var holderEntry : manager.getHolders().entrySet()) { 34 | var id = holderEntry.getKey(); 35 | var holder = holderEntry.getValue(); 36 | 37 | data.clearWorkingContext(); 38 | data.setCheckedPreset(id); 39 | 40 | final boolean conditionResult = holder.evaluate(player, data.getWorkingContext()); 41 | 42 | final boolean hasCurrentPreset = data.hasCurrentPreset(); 43 | final boolean isSamePreset = hasCurrentPreset && data.getCurrentPreset().equals(id); 44 | 45 | /* Handling the same preset */ 46 | 47 | if (isSamePreset) { 48 | // Same preset true again, no actions taken 49 | if (conditionResult) { 50 | data.clearPendingContext(); 51 | data.updatePendingContext(data.getWorkingContext()); 52 | break; 53 | } 54 | 55 | // Same preset false, reset current preset 56 | data.setCurrentPreset(null); 57 | continue; 58 | } 59 | 60 | /* Handling a new preset */ 61 | if (conditionResult) { 62 | data.clearPendingContext(); 63 | data.updatePendingContext(data.getWorkingContext()); 64 | data.setCurrentPreset(id); 65 | break; 66 | } 67 | } 68 | 69 | 70 | 71 | } 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/managers/tooltip/tasks/data/CooldownType.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.managers.tooltip.tasks.data; 2 | 3 | public enum CooldownType { 4 | FADE_OUT, 5 | STAY, 6 | FADE_IN, 7 | COOLDOWN; 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/pack/Generator.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.pack; 2 | 3 | import java.io.File; 4 | 5 | public interface Generator { 6 | 7 | /** 8 | * Method to generate required files by this generator in the generated 9 | * directory. 10 | * 11 | * @param directory Directory where to generate the files 12 | */ 13 | public void generate(final PackData packData, final File assetsDirectory, final File targetDirectory); 14 | 15 | /** 16 | * Get the simple name of this generator. Used in error logging. 17 | * 18 | * @return Name of the generator 19 | */ 20 | public String getName(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/pack/PackData.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.pack; 2 | 3 | import com.google.gson.JsonObject; 4 | import fi.septicuss.tooltips.utils.NamespacedPath; 5 | import fi.septicuss.tooltips.utils.Utils; 6 | 7 | import java.util.Collections; 8 | import java.util.EnumMap; 9 | import java.util.HashSet; 10 | import java.util.Set; 11 | 12 | public class PackData { 13 | 14 | private EnumMap> providerMap; 15 | private Set usedTextures; 16 | private Set usedAscents; 17 | 18 | public PackData() { 19 | this.providerMap = new EnumMap<>(ProviderType.class); 20 | this.usedTextures = new HashSet<>(); 21 | this.usedAscents = new HashSet<>(); 22 | } 23 | 24 | public void addProviders(ProviderType providerType, JsonObject... providers) { 25 | boolean containsType = providerMap.containsKey(providerType); 26 | Set objectSet = ((containsType) ? providerMap.get(providerType) : new HashSet<>()); 27 | 28 | for (var provider : providers) 29 | objectSet.add(provider); 30 | 31 | providerMap.put(providerType, objectSet); 32 | } 33 | 34 | public void addUsedTexture(NamespacedPath path) { 35 | usedTextures.add(path); 36 | } 37 | 38 | public Set getUsedTextures() { 39 | return Collections.unmodifiableSet(usedTextures); 40 | } 41 | 42 | public void addUsedAscent(int ascent) { 43 | usedAscents.add(ascent); 44 | } 45 | 46 | public Set getUsedAscents() { 47 | return Collections.unmodifiableSet(usedAscents); 48 | } 49 | 50 | public Set getProviders(ProviderType providerType) { 51 | Set providers = providerMap.get(providerType); 52 | return Collections.unmodifiableSet(Utils.getJsonSetCopy(providers)); 53 | } 54 | 55 | 56 | 57 | 58 | public enum ProviderType { 59 | GLOBAL, // Included in every font file 60 | REGULAR, // Included in regular font lines 61 | OFFSET; // Included in offset font lines 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/pack/PackGenerator.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.pack; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.utils.FileUtils; 5 | import fi.septicuss.tooltips.utils.Utils; 6 | 7 | import java.io.File; 8 | import java.util.LinkedList; 9 | 10 | public class PackGenerator { 11 | 12 | private Tooltips plugin; 13 | private LinkedList generators; 14 | 15 | public PackGenerator(Tooltips plugin) { 16 | this.plugin = plugin; 17 | this.generators = new LinkedList<>(); 18 | } 19 | 20 | public void generate() { 21 | 22 | Tooltips.log("Generating resources..."); 23 | 24 | File targetDirectory = getTargetDirectory(); 25 | FileUtils.createDirectoryIfNotExists(targetDirectory); 26 | FileUtils.cleanDirectory(targetDirectory); 27 | 28 | PackData packData = new PackData(); 29 | 30 | for (Generator generator : generators) { 31 | try { 32 | generator.generate(packData, getAssetsDirectory(), targetDirectory); 33 | } catch (Exception exception) { 34 | final var generatorName = Utils.quote(generator.getName()); 35 | final var warningMessage = String.format("Generator %s has failed. Error:", generatorName); 36 | 37 | Tooltips.warn(warningMessage); 38 | exception.printStackTrace(); 39 | } 40 | } 41 | 42 | boolean copyPack = plugin.getConfig().getBoolean("copy-resource-pack.enabled", false); 43 | 44 | if (copyPack) { 45 | copyOutput(); 46 | } 47 | 48 | } 49 | 50 | public void copyOutput() { 51 | final String relativePath = plugin.getConfig().getString("copy-resource-pack.path", null); 52 | 53 | if (relativePath == null) { 54 | return; 55 | } 56 | 57 | File copyToDirectory = new File(plugin.getDataFolder().getParentFile(), relativePath); 58 | FileUtils.createDirectoryIfNotExists(copyToDirectory); 59 | FileUtils.copyFiles(getTargetDirectory(), copyToDirectory); 60 | } 61 | 62 | public void registerGenerator(Generator generator) { 63 | this.generators.add(generator); 64 | } 65 | 66 | public File getTargetDirectory() { 67 | return new File(plugin.getDataFolder(), ".generated"); 68 | } 69 | 70 | public File getAssetsDirectory() { 71 | return new File(plugin.getDataFolder(), "pack/assets"); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/pack/impl/IconGenerator.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.pack.impl; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonObject; 5 | import fi.septicuss.tooltips.Tooltips; 6 | import fi.septicuss.tooltips.managers.icon.Icon; 7 | import fi.septicuss.tooltips.managers.icon.IconManager; 8 | import fi.septicuss.tooltips.pack.Generator; 9 | import fi.septicuss.tooltips.pack.PackData; 10 | import fi.septicuss.tooltips.pack.PackData.ProviderType; 11 | import fi.septicuss.tooltips.utils.FileUtils; 12 | import fi.septicuss.tooltips.utils.Utils; 13 | 14 | import java.io.File; 15 | import java.util.HashSet; 16 | import java.util.Set; 17 | 18 | public class IconGenerator implements Generator { 19 | 20 | public static final String ICON_FONT_FORMAT = "i%d"; 21 | private static final String ICON_PATH = "tooltips/font/icons/" + ICON_FONT_FORMAT + ".json"; 22 | 23 | private IconManager iconManager; 24 | 25 | public IconGenerator(IconManager iconManager) { 26 | this.iconManager = iconManager; 27 | } 28 | 29 | @Override 30 | public void generate(PackData packData, File assetsDirectory, File targetDirectory) { 31 | 32 | 33 | Set iconProviders = new HashSet<>(); 34 | 35 | iconManager.getAllIcons().forEach(icon -> { 36 | // 1. 37 | packData.addUsedTexture(icon.getTexturePath()); 38 | 39 | // 2. 40 | iconProviders.add(getProviderFromIcon(icon)); 41 | }); 42 | 43 | 44 | // 3. 45 | packData.getUsedAscents().forEach(ascent -> { 46 | Set copy = Utils.getJsonSetCopy(iconProviders); 47 | addAscentToProviders(copy, ascent); 48 | 49 | for (var globalProvider : packData.getProviders(ProviderType.GLOBAL)) { 50 | copy.add(globalProvider); 51 | } 52 | 53 | JsonObject root = new JsonObject(); 54 | JsonArray array = new JsonArray(); 55 | 56 | copy.forEach(array::add); 57 | root.add("providers", array); 58 | 59 | File iconFontFile = new File(targetDirectory, String.format(ICON_PATH, ascent)); 60 | FileUtils.createFileIfNotExists(iconFontFile); 61 | FileUtils.writeToFile(iconFontFile, Tooltips.GSON.toJson(root)); 62 | }); 63 | 64 | } 65 | 66 | @Override 67 | public String getName() { 68 | return "Icon Generator"; 69 | } 70 | 71 | private void addAscentToProviders(Set providers, int ascent) { 72 | for (var provider : providers) { 73 | int currentAscent = (provider.has("ascent") ? provider.get("ascent").getAsInt() : 0); 74 | int completeAscent = currentAscent + ascent; 75 | 76 | provider.addProperty("ascent", completeAscent); 77 | } 78 | } 79 | 80 | public JsonObject getProviderFromIcon(Icon icon) { 81 | JsonObject provider = new JsonObject(); 82 | provider.addProperty("type", "bitmap"); 83 | provider.addProperty("file", icon.getTexturePath().getNamespacedPath()); 84 | provider.addProperty("ascent", icon.getAscent()); 85 | provider.addProperty("height", icon.getHeight()); 86 | 87 | JsonArray chars = new JsonArray(); 88 | chars.add(icon.getUnicode()); 89 | 90 | provider.add("chars", chars); 91 | return provider; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/pack/impl/TextureGenerator.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.pack.impl; 2 | 3 | import fi.septicuss.tooltips.pack.Generator; 4 | import fi.septicuss.tooltips.pack.PackData; 5 | import fi.septicuss.tooltips.utils.FileUtils; 6 | import fi.septicuss.tooltips.utils.NamespacedPath; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.nio.file.Files; 11 | import java.nio.file.Path; 12 | import java.nio.file.StandardCopyOption; 13 | 14 | public class TextureGenerator implements Generator { 15 | 16 | @Override 17 | public void generate(PackData packData, File assetsDirectory, File targetDirectory) { 18 | 19 | for (NamespacedPath namespacedPath : packData.getUsedTextures()) { 20 | String filePath = namespacedPath.getFullPath(); 21 | 22 | Path from = Path.of(assetsDirectory.getPath(), filePath); 23 | Path to = Path.of(targetDirectory.getPath(), filePath); 24 | 25 | try { 26 | FileUtils.createIfNotExists(to.toFile()); 27 | Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING); 28 | } catch (IOException exception) { 29 | exception.printStackTrace(); 30 | } 31 | 32 | } 33 | } 34 | 35 | @Override 36 | public String getName() { 37 | return "Texture Generator"; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/Colors.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils; 2 | 3 | public class Colors { 4 | 5 | public static final String PLUGIN = "<#d33682>"; 6 | public static final String INFO = "<#ffffff>"; 7 | public static final String WARN = "<#852051>"; 8 | 9 | public static String quote(String message) { 10 | return "\"" + message + "\""; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/NamespacedPath.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | 5 | public class NamespacedPath { 6 | 7 | private String namespace = "minecraft"; 8 | private String relativePath; 9 | private String fullPath; 10 | private String category; 11 | private String namespacedPath; 12 | 13 | /** 14 | * @param namespacedPath minecraft:relative_path/texture.png 15 | * @param category textures, font 16 | */ 17 | public NamespacedPath(String namespacedPath, String category) { 18 | this.namespacedPath = namespacedPath; 19 | this.category = category; 20 | 21 | String[] splitPath = namespacedPath.split(":"); 22 | 23 | if (splitPath.length == 1) { 24 | this.relativePath = splitPath[0]; 25 | } else if (splitPath.length == 2) { 26 | this.namespace = splitPath[0]; 27 | this.relativePath = splitPath[1]; 28 | } else { 29 | Tooltips.warn(String.format("Failed loading path \"%s\". Two namespaces?", namespacedPath)); 30 | return; 31 | } 32 | 33 | this.fullPath = namespace + "/textures/" + relativePath; 34 | } 35 | 36 | /** 37 | * @param fullPath Must be inside .../assets/ | For example 38 | * "tooltips/textures/font/accented.png" 39 | */ 40 | public NamespacedPath(String fullPath) { 41 | this.fullPath = fullPath; 42 | 43 | int namespaceBreakIndex = fullPath.indexOf('/'); 44 | 45 | this.namespace = fullPath.substring(0, namespaceBreakIndex); 46 | String path = fullPath.substring(namespaceBreakIndex + 1); 47 | 48 | int categoryBreakIndex = path.indexOf('/'); 49 | 50 | this.category = path.substring(0, categoryBreakIndex); 51 | this.relativePath = path.substring(categoryBreakIndex + 1); 52 | 53 | this.namespacedPath = namespace + ":" + relativePath; 54 | } 55 | 56 | /** 57 | * @return minecraft 58 | */ 59 | public String getNamespace() { 60 | return namespace; 61 | } 62 | 63 | /** 64 | * @return (Inside of assets/namespace/category/) custom/texture.png 65 | */ 66 | public String getRelativePath() { 67 | return relativePath; 68 | } 69 | 70 | /** 71 | * @return (Inside of assets/) minecraft/textures/custom/texture.png 72 | */ 73 | public String getFullPath() { 74 | return fullPath; 75 | } 76 | 77 | /** 78 | * @return (Inside of assets/namespace/) textures 79 | */ 80 | public String getCategory() { 81 | return category; 82 | } 83 | 84 | /** 85 | * @return minecraft:custom/texture.png 86 | */ 87 | public String getNamespacedPath() { 88 | return namespacedPath; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/Placeholders.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils; 2 | 3 | import com.google.common.collect.Lists; 4 | import fi.septicuss.tooltips.managers.integration.impl.papi.PAPI; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.util.List; 8 | 9 | public class Placeholders { 10 | 11 | public static String replacePlaceholders(Player player, String str) { 12 | if (!str.contains("%")) { 13 | return str; 14 | } 15 | 16 | return PAPI.replacePlaceholders(player, str.replace("%player%", player.getName())); 17 | } 18 | 19 | public static List replacePlaceholders(Player player, List str) { 20 | final List result = Lists.newArrayList(); 21 | for (String line : str) { 22 | result.add(replacePlaceholders(player, line)); 23 | } 24 | return result; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/Text.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils; 2 | 3 | import fi.septicuss.tooltips.Tooltips; 4 | import fi.septicuss.tooltips.managers.condition.Context; 5 | import fi.septicuss.tooltips.managers.preset.animation.Animations; 6 | import fi.septicuss.tooltips.managers.preset.functions.Functions; 7 | import fi.septicuss.tooltips.managers.tooltip.tasks.data.PlayerTooltipData; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class Text { 15 | 16 | private static final List PREPROCESS_FUNCTIONS = List.of("preprocess", "strip", "static"); 17 | 18 | public static List preprocessAnimatedText(final Player player, final List text) { 19 | final List functionsParsed = Functions.parse(player, Text.getPreset(player), text, PREPROCESS_FUNCTIONS); 20 | return Animations.parse(player, functionsParsed); 21 | } 22 | 23 | public static String processText(final Player player, final String text) { 24 | final String placeholdersReplaced = Placeholders.replacePlaceholders(player, text); 25 | return Functions.parse(player, Text.getPreset(player), placeholdersReplaced); 26 | } 27 | 28 | public static String processTextWithContext(final Player player, final String text, Context context) { 29 | final String placeholdersReplaced = Placeholders.replacePlaceholders(player, text); 30 | return Functions.parse(player, Text.getPreset(player), placeholdersReplaced, null, context); 31 | } 32 | 33 | public static List processText(final Player player, final List text) { 34 | final List placeholdersReplaced = Placeholders.replacePlaceholders(player, text); 35 | final List functionsParsed = Functions.parse(player, Text.getPreset(player), placeholdersReplaced); 36 | return Text.splitText(functionsParsed); 37 | } 38 | 39 | public static List splitText(List text) { 40 | final List result = new ArrayList<>(); 41 | for (String line : text) { 42 | if (line.contains("\n")) { 43 | line = line.replace("\n", "\\n"); 44 | } 45 | 46 | if (line.contains("\\n")) { 47 | result.addAll(Arrays.asList(line.split("\\\\n"))); 48 | } else { 49 | result.add(line); 50 | } 51 | } 52 | return result; 53 | } 54 | 55 | private static String getPreset(Player player) { 56 | final PlayerTooltipData playerTooltipData = Tooltips.get().getTooltipManager().getPlayerTooltipData(player); 57 | final String preset = playerTooltipData.hasDisplayedPreset() ? playerTooltipData.getDisplayedPreset() : playerTooltipData.getSentPreset(); 58 | return preset == null ? playerTooltipData.getCheckedPreset() : preset; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/cache/area/CurrentAreaCache.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils.cache.area; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.Collections; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.UUID; 10 | 11 | public class CurrentAreaCache { 12 | 13 | private static final Map> CACHED_AREAS = new HashMap<>(); 14 | 15 | public static void put(Player player, List areaIds) { 16 | final UUID uuid = player.getUniqueId(); 17 | 18 | if (areaIds == null || areaIds.isEmpty()) { 19 | CACHED_AREAS.remove(uuid); 20 | return; 21 | } 22 | 23 | CACHED_AREAS.put(uuid, areaIds); 24 | } 25 | 26 | public static List get(Player player) { 27 | final UUID uuid = player.getUniqueId(); 28 | 29 | if (!CACHED_AREAS.containsKey(uuid)) { 30 | return null; 31 | } 32 | 33 | return Collections.unmodifiableList(CACHED_AREAS.get(uuid)); 34 | } 35 | 36 | public static boolean has(Player player) { 37 | final UUID uuid = player.getUniqueId(); 38 | if (!CACHED_AREAS.containsKey(uuid)) { 39 | return false; 40 | } 41 | return CACHED_AREAS.containsKey(uuid); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/cache/furniture/FurnitureCache.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils.cache.furniture; 2 | 3 | import fi.septicuss.tooltips.managers.integration.wrappers.FurnitureWrapper; 4 | 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class FurnitureCache { 10 | 11 | private static final Map CACHE_MAP = new HashMap<>(); 12 | 13 | public static void cacheAll(List list) { 14 | for (var furniture : list) 15 | cache(furniture); 16 | } 17 | 18 | public static void clear() { 19 | CACHE_MAP.clear(); 20 | } 21 | 22 | public static void cache(FurnitureWrapper furniture) { 23 | CACHE_MAP.put(furniture.id(), furniture); 24 | } 25 | 26 | public static boolean contains(String id) { 27 | return CACHE_MAP.containsKey(id); 28 | } 29 | 30 | public static FurnitureWrapper getFurniture(String id) { 31 | return CACHE_MAP.get(id); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/cache/player/LookingAtCache.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils.cache.player; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.UUID; 8 | 9 | public class LookingAtCache { 10 | 11 | private static final Map lookingAtFurnitureIdMap = new HashMap<>(); 12 | 13 | public static boolean contains(Player player) { 14 | return (lookingAtFurnitureIdMap.containsKey(player.getUniqueId())); 15 | } 16 | 17 | public static String get(Player player) { 18 | return (lookingAtFurnitureIdMap.get(player.getUniqueId())); 19 | } 20 | 21 | public static void put(Player player, String value) { 22 | lookingAtFurnitureIdMap.put(player.getUniqueId(), value); 23 | } 24 | 25 | public static void remove(Player player) { 26 | lookingAtFurnitureIdMap.remove(player.getUniqueId()); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/cache/tooltip/TooltipCache.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils.cache.tooltip; 2 | 3 | import fi.septicuss.tooltips.managers.title.TitleBuilder; 4 | import fi.septicuss.tooltips.utils.Text; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.UUID; 11 | import java.util.concurrent.ConcurrentHashMap; 12 | 13 | public class TooltipCache { 14 | 15 | // Player -> Hash Code -> Tooltip 16 | private static final Map> PLAYER_TOOLTIP_CACHE = new ConcurrentHashMap<>(); 17 | 18 | public static void clear() { 19 | PLAYER_TOOLTIP_CACHE.clear(); 20 | } 21 | 22 | public static void cache(Player player, List unprocessedText, TitleBuilder builder) { 23 | UUID uuid = player.getUniqueId(); 24 | int code = getHashCode(player, unprocessedText); 25 | 26 | Map map = PLAYER_TOOLTIP_CACHE.getOrDefault(uuid, new HashMap<>()); 27 | map.put(code, builder); 28 | PLAYER_TOOLTIP_CACHE.put(uuid, map); 29 | } 30 | 31 | public static void remove(Player player) { 32 | PLAYER_TOOLTIP_CACHE.remove(player.getUniqueId()); 33 | } 34 | 35 | public static boolean contains(Player player, List unprocessedText) { 36 | UUID uuid = player.getUniqueId(); 37 | 38 | Map map = PLAYER_TOOLTIP_CACHE.getOrDefault(uuid, new HashMap<>()); 39 | if (map.isEmpty()) 40 | return false; 41 | 42 | int code = getHashCode(player, unprocessedText); 43 | return map.containsKey(code); 44 | } 45 | 46 | public static TitleBuilder get(Player player, List unprocessedText) { 47 | UUID uuid = player.getUniqueId(); 48 | 49 | Map map = PLAYER_TOOLTIP_CACHE.getOrDefault(uuid, new HashMap<>()); 50 | if (map.isEmpty()) 51 | return null; 52 | 53 | int code = getHashCode(player, unprocessedText); 54 | return map.get(code); 55 | } 56 | 57 | private static int getHashCode(Player player, List unprocessedText) { 58 | List processed = Text.processText(player, unprocessedText); 59 | return processed.hashCode(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/font/Spaces.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils.font; 2 | 3 | import com.google.common.collect.Maps; 4 | import net.kyori.adventure.key.Key; 5 | import net.kyori.adventure.text.Component; 6 | 7 | import java.util.Collections; 8 | import java.util.Map; 9 | import java.util.Set; 10 | 11 | public class Spaces { 12 | 13 | public static final Key OFFSET_FONT_KEY = Key.key("tooltips", "space"); 14 | private static final Map OFFSET_MAP; 15 | 16 | // Inside each theme line 17 | public static final char NEGATIVE_ONE = '\uE000'; 18 | public static final char POSITIVE_ONE = '\uE001'; 19 | 20 | static { 21 | OFFSET_MAP = Maps.newHashMap(); 22 | 23 | OFFSET_MAP.put(-1, '\uE001'); 24 | OFFSET_MAP.put(-2, '\uE002'); 25 | OFFSET_MAP.put(-4, '\uE003'); 26 | OFFSET_MAP.put(-8, '\uE004'); 27 | OFFSET_MAP.put(-16, '\uE005'); 28 | OFFSET_MAP.put(-32, '\uE006'); 29 | OFFSET_MAP.put(-64, '\uE007'); 30 | OFFSET_MAP.put(-128, '\uE008'); 31 | 32 | OFFSET_MAP.put(1, '\uE009'); 33 | OFFSET_MAP.put(2, '\uE010'); 34 | OFFSET_MAP.put(4, '\uE011'); 35 | OFFSET_MAP.put(8, '\uE012'); 36 | OFFSET_MAP.put(16, '\uE013'); 37 | OFFSET_MAP.put(32, '\uE014'); 38 | OFFSET_MAP.put(64, '\uE015'); 39 | OFFSET_MAP.put(128, '\uE016'); 40 | } 41 | 42 | public static Component getOffset(int pixels) { 43 | return Component.text(getOffsetText(pixels)).font(OFFSET_FONT_KEY); 44 | } 45 | 46 | public static String getOffsetText(int pixels) { 47 | final StringBuilder builder = new StringBuilder(); 48 | if (pixels == 0) 49 | return builder.toString(); // Return empty string 50 | 51 | final boolean negative = Integer.signum(pixels) == -1; 52 | pixels = Math.abs(pixels); // Get negative pixels absolute value 53 | 54 | while (pixels > 0) { 55 | int highestBit = Integer.highestOneBit(pixels); 56 | if (highestBit > 128) 57 | highestBit = 128; // Max is 128 58 | builder.append(OFFSET_MAP.get(negative ? -highestBit : highestBit)); 59 | 60 | pixels -= highestBit; 61 | } 62 | 63 | return builder.toString(); 64 | } 65 | 66 | public static Set> getOffsetMapEntries() { 67 | return Collections.unmodifiableSet(OFFSET_MAP.entrySet()); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/validation/Validatable.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils.validation; 2 | 3 | public interface Validatable { 4 | 5 | public boolean isValid(); 6 | 7 | default Validity validity() { 8 | return Validity.TRUE; 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/fi/septicuss/tooltips/utils/validation/Validity.java: -------------------------------------------------------------------------------- 1 | package fi.septicuss.tooltips.utils.validation; 2 | 3 | public class Validity { 4 | 5 | public static final Validity TRUE = Validity.of(true); 6 | public static final Validity FALSE = Validity.of(false); 7 | 8 | private boolean result; 9 | private String reason; 10 | 11 | protected Validity(boolean result, String reason) { 12 | this.result = result; 13 | this.reason = reason; 14 | } 15 | 16 | public boolean isValid() { 17 | return result; 18 | } 19 | 20 | public String getReason() { 21 | return reason; 22 | } 23 | 24 | public boolean hasReason() { 25 | return reason != null; 26 | } 27 | 28 | public static Validity of(boolean result) { 29 | return new Validity(result, null); 30 | } 31 | 32 | public static Validity of(boolean result, String reason) { 33 | return new Validity(result, reason); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/resources/default/.data/schemas/textures/accented.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/.data/schemas/textures/accented.png -------------------------------------------------------------------------------- /src/main/resources/default/.data/schemas/textures/ascii.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/.data/schemas/textures/ascii.png -------------------------------------------------------------------------------- /src/main/resources/default/.data/schemas/textures/nonlatin_european.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/.data/schemas/textures/nonlatin_european.png -------------------------------------------------------------------------------- /src/main/resources/default/.data/schemas/textures/space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/.data/schemas/textures/space.png -------------------------------------------------------------------------------- /src/main/resources/default/.data/widths.yml: -------------------------------------------------------------------------------- 1 | # Optional file, which allows you to specify the pixel widths of unicodes 2 | # Note that pixels in this file can be of decimal format (1.25, 4.5 etc..) 3 | # This helps the plugin in width calculation 4 | 5 | !: 2 6 | `: 2 7 | a: 3 8 | b: 3 9 | c: 3 10 | d: 3 11 | e: 3 12 | f: 3 13 | g: 3 14 | h: 3 15 | i: 3 16 | j: 3 17 | k: 3 18 | l: 3 19 | m: 3 20 | n: 3 21 | o: 3 -------------------------------------------------------------------------------- /src/main/resources/default/config/config.yml: -------------------------------------------------------------------------------- 1 | # How often, in ticks the plugin will attempt to check the conditions 2 | condition-check-frequency: 3 3 | 4 | # Copy the resource packs namespaces to a given directory 5 | # The parent directory is the plugins folder 6 | copy-resource-pack: 7 | enabled: false 8 | path: '' 9 | 10 | # Which furniture plugin is used if there are multiple 11 | # Options: Automatic, Oraxen, ItemsAdder, MythicCrucible 12 | furniture-plugin: automatic 13 | 14 | # This determines, which negative space mode is used. Set to 'false' for versions before 15 | # 1.19 and 'true' for 1.19+ 16 | use-spaces: true -------------------------------------------------------------------------------- /src/main/resources/default/config/icons/default.yml: -------------------------------------------------------------------------------- 1 | gem: 2 | path: "tooltips:example-icons/gem.png" 3 | ascent: 2 4 | height: 8 5 | box: 6 | path: "tooltips:example-icons/box.png" 7 | ascent: 0 8 | height: 4 9 | right-click: 10 | path: "tooltips:example-icons/right-click.png" 11 | ascent: 0 12 | height: 4 -------------------------------------------------------------------------------- /src/main/resources/default/config/presets/default.yml: -------------------------------------------------------------------------------- 1 | preset: 2 | # The max amount of lines here, is the amount of lines in the themes settings 3 | text: 4 | - 'Test Tooltip' 5 | - 'Price: 500{default/gem}' 6 | - '(Click to buy)' 7 | # Which theme to use 8 | theme: default/three-line 9 | # Settings related to how this tooltips is displayed 10 | display: 11 | # The color of the theme (background) 12 | color: white 13 | # List of conditions 14 | conditions: 15 | - op 16 | - lookingatblock{type=bedrock} -------------------------------------------------------------------------------- /src/main/resources/default/config/themes/default.yml: -------------------------------------------------------------------------------- 1 | one-line: 2 | path: "tooltips:tooltips/default/one-line.png" 3 | height: 10 4 | padding: 1 5 | lines: 1 6 | ascents: 7 | theme-ascent: 0 8 | text-start-ascent: -3 9 | text-line-spacing: 5 10 | two-line: 11 | path: "tooltips:tooltips/default/two-line.png" 12 | height: 13 13 | padding: 1 14 | lines: 2 15 | ascents: 16 | theme-ascent: 0 17 | text-start-ascent: -2 18 | text-line-spacing: 5 19 | three-line: 20 | path: "tooltips:tooltips/default/three-line.png" 21 | height: 18 22 | padding: 1 23 | lines: 3 24 | ascents: 25 | theme-ascent: 0 26 | text-start-ascent: -2 27 | text-line-spacing: 5 28 | four-line: 29 | path: "tooltips:tooltips/default/four-line.png" 30 | height: 23 31 | padding: 1 32 | lines: 4 33 | ascents: 34 | theme-ascent: 0 35 | text-start-ascent: -2 36 | text-line-spacing: 5 37 | five-line: 38 | path: "tooltips:tooltips/default/five-line.png" 39 | height: 28 40 | padding: 1 41 | lines: 5 42 | ascents: 43 | theme-ascent: 0 44 | text-start-ascent: -2 45 | text-line-spacing: 5 -------------------------------------------------------------------------------- /src/main/resources/default/pack/assets/tooltips/textures/example-icons/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/pack/assets/tooltips/textures/example-icons/box.png -------------------------------------------------------------------------------- /src/main/resources/default/pack/assets/tooltips/textures/example-icons/gem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/pack/assets/tooltips/textures/example-icons/gem.png -------------------------------------------------------------------------------- /src/main/resources/default/pack/assets/tooltips/textures/example-icons/right-click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/pack/assets/tooltips/textures/example-icons/right-click.png -------------------------------------------------------------------------------- /src/main/resources/default/pack/assets/tooltips/textures/space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/pack/assets/tooltips/textures/space.png -------------------------------------------------------------------------------- /src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/five-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/five-line.png -------------------------------------------------------------------------------- /src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/four-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/four-line.png -------------------------------------------------------------------------------- /src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/one-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/one-line.png -------------------------------------------------------------------------------- /src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/three-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/three-line.png -------------------------------------------------------------------------------- /src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/two-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septicuss/tooltips/249af0b49c44b861ea229ddea28f41a583d5bcd8/src/main/resources/default/pack/assets/tooltips/textures/tooltips/default/two-line.png -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: Tooltips 2 | main: fi.septicuss.tooltips.Tooltips 3 | version: ${project.version} 4 | api-version: 1.16 5 | 6 | author: Septicuss 7 | 8 | softdepend: [ PlaceholderAPI, ItemsAdder, Nexo, Oraxen, WorldGuard, WorldEdit, MythicCrucible, MythicMobs, Citizens, ProtocolLib, packetevents, BetonQuest ] 9 | 10 | libraries: 11 | - net.kyori:adventure-api:${adventure.core.version} 12 | - net.kyori:adventure-platform-bukkit:${adventure.bukkit.version} 13 | - net.kyori:adventure-text-minimessage:${adventure.core.version} 14 | - net.kyori:adventure-text-serializer-plain:${adventure.core.version} 15 | - net.kyori:adventure-text-serializer-gson:${adventure.core.version} 16 | 17 | commands: 18 | tooltips: 19 | aliases: [tooltip, tt] --------------------------------------------------------------------------------