Compare commits
1
Commits
a03219c114
...
c1158d50c3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1158d50c3 |
@@ -34,4 +34,10 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="assets\**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
using Vintagestory.API.MathTools;
|
||||
|
||||
namespace ClaimLink;
|
||||
|
||||
internal static class ClaimLinkBufferIndex
|
||||
{
|
||||
private static readonly Dictionary<long, HashSet<int>> groupIdsByRegion = new();
|
||||
private static readonly Dictionary<int, List<Cuboidi>> buffersByGroupId = new();
|
||||
|
||||
internal static void Rebuild()
|
||||
{
|
||||
groupIdsByRegion.Clear();
|
||||
buffersByGroupId.Clear();
|
||||
|
||||
int regionSize = ClaimLinkModSystem.WorldManager.RegionSize;
|
||||
if (regionSize <= 0)
|
||||
return;
|
||||
|
||||
foreach (int groupId in ClaimLinkModSystem.Registry.All)
|
||||
{
|
||||
List<Cuboidi> buffers = ClaimLinkBuffer.GetBuffer(groupId);
|
||||
buffersByGroupId[groupId] = buffers;
|
||||
|
||||
HashSet<long> regionKeys = new();
|
||||
foreach (Cuboidi buffer in buffers)
|
||||
{
|
||||
int minRegionX = buffer.MinX / regionSize;
|
||||
int maxRegionX = buffer.MaxX / regionSize;
|
||||
int minRegionZ = buffer.MinZ / regionSize;
|
||||
int maxRegionZ = buffer.MaxZ / regionSize;
|
||||
|
||||
for (int rx = minRegionX; rx <= maxRegionX; rx++)
|
||||
for (int rz = minRegionZ; rz <= maxRegionZ; rz++)
|
||||
regionKeys.Add(ClaimLinkModSystem.WorldManager.MapRegionIndex2D(rx, rz));
|
||||
}
|
||||
|
||||
foreach (long regionKey in regionKeys)
|
||||
{
|
||||
if (!groupIdsByRegion.TryGetValue(regionKey, out HashSet<int>? groupIds))
|
||||
groupIdsByRegion[regionKey] = groupIds = new();
|
||||
groupIds.Add(groupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static IEnumerable<int> CandidateGroupIds(BlockPos pos)
|
||||
{
|
||||
int regionSize = ClaimLinkModSystem.WorldManager.RegionSize;
|
||||
if (regionSize <= 0)
|
||||
return System.Array.Empty<int>();
|
||||
|
||||
long regionKey = ClaimLinkModSystem.WorldManager.MapRegionIndex2D(
|
||||
pos.X / regionSize,
|
||||
pos.Z / regionSize
|
||||
);
|
||||
|
||||
return groupIdsByRegion.TryGetValue(regionKey, out HashSet<int>? groupIds)
|
||||
? groupIds
|
||||
: System.Array.Empty<int>();
|
||||
}
|
||||
|
||||
internal static List<Cuboidi> CachedBuffer(int groupId) =>
|
||||
buffersByGroupId.TryGetValue(groupId, out List<Cuboidi>? buffers)
|
||||
? buffers
|
||||
: new List<Cuboidi>();
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ public class ClaimLinkModSystem : ModSystem
|
||||
internal static ClaimLinkRegistry Registry = null!;
|
||||
internal static IGroupManager Groups = null!;
|
||||
internal static IWorldAccessor World = null!;
|
||||
internal static IWorldManagerAPI WorldManager = null!;
|
||||
internal static IPlayerDataManager PlayerData = null!;
|
||||
internal static ClaimLinkConfig Config = null!;
|
||||
internal CommandListener? CmdListener;
|
||||
@@ -23,12 +24,15 @@ public class ClaimLinkModSystem : ModSystem
|
||||
{
|
||||
LandClaimAPI = api.World.Claims;
|
||||
World = api.World;
|
||||
WorldManager = api.WorldManager;
|
||||
Groups = api.Groups;
|
||||
Logger = api.Logger;
|
||||
PlayerData = api.PlayerData;
|
||||
Config = api.LoadModConfig<ClaimLinkConfig>("claimlink.json") ?? new ClaimLinkConfig();
|
||||
api.StoreModConfig(Config, "claimlink.json");
|
||||
Registry = new ClaimLinkRegistry(api.WorldManager.SaveGame);
|
||||
ClaimLinkBufferIndex.Rebuild();
|
||||
api.Event.SaveGameLoaded += ClaimLinkBufferIndex.Rebuild;
|
||||
|
||||
CmdListener = new CommandListener();
|
||||
CommandHookModSystem.Register(CmdListener);
|
||||
@@ -36,6 +40,7 @@ public class ClaimLinkModSystem : ModSystem
|
||||
CommandHookModSystem.Register(GroupCmdListener);
|
||||
ClaimLinkChatCommand.Register(api);
|
||||
ClaimLinkVisualizerNetwork.Start(api);
|
||||
ClaimLinkBufferProtection.Register(api);
|
||||
|
||||
api.Event.PlayerDisconnect += CommandListener.OnPlayerDisconnect;
|
||||
api.Event.PlayerDisconnect += GroupCommandListener.OnPlayerDisconnect;
|
||||
|
||||
@@ -197,5 +197,7 @@ public class ClaimLinkRegistry
|
||||
SaveKey,
|
||||
new ClaimLinkSaveData { Links = claimLinks, Entries = entryList }
|
||||
);
|
||||
|
||||
ClaimLinkBufferIndex.Rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,10 @@ public class CommandListener : ICommandHookListener
|
||||
);
|
||||
|
||||
if (!violatesClaimLink && !violatesClaim)
|
||||
{
|
||||
ClaimLinkBufferIndex.Rebuild();
|
||||
return;
|
||||
}
|
||||
|
||||
ClaimLinkModSystem.LandClaimAPI.Remove(savedClaim);
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"custommessage-claimlink-buffer-zone": "This area is a claim link buffer zone.",
|
||||
"ingameerror-noprivilege-buildbreak-claimlink-buffer-zone": "This area is a claim link buffer zone."
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"anth64"
|
||||
],
|
||||
"description": "Link claims together with groups.",
|
||||
"version": "0.3.0",
|
||||
"version": "0.4.0",
|
||||
"dependencies": {
|
||||
"game": "1.22.5",
|
||||
"commandhook": "2.1.0"
|
||||
|
||||
Reference in New Issue
Block a user