mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
feat: Update appVersion to 2023.03.21 and enhance avatar-item linkage in store service
This commit is contained in:
@@ -64,7 +64,12 @@ public class GameSessionService(DorkNetDbContext db)
|
||||
// in, so we save once with a placeholder, then patch and save
|
||||
// again. Two SaveChangesAsync calls is cheap at our QPS.
|
||||
PhotonRoomName = "pending",
|
||||
MaxCapacity = 8,
|
||||
// Track the room's "Max Player Count in This Subroom" slider
|
||||
// instead of a hardcoded 8, so matchmade joiners fill the room to
|
||||
// the host's chosen limit rather than fragmenting into a new
|
||||
// instance every 8 players. (Existing sessions keep whatever cap
|
||||
// they were created with.)
|
||||
MaxCapacity = await ResolveRoomMaxCapacityAsync(effectiveRoom),
|
||||
PlayerCount = 1,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
};
|
||||
@@ -75,6 +80,28 @@ public class GameSessionService(DorkNetDbContext db)
|
||||
return ToDto(session);
|
||||
}
|
||||
|
||||
// Default session cap when we can't resolve a room-specific value (system
|
||||
// rooms like the dorm use a GUID roomId that doesn't map to a RoomEntity).
|
||||
private const int DefaultMaxCapacity = 8;
|
||||
|
||||
/// <summary>Resolve a new session's capacity from the room's entry
|
||||
/// subroom (lowest <c>OrderIndex</c>) <see cref="RoomSceneEntity.MaxPlayers"/>
|
||||
/// — the value the in-game "Max Player Count in This Subroom" slider
|
||||
/// writes. Matchmade sessions land in the entry subroom, so its cap is the
|
||||
/// right ceiling. GameSession roomIds are the room's numeric Id as a
|
||||
/// string for user rooms; non-numeric (dorm GUID, etc.) → default. Clamped
|
||||
/// to a sane Photon ceiling.</summary>
|
||||
private async Task<int> ResolveRoomMaxCapacityAsync(string roomId)
|
||||
{
|
||||
if (!long.TryParse(roomId, out var roomLongId)) return DefaultMaxCapacity;
|
||||
var max = await db.RoomScenes
|
||||
.Where(s => s.RoomId == roomLongId)
|
||||
.OrderBy(s => s.OrderIndex)
|
||||
.Select(s => (int?)s.MaxPlayers)
|
||||
.FirstOrDefaultAsync();
|
||||
return max is int v && v > 0 ? Math.Clamp(v, 1, 80) : DefaultMaxCapacity;
|
||||
}
|
||||
|
||||
public async Task<GameSession?> GetByIdAsync(long id)
|
||||
{
|
||||
var s = await db.GameSessions.AsNoTracking()
|
||||
|
||||
@@ -297,7 +297,10 @@ public class NotificationService(
|
||||
},
|
||||
// 2020.12 PlayerPresence.Deserialize requires these.
|
||||
["isOnline"] = redacted is not null,
|
||||
["appVersion"] = 20201210,
|
||||
// 2023.03.21 client build version ("20230317"); must match the
|
||||
// joining client's own version or it reports a version mismatch.
|
||||
// Stale 2020 value (20201210) carried over from the December branch.
|
||||
["appVersion"] = 20230317,
|
||||
};
|
||||
|
||||
var envelope = new System.Text.Json.Nodes.JsonObject
|
||||
|
||||
@@ -968,6 +968,15 @@ public class StoreService(DorkNetDbContext db, LevelService level, IConfiguratio
|
||||
Tooltip = i.Description,
|
||||
AvatarItemDesc = avatarItemDesc,
|
||||
AvatarItemDescOrHairDyeDesc = avatarItemDesc,
|
||||
// AvatarItemId is the field the 2023 client's StoreItemListModel
|
||||
// actually reads (store-item +0x38) to resolve the card to a baked
|
||||
// AvatarItem and read its OutfitType for tab placement — verified
|
||||
// vs 2023 ISIL (EMBCEDNHFLB/CLIANCNHNIE, AvatarItem.GIJPCPDKHPO).
|
||||
// AvatarItemDesc alone is NOT the join key, so clothing cards
|
||||
// resolved to OutfitType=-1 and the Shop rendered empty. Ship the
|
||||
// same {guid},,, descriptor (GIJPCPDKHPO accepts bare {guid} or the
|
||||
// composite and falls back to parsing it to the immutable Guid).
|
||||
AvatarItemId = avatarItemDesc,
|
||||
AvatarItemType = string.IsNullOrEmpty(avatarItemDesc) ? (int?)null : avatarItemType,
|
||||
ConsumableItemDesc = consumableItemDesc,
|
||||
EquipmentPrefabName = equipmentPrefabName,
|
||||
|
||||
Reference in New Issue
Block a user