mirror of
https://github.com/EpinelPS/EpinelPS.git
synced 2025-12-23 12:24:40 +01:00
Compare commits
2 Commits
8b8d58854f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
735060b16e | ||
|
|
da51e6ba3e |
@@ -351,6 +351,23 @@ namespace EpinelPS.Data
|
||||
public readonly Dictionary<int, EventAZXAppleGameSkillRecord_Raw> EventAZXAppleGameSkillTable = [];
|
||||
[LoadRecord("EventAZXAppleGameCutSceneTable.json", "Id")]
|
||||
public readonly Dictionary<int, EventAZXAppleGameCutSceneRecord_Raw> EventAZXAppleGameCutSceneTable = [];
|
||||
|
||||
// solo raid data Table
|
||||
[LoadRecord("SoloRaidManagerTable.json", "Id")]
|
||||
public readonly Dictionary<int, SoloRaidManagerRecord> SoloRaidManagerTable = [];
|
||||
[LoadRecord("SoloRaidPresetTable.json", "Id")]
|
||||
public readonly Dictionary<int, SoloRaidPresetRecord> SoloRaidPresetTable = [];
|
||||
|
||||
// Monster data Table
|
||||
[LoadRecord("MonsterTable.json", "Id")]
|
||||
public readonly Dictionary<long, MonsterRecord> MonsterTable = [];
|
||||
[LoadRecord("MonsterModelTable.json", "Id")]
|
||||
public readonly Dictionary<int, MonsterModelRecord> MonsterModelTable = [];
|
||||
[LoadRecord("MonsterStatEnhanceTable.json", "Id")]
|
||||
public readonly Dictionary<int, MonsterStatEnhanceRecord> MonsterStatEnhanceTable = [];
|
||||
[LoadRecord("WaveDataTable.wave_Intercept_001.json", "StageId")]
|
||||
public readonly Dictionary<int, WaveDataRecord> WaveIntercept001Table = [];
|
||||
|
||||
|
||||
static async Task<GameData> BuildAsync()
|
||||
{
|
||||
|
||||
@@ -31,15 +31,15 @@ namespace EpinelPS.LobbyServer.Character
|
||||
return;
|
||||
}
|
||||
|
||||
// Find a new CSN based on the `NameCode` of the current character and `GradeCoreId + 1`
|
||||
// Find a new CSN based on the `NameCode` of the current character and `GradeCoreId + req.Count`
|
||||
// For some reason, there is a seperate character for each limit/core break value.
|
||||
CharacterRecord? newCharacter = fullchardata.FirstOrDefault(c => c.NameCode == currentCharacter.NameCode && c.GradeCoreId == currentCharacter.GradeCoreId + 1);
|
||||
CharacterRecord? newCharacter = fullchardata.FirstOrDefault(c => c.NameCode == currentCharacter.NameCode && c.GradeCoreId == currentCharacter.GradeCoreId + req.Count);
|
||||
|
||||
|
||||
if (newCharacter != null)
|
||||
{
|
||||
// replace character in DB with new character
|
||||
targetCharacter.Grade++;
|
||||
targetCharacter.Grade += req.Count;
|
||||
targetCharacter.Tid = newCharacter.Id;
|
||||
|
||||
response.Character = new NetUserCharacterDefaultData()
|
||||
@@ -47,7 +47,7 @@ namespace EpinelPS.LobbyServer.Character
|
||||
Csn = req.Csn,
|
||||
CostumeId = targetCharacter.CostumeId,
|
||||
Grade = targetCharacter.Grade,
|
||||
Lv = user.GetSynchroLevel(),
|
||||
Lv = targetCharacter.Level,
|
||||
Skill1Lv = targetCharacter.Skill1Lvl,
|
||||
Skill2Lv = targetCharacter.Skill2Lvl,
|
||||
Tid = targetCharacter.Tid,
|
||||
@@ -56,7 +56,7 @@ namespace EpinelPS.LobbyServer.Character
|
||||
|
||||
// remove spare body item
|
||||
ItemData bodyItem = user.Items.FirstOrDefault(i => i.Isn == req.Isn) ?? throw new NullReferenceException();
|
||||
user.RemoveItemBySerialNumber(req.Isn, 1);
|
||||
user.RemoveItemBySerialNumber(req.Isn, req.Count);
|
||||
response.Items.Add(NetUtils.ToNet(bodyItem));
|
||||
|
||||
JsonDb.Save();
|
||||
|
||||
@@ -32,15 +32,15 @@ namespace EpinelPS.LobbyServer.Character
|
||||
return;
|
||||
}
|
||||
|
||||
// Find a new CSN based on the `NameCode` of the current character and `GradeCoreId + 1`
|
||||
// Find a new CSN based on the `NameCode` of the current character and `GradeCoreId + req.Count`
|
||||
// For some reason, there is a seperate character for each limit/core break value.
|
||||
CharacterRecord? newCharacter = fullchardata.FirstOrDefault(c => c.NameCode == currentCharacter.NameCode && c.GradeCoreId == currentCharacter.GradeCoreId + 1);
|
||||
CharacterRecord? newCharacter = fullchardata.FirstOrDefault(c => c.NameCode == currentCharacter.NameCode && c.GradeCoreId == currentCharacter.GradeCoreId + req.Count);
|
||||
|
||||
|
||||
if (newCharacter != null)
|
||||
{
|
||||
// replace character in DB with new character
|
||||
targetCharacter.Grade++;
|
||||
targetCharacter.Grade += req.Count;
|
||||
targetCharacter.Tid = newCharacter.Id;
|
||||
|
||||
response.Character = new NetUserCharacterDefaultData()
|
||||
@@ -48,7 +48,7 @@ namespace EpinelPS.LobbyServer.Character
|
||||
Csn = req.Csn,
|
||||
CostumeId = targetCharacter.CostumeId,
|
||||
Grade = targetCharacter.Grade,
|
||||
Lv = user.GetSynchroLevel(),
|
||||
Lv = targetCharacter.Level,
|
||||
Skill1Lv = targetCharacter.Skill1Lvl,
|
||||
Skill2Lv = targetCharacter.Skill2Lvl,
|
||||
Tid = targetCharacter.Tid,
|
||||
@@ -57,7 +57,7 @@ namespace EpinelPS.LobbyServer.Character
|
||||
|
||||
// remove spare body item
|
||||
ItemData bodyItem = user.Items.FirstOrDefault(i => i.Isn == req.Isn) ?? throw new NullReferenceException();
|
||||
user.RemoveItemBySerialNumber(req.Isn, 1);
|
||||
user.RemoveItemBySerialNumber(req.Isn, req.Count);
|
||||
response.Items.Add(NetUtils.ToNet(bodyItem));
|
||||
|
||||
if (newCharacter.GradeCoreId == 103 || newCharacter.GradeCoreId == 11 || newCharacter.GradeCoreId == 201)
|
||||
|
||||
28
EpinelPS/LobbyServer/Soloraid/Close.cs
Normal file
28
EpinelPS/LobbyServer/Soloraid/Close.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/close")]
|
||||
public class Close : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
// int RaidId, int RaidLevel
|
||||
var req = await ReadData<ReqCloseSoloRaid>();
|
||||
var user = GetUser();
|
||||
ResCloseSoloRaid response = new()
|
||||
{
|
||||
PeriodResult = SoloRaidPeriodResult.Success
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.CloseSoloRaid(user, req.RaidId, req.RaidLevel, SoloRaidType.Normal);
|
||||
}catch(Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"CloseSoloRaid Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
28
EpinelPS/LobbyServer/Soloraid/ClosePractice.cs
Normal file
28
EpinelPS/LobbyServer/Soloraid/ClosePractice.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/practice/close")]
|
||||
public class ClosePractice : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
// int RaidId, int RaidLevel
|
||||
var req = await ReadData<ReqCloseSoloRaidPractice>();
|
||||
var user = GetUser();
|
||||
ResCloseSoloRaidPractice response = new()
|
||||
{
|
||||
PeriodResult = SoloRaidPeriodResult.Success
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.CloseSoloRaid(user, req.RaidId, req.RaidLevel, SoloRaidType.Practice);
|
||||
}catch(Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"CloseSoloRaidPractice Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
28
EpinelPS/LobbyServer/Soloraid/CloseTrial.cs
Normal file
28
EpinelPS/LobbyServer/Soloraid/CloseTrial.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/trial/close")]
|
||||
public class CloseTrial : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
// int RaidId, int RaidLevel
|
||||
var req = await ReadData<ReqCloseSoloRaidTrial>();
|
||||
var user = GetUser();
|
||||
ResCloseSoloRaidTrial response = new()
|
||||
{
|
||||
PeriodResult = SoloRaidPeriodResult.Success
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.CloseSoloRaid(user, req.RaidId, req.RaidLevel, SoloRaidType.Trial);
|
||||
}catch(Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"CloseSoloRaidTrial Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
21
EpinelPS/LobbyServer/Soloraid/Enter.cs
Normal file
21
EpinelPS/LobbyServer/Soloraid/Enter.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/enter")]
|
||||
public class Enter : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqEnterSoloRaid>();
|
||||
|
||||
Logging.WriteLine($"Entering solo raid {req.RaidId} at level {req.RaidLevel} for user {GetUser().ID} team {req.Team} members");
|
||||
|
||||
ResEnterSoloRaid response = new()
|
||||
{
|
||||
PeriodResult = SoloRaidPeriodResult.Success,
|
||||
};
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
21
EpinelPS/LobbyServer/Soloraid/EnterTrial.cs
Normal file
21
EpinelPS/LobbyServer/Soloraid/EnterTrial.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/trial/enter")]
|
||||
public class EnterTrial : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqEnterSoloRaidTrial>();
|
||||
|
||||
Logging.WriteLine($"Entering solo raid {req.RaidId} at level {req.RaidLevel} for user {GetUser().ID} team {req.Team} members");
|
||||
|
||||
ResEnterSoloRaidTrial response = new()
|
||||
{
|
||||
PeriodResult = SoloRaidPeriodResult.Success,
|
||||
};
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
25
EpinelPS/LobbyServer/Soloraid/FastBattle.cs
Normal file
25
EpinelPS/LobbyServer/Soloraid/FastBattle.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/fastbattle")]
|
||||
public class FastBattle : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqFastBattleSoloRaid>();
|
||||
var user = GetUser();
|
||||
ResFastBattleSoloRaid response = new();
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.FastBattle(user, ref response, req.RaidId, req.RaidLevel, req.ClearCount);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.WriteLine($"FastBattle Error {e.Message}");
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.SoloraId;
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraidmuseum/get/reddotdata")]
|
||||
public class GetBadgeData : LobbyMsgHandler
|
||||
|
||||
35
EpinelPS/LobbyServer/Soloraid/GetInfo.cs
Normal file
35
EpinelPS/LobbyServer/Soloraid/GetInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/get")]
|
||||
public class GetInfo : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
await ReadData<ReqGetSoloRaidInfo>();
|
||||
User user = GetUser();
|
||||
|
||||
// ResGetSoloRaidInfo Fields
|
||||
// NetUserSoloRaidInfo Info
|
||||
// SoloRaidPeriodResult PeriodResult
|
||||
// SoloRaidBanResult BanResult
|
||||
ResGetSoloRaidInfo response = new()
|
||||
{
|
||||
Info = new NetUserSoloRaidInfo(),
|
||||
PeriodResult = SoloRaidPeriodResult.Success,
|
||||
BanResult = SoloRaidBanResult.Success
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
response.Info = SoloRaidHelper.GetUserSoloRaidInfo(user);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"GetSoloRaidInfo error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
25
EpinelPS/LobbyServer/Soloraid/GetLevel.cs
Normal file
25
EpinelPS/LobbyServer/Soloraid/GetLevel.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/getlevel")]
|
||||
public class GetLevel : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqGetLevelSoloRaid>();
|
||||
User user = GetUser();
|
||||
ResGetLevelSoloRaid response = new();
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.GetLevelInfo(user, ref response, req.RaidLevel);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"GetLevelSoloRaid Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
25
EpinelPS/LobbyServer/Soloraid/GetLevelPractice.cs
Normal file
25
EpinelPS/LobbyServer/Soloraid/GetLevelPractice.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/practice/getlevel")]
|
||||
public class GetLevelPractice : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqGetLevelPracticeSoloRaid>();
|
||||
var user = GetUser();
|
||||
ResGetLevelPracticeSoloRaid response = new();
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.GetLevelPracticeInfo(user, ref response, req.RaidLevel);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"GetLevelPractice Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
26
EpinelPS/LobbyServer/Soloraid/GetLevelTrial.cs
Normal file
26
EpinelPS/LobbyServer/Soloraid/GetLevelTrial.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/trial/getlevel")]
|
||||
public class GetLevelTrial : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
// int RaidLevel
|
||||
var req = await ReadData<ReqGetLevelTrialSoloRaid>();
|
||||
User user = GetUser();
|
||||
ResGetLevelTrialSoloRaid response = new();
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.GetLevelTrialInfo(user, ref response, req.RaidLevel);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"GetLevelTrial Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
27
EpinelPS/LobbyServer/Soloraid/GetLogs.cs
Normal file
27
EpinelPS/LobbyServer/Soloraid/GetLogs.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid
|
||||
{
|
||||
[PacketPath("/soloraid/getlogs")]
|
||||
public class GetLogs : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
// int RaidId, int RaidLevel
|
||||
var req = await ReadData<ReqGetSoloRaidLogs>();
|
||||
var user = GetUser();
|
||||
ResGetSoloRaidLogs response = new();
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.GetSoloRaidLog(user, ref response, req.RaidId, req.RaidLevel);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"GetLogs Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,17 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.SoloraId
|
||||
namespace EpinelPS.LobbyServer.Soloraid
|
||||
{
|
||||
[PacketPath("/soloraid/getperiod")]
|
||||
public class GetSoloraidPeriod : LobbyMsgHandler
|
||||
public class GetPeriod : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
ReqGetSoloRaidPeriod req = await ReadData<ReqGetSoloRaidPeriod>();
|
||||
await ReadData<ReqGetSoloRaidPeriod>();
|
||||
|
||||
ResGetSoloRaidPeriod response = new()
|
||||
{
|
||||
Period = new NetSoloRaidPeriodData
|
||||
{
|
||||
|
||||
}
|
||||
Period = SoloRaidHelper.GetSoloRaidPeriod()
|
||||
};
|
||||
// TODO
|
||||
await WriteDataAsync(response);
|
||||
18
EpinelPS/LobbyServer/Soloraid/GetRanking.cs
Normal file
18
EpinelPS/LobbyServer/Soloraid/GetRanking.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/getranking")]
|
||||
public class GetRanking : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
await ReadData<ReqGetSoloRaidRanking>();
|
||||
|
||||
ResGetSoloRaidRanking response = new();
|
||||
|
||||
// TODO
|
||||
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
32
EpinelPS/LobbyServer/Soloraid/Open.cs
Normal file
32
EpinelPS/LobbyServer/Soloraid/Open.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using EpinelPS.Database;
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/open")]
|
||||
public class Open : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
// { "raidId": 1000030, "raidLevel": 1 }
|
||||
var req = await ReadData<ReqOpenSoloRaid>();
|
||||
User user = GetUser();
|
||||
ResOpenSoloRaid response = new()
|
||||
{
|
||||
PeriodResult = SoloRaidPeriodResult.Success,
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
int openCount = SoloRaidHelper.OpenSoloRaid(user, req.RaidId, req.RaidLevel);
|
||||
response.RaidOpenCount = openCount;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"OpenSoloRaid error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
JsonDb.Save();
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
33
EpinelPS/LobbyServer/Soloraid/OpenPractice.cs
Normal file
33
EpinelPS/LobbyServer/Soloraid/OpenPractice.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using EpinelPS.Database;
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/practice/open")]
|
||||
public class OpenPractice : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
// ReqOpenSoloRaidPractice Fields:
|
||||
// int RaidLevel
|
||||
// SoloRaidDifficultyType DifficultyType
|
||||
var req = await ReadData<ReqOpenSoloRaidPractice>();
|
||||
User user = GetUser();
|
||||
ResOpenSoloRaidPractice response = new()
|
||||
{
|
||||
PeriodResult = SoloRaidPeriodResult.Success,
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.OpenSoloRaid(user, 0, req.RaidLevel, type: SoloRaidType.Practice);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"OpenSoloRaid error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
JsonDb.Save();
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
32
EpinelPS/LobbyServer/Soloraid/OpenTrial.cs
Normal file
32
EpinelPS/LobbyServer/Soloraid/OpenTrial.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using EpinelPS.Database;
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/trial/open")]
|
||||
public class OpenTrial : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
// { "raidLevel": 8 }
|
||||
var req = await ReadData<ReqOpenSoloRaidTrial>();
|
||||
User user = GetUser();
|
||||
ResOpenSoloRaidTrial response = new()
|
||||
{
|
||||
PeriodResult = SoloRaidPeriodResult.Success,
|
||||
RaidOpenCount = 1,
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
response.RaidOpenCount = SoloRaidHelper.OpenSoloRaid(user, 0, req.RaidLevel, type: SoloRaidType.Trial);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"OpenSoloRaid error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
JsonDb.Save();
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
29
EpinelPS/LobbyServer/Soloraid/SetDamage.cs
Normal file
29
EpinelPS/LobbyServer/Soloraid/SetDamage.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using EpinelPS.Database;
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/setdamage")]
|
||||
public class SetDamage : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
|
||||
var req = await ReadData<ReqSetSoloRaidDamage>();
|
||||
User user = GetUser();
|
||||
|
||||
ResSetSoloRaidDamage response = new();
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.SetDamage(user, ref response, req);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"SetDamage Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
JsonDb.Save();
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
27
EpinelPS/LobbyServer/Soloraid/SetDamagePractice.cs
Normal file
27
EpinelPS/LobbyServer/Soloraid/SetDamagePractice.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using EpinelPS.Database;
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/practice/setdamage")]
|
||||
public class SetDamagePractice : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
var req = await ReadData<ReqSetSoloRaidPracticeDamage>();
|
||||
var user = GetUser();
|
||||
ResSetSoloRaidPracticeDamage response = new();
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.SetDamagePractice(user, ref response, req);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"SetDamagePractice Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
JsonDb.Save();
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
29
EpinelPS/LobbyServer/Soloraid/SetDamageTrial.cs
Normal file
29
EpinelPS/LobbyServer/Soloraid/SetDamageTrial.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using EpinelPS.Database;
|
||||
using EpinelPS.Utils;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid;
|
||||
|
||||
[PacketPath("/soloraid/trial/setdamage")]
|
||||
public class SetDamageTrial : LobbyMsgHandler
|
||||
{
|
||||
protected override async Task HandleAsync()
|
||||
{
|
||||
|
||||
var req = await ReadData<ReqSetSoloRaidTrialDamage>();
|
||||
User user = GetUser();
|
||||
|
||||
ResSetSoloRaidTrialDamage response = new();
|
||||
|
||||
try
|
||||
{
|
||||
SoloRaidHelper.SetDamageTrial(user, ref response, req);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.WriteLine($"SetDamageTrial Error: {ex.Message}", LogType.Error);
|
||||
}
|
||||
|
||||
JsonDb.Save();
|
||||
await WriteDataAsync(response);
|
||||
}
|
||||
}
|
||||
527
EpinelPS/LobbyServer/Soloraid/SoloRaidHelper.cs
Normal file
527
EpinelPS/LobbyServer/Soloraid/SoloRaidHelper.cs
Normal file
@@ -0,0 +1,527 @@
|
||||
using EpinelPS.Data;
|
||||
using EpinelPS.Database;
|
||||
using EpinelPS.Utils;
|
||||
using Google.Protobuf.Collections;
|
||||
using log4net;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace EpinelPS.LobbyServer.Soloraid
|
||||
{
|
||||
public class SoloRaidHelper
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(SoloRaidHelper));
|
||||
|
||||
/// <summary>
|
||||
/// Open a solo raid
|
||||
/// </summary>
|
||||
public static int OpenSoloRaid(User user, int raidId, int raidLevel, SoloRaidType type = SoloRaidType.Normal)
|
||||
{
|
||||
if (raidId == 0) raidId = GetRaidId();
|
||||
|
||||
// Check if the raid manager exists, if not, exit
|
||||
if (!GameData.Instance.SoloRaidManagerTable.TryGetValue(raidId, out var manager)) return 0;
|
||||
log.Debug($"Fond SoloRaidManager: RaidId: {raidId}, SoloRaidManager: {JsonConvert.SerializeObject(manager)}");
|
||||
|
||||
// Get the preset for the raid level
|
||||
var preset = GameData.Instance.SoloRaidPresetTable.Values.FirstOrDefault(r =>
|
||||
r.PresetGroupId == manager.MonsterPreset && r.WaveOrder == raidLevel);
|
||||
if (preset is null) return 0; // If the preset is null, exit
|
||||
log.Debug($"Fond SoloRaidPreset: PresetGroupId: {manager.MonsterPreset}, WaveOrder: {raidLevel}, SoloRaidPreset: {JsonConvert.SerializeObject(preset)}");
|
||||
|
||||
var statEnhanceId = GetStatEnhanceIdByWave(preset.Wave); // Get the stat enhance id for the wave
|
||||
if (statEnhanceId == 0) return 0; // If the stat enhance id is 0, exit
|
||||
|
||||
// Get the stat enhance data for the raid level
|
||||
var statEnhance = GameData.Instance.MonsterStatEnhanceTable.Values.Where(m => m.Lv == preset.MonsterStageLv && m.GroupId == statEnhanceId);
|
||||
log.Debug($"Fond MonsterStatEnhance: Lv: {preset.MonsterStageLv}, GroupId: {statEnhanceId}, MonsterStatEnhance: {JsonConvert.SerializeObject(statEnhance)}");
|
||||
|
||||
var levelHp = statEnhance.Sum(m => m.LevelHp); // Monster level hp = statEnhance.Sum(m => m.LevelHp)
|
||||
|
||||
var raid = GetSoloRaidData(user, raidId, isAdd: true);
|
||||
switch (type)
|
||||
{
|
||||
case SoloRaidType.Normal:
|
||||
raid.RaidOpenCount++; // If the raid is a normal raid, increment the raid open count
|
||||
break;
|
||||
case SoloRaidType.Trial:
|
||||
raid.TrialCount++; // If the raid is a trial raid, increment the trial count
|
||||
break;
|
||||
case SoloRaidType.Practice:
|
||||
break;
|
||||
default:
|
||||
Logging.Warn($"Unknown SoloRaidType: {type}");
|
||||
break;
|
||||
}
|
||||
|
||||
var level = GetSoloRaidLevelData(raid, raidLevel, type, isOpen: true);
|
||||
// Reset the level data
|
||||
if (level != null)
|
||||
{
|
||||
raid.SoloRaidLevels.Remove(level);
|
||||
}
|
||||
level = new SoloRaidLevelData
|
||||
{
|
||||
RaidLevel = raidLevel,
|
||||
Hp = levelHp,
|
||||
Type = type,
|
||||
Status = SoloRaidStatus.Alive,
|
||||
IsClear = false,
|
||||
IsOpen = true,
|
||||
};
|
||||
raid.SoloRaidLevels.Add(level);
|
||||
|
||||
user.SoloRaidData[raidId] = raid;
|
||||
return type == SoloRaidType.Trial ? raid.TrialCount : raid.RaidOpenCount;
|
||||
}
|
||||
|
||||
public static void CloseSoloRaid(User user, int raidId, int raidLevel, SoloRaidType type = SoloRaidType.Normal)
|
||||
{
|
||||
Logging.WriteLine($"CloseSoloRaid: raidId: {raidId}, raidLevel: {raidLevel}, type: {type}");
|
||||
if (raidId == 0) raidId = GetRaidId();
|
||||
|
||||
var raid = GetSoloRaidData(user, raidId, isAdd: false);
|
||||
// Reset the raid data
|
||||
if (type == SoloRaidType.Normal) raid.RaidOpenCount--; // If the raid is a normal raid, decrement the raid open count
|
||||
if (raid.RaidOpenCount < 0) raid.RaidOpenCount = 0; // If the raid open count is less than 0, set it to 0
|
||||
if (type == SoloRaidType.Trial) raid.TrialCount--;
|
||||
if (raid.TrialCount < 0) raid.TrialCount = 0;
|
||||
|
||||
var level = GetSoloRaidLevelData(raid, raidLevel, type, isOpen: true);
|
||||
if (level is not null) raid.SoloRaidLevels.Remove(level); // If the level is not null, remove it from the raid data
|
||||
if (type == SoloRaidType.Trial && level is not null)
|
||||
{
|
||||
// If the raid is a trial raid and the level is not null, check if the level is the highest damage level
|
||||
// If the current level's damage is higher than the previous level, update the status and remove the old level
|
||||
level.Status = SoloRaidStatus.Kill;
|
||||
level.IsClear = true;
|
||||
level.IsOpen = false;
|
||||
var oldLevel = GetSoloRaidLevelData(raid, raidLevel, SoloRaidType.Trial, isOpen: false);
|
||||
if (oldLevel is null)
|
||||
{
|
||||
raid.SoloRaidLevels.Add(level);
|
||||
}
|
||||
else if (level.TotalDamage > oldLevel.TotalDamage)
|
||||
{
|
||||
raid.SoloRaidLevels.Remove(oldLevel);
|
||||
raid.SoloRaidLevels.Add(level);
|
||||
}
|
||||
}
|
||||
user.SoloRaidData[raidId] = raid;
|
||||
JsonDb.Save();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user solo raid info
|
||||
/// </summary>
|
||||
public static NetUserSoloRaidInfo GetUserSoloRaidInfo(User user)
|
||||
{
|
||||
int SoloRaidManagerTid = GetRaidId();
|
||||
NetUserSoloRaidInfo info = new()
|
||||
{
|
||||
SoloRaidManagerTid = SoloRaidManagerTid,
|
||||
LastClearLevel = 0, // set the last clear level
|
||||
RaidOpenCount = 0, // set the raid open count
|
||||
Period = GetSoloRaidPeriod(),
|
||||
};
|
||||
|
||||
var raidData = GetSoloRaidData(user, SoloRaidManagerTid);
|
||||
if (raidData is null) return info;
|
||||
info.RaidOpenCount = raidData.RaidOpenCount;
|
||||
|
||||
int lastClearLevel = GetLastClearLevelId(user, SoloRaidManagerTid);
|
||||
info.LastClearLevel = lastClearLevel;
|
||||
|
||||
var openLevelData = raidData.SoloRaidLevels.Where(r => r.IsOpen).OrderBy(x => x.RaidLevel).FirstOrDefault();
|
||||
if (openLevelData is not null) info.LastOpenRaid = new NetSoloRaid { Level = openLevelData.RaidLevel, Type = openLevelData.Type };
|
||||
|
||||
var trialLevelData = GetSoloRaidLevelData(raidData, 8, SoloRaidType.Trial);
|
||||
if (trialLevelData is null) return info;
|
||||
|
||||
info.TrialCount = raidData.TrialCount;
|
||||
info.TrialDamage = trialLevelData.TotalDamage;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public static void SetDamage(User user, ref ResSetSoloRaidDamage response, ReqSetSoloRaidDamage req)
|
||||
{
|
||||
(int rewardId, int FirstRewardId, var levelData) =
|
||||
SetDamage(user, req.RaidLevel, req.Damage, req.AntiCheatBattleData.WaveId, req.AntiCheatBattleData.Characters);
|
||||
|
||||
if (rewardId > 0) response.Reward = RewardUtils.RegisterRewardsForUser(user, rewardId);
|
||||
if (FirstRewardId > 0) response.FirstClearReward = RewardUtils.RegisterRewardsForUser(user, FirstRewardId);
|
||||
|
||||
response.Info = new NetNormalSoloRaid
|
||||
{
|
||||
Level = req.RaidLevel,
|
||||
Hp = levelData.Hp - levelData.TotalDamage,
|
||||
};
|
||||
|
||||
response.RaidJoinCount = levelData.RaidJoinCount;
|
||||
response.Status = levelData.Status;
|
||||
response.PeriodResult = SoloRaidPeriodResult.Success;
|
||||
response.JoinData = GetJoinData(levelData);
|
||||
}
|
||||
|
||||
public static void SetDamagePractice(User user, ref ResSetSoloRaidPracticeDamage response, ReqSetSoloRaidPracticeDamage req)
|
||||
{
|
||||
(_, _, var levelData) =
|
||||
SetDamage(user, req.RaidLevel, req.Damage, req.AntiCheatBattleData.WaveId, req.AntiCheatBattleData.Characters, SoloRaidType.Practice);
|
||||
|
||||
response.Info = new NetPracticeSoloRaid
|
||||
{
|
||||
Level = req.RaidLevel,
|
||||
Hp = levelData.Hp - levelData.TotalDamage,
|
||||
};
|
||||
|
||||
response.RaidJoinCount = levelData.RaidJoinCount;
|
||||
response.Status = levelData.Status;
|
||||
response.PeriodResult = SoloRaidPeriodResult.Success;
|
||||
response.JoinData = GetJoinData(levelData);
|
||||
}
|
||||
|
||||
public static void SetDamageTrial(User user, ref ResSetSoloRaidTrialDamage response, ReqSetSoloRaidTrialDamage req)
|
||||
{
|
||||
(_, _, var levelData) =
|
||||
SetDamage(user, req.RaidLevel, req.Damage, req.AntiCheatBattleData.WaveId, req.AntiCheatBattleData.Characters, SoloRaidType.Trial);
|
||||
|
||||
response.Info = new NetTrialSoloRaid
|
||||
{
|
||||
Level = req.RaidLevel,
|
||||
Damage = levelData.TotalDamage,
|
||||
};
|
||||
|
||||
response.RaidJoinCount = levelData.RaidJoinCount;
|
||||
response.Status = levelData.Status;
|
||||
response.PeriodResult = SoloRaidPeriodResult.Success;
|
||||
response.JoinData = GetJoinData(levelData);
|
||||
}
|
||||
|
||||
public static void GetLevelInfo(User user, ref ResGetLevelSoloRaid response, int raidLevel)
|
||||
{
|
||||
int raidId = GetRaidId();
|
||||
|
||||
response.PeriodResult = SoloRaidPeriodResult.Success;
|
||||
var raidData = GetSoloRaidData(user, raidId, isAdd: false);
|
||||
var levelData = GetSoloRaidLevelData(raidData, raidLevel, SoloRaidType.Normal, true);
|
||||
if (levelData is null) return;
|
||||
|
||||
response.Raid = new NetNormalSoloRaid
|
||||
{
|
||||
Level = raidLevel,
|
||||
Hp = levelData.Hp - levelData.TotalDamage,
|
||||
};
|
||||
response.RaidJoinCount = levelData.RaidJoinCount;
|
||||
response.JoinData = GetJoinData(levelData);
|
||||
}
|
||||
|
||||
public static void GetLevelPracticeInfo(User user, ref ResGetLevelPracticeSoloRaid response, int raidLevel)
|
||||
{
|
||||
int raidId = GetRaidId();
|
||||
|
||||
response.PeriodResult = SoloRaidPeriodResult.Success;
|
||||
var raidData = GetSoloRaidData(user, raidId, isAdd: false);
|
||||
var levelData = GetSoloRaidLevelData(raidData, raidLevel, SoloRaidType.Practice, true);
|
||||
if (levelData is null) return;
|
||||
|
||||
response.Raid = new NetPracticeSoloRaid
|
||||
{
|
||||
Level = raidLevel,
|
||||
Hp = levelData.Hp - levelData.TotalDamage,
|
||||
};
|
||||
response.RaidJoinCount = levelData.RaidJoinCount;
|
||||
response.PeriodResult = SoloRaidPeriodResult.Success;
|
||||
response.JoinData = GetJoinData(levelData);
|
||||
}
|
||||
|
||||
public static void GetLevelTrialInfo(User user, ref ResGetLevelTrialSoloRaid response, int raidLevel)
|
||||
{
|
||||
int raidId = GetRaidId();
|
||||
|
||||
response.PeriodResult = SoloRaidPeriodResult.Success;
|
||||
var raidData = GetSoloRaidData(user, raidId, isAdd: false);
|
||||
var levelData = GetSoloRaidLevelData(raidData, raidLevel, SoloRaidType.Trial, true);
|
||||
if (levelData is null) return;
|
||||
|
||||
response.Raid = new NetTrialSoloRaid
|
||||
{
|
||||
Level = raidLevel,
|
||||
Damage = levelData.TotalDamage,
|
||||
};
|
||||
response.RaidJoinCount = levelData.RaidJoinCount;
|
||||
response.PeriodResult = SoloRaidPeriodResult.Success;
|
||||
response.JoinData = GetJoinData(levelData);
|
||||
}
|
||||
|
||||
public static void GetSoloRaidLog(User user, ref ResGetSoloRaidLogs response, int raidId, int raidLevel)
|
||||
{
|
||||
// ResGetSoloRaidLogs Fields:
|
||||
// RepeatedField<NetSoloRaidLog> Logs
|
||||
// SoloRaidBanResult BanResult
|
||||
// RepeatedField<NetSoloRaidLog> PracticeLogs
|
||||
// NetSoloRaidLog Fields:
|
||||
// long Damage
|
||||
// RepeatedField<NetSoloRaidTeamCharacter> Team
|
||||
// bool Kill
|
||||
// NetSoloRaidTeamCharacter Fields:
|
||||
// int Slot
|
||||
// int Tid
|
||||
// int Lv
|
||||
// int Combat
|
||||
// int CostumeId
|
||||
|
||||
if (raidId == 0) raidId = GetRaidId();
|
||||
var raidData = GetSoloRaidData(user, raidId);
|
||||
var levelData = GetSoloRaidLevelData(raidData, raidLevel, SoloRaidType.Normal);
|
||||
if (levelData is not null && levelData.Logs.Count > 0)
|
||||
{
|
||||
response.Logs.AddRange(levelData.Logs.Select(x => x.ToNet()));
|
||||
}
|
||||
levelData = GetSoloRaidLevelData(raidData, raidLevel, SoloRaidType.Normal, true);
|
||||
if (levelData is not null && levelData.Logs.Count > 0)
|
||||
{
|
||||
response.Logs.AddRange(levelData.Logs.Select(x => x.ToNet()));
|
||||
}
|
||||
|
||||
var practiceLevelData = GetSoloRaidLevelData(raidData, raidLevel, type: SoloRaidType.Practice);
|
||||
if (practiceLevelData is not null && practiceLevelData.Logs.Count > 0)
|
||||
{
|
||||
response.PracticeLogs.AddRange(practiceLevelData.Logs.Select(x => x.ToNet()));
|
||||
}
|
||||
practiceLevelData = GetSoloRaidLevelData(raidData, raidLevel, type: SoloRaidType.Practice, true);
|
||||
if (practiceLevelData is not null && practiceLevelData.Logs.Count > 0)
|
||||
{
|
||||
response.PracticeLogs.AddRange(practiceLevelData.Logs.Select(x => x.ToNet()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetSoloRaidRanking(User user, ref ResGetSoloRaidRanking response)
|
||||
{
|
||||
// ResGetSoloRaidRanking Fields:
|
||||
// RepeatedField<NetSoloRaidRankingData> Rankings
|
||||
// NetSoloRaidRankingData User
|
||||
// long TotalUserCount
|
||||
// SoloRaidBanResult BanResult
|
||||
// NetSoloRaidRankingData Fields:
|
||||
// long Ranking
|
||||
// long Damage
|
||||
// NetWholeUserData User
|
||||
// long ReportBattleId
|
||||
// Google.Protobuf.WellKnownTypes.Timestamp ReportBattleDate
|
||||
//
|
||||
}
|
||||
public static void FastBattle(User user, ref ResFastBattleSoloRaid response, int raidId, int raidLevel, int clearCount)
|
||||
{
|
||||
var raidData = GetSoloRaidData(user, raidId, isAdd: true);
|
||||
raidData.RaidOpenCount += clearCount;
|
||||
user.SoloRaidData[raidId] = raidData;
|
||||
response.PeriodResult = SoloRaidPeriodResult.Success;
|
||||
if (GameData.Instance.SoloRaidManagerTable.TryGetValue(raidId, out var manager))
|
||||
{
|
||||
var presetData = GameData.Instance.SoloRaidPresetTable.Values.FirstOrDefault(r =>
|
||||
r.PresetGroupId == manager.MonsterPreset && r.WaveOrder == raidLevel);
|
||||
if (presetData is not null)
|
||||
{
|
||||
NetRewardData reward = new();
|
||||
for (int i = 0; i < clearCount; i++)
|
||||
{
|
||||
var newReward = RewardUtils.RegisterRewardsForUser(user, presetData.RewardId);
|
||||
reward.MergeFrom(newReward);
|
||||
}
|
||||
response.Reward = reward;
|
||||
}
|
||||
}
|
||||
response.RaidOpenCount = raidData.RaidOpenCount;
|
||||
|
||||
JsonDb.Save();
|
||||
}
|
||||
|
||||
|
||||
public static (int rewardId, int FirstRewardId, SoloRaidLevelData levelData)
|
||||
SetDamage(User user, int raidLevel, long damage, int waveId,
|
||||
RepeatedField<NetAntiCheatCharacter> characters, SoloRaidType type = SoloRaidType.Normal)
|
||||
{
|
||||
int rewardId = 0;
|
||||
int FirstRewardId = 0;
|
||||
int raidId = GetRaidId();
|
||||
|
||||
var raidData = GetSoloRaidData(user, raidId, isAdd: true);
|
||||
var levelData = GetSoloRaidLevelData(raidData, raidLevel, type, isOpen: true);
|
||||
var oldLevel = GetSoloRaidLevelData(raidData, raidLevel, type, isOpen: false);
|
||||
|
||||
// Remove existing level data
|
||||
if (levelData is not null)
|
||||
raidData.SoloRaidLevels.Remove(levelData);
|
||||
else
|
||||
levelData = new SoloRaidLevelData() { RaidLevel = raidLevel, Type = type, IsOpen = true };
|
||||
|
||||
levelData.TotalDamage += damage;
|
||||
levelData.RaidJoinCount++;
|
||||
|
||||
if (type == SoloRaidType.Trial || raidLevel == 8)
|
||||
{
|
||||
if (levelData.RaidJoinCount == 5)
|
||||
{
|
||||
levelData.Status = SoloRaidStatus.Kill;
|
||||
levelData.IsClear = true;
|
||||
levelData.IsOpen = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
levelData.Status = SoloRaidStatus.Alive;
|
||||
}
|
||||
}
|
||||
else if (levelData.TotalDamage >= levelData.Hp)
|
||||
{
|
||||
levelData.TotalDamage = levelData.Hp;
|
||||
levelData.Status = SoloRaidStatus.Kill;
|
||||
if (type == SoloRaidType.Normal)
|
||||
{
|
||||
var presetData = GameData.Instance.SoloRaidPresetTable.Values.FirstOrDefault(r =>
|
||||
r.Wave == waveId && r.WaveOrder == raidLevel);
|
||||
if (presetData is not null)
|
||||
{
|
||||
bool isFirstClear = oldLevel is null;
|
||||
rewardId = presetData.RewardId;
|
||||
FirstRewardId = !isFirstClear ? 0 : presetData.FirstClearRewardId;
|
||||
}
|
||||
}
|
||||
|
||||
levelData.IsClear = true;
|
||||
levelData.IsOpen = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
levelData.Status = SoloRaidStatus.Alive;
|
||||
}
|
||||
|
||||
SoloRaidLogData logData = new()
|
||||
{
|
||||
Damage = damage,
|
||||
Kill = levelData.Status == SoloRaidStatus.Kill,
|
||||
};
|
||||
|
||||
foreach (var item in characters)
|
||||
{
|
||||
int costumeId = user.Characters.FirstOrDefault(c => c.Tid == item.Tid)?.CostumeId ?? 0;
|
||||
logData.Team.Add(new TeamCharacterData
|
||||
{
|
||||
Slot = item.Slot,
|
||||
Tid = item.Tid,
|
||||
Csn = item.Csn,
|
||||
Lv = item.CharacterSpec.Level,
|
||||
Combat = (int)item.CharacterSpec.Combat,
|
||||
CostumeId = costumeId,
|
||||
});
|
||||
}
|
||||
|
||||
levelData.Logs.Add(logData);
|
||||
|
||||
// If the level is not open, remove the old level data
|
||||
if (!levelData.IsOpen && oldLevel is not null)
|
||||
{
|
||||
raidData.SoloRaidLevels.Remove(oldLevel);
|
||||
}
|
||||
// If the level is not open and join count is 5, do not add to levels
|
||||
if (!(levelData.RaidJoinCount == 5 && levelData.IsOpen))
|
||||
{
|
||||
raidData.SoloRaidLevels.Add(levelData);
|
||||
}
|
||||
user.SoloRaidData[raidId] = raidData;
|
||||
|
||||
return (rewardId, FirstRewardId, levelData);
|
||||
}
|
||||
|
||||
public static NetSoloRaidJoinData GetJoinData(SoloRaidLevelData? levelData)
|
||||
{
|
||||
var joinData = new NetSoloRaidJoinData();
|
||||
if (levelData is null || levelData.Logs.Count <= 0) return joinData;
|
||||
foreach (var item in levelData.Logs)
|
||||
{
|
||||
joinData.CsnList.AddRange(item.Team.Select(l => l.Csn));
|
||||
}
|
||||
|
||||
return joinData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the solo raid data for the user
|
||||
/// </summary>
|
||||
public static SoloRaidInfo? GetSoloRaidData(User user, int raidId, bool isAdd = false)
|
||||
{
|
||||
// Get the solo raid data for the raidId, if not found, isAdd is true, create a new one
|
||||
if (!user.SoloRaidData.TryGetValue(raidId, out var raidData))
|
||||
{
|
||||
raidData = new() { RaidId = raidId, LastDateDay = user.GetDateDay() };
|
||||
if (isAdd) user.SoloRaidData.TryAdd(raidId, raidData);
|
||||
return isAdd ? raidData : null;
|
||||
}
|
||||
|
||||
ResetOpenCount(user, ref raidData);
|
||||
return raidData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last clear level id
|
||||
/// </summary>
|
||||
public static int GetLastClearLevelId(User user, int raidId)
|
||||
{
|
||||
var raidData = GetSoloRaidData(user, raidId, isAdd: false);
|
||||
if (raidData is null || !raidData.SoloRaidLevels.Where(r => r.IsClear && r.Type == SoloRaidType.Normal).Any()) return 0;
|
||||
return raidData.SoloRaidLevels.Where(r => r.IsClear && r.Type == SoloRaidType.Normal).Max(r => r.RaidLevel);
|
||||
}
|
||||
|
||||
public static SoloRaidLevelData? GetSoloRaidLevelData(SoloRaidInfo raidData, int raidLevel, SoloRaidType type, bool isOpen = false)
|
||||
{
|
||||
return raidData.SoloRaidLevels.FirstOrDefault(r => r.RaidLevel == raidLevel && r.Type == type && r.IsOpen == isOpen);
|
||||
}
|
||||
|
||||
public static void ResetOpenCount(User user, ref SoloRaidInfo? raidData)
|
||||
{
|
||||
if (raidData is null) return;
|
||||
int newDateDay = user.GetDateDay();
|
||||
if (newDateDay <= raidData.LastDateDay) return;
|
||||
Logging.WriteLine($"Reset OpenCount: LastDateDay: {raidData.LastDateDay}, NewDateDay: {newDateDay}, Old: {raidData.RaidOpenCount}, New: 0 ", LogType.Warning);
|
||||
raidData.LastDateDay = newDateDay;
|
||||
raidData.RaidOpenCount = 0;
|
||||
raidData.TrialCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the solo raid period data
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static NetSoloRaidPeriodData GetSoloRaidPeriod()
|
||||
{
|
||||
DateTime utcNow = DateTime.UtcNow.Date;
|
||||
return new NetSoloRaidPeriodData
|
||||
{
|
||||
VisibleDate = utcNow.AddDays(-10).Ticks,
|
||||
StartDate = utcNow.AddDays(-5).Ticks,
|
||||
EndDate = utcNow.AddDays(5).Ticks,
|
||||
DisableDate = utcNow.AddDays(10).Ticks,
|
||||
SettleDate = utcNow.AddDays(15).Ticks,
|
||||
};
|
||||
}
|
||||
|
||||
private static int GetStatEnhanceIdByWave(int wave)
|
||||
{
|
||||
// Get the intercept data for the wave, if not found, return 0
|
||||
if (!GameData.Instance.WaveIntercept001Table.TryGetValue(wave, out var intercept)) return 0;
|
||||
log.Debug($"Fond WaveIntercept001: Wave: {wave}, WaveIntercept: {JsonConvert.SerializeObject(intercept)}");
|
||||
if (intercept.TargetList!.Count == 0) return 0;
|
||||
|
||||
var monsterId = intercept.TargetList[0]; // monsterId is the first element of the TargetList
|
||||
// Get the monster data for the monsterId, if not found, return 0
|
||||
if (!GameData.Instance.MonsterTable.TryGetValue(monsterId, out var monster)) return 0;
|
||||
monster.SkillData = [];
|
||||
log.Debug($"Fond Monster: MonsterId: {monsterId}, Monster: {JsonConvert.SerializeObject(monster)}");
|
||||
return monster.StatenhanceId;
|
||||
}
|
||||
|
||||
public static int GetRaidId()
|
||||
{
|
||||
return GameData.Instance.SoloRaidManagerTable.Keys.Max();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,4 +440,63 @@ namespace EpinelPS.Models
|
||||
public int CutSceneId { get; set; }
|
||||
public bool IsNew { get; set; }
|
||||
}
|
||||
|
||||
// Solo Raid Data
|
||||
public class SoloRaidInfo
|
||||
{
|
||||
public int RaidId { get; set; }
|
||||
public int RaidOpenCount { get; set; }
|
||||
public int TrialCount { get; set; }
|
||||
public int LastDateDay { get; set; }
|
||||
public List<SoloRaidLevelData> SoloRaidLevels { get; set; } = []; // key: raidLevel
|
||||
}
|
||||
public class SoloRaidLevelData
|
||||
{
|
||||
public int RaidLevel { get; set; }
|
||||
public int RaidJoinCount { get; set; }
|
||||
public long Hp { get; set; }
|
||||
public long TotalDamage { get; set; }
|
||||
public bool IsClear { get; set; }
|
||||
public SoloRaidStatus Status { get; set; }
|
||||
public SoloRaidType Type { get; set; }
|
||||
public bool IsOpen { get; set; }
|
||||
public List<SoloRaidLogData> Logs { get; set; } = [];
|
||||
}
|
||||
public class SoloRaidLogData
|
||||
{
|
||||
public long Damage { get; set; }
|
||||
public bool Kill { get; set; }
|
||||
public List<TeamCharacterData> Team { get; set; } = [];
|
||||
|
||||
public NetSoloRaidLog ToNet()
|
||||
{
|
||||
return new NetSoloRaidLog()
|
||||
{
|
||||
Damage = Damage,
|
||||
Kill = Kill,
|
||||
Team = { Team.Select(x => x.ToNet()).ToList() },
|
||||
};
|
||||
}
|
||||
}
|
||||
public class TeamCharacterData
|
||||
{
|
||||
public int Slot { get; set; }
|
||||
public long Csn { get; set; }
|
||||
public int Tid { get; set; }
|
||||
public int Lv { get; set; }
|
||||
public int Combat { get; set; }
|
||||
public int CostumeId { get; set; }
|
||||
|
||||
public NetSoloRaidTeamCharacter ToNet()
|
||||
{
|
||||
return new NetSoloRaidTeamCharacter()
|
||||
{
|
||||
Slot = Slot,
|
||||
Tid = Tid,
|
||||
Lv = Lv,
|
||||
Combat = Combat,
|
||||
CostumeId = CostumeId,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,6 +126,8 @@ public class User
|
||||
|
||||
public List<int> LobbyPrivateBannerIds = [];
|
||||
public Dictionary<int, MiniGameAzxData> MiniGameAzxInfo = [];
|
||||
// solo raid data
|
||||
public Dictionary<int, SoloRaidInfo> SoloRaidData = []; // key: raidId
|
||||
|
||||
public TriggerModel AddTrigger(Trigger type, int value, int conditionId = 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user