视觉小说增强;房间类多线程优化 (#151)

This commit is contained in:
yeziuku 2026-04-05 22:47:49 +08:00 committed by GitHub
parent 6942779303
commit ce29844593
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 92 additions and 25 deletions

View File

@ -1,4 +1,5 @@
using Milimoe.FunGame.Core.Interface.Entity; using System.Collections.Concurrent;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Entity namespace Milimoe.FunGame.Core.Entity
@ -18,7 +19,7 @@ namespace Milimoe.FunGame.Core.Entity
public bool HasPass => Password.Trim() != ""; public bool HasPass => Password.Trim() != "";
public string Password { get; set; } = ""; public string Password { get; set; } = "";
public int MaxUsers { get; set; } = 0; public int MaxUsers { get; set; } = 0;
public Dictionary<User, bool> UserAndIsReady { get; } = []; public ConcurrentDictionary<User, bool> UserAndIsReady { get; } = [];
public GameStatistics Statistics { get; set; } public GameStatistics Statistics { get; set; }
internal Room() internal Room()

View File

@ -0,0 +1,44 @@
using System.Text.Json;
using Milimoe.FunGame.Core.Library.Common.Architecture;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
{
public class NovelCharacterNodeConverter : BaseEntityConverter<NovelCharacterNode>
{
public override NovelCharacterNode NewInstance()
{
return new NovelCharacterNode();
}
public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref NovelCharacterNode result, Dictionary<string, object> convertingContext)
{
switch (propertyName)
{
case nameof(NovelCharacterNode.Name):
result.Name = reader.GetString() ?? "";
break;
case nameof(NovelCharacterNode.PortraitImagePath):
result.PortraitImagePath = reader.GetString() ?? "";
break;
case nameof(NovelCharacterNode.StandOut):
result.StandOut = reader.GetBoolean();
break;
case nameof(NovelCharacterNode.PositionType):
result.PositionType = (PositionType)reader.GetInt32();
break;
}
}
public override void Write(Utf8JsonWriter writer, NovelCharacterNode value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString(nameof(NovelCharacterNode.Name), value.Name);
if (value.PortraitImagePath != "") writer.WriteString(nameof(NovelCharacterNode.PortraitImagePath), value.PortraitImagePath);
if (value.StandOut) writer.WriteBoolean(nameof(NovelCharacterNode.StandOut), value.StandOut);
if (value.PositionType != PositionType.Center) writer.WriteNumber(nameof(NovelCharacterNode.PositionType), (int)value.PositionType);
writer.WriteEndObject();
}
}
}

View File

@ -34,14 +34,17 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(NovelNode.Name): case nameof(NovelNode.Name):
result.Name = reader.GetString() ?? ""; result.Name = reader.GetString() ?? "";
break; break;
case nameof(NovelNode.Name2):
result.Name2 = reader.GetString() ?? "";
break;
case nameof(NovelNode.Content): case nameof(NovelNode.Content):
result.Content = reader.GetString() ?? ""; result.Content = reader.GetString() ?? "";
break; break;
case nameof(NovelNode.PortraitImagePath): case nameof(NovelNode.Character):
result.PortraitImagePath = reader.GetString() ?? ""; result.Character = NetworkUtility.JsonDeserialize<NovelCharacterNode>(ref reader, options) ?? new()
{
StandOut = true
};
break;
case nameof(NovelNode.Opponents):
result.Opponents = NetworkUtility.JsonDeserialize<List<NovelCharacterNode>>(ref reader, options) ?? [];
break; break;
case nameof(NovelNode.AndPredicates): case nameof(NovelNode.AndPredicates):
result.Values[nameof(NovelNode.AndPredicates)] = NetworkUtility.JsonDeserialize<List<string>>(ref reader, options) ?? []; result.Values[nameof(NovelNode.AndPredicates)] = NetworkUtility.JsonDeserialize<List<string>>(ref reader, options) ?? [];
@ -66,9 +69,14 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
JsonSerializer.Serialize(writer, value.Options, options); JsonSerializer.Serialize(writer, value.Options, options);
} }
writer.WriteString(nameof(NovelNode.Name), value.Name); writer.WriteString(nameof(NovelNode.Name), value.Name);
if (value.Name2 != "") writer.WriteString(nameof(NovelNode.Name2), value.Name2);
writer.WriteString(nameof(NovelNode.Content), value.Content); writer.WriteString(nameof(NovelNode.Content), value.Content);
if (value.PortraitImagePath != "") writer.WriteString(nameof(NovelNode.PortraitImagePath), value.PortraitImagePath); writer.WritePropertyName(nameof(NovelNode.Character));
JsonSerializer.Serialize(writer, value.Character, options);
if (value.Opponents.Count > 0)
{
writer.WritePropertyName(nameof(NovelNode.Opponents));
JsonSerializer.Serialize(writer, value.Opponents, options);
}
if (value.AndPredicates.Count > 0) if (value.AndPredicates.Count > 0)
{ {
writer.WritePropertyName(nameof(NovelNode.AndPredicates)); writer.WritePropertyName(nameof(NovelNode.AndPredicates));

View File

@ -1,4 +1,6 @@
namespace Milimoe.FunGame.Core.Model using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Model
{ {
public class NovelNode public class NovelNode
{ {
@ -6,13 +8,16 @@
public int Priority { get; set; } = 0; public int Priority { get; set; } = 0;
public NovelNode? Previous { get; set; } = null; public NovelNode? Previous { get; set; } = null;
public List<NovelNode> NextNodes { get; set; } = []; public List<NovelNode> NextNodes { get; set; } = [];
public NovelNode? Next => NextNodes.OrderByDescending(n => n.Priority).Where(n => n.ShowNode).FirstOrDefault(); public NovelNode? Next => NextNodes.OrderByDescending(n => n.Priority).FirstOrDefault(n => n.ShowNode);
public List<NovelOption> Options { get; set; } = []; public List<NovelOption> Options { get; set; } = [];
public List<NovelOption> AvailableOptions => [.. Options.Where(o => o.ShowOption)]; public List<NovelOption> AvailableOptions => [.. Options.Where(o => o.ShowOption)];
public string Name { get; set; } = ""; public string Name { get; set; } = "";
public string Name2 { get; set; } = "";
public string Content { get; set; } = ""; public string Content { get; set; } = "";
public string PortraitImagePath { get; set; } = ""; public NovelCharacterNode Character { get; set; } = new()
{
StandOut = true
};
public List<NovelCharacterNode> Opponents { get; set; } = [];
public Dictionary<string, Func<bool>> AndPredicates { get; set; } = []; public Dictionary<string, Func<bool>> AndPredicates { get; set; } = [];
public Dictionary<string, Func<bool>> OrPredicates { get; set; } = []; public Dictionary<string, Func<bool>> OrPredicates { get; set; } = [];
public bool ShowNode public bool ShowNode
@ -45,4 +50,12 @@
} }
internal Dictionary<string, object> Values { get; set; } = []; internal Dictionary<string, object> Values { get; set; } = [];
} }
public class NovelCharacterNode
{
public string Name { get; set; } = "";
public string PortraitImagePath { get; set; } = "";
public bool StandOut { get; set; } = false;
public PositionType PositionType { get; set; } = PositionType.Center;
}
} }

View File

@ -1,4 +1,5 @@
using System.Collections; using System.Collections;
using System.Collections.Concurrent;
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
@ -6,9 +7,9 @@ namespace Milimoe.FunGame.Core.Model
{ {
public class RoomList : IEnumerable<Room> public class RoomList : IEnumerable<Room>
{ {
private readonly Dictionary<string, Room> _list = []; private readonly ConcurrentDictionary<string, Room> _list = [];
private readonly Dictionary<string, List<User>> _userList = []; private readonly ConcurrentDictionary<string, List<User>> _userList = [];
private readonly Dictionary<string, List<User>> _readyUserList = []; private readonly ConcurrentDictionary<string, List<User>> _readyUserList = [];
public Room this[string roomid] => GetRoom(roomid); public Room this[string roomid] => GetRoom(roomid);
@ -39,9 +40,9 @@ namespace Milimoe.FunGame.Core.Model
public void AddRoom(Room room) public void AddRoom(Room room)
{ {
_list.Add(room.Roomid, room); _list.TryAdd(room.Roomid, room);
_userList.Add(room.Roomid, []); _userList.TryAdd(room.Roomid, []);
_readyUserList.Add(room.Roomid, []); _readyUserList.TryAdd(room.Roomid, []);
} }
public void AddRooms(List<Room> rooms) public void AddRooms(List<Room> rooms)
@ -54,9 +55,9 @@ namespace Milimoe.FunGame.Core.Model
public void RemoveRoom(string roomid) public void RemoveRoom(string roomid)
{ {
_list.Remove(roomid); _list.TryRemove(roomid, out _);
_userList.Remove(roomid); _userList.TryRemove(roomid, out _);
_readyUserList.Remove(roomid); _readyUserList.TryRemove(roomid, out _);
} }
public void RemoveRoom(Room room) => RemoveRoom(room.Roomid); public void RemoveRoom(Room room) => RemoveRoom(room.Roomid);
@ -76,7 +77,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
if (roomid != "-1" && user.Id != 0) if (roomid != "-1" && user.Id != 0)
{ {
this[roomid].UserAndIsReady.Remove(user); this[roomid].UserAndIsReady.TryRemove(user, out _);
} }
} }

View File

@ -22,8 +22,8 @@ namespace Milimoe.FunGame.Core.Service
Converters = { new DateTimeConverter(), new DataTableConverter(), new DataSetConverter(), new UserConverter(), new RoomConverter(), Converters = { new DateTimeConverter(), new DataTableConverter(), new DataSetConverter(), new UserConverter(), new RoomConverter(),
new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter(), new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter(),
new InventoryConverter(), new NormalAttackConverter(), new ClubConverter(), new GoodsConverter(), new StoreConverter(), new InventoryConverter(), new NormalAttackConverter(), new ClubConverter(), new GoodsConverter(), new StoreConverter(),
new NovelOptionConverter(), new NovelNodeConverter(), new ShieldConverter(), new RoundRecordConverter(), new ActivityConverter(), new QuestConverter(), new NovelOptionConverter(), new NovelNodeConverter(), new NovelCharacterNodeConverter(), new ShieldConverter(), new RoundRecordConverter(), new ActivityConverter(),
new MarketConverter(), new MarketItemConverter() new QuestConverter(), new MarketConverter(), new MarketItemConverter()
} }
}; };