fix(bugs): some gacha and visual issues
This commit is contained in:
1 parent
116ea108f9
commit
138b5a9484
5 files changed
+57
-2
No files matched your search
@@ -175,6 +175,13 @@ public sealed class TutorialGuideGroupExcel
|
|||||||
public uint GroupID { get; set; }
|
public uint GroupID { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class GachaCeilingExcel
|
||||||
|
{
|
||||||
|
public string GachaType { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public List<uint> CeilingItemList { get; set; } = [];
|
||||||
|
}
|
||||||
|
|
||||||
// maps an item id to its main/sub type. the client NPEs on an item it cannot type.
|
// maps an item id to its main/sub type. the client NPEs on an item it cannot type.
|
||||||
public sealed class ItemConfigExcel
|
public sealed class ItemConfigExcel
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -114,4 +114,9 @@ public sealed partial class GameData
|
|||||||
row.TryGetPropertyValue(name, out var node) && node is not null && node.GetValueKind() is JsonValueKind.Number
|
row.TryGetPropertyValue(name, out var node) && node is not null && node.GetValueKind() is JsonValueKind.Number
|
||||||
? node.GetValue<uint>()
|
? node.GetValue<uint>()
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
private static string? Str(JsonObject row, string name) =>
|
||||||
|
row.TryGetPropertyValue(name, out var node) && node is not null && node.GetValueKind() is JsonValueKind.String
|
||||||
|
? node.GetValue<string>()
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
@@ -120,6 +120,9 @@ public sealed partial class GameData
|
|||||||
|
|
||||||
public IReadOnlyList<uint> TutorialGuideIds { get; private set; } = [];
|
public IReadOnlyList<uint> TutorialGuideIds { get; private set; } = [];
|
||||||
|
|
||||||
|
// the standard banner's guaranteed 5* pool
|
||||||
|
public IReadOnlyList<uint> GachaCeilingAvatars { get; private set; } = [];
|
||||||
|
|
||||||
// every relic / lightcone id the client can resolve a type for
|
// every relic / lightcone id the client can resolve a type for
|
||||||
public IReadOnlySet<uint> KnownRelicIds { get; private set; } = new HashSet<uint>();
|
public IReadOnlySet<uint> KnownRelicIds { get; private set; } = new HashSet<uint>();
|
||||||
|
|
||||||
@@ -207,6 +210,9 @@ public sealed partial class GameData
|
|||||||
data.MainMissions = data.Merge<MainMissionExcel>("MainMission.json", r => UInt(r, "MainMissionID"), required: false);
|
data.MainMissions = data.Merge<MainMissionExcel>("MainMission.json", r => UInt(r, "MainMissionID"), required: false);
|
||||||
data.TutorialIds = [.. data.Merge<TutorialExcel>("TutorialData.json", r => UInt(r, "TutorialID"), required: false).Keys];
|
data.TutorialIds = [.. data.Merge<TutorialExcel>("TutorialData.json", r => UInt(r, "TutorialID"), required: false).Keys];
|
||||||
data.TutorialGuideIds = [.. data.Merge<TutorialGuideGroupExcel>("TutorialGuideGroup.json", r => UInt(r, "GroupID"), required: false).Keys];
|
data.TutorialGuideIds = [.. data.Merge<TutorialGuideGroupExcel>("TutorialGuideGroup.json", r => UInt(r, "GroupID"), required: false).Keys];
|
||||||
|
data.GachaCeilingAvatars = [.. data
|
||||||
|
.Merge<GachaCeilingExcel>("GachaCeiling.json", r => Str(r, "GachaType") == "Normal" ? 0u : null, required: false)
|
||||||
|
.Values.SelectMany(r => r.CeilingItemList)];
|
||||||
data.KnownRelicIds = data.Merge<ItemConfigExcel>("ItemConfigRelic.json", r => UInt(r, "ID"), required: false).Keys.ToHashSet();
|
data.KnownRelicIds = data.Merge<ItemConfigExcel>("ItemConfigRelic.json", r => UInt(r, "ID"), required: false).Keys.ToHashSet();
|
||||||
data.KnownLightconeIds = data.Merge<ItemConfigExcel>("ItemConfigEquipment.json", r => UInt(r, "ID"), required: false).Keys.ToHashSet();
|
data.KnownLightconeIds = data.Merge<ItemConfigExcel>("ItemConfigEquipment.json", r => UInt(r, "ID"), required: false).Keys.ToHashSet();
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ namespace CapySR.GameServer.Handlers;
|
|||||||
[Handlers]
|
[Handlers]
|
||||||
public static class MiscHandlers
|
public static class MiscHandlers
|
||||||
{
|
{
|
||||||
|
private const uint StandardBannerId = 1001;
|
||||||
|
|
||||||
// client settings the game stores server side (auto battle, speed, ...)
|
// client settings the game stores server side (auto battle, speed, ...)
|
||||||
public static Task OnGetAllServerPrefsData(PlayerSession session, GetAllServerPrefsDataCsReq request)
|
public static Task OnGetAllServerPrefsData(PlayerSession session, GetAllServerPrefsDataCsReq request)
|
||||||
{
|
{
|
||||||
@@ -63,8 +65,29 @@ public static class MiscHandlers
|
|||||||
public static Task OnGetVideoVersionKey(PlayerSession session, GetVideoVersionKeyCsReq request) =>
|
public static Task OnGetVideoVersionKey(PlayerSession session, GetVideoVersionKeyCsReq request) =>
|
||||||
session.SendAsync(new GetVideoVersionKeyScRsp { Retcode = 0 });
|
session.SendAsync(new GetVideoVersionKeyScRsp { Retcode = 0 });
|
||||||
|
|
||||||
public static Task OnGetGachaInfo(PlayerSession session, GetGachaInfoCsReq request) =>
|
// an empty list leaves the gacha red-dot filter indexing nil every UI tick, which throws
|
||||||
session.SendAsync(new GetGachaInfoScRsp { Retcode = 0 });
|
// out of UIManager.Tick every frame. hand it the standard banner and nothing else.
|
||||||
|
public static Task OnGetGachaInfo(PlayerSession session, GetGachaInfoCsReq request)
|
||||||
|
{
|
||||||
|
var ceiling = new GachaCeiling { CeilingNum = 300, IsClaimed = false };
|
||||||
|
|
||||||
|
foreach (var avatarId in session.World.Data.GachaCeilingAvatars)
|
||||||
|
{
|
||||||
|
ceiling.AvatarList.Add(new GachaCeilingAvatar { AvatarId = avatarId, RepeatedCnt = 300 });
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = new GetGachaInfoScRsp { Retcode = 0, GachaRandom = 0 };
|
||||||
|
|
||||||
|
response.GachaInfoList.Add(new GachaInfo
|
||||||
|
{
|
||||||
|
GachaId = StandardBannerId,
|
||||||
|
GachaCeiling = ceiling,
|
||||||
|
BeginTime = 0,
|
||||||
|
EndTime = 2524608000,
|
||||||
|
});
|
||||||
|
|
||||||
|
return session.SendAsync(response);
|
||||||
|
}
|
||||||
|
|
||||||
public static Task OnGetDailyActiveInfo(PlayerSession session, GetDailyActiveInfoCsReq request) =>
|
public static Task OnGetDailyActiveInfo(PlayerSession session, GetDailyActiveInfoCsReq request) =>
|
||||||
session.SendAsync(new GetDailyActiveInfoScRsp { Retcode = 0 });
|
session.SendAsync(new GetDailyActiveInfoScRsp { Retcode = 0 });
|
||||||
|
|||||||
@@ -36,6 +36,20 @@ public class GameDataTests(ITestOutputHelper output)
|
|||||||
Assert.NotEmpty(data.Equipment);
|
Assert.NotEmpty(data.Equipment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// an empty banner leaves the client's gacha red dot throwing once a frame
|
||||||
|
[Fact]
|
||||||
|
public void ReadsStandardBannerCeiling()
|
||||||
|
{
|
||||||
|
var data = TryLoad(output);
|
||||||
|
if (data is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.NotEmpty(data.GachaCeilingAvatars);
|
||||||
|
Assert.Contains(1003u, data.GachaCeilingAvatars);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ParsesMarch7th()
|
public void ParsesMarch7th()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user