mirror of
https://github.com/EpinelPS/EpinelPS.git
synced 2025-12-12 15:04:36 +01:00
feat: Implement AZX mini-game functionality and related event handling - 实现 AZX 小游戏功能及相关事件处理 (#69)
- Added new classes for handling AZX mini-game events including entering, finishing, and retrieving data. - Introduced helper methods for managing rewards, rankings, and achievements within the AZX mini-game. - Updated existing event handling to include user-specific data for events and mini-games. - Enhanced user model to store AZX mini-game data and private banner IDs. - Modified event response structures to accommodate new data fields related to AZX mini-game. - Implemented logging for better traceability of AZX mini-game actions and errors.
This commit is contained in:
@@ -322,6 +322,18 @@ namespace EpinelPS.Data
|
|||||||
[LoadRecord("SimulationRoomOcSeasonTable.json", "Id")]
|
[LoadRecord("SimulationRoomOcSeasonTable.json", "Id")]
|
||||||
public readonly Dictionary<int, SimulationRoomOverclockSeasonRecord> SimulationRoomOcSeasonTable = [];
|
public readonly Dictionary<int, SimulationRoomOverclockSeasonRecord> SimulationRoomOcSeasonTable = [];
|
||||||
|
|
||||||
|
// MiniGame AZX Tables
|
||||||
|
[LoadRecord("EventAZXAppleGameMissionTable.json", "Id")]
|
||||||
|
public readonly Dictionary<int, EventAZXAppleGameMissionRecord_Raw> EventAZXAppleGameMissionTable = [];
|
||||||
|
[LoadRecord("EventAZXAppleGameBoardTable.json", "Id")]
|
||||||
|
public readonly Dictionary<int, EventAZXAppleGameBoardRecord_Raw> EventAZXAppleGameBoardTable = [];
|
||||||
|
[LoadRecord("EventAZXAppleGameCharacterTable.json", "Id")]
|
||||||
|
public readonly Dictionary<int, EventAZXAppleGameCharacterRecord_Raw> EventAZXAppleGameCharacterTable = [];
|
||||||
|
[LoadRecord("EventAZXAppleGameSkillTable.json", "Id")]
|
||||||
|
public readonly Dictionary<int, EventAZXAppleGameSkillRecord_Raw> EventAZXAppleGameSkillTable = [];
|
||||||
|
[LoadRecord("EventAZXAppleGameCutSceneTable.json", "Id")]
|
||||||
|
public readonly Dictionary<int, EventAZXAppleGameCutSceneRecord_Raw> EventAZXAppleGameCutSceneTable = [];
|
||||||
|
|
||||||
static async Task<GameData> BuildAsync()
|
static async Task<GameData> BuildAsync()
|
||||||
{
|
{
|
||||||
await Load();
|
await Load();
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ namespace EpinelPS.LobbyServer.Event
|
|||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(typeof(EventHelper));
|
private static readonly ILog log = LogManager.GetLogger(typeof(EventHelper));
|
||||||
|
|
||||||
public static void AddEvents(ref ResGetEventList response)
|
public static void AddEvents(User user, ref ResGetEventList response)
|
||||||
{
|
{
|
||||||
List<LobbyPrivateBannerRecord> lobbyPrivateBanners = GetLobbyPrivateBannerData();
|
List<LobbyPrivateBannerRecord> lobbyPrivateBanners = GetLobbyPrivateBannerData(user);
|
||||||
if (lobbyPrivateBanners.Count == 0)
|
if (lobbyPrivateBanners.Count == 0)
|
||||||
{
|
{
|
||||||
// No active lobby private banners
|
// No active lobby private banners
|
||||||
@@ -32,6 +32,11 @@ namespace EpinelPS.LobbyServer.Event
|
|||||||
List<NetEventData> gachaEvents = GetEventDataBySystemTypes(banner, eventManagers, systemTypes);
|
List<NetEventData> gachaEvents = GetEventDataBySystemTypes(banner, eventManagers, systemTypes);
|
||||||
log.Debug($"Banner EventId: {banner.EventId} has {gachaEvents.Count} associated gacha events: {JsonConvert.SerializeObject(gachaEvents)}");
|
log.Debug($"Banner EventId: {banner.EventId} has {gachaEvents.Count} associated gacha events: {JsonConvert.SerializeObject(gachaEvents)}");
|
||||||
AddEvents(ref response, gachaEvents);
|
AddEvents(ref response, gachaEvents);
|
||||||
|
|
||||||
|
// add challenge events
|
||||||
|
var challengeEvents = GetChallengeEventData(banner, eventManagers);
|
||||||
|
log.Debug($"Banner EventId: {banner.EventId} has {challengeEvents.Count} associated challenge events: {JsonConvert.SerializeObject(challengeEvents)}");
|
||||||
|
AddEvents(ref response, challengeEvents);
|
||||||
}
|
}
|
||||||
// add daily mission events
|
// add daily mission events
|
||||||
List<NetEventData> dailyMissionEvents = GetDailyMissionEventData(eventManagers);
|
List<NetEventData> dailyMissionEvents = GetDailyMissionEventData(eventManagers);
|
||||||
@@ -39,9 +44,9 @@ namespace EpinelPS.LobbyServer.Event
|
|||||||
AddEvents(ref response, dailyMissionEvents);
|
AddEvents(ref response, dailyMissionEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddJoinedEvents(ref ResGetJoinedEvent response)
|
public static void AddJoinedEvents(User user, ref ResGetJoinedEvent response)
|
||||||
{
|
{
|
||||||
List<LobbyPrivateBannerRecord> lobbyPrivateBanners = GetLobbyPrivateBannerData();
|
List<LobbyPrivateBannerRecord> lobbyPrivateBanners = GetLobbyPrivateBannerData(user);
|
||||||
if (lobbyPrivateBanners.Count == 0)
|
if (lobbyPrivateBanners.Count == 0)
|
||||||
{
|
{
|
||||||
// No active lobby private banners
|
// No active lobby private banners
|
||||||
@@ -182,11 +187,19 @@ namespace EpinelPS.LobbyServer.Event
|
|||||||
/// Get active lobby private banner data
|
/// Get active lobby private banner data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>List of active lobby private banners</returns>
|
/// <returns>List of active lobby private banners</returns>
|
||||||
public static List<LobbyPrivateBannerRecord> GetLobbyPrivateBannerData()
|
public static List<LobbyPrivateBannerRecord> GetLobbyPrivateBannerData(User user)
|
||||||
{
|
{
|
||||||
|
var lobbyPrivateBannerIds = user.LobbyPrivateBannerIds;
|
||||||
|
var lobbyPrivateBannerRecords = GameData.Instance.LobbyPrivateBannerTable.Values;
|
||||||
List<LobbyPrivateBannerRecord> lobbyPrivateBanners = [];
|
List<LobbyPrivateBannerRecord> lobbyPrivateBanners = [];
|
||||||
// lobbyPrivateBanners = [.. GameData.Instance.LobbyPrivateBannerTable.Values.Where(b => b.StartDate <= DateTime.UtcNow && b.EndDate >= DateTime.UtcNow)];
|
if (lobbyPrivateBannerIds is not null && lobbyPrivateBannerIds.Count > 0)
|
||||||
lobbyPrivateBanners.Add(new LobbyPrivateBannerRecord() { Id = 10093, PrivateBannerShowDuration = 8, EventId = 82700 });
|
{
|
||||||
|
lobbyPrivateBanners = [.. lobbyPrivateBannerRecords.Where(b => lobbyPrivateBannerIds.Contains(b.Id))];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lobbyPrivateBanners.Add(lobbyPrivateBannerRecords.OrderBy(b => b.Id).Last());
|
||||||
|
}
|
||||||
Logging.WriteLine($"Found {lobbyPrivateBanners.Count} active lobby private banners.", LogType.Debug);
|
Logging.WriteLine($"Found {lobbyPrivateBanners.Count} active lobby private banners.", LogType.Debug);
|
||||||
log.Debug($"Active lobby private banners: {JsonConvert.SerializeObject(lobbyPrivateBanners)}");
|
log.Debug($"Active lobby private banners: {JsonConvert.SerializeObject(lobbyPrivateBanners)}");
|
||||||
return lobbyPrivateBanners;
|
return lobbyPrivateBanners;
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ namespace EpinelPS.LobbyServer.Event
|
|||||||
await ReadData<ReqGetJoinedEvent>();
|
await ReadData<ReqGetJoinedEvent>();
|
||||||
//types are defined in EventTypes.cs
|
//types are defined in EventTypes.cs
|
||||||
ResGetJoinedEvent response = new();
|
ResGetJoinedEvent response = new();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
// add gacha events from active lobby banners
|
||||||
|
EventHelper.AddJoinedEvents(user, ref response);
|
||||||
|
|
||||||
// add gacha events from active lobby banners
|
|
||||||
EventHelper.AddJoinedEvents(ref response);
|
|
||||||
|
|
||||||
await WriteDataAsync(response);
|
await WriteDataAsync(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ namespace EpinelPS.LobbyServer.Event
|
|||||||
|
|
||||||
// types are defined in EventTypes.cs
|
// types are defined in EventTypes.cs
|
||||||
ResGetEventList response = new();
|
ResGetEventList response = new();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
// add events from active lobby banners
|
// add events from active lobby banners
|
||||||
EventHelper.AddEvents(ref response);
|
EventHelper.AddEvents(user, ref response);
|
||||||
|
|
||||||
await WriteDataAsync(response);
|
await WriteDataAsync(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/acquire/achievementmission/reward")]
|
||||||
|
public class AcquireAzxAchievementMissionReward : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// ReqAcquireMiniGameAzxAchievementMissionReward Fields
|
||||||
|
// int AzxId
|
||||||
|
// RepeatedField<int> AchievementMissionIdList
|
||||||
|
ReqAcquireMiniGameAzxAchievementMissionReward req = await ReadData<ReqAcquireMiniGameAzxAchievementMissionReward>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
// ResAcquireMiniGameAzxAchievementMissionReward Fields
|
||||||
|
// NetRewardData Reward
|
||||||
|
ResAcquireMiniGameAzxAchievementMissionReward response = new();
|
||||||
|
|
||||||
|
NetRewardData reward = new();
|
||||||
|
AzxHelper.AcquireReward(user, ref reward, req.AzxId, req.AchievementMissionIdList);
|
||||||
|
|
||||||
|
response.Reward = reward;
|
||||||
|
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
568
EpinelPS/LobbyServer/Event/Minigame/AZX/AzxHelper.cs
Normal file
568
EpinelPS/LobbyServer/Event/Minigame/AZX/AzxHelper.cs
Normal file
@@ -0,0 +1,568 @@
|
|||||||
|
using EpinelPS.Data;
|
||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
using Google.Protobuf.Collections;
|
||||||
|
using Google.Protobuf.WellKnownTypes;
|
||||||
|
using log4net;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
public static class AzxHelper
|
||||||
|
{
|
||||||
|
private static readonly ILog log = LogManager.GetLogger(typeof(AzxHelper));
|
||||||
|
|
||||||
|
public static void AcquireReward(User user, ref NetRewardData reward, int azxId, RepeatedField<int> missionIds)
|
||||||
|
{
|
||||||
|
log.Debug($"Acquiring reward for user {user.ID}, azxId: {azxId}, missionIds: {JsonConvert.SerializeObject(missionIds)}");
|
||||||
|
if (missionIds.Count == 0 || azxId == 0) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var missions = GameData.Instance.EventAZXAppleGameMissionTable.Values.Where(x =>
|
||||||
|
x.MissionRewardId > 0 && missionIds.Contains(x.Id)).ToList();
|
||||||
|
if (missions.Count == 0) return;
|
||||||
|
List<Reward_Data> rewardDatas = [];
|
||||||
|
foreach (var mission in missions)
|
||||||
|
{
|
||||||
|
var rewardRecord = GameData.Instance.GetRewardTableEntry(mission.MissionRewardId);
|
||||||
|
if (rewardRecord is null || rewardRecord.Rewards.Count == 0) continue;
|
||||||
|
foreach (var rewardItem in rewardRecord.Rewards)
|
||||||
|
{
|
||||||
|
if (rewardItem.RewardValue == 0) continue;
|
||||||
|
int itemIndex = rewardDatas.FindIndex(x => x.RewardId == rewardItem.RewardId);
|
||||||
|
if (itemIndex >= 0)
|
||||||
|
rewardDatas[itemIndex].RewardValue += rewardItem.RewardValue;
|
||||||
|
else
|
||||||
|
rewardDatas.Add(rewardItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var rewardData in rewardDatas)
|
||||||
|
{
|
||||||
|
RewardUtils.AddSingleObject(user, ref reward, rewardData.RewardId, rewardData.RewardType, rewardData.RewardValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
var azxInfo = GetAzxInfo(user, azxId);
|
||||||
|
azxInfo.AchievementMissionDataList.AddRange(missionIds.Select(x =>
|
||||||
|
new AchievementMissionData() { MissionId = x, IsReceived = true }));
|
||||||
|
|
||||||
|
user.MiniGameAzxInfo[azxId] = azxInfo;
|
||||||
|
JsonDb.Save();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Acquiring reward failed: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GetRanking(User user, int azxId, ref ResGetMiniGameAzxRanking response)
|
||||||
|
{
|
||||||
|
// ResGetMiniGameAzxRanking Fields
|
||||||
|
// NetMiniGameAzxRankingData UserGuildRanking
|
||||||
|
// RepeatedField<NetMiniGameAzxRankingData> GuildRankingList
|
||||||
|
// NetMiniGameAzxRankingData Fields
|
||||||
|
// int Rank
|
||||||
|
// NetMiniGameAzxScoreAndTime ScoreAndTime
|
||||||
|
// NetWholeUserData User
|
||||||
|
// NetMiniGameAzxScoreAndTime Fields
|
||||||
|
// int Score
|
||||||
|
// Google.Protobuf.WellKnownTypes.Duration TimeToScore
|
||||||
|
|
||||||
|
int dateDay = GetDateDay();
|
||||||
|
var azxInfo = GetAzxInfo(user, azxId);
|
||||||
|
var scoreData = azxInfo.ScoreDatas.Find(x => x.DateDay == dateDay && x.AzxId == azxId);
|
||||||
|
int score = scoreData?.HighScore ?? 0;
|
||||||
|
Duration timeToScore = scoreData?.HighScoreTime ?? new Duration() { Seconds = 0, Nanos = 0 };
|
||||||
|
|
||||||
|
response.UserGuildRanking = new NetMiniGameAzxRankingData()
|
||||||
|
{
|
||||||
|
Rank = 1,
|
||||||
|
ScoreAndTime = new NetMiniGameAzxScoreAndTime()
|
||||||
|
{
|
||||||
|
Score = score,
|
||||||
|
TimeToScore = timeToScore
|
||||||
|
},
|
||||||
|
User = new NetWholeUserData()
|
||||||
|
{
|
||||||
|
Usn = (long)user.ID,
|
||||||
|
Server = 10001,
|
||||||
|
Nickname = user.Nickname,
|
||||||
|
Lv = user.userPointData?.UserLevel ?? 99,
|
||||||
|
Icon = user.ProfileIconId,
|
||||||
|
IconPrism = user.ProfileIconIsPrism,
|
||||||
|
Frame = user.ProfileFrame,
|
||||||
|
LastActionAt = user.LastLogin.Ticks,
|
||||||
|
UserTitleId = user.TitleId,
|
||||||
|
GuildName = user.Nickname,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
response.GuildRankingList.Add(new NetMiniGameAzxRankingData()
|
||||||
|
{
|
||||||
|
Rank = 2,
|
||||||
|
ScoreAndTime = new NetMiniGameAzxScoreAndTime()
|
||||||
|
{
|
||||||
|
Score = 80000,
|
||||||
|
TimeToScore = new Duration() { Seconds = 118, Nanos = 432877000 }
|
||||||
|
},
|
||||||
|
User = new NetWholeUserData()
|
||||||
|
{
|
||||||
|
Usn = (long)user.ID,
|
||||||
|
Server = 10001,
|
||||||
|
Nickname = user.Nickname,
|
||||||
|
Lv = user.userPointData?.UserLevel ?? 99,
|
||||||
|
Icon = user.ProfileIconId,
|
||||||
|
IconPrism = user.ProfileIconIsPrism,
|
||||||
|
Frame = user.ProfileFrame,
|
||||||
|
LastActionAt = user.LastLogin.Ticks,
|
||||||
|
UserTitleId = user.TitleId,
|
||||||
|
GuildName = user.Nickname,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FinishAzx(User user, ReqFinishMiniGameAzx req, ref ResFinishMiniGameAzx response)
|
||||||
|
{
|
||||||
|
// ReqEnterMiniGameAzx Fields
|
||||||
|
// int AzxId
|
||||||
|
// NetMiniGameAzxScoreAndTime ScoreAndTime
|
||||||
|
// int PlayBoardId
|
||||||
|
// int PlayCharacterId
|
||||||
|
// RepeatedField<NetSkillUseCountData> SkillUseCountList
|
||||||
|
// int CutSceneId
|
||||||
|
|
||||||
|
// ResFinishMiniGameAzx Fields
|
||||||
|
// NetRewardData Reward
|
||||||
|
// NetMiniGameAzxDailyMissionData DailyMissionData
|
||||||
|
// bool IsNewHighScore
|
||||||
|
// bool IsNewHighScoreTime
|
||||||
|
try
|
||||||
|
{
|
||||||
|
log.Debug($"Finishing AZX for user {user.ID}, data: {JsonConvert.SerializeObject(req)}");
|
||||||
|
int dateDay = GetDateDay();
|
||||||
|
|
||||||
|
int score = req.ScoreAndTime.Score;
|
||||||
|
Duration timeToScore = req.ScoreAndTime.TimeToScore;
|
||||||
|
|
||||||
|
NetMiniGameAzxDailyMissionData dailyMissionData = new() { IsDailyRewarded = false, DailyAccumulatedScore = 0 };
|
||||||
|
NetRewardData reward = new();
|
||||||
|
|
||||||
|
var azxInfo = GetAzxInfo(user, req.AzxId);
|
||||||
|
|
||||||
|
if (req.CutSceneId > 0 && azxInfo.CutSceneDataList.Find(x => x.CutSceneId == req.CutSceneId) is null)
|
||||||
|
{
|
||||||
|
azxInfo.CutSceneDataList.Add(new CutSceneData() { CutSceneId = req.CutSceneId, IsNew = true });
|
||||||
|
}
|
||||||
|
|
||||||
|
var scoreDataIndex = azxInfo.ScoreDatas.FindIndex(x => x.DateDay == dateDay && x.AzxId == req.AzxId);
|
||||||
|
if (scoreDataIndex >= 0)
|
||||||
|
{
|
||||||
|
if (score > 10000 && !azxInfo.ScoreDatas[scoreDataIndex].IsDailyRewarded)
|
||||||
|
{
|
||||||
|
azxInfo.ScoreDatas[scoreDataIndex].IsDailyRewarded = true;
|
||||||
|
dailyMissionData.IsDailyRewarded = true;
|
||||||
|
RewardUtils.AddSingleCurrencyObject(user, ref reward, CurrencyType.FreeCash, 30);
|
||||||
|
}
|
||||||
|
azxInfo.ScoreDatas[scoreDataIndex].AccumulatedScore += score;
|
||||||
|
dailyMissionData.DailyAccumulatedScore = azxInfo.ScoreDatas[scoreDataIndex].AccumulatedScore;
|
||||||
|
if (azxInfo.ScoreDatas[scoreDataIndex].HighScore < score)
|
||||||
|
{
|
||||||
|
response.IsNewHighScore = true;
|
||||||
|
azxInfo.ScoreDatas[scoreDataIndex].HighScore = score;
|
||||||
|
}
|
||||||
|
if (azxInfo.ScoreDatas[scoreDataIndex].HighScoreTime.ToTimeSpan() > timeToScore.ToTimeSpan())
|
||||||
|
{
|
||||||
|
response.IsNewHighScoreTime = true;
|
||||||
|
azxInfo.ScoreDatas[scoreDataIndex].HighScoreTime = timeToScore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool isDailyRewarded = false;
|
||||||
|
if (score > 10000)
|
||||||
|
{
|
||||||
|
isDailyRewarded = true;
|
||||||
|
dailyMissionData.IsDailyRewarded = true;
|
||||||
|
RewardUtils.AddSingleCurrencyObject(user, ref reward, CurrencyType.FreeCash, 30);
|
||||||
|
}
|
||||||
|
response.IsNewHighScoreTime = true;
|
||||||
|
response.IsNewHighScore = true;
|
||||||
|
azxInfo.ScoreDatas.Add(new MiniGameAzxScoreData
|
||||||
|
{
|
||||||
|
AzxId = req.AzxId,
|
||||||
|
DateDay = dateDay,
|
||||||
|
AccumulatedScore = score,
|
||||||
|
HighScore = score,
|
||||||
|
HighScoreTime = timeToScore,
|
||||||
|
IsDailyRewarded = isDailyRewarded
|
||||||
|
});
|
||||||
|
dailyMissionData.DailyAccumulatedScore = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
// int PlayBoardId
|
||||||
|
// int PlayCharacterId
|
||||||
|
azxInfo.CharacterCount ??= [];
|
||||||
|
if (azxInfo.CharacterCount.TryGetValue(req.PlayCharacterId, out var characterCount))
|
||||||
|
azxInfo.CharacterCount[req.PlayCharacterId] = characterCount + 1;
|
||||||
|
else
|
||||||
|
azxInfo.CharacterCount.Add(req.PlayCharacterId, 1);
|
||||||
|
// RepeatedField<NetSkillUseCountData> SkillUseCountList
|
||||||
|
if (req.SkillUseCountList != null && req.SkillUseCountList.Count > 0)
|
||||||
|
{
|
||||||
|
azxInfo.SkillCount ??= [];
|
||||||
|
foreach (var item in req.SkillUseCountList)
|
||||||
|
{
|
||||||
|
if (azxInfo.SkillCount.TryGetValue(item.SkillId, out var skillCount))
|
||||||
|
azxInfo.SkillCount[item.SkillId] = skillCount + item.SkillUseCount;
|
||||||
|
else
|
||||||
|
azxInfo.SkillCount.Add(item.SkillId, item.SkillUseCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response.DailyMissionData = dailyMissionData;
|
||||||
|
response.Reward = reward;
|
||||||
|
// Save changes
|
||||||
|
user.MiniGameAzxInfo[req.AzxId] = azxInfo;
|
||||||
|
JsonDb.Save();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Finish AZX Error: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EnterAzx(User user, ref ResEnterMiniGameAzx response, int azxId, int playBoardId, int playCharacterId)
|
||||||
|
{
|
||||||
|
log.Debug($"Entering AZX AzxId: {azxId}, PlayBoardId: {playBoardId}, PlayCharacterId: {playCharacterId}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var azxInfo = GetAzxInfo(user, azxId);
|
||||||
|
azxInfo.SelectedBoardId = playBoardId;
|
||||||
|
azxInfo.SelectedCharacterId = playCharacterId;
|
||||||
|
user.MiniGameAzxInfo[azxId] = azxInfo;
|
||||||
|
response.PreviousSRankCount = 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Enter AZX Error: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GetAzxData(User user, int azxId, ref ResGetMiniGameAzxData response)
|
||||||
|
{
|
||||||
|
log.Debug($"Getting AZX data for user {user.ID}");
|
||||||
|
|
||||||
|
var azxInfo = GetAzxInfo(user, azxId);
|
||||||
|
// Initialize score data if null
|
||||||
|
azxInfo.ScoreDatas ??= [];
|
||||||
|
// Get sum score
|
||||||
|
int sumScore = azxInfo.ScoreDatas.Sum(x => x.AccumulatedScore);
|
||||||
|
|
||||||
|
log.Debug($"AZX data: {JsonConvert.SerializeObject(azxInfo)}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// AchievementMissionDataList
|
||||||
|
var missions = GameData.Instance.EventAZXAppleGameMissionTable.Values.ToList();
|
||||||
|
|
||||||
|
foreach (var mission in missions)
|
||||||
|
{
|
||||||
|
bool isReceived = false;
|
||||||
|
azxInfo.AchievementMissionDataList ??= [];
|
||||||
|
var item = azxInfo.AchievementMissionDataList.Find(x => x.MissionId == mission.Id);
|
||||||
|
if (item is not null) isReceived = item.IsReceived;
|
||||||
|
if (mission.MissionType == EventAZXAppleGameMissionMissionType.GetScore)
|
||||||
|
{
|
||||||
|
AddAchievementMission(ref response, mission.Id, sumScore, isReceived);
|
||||||
|
}
|
||||||
|
else if (mission.MissionType == EventAZXAppleGameMissionMissionType.UseSkillCount)
|
||||||
|
{
|
||||||
|
int progress = 0;
|
||||||
|
if (azxInfo.SkillCount.TryGetValue(mission.MissionConditionId, out var skillCount)) progress = skillCount;
|
||||||
|
AddAchievementMission(ref response, mission.Id, progress, isReceived);
|
||||||
|
}
|
||||||
|
else if (mission.MissionType == EventAZXAppleGameMissionMissionType.PlayCharacterCount)
|
||||||
|
{
|
||||||
|
int progress = 0;
|
||||||
|
if (azxInfo.CharacterCount.TryGetValue(mission.MissionConditionId, out var characterCount)) progress = characterCount;
|
||||||
|
AddAchievementMission(ref response, mission.Id, progress, isReceived);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddAchievementMission(ref response, mission.Id, 0, isReceived);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.Error($"Get AchievementMissionDataList Error: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// ConditionalBoardDataList
|
||||||
|
azxInfo.ConditionalBoardDataList ??= [];
|
||||||
|
var boards = GameData.Instance.EventAZXAppleGameBoardTable.Values.ToList();
|
||||||
|
foreach (var board in boards)
|
||||||
|
{
|
||||||
|
var item = azxInfo.ConditionalBoardDataList.Find(x => x.BoardId == board.Id);
|
||||||
|
bool isUnlocked = item is not null && item.IsUnlocked;
|
||||||
|
if (board.BoardOpenScore == 0) continue;
|
||||||
|
response.ConditionalBoardDataList.Add(new NetMiniGameAzxConditionalBoardData()
|
||||||
|
{
|
||||||
|
BoardId = board.Id,
|
||||||
|
Progress = sumScore,
|
||||||
|
IsUnlocked = isUnlocked
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// SelectedBoardId
|
||||||
|
int selectedBoardId = azxInfo.SelectedBoardId > 0 ? azxInfo.SelectedBoardId : boards.Min(x => x.Id);
|
||||||
|
response.SelectedBoardId = selectedBoardId;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.Error($"Get ConditionalBoardDataList Error: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// ConditionalCharacterDataList
|
||||||
|
azxInfo.ConditionalCharacterDataList ??= [];
|
||||||
|
var characters = GameData.Instance.EventAZXAppleGameCharacterTable.Values.ToList();
|
||||||
|
foreach (var character in characters)
|
||||||
|
{
|
||||||
|
var item = azxInfo.ConditionalCharacterDataList.Find(x => x.CharacterId == character.Id);
|
||||||
|
bool isUnlocked = item is not null && item.IsUnlocked;
|
||||||
|
if (character.CharacterOpenScore == 0) continue;
|
||||||
|
response.ConditionalCharacterDataList.Add(new NetMiniGameAzxConditionalCharacterData()
|
||||||
|
{
|
||||||
|
CharacterId = character.Id,
|
||||||
|
Progress = sumScore,
|
||||||
|
IsUnlocked = isUnlocked
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// SelectedCharacterId
|
||||||
|
int selectedCharacterId = azxInfo.SelectedCharacterId > 0 ? azxInfo.SelectedCharacterId : characters.Min(x => x.Id);
|
||||||
|
response.SelectedCharacterId = selectedCharacterId;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.Error($"Get ConditionalCharacterDataList Error: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// ConditionalSkillDataList
|
||||||
|
azxInfo.ConditionalSkillDataList ??= [];
|
||||||
|
foreach (var skill in GameData.Instance.EventAZXAppleGameSkillTable.Values)
|
||||||
|
{
|
||||||
|
var item = azxInfo.ConditionalSkillDataList.Find(x => x.SkillId == skill.Id);
|
||||||
|
bool isUnlocked = item is not null && item.IsUnlocked;
|
||||||
|
if (skill.SkillOpenUseValue == 0) continue;
|
||||||
|
response.ConditionalSkillDataList.Add(new NetMiniGameAzxConditionalSkillData()
|
||||||
|
{
|
||||||
|
SkillId = skill.Id,
|
||||||
|
IsUnlocked = isUnlocked
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.Error($"Get ConditionalSkillDataList Error: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
azxInfo.CutSceneDataList ??= [];
|
||||||
|
foreach (var cutScene in GameData.Instance.EventAZXAppleGameCutSceneTable.Values)
|
||||||
|
{
|
||||||
|
var item = azxInfo.CutSceneDataList.Find(x => x.CutSceneId == cutScene.Id);
|
||||||
|
if (item is not null && item.CutSceneId > 0)
|
||||||
|
{
|
||||||
|
response.CutSceneList.Add(new NetMiniGameAzxCutSceneData { CutSceneId = cutScene.Id, IsNew = item.IsNew });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Get CutSceneList Error: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// NetMiniGameAzxDailyMissionData DailyMissionData
|
||||||
|
azxInfo.ScoreDatas ??= [];
|
||||||
|
int dateDay = GetDateDay();
|
||||||
|
var scoreData = azxInfo.ScoreDatas.Find(x => x.DateDay == dateDay && x.AzxId == azxId);
|
||||||
|
if (scoreData is not null)
|
||||||
|
{
|
||||||
|
response.DailyMissionData = new NetMiniGameAzxDailyMissionData()
|
||||||
|
{
|
||||||
|
DailyAccumulatedScore = scoreData.AccumulatedScore,
|
||||||
|
IsDailyRewarded = scoreData.IsDailyRewarded,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Get DailyMissionData Error: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.IsTutorialConfirmed = azxInfo.IsTutorialConfirmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetTutorialConfirmed(User user, int azxId)
|
||||||
|
{
|
||||||
|
log.Debug($"Setting tutorial confirmed for AZX {azxId}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var azxInfo = GetAzxInfo(user, azxId);
|
||||||
|
azxInfo.IsTutorialConfirmed = true;
|
||||||
|
user.MiniGameAzxInfo[azxId] = azxInfo;
|
||||||
|
log.Debug($"Tutorial data after: {azxInfo.IsTutorialConfirmed}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Setting AZX tutorial confirmed failed: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetBoardUnlocked(User user, int azxId, int boardId)
|
||||||
|
{
|
||||||
|
log.Debug($"Setting board {boardId} unlocked for AZX {azxId}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
var azxInfo = GetAzxInfo(user, azxId);
|
||||||
|
azxInfo.ConditionalBoardDataList ??= [];
|
||||||
|
log.Debug($"Board data before: {JsonConvert.SerializeObject(azxInfo.ConditionalBoardDataList)}");
|
||||||
|
var itemIndex = azxInfo.ConditionalBoardDataList.FindIndex(x => x.BoardId == boardId);
|
||||||
|
if (itemIndex >= 0)
|
||||||
|
{
|
||||||
|
azxInfo.ConditionalBoardDataList[itemIndex].IsUnlocked = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
azxInfo.ConditionalBoardDataList.Add(new ConditionalBoardData() { BoardId = boardId, IsUnlocked = true });
|
||||||
|
}
|
||||||
|
user.MiniGameAzxInfo[azxId] = azxInfo;
|
||||||
|
log.Debug($"Board data after: {JsonConvert.SerializeObject(azxInfo.ConditionalBoardDataList)}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Setting AZX board unlocked failed: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetSkillUnlocked(User user, int azxId, int skillId)
|
||||||
|
{
|
||||||
|
log.Debug($"Setting skill {skillId} unlocked for AZX {azxId}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var azxInfo = GetAzxInfo(user, azxId);
|
||||||
|
azxInfo.ConditionalSkillDataList ??= [];
|
||||||
|
log.Debug($"Skill data before: {JsonConvert.SerializeObject(azxInfo.ConditionalSkillDataList)}");
|
||||||
|
var itemIndex = azxInfo.ConditionalSkillDataList.FindIndex(x => x.SkillId == skillId);
|
||||||
|
if (itemIndex >= 0)
|
||||||
|
{
|
||||||
|
azxInfo.ConditionalSkillDataList[itemIndex].IsUnlocked = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
azxInfo.ConditionalSkillDataList.Add(new ConditionalSkillData() { SkillId = skillId, IsUnlocked = true });
|
||||||
|
}
|
||||||
|
user.MiniGameAzxInfo[azxId] = azxInfo;
|
||||||
|
log.Debug($"Skill data after: {JsonConvert.SerializeObject(azxInfo.ConditionalSkillDataList)}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Setting AZX skill unlocked failed: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetCharacterUnlocked(User user, int azxId, int characterId)
|
||||||
|
{
|
||||||
|
log.Debug($"Setting character {characterId} unlocked for AZX {azxId}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var azxInfo = GetAzxInfo(user, azxId);
|
||||||
|
azxInfo.ConditionalCharacterDataList ??= [];
|
||||||
|
log.Debug($"Character data before: {JsonConvert.SerializeObject(azxInfo.ConditionalCharacterDataList)}");
|
||||||
|
var itemIndex = azxInfo.ConditionalCharacterDataList.FindIndex(x => x.CharacterId == characterId);
|
||||||
|
if (itemIndex >= 0)
|
||||||
|
{
|
||||||
|
azxInfo.ConditionalCharacterDataList[itemIndex].IsUnlocked = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
azxInfo.ConditionalCharacterDataList.Add(new ConditionalCharacterData() { CharacterId = characterId, IsUnlocked = true });
|
||||||
|
}
|
||||||
|
user.MiniGameAzxInfo[azxId] = azxInfo;
|
||||||
|
log.Debug($"Character data after: {JsonConvert.SerializeObject(azxInfo.ConditionalCharacterDataList)}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Setting AZX character unlocked failed: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetCutSceneConfirmed(User user, int azxId, List<int> cutSceneIdList)
|
||||||
|
{
|
||||||
|
log.Debug($"Setting cutscenes confirmed for AZX {azxId}: {string.Join(", ", cutSceneIdList)}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var azxInfo = GetAzxInfo(user, azxId);
|
||||||
|
azxInfo.CutSceneDataList ??= [];
|
||||||
|
log.Debug($"Cutscene data before: {JsonConvert.SerializeObject(azxInfo.CutSceneDataList)}");
|
||||||
|
foreach (var item in cutSceneIdList)
|
||||||
|
{
|
||||||
|
var itemIndex = azxInfo.CutSceneDataList.FindIndex(x => x.CutSceneId == item);
|
||||||
|
if (itemIndex >= 0)
|
||||||
|
{
|
||||||
|
azxInfo.CutSceneDataList[itemIndex].IsNew = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
azxInfo.CutSceneDataList.Add(new CutSceneData() { CutSceneId = item, IsNew = false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user.MiniGameAzxInfo[azxId] = azxInfo;
|
||||||
|
log.Debug($"Cutscene data after: {JsonConvert.SerializeObject(azxInfo.CutSceneDataList)}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.WriteLine($"Setting AZX cutscene confirmed failed: {ex.Message}", LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetDateDay()
|
||||||
|
{
|
||||||
|
// +4 每天4点重新计算
|
||||||
|
DateTime dateTime = DateTime.UtcNow.AddHours(4);
|
||||||
|
return dateTime.Year * 10000 + dateTime.Month * 100 + dateTime.Day;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddAchievementMission(ref ResGetMiniGameAzxData response, int missionId, int progress, bool isReceived)
|
||||||
|
{
|
||||||
|
response.AchievementMissionDataList.Add(new NetMiniGameAzxAchievementMissionData()
|
||||||
|
{
|
||||||
|
MissionId = missionId,
|
||||||
|
Progress = progress,
|
||||||
|
IsReceived = isReceived
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MiniGameAzxData GetAzxInfo(User user, int azxId)
|
||||||
|
{
|
||||||
|
if (!user.MiniGameAzxInfo.TryGetValue(azxId, out var azxInfo))
|
||||||
|
{
|
||||||
|
log.Debug($"Creating new AZX info for {azxId}");
|
||||||
|
user.MiniGameAzxInfo.TryAdd(azxId, new MiniGameAzxData() { });
|
||||||
|
azxInfo = new MiniGameAzxData() { };
|
||||||
|
}
|
||||||
|
log.Debug($"Getting AZX info for {azxId}, data: {JsonConvert.SerializeObject(azxInfo)}");
|
||||||
|
return azxInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
32
EpinelPS/LobbyServer/Event/Minigame/AZX/EnterAzx.cs
Normal file
32
EpinelPS/LobbyServer/Event/Minigame/AZX/EnterAzx.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/enter")]
|
||||||
|
public class EnterAzx : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// ReqEnterMiniGameAzx Fields
|
||||||
|
// int AzxId
|
||||||
|
// int PlayBoardId
|
||||||
|
// int PlayCharacterId
|
||||||
|
ReqEnterMiniGameAzx req = await ReadData<ReqEnterMiniGameAzx>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
// ResEnterMiniGameAzx Fields
|
||||||
|
// int PreviousSRankCount
|
||||||
|
ResEnterMiniGameAzx response = new()
|
||||||
|
{
|
||||||
|
PreviousSRankCount = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
if (req.AzxId > 0 && req.PlayBoardId > 0 && req.PlayCharacterId > 0)
|
||||||
|
AzxHelper.EnterAzx(user, ref response, req.AzxId, req.PlayBoardId, req.PlayCharacterId);
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
EpinelPS/LobbyServer/Event/Minigame/AZX/FinishAzx.cs
Normal file
22
EpinelPS/LobbyServer/Event/Minigame/AZX/FinishAzx.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/finish")]
|
||||||
|
public class FinishAzx : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// { "azxId": 1, "scoreAndTime": { "score": 50000, "timeToScore": "110.122697s" },
|
||||||
|
// "playBoardId": 101, "playCharacterId": 101, "skillUseCountList": [ { "skillId": 102 } ], "cutSceneId": 10101 }
|
||||||
|
ReqFinishMiniGameAzx req = await ReadData<ReqFinishMiniGameAzx>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
ResFinishMiniGameAzx response = new();
|
||||||
|
|
||||||
|
AzxHelper.FinishAzx(user, req, ref response);
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
EpinelPS/LobbyServer/Event/Minigame/AZX/GetAzxData.cs
Normal file
43
EpinelPS/LobbyServer/Event/Minigame/AZX/GetAzxData.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using EpinelPS.Data;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/get/data")]
|
||||||
|
public class GetAzxData : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog log = LogManager.GetLogger(typeof(LobbyMsgHandler));
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// int AzxId
|
||||||
|
ReqGetMiniGameAzxData req = await ReadData<ReqGetMiniGameAzxData>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
// ResGetMiniGameAzxData Fields
|
||||||
|
// NetMiniGameAzxDailyMissionData DailyMissionData
|
||||||
|
// RepeatedField<NetMiniGameAzxAchievementMissionData> AchievementMissionDataList
|
||||||
|
// RepeatedField<NetMiniGameAzxCutSceneData> CutSceneList
|
||||||
|
// int SelectedBoardId
|
||||||
|
// int SelectedCharacterId
|
||||||
|
// RepeatedField<NetMiniGameAzxConditionalBoardData> ConditionalBoardDataList
|
||||||
|
// RepeatedField<NetMiniGameAzxConditionalCharacterData> ConditionalCharacterDataList
|
||||||
|
// RepeatedField<NetMiniGameAzxConditionalSkillData> ConditionalSkillDataList
|
||||||
|
// bool IsTutorialConfirmed
|
||||||
|
ResGetMiniGameAzxData response = new()
|
||||||
|
{
|
||||||
|
DailyMissionData = new NetMiniGameAzxDailyMissionData()
|
||||||
|
{
|
||||||
|
DailyAccumulatedScore = 0,
|
||||||
|
IsDailyRewarded = false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Add implementation for AchievementMissionDataList, CutSceneList, etc.
|
||||||
|
AzxHelper.GetAzxData(user, req.AzxId, ref response);
|
||||||
|
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
EpinelPS/LobbyServer/Event/Minigame/AZX/GetAzxRanking.cs
Normal file
23
EpinelPS/LobbyServer/Event/Minigame/AZX/GetAzxRanking.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/get/ranking")]
|
||||||
|
public class GetAzxRanking : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// int AzxId
|
||||||
|
ReqGetMiniGameAzxRanking req = await ReadData<ReqGetMiniGameAzxRanking>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
ResGetMiniGameAzxRanking response = new();
|
||||||
|
|
||||||
|
if (req.AzxId > 0)
|
||||||
|
AzxHelper.GetRanking(user, req.AzxId, ref response);
|
||||||
|
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
EpinelPS/LobbyServer/Event/Minigame/AZX/GetAzxRedDotData.cs
Normal file
28
EpinelPS/LobbyServer/Event/Minigame/AZX/GetAzxRedDotData.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/get/reddot/data")]
|
||||||
|
public class GetAzxRedDotData : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// ReqGetMiniGameAzxRedDotData Fields
|
||||||
|
// int AzxId
|
||||||
|
ReqGetMiniGameAzxRedDotData req = await ReadData<ReqGetMiniGameAzxRedDotData>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
// ResGetMiniGameAzxRedDotData Fields
|
||||||
|
// bool IsDailyMissionAvailable
|
||||||
|
// bool AchievementMissionRewardExists
|
||||||
|
ResGetMiniGameAzxRedDotData response = new()
|
||||||
|
{
|
||||||
|
IsDailyMissionAvailable = true,
|
||||||
|
AchievementMissionRewardExists = true
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/set/board/unlocked")]
|
||||||
|
public class SetAzxBoardUnlocked : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// ReqSetMiniGameAzxBoardUnlocked Fields
|
||||||
|
// int AzxId
|
||||||
|
// int BoardId
|
||||||
|
ReqSetMiniGameAzxBoardUnlocked req = await ReadData<ReqSetMiniGameAzxBoardUnlocked>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
ResSetMiniGameAzxBoardUnlocked response = new();
|
||||||
|
|
||||||
|
if (req.BoardId > 0 && req.AzxId > 0)
|
||||||
|
AzxHelper.SetBoardUnlocked(user, req.AzxId, req.BoardId);
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/set/character/unlocked")]
|
||||||
|
public class SetAzxCharacterUnlocked : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// ReqSetMiniGameAzxCharacterUnlocked Fields
|
||||||
|
// int AzxId
|
||||||
|
// int CharacterId
|
||||||
|
ReqSetMiniGameAzxCharacterUnlocked req = await ReadData<ReqSetMiniGameAzxCharacterUnlocked>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
ResSetMiniGameAzxCharacterUnlocked response = new();
|
||||||
|
|
||||||
|
if (req.CharacterId > 0 && req.AzxId > 0)
|
||||||
|
AzxHelper.SetCharacterUnlocked(user, req.AzxId, req.CharacterId);
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/set/cutscene/confirmed")]
|
||||||
|
public class SetAzxCutSceneConfirmed : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// ReqEnterMiniGameAzx Fields
|
||||||
|
// int AzxId
|
||||||
|
// RepeatedField<int> ConfirmedCutSceneIdList
|
||||||
|
ReqSetMiniGameAzxCutSceneConfirmed req = await ReadData<ReqSetMiniGameAzxCutSceneConfirmed>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
ResSetMiniGameAzxCutSceneConfirmed response = new();
|
||||||
|
|
||||||
|
if (req.AzxId > 0 && req.ConfirmedCutSceneIdList.Count > 0)
|
||||||
|
AzxHelper.SetCutSceneConfirmed(user, req.AzxId, [.. req.ConfirmedCutSceneIdList]);
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/set/skill/unlocked")]
|
||||||
|
public class SetAzxSkillUnlocked : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
// ReqSetMiniGameAzxSkillUnlocked Fields
|
||||||
|
// int AzxId
|
||||||
|
// int SkillId
|
||||||
|
ReqSetMiniGameAzxSkillUnlocked req = await ReadData<ReqSetMiniGameAzxSkillUnlocked>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
ResSetMiniGameAzxSkillUnlocked response = new();
|
||||||
|
|
||||||
|
if (req.SkillId > 0 && req.AzxId > 0)
|
||||||
|
AzxHelper.SetSkillUnlocked(user, req.AzxId, req.SkillId);
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Event.Minigame.AZX
|
||||||
|
{
|
||||||
|
[PacketPath("/event/minigame/azx/set/tutorial/confirmed")]
|
||||||
|
public class SetAzxTutorialConfirmed : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
await ReadData<ReqSetMiniGameAzxTutorialConfirmed>();
|
||||||
|
User user = GetUser();
|
||||||
|
|
||||||
|
ResSetMiniGameAzxTutorialConfirmed response = new();
|
||||||
|
|
||||||
|
AzxHelper.SetTutorialConfirmed(user, 1);
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ namespace EpinelPS.LobbyServer.Pass
|
|||||||
ResGetActiveEventPassData response = new(); // fields PassList = NetPassInfo
|
ResGetActiveEventPassData response = new(); // fields PassList = NetPassInfo
|
||||||
|
|
||||||
List<LobbyPrivateBannerRecord> lobbyPrivateBanners = [];//[.. GameData.Instance.LobbyPrivateBannerTable.Values.Where(b => b.PrivateBannerShowDuration <= DateTime.UtcNow && b.EndDate >= DateTime.UtcNow)];
|
List<LobbyPrivateBannerRecord> lobbyPrivateBanners = [];//[.. GameData.Instance.LobbyPrivateBannerTable.Values.Where(b => b.PrivateBannerShowDuration <= DateTime.UtcNow && b.EndDate >= DateTime.UtcNow)];
|
||||||
lobbyPrivateBanners = EventHelper.GetLobbyPrivateBannerData();
|
lobbyPrivateBanners = EventHelper.GetLobbyPrivateBannerData(user);
|
||||||
// TODO: PrivateBannerShowDuration
|
// TODO: PrivateBannerShowDuration
|
||||||
log.Debug($"Active lobby private banners: {JsonConvert.SerializeObject(lobbyPrivateBanners)}");
|
log.Debug($"Active lobby private banners: {JsonConvert.SerializeObject(lobbyPrivateBanners)}");
|
||||||
if (lobbyPrivateBanners.Count <= 0)
|
if (lobbyPrivateBanners.Count <= 0)
|
||||||
|
|||||||
@@ -367,4 +367,55 @@ namespace EpinelPS.Models
|
|||||||
public List<PassRankData> PassRankList { get; set; } = [];
|
public List<PassRankData> PassRankList { get; set; } = [];
|
||||||
public List<PassMissionData> PassMissionList { get; set; } = [];
|
public List<PassMissionData> PassMissionList { get; set; } = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MiniGameAzxData
|
||||||
|
public class MiniGameAzxData
|
||||||
|
{
|
||||||
|
public List<MiniGameAzxScoreData> ScoreDatas { get; set; } = [];
|
||||||
|
public List<AchievementMissionData> AchievementMissionDataList { get; set; } = [];
|
||||||
|
public List<ConditionalBoardData> ConditionalBoardDataList { get; set; } = [];
|
||||||
|
public List<ConditionalCharacterData> ConditionalCharacterDataList { get; set; } = [];
|
||||||
|
public List<ConditionalSkillData> ConditionalSkillDataList { get; set; } = [];
|
||||||
|
public List<CutSceneData> CutSceneDataList { get; set; } = [];
|
||||||
|
public bool IsTutorialConfirmed { get; set; } = false;
|
||||||
|
public int SelectedBoardId { get; set; }
|
||||||
|
public int SelectedCharacterId { get; set; }
|
||||||
|
public Dictionary<int, int> SkillCount { get; set; } = [];
|
||||||
|
public Dictionary<int, int> CharacterCount { get; set; } = [];
|
||||||
|
}
|
||||||
|
public class MiniGameAzxScoreData
|
||||||
|
{
|
||||||
|
public int AzxId { get; set; }
|
||||||
|
public int DateDay { get; set; }
|
||||||
|
public int AccumulatedScore { get; set; }
|
||||||
|
public int HighScore { get; set; }
|
||||||
|
public bool IsDailyRewarded { get; set; } = false;
|
||||||
|
public Google.Protobuf.WellKnownTypes.Duration? HighScoreTime { get; set; }
|
||||||
|
}
|
||||||
|
public class AchievementMissionData
|
||||||
|
{
|
||||||
|
public int MissionId { get; set; }
|
||||||
|
public bool IsReceived { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
public class ConditionalBoardData
|
||||||
|
{
|
||||||
|
public int BoardId { get; set; }
|
||||||
|
public bool IsUnlocked { get; set; }
|
||||||
|
}
|
||||||
|
public class ConditionalCharacterData
|
||||||
|
{
|
||||||
|
public int CharacterId { get; set; }
|
||||||
|
public bool IsUnlocked { get; set; }
|
||||||
|
}
|
||||||
|
public class ConditionalSkillData
|
||||||
|
{
|
||||||
|
public int SkillId { get; set; }
|
||||||
|
public bool IsUnlocked { get; set; }
|
||||||
|
}
|
||||||
|
public class CutSceneData
|
||||||
|
{
|
||||||
|
public int CutSceneId { get; set; }
|
||||||
|
public bool IsNew { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -122,6 +122,9 @@ public class User
|
|||||||
|
|
||||||
public Dictionary<int, PassData> UserPassInfo = []; // user pass data, key is PassId
|
public Dictionary<int, PassData> UserPassInfo = []; // user pass data, key is PassId
|
||||||
|
|
||||||
|
public List<int> LobbyPrivateBannerIds = [];
|
||||||
|
public Dictionary<int, MiniGameAzxData> MiniGameAzxInfo = [];
|
||||||
|
|
||||||
public TriggerModel AddTrigger(Trigger type, int value, int conditionId = 0)
|
public TriggerModel AddTrigger(Trigger type, int value, int conditionId = 0)
|
||||||
{
|
{
|
||||||
TriggerModel t = new()
|
TriggerModel t = new()
|
||||||
|
|||||||
Reference in New Issue
Block a user