Adds a region-indexed lookup (ClaimLinkBufferIndex), keyed via the game's own WorldManager.MapRegionIndex2D and rebuilt on every registry mutation and on SaveGameLoaded, feeding a block break/place/use gate (ClaimLinkBufferProtection) that denies players who aren't members of the relevant claim link from modifying buffer-zone land. Any existing vanilla claim access (owner, claim's group, explicit permission grant, or AllowUseEveryone) always overrides the buffer check. Bump to 0.4.0.
79 lines
2.2 KiB
C#
79 lines
2.2 KiB
C#
using Vintagestory.API.Common;
|
|
using Vintagestory.API.MathTools;
|
|
using Vintagestory.API.Server;
|
|
|
|
namespace ClaimLink;
|
|
|
|
internal static class ClaimLinkBufferProtection
|
|
{
|
|
internal static void Register(ICoreServerAPI api)
|
|
{
|
|
api.Event.CanPlaceOrBreakBlock += OnCanPlaceOrBreakBlock;
|
|
api.Event.CanUseBlock += OnCanUseBlock;
|
|
}
|
|
|
|
private static bool OnCanUseBlock(IServerPlayer byPlayer, BlockSelection blockSel) =>
|
|
IsAllowed(byPlayer, blockSel.Position, EnumBlockAccessFlags.Use);
|
|
|
|
private static bool OnCanPlaceOrBreakBlock(
|
|
IServerPlayer byPlayer,
|
|
BlockSelection blockSel,
|
|
out string claimant
|
|
)
|
|
{
|
|
bool allowed = IsAllowed(byPlayer, blockSel.Position, EnumBlockAccessFlags.BuildOrBreak);
|
|
claimant = allowed ? null! : "custommessage-claimlink-buffer-zone";
|
|
return allowed;
|
|
}
|
|
|
|
private static bool IsAllowed(
|
|
IServerPlayer byPlayer,
|
|
BlockPos pos,
|
|
EnumBlockAccessFlags accessFlag
|
|
)
|
|
{
|
|
bool allowed = true;
|
|
|
|
foreach (int groupId in ClaimLinkBufferIndex.CandidateGroupIds(pos))
|
|
{
|
|
if (IsMember(byPlayer, groupId))
|
|
continue;
|
|
|
|
foreach (Cuboidi buffer in ClaimLinkBufferIndex.CachedBuffer(groupId))
|
|
if (buffer.Contains(pos))
|
|
allowed = false;
|
|
}
|
|
|
|
return allowed || HasClaimAccess(byPlayer, pos, accessFlag);
|
|
}
|
|
|
|
private static bool IsMember(IServerPlayer player, int groupId)
|
|
{
|
|
foreach (PlayerGroupMembership membership in player.Groups)
|
|
if (membership.GroupUid == groupId)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
private static bool HasClaimAccess(
|
|
IServerPlayer player,
|
|
BlockPos pos,
|
|
EnumBlockAccessFlags accessFlag
|
|
)
|
|
{
|
|
LandClaim[]? claims = ClaimLinkModSystem.LandClaimAPI.Get(pos);
|
|
if (claims == null)
|
|
return false;
|
|
|
|
foreach (LandClaim claim in claims)
|
|
{
|
|
if (claim.TestPlayerAccess(player, accessFlag) != EnumPlayerAccessResult.Denied)
|
|
return true;
|
|
if (accessFlag == EnumBlockAccessFlags.Use && claim.AllowUseEveryone)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|