mirror of
https://github.com/edgegamers/Gangs.git
synced 2025-12-05 20:40:30 -08:00
More work
This commit is contained in:
@@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CS2", "CS2", "{AC07CD29-5C9
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Commands", "Commands\Commands.csproj", "{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stats", "GangsImpl\Stats\Stats.csproj", "{BA8D993B-754E-4BB4-B103-482A4F779404}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -58,6 +60,10 @@ Global
|
||||
{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BA8D993B-754E-4BB4-B103-482A4F779404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BA8D993B-754E-4BB4-B103-482A4F779404}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BA8D993B-754E-4BB4-B103-482A4F779404}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BA8D993B-754E-4BB4-B103-482A4F779404}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{1899055E-62B8-4907-85A2-DFE22531729E} = {3AB7703F-880F-4A41-96EE-B891FA888C65}
|
||||
@@ -66,5 +72,6 @@ Global
|
||||
{140E1706-30E8-4440-AAA0-56E8DD32F054} = {3AB7703F-880F-4A41-96EE-B891FA888C65}
|
||||
{3EA38296-9022-4874-8309-872388D884DE} = {AC07CD29-5C9D-4AD1-99C7-01DABAB8D0EC}
|
||||
{C7DF1D47-8D2B-4651-98AB-AEEBE5860ECA} = {AC07CD29-5C9D-4AD1-99C7-01DABAB8D0EC}
|
||||
{BA8D993B-754E-4BB4-B103-482A4F779404} = {3AB7703F-880F-4A41-96EE-B891FA888C65}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -37,70 +37,6 @@ public interface IGang : IEqualityComparer<IGang>, IEquatable<IGang>,
|
||||
=> Members.First(m => m.Value.Perms.HasFlag(IGangRank.Permissions.OWNER))
|
||||
.Key;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of currency the gang has in its bank.
|
||||
/// </summary>
|
||||
int? Bank {
|
||||
get {
|
||||
var stat = GetStat("gang_bank") as IStat<int>;
|
||||
return stat?.Value;
|
||||
}
|
||||
|
||||
set {
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
if (GetStat("gang_bank") is IStat<int> stat) stat.Value = value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The set of perks the gang has.
|
||||
/// </summary>
|
||||
ISet<IStat> Perks { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of statistics the gang has.
|
||||
/// </summary>
|
||||
ISet<IStat> Stats { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The gang's capacity. Underlying implementation
|
||||
/// should be a perk with the id "gang_capacity".
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
int? GangCapacity {
|
||||
get {
|
||||
var perk = GetPerk("gang_capacity") as IGangStat<int>;
|
||||
return perk?.Value;
|
||||
}
|
||||
|
||||
set {
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
|
||||
if (GetPerk("gang_capacity") is IGangStat<int> perk)
|
||||
perk.Value = value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The gang's "message of the day".
|
||||
/// Underlying implementation should be a perk with the id "gang_motd".
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
string? MOTD {
|
||||
get {
|
||||
var perk = GetPerk("gang_motd") as IGangStat<string>;
|
||||
return perk?.Value;
|
||||
}
|
||||
|
||||
set {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException(nameof(value),
|
||||
"To un-set MOTD, remove the perk from the gang.");
|
||||
|
||||
if (GetPerk("gang_motd") is IGangStat<string> perk) perk.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return Members.Keys.GetEnumerator();
|
||||
}
|
||||
@@ -122,12 +58,4 @@ public interface IGang : IEqualityComparer<IGang>, IEquatable<IGang>,
|
||||
if (other is null) return false;
|
||||
return GangId == other.GangId;
|
||||
}
|
||||
|
||||
IStat? GetPerk(string perkId) {
|
||||
return Perks.FirstOrDefault(p => p.StatId.Equals(perkId));
|
||||
}
|
||||
|
||||
IStat? GetStat(string statId) {
|
||||
return Stats.FirstOrDefault(s => s.StatId.Equals(statId));
|
||||
}
|
||||
}
|
||||
@@ -27,39 +27,4 @@ public interface IGangPlayer {
|
||||
/// The rank the player has in the gang (if in one).
|
||||
/// </summary>
|
||||
IGangRank? Rank { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The last time the player was seen by the plugin.
|
||||
/// </summary>
|
||||
DateTime? LastSeen {
|
||||
get {
|
||||
var stat = GetStat("gang_native_lastseen") as IStat<DateTime>;
|
||||
return stat?.Value;
|
||||
}
|
||||
|
||||
set {
|
||||
if (GetStat("gang_native_lastseen") is IStat<DateTime?> stat)
|
||||
stat.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
ISet<IStat> Stats { get; }
|
||||
ISet<IStat> Perks { get; }
|
||||
|
||||
int? Balance {
|
||||
get {
|
||||
var stat = GetStat("gang_native_balance") as IStat<int>;
|
||||
return stat?.Value;
|
||||
}
|
||||
|
||||
set {
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
if (GetStat("gang_native_balance") is IStat<int> stat)
|
||||
stat.Value = value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
IStat? GetStat(string statId) {
|
||||
return Stats.FirstOrDefault(stat => stat.StatId == statId);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace GangsAPI.Data.Stat;
|
||||
|
||||
public interface IGangStat<T> : IStat<T> { }
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace GangsAPI.Data.Stat;
|
||||
|
||||
public interface IPlayerStat<T> : IStat<T> { }
|
||||
@@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// Represents a numerical statistic.
|
||||
/// </summary>
|
||||
public interface IStat : IEqualityComparer<IStat>, IEquatable<IStat> {
|
||||
public interface IStat : IEquatable<IStat> {
|
||||
/// <summary>
|
||||
/// The unique identifier of the statistic.
|
||||
/// </summary>
|
||||
@@ -19,15 +19,6 @@ public interface IStat : IEqualityComparer<IStat>, IEquatable<IStat> {
|
||||
/// </summary>
|
||||
string? Description { get; }
|
||||
|
||||
bool IEqualityComparer<IStat>.Equals(IStat? x, IStat? y) {
|
||||
if (x is null || y is null) return false;
|
||||
return x.StatId == y.StatId;
|
||||
}
|
||||
|
||||
int IEqualityComparer<IStat>.GetHashCode(IStat obj) {
|
||||
return obj.StatId.GetHashCode();
|
||||
}
|
||||
|
||||
bool IEquatable<IStat>.Equals(IStat? other) {
|
||||
if (other is null) return false;
|
||||
return StatId == other.StatId;
|
||||
|
||||
@@ -5,10 +5,15 @@ using GangsAPI.Data.Stat;
|
||||
namespace GangsAPI.Services;
|
||||
|
||||
public interface IGangStatManager : ICacher {
|
||||
Task<IGangStat<V>?> GetForGang<V>(int key, string id);
|
||||
Task<IStat<V>?> GetForGang<V>(int key, string id);
|
||||
Task<IStat?> GetForGang(int key, string id);
|
||||
Task<bool> PushToGang<V>(int gangId, string id, V value);
|
||||
|
||||
Task<IGangStat<V>?> GetForGang<V>(IGang gang, string id) {
|
||||
Task<IStat?> GetForGang(IGang gang, string id) {
|
||||
return GetForGang(gang.GangId, id);
|
||||
}
|
||||
|
||||
Task<IStat<V>?> GetForGang<V>(IGang gang, string id) {
|
||||
return GetForGang<V>(gang.GangId, id);
|
||||
}
|
||||
|
||||
@@ -16,10 +21,6 @@ public interface IGangStatManager : ICacher {
|
||||
return PushToGang(gang.GangId, id, value);
|
||||
}
|
||||
|
||||
Task<IGangStat<V>?> GetForGang<V>(IGang gang, IStat stat, V value) {
|
||||
return GetForGang<V>(gang, stat.StatId);
|
||||
}
|
||||
|
||||
Task<bool> PushToGang<V>(IGang gang, IStat stat, V value) {
|
||||
return PushToGang(gang, stat.StatId, value);
|
||||
}
|
||||
@@ -32,15 +33,15 @@ public interface IGangStatManager : ICacher {
|
||||
return PushToGang(gang, stat.StatId, stat.Value);
|
||||
}
|
||||
|
||||
Task<IGangStat<V>?> GetForGang<V>(int key, IStat stat, V value) {
|
||||
return GetForGang<V>(key, stat.StatId);
|
||||
}
|
||||
|
||||
Task<bool> PushToGang<V>(int gangId, IStat stat, V value) {
|
||||
return PushToGang(gangId, stat.StatId, value);
|
||||
}
|
||||
|
||||
Task<IGangStat<V>?> GetForGang<V>(IGang gang, IStat stat) {
|
||||
Task<IStat?> GetForGang(IGang gang, IStat stat) {
|
||||
return GetForGang(gang, stat.StatId);
|
||||
}
|
||||
|
||||
Task<IStat<V>?> GetForGang<V>(IGang gang, IStat<V> stat) {
|
||||
return GetForGang<V>(gang, stat.StatId);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@ using GangsAPI.Data.Stat;
|
||||
namespace GangsAPI.Services;
|
||||
|
||||
public interface IPlayerStatManager : IPluginBehavior, ICacher {
|
||||
Task<IPlayerStat<V>?> GetForPlayer<V>(ulong key, string statId);
|
||||
Task<IStat<V>?> GetForPlayer<V>(ulong key, string statId);
|
||||
|
||||
Task<bool> PushToPlayer<V>(ulong key, IPlayerStat<V> value) {
|
||||
Task<bool> PushToPlayer<V>(ulong key, IStat<V> value) {
|
||||
return PushToPlayer(key, value.StatId, value.Value);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ public interface IStatManager : IPluginBehavior, ICacher {
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<IStat?> GetStat(string id);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a statistic with the manager, but does not register it.
|
||||
/// If the statistic already exists with the same ID,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using GangsAPI.Data.Gang;
|
||||
using GangsAPI.Data.Stat;
|
||||
using GangsAPI.Permissions;
|
||||
using Mock;
|
||||
|
||||
@@ -10,19 +9,15 @@ namespace GenericDB;
|
||||
/// </summary>
|
||||
public class DBGang : MockGang {
|
||||
public DBGang(int id, string name, ulong owner,
|
||||
IDictionary<ulong, IGangRank> members, ISet<IGangRank> ranks,
|
||||
ISet<IStat> perks, ISet<IStat> stats) : base(id, name, owner) {
|
||||
IDictionary<ulong, IGangRank> members, ISet<IGangRank> ranks) : base(id,
|
||||
name, owner) {
|
||||
Members = members;
|
||||
Ranks = ranks;
|
||||
Perks = perks;
|
||||
Stats = stats;
|
||||
}
|
||||
|
||||
public DBGang(IGang gang) : base(gang.GangId, gang.Name, gang.Owner) {
|
||||
Members = gang.Members;
|
||||
Ranks = gang.Ranks;
|
||||
Perks = gang.Perks;
|
||||
Stats = gang.Stats;
|
||||
}
|
||||
|
||||
public DBGang(int id, string name, ulong owner) : base(id, name, owner) { }
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using GangsAPI.Data.Stat;
|
||||
|
||||
namespace Mock;
|
||||
|
||||
public class MockBankStat : IGangStat<int> {
|
||||
public string StatId => "gang_bank";
|
||||
public string Name => "Mock Bank";
|
||||
public string? Description => "The balance of the gang's bank.";
|
||||
public int Value { get; set; } = 0;
|
||||
}
|
||||
@@ -10,12 +10,20 @@ public class MockInstanceStatManager(IStatManager mgr)
|
||||
private readonly Dictionary<ulong, Dictionary<string, IStat>>
|
||||
playerStats = [];
|
||||
|
||||
public Task<IGangStat<V>?> GetForGang<V>(int key, string id) {
|
||||
public Task<IStat<V>?> GetForGang<V>(int key, string id) {
|
||||
if (!gangStats.TryGetValue(key, out var gangStatMap))
|
||||
return Task.FromResult<IGangStat<V>?>(null);
|
||||
return Task.FromResult<IStat<V>?>(null);
|
||||
if (!gangStatMap.TryGetValue(id, out var result))
|
||||
return Task.FromResult<IGangStat<V>?>(null);
|
||||
return Task.FromResult(result as IGangStat<V>);
|
||||
return Task.FromResult<IStat<V>?>(null);
|
||||
return Task.FromResult(result as IStat<V>);
|
||||
}
|
||||
|
||||
public Task<IStat?> GetForGang(int key, string id) {
|
||||
if (!gangStats.TryGetValue(key, out var gangStatMap))
|
||||
return Task.FromResult<IStat?>(null);
|
||||
if (!gangStatMap.TryGetValue(id, out var result))
|
||||
return Task.FromResult<IStat?>(null);
|
||||
return Task.FromResult(result)!;
|
||||
}
|
||||
|
||||
public async Task<bool> PushToGang<V>(int gangId, string id, V value) {
|
||||
@@ -23,16 +31,16 @@ public class MockInstanceStatManager(IStatManager mgr)
|
||||
gangStats[gangId] = gangStatMap = new Dictionary<string, IStat>();
|
||||
var stat = await mgr.GetStat(id);
|
||||
if (stat == null) return false;
|
||||
gangStatMap[id] = new MockGangStat<V>(stat, value);
|
||||
gangStatMap[id] = new MockStat<V>(stat, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Task<IPlayerStat<V>?> GetForPlayer<V>(ulong key, string id) {
|
||||
public Task<IStat<V>?> GetForPlayer<V>(ulong key, string id) {
|
||||
if (!playerStats.TryGetValue(key, out var playerStatMap))
|
||||
return Task.FromResult<IPlayerStat<V>?>(null);
|
||||
return Task.FromResult<IStat<V>?>(null);
|
||||
if (!playerStatMap.TryGetValue(id, out var result))
|
||||
return Task.FromResult<IPlayerStat<V>?>(null);
|
||||
return Task.FromResult(result as IPlayerStat<V>);
|
||||
return Task.FromResult<IStat<V>?>(null);
|
||||
return Task.FromResult(result as IStat<V>);
|
||||
}
|
||||
|
||||
public async Task<bool> PushToPlayer<V>(ulong key, string id, V value) {
|
||||
@@ -40,7 +48,7 @@ public class MockInstanceStatManager(IStatManager mgr)
|
||||
playerStats[key] = playerStatMap = new Dictionary<string, IStat>();
|
||||
var stat = await mgr.GetStat(id);
|
||||
if (stat == null) return false;
|
||||
playerStatMap[id] = new MockPlayerStat<V>(stat, value);
|
||||
playerStatMap[id] = new MockStat<V>(stat, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,34 +2,37 @@ using GangsAPI.Data.Stat;
|
||||
|
||||
namespace Mock;
|
||||
|
||||
public class MockStat(string statId, string name, string? desc = null) : IStat {
|
||||
public class MockStat(string statId, string name, string? desc = null)
|
||||
: IStat, IEquatable<MockStat> {
|
||||
public string StatId { get; } = statId;
|
||||
public string Name { get; } = name;
|
||||
public string? Description { get; } = desc;
|
||||
|
||||
public bool Equals(MockStat? other) {
|
||||
return other is not null && ((IStat)this).Equals(other);
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj) { return Equals(obj as MockStat); }
|
||||
|
||||
public override int GetHashCode() { return HashCode.Combine(StatId); }
|
||||
}
|
||||
|
||||
public class MockStat<KType, VType>(string statId, string name, string? desc,
|
||||
KType key, VType value) : MockStat(statId, name, desc) {
|
||||
public MockStat(IStat b, KType key, VType value) : this(b.StatId, b.Name,
|
||||
b.Description, key, value) { }
|
||||
|
||||
public KType Key { get; init; } = key;
|
||||
public VType Value { get; set; } = value;
|
||||
}
|
||||
|
||||
public class MockPlayerStat<VType>(string statId, string name, string? desc,
|
||||
VType value) : MockStat(statId, name, desc), IPlayerStat<VType> {
|
||||
public MockPlayerStat(IStat b, VType value) : this(b.StatId, b.Name,
|
||||
b.Description, value) { }
|
||||
|
||||
public ulong Key { get; init; }
|
||||
public VType Value { get; set; } = value;
|
||||
}
|
||||
|
||||
public class MockGangStat<T>(string statId, string name, string? desc, T value)
|
||||
: MockStat(statId, name, desc), IGangStat<T> {
|
||||
public MockGangStat(IStat b, T value) : this(b.StatId, b.Name, b.Description,
|
||||
public class MockStat<VType>(string statId, string name, string? desc,
|
||||
VType value) : MockStat(statId, name, desc), IEquatable<MockStat<VType>> {
|
||||
public MockStat(IStat b, VType value) : this(b.StatId, b.Name, b.Description,
|
||||
value) { }
|
||||
|
||||
public T Value { get; set; } = value;
|
||||
public VType Value { get; set; } = value;
|
||||
|
||||
public bool Equals(MockStat<VType>? other) {
|
||||
return other is not null && base.Equals(other);
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj) {
|
||||
return Equals(obj as MockStat<VType>);
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return HashCode.Combine(base.GetHashCode());
|
||||
}
|
||||
}
|
||||
10
GangsImpl/Stats/GangBankStat.cs
Normal file
10
GangsImpl/Stats/GangBankStat.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using GangsAPI.Data.Stat;
|
||||
|
||||
namespace Stats;
|
||||
|
||||
public class GangBankStat : IStat<int> {
|
||||
public string StatId => "gang_native_bank";
|
||||
public string Name => "Gang Bank";
|
||||
public string? Description => "The amount of money in the gang's bank.";
|
||||
public int Value { get; set; } = 0;
|
||||
}
|
||||
13
GangsImpl/Stats/Stats.csproj
Normal file
13
GangsImpl/Stats/Stats.csproj
Normal file
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\GangsAPI\GangsAPI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
using GangsAPI.Data.Command;
|
||||
using GangsAPI.Services.Commands;
|
||||
|
||||
namespace GangsTest.Commands.CommandLogic;
|
||||
namespace GangsTest.Commands;
|
||||
|
||||
public class LogicTests : ManagerTests.ManagerTests {
|
||||
[Theory]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using GangsAPI.Data.Command;
|
||||
using GangsAPI.Services.Commands;
|
||||
|
||||
namespace GangsTest.Commands.CommandPerms;
|
||||
namespace GangsTest.Commands;
|
||||
|
||||
public class PermissionTests : ManagerTests.ManagerTests {
|
||||
[Theory]
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
using GangsAPI.Data.Stat;
|
||||
using GangsAPI.Services;
|
||||
using GangsTest.GangTests;
|
||||
using Mock;
|
||||
|
||||
namespace GangsTest.GangBankTests;
|
||||
|
||||
public class GangBankTest {
|
||||
private readonly IStat bankStat = new MockBankStat();
|
||||
private readonly IGangManager gangManager;
|
||||
private readonly IGangStatManager gangStatManager;
|
||||
private readonly IStatManager statManager;
|
||||
|
||||
public GangBankTest(IGangManager gangManager, IStatManager statManager,
|
||||
IGangStatManager gangStatManager) {
|
||||
this.gangManager = gangManager;
|
||||
this.statManager = statManager;
|
||||
this.gangStatManager = gangStatManager;
|
||||
|
||||
Assert.True(
|
||||
this.statManager.RegisterStat(bankStat).GetAwaiter().GetResult());
|
||||
Assert.NotNull(this.statManager.GetStat(bankStat.StatId)
|
||||
.GetAwaiter()
|
||||
.GetResult());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GangBank_ZeroBalance() {
|
||||
var gang = await GangTestUtil.CreateGang(gangManager);
|
||||
Assert.NotNull(gang);
|
||||
Assert.Null(gang.Bank);
|
||||
gang.Stats.Add(bankStat);
|
||||
Assert.Equal(0, gang.Bank);
|
||||
|
||||
Assert.True(await gangManager.UpdateGang(gang));
|
||||
gang = await gangManager.GetGang(gang.GangId);
|
||||
Assert.NotNull(gang);
|
||||
Assert.Null(gang.Bank);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GangBank_Deposit() {
|
||||
var gang = await GangTestUtil.CreateGang(gangManager);
|
||||
Assert.NotNull(gang);
|
||||
gang.Stats.Add(bankStat);
|
||||
Assert.Equal(0, gang.Bank);
|
||||
|
||||
var stat = gang.GetStat(bankStat.StatId);
|
||||
Assert.Same(stat, bankStat);
|
||||
|
||||
var bank = stat as IGangStat<int>;
|
||||
Assert.NotNull(bank);
|
||||
Assert.Equal(0, bank.Value);
|
||||
|
||||
bank.Value += 1;
|
||||
Assert.NotEmpty(await statManager.GetStats());
|
||||
Assert.True(await gangStatManager.PushToGang(gang, bank),
|
||||
"Failed to push bank value to gang");
|
||||
gang = await gangManager.GetGang(gang.GangId);
|
||||
Assert.NotNull(gang);
|
||||
|
||||
bank = await gangStatManager.GetForGang<int>(gang, bank);
|
||||
Assert.NotNull(bank);
|
||||
Assert.Equal(1, bank.Value);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(50, 25)]
|
||||
[InlineData(5, 25)]
|
||||
[InlineData(-5, 25)]
|
||||
[InlineData(-5, -25)]
|
||||
[InlineData(int.MaxValue, int.MinValue)]
|
||||
[InlineData(int.MinValue, int.MaxValue)]
|
||||
[InlineData(int.MaxValue, int.MaxValue)]
|
||||
[InlineData(int.MinValue, int.MinValue)]
|
||||
public async Task GangBank_Withdraw(int initial, int withdraw) {
|
||||
var gang = await GangTestUtil.CreateGang(gangManager);
|
||||
Assert.NotNull(gang);
|
||||
Assert.True(await gangStatManager.PushToGang(gang, bankStat, initial));
|
||||
var stat = await gangStatManager.GetForGang<int>(gang, bankStat);
|
||||
Assert.NotNull(stat);
|
||||
Assert.Equal(initial, stat.Value);
|
||||
|
||||
stat.Value -= withdraw;
|
||||
Assert.True(await gangStatManager.PushToGang(gang, stat));
|
||||
stat = await gangStatManager.GetForGang<int>(gang, bankStat);
|
||||
Assert.NotNull(stat);
|
||||
Assert.Equal(initial - withdraw, stat.Value);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(50, 25)]
|
||||
[InlineData(5, 25)]
|
||||
[InlineData(-5, 25)]
|
||||
[InlineData(-5, -25)]
|
||||
[InlineData(int.MaxValue, int.MinValue)]
|
||||
[InlineData(int.MinValue, int.MaxValue)]
|
||||
[InlineData(int.MaxValue, int.MaxValue)]
|
||||
[InlineData(int.MinValue, int.MinValue)]
|
||||
public async Task
|
||||
GangBank_Withdraw_Indirect_Alias(int initial, int withdraw) {
|
||||
var gang = await GangTestUtil.CreateGang(gangManager);
|
||||
Assert.NotNull(gang);
|
||||
Assert.True(await gangStatManager.PushToGang(gang, bankStat, initial));
|
||||
var stat = await gangStatManager.GetForGang<int>(gang, bankStat);
|
||||
Assert.NotNull(stat);
|
||||
Assert.Equal(initial, stat.Value);
|
||||
|
||||
gang.Stats.Add(stat);
|
||||
gang.Bank -= withdraw;
|
||||
|
||||
Assert.True(await gangStatManager.PushToGang(gang, stat));
|
||||
stat = await gangStatManager.GetForGang<int>(gang, bankStat);
|
||||
Assert.NotNull(stat);
|
||||
Assert.Equal(initial - withdraw, stat.Value);
|
||||
Assert.Equal(initial - withdraw, gang.Bank);
|
||||
}
|
||||
}
|
||||
@@ -41,44 +41,6 @@ public class GangCreationTests(IPlayerManager playerMgr) {
|
||||
Assert.NotSame(dummy, clone);
|
||||
Assert.NotSame(dummy.Members, clone.Members);
|
||||
Assert.NotSame(dummy.Ranks, clone.Ranks);
|
||||
Assert.NotSame(dummy.Perks, clone.Perks);
|
||||
Assert.NotSame(dummy.Stats, clone.Stats);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(GangManagerData))]
|
||||
public async Task Gang_Clone_WithPerks(IGangManager mgr) {
|
||||
var dummy = await mgr.CreateGang("foobar", 0);
|
||||
Assert.NotNull(dummy);
|
||||
dummy.Perks.Add(new MockStat("test_perk", "Test Perk"));
|
||||
var clone = dummy.Clone() as IGang;
|
||||
Assert.NotNull(clone);
|
||||
|
||||
Assert.Equivalent(dummy, clone, true);
|
||||
|
||||
Assert.NotSame(dummy, clone);
|
||||
Assert.NotSame(dummy.Members, clone.Members);
|
||||
Assert.NotSame(dummy.Ranks, clone.Ranks);
|
||||
Assert.NotSame(dummy.Perks, clone.Perks);
|
||||
Assert.NotSame(dummy.Stats, clone.Stats);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(GangManagerData))]
|
||||
public async Task Gang_Clone_WithStats(IGangManager mgr) {
|
||||
var dummy = await mgr.CreateGang("foobar", 0);
|
||||
Assert.NotNull(dummy);
|
||||
dummy.Stats.Add(new MockStat("test_stats", "Test Stat"));
|
||||
var clone = dummy.Clone() as IGang;
|
||||
Assert.NotNull(clone);
|
||||
|
||||
Assert.Equivalent(dummy, clone, true);
|
||||
|
||||
Assert.NotSame(dummy, clone);
|
||||
Assert.NotSame(dummy.Members, clone.Members);
|
||||
Assert.NotSame(dummy.Ranks, clone.Ranks);
|
||||
Assert.NotSame(dummy.Perks, clone.Perks);
|
||||
Assert.NotSame(dummy.Stats, clone.Stats);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
||||
@@ -20,22 +20,6 @@ public class GangFieldTests {
|
||||
Assert.Single(dummy.Members);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(GangManagerData))]
|
||||
public async Task Gang_Fields_Perks(IGangManager mgr) {
|
||||
var dummy = await GangTestUtil.CreateGang(mgr);
|
||||
Assert.NotNull(dummy);
|
||||
Assert.NotNull(dummy.Perks);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(GangManagerData))]
|
||||
public async Task Gang_Fields_Stats(IGangManager mgr) {
|
||||
var dummy = await GangTestUtil.CreateGang(mgr);
|
||||
Assert.NotNull(dummy);
|
||||
Assert.NotNull(dummy.Stats);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(GangManagerData))]
|
||||
public async Task Gang_Fields_Iteration(IGangManager mgr) {
|
||||
|
||||
@@ -32,7 +32,13 @@
|
||||
<ProjectReference Include="..\GangsImpl\Mock\Mock.csproj"/>
|
||||
<ProjectReference Include="..\GangsImpl\SQLite\SQLite.csproj"/>
|
||||
<ProjectReference Include="..\GangsImpl\SQL\SQL.csproj"/>
|
||||
<ProjectReference Include="..\GangsImpl\Stats\Stats.csproj" />
|
||||
<ProjectReference Include="..\Gangs\Gangs.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="StatTests\InstanceManageTests\GangManager\" />
|
||||
<Folder Include="StatTests\InstanceManageTests\PlayerManager\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
56
GangsTest/StatTests/InstanceManageTests/InstanceGangTests.cs
Normal file
56
GangsTest/StatTests/InstanceManageTests/InstanceGangTests.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using GangsAPI.Data.Gang;
|
||||
using GangsAPI.Data.Stat;
|
||||
using GangsAPI.Services;
|
||||
|
||||
namespace GangsTest.StatTests.InstanceManageTests;
|
||||
|
||||
public class InstanceGangTests(IGangManager gangMgr) {
|
||||
private class TestStatInstance : IStat<int> {
|
||||
public string StatId => "test_stat";
|
||||
public string Name => "Test Stat";
|
||||
public string? Description => "A test stat.";
|
||||
public int Value { get; set; } = 32;
|
||||
}
|
||||
|
||||
private IGang testGang =
|
||||
gangMgr.CreateGang("Test Gang", (ulong)new Random().NextInt64())
|
||||
.GetAwaiter()
|
||||
.GetResult() ?? throw new InvalidOperationException();
|
||||
|
||||
private readonly IStat<int> testStat = new TestStatInstance();
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(InstanceManageData))]
|
||||
public async Task Instance_Register(IStatManager stat,
|
||||
IGangStatManager manager) {
|
||||
Assert.True(await stat.RegisterStat(testStat));
|
||||
Assert.True(await manager.PushToGang(testGang, testStat));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(InstanceManageData))]
|
||||
public async Task Instance_Register_Unregistered(IStatManager _,
|
||||
IGangStatManager manager) {
|
||||
Assert.False(await manager.PushToGang(testGang, testStat));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(InstanceManageData))]
|
||||
public async Task Instance_Fetch_Registered(IStatManager stat,
|
||||
IGangStatManager manager) {
|
||||
Assert.True(await stat.RegisterStat(testStat));
|
||||
Assert.True(await manager.PushToGang(testGang, testStat));
|
||||
var result = await manager.GetForGang(testGang, testStat);
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal(testStat, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[ClassData(typeof(InstanceManageData))]
|
||||
public async Task Instance_Fetch_Unregistered(IStatManager stat,
|
||||
IGangStatManager manager) {
|
||||
Assert.True(await stat.RegisterStat(testStat));
|
||||
var result = await manager.GetForGang(testGang, testStat);
|
||||
Assert.Null(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections;
|
||||
using Mock;
|
||||
|
||||
namespace GangsTest.StatTests.InstanceManageTests;
|
||||
|
||||
public class InstanceManageData : IEnumerable<object[]> {
|
||||
private object[][] behaviors;
|
||||
|
||||
public InstanceManageData() {
|
||||
var inst = new MockStatManager();
|
||||
behaviors = new object[][] { [inst, new MockInstanceStatManager(inst)] };
|
||||
}
|
||||
|
||||
public IEnumerator<object[]> GetEnumerator() {
|
||||
return behaviors.Select(behavior => behavior).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
||||
}
|
||||
11
GangsTest/StatTests/InstanceTests/InstanceFieldTests.cs
Normal file
11
GangsTest/StatTests/InstanceTests/InstanceFieldTests.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using GangsAPI.Data.Stat;
|
||||
|
||||
namespace GangsTest.StatTests.InstanceTests;
|
||||
|
||||
public class InstanceFieldTests {
|
||||
[Theory]
|
||||
[ClassData(typeof(StatInstanceData))]
|
||||
public void Instance_Id(IStat stat) {
|
||||
Assert.Matches("^[a-z0-9_]+$", stat.StatId);
|
||||
}
|
||||
}
|
||||
15
GangsTest/StatTests/InstanceTests/StatInstanceData.cs
Normal file
15
GangsTest/StatTests/InstanceTests/StatInstanceData.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.Collections;
|
||||
using GangsAPI.Data.Stat;
|
||||
using Stats;
|
||||
|
||||
namespace GangsTest.StatTests.InstanceTests;
|
||||
|
||||
public class StatInstanceData : IEnumerable<object[]> {
|
||||
private readonly IStat[] stats = [new GangBankStat()];
|
||||
|
||||
public IEnumerator<object[]> GetEnumerator() {
|
||||
return stats.Select(stat => (object[]) [stat]).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using GangsAPI.Services;
|
||||
|
||||
namespace GangsTest.StatTests;
|
||||
namespace GangsTest.StatTests.ManageTests;
|
||||
|
||||
public class MockStatManagerTests {
|
||||
[Theory]
|
||||
@@ -4,7 +4,7 @@ using Mock;
|
||||
using SQLImpl;
|
||||
using SQLite;
|
||||
|
||||
namespace GangsTest.StatTests;
|
||||
namespace GangsTest.StatTests.ManageTests;
|
||||
|
||||
public class StatManagerData : IEnumerable<object[]> {
|
||||
private readonly IBehavior[] behaviors = [
|
||||
@@ -1,6 +1,6 @@
|
||||
using GangsAPI.Services;
|
||||
|
||||
namespace GangsTest.StatTests;
|
||||
namespace GangsTest.StatTests.ManageTests;
|
||||
|
||||
public class StatRegistrationTests {
|
||||
[Theory]
|
||||
@@ -1,6 +1,6 @@
|
||||
using GangsAPI.Services;
|
||||
|
||||
namespace GangsTest.StatTests;
|
||||
namespace GangsTest.StatTests.ManageTests;
|
||||
|
||||
public class StatRetainTests {
|
||||
[Theory]
|
||||
@@ -1,4 +1,5 @@
|
||||
using GangsAPI.Services;
|
||||
using GangsTest.StatTests.ManageTests;
|
||||
|
||||
namespace GangsTest.StatTests;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using GangsAPI.Services;
|
||||
using GangsTest.StatTests.ManageTests;
|
||||
|
||||
namespace GangsTest.StatTests;
|
||||
|
||||
|
||||
47
GangsTest/StatTests/StatInstanceEqualityTests.cs
Normal file
47
GangsTest/StatTests/StatInstanceEqualityTests.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using GangsAPI.Services;
|
||||
using GangsTest.StatTests.ManageTests;
|
||||
using Mock;
|
||||
|
||||
namespace GangsTest.StatTests;
|
||||
|
||||
public class StatInstanceEqualityTests {
|
||||
[Fact]
|
||||
public void Stat_Equality_SameEverything() {
|
||||
var foo1 = new MockStat<int>("foo", "bar", null, 0);
|
||||
var foo2 = new MockStat<int>("foo", "bar", null, 0);
|
||||
Assert.Equal(foo1, foo2);
|
||||
Assert.StrictEqual(foo1, foo2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Stat_Equality_DiffName() {
|
||||
var foo1 = new MockStat<int>("foo", "foobar", null, 0);
|
||||
var foo2 = new MockStat<int>("foo", "bar", null, 0);
|
||||
Assert.Equal(foo1, foo2);
|
||||
Assert.StrictEqual(foo1, foo2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Stat_Equality_DiffDesc() {
|
||||
var foo1 = new MockStat<int>("foo", "bar", null, 0);
|
||||
var foo2 = new MockStat<int>("foo", "bar", "foobar", 0);
|
||||
Assert.Equal(foo1, foo2);
|
||||
Assert.StrictEqual(foo1, foo2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Stat_Equality_DiffBoth() {
|
||||
var foo1 = new MockStat<int>("foo", "barfoo", null, 0);
|
||||
var foo2 = new MockStat<int>("foo", "bar", "foobar", 0);
|
||||
Assert.Equal(foo1, foo2);
|
||||
Assert.StrictEqual(foo1, foo2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Stat_Equality_DiffIDs() {
|
||||
var foo1 = new MockStat<int>("foo", "bar", null, 0);
|
||||
var foo2 = new MockStat<int>("foobar", "bar", null, 0);
|
||||
Assert.NotStrictEqual(foo1, foo2);
|
||||
Assert.NotEqual(foo1, foo2);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using GangsAPI.Services;
|
||||
using GangsTest.StatTests.ManageTests;
|
||||
|
||||
namespace GangsTest.StatTests;
|
||||
|
||||
|
||||
7
compose.yml
Normal file
7
compose.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
services:
|
||||
mariadb:
|
||||
image: mariadb:latest
|
||||
environment:
|
||||
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes
|
||||
MARIADB_DATABASE: gangs
|
||||
network_mode: host
|
||||
Reference in New Issue
Block a user