Merge branch 'RELEASE-2023.03' of https://github.com/AtlasMediaGroup/TotalFreedomMod into RELEASE-2023.03

This commit is contained in:
Video 2023-03-27 23:27:22 -06:00
commit f91c21cc81
7 changed files with 193 additions and 136 deletions

View File

@ -0,0 +1,7 @@
package me.totalfreedom.totalfreedommod.api;
@FunctionalInterface
public interface Interpolator
{
double[] interpolate(double from, double to, int max);
}

View File

@ -47,34 +47,34 @@ public class Command_notes extends FreedomCommand
switch (args[1])
{
case "list":
case "list" ->
{
msgNew("<green>Player notes for <player>:", Placeholder.unparsed("player", playerData.getName()));
int id = 1;
for (String note : playerData.getNotes())
{
String a = note.replace("\\u002C", ",");
msgNew("<num>. <note>",
Placeholder.unparsed("num", String.valueOf(id)),
Placeholder.unparsed("note", note));
Placeholder.unparsed("note", a));
id++;
}
return true;
}
case "add":
case "add" ->
{
if (args.length < 3)
{
return false;
}
String note = sender.getName() + ": " + StringUtils.join(ArrayUtils.subarray(args, 2, args.length), " ");
String note = sender.getName() + ": " + StringUtils.join(ArrayUtils.subarray(args, 2, args.length), " ")
.replace(",", "\\u002C");
playerData.addNote(note);
plugin.pl.save(playerData);
msgNew("<green>Note added.");
return true;
}
case "remove":
case "remove" ->
{
if (args.length < 3)
{
@ -85,8 +85,7 @@ public class Command_notes extends FreedomCommand
try
{
id = Integer.parseInt(args[2]);
}
catch (NumberFormatException e)
} catch (NumberFormatException e)
{
msgNew("<red>Invalid number: <num>", Placeholder.unparsed("num", args[2]));
return true;
@ -98,16 +97,14 @@ public class Command_notes extends FreedomCommand
{
plugin.pl.save(playerData);
msgNew("<green>Note removed.");
}
else
} else
{
msgNew("<red>No note with the ID of <id> exists.", Placeholder.unparsed("id", args[2]));
}
return true;
}
case "clear":
case "clear" ->
{
int count = playerData.getNotes().size();
playerData.clearNotes();
@ -115,8 +112,7 @@ public class Command_notes extends FreedomCommand
msgNew("<green>Cleared <count> notes.", Placeholder.unparsed("count", String.valueOf(count)));
return true;
}
default:
default ->
{
return false;
}

View File

@ -1,28 +1,22 @@
package me.totalfreedom.totalfreedommod.fun;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.SplittableRandom;
import java.util.UUID;
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.api.ShopItem;
import me.totalfreedom.totalfreedommod.util.Groups;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import me.totalfreedom.totalfreedommod.util.ParticleDisplay;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.SplittableRandom;
import java.util.UUID;
public class Trailer extends FreedomService
{
private final SplittableRandom random = new SplittableRandom();
private final Set<UUID> trailPlayers = new HashSet<>(); // player UUID
private final Map<UUID, ParticleDisplay> trailPlayers = new HashMap<>(); // player UUID and relative particle instance.
@Override
public void onStart()
@ -46,42 +40,15 @@ public class Trailer extends FreedomService
* - The player doesn't have permission to modify blocks in their current world
*/
if (trailPlayers.isEmpty()
|| !trailPlayers.contains(event.getPlayer().getUniqueId())
|| !plugin.pl.getData(event.getPlayer()).hasItem(ShopItem.RAINBOW_TRAIL)
|| plugin.wr.doRestrict(event.getPlayer())
|| !plugin.wgb.canEditCurrentWorld(event.getPlayer()))
|| !trailPlayers.containsKey(event.getPlayer().getUniqueId())
|| !plugin.pl.getData(event.getPlayer()).hasItem(ShopItem.RAINBOW_TRAIL))
{
return;
}
Block fromBlock = event.getFrom().getBlock();
if (!fromBlock.isEmpty())
{
return;
}
Block toBlock = Objects.requireNonNull(event.getTo()).getBlock();
if (fromBlock.equals(toBlock))
{
return;
}
// TODO: Make this particles instead of blocks!
fromBlock.setType(Groups.WOOL_COLORS.get(random.nextInt(Groups.WOOL_COLORS.size())));
BlockData data = fromBlock.getBlockData();
Material material = Material.getMaterial(String.valueOf(fromBlock.getType()));
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
final Location trail_pos;
trail_pos = new Location(event.getPlayer().getWorld(), fromBlock.getX() + x, fromBlock.getY(), fromBlock.getZ() + z);
if (trailPlayers.contains(event.getPlayer().getUniqueId()) && plugin.cpb.isEnabled())
{
plugin.cpb.getCoreProtectAPI().logPlacement(event.getPlayer().getName(), trail_pos, material, data);
}
}
}
final Player player = event.getPlayer();
final ParticleDisplay particleDisplay = trailPlayers.get(player.getUniqueId());
particleDisplay.spawnNext(player);
}
public void remove(Player player)
@ -91,11 +58,13 @@ public class Trailer extends FreedomService
public void add(Player player)
{
trailPlayers.add(player.getUniqueId());
if (trailPlayers.containsKey(player.getUniqueId())) return;
trailPlayers.put(player.getUniqueId(), new ParticleDisplay());
}
public boolean contains(Player player)
{
return trailPlayers.contains(player.getUniqueId());
return trailPlayers.containsKey(player.getUniqueId());
}
}

View File

@ -1,19 +1,22 @@
package me.totalfreedom.totalfreedommod.util;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.entity.EntityType;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
public class Groups
{
public static final List<Material> WOOL_COLORS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_WOOL")).toList();
public static final List<Material> SHULKER_BOXES = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("SHULKER_BOX")).toList();
public static final List<EntityType> MOB_TYPES = Arrays.stream(EntityType.values()).filter(EntityType::isAlive).filter(EntityType::isSpawnable).toList();
public static final List<Material> SPAWN_EGGS = Arrays.stream(Material.values()).filter((mat) -> mat.name().endsWith("_SPAWN_EGG")).toList();
public static final List<Material> BANNERS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_BANNER")).toList();
public static final List<Biome> EXPLOSIVE_BED_BIOMES = Arrays.asList(
public static final Set<Material> WOOL_COLORS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_WOOL")).collect(Collectors.toSet());
public static final Set<Material> SHULKER_BOXES = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("SHULKER_BOX")).collect(Collectors.toSet());
public static final Set<EntityType> MOB_TYPES = Arrays.stream(EntityType.values()).filter(EntityType::isAlive).filter(EntityType::isSpawnable).collect(Collectors.toSet());
public static final Set<Material> SPAWN_EGGS = Arrays.stream(Material.values()).filter((mat) -> mat.name().endsWith("_SPAWN_EGG")).collect(Collectors.toSet());
public static final Set<Material> BANNERS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_BANNER")).collect(Collectors.toSet());
public static final Set<Biome> EXPLOSIVE_BED_BIOMES = new HashSet<>(Arrays.asList(
Biome.NETHER_WASTES,
Biome.CRIMSON_FOREST,
Biome.SOUL_SAND_VALLEY,
@ -23,5 +26,5 @@ public class Groups
Biome.END_HIGHLANDS,
Biome.END_MIDLANDS,
Biome.THE_END,
Biome.SMALL_END_ISLANDS);
Biome.SMALL_END_ISLANDS));
}

View File

@ -0,0 +1,58 @@
package me.totalfreedom.totalfreedommod.util;
import me.totalfreedom.totalfreedommod.api.Interpolator;
import org.bukkit.Color;
import java.util.LinkedHashSet;
public class Interpolation
{
public LinkedHashSet<Color> rainbow(int length)
{
LinkedHashSet<Color> base = new LinkedHashSet<>();
LinkedHashSet<Color> redToOrange = hsvGradient(length, Color.RED, Color.ORANGE, this::linear);
LinkedHashSet<Color> orangeToYellow = hsvGradient(length, Color.ORANGE, Color.YELLOW, this::linear);
LinkedHashSet<Color> yellowToGreen = hsvGradient(length, Color.YELLOW, Color.GREEN, this::linear);
LinkedHashSet<Color> greenToBlue = hsvGradient(length, Color.GREEN, Color.BLUE, this::linear);
LinkedHashSet<Color> blueToPurple = hsvGradient(length, Color.BLUE, Color.PURPLE, this::linear);
LinkedHashSet<Color> purpleToRed = hsvGradient(length, Color.PURPLE, Color.RED, this::linear);
base.addAll(redToOrange);
base.addAll(orangeToYellow);
base.addAll(yellowToGreen);
base.addAll(greenToBlue);
base.addAll(blueToPurple);
base.addAll(purpleToRed);
return base;
}
private double[] linear(double from, double to, int max)
{
final double[] res = new double[max];
for (int i = 0; i < max; i++)
{
res[i] = from + i * ((to - from) / (max - 1));
}
return res;
}
private LinkedHashSet<Color> hsvGradient(int length, Color from, Color to, Interpolator interpolator)
{
// returns a float-array where hsv[0] = hue, hsv[1] = saturation, hsv[2] = value/brightness
final float[] hsvFrom = java.awt.Color.RGBtoHSB(from.getRed(), from.getGreen(), from.getBlue(), null);
final float[] hsvTo = java.awt.Color.RGBtoHSB(to.getRed(), to.getGreen(), to.getBlue(), null);
final double[] h = interpolator.interpolate(hsvFrom[0], hsvTo[0], length);
final double[] s = interpolator.interpolate(hsvFrom[1], hsvTo[1], length);
final double[] v = interpolator.interpolate(hsvFrom[2], hsvTo[2], length);
final LinkedHashSet<Color> gradient = new LinkedHashSet<>();
for (int i = 0; i < length; i++)
{
final int rgb = java.awt.Color.HSBtoRGB((float) h[i], (float) s[i], (float) v[i]);
final Color color = Color.fromRGB(rgb);
gradient.add(color);
}
return gradient;
}
}

View File

@ -0,0 +1,57 @@
package me.totalfreedom.totalfreedommod.util;
import com.destroystokyo.paper.ParticleBuilder;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
public class ParticleDisplay
{
private final Interpolation interpolation;
private Iterator<Color> colorIterator;
public ParticleDisplay()
{
this.interpolation = new Interpolation();
this.colorIterator = interpolation.rainbow(43).iterator();
}
public void spawnNext(Player player)
{
Location location = getBehind(player);
Color color = getIterator().next();
Particle.DustOptions options = new Particle.DustOptions(color, 3);
ParticleBuilder builder = new ParticleBuilder(Particle.REDSTONE);
builder.data(options)
.receivers(30, 15, true)
.offset(0.5, 0.5, 0.5)
.location(location)
.spawn();
}
private Location getBehind(Player player)
{
@NotNull Vector inverse = player.getLocation()
.clone()
.getDirection()
.normalize()
.multiply(-1);
return player.getLocation().add(inverse);
}
private Iterator<Color> getIterator()
{
if (!this.colorIterator.hasNext())
{
this.colorIterator = interpolation.rainbow(43).iterator();
}
return this.colorIterator;
}
}

View File

@ -1,18 +1,8 @@
package me.totalfreedom.totalfreedommod.world;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import me.totalfreedom.totalfreedommod.FreedomService;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -23,8 +13,10 @@ import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class WorldRestrictions extends FreedomService
{
import java.util.Arrays;
import java.util.List;
public class WorldRestrictions extends FreedomService {
private final List<String> BLOCKED_WORLDEDIT_COMMANDS = Arrays.asList(
"green", "fixlava", "fixwater", "br", "brush", "tool", "mat", "range", "cs", "up", "fill", "setblock", "tree", "replacenear", "bigtree");
@ -33,118 +25,93 @@ public class WorldRestrictions extends FreedomService
"bigtree", "ebigtree", "largetree", "elargetree");
@Override
public void onStart()
{
public void onStart() {
}
@Override
public void onStop()
{
public void onStop() {
}
public boolean doRestrict(Player player)
{
if (!plugin.pl.getData(player).isMasterBuilder() && plugin.pl.canManageMasterBuilders(player.getName()))
{
if (player.getWorld().equals(plugin.wm.masterBuilderWorld.getWorld()))
{
public boolean doRestrict(Player player) {
if (!plugin.pl.getData(player).isMasterBuilder()
&& plugin.pl.canManageMasterBuilders(player.getName())
&& (player.getWorld().equals(plugin.wm.masterBuilderWorld.getWorld()))) {
return true;
}
}
return !plugin.al.isAdmin(player) && player.getWorld().equals(plugin.wm.adminworld.getWorld());
return !plugin.al.isAdmin(player)
&& player.getWorld().equals(plugin.wm.adminworld.getWorld());
}
@EventHandler(priority = EventPriority.NORMAL)
public void onBlockPlace(BlockPlaceEvent event)
{
public void onBlockPlace(BlockPlaceEvent event) {
final Player player = event.getPlayer();
if (doRestrict(player))
{
if (doRestrict(player)) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event)
{
public void onBlockBreak(BlockBreakEvent event) {
final Player player = event.getPlayer();
if (doRestrict(player))
{
if (doRestrict(player)) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerInteract(PlayerInteractEvent event)
{
public void onPlayerInteract(PlayerInteractEvent event) {
final Player player = event.getPlayer();
if (doRestrict(player))
{
if (doRestrict(player)) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onArmorStandManipulate(PlayerArmorStandManipulateEvent event)
{
public void onArmorStandManipulate(PlayerArmorStandManipulateEvent event) {
final Player player = event.getPlayer();
if (doRestrict(player))
{
if (doRestrict(player)) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onEntityDamageByEntity(EntityDamageByEntityEvent event)
{
if (event.getDamager() instanceof Player)
{
Player player = (Player)event.getDamager();
if (doRestrict(player))
{
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Player player && (doRestrict(player))) {
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onCommandPreprocess(PlayerCommandPreprocessEvent event)
{
public void onCommandPreprocess(PlayerCommandPreprocessEvent event) {
final Player player = event.getPlayer();
String command = event.getMessage().split("\\s+")[0].substring(1).toLowerCase();
if (doRestrict(player))
{
if (doRestrict(player)) {
/* This is a very poor way of blocking WorldEdit commands, all the methods I know of
for obtaining a list of a plugin's commands are returning null for world edit. */
String allowed = player.getWorld().equals(plugin.wm.adminworld.getWorld()) ? "Admins" : "Master Builders";
if (command.startsWith("/") || BLOCKED_WORLDEDIT_COMMANDS.contains(command))
{
if (command.startsWith("/") || BLOCKED_WORLDEDIT_COMMANDS.contains(command)) {
player.sendMessage(ChatColor.RED + "Only " + allowed + " are allowed to use WorldEdit here.");
event.setCancelled(true);
}
if (command.equalsIgnoreCase("coreprotect") || command.equalsIgnoreCase("core") || command.equalsIgnoreCase("co"))
{
if (command.equalsIgnoreCase("coreprotect") || command.equalsIgnoreCase("core") || command.equalsIgnoreCase("co")) {
player.sendMessage(ChatColor.RED + "Only " + allowed + " are allowed to use CoreProtect here.");
event.setCancelled(true);
}
}
if (player.getWorld().equals(Bukkit.getWorld("plotworld")))
{
if (BLOCKED_ESSENTIALS_COMMANDS.contains(command))
{
if (player.getWorld().equals(Bukkit.getWorld("plotworld"))
&& (BLOCKED_ESSENTIALS_COMMANDS.contains(command))) {
player.sendMessage(ChatColor.RED + "Sorry, this command is restricted in the plotworld");
event.setCancelled(true);
}
}
}
}