I don't know man, it's just too much
This commit is contained in:
24
MareSynchronosServer/MareSynchronos.API/CharacterCacheDto.cs
Normal file
24
MareSynchronosServer/MareSynchronos.API/CharacterCacheDto.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace MareSynchronos.API
|
||||||
|
{
|
||||||
|
public class CharacterCacheDto
|
||||||
|
{
|
||||||
|
public List<FileReplacementDto> FileReplacements { get; set; } = new();
|
||||||
|
public string GlamourerData { get; set; }
|
||||||
|
public string Hash { get; set; }
|
||||||
|
public int JobId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FileReplacementDto
|
||||||
|
{
|
||||||
|
public string[] GamePaths { get; set; } = Array.Empty<string>();
|
||||||
|
public string Hash { get; set; }
|
||||||
|
public string ImcData { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,4 +4,8 @@
|
|||||||
<TargetFramework>net5.0</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using MareSynchronosServer.Models;
|
using System.Collections.Generic;
|
||||||
|
using MareSynchronos.API;
|
||||||
|
using MareSynchronosServer.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace MareSynchronosServer.Data
|
namespace MareSynchronosServer.Data
|
||||||
{
|
{
|
||||||
@@ -12,12 +15,24 @@ namespace MareSynchronosServer.Data
|
|||||||
public DbSet<User> Users { get; set; }
|
public DbSet<User> Users { get; set; }
|
||||||
public DbSet<FileCache> Files { get; set; }
|
public DbSet<FileCache> Files { get; set; }
|
||||||
public DbSet<Whitelist> Whitelists { get; set; }
|
public DbSet<Whitelist> Whitelists { get; set; }
|
||||||
|
public DbSet<Visibility> Visibilities { get; set; }
|
||||||
|
public DbSet<CharacterData> CharacterData { get; set; }
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
modelBuilder.Entity<User>().ToTable("Users");
|
modelBuilder.Entity<User>().ToTable("Users");
|
||||||
modelBuilder.Entity<FileCache>().ToTable("FileCaches");
|
modelBuilder.Entity<FileCache>().ToTable("FileCaches");
|
||||||
modelBuilder.Entity<Whitelist>().ToTable("Whitelists");
|
modelBuilder.Entity<Whitelist>().ToTable("Whitelists");
|
||||||
|
modelBuilder.Entity<Visibility>().ToTable("Visibility")
|
||||||
|
.HasKey(k => new { k.CID, k.OtherCID });
|
||||||
|
modelBuilder.Entity<CharacterData>()
|
||||||
|
.Property(b => b.EquipmentData)
|
||||||
|
.HasConversion(
|
||||||
|
v => JsonConvert.SerializeObject(v),
|
||||||
|
v => JsonConvert.DeserializeObject<List<FileReplacementDto>>(v));
|
||||||
|
modelBuilder.Entity<CharacterData>()
|
||||||
|
.ToTable("CharacterData")
|
||||||
|
.HasKey(k => new { k.UserId, k.JobId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
61
MareSynchronosServer/MareSynchronosServer/Hubs/BaseHub.cs
Normal file
61
MareSynchronosServer/MareSynchronosServer/Hubs/BaseHub.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using MareSynchronosServer.Data;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
|
||||||
|
namespace MareSynchronosServer.Hubs
|
||||||
|
{
|
||||||
|
public abstract class BaseHub : Hub
|
||||||
|
{
|
||||||
|
protected MareDbContext DbContext { get; init; }
|
||||||
|
|
||||||
|
protected BaseHub(MareDbContext context)
|
||||||
|
{
|
||||||
|
DbContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string AuthenticatedUserId => Context.User?.Claims?.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value ?? "Unknown";
|
||||||
|
|
||||||
|
protected Models.User? GetAuthenticatedUser()
|
||||||
|
{
|
||||||
|
return DbContext.Users.Single(u => u.UID == AuthenticatedUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Models.User? GetUserFromCID(string cid)
|
||||||
|
{
|
||||||
|
return DbContext.Users.SingleOrDefault(c => c.CharacterIdentification == cid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Models.User? GetUserFromUID(string uid)
|
||||||
|
{
|
||||||
|
return DbContext.Users.SingleOrDefault(c => c.UID == uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool IsUserOnline(string uid)
|
||||||
|
{
|
||||||
|
return DbContext.Users.Any(c => c.UID == uid && !string.IsNullOrEmpty(c.CharacterIdentification));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GenerateRandomString(int length, string allowableChars = null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(allowableChars))
|
||||||
|
allowableChars = @"ABCDEFGHJKLMNPQRSTUVWXYZ0123456789";
|
||||||
|
|
||||||
|
// Generate random data
|
||||||
|
var rnd = new byte[length];
|
||||||
|
using (var rng = new RNGCryptoServiceProvider())
|
||||||
|
rng.GetBytes(rnd);
|
||||||
|
|
||||||
|
// Generate the output string
|
||||||
|
var allowable = allowableChars.ToCharArray();
|
||||||
|
var l = allowable.Length;
|
||||||
|
var chars = new char[length];
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
chars[i] = allowable[rnd[i] % l];
|
||||||
|
|
||||||
|
return new string(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,47 +6,53 @@ using System.Linq;
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MareSynchronos.API;
|
||||||
using MareSynchronosServer.Authentication;
|
using MareSynchronosServer.Authentication;
|
||||||
using MareSynchronosServer.Data;
|
using MareSynchronosServer.Data;
|
||||||
using MareSynchronosServer.Models;
|
using MareSynchronosServer.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace MareSynchronosServer.Hubs
|
namespace MareSynchronosServer.Hubs
|
||||||
{
|
{
|
||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
public class Files : BaseHub
|
||||||
public class Files : Hub
|
|
||||||
{
|
{
|
||||||
private readonly MareDbContext _dbContext;
|
public Files(MareDbContext dbContext) : base(dbContext)
|
||||||
|
|
||||||
public Files(MareDbContext dbContext)
|
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
public async Task SendFiles(List<string> fileList)
|
public async Task SendFiles(List<FileReplacementDto> fileList)
|
||||||
{
|
{
|
||||||
var existingFiles = _dbContext.Files.Where(f => fileList.Contains(f.Hash)).ToList();
|
var fileListHashes = fileList.Select(x => x.Hash).ToList();
|
||||||
foreach (var file in fileList.Where(f => existingFiles.All(e => e.Hash != f)))
|
var existingFiles = DbContext.Files.Where(f => fileListHashes.Contains(f.Hash)).ToList();
|
||||||
|
foreach (var file in fileListHashes.Where(f => existingFiles.All(e => e.Hash != f)))
|
||||||
{
|
{
|
||||||
var userId = Context.User!.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value ?? "Unknown";
|
var userId = AuthenticatedUserId;
|
||||||
await _dbContext.Files.AddAsync(new FileCache()
|
await DbContext.Files.AddAsync(new FileCache()
|
||||||
{
|
{
|
||||||
Hash = file,
|
Hash = file,
|
||||||
LastAccessTime = DateTime.Now,
|
LastAccessTime = DateTime.Now,
|
||||||
Uploaded = false,
|
Uploaded = false,
|
||||||
Uploader = _dbContext.Users.Single(u => u.UID == userId)
|
Uploader = DbContext.Users.Single(u => u.UID == userId)
|
||||||
});
|
});
|
||||||
await _dbContext.SaveChangesAsync();
|
await DbContext.SaveChangesAsync();
|
||||||
await Clients.Caller!.SendAsync("FileRequest", file);
|
await Clients.Caller!.SendAsync("FileRequest", file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
|
public async Task<bool> IsUploadFinished()
|
||||||
|
{
|
||||||
|
var userUid = AuthenticatedUserId;
|
||||||
|
return await DbContext.Files.AnyAsync(f => f.Uploader.UID == userUid && !f.Uploaded);
|
||||||
|
}
|
||||||
|
|
||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
public async Task<bool> UploadFile(string hash, byte[] file)
|
public async Task<bool> UploadFile(string hash, byte[] file)
|
||||||
{
|
{
|
||||||
var relatedFile = _dbContext.Files.SingleOrDefault(f => f.Hash == hash);
|
var relatedFile = DbContext.Files.SingleOrDefault(f => f.Hash == hash);
|
||||||
if (relatedFile == null) return false;
|
if (relatedFile == null) return false;
|
||||||
var decodedFile = LZ4.LZ4Codec.Unwrap(file);
|
var decodedFile = LZ4.LZ4Codec.Unwrap(file);
|
||||||
using var sha1 = new SHA1CryptoServiceProvider();
|
using var sha1 = new SHA1CryptoServiceProvider();
|
||||||
@@ -54,21 +60,31 @@ namespace MareSynchronosServer.Hubs
|
|||||||
var computedHashString = BitConverter.ToString(computedHash).Replace("-", "");
|
var computedHashString = BitConverter.ToString(computedHash).Replace("-", "");
|
||||||
if (hash != computedHashString)
|
if (hash != computedHashString)
|
||||||
{
|
{
|
||||||
|
DbContext.Remove(relatedFile);
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
await File.WriteAllBytesAsync(@"G:\ServerTest\" + hash, file);
|
await File.WriteAllBytesAsync(@"G:\ServerTest\" + hash, file);
|
||||||
relatedFile.Uploaded = true;
|
relatedFile.Uploaded = true;
|
||||||
relatedFile.LastAccessTime = DateTime.Now;
|
relatedFile.LastAccessTime = DateTime.Now;
|
||||||
await _dbContext.SaveChangesAsync();
|
await DbContext.SaveChangesAsync();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
|
public async Task<byte[]> DownloadFile(string hash)
|
||||||
|
{
|
||||||
|
var file = DbContext.Files.SingleOrDefault(f => f.Hash == hash);
|
||||||
|
if (file == null) return Array.Empty<byte>();
|
||||||
|
return await File.ReadAllBytesAsync(@"G:\ServerTest\" + hash);
|
||||||
|
}
|
||||||
|
|
||||||
public override Task OnDisconnectedAsync(Exception exception)
|
public override Task OnDisconnectedAsync(Exception exception)
|
||||||
{
|
{
|
||||||
var userId = Context.User!.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
|
var userId = AuthenticatedUserId;
|
||||||
var notUploadedFiles = _dbContext.Files.Where(f => !f.Uploaded && f.Uploader.UID == userId).ToList();
|
var notUploadedFiles = DbContext.Files.Where(f => !f.Uploaded && f.Uploader.UID == userId).ToList();
|
||||||
_dbContext.RemoveRange(notUploadedFiles);
|
DbContext.RemoveRange(notUploadedFiles);
|
||||||
_dbContext.SaveChanges();
|
DbContext.SaveChanges();
|
||||||
return base.OnDisconnectedAsync(exception);
|
return base.OnDisconnectedAsync(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -16,13 +15,10 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace MareSynchronosServer.Hubs
|
namespace MareSynchronosServer.Hubs
|
||||||
{
|
{
|
||||||
public class User : Hub
|
public class User : BaseHub
|
||||||
{
|
{
|
||||||
private readonly MareDbContext _dbContext;
|
public User(MareDbContext dbContext) : base(dbContext)
|
||||||
|
|
||||||
public User(MareDbContext dbContext)
|
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> Register()
|
public async Task<string> Register()
|
||||||
@@ -39,119 +35,269 @@ namespace MareSynchronosServer.Hubs
|
|||||||
while (!hasValidUid)
|
while (!hasValidUid)
|
||||||
{
|
{
|
||||||
var uid = GenerateRandomString(10);
|
var uid = GenerateRandomString(10);
|
||||||
if (_dbContext.Users.Any(u => u.UID == uid)) continue;
|
if (DbContext.Users.Any(u => u.UID == uid)) continue;
|
||||||
user.UID = uid;
|
user.UID = uid;
|
||||||
hasValidUid = true;
|
hasValidUid = true;
|
||||||
}
|
}
|
||||||
_dbContext.Users.Add(user);
|
DbContext.Users.Add(user);
|
||||||
|
|
||||||
await _dbContext.SaveChangesAsync();
|
await DbContext.SaveChangesAsync();
|
||||||
return computedHash;
|
return computedHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Whitelist OppositeEntry(string otherUID) =>
|
||||||
|
DbContext.Whitelists.SingleOrDefault(w => w.User.UID == otherUID && w.OtherUser.UID == AuthenticatedUserId);
|
||||||
|
|
||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
public string GetUID()
|
public string GetUID()
|
||||||
{
|
{
|
||||||
return Context.User!.Claims.Single(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
return AuthenticatedUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
public async Task SendWhitelist(List<WhitelistDto> whiteListEntries)
|
public async Task SendVisibilityList(List<string> currentVisibilityList)
|
||||||
{
|
{
|
||||||
var currentUserId = Context.User!.Claims.Single(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
Stopwatch st = Stopwatch.StartNew();
|
||||||
var user = _dbContext.Users.Single(u => u.UID == currentUserId);
|
var cid = DbContext.Users.Single(u => u.UID == AuthenticatedUserId).CharacterIdentification;
|
||||||
var userWhitelists = _dbContext.Whitelists
|
var visibilities = DbContext.Visibilities.Where(v => v.CID == cid).ToList();
|
||||||
|
foreach (var visibility in currentVisibilityList.Where(visibility => visibilities.All(v => v.OtherCID != visibility)))
|
||||||
|
{
|
||||||
|
await DbContext.Visibilities.AddAsync(new Visibility { CID = cid, OtherCID = visibility });
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var visibility in visibilities.Where(v => currentVisibilityList.Contains(v.OtherCID)))
|
||||||
|
{
|
||||||
|
DbContext.Visibilities.Remove(visibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
st.Stop();
|
||||||
|
Debug.WriteLine("Visibility update took " + st.Elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
|
public async Task GetCharacterData(Dictionary<string, int> visibleCharacterWithJobs)
|
||||||
|
{
|
||||||
|
var uid = AuthenticatedUserId;
|
||||||
|
Dictionary<string, CharacterCacheDto> ret = new();
|
||||||
|
var whitelistEntriesHavingThisUser = DbContext.Whitelists
|
||||||
.Include(w => w.User)
|
.Include(w => w.User)
|
||||||
.Include(w => w.OtherUser)
|
.Include(w => w.OtherUser)
|
||||||
.Where(w => w.User.UID == currentUserId)
|
.Where(w => w.OtherUser.UID == uid && !w.IsPaused
|
||||||
|
&& visibleCharacterWithJobs.Keys.Contains(w.User.CharacterIdentification))
|
||||||
.ToList();
|
.ToList();
|
||||||
foreach (var whitelist in whiteListEntries)
|
foreach (var whiteListEntry in whitelistEntriesHavingThisUser)
|
||||||
{
|
{
|
||||||
var otherEntry = _dbContext.Whitelists.SingleOrDefault(w =>
|
bool isNotPaused = await DbContext.Whitelists.AnyAsync(w =>
|
||||||
w.User.UID == whitelist.OtherUID && w.OtherUser.UID == user.UID);
|
!w.IsPaused && w.User.UID == uid && w.OtherUser.UID == whiteListEntry.User.UID);
|
||||||
|
if (!isNotPaused) continue;
|
||||||
|
var dictEntry = visibleCharacterWithJobs[whiteListEntry.User.CharacterIdentification];
|
||||||
|
|
||||||
var prevEntry = userWhitelists.SingleOrDefault(w => w.OtherUser.UID == whitelist.OtherUID);
|
var cachedChar = await
|
||||||
if (prevEntry != null)
|
DbContext.CharacterData.SingleOrDefaultAsync(c => c.UserId == whiteListEntry.User.UID && c.JobId == dictEntry);
|
||||||
|
if (cachedChar != null)
|
||||||
{
|
{
|
||||||
prevEntry.IsPaused = whitelist.IsPaused;
|
await Clients.User(uid).SendAsync("ReceiveCharacterData", cachedChar,
|
||||||
|
whiteListEntry.User.CharacterIdentification);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
|
public async Task PushCharacterData(CharacterCacheDto characterCache, List<string> visibleCharacterIds)
|
||||||
|
{
|
||||||
|
var uid = AuthenticatedUserId;
|
||||||
|
var whitelistEntriesHavingThisUser = DbContext.Whitelists
|
||||||
|
.Include(w => w.User)
|
||||||
|
.Include(w => w.OtherUser)
|
||||||
|
.Where(w => w.OtherUser.UID == uid && !w.IsPaused
|
||||||
|
&& visibleCharacterIds.Contains(w.User.CharacterIdentification)).ToList();
|
||||||
|
var existingCharacterData =
|
||||||
|
await DbContext.CharacterData.SingleOrDefaultAsync(s =>
|
||||||
|
s.UserId == uid && s.JobId == characterCache.JobId);
|
||||||
|
if (existingCharacterData != null && existingCharacterData.Hash != characterCache.Hash)
|
||||||
|
{
|
||||||
|
existingCharacterData.EquipmentData =
|
||||||
|
characterCache.FileReplacements;
|
||||||
|
existingCharacterData.Hash = characterCache.Hash;
|
||||||
|
existingCharacterData.GlamourerData = characterCache.GlamourerData;
|
||||||
|
DbContext.CharacterData.Update(existingCharacterData);
|
||||||
|
}
|
||||||
|
else if (existingCharacterData == null)
|
||||||
|
{
|
||||||
|
CharacterData data = new CharacterData
|
||||||
{
|
{
|
||||||
var otherUser = _dbContext.Users.SingleOrDefault(u => u.UID == whitelist.OtherUID);
|
UserId = AuthenticatedUserId,
|
||||||
if (otherUser != null)
|
EquipmentData = characterCache.FileReplacements,
|
||||||
|
Hash = characterCache.Hash,
|
||||||
|
GlamourerData = characterCache.GlamourerData,
|
||||||
|
JobId = characterCache.JobId
|
||||||
|
};
|
||||||
|
await DbContext.CharacterData.AddAsync(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
foreach (var whitelistEntry in whitelistEntriesHavingThisUser)
|
||||||
|
{
|
||||||
|
var ownEntry = DbContext.Whitelists.SingleOrDefault(w =>
|
||||||
|
w.User.UID == uid && w.OtherUser.UID == whitelistEntry.User.UID);
|
||||||
|
if (ownEntry == null || ownEntry.IsPaused) continue;
|
||||||
|
await Clients.User(whitelistEntry.User.UID).SendAsync("ReceiveCharacterData", characterCache, whitelistEntry.OtherUser.CharacterIdentification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
|
public async Task SendCharacterNameHash(string characterNameHash)
|
||||||
|
{
|
||||||
|
DbContext.Users.Single(u => u.UID == AuthenticatedUserId).CharacterIdentification = characterNameHash;
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
|
public async Task SendWhitelistAddition(string uid)
|
||||||
|
{
|
||||||
|
var user = await DbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId);
|
||||||
|
var otherUser = await DbContext.Users.SingleOrDefaultAsync(u => u.UID == uid);
|
||||||
|
if (otherUser == null) return;
|
||||||
|
Whitelist wl = new Whitelist()
|
||||||
|
{
|
||||||
|
IsPaused = false,
|
||||||
|
OtherUser = otherUser,
|
||||||
|
User = user
|
||||||
|
};
|
||||||
|
await DbContext.Whitelists.AddAsync(wl);
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
var otherEntry = OppositeEntry(uid);
|
||||||
|
await Clients.User(user.UID)
|
||||||
|
.SendAsync("UpdateWhitelist", new WhitelistDto()
|
||||||
|
{
|
||||||
|
OtherUID = otherUser.UID,
|
||||||
|
IsPaused = false,
|
||||||
|
IsPausedFromOthers = otherEntry?.IsPaused ?? false,
|
||||||
|
IsSynced = otherEntry != null
|
||||||
|
}, otherUser.CharacterIdentification);
|
||||||
|
if (otherEntry != null)
|
||||||
|
{
|
||||||
|
await Clients.User(uid).SendAsync("UpdateWhitelist",
|
||||||
|
new WhitelistDto()
|
||||||
{
|
{
|
||||||
Whitelist wl = new Whitelist
|
OtherUID = user.UID,
|
||||||
{
|
IsPaused = otherEntry.IsPaused,
|
||||||
User = user,
|
IsPausedFromOthers = false,
|
||||||
OtherUser = otherUser,
|
IsSynced = true
|
||||||
IsPaused = whitelist.IsPaused
|
}, user.CharacterIdentification);
|
||||||
};
|
|
||||||
otherEntry = wl;
|
|
||||||
await _dbContext.Whitelists.AddAsync(wl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (otherEntry != null)
|
|
||||||
{
|
|
||||||
await Clients.User(whitelist.OtherUID).SendAsync("UpdateWhitelist", currentUserId, true,
|
|
||||||
whitelist.IsPaused);
|
|
||||||
}
|
|
||||||
|
|
||||||
await _dbContext.SaveChangesAsync();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var deletedEntry in userWhitelists.Where(u => whiteListEntries.All(e => e.OtherUID != u.OtherUser.UID)).ToList())
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
|
public async Task SendWhitelistRemoval(string uid)
|
||||||
|
{
|
||||||
|
var user = await DbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId);
|
||||||
|
var otherUser = await DbContext.Users.SingleOrDefaultAsync(u => u.UID == uid);
|
||||||
|
if (otherUser == null) return;
|
||||||
|
Whitelist wl =
|
||||||
|
await DbContext.Whitelists.SingleOrDefaultAsync(w => w.User == user && w.OtherUser == otherUser);
|
||||||
|
DbContext.Whitelists.Remove(wl);
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
var otherEntry = OppositeEntry(uid);
|
||||||
|
await Clients.User(user.UID)
|
||||||
|
.SendAsync("UpdateWhitelist", new WhitelistDto()
|
||||||
|
{
|
||||||
|
OtherUID = otherUser.UID,
|
||||||
|
IsPaused = false,
|
||||||
|
IsPausedFromOthers = otherEntry?.IsPaused ?? false,
|
||||||
|
IsSynced = otherEntry != null
|
||||||
|
}, otherUser.CharacterIdentification);
|
||||||
|
if (otherEntry != null)
|
||||||
{
|
{
|
||||||
var otherEntry = _dbContext.Whitelists.SingleOrDefault(w =>
|
await Clients.User(uid).SendAsync("UpdateWhitelist", new WhitelistDto()
|
||||||
w.User.UID == deletedEntry.OtherUser.UID && w.OtherUser.UID == user.UID);
|
|
||||||
if (otherEntry != null)
|
|
||||||
{
|
{
|
||||||
await Clients.User(otherEntry.User.UID).SendAsync("UpdateWhitelist", currentUserId, false, false);
|
OtherUID = user.UID,
|
||||||
}
|
IsPaused = otherEntry.IsPaused,
|
||||||
|
IsPausedFromOthers = false,
|
||||||
_dbContext.Whitelists.Remove(deletedEntry);
|
IsSynced = false
|
||||||
|
}, user.CharacterIdentification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
|
public async Task SendWhitelistPauseChange(string uid, bool isPaused)
|
||||||
|
{
|
||||||
|
var user = DbContext.Users.Single(u => u.UID == AuthenticatedUserId);
|
||||||
|
var otherUser = await DbContext.Users.SingleOrDefaultAsync(u => u.UID == uid);
|
||||||
|
if (otherUser == null) return;
|
||||||
|
Whitelist wl =
|
||||||
|
await DbContext.Whitelists.SingleOrDefaultAsync(w => w.User == user && w.OtherUser == otherUser);
|
||||||
|
wl.IsPaused = isPaused;
|
||||||
|
DbContext.Update(wl);
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
var otherEntry = OppositeEntry(uid);
|
||||||
|
await Clients.User(user.UID)
|
||||||
|
.SendAsync("UpdateWhitelist", new WhitelistDto()
|
||||||
|
{
|
||||||
|
OtherUID = otherUser.UID,
|
||||||
|
IsPaused = isPaused,
|
||||||
|
IsPausedFromOthers = otherEntry?.IsPaused ?? false,
|
||||||
|
IsSynced = otherEntry != null
|
||||||
|
}, otherUser.CharacterIdentification);
|
||||||
|
if (otherEntry != null)
|
||||||
|
{
|
||||||
|
await Clients.User(uid).SendAsync("UpdateWhitelist", new WhitelistDto()
|
||||||
|
{
|
||||||
|
OtherUID = user.UID,
|
||||||
|
IsPaused = otherEntry.IsPaused,
|
||||||
|
IsPausedFromOthers = isPaused,
|
||||||
|
IsSynced = true
|
||||||
|
}, user.CharacterIdentification);
|
||||||
}
|
}
|
||||||
_dbContext.Whitelists.RemoveRange();
|
|
||||||
await _dbContext.SaveChangesAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AUTH_SCHEME)]
|
||||||
public async Task<List<WhitelistDto>> GetWhitelist()
|
public async Task<List<WhitelistDto>> GetWhitelist()
|
||||||
{
|
{
|
||||||
string userid = Context.User!.Claims.Single(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
string userid = AuthenticatedUserId;
|
||||||
return _dbContext.Whitelists.Include(u => u.OtherUser).Include(u => u.User).Where(w => w.User.UID == userid)
|
var user = GetAuthenticatedUser();
|
||||||
|
return DbContext.Whitelists
|
||||||
|
.Include(u => u.OtherUser)
|
||||||
|
.Include(u => u.User)
|
||||||
|
.Where(w => w.User.UID == userid)
|
||||||
.ToList()
|
.ToList()
|
||||||
.Select(w =>
|
.Select(w =>
|
||||||
{
|
{
|
||||||
var otherEntry = _dbContext.Whitelists.SingleOrDefault(a => a.User.UID == w.OtherUser.UID && a.OtherUser.UID == userid);
|
var otherEntry = OppositeEntry(w.OtherUser.UID);
|
||||||
|
var otherUser = GetUserFromUID(w.OtherUser.UID);
|
||||||
|
var seesYou = false;
|
||||||
|
if (otherEntry != null)
|
||||||
|
{
|
||||||
|
seesYou = DbContext.Visibilities.Any(v =>
|
||||||
|
v.CID == otherUser.CharacterIdentification && v.OtherCID == user.CharacterIdentification);
|
||||||
|
}
|
||||||
return new WhitelistDto
|
return new WhitelistDto
|
||||||
{
|
{
|
||||||
IsPaused = w.IsPaused,
|
IsPaused = w.IsPaused,
|
||||||
OtherUID = w.OtherUser.UID,
|
OtherUID = w.OtherUser.UID,
|
||||||
IsSynced = otherEntry != null,
|
IsSynced = otherEntry != null,
|
||||||
IsPausedFromOthers = otherEntry?.IsPaused ?? false
|
IsPausedFromOthers = otherEntry?.IsPaused ?? false,
|
||||||
};
|
};
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GenerateRandomString(int length, string allowableChars = null)
|
|
||||||
|
public override Task OnDisconnectedAsync(Exception exception)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(allowableChars))
|
var user = DbContext.Users.SingleOrDefault(u => u.UID == AuthenticatedUserId);
|
||||||
allowableChars = @"ABCDEFGHJKLMNPQRSTUVWXYZ0123456789";
|
if (user != null)
|
||||||
|
{
|
||||||
|
var outdatedVisibilities = DbContext.Visibilities.Where(v => v.CID == user.CharacterIdentification);
|
||||||
|
DbContext.RemoveRange(outdatedVisibilities);
|
||||||
|
var outdatedCharacterData = DbContext.CharacterData.Where(v => v.UserId == user.UID);
|
||||||
|
DbContext.RemoveRange(outdatedCharacterData);
|
||||||
|
user.CharacterIdentification = null;
|
||||||
|
DbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
// Generate random data
|
return base.OnDisconnectedAsync(exception);
|
||||||
var rnd = new byte[length];
|
|
||||||
using (var rng = new RNGCryptoServiceProvider())
|
|
||||||
rng.GetBytes(rnd);
|
|
||||||
|
|
||||||
// Generate the output string
|
|
||||||
var allowable = allowableChars.ToCharArray();
|
|
||||||
var l = allowable.Length;
|
|
||||||
var chars = new char[length];
|
|
||||||
for (var i = 0; i < length; i++)
|
|
||||||
chars[i] = allowable[rnd[i] % l];
|
|
||||||
|
|
||||||
return new string(chars);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using MareSynchronos.API;
|
||||||
|
|
||||||
|
namespace MareSynchronosServer.Models
|
||||||
|
{
|
||||||
|
public class CharacterData
|
||||||
|
{
|
||||||
|
public string UserId { get; set; }
|
||||||
|
public int JobId { get; set; }
|
||||||
|
public List<FileReplacementDto> EquipmentData { get; set; }
|
||||||
|
public string GlamourerData { get; set; }
|
||||||
|
public string Hash { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace MareSynchronosServer.Models
|
||||||
|
{
|
||||||
|
public class Visibility
|
||||||
|
{
|
||||||
|
public string CID { get; set; }
|
||||||
|
public string OtherCID { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user