Add MCDO (#31)
* rudimentary charadata first impl * update submodule * update properly * some fixes etc * add cascade and some other fixes * most of charadata impl * dotnet 9 * net9 and migration to k4os * bum papi --------- Co-authored-by: Stanley Dimant <root.darkarchon@outlook.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
@@ -12,7 +12,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MaxMind.GeoIP2" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using MareSynchronos.API.Data.Enum;
|
||||
using MareSynchronos.API.SignalR;
|
||||
using MareSynchronos.API.SignalR;
|
||||
using MareSynchronosServer.Hubs;
|
||||
using MareSynchronosShared.Utils;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
@@ -0,0 +1,554 @@
|
||||
using MareSynchronos.API.Data;
|
||||
using MareSynchronos.API.Dto.CharaData;
|
||||
using MareSynchronosServer.Utils;
|
||||
using MareSynchronosShared.Models;
|
||||
using MareSynchronosShared.Utils;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace MareSynchronosServer.Hubs;
|
||||
|
||||
public partial class MareHub
|
||||
{
|
||||
[Authorize(Policy = "Identified")]
|
||||
public async Task<CharaDataFullDto?> CharaDataCreate()
|
||||
{
|
||||
_logger.LogCallInfo();
|
||||
|
||||
int uploadCount = DbContext.CharaData.Count(c => c.UploaderUID == UserUID);
|
||||
User user = DbContext.Users.Single(u => u.UID == UserUID);
|
||||
int maximumUploads = string.IsNullOrEmpty(user.Alias) ? _maxCharaDataByUser : _maxCharaDataByUserVanity;
|
||||
if (uploadCount >= maximumUploads)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string charaDataId = null;
|
||||
while (charaDataId == null)
|
||||
{
|
||||
charaDataId = StringUtils.GenerateRandomString(10, "abcdefghijklmnopqrstuvwxyzABCDEFHIJKLMNOPQRSTUVWXYZ");
|
||||
bool idExists = await DbContext.CharaData.AnyAsync(c => c.UploaderUID == UserUID && c.Id == charaDataId).ConfigureAwait(false);
|
||||
if (idExists)
|
||||
{
|
||||
charaDataId = null;
|
||||
}
|
||||
}
|
||||
|
||||
DateTime createdDate = DateTime.UtcNow;
|
||||
CharaData charaData = new()
|
||||
{
|
||||
Id = charaDataId,
|
||||
UploaderUID = UserUID,
|
||||
CreatedDate = createdDate,
|
||||
UpdatedDate = createdDate,
|
||||
AccessType = CharaDataAccess.Individuals,
|
||||
ShareType = CharaDataShare.Private,
|
||||
CustomizeData = string.Empty,
|
||||
GlamourerData = string.Empty,
|
||||
ExpiryDate = DateTime.MaxValue,
|
||||
Description = string.Empty,
|
||||
};
|
||||
|
||||
await DbContext.CharaData.AddAsync(charaData).ConfigureAwait(false);
|
||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
_logger.LogCallInfo(MareHubLogger.Args("SUCCESS", charaDataId));
|
||||
|
||||
return GetCharaDataFullDto(charaData);
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
public async Task<bool> CharaDataDelete(string id)
|
||||
{
|
||||
var existingData = await DbContext.CharaData.SingleOrDefaultAsync(u => u.Id == id && u.UploaderUID == UserUID).ConfigureAwait(false);
|
||||
if (existingData == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
_logger.LogCallInfo(MareHubLogger.Args("SUCCESS", id));
|
||||
|
||||
DbContext.Remove(existingData);
|
||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogCallWarning(MareHubLogger.Args("FAILURE", id, ex.Message));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
public async Task<CharaDataDownloadDto?> CharaDataDownload(string id)
|
||||
{
|
||||
CharaData charaData = await GetCharaDataById(id, nameof(CharaDataDownload)).ConfigureAwait(false);
|
||||
|
||||
if (!string.Equals(charaData.UploaderUID, UserUID, StringComparison.Ordinal))
|
||||
{
|
||||
charaData.DownloadCount++;
|
||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_logger.LogCallInfo(MareHubLogger.Args("SUCCESS", id));
|
||||
|
||||
return GetCharaDataDownloadDto(charaData);
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
public async Task<CharaDataMetaInfoDto?> CharaDataGetMetainfo(string id)
|
||||
{
|
||||
var charaData = await GetCharaDataById(id, nameof(CharaDataGetMetainfo)).ConfigureAwait(false);
|
||||
|
||||
_logger.LogCallInfo(MareHubLogger.Args("SUCCESS", id));
|
||||
|
||||
return GetCharaDataMetaInfoDto(charaData);
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
public async Task<List<CharaDataFullDto>> CharaDataGetOwn()
|
||||
{
|
||||
var ownCharaData = await DbContext.CharaData
|
||||
.Include(u => u.Files)
|
||||
.Include(u => u.FileSwaps)
|
||||
.Include(u => u.OriginalFiles)
|
||||
.Include(u => u.AllowedIndividiuals)
|
||||
.ThenInclude(u => u.AllowedUser)
|
||||
.Include(u => u.Poses)
|
||||
.AsSplitQuery()
|
||||
.Where(c => c.UploaderUID == UserUID).ToListAsync().ConfigureAwait(false);
|
||||
_logger.LogCallInfo(MareHubLogger.Args("SUCCESS"));
|
||||
return [.. ownCharaData.Select(GetCharaDataFullDto)];
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
public async Task<List<CharaDataMetaInfoDto>> CharaDataGetShared()
|
||||
{
|
||||
_logger.LogCallInfo();
|
||||
|
||||
var allPairs = await GetAllPairInfo(UserUID).ConfigureAwait(false);
|
||||
List<CharaData> sharedCharaData = [];
|
||||
foreach (var pair in allPairs.Where(p => !p.Value.OwnPermissions.IsPaused && !p.Value.OtherPermissions.IsPaused))
|
||||
{
|
||||
var allSharedDataByPair = await DbContext.CharaData
|
||||
.Include(u => u.Files)
|
||||
.Include(u => u.OriginalFiles)
|
||||
.Include(u => u.AllowedIndividiuals)
|
||||
.Include(u => u.Poses)
|
||||
.Include(u => u.Uploader)
|
||||
.Where(p => p.ShareType == CharaDataShare.Shared && p.UploaderUID == pair.Key)
|
||||
.AsSplitQuery()
|
||||
.AsNoTracking()
|
||||
.ToListAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
foreach (var charaData in allSharedDataByPair)
|
||||
{
|
||||
if (await CheckCharaDataAllowance(charaData).ConfigureAwait(false))
|
||||
{
|
||||
sharedCharaData.Add(charaData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var charaDataDirectlyShared = await DbContext.CharaData.Include(u => u.Files)
|
||||
.Include(u => u.OriginalFiles)
|
||||
.Include(u => u.AllowedIndividiuals)
|
||||
.Include(u => u.Poses)
|
||||
.Include(u => u.Uploader)
|
||||
.Where(p => p.ShareType == CharaDataShare.Shared && p.AllowedIndividiuals.Any(u => u.AllowedUserUID == UserUID))
|
||||
.AsSplitQuery()
|
||||
.AsNoTracking()
|
||||
.ToListAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
foreach (var data in charaDataDirectlyShared)
|
||||
{
|
||||
if (sharedCharaData.Exists(d => string.Equals(d.Id, data.Id, StringComparison.Ordinal)
|
||||
&& string.Equals(d.UploaderUID, d.UploaderUID, StringComparison.Ordinal)))
|
||||
continue;
|
||||
sharedCharaData.Add(data);
|
||||
}
|
||||
|
||||
_logger.LogCallInfo(MareHubLogger.Args("SUCCESS", sharedCharaData.Count));
|
||||
|
||||
return [.. sharedCharaData.Select(GetCharaDataMetaInfoDto)];
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
public async Task<CharaDataFullDto?> CharaDataUpdate(CharaDataUpdateDto updateDto)
|
||||
{
|
||||
var charaData = await DbContext.CharaData
|
||||
.Include(u => u.Files)
|
||||
.Include(u => u.OriginalFiles)
|
||||
.Include(u => u.AllowedIndividiuals)
|
||||
.ThenInclude(u => u.AllowedUser)
|
||||
.Include(u => u.FileSwaps)
|
||||
.Include(u => u.Poses)
|
||||
.AsSplitQuery()
|
||||
.SingleOrDefaultAsync(u => u.Id == updateDto.Id && u.UploaderUID == UserUID).ConfigureAwait(false);
|
||||
|
||||
if (charaData == null)
|
||||
return null;
|
||||
|
||||
bool anyChanges = false;
|
||||
|
||||
if (updateDto.Description != null)
|
||||
{
|
||||
charaData.Description = updateDto.Description;
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.ExpiryDate != null)
|
||||
{
|
||||
charaData.ExpiryDate = updateDto.ExpiryDate;
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.GlamourerData != null)
|
||||
{
|
||||
charaData.GlamourerData = updateDto.GlamourerData;
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.CustomizeData != null)
|
||||
{
|
||||
charaData.CustomizeData = updateDto.CustomizeData;
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.ManipulationData != null)
|
||||
{
|
||||
charaData.ManipulationData = updateDto.ManipulationData;
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.AccessType != null)
|
||||
{
|
||||
charaData.AccessType = GetAccessType(updateDto.AccessType.Value);
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.ShareType != null)
|
||||
{
|
||||
charaData.ShareType = GetShareType(updateDto.ShareType.Value);
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.AllowedUsers != null)
|
||||
{
|
||||
var individuals = charaData.AllowedIndividiuals.ToList();
|
||||
charaData.AllowedIndividiuals.Clear();
|
||||
DbContext.RemoveRange(individuals);
|
||||
var allowedUserList = updateDto.AllowedUsers.ToList();
|
||||
foreach (var user in updateDto.AllowedUsers)
|
||||
{
|
||||
var dbUser = await DbContext.Users.SingleOrDefaultAsync(u => u.UID == user || u.Alias == user).ConfigureAwait(false);
|
||||
if (dbUser != null)
|
||||
{
|
||||
if (!allowedUserList.Contains(dbUser.UID, StringComparer.Ordinal) && !allowedUserList.Contains(dbUser.Alias, StringComparer.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
allowedUserList.RemoveAll(u => string.Equals(u, dbUser.UID, StringComparison.Ordinal));
|
||||
allowedUserList.RemoveAll(u => string.Equals(u, dbUser.Alias, StringComparison.Ordinal));
|
||||
|
||||
charaData.AllowedIndividiuals.Add(new CharaDataAllowance()
|
||||
{
|
||||
AllowedUser = dbUser,
|
||||
Parent = charaData
|
||||
});
|
||||
}
|
||||
}
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.FileGamePaths != null)
|
||||
{
|
||||
var originalFiles = charaData.OriginalFiles.ToList();
|
||||
charaData.OriginalFiles.Clear();
|
||||
DbContext.RemoveRange(originalFiles);
|
||||
var files = charaData.Files.ToList();
|
||||
charaData.Files.Clear();
|
||||
DbContext.RemoveRange(files);
|
||||
foreach (var file in updateDto.FileGamePaths)
|
||||
{
|
||||
charaData.Files.Add(new CharaDataFile()
|
||||
{
|
||||
FileCacheHash = file.HashOrFileSwap,
|
||||
GamePath = file.GamePath,
|
||||
Parent = charaData
|
||||
});
|
||||
|
||||
charaData.OriginalFiles.Add(new CharaDataOriginalFile()
|
||||
{
|
||||
Hash = file.HashOrFileSwap,
|
||||
Parent = charaData,
|
||||
GamePath = file.GamePath
|
||||
});
|
||||
}
|
||||
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.FileSwaps != null)
|
||||
{
|
||||
var fileSwaps = charaData.FileSwaps.ToList();
|
||||
charaData.FileSwaps.Clear();
|
||||
DbContext.RemoveRange(fileSwaps);
|
||||
foreach (var file in updateDto.FileSwaps)
|
||||
{
|
||||
charaData.FileSwaps.Add(new CharaDataFileSwap()
|
||||
{
|
||||
FilePath = file.HashOrFileSwap,
|
||||
GamePath = file.GamePath,
|
||||
Parent = charaData
|
||||
});
|
||||
}
|
||||
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
if (updateDto.Poses != null)
|
||||
{
|
||||
foreach (var pose in updateDto.Poses)
|
||||
{
|
||||
if (pose.Id == null)
|
||||
{
|
||||
charaData.Poses.Add(new CharaDataPose()
|
||||
{
|
||||
Description = pose.Description,
|
||||
Parent = charaData,
|
||||
ParentUploaderUID = UserUID,
|
||||
PoseData = pose.PoseData,
|
||||
WorldData = pose.WorldData == null ? string.Empty : JsonSerializer.Serialize(pose.WorldData),
|
||||
});
|
||||
|
||||
anyChanges = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var associatedPose = charaData.Poses.FirstOrDefault(p => p.Id == pose.Id);
|
||||
if (associatedPose == null)
|
||||
continue;
|
||||
|
||||
if (pose.Description == null && pose.PoseData == null && pose.WorldData == null)
|
||||
{
|
||||
charaData.Poses.Remove(associatedPose);
|
||||
DbContext.Remove(associatedPose);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pose.Description != null)
|
||||
associatedPose.Description = pose.Description;
|
||||
if (pose.WorldData != null)
|
||||
{
|
||||
if (pose.WorldData.Value == default) associatedPose.WorldData = string.Empty;
|
||||
else associatedPose.WorldData = JsonSerializer.Serialize(pose.WorldData.Value);
|
||||
}
|
||||
if (pose.PoseData != null)
|
||||
associatedPose.PoseData = pose.PoseData;
|
||||
}
|
||||
|
||||
anyChanges = true;
|
||||
}
|
||||
|
||||
var overflowingPoses = charaData.Poses.Skip(10).ToList();
|
||||
foreach (var overflowing in overflowingPoses)
|
||||
{
|
||||
charaData.Poses.Remove(overflowing);
|
||||
DbContext.Remove(overflowing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (anyChanges)
|
||||
{
|
||||
charaData.UpdatedDate = DateTime.UtcNow;
|
||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
_logger.LogCallInfo(MareHubLogger.Args("SUCCESS", anyChanges));
|
||||
}
|
||||
|
||||
return GetCharaDataFullDto(charaData);
|
||||
}
|
||||
|
||||
private static CharaDataAccess GetAccessType(AccessTypeDto dataAccess) => dataAccess switch
|
||||
{
|
||||
AccessTypeDto.Public => CharaDataAccess.Public,
|
||||
AccessTypeDto.AllPairs => CharaDataAccess.AllPairs,
|
||||
AccessTypeDto.ClosePairs => CharaDataAccess.ClosePairs,
|
||||
AccessTypeDto.Individuals => CharaDataAccess.Individuals,
|
||||
_ => throw new NotSupportedException(),
|
||||
};
|
||||
|
||||
private static AccessTypeDto GetAccessTypeDto(CharaDataAccess dataAccess) => dataAccess switch
|
||||
{
|
||||
CharaDataAccess.Public => AccessTypeDto.Public,
|
||||
CharaDataAccess.AllPairs => AccessTypeDto.AllPairs,
|
||||
CharaDataAccess.ClosePairs => AccessTypeDto.ClosePairs,
|
||||
CharaDataAccess.Individuals => AccessTypeDto.Individuals,
|
||||
_ => throw new NotSupportedException(),
|
||||
};
|
||||
|
||||
private static CharaDataDownloadDto GetCharaDataDownloadDto(CharaData charaData)
|
||||
{
|
||||
return new CharaDataDownloadDto(charaData.Id, charaData.Uploader.ToUserData())
|
||||
{
|
||||
CustomizeData = charaData.CustomizeData,
|
||||
Description = charaData.Description,
|
||||
FileGamePaths = charaData.Files.Select(k => new GamePathEntry(k.FileCacheHash, k.GamePath)).ToList(),
|
||||
GlamourerData = charaData.GlamourerData,
|
||||
FileSwaps = charaData.FileSwaps.Select(k => new GamePathEntry(k.FilePath, k.GamePath)).ToList(),
|
||||
ManipulationData = charaData.ManipulationData,
|
||||
};
|
||||
}
|
||||
|
||||
private CharaDataFullDto GetCharaDataFullDto(CharaData charaData)
|
||||
{
|
||||
return new CharaDataFullDto(charaData.Id, new(UserUID))
|
||||
{
|
||||
AccessType = GetAccessTypeDto(charaData.AccessType),
|
||||
ShareType = GetShareTypeDto(charaData.ShareType),
|
||||
AllowedUsers = [.. charaData.AllowedIndividiuals.Select(u => new UserData(u.AllowedUser.UID, u.AllowedUser.Alias))],
|
||||
CustomizeData = charaData.CustomizeData,
|
||||
Description = charaData.Description,
|
||||
ExpiryDate = charaData.ExpiryDate ?? DateTime.MaxValue,
|
||||
OriginalFiles = charaData.OriginalFiles.Select(k => new GamePathEntry(k.Hash, k.GamePath)).ToList(),
|
||||
FileGamePaths = charaData.Files.Select(k => new GamePathEntry(k.FileCacheHash, k.GamePath)).ToList(),
|
||||
FileSwaps = charaData.FileSwaps.Select(k => new GamePathEntry(k.FilePath, k.GamePath)).ToList(),
|
||||
GlamourerData = charaData.GlamourerData,
|
||||
CreatedDate = charaData.CreatedDate,
|
||||
UpdatedDate = charaData.UpdatedDate,
|
||||
ManipulationData = charaData.ManipulationData,
|
||||
DownloadCount = charaData.DownloadCount,
|
||||
PoseData = [.. charaData.Poses.OrderBy(p => p.Id).Select(k =>
|
||||
{
|
||||
WorldData data = default;
|
||||
|
||||
if(!string.IsNullOrEmpty(k.WorldData)) data = JsonSerializer.Deserialize<WorldData>(k.WorldData);
|
||||
return new PoseEntry(k.Id)
|
||||
{
|
||||
Description = k.Description,
|
||||
PoseData = k.PoseData,
|
||||
WorldData = data
|
||||
};
|
||||
})],
|
||||
};
|
||||
}
|
||||
|
||||
private static CharaDataMetaInfoDto GetCharaDataMetaInfoDto(CharaData charaData)
|
||||
{
|
||||
var allOrigHashes = charaData.OriginalFiles.Select(k => k.Hash).ToList();
|
||||
var allFileHashes = charaData.Files.Select(f => f.FileCacheHash).ToList();
|
||||
var allHashesPresent = allOrigHashes.TrueForAll(h => allFileHashes.Contains(h, StringComparer.Ordinal));
|
||||
var canBeDownloaded = allHashesPresent &= !string.IsNullOrEmpty(charaData.GlamourerData);
|
||||
return new CharaDataMetaInfoDto(charaData.Id, charaData.Uploader.ToUserData())
|
||||
{
|
||||
CanBeDownloaded = canBeDownloaded,
|
||||
Description = charaData.Description,
|
||||
UpdatedDate = charaData.UpdatedDate,
|
||||
PoseData = [.. charaData.Poses.OrderBy(p => p.Id).Select(k =>
|
||||
{
|
||||
WorldData data = default;
|
||||
if(!string.IsNullOrEmpty(k.WorldData)) data = JsonSerializer.Deserialize<WorldData>(k.WorldData);
|
||||
return new PoseEntry(k.Id)
|
||||
{
|
||||
Description = k.Description,
|
||||
PoseData = k.PoseData,
|
||||
WorldData = data
|
||||
};
|
||||
})],
|
||||
};
|
||||
}
|
||||
|
||||
private static CharaDataShare GetShareType(ShareTypeDto dataShare) => dataShare switch
|
||||
{
|
||||
ShareTypeDto.Shared => CharaDataShare.Shared,
|
||||
ShareTypeDto.Private => CharaDataShare.Private,
|
||||
_ => throw new NotSupportedException(),
|
||||
};
|
||||
|
||||
private static ShareTypeDto GetShareTypeDto(CharaDataShare dataShare) => dataShare switch
|
||||
{
|
||||
CharaDataShare.Shared => ShareTypeDto.Shared,
|
||||
CharaDataShare.Private => ShareTypeDto.Private,
|
||||
_ => throw new NotSupportedException(),
|
||||
};
|
||||
|
||||
private async Task<bool> CheckCharaDataAllowance(CharaData charaData)
|
||||
{
|
||||
// check for self
|
||||
if (string.Equals(charaData.UploaderUID, UserUID, StringComparison.Ordinal))
|
||||
return true;
|
||||
|
||||
// check for public access
|
||||
if (charaData.AccessType == CharaDataAccess.Public)
|
||||
return true;
|
||||
|
||||
// check for individuals
|
||||
if (charaData.AllowedIndividiuals.Any(u => string.Equals(u.AllowedUserUID, UserUID, StringComparison.Ordinal)))
|
||||
return true;
|
||||
|
||||
var pairInfoUploader = await GetAllPairInfo(charaData.UploaderUID).ConfigureAwait(false);
|
||||
|
||||
// check for all pairs
|
||||
if (charaData.AccessType == CharaDataAccess.AllPairs)
|
||||
{
|
||||
if (pairInfoUploader.TryGetValue(UserUID, out var userInfo) && userInfo.IsSynced && !userInfo.OwnPermissions.IsPaused && !userInfo.OtherPermissions.IsPaused)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for individual pairs
|
||||
if (charaData.AccessType == CharaDataAccess.ClosePairs)
|
||||
{
|
||||
if (pairInfoUploader.TryGetValue(UserUID, out var userInfo) && userInfo.IsSynced && !userInfo.OwnPermissions.IsPaused && !userInfo.OtherPermissions.IsPaused
|
||||
&& userInfo.IndividuallyPaired)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task<CharaData> GetCharaDataById(string id, string methodName)
|
||||
{
|
||||
var splitid = id.Split(":", StringSplitOptions.None);
|
||||
if (splitid.Length != 2)
|
||||
{
|
||||
_logger.LogCallWarning(MareHubLogger.Args("INVALID", id));
|
||||
throw new InvalidOperationException($"Id {id} not in expected format");
|
||||
}
|
||||
|
||||
var charaData = await DbContext.CharaData
|
||||
.Include(u => u.Files)
|
||||
.Include(u => u.FileSwaps)
|
||||
.Include(u => u.AllowedIndividiuals)
|
||||
.Include(u => u.Poses)
|
||||
.Include(u => u.Uploader)
|
||||
.AsSplitQuery()
|
||||
.SingleOrDefaultAsync(c => c.Id == splitid[1] && c.UploaderUID == splitid[0]).ConfigureAwait(false);
|
||||
|
||||
if (charaData == null)
|
||||
{
|
||||
_logger.LogCallWarning(MareHubLogger.Args("NOT FOUND", id));
|
||||
throw new InvalidDataException($"No chara data with {id} found");
|
||||
}
|
||||
|
||||
if (!await CheckCharaDataAllowance(charaData).ConfigureAwait(false))
|
||||
{
|
||||
_logger.LogCallWarning(MareHubLogger.Args("UNAUTHORIZED", id));
|
||||
throw new UnauthorizedAccessException($"User is not allowed to download {id}");
|
||||
}
|
||||
|
||||
return charaData;
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,10 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MareSynchronosServer.Utils;
|
||||
using MareSynchronosShared.Utils;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using MareSynchronos.API.Data;
|
||||
using MareSynchronos.API.Dto.Group;
|
||||
using MareSynchronosShared.Metrics;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using MareSynchronosShared.Data;
|
||||
|
||||
namespace MareSynchronosServer.Hubs;
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
||||
private readonly Version _expectedClientVersion;
|
||||
private readonly Lazy<MareDbContext> _dbContextLazy;
|
||||
private MareDbContext DbContext => _dbContextLazy.Value;
|
||||
private readonly int _maxCharaDataByUser;
|
||||
private readonly int _maxCharaDataByUserVanity;
|
||||
|
||||
public MareHub(MareMetrics mareMetrics,
|
||||
IDbContextFactory<MareDbContext> mareDbContextFactory, ILogger<MareHub> logger, SystemInfoService systemInfoService,
|
||||
@@ -51,6 +53,8 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
||||
_maxGroupUserCount = configuration.GetValueOrDefault(nameof(ServerConfiguration.MaxGroupUserCount), 100);
|
||||
_fileServerAddress = configuration.GetValue<Uri>(nameof(ServerConfiguration.CdnFullUrl));
|
||||
_expectedClientVersion = configuration.GetValueOrDefault(nameof(ServerConfiguration.ExpectedClientVersion), new Version(0, 0, 0));
|
||||
_maxCharaDataByUser = configuration.GetValueOrDefault(nameof(ServerConfiguration.MaxCharaDataByUser), 10);
|
||||
_maxCharaDataByUserVanity = configuration.GetValueOrDefault(nameof(ServerConfiguration.MaxCharaDataByUserVanity), 50);
|
||||
_contextAccessor = contextAccessor;
|
||||
_redis = redisDb;
|
||||
_onlineSyncedPairCacheService = onlineSyncedPairCacheService;
|
||||
@@ -109,6 +113,8 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
||||
MaxGroupsJoinedByUser = _maxJoinedGroupsByUser,
|
||||
MaxGroupUserCount = _maxGroupUserCount,
|
||||
FileServerAddress = _fileServerAddress,
|
||||
MaxCharaData = _maxCharaDataByUser,
|
||||
MaxCharaDataVanity = _maxCharaDataByUserVanity,
|
||||
},
|
||||
DefaultPreferredPermissions = new DefaultPermissionsDto()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<UserSecretsId>aspnet-MareSynchronosServer-BA82A12A-0B30-463C-801D-B7E81318CD50</UserSecretsId>
|
||||
<AssemblyVersion>1.1.0.0</AssemblyVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
@@ -25,14 +25,12 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.176">
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.184">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.1.2" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="9.0.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
using MareSynchronosShared.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace MareSynchronosServer.Services;
|
||||
|
||||
public class CharaDataCleanupService : IHostedService
|
||||
{
|
||||
private readonly ILogger<CharaDataCleanupService> _logger;
|
||||
private readonly IDbContextFactory<MareDbContext> _dbContextFactory;
|
||||
private readonly CancellationTokenSource _cleanupCts = new();
|
||||
|
||||
public CharaDataCleanupService(ILogger<CharaDataCleanupService> logger, IDbContextFactory<MareDbContext> dbContextFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_dbContextFactory = dbContextFactory;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_ = Cleanup(cancellationToken);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task Cleanup(CancellationToken ct)
|
||||
{
|
||||
_logger.LogInformation("CharaData Cleanup Service started");
|
||||
while (!ct.IsCancellationRequested)
|
||||
{
|
||||
using (var db = await _dbContextFactory.CreateDbContextAsync(ct).ConfigureAwait(false))
|
||||
{
|
||||
var dateTime = DateTime.UtcNow;
|
||||
var expiredData = await db.CharaData.Where(c => c.ExpiryDate <= DateTime.UtcNow).ToListAsync(cancellationToken: ct).ConfigureAwait(false);
|
||||
|
||||
_logger.LogInformation("Removing {count} expired Chara Data entries", expiredData.Count);
|
||||
|
||||
db.RemoveRange(expiredData);
|
||||
await db.SaveChangesAsync(ct).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromHours(12), ct).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_cleanupCts?.Cancel();
|
||||
_cleanupCts?.Dispose();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using Microsoft.VisualBasic.FileIO;
|
||||
using Prometheus;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace MareSynchronosServer.Services;
|
||||
|
||||
|
||||
@@ -12,15 +12,15 @@ public class UserCleanupService : IHostedService
|
||||
{
|
||||
private readonly MareMetrics metrics;
|
||||
private readonly ILogger<UserCleanupService> _logger;
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly IDbContextFactory<MareDbContext> _mareDbContextFactory;
|
||||
private readonly IConfigurationService<ServerConfiguration> _configuration;
|
||||
private CancellationTokenSource _cleanupCts;
|
||||
|
||||
public UserCleanupService(MareMetrics metrics, ILogger<UserCleanupService> logger, IServiceProvider services, IConfigurationService<ServerConfiguration> configuration)
|
||||
public UserCleanupService(MareMetrics metrics, ILogger<UserCleanupService> logger, IDbContextFactory<MareDbContext> mareDbContextFactory, IConfigurationService<ServerConfiguration> configuration)
|
||||
{
|
||||
this.metrics = metrics;
|
||||
_logger = logger;
|
||||
_services = services;
|
||||
_mareDbContextFactory = mareDbContextFactory;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
@@ -38,16 +38,17 @@ public class UserCleanupService : IHostedService
|
||||
{
|
||||
while (!ct.IsCancellationRequested)
|
||||
{
|
||||
using var scope = _services.CreateScope();
|
||||
using var dbContext = scope.ServiceProvider.GetService<MareDbContext>()!;
|
||||
using (var dbContext = await _mareDbContextFactory.CreateDbContextAsync(ct).ConfigureAwait(false))
|
||||
{
|
||||
|
||||
CleanUpOutdatedLodestoneAuths(dbContext);
|
||||
CleanUpOutdatedLodestoneAuths(dbContext);
|
||||
|
||||
await PurgeUnusedAccounts(dbContext).ConfigureAwait(false);
|
||||
await PurgeUnusedAccounts(dbContext).ConfigureAwait(false);
|
||||
|
||||
await PurgeTempInvites(dbContext).ConfigureAwait(false);
|
||||
await PurgeTempInvites(dbContext).ConfigureAwait(false);
|
||||
|
||||
dbContext.SaveChanges();
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
var now = DateTime.Now;
|
||||
TimeOnly currentTime = new(now.Hour, now.Minute, now.Second);
|
||||
|
||||
@@ -101,6 +101,8 @@ public class Startup
|
||||
{
|
||||
services.AddSingleton<UserCleanupService>();
|
||||
services.AddHostedService(provider => provider.GetService<UserCleanupService>());
|
||||
services.AddSingleton<CharaDataCleanupService>();
|
||||
services.AddHostedService(provider => provider.GetService<CharaDataCleanupService>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -21,17 +21,17 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net" Version="3.16.0" />
|
||||
<PackageReference Include="Discord.Net" Version="3.17.0" />
|
||||
<PackageReference Include="IDisposableAnalyzers" Version="4.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.176">
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.184">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -47,49 +47,96 @@ public class MareDbContext : DbContext
|
||||
public DbSet<UserPermissionSet> Permissions { get; set; }
|
||||
public DbSet<GroupPairPreferredPermission> GroupPairPreferredPermissions { get; set; }
|
||||
public DbSet<UserDefaultPreferredPermission> UserDefaultPreferredPermissions { get; set; }
|
||||
public DbSet<CharaData> CharaData { get; set; }
|
||||
public DbSet<CharaDataFile> CharaDataFiles { get; set; }
|
||||
public DbSet<CharaDataFileSwap> CharaDataFileSwaps { get; set; }
|
||||
public DbSet<CharaDataOriginalFile> CharaDataOriginalFiles { get; set; }
|
||||
public DbSet<CharaDataPose> CharaDataPoses { get; set; }
|
||||
public DbSet<CharaDataAllowance> CharaDataAllowances { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
protected override void OnModelCreating(ModelBuilder mb)
|
||||
{
|
||||
modelBuilder.Entity<Auth>().ToTable("auth");
|
||||
modelBuilder.Entity<User>().ToTable("users");
|
||||
modelBuilder.Entity<FileCache>().ToTable("file_caches");
|
||||
modelBuilder.Entity<FileCache>().HasIndex(c => c.UploaderUID);
|
||||
modelBuilder.Entity<ClientPair>().ToTable("client_pairs");
|
||||
modelBuilder.Entity<ClientPair>().HasKey(u => new { u.UserUID, u.OtherUserUID });
|
||||
modelBuilder.Entity<ClientPair>().HasIndex(c => c.UserUID);
|
||||
modelBuilder.Entity<ClientPair>().HasIndex(c => c.OtherUserUID);
|
||||
modelBuilder.Entity<ForbiddenUploadEntry>().ToTable("forbidden_upload_entries");
|
||||
modelBuilder.Entity<Banned>().ToTable("banned_users");
|
||||
modelBuilder.Entity<LodeStoneAuth>().ToTable("lodestone_auth");
|
||||
modelBuilder.Entity<BannedRegistrations>().ToTable("banned_registrations");
|
||||
modelBuilder.Entity<Group>().ToTable("groups");
|
||||
modelBuilder.Entity<Group>().HasIndex(c => c.OwnerUID);
|
||||
modelBuilder.Entity<GroupPair>().ToTable("group_pairs");
|
||||
modelBuilder.Entity<GroupPair>().HasKey(u => new { u.GroupGID, u.GroupUserUID });
|
||||
modelBuilder.Entity<GroupPair>().HasIndex(c => c.GroupUserUID);
|
||||
modelBuilder.Entity<GroupPair>().HasIndex(c => c.GroupGID);
|
||||
modelBuilder.Entity<GroupBan>().ToTable("group_bans");
|
||||
modelBuilder.Entity<GroupBan>().HasKey(u => new { u.GroupGID, u.BannedUserUID });
|
||||
modelBuilder.Entity<GroupBan>().HasIndex(c => c.BannedUserUID);
|
||||
modelBuilder.Entity<GroupBan>().HasIndex(c => c.GroupGID);
|
||||
modelBuilder.Entity<GroupTempInvite>().ToTable("group_temp_invites");
|
||||
modelBuilder.Entity<GroupTempInvite>().HasKey(u => new { u.GroupGID, u.Invite });
|
||||
modelBuilder.Entity<GroupTempInvite>().HasIndex(c => c.GroupGID);
|
||||
modelBuilder.Entity<GroupTempInvite>().HasIndex(c => c.Invite);
|
||||
modelBuilder.Entity<UserProfileData>().ToTable("user_profile_data");
|
||||
modelBuilder.Entity<UserProfileData>().HasKey(c => c.UserUID);
|
||||
modelBuilder.Entity<UserPermissionSet>().ToTable("user_permission_sets");
|
||||
modelBuilder.Entity<UserPermissionSet>().HasKey(u => new { u.UserUID, u.OtherUserUID });
|
||||
modelBuilder.Entity<UserPermissionSet>().HasIndex(c => c.UserUID);
|
||||
modelBuilder.Entity<UserPermissionSet>().HasIndex(c => c.OtherUserUID);
|
||||
modelBuilder.Entity<UserPermissionSet>().HasIndex(c => new { c.UserUID, c.OtherUserUID, c.IsPaused });
|
||||
modelBuilder.Entity<GroupPairPreferredPermission>().ToTable("group_pair_preferred_permissions");
|
||||
modelBuilder.Entity<GroupPairPreferredPermission>().HasKey(u => new { u.UserUID, u.GroupGID });
|
||||
modelBuilder.Entity<GroupPairPreferredPermission>().HasIndex(c => c.UserUID);
|
||||
modelBuilder.Entity<GroupPairPreferredPermission>().HasIndex(c => c.GroupGID);
|
||||
modelBuilder.Entity<UserDefaultPreferredPermission>().ToTable("user_default_preferred_permissions");
|
||||
modelBuilder.Entity<UserDefaultPreferredPermission>().HasKey(u => u.UserUID);
|
||||
modelBuilder.Entity<UserDefaultPreferredPermission>().HasIndex(u => u.UserUID);
|
||||
modelBuilder.Entity<UserDefaultPreferredPermission>().HasOne(u => u.User);
|
||||
mb.Entity<Auth>().ToTable("auth");
|
||||
mb.Entity<User>().ToTable("users");
|
||||
mb.Entity<FileCache>().ToTable("file_caches");
|
||||
mb.Entity<FileCache>().HasIndex(c => c.UploaderUID);
|
||||
mb.Entity<ClientPair>().ToTable("client_pairs");
|
||||
mb.Entity<ClientPair>().HasKey(u => new { u.UserUID, u.OtherUserUID });
|
||||
mb.Entity<ClientPair>().HasIndex(c => c.UserUID);
|
||||
mb.Entity<ClientPair>().HasIndex(c => c.OtherUserUID);
|
||||
mb.Entity<ForbiddenUploadEntry>().ToTable("forbidden_upload_entries");
|
||||
mb.Entity<Banned>().ToTable("banned_users");
|
||||
mb.Entity<LodeStoneAuth>().ToTable("lodestone_auth");
|
||||
mb.Entity<BannedRegistrations>().ToTable("banned_registrations");
|
||||
mb.Entity<Group>().ToTable("groups");
|
||||
mb.Entity<Group>().HasIndex(c => c.OwnerUID);
|
||||
mb.Entity<GroupPair>().ToTable("group_pairs");
|
||||
mb.Entity<GroupPair>().HasKey(u => new { u.GroupGID, u.GroupUserUID });
|
||||
mb.Entity<GroupPair>().HasIndex(c => c.GroupUserUID);
|
||||
mb.Entity<GroupPair>().HasIndex(c => c.GroupGID);
|
||||
mb.Entity<GroupBan>().ToTable("group_bans");
|
||||
mb.Entity<GroupBan>().HasKey(u => new { u.GroupGID, u.BannedUserUID });
|
||||
mb.Entity<GroupBan>().HasIndex(c => c.BannedUserUID);
|
||||
mb.Entity<GroupBan>().HasIndex(c => c.GroupGID);
|
||||
mb.Entity<GroupTempInvite>().ToTable("group_temp_invites");
|
||||
mb.Entity<GroupTempInvite>().HasKey(u => new { u.GroupGID, u.Invite });
|
||||
mb.Entity<GroupTempInvite>().HasIndex(c => c.GroupGID);
|
||||
mb.Entity<GroupTempInvite>().HasIndex(c => c.Invite);
|
||||
mb.Entity<UserProfileData>().ToTable("user_profile_data");
|
||||
mb.Entity<UserProfileData>().HasKey(c => c.UserUID);
|
||||
mb.Entity<UserPermissionSet>().ToTable("user_permission_sets");
|
||||
mb.Entity<UserPermissionSet>().HasKey(u => new { u.UserUID, u.OtherUserUID });
|
||||
mb.Entity<UserPermissionSet>().HasIndex(c => c.UserUID);
|
||||
mb.Entity<UserPermissionSet>().HasIndex(c => c.OtherUserUID);
|
||||
mb.Entity<UserPermissionSet>().HasIndex(c => new { c.UserUID, c.OtherUserUID, c.IsPaused });
|
||||
mb.Entity<GroupPairPreferredPermission>().ToTable("group_pair_preferred_permissions");
|
||||
mb.Entity<GroupPairPreferredPermission>().HasKey(u => new { u.UserUID, u.GroupGID });
|
||||
mb.Entity<GroupPairPreferredPermission>().HasIndex(c => c.UserUID);
|
||||
mb.Entity<GroupPairPreferredPermission>().HasIndex(c => c.GroupGID);
|
||||
mb.Entity<UserDefaultPreferredPermission>().ToTable("user_default_preferred_permissions");
|
||||
mb.Entity<UserDefaultPreferredPermission>().HasKey(u => u.UserUID);
|
||||
mb.Entity<UserDefaultPreferredPermission>().HasIndex(u => u.UserUID);
|
||||
mb.Entity<UserDefaultPreferredPermission>().HasOne(u => u.User);
|
||||
mb.Entity<CharaData>().ToTable("chara_data");
|
||||
mb.Entity<CharaData>()
|
||||
.HasMany(p => p.Poses)
|
||||
.WithOne(c => c.Parent)
|
||||
.HasForeignKey(c => new { c.ParentId, c.ParentUploaderUID });
|
||||
mb.Entity<CharaData>()
|
||||
.HasMany(p => p.Files)
|
||||
.WithOne(c => c.Parent)
|
||||
.HasForeignKey(c => new { c.ParentId, c.ParentUploaderUID });
|
||||
mb.Entity<CharaData>()
|
||||
.HasMany(p => p.OriginalFiles)
|
||||
.WithOne(p => p.Parent)
|
||||
.HasForeignKey(p => new { p.ParentId, p.ParentUploaderUID });
|
||||
mb.Entity<CharaData>()
|
||||
.HasMany(p => p.AllowedIndividiuals)
|
||||
.WithOne(p => p.Parent)
|
||||
.HasForeignKey(p => new { p.ParentId, p.ParentUploaderUID });
|
||||
mb.Entity<CharaData>()
|
||||
.HasMany(p => p.FileSwaps)
|
||||
.WithOne(p => p.Parent)
|
||||
.HasForeignKey(p => new { p.ParentId, p.ParentUploaderUID });
|
||||
mb.Entity<CharaData>().HasKey(p => new { p.Id, p.UploaderUID });
|
||||
mb.Entity<CharaData>().HasIndex(p => p.UploaderUID);
|
||||
mb.Entity<CharaData>().HasIndex(p => p.Id);
|
||||
mb.Entity<CharaDataFile>().ToTable("chara_data_files");
|
||||
mb.Entity<CharaDataFile>().HasKey(c => new { c.ParentId, c.ParentUploaderUID, c.GamePath });
|
||||
mb.Entity<CharaDataFile>().HasIndex(c => c.ParentId);
|
||||
mb.Entity<CharaDataFile>().HasOne(f => f.FileCache).WithMany().HasForeignKey(f => f.FileCacheHash).OnDelete(DeleteBehavior.Cascade);
|
||||
mb.Entity<CharaDataFileSwap>().ToTable("chara_data_file_swaps");
|
||||
mb.Entity<CharaDataFileSwap>().HasKey(c => new { c.ParentId, c.ParentUploaderUID, c.GamePath });
|
||||
mb.Entity<CharaDataFileSwap>().HasIndex(c => c.ParentId);
|
||||
mb.Entity<CharaDataPose>().ToTable("chara_data_poses");
|
||||
mb.Entity<CharaDataPose>().Property(p => p.Id).ValueGeneratedOnAdd();
|
||||
mb.Entity<CharaDataPose>().HasKey(c => new { c.ParentId, c.ParentUploaderUID, c.Id });
|
||||
mb.Entity<CharaDataPose>().HasIndex(c => c.ParentId);
|
||||
mb.Entity<CharaDataOriginalFile>().ToTable("chara_data_orig_files");
|
||||
mb.Entity<CharaDataOriginalFile>().HasKey(c => new { c.ParentId, c.ParentUploaderUID, c.GamePath });
|
||||
mb.Entity<CharaDataOriginalFile>().HasIndex(c => c.ParentId);
|
||||
mb.Entity<CharaDataAllowance>().ToTable("chara_data_allowance");
|
||||
mb.Entity<CharaDataAllowance>().HasKey(c => new { c.ParentId, c.ParentUploaderUID, c.AllowedUserUID });
|
||||
mb.Entity<CharaDataAllowance>().HasIndex(c => c.ParentId);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -15,40 +15,38 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ByteSize" Version="2.1.2" />
|
||||
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
|
||||
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0" />
|
||||
<PackageReference Include="IDisposableAnalyzers" Version="4.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Karambolo.Extensions.Logging.File" Version="3.6.0" />
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.176">
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.184">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Core" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.1.2" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.3.0" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.2" />
|
||||
<PackageReference Include="prometheus-net" Version="8.2.1" />
|
||||
<PackageReference Include="prometheus-net.AspNetCore" Version="8.2.1" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.16" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.24" />
|
||||
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="10.2.0" />
|
||||
<PackageReference Include="StackExchange.Redis.Extensions.Core" Version="10.2.0" />
|
||||
<PackageReference Include="StackExchange.Redis.Extensions.System.Text.Json" Version="10.2.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.1.2" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.3.0" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
1024
MareSynchronosServer/MareSynchronosShared/Migrations/20241226112428_CharaData.Designer.cs
generated
Normal file
1024
MareSynchronosServer/MareSynchronosShared/Migrations/20241226112428_CharaData.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MareSynchronosServer.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class CharaData : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "chara_data",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<string>(type: "text", nullable: false),
|
||||
uploader_uid = table.Column<string>(type: "character varying(10)", nullable: false),
|
||||
created_date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
updated_date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
description = table.Column<string>(type: "text", nullable: true),
|
||||
access_type = table.Column<int>(type: "integer", nullable: false),
|
||||
share_type = table.Column<int>(type: "integer", nullable: false),
|
||||
expiry_date = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
glamourer_data = table.Column<string>(type: "text", nullable: true),
|
||||
customize_data = table.Column<string>(type: "text", nullable: true),
|
||||
download_count = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_chara_data", x => new { x.id, x.uploader_uid });
|
||||
table.ForeignKey(
|
||||
name: "fk_chara_data_users_uploader_uid",
|
||||
column: x => x.uploader_uid,
|
||||
principalTable: "users",
|
||||
principalColumn: "uid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "chara_data_allowance",
|
||||
columns: table => new
|
||||
{
|
||||
parent_id = table.Column<string>(type: "text", nullable: false),
|
||||
parent_uploader_uid = table.Column<string>(type: "character varying(10)", nullable: false),
|
||||
allowed_user_uid = table.Column<string>(type: "character varying(10)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_chara_data_allowance", x => new { x.parent_id, x.parent_uploader_uid, x.allowed_user_uid });
|
||||
table.ForeignKey(
|
||||
name: "fk_chara_data_allowance_chara_data_parent_id_parent_uploader_u",
|
||||
columns: x => new { x.parent_id, x.parent_uploader_uid },
|
||||
principalTable: "chara_data",
|
||||
principalColumns: new[] { "id", "uploader_uid" },
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "fk_chara_data_allowance_users_allowed_user_uid",
|
||||
column: x => x.allowed_user_uid,
|
||||
principalTable: "users",
|
||||
principalColumn: "uid",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "chara_data_files",
|
||||
columns: table => new
|
||||
{
|
||||
game_path = table.Column<string>(type: "text", nullable: false),
|
||||
parent_id = table.Column<string>(type: "text", nullable: false),
|
||||
file_cache_hash = table.Column<string>(type: "character varying(40)", nullable: true),
|
||||
parent_uploader_uid = table.Column<string>(type: "character varying(10)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_chara_data_files", x => new { x.parent_id, x.game_path });
|
||||
table.ForeignKey(
|
||||
name: "fk_chara_data_files_chara_data_parent_id_parent_uploader_uid",
|
||||
columns: x => new { x.parent_id, x.parent_uploader_uid },
|
||||
principalTable: "chara_data",
|
||||
principalColumns: new[] { "id", "uploader_uid" });
|
||||
table.ForeignKey(
|
||||
name: "fk_chara_data_files_files_file_cache_hash",
|
||||
column: x => x.file_cache_hash,
|
||||
principalTable: "file_caches",
|
||||
principalColumn: "hash");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "chara_data_orig_files",
|
||||
columns: table => new
|
||||
{
|
||||
parent_id = table.Column<string>(type: "text", nullable: false),
|
||||
parent_uploader_uid = table.Column<string>(type: "character varying(10)", nullable: false),
|
||||
hash = table.Column<string>(type: "text", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_chara_data_orig_files", x => new { x.parent_id, x.parent_uploader_uid, x.hash });
|
||||
table.ForeignKey(
|
||||
name: "fk_chara_data_orig_files_chara_data_parent_id_parent_uploader_",
|
||||
columns: x => new { x.parent_id, x.parent_uploader_uid },
|
||||
principalTable: "chara_data",
|
||||
principalColumns: new[] { "id", "uploader_uid" },
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "chara_data_poses",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
parent_id = table.Column<string>(type: "text", nullable: false),
|
||||
parent_uploader_uid = table.Column<string>(type: "character varying(10)", nullable: false),
|
||||
description = table.Column<string>(type: "text", nullable: true),
|
||||
pose_data = table.Column<string>(type: "text", nullable: true),
|
||||
world_data = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_chara_data_poses", x => new { x.parent_id, x.parent_uploader_uid, x.id });
|
||||
table.ForeignKey(
|
||||
name: "fk_chara_data_poses_chara_data_parent_id_parent_uploader_uid",
|
||||
columns: x => new { x.parent_id, x.parent_uploader_uid },
|
||||
principalTable: "chara_data",
|
||||
principalColumns: new[] { "id", "uploader_uid" },
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_id",
|
||||
table: "chara_data",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_uploader_uid",
|
||||
table: "chara_data",
|
||||
column: "uploader_uid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_allowance_allowed_user_uid",
|
||||
table: "chara_data_allowance",
|
||||
column: "allowed_user_uid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_allowance_parent_id",
|
||||
table: "chara_data_allowance",
|
||||
column: "parent_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_files_file_cache_hash",
|
||||
table: "chara_data_files",
|
||||
column: "file_cache_hash");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_files_parent_id",
|
||||
table: "chara_data_files",
|
||||
column: "parent_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_files_parent_id_parent_uploader_uid",
|
||||
table: "chara_data_files",
|
||||
columns: new[] { "parent_id", "parent_uploader_uid" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_orig_files_parent_id",
|
||||
table: "chara_data_orig_files",
|
||||
column: "parent_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_poses_parent_id",
|
||||
table: "chara_data_poses",
|
||||
column: "parent_id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "chara_data_allowance");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "chara_data_files");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "chara_data_orig_files");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "chara_data_poses");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "chara_data");
|
||||
}
|
||||
}
|
||||
}
|
||||
1064
MareSynchronosServer/MareSynchronosShared/Migrations/20241226194944_CharaDataFileSwap.Designer.cs
generated
Normal file
1064
MareSynchronosServer/MareSynchronosShared/Migrations/20241226194944_CharaDataFileSwap.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,114 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MareSynchronosServer.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class CharaDataFileSwap : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "fk_chara_data_files_chara_data_parent_id_parent_uploader_uid",
|
||||
table: "chara_data_files");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "pk_chara_data_files",
|
||||
table: "chara_data_files");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "ix_chara_data_files_parent_id_parent_uploader_uid",
|
||||
table: "chara_data_files");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "parent_uploader_uid",
|
||||
table: "chara_data_files",
|
||||
type: "character varying(10)",
|
||||
nullable: false,
|
||||
defaultValue: "",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "character varying(10)",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "pk_chara_data_files",
|
||||
table: "chara_data_files",
|
||||
columns: new[] { "parent_id", "parent_uploader_uid", "game_path" });
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "chara_data_file_swaps",
|
||||
columns: table => new
|
||||
{
|
||||
parent_id = table.Column<string>(type: "text", nullable: false),
|
||||
parent_uploader_uid = table.Column<string>(type: "character varying(10)", nullable: false),
|
||||
game_path = table.Column<string>(type: "text", nullable: false),
|
||||
file_path = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_chara_data_file_swaps", x => new { x.parent_id, x.parent_uploader_uid, x.game_path });
|
||||
table.ForeignKey(
|
||||
name: "fk_chara_data_file_swaps_chara_data_parent_id_parent_uploader_",
|
||||
columns: x => new { x.parent_id, x.parent_uploader_uid },
|
||||
principalTable: "chara_data",
|
||||
principalColumns: new[] { "id", "uploader_uid" },
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_file_swaps_parent_id",
|
||||
table: "chara_data_file_swaps",
|
||||
column: "parent_id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "fk_chara_data_files_chara_data_parent_id_parent_uploader_uid",
|
||||
table: "chara_data_files",
|
||||
columns: new[] { "parent_id", "parent_uploader_uid" },
|
||||
principalTable: "chara_data",
|
||||
principalColumns: new[] { "id", "uploader_uid" },
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "fk_chara_data_files_chara_data_parent_id_parent_uploader_uid",
|
||||
table: "chara_data_files");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "chara_data_file_swaps");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "pk_chara_data_files",
|
||||
table: "chara_data_files");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "parent_uploader_uid",
|
||||
table: "chara_data_files",
|
||||
type: "character varying(10)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "character varying(10)");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "pk_chara_data_files",
|
||||
table: "chara_data_files",
|
||||
columns: new[] { "parent_id", "game_path" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_chara_data_files_parent_id_parent_uploader_uid",
|
||||
table: "chara_data_files",
|
||||
columns: new[] { "parent_id", "parent_uploader_uid" });
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "fk_chara_data_files_chara_data_parent_id_parent_uploader_uid",
|
||||
table: "chara_data_files",
|
||||
columns: new[] { "parent_id", "parent_uploader_uid" },
|
||||
principalTable: "chara_data",
|
||||
principalColumns: new[] { "id", "uploader_uid" });
|
||||
}
|
||||
}
|
||||
}
|
||||
1065
MareSynchronosServer/MareSynchronosShared/Migrations/20241227130901_CascadeFile.Designer.cs
generated
Normal file
1065
MareSynchronosServer/MareSynchronosShared/Migrations/20241227130901_CascadeFile.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MareSynchronosServer.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class CascadeFile : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "fk_chara_data_files_files_file_cache_hash",
|
||||
table: "chara_data_files");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "fk_chara_data_files_files_file_cache_hash",
|
||||
table: "chara_data_files",
|
||||
column: "file_cache_hash",
|
||||
principalTable: "file_caches",
|
||||
principalColumn: "hash",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "fk_chara_data_files_files_file_cache_hash",
|
||||
table: "chara_data_files");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "fk_chara_data_files_files_file_cache_hash",
|
||||
table: "chara_data_files",
|
||||
column: "file_cache_hash",
|
||||
principalTable: "file_caches",
|
||||
principalColumn: "hash");
|
||||
}
|
||||
}
|
||||
}
|
||||
1069
MareSynchronosServer/MareSynchronosShared/Migrations/20241227190944_OrigFileGamePath.Designer.cs
generated
Normal file
1069
MareSynchronosServer/MareSynchronosShared/Migrations/20241227190944_OrigFileGamePath.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MareSynchronosServer.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class OrigFileGamePath : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "pk_chara_data_orig_files",
|
||||
table: "chara_data_orig_files");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "hash",
|
||||
table: "chara_data_orig_files",
|
||||
type: "text",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "game_path",
|
||||
table: "chara_data_orig_files",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "pk_chara_data_orig_files",
|
||||
table: "chara_data_orig_files",
|
||||
columns: new[] { "parent_id", "parent_uploader_uid", "game_path" });
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "pk_chara_data_orig_files",
|
||||
table: "chara_data_orig_files");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "game_path",
|
||||
table: "chara_data_orig_files");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "hash",
|
||||
table: "chara_data_orig_files",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "pk_chara_data_orig_files",
|
||||
table: "chara_data_orig_files",
|
||||
columns: new[] { "parent_id", "parent_uploader_uid", "hash" });
|
||||
}
|
||||
}
|
||||
}
|
||||
1073
MareSynchronosServer/MareSynchronosShared/Migrations/20241228190750_ManipData.Designer.cs
generated
Normal file
1073
MareSynchronosServer/MareSynchronosShared/Migrations/20241228190750_ManipData.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MareSynchronosServer.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ManipData : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "manipulation_data",
|
||||
table: "chara_data",
|
||||
type: "text",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "manipulation_data",
|
||||
table: "chara_data");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace MareSynchronosServer.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.4")
|
||||
.HasAnnotation("ProductVersion", "8.0.10")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
@@ -93,6 +93,216 @@ namespace MareSynchronosServer.Migrations
|
||||
b.ToTable("banned_registrations", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaData", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("UploaderUID")
|
||||
.HasColumnType("character varying(10)")
|
||||
.HasColumnName("uploader_uid");
|
||||
|
||||
b.Property<int>("AccessType")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("access_type");
|
||||
|
||||
b.Property<DateTime>("CreatedDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("created_date");
|
||||
|
||||
b.Property<string>("CustomizeData")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("customize_data");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("description");
|
||||
|
||||
b.Property<int>("DownloadCount")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("download_count");
|
||||
|
||||
b.Property<DateTime?>("ExpiryDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("expiry_date");
|
||||
|
||||
b.Property<string>("GlamourerData")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("glamourer_data");
|
||||
|
||||
b.Property<string>("ManipulationData")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("manipulation_data");
|
||||
|
||||
b.Property<int>("ShareType")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("share_type");
|
||||
|
||||
b.Property<DateTime>("UpdatedDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("updated_date");
|
||||
|
||||
b.HasKey("Id", "UploaderUID")
|
||||
.HasName("pk_chara_data");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.HasDatabaseName("ix_chara_data_id");
|
||||
|
||||
b.HasIndex("UploaderUID")
|
||||
.HasDatabaseName("ix_chara_data_uploader_uid");
|
||||
|
||||
b.ToTable("chara_data", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataAllowance", b =>
|
||||
{
|
||||
b.Property<string>("ParentId")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("parent_id");
|
||||
|
||||
b.Property<string>("ParentUploaderUID")
|
||||
.HasColumnType("character varying(10)")
|
||||
.HasColumnName("parent_uploader_uid");
|
||||
|
||||
b.Property<string>("AllowedUserUID")
|
||||
.HasColumnType("character varying(10)")
|
||||
.HasColumnName("allowed_user_uid");
|
||||
|
||||
b.HasKey("ParentId", "ParentUploaderUID", "AllowedUserUID")
|
||||
.HasName("pk_chara_data_allowance");
|
||||
|
||||
b.HasIndex("AllowedUserUID")
|
||||
.HasDatabaseName("ix_chara_data_allowance_allowed_user_uid");
|
||||
|
||||
b.HasIndex("ParentId")
|
||||
.HasDatabaseName("ix_chara_data_allowance_parent_id");
|
||||
|
||||
b.ToTable("chara_data_allowance", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataFile", b =>
|
||||
{
|
||||
b.Property<string>("ParentId")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("parent_id");
|
||||
|
||||
b.Property<string>("ParentUploaderUID")
|
||||
.HasColumnType("character varying(10)")
|
||||
.HasColumnName("parent_uploader_uid");
|
||||
|
||||
b.Property<string>("GamePath")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("game_path");
|
||||
|
||||
b.Property<string>("FileCacheHash")
|
||||
.HasColumnType("character varying(40)")
|
||||
.HasColumnName("file_cache_hash");
|
||||
|
||||
b.HasKey("ParentId", "ParentUploaderUID", "GamePath")
|
||||
.HasName("pk_chara_data_files");
|
||||
|
||||
b.HasIndex("FileCacheHash")
|
||||
.HasDatabaseName("ix_chara_data_files_file_cache_hash");
|
||||
|
||||
b.HasIndex("ParentId")
|
||||
.HasDatabaseName("ix_chara_data_files_parent_id");
|
||||
|
||||
b.ToTable("chara_data_files", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataFileSwap", b =>
|
||||
{
|
||||
b.Property<string>("ParentId")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("parent_id");
|
||||
|
||||
b.Property<string>("ParentUploaderUID")
|
||||
.HasColumnType("character varying(10)")
|
||||
.HasColumnName("parent_uploader_uid");
|
||||
|
||||
b.Property<string>("GamePath")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("game_path");
|
||||
|
||||
b.Property<string>("FilePath")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("file_path");
|
||||
|
||||
b.HasKey("ParentId", "ParentUploaderUID", "GamePath")
|
||||
.HasName("pk_chara_data_file_swaps");
|
||||
|
||||
b.HasIndex("ParentId")
|
||||
.HasDatabaseName("ix_chara_data_file_swaps_parent_id");
|
||||
|
||||
b.ToTable("chara_data_file_swaps", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataOriginalFile", b =>
|
||||
{
|
||||
b.Property<string>("ParentId")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("parent_id");
|
||||
|
||||
b.Property<string>("ParentUploaderUID")
|
||||
.HasColumnType("character varying(10)")
|
||||
.HasColumnName("parent_uploader_uid");
|
||||
|
||||
b.Property<string>("GamePath")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("game_path");
|
||||
|
||||
b.Property<string>("Hash")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("hash");
|
||||
|
||||
b.HasKey("ParentId", "ParentUploaderUID", "GamePath")
|
||||
.HasName("pk_chara_data_orig_files");
|
||||
|
||||
b.HasIndex("ParentId")
|
||||
.HasDatabaseName("ix_chara_data_orig_files_parent_id");
|
||||
|
||||
b.ToTable("chara_data_orig_files", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataPose", b =>
|
||||
{
|
||||
b.Property<string>("ParentId")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("parent_id");
|
||||
|
||||
b.Property<string>("ParentUploaderUID")
|
||||
.HasColumnType("character varying(10)")
|
||||
.HasColumnName("parent_uploader_uid");
|
||||
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("description");
|
||||
|
||||
b.Property<string>("PoseData")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("pose_data");
|
||||
|
||||
b.Property<string>("WorldData")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("world_data");
|
||||
|
||||
b.HasKey("ParentId", "ParentUploaderUID", "Id")
|
||||
.HasName("pk_chara_data_poses");
|
||||
|
||||
b.HasIndex("ParentId")
|
||||
.HasDatabaseName("ix_chara_data_poses_parent_id");
|
||||
|
||||
b.ToTable("chara_data_poses", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b =>
|
||||
{
|
||||
b.Property<string>("UserUID")
|
||||
@@ -575,6 +785,95 @@ namespace MareSynchronosServer.Migrations
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaData", b =>
|
||||
{
|
||||
b.HasOne("MareSynchronosShared.Models.User", "Uploader")
|
||||
.WithMany()
|
||||
.HasForeignKey("UploaderUID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_chara_data_users_uploader_uid");
|
||||
|
||||
b.Navigation("Uploader");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataAllowance", b =>
|
||||
{
|
||||
b.HasOne("MareSynchronosShared.Models.User", "AllowedUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("AllowedUserUID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_chara_data_allowance_users_allowed_user_uid");
|
||||
|
||||
b.HasOne("MareSynchronosShared.Models.CharaData", "Parent")
|
||||
.WithMany("AllowedIndividiuals")
|
||||
.HasForeignKey("ParentId", "ParentUploaderUID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_chara_data_allowance_chara_data_parent_id_parent_uploader_u");
|
||||
|
||||
b.Navigation("AllowedUser");
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataFile", b =>
|
||||
{
|
||||
b.HasOne("MareSynchronosShared.Models.FileCache", "FileCache")
|
||||
.WithMany()
|
||||
.HasForeignKey("FileCacheHash")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.HasConstraintName("fk_chara_data_files_files_file_cache_hash");
|
||||
|
||||
b.HasOne("MareSynchronosShared.Models.CharaData", "Parent")
|
||||
.WithMany("Files")
|
||||
.HasForeignKey("ParentId", "ParentUploaderUID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_chara_data_files_chara_data_parent_id_parent_uploader_uid");
|
||||
|
||||
b.Navigation("FileCache");
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataFileSwap", b =>
|
||||
{
|
||||
b.HasOne("MareSynchronosShared.Models.CharaData", "Parent")
|
||||
.WithMany("FileSwaps")
|
||||
.HasForeignKey("ParentId", "ParentUploaderUID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_chara_data_file_swaps_chara_data_parent_id_parent_uploader_");
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataOriginalFile", b =>
|
||||
{
|
||||
b.HasOne("MareSynchronosShared.Models.CharaData", "Parent")
|
||||
.WithMany("OriginalFiles")
|
||||
.HasForeignKey("ParentId", "ParentUploaderUID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_chara_data_orig_files_chara_data_parent_id_parent_uploader_");
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaDataPose", b =>
|
||||
{
|
||||
b.HasOne("MareSynchronosShared.Models.CharaData", "Parent")
|
||||
.WithMany("Poses")
|
||||
.HasForeignKey("ParentId", "ParentUploaderUID")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_chara_data_poses_chara_data_parent_id_parent_uploader_uid");
|
||||
|
||||
b.Navigation("Parent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b =>
|
||||
{
|
||||
b.HasOne("MareSynchronosShared.Models.User", "OtherUser")
|
||||
@@ -752,6 +1051,19 @@ namespace MareSynchronosServer.Migrations
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MareSynchronosShared.Models.CharaData", b =>
|
||||
{
|
||||
b.Navigation("AllowedIndividiuals");
|
||||
|
||||
b.Navigation("FileSwaps");
|
||||
|
||||
b.Navigation("Files");
|
||||
|
||||
b.Navigation("OriginalFiles");
|
||||
|
||||
b.Navigation("Poses");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace MareSynchronosShared.Models;
|
||||
|
||||
public enum CharaDataAccess
|
||||
{
|
||||
Individuals,
|
||||
ClosePairs,
|
||||
AllPairs,
|
||||
Public
|
||||
}
|
||||
|
||||
public enum CharaDataShare
|
||||
{
|
||||
Private,
|
||||
Shared
|
||||
}
|
||||
|
||||
public class CharaData
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public virtual User Uploader { get; set; }
|
||||
public string UploaderUID { get; set; }
|
||||
public DateTime CreatedDate { get; set; }
|
||||
public DateTime UpdatedDate { get; set; }
|
||||
public string Description { get; set; }
|
||||
public CharaDataAccess AccessType { get; set; }
|
||||
public CharaDataShare ShareType { get; set; }
|
||||
public DateTime? ExpiryDate { get; set; }
|
||||
public string? GlamourerData { get; set; }
|
||||
public string? CustomizeData { get; set; }
|
||||
public string? ManipulationData { get; set; }
|
||||
public int DownloadCount { get; set; } = 0;
|
||||
public virtual ICollection<CharaDataPose> Poses { get; set; } = [];
|
||||
public virtual ICollection<CharaDataFile> Files { get; set; } = [];
|
||||
public virtual ICollection<CharaDataFileSwap> FileSwaps { get; set; } = [];
|
||||
public virtual ICollection<CharaDataOriginalFile> OriginalFiles { get; set; } = [];
|
||||
public virtual ICollection<CharaDataAllowance> AllowedIndividiuals { get; set; } = [];
|
||||
}
|
||||
|
||||
public class CharaDataAllowance
|
||||
{
|
||||
public virtual CharaData Parent { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
public string ParentUploaderUID { get; set; }
|
||||
public virtual User AllowedUser { get; set; }
|
||||
public string AllowedUserUID { get; set; }
|
||||
}
|
||||
|
||||
public class CharaDataOriginalFile
|
||||
{
|
||||
public virtual CharaData Parent { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
public string ParentUploaderUID { get; set; }
|
||||
public string GamePath { get; set; }
|
||||
public string Hash { get; set; }
|
||||
}
|
||||
|
||||
public class CharaDataFile
|
||||
{
|
||||
public virtual FileCache FileCache { get; set; }
|
||||
public string FileCacheHash { get; set; }
|
||||
public string GamePath { get; set; }
|
||||
public virtual CharaData Parent { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
public string ParentUploaderUID { get; set; }
|
||||
}
|
||||
|
||||
public class CharaDataFileSwap
|
||||
{
|
||||
public virtual CharaData Parent { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
public string ParentUploaderUID { get; set; }
|
||||
public string GamePath { get; set; }
|
||||
public string FilePath { get; set; }
|
||||
}
|
||||
|
||||
public class CharaDataPose
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public virtual CharaData Parent { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
public string ParentUploaderUID { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string PoseData { get; set; }
|
||||
public string WorldData { get; set; }
|
||||
}
|
||||
@@ -24,7 +24,12 @@ public class ServerConfiguration : MareConfigurationBase
|
||||
|
||||
[RemoteConfiguration]
|
||||
public int PurgeUnusedAccountsPeriodInDays { get; set; } = 14;
|
||||
public string GeoIPDbCityFile { get; set; } = string.Empty;
|
||||
|
||||
[RemoteConfiguration]
|
||||
public int MaxCharaDataByUser { get; set; } = 10;
|
||||
|
||||
[RemoteConfiguration]
|
||||
public int MaxCharaDataByUserVanity { get; set; } = 50;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
@@ -38,7 +43,6 @@ public class ServerConfiguration : MareConfigurationBase
|
||||
sb.AppendLine($"{nameof(MaxGroupUserCount)} => {MaxGroupUserCount}");
|
||||
sb.AppendLine($"{nameof(PurgeUnusedAccounts)} => {PurgeUnusedAccounts}");
|
||||
sb.AppendLine($"{nameof(PurgeUnusedAccountsPeriodInDays)} => {PurgeUnusedAccountsPeriodInDays}");
|
||||
sb.AppendLine($"{nameof(GeoIPDbCityFile)} => {GeoIPDbCityFile}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using LZ4;
|
||||
using K4os.Compression.LZ4.Legacy;
|
||||
using MareSynchronos.API.Dto.Files;
|
||||
using MareSynchronos.API.Routes;
|
||||
using MareSynchronos.API.SignalR;
|
||||
@@ -216,7 +216,7 @@ public class ServerFilesController : ControllerBase
|
||||
await Request.Body.CopyToAsync(compressedFileStream, requestAborted).ConfigureAwait(false);
|
||||
|
||||
// decompress and copy the decompressed stream to memory
|
||||
var data = LZ4Codec.Unwrap(compressedFileStream.ToArray());
|
||||
var data = LZ4Wrapper.Unwrap(compressedFileStream.ToArray());
|
||||
|
||||
// reset streams
|
||||
compressedFileStream.Seek(0, SeekOrigin.Begin);
|
||||
@@ -323,7 +323,7 @@ public class ServerFilesController : ControllerBase
|
||||
MungeBuffer(unmungedFile.AsSpan());
|
||||
|
||||
// decompress and copy the decompressed stream to memory
|
||||
var data = LZ4Codec.Unwrap(unmungedFile);
|
||||
var data = LZ4Wrapper.Unwrap(unmungedFile);
|
||||
|
||||
// compute hash to verify
|
||||
var hashString = BitConverter.ToString(SHA1.HashData(data))
|
||||
@@ -442,7 +442,7 @@ public class ServerFilesController : ControllerBase
|
||||
// save file
|
||||
var path = FilePathUtil.GetFilePath(_basePath, hash);
|
||||
using var fileStream = new FileStream(path, FileMode.Create);
|
||||
var lz4 = LZ4Codec.WrapHC(rawFileStream.ToArray(), 0, (int)rawFileStream.Length);
|
||||
var lz4 = LZ4Wrapper.WrapHC(rawFileStream.ToArray(), 0, (int)rawFileStream.Length);
|
||||
using var compressedStream = new MemoryStream(lz4);
|
||||
await compressedStream.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.176">
|
||||
<PackageReference Include="K4os.Compression.LZ4.Legacy" Version="1.3.8" />
|
||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.184">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using ByteSizeLib;
|
||||
using LZ4;
|
||||
using K4os.Compression.LZ4.Legacy;
|
||||
using MareSynchronosShared.Data;
|
||||
using MareSynchronosShared.Metrics;
|
||||
using MareSynchronosShared.Models;
|
||||
@@ -270,7 +270,7 @@ public class MainFileCleanupService : IHostedService
|
||||
{
|
||||
try
|
||||
{
|
||||
var length = LZ4Codec.Unwrap(File.ReadAllBytes(file.FullName)).LongLength;
|
||||
var length = LZ4Wrapper.Unwrap(File.ReadAllBytes(file.FullName)).LongLength;
|
||||
_logger.LogInformation("Setting Raw File Size of " + fileCache.Hash + " to " + length);
|
||||
fileCache.RawSize = length;
|
||||
if (fileCounter % 1000 == 0)
|
||||
|
||||
Reference in New Issue
Block a user