From ecea17195a74afcdcdb72367c085317bdf0db1c5 Mon Sep 17 00:00:00 2001
From: Josh Roy <10731363+JRoy@users.noreply.github.com>
Date: Tue, 8 Jun 2021 16:51:47 -0400
Subject: [PATCH] Fix parsing of command cooldowns with invalid data (#4212)

---
 .../config/EssentialsConfiguration.java       |  3 ++
 .../config/entities/CommandCooldown.java      |  2 -
 .../CommandCooldownSerializer.java            | 40 +++++++++++++++++++
 3 files changed, 43 insertions(+), 2 deletions(-)
 create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/serializers/CommandCooldownSerializer.java

diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java
index 10e870fc8..e136b8392 100644
--- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java
+++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java
@@ -2,10 +2,12 @@ package com.earth2me.essentials.config;
 
 import com.earth2me.essentials.config.annotations.DeleteIfIncomplete;
 import com.earth2me.essentials.config.annotations.DeleteOnEmpty;
+import com.earth2me.essentials.config.entities.CommandCooldown;
 import com.earth2me.essentials.config.entities.LazyLocation;
 import com.earth2me.essentials.config.processors.DeleteIfIncompleteProcessor;
 import com.earth2me.essentials.config.processors.DeleteOnEmptyProcessor;
 import com.earth2me.essentials.config.serializers.BigDecimalTypeSerializer;
+import com.earth2me.essentials.config.serializers.CommandCooldownSerializer;
 import com.earth2me.essentials.config.serializers.LocationTypeSerializer;
 import com.earth2me.essentials.config.serializers.MaterialTypeSerializer;
 import net.ess3.api.InvalidWorldException;
@@ -55,6 +57,7 @@ public class EssentialsConfiguration {
             .register(BigDecimal.class, new BigDecimalTypeSerializer())
             .register(LazyLocation.class, new LocationTypeSerializer())
             .register(Material.class, new MaterialTypeSerializer())
+            .register(CommandCooldown.class, new CommandCooldownSerializer())
             .build();
 
     private final AtomicInteger pendingWrites = new AtomicInteger(0);
diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/entities/CommandCooldown.java b/Essentials/src/main/java/com/earth2me/essentials/config/entities/CommandCooldown.java
index 1373902fe..4c5ed935d 100644
--- a/Essentials/src/main/java/com/earth2me/essentials/config/entities/CommandCooldown.java
+++ b/Essentials/src/main/java/com/earth2me/essentials/config/entities/CommandCooldown.java
@@ -1,11 +1,9 @@
 package com.earth2me.essentials.config.entities;
 
 import com.earth2me.essentials.config.processors.DeleteIfIncompleteProcessor;
-import org.spongepowered.configurate.objectmapping.ConfigSerializable;
 
 import java.util.regex.Pattern;
 
-@ConfigSerializable
 public class CommandCooldown implements DeleteIfIncompleteProcessor.IncompleteEntity {
     private Pattern pattern;
 
diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/serializers/CommandCooldownSerializer.java b/Essentials/src/main/java/com/earth2me/essentials/config/serializers/CommandCooldownSerializer.java
new file mode 100644
index 000000000..3100650d9
--- /dev/null
+++ b/Essentials/src/main/java/com/earth2me/essentials/config/serializers/CommandCooldownSerializer.java
@@ -0,0 +1,40 @@
+package com.earth2me.essentials.config.serializers;
+
+import com.earth2me.essentials.config.entities.CommandCooldown;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.spongepowered.configurate.ConfigurationNode;
+import org.spongepowered.configurate.serialize.SerializationException;
+import org.spongepowered.configurate.serialize.TypeSerializer;
+
+import java.lang.reflect.Type;
+import java.util.regex.Pattern;
+
+public class CommandCooldownSerializer implements TypeSerializer<CommandCooldown> {
+    @Override
+    public CommandCooldown deserialize(Type type, ConfigurationNode node) throws SerializationException {
+        try {
+            final Pattern pattern = node.node("pattern").get(Pattern.class);
+            if (node.node("value").isNull()) {
+                return null;
+            }
+            final Long longValue = node.node("value").getLong();
+            final CommandCooldown cooldown = new CommandCooldown();
+            cooldown.pattern(pattern);
+            cooldown.value(longValue);
+            return cooldown;
+        } catch (final SerializationException ignored) {
+        }
+        return null;
+    }
+
+    @Override
+    public void serialize(Type type, @Nullable CommandCooldown obj, ConfigurationNode node) throws SerializationException {
+        if (obj == null || obj.isIncomplete()) {
+            node.raw(null);
+            return;
+        }
+
+        node.node("pattern").set(Pattern.class, obj.pattern());
+        node.node("value").set(Long.class, obj.value());
+    }
+}