some changes

- girl favorite
- immediately read new item
- save database on request login
This commit is contained in:
Naruse
2026-04-26 10:48:29 +08:00
parent 665da256d9
commit f4692a771d
11 changed files with 116 additions and 26 deletions

View File

@@ -1,4 +1,5 @@
using MikuSB.Proto; using MikuSB.Enums.Item;
using MikuSB.Proto;
using SqlSugar; using SqlSugar;
namespace MikuSB.Database.Character; namespace MikuSB.Database.Character;
@@ -21,7 +22,7 @@ public class CharacterInfo
public int Trust { get; set; } public int Trust { get; set; }
public uint WeaponUniqueId { get; set; } public uint WeaponUniqueId { get; set; }
public uint SkinId { get; set; } public uint SkinId { get; set; }
public uint Flag { get; set; } public ItemFlagEnum Flag { get; set; }
public uint Expiration { get; set; } public uint Expiration { get; set; }
[SugarColumn(IsJson = true)] public List<uint> UnlockedSkin { get; set; } = []; [SugarColumn(IsJson = true)] public List<uint> UnlockedSkin { get; set; } = [];
[SugarColumn(IsJson = true)] public List<uint> Spines { get; set; } = []; [SugarColumn(IsJson = true)] public List<uint> Spines { get; set; } = [];
@@ -36,7 +37,7 @@ public class CharacterInfo
Id = Guid, Id = Guid,
Template = TemplateId, Template = TemplateId,
Count = Count, Count = Count,
Flag = Flag, Flag = (uint)Flag,
Expiration = Expiration, Expiration = Expiration,
Enhance = new Enhance Enhance = new Enhance
{ {

View File

@@ -1,4 +1,5 @@
using MikuSB.Proto; using MikuSB.Enums.Item;
using MikuSB.Proto;
using SqlSugar; using SqlSugar;
namespace MikuSB.Database.Inventory; namespace MikuSB.Database.Inventory;
@@ -23,6 +24,7 @@ public abstract class BaseGameItemInfo
public uint UniqueId { get; set; } public uint UniqueId { get; set; }
public ulong TemplateId { get; set; } public ulong TemplateId { get; set; }
public uint ItemCount { get; set; } public uint ItemCount { get; set; }
public ItemFlagEnum Flag { get; set; }
public virtual Item ToProto() public virtual Item ToProto()
{ {
@@ -30,7 +32,8 @@ public abstract class BaseGameItemInfo
{ {
Id = UniqueId, Id = UniqueId,
Template = TemplateId, Template = TemplateId,
Count = ItemCount Count = ItemCount,
Flag = (uint)Flag
}; };
} }
} }
@@ -53,6 +56,7 @@ public class GameWeaponInfo : GrowableItemInfo
Id = UniqueId, Id = UniqueId,
Template = TemplateId, Template = TemplateId,
Count = ItemCount, Count = ItemCount,
Flag = (uint)Flag,
Enhance = new Enhance Enhance = new Enhance
{ {
Level = Level, Level = Level,
@@ -71,7 +75,8 @@ public class GameWeaponInfo : GrowableItemInfo
{ {
Id = UniqueId, Id = UniqueId,
Template = TemplateId, Template = TemplateId,
Count = ItemCount Count = ItemCount,
Flag = (uint)Flag,
}; };
return proto; return proto;
} }

View File

@@ -0,0 +1,13 @@
namespace MikuSB.Enums.Item;
public enum ItemFlagEnum
{
FLAG_USE = 1,// 使用中
FLAG_LOCK = 2,// 锁定中
FLAG_READED = 4,// 道具已查看
FLAG_LEAVE = 8,// 角色大招后离场
FLAG_WEAPON_DEFAULT = 16,// 武器显示原始样式
FLAG_WEAPON_AUDIO = 32,// 武器消音器音效
FLAG_ROLE_LIKE = 64,// 心选角色
}

View File

@@ -25,6 +25,7 @@ public class CharacterManager(PlayerInstance player) : BasePlayerManager(player)
Level = level, Level = level,
Break = CharacterExcel.InitBreak, Break = CharacterExcel.InitBreak,
Timestamp = Extensions.GetUnixSec(), Timestamp = Extensions.GetUnixSec(),
Flag = ItemFlagEnum.FLAG_READED
}; };
var weaponInfo = await Player.InventoryManager!.AddWeaponItem((ItemTypeEnum)CharacterExcel.DefaultWeaponGPDL[0], CharacterExcel.DefaultWeaponGPDL[1], CharacterExcel.DefaultWeaponGPDL[2], (uint)CharacterExcel.DefaultWeaponGPDL[3]); var weaponInfo = await Player.InventoryManager!.AddWeaponItem((ItemTypeEnum)CharacterExcel.DefaultWeaponGPDL[0], CharacterExcel.DefaultWeaponGPDL[1], CharacterExcel.DefaultWeaponGPDL[2], (uint)CharacterExcel.DefaultWeaponGPDL[3]);

View File

@@ -23,6 +23,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player)
UniqueId = InventoryData.NextUniqueUid++, UniqueId = InventoryData.NextUniqueUid++,
Level = level, Level = level,
Break = weaponData.InitBreak, Break = weaponData.InitBreak,
Flag = ItemFlagEnum.FLAG_READED,
ItemCount = 1 ItemCount = 1
}; };
InventoryData.Weapons[weaponInfo.UniqueId] = weaponInfo; InventoryData.Weapons[weaponInfo.UniqueId] = weaponInfo;
@@ -58,6 +59,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player)
TemplateId = templateId, TemplateId = templateId,
UniqueId = InventoryData.NextUniqueUid++, UniqueId = InventoryData.NextUniqueUid++,
Level = level, Level = level,
Flag = ItemFlagEnum.FLAG_READED,
ItemCount = 1 ItemCount = 1
}; };
InventoryData.Skins[skinInfo.UniqueId] = skinInfo; InventoryData.Skins[skinInfo.UniqueId] = skinInfo;

View File

@@ -246,25 +246,7 @@ public class PlayerInstance(PlayerGameData data)
// Launch.GPASSID = 22 stores pass counts. ChapterLevel.GID = 21 stores star flags. // Launch.GPASSID = 22 stores pass counts. ChapterLevel.GID = 21 stores star flags.
// Completing the prologue/early chapter range prevents function conditions from // Completing the prologue/early chapter range prevents function conditions from
// treating the account as a fresh tutorial player. // treating the account as a fresh tutorial player.
for (uint levelId = 10_000; levelId <= 10_160; levelId++) for (uint levelId = 10_000; levelId <= 10_700; levelId++)
{
yield return (21, levelId, 7);
yield return (22, levelId, 1);
}
for (uint levelId = 12_001; levelId <= 12_075; levelId++)
{
yield return (21, levelId, 7);
yield return (22, levelId, 1);
}
for (uint levelId = 13_002; levelId <= 13_081; levelId++)
{
yield return (21, levelId, 7);
yield return (22, levelId, 1);
}
foreach (var levelId in new uint[] { 11_315, 11_311, 11_313, 11_322, 11_331, 11_333, 10_123, 50_000, 50_151 })
{ {
yield return (21, levelId, 7); yield return (21, levelId, 7);
yield return (22, levelId, 1); yield return (22, levelId, 1);

View File

@@ -0,0 +1,15 @@
namespace MikuSB.GameServer.Server.CallGS.Handlers.Daily;
// Success response shape expected by Lua:
// { nSeed = random_number }
[CallGSApi("Daily_EnterLevel")]
public class Daily_EnterLevel : ICallGSHandler
{
private static readonly Random Random = new();
public async Task Handle(Connection connection, string param, ushort seqNo)
{
var rsp = $"{{\"nSeed\":{Random.Next(1, 1000000000)}}}";
await CallGSRouter.SendScript(connection, "Daily_EnterLevel", rsp);
}
}

View File

@@ -0,0 +1,40 @@
using MikuSB.Enums.Item;
using MikuSB.Proto;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace MikuSB.GameServer.Server.CallGS.Handlers.Girl;
[CallGSApi("GirlCard_SetRoleLikeFlag")]
public class GirlCard_SetRoleLikeFlag : ICallGSHandler
{
public async Task Handle(Connection connection, string param, ushort seqNo)
{
var player = connection.Player!;
var girlData = JsonSerializer.Deserialize<SetRoleLikeFlagParam>(param);
if (girlData == null) return;
var cardData = player.CharacterManager.GetCharacterByGUID(girlData.CardId);
if (cardData == null) return;
cardData.Flag = girlData.Flag == 1
? ItemFlagEnum.FLAG_ROLE_LIKE
: ItemFlagEnum.FLAG_READED;
var sync = new NtfSyncPlayer
{
Items = { cardData.ToProto() }
};
await CallGSRouter.SendScript(connection, "GirlCard_SetRoleLikeFlag", "{}", sync);
}
}
internal sealed class SetRoleLikeFlagParam
{
[JsonPropertyName("nFlag")]
public int Flag { get; set; }
[JsonPropertyName("nCardID")]
public uint CardId { get; set; }
}

View File

@@ -1,7 +1,7 @@
using MikuSB.Proto; using MikuSB.Proto;
using System.Text.Json; using System.Text.Json;
namespace MikuSB.GameServer.Server.CallGS.Handlers.Daily; namespace MikuSB.GameServer.Server.CallGS.Handlers.Girl;
[CallGSApi("GirlSkin_Change")] [CallGSApi("GirlSkin_Change")]
public class GirlSkin_Change : ICallGSHandler public class GirlSkin_Change : ICallGSHandler

View File

@@ -0,0 +1,30 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace MikuSB.GameServer.Server.CallGS.Handlers.Girl;
[CallGSApi("GirlSkin_ChangeSkinType")]
public class GirlSkin_ChangeSkinType : ICallGSHandler
{
public async Task Handle(Connection connection, string param, ushort seqNo)
{
var req = JsonSerializer.Deserialize<ChangeSkinTypeParam>(param);
var response = new JsonObject
{
["nType"] = req?.Type ?? 1,
["nSkinId"] = req?.SkinId
};
// TODO change type in proto Item ??
await CallGSRouter.SendScript(connection, "GirlSkin_ChangeSkinType", response.ToJsonString());
}
}
internal sealed class ChangeSkinTypeParam
{
[JsonPropertyName("nType")]
public int? Type { get; set; }
[JsonPropertyName("nSkinId")]
public uint? SkinId { get; set; }
}

View File

@@ -46,5 +46,6 @@ public class HandlerReqLogin : Handler
await connection.Player.OnEnterGame(); await connection.Player.OnEnterGame();
connection.Player.Connection = connection; connection.Player.Connection = connection;
await connection.SendPacket(new PacketRspLogin(connection.Player!)); await connection.SendPacket(new PacketRspLogin(connection.Player!));
await connection.Player.OnHeartBeat();
} }
} }