Don't allow deletion of the selected character slot.

This commit is contained in:
Pieter-Jan Briers
2020-10-07 18:02:10 +02:00
parent a984076574
commit 882ed619fd
3 changed files with 56 additions and 14 deletions

View File

@@ -39,21 +39,22 @@ namespace Content.Server.Database
{ {
await using var db = await GetDb(); await using var db = await GetDb();
var prefs = await db.DbContext.Preference.SingleAsync(p => p.UserId == userId.UserId); await SetSelectedCharacterSlotAsync(userId, index, db.DbContext);
prefs.SelectedCharacterSlot = index;
await db.DbContext.SaveChangesAsync(); await db.DbContext.SaveChangesAsync();
} }
public async Task SaveCharacterSlotAsync(NetUserId userId, ICharacterProfile? profile, int slot) public async Task SaveCharacterSlotAsync(NetUserId userId, ICharacterProfile? profile, int slot)
{ {
await using var db = await GetDb();
if (profile is null) if (profile is null)
{ {
await DeleteCharacterSlotAsync(userId, slot); DeleteCharacterSlot(db.DbContext, userId, slot);
await db.DbContext.SaveChangesAsync();
return; return;
} }
await using var db = await GetDb();
if (!(profile is HumanoidCharacterProfile humanoid)) if (!(profile is HumanoidCharacterProfile humanoid))
{ {
// TODO: Handle other ICharacterProfile implementations properly // TODO: Handle other ICharacterProfile implementations properly
@@ -80,17 +81,12 @@ namespace Content.Server.Database
await db.DbContext.SaveChangesAsync(); await db.DbContext.SaveChangesAsync();
} }
private async Task DeleteCharacterSlotAsync(NetUserId userId, int slot) private static void DeleteCharacterSlot(ServerDbContext db, NetUserId userId, int slot)
{ {
await using var db = await GetDb(); db.Preference
db.DbContext
.Preference
.Single(p => p.UserId == userId.UserId) .Single(p => p.UserId == userId.UserId)
.Profiles .Profiles
.RemoveAll(h => h.Slot == slot); .RemoveAll(h => h.Slot == slot);
await db.DbContext.SaveChangesAsync();
} }
public async Task<PlayerPreferences> InitPrefsAsync(NetUserId userId, ICharacterProfile defaultProfile) public async Task<PlayerPreferences> InitPrefsAsync(NetUserId userId, ICharacterProfile defaultProfile)
@@ -113,6 +109,22 @@ namespace Content.Server.Database
return new PlayerPreferences(new[] {new KeyValuePair<int, ICharacterProfile>(0, defaultProfile)}, 0); return new PlayerPreferences(new[] {new KeyValuePair<int, ICharacterProfile>(0, defaultProfile)}, 0);
} }
public async Task DeleteSlotAndSetSelectedIndex(NetUserId userId, int deleteSlot, int newSlot)
{
await using var db = await GetDb();
DeleteCharacterSlot(db.DbContext, userId, deleteSlot);
await SetSelectedCharacterSlotAsync(userId, newSlot, db.DbContext);
await db.DbContext.SaveChangesAsync();
}
private static async Task SetSelectedCharacterSlotAsync(NetUserId userId, int newSlot, ServerDbContext db)
{
var prefs = await db.Preference.SingleAsync(p => p.UserId == userId.UserId);
prefs.SelectedCharacterSlot = newSlot;
}
private static HumanoidCharacterProfile ConvertProfiles(Profile profile) private static HumanoidCharacterProfile ConvertProfiles(Profile profile)
{ {
var jobs = profile.Jobs.ToDictionary(j => j.JobName, j => (JobPriority) j.Priority); var jobs = profile.Jobs.ToDictionary(j => j.JobName, j => (JobPriority) j.Priority);
@@ -188,6 +200,7 @@ namespace Content.Server.Database
await db.DbContext.SaveChangesAsync(); await db.DbContext.SaveChangesAsync();
} }
/* /*
* BAN STUFF * BAN STUFF
*/ */

View File

@@ -1,4 +1,4 @@
using System; using System;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -28,6 +28,8 @@ namespace Content.Server.Database
Task<PlayerPreferences> InitPrefsAsync(NetUserId userId, ICharacterProfile defaultProfile); Task<PlayerPreferences> InitPrefsAsync(NetUserId userId, ICharacterProfile defaultProfile);
Task SaveSelectedCharacterIndexAsync(NetUserId userId, int index); Task SaveSelectedCharacterIndexAsync(NetUserId userId, int index);
Task SaveCharacterSlotAsync(NetUserId userId, ICharacterProfile? profile, int slot); Task SaveCharacterSlotAsync(NetUserId userId, ICharacterProfile? profile, int slot);
// Single method for two operations for transaction.
Task DeleteSlotAndSetSelectedIndex(NetUserId userId, int deleteSlot, int newSlot);
Task<PlayerPreferences?> GetPlayerPreferencesAsync(NetUserId userId); Task<PlayerPreferences?> GetPlayerPreferencesAsync(NetUserId userId);
// Username assignment (for guest accounts, so they persist GUID) // Username assignment (for guest accounts, so they persist GUID)
@@ -95,6 +97,11 @@ namespace Content.Server.Database
return _db.SaveCharacterSlotAsync(userId, profile, slot); return _db.SaveCharacterSlotAsync(userId, profile, slot);
} }
public Task DeleteSlotAndSetSelectedIndex(NetUserId userId, int deleteSlot, int newSlot)
{
return _db.DeleteSlotAndSetSelectedIndex(userId, deleteSlot, newSlot);
}
public Task<PlayerPreferences?> GetPlayerPreferencesAsync(NetUserId userId) public Task<PlayerPreferences?> GetPlayerPreferencesAsync(NetUserId userId)
{ {
return _db.GetPlayerPreferencesAsync(userId); return _db.GetPlayerPreferencesAsync(userId);

View File

@@ -131,14 +131,36 @@ namespace Content.Server.Preferences
var curPrefs = prefsData.Prefs!; var curPrefs = prefsData.Prefs!;
// If they try to delete the slot they have selected then we switch to another one.
// Of course, that's only if they HAVE another slot.
int? nextSlot = null;
if (curPrefs.SelectedCharacterIndex == slot)
{
var (ns, profile) = curPrefs.Characters.FirstOrDefault(p => p.Key != message.Slot);
if (profile == null)
{
// Only slot left, can't delete.
return;
}
nextSlot = ns;
}
var arr = new Dictionary<int, ICharacterProfile>(curPrefs.Characters); var arr = new Dictionary<int, ICharacterProfile>(curPrefs.Characters);
arr.Remove(slot); arr.Remove(slot);
prefsData.Prefs = new PlayerPreferences(arr, slot); prefsData.Prefs = new PlayerPreferences(arr, nextSlot ?? curPrefs.SelectedCharacterIndex);
if (ShouldStorePrefs(message.MsgChannel.AuthType)) if (ShouldStorePrefs(message.MsgChannel.AuthType))
{ {
await _db.SaveCharacterSlotAsync(message.MsgChannel.UserId, null, message.Slot); if (nextSlot != null)
{
await _db.DeleteSlotAndSetSelectedIndex(userId, slot, nextSlot.Value);
}
else
{
await _db.SaveCharacterSlotAsync(userId, null, slot);
}
} }
} }