Skip to content

Commit

Permalink
added anti-vault-spam to prevent client-side graphical glitches when …
Browse files Browse the repository at this point in the history
…spammed
  • Loading branch information
ShimmyMySherbet committed Dec 4, 2022
1 parent 3379938 commit ae7c1a3
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 26 deletions.
64 changes: 38 additions & 26 deletions SherbetVaults/Commands/VaultCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Rocket.API;
using RocketExtensions.Models;
using RocketExtensions.Plugins;
using SherbetVaults.Models;
using SherbetVaults.Models.Enums;

namespace SherbetVaults.Commands
Expand All @@ -11,43 +12,54 @@ namespace SherbetVaults.Commands
[AllowedCaller(AllowedCaller.Player)]
public class VaultCommand : RocketCommand
{
private VaultPlayerLock PlayerLock { get; } = new VaultPlayerLock();

public override async UniTask Execute(CommandContext context)
{
var targetVault = context.Arguments.Get(0, defaultValue: string.Empty, paramName: "Vault Name");

var (vaultConfig, availability) = await Plugin.VaultSelector.GetVault(context.LDMPlayer, targetVault);

switch (availability)
using (PlayerLock.TryObtainLock(context.PlayerID, out var valid))
{
case EVaultAvailability.BadVaultID:
await context.ReplyKeyAsync("Vault_Fail_NotFound", targetVault);
if (!valid)
{
// This player is already opening a vault.
return;
}

case EVaultAvailability.NotAllowed:
await context.ReplyKeyAsync("Vault_Fail_NoPermission", targetVault);
return;
var targetVault = context.Arguments.Get(0, defaultValue: string.Empty, paramName: "Vault Name");

var (vaultConfig, availability) = await Plugin.VaultSelector.GetVault(context.LDMPlayer, targetVault);

switch (availability)
{
case EVaultAvailability.BadVaultID:
await context.ReplyKeyAsync("Vault_Fail_NotFound", targetVault);
return;

case EVaultAvailability.NotAllowed:
await context.ReplyKeyAsync("Vault_Fail_NoPermission", targetVault);
return;

case EVaultAvailability.NoVaults:
case EVaultAvailability.NoAllowedVaults:
await context.ReplyKeyAsync("Vaults_No_Vaults");
case EVaultAvailability.NoVaults:
case EVaultAvailability.NoAllowedVaults:
await context.ReplyKeyAsync("Vaults_No_Vaults");
return;
}

if (vaultConfig == null)
{
await context.ReplyKeyAsync("Vault_Fail_CannotLoad", targetVault);
return;
}
}

if (vaultConfig == null)
{
await context.ReplyKeyAsync("Vault_Fail_CannotLoad", targetVault);
return;
}
var vault = await Plugin.VaultManager.GetVault(context.PlayerID, vaultConfig.VaultID);

var vault = await Plugin.VaultManager.GetVault(context.PlayerID, vaultConfig.VaultID);
if (vault == null)
{
await context.ReplyKeyAsync("Vault_Fail_CannotLoad", vaultConfig.VaultID);
return;
}

if (vault == null)
{
await context.ReplyKeyAsync("Vault_Fail_CannotLoad", vaultConfig.VaultID);
return;
await vault.OpenForPlayerAsync(context.LDMPlayer);
}

await vault.OpenForPlayerAsync(context.LDMPlayer);
}

private new SherbetVaultsPlugin Plugin =>
Expand Down
57 changes: 57 additions & 0 deletions SherbetVaults/Models/VaultPlayerLock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Collections.Concurrent;

namespace SherbetVaults.Models
{
/// <summary>
/// Helps prevent client-side graphical item graphical glitches if a player spams the vault command.
/// </summary>
public class VaultPlayerLock
{
public ConcurrentDictionary<ulong, bool> m_PlayerBlocks = new ConcurrentDictionary<ulong, bool>();

public OpenBlockToken TryObtainLock(ulong player, out bool valid)
{
if (m_PlayerBlocks.TryGetValue(player, out var blocked))
{
if (blocked)
{
valid = false;
return default;
}
}
m_PlayerBlocks[player] = true;
valid = true;
return new OpenBlockToken(player, this);
}

private void Release(ulong player)
{
m_PlayerBlocks[player] = false;
}

public struct OpenBlockToken : IDisposable
{
public ulong PlayerID { get; }
private VaultPlayerLock Parent { get; }

private bool Disposed;

public OpenBlockToken(ulong playerID, VaultPlayerLock parent)
{
Disposed = false;
PlayerID = playerID;
Parent = parent;
}

public void Dispose()
{
if (!Disposed)
{
Disposed = true;
Parent?.Release(PlayerID);
}
}
}
}
}
1 change: 1 addition & 0 deletions SherbetVaults/SherbetVaults.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@
<Compile Include="Models\Utility\VaultSelector.cs" />
<Compile Include="Models\Data\VaultItems.cs" />
<Compile Include="Models\VaultManager.cs" />
<Compile Include="Models\VaultPlayerLock.cs" />
<Compile Include="Models\VaultStoreDeniedException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SherbetVaultsPlugin.cs" />
Expand Down

0 comments on commit ae7c1a3

Please sign in to comment.