mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-27 07:59:03 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,574 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.Extensions;
|
||||
using RadicadeServer.RecNet;
|
||||
using RadicadeServer.RecNet.Accounts;
|
||||
using RadicadeServer.RecNet.Enums;
|
||||
using RadicadeServer.RecNet.Enums.Messages;
|
||||
using RadicadeServer.RecNet.Enums.Rooms;
|
||||
using RadicadeServer.RecNet.Messages;
|
||||
using RadicadeServer.RecNet.Rooms;
|
||||
|
||||
namespace RadicadeServer.Utils
|
||||
{
|
||||
public static class RoomUtils
|
||||
{
|
||||
public static IDbContextFactory<RecDBContext> DbFactory = null!;
|
||||
|
||||
public static async Task<bool> VerifyRole(long playerId, long roomId, RoleType roleType)
|
||||
{
|
||||
var role = await GetRoleForPlayer(playerId, roomId);
|
||||
if (role == null) return false;
|
||||
|
||||
return role.Role >= roleType;
|
||||
}
|
||||
|
||||
public static async Task<bool> CanSeeRoom(RoomData room, long? accountId)
|
||||
{
|
||||
if (room.Accessibility != Accessibility.Private) return true;
|
||||
if (accountId == null) return false;
|
||||
if (room.CreatorAccountId == accountId.Value) return true;
|
||||
if (await VerifyRole(accountId.Value, room.RoomId, RoleType.CoOwner)) return true;
|
||||
|
||||
if (DbFactory != null)
|
||||
{
|
||||
await using var db = await DbFactory.CreateDbContextAsync();
|
||||
if (await (
|
||||
from presence in db.Presences.AsNoTracking()
|
||||
join instance in db.RoomInstances.AsNoTracking()
|
||||
on presence.roomInstance equals instance.roomInstanceId
|
||||
where presence.playerId == accountId.Value && presence.isOnline &&
|
||||
instance.roomId == room.RoomId
|
||||
select presence.playerId).AnyAsync()) return true;
|
||||
}
|
||||
|
||||
return await HasLiveGameInvite(room.RoomId, accountId.Value);
|
||||
}
|
||||
|
||||
public static async Task<bool> HasLiveGameInvite(long roomId, long accountId)
|
||||
{
|
||||
if (DbFactory == null) return false;
|
||||
|
||||
await using var db = await DbFactory.CreateDbContextAsync();
|
||||
|
||||
long? inviter = await db.Messages.AsNoTracking()
|
||||
.Where(message =>
|
||||
message.ToPlayerId == accountId &&
|
||||
(message.Type == MessageType.GameInvite || message.Type == MessageType.GameInviteV2) &&
|
||||
message.RoomId == roomId)
|
||||
.OrderByDescending(message => message.Id)
|
||||
.Select(message => (long?)message.FromPlayerId)
|
||||
.FirstOrDefaultAsync();
|
||||
if (inviter == null) return false;
|
||||
|
||||
return await (
|
||||
from presence in db.Presences.AsNoTracking()
|
||||
join instance in db.RoomInstances.AsNoTracking()
|
||||
on presence.roomInstance equals instance.roomInstanceId
|
||||
where presence.playerId == inviter.Value &&
|
||||
presence.isOnline &&
|
||||
instance.roomId == roomId
|
||||
select presence.playerId).AnyAsync();
|
||||
}
|
||||
|
||||
public static async Task<List<RoomData>> VisibleRooms(IEnumerable<RoomData> rooms, long? accountId)
|
||||
{
|
||||
var visible = new List<RoomData>();
|
||||
foreach (var room in rooms)
|
||||
{
|
||||
if (await CanSeeRoom(room, accountId)) visible.Add(room);
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
public const string PrivateRoomName = "PRIVATE ROOM";
|
||||
|
||||
public static async Task<bool> IsHiddenFrom(RoomData room, long? accountId)
|
||||
=> !room.IsDorm && !await CanSeeRoom(room, accountId);
|
||||
|
||||
public static FullRoom MaskHiddenRoom(RoomData room)
|
||||
{
|
||||
return new FullRoom
|
||||
{
|
||||
RoomId = room.RoomId,
|
||||
Name = PrivateRoomName,
|
||||
Description = string.Empty,
|
||||
ImageName = DBConfig.DefaultRoomImage,
|
||||
IsDorm = false,
|
||||
State = room.State,
|
||||
Accessibility = Accessibility.Private,
|
||||
CreatedAt = room.CreatedAt,
|
||||
CreatorAccountId = room.CreatorAccountId,
|
||||
MaxPlayers = room.MaxPlayers,
|
||||
MaxPlayerCalculationMode = room.MaxPlayerCalculationMode,
|
||||
CloningAllowed = false,
|
||||
DisableRoomComments = true,
|
||||
CustomWarning = string.Empty,
|
||||
SubRooms = new List<SubRoom>(),
|
||||
Roles = new List<RoomRole>(),
|
||||
LoadScreens = new List<RoomLoadScreen>(),
|
||||
PromoImages = new List<string>(),
|
||||
PromoExternalContent = new List<ExternalContent>(),
|
||||
DataBlob = string.Empty,
|
||||
Tags = new List<ItemTag>(),
|
||||
Stats = new RoomStats { RoomId = room.RoomId },
|
||||
Version = 1
|
||||
};
|
||||
}
|
||||
|
||||
public static async Task<RoomInstance?> ForViewerAsync(RoomInstance? instance, long? viewerId)
|
||||
{
|
||||
if (instance == null) return null;
|
||||
|
||||
await using var db = await DbFactory.CreateDbContextAsync();
|
||||
var room = await db.Rooms.AsNoTracking().FirstOrDefaultAsync(x => x.RoomId == instance.roomId);
|
||||
if (room == null || !await IsHiddenFrom(room, viewerId)) return instance;
|
||||
|
||||
var masked = instance.Copy();
|
||||
masked.name = PrivateRoomName;
|
||||
return masked;
|
||||
}
|
||||
public static async Task<List<RoomRole>> GetRoles(long roomId)
|
||||
{
|
||||
await using var db = await DbFactory.CreateDbContextAsync();
|
||||
|
||||
var room = await db.Rooms.AsNoTracking().FirstOrDefaultAsync(x => x.RoomId == roomId);
|
||||
if (room == null) return [];
|
||||
|
||||
var roomRole = await db.RoomRoles.AsNoTracking().Where(x => x.RoomId == roomId).ToListAsync();
|
||||
|
||||
var creatorRow = roomRole.FirstOrDefault(x => x.AccountId == room.CreatorAccountId);
|
||||
if (creatorRow == null)
|
||||
roomRole.Add(new RoomRole { AccountId = room.CreatorAccountId, InvitedRole = RoleType.None, Role = RoleType.Creator, RoomId = roomId });
|
||||
else if (creatorRow.Role < RoleType.Creator)
|
||||
creatorRow.Role = RoleType.Creator;
|
||||
|
||||
if (room.IsRRO)
|
||||
{
|
||||
var rroOwners = (await db.ServerConfig.AsNoTracking().FirstOrDefaultAsync(x => x.Key == "HighRanks"))?.Value;
|
||||
|
||||
foreach (var dev in (rroOwners ?? string.Empty).Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (!long.TryParse(dev, out long userId)) continue;
|
||||
|
||||
foreach (var role in new[] { RoleType.Creator, RoleType.Moderator })
|
||||
{
|
||||
if (roomRole.Any(x => x.AccountId == userId && x.Role == role)) continue;
|
||||
|
||||
roomRole.Add(new RoomRole { AccountId = userId, InvitedRole = RoleType.None, Role = role, RoomId = roomId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return roomRole;
|
||||
}
|
||||
public static async Task<RoomRole?> GetRoleForPlayer(long playerId, long roomId)
|
||||
{
|
||||
var roomRoles = await GetRoles(roomId);
|
||||
|
||||
return roomRoles
|
||||
.Where(x => x.AccountId == playerId)
|
||||
.OrderByDescending(x => x.Role)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public static SubRoomDataSave BuildCurrentSave(SubRoom subRoom)
|
||||
{
|
||||
return new SubRoomDataSave
|
||||
{
|
||||
SubRoomDataSaveId = 1,
|
||||
SubRoomId = subRoom.SubRoomId,
|
||||
DataBlob = subRoom.DataBlob,
|
||||
SavedByAccountId = subRoom.SavedByAccountId,
|
||||
CreatedAt = subRoom.CreatedAt,
|
||||
UnityAssetId = string.IsNullOrEmpty(subRoom.UnityAssetId) ? null : subRoom.UnityAssetId,
|
||||
PersistenceVersion = 1,
|
||||
OMVersion = 1,
|
||||
UgcSubVersion = 1,
|
||||
SavedOnPlatform = 0,
|
||||
SavedOnDeviceClass = 0,
|
||||
Description = string.Empty,
|
||||
ModerationState = 0
|
||||
};
|
||||
}
|
||||
|
||||
public static object BuildSaveResponse(SubRoom subRoom, string? dataBlobHash)
|
||||
{
|
||||
return new
|
||||
{
|
||||
subRoomDataSaveId = 1L,
|
||||
subRoomId = subRoom.SubRoomId,
|
||||
unityAssetId = string.IsNullOrEmpty(subRoom.UnityAssetId) ? null : subRoom.UnityAssetId,
|
||||
unityAsset = (string?)null,
|
||||
unityAssetHash = (string?)null,
|
||||
dataBlob = subRoom.DataBlob ?? string.Empty,
|
||||
dataBlobHash,
|
||||
savedByAccountId = (long?)subRoom.SavedByAccountId,
|
||||
savedOnPlatform = 0,
|
||||
savedOnDeviceClass = 0,
|
||||
description = string.Empty,
|
||||
createdAt = subRoom.CreatedAt
|
||||
};
|
||||
}
|
||||
|
||||
public static async Task<List<SubRoomDataSave>> GetSaveHistory(RecDBContext ctx, long roomId, long subRoomId)
|
||||
{
|
||||
var subRoom = await ctx.SubRooms.AsNoTracking()
|
||||
.FirstOrDefaultAsync(x => x.RoomId == roomId && x.SubRoomId == subRoomId);
|
||||
|
||||
if (subRoom == null) return new List<SubRoomDataSave>();
|
||||
|
||||
var saves = new List<SubRoomDataSave>();
|
||||
|
||||
if (!string.IsNullOrEmpty(subRoom.DataBlob)) saves.Add(BuildCurrentSave(subRoom));
|
||||
|
||||
var history = await ctx.SubRoomHistory.AsNoTracking()
|
||||
.Where(x => x.RoomId == roomId && x.SubRoomId == subRoomId && x.DataBlob != "")
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.ThenByDescending(x => x.HistoryId)
|
||||
.ToListAsync();
|
||||
|
||||
saves.AddRange(history.Select(BuildRestorableSave));
|
||||
|
||||
return saves;
|
||||
}
|
||||
|
||||
public static SubRoomDataSave BuildRestorableSave(RestorableSubRoom row)
|
||||
{
|
||||
return new SubRoomDataSave
|
||||
{
|
||||
SubRoomDataSaveId = row.HistoryId + 1,
|
||||
SubRoomId = row.SubRoomId,
|
||||
DataBlob = row.DataBlob,
|
||||
SavedByAccountId = row.SavedByAccountId,
|
||||
CreatedAt = row.CreatedAt,
|
||||
PersistenceVersion = 1,
|
||||
OMVersion = 1,
|
||||
UgcSubVersion = 1,
|
||||
SavedOnPlatform = 0,
|
||||
SavedOnDeviceClass = 0,
|
||||
Description = string.Empty,
|
||||
ModerationState = 0
|
||||
};
|
||||
}
|
||||
|
||||
public static FullRoom ConvertToFull(this RoomData room, List<SubRoom> subRooms, RoomStats stats, List<RoomRole> roles)
|
||||
{
|
||||
FullRoom fullRoom = new FullRoom
|
||||
{
|
||||
Name = room.Name,
|
||||
RoomId = room.RoomId,
|
||||
Description = room.Description ?? string.Empty,
|
||||
ImageName = room.ImageName,
|
||||
IsRRO = room.IsRRO,
|
||||
IsDeveloperOwned = room.IsDeveloperOwned,
|
||||
IsDorm = room.IsDorm,
|
||||
State = room.State,
|
||||
Accessibility = room.Accessibility,
|
||||
CreatedAt = room.CreatedAt,
|
||||
CreatorAccountId = room.CreatorAccountId,
|
||||
SupportsJuniors = room.SupportsJuniors,
|
||||
SupportsLevelVoting = room.SupportsLevelVoting,
|
||||
SupportsMobile = room.SupportsMobile,
|
||||
SupportsQuest2 = room.SupportsQuest2,
|
||||
SupportsScreens = room.SupportsScreens,
|
||||
SupportsTeleportVR = room.SupportsTeleportVR,
|
||||
SupportsVRLow = room.SupportsVRLow,
|
||||
SupportsWalkVR = room.SupportsWalkVR,
|
||||
EncryptVoiceChat = room.EncryptVoiceChat,
|
||||
MaxPlayerCalculationMode = room.MaxPlayerCalculationMode,
|
||||
MaxPlayers = room.MaxPlayers,
|
||||
SubRooms = subRooms,
|
||||
Stats = stats,
|
||||
CloningAllowed = room.CloningAllowed,
|
||||
CustomWarning = room.CustomWarning ?? string.Empty,
|
||||
Roles = roles,
|
||||
DataBlob = null,
|
||||
Tags = StringTools.ReadTags(room.Tags),
|
||||
LoadScreens = room.loadScreen.FromJson<List<RoomLoadScreen>>() ?? new(),
|
||||
WarningMask = room.WarningMask,
|
||||
Version = room.Version,
|
||||
DisableRoomComments = room.DisableRoomComments,
|
||||
DisableMicAutoMute = room.DisableMicAutoMute,
|
||||
MinLevel = room.MinLevel
|
||||
};
|
||||
|
||||
foreach (var subRoom in subRooms)
|
||||
{
|
||||
subRoom.CurrentSave = string.IsNullOrEmpty(subRoom.DataBlob) ? null : BuildCurrentSave(subRoom);
|
||||
|
||||
subRoom.CreatorAccountId = subRoom.SavedByAccountId != 0 ? subRoom.SavedByAccountId : null;
|
||||
}
|
||||
|
||||
return fullRoom;
|
||||
}
|
||||
|
||||
public static async Task<List<FullRoom>> BulkConvertRoomData(List<RoomData> data)
|
||||
{
|
||||
var fullRooms = new List<FullRoom>();
|
||||
foreach (var d in data)
|
||||
{
|
||||
var found = await GetRoom(d.RoomId);
|
||||
if (found != null)
|
||||
fullRooms.Add(found);
|
||||
}
|
||||
return fullRooms;
|
||||
}
|
||||
public static async Task<List<RoomDetail>> BulkConvertRoomDataToRoomDetail(List<RoomData> data)
|
||||
{
|
||||
var rooms = new List<RoomDetail>();
|
||||
foreach (var d in data)
|
||||
{
|
||||
var found = await GetRoom(d.RoomId);
|
||||
if (found != null)
|
||||
rooms.Add(found);
|
||||
}
|
||||
return rooms;
|
||||
}
|
||||
|
||||
public static async Task<FullRoom?> GetRoom(string Name)
|
||||
{
|
||||
await using var ctx = await DbFactory.CreateDbContextAsync();
|
||||
|
||||
var room = await ctx.Rooms.AsNoTracking().FirstOrDefaultAsync((x) => x.Name == Name);
|
||||
if (room == null && !string.IsNullOrWhiteSpace(Name) && Name.StartsWith("@", StringComparison.Ordinal) && Name.EndsWith("'s Dorm", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var username = Name.Substring(1, Name.Length - 8);
|
||||
var owner = await ctx.Profiles.AsNoTracking().FirstOrDefaultAsync(x => x.username == username || x.displayName == username);
|
||||
if (owner != null)
|
||||
{
|
||||
room = await ctx.Rooms.AsNoTracking().FirstOrDefaultAsync(x => x.IsDorm && x.CreatorAccountId == owner.accountId);
|
||||
}
|
||||
}
|
||||
if (room == null) return null;
|
||||
|
||||
return await GetRoom(room.RoomId);
|
||||
}
|
||||
public static async Task<FullRoom?> GetRoom(long Id)
|
||||
{
|
||||
await using var ctx = await DbFactory.CreateDbContextAsync();
|
||||
|
||||
var room = await ctx.Rooms.AsNoTracking().FirstOrDefaultAsync((x) => x.RoomId == Id);
|
||||
if (room == null) return null;
|
||||
|
||||
var cheers = await ctx.RoomInteractions.AsNoTracking().CountAsync(x => x.RoomId == Id && x.Cheered);
|
||||
var favourites = await ctx.RoomInteractions.AsNoTracking().CountAsync(x => x.RoomId == Id && x.Favorited);
|
||||
var visitorCount = await ctx.RoomInteractions.AsNoTracking().CountAsync(x => x.RoomId == Id && x.Visited);
|
||||
var visitCount = await ctx.RoomInteractions.AsNoTracking()
|
||||
.Where(x => x.RoomId == Id && x.Visited)
|
||||
.SumAsync(x => (int?)x.VisitCount) ?? 0;
|
||||
|
||||
var roomStats = new RoomStats { CheerCount = cheers, FavoriteCount = favourites, RoomId = Id, VisitCount = visitCount, VisitorCount = visitorCount };
|
||||
|
||||
var roomRoles = await GetRoles(Id);
|
||||
|
||||
var subRooms = await ctx.SubRooms.AsNoTracking().Where((x) => x.RoomId == Id).ToListAsync();
|
||||
|
||||
var missingBlobs = subRooms
|
||||
.Where(x => !string.IsNullOrEmpty(x.DataBlob) && !File.Exists(Path.Join(DBConfig.CDNStorage, x.DataBlob)))
|
||||
.ToList();
|
||||
|
||||
if (missingBlobs.Count > 0)
|
||||
{
|
||||
var missingIds = missingBlobs.Select(x => x.SubRoomId).ToList();
|
||||
|
||||
var candidates = await ctx.SubRoomHistory.AsNoTracking()
|
||||
.Where(x => missingIds.Contains(x.SubRoomId) && x.DataBlob != "")
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var subRoom in missingBlobs)
|
||||
{
|
||||
var recovered = candidates
|
||||
.Where(x => x.SubRoomId == subRoom.SubRoomId)
|
||||
.Select(x => x.DataBlob)
|
||||
.FirstOrDefault(blob => !string.IsNullOrEmpty(blob) && File.Exists(Path.Join(DBConfig.CDNStorage, blob)));
|
||||
|
||||
subRoom.DataBlob = recovered ?? "";
|
||||
ctx.SubRooms.Attach(subRoom);
|
||||
ctx.Entry(subRoom).Property(x => x.DataBlob).IsModified = true;
|
||||
}
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return room.ConvertToFull(subRooms, roomStats, roomRoles);
|
||||
}
|
||||
|
||||
public static async Task<RoomStats?> GetRoomStats(long roomId, long? playerId)
|
||||
{
|
||||
await using var ctx = await DbFactory.CreateDbContextAsync();
|
||||
|
||||
var cheers = await ctx.RoomInteractions.AsNoTracking().CountAsync(x => x.RoomId == roomId && x.Cheered);
|
||||
var favourites = await ctx.RoomInteractions.AsNoTracking().CountAsync(x => x.RoomId == roomId && x.Favorited);
|
||||
|
||||
var visitorCount = await ctx.RoomInteractions.AsNoTracking().CountAsync(x => x.RoomId == roomId && x.Visited);
|
||||
|
||||
var visited = 0;
|
||||
if (playerId != null)
|
||||
{
|
||||
var interaction = await ctx.RoomInteractions.AsNoTracking()
|
||||
.FirstOrDefaultAsync(x => x.RoomId == roomId && x.PlayerId == playerId);
|
||||
|
||||
if (interaction != null)
|
||||
visited = interaction.VisitCount;
|
||||
}
|
||||
|
||||
return new RoomStats() { CheerCount = cheers, FavoriteCount = favourites, RoomId = roomId, VisitCount = visited, VisitorCount = visitorCount };
|
||||
}
|
||||
|
||||
|
||||
public static async Task<FullRoom?> CloneRoom(long originalRoomId, long newCreator, string newName)
|
||||
{
|
||||
await using var ctx = await DbFactory.CreateDbContextAsync();
|
||||
|
||||
FullRoom? room = await GetRoom(originalRoomId);
|
||||
if (room == null)
|
||||
return null;
|
||||
|
||||
|
||||
|
||||
var tags = room.Tags;
|
||||
var rro = tags.Find(x => x.Tag.StartsWith("rro") && x.Type >= TagType.Auto);
|
||||
if (rro != null)
|
||||
tags.Remove(rro);
|
||||
|
||||
RoomData roomData = new RoomData
|
||||
{
|
||||
State = RoomState.Active,
|
||||
SupportsJuniors = room.SupportsJuniors,
|
||||
SupportsLevelVoting = room.SupportsLevelVoting,
|
||||
SupportsMobile = room.SupportsMobile,
|
||||
SupportsQuest2 = room.SupportsQuest2,
|
||||
SupportsScreens = room.SupportsScreens,
|
||||
SupportsTeleportVR = room.SupportsTeleportVR,
|
||||
SupportsVRLow = room.SupportsVRLow,
|
||||
SupportsWalkVR = room.SupportsWalkVR,
|
||||
Accessibility = Accessibility.Private,
|
||||
CloningAllowed = false,
|
||||
CreatedAt = DateTime.Now,
|
||||
CreatorAccountId = newCreator,
|
||||
CustomWarning = room.CustomWarning,
|
||||
Description = room.Description,
|
||||
DisableMicAutoMute = room.DisableMicAutoMute,
|
||||
DisableRoomComments = room.DisableRoomComments,
|
||||
EncryptVoiceChat = room.EncryptVoiceChat,
|
||||
ImageName = room.ImageName,
|
||||
IsDorm = room.IsDorm,
|
||||
IsRRO = false,
|
||||
|
||||
IsDeveloperOwned = !room.IsDorm && await ctx.IsDeveloper(newCreator),
|
||||
MaxPlayerCalculationMode = room.MaxPlayerCalculationMode,
|
||||
MaxPlayers = room.MaxPlayers,
|
||||
MinLevel = room.MinLevel,
|
||||
Name = newName,
|
||||
Tags = StringTools.CreateTagString(tags),
|
||||
WarningMask = room.WarningMask,
|
||||
};
|
||||
|
||||
await ctx.AddAsync(roomData);
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
|
||||
if (room.SubRooms == null || room.SubRooms.Count == 0)
|
||||
{
|
||||
ctx.Remove(roomData);
|
||||
await ctx.SaveChangesAsync();
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (SubRoom subRoom in room.SubRooms)
|
||||
{
|
||||
if (subRoom == null) continue;
|
||||
await ctx.SubRooms.AddAsync(new SubRoom
|
||||
{
|
||||
Accessibility = subRoom.Accessibility,
|
||||
DataBlob = subRoom.DataBlob,
|
||||
UnityAssetId = subRoom.UnityAssetId,
|
||||
IsSandbox = subRoom.IsSandbox,
|
||||
UnitySceneId = subRoom.UnitySceneId,
|
||||
MaxPlayers = subRoom.MaxPlayers,
|
||||
Name = subRoom.Name,
|
||||
RoomId = roomData.RoomId
|
||||
});
|
||||
}
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
|
||||
await ctx.RoomStats.AddAsync(new RoomStats
|
||||
{
|
||||
RoomId = roomData.RoomId,
|
||||
FavoriteCount = 0,
|
||||
CheerCount = 0,
|
||||
VisitCount = 0,
|
||||
VisitorCount = 0,
|
||||
});
|
||||
|
||||
|
||||
await ctx.RoomRoles.AddAsync(new RoomRole
|
||||
{
|
||||
RoomId = roomData.RoomId,
|
||||
Role = RoleType.Creator,
|
||||
InvitedRole = RoleType.None,
|
||||
AccountId = newCreator
|
||||
});
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
return await GetRoom(roomData.RoomId);
|
||||
}
|
||||
|
||||
private static async Task<FullRoom?> GetDormTemplateRoom()
|
||||
{
|
||||
var templateRoom = await GetRoom(1);
|
||||
if (templateRoom != null) return templateRoom;
|
||||
|
||||
await using var ctx = await DbFactory.CreateDbContextAsync();
|
||||
var template = await ctx.Rooms.AsNoTracking().FirstOrDefaultAsync(room => room.IsDorm && room.CreatorAccountId == 1);
|
||||
return template == null ? null : await GetRoom(template.RoomId);
|
||||
}
|
||||
|
||||
public static async Task<FullRoom?> GetOrCreateDorm(long playerId)
|
||||
{
|
||||
await using var ctx = await DbFactory.CreateDbContextAsync();
|
||||
|
||||
var roomData = await ctx.Rooms.AsNoTracking().FirstOrDefaultAsync((x) => x.IsDorm && x.CreatorAccountId == playerId);
|
||||
if (roomData == null)
|
||||
{
|
||||
var templateRoom = await GetDormTemplateRoom();
|
||||
if (templateRoom == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await CloneRoom(templateRoom.RoomId, playerId, "DormRoom");
|
||||
}
|
||||
|
||||
|
||||
var hasSubRoom = await ctx.SubRooms.AnyAsync(s => s.RoomId == roomData.RoomId);
|
||||
if (!hasSubRoom)
|
||||
{
|
||||
var templateRoom = await GetDormTemplateRoom();
|
||||
var templateSub = templateRoom?.SubRooms?.FirstOrDefault();
|
||||
if (templateSub != null)
|
||||
{
|
||||
await ctx.SubRooms.AddAsync(new SubRoom
|
||||
{
|
||||
RoomId = roomData.RoomId,
|
||||
DataBlob = templateSub.DataBlob,
|
||||
UnityAssetId = templateSub.UnityAssetId,
|
||||
IsSandbox = templateSub.IsSandbox,
|
||||
UnitySceneId = templateSub.UnitySceneId,
|
||||
MaxPlayers = templateSub.MaxPlayers,
|
||||
Name = templateSub.Name,
|
||||
Accessibility = templateSub.Accessibility
|
||||
});
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return await GetRoom(roomData.RoomId);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user