Skip to content

Split API to other project + major rework #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3051046
Split API to other project. Code cleanup. Start of making global serv…
DiFFoZ May 11, 2023
f84c4fb
Add support for configurable cooldown store provider
DiFFoZ May 15, 2023
05a20df
Make `IKitCooldownStore` as global service
DiFFoZ May 17, 2023
28fc16f
Make `IKitStore` as global service
DiFFoZ May 17, 2023
b893810
Make `IKitManager` as global service
DiFFoZ May 21, 2023
5a31bab
Add debug log to measure available kits method
DiFFoZ May 21, 2023
1495957
Update deploy workflow
DiFFoZ May 23, 2023
f3bfc63
Include readme to package
DiFFoZ May 23, 2023
8da9801
Implement forgotten methods
DiFFoZ May 23, 2023
80255fc
Make store provider safe to load. Fix plugin configuration event is n…
DiFFoZ May 23, 2023
dfc23d0
Dispose previous store provider when reloading
DiFFoZ May 26, 2023
2ab294c
Add value comparer for Items list
DiFFoZ May 26, 2023
b206bc6
Add message on how to use cooldown parameter
DiFFoZ May 26, 2023
c648150
Add CooldownSpan parameter for `cooldown` localizable string
DiFFoZ Jun 1, 2023
e83a5c8
Copy array of item state when saving the kit to datastore provider
DiFFoZ Jun 1, 2023
c731c8e
Update packages
DiFFoZ Jun 1, 2023
d59cd90
Register permission when new kit added to DB
DiFFoZ Jun 6, 2023
23b8c91
Add kit update command
DiFFoZ Jun 6, 2023
d8c4ce1
Start working on EF Core storing cooldowns
DiFFoZ Jul 27, 2023
60476d3
Add implementation of mysql kit cooldowns
DiFFoZ Jul 27, 2023
b864214
Add memory caching for mysql kit store provider
DiFFoZ Jul 28, 2023
2b9d62c
Add helper AsyncLock
DiFFoZ Jul 30, 2023
57b43b7
Fixed missing async calls to EF database
DiFFoZ Aug 2, 2023
8d177d8
Add conversion of DateTime to save it as UTC and get back as UTC
DiFFoZ Aug 2, 2023
263c2fc
Add MySQL cooldowns provider to list
DiFFoZ Aug 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,33 @@ jobs:
name: "NuGet Deployment"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
name: Checkout Repository
with:
fetch-depth: 0
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v3
with:
dotnet-version: 5.0.x
dotnet-version: 6.0.x
- name: Install dependencies
run: dotnet restore

- name: API Update version
run: "sed -i \"s#<Version>0.0.0</Version>#<Version>${{ github.event.inputs.version }}</Version>#\" Kits.API/Kits.API.csproj"
- name: API Update package version
run: "sed -i \"s#<PackageVersion>0.0.0</PackageVersion>#<PackageVersion>${{ github.event.inputs.version }}</PackageVersion>#\" Kits.API/Kits.API.csproj"
- name: API Update informational version
run: "sed -i \"s#<InformationalVersion>0.0.0</InformationalVersion>#<InformationalVersion>${{ github.event.inputs.version }}</InformationalVersion>#\" Kits.API/Kits.API.csproj"

- name: Update version
run: "sed -i \"s#<Version>0.0.0</Version>#<Version>${{ github.event.inputs.version }}</Version>#\" Kits/Kits.csproj"
- name: Update package version
run: "sed -i \"s#<PackageVersion>0.0.0</PackageVersion>#<PackageVersion>${{ github.event.inputs.version }}</PackageVersion>#\" Kits/Kits.csproj"
- name: Update informational version
run: "sed -i \"s#<InformationalVersion>0.0.0</InformationalVersion>#<InformationalVersion>${{ github.event.inputs.version }}</InformationalVersion>#\" Kits/Kits.csproj"
- name: Build
run: "sed -i \"s#<InformationalVersion>0.0.0</InformationalVersion>#<InformationalVersion>${{ github.event.inputs.version }}</InformationalVersion>#\" Kits/Kits.csproj"
- name: Build API
run: dotnet build Kits.API/Kits.API.csproj --configuration Release --no-restore
- name: Build Kits
run: dotnet build Kits/Kits.csproj --configuration Release --no-restore
- name: Deploy to NuGet
run: dotnet nuget push Kits/bin/Release/*.nupkg
--api-key ${{ secrets.NUGET_DEPLOY_KEY }}
--source https://api.nuget.org/v3/index.json
run: dotnet nuget push *.nupkg --api-key ${{ secrets.NUGET_DEPLOY_KEY }} --source https://api.nuget.org/v3/index.json
- name: Release to GitHub
uses: actions/create-release@master
env:
Expand All @@ -48,4 +53,4 @@ jobs:
Changelog:
${{ github.event.inputs.update_notes }}
release_name: DiFFoZ.Kits v${{ github.event.inputs.version }}
tag_name: v${{ github.event.inputs.version }}
tag_name: v${{ github.event.inputs.version }}
46 changes: 46 additions & 0 deletions Kits.API/Configuration/GenericOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Kits.API.Configuration;
public class GenericOptions<TProvider> where TProvider : class
{
private readonly List<(Type implementationService, string name)> m_KitProviders = new();
public IReadOnlyCollection<(Type implementationService, string name)> KitProviders => m_KitProviders.AsReadOnly();

public void AddProvider<T>(string name) where T : TProvider
{
AddProvider(typeof(T), name);
}

public void AddProvider(Type type, string name)
{
if (!typeof(TProvider).IsAssignableFrom(type))
{
throw new Exception($"Type {type} must be an instance of {typeof(TProvider).Name}!");
}

if (m_KitProviders.Any(x => x.name.Equals(name, StringComparison.OrdinalIgnoreCase)))
{
return;
}

m_KitProviders.Add((type, name));
}

public void RemoveProvider<T>() where T : TProvider
{
RemoveProvider(typeof(T));
}

public void RemoveProvider(Type type)
{
m_KitProviders.RemoveAll(c => c.implementationService == type);
}

public Type? FindType(string type)
{
return m_KitProviders.Find(x => x.name.Equals(type, StringComparison.OrdinalIgnoreCase))
.implementationService;
}
}
14 changes: 14 additions & 0 deletions Kits.API/Cooldowns/IKitCooldownStore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using OpenMod.API.Ioc;
using OpenMod.API.Permissions;
using System;
using System.Threading.Tasks;

namespace Kits.API.Cooldowns;

[Service]
public interface IKitCooldownStore
{
Task<TimeSpan?> GetLastCooldownAsync(IPermissionActor actor, string kitName);

Task RegisterCooldownAsync(IPermissionActor actor, string kitName, DateTime time);
}
7 changes: 7 additions & 0 deletions Kits.API/Cooldowns/IKitCooldownStoreProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using System.Threading.Tasks;

namespace Kits.API.Cooldowns;
public interface IKitCooldownStoreProvider : IKitCooldownStore
{
Task InitAsync();
}
6 changes: 6 additions & 0 deletions Kits.API/Cooldowns/KitCooldownOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using Kits.API.Configuration;

namespace Kits.API.Cooldowns;
public class KitCooldownOptions : GenericOptions<IKitCooldownStoreProvider>
{
}
8 changes: 8 additions & 0 deletions Kits.API/Databases/IKitStoreProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Threading.Tasks;

namespace Kits.API.Databases;

public interface IKitStoreProvider : IKitStore
{
Task InitAsync();
}
6 changes: 6 additions & 0 deletions Kits.API/Databases/KitStoreOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using Kits.API.Configuration;

namespace Kits.API.Databases;
public class KitStoreOptions : GenericOptions<IKitStoreProvider>
{
}
18 changes: 18 additions & 0 deletions Kits.API/IKitManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Kits.API.Models;
using OpenMod.API.Commands;
using OpenMod.API.Ioc;
using OpenMod.Extensions.Games.Abstractions.Players;

namespace Kits.API;

[Service]
public interface IKitManager
{
Task GiveKitAsync(IPlayerUser user, string name, ICommandActor? instigator = null, bool forceGiveKit = false);

Task GiveKitAsync(IPlayerUser user, Kit kit, ICommandActor? instigator = null, bool forceGiveKit = false);

Task<IReadOnlyCollection<Kit>> GetAvailableKitsForPlayerAsync(IPlayerUser player);
}
30 changes: 30 additions & 0 deletions Kits.API/IKitStore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Kits.API.Databases;
using Kits.API.Models;
using OpenMod.API.Ioc;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Kits.API;

/// <summary>
/// The service for getting kits
/// </summary>
[Service]
public interface IKitStore
{
/// <summary>
/// Gets the kits from <see cref="IKitStoreProvider"/>
/// </summary>
/// <returns>Kits list</returns>
Task<IReadOnlyCollection<Kit>> GetKitsAsync();

Task<Kit?> FindKitByNameAsync(string name);

Task<bool> IsKitExists(string name);

Task AddKitAsync(Kit kit);

Task RemoveKitAsync(string name);

Task UpdateKitAsync(Kit kit);
}
37 changes: 37 additions & 0 deletions Kits.API/Kits.API.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<PackageLicenseExpression>EUPL-1.2</PackageLicenseExpression>
<RootNamespace>Kits.API</RootNamespace>
<AssemblyName>Kits.API</AssemblyName>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GenerateNugetPackage>true</GenerateNugetPackage>
<Product>Kits.API</Product>
<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
<WarningsAsErrors>nullable</WarningsAsErrors>
<Version>0.0.0</Version>
<InformationalVersion>0.0.0</InformationalVersion>
<PackageVersion>0.0.0</PackageVersion>
<Authors>EvolutionPlugins</Authors>
<Company>EvolutionPlugins</Company>
<PackageId>DiFFoZ.Kits.API</PackageId>
<Description>API of OpenMod kits plugin</Description>
<RepositoryUrl>https://github.com/DiFFoZ/Kits</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>https://github.com/DiFFoZ/Kits</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="OpenMod.Core" Version="3.3.15" />
<PackageReference Include="OpenMod.Extensions.Economy.Abstractions" Version="3.3.15" />
<PackageReference Include="OpenMod.Extensions.Games.Abstractions" Version="3.3.15" />
</ItemGroup>

<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="\"/>
</ItemGroup>

</Project>
82 changes: 82 additions & 0 deletions Kits.API/Models/Kit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using OpenMod.Extensions.Economy.Abstractions;
using OpenMod.Extensions.Games.Abstractions.Items;
using OpenMod.Extensions.Games.Abstractions.Players;
using OpenMod.Extensions.Games.Abstractions.Vehicles;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Threading.Tasks;
using YamlDotNet.Serialization;

namespace Kits.API.Models;

public sealed class Kit
{
[YamlIgnore]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

[StringLength(25)]
[Required]
public string Name { get; set; } = string.Empty;

public float Cooldown { get; set; }

[Column(TypeName = "decimal(18,2)")] // by default it creates decimal(65, 30)
public decimal Cost { get; set; }

[Column(TypeName = "decimal(18,2)")] // by default it creates decimal(65, 30)
public decimal Money { get; set; }

[StringLength(5)]
public string? VehicleId { get; set; }

[MaxLength(ushort.MaxValue)]
[Column(TypeName = "blob")] // by default it creates longblob (2^32 - 1), we need only ushort.MaxValue length ( 65535 )
public List<KitItem>? Items { get; set; }

public async Task GiveKitToPlayer(IPlayerUser playerUser, IServiceProvider serviceProvider)
{
var stringLocalizer = serviceProvider.GetRequiredService<IStringLocalizer>();
var logger = serviceProvider.GetRequiredService<ILogger<Kit>>();

if (Items != null && playerUser.Player is IHasInventory hasInventory && hasInventory.Inventory != null)
{
var itemSpawner = serviceProvider.GetRequiredService<IItemSpawner>();

foreach (var item in Items)
{
var result = await itemSpawner.GiveItemAsync(hasInventory.Inventory, item.ItemAssetId,
item.State);
if (result == null)
{
logger.LogWarning("Item {Id} was unable to give to player {Name})", item.ItemAssetId, playerUser.FullActorName);
}
}
}

if (!string.IsNullOrEmpty(VehicleId))
{
var vehicleSpawner = serviceProvider.GetRequiredService<IVehicleSpawner>();

var result = await vehicleSpawner.SpawnVehicleAsync(playerUser.Player, VehicleId!);
if (result == null)
{
logger.LogWarning("Vehicle {Id} was unable to give to player {Name})", VehicleId, playerUser.FullActorName);
}
}

if (Money != 0)
{
var economyProvider = serviceProvider.GetRequiredService<IEconomyProvider>();

await economyProvider.UpdateBalanceAsync(playerUser.Id, playerUser.Type, Money,
stringLocalizer["commands:kit:balanceUpdateReason:got"]);
}
}
}
45 changes: 45 additions & 0 deletions Kits.API/Models/KitItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using OpenMod.Extensions.Games.Abstractions.Items;
using System;
using System.IO;
using System.Linq;

namespace Kits.API.Models;

public class KitItem
{
public string ItemAssetId { get; set; }

public KitItemState State { get; set; }

public KitItem() : this(null, null)
{
}

public KitItem(string? itemAssetId, IItemState? itemState)
{
ItemAssetId = itemAssetId ?? string.Empty;
State = new KitItemState(itemState);
}

public void Serialize(BinaryWriter bw)
{
bw.Write(ItemAssetId);
State.Serialize(bw);
}

public void Deserialize(BinaryReader br)
{
ItemAssetId = br.ReadString();
State.Deserialize(br);
}

public override int GetHashCode()
{
var itemStateDataHash = State.StateData.Aggregate(new HashCode(), (hash, i) =>
{
hash.Add(i);
return hash;
}).ToHashCode();
return HashCode.Combine(ItemAssetId, State.ItemAmount, State.ItemQuality, State.ItemDurability, itemStateDataHash);
}
}
Loading