Add project data

This commit is contained in:
2025-12-30 02:22:44 +01:00
parent a6316b8b06
commit 747af63a29
2301 changed files with 67690 additions and 1 deletions

View File

@@ -0,0 +1,209 @@
using DbController;
using System.Globalization;
using System.Text;
using Tabletop.Core.Filters;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class AbilityService : IModelService<Ability, int, AbilityFilter>
{
public async Task CreateAsync(Ability input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = $@"INSERT INTO Fractions
(
Quality,
Force
)
VALUES
(
@QUALITY,
@FORCE
); {dbController.GetLastIdSql()}";
input.AbilityId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"INSERT INTO AbilityDescription
(
AbilityId,
Code,
Name,
Description,
Mechanic
)
VALUES
(
@ABILITY_ID,
@CODE,
@NAME,
@DESCRIPTION,
@MECHANIC
)";
var parameters = new
{
ABILTIY_ID = input.AbilityId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task DeleteAsync(Ability input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "DELETE FROM Abilities WHERE AbilityId = @ABILITY_ID";
await dbController.QueryAsync(sql, new
{
ABILITY_ID = input.AbilityId
}, cancellationToken);
}
public static async Task<List<Ability>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "SELECT * FROM Abilities";
var list = await dbController.SelectDataAsync<Ability>(sql, cancellationToken: cancellationToken);
await LoadClassDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task<Ability?> GetAsync(int abilityId, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"SELECT * FROM Abilities WHERE AbilityId = @ABILITY_ID";
var ability = await dbController.GetFirstAsync<Ability>(sql, new
{
ABILITY_ID = abilityId
}, cancellationToken);
return ability;
}
private static async Task LoadClassDescriptionsAsync(List<Ability> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> abilityIds = list.Select(x => x.AbilityId);
string sql = $"SELECT * FROM AbilityDescription WHERE AbilityId IN ({string.Join(",", abilityIds)})";
List<AbilityDescription> descriptions = await dbController.SelectDataAsync<AbilityDescription>(sql, null, cancellationToken);
foreach (var item in list)
{
item.Description = [.. descriptions.Where(x => x.AbilityId == item.AbilityId)];
}
}
}
public async Task UpdateAsync(Ability input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"UPDATE Abilities SET
Quality = @QUALITY,
Force = @FORCE
WHERE AbilityId = @ABILITY_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"UPDATE AbilityDescription SET
Name = @NAME,
Description = @DESCRIPTION,
Mechanic = @MECHANIC
WHERE AbilityId = @ABILITY_ID AND Code = @CODE";
var parameters = new
{
ABILITY_ID = input.AbilityId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description,
MECHANIC = description.Mechanic
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task<List<Ability>> GetAsync(AbilityFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT ad.Name, a.* " +
"FROM AbilityDescription ad " +
"INNER JOIN Abilities a " +
"ON (a.AbilityId = ad.AbilityId) " +
"WHERE 1 = 1");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
sqlBuilder.AppendLine(@$" ORDER BY Name ASC ");
sqlBuilder.AppendLine(dbController.GetPaginationSyntax(filter.PageNumber, filter.Limit));
// Zum Debuggen schreiben wir den Wert einmal als Variabel
string sql = sqlBuilder.ToString();
List<Ability> list = await dbController.SelectDataAsync<Ability>(sql, GetFilterParameter(filter), cancellationToken);
await LoadAbilityDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task<int> GetTotalAsync(AbilityFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT COUNT(*) AS record_count FROM AbilityDescription WHERE 1 = 1 ");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
string sql = sqlBuilder.ToString();
int result = await dbController.GetFirstAsync<int>(sql, GetFilterParameter(filter), cancellationToken);
return result;
}
public string GetFilterWhere(AbilityFilter filter)
{
StringBuilder sqlBuilder = new();
if (!string.IsNullOrWhiteSpace(filter.SearchPhrase))
{
sqlBuilder.AppendLine(@" AND (UPPER(Name) LIKE @SEARCHPHRASE)");
}
string sql = sqlBuilder.ToString();
return sql;
}
public Dictionary<string, object?> GetFilterParameter(AbilityFilter filter)
{
return new Dictionary<string, object?>
{
{ "SEARCHPHRASE", $"%{filter.SearchPhrase}%" },
{ "CULTURE", CultureInfo.CurrentCulture.Name }
};
}
private static async Task LoadAbilityDescriptionsAsync(List<Ability> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> abilityIds = list.Select(x => x.AbilityId);
string sql = $"SELECT * FROM AbilityDescription WHERE AbilityId IN ({string.Join(",", abilityIds)})";
List<AbilityDescription> descriptions = await dbController.SelectDataAsync<AbilityDescription>(sql, null, cancellationToken);
foreach (var ability in list)
{
ability.Description = [.. descriptions.Where(x => x.AbilityId == ability.AbilityId)];
}
}
}
}
}

View File

@@ -0,0 +1,128 @@
using DbController;
using DbController.SqlServer;
using Microsoft.Extensions.Configuration;
using System.Globalization;
using Tabletop.Core.Interfaces;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public static class AppdataService
{
public static string[] SupportedCultureCodes => [.. SupportedCultures.Select(x => x.Name)];
public static CultureInfo[] SupportedCultures =>
[
new ("en"),
new ("de")
];
public static bool FirstUserExists { get; set; } = false;
public static List<Permission> Permissions { get; set; } = [];
public static List<Unit> Units { get; set; } = [];
public static List<Weapon> Weapons { get; set; } = [];
public static List<Fraction> Fractions { get; set; } = [];
public static List<Gamemode> Gamemodes { get; set; } = [];
public static List<Class> Classes { get; set; } = [];
public static List<Ability> Abilities { get; set; } = [];
public static List<Layout> Layouts { get; set; } = [];
public static List<Surface> Surfaces { get; set; } = [];
public static readonly Dictionary<string, Game> Games = [];
private static IConfiguration? _configuration;
public static async Task InitAsync(IConfiguration configuration)
{
_configuration = configuration;
using IDbController dbController = new SqlController(ConnectionString);
Permissions = await PermissionService.GetAllAsync(dbController);
FirstUserExists = await UserService.FirstUserExistsAsync(dbController);
Units = await UnitService.GetAllAsync(dbController);
Weapons = await WeaponService.GetAllAsync(dbController);
Fractions = await FractionService.GetAllAsync(dbController);
Gamemodes = await GamemodeService.GetAllAsync(dbController);
Classes = await ClassService.GetAllAsync(dbController);
Abilities = await AbilityService.GetAllAsync(dbController);
Layouts = await LayoutService.GetAllAsync(dbController);
Surfaces = await SurfaceService.GetAllAsync(dbController);
}
/// <summary>
/// Creates or updates an object in the corresponding list fro the type <see cref="T"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="input"></param>
public static void UpdateRecord<T>(T input) where T : class, IDbModel<int?>, new()
{
List<T> list = GetList<T>();
T? item = list.FirstOrDefault(x => x.GetIdentifier() == input.GetIdentifier());
if (item is null)
{
list.Add(input);
}
else
{
int index = list.IndexOf(item);
list[index] = input;
}
}
/// <summary>
/// Deletes an item from the corresponding object list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="input"></param>
public static void DeleteRecord<T>(T input) where T : class, IDbModel<int?>, new()
{
List<T> list = GetList<T>();
list.Remove(input);
}
/// <summary>
/// Gets the corresponding list for the type <see cref="T"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>This method never returns null. When no list for <see cref="T"/> is specified, it returns a new empty list</returns>
public static List<T> GetList<T>() where T : class, IDbModel<int?>, new()
{
var input = new T();
object tmp = input switch
{
Permission => Permissions,
_ => new List<T>()
};
List<T> list = (List<T>)tmp;
return list;
}
public static string ConnectionString => _configuration?["Sql:ConnectionString"] ?? string.Empty;
public static int PageLimit => _configuration?.GetValue<int>("Filter:PageLimit") ?? 30;
public static string ApiKey => _configuration?["IpGeolocation:ApiKey"] ?? string.Empty;
public static CultureInfo ToCulture(this ILocalizationHelper helper)
{
var culture = SupportedCultures.FirstOrDefault(x => x.TwoLetterISOLanguageName.Equals(helper.Code, StringComparison.OrdinalIgnoreCase));
if (culture is null)
{
return SupportedCultures[0];
}
else
{
return culture;
}
}
}
}

View File

@@ -0,0 +1,62 @@
using DbController;
using DbController.SqlServer;
using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class AuthService(AuthenticationStateProvider authenticationStateProvider, UserService userService)
{
/// <summary>
/// Converts the active claims into a <see cref="User"/> object
/// </summary>
/// <returns></returns>
public async Task<User?> GetUserAsync(IDbController? dbController = null)
{
var authState = await authenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
Claim? claim = user.FindFirst("UserId");
if (claim is null)
{
return null;
}
var userId = Convert.ToInt32(claim.Value);
bool shouldDispose = dbController is null;
dbController ??= new SqlController(AppdataService.ConnectionString);
var result = await userService.GetAsync(userId, dbController);
if (shouldDispose)
{
dbController.Dispose();
}
return result;
}
return null;
}
/// <summary>
/// Checks if the currently logged in user as a specific role within it's claims.
/// </summary>
/// <param name="roleName"></param>
/// <returns></returns>
public async Task<bool> HasRole(string roleName)
{
var authState = await authenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
return user.IsInRole(roleName);
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tabletop.Core.Services
{
internal class CaptureService
{
}
}

View File

@@ -0,0 +1,53 @@
using DbController;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class ClassService : IModelService<Class, int>
{
public Task CreateAsync(Class input, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
public Task DeleteAsync(Class input, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
public static async Task<List<Class>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "SELECT * FROM Classes";
var list = await dbController.SelectDataAsync<Class>(sql, cancellationToken: cancellationToken);
await LoadClassDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public Task<Class?> GetAsync(int identifier, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
private static async Task LoadClassDescriptionsAsync(List<Class> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> classIds = list.Select(x => x.ClassId);
string sql = $"SELECT * FROM ClassDescription WHERE ClassId IN ({string.Join(",", classIds)})";
List<ClassDescription> descriptions = await dbController.SelectDataAsync<ClassDescription>(sql, null, cancellationToken);
foreach (var item in list)
{
item.Description = [.. descriptions.Where(x => x.ClassId == item.ClassId)];
}
}
}
public Task UpdateAsync(Class input, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,132 @@
using DbController;
using Microsoft.AspNetCore.Http;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class ConnectionLogService(GeolocationService geolocationService)
{
private readonly GeolocationService _geolocationService = geolocationService;
public static async Task CreateAsync(ConnectionLog input, IDbController dbController, CancellationToken cancellationToken = default)
{
// SQL-Insert-Statement für das ConnectionLog
string sql = $@"
INSERT INTO ConnectionLogs
(
IpAddress,
ConnectionTime,
UserAgent,
Referrer,
RequestedUrl,
Geolocation,
SessionId,
StatusCode,
DeviceType,
OperatingSystem
)
VALUES
(
@IP_ADDRESS,
@CONNECTION_TIME,
@USER_AGENT,
@REFERRER,
@REQUESTED_URL,
@GEOLOCATION,
@SESSION_ID,
@STATUS_CODE,
@DEVICE_TYPE,
@OPERATING_SYSTEM
); {dbController.GetLastIdSql()}";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
}
public async Task<ConnectionLog> GetConnectionLogAsync(HttpContext context)
{
// Extrahiere die IP-Adresse
var ipAddress = context.Connection.RemoteIpAddress?.ToString() ?? "Unknown";
// Hole die Geolocation (Stadt, Land, Koordinaten etc.) basierend auf der IP-Adresse
var geolocation = await _geolocationService.GetGeolocationAsync(ipAddress);
// Extrahiere den User-Agent-Header aus dem HttpContext
var userAgent = context.Request.Headers["User-Agent"].FirstOrDefault() ?? "Unknown";
// Bestimmung des DeviceTypes und des Betriebssystems
var deviceType = await GetDeviceType(userAgent);
var operatingSystem = await GetOperatingSystem(userAgent);
// Erstelle das ConnectionLog
return new ConnectionLog
{
IpAddress = ipAddress,
ConnectionTime = DateTime.UtcNow,
UserAgent = userAgent,
Referrer = context.Request.Headers["Referer"].FirstOrDefault() ?? "Unknown",
RequestedUrl = context.Request.Path,
Geolocation = geolocation, // Füge die Geolocation hinzu
SessionId = context.Session?.Id ?? Guid.NewGuid().ToString(),
StatusCode = context.Response.StatusCode,
DeviceType = deviceType,
OperatingSystem = operatingSystem
};
}
// Methode zur Bestimmung des Device-Typs anhand des User-Agent-Strings
public static Task<string> GetDeviceType(string userAgent)
{
string deviceType;
if (userAgent.Contains("Mobi") || userAgent.Contains("Android") || userAgent.Contains("iPhone") || userAgent.Contains("iPad"))
{
deviceType = "Mobile";
}
else if (userAgent.Contains("Tablet") || userAgent.Contains("iPad"))
{
deviceType = "Tablet";
}
else
{
deviceType = "Desktop"; // Default ist Desktop
}
return Task.FromResult(deviceType); // Verpackt den Wert in einem Task
}
// Methode zur Bestimmung des Betriebssystems anhand des User-Agent-Strings
public static Task<string> GetOperatingSystem(string userAgent)
{
string operatingSystem;
if (userAgent.Contains("Windows"))
{
operatingSystem = "Windows";
}
else if (userAgent.Contains("Mac OS"))
{
operatingSystem = "macOS";
}
else if (userAgent.Contains("Linux"))
{
operatingSystem = "Linux";
}
else if (userAgent.Contains("Android"))
{
operatingSystem = "Android";
}
else if (userAgent.Contains("iPhone") || userAgent.Contains("iPad"))
{
operatingSystem = "iOS";
}
else
{
operatingSystem = "Other"; // Default: Unbekanntes Betriebssystem
}
return Task.FromResult(operatingSystem); // Verpackt den Wert in einem Task
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tabletop.Core.Services
{
internal class EliminationService
{
}
}

View File

@@ -0,0 +1,189 @@
using DbController;
using System.Globalization;
using System.Text;
using Tabletop.Core.Filters;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class FractionService : IModelService<Fraction, int, FractionFilter>
{
public async Task CreateAsync(Fraction input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = $@"INSERT INTO Fractions
(
)
VALUES
(
); {dbController.GetLastIdSql()}";
input.FractionId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"INSERT INTO FractionDescription
(
FractionId,
Code,
Name,
ShortName,
Description
)
VALUES
(
@FRACTION_ID,
@CODE,
@NAME,
@SHORT_NAME,
@DESCRIPTION
)";
var parameters = new
{
FRACTION_ID = input.FractionId,
CODE = description.Code,
NAME = description.Name,
SHORT_NAME = description.ShortName,
DESCRIPTION = description.Description
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task DeleteAsync(Fraction input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "DELETE FROM Fractions WHERE FractionId = @FRACTION_ID";
await dbController.QueryAsync(sql, new
{
FRACTION_ID = input.FractionId
}, cancellationToken);
}
public async Task<Fraction?> GetAsync(int fractionId, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"SELECT * FROM Fractions WHERE FractionId = @FRACTION_ID";
var fraction = await dbController.GetFirstAsync<Fraction>(sql, new
{
FRACTION_ID = fractionId
}, cancellationToken);
return fraction;
}
public static async Task<List<Fraction>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "SELECT * FROM Fractions";
var list = await dbController.SelectDataAsync<Fraction>(sql, cancellationToken: cancellationToken);
await LoadFractionDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task UpdateAsync(Fraction input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"UPDATE Fractions SET
Image = @IMAGE
WHERE FractionId = @FRACTION_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"UPDATE FractionDescription SET
Name = @NAME,
Description = @DESCRIPTION,
ShortName = @SHORT_NAME
WHERE FractionId = @FRACTION_ID AND Code = @CODE";
var parameters = new
{
FRACTION_ID = input.FractionId,
CODE = description.Code,
NAME = description.Name,
SHORT_NAME = description.ShortName,
DESCRIPTION = description.Description
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task<List<Fraction>> GetAsync(FractionFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT fd.Name, f.* " +
"FROM FractionDescription fd " +
"INNER JOIN Fractions f " +
"ON (f.FractionId = fd.FractionId) " +
"WHERE 1 = 1");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
sqlBuilder.AppendLine(@$" ORDER BY Name ASC ");
sqlBuilder.AppendLine(dbController.GetPaginationSyntax(filter.PageNumber, filter.Limit));
// Zum Debuggen schreiben wir den Wert einmal als Variabel
string sql = sqlBuilder.ToString();
List<Fraction> list = await dbController.SelectDataAsync<Fraction>(sql, GetFilterParameter(filter), cancellationToken);
await LoadFractionDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task<int> GetTotalAsync(FractionFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT COUNT(*) AS record_count FROM FractionDescription WHERE 1 = 1 ");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
string sql = sqlBuilder.ToString();
int result = await dbController.GetFirstAsync<int>(sql, GetFilterParameter(filter), cancellationToken);
return result;
}
public string GetFilterWhere(FractionFilter filter)
{
StringBuilder sqlBuilder = new();
if (!string.IsNullOrWhiteSpace(filter.SearchPhrase))
{
sqlBuilder.AppendLine(@" AND (UPPER(Name) LIKE @SEARCHPHRASE)");
}
string sql = sqlBuilder.ToString();
return sql;
}
public Dictionary<string, object?> GetFilterParameter(FractionFilter filter)
{
return new Dictionary<string, object?>
{
{ "SEARCHPHRASE", $"%{filter.SearchPhrase}%" },
{ "CULTURE", CultureInfo.CurrentCulture.Name }
};
}
private static async Task LoadFractionDescriptionsAsync(List<Fraction> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> fractionIds = list.Select(x => x.FractionId);
string sql = $"SELECT * FROM FractionDescription WHERE FractionId IN ({string.Join(",", fractionIds)})";
List<FractionDescription> descriptions = await dbController.SelectDataAsync<FractionDescription>(sql, null, cancellationToken);
foreach (var fraction in list)
{
fraction.Description = [.. descriptions.Where(x => x.FractionId == fraction.FractionId)];
}
}
}
}
}

View File

@@ -0,0 +1,182 @@
using DbController;
using System.Text;
using Tabletop.Core.Filters;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class GameService(PlayerService playerService, UserService userService) : IModelService<Game, int, GameFilter>
{
private readonly PlayerService _playerService = playerService;
private readonly UserService _userService = userService;
public async Task CreateAsync(Game input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = $@"INSERT INTO Games
(
UserId,
GamemodeId,
SurfaceId,
LayoutId,
Name,
NumberOfRounds,
Force,
NumberOfTeams,
NumberOfPlayers,
Date
)
VALUES
(
@USER_ID,
@GAMEMODE_ID,
@SURFACE_ID,
@LAYOUT_ID,
@NAME,
@NUMBER_OF_ROUNDS,
@FORCE,
@NUMBER_OF_TEAMS,
@NUMBER_OF_PLAYERS,
@DATE
); {dbController.GetLastIdSql()}";
input.GameId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
foreach (var item in input.Players)
{
item.GameId = input.GameId;
await _playerService.CreateAsync(item, dbController, cancellationToken);
}
}
public async Task DeleteAsync(Game input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "DELETE FROM Games WHERE GameId = @GAME_ID";
await dbController.QueryAsync(sql, new
{
GAME_ID = input.GameId,
}, cancellationToken);
}
public async Task<Game?> GetAsync(int gameId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT * FROM Games WHERE GameId = @GAME_ID";
var game = await dbController.GetFirstAsync<Game>(sql, new
{
GAME_ID = gameId
}, cancellationToken);
if (game != null)
{
game.Players = await _playerService.GetGamePlayersAsync(game.GameId, dbController, cancellationToken);
}
return game;
}
public static async Task<List<Game>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "SELECT * FROM Games";
var list = await dbController.SelectDataAsync<Game>(sql, cancellationToken: cancellationToken);
return list;
}
public async Task<List<Game>> GetAsync(GameFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sb = new();
sb.AppendLine("SELECT DISTINCT g.* FROM Games g LEFT JOIN Players p ON g.GameId = p.GameId WHERE p.UserId = @USER_ID OR g.UserId = @USER_ID ");
sb.AppendLine(GetFilterWhere(filter));
sb.AppendLine(@$" ORDER BY Date DESC ");
sb.AppendLine(dbController.GetPaginationSyntax(filter.PageNumber, filter.Limit));
string sql = sb.ToString();
List<Game> list = await dbController.SelectDataAsync<Game>(sql, GetFilterParameter(filter), cancellationToken);
if (list.Count != 0)
{
foreach (var item in list)
{
item.Players = await _playerService.GetGamePlayersAsync(item.GameId, dbController, cancellationToken);
item.Host = await _userService.GetUsernameAsync(item.UserId, dbController, cancellationToken);
}
}
return list;
}
public async Task<List<Game>> GetLastGamesOfPlayerAsync(int userId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "SELECT TOP 5 g.GameId, g.GamemodeId, g.Date, g.Force FROM Games g INNER JOIN Players p ON g.GameId = p.GameId WHERE p.UserId = @USER_ID ORDER BY g.Date DESC";
var list = await dbController.SelectDataAsync<Game>(sql, new
{
USER_ID = userId,
}, cancellationToken: cancellationToken);
return list;
}
public Dictionary<string, object?> GetFilterParameter(GameFilter filter)
{
return new Dictionary<string, object?>
{
{ "SEARCHPHRASE", $"%{filter.SearchPhrase}%" },
{ "USER_ID", filter.UserId }
};
}
public string GetFilterWhere(GameFilter filter)
{
StringBuilder sb = new();
if (!string.IsNullOrWhiteSpace(filter.SearchPhrase))
{
sb.AppendLine(@" AND (UPPER(Name) LIKE @SEARCHPHRASE)");
}
string sql = sb.ToString();
return sql;
}
public async Task<int> GetTotalAsync(GameFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sb = new();
sb.AppendLine("SELECT COUNT(*) FROM Games WHERE UserId = @USER_ID");
sb.AppendLine(GetFilterWhere(filter));
string sql = sb.ToString();
int result = await dbController.GetFirstAsync<int>(sql, GetFilterParameter(filter), cancellationToken);
return result;
}
public async Task UpdateAsync(Game input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"UPDATE Games SET
GamemodeId = @GAMEMODE_ID,
SurfaceId = @SURFACE_ID,
LayoutId = @LAYOUT_ID,
Name = @NAME,
NumberOfRounds = @NUMBER_OF_ROUNDS,
Force = @FORCE,
NumberOfTeams = @NUMBER_OF_TEAMS,
NumberOfPlayers = @NUMBER_OF_PLAYERS,
Date = @DATE
WHERE GameId = @GAME_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
}
}
}

View File

@@ -0,0 +1,189 @@
using DbController;
using System.Globalization;
using System.Text;
using Tabletop.Core.Filters;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class GamemodeService : IModelService<Gamemode, int, GamemodeFilter>
{
public async Task CreateAsync(Gamemode input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = $@"INSERT INTO Gamemodes
(
)
VALUES
(
); {dbController.GetLastIdSql()}";
input.GamemodeId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"INSERT INTO GamemodeDescription
(
GamemodeId,
Code,
Name,
Description,
Mechanic
)
VALUES
(
@GAMEMODE_ID,
@CODE,
@NAME,
@DESCRIPTION,
@MECHANIC
)";
var parameters = new
{
GAMEMODE_ID = input.GamemodeId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task DeleteAsync(Gamemode input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "DELETE FROM Gamemodes WHERE GamemodeId = @GAMEMODE_ID";
await dbController.QueryAsync(sql, new
{
GAMEMODE_ID = input.GamemodeId
}, cancellationToken);
}
public async Task<Gamemode?> GetAsync(int gamemodeId, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"SELECT * FROM Gamemodes WHERE GamemodeId = @GAMEMODE_ID";
var gamemode = await dbController.GetFirstAsync<Gamemode>(sql, new
{
GAMEMODE_ID = gamemodeId
}, cancellationToken);
return gamemode;
}
public static async Task<List<Gamemode>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "SELECT * FROM Gamemodes";
var list = await dbController.SelectDataAsync<Gamemode>(sql, cancellationToken: cancellationToken);
await LoadGamemodeDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task UpdateAsync(Gamemode input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql;
//string sql = @"UPDATE Gamemodes SET
// Image = @IMAGE
// WHERE GamemodeId = @GAMEMODE_ID";
//await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"UPDATE GamemodeDescription SET
Name = @NAME,
Description = @DESCRIPTION,
Mechanic = @MECHANIC
WHERE GamemodeId = @GAMEMODE_ID AND Code = @CODE";
var parameters = new
{
GAMEMODE_ID = input.GamemodeId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description,
MECHANIC = description.Mechanic
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task<List<Gamemode>> GetAsync(GamemodeFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT gd.Name, g.* " +
"FROM GamemodeDescription gd " +
"INNER JOIN Gamemodes g " +
"ON (g.GamemodeId = gd.GamemodeId) " +
"WHERE 1 = 1");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
sqlBuilder.AppendLine(@$" ORDER BY Name ASC ");
sqlBuilder.AppendLine(dbController.GetPaginationSyntax(filter.PageNumber, filter.Limit));
// Zum Debuggen schreiben wir den Wert einmal als Variabel
string sql = sqlBuilder.ToString();
List<Gamemode> list = await dbController.SelectDataAsync<Gamemode>(sql, GetFilterParameter(filter), cancellationToken);
await LoadGamemodeDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task<int> GetTotalAsync(GamemodeFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT COUNT(*) AS record_count FROM GamemodeDescription WHERE 1 = 1 ");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
string sql = sqlBuilder.ToString();
int result = await dbController.GetFirstAsync<int>(sql, GetFilterParameter(filter), cancellationToken);
return result;
}
public string GetFilterWhere(GamemodeFilter filter)
{
StringBuilder sqlBuilder = new();
if (!string.IsNullOrWhiteSpace(filter.SearchPhrase))
{
sqlBuilder.AppendLine(@" AND (UPPER(Name) LIKE @SEARCHPHRASE)");
}
string sql = sqlBuilder.ToString();
return sql;
}
public Dictionary<string, object?> GetFilterParameter(GamemodeFilter filter)
{
return new Dictionary<string, object?>
{
{ "SEARCHPHRASE", $"%{filter.SearchPhrase}%" },
{ "CULTURE", CultureInfo.CurrentCulture.Name }
};
}
private static async Task LoadGamemodeDescriptionsAsync(List<Gamemode> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> gamemodeIds = list.Select(x => x.GamemodeId);
string sql = $"SELECT * FROM GamemodeDescription WHERE GamemodeId IN ({string.Join(",", gamemodeIds)})";
List<GamemodeDescription> descriptions = await dbController.SelectDataAsync<GamemodeDescription>(sql, null, cancellationToken);
foreach (var gamemode in list)
{
gamemode.Description = [.. descriptions.Where(x => x.GamemodeId == gamemode.GamemodeId)];
}
}
}
}
}

View File

@@ -0,0 +1,51 @@
namespace Tabletop.Core.Services
{
public class GeolocationService(HttpClient httpClient)
{
private readonly HttpClient _httpClient = httpClient;
public Task<string> GetGeolocationAsync(string ipAddress)
{
//// Überprüfen, ob die IP-Adresse lokal ist (127.0.0.1 oder localhost)
//if (await IsLocalIpAddressAsync(ipAddress))
//{
// // Wenn es eine lokale IP-Adresse ist, keine Geolokalisierung durchführen
// return "Lokale IP-Adresse";
//}
//try
//{
// // URL für Geolokalisierung
// var url = $"https://api.ipgeolocation.io/ipgeo?apiKey={AppdataService.ApiKey}&ip={ipAddress}";
// // HTTP-Anfrage senden
// var response = await _httpClient.GetAsync(url);
// // Fehlerbehandlung: Prüfen, ob der Statuscode erfolgreich war
// response.EnsureSuccessStatusCode(); // Wird eine Ausnahme werfen, wenn der Statuscode nicht erfolgreich ist
// // Rückgabe der Geolokalisierungsdaten
// return await response.Content.ReadAsStringAsync();
//}
//catch (HttpRequestException ex)
//{
// // Fehlerbehandlung: Loggen oder Weiterverarbeiten des Fehlers
// throw new Exception($"Fehler bei der Geolokalisierung: {ex.Message}", ex);
//}
return Task.FromResult("Lokale IP-Adresse");
}
// Hilfsmethode, um zu prüfen, ob die IP-Adresse lokal ist
private static Task<bool> IsLocalIpAddressAsync(string ipAddress)
{
// Überprüfen, ob die IP-Adresse eine der folgenden ist
bool isLocal = ipAddress == "127.0.0.1" || ipAddress == "localhost" ||
ipAddress.StartsWith("10.") || ipAddress.StartsWith("192.168.") ||
ipAddress.StartsWith("172.16.");
return Task.FromResult(isLocal); // Rückgabe des Ergebnisses als Task
}
}
}

View File

@@ -0,0 +1,97 @@
using DbController;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class LayoutService : IModelService<Layout, int>
{
public async Task CreateAsync(Layout input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = $@"INSERT INTO Layouts
(
GamemodeId,
Teams,
Width,
Height
)
VALUES
(
@GAMEMODE_ID
@TEAMS,
@WIDTH,
@HEIGHT
); {dbController.GetLastIdSql()}";
input.LayoutId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
}
public async Task DeleteAsync(Layout input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "DELETE FROM Layouts WHERE LayoutId = @LAYOUT_ID";
await dbController.QueryAsync(sql, new
{
LAYOUT_ID = input.LayoutId
}, cancellationToken);
}
public static async Task<List<SetupZone>> GetSetupZonesAsync(int layoutId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"
SELECT sz.SetupZoneId, sz.LayoutId, z.*
FROM SetupZones sz
INNER JOIN Zones z ON (z.ZoneId = sz.ZoneId)
WHERE sz.LayoutId = @LAYOUT_ID";
var list = await dbController.SelectDataAsync<SetupZone>(sql, new
{
LAYOUT_ID = layoutId
}, cancellationToken);
return list;
}
public static async Task<List<CaptureZone>> GetCaptureZonesAsync(int layoutId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"
SELECT cz.CaptureZoneId, cz.LayoutId, z.*
FROM CaptureZones cz
INNER JOIN Zones z ON (z.ZoneId = cz.ZoneId)
WHERE cz.LayoutId = @LAYOUT_ID";
var list = await dbController.SelectDataAsync<CaptureZone>(sql, new
{
LAYOUT_ID = layoutId
}, cancellationToken);
return list;
}
public static async Task<List<Layout>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "SELECT * FROM Layouts";
var list = await dbController.SelectDataAsync<Layout>(sql, cancellationToken: cancellationToken);
foreach(var layout in list)
{
layout.SetupZones = await GetSetupZonesAsync(layout.LayoutId, dbController, cancellationToken);
layout.CaptureZones = await GetCaptureZonesAsync(layout.LayoutId, dbController, cancellationToken);
}
return list;
}
public Task<Layout?> GetAsync(int battlegroundId, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
public Task UpdateAsync(Layout input, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,57 @@
using DbController;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class MoveService : IModelService<Move, int>
{
public async Task CreateAsync(Move input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = $@"INSERT INTO Moves
(
PlayerId,
GameId,
TurnNr,
MoveNr,
StartMove,
EndMove
)
VALUES
(
@PLAYER_ID
@GAME_ID,
@TURN_NR,
@MOVE_NR,
@START_MOVE,
@END_END
); {dbController.GetLastIdSql()}";
input.MoveId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
}
public Task DeleteAsync(Move input, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
public Task<Move?> GetAsync(int identifier, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
public async Task UpdateAsync(Move input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"UPDATE Moves SET
PlayerId = @PLAYER_ID,
GameId = @GAME_ID,
TurnNr = @TURN_NR,
MoveNr = @MOVE_NR,
StartMove = @START_MOVE,
EndMove = @END_END
WHERE MoveId = @MOVE_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
}
}
}

View File

@@ -0,0 +1,84 @@
using DbController;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class PermissionService
{
public static async Task<List<Permission>> GetUserPermissionsAsync(int userId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT p.*
FROM UserPermissions up
INNER JOIN Permissions p ON (p.PermissionId = up.PermissionId)
WHERE UserId = @USER_ID";
var list = await dbController.SelectDataAsync<Permission>(sql, new
{
USER_ID = userId
}, cancellationToken);
await LoadPermissionDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task UpdateUserPermissionsAsync(User user, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
// Step 1: Delete all permissions for the user.
string sql = "DELETE FROM UserPermissions WHERE UserId = @USER_ID";
await dbController.QueryAsync(sql, new
{
USER_ID = user.UserId
}, cancellationToken);
// Step 2: Add all permissions from the object back.
foreach (var permission in user.Permissions)
{
sql = @"INSERT INTO UserPermissions
(
UserId,
PermissionId
)
VALUES
(
@USER_ID,
@PERMISSION_ID
)";
await dbController.QueryAsync(sql, new
{
USER_ID = user.UserId,
PERMISSION_ID = permission.PermissionId
}, cancellationToken);
}
}
public static async Task<List<Permission>> GetAllAsync(IDbController dbController)
{
string sql = "SELECT * FROM Permissions";
var list = await dbController.SelectDataAsync<Permission>(sql);
await LoadPermissionDescriptionsAsync(list, dbController);
return list;
}
private static async Task LoadPermissionDescriptionsAsync(List<Permission> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> permissionIds = list.Select(x => x.PermissionId);
string sql = $"SELECT * FROM PermissionDescription WHERE PermissionId IN ({string.Join(",", permissionIds)})";
List<PermissionDescription> descriptions = await dbController.SelectDataAsync<PermissionDescription>(sql, null, cancellationToken);
foreach (var permission in list)
{
permission.Description = [.. descriptions.Where(x => x.PermissionId == permission.PermissionId)];
}
}
}
}
}

View File

@@ -0,0 +1,127 @@
using DbController;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class PlayerService(UserService userService, UnitService unitService) : IModelService<Player, int>
{
private readonly UserService _userService = userService;
private readonly UnitService _unitService = unitService;
public async Task CreateAsync(Player input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = $@"INSERT INTO Players
(
UserId,
GameId,
FractionId,
Team,
Color,
UsedForce
)
VALUES
(
@USER_ID,
@GAME_ID,
@FRACTION_ID,
@TEAM,
@COLOR,
@USED_FORCE
); {dbController.GetLastIdSql()}";
input.PlayerId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
}
public async Task DeleteAsync(Player Input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "DELETE FROM Players WHERE PlayerId = @PLAYER_ID";
await dbController.QueryAsync(sql, new
{
Input_ID = Input.PlayerId
}, cancellationToken);
}
public static async Task DeleteByGameAsync(int gameId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "DELETE FROM Players WHERE GameId = @GAME_ID";
await dbController.QueryAsync(sql, new
{
GAME_ID = gameId
}, cancellationToken);
}
public Task<Player?> GetAsync(int identifier, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
public async Task<List<Player>> GetGamePlayersAsync(int gameId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = ("SELECT * FROM Players WHERE GameId = @GAME_ID");
List<Player> list = await dbController.SelectDataAsync<Player>(sql, new
{
GAME_ID = gameId
}, cancellationToken);
if (list.Count != 0)
{
foreach (var item in list)
{
item.Units = await _unitService.GetPlayerUnitsAsync(item.PlayerId, dbController, cancellationToken);
item.User = await _userService.GetUserInformationAsync(item.UserId, dbController, cancellationToken) ?? new();
}
}
return list;
}
public async Task UpdateAsync(Player player, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
await UnitService.DeletePlayerUnitsAsync(player.PlayerId, dbController, cancellationToken);
string sql = @"UPDATE Players SET
Points = @POINTS
WHERE PlayerId = @PLAYER_ID";
await dbController.QueryAsync(sql, player.GetParameters(), cancellationToken);
}
public async Task UpdatePlayerOrderAsync(Player player, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"UPDATE Players SET
OrderNr = @ORDER_NR,
StartZone = @START_ZONE
WHERE PlayerId = @PLAYER_ID";
await dbController.QueryAsync(sql, player.GetParameters(), cancellationToken);
}
public async Task UpdatePlayerArmyAsync(Player player, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
await UnitService.DeletePlayerUnitsAsync(player.PlayerId, dbController, cancellationToken);
string sql = @"UPDATE Players SET
UsedForce = @USED_FORCE
WHERE PlayerId = @PLAYER_ID";
await dbController.QueryAsync(sql, player.GetParameters(), cancellationToken);
foreach (var unit in player.Units)
{
await _unitService.CreatePlayerUnitAsync(player, unit, dbController, cancellationToken);
}
}
}
}

View File

@@ -0,0 +1,112 @@
using DbController;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class SurfaceService : IModelService<Surface, int>
{
public async Task CreateAsync(Surface input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = $@"INSERT INTO Surfaces
(
Image
)
VALUES
(
@IMAGE
); {dbController.GetLastIdSql()}";
input.SurfaceId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"INSERT INTO SurfaceDescription
(
SurfaceId,
Code,
Name,
Description
)
VALUES
(
@SURFACE_ID,
@CODE,
@NAME,
@DESCRIPTION
)";
var parameters = new
{
BATTLEGROUND_ID = input.SurfaceId,
CODE = description.Code,
NAME = description.Name,
description = description.Description,
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task DeleteAsync(Surface input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "DELETE FROM Surfaces WHERE SurfaceId = @SURFACE_ID";
await dbController.QueryAsync(sql, new
{
SURFACE_ID = input.SurfaceId
}, cancellationToken);
}
public static async Task<List<Surface>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "SELECT * FROM Surfaces";
var list = await dbController.SelectDataAsync<Surface>(sql, cancellationToken: cancellationToken);
foreach(var item in list)
{
if(item.Image != null)
{
string base64String = Convert.ToBase64String(item.Image);
item.ConvertedImage = $"data:image/png;base64,{base64String}";
}
}
await LoadSurfaceDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task<Surface?> GetAsync(int surfaceId, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"SELECT * FROM Surfaces WHERE SurfaceId = @SURFACE_ID";
var surface = await dbController.GetFirstAsync<Surface>(sql, new
{
SURFACE_ID = surfaceId
}, cancellationToken);
return surface;
}
private static async Task LoadSurfaceDescriptionsAsync(List<Surface> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> surfaceIds = list.Select(x => x.SurfaceId);
string sql = $"SELECT * FROM SurfaceDescription WHERE SurfaceId IN ({string.Join(",", surfaceIds)})";
List<SurfaceDescription> descriptions = await dbController.SelectDataAsync<SurfaceDescription>(sql, null, cancellationToken);
foreach (var battleLocation in list)
{
battleLocation.Description = [.. descriptions.Where(x => x.SurfaceId == battleLocation.SurfaceId)];
}
}
}
public Task UpdateAsync(Surface input, IDbController dbController, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,171 @@
using DbController;
using System.Text;
using Tabletop.Core.Filters;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class TemplateService : IModelService<Template, int, TemplateFilter>
{
public async Task CreateAsync(Template input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = $@"INSERT INTO Templates
(
UserId,
FractionId,
Name,
Force,
UsedForce
)
VALUES
(
@USER_ID,
@FRACTION_ID,
@NAME,
@FORCE,
@USED_FORCE
); {dbController.GetLastIdSql()}";
input.TemplateId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
foreach(var unit in input.Units)
{
await UnitService.CreateTemplateUnitAsync(input.TemplateId, unit, dbController, cancellationToken);
}
}
public async Task DeleteAsync(Template input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
await UnitService.DeleteTemplateUnitsAsync(input.TemplateId, dbController, cancellationToken);
string sql = "DELETE FROM Templates WHERE TemplateId = @TEMPLATE_ID";
await dbController.QueryAsync(sql, new
{
TEMPLATE_ID = input.TemplateId
}, cancellationToken);
}
public async Task<Template?> GetAsync(int templateId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT * FROM Templates WHERE TemplateId = @TEMPLATE_ID";
var template = await dbController.GetFirstAsync<Template>(sql, new
{
TEMPLATE_ID = templateId
}, cancellationToken);
return template;
}
public static async Task<List<Template>> GetTemplateOnForceAsync(int user_id, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "SELECT * FROM Templates WHERE UserId = @USER_ID";
var list = await dbController.SelectDataAsync<Template>(sql, new
{
USER_ID = user_id
}, cancellationToken);
foreach (var item in list)
{
item.Units = await UnitService.GetTemplateUnitsAsync(item.TemplateId, dbController, cancellationToken);
}
return list;
}
public async Task<List<Template>> GetAsync(TemplateFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sb = new();
sb.AppendLine("SELECT * FROM Templates WHERE UserId = @USER_ID");
sb.AppendLine(GetFilterWhere(filter));
sb.AppendLine(@$" ORDER BY Name ASC");
sb.AppendLine(dbController.GetPaginationSyntax(filter.PageNumber, filter.Limit));
string sql = sb.ToString();
List<Template> list = await dbController.SelectDataAsync<Template>(sql, GetFilterParameter(filter), cancellationToken);
foreach(var item in list)
{
item.Units = await UnitService.GetTemplateUnitsAsync(item.TemplateId, dbController, cancellationToken);
}
return list;
}
public Dictionary<string, object?> GetFilterParameter(TemplateFilter filter)
{
return new Dictionary<string, object?>
{
{ "SEARCHPHRASE", $"%{filter.SearchPhrase}%" },
{ "USER_ID", filter.UserId },
{ "FRACTION_ID", filter.FractionId },
{ "FORCE", filter.Force }
};
}
public string GetFilterWhere(TemplateFilter filter)
{
StringBuilder sb = new();
if (!string.IsNullOrWhiteSpace(filter.SearchPhrase))
{
sb.AppendLine(@" AND (UPPER(Name) LIKE @SEARCHPHRASE)");
}
if (filter.FractionId != 0)
{
sb.AppendLine(@" AND FractionId = @FRACTION_ID");
}
if (filter.Force != 0)
{
sb.AppendLine(@" AND Force = @FORCE");
}
string sql = sb.ToString();
return sql;
}
public async Task<int> GetTotalAsync(TemplateFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sb = new();
sb.AppendLine("SELECT COUNT(*) FROM Templates WHERE UserId = @USER_ID");
sb.AppendLine(GetFilterWhere(filter));
string sql = sb.ToString();
int result = await dbController.GetFirstAsync<int>(sql, GetFilterParameter(filter), cancellationToken);
return result;
}
public async Task UpdateAsync(Template input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
await UnitService.DeleteTemplateUnitsAsync(input.TemplateId, dbController, cancellationToken);
string sql = @"UPDATE Templates SET
FractionId = @FRACTION_ID,
Name = @NAME,
Force = @FORCE,
UsedForce = @USED_FORCE
WHERE TemplateId = @TEMPLATE_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
foreach (var unit in input.Units)
{
await UnitService.CreateTemplateUnitAsync(input.TemplateId, unit, dbController, cancellationToken);
}
}
}
}

View File

@@ -0,0 +1,393 @@
using DbController;
using System.Globalization;
using System.Text;
using Tabletop.Core.Filters;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class UnitService(WeaponService weaponService) : IModelService<Unit, int, UnitFilter>
{
private readonly WeaponService _weaponService = weaponService;
public async Task CreateAsync(Unit input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = $@"INSERT INTO Units
(
FractionId,
ClassId,
TroopQuantity,
Defense,
Moving,
PrimaryWeaponId,
SecondaryWeaponId,
FistAbilityId,
SecondAbilityId
)
VALUES
(
@FRACTION_ID,
@CLASS_ID,
@TROOP_QUANTITY,
@DEFENSE,
@MOVING,
@PRIMARY_WEAPON_ID,
@SECONDARY_WEAPON_ID,
@FIRST_ABILITY_ID,
@SECOND_ABILITY_ID
); {dbController.GetLastIdSql()}";
input.UnitId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"INSERT INTO UnitDescription
(
UnitId,
Code,
Name,
Description
)
VALUES
(
@UNIT_ID,
@CODE,
@NAME,
@DESCRIPTION
)";
var parameters = new
{
UNIT_ID = input.UnitId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task DeleteAsync(Unit input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "DELETE FROM Units WHERE UnitId = @UNIT_ID";
await dbController.QueryAsync(sql, new
{
UNIT_ID = input.UnitId
}, cancellationToken);
}
public async Task DeleteUnitAsync(int userId, int unitId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "DELETE FROM UserUnits WHERE UserId = @USER_ID AND UnitId = @UNIT_ID";
await dbController.QueryAsync(sql, new
{
USER_ID = userId,
UNIT_ID = unitId
}, cancellationToken);
}
public async Task<Unit?> GetAsync(int unitId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT * FROM Units WHERE UnitId = @UNIT_ID";
var unit = await dbController.GetFirstAsync<Unit>(sql, new
{
UNIT_ID = unitId
}, cancellationToken);
if (unit?.PrimaryWeaponId != null && unit?.SecondaryWeaponId != null)
{
unit.PrimaryWeapon = await _weaponService.GetAsync((int)unit.PrimaryWeaponId, dbController, cancellationToken) ?? new();
unit.SecondaryWeapon = await _weaponService.GetAsync((int)unit.SecondaryWeaponId, dbController, cancellationToken) ?? new();
}
return unit;
}
public static async Task<List<Unit>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "SELECT * FROM Units";
var list = await dbController.SelectDataAsync<Unit>(sql, cancellationToken: cancellationToken);
await LoadUnitDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task<List<Unit>> GetAsync(UnitFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT ud.Name, u.* " +
"FROM UnitDescription ud " +
"INNER JOIN Units u " +
"ON (u.UnitId = ud.UnitId) " +
"WHERE 1 = 1");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
sqlBuilder.AppendLine(@$" ORDER BY Name ASC ");
sqlBuilder.AppendLine(dbController.GetPaginationSyntax(filter.PageNumber, filter.Limit));
string sql = sqlBuilder.ToString();
List<Unit> list = await dbController.SelectDataAsync<Unit>(sql, GetFilterParameter(filter), cancellationToken);
await LoadUnitDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public Dictionary<string, object?> GetFilterParameter(UnitFilter filter)
{
return new Dictionary<string, object?>
{
{ "SEARCHPHRASE", $"%{filter.SearchPhrase}%" },
{ "FRACTION_ID", filter.FractionId },
{ "CULTURE", CultureInfo.CurrentCulture.Name }
};
}
public string GetFilterWhere(UnitFilter filter)
{
StringBuilder sqlBuilder = new();
if (!string.IsNullOrWhiteSpace(filter.SearchPhrase))
{
sqlBuilder.AppendLine(@" AND (UPPER(Name) LIKE @SEARCHPHRASE)");
}
if (filter.FractionId != 0)
{
sqlBuilder.AppendLine(@" AND FractionId = @FRACTION_ID");
}
string sql = sqlBuilder.ToString();
return sql;
}
public async Task<int> GetTotalAsync(UnitFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT COUNT(*) AS record_count FROM UnitDescription ud JOIN Units u ON ud.UnitId = u.UnitId WHERE 1 = 1");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
string sql = sqlBuilder.ToString();
int result = await dbController.GetFirstAsync<int>(sql, GetFilterParameter(filter), cancellationToken);
return result;
}
public static async Task<List<Unit>> GetUserUnitsAsync(int userId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"
SELECT uu.Quantity, u.*
FROM UserUnits uu
INNER JOIN Units u ON (u.UnitId = uu.UnitId)
WHERE uu.UserId = @USER_ID";
var list = await dbController.SelectDataAsync<Unit>(sql, new
{
USER_ID = userId
}, cancellationToken);
await LoadUnitDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task<List<Unit>> GetPlayerUnitsAsync(int playerId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"
SELECT pu.Quantity, u.*
FROM PlayerUnits pu
INNER JOIN Units u ON (u.UnitId = pu.UnitId)
WHERE pu.PlayerId = @PLAYER_ID";
var list = await dbController.SelectDataAsync<Unit>(sql, new
{
PLAYER_ID = playerId
}, cancellationToken);
await LoadUnitDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public static async Task<List<Unit>> GetTemplateUnitsAsync(int templateId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"
SELECT tu.Quantity, u.*
FROM TemplateUnits tu
INNER JOIN Units u ON (u.UnitId = tu.UnitId)
WHERE tu.TemplateId = @TEMPLATE_ID";
var list = await dbController.SelectDataAsync<Unit>(sql, new
{
TEMPLATE_ID = templateId
}, cancellationToken);
await LoadUnitDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public async Task CreateUserUnitAsync(User user, Unit unit, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "DELETE FROM UserUnits WHERE UserId = @USER_ID AND UnitId = @UNIT_ID";
await dbController.QueryAsync(sql, new
{
USER_ID = user.UserId,
UNIT_ID = unit.UnitId
}, cancellationToken);
sql = @"INSERT INTO UserUnits
(
UserId,
UnitId,
Quantity
)
VALUES
(
@USER_ID,
@UNIT_ID,
@QUANTITY
)";
await dbController.QueryAsync(sql, new
{
USER_ID = user.UserId,
UNIT_ID = unit.UnitId,
QUANTITY = unit.Quantity
}, cancellationToken);
}
public static async Task DeleteTemplateUnitsAsync(int templateId, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "DELETE FROM TemplateUnits WHERE TemplateId = @TEMPLATE_ID";
await dbController.QueryAsync(sql, new
{
TEMPLATE_ID = templateId
}, cancellationToken);
}
public static async Task DeletePlayerUnitsAsync(int playerid, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = "DELETE FROM PlayerUnits WHERE PlayerId = @PLAYER_ID";
await dbController.QueryAsync(sql, new
{
PLAYER_ID = playerid
}, cancellationToken);
}
public static async Task CreateTemplateUnitAsync(int templateId, Unit unit, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"INSERT INTO TemplateUnits
(
TemplateId,
UnitId,
Quantity
)
VALUES
(
@TEMPLATE_ID,
@UNIT_ID,
@QUANTITY
)";
await dbController.QueryAsync(sql, new
{
TEMPLATE_ID = templateId,
UNIT_ID = unit.UnitId,
QUANTITY = unit.Quantity
}, cancellationToken);
}
public async Task CreatePlayerUnitAsync(Player Input, Unit unit, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"INSERT INTO PlayerUnits
(
PlayerId,
UnitId,
Quantity
)
VALUES
(
@PLAYER_ID,
@UNIT_ID,
@QUANTITY
)";
await dbController.QueryAsync(sql, new
{
PLAYER_ID = Input.PlayerId,
UNIT_ID = unit.UnitId,
QUANTITY = unit.Quantity
}, cancellationToken);
}
public async Task UpdateAsync(Unit input, IDbController dbController, CancellationToken cancellationToken = default)
{
string sql = @"UPDATE Units SET
FractionId = @FRACTION_ID,
ClassId = @CLASS_ID,
TroopQuantity = @TROOP_QUANTITY,
Defense = @DEFENSE,
Moving = @MOVING,
PrimaryWeaponId = @PRIMARY_WEAPON_ID,
SecondaryWeaponId = @SECONDARY_WEAPON_ID,
FirstAbilityId = @FIRST_ABILITY_ID,
SecondAbilityId = @SECOND_ABILITY_ID
WHERE UnitId = @UNIT_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"UPDATE UnitDescription SET
Name = @NAME,
Description = @DESCRIPTION,
Mechanic = @MECHANIC
WHERE UnitId = @UNIT_ID AND Code = @CODE";
var parameters = new
{
UNIT_ID = input.UnitId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description,
MECHANIC = description.Mechanic
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
private static async Task LoadUnitDescriptionsAsync(List<Unit> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> unitIds = list.Select(x => x.UnitId);
string sql = $"SELECT * FROM UnitDescription WHERE UnitId IN ({string.Join(",", unitIds)})";
List<UnitDescription> descriptions = await dbController.SelectDataAsync<UnitDescription>(sql, null, cancellationToken);
foreach (var unit in list)
{
unit.Description = [.. descriptions.Where(x => x.UnitId == unit.UnitId)];
}
}
}
}
}

View File

@@ -0,0 +1,298 @@
using DbController;
using System.Text;
using Tabletop.Core.Filters;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class UserService(PermissionService permissionService) : IModelService<User, int, UserFilter>
{
private readonly PermissionService _permissionService = permissionService;
public async Task CreateAsync(User input, IDbController dbController, CancellationToken cancellationToken = default)
{
input.LastLogin = DateTime.Now;
input.RegistrationDate = DateTime.Now;
cancellationToken.ThrowIfCancellationRequested();
string sql = $@"INSERT INTO Users
(
Username,
DisplayName,
Password,
Salt,
LastLogin,
RegistrationDate
)
VALUES
(
@USERNAME,
@DISPLAY_NAME,
@PASSWORD,
@SALT,
@LAST_LOGIN,
@REGISTRATION_DATE
); {dbController.GetLastIdSql()}";
input.UserId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
await _permissionService.UpdateUserPermissionsAsync(input, dbController, cancellationToken);
}
public async Task DeleteAsync(User input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "DELETE FROM Users WHERE UserId = @USER_ID";
await dbController.QueryAsync(sql, new
{
USER_ID = input.UserId
}, cancellationToken);
}
public static async Task DeleteFriendAsync(int userId, int friendId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "DELETE FROM UserFriends WHERE UserId = @USER_ID AND FriendId = @FRIEND_ID";
await dbController.QueryAsync(sql, new
{
USER_ID = userId,
FRIEND_ID = friendId
}, cancellationToken);
}
public async Task<User?> GetAsync(int userId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT * FROM Users WHERE UserId = @USER_ID";
var user = await dbController.GetFirstAsync<User>(sql, new
{
USER_ID = userId
}, cancellationToken);
if (user is not null)
{
user.Permissions = await PermissionService.GetUserPermissionsAsync(user.UserId, dbController, cancellationToken);
}
return user;
}
public static async Task<User?> GetAsync(string username, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT * FROM Users WHERE UPPER(username) = UPPER(@USERNAME)";
var user = await dbController.GetFirstAsync<User>(sql, new
{
USERNAME = username
}, cancellationToken);
if (user is not null)
{
user.Permissions = await PermissionService.GetUserPermissionsAsync(user.UserId, dbController, cancellationToken);
}
return user;
}
public async Task<User?> GetUserInformationAsync(int userId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT UserId, Username, DisplayName, Image FROM Users WHERE UserId = @USER_ID";
var user = await dbController.GetFirstAsync<User>(sql, new
{
USER_ID = userId
}, cancellationToken);
return user;
}
public async Task<List<User>> GetAsync(UserFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.Append("SELECT UserId, Username, DisplayName, Description, MainFractionId, LastLogin, RegistrationDate, Image FROM Users WHERE 1 = 1");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@$" ORDER BY UserId DESC");
sqlBuilder.AppendLine(dbController.GetPaginationSyntax(filter.PageNumber, filter.Limit));
// Zum Debuggen schreiben wir den Wert einmal als Variabel
string sql = sqlBuilder.ToString();
List<User> list = await dbController.SelectDataAsync<User>(sql, GetFilterParameter(filter), cancellationToken);
// Berechtigungen müssen noch geladen werden
List<Permission> permissions = await PermissionService.GetAllAsync(dbController);
sql = "SELECT * FROM UserPermissions";
List<UserPermission> user_permissions = await dbController.SelectDataAsync<UserPermission>(sql, null, cancellationToken);
foreach (var user in list)
{
List<UserPermission> permissions_for_user = [.. user_permissions.Where(x => x.UserId == user.UserId)];
List<int> permission_ids = [.. permissions_for_user.Select(x => x.PermissionId)];
user.Permissions = [.. permissions.Where(x => permission_ids.Contains(x.PermissionId))];
}
return list;
}
public Dictionary<string, object?> GetFilterParameter(UserFilter filter)
{
return new Dictionary<string, object?>
{
{ "SEARCHPHRASE", $"%{filter.SearchPhrase}%" }
};
}
public string GetFilterWhere(UserFilter filter)
{
StringBuilder sb = new();
if (!string.IsNullOrWhiteSpace(filter.SearchPhrase))
{
sb.AppendLine(@" AND
(
UPPER(DisplayName) LIKE @SEARCHPHRASE
OR UPPER(Username) LIKE @SEARCHPHRASE
)");
}
string sql = sb.ToString();
return sql;
}
public async Task<int> GetTotalAsync(UserFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT COUNT(*) FROM Users WHERE 1 = 1");
sqlBuilder.AppendLine(GetFilterWhere(filter));
string sql = sqlBuilder.ToString();
int result = await dbController.GetFirstAsync<int>(sql, GetFilterParameter(filter), cancellationToken);
return result;
}
public static async Task<List<User>> GetUserFriendsAsync(int userId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT u.UserId, u.Username, u.DisplayName, u.Image
FROM Users AS u
JOIN UserFriends AS uf ON u.UserId = uf.FriendId
WHERE uf.UserId = @USER_ID";
var list = await dbController.SelectDataAsync<User>(sql, new
{
USER_ID = userId
}, cancellationToken);
return list;
}
public static async Task<bool> CheckUserFriendAsync(int userId, int friendId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT
CASE
WHEN EXISTS (
SELECT 1
FROM UserFriends
WHERE UserId = @USER_ID AND FriendId = @FRIEND_ID
) THEN 'true'
ELSE 'false'
END AS IsFriend;";
bool isfriend = await dbController.GetFirstAsync<bool>(sql, new
{
USER_ID = userId,
FRIEND_ID = friendId
}, cancellationToken);
return isfriend;
}
public async Task UpdateAsync(User input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"UPDATE Users SET
Username = @USERNAME,
DisplayName = @DISPLAY_NAME,
Description = @DESCRIPTION,
MainFractionId = @MAIN_FRACTION_ID
WHERE UserId = @USER_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
await _permissionService.UpdateUserPermissionsAsync(input, dbController, cancellationToken);
}
public async Task UpdateLastLoginAsync(User input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
input.LastLogin = DateTime.Now;
string sql = @"UPDATE Users SET
LastLogin = @LAST_LOGIN
WHERE UserId = @USER_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
}
public static async Task<bool> FirstUserExistsAsync(IDbController dbController)
{
string sql = "SELECT * FROM Users";
var tmp = await dbController.GetFirstAsync<object>(sql);
return tmp != null;
}
public async Task<string> GetUsernameAsync(int userId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT Username FROM Users WHERE UserId = @USER_ID";
var user = await dbController.GetFirstAsync<User>(sql, new
{
USER_ID = userId
}, cancellationToken);
if (user != null)
{
return user.Username;
}
else
{
return string.Empty;
}
}
public static async Task CreateUserFriendAsync(int userId, int friendId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"INSERT INTO UserFriends
(
UserId,
FriendId
)
VALUES
(
@USER_ID,
@FRIEND_ID
)";
await dbController.QueryAsync(sql, new
{
USER_ID = userId,
FRIEND_ID = friendId
}, cancellationToken);
}
}
}

View File

@@ -0,0 +1,215 @@
using DbController;
using System.Globalization;
using System.Text;
using Tabletop.Core.Filters;
using Tabletop.Core.Models;
namespace Tabletop.Core.Services
{
public class WeaponService : IModelService<Weapon, int, WeaponFilter>
{
public async Task CreateAsync(Weapon input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = $@"INSERT INTO Weapons
(
Attack,
Quality,
Range,
Dices
)
VALUES
(
@ATTACK,
@QUALITY,
@RANGE,
@DICES
); {dbController.GetLastIdSql()}";
input.WeaponId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"INSERT INTO WeaponDescription
(
WeaponId,
Code,
Name,
Description
)
VALUES
(
@WEAPON_ID,
@CODE,
@NAME,
@DESCRIPTION
)";
var parameters = new
{
WEAPON_ID = input.WeaponId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
public async Task DeleteAsync(Weapon input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = "DELETE FROM Weapons WHERE WeaponId = @WEAPON_ID";
await dbController.QueryAsync(sql, new
{
WEAPON_ID = input.WeaponId
}, cancellationToken);
}
public async Task<Weapon?> GetAsync(int weaponId, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"SELECT * FROM Weapons WHERE WeaponId = @WEAPON_ID";
var weapon = await dbController.GetFirstAsync<Weapon>(sql, new
{
WEAPON_ID = weaponId
}, cancellationToken);
if(weapon != null)
{
await LoadWeaponDescriptionAsync(weapon, dbController, cancellationToken);
}
return weapon;
}
public async Task<List<Weapon>> GetAsync(WeaponFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT wd.Name, w.* " +
"FROM WeaponDescription wd " +
"INNER JOIN Weapons w " +
"ON (w.WeaponId = wd.WeaponId) " +
"WHERE 1 = 1");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
sqlBuilder.AppendLine(@$" ORDER BY Name ASC ");
sqlBuilder.AppendLine(dbController.GetPaginationSyntax(filter.PageNumber, filter.Limit));
string sql = sqlBuilder.ToString();
List<Weapon> list = await dbController.SelectDataAsync<Weapon>(sql, GetFilterParameter(filter), cancellationToken);
await LoadWeaponDescriptionsAsync(list, dbController, cancellationToken);
return list;
}
public Dictionary<string, object?> GetFilterParameter(WeaponFilter filter)
{
return new Dictionary<string, object?>
{
{ "SEARCHPHRASE", $"%{filter.SearchPhrase}%" },
{ "CULTURE", CultureInfo.CurrentCulture.Name }
};
}
public string GetFilterWhere(WeaponFilter filter)
{
StringBuilder sqlBuilder = new();
if (!string.IsNullOrWhiteSpace(filter.SearchPhrase))
{
sqlBuilder.AppendLine(@" AND (UPPER(Name) LIKE @SEARCHPHRASE)");
}
string sql = sqlBuilder.ToString();
return sql;
}
public async Task<int> GetTotalAsync(WeaponFilter filter, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
StringBuilder sqlBuilder = new();
sqlBuilder.AppendLine("SELECT COUNT(*) AS record_count FROM WeaponDescription WHERE 1 = 1 ");
sqlBuilder.AppendLine(GetFilterWhere(filter));
sqlBuilder.AppendLine(@" AND Code = @CULTURE");
string sql = sqlBuilder.ToString();
int result = await dbController.GetFirstAsync<int>(sql, GetFilterParameter(filter), cancellationToken);
return result;
}
public static async Task<List<Weapon>> GetAllAsync(IDbController dbController)
{
string sql = "SELECT * FROM Weapons";
var list = await dbController.SelectDataAsync<Weapon>(sql);
await LoadWeaponDescriptionsAsync(list, dbController);
return list;
}
public async Task UpdateAsync(Weapon input, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = @"UPDATE Weapons SET
Attack = @ATTACK,
Quality = @QUALITY,
Range = @RANGE,
Dices = @DICES
WHERE WeaponId = @WEAPON_ID";
await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
foreach (var description in input.Description)
{
sql = @"UPDATE WeaponDescription SET
Name = @NAME,
Description = @DESCRIPTION
WHERE WeaponId = @WEAPON_ID AND Code = @CODE";
var parameters = new
{
WEAPON_ID = input.WeaponId,
CODE = description.Code,
NAME = description.Name,
DESCRIPTION = description.Description
};
await dbController.QueryAsync(sql, parameters, cancellationToken);
}
}
private static async Task LoadWeaponDescriptionsAsync(List<Weapon> list, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
if (list.Count != 0)
{
IEnumerable<int> weaponIds = list.Select(x => x.WeaponId);
string sql = $"SELECT * FROM WeaponDescription WHERE WeaponId IN ({string.Join(",", weaponIds)})";
List<WeaponDescription> descriptions = await dbController.SelectDataAsync<WeaponDescription>(sql, null, cancellationToken);
foreach (var weapon in list)
{
weapon.Description = descriptions.Where(x => x.WeaponId == weapon.WeaponId).ToList();
}
}
}
private static async Task LoadWeaponDescriptionAsync(Weapon weapon, IDbController dbController, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string sql = $"SELECT * FROM WeaponDescription WHERE WeaponId IN @WEAPON_ID";
weapon.Description = await dbController.SelectDataAsync<WeaponDescription>(sql, new
{
WEAPON_ID = weapon.WeaponId
}, cancellationToken);
}
}
}