generated from AriasCreations/vsmodtemplate
234 lines
No EOL
7.2 KiB
C#
234 lines
No EOL
7.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection.Metadata;
|
|
using System.Runtime.ConstrainedExecution;
|
|
using Vintagestory.API.Common;
|
|
using Vintagestory.API.Server;
|
|
|
|
namespace AriasServerUtils
|
|
{
|
|
public enum ModConfigType
|
|
{
|
|
Global,
|
|
World
|
|
}
|
|
|
|
[Serializable]
|
|
public class ASUModConfig
|
|
{
|
|
private readonly static Dictionary<CooldownType, string> m_defaultCD = new Dictionary<CooldownType, string>{
|
|
|
|
{ CooldownType.Home, "5s" },
|
|
{ CooldownType.Warp, "10s" },
|
|
{ CooldownType.Spawn, "5s" },
|
|
{ CooldownType.RTP, "30s" },
|
|
{ CooldownType.Back, "5s" }
|
|
};
|
|
private static readonly int CURRENT_VERSION = 7;
|
|
|
|
|
|
public int Version { get; set; } = 0;
|
|
public int MaxHomes { get; set; } = 20;
|
|
public bool AdminsBypassMaxHomes { get; set; } = true;
|
|
public bool onlyAdminsCreateWarps { get; set; } = true;
|
|
public bool AdminsBypassCooldowns { get; set; } = true;
|
|
public bool AdminsBypassRTPMaxDistance { get; set; } = false;
|
|
public int MaxBackCache { get; set; } = 10;
|
|
public int PlayerSleepingPercentage { get; set; } = 50;
|
|
public int MaxRTPBlockDistance { get; set; } = 50000;
|
|
public Dictionary<CooldownType, string> Cooldowns { get; set; } = new Dictionary<CooldownType, string>();
|
|
public Costs costs { get; set; } = new Costs();
|
|
|
|
|
|
/// <summary>
|
|
/// If true, attempts to downgrade the soil quality when breaking farmland.
|
|
/// </summary>
|
|
public bool EnableFarmlandDowngrade { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// If true, farmland will drop as soil when broken.
|
|
/// </summary>
|
|
public bool EnableFarmlandDrop { get; set; } = true;
|
|
|
|
public Dictionary<CooldownType, string> GetDefaultCooldowns()
|
|
{
|
|
return m_defaultCD;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs some checks against known possible invalid values and sets them to sane values.
|
|
/// </summary>
|
|
public void SanityCheck()
|
|
{
|
|
foreach (var cd in GetDefaultCooldowns())
|
|
{
|
|
if (!Cooldowns.ContainsKey(cd.Key))
|
|
{
|
|
Cooldowns.Add(cd.Key, cd.Value);
|
|
ServerUtilities.MarkDirty();
|
|
}
|
|
}
|
|
|
|
if (Version < CURRENT_VERSION)
|
|
{
|
|
Version = CURRENT_VERSION;
|
|
ServerUtilities.MarkDirty(); // This is here to ensure that the config gets saved when there is a update. Whenever a new field is added to config, the CURRENT_VERSION should get bumped so that this SanityCheck can properly work
|
|
}
|
|
|
|
// Sanity check costs config
|
|
bool checkCostDefaults = false;
|
|
if (costs == null)
|
|
{
|
|
costs = new Costs(); // Initialize a brand new costs object
|
|
checkCostDefaults = true;
|
|
}
|
|
else if (costs.costs.Count != Costs.defaults.Count) checkCostDefaults = true;
|
|
|
|
if (checkCostDefaults)
|
|
{
|
|
|
|
foreach (var def in Costs.defaults)
|
|
{
|
|
if (!costs.costs.ContainsKey(def.Key))
|
|
{
|
|
costs.costs.Add(def.Key, def.Value);
|
|
}
|
|
}
|
|
|
|
ServerUtilities.MarkDirty();
|
|
}
|
|
}
|
|
|
|
|
|
public PlayerPosition Spawn { get; set; }
|
|
}
|
|
|
|
[Serializable]
|
|
public enum CooldownType
|
|
{
|
|
Home, // Default: 5s
|
|
Warp, // Default 10s
|
|
Spawn, // Default 5s
|
|
RTP, // Default 30s
|
|
Back // Default 5s
|
|
}
|
|
|
|
[Serializable]
|
|
public class Warp
|
|
{
|
|
public PlayerPosition Location;
|
|
public string CreatedBy;
|
|
public DateTime CreatedAt;
|
|
public bool CanHaveMount = false;
|
|
|
|
|
|
public static Warp Create(IServerPlayer player, bool withMount = false)
|
|
{
|
|
Warp warp = new Warp();
|
|
warp.Location = PlayerPosition.from(player.Entity);
|
|
warp.CreatedBy = player.PlayerName;
|
|
warp.CreatedAt = DateTime.Now;
|
|
warp.CanHaveMount = withMount;
|
|
|
|
return warp;
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class Warps
|
|
{
|
|
public Dictionary<string, Warp> warps = new Dictionary<string, Warp>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// This contains per command costs, as well as helper functions that can refund a player, or check if the player has the required balance, or payment
|
|
///
|
|
/// </summary>
|
|
[Serializable]
|
|
public class Costs
|
|
{
|
|
public enum CostType
|
|
{
|
|
sethome,
|
|
home,
|
|
delhome,
|
|
sethomemount,
|
|
warp,
|
|
setwarp,
|
|
delwarp,
|
|
spawn
|
|
}
|
|
public Dictionary<CostType, int> costs = new Dictionary<CostType, int>();
|
|
public static readonly Dictionary<CostType, int> defaults = new Dictionary<CostType, int>()
|
|
{
|
|
{ CostType.sethome, 0 },
|
|
{ CostType.home, 0 },
|
|
{ CostType.delhome, 0 },
|
|
{ CostType.sethomemount, 10 },
|
|
{ CostType.setwarp, 5 },
|
|
{ CostType.warp, 1 },
|
|
{ CostType.delwarp, 5 },
|
|
{ CostType.spawn, 0 }
|
|
};
|
|
|
|
/// <summary>
|
|
/// Checks if the player has the balance required to use the command
|
|
/// </summary>
|
|
/// <param name="cmd">The command the player is trying to use</param>
|
|
/// <param name="player">The player</param>
|
|
/// <returns>True if the player has the required balance</returns>
|
|
public bool PlayerHasBalance(CostType cmd, EntityPlayer player)
|
|
{
|
|
int gears = 0;
|
|
int required = 0;
|
|
if (costs.ContainsKey(cmd))
|
|
{
|
|
// Get the cost for that command
|
|
required = costs[cmd];
|
|
}
|
|
|
|
// Scan the player inventory, check gears
|
|
|
|
|
|
|
|
|
|
if (gears >= required) return true;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
public class BackCaches
|
|
{
|
|
private const int MaxCacheSize = 10;
|
|
private readonly Dictionary<string, LinkedList<PlayerPosition>> playerCache = new();
|
|
|
|
public void AddPosition(string playerName, PlayerPosition position)
|
|
{
|
|
if (!playerCache.TryGetValue(playerName, out var positions))
|
|
{
|
|
positions = new LinkedList<PlayerPosition>();
|
|
playerCache[playerName] = positions;
|
|
}
|
|
|
|
if (positions.Count >= MaxCacheSize)
|
|
{
|
|
positions.RemoveFirst(); // Remove the oldest position
|
|
}
|
|
|
|
positions.AddLast(position.Clone()); // Add the new position
|
|
}
|
|
|
|
public PlayerPosition ReadAndPopNewestPosition(string playerName)
|
|
{
|
|
if (playerCache.TryGetValue(playerName, out var positions) && positions.Count > 0)
|
|
{
|
|
var newestPosition = positions.Last.Value;
|
|
positions.RemoveLast(); // Remove the newest position
|
|
return newestPosition;
|
|
}
|
|
|
|
return null; // Return null if no positions are available
|
|
}
|
|
}
|
|
} |