Compare commits

..

13 Commits

Author SHA1 Message Date
benamaurer 74709cef0b Added alternate spelling of color as aliases for color command.
Added alternate spelling of color as aliases for color command.
2022-08-24 00:38:48 +00:00
Joey Hines 0c08c26854 Added Head Shop (#18)
Moved ShopkeepersAPI reference to listener

Moved head shop logic to its own listener

Move checkup command join outside shopkeeper check

Refresh player head on login

+ Cleaned up imports

Use UUID instead of display name to determine if a player is in the shop

Check if Shopkeepers is present before trying to enable it

Added Head Shop

+ Integrates with ShopKeepers
+ On login, users with the `qol.head_shop` perm have their head added to the shop, if not already added
+ The shop id and the price to charge are both configurable

Co-authored-by: Joey Hines <joey@ahines.net>
Reviewed-on: https://git.canopymc.net/Canopy/QoL/pulls/18
Reviewed-by: Etzelia <etzelia@hotmail.com>
Co-Authored-By: ZeroHD <joey@ahines.net>
Co-Committed-By: ZeroHD <joey@ahines.net>
2021-08-10 01:32:17 +00:00
Joey Hines f327f59d6c Added `discordignore` command (#17)
Small tweaks

+ Fixed permission node
+ Removed unused imports

Added `discordignore` command

+ Toggles Discord messages on/off for the user
+ Resolves #16

Co-authored-by: Joey Hines <joey@ahines.net>
Reviewed-on: https://git.canopymc.net/Canopy/QoL/pulls/17
Reviewed-by: Etzelia <etzelia@hotmail.com>
Co-Authored-By: ZeroHD <joey@ahines.net>
Co-Committed-By: ZeroHD <joey@ahines.net>
2021-08-03 02:34:17 +00:00
Mighty_Squid df292f88c5 Add moon phase command (#15)
Add moon phase command

Co-authored-by: Mighty_Squid <103967@gmail.com>
Reviewed-on: https://git.canopymc.net/Canopy/QoL/pulls/15
Reviewed-by: ZeroHD <joey@ahines.net>
Co-Authored-By: Mighty_Squid <mighty_squid@noreply.git.canopymc.net>
Co-Committed-By: Mighty_Squid <mighty_squid@noreply.git.canopymc.net>
2021-08-03 00:29:04 +00:00
Joey Hines fa2f79239e Add Config To Disable Enderman Grief (#14)
Added default config value

Bumped version number

Add config for disabling enderman grief

Co-authored-by: Joey Hines <joey@ahines.net>
Reviewed-on: https://git.canopymc.net/Canopy/QoL/pulls/14
Reviewed-by: Etzelia <etzelia@hotmail.com>
Co-Authored-By: ZeroHD <joey@ahines.net>
Co-Committed-By: ZeroHD <joey@ahines.net>
2021-07-21 00:20:25 +00:00
Mighty_Squid 2e72736571 Initial version of wiki command (#13)
Version 1.12

Initial version of wiki command

Co-authored-by: Mighty_Squid <103967@gmail.com>
Reviewed-on: https://git.canopymc.net/Canopy/QoL/pulls/13
Reviewed-by: Etzelia <etzelia@hotmail.com>
Co-Authored-By: Mighty_Squid <mighty_squid@noreply.git.canopymc.net>
Co-Committed-By: Mighty_Squid <mighty_squid@noreply.git.canopymc.net>
2021-07-19 17:30:59 +00:00
Joey Hines 3c54c249a1 Each player now gets the same reminder (#12)
Each player now gets the same reminder

+ Reminders are logged to console now
+ Fixes #11

Co-authored-by: Joey Hines <joey@ahines.net>
Reviewed-on: https://git.canopymc.net/Canopy/QoL/pulls/12
Reviewed-by: Etzelia <etzelia@hotmail.com>
Co-Authored-By: ZeroHD <joey@ahines.net>
Co-Committed-By: ZeroHD <joey@ahines.net>
2021-07-12 21:36:03 +00:00
Joey Hines 3ae415d7d0 Marked dynmap-api dependency as `provided` (#10)
Marked dynmap-api dependency as `provided`

+ Fixes #9

Co-authored-by: Joey Hines <joey@ahines.net>
Reviewed-on: https://git.canopymc.net/Canopy/QoL/pulls/10
Reviewed-by: Etzelia <etzelia@hotmail.com>
Co-Authored-By: ZeroHD <joey@ahines.net>
Co-Committed-By: ZeroHD <joey@ahines.net>
2021-07-11 16:12:13 +00:00
Joey Hines e3cf0d6d9f Switched to Spark for TPS alerts (#8)
Switched to Spark for TPS alerts

+ Currently just looks at tps, but we could hook in mspt
+ Fixes #6

Co-authored-by: Joey Hines <joey@ahines.net>
Reviewed-on: https://git.canopymc.net/Canopy/QoL/pulls/8
Reviewed-by: Etzelia <etzelia@hotmail.com>
Co-Authored-By: ZeroHD <joey@ahines.net>
Co-Committed-By: ZeroHD <joey@ahines.net>
2021-07-05 14:52:41 +00:00
Joey Hines 3c3fdc1725 Merge pull request 'Added .drone.yml' (#7) from ZeroHD/QoL:iss/5 into main
Reviewed-on: https://git.birbmc.com/Canopy/QoL/pulls/7
Reviewed-by: Etzelia <etzelia@hotmail.com>
2021-06-28 02:30:38 +00:00
Joey Hines 9c316f9fff
why do we even *need* https 2021-06-27 20:18:41 -06:00
Joey Hines e91e5ae9e5
Added .drone.yml 2021-06-27 20:13:43 -06:00
Joey Hines 684b269039 Added reminder groups (#3)
Added reminder groups

+ Multiple reminder groups can be define
+ Reminders still occur as set by the frequency
+ Each group can be configured with its own chat color and period
+ The period config defines how many reminder cycles it takes before that group's next message is used

Co-authored-by: Joey Hines <joey@ahines.net>
Reviewed-on: https://git.birbmc.com/Canopy/QoL/pulls/3
Reviewed-by: Etzelia <etzelia@hotmail.com>
Co-Authored-By: ZeroHD <joey@ahines.net>
Co-Committed-By: ZeroHD <joey@ahines.net>
2021-06-25 16:08:50 +00:00
16 changed files with 544 additions and 67 deletions

36
.drone.yml 100644
View File

@ -0,0 +1,36 @@
---
kind: pipeline
type: docker
name: compliance
steps:
- name: build
image: maven:3-openjdk-16
commands:
- mvn install
---
kind: pipeline
type: docker
name: release
trigger:
branch:
- main
event:
- push
steps:
- name: build
image: maven:3-openjdk-16
commands:
- mvn install
- name: gitea-release
pull: always
image: jolheiser/drone-gitea-main:latest
settings:
token:
from_secret: gitea_token
base: https://git.canopymc.net
files:
- "target/QoL-*.jar"

42
pom.xml
View File

@ -3,7 +3,7 @@
<groupId>xyz.etztech</groupId>
<artifactId>QoL</artifactId>
<!-- Version is used in plugin.yml -->
<version>1.10</version>
<version>1.16</version>
<packaging>jar</packaging>
<!-- Plugin Information -->
@ -37,17 +37,13 @@
<dependency>
<groupId>xyz.etztech</groupId>
<artifactId>plugin-api</artifactId>
<version>1.0.8</version>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>EssentialsX</artifactId>
<version>2.18.1</version>
<version>1.0.7</version>
</dependency>
<dependency>
<groupId>us.dynmap</groupId>
<artifactId>dynmap-api</artifactId>
<version>1.9.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
@ -57,7 +53,19 @@
<dependency>
<groupId>com.discordsrv</groupId>
<artifactId>discordsrv</artifactId>
<version>1.19.1</version>
<version>1.23.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.lucko</groupId>
<artifactId>spark-api</artifactId>
<version>0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.nisovin.shopkeepers</groupId>
<artifactId>ShopkeepersAPI</artifactId>
<version>2.13.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
@ -72,16 +80,12 @@
<url>https://nexus.scarsz.me/content/groups/public/</url>
</repository>
<repository>
<id>etztech-repo</id>
<url>http://repo.etztech.xyz</url>
<id>birbmc-repo</id>
<url>https://mvn.birbmc.com</url>
</repository>
<repository>
<id>dynmap-repo</id>
<url>http://repo.mikeprimm.com/</url>
</repository>
<repository>
<id>ess-repo</id>
<url>https://ci.ender.zone/plugin/repository/everything/</url>
<url>https://repo.mikeprimm.com/</url>
</repository>
<repository>
<id>mvn-repo</id>
@ -95,6 +99,14 @@
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>sonatype-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
<repository>
<id>shopkeepers-repo</id>
<url>https://nexus.lichtspiele.org/repository/releases/</url>
</repository>
</repositories>
<build>

View File

@ -1,11 +1,13 @@
package xyz.etztech.qol;
import net.ess3.api.IEssentials;
import com.nisovin.shopkeepers.api.ShopkeepersPlugin;
import github.scarsz.discordsrv.DiscordSRV;
import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import org.dynmap.DynmapAPI;
import org.dynmap.markers.Marker;
@ -15,7 +17,9 @@ import org.dynmap.markers.MarkerSet;
import xyz.etztech.qol.commands.*;
import xyz.etztech.qol.listeners.*;
import xyz.etztech.qol.other.LinkCommand;
import xyz.etztech.qol.other.Reminder;
import xyz.etztech.qol.other.TPSRunnable;
import me.lucko.spark.api.Spark;
import java.util.ArrayList;
import java.util.List;
@ -28,7 +32,7 @@ public class QoL extends JavaPlugin {
private String qolMarkerIcon = null;
private static QoL instance;
private IEssentials essentials = null;
private Spark spark = null;
private DynmapAPI dynmap = null;
private MarkerAPI markerAPI = null;
private MarkerSet playerMarkerSet = null;
@ -45,16 +49,19 @@ public class QoL extends JavaPlugin {
private static List<String> audits = new ArrayList<>();
private static List<LinkCommand> links = new ArrayList<>();
private Reminder reminder = null;
public void onEnable() {
instance = this;
saveDefaultConfig();
reloadConfig();
saveResource("qol.png", true);
//Essentials hook
if (Bukkit.getPluginManager().isPluginEnabled("Essentials")) {
log("Hooked into Essentials for TPS alert.");
essentials = (IEssentials) Bukkit.getPluginManager().getPlugin("Essentials");
//Spark hook
RegisteredServiceProvider<Spark> sparkProvider = Bukkit.getServicesManager().getRegistration(Spark.class);
if (sparkProvider != null) {
log("Hooked into Spark for TPS alert.");
spark = sparkProvider.getProvider();
}
//Dynmap hook
@ -84,10 +91,17 @@ public class QoL extends JavaPlugin {
}
}
// DiscordSRV Hook
if (Bukkit.getPluginManager().isPluginEnabled("DiscordSRV")) {
new DiscordSRVListener(this);
}
// Shopkeepers Hook
if (Bukkit.getPluginManager().isPluginEnabled("Shopkeepers")) {
new HeadShopListener(this);
log("Hooked in Shopkeepers for the head shop");
}
if( isEnabled() ) {
// Add listeners
@ -98,6 +112,7 @@ public class QoL extends JavaPlugin {
new BlockIgniteListener(this);
new CommandPreprocessListener(this);
new DeathListener(this);
new EntityChangeBlockListener(this);
// Add commands
new MainCommand(this);
@ -114,6 +129,12 @@ public class QoL extends JavaPlugin {
new DeathMuteCommand(this);
new CheckupCommand(this);
new DynmapLinkCommand(this);
new WikiCommand(this);
new MoonCommand(this);
if (DiscordSRV.api.isAnyHooked()) {
new DiscordIgnoreCommand(this);
}
if (dynmap != null) {
new MarkerCommand(this);
@ -136,25 +157,17 @@ public class QoL extends JavaPlugin {
}, 0, EtzTechUtil.minutesToTicks(schedule));
}
// Reminders
int frequency = config.getInt("reminders.frequency");
if (frequency > 0) {
if (reminder != null && reminder.getFrequency() != 0) {
Bukkit.getScheduler().scheduleSyncRepeatingTask(QoL.getInstance(), new Runnable() {
int idx = 0;
@Override
public void run() {
List<String> reminders = config.getStringList("reminders.messages");
ChatColor color = ChatColor.getByChar(config.getString("reminders.color").replace("&", ""));
if (idx >= reminders.size()) {
idx = 0;
}
BaseComponent [] msg = reminder.nextReminder();
for (Player player : Bukkit.getOnlinePlayers()) {
EtzTechUtil.sms(player, color + reminders.get(idx));
player.spigot().sendMessage(msg);
}
idx++;
Bukkit.getConsoleSender().spigot().sendMessage(msg);
}
}, 0, EtzTechUtil.minutesToTicks(frequency));
}, 0, EtzTechUtil.minutesToTicks(reminder.getFrequency()));
}
// TPS Check
@ -186,6 +199,8 @@ public class QoL extends JavaPlugin {
qolMarkerIcon = config.getString("dynmap.marker_icon", "blueflag");
qolMarkerLayerShow = config.getBoolean("dynmap.marker_set_show", false);
qolMarkerSetLabel = config.getString("dynmap.marker_set_label", "QoL Markers");
reminder = Reminder.fromConfig(config.getConfigurationSection("reminders"));
}
@ -282,8 +297,6 @@ public class QoL extends JavaPlugin {
return links;
}
public IEssentials getEssentials() { return essentials; }
public DynmapAPI getDynmap() { return dynmap; }
public void runTask(final String command) {
@ -336,5 +349,9 @@ public class QoL extends JavaPlugin {
return marker;
}
}
public Spark getSpark() {
return spark;
}
}

View File

@ -0,0 +1,55 @@
package xyz.etztech.qol.commands;
import github.scarsz.discordsrv.DiscordSRV;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import xyz.etztech.qol.EtzTechUtil;
import xyz.etztech.qol.Lang;
import xyz.etztech.qol.QoL;
public class DiscordIgnoreCommand implements CommandExecutor {
public static final String DISCORD_IGNORE_METADATA = "qol.discord_ignore";
QoL plugin;
public DiscordIgnoreCommand(QoL plugin) {
this.plugin = plugin;
plugin.getCommand("discordignore").setExecutor(this);
}
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
if (!( commandSender instanceof Player)) {
EtzTechUtil.sms(commandSender, Lang.NO_CONSOLE.getDef());
return true;
}
if (!commandSender.hasPermission("qol.discordignore")) {
EtzTechUtil.sms(commandSender, Lang.NO_PERMISSION.getDef());
return true;
}
if (!DiscordSRV.api.isAnyHooked()) {
EtzTechUtil.sms(commandSender, "Command not enabled!");
return true;
}
Player player = (Player) commandSender;
boolean ignoreState = player.hasMetadata(DISCORD_IGNORE_METADATA);
String msg;
if (ignoreState) {
player.removeMetadata(DISCORD_IGNORE_METADATA, plugin);
msg = "Discord messages will now appear.";
}
else {
player.setMetadata(DISCORD_IGNORE_METADATA, new FixedMetadataValue(plugin, DISCORD_IGNORE_METADATA));
msg = "Ignoring Discord messages.";
}
EtzTechUtil.sms(commandSender, org.bukkit.ChatColor.GREEN + msg);
return true;
}
}

View File

@ -0,0 +1,51 @@
package xyz.etztech.qol.commands;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import xyz.etztech.qol.QoL;
import xyz.etztech.qol.EtzTechUtil;
import xyz.etztech.qol.Lang;
import java.util.Map;
import java.lang.*;
public class MoonCommand implements CommandExecutor {
QoL plugin;
private final Map<Integer, String> moonPhases = Map.of(
0, "Full moon",
1, "Waning gibbous",
2, "Third quarter",
3, "Waning crescent",
4, "New moon",
5, "Waxing crescent",
6, "First quarter",
7, "Waxing gibbous"
);
public MoonCommand(QoL paramQoL) {
this.plugin = paramQoL;
plugin.getCommand("moon").setExecutor(this);
}
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
if (!commandSender.hasPermission("qol.moon")) {
EtzTechUtil.sms(commandSender, Lang.NO_PERMISSION.getDef());
return true;
}
String playername = commandSender.getName();
long time = commandSender.getServer().getPlayer(playername).getWorld().getFullTime();
double day = Math.floor(time / 24000);
int moonPhase = (int)(day % 8);
StringBuilder message = new StringBuilder(ChatColor.GOLD + "===== Moon Phase Utility =====");
message.append("\n" + ChatColor.GREEN + "Current moon phase: " + moonPhases.get(moonPhase) + ".");
message.append("\n" + ChatColor.GREEN + "Full moon is " + (moonPhase == 0 ? "tonight." : "in " + (8 - moonPhase) + ((moonPhase == 7) ? " day." : " days.")));
EtzTechUtil.sms(commandSender, message.toString());
return true;
}
}

View File

@ -0,0 +1,60 @@
package xyz.etztech.qol.commands;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import xyz.etztech.qol.QoL;
import xyz.etztech.qol.EtzTechUtil;
import xyz.etztech.qol.Lang;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Date;
public class WikiCommand implements CommandExecutor {
QoL plugin;
public WikiCommand(QoL paramQoL) {
this.plugin = paramQoL;
plugin.getCommand("wiki").setExecutor(this);
}
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
if (!commandSender.hasPermission("qol.wiki")) {
EtzTechUtil.sms(commandSender, Lang.NO_PERMISSION.getDef());
return true;
}
if (args.length < 1) {
EtzTechUtil.sms(commandSender, ChatColor.RED + "Please give a search argument.");
return true;
}
try {
Date changedToAt;
JsonObject obj;
InputStream response = new URL(String.format("https://minecraft.gamepedia.com/api.php?action=opensearch&format=json&formatversion=2&search=%s&namespace=0&limit=1", args[0])).openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(response));
JsonArray jsonArray = new JsonParser().parse(reader.readLine()).getAsJsonArray();
StringBuilder message = new StringBuilder(ChatColor.GREEN + jsonArray.get(1).getAsJsonArray().get(0).getAsString());
message.append(": ");
message.append(ChatColor.WHITE + jsonArray.get(3).getAsJsonArray().get(0).getAsString());
EtzTechUtil.sms(commandSender, message.toString());
} catch (IOException e) {
EtzTechUtil.sms(commandSender, ChatColor.RED + "Minecraft wiki API returned nothing.");
} catch (IndexOutOfBoundsException e) {
EtzTechUtil.sms(commandSender, ChatColor.RED + String.format("Nothing was found on the wiki using: %s", args[0]));
}
return true;
}
}

View File

@ -6,8 +6,6 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.advancement.Advancement;
import org.bukkit.Namespacedkey;
import xyz.etztech.qol.QoL;
import java.util.Arrays;
@ -50,16 +48,6 @@ public class AsyncPlayerChatListener implements Listener {
String chat = event.getMessage();
boolean escape = false;
//Checking if player has been awarded the chat advancement, if not, message is searched for triggers
Advancement adv = Bukkit.getAdvancement(new Namespacedkey("canopy", "chat_advancement"));
if (!player.getAdvancementProgress(adv).isDone()) {
List<String> advancementTriggerList = plugin.getConfig().getStringList("chat-advancement-triggers");
if (advancementTriggerList.stream().anyMatch(t -> chat.toLowerCase().contains(t.toLowerCase()))) {
player.getAdvancementProgress(adv).awardCriteria("win");
}
}
// Escape
if (chat.startsWith("\\")) {
escape = true;

View File

@ -1,9 +1,15 @@
package xyz.etztech.qol.listeners;
import github.scarsz.discordsrv.DiscordSRV;
import github.scarsz.discordsrv.api.events.DiscordGuildMessagePreBroadcastEvent;
import github.scarsz.discordsrv.api.events.GameChatMessagePreProcessEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import xyz.etztech.qol.EtzTechUtil;
import xyz.etztech.qol.Lang;
import xyz.etztech.qol.QoL;
import github.scarsz.discordsrv.api.Subscribe;
import xyz.etztech.qol.commands.DiscordIgnoreCommand;
public class DiscordSRVListener {
private final QoL plugin;
@ -20,4 +26,18 @@ public class DiscordSRVListener {
}
}
@Subscribe
public void discordGuildMessagePreBroadcastEvent(DiscordGuildMessagePreBroadcastEvent event) {
event.getRecipients().removeIf(recipient -> {
if (recipient instanceof Player) {
Player player = (Player) recipient;
return player.hasMetadata(DiscordIgnoreCommand.DISCORD_IGNORE_METADATA);
}
else {
return false;
}
});
}
}

View File

@ -0,0 +1,26 @@
package xyz.etztech.qol.listeners;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import xyz.etztech.qol.QoL;
public class EntityChangeBlockListener implements Listener {
QoL plugin;
public EntityChangeBlockListener(QoL plugin) {
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onEntityChangeBlock(EntityChangeBlockEvent e) {
if (e.getEntity().getType() == EntityType.ENDERMAN) {
if(plugin.getConfig().getBoolean("disable-mob-grief.enderman", false)){
e.setCancelled(true);
}
}
}
}

View File

@ -0,0 +1,68 @@
package xyz.etztech.qol.listeners;
import com.nisovin.shopkeepers.api.ShopkeepersPlugin;
import com.nisovin.shopkeepers.api.shopkeeper.ShopkeeperRegistry;
import com.nisovin.shopkeepers.api.shopkeeper.admin.regular.RegularAdminShopkeeper;
import com.nisovin.shopkeepers.api.shopkeeper.offers.TradeOffer;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import xyz.etztech.qol.QoL;
import java.util.ArrayList;
import java.util.List;
public class HeadShopListener implements Listener{
private final QoL plugin;
private final ShopkeepersPlugin shopkeepersAPI;
public HeadShopListener(QoL plugin) {
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.shopkeepersAPI = ShopkeepersPlugin.getInstance();
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
final Player player = event.getPlayer();
if (shopkeepersAPI != null && player.hasPermission("qol.head_shop")) {
int shopKeeperID = plugin.getConfig().getInt("head_shop.id", -1);
if (shopKeeperID != -1) {
ShopkeeperRegistry shopkeeperRegistry = shopkeepersAPI.getShopkeeperRegistry();
RegularAdminShopkeeper donorHeadShop = (RegularAdminShopkeeper) shopkeeperRegistry.getShopkeeperById(shopKeeperID);
if (donorHeadShop != null) {
// Remove the head if it already exists. This is done to refresh the skin of the head.
List<? extends TradeOffer> tradeOffers = new ArrayList<>(donorHeadShop.getOffers());
tradeOffers.removeIf(tradeOffer -> {
SkullMeta itemOfferMeta = (SkullMeta)tradeOffer.getResultItem().getItemMeta();
return itemOfferMeta.getOwningPlayer().getUniqueId() == player.getUniqueId();
});
donorHeadShop.setOffers(tradeOffers);
// Add the head to the shop
int diamondPrice = plugin.getConfig().getInt("head_shop.price", 2);
ItemStack playerHead = new ItemStack(Material.PLAYER_HEAD);
SkullMeta skullMeta = (SkullMeta) playerHead.getItemMeta();
skullMeta.setOwningPlayer(player);
skullMeta.setDisplayName(player.getDisplayName());
playerHead.setItemMeta(skullMeta);
TradeOffer donorHeadTrade = TradeOffer.create(playerHead, new ItemStack(Material.DIAMOND, diamondPrice), null);
donorHeadShop.addOffer(donorHeadTrade);
}
}
}
}
}

View File

@ -2,13 +2,10 @@ package xyz.etztech.qol.listeners;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.dynmap.markers.Marker;
import xyz.etztech.qol.QoL;
import xyz.etztech.qol.commands.CheckupCommand;

View File

@ -0,0 +1,63 @@
package xyz.etztech.qol.other;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import org.bukkit.configuration.ConfigurationSection;
import net.md_5.bungee.api.ChatColor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Reminder {
private final int frequency;
private final List<ReminderList> reminderLists;
public Reminder(int frequency, List<ReminderList> reminderLists) {
this.frequency = frequency;
this.reminderLists = reminderLists;
Collections.sort(reminderLists);
}
public static Reminder fromConfig(ConfigurationSection config) {
int frequency = config.getInt("frequency");
List<ReminderList> reminderLists = new ArrayList();
ConfigurationSection reminderGroups = config.getConfigurationSection("reminder_groups");
for (String groupName: reminderGroups.getKeys(false)) {
ConfigurationSection group = reminderGroups.getConfigurationSection(groupName);
int period = group.getInt("period", 0);
ChatColor color = ChatColor.of(group.getString("color", "#3273DC"));
List<String> reminders = group.getStringList("reminders");
reminderLists.add(new ReminderList(reminders, period, color));
}
return new Reminder(frequency, reminderLists);
}
public BaseComponent[] nextReminder() {
BaseComponent[] msg = null;
boolean reminderFound = false;
for (ReminderList reminderList: reminderLists) {
if (!reminderFound && reminderList.isReady()) {
msg = new ComponentBuilder().
color(reminderList.getColor())
.append(reminderList.nextReminder())
.create();
reminderFound = true;
}
reminderList.incCount();
}
return msg;
}
public int getFrequency() {
return frequency;
}
}

View File

@ -0,0 +1,46 @@
package xyz.etztech.qol.other;
import net.md_5.bungee.api.ChatColor;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class ReminderList implements Comparable<ReminderList>{
private final List<String> reminders;
private final int period;
private final ChatColor color;
private int ndx;
private int count;
public ReminderList(List<String> reminders, int period, ChatColor color) {
this.reminders = reminders;
this.period = period;
this.color = color;
this.ndx = 0;
this.count = 0;
}
public void incCount() {
count = (count + 1) % (period + 1);
}
public boolean isReady() {
return count == period;
}
public String nextReminder() {
String nextReminder = reminders.get(ndx);
ndx = (ndx + 1) % reminders.size();
return nextReminder;
}
@Override
public int compareTo(@NotNull ReminderList o) {
return Integer.compare(o.period, this.period);
}
public ChatColor getColor() {
return color;
}
}

View File

@ -1,9 +1,11 @@
package xyz.etztech.qol.other;
import net.ess3.api.IEssentials;
import me.lucko.spark.api.statistic.StatisticWindow;
import me.lucko.spark.api.statistic.types.DoubleStatistic;
import org.apache.commons.lang.StringUtils;
import xyz.etztech.core.web.Http;
import xyz.etztech.qol.QoL;
import me.lucko.spark.api.Spark;
import java.util.HashMap;
import java.util.Map;
@ -18,13 +20,13 @@ public class TPSRunnable implements Runnable {
@Override
public void run() {
IEssentials essentials = plugin.getEssentials();
if (essentials != null) {
double tps = essentials.getTimer().getAverageTPS();
Spark spark = plugin.getSpark();
if (spark != null) {
DoubleStatistic<StatisticWindow.TicksPerSecond> tps = spark.tps();
int threshold = plugin.getConfig().getInt("tps.threshold", 0);
String webhook = plugin.getConfig().getString("tps.webhook", "");
String message = "@here TPS has fallen below " + threshold + "!";
if (tps < threshold) {
if (tps.poll(StatisticWindow.TicksPerSecond.SECONDS_10) < threshold) {
plugin.log(message);
if (StringUtils.isNotEmpty(webhook)) {
Map<String, String> data = new HashMap<>();

View File

@ -60,10 +60,19 @@ schedule:
# To disable, set minutes to 0
reminders:
frequency: 5 # In minutes
color: '&a'
messages:
- 'Check out the Discord!'
frequency: 1 # In minutes
reminder_groups:
standard:
color: '#3273DC'
reminders:
- '1st Standard Reminder'
- '2nd Standard Reminder'
event:
color: '#3273DC'
period: 2
reminders:
- '1st Event Reminder'
- '2nd Event Reminder'
# A list of links for link command aliases, separated by a comma between name and URL
links:
@ -84,6 +93,9 @@ disable-fire:
ender_crystal: false
explosion: false
disable-mob-grief:
enderman: false
# A list of commands to confirm before using if the user isn't in spectator mode
spec-confirm:
- "tp"
@ -105,6 +117,10 @@ dynmap:
map: "surface"
zoom: 5
# A list of words/phrases which will award the chant advancement to the message author
chat-advancement-triggers:
- chat_advancment_test
# Shopkeepers Player Head Shop
head_shop:
# Shopkeeper Shop ID, set to -1 to disable
id: -1
# Diamond price of a head in the shop, default is 2 diamonds
price: 2

View File

@ -4,13 +4,14 @@ description: ${description}
author: ${author}
website: ${url}
main: ${mainClass}
softdepend: [Essentials, dynmap, DiscordSRV]
softdepend: [spark, dynmap, DiscordSRV, Shopkeepers]
api-version: 1.13
commands:
qol:
description: Base command
colors:
description: See all color/formatting codes
aliases: [color, c]
aliases: [color, c, colour, colours]
list:
description: See a list of players
aliases: [players, playerlist]
@ -46,6 +47,13 @@ commands:
marker:
description: Dynmap marker command
aliases: [mark]
wiki:
description: Search the Minecraft wiki
moon:
description: Get information about the current moon phase
discordignore:
description: Mute chat messages coming from Discord
aliases: [dignore]
permissions:
qol.admin:
description: Ability to reload the plugin
@ -116,3 +124,15 @@ permissions:
default: op
children:
qol.marker.limit: true
qol.wiki:
description: Ability to use the wiki command
default: op
qol.moon:
description: Ability to use the moon command
default: op
qol.discordignore:
description: Ability to use the use the discordignore command
default: op
qol.head_shop:
description: Controls if a player's head should be added to the head shop
default: op