Skip to content

Commit

Permalink
Improve warnings for incorrect entity types in profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
froobynooby committed Apr 28, 2024
1 parent 8a52e26 commit b7a9279
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import com.froobworld.farmcontrol.FarmControl;
import com.froobworld.farmcontrol.controller.action.Action;
import com.froobworld.farmcontrol.group.GroupDefinition;
import com.froobworld.farmcontrol.utils.EntityCategory;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;

public class ProfileManager {
private final FarmControl farmControl;
Expand All @@ -33,18 +35,31 @@ public void load() throws IOException {
for (String name : Objects.requireNonNull(profilesSection).getKeys(false)) {
try {
ConfigurationSection profileSection = Objects.requireNonNull(profilesSection.getConfigurationSection(name));
GroupDefinition groupDefinition = GroupDefinition.fromConfigurationSection(Objects.requireNonNull(profileSection.getConfigurationSection("group")));
GroupDefinition groupDefinition = GroupDefinition.fromConfigurationSection(farmControl, name, Objects.requireNonNull(profileSection.getConfigurationSection("group")));
Set<Action> actions = new HashSet<>();
for (String actionName : profileSection.getStringList("actions")) {
Action action = farmControl.getActionManager().getAction(actionName.toLowerCase());
if (action == null) {
farmControl.getLogger().warning("Unknown action for profile '" + name + "': '" + actionName.toLowerCase() + "'");
continue;
}
Set<String> incompatibleCategories = new HashSet<>();
for (EntityCategory memberCategory : groupDefinition.getMemberCategories()) {
if (!memberCategory.isCompatibleWith(action)) {
incompatibleCategories.add(memberCategory.getName());
}
}
if (!incompatibleCategories.isEmpty()) {
String incompatibleCategoriesString = incompatibleCategories.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
farmControl.getLogger().warning("Note: action '" + actionName + "' in profile '" + name + "' is incompatible with the following entity types: " + incompatibleCategoriesString);
}
actions.add(action);
}
actionProfileMap.put(name, new ActionProfile(groupDefinition, actions));
} catch (Exception ex) {
ex.printStackTrace();
farmControl.getLogger().warning("Unable to load the profile '" + name + "'. Incorrect syntax?");
}
}
Expand Down
59 changes: 45 additions & 14 deletions src/main/java/com/froobworld/farmcontrol/group/GroupDefinition.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package com.froobworld.farmcontrol.group;

import com.froobworld.farmcontrol.FarmControl;
import com.froobworld.farmcontrol.controller.entity.SnapshotEntity;
import com.froobworld.farmcontrol.utils.EntityTypeUtils;
import com.froobworld.farmcontrol.utils.EntityCategory;
import org.bukkit.configuration.ConfigurationSection;

import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

public class GroupDefinition {
private final Set<EntityCategory> memberCategories;
private final Set<EntityCategory> excludedCategories;
private final Predicate<SnapshotEntity> typePredicate;
private final Predicate<SnapshotEntity> excludeTypePredicate;
private final int size;
Expand All @@ -16,15 +21,31 @@ public class GroupDefinition {
private final boolean ignoreVerticalDistance;
private final boolean pure;

public GroupDefinition(Predicate<SnapshotEntity> typePredicate, Predicate<SnapshotEntity> excludeTypePredicate, int size, double distance, boolean sameChunk, boolean ignoreVerticalDistance, boolean pure) {
this.typePredicate = typePredicate;
this.excludeTypePredicate = excludeTypePredicate;
public GroupDefinition(Set<EntityCategory> memberCategories, Set<EntityCategory> excludedCategories, int size, double distance, boolean sameChunk, boolean ignoreVerticalDistance, boolean pure) {
this.memberCategories = memberCategories;
this.excludedCategories = excludedCategories;
this.size = size;
this.distance = distance;
this.distanceSquared = distance * distance;
this.sameChunk = sameChunk;
this.ignoreVerticalDistance = ignoreVerticalDistance;
this.pure = pure;
this.typePredicate = memberCategories.stream()
.map(EntityCategory::asSnapshotEntityPredicate)
.reduce(Predicate::or)
.orElse(snapshotEntity -> false); // require explicit specification of types by defaulting to false
this.excludeTypePredicate = excludedCategories.stream()
.map(EntityCategory::asSnapshotEntityPredicate)
.reduce(Predicate::or)
.orElse(snapshotEntity -> false);
}

public Set<EntityCategory> getMemberCategories() {
return memberCategories;
}

public Set<EntityCategory> getExcludedCategories() {
return excludedCategories;
}

public Predicate<SnapshotEntity> getTypePredicate() {
Expand Down Expand Up @@ -59,22 +80,32 @@ public boolean isPure() {
return pure;
}

public static GroupDefinition fromConfigurationSection(ConfigurationSection section) {
Predicate<SnapshotEntity> typePredicate = section.getStringList("types").stream()
.map(EntityTypeUtils::fromString)
.reduce(Predicate::or)
.orElse(snapshotEntity -> false); // require explicit specification of types by defaulting to false
Predicate<SnapshotEntity> excludeTypePredicate = section.getStringList("exclude-types").stream()
.map(EntityTypeUtils::fromString)
.reduce(Predicate::or)
.orElse(snapshotEntity -> false);
public static GroupDefinition fromConfigurationSection(FarmControl farmControl, String profileName, ConfigurationSection section) {
Set<EntityCategory> memberCategories = new HashSet<>();
for (String entityType : section.getStringList("types")) {
EntityCategory entityCategory = EntityCategory.ofName(entityType);
if (entityCategory == null) {
farmControl.getLogger().warning("Unknown entity type '" + entityType + "' for profile '" + profileName + "'.");
} else {
memberCategories.add(entityCategory);
}
}
Set<EntityCategory> excludedCategories = new HashSet<>();
for (String entityType : section.getStringList("exclude-types")) {
EntityCategory entityCategory = EntityCategory.ofName(entityType);
if (entityCategory == null) {
farmControl.getLogger().warning("Unknown excluded entity type '" + entityType + "' for profile '" + profileName + "'.");
} else {
excludedCategories.add(entityCategory);
}
}
int size = section.getInt("count");
boolean sameChunk = section.isString("distance") && "same-chunk".equalsIgnoreCase(section.getString("distance"));
double distance = sameChunk ? 0 : section.getDouble("distance");
boolean ignoreVerticalDistance = section.getBoolean("ignore-vertical-distance");
boolean pure = section.getBoolean("pure");

return new GroupDefinition(typePredicate, excludeTypePredicate, size, distance, sameChunk, ignoreVerticalDistance, pure);
return new GroupDefinition(memberCategories, excludedCategories, size, distance, sameChunk, ignoreVerticalDistance, pure);
}

}
96 changes: 96 additions & 0 deletions src/main/java/com/froobworld/farmcontrol/utils/EntityCategory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.froobworld.farmcontrol.utils;

import com.froobworld.farmcontrol.controller.action.Action;
import com.froobworld.farmcontrol.controller.entity.SnapshotEntity;
import org.bukkit.entity.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

public class EntityCategory {
private static final Map<String, EntityCategory> entityCategoryMap;
private final String name;
private final boolean allowInheritance;
private final Class<?>[] memberClasses;

static {
List<EntityCategory> entityCategories = new ArrayList<>();
for (EntityType entityType : EntityType.values()) {
Class<?> entityTypeClass = entityType.getEntityClass();
if (entityTypeClass != null) {
entityCategories.add(new EntityCategory(entityType.toString().toLowerCase(), false, entityTypeClass));
}
}
entityCategories.addAll(
List.of(
new EntityCategory("category:animal", true, Animals.class),
new EntityCategory("category:monster", true, Monster.class),
new EntityCategory("category:golem", true, Golem.class),
new EntityCategory("category:ambient", true, Ambient.class),
new EntityCategory("category:fish", true, Fish.class),
new EntityCategory("category:tameable", true, Tameable.class),
new EntityCategory("category:raider", true, Raider.class),
new EntityCategory("category:mob", true, Mob.class),
new EntityCategory("category:vehicle", true, Boat.class, Minecart.class),
new EntityCategory("category:projectile", true, Projectile.class)
)
);

entityCategoryMap = new HashMap<>();
entityCategories.forEach(entityCategory -> entityCategoryMap.put(entityCategory.name, entityCategory));
}

private EntityCategory(String name, boolean allowInheritance, Class<?>... memberClasses) {
this.name = name;
this.allowInheritance = allowInheritance;
this.memberClasses = memberClasses;
}

public String getName() {
return name;
}

public boolean isMember(Class<?> entityClass) {
for (Class<?> memberClass : memberClasses) {
if (allowInheritance ? memberClass.isAssignableFrom(entityClass) : memberClass.equals(entityClass)) {
return true;
}
}
return false;
}

public boolean isMember(SnapshotEntity entity) {
return isMember(entity.getEntityClass());
}

public boolean isMember(EntityType entityType) {
if (entityType.getEntityClass() == null) {
return false;
}
return isMember(entityType.getEntityClass());
}

public Predicate<SnapshotEntity> asSnapshotEntityPredicate() {
return this::isMember;
}

public boolean isCompatibleWith(Action action) {
for (EntityType entityType : EntityType.values()) {
if (isMember(entityType)) {
Class<?> entityTypeClass = entityType.getEntityClass();
if (entityTypeClass != null && action.getEntityClass().isAssignableFrom(entityTypeClass)) {
return true;
}
}
}
return false;
}

public static EntityCategory ofName(String categoryName) {
return EntityCategory.entityCategoryMap.get(categoryName);
}

}

0 comments on commit b7a9279

Please sign in to comment.