Compare commits

...

9 Commits
3.1.0 ... 3.2.0

Author SHA1 Message Date
Auxilor
f0cd9ae16d Updated to 3.2.0 2021-01-20 20:13:09 +00:00
Auxilor
b220428b8c Added StaticBaseConfig, a non-updating config implementation 2021-01-20 20:12:53 +00:00
Auxilor
8386aacfd8 Updated to 3.1.3 2021-01-20 19:06:07 +00:00
Auxilor
3c54e24102 Reworked gradients 2021-01-20 19:05:55 +00:00
Auxilor
3dc0693b8c Reworked gradients 2021-01-20 18:47:56 +00:00
Auxilor
f087113ddf Updated to 3.1.2 2021-01-20 17:38:51 +00:00
Auxilor
d5d1f5d8cc Added fix for PacketPlayOutRecipeUpdate being too large 2021-01-20 17:35:29 +00:00
Auxilor
0d5bf901e2 Updated to 3.1.1 2021-01-20 11:27:57 +00:00
Auxilor
ae0445f47b Fixed recipe listener registration 2021-01-20 11:27:46 +00:00
12 changed files with 500 additions and 95 deletions

View File

@@ -0,0 +1,46 @@
package com.willfp.eco.proxy.v1_15_R1;
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
import net.minecraft.server.v1_15_R1.IRecipe;
import net.minecraft.server.v1_15_R1.PacketPlayOutRecipeUpdate;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@SuppressWarnings("unchecked")
public final class PacketPlayOutRecipeUpdateFix implements PacketPlayOutRecipeUpdateFixProxy {
@Override
public List<Object> splitPackets(@NotNull final Object object,
@NotNull final Player player) {
if (!(object instanceof PacketPlayOutRecipeUpdate)) {
throw new IllegalArgumentException("Parameter not packet!");
}
PacketPlayOutRecipeUpdate oldPacket = (PacketPlayOutRecipeUpdate) object;
List<IRecipe<?>> recipes = new ArrayList<>();
try {
Field f = oldPacket.getClass().getDeclaredField("a");
f.setAccessible(true);
recipes.addAll((Collection<? extends IRecipe<?>>) f.get(oldPacket));
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
List<Object> splitPackets = new ArrayList<>();
List<IRecipe<?>> splitRecipes = new ArrayList<>();
for (int i = 0; i < recipes.size(); i++) {
splitRecipes.add(recipes.get(i));
if (i % 100 == 0) {
PacketPlayOutRecipeUpdate newPacket = new PacketPlayOutRecipeUpdate(splitRecipes);
splitPackets.add(newPacket);
splitRecipes.clear();
}
}
return splitPackets;
}
}

View File

@@ -0,0 +1,46 @@
package com.willfp.eco.proxy.v1_16_R1;
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
import net.minecraft.server.v1_16_R1.IRecipe;
import net.minecraft.server.v1_16_R1.PacketPlayOutRecipeUpdate;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@SuppressWarnings("unchecked")
public final class PacketPlayOutRecipeUpdateFix implements PacketPlayOutRecipeUpdateFixProxy {
@Override
public List<Object> splitPackets(@NotNull final Object object,
@NotNull final Player player) {
if (!(object instanceof PacketPlayOutRecipeUpdate)) {
throw new IllegalArgumentException("Parameter not packet!");
}
PacketPlayOutRecipeUpdate oldPacket = (PacketPlayOutRecipeUpdate) object;
List<IRecipe<?>> recipes = new ArrayList<>();
try {
Field f = oldPacket.getClass().getDeclaredField("a");
f.setAccessible(true);
recipes.addAll((Collection<? extends IRecipe<?>>) f.get(oldPacket));
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
List<Object> splitPackets = new ArrayList<>();
List<IRecipe<?>> splitRecipes = new ArrayList<>();
for (int i = 0; i < recipes.size(); i++) {
splitRecipes.add(recipes.get(i));
if (i % 100 == 0) {
PacketPlayOutRecipeUpdate newPacket = new PacketPlayOutRecipeUpdate(splitRecipes);
splitPackets.add(newPacket);
splitRecipes.clear();
}
}
return splitPackets;
}
}

View File

@@ -0,0 +1,46 @@
package com.willfp.eco.proxy.v1_16_R2;
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
import net.minecraft.server.v1_16_R2.IRecipe;
import net.minecraft.server.v1_16_R2.PacketPlayOutRecipeUpdate;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@SuppressWarnings("unchecked")
public final class PacketPlayOutRecipeUpdateFix implements PacketPlayOutRecipeUpdateFixProxy {
@Override
public List<Object> splitPackets(@NotNull final Object object,
@NotNull final Player player) {
if (!(object instanceof PacketPlayOutRecipeUpdate)) {
throw new IllegalArgumentException("Parameter not packet!");
}
PacketPlayOutRecipeUpdate oldPacket = (PacketPlayOutRecipeUpdate) object;
List<IRecipe<?>> recipes = new ArrayList<>();
try {
Field f = oldPacket.getClass().getDeclaredField("a");
f.setAccessible(true);
recipes.addAll((Collection<? extends IRecipe<?>>) f.get(oldPacket));
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
List<Object> splitPackets = new ArrayList<>();
List<IRecipe<?>> splitRecipes = new ArrayList<>();
for (int i = 0; i < recipes.size(); i++) {
splitRecipes.add(recipes.get(i));
if (i % 100 == 0) {
PacketPlayOutRecipeUpdate newPacket = new PacketPlayOutRecipeUpdate(splitRecipes);
splitPackets.add(newPacket);
splitRecipes.clear();
}
}
return splitPackets;
}
}

View File

@@ -0,0 +1,46 @@
package com.willfp.eco.proxy.v1_16_R3;
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
import net.minecraft.server.v1_16_R3.IRecipe;
import net.minecraft.server.v1_16_R3.PacketPlayOutRecipeUpdate;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@SuppressWarnings("unchecked")
public final class PacketPlayOutRecipeUpdateFix implements PacketPlayOutRecipeUpdateFixProxy {
@Override
public List<Object> splitPackets(@NotNull final Object object,
@NotNull final Player player) {
if (!(object instanceof PacketPlayOutRecipeUpdate)) {
throw new IllegalArgumentException("Parameter not packet!");
}
PacketPlayOutRecipeUpdate oldPacket = (PacketPlayOutRecipeUpdate) object;
List<IRecipe<?>> recipes = new ArrayList<>();
try {
Field f = oldPacket.getClass().getDeclaredField("a");
f.setAccessible(true);
recipes.addAll((Collection<? extends IRecipe<?>>) f.get(oldPacket));
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
List<Object> splitPackets = new ArrayList<>();
List<IRecipe<?>> splitRecipes = new ArrayList<>();
for (int i = 0; i < recipes.size(); i++) {
splitRecipes.add(recipes.get(i));
if (i % 100 == 0) {
PacketPlayOutRecipeUpdate newPacket = new PacketPlayOutRecipeUpdate(splitRecipes);
splitPackets.add(newPacket);
splitRecipes.clear();
}
}
return splitPackets;
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.spigot;
import com.comphenix.protocol.ProtocolLibrary;
import com.willfp.eco.spigot.display.packets.PacketAutoRecipe;
import com.willfp.eco.spigot.display.packets.PacketChat;
import com.willfp.eco.spigot.display.packets.PacketOpenWindowMerchant;
@@ -57,6 +58,7 @@ public class EcoPlugin extends AbstractEcoPlugin {
this.getEventManager().registerListener(new DispenserArmorListener());
this.getEventManager().registerListener(new EntityDeathByEntityListeners(this));
this.getEventManager().registerListener(new RecipeListener(this));
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketPlayOutRecipeUpdateFix(this));
}
@Override

View File

@@ -0,0 +1,44 @@
package com.willfp.eco.spigot;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.willfp.eco.proxy.proxies.PacketPlayOutRecipeUpdateFixProxy;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
public class PacketPlayOutRecipeUpdateFix extends PacketAdapter {
/**
* Create new fixer for PacketPlayOutRecipeUpdate.
*
* @param plugin Plugin.
*/
public PacketPlayOutRecipeUpdateFix(@NotNull final AbstractEcoPlugin plugin) {
super(plugin, PacketType.Play.Server.RECIPE_UPDATE);
}
@Override
public void onPacketSending(@NotNull final PacketEvent event) {
PacketContainer packet = event.getPacket();
Player player = event.getPlayer();
List<Object> packets = InternalProxyUtils.getProxy(PacketPlayOutRecipeUpdateFixProxy.class).splitPackets(packet.getHandle(), player);
if (packets.size() > 1) {
event.setCancelled(true);
for (Object o : packets) {
PacketContainer container = PacketContainer.fromPacket(o);
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, container);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
package com.willfp.eco.proxy.proxies;
import com.willfp.eco.util.proxy.AbstractProxy;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public interface PacketPlayOutRecipeUpdateFixProxy extends AbstractProxy {
/**
* Split recipe update packet into smaller packets.
*
* @param object The packet.
* @param player The player.
* @return The packets, split up.
*/
List<Object> splitPackets(@NotNull Object object,
@NotNull Player player);
}

View File

@@ -10,9 +10,7 @@ import org.jetbrains.annotations.Nullable;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -25,7 +23,12 @@ public class StringUtils {
/**
* Regex for gradients.
*/
private static final String GRADIENT_REGEX = "<\\$#[A-Fa-f0-9]{6}>";
private static final Pattern GRADIENT_REGEX = Pattern.compile("<GRADIENT:([0-9A-Fa-f]{6})>(.*?)</GRADIENT:([0-9A-Fa-f]{6})>");
/**
* Regex for hex codes.
*/
private static final Pattern HEX_PATTERN = Pattern.compile("&#" + "([A-Fa-f0-9]{6})" + "");
/**
* Translate a string - converts Placeholders and Color codes.
@@ -58,8 +61,7 @@ public class StringUtils {
}
private static String translateHexColorCodes(@NotNull final String message) {
Pattern hexPattern = Pattern.compile("&#" + "([A-Fa-f0-9]{6})" + "");
Matcher matcher = hexPattern.matcher(message);
Matcher matcher = HEX_PATTERN.matcher(message);
StringBuffer buffer = new StringBuffer(message.length() + 4 * 8);
while (matcher.find()) {
String group = matcher.group(1);
@@ -73,102 +75,90 @@ public class StringUtils {
}
/**
* Apply gradients to the provided string.
* Colors a string with a gradient.
*
* @param message the string to parse.
* @return the parsed string.
* @param string The string to color.
* @param start The start color.
* @param end The end color.
* @return The string, colored.
*/
public static String translateGradients(@NotNull final String message) {
List<String> hexes = new ArrayList<>();
Matcher matcher = Pattern.compile(GRADIENT_REGEX).matcher(message);
while (matcher.find()) {
hexes.add(matcher.group().replace("<$", "").replace(">", ""));
private static String processGradients(@NotNull final String string,
@NotNull final Color start,
@NotNull final Color end) {
String processedString = string;
List<ChatColor> modifiers = new ArrayList<>();
if (processedString.contains("&l")) {
modifiers.add(ChatColor.BOLD);
}
int hexIndex = 0;
List<String> texts = new LinkedList<>(Arrays.asList(message.split(GRADIENT_REGEX)));
StringBuilder finalMsg = new StringBuilder();
for (String text : texts) {
if (texts.get(0).equalsIgnoreCase(text)) {
finalMsg.append(text);
continue;
}
if (text.length() == 0) {
continue;
}
if (hexIndex + 1 >= hexes.size()) {
if (!finalMsg.toString().contains(text)) {
finalMsg.append(text);
}
continue;
}
String fromHex = hexes.get(hexIndex);
String toHex = hexes.get(hexIndex + 1);
finalMsg.append(insertFades(text, fromHex, toHex));
hexIndex++;
if (processedString.contains("&o")) {
modifiers.add(ChatColor.ITALIC);
}
return finalMsg.toString();
if (processedString.contains("&n")) {
modifiers.add(ChatColor.UNDERLINE);
}
if (processedString.contains("&k")) {
modifiers.add(ChatColor.MAGIC);
}
processedString = processedString.replace("&l", "");
processedString = processedString.replace("&o", "");
processedString = processedString.replace("&n", "");
processedString = processedString.replace("&k", "");
StringBuilder stringBuilder = new StringBuilder();
ChatColor[] colors = getGradientColors(start, end, processedString.length());
String[] characters = processedString.split("");
for (int i = 0; i < processedString.length(); i++) {
stringBuilder.append(colors[i]);
modifiers.forEach(stringBuilder::append);
stringBuilder.append(characters[i]);
}
return stringBuilder.toString();
}
private static String insertFades(@NotNull final String message,
@NotNull final String fromHex,
@NotNull final String toHex) {
boolean bold = message.contains("&l");
boolean italic = message.contains("&o");
String msg = message;
msg = msg.replace("&l", "");
msg = msg.replace("&o", "");
int length = msg.length();
Color fromRGB = Color.decode(fromHex);
Color toRGB = Color.decode(toHex);
double rStep = Math.abs((double) (fromRGB.getRed() - toRGB.getRed()) / length);
double gStep = Math.abs((double) (fromRGB.getGreen() - toRGB.getGreen()) / length);
double bStep = Math.abs((double) (fromRGB.getBlue() - toRGB.getBlue()) / length);
if (fromRGB.getRed() > toRGB.getRed()) {
rStep = -rStep;
/**
* Creates chatColors for gradients.
*
* @param start The start color.
* @param end The end color.
* @param step How many colors are returned.
* @return Array of chat colors.
*/
private static ChatColor[] getGradientColors(@NotNull final Color start,
@NotNull final Color end,
final int step) {
ChatColor[] colors = new ChatColor[step];
int stepR = Math.abs(start.getRed() - end.getRed()) / (step - 1);
int stepG = Math.abs(start.getGreen() - end.getGreen()) / (step - 1);
int stepB = Math.abs(start.getBlue() - end.getBlue()) / (step - 1);
int[] direction = new int[]{
start.getRed() < end.getRed() ? +1 : -1,
start.getGreen() < end.getGreen() ? +1 : -1,
start.getBlue() < end.getBlue() ? +1 : -1
};
for (int i = 0; i < step; i++) {
Color color = new Color(start.getRed() + ((stepR * i) * direction[0]), start.getGreen() + ((stepG * i) * direction[1]), start.getBlue() + ((stepB * i) * direction[2]));
colors[i] = ChatColor.of(color);
}
if (fromRGB.getGreen() > toRGB.getGreen()) {
gStep = -gStep;
return colors;
}
/**
* Add gradients to a string.
*
* @param string The string.
* @return The string, colorized.
*/
private static String translateGradients(@NotNull final String string) {
String processedString = string;
Matcher matcher = GRADIENT_REGEX.matcher(string);
while (matcher.find()) {
String start = matcher.group(1);
String end = matcher.group(3);
String content = matcher.group(2);
processedString = processedString.replace(matcher.group(), processGradients(content, new Color(Integer.parseInt(start, 16)), new Color(Integer.parseInt(end, 16))));
}
if (fromRGB.getBlue() > toRGB.getBlue()) {
bStep = -bStep;
}
Color finalColor = new Color(fromRGB.getRGB());
msg = msg.replaceAll(GRADIENT_REGEX, "");
msg = msg.replace("", "<$>");
for (int index = 0; index <= length; index++) {
int red = (int) Math.round(finalColor.getRed() + rStep);
int green = (int) Math.round(finalColor.getGreen() + gStep);
int blue = (int) Math.round(finalColor.getBlue() + bStep);
if (red > 255) {
red = 255;
}
if (red < 0) {
red = 0;
}
if (green > 255) {
green = 255;
}
if (green < 0) {
green = 0;
}
if (blue > 255) {
blue = 255;
}
if (blue < 0) {
blue = 0;
}
finalColor = new Color(red, green, blue);
String hex = "#" + Integer.toHexString(finalColor.getRGB()).substring(2);
String formats = "";
if (bold) {
formats += ChatColor.BOLD;
}
if (italic) {
formats += ChatColor.ITALIC;
}
msg = msg.replaceFirst("<\\$>", ChatColor.of(hex) + formats);
}
return msg;
return processedString;
}
/**

View File

@@ -0,0 +1,163 @@
package com.willfp.eco.util.config;
import com.willfp.eco.util.StringUtils;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.List;
import java.util.Objects;
public abstract class StaticBaseConfig extends PluginDependent implements ValueGetter {
/**
* The linked {@link YamlConfiguration} where values are physically stored.
*/
@Getter(AccessLevel.PUBLIC)
private final YamlConfiguration config;
/**
* The physical config file, as stored on disk.
*/
@Getter(AccessLevel.PROTECTED)
private final File configFile;
/**
* The full name of the config file (eg config.yml).
*/
private final String name;
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected StaticBaseConfig(@NotNull final String configName,
@NotNull final AbstractEcoPlugin plugin) {
super(plugin);
this.name = configName + ".yml";
if (!new File(this.getPlugin().getDataFolder(), this.name).exists()) {
createFile();
}
this.configFile = new File(this.getPlugin().getDataFolder(), this.name);
this.config = YamlConfiguration.loadConfiguration(configFile);
}
private void createFile() {
this.getPlugin().saveResource(name, false);
}
/**
* Get an integer from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
@Override
public int getInt(@NotNull final String path) {
return config.getInt(path, 0);
}
/**
* Get an integer from config with a specified default (not found) value.
*
* @param path The key to fetch the value from.
* @param def The value to default to if not found.
* @return The found value, or the default.
*/
@Override
public int getInt(@NotNull final String path,
final int def) {
return config.getInt(path, def);
}
/**
* Get a list of integers from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<Integer> getInts(@NotNull final String path) {
return config.getIntegerList(path);
}
/**
* Get a boolean from config.
*
* @param path The key to fetch the value from.
* @return The found value, or false if not found.
*/
@Override
public boolean getBool(@NotNull final String path) {
return config.getBoolean(path, false);
}
/**
* Get a list of booleans from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<Boolean> getBools(@NotNull final String path) {
return config.getBooleanList(path);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @return The found value, or an empty string if not found.
*/
@Override
@NotNull
public String getString(@NotNull final String path) {
return StringUtils.translate(Objects.requireNonNull(config.getString(path, "")));
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<String> getStrings(@NotNull final String path) {
return config.getStringList(path);
}
/**
* Get a decimal from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
@Override
public double getDouble(@NotNull final String path) {
return config.getDouble(path, 0);
}
/**
* Get a list of decimals from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<Double> getDoubles(@NotNull final String path) {
return config.getDoubleList(path);
}
}

View File

@@ -22,6 +22,7 @@ import com.willfp.eco.util.integrations.placeholder.PlaceholderManager;
import com.willfp.eco.util.integrations.placeholder.plugins.PlaceholderIntegrationPAPI;
import com.willfp.eco.util.optional.Prerequisite;
import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
import com.willfp.eco.util.recipe.RecipeListener;
import com.willfp.eco.util.recipe.RecipeManager;
import com.willfp.eco.util.updater.UpdateChecker;
import lombok.Getter;
@@ -214,6 +215,7 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.getLog().info("Loading " + this.color + this.pluginName);
this.getEventManager().registerListener(new ArrowDataListener(this));
this.getEventManager().registerListener(new RecipeListener(this));
new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());

View File

@@ -52,8 +52,8 @@ public class RecipeManager extends PluginDependent {
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(recipe.getDisplayedAtIndex(i)));
}
Bukkit.getServer().addRecipe(shapedRecipe);
Bukkit.getServer().addRecipe(displayedRecipe);
Bukkit.getServer().addRecipe(shapedRecipe);
}
/**

View File

@@ -1,2 +1,2 @@
version = 3.1.0
version = 3.2.0
plugin-name = eco