mirror of
https://github.com/TotalFreedomMC/TF-EssentialsX.git
synced 2024-12-31 20:42:17 +00:00
Fix invalid CommandCooldowns causing NPEs (#4210)
* Fix invalid CommandCooldowns causing NPEs * Add Map support
This commit is contained in:
parent
6e6561a267
commit
a28d0823b2
5 changed files with 82 additions and 1 deletions
|
@ -1,7 +1,9 @@
|
|||
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.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.LocationTypeSerializer;
|
||||
|
@ -46,6 +48,7 @@ public class EssentialsConfiguration {
|
|||
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
|
||||
private static final ObjectMapper.Factory MAPPER_FACTORY = ObjectMapper.factoryBuilder()
|
||||
.addProcessor(DeleteOnEmpty.class, (data, value) -> new DeleteOnEmptyProcessor())
|
||||
.addProcessor(DeleteIfIncomplete.class, (data, value) -> new DeleteIfIncompleteProcessor())
|
||||
.build();
|
||||
private static final TypeSerializerCollection SERIALIZERS = TypeSerializerCollection.defaults().childBuilder()
|
||||
.registerAnnotatedObjects(MAPPER_FACTORY)
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package com.earth2me.essentials.config.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Used to indicate to Configurate that the annotated field should be
|
||||
* treated as null if it is treated as incomplete.
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DeleteIfIncomplete {
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
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 {
|
||||
public class CommandCooldown implements DeleteIfIncompleteProcessor.IncompleteEntity {
|
||||
private Pattern pattern;
|
||||
|
||||
public Pattern pattern() {
|
||||
|
@ -25,4 +26,9 @@ public class CommandCooldown {
|
|||
public void value(final Long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncomplete() {
|
||||
return value == null || pattern == null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.earth2me.essentials.config.holders;
|
||||
|
||||
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;
|
||||
|
@ -413,6 +414,7 @@ public class UserConfigHolder {
|
|||
}
|
||||
|
||||
@DeleteOnEmpty
|
||||
@DeleteIfIncomplete
|
||||
private @MonotonicNonNull List<CommandCooldown> commandCooldowns;
|
||||
|
||||
public List<CommandCooldown> commandCooldowns() {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package com.earth2me.essentials.config.processors;
|
||||
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.objectmapping.meta.Processor;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DeleteIfIncompleteProcessor implements Processor<Object> {
|
||||
@Override
|
||||
public void process(Object value, ConfigurationNode destination) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (value instanceof IncompleteEntity && ((IncompleteEntity) value).isIncomplete()) {
|
||||
destination.set(null);
|
||||
} else if (value instanceof List<?>) {
|
||||
boolean modified = false;
|
||||
final List<?> newList = new ArrayList<>((List<?>) value);
|
||||
for (final Object o : (List<?>) value) {
|
||||
if (o instanceof IncompleteEntity && ((IncompleteEntity) o).isIncomplete()) {
|
||||
newList.remove(o);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
destination.set(newList);
|
||||
}
|
||||
} else if (value instanceof Map<?, ?>) {
|
||||
boolean modified = false;
|
||||
final Map<?, ?> newMap = new HashMap<>((Map<?, ?>) value);
|
||||
for (final Map.Entry<?, ?> entry : newMap.entrySet()) {
|
||||
if (entry.getValue() instanceof IncompleteEntity && ((IncompleteEntity) entry.getValue()).isIncomplete()) {
|
||||
newMap.remove(entry.getKey());
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
destination.set(newMap);
|
||||
}
|
||||
}
|
||||
} catch (final SerializationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IncompleteEntity {
|
||||
boolean isIncomplete();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue