Skip to content

Commit

Permalink
Improve possible server stall from large config values on colony crea…
Browse files Browse the repository at this point in the history
…tion (ldtteam#6870)

Improve colony creation range checks to no longer load a lot of chunks
Improve error output when colony creation fails
  • Loading branch information
someaddons authored Apr 6, 2021
1 parent f0c776c commit 120cb87
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static IColonyManager getInstance()
* @param pos coordinates.
* @return true if so.
*/
boolean isTooCloseToColony(@NotNull World w, @NotNull BlockPos pos);
boolean isFarEnoughFromColonies(@NotNull World w, @NotNull BlockPos pos);

/**
* Get all colonies in this world.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ protected ServerConfiguration(final ForgeConfigSpec.Builder builder)

maxColonySize = defineInteger(builder, "maxColonySize", 20, 1, 50);
minColonyDistance = defineInteger(builder, "minColonyDistance", 8, 1, 200);
initialColonySize = defineInteger(builder, "initialColonySize", 4, 1, 200);
initialColonySize = defineInteger(builder, "initialColonySize", 4, 1, 15);
restrictColonyPlacement = defineBoolean(builder, "restrictcolonyplacement", false);
maxDistanceFromWorldSpawn = defineInteger(builder, "maxdistancefromworldspawn", 8000, 1000, 100000);
minDistanceFromWorldSpawn = defineInteger(builder, "mindistancefromworldspawn", 512, 1, 1000);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,10 @@ public WindowTownHallColonyManage(final PlayerEntity player, final BlockPos pos,
{
findPaneOfTypeByID(TEXT_OWN, Text.class).setText(LanguageHandler.format("com.minecolonies.coremod.gui.colony.none"));

if (existingColony != null || IColonyManager.getInstance().isTooCloseToColony(world, pos))
if (existingColony != null || !IColonyManager.getInstance().isFarEnoughFromColonies(world, pos))
{
findPaneOfTypeByID(TEXT_FEEDBACK, Text.class).setText(LanguageHandler.format("com.minecolonies.coremod.gui.colony.denied.tooclose"));
final IColony colony = IColonyManager.getInstance().getClosestColony(world, pos);
findPaneOfTypeByID(TEXT_FEEDBACK, Text.class).setText(LanguageHandler.format("com.minecolonies.coremod.gui.colony.denied.tooclose", colony.getName()));
}
}

Expand Down
26 changes: 18 additions & 8 deletions src/main/java/com/minecolonies/coremod/colony/ColonyManager.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.minecolonies.coremod.colony;

import com.ldtteam.structurize.util.LanguageHandler;
import com.minecolonies.api.IMinecoloniesAPI;
import com.minecolonies.api.blocks.AbstractBlockHut;
import com.minecolonies.api.colony.*;
import com.minecolonies.api.colony.buildings.IBuilding;
Expand All @@ -11,8 +10,7 @@
import com.minecolonies.api.compatibility.CompatibilityManager;
import com.minecolonies.api.compatibility.ICompatibilityManager;
import com.minecolonies.api.crafting.IRecipeManager;
import com.minecolonies.api.items.ModTags;
import com.minecolonies.api.util.ItemStackUtils;
import com.minecolonies.api.util.BlockPosUtil;
import com.minecolonies.api.util.Log;
import com.minecolonies.apiimp.initializer.ModTagsInitializer;
import com.minecolonies.coremod.MineColonies;
Expand All @@ -21,7 +19,6 @@
import com.minecolonies.coremod.network.messages.client.colony.ColonyViewRemoveMessage;
import com.minecolonies.coremod.util.BackUpHelper;
import com.minecolonies.coremod.util.ChunkDataHelper;
import com.minecolonies.coremod.util.FurnaceRecipes;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
Expand Down Expand Up @@ -301,11 +298,19 @@ public IColony getColonyByPosFromDim(final RegistryKey<World> registryKey, @NotN
}

@Override
public boolean isTooCloseToColony(@NotNull final World w, @NotNull final BlockPos pos)
public boolean isFarEnoughFromColonies(@NotNull final World w, @NotNull final BlockPos pos)
{
return !ChunkDataHelper.canClaimChunksInRange(w,
final int blockRange = Math.max(MineColonies.getConfig().getServer().minColonyDistance.get(), getConfig().getServer().initialColonySize.get()) << 4;
final IColony closest = getClosestColony(w, pos);

if (closest != null && BlockPosUtil.getDistance(pos, closest.getCenter()) < blockRange)
{
return false;
}

return ChunkDataHelper.canClaimChunksInRange(w,
pos,
Math.max(MineColonies.getConfig().getServer().minColonyDistance.get(), getConfig().getServer().initialColonySize.get()));
getConfig().getServer().initialColonySize.get());
}

@Override
Expand Down Expand Up @@ -700,7 +705,12 @@ public void onWorldUnload(@NotNull final World world)
}

@Override
public void handleColonyViewMessage(final int colonyId, @NotNull final PacketBuffer colonyData, @NotNull final World world, final boolean isNewSubscription, final RegistryKey<World> dim)
public void handleColonyViewMessage(
final int colonyId,
@NotNull final PacketBuffer colonyData,
@NotNull final World world,
final boolean isNewSubscription,
final RegistryKey<World> dim)
{
IColonyView view = getColonyView(colonyId, dim);
if (view == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
import net.minecraft.entity.ai.goal.NearestAttackableTargetGoal;
import net.minecraft.entity.monster.EndermanEntity;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.monster.MonsterEntity;
import net.minecraft.entity.passive.horse.LlamaEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
Expand Down Expand Up @@ -79,7 +78,10 @@

import java.time.LocalDateTime;
import java.time.Month;
import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.minecolonies.api.util.constant.NbtTagConstants.TAG_COLONY_ID;
import static com.minecolonies.api.util.constant.NbtTagConstants.TAG_EVENT_ID;
Expand Down Expand Up @@ -147,7 +149,7 @@ public static void onDebugOverlay(final RenderGameOverlayEvent.Text event)
IColony colony = IColonyManager.getInstance().getIColony(world, pos);
if (colony == null)
{
if (!IColonyManager.getInstance().isTooCloseToColony(world, pos))
if (IColonyManager.getInstance().isFarEnoughFromColonies(world, pos))
{
event.getLeft().add(LanguageHandler.format("com.minecolonies.coremod.gui.debugScreen.noCloseColony"));
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,12 @@ else if (spawnDistance > MineColonies.getConfig().getServer().maxDistanceFromWor
}
}

if (colony == null || !IColonyManager.getInstance().isTooCloseToColony(world, townHall))
if (colony != null && !IColonyManager.getInstance().isFarEnoughFromColonies(world, townHall))
{
LanguageHandler.sendPlayerMessage(sender, "com.minecolonies.coremod.gui.colony.denied.tooclose", colony.getName());
return;
}

final IColony ownedColony = IColonyManager.getInstance().getIColonyByOwner(world, sender);

if (ownedColony == null)
Expand All @@ -129,7 +133,6 @@ else if (spawnDistance > MineColonies.getConfig().getServer().maxDistanceFromWor
LanguageHandler.sendPlayerMessage((PlayerEntity) sender, "com.minecolonies.coremod.progress.colony_founded");
return;
}
}

LanguageHandler.sendPlayerMessage((PlayerEntity) sender, "com.minecolonies.coremod.gui.colony.create.failed");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ private static void handleHut(
final IColony tempColony = IColonyManager.getInstance().getClosestColony(world, buildPos);
if (!complete && tempColony != null
&& !tempColony.getPermissions().hasPermission(player, Action.MANAGE_HUTS)
&& !IColonyManager.getInstance().isTooCloseToColony(world, buildPos))
&& IColonyManager.getInstance().isFarEnoughFromColonies(world, buildPos))
{
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ private static void handleHut(
if (tempColony != null
&& (!tempColony.getPermissions().hasPermission(player, Action.MANAGE_HUTS)
&& !(block instanceof BlockHutTownHall
&& !IColonyManager.getInstance().isTooCloseToColony(world, buildPos))))
&& IColonyManager.getInstance().isFarEnoughFromColonies(world, buildPos))))
{
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/assets/minecolonies/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,7 @@
"com.minecolonies.coremod.gui.colony.create.failed": "§l§4Colony creation failed, try somewhere else!",
"com.minecolonies.coremod.gui.colony.denied.existing": "§l§4There is an existing colony you own, delete it before creating a new one.",
"com.minecolonies.coremod.gui.colony.denied.existingandabandon": "§4There is an existing colony you own, delete or abandon it before creating a new one.",
"com.minecolonies.coremod.gui.colony.denied.tooclose": "§l§4There is an existing colony too close.",
"com.minecolonies.coremod.gui.colony.denied.tooclose": "§l§4 Colony %s is too close.",
"com.minecolonies.coremod.gui.colony.allowed.create": "§2You are able to create a new colony here",

"block.minecolonies.composted_dirt": "Composted Dirt",
Expand Down

0 comments on commit 120cb87

Please sign in to comment.