Move Plex to API-driven plugin and fix NoClassDefFoundError on startup

This commit is contained in:
Focusvity
2022-04-24 14:16:14 +10:00
parent edeecb51f4
commit f9a577035b
346 changed files with 736 additions and 118 deletions

View File

@ -0,0 +1,31 @@
package dev.plex.services;
import dev.plex.PlexBase;
import lombok.Getter;
import lombok.Setter;
@Getter
public abstract class AbstractService implements IService, PlexBase
{
private boolean asynchronous;
private boolean repeating;
@Setter
private int taskId;
public AbstractService(boolean repeating, boolean async)
{
this.repeating = repeating;
this.asynchronous = async;
}
public void onStart()
{
}
public void onEnd()
{
}
}

View File

@ -0,0 +1,8 @@
package dev.plex.services;
public interface IService
{
void run();
int repeatInSeconds();
}

View File

@ -0,0 +1,104 @@
package dev.plex.services;
import com.google.common.collect.Lists;
import dev.plex.Plex;
import dev.plex.services.impl.AutoWipeService;
import dev.plex.services.impl.BanService;
import dev.plex.services.impl.CommandBlockerService;
import dev.plex.services.impl.GameRuleService;
import dev.plex.services.impl.TimingService;
import dev.plex.services.impl.UpdateCheckerService;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
public class ServiceManager
{
private final List<AbstractService> services = Lists.newArrayList();
public ServiceManager()
{
registerService(new AutoWipeService());
registerService(new BanService());
registerService(new CommandBlockerService());
registerService(new GameRuleService());
registerService(new TimingService());
registerService(new UpdateCheckerService());
}
public void startServices()
{
for (AbstractService service : services)
{
startService(service);
}
}
public void endServices()
{
services.forEach(this::endService);
}
public AbstractService getService(Class<? extends AbstractService> clazz)
{
return services.stream().filter(service -> service.getClass().isAssignableFrom(clazz)).findFirst().orElse(null);
}
public void startService(AbstractService service)
{
if (!service.isRepeating())
{
int time = service.repeatInSeconds();
BukkitTask task;
if (time == 0)
{
task = Bukkit.getScheduler().runTask(Plex.get(), service::run);
}
else
{
task = Bukkit.getScheduler().runTaskLater(Plex.get(), service::run, time);
}
service.setTaskId(task.getTaskId());
}
else if (service.isRepeating() && service.isAsynchronous())
{
BukkitTask task = Bukkit.getScheduler().runTaskTimerAsynchronously(Plex.get(), service::run, 0, 20L * service.repeatInSeconds());
service.setTaskId(task.getTaskId());
}
else if (service.isRepeating() && !service.isAsynchronous())
{
BukkitTask task = Bukkit.getScheduler().runTaskTimer(Plex.get(), service::run, 0, 20L * service.repeatInSeconds());
service.setTaskId(task.getTaskId());
}
if (!services.contains(service))
{
services.add(service);
}
service.onStart();
}
public void endService(AbstractService service, boolean remove)
{
Bukkit.getScheduler().cancelTask(service.getTaskId());
service.onEnd();
if (remove)
{
services.remove(service);
}
}
public void endService(AbstractService service)
{
endService(service, false);
}
private void registerService(AbstractService service)
{
services.add(service);
}
public int serviceCount()
{
return services.size();
}
}

View File

@ -0,0 +1,42 @@
package dev.plex.services.impl;
import dev.plex.Plex;
import dev.plex.services.AbstractService;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
public class AutoWipeService extends AbstractService
{
public AutoWipeService()
{
super(true, false);
}
@Override
public void run()
{
if (Plex.get().config.getBoolean("autowipe.enabled"))
{
List<String> entities = plugin.config.getStringList("autowipe.entities");
for (World world : Bukkit.getWorlds())
{
for (Entity entity : world.getEntities())
{
if (entities.stream().anyMatch(entityName -> entityName.equalsIgnoreCase(entity.getType().name())))
{
entity.remove();
}
}
}
}
}
@Override
public int repeatInSeconds()
{
return Math.max(1, plugin.config.getInt("autowipe.interval"));
}
}

View File

@ -0,0 +1,40 @@
package dev.plex.services.impl;
import dev.plex.Plex;
import dev.plex.services.AbstractService;
import dev.plex.util.TimeUtils;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
public class BanService extends AbstractService
{
public BanService()
{
super(true, true);
}
@Override
public void run()
{
Plex.get().getPunishmentManager().getActiveBans().whenComplete((punishments, throwable) ->
{
punishments.forEach(punishment ->
{
if (ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE)).isAfter(punishment.getEndDate()))
{
Plex.get().getPunishmentManager().unban(punishment);
Bukkit.broadcast(Component.text("Plex - Unbanned " + Bukkit.getOfflinePlayer(punishment.getPunished()).getName()));
}
});
});
}
@Override
public int repeatInSeconds()
{
// Every 30 seconds
return 30;
}
}

View File

@ -0,0 +1,74 @@
package dev.plex.services.impl;
import com.google.common.collect.Lists;
import dev.plex.command.blocking.BlockedCommand;
import dev.plex.services.AbstractService;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils;
import java.util.List;
import java.util.Locale;
import lombok.Getter;
import org.bukkit.command.Command;
public class CommandBlockerService extends AbstractService
{
@Getter
private static final List<BlockedCommand> BLOCKED_COMMANDS = Lists.newArrayList();
public CommandBlockerService()
{
super(false, false);
}
@Override
public void run()
{
BLOCKED_COMMANDS.clear();
plugin.commands.getStringList("commands").forEach(s ->
{
BlockedCommand command = new BlockedCommand();
int lastDelim = s.lastIndexOf(':');
String cmdWithoutMsg = s.substring(0, lastDelim);
String[] args = cmdWithoutMsg.split(":", 3); // Delimiter code by ayunami
if (s.toLowerCase(Locale.ROOT).startsWith("r"))
{
command.setRequiredLevel(args[1]);
command.setRegex(args[2]);
command.setMessage(s.substring(lastDelim + 1).equalsIgnoreCase("_") ? PlexUtils.messageComponent("commandBlocked") : PlexUtils.mmDeserialize(s.substring(lastDelim + 1)));
/*PlexLog.debug("=Found regex blocked=");
PlexLog.debug(" Regex: " + command.getRegex());
PlexLog.debug(" Message: " + command.getMessage());
PlexLog.debug("====================");*/
}
else if (s.toLowerCase(Locale.ROOT).startsWith("m"))
{
command.setRequiredLevel(args[1]);
command.setCommand(args[2]);
command.setMessage(s.substring(lastDelim + 1).equalsIgnoreCase("_") ? PlexUtils.messageComponent("commandBlocked") : PlexUtils.mmDeserialize(s.substring(lastDelim + 1)));
Command cmd = plugin.getServer().getCommandMap().getCommand(command.getCommand().split(" ")[0]);
if (cmd == null)
{
PlexLog.error("Command '{0}' does not belong to any plugin!", command.getCommand().split(" ")[0]);
return;
}
command.setCommandAliases(cmd.getAliases());
command.getCommandAliases().add(command.getCommand().split(" ")[0]);
/*PlexLog.debug("=Found command blocked=");
PlexLog.debug(" Required Level: " + command.getRequiredLevel());
PlexLog.debug(" Command: " + command.getCommand());
PlexLog.debug(" Message: " + command.getMessage());
PlexLog.debug(" Aliases: " + Arrays.toString(command.getCommandAliases().toArray(new String[0])));
PlexLog.debug("====================");*/
}
BLOCKED_COMMANDS.add(command);
});
PlexLog.log("Command Blocker has loaded {0} entries!", BLOCKED_COMMANDS.size());
}
@Override
public int repeatInSeconds()
{
return 0;
}
}

View File

@ -0,0 +1,41 @@
package dev.plex.services.impl;
import dev.plex.services.AbstractService;
import dev.plex.util.GameRuleUtil;
import dev.plex.util.PlexLog;
import java.util.Locale;
import org.bukkit.Bukkit;
import org.bukkit.World;
public class GameRuleService extends AbstractService
{
public GameRuleService()
{
super(false, true);
}
@Override
public void run()
{
for (World world : Bukkit.getWorlds())
{
GameRuleUtil.commitGlobalGameRules(world);
PlexLog.log("Set global gamerules for world: " + world.getName());
}
for (String world : plugin.config.getConfigurationSection("worlds").getKeys(false))
{
World bukkitWorld = Bukkit.getWorld(world);
if (bukkitWorld != null)
{
GameRuleUtil.commitSpecificGameRules(bukkitWorld);
PlexLog.log("Set specific gamerules for world: " + world.toLowerCase(Locale.ROOT));
}
}
}
@Override
public int repeatInSeconds()
{
return 0;
}
}

View File

@ -0,0 +1,67 @@
package dev.plex.services.impl;
import dev.plex.cache.DataUtils;
import dev.plex.player.PlexPlayer;
import dev.plex.punishment.Punishment;
import dev.plex.punishment.PunishmentType;
import dev.plex.services.AbstractService;
import dev.plex.util.PlexLog;
import dev.plex.util.TimeUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class TimingService extends AbstractService
{
public static final Map<UUID, Long> spamCooldown = new HashMap<>();
public static final Map<UUID, Long> nukerCooldown = new HashMap<>();
public static final Map<UUID, Long> strikes = new HashMap<>();
public TimingService()
{
super(true, true);
}
@Override
public void run()
{
spamCooldown.clear();
nukerCooldown.clear();
for (Map.Entry<UUID, Long> map : strikes.entrySet())
{
PlexLog.debug(map.getKey() + ": " + map.getValue());
// Tempban for 5 minutes and reset strikes. This will probably stop people from actually trying to use a Nuker to grief.
if (map.getValue() >= 2L)
{
issueBan(map);
strikes.remove(map.getKey());
}
}
}
private void issueBan(Map.Entry<UUID, Long> map)
{
Punishment punishment = new Punishment(map.getKey(), null);
Player player = Bukkit.getPlayer(map.getKey());
PlexPlayer plexPlayer = DataUtils.getPlayer(map.getKey());
punishment.setType(PunishmentType.TEMPBAN);
punishment.setReason("You are temporarily banned for five minutes for using a Nuker.");
if (player != null)
{
punishment.setPunishedUsername(player.getName());
punishment.setIp(player.getAddress().getAddress().getHostAddress());
}
punishment.setEndDate(TimeUtils.createDate("5m"));
punishment.setCustomTime(false);
punishment.setActive(!plexPlayer.isAdminActive());
plugin.getPunishmentManager().punish(plexPlayer, punishment);
}
@Override
public int repeatInSeconds()
{
return 5;
}
}

View File

@ -0,0 +1,33 @@
package dev.plex.services.impl;
import dev.plex.services.AbstractService;
import org.bukkit.Bukkit;
public class UpdateCheckerService extends AbstractService
{
private boolean newVersion = false;
public UpdateCheckerService()
{
super(true, true);
}
@Override
public void run()
{
if (!newVersion)
{
if (plugin.getUpdateChecker().getUpdateStatusMessage(Bukkit.getConsoleSender(), false, 1))
{
newVersion = true;
}
}
}
@Override
public int repeatInSeconds()
{
// Every 30 minutes
return 1800;
}
}