Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Build FarmControl

on: [push, pull_request]
on: [ push, pull_request ]

jobs:
build:
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@
**Plugin page**: [https://www.spigotmc.org/resources/86923/](https://www.spigotmc.org/resources/86923/)

## About
FarmControl is a Bukkit plugin that allows you to control certain properties of farms on your server. Among other things, you can limit the size of mob farms, remove the ability of mobs in farms to collide and perform random movements, or completely disable the AI of mobs in farms.

FarmControl is a Bukkit plugin that allows you to control certain properties of farms on your server. Among other
things, you can limit the size of mob farms, remove the ability of mobs in farms to collide and perform random
movements, or completely disable the AI of mobs in farms.

## Building

1. Install dependency NabConfiguration to maven local

```bash
git clone https://github.com/froobynooby/nab-configuration
cd nab-configuration
./gradlew clean install
```

2. Clone FarmControl and build

```bash
git clone https://github.com/froobynooby/FarmControl
cd FarmControl
Expand Down
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group 'com.froobworld'
version '1.2.0'
version '1.2.1'
jar.enabled = false;

sourceCompatibility = 1.8
Expand Down Expand Up @@ -33,9 +33,9 @@ dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compileOnly 'com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT'
compileOnly 'me.clip:placeholderapi:2.10.9'
compile 'org.jooq:joor-java-8:0.9.13'
compile 'org.jooq:joor-java-8:0.9.14'
compile 'com.froobworld:nab-configuration:1.0.2'
compile 'org.bstats:bstats-bukkit:2.2.1'
compile 'org.bstats:bstats-bukkit:3.0.0'
}

processResources {
Expand All @@ -47,7 +47,7 @@ shadowJar {

relocate 'com.froobworld.nabconfiguration', 'com.froobworld.farmcontrol.lib.nabconfiguration'
relocate 'org.joor', 'com.froobworld.farmcontrol.lib.joor'
relocate 'org.bstats','com.froobworld.farmcontrol.lib.bstats'
relocate 'org.bstats', 'com.froobworld.farmcontrol.lib.bstats'
}

artifacts {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private void sendHelp(CommandSender sender, String cl) {
sender.sendMessage("/" + cl + " reload");
}
if (sender.hasPermission("farmcontrol.command.status")) {
sender.sendMessage("/" + cl + " status " + (sender instanceof Player ? "[world]" :"<world>"));
sender.sendMessage("/" + cl + " status " + (sender instanceof Player ? "[world]" : "<world>"));
}
if (sender.hasPermission("farmcontrol.command.history")) {
sender.sendMessage("/" + cl + " history ");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.froobworld.farmcontrol.command;

import com.froobworld.farmcontrol.FarmControl;
import com.froobworld.farmcontrol.controller.action.Action;
import com.froobworld.farmcontrol.data.FcData;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package com.froobworld.farmcontrol.controller;

import com.froobworld.farmcontrol.FarmControl;
import com.froobworld.farmcontrol.controller.task.*;
import com.froobworld.farmcontrol.controller.task.ActionPerformTask;
import com.froobworld.farmcontrol.controller.task.TriggerCheckTask;
import com.froobworld.farmcontrol.controller.task.UntriggerPerformTask;
import com.froobworld.farmcontrol.controller.tracker.CycleHistoryManager;
import com.froobworld.farmcontrol.controller.trigger.Trigger;
import com.froobworld.farmcontrol.utils.Actioner;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;

import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class FarmController {
private final FarmControl farmControl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public void doAction(Mob mob) {
}

@Override
public void undoAction(Mob mob) {}
public void undoAction(Mob mob) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public void doAction(Mob mob) {
}

@Override
public void undoAction(Mob mob) {}
public void undoAction(Mob mob) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@

import java.util.*;

import static org.joor.Reflect.*;
import static org.joor.Reflect.on;

public class RemoveRandomMovementAction extends Action {
private final static Map<Mob, Set<Object>> entityRemovedGoalsMap = new WeakHashMap<>();
private final static Set<Class<?>> randomMovementGoals = new HashSet<>();

static {
try {
randomMovementGoals.add(Class.forName(NmsUtils.getFullyQualifiedClassName("PathfinderGoalRandomFly", "world.entity.ai.goal")));
randomMovementGoals.add(Class.forName(NmsUtils.getFullyQualifiedClassName("PathfinderGoalRandomStroll", "world.entity.ai.goal")));
randomMovementGoals.add(Class.forName(NmsUtils.getFullyQualifiedClassName("PathfinderGoalRandomStrollLand", "world.entity.ai.goal")));
randomMovementGoals.add(Class.forName(NmsUtils.getFullyQualifiedClassName("PathfinderGoalRandomSwim", "world.entity.ai.goal")));
randomMovementGoals.add(Class.forName(NmsUtils.getFullyQualifiedClassName("PathfinderGoalRandomFly", "world.entity.ai.goal")));
randomMovementGoals.add(Class.forName(NmsUtils.getFullyQualifiedClassName("PathfinderGoalRandomStroll", "world.entity.ai.goal")));
randomMovementGoals.add(Class.forName(NmsUtils.getFullyQualifiedClassName("PathfinderGoalRandomStrollLand", "world.entity.ai.goal")));
randomMovementGoals.add(Class.forName(NmsUtils.getFullyQualifiedClassName("PathfinderGoalRandomSwim", "world.entity.ai.goal")));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Expand Down Expand Up @@ -56,7 +56,7 @@ public void doAction(Mob mob) {
@Override
public void undoAction(Mob mob) {
Object entityObject = on(mob).call("getHandle").get();
Set<Object> wrappedGoals = on(entityObject)
Set wrappedGoals = on(entityObject)
.field(NmsUtils.GoalSelectorHelper.getGoalSelectorFieldName())
.field("d")
.as(Set.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
import com.froobworld.farmcontrol.controller.ActionProfile;
import com.froobworld.farmcontrol.controller.FarmController;
import com.froobworld.farmcontrol.controller.TriggerActionPair;
import com.froobworld.farmcontrol.controller.action.Action;
import com.froobworld.farmcontrol.controller.entity.SnapshotEntity;
import com.froobworld.farmcontrol.controller.tracker.CycleTracker;
import com.froobworld.farmcontrol.controller.trigger.Trigger;
import com.froobworld.farmcontrol.data.FcData;
import com.froobworld.farmcontrol.group.EntityGrouper;
import com.froobworld.farmcontrol.group.EntityGrouperResult;
import com.froobworld.farmcontrol.group.Group;
import com.froobworld.farmcontrol.controller.action.Action;
import com.froobworld.farmcontrol.controller.entity.SnapshotEntity;
import com.froobworld.farmcontrol.utils.MixedEntitySet;
import org.bukkit.World;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.froobworld.farmcontrol.controller.task;

import com.froobworld.farmcontrol.controller.TriggerActionPair;
import com.froobworld.farmcontrol.controller.entity.SnapshotEntity;
import com.froobworld.farmcontrol.controller.tracker.CycleTracker;
import com.froobworld.farmcontrol.data.FcData;
import com.froobworld.farmcontrol.controller.entity.SnapshotEntity;
import org.bukkit.World;
import org.bukkit.entity.Mob;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.bukkit.entity.EntityType;

import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

public class CycleStats {
Expand Down Expand Up @@ -73,7 +72,8 @@ public static class Builder {
private final Set<SnapshotEntity> removedEntities = new HashSet<>();
private final Map<Action, Map<EntityType, Integer>> actionCounts = new HashMap<>();

private Builder() {}
private Builder() {
}

public static Builder start(long startTime) {
Builder builder = new Builder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void load() {
return;
}
try (BufferedReader reader = new BufferedReader(new FileReader(userFile))) {
for(String line; (line = reader.readLine()) != null; ) {
for (String line; (line = reader.readLine()) != null; ) {
if (!line.isEmpty()) {
notifiableUsers.add(UUID.fromString(line));
}
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/com/froobworld/farmcontrol/data/FcData.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;

import java.util.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;

public class FcData {
private static final Map<Entity, FcData> dataCache = new WeakHashMap<>();
private static final NamespacedKey KEY = new NamespacedKey(FarmControl.getPlugin(FarmControl.class), "data");
private static final PersistentDataType<String, FcData> TYPE = new PersistentDataType<String, FcData>() {
private final Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

@Override
public @NotNull Class<String> getPrimitiveType() {
return String.class;
Expand Down Expand Up @@ -54,7 +58,8 @@ public FcData fromPrimitive(@NotNull String s, @NotNull PersistentDataAdapterCon
private final ConcurrentHashMap<String, Set<String>> triggerActionMap = new ConcurrentHashMap<>();
private boolean dirty = false;

private FcData() {}
private FcData() {
}

public Set<String> getActions(Trigger trigger) {
return triggerActionMap.get(trigger.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.froobworld.farmcontrol.controller.entity.SnapshotEntity;

import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;

public class EntityGrouperResult {
Expand All @@ -25,7 +27,7 @@ public static class Builder {
}

public void addEntity(SnapshotEntity entity) {
if (!groupDefinition.getTypePredicate().test(entity) || groupDefinition.getExcludeTypePredicate().test(entity)) {
if (!groupDefinition.getTypePredicate().test(entity) || groupDefinition.getExcludeTypePredicate().test(entity) || !groupDefinition.getNamePredicate().test(entity)) {
return;
}
ListIterator<ProtoGroup> iterator = protoGroups.listIterator();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.froobworld.farmcontrol.group;

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

Expand All @@ -9,16 +10,18 @@
public class GroupDefinition {
private final Predicate<SnapshotEntity> typePredicate;
private final Predicate<SnapshotEntity> excludeTypePredicate;
private final Predicate<SnapshotEntity> namePredicate;
private final int size;
private final double distance;
private final double distanceSquared;
private final boolean sameChunk;
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) {
public GroupDefinition(Predicate<SnapshotEntity> typePredicate, Predicate<SnapshotEntity> excludeTypePredicate, Predicate<SnapshotEntity> namePredicate, int size, double distance, boolean sameChunk, boolean ignoreVerticalDistance, boolean pure) {
this.typePredicate = typePredicate;
this.excludeTypePredicate = excludeTypePredicate;
this.namePredicate = namePredicate;
this.size = size;
this.distance = distance;
this.distanceSquared = distance * distance;
Expand All @@ -35,6 +38,10 @@ public Predicate<SnapshotEntity> getExcludeTypePredicate() {
return excludeTypePredicate;
}

public Predicate<SnapshotEntity> getNamePredicate() {
return namePredicate;
}

public int getSize() {
return size;
}
Expand Down Expand Up @@ -68,13 +75,17 @@ public static GroupDefinition fromConfigurationSection(ConfigurationSection sect
.map(EntityTypeUtils::fromString)
.reduce(Predicate::or)
.orElse(snapshotEntity -> false);
Predicate<SnapshotEntity> namePredicate = section.getStringList("names").stream()
.map(EntityNameUtils::fromString)
.reduce(Predicate::or)
.orElse(snapshotEntity -> true);
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(typePredicate, excludeTypePredicate, namePredicate, size, distance, sameChunk, ignoreVerticalDistance, pure);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
import java.util.Set;
import java.util.function.Consumer;

import static org.joor.Reflect.*;
import static org.joor.Reflect.on;

public class SpigotTickHook implements TickHook {
private static final long[] tickTimes;

static {
Class<?> serverClass = null;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ public void onEntityTempt(EntityTargetLivingEntityEvent event) {
return;
}
for (Action action : farmControl.getActionManager().getActions()) {
if (action instanceof RemoveRandomMovementAction) continue; // Hacky solution for https://github.com/froobynooby/FarmControl/issues/4
if (action instanceof RemoveRandomMovementAction)
continue; // Hacky solution for https://github.com/froobynooby/FarmControl/issues/4
if (farmControl.getFcConfig().worldSettings.of(entity.getWorld()).actionSettings.undoOn.of(action).tempt.get()) {
if (fcData.removeAction(action)) {
action.undoAction((Mob) entity);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/froobworld/farmcontrol/utils/Actioner.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

public final class Actioner {

private Actioner() {}
private Actioner() {
}

public static void undoAllActions(Entity entity, FarmControl farmControl) {
if (!(entity instanceof Mob)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

public final class DurationDisplayer {

private DurationDisplayer() {}
private DurationDisplayer() {
}

private static String quantityText(int quantity, String singularSuffix, String pluralSuffix) {
String quantityText = quantity + "";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.froobworld.farmcontrol.utils;

import com.froobworld.farmcontrol.controller.entity.SnapshotEntity;

import java.util.function.Predicate;

public final class EntityNameUtils {

public static Predicate<SnapshotEntity> fromString(String string) {
if (string.startsWith("*")) {
String name = string.split("\\*")[1];
return entity -> entity.getEntity().getCustomName() != null && entity.getEntity().getCustomName().toLowerCase().endsWith(name.toLowerCase());
} else if (string.endsWith("*")) {
String name = string.split("\\*")[0];
return entity -> entity.getEntity().getCustomName() != null && entity.getEntity().getCustomName().toLowerCase().startsWith(name.toLowerCase());
}
return entity -> entity.getEntity().getCustomName() != null && entity.getEntity().getCustomName().equalsIgnoreCase(string);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

public final class EntityTypeUtils {

private EntityTypeUtils(){}

public static Predicate<SnapshotEntity> fromString(String string) {
if (string.toLowerCase().startsWith("category:")) {
String category = string.split(":")[1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import java.lang.reflect.Field;

import static org.joor.Reflect.*;
import static org.joor.Reflect.on;

public class NmsUtils {
private static final String NMS_PACKAGE_NAME = on(Bukkit.getServer()).call("getHandle")
Expand Down
Loading