diff --git a/Arrowgene.Ddon.Database/IDatabase.cs b/Arrowgene.Ddon.Database/IDatabase.cs index 52ac6c19a..a95b648e3 100644 --- a/Arrowgene.Ddon.Database/IDatabase.cs +++ b/Arrowgene.Ddon.Database/IDatabase.cs @@ -254,11 +254,9 @@ Ability ability bool DeleteCommunicationShortcut(uint characterId, uint pageNo, uint buttonNo); // GameToken - bool SetToken(GameToken token); - GameToken SelectTokenByAccountId(int accountId); - GameToken SelectToken(string tokenStr); - bool DeleteTokenByAccountId(int accountId); - bool DeleteToken(string token); + bool ReplaceToken(GameToken token, DbConnection? connectionIn = null); + GameToken SelectToken(string tokenStr, DbConnection? connectionIn = null); + bool DeleteTokenByAccountId(int accountId, DbConnection? connectionIn = null); // Connections bool InsertConnection(Connection connection); diff --git a/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbGameToken.cs b/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbGameToken.cs index 0b515ea91..8db9612d3 100644 --- a/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbGameToken.cs +++ b/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbGameToken.cs @@ -1,85 +1,57 @@ -using Arrowgene.Ddon.Shared.Model; +using System.Data.Common; +using System.Linq; +using Arrowgene.Ddon.Shared.Model; namespace Arrowgene.Ddon.Database.Sql.Core; public partial class DdonSqlDb : SqlDb { - private const string SqlInsertToken = - "INSERT INTO \"ddon_game_token\" (\"account_id\", \"character_id\", \"token\", \"created\") VALUES (@account_id, @character_id, @token, @created);"; - - private const string SqlUpdateToken = - "UPDATE \"ddon_game_token\" SET \"character_id\"=@character_id, \"token\"=@token, \"created\"=@created WHERE \"account_id\" = @account_id;"; - - private const string SqlSelectTokenByAccountId = - "SELECT \"token\", \"account_id\", \"character_id\", \"token\", \"created\" FROM \"ddon_game_token\" WHERE \"account_id\" = @account_id;"; - + private static readonly string[] GameTokenFields = ["account_id", "character_id", "token", "created"]; + private static readonly string[] GameTokenKeyFields = ["account_id"]; + private static readonly string[] GameTokenNonKeyFields = GameTokenFields.Except(GameTokenKeyFields).ToArray(); + private static readonly string SqlSelectToken = $"SELECT {BuildQueryField(GameTokenFields)} FROM \"ddon_game_token\" WHERE \"token\" = @token;"; + private static readonly string SqlInsertToken = $"INSERT INTO \"ddon_game_token\" ({BuildQueryField(GameTokenFields)}) VALUES ({BuildQueryInsert(GameTokenFields)});"; + private static readonly string SqlUpdateToken = $"UPDATE \"ddon_game_token\" SET {BuildQueryUpdate(GameTokenFields)} WHERE \"account_id\" = @account_id;"; private const string SqlDeleteTokenByAccountId = "DELETE FROM \"ddon_game_token\" WHERE \"account_id\"=@account_id;"; - private const string SqlSelectToken = "SELECT \"token\", \"account_id\", \"character_id\", \"token\", \"created\" FROM \"ddon_game_token\" WHERE \"token\" = @token;"; private const string SqlDeleteToken = "DELETE FROM \"ddon_game_token\" WHERE \"token\"=@token;"; + private readonly string SqlUpsertToken = + $""" + INSERT INTO "ddon_game_token" ({BuildQueryField(GameTokenFields)}) VALUES ({BuildQueryInsert(GameTokenFields)}) + ON CONFLICT ("account_id") DO UPDATE SET {BuildQueryUpdateWithPrefix("EXCLUDED.", GameTokenNonKeyFields)}; + """; - public override bool SetToken(GameToken token) + public override bool ReplaceToken(GameToken token, DbConnection? connectionIn = null) { - int rowsAffected = ExecuteNonQuery(SqlUpdateToken, command => - { - AddParameter(command, "@account_id", token.AccountId); - AddParameter(command, "@character_id", token.CharacterId); - AddParameter(command, "@token", token.Token); - AddParameter(command, "@created", token.Created); - }); - if (rowsAffected > NoRowsAffected) return true; - - rowsAffected = ExecuteNonQuery(SqlInsertToken, command => - { - AddParameter(command, "@account_id", token.AccountId); - AddParameter(command, "@character_id", token.CharacterId); - AddParameter(command, "@token", token.Token); - AddParameter(command, "@created", token.Created); - }); - - return rowsAffected > NoRowsAffected; - } - - public override GameToken SelectTokenByAccountId(int accountId) - { - GameToken token = null; - ExecuteReader(SqlSelectTokenByAccountId, command => { AddParameter(command, "@account_id", accountId); }, reader => - { - if (reader.Read()) + return ExecuteQuerySafe(connectionIn, + connection => { return ExecuteNonQuery(connection, SqlUpsertToken, command => { - token = new GameToken(); - token.AccountId = GetInt32(reader, "account_id"); - token.CharacterId = GetUInt32(reader, "character_id"); - token.Token = GetString(reader, "token"); - token.Created = GetDateTime(reader, "created"); - } - }); - return token; + AddParameter(command, "@account_id", token.AccountId); + AddParameter(command, "@character_id", token.CharacterId); + AddParameter(command, "@token", token.Token); + AddParameter(command, "@created", token.Created); + }) == 1; }); } - public override GameToken SelectToken(string tokenStr) + public override GameToken SelectToken(string tokenStr, DbConnection? connectionIn = null) { GameToken token = null; ExecuteReader(SqlSelectToken, command => { AddParameter(command, "@token", tokenStr); }, reader => { if (reader.Read()) { - token = new GameToken(); - token.AccountId = GetInt32(reader, "account_id"); - token.CharacterId = GetUInt32(reader, "character_id"); - token.Token = GetString(reader, "token"); - token.Created = GetDateTime(reader, "created"); + token = new GameToken + { + AccountId = GetInt32(reader, "account_id"), + CharacterId = GetUInt32(reader, "character_id"), + Token = GetString(reader, "token"), + Created = GetDateTime(reader, "created") + }; } }); return token; } - public override bool DeleteToken(string token) - { - int rowsAffected = ExecuteNonQuery(SqlDeleteToken, command => { AddParameter(command, "@token", token); }); - return rowsAffected > NoRowsAffected; - } - - public override bool DeleteTokenByAccountId(int accountId) + public override bool DeleteTokenByAccountId(int accountId, DbConnection? connectionIn = null) { int rowsAffected = ExecuteNonQuery(SqlDeleteTokenByAccountId, command => { AddParameter(command, "@account_id", accountId); }); return rowsAffected > NoRowsAffected; diff --git a/Arrowgene.Ddon.Database/Sql/SqlDb.cs b/Arrowgene.Ddon.Database/Sql/SqlDb.cs index fd41d9cb7..f8369d5e8 100644 --- a/Arrowgene.Ddon.Database/Sql/SqlDb.cs +++ b/Arrowgene.Ddon.Database/Sql/SqlDb.cs @@ -410,11 +410,9 @@ public bool MigrateDatabase(DatabaseMigrator migrator, uint toVersion) public abstract bool ReplaceCommunicationShortcut(uint characterId, CDataCommunicationShortCut communicationShortcut, DbConnection? connectionIn = null); public abstract bool UpdateCommunicationShortcut(uint characterId, uint oldPageNo, uint oldButtonNo, CDataCommunicationShortCut updatedCommunicationShortcut, DbConnection? connectionIn = null); public abstract bool DeleteCommunicationShortcut(uint characterId, uint pageNo, uint buttonNo); - public abstract bool SetToken(GameToken token); - public abstract GameToken SelectTokenByAccountId(int accountId); - public abstract GameToken SelectToken(string tokenStr); - public abstract bool DeleteTokenByAccountId(int accountId); - public abstract bool DeleteToken(string token); + public abstract bool ReplaceToken(GameToken token, DbConnection? connectionIn = null); + public abstract GameToken SelectToken(string tokenStr, DbConnection? connectionIn = null); + public abstract bool DeleteTokenByAccountId(int accountId, DbConnection? connectionIn = null); public abstract bool InsertConnection(Connection connection); public abstract List SelectConnections(); public abstract List SelectConnectionsByAccountId(int accountId); diff --git a/Arrowgene.Ddon.GameServer/Characters/CharacterManager.cs b/Arrowgene.Ddon.GameServer/Characters/CharacterManager.cs index ff991b33e..af389c31d 100644 --- a/Arrowgene.Ddon.GameServer/Characters/CharacterManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/CharacterManager.cs @@ -319,7 +319,7 @@ private Dictionary> CalculateAcquirableSkills(Chara return acquirableSkills; } - private void SelectPawns(Character character, DbConnection? connectionIn = null) + public void SelectPawns(Character character, DbConnection? connectionIn = null) { character.Pawns = Server.Database.SelectPawnsByCharacterId(character.ContentCharacterId, connectionIn); diff --git a/Arrowgene.Ddon.GameServer/DdonGameServer.cs b/Arrowgene.Ddon.GameServer/DdonGameServer.cs index c97032feb..e9f9d9165 100644 --- a/Arrowgene.Ddon.GameServer/DdonGameServer.cs +++ b/Arrowgene.Ddon.GameServer/DdonGameServer.cs @@ -237,6 +237,9 @@ private void LoadPacketHandler() AddHandler(new BattleContentInfoListHandler(this)); AddHandler(new BattleContentGetContentStatusFromOmHandler(this)); + AddHandler(new BattleContentGetPhaseToChangeFromOmHandler(this)); + AddHandler(new BattleContentPhaseEntryBeginRecruitmentHandler(this)); + AddHandler(new BattleContentPhaseEntryReadyCancelHandler(this)); AddHandler(new BattleContentContentEntryHandler(this)); AddHandler(new BattleContentInstantClearInfoHandler(this)); AddHandler(new BattleContentPartyMemberInfoHandler(this)); diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentCharacterInfoHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentCharacterInfoHandler.cs index 5f204d306..13dbeae00 100644 --- a/Arrowgene.Ddon.GameServer/Handler/BattleContentCharacterInfoHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentCharacterInfoHandler.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Arrowgene.Ddon.GameServer.Dump; using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Shared.Entity; @@ -19,22 +20,61 @@ public BattleContentCharacterInfoHandler(DdonGameServer server) : base(server) public override S2CBattleContentCharacterInfoRes Handle(GameClient client, C2SBattleContentCharacterInfoReq request) { - S2CBattleContentInfoListRes pcap = EntitySerializer.Get().Read(InGameDump.Dump_93.AsBuffer()); - pcap.BattleContentStatusList[0].BattleContentSituationData.StartTime = 4875391515; - pcap.BattleContentStatusList[0].BattleContentSituationData.ContentId = 2; - pcap.BattleContentStatusList[0].BattleContentSituationData.Unk8 = 0; - pcap.BattleContentStatusList[0].BattleContentSituationData.Unk11 = 0; - pcap.BattleContentStatusList[0].BattleContentSituationData.RewardReceived = true; - pcap.BattleContentStatusList[0].BattleContentSituationData.RewardBonus = BattleContentRewardBonus.Normal; - - pcap.BattleContentStatusList[0].BattleContentSituationData.Unk3 = true; - pcap.BattleContentStatusList[0].BattleContentSituationData.ReportReset = 1; - pcap.BattleContentStatusList[0].BattleContentSituationData.ReportSearchResults = 0; var result = new S2CBattleContentCharacterInfoRes() { - SituationData = pcap.BattleContentStatusList[0].BattleContentSituationData, - Unk2List = pcap.BattleContentStatusList[0].BattleContentAvailableRewardsList + SituationData = new CDataBattleContentSituationData + { + GameMode = GameMode.BitterblackMaze, + StartTime = 1, + RewardReceived = false, + Unk3 = false, + RewardBonus = BattleContentRewardBonus.Normal, + ReportReset = 0, + ReportSearchResults = 0, + Unk7 = 2, + Unk8 = 2, + Unktime = 0, + ContentId = 2, + Unk11 = 2 + }, + AvailableRewardsList = [ + new CDataBattleContentAvailableRewards + { + Id = 10, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 2, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 11, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 3, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 12, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 4, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 13, + Amount = 1 + } + ] }; return result; diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentContentEntryHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentContentEntryHandler.cs index c760d7414..34057f75d 100644 --- a/Arrowgene.Ddon.GameServer/Handler/BattleContentContentEntryHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentContentEntryHandler.cs @@ -31,17 +31,24 @@ public override S2CBattleContentContentEntryRes Handle(GameClient client, C2SBat Server.Database.UpdateBBMProgress(client.Character.CharacterId, progress); } - var contentStatus = BitterblackMazeManager.GetUpdatedContentStatus(Server, client.Character); - S2CBattleContentContentEntryNtc ntc = new S2CBattleContentContentEntryNtc() + // var contentStatus = BitterblackMazeManager.GetUpdatedContentStatus(Server, client.Character); + // S2CBattleContentContentEntryNtc ntc = new S2CBattleContentContentEntryNtc() + // { + // GameMode = GameMode.BitterblackMaze, + // }; + // ntc.BattleContentStatusList.Add(contentStatus); + // client.Send(ntc); + // + // S2CBattleContentProgressNtc ntc2 = new S2CBattleContentProgressNtc(); + // ntc2.BattleContentStatusList.Add(contentStatus); + // client.Send(ntc2); + + S2CBattleContentPhaseEntryReadyNtc phaseEntryReadyNtc = new() { - GameMode = GameMode.BitterblackMaze, + Unk0 = 2, + Unk1 = 0 }; - ntc.BattleContentStatusList.Add(contentStatus); - client.Send(ntc); - - S2CBattleContentProgressNtc ntc2 = new S2CBattleContentProgressNtc(); - ntc2.BattleContentStatusList.Add(contentStatus); - client.Send(ntc2); + client.Send(phaseEntryReadyNtc); return new S2CBattleContentContentEntryRes(); } diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentGetContentStatusFromOmHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentGetContentStatusFromOmHandler.cs index b0502f19d..752a94a04 100644 --- a/Arrowgene.Ddon.GameServer/Handler/BattleContentGetContentStatusFromOmHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentGetContentStatusFromOmHandler.cs @@ -1,14 +1,10 @@ +using System; +using System.Linq; using Arrowgene.Ddon.GameServer.Characters; using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Shared.Entity.PacketStructure; using Arrowgene.Ddon.Shared.Model; -using Arrowgene.Ddon.Shared.Model.BattleContent; using Arrowgene.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Mime; -using YamlDotNet.Core.Tokens; namespace Arrowgene.Ddon.GameServer.Handler { @@ -60,10 +56,10 @@ public override S2CBattleContentGetContentStatusFromOmRes Handle(GameClient clie return new S2CBattleContentGetContentStatusFromOmRes() { GameMode = GameMode.BitterblackMaze, - NotifyJobLock = contentInProgress ? 1U : 0U, - Unk2 = 2, - Unk3 = 3, - Unk4 = 4, + NotifyJobLock = 0, //contentInProgress ? 1U : 0U, + Unk2 = 0, + RouteIsNotInProgress = 1, // "Cannot enter because another route is in progress": 0 = display, 1 = skip for regular, + Unk4 = 0 }; // 0, 0, 0, 0 says can't do content diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentGetPhaseToChangeFromOmHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentGetPhaseToChangeFromOmHandler.cs new file mode 100644 index 000000000..ff601e862 --- /dev/null +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentGetPhaseToChangeFromOmHandler.cs @@ -0,0 +1,32 @@ +using Arrowgene.Ddon.Server; +using Arrowgene.Ddon.Shared.Entity.PacketStructure; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Model; +using Arrowgene.Logging; + +namespace Arrowgene.Ddon.GameServer.Handler +{ + public class BattleContentGetPhaseToChangeFromOmHandler : GameRequestPacketHandler + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(BattleContentGetPhaseToChangeFromOmHandler)); + + public BattleContentGetPhaseToChangeFromOmHandler(DdonGameServer server) : base(server) + { + } + + public override S2CBattleContentGetPhaseToChangeFromOmRes Handle(GameClient client, C2SBattleContentGetPhaseToChangeFromOmReq request) + { + S2CBattleContentGetPhaseToChangeFromOmRes res = new() + { + BattleContentStage = new CDataBattleContentStage + { + Id = 2, + StageName = "Bitterblack Maze Rotunda: Netherworld 1", + Mode = BattleContentMode.Rotunda + } + }; + + return res; + } + } +} diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentInstantClearInfoHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentInstantClearInfoHandler.cs index a1aa5ef42..6b2fe03fe 100644 --- a/Arrowgene.Ddon.GameServer/Handler/BattleContentInstantClearInfoHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentInstantClearInfoHandler.cs @@ -1,11 +1,8 @@ using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Shared.Entity.PacketStructure; -using Arrowgene.Logging; using Arrowgene.Ddon.Shared.Entity.Structure; -using System.Collections.Generic; -using Arrowgene.Ddon.GameServer.Dump; -using Arrowgene.Ddon.Shared.Entity; using Arrowgene.Ddon.Shared.Model; +using Arrowgene.Logging; namespace Arrowgene.Ddon.GameServer.Handler { @@ -19,10 +16,36 @@ public BattleContentInstantClearInfoHandler(DdonGameServer server) : base(server public override S2CBattleContentInstantClearInfoRes Handle(GameClient client, C2SBattleContentInstantClearInfoReq request) { - // Not sure what this does, can't seem to make anything show up - // I think it must be related to the ready up select menu, but not sure - var result = new S2CBattleContentInstantClearInfoRes(); - return result; + S2CBattleContentInstantClearInfoRes res = new S2CBattleContentInstantClearInfoRes + { + Unk0 = + [ + new CDataBattleContentUnk4 + { + Unk0 = 2, + Unk1 = 0, + UnknownString = "Bitterblack Maze Rotunda: Netherworld 1", + WalletPoints = + [ + new CDataWalletPoint + { + Type = WalletType.Gold, + Value = 123 + } + ], + Unk3 = + [ + new CDataBattleContentUnk5 + { + Unk0 = 2, + Unk1 = 2 + } + ] + } + ] + }; + + return res; } } } diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentPartyMemberInfoHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentPartyMemberInfoHandler.cs index cd69bff3f..aac90530a 100644 --- a/Arrowgene.Ddon.GameServer/Handler/BattleContentPartyMemberInfoHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentPartyMemberInfoHandler.cs @@ -45,17 +45,74 @@ public override S2CBattleContentPartyMemberInfoRes Handle(GameClient client, C2S throw new ResponseErrorException(ErrorCode.ERROR_CODE_MATCHING_PLAY_ENTRY_IS_NOT_READY, $"Leader didn't enter yet"); } - // This NTC will force the player into the dungeon and skip the board - S2CBattleContentAreaChangeNtc ntc = new S2CBattleContentAreaChangeNtc() + S2CBattleContentPartyMemberInfoRes res = new() { - // Unk0 = 2, // client.Character.NormalCharacterId, - StageId = leader.NextBBMStageId, - StartPos = 0, - Unk4 = true, + Unk0 = + [ + new CDataBattleContentUnk6 + { + Unk0 = 2, + CurrentContentId = 0, + BattleContentSituationData = new CDataBattleContentSituationData + { + GameMode = GameMode.BitterblackMaze, + StartTime = 1, + RewardReceived = false, + Unk3 = false, + RewardBonus = BattleContentRewardBonus.Normal, + ReportReset = 0, + ReportSearchResults = 0, + Unk7 = 0, + Unk8 = 0, + Unktime = 0, + ContentId = 2, + Unk11 = 0 + }, + BattleContentAvailableRewardsList = + [ + new CDataBattleContentAvailableRewards + { + Id = 10, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 2, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 11, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 3, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 12, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 4, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 13, + Amount = 1 + }, + ], + Unk4 = true + } + ], + Unk1 = true }; - client.Send(ntc); - return new S2CBattleContentPartyMemberInfoRes(); + return res; } } } diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentPartyMemberInfoUpdateHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentPartyMemberInfoUpdateHandler.cs index 7daac717e..00678ba7f 100644 --- a/Arrowgene.Ddon.GameServer/Handler/BattleContentPartyMemberInfoUpdateHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentPartyMemberInfoUpdateHandler.cs @@ -1,11 +1,9 @@ -using Arrowgene.Ddon.GameServer.Dump; -using Arrowgene.Ddon.GameServer.Party; using Arrowgene.Ddon.Server; -using Arrowgene.Ddon.Shared.Entity; using Arrowgene.Ddon.Shared.Entity.PacketStructure; using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Model; +using Arrowgene.Ddon.Shared.Model.BattleContent; using Arrowgene.Logging; -using System.Collections.Generic; namespace Arrowgene.Ddon.GameServer.Handler { @@ -19,20 +17,63 @@ public BattleContentPartyMemberInfoUpdateHandler(DdonGameServer server) : base(s public override S2CBattleContentPartyMemberInfoUpdateRes Handle(GameClient client, C2SBattleContentPartyMemberInfoUpdateReq request) { - EntitySerializer serializer = EntitySerializer.Get(); - S2CBattleContentInfoListRes pcap = serializer.Read(InGameDump.Dump_93.AsBuffer()); - - S2CBattleContentPartyMemberInfoUpdateNtc ntc = new S2CBattleContentPartyMemberInfoUpdateNtc() { CharacterId = client.Character.CharacterId, - Pos = 0, - BattleContentSituationData = new CDataBattleContentSituationData() + Location = 0, + BattleContentSituationData = new CDataBattleContentSituationData { - + GameMode = GameMode.BitterblackMaze, + StartTime = 1, + RewardReceived = false, + Unk3 = false, + RewardBonus = BattleContentRewardBonus.Normal, + ReportReset = 0, + ReportSearchResults = 0, + Unk7 = 0, + Unk8 = 0, + Unktime = 0, + ContentId = 2, + Unk11 = 0 }, - // Progress = item.Unk0, - // Unk0 = item.Unk1, + BattleContentAvailableRewardsList = + [ + new CDataBattleContentAvailableRewards + { + Id = 10, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 2, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 11, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 3, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 12, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 4, + Amount = 1 + }, + new CDataBattleContentAvailableRewards + { + Id = 13, + Amount = 1 + } + ], Status = true }; client.Send(ntc); @@ -41,4 +82,3 @@ public override S2CBattleContentPartyMemberInfoUpdateRes Handle(GameClient clien } } } - diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentPhaseEntryBeginRecruitmentHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentPhaseEntryBeginRecruitmentHandler.cs new file mode 100644 index 000000000..0ed9b0acc --- /dev/null +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentPhaseEntryBeginRecruitmentHandler.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using Arrowgene.Ddon.GameServer.Characters; +using Arrowgene.Ddon.Server; +using Arrowgene.Ddon.Shared.Entity.PacketStructure; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Model; +using Arrowgene.Ddon.Shared.Model.BattleContent; +using Arrowgene.Logging; + +namespace Arrowgene.Ddon.GameServer.Handler +{ + public class BattleContentPhaseEntryBeginRecruitmentHandler : GameRequestPacketHandler + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(BattleContentPhaseEntryBeginRecruitmentHandler)); + + public BattleContentPhaseEntryBeginRecruitmentHandler(DdonGameServer server) : base(server) + { + } + + public override S2CBattleContentPhaseEntryBeginRecruitmentRes Handle(GameClient client, C2SBattleContentPhaseEntryBeginRecruitmentReq request) + { + // TODO: The request has lots of data.. + + var leader = client.Party.Leader?.Client.Character + ?? throw new ResponseErrorException(ErrorCode.ERROR_CODE_PARTY_LEADER_ABSENCE); + + // This NTC will force the player into the dungeon and skip the board + S2CBattleContentAreaChangeNtc areaChangeNtc = new S2CBattleContentAreaChangeNtc + { + Unk0 = request.Unk3, + Unk1 = request.UnknownString, + StageId = leader.NextBBMStageId, + StartPos = 0, + Unk4 = request.Unk6, + Unk5 = [new CDataBattleContentUnk5 + { + Unk0 = 0, + Unk1 = 0 + } + ], + }; + client.Send(areaChangeNtc); + + S2CBattleContentPhaseEntryBeginRecruitmentRes res = new(); + return res; + } + } +} diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentPhaseEntryReadyCancelHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentPhaseEntryReadyCancelHandler.cs new file mode 100644 index 000000000..da76a1ea6 --- /dev/null +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentPhaseEntryReadyCancelHandler.cs @@ -0,0 +1,22 @@ +using Arrowgene.Ddon.Server; +using Arrowgene.Ddon.Shared.Entity.PacketStructure; +using Arrowgene.Logging; + +namespace Arrowgene.Ddon.GameServer.Handler +{ + public class BattleContentPhaseEntryReadyCancelHandler : GameRequestPacketHandler + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(BattleContentPhaseEntryReadyCancelHandler)); + + public BattleContentPhaseEntryReadyCancelHandler(DdonGameServer server) : base(server) + { + } + + public override S2CBattleContentPhaseEntryReadyCancelRes Handle(GameClient client, C2SBattleContentPhaseEntryReadyCancelReq request) + { + S2CBattleContentPhaseEntryReadyCancelRes res = new(); + return res; + } + } +} diff --git a/Arrowgene.Ddon.GameServer/Handler/CharacterSwitchGameModeHandler.cs b/Arrowgene.Ddon.GameServer/Handler/CharacterSwitchGameModeHandler.cs index 5afba8800..b9c284634 100644 --- a/Arrowgene.Ddon.GameServer/Handler/CharacterSwitchGameModeHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/CharacterSwitchGameModeHandler.cs @@ -57,6 +57,7 @@ public override S2CCharacterSwitchGameModeRes Handle(GameClient client, C2SChara client.Character = Server.CharacterManager.SelectCharacter(client, bbmCharacterId); client.Character.BbmCharacterId = client.Character.CharacterId; client.Character.CharacterId = originalCharacterId; + Server.CharacterManager.SelectPawns(client.Character); } else { @@ -120,8 +121,8 @@ private Character CreateNewCharacter(Character normalCharacter) bbmCharacter.StatusInfo = normalCharacter.StatusInfo; bbmCharacter.Job = normalCharacter.Job; bbmCharacter.JewelrySlotNum = 1; - bbmCharacter.MyPawnSlotNum = 0; - bbmCharacter.RentalPawnSlotNum = 0; + bbmCharacter.MyPawnSlotNum = normalCharacter.MyPawnSlotNum; + bbmCharacter.RentalPawnSlotNum = normalCharacter.RentalPawnSlotNum; bbmCharacter.MatchingProfile = normalCharacter.MatchingProfile; bbmCharacter.ArisenProfile = normalCharacter.ArisenProfile; bbmCharacter.HideEquipHead = normalCharacter.HideEquipHead; diff --git a/Arrowgene.Ddon.GameServer/Handler/ConnectionMoveOutServerHandler.cs b/Arrowgene.Ddon.GameServer/Handler/ConnectionMoveOutServerHandler.cs index d38dfb059..fc5d84f56 100644 --- a/Arrowgene.Ddon.GameServer/Handler/ConnectionMoveOutServerHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/ConnectionMoveOutServerHandler.cs @@ -18,7 +18,7 @@ public override S2CConnectionMoveOutServerRes Handle(GameClient client, C2SConne Logger.Debug(client, $"Creating SessionKey"); S2CConnectionMoveOutServerRes res = new S2CConnectionMoveOutServerRes(); GameToken token = GameToken.GenerateGameToken(client.Account.Id, client.Character.CharacterId); - if (!Database.SetToken(token)) + if (!Database.ReplaceToken(token)) { throw new ResponseErrorException(ErrorCode.ERROR_CODE_AUTH_SESSION_KEY_GENERATE, "Failed to store SessionKey"); } diff --git a/Arrowgene.Ddon.GameServer/Handler/QuestGetPackageQuestListHandler.cs b/Arrowgene.Ddon.GameServer/Handler/QuestGetPackageQuestListHandler.cs index 50c76f449..f042e4f4d 100644 --- a/Arrowgene.Ddon.GameServer/Handler/QuestGetPackageQuestListHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/QuestGetPackageQuestListHandler.cs @@ -18,7 +18,7 @@ public override S2CQuestGetPackageQuestListRes Handle(GameClient client, C2SQues return new() { - Unk0 = request.Unk0 + StageNo = request.StageNo }; } } diff --git a/Arrowgene.Ddon.LoginServer/Handler/ClientChallengeHandler.cs b/Arrowgene.Ddon.LoginServer/Handler/ClientChallengeHandler.cs index d68ae918d..4d245fb67 100644 --- a/Arrowgene.Ddon.LoginServer/Handler/ClientChallengeHandler.cs +++ b/Arrowgene.Ddon.LoginServer/Handler/ClientChallengeHandler.cs @@ -1,37 +1,29 @@ -using Arrowgene.Buffers; using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Server.Network; -using Arrowgene.Ddon.Shared.Entity; using Arrowgene.Ddon.Shared.Entity.PacketStructure; -using Arrowgene.Ddon.Shared.Network; +using Arrowgene.Ddon.Shared.Model; using Arrowgene.Logging; -namespace Arrowgene.Ddon.LoginServer.Handler -{ - public class ClientChallengeHandler : LoginRequestPacketHandler - { - private static readonly ServerLogger Logger = LogProvider.Logger(typeof(ClientChallengeHandler)); +namespace Arrowgene.Ddon.LoginServer.Handler; +public sealed class ClientChallengeHandler(DdonLoginServer server) : LoginRequestPacketHandler(server) +{ + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(ClientChallengeHandler)); - public ClientChallengeHandler(DdonLoginServer server) : base(server) + public override L2CClientChallengeRes Handle(LoginClient client, C2LClientChallengeReq request) + { + Challenge.Response challenge = client.HandleChallenge(request); + if (challenge.Error) { + Logger.Error(client, "Failed client challenge."); + throw new ResponseErrorException(ErrorCode.ERROR_CODE_AUTH_LOGIN_FAILED); } - public override L2CClientChallengeRes Handle(LoginClient client, C2LClientChallengeReq request) + return new L2CClientChallengeRes { - Challenge.Response challenge = client.HandleChallenge(request); - if (challenge.Error) - { - Logger.Error(client, "Failed CertChallenge"); - throw new ResponseErrorException(Shared.Model.ErrorCode.ERROR_CODE_AUTH_LOGIN_FAILED); - } - - return new L2CClientChallengeRes() - { - PasswordSrcSize = challenge.DecryptedBlowFishKeyLength, - PasswordEncSize = challenge.EncryptedBlowFishKeyLength, - PasswordEnc = challenge.EncryptedBlowFishPassword - }; - } + PasswordSrcSize = challenge.DecryptedBlowFishKeyLength, + PasswordEncSize = challenge.EncryptedBlowFishKeyLength, + PasswordEnc = challenge.EncryptedBlowFishPassword + }; } } diff --git a/Arrowgene.Ddon.LoginServer/Handler/ClientDecideCancelCharacterHandler.cs b/Arrowgene.Ddon.LoginServer/Handler/ClientDecideCancelCharacterHandler.cs index a45dbf66e..deb95a118 100644 --- a/Arrowgene.Ddon.LoginServer/Handler/ClientDecideCancelCharacterHandler.cs +++ b/Arrowgene.Ddon.LoginServer/Handler/ClientDecideCancelCharacterHandler.cs @@ -1,23 +1,14 @@ -using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Shared.Entity.PacketStructure; -using Arrowgene.Logging; - -namespace Arrowgene.Ddon.LoginServer.Handler -{ - public class ClientDecideCancelCharacterHandler : LoginRequestPacketHandler - { - private static readonly ServerLogger Logger = LogProvider.Logger(typeof(ClientDecideCancelCharacterHandler)); +namespace Arrowgene.Ddon.LoginServer.Handler; - public ClientDecideCancelCharacterHandler(DdonLoginServer server) : base(server) - { - } - - public override L2CDecideCancelCharacterRes Handle(LoginClient client, C2LDecideCancelCharacterReq request) - { - Server.LoginQueueManager.Remove(client.Account.Id); +public sealed class ClientDecideCancelCharacterHandler(DdonLoginServer server) : LoginRequestPacketHandler(server) +{ + private static readonly L2CDecideCancelCharacterRes Response = new(); - return new(); - } + public override L2CDecideCancelCharacterRes Handle(LoginClient client, C2LDecideCancelCharacterReq request) + { + Server.LoginQueueManager.Remove(client.Account.Id); + return Response; } } diff --git a/Arrowgene.Ddon.LoginServer/Handler/ClientGetGameSessionKeyHandler.cs b/Arrowgene.Ddon.LoginServer/Handler/ClientGetGameSessionKeyHandler.cs index bcb8d88f8..35ffce215 100644 --- a/Arrowgene.Ddon.LoginServer/Handler/ClientGetGameSessionKeyHandler.cs +++ b/Arrowgene.Ddon.LoginServer/Handler/ClientGetGameSessionKeyHandler.cs @@ -5,26 +5,27 @@ namespace Arrowgene.Ddon.LoginServer.Handler { - public class ClientGetGameSessionKeyHandler : LoginRequestPacketHandler + public sealed class ClientGetGameSessionKeyHandler(DdonLoginServer server) : LoginRequestPacketHandler(server) { private static readonly ServerLogger Logger = LogProvider.Logger(typeof(ClientGetGameSessionKeyHandler)); - public ClientGetGameSessionKeyHandler(DdonLoginServer server) : base(server) - { - } - public override L2CGetGameSessionKeyRes Handle(LoginClient client, C2LGetGameSessionKeyReq request) { Logger.Debug(client, $"Creating SessionKey for CharacterId:{client.SelectedCharacterId}"); - L2CGetGameSessionKeyRes res = new L2CGetGameSessionKeyRes(); + GameToken token = GameToken.GenerateGameToken(client.Account.Id, client.SelectedCharacterId); - if (!Database.SetToken(token)) + if (!Database.ReplaceToken(token)) { throw new ResponseErrorException(ErrorCode.ERROR_CODE_AUTH_SESSION_KEY_GENERATE, "Failed to store GameToken"); } - Logger.Info(client, $"Created SessionKey:{token.Token} for CharacterId:{client.SelectedCharacterId}"); - res.SessionKey = token.Token; + + L2CGetGameSessionKeyRes res = new() + { + SessionKey = token.Token, + // TODO: combine with character decide handler logic somehow? This should refer to a game server ID + GameServerUniqueID = (ushort)Server.Setting.ServerSetting.Id + }; return res; } } diff --git a/Arrowgene.Ddon.LoginServer/Handler/ClientLogoutHandler.cs b/Arrowgene.Ddon.LoginServer/Handler/ClientLogoutHandler.cs index b7e3a7663..343f085f1 100644 --- a/Arrowgene.Ddon.LoginServer/Handler/ClientLogoutHandler.cs +++ b/Arrowgene.Ddon.LoginServer/Handler/ClientLogoutHandler.cs @@ -1,20 +1,13 @@ -using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Shared.Entity.PacketStructure; -using Arrowgene.Logging; -namespace Arrowgene.Ddon.LoginServer.Handler -{ - public class ClientLogoutHandler : LoginRequestPacketHandler - { - private static readonly ServerLogger Logger = LogProvider.Logger(typeof(ClientLogoutHandler)); +namespace Arrowgene.Ddon.LoginServer.Handler; - public ClientLogoutHandler(DdonLoginServer server) : base(server) - { - } +public sealed class ClientLogoutHandler(DdonLoginServer server) : LoginRequestPacketHandler(server) +{ + private static readonly L2CLogoutRes Response = new(); - public override L2CLogoutRes Handle(LoginClient client, C2LLogoutReq request) - { - return new(); - } + public override L2CLogoutRes Handle(LoginClient client, C2LLogoutReq request) + { + return Response; } } diff --git a/Arrowgene.Ddon.LoginServer/Handler/ClientPingHandler.cs b/Arrowgene.Ddon.LoginServer/Handler/ClientPingHandler.cs index 20a49ad1e..19426b6aa 100644 --- a/Arrowgene.Ddon.LoginServer/Handler/ClientPingHandler.cs +++ b/Arrowgene.Ddon.LoginServer/Handler/ClientPingHandler.cs @@ -1,24 +1,17 @@ using System; -using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Server.Network; using Arrowgene.Ddon.Shared.Entity.PacketStructure; -using Arrowgene.Logging; -namespace Arrowgene.Ddon.LoginServer.Handler -{ - // These requests are sent periodically by the client (every ~10 seconds) - // after successfully connecting to the server (client._challengeCompleted is true) - public class ClientPingHandler : PingRequestPacketHandler - { - private static readonly ServerLogger Logger = LogProvider.Logger(typeof(ClientPingHandler)); +namespace Arrowgene.Ddon.LoginServer.Handler; - public ClientPingHandler(DdonLoginServer server) : base(server) - { - } +// These requests are sent periodically by the client (every ~10 seconds) +// after successfully connecting to the server (client._challengeCompleted is true) +public sealed class ClientPingHandler(DdonLoginServer server) : PingRequestPacketHandler(server) +{ + private static readonly L2CPingRes Response = new(); - public override L2CPingRes BuildPingResponse(LoginClient client, DateTime now) - { - return new L2CPingRes(); - } + public override L2CPingRes BuildPingResponse(LoginClient client, DateTime now) + { + return Response; } } diff --git a/Arrowgene.Ddon.LoginServer/Handler/DeleteCharacterHandler.cs b/Arrowgene.Ddon.LoginServer/Handler/DeleteCharacterHandler.cs index bbcf2e4bc..0e0e2202d 100644 --- a/Arrowgene.Ddon.LoginServer/Handler/DeleteCharacterHandler.cs +++ b/Arrowgene.Ddon.LoginServer/Handler/DeleteCharacterHandler.cs @@ -3,28 +3,24 @@ using Arrowgene.Ddon.Shared.Model; using Arrowgene.Logging; -namespace Arrowgene.Ddon.LoginServer.Handler +namespace Arrowgene.Ddon.LoginServer.Handler; + +public sealed class DeleteCharacterHandler(DdonLoginServer server) : LoginRequestPacketHandler(server) { - public class DeleteCharacterHandler : LoginRequestPacketHandler - { - private static readonly ServerLogger Logger = LogProvider.Logger(typeof(DeleteCharacterHandler)); + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(DeleteCharacterHandler)); + private static readonly L2CDeleteCharacterInfoRes Response = new(); - public DeleteCharacterHandler(DdonLoginServer server) : base(server) + public override L2CDeleteCharacterInfoRes Handle(LoginClient client, C2LDeleteCharacterInfoReq request) + { + if (!Database.DeleteCharacter(request.CharacterId)) { + throw new ResponseErrorException(ErrorCode.ERROR_CODE_CHARACTER_INTERNAL, $"Failed to delete character with ID: {request.CharacterId}"); } - - public override L2CDeleteCharacterInfoRes Handle(LoginClient client, C2LDeleteCharacterInfoReq request) + else { - if (!Database.DeleteCharacter(request.CharacterId)) - { - throw new ResponseErrorException(ErrorCode.ERROR_CODE_CHARACTER_INTERNAL, $"Failed to delete character with ID: {request.CharacterId}"); - } - else - { - Logger.Info(client, $"Deleted character with ID: {request.CharacterId}"); - } - - return new(); + Logger.Info(client, $"Deleted character with ID: {request.CharacterId}"); } + + return Response; } } diff --git a/Arrowgene.Ddon.LoginServer/Handler/GetCharacterListHandler.cs b/Arrowgene.Ddon.LoginServer/Handler/GetCharacterListHandler.cs index ed5555830..0262c3839 100644 --- a/Arrowgene.Ddon.LoginServer/Handler/GetCharacterListHandler.cs +++ b/Arrowgene.Ddon.LoginServer/Handler/GetCharacterListHandler.cs @@ -9,7 +9,7 @@ namespace Arrowgene.Ddon.LoginServer.Handler { - public class GetCharacterListHandler : LoginRequestPacketHandler + public sealed class GetCharacterListHandler : LoginRequestPacketHandler { private static readonly ServerLogger Logger = LogProvider.Logger(typeof(GetCharacterListHandler)); @@ -83,6 +83,9 @@ public override L2CGetCharacterListRes Handle(LoginClient client, C2LGetCharacte cResponse.ClanNameShort = c.ClanName.ShortName; res.CharacterList.Add(cResponse); } + + // Add additional dead login token clean up + Database.DeleteTokenByAccountId(client.Account.Id); return res; } diff --git a/Arrowgene.Ddon.LoginServer/Handler/GetErrorMessageListHandler.cs b/Arrowgene.Ddon.LoginServer/Handler/GetErrorMessageListHandler.cs index 9a31900c7..fbc9c690c 100644 --- a/Arrowgene.Ddon.LoginServer/Handler/GetErrorMessageListHandler.cs +++ b/Arrowgene.Ddon.LoginServer/Handler/GetErrorMessageListHandler.cs @@ -1,68 +1,57 @@ +using System; using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Shared.Entity.PacketStructure; +using Arrowgene.Ddon.Shared.Entity.Structure; using Arrowgene.Ddon.Shared.Model; using Arrowgene.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -namespace Arrowgene.Ddon.LoginServer.Handler +namespace Arrowgene.Ddon.LoginServer.Handler; + +public sealed class GetErrorMessageListHandler(DdonLoginServer server) : LoginRequestPacketHandler(server) { - public class GetErrorMessageListHandler : LoginRequestPacketHandler - { - private static readonly ServerLogger Logger = LogProvider.Logger(typeof(GetErrorMessageListHandler)); + /// + /// Total allowable packet size, in bytes. + /// Break up the list into multiple packets if we exceed this value. + /// This is slightly smaller than ushort.MaxValue (the hard cap) to give some wiggle room. + /// + private const uint PacketSizeLimit = ushort.MaxValue - 1000; - public GetErrorMessageListHandler(DdonLoginServer server) : base(server) - { - } + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(GetErrorMessageListHandler)); - /// - /// Total allowable packet size, in bytes. - /// Break up the list into multiple packets if we exceed this value. - /// This is slightly smaller than ushort.MaxValue (the hard cap) to give some wiggle room. - /// - private static uint PACKET_SIZE_LIMIT = ushort.MaxValue - 1000; + public override L2CGetErrorMessageListRes Handle(LoginClient client, C2LGetErrorMessageListReq packet) + { + L2CGetErrorMessageListNtc ntc = new(); + uint totalLength = 0; - public override L2CGetErrorMessageListRes Handle(LoginClient client, C2LGetErrorMessageListReq packet) + foreach (ErrorCode code in Enum.GetValues()) { - L2CGetErrorMessageListNtc ntc = new L2CGetErrorMessageListNtc(); - uint totalLength = 0; + // An MtString of length N takes up N+2 bytes. + // Each CDataErrorMessage is thus at least N+2+2+4+4 bytes. + string message = code.ToString(); - foreach (ErrorCode code in Enum.GetValues(typeof(ErrorCode))) - { - // An MtString of length N takes up N+2 bytes. - // Each CDataErrorMessage is thus at least N+2+2+4+4 bytes. - var message = code.ToString(); - - if (Server.AssetRepository.ClientErrorCodes.TryGetValue(code, out var asset) - && asset.Message.TryGetValue("en", out string assetMessage)) - { - message = assetMessage; - } - - totalLength += (uint)(message.Length + 12); + if (Server.AssetRepository.ClientErrorCodes.TryGetValue(code, out ClientErrorCode asset) + && asset.Message.TryGetValue("en", out string assetMessage)) + message = assetMessage; - ntc.ErrorMessages.Add(new() - { - ErrorId = code, - MessageId = 1, - Message = message - }); + totalLength += (uint)(message.Length + 12); - if (totalLength >= PACKET_SIZE_LIMIT) - { - client.Send(ntc); - ntc = new(); - totalLength = 0; - } - } + ntc.ErrorMessages.Add(new CDataErrorMessage + { + ErrorId = code, + MessageId = 1, + Message = message + }); - if (ntc.ErrorMessages.Any()) + if (totalLength >= PacketSizeLimit) { client.Send(ntc); + ntc = new L2CGetErrorMessageListNtc(); + totalLength = 0; } - L2CGetErrorMessageListRes res = new L2CGetErrorMessageListRes(); - return res; } + + if (ntc.ErrorMessages.Count != 0) client.Send(ntc); + L2CGetErrorMessageListRes res = new(); + return res; } } diff --git a/Arrowgene.Ddon.LoginServer/Handler/GetLoginSettingHandler.cs b/Arrowgene.Ddon.LoginServer/Handler/GetLoginSettingHandler.cs index 2c4166f93..796848b28 100644 --- a/Arrowgene.Ddon.LoginServer/Handler/GetLoginSettingHandler.cs +++ b/Arrowgene.Ddon.LoginServer/Handler/GetLoginSettingHandler.cs @@ -1,56 +1,65 @@ -using Arrowgene.Ddon.Server; +using Arrowgene.Ddon.Server.Settings; using Arrowgene.Ddon.Shared.Entity.PacketStructure; using Arrowgene.Ddon.Shared.Entity.Structure; -using Arrowgene.Logging; -using System.Collections.Generic; -namespace Arrowgene.Ddon.LoginServer.Handler +namespace Arrowgene.Ddon.LoginServer.Handler; + +public sealed class GetLoginSettingHandler(DdonLoginServer server) : LoginRequestPacketHandler(server) { - public class GetLoginSettingHandler : LoginRequestPacketHandler + private readonly L2CGetLoginSettingRes _response = BuildResponse(server); + + public override L2CGetLoginSettingRes Handle( + LoginClient client, + C2LGetLoginSettingReq request) { - private static readonly ServerLogger Logger = LogProvider.Logger(typeof(GetLoginSettingHandler)); + return _response; + } - public GetLoginSettingHandler(DdonLoginServer server) : base(server) - { - } + private static L2CGetLoginSettingRes BuildResponse(DdonLoginServer server) + { + GameServerSettings settings = server.GameSetting.GameServerSettings; - public override L2CGetLoginSettingRes Handle(LoginClient client, C2LGetLoginSettingReq request) + L2CGetLoginSettingRes response = new() { - L2CGetLoginSettingRes response = new L2CGetLoginSettingRes + LoginSetting = { - LoginSetting = - { - JobLevelMax = Server.GameSetting.GameServerSettings.JobLevelMax, - ClanMemberMax = Server.GameSetting.GameServerSettings.ClanMemberMax, - CharacterNumMax = Server.GameSetting.GameServerSettings.CharacterNumMax, - EnableVisualEquip = Server.GameSetting.GameServerSettings.EnableVisualEquip, - FriendListMax = Server.GameSetting.GameServerSettings.FriendListMax, - URLInfoList = new List() - { - new CDataURLInfo {Type = 1, URL = Server.GameSetting.GameServerSettings.UrlManual}, - new CDataURLInfo {Type = 2, URL = Server.GameSetting.GameServerSettings.UrlShopDetail}, - new CDataURLInfo {Type = 3, URL = Server.GameSetting.GameServerSettings.UrlShopCounterA}, - new CDataURLInfo {Type = 4, URL = Server.GameSetting.GameServerSettings.UrlShopAttention}, - new CDataURLInfo {Type = 5, URL = Server.GameSetting.GameServerSettings.UrlShopStoneLimit}, - new CDataURLInfo {Type = 6, URL = Server.GameSetting.GameServerSettings.UrlShopCounterB}, - new CDataURLInfo {Type = 7, URL = Server.GameSetting.GameServerSettings.UrlChargeCallback}, - new CDataURLInfo {Type = 8, URL = Server.GameSetting.GameServerSettings.UrlChargeA}, - new CDataURLInfo {Type = 9, URL = Server.GameSetting.GameServerSettings.UrlSample9}, - new CDataURLInfo {Type = 10, URL = Server.GameSetting.GameServerSettings.UrlSample10}, - new CDataURLInfo {Type = 11, URL = Server.GameSetting.GameServerSettings.UrlCampaignBanner}, - new CDataURLInfo {Type = 12, URL = Server.GameSetting.GameServerSettings.UrlSupportIndex}, - new CDataURLInfo {Type = 13, URL = Server.GameSetting.GameServerSettings.UrlPhotoupAuthorize}, - new CDataURLInfo {Type = 14, URL = Server.GameSetting.GameServerSettings.UrlApiA}, - new CDataURLInfo {Type = 15, URL = Server.GameSetting.GameServerSettings.UrlApiB}, - new CDataURLInfo {Type = 16, URL = Server.GameSetting.GameServerSettings.UrlIndex}, - new CDataURLInfo {Type = 17, URL = Server.GameSetting.GameServerSettings.UrlCampaign}, - new CDataURLInfo {Type = 19, URL = Server.GameSetting.GameServerSettings.UrlChargeB}, - new CDataURLInfo {Type = 20, URL = Server.GameSetting.GameServerSettings.UrlCompanionImage}, - }, - NoOperationTimeOutTime = Server.Setting.NoOperationTimeOutTime, - }, - }; - return response; - } + JobLevelMax = settings.JobLevelMax, + ClanMemberMax = settings.ClanMemberMax, + CharacterNumMax = settings.CharacterNumMax, + EnableVisualEquip = settings.EnableVisualEquip, + FriendListMax = settings.FriendListMax, + NoOperationTimeOutTime = server.Setting.NoOperationTimeOutTime + } + }; + + (uint, string)[] urlInfos = + [ + (1u, settings.UrlManual), + (2u, settings.UrlShopDetail), + (3u, settings.UrlShopCounterA), + (4u, settings.UrlShopAttention), + (5u, settings.UrlShopStoneLimit), + (6u, settings.UrlShopCounterB), + (7u, settings.UrlChargeCallback), + (8u, settings.UrlChargeA), + (9u, settings.UrlSample9), + (10u, settings.UrlSample10), + (11u, settings.UrlCampaignBanner), + (12u, settings.UrlSupportIndex), + (13u, settings.UrlPhotoupAuthorize), + (14u, settings.UrlApiA), + (15u, settings.UrlApiB), + (16u, settings.UrlIndex), + (17u, settings.UrlCampaign), + (19u, settings.UrlChargeB), + (20u, settings.UrlCompanionImage) + ]; + + foreach ((uint type, string url) in urlInfos) + response.LoginSetting.URLInfoList.Add( + new CDataURLInfo { Type = type, URL = url } + ); + + return response; } } diff --git a/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs b/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs index ae59db500..4a47445f7 100644 --- a/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs +++ b/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs @@ -545,6 +545,9 @@ static EntitySerializer() Create(new C2SBattleContentContentFirstPhaseChangeReq.Serializer()); Create(new C2SBattleContentContentResetReq.Serializer()); Create(new C2SBattleContentGetContentStatusFromOmReq.Serializer()); + Create(new C2SBattleContentGetPhaseToChangeFromOmReq.Serializer()); + Create(new C2SBattleContentPhaseEntryBeginRecruitmentReq.Serializer()); + Create(new C2SBattleContentPhaseEntryReadyCancelReq.Serializer()); Create(new C2SBattleContentGetRewardReq.Serializer()); Create(new C2SBattleContentInfoListReq.Serializer()); Create(new C2SBattleContentInstantClearInfoReq.Serializer()); @@ -1066,6 +1069,7 @@ static EntitySerializer() Create(new S2CAreaRankUpReadyNtc.Serializer()); Create(new S2CBattleContentAreaChangeNtc.Serializer()); + Create(new S2CBattleContentPhaseEntryReadyNtc.Serializer()); Create(new S2CBattleContentCharacterInfoRes.Serializer()); Create(new S2CBattleContentClearContentNtc.Serializer()); Create(new S2CBattleContentClearTierNtc.Serializer()); @@ -1075,6 +1079,9 @@ static EntitySerializer() Create(new S2CBattleContentContentResetNtc.Serializer()); Create(new S2CBattleContentContentResetRes.Serializer()); Create(new S2CBattleContentGetContentStatusFromOmRes.Serializer()); + Create(new S2CBattleContentGetPhaseToChangeFromOmRes.Serializer()); + Create(new S2CBattleContentPhaseEntryBeginRecruitmentRes.Serializer()); + Create(new S2CBattleContentPhaseEntryReadyCancelRes.Serializer()); Create(new S2CBattleContentGetRewardRes.Serializer()); Create(new S2CBattleContentGetRewardsNtc.Serializer()); Create(new S2CBattleContentInfoListRes.Serializer()); diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentGetContentStatusFromOmReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentGetContentStatusFromOmReq.cs index d3e02e5fe..4863b2ec0 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentGetContentStatusFromOmReq.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentGetContentStatusFromOmReq.cs @@ -1,6 +1,5 @@ using Arrowgene.Buffers; using Arrowgene.Ddon.Shared.Entity.Structure; -using Arrowgene.Ddon.Shared.Model; using Arrowgene.Ddon.Shared.Network; namespace Arrowgene.Ddon.Shared.Entity.PacketStructure @@ -9,6 +8,9 @@ public class C2SBattleContentGetContentStatusFromOmReq : IPacketStructure { public PacketId Id => PacketId.C2S_BATTLE_CONTENT_GET_CONTENT_STATUS_FROM_OM_REQ; + /// + /// Uses the same data structures as C2SBattleContentGetPhaseToChangeFromOmReq + /// public C2SBattleContentGetContentStatusFromOmReq() { StageLayoutId = new CDataStageLayoutId(); diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentGetPhaseToChangeFromOmReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentGetPhaseToChangeFromOmReq.cs new file mode 100644 index 000000000..3bd5b00c8 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentGetPhaseToChangeFromOmReq.cs @@ -0,0 +1,41 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class C2SBattleContentGetPhaseToChangeFromOmReq : IPacketStructure + { + public PacketId Id => PacketId.C2S_BATTLE_CONTENT_GET_PHASE_TO_CHANGE_FROM_OM_REQ; + + /// + /// Uses the same data structures as C2SBattleContentGetContentStatusFromOmReq + /// + public C2SBattleContentGetPhaseToChangeFromOmReq() + { + StageLayoutId = new CDataStageLayoutId(); + } + + public CDataStageLayoutId StageLayoutId { get; set; } + public uint Unk0 { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, C2SBattleContentGetPhaseToChangeFromOmReq obj) + { + WriteEntity(buffer, obj.StageLayoutId); + WriteUInt32(buffer, obj.Unk0); + } + + public override C2SBattleContentGetPhaseToChangeFromOmReq Read(IBuffer buffer) + { + C2SBattleContentGetPhaseToChangeFromOmReq obj = new() + { + StageLayoutId = ReadEntity(buffer), + Unk0 = ReadUInt32(buffer) + }; + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPartyMemberInfoReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPartyMemberInfoReq.cs index 7c4344f33..30ecf2249 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPartyMemberInfoReq.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPartyMemberInfoReq.cs @@ -12,22 +12,22 @@ public C2SBattleContentPartyMemberInfoReq() { } - public uint Unk0 { get; set; } - public uint Unk1 { get; set; } + public uint TargetContentId { get; set; } + public uint UnknownFlag { get; set; } public class Serializer : PacketEntitySerializer { public override void Write(IBuffer buffer, C2SBattleContentPartyMemberInfoReq obj) { - WriteUInt32(buffer, obj.Unk0); - WriteUInt32(buffer, obj.Unk1); + WriteUInt32(buffer, obj.TargetContentId); + WriteUInt32(buffer, obj.UnknownFlag); } public override C2SBattleContentPartyMemberInfoReq Read(IBuffer buffer) { C2SBattleContentPartyMemberInfoReq obj = new C2SBattleContentPartyMemberInfoReq(); - obj.Unk0 = ReadUInt32(buffer); - obj.Unk1 = ReadUInt32(buffer); + obj.TargetContentId = ReadUInt32(buffer); + obj.UnknownFlag = ReadUInt32(buffer); return obj; } } diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPartyMemberInfoUpdateReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPartyMemberInfoUpdateReq.cs index 2e3a76843..5b20c93ec 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPartyMemberInfoUpdateReq.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPartyMemberInfoUpdateReq.cs @@ -14,7 +14,7 @@ public C2SBattleContentPartyMemberInfoUpdateReq() public uint Unk0 { get; set; } public byte Unk1 { get; set; } - public uint Unk2 { get; set; } + public uint UnknownFlag { get; set; } public class Serializer : PacketEntitySerializer { @@ -22,7 +22,7 @@ public override void Write(IBuffer buffer, C2SBattleContentPartyMemberInfoUpdate { WriteUInt32(buffer, obj.Unk0); WriteByte(buffer, obj.Unk1); - WriteUInt32(buffer, obj.Unk2); + WriteUInt32(buffer, obj.UnknownFlag); } public override C2SBattleContentPartyMemberInfoUpdateReq Read(IBuffer buffer) @@ -30,7 +30,7 @@ public override C2SBattleContentPartyMemberInfoUpdateReq Read(IBuffer buffer) C2SBattleContentPartyMemberInfoUpdateReq obj = new C2SBattleContentPartyMemberInfoUpdateReq(); obj.Unk0 = ReadUInt32(buffer); obj.Unk1 = ReadByte(buffer); - obj.Unk2 = ReadUInt32(buffer); + obj.UnknownFlag = ReadUInt32(buffer); return obj; } } diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPhaseEntryBeginRecruitmentReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPhaseEntryBeginRecruitmentReq.cs new file mode 100644 index 000000000..36e84626b --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPhaseEntryBeginRecruitmentReq.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class C2SBattleContentPhaseEntryBeginRecruitmentReq : IPacketStructure + { + public PacketId Id => PacketId.C2S_BATTLE_CONTENT_PHASE_ENTRY_BEGIN_RECRUITMENT_REQ; + + /// + /// Uses the same data structures as C2SBattleContentGetContentStatusFromOmReq + /// + public C2SBattleContentPhaseEntryBeginRecruitmentReq() + { + StageLayoutId = new CDataStageLayoutId(); + BattleContentStageList = []; + UnknownString = string.Empty; + } + + public CDataStageLayoutId StageLayoutId { get; set; } + public uint Unk3 { get; set; } + public List BattleContentStageList { get; set; } + public uint UnknownFlag { get; set; } + public string UnknownString { get; set; } + public bool Unk6 { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, C2SBattleContentPhaseEntryBeginRecruitmentReq obj) + { + WriteEntity(buffer, obj.StageLayoutId); + WriteUInt32(buffer, obj.Unk3); + WriteEntityList(buffer, obj.BattleContentStageList); + WriteUInt32(buffer, obj.UnknownFlag); + WriteMtString(buffer, obj.UnknownString); + WriteBool(buffer, obj.Unk6); + } + + public override C2SBattleContentPhaseEntryBeginRecruitmentReq Read(IBuffer buffer) + { + C2SBattleContentPhaseEntryBeginRecruitmentReq obj = new() + { + StageLayoutId = ReadEntity(buffer), + Unk3 = ReadUInt32(buffer), + BattleContentStageList = ReadEntityList(buffer), + UnknownFlag = ReadUInt32(buffer), + UnknownString = ReadMtString(buffer), + Unk6 = ReadBool(buffer) + }; + + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPhaseEntryReadyCancelReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPhaseEntryReadyCancelReq.cs new file mode 100644 index 000000000..918e19f17 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SBattleContentPhaseEntryReadyCancelReq.cs @@ -0,0 +1,34 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class C2SBattleContentPhaseEntryReadyCancelReq : IPacketStructure + { + public PacketId Id => PacketId.C2S_BATTLE_CONTENT_PHASE_ENTRY_READY_CANCEL_REQ; + + public C2SBattleContentPhaseEntryReadyCancelReq() + { + } + + public uint Unk0 { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, C2SBattleContentPhaseEntryReadyCancelReq obj) + { + WriteUInt32(buffer, obj.Unk0); + } + + public override C2SBattleContentPhaseEntryReadyCancelReq Read(IBuffer buffer) + { + C2SBattleContentPhaseEntryReadyCancelReq obj = new() + { + Unk0 = ReadUInt32(buffer), + }; + + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SQuestGetPackageQuestListReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SQuestGetPackageQuestListReq.cs index 992b031ec..e5ec3923e 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SQuestGetPackageQuestListReq.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SQuestGetPackageQuestListReq.cs @@ -7,22 +7,22 @@ public class C2SQuestGetPackageQuestListReq : IPacketStructure { public PacketId Id => PacketId.C2S_QUEST_GET_PACKAGE_QUEST_LIST_REQ; - public uint Unk0 { get; set; } + public uint StageNo { get; set; } public class Serializer : PacketEntitySerializer { public override void Write(IBuffer buffer, C2SQuestGetPackageQuestListReq obj) { - WriteUInt32(buffer, obj.Unk0); + WriteUInt32(buffer, obj.StageNo); } public override C2SQuestGetPackageQuestListReq Read(IBuffer buffer) { C2SQuestGetPackageQuestListReq obj = new C2SQuestGetPackageQuestListReq(); - obj.Unk0 = ReadUInt32(buffer); + obj.StageNo = ReadUInt32(buffer); return obj; } } } -} \ No newline at end of file +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/L2CGetGameSessionKeyRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/L2CGetGameSessionKeyRes.cs index dbda0d959..506c20710 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/L2CGetGameSessionKeyRes.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/L2CGetGameSessionKeyRes.cs @@ -7,8 +7,8 @@ public class L2CGetGameSessionKeyRes : ServerResponse { public override PacketId Id => PacketId.L2C_GET_GAME_SESSION_KEY_RES; - public string SessionKey { get; set; } = string.Empty; - public uint Unknown { get; set; } + public string SessionKey { get; set; } = string.Empty; // MtString + public ushort GameServerUniqueID { get; set; } // 0 means some error during the login occurred public class Serializer : PacketEntitySerializer { @@ -17,7 +17,7 @@ public override void Write(IBuffer buffer, L2CGetGameSessionKeyRes obj) { WriteServerResponse(buffer, obj); WriteMtString(buffer, obj.SessionKey); - WriteUInt32(buffer, obj.Unknown); + WriteUInt16(buffer, obj.GameServerUniqueID); } public override L2CGetGameSessionKeyRes Read(IBuffer buffer) @@ -25,7 +25,7 @@ public override L2CGetGameSessionKeyRes Read(IBuffer buffer) L2CGetGameSessionKeyRes obj = new L2CGetGameSessionKeyRes(); ReadServerResponse(buffer, obj); obj.SessionKey = ReadMtString(buffer); - obj.Unknown = ReadUInt32(buffer); + obj.GameServerUniqueID = ReadUInt16(buffer); return obj; } } diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentCharacterInfoRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentCharacterInfoRes.cs index e3334f4ab..bc7f2ec47 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentCharacterInfoRes.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentCharacterInfoRes.cs @@ -14,11 +14,11 @@ public class S2CBattleContentCharacterInfoRes : ServerResponse public S2CBattleContentCharacterInfoRes() { SituationData = new CDataBattleContentSituationData(); - Unk2List = new List(); + AvailableRewardsList = new List(); } public CDataBattleContentSituationData SituationData { get; set; } - public List Unk2List { get; set; } + public List AvailableRewardsList { get; set; } public class Serializer : PacketEntitySerializer { @@ -26,7 +26,7 @@ public override void Write(IBuffer buffer, S2CBattleContentCharacterInfoRes obj) { WriteServerResponse(buffer, obj); WriteEntity(buffer, obj.SituationData); - WriteEntityList(buffer, obj.Unk2List); + WriteEntityList(buffer, obj.AvailableRewardsList); } public override S2CBattleContentCharacterInfoRes Read(IBuffer buffer) @@ -34,7 +34,7 @@ public override S2CBattleContentCharacterInfoRes Read(IBuffer buffer) S2CBattleContentCharacterInfoRes obj = new S2CBattleContentCharacterInfoRes(); ReadServerResponse(buffer, obj); obj.SituationData = ReadEntity(buffer); - obj.Unk2List = ReadEntityList(buffer); + obj.AvailableRewardsList = ReadEntityList(buffer); return obj; } } diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentGetContentStatusFromOmRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentGetContentStatusFromOmRes.cs index c4a8db138..0e5fcac53 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentGetContentStatusFromOmRes.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentGetContentStatusFromOmRes.cs @@ -11,7 +11,7 @@ public class S2CBattleContentGetContentStatusFromOmRes : ServerResponse public GameMode GameMode { get; set; } public uint NotifyJobLock { get; set; } // Related to either starting new or continuing? public uint Unk2 { get; set; } - public uint Unk3 { get; set; } + public uint RouteIsNotInProgress { get; set; } public uint Unk4 { get; set; } public class Serializer : PacketEntitySerializer @@ -22,7 +22,7 @@ public override void Write(IBuffer buffer, S2CBattleContentGetContentStatusFromO WriteUInt32(buffer, (uint) obj.GameMode); WriteUInt32(buffer, obj.NotifyJobLock); WriteUInt32(buffer, obj.Unk2); - WriteUInt32(buffer, obj.Unk3); + WriteUInt32(buffer, obj.RouteIsNotInProgress); WriteUInt32(buffer, obj.Unk4); } @@ -33,7 +33,7 @@ public override S2CBattleContentGetContentStatusFromOmRes Read(IBuffer buffer) obj.GameMode = (GameMode) ReadUInt32(buffer); obj.NotifyJobLock = ReadUInt32(buffer); obj.Unk2 = ReadUInt32(buffer); - obj.Unk3 = ReadUInt32(buffer); + obj.RouteIsNotInProgress = ReadUInt32(buffer); obj.Unk4 = ReadUInt32(buffer); return obj; } diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentGetPhaseToChangeFromOmRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentGetPhaseToChangeFromOmRes.cs new file mode 100644 index 000000000..f0f6f2022 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentGetPhaseToChangeFromOmRes.cs @@ -0,0 +1,41 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CBattleContentGetPhaseToChangeFromOmRes : ServerResponse + { + public S2CBattleContentGetPhaseToChangeFromOmRes() + { + BattleContentStage = new CDataBattleContentStage(); + } + + public override PacketId Id => PacketId.S2C_BATTLE_CONTENT_GET_PHASE_TO_CHANGE_FROM_OM_RES; + + // public int Unk0 { get; set; } + // public int Unk1 { get; set; } + public CDataBattleContentStage BattleContentStage { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CBattleContentGetPhaseToChangeFromOmRes obj) + { + WriteServerResponse(buffer, obj); + // WriteInt32(buffer, obj.Unk0); + // WriteInt32(buffer, obj.Unk1); + WriteEntity(buffer, obj.BattleContentStage); + } + + public override S2CBattleContentGetPhaseToChangeFromOmRes Read(IBuffer buffer) + { + S2CBattleContentGetPhaseToChangeFromOmRes obj = new(); + ReadServerResponse(buffer, obj); + // obj.Unk0 = ReadInt32(buffer); + // obj.Unk1 = ReadInt32(buffer); + obj.BattleContentStage = ReadEntity(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPartyMemberInfoUpdateNtc.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPartyMemberInfoUpdateNtc.cs index d6e889430..9ca6e4a58 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPartyMemberInfoUpdateNtc.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPartyMemberInfoUpdateNtc.cs @@ -16,7 +16,7 @@ public S2CBattleContentPartyMemberInfoUpdateNtc() } public uint CharacterId { get; set; } - public byte Pos { get; set; } + public byte Location { get; set; } // If this is not 0, then an error shows up "There are members in a different location" public CDataBattleContentSituationData BattleContentSituationData { get; set; } public List BattleContentAvailableRewardsList { get; set; } public bool Status { get; set; } @@ -26,7 +26,7 @@ public class Serializer : PacketEntitySerializer(buffer); obj.BattleContentAvailableRewardsList = ReadEntityList(buffer); obj.Status = ReadBool(buffer); diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPhaseEntryBeginRecruitmentRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPhaseEntryBeginRecruitmentRes.cs new file mode 100644 index 000000000..3c5b83f5f --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPhaseEntryBeginRecruitmentRes.cs @@ -0,0 +1,29 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CBattleContentPhaseEntryBeginRecruitmentRes : ServerResponse + { + public S2CBattleContentPhaseEntryBeginRecruitmentRes() + { + } + + public override PacketId Id => PacketId.S2C_BATTLE_CONTENT_PHASE_ENTRY_BEGIN_RECRUITMENT_RES; + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CBattleContentPhaseEntryBeginRecruitmentRes obj) + { + WriteServerResponse(buffer, obj); + } + + public override S2CBattleContentPhaseEntryBeginRecruitmentRes Read(IBuffer buffer) + { + S2CBattleContentPhaseEntryBeginRecruitmentRes obj = new(); + ReadServerResponse(buffer, obj); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPhaseEntryReadyCancelRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPhaseEntryReadyCancelRes.cs new file mode 100644 index 000000000..8007d4749 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPhaseEntryReadyCancelRes.cs @@ -0,0 +1,29 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CBattleContentPhaseEntryReadyCancelRes : ServerResponse + { + public S2CBattleContentPhaseEntryReadyCancelRes() + { + } + + public override PacketId Id => PacketId.S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_CANCEL_RES; + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CBattleContentPhaseEntryReadyCancelRes obj) + { + WriteServerResponse(buffer, obj); + } + + public override S2CBattleContentPhaseEntryReadyCancelRes Read(IBuffer buffer) + { + S2CBattleContentPhaseEntryReadyCancelRes obj = new(); + ReadServerResponse(buffer, obj); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPhaseEntryReadyNtc.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPhaseEntryReadyNtc.cs new file mode 100644 index 000000000..794a298ba --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentPhaseEntryReadyNtc.cs @@ -0,0 +1,40 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; +using System.Collections.Generic; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CBattleContentPhaseEntryReadyNtc : IPacketStructure + { + public PacketId Id => PacketId.S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_NTC; + + public S2CBattleContentPhaseEntryReadyNtc() + { + } + + public uint Unk0 { get; set; } + public uint Unk1 { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CBattleContentPhaseEntryReadyNtc obj) + { + WriteUInt32(buffer, obj.Unk0); + WriteUInt32(buffer, obj.Unk1); + } + + public override S2CBattleContentPhaseEntryReadyNtc Read(IBuffer buffer) + { + S2CBattleContentPhaseEntryReadyNtc obj = new S2CBattleContentPhaseEntryReadyNtc + { + Unk0 = ReadUInt32(buffer), + Unk1 = ReadUInt32(buffer) + }; + return obj; + } + } + } +} + + diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentProgressNtc.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentProgressNtc.cs index 1dc07e4b7..73680de15 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentProgressNtc.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CBattleContentProgressNtc.cs @@ -7,7 +7,7 @@ namespace Arrowgene.Ddon.Shared.Entity.PacketStructure { public class S2CBattleContentProgressNtc : IPacketStructure { - public PacketId Id => PacketId.S2C_BATTLE_71_19_16_NTC; + public PacketId Id => PacketId.S2C_BATTLE_CONTENT_STATUS_PROGRESS_NTC; public S2CBattleContentProgressNtc() { diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestGetPackageQuestListRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestGetPackageQuestListRes.cs index a79da1de7..1b556bad6 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestGetPackageQuestListRes.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestGetPackageQuestListRes.cs @@ -18,7 +18,7 @@ public S2CQuestGetPackageQuestListRes() PackageQuestList = new List(); } - public uint Unk0 { get; set; } + public uint StageNo { get; set; } public List PackageQuestList { get; set; } public class Serializer : PacketEntitySerializer @@ -26,7 +26,7 @@ public class Serializer : PacketEntitySerializer public override void Write(IBuffer buffer, S2CQuestGetPackageQuestListRes obj) { WriteServerResponse(buffer, obj); - WriteUInt32(buffer, obj.Unk0); + WriteUInt32(buffer, obj.StageNo); WriteEntityList(buffer, obj.PackageQuestList); } @@ -34,7 +34,7 @@ public override S2CQuestGetPackageQuestListRes Read(IBuffer buffer) { S2CQuestGetPackageQuestListRes obj = new S2CQuestGetPackageQuestListRes(); ReadServerResponse(buffer, obj); - obj.Unk0 = ReadUInt32(buffer); + obj.StageNo = ReadUInt32(buffer); obj.PackageQuestList = ReadEntityList(buffer); return obj; } diff --git a/Arrowgene.Ddon.Shared/Entity/Structure/CDataBattleContentSituationData.cs b/Arrowgene.Ddon.Shared/Entity/Structure/CDataBattleContentSituationData.cs index a238cfd3b..7339a2919 100644 --- a/Arrowgene.Ddon.Shared/Entity/Structure/CDataBattleContentSituationData.cs +++ b/Arrowgene.Ddon.Shared/Entity/Structure/CDataBattleContentSituationData.cs @@ -18,7 +18,7 @@ public CDataBattleContentSituationData() public BattleContentRewardBonus RewardBonus { get; set; } public uint ReportReset { get; set; } // Related to reset progress (Lyka gets ! in menu if > 0 and RewardReceived = true) public uint ReportSearchResults { get; set; } // 0x18 (Lyka gets ! in menu) - public uint Unk7 { get; set; } + public uint Unk7 { get; set; } // values in pcapcs: 0, 1, 23, it is only not 0 when Unktime is set to a non zero value public byte Unk8 { get; set; } // Impacts "Status:" some how public ulong Unktime { get; set; } // Reset time? public uint ContentId { get; set; } // Corresponds with the "ID" in the BattleContentStageList diff --git a/Arrowgene.Ddon.Shared/Entity/Structure/CDataBattleContentUnk6.cs b/Arrowgene.Ddon.Shared/Entity/Structure/CDataBattleContentUnk6.cs index 1727fa0d6..b1ff8f811 100644 --- a/Arrowgene.Ddon.Shared/Entity/Structure/CDataBattleContentUnk6.cs +++ b/Arrowgene.Ddon.Shared/Entity/Structure/CDataBattleContentUnk6.cs @@ -14,7 +14,7 @@ public CDataBattleContentUnk6() } public uint Unk0 { get; set; } - public byte Unk1 { get; set; } + public byte CurrentContentId { get; set; } // If this is not 0 when embarking, it will report "There are members with different progress" public CDataBattleContentSituationData BattleContentSituationData { get; set; } public List BattleContentAvailableRewardsList { get; set; } public bool Unk4 { get; set; } @@ -24,7 +24,7 @@ public class Serializer : EntitySerializer public override void Write(IBuffer buffer, CDataBattleContentUnk6 obj) { WriteUInt32(buffer, obj.Unk0); - WriteByte(buffer, obj.Unk1); + WriteByte(buffer, obj.CurrentContentId); WriteEntity(buffer, obj.BattleContentSituationData); WriteEntityList(buffer, obj.BattleContentAvailableRewardsList); WriteBool(buffer, obj.Unk4); @@ -34,7 +34,7 @@ public override CDataBattleContentUnk6 Read(IBuffer buffer) { CDataBattleContentUnk6 obj = new CDataBattleContentUnk6(); obj.Unk0 = ReadUInt32(buffer); - obj.Unk1 = ReadByte(buffer); + obj.CurrentContentId = ReadByte(buffer); obj.BattleContentSituationData = ReadEntity(buffer); obj.BattleContentAvailableRewardsList = ReadEntityList(buffer); obj.Unk4 = ReadBool(buffer); diff --git a/Arrowgene.Ddon.Shared/Model/GameToken.cs b/Arrowgene.Ddon.Shared/Model/GameToken.cs index 4ce730bad..07f8e1665 100644 --- a/Arrowgene.Ddon.Shared/Model/GameToken.cs +++ b/Arrowgene.Ddon.Shared/Model/GameToken.cs @@ -1,46 +1,27 @@ using System; -using System.Text; -using Arrowgene.Ddon.Shared.Crypto; -namespace Arrowgene.Ddon.Shared.Model +namespace Arrowgene.Ddon.Shared.Model; + +public class GameToken { - public class GameToken + public int AccountId { get; init; } + public uint CharacterId { get; init; } + public string Token { get; init; } + public DateTime Created { get; init; } + + public static string GenerateLoginToken() { - private static string TokenPool = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - public const int LoginTokenLength = 20; - public const int GameTokenLength = 20; + return Guid.NewGuid().ToString("N"); + } - public static string GenerateLoginToken() - { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < LoginTokenLength; i++) - { - int tokenPoolIndex = CryptoRandom.Instance.Next(0, TokenPool.Length - 1); - sb.Append(TokenPool[tokenPoolIndex]); - } - return sb.ToString(); - } - - public static GameToken GenerateGameToken(int accountId, uint characterId) + public static GameToken GenerateGameToken(int accountId, uint characterId) + { + return new GameToken { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < GameTokenLength; i++) - { - int tokenPoolIndex = CryptoRandom.Instance.Next(0, TokenPool.Length - 1); - sb.Append(TokenPool[tokenPoolIndex]); - } - - GameToken token = new GameToken(); - token.Token = sb.ToString(); - token.Created = DateTime.UtcNow; - token.AccountId = accountId; - token.CharacterId = characterId; - return token; - } - - public int AccountId { get; set; } - public uint CharacterId { get; set; } - public string Token { get; set; } - public DateTime Created { get; set; } + AccountId = accountId, + CharacterId = characterId, + Token = GenerateLoginToken(), + Created = DateTime.UtcNow + }; } } diff --git a/Arrowgene.Ddon.Shared/Network/PacketId.cs b/Arrowgene.Ddon.Shared/Network/PacketId.cs index 2b2d62a4a..fb6b18648 100644 --- a/Arrowgene.Ddon.Shared/Network/PacketId.cs +++ b/Arrowgene.Ddon.Shared/Network/PacketId.cs @@ -2109,7 +2109,7 @@ private static Dictionary InitializeLoginPacketIds() public static readonly PacketId S2C_BATTLE_CONTENT_GET_REWARD_NTC = new PacketId(71, 2, 16, "S2C_BATTLE_CONTENT_GET_REWARD_NTC", ServerType.Game, PacketSource.Server, "S2C_BATTLE_71_2_16_NTC"); public static readonly PacketId C2S_BATTLE_CONTENT_CONTENT_ENTRY_REQ = new PacketId(71, 3, 1, "C2S_BATTLE_CONTENT_CONTENT_ENTRY_REQ", ServerType.Game, PacketSource.Client); public static readonly PacketId S2C_BATTLE_CONTENT_CONTENT_ENTRY_RES = new PacketId(71, 3, 2, "S2C_BATTLE_CONTENT_CONTENT_ENTRY_RES", ServerType.Game, PacketSource.Server); // コンテンツのエントリーに - public static readonly PacketId S2C_BATTLE_CONTENT_CONTENT_ENTRY_NTC = new PacketId(71, 3, 16, "S2C_BATTLE_71_3_16_NTC", ServerType.Game, PacketSource.Server, "S2C_BATTLE_71_3_16_NTC"); + public static readonly PacketId S2C_BATTLE_CONTENT_CONTENT_ENTRY_NTC = new PacketId(71, 3, 16, "S2C_BATTLE_CONTENT_CONTENT_ENTRY_NTC", ServerType.Game, PacketSource.Server, "S2C_BATTLE_71_3_16_NTC"); public static readonly PacketId C2S_BATTLE_CONTENT_CONTENT_FIRST_PHASE_CHANGE_REQ = new PacketId(71, 4, 1, "C2S_BATTLE_CONTENT_CONTENT_FIRST_PHASE_CHANGE_REQ", ServerType.Game, PacketSource.Client, "C2S_BATTLE_CONTENT_CONTENT_FIRST_FHASE_CHANGE_REQ"); public static readonly PacketId S2C_BATTLE_CONTENT_CONTENT_FIRST_PHASE_CHANGE_RES = new PacketId(71, 4, 2, "S2C_BATTLE_CONTENT_CONTENT_FIRST_PHASE_CHANGE_RES", ServerType.Game, PacketSource.Server, "S2C_BATTLE_CONTENT_CONTENT_FIRST_FHASE_CHANGE_RES"); // バトルコンテンツ最初のフェーズ変更 public static readonly PacketId C2S_BATTLE_CONTENT_CONTENT_RESET_REQ = new PacketId(71, 5, 1, "C2S_BATTLE_CONTENT_CONTENT_RESET_REQ", ServerType.Game, PacketSource.Client); @@ -2125,7 +2125,7 @@ private static Dictionary InitializeLoginPacketIds() public static readonly PacketId S2C_BATTLE_CONTENT_PHASE_ENTRY_GET_RECRUITMENT_STATE_RES = new PacketId(71, 9, 2, "S2C_BATTLE_CONTENT_PHASE_ENTRY_GET_RECRUITMENT_STATE_RES", ServerType.Game, PacketSource.Server); // 一斉ステージ移動待ち受け状態取得に public static readonly PacketId C2S_BATTLE_CONTENT_PHASE_ENTRY_READY_REQ = new PacketId(71, 10, 1, "C2S_BATTLE_CONTENT_PHASE_ENTRY_READY_REQ", ServerType.Game, PacketSource.Client); public static readonly PacketId S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_RES = new PacketId(71, 10, 2, "S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_RES", ServerType.Game, PacketSource.Server); // 一斉ステージ移動準備に - public static readonly PacketId S2C_BATTLE_71_10_16_NTC = new PacketId(71, 10, 16, "S2C_BATTLE_71_10_16_NTC", ServerType.Game, PacketSource.Server); + public static readonly PacketId S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_NTC = new PacketId(71, 10, 16, "S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_NTC", ServerType.Game, PacketSource.Server, "S2C_BATTLE_71_10_16_NTC"); public static readonly PacketId C2S_BATTLE_CONTENT_PHASE_ENTRY_READY_CANCEL_REQ = new PacketId(71, 11, 1, "C2S_BATTLE_CONTENT_PHASE_ENTRY_READY_CANCEL_REQ", ServerType.Game, PacketSource.Client); public static readonly PacketId S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_CANCEL_RES = new PacketId(71, 11, 2, "S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_CANCEL_RES", ServerType.Game, PacketSource.Server); // 一斉ステージ移動準備キャンセルに public static readonly PacketId S2C_BATTLE_CONTENT_AREA_CHANGE_NTC = new PacketId(71, 12, 16, "S2C_BATTLE_CONTENT_AREA_CHANGE_NTC", ServerType.Game, PacketSource.Server, "S2C_BATTLE_71_12_16_NTC"); @@ -2138,7 +2138,7 @@ private static Dictionary InitializeLoginPacketIds() public static readonly PacketId S2C_BATTLE_CONTENT_INSTANT_CLEAR_INFO_RES = new PacketId(71, 17, 2, "S2C_BATTLE_CONTENT_INSTANT_CLEAR_INFO_RES", ServerType.Game, PacketSource.Server); // バトルコンテンツ即時クリア情報取得 public static readonly PacketId C2S_BATTLE_CONTENT_CHARACTER_INFO_REQ = new PacketId(71, 18, 1, "C2S_BATTLE_CONTENT_CHARACTER_INFO_REQ", ServerType.Game, PacketSource.Client); public static readonly PacketId S2C_BATTLE_CONTENT_CHARACTER_INFO_RES = new PacketId(71, 18, 2, "S2C_BATTLE_CONTENT_CHARACTER_INFO_RES", ServerType.Game, PacketSource.Server); // バトルコンテンツ:進行情報の取得 - public static readonly PacketId S2C_BATTLE_71_19_16_NTC = new PacketId(71, 19, 16, "S2C_BATTLE_71_19_16_NTC", ServerType.Game, PacketSource.Server); + public static readonly PacketId S2C_BATTLE_CONTENT_STATUS_PROGRESS_NTC = new PacketId(71, 19, 16, "S2C_BATTLE_CONTENT_STATUS_PROGRESS_NTC", ServerType.Game, PacketSource.Server, "S2C_BATTLE_71_19_16_NTC"); public static readonly PacketId C2S_BATTLE_CONTENT_PARTY_MEMBER_INFO_REQ = new PacketId(71, 20, 1, "C2S_BATTLE_CONTENT_PARTY_MEMBER_INFO_REQ", ServerType.Game, PacketSource.Client); public static readonly PacketId S2C_BATTLE_CONTENT_PARTY_MEMBER_INFO_RES = new PacketId(71, 20, 2, "S2C_BATTLE_CONTENT_PARTY_MEMBER_INFO_RES", ServerType.Game, PacketSource.Server); // パーティメンバのバトルコンテンツ情報を取得 public static readonly PacketId C2S_BATTLE_CONTENT_PARTY_MEMBER_INFO_UPDATE_REQ = new PacketId(71, 21, 1, "C2S_BATTLE_CONTENT_PARTY_MEMBER_INFO_UPDATE_REQ", ServerType.Game, PacketSource.Client); @@ -4056,7 +4056,7 @@ private static Dictionary InitializeGamePacketIds() AddPacketIdEntry(packetIds, S2C_BATTLE_CONTENT_PHASE_ENTRY_GET_RECRUITMENT_STATE_RES); AddPacketIdEntry(packetIds, C2S_BATTLE_CONTENT_PHASE_ENTRY_READY_REQ); AddPacketIdEntry(packetIds, S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_RES); - AddPacketIdEntry(packetIds, S2C_BATTLE_71_10_16_NTC); + AddPacketIdEntry(packetIds, S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_NTC); AddPacketIdEntry(packetIds, C2S_BATTLE_CONTENT_PHASE_ENTRY_READY_CANCEL_REQ); AddPacketIdEntry(packetIds, S2C_BATTLE_CONTENT_PHASE_ENTRY_READY_CANCEL_RES); AddPacketIdEntry(packetIds, S2C_BATTLE_CONTENT_AREA_CHANGE_NTC); @@ -4069,7 +4069,7 @@ private static Dictionary InitializeGamePacketIds() AddPacketIdEntry(packetIds, S2C_BATTLE_CONTENT_INSTANT_CLEAR_INFO_RES); AddPacketIdEntry(packetIds, C2S_BATTLE_CONTENT_CHARACTER_INFO_REQ); AddPacketIdEntry(packetIds, S2C_BATTLE_CONTENT_CHARACTER_INFO_RES); - AddPacketIdEntry(packetIds, S2C_BATTLE_71_19_16_NTC); + AddPacketIdEntry(packetIds, S2C_BATTLE_CONTENT_STATUS_PROGRESS_NTC); AddPacketIdEntry(packetIds, C2S_BATTLE_CONTENT_PARTY_MEMBER_INFO_REQ); AddPacketIdEntry(packetIds, S2C_BATTLE_CONTENT_PARTY_MEMBER_INFO_RES); AddPacketIdEntry(packetIds, C2S_BATTLE_CONTENT_PARTY_MEMBER_INFO_UPDATE_REQ); diff --git a/Arrowgene.Ddon.Shared/Network/StructurePacket.cs b/Arrowgene.Ddon.Shared/Network/StructurePacket.cs index dbf6359f4..a13c198ae 100644 --- a/Arrowgene.Ddon.Shared/Network/StructurePacket.cs +++ b/Arrowgene.Ddon.Shared/Network/StructurePacket.cs @@ -4,6 +4,7 @@ using System.IO; using System.Text; using Arrowgene.Ddon.Shared.Entity; +using Arrowgene.Logging; using YamlDotNet.Core; using YamlDotNet.Serialization; using YamlDotNet.Serialization.TypeInspectors; @@ -48,6 +49,7 @@ private TStruct GetStructure() public abstract class StructurePacket : Packet, IStructurePacket { + private static readonly ILogger Logger = LogProvider.Logger(typeof(StructurePacket)); public static ISerializer YamlSerializer { get; } = new SerializerBuilder() .WithTypeInspector(inspector => new MyTypeInspector(inspector)) .WithTypeConverter(new ByteArrayConverter()) @@ -72,7 +74,15 @@ public string PrintStructure() StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(PrintHeader()); stringBuilder.Append(Environment.NewLine); - YamlSerializer.Serialize(new IndentedTextWriter(new StringWriter(stringBuilder)), this); + try + { + YamlSerializer.Serialize(new IndentedTextWriter(new StringWriter(stringBuilder)), this); + } + catch (Exception e) + { + Logger.Error("Failed to serialize structure packet, can not dump."); + Logger.Exception(e); + } return stringBuilder.ToString(); } diff --git a/Arrowgene.Ddon.Test/Database/DatabaseMigratorTest.cs b/Arrowgene.Ddon.Test/Database/DatabaseMigratorTest.cs index fc71b190e..b3ab4e7ca 100644 --- a/Arrowgene.Ddon.Test/Database/DatabaseMigratorTest.cs +++ b/Arrowgene.Ddon.Test/Database/DatabaseMigratorTest.cs @@ -220,8 +220,6 @@ public void CreateListItems(DbConnection conn, Character character, StorageType public bool DeleteStorageItem(uint characterId, StorageType storageType, ushort slotNo, DbConnection? connectionIn = null) { return true; } public void DeleteAllStorageItems(DbConnection connection, uint characterId) { } public void DeleteAllEquipItems(uint commonId, DbConnection? connectionIn = null) { } - public bool DeleteToken(string token) { return true; } - public bool DeleteTokenByAccountId(int accountId) { return true; } public bool DeleteWalletPoint(uint characterId, WalletType type) { return true; } public DbConnection OpenNewConnection() { return null; } public DbConnection OpenExistingConnection() { return null; } @@ -315,12 +313,12 @@ public void Execute(DbConnection conn, string sql, bool rethrowException = false public Pawn SelectPawn(DbConnection connection, uint pawnId) { return new Pawn(); } public List SelectPawnsByCharacterId(uint characterId, DbConnection? connectionIn = null) { return new List(); } public List SelectReleasedWarpPoints(uint characterId) { return new List(); } - public GameToken SelectToken(string tokenStr) { return new GameToken(); } - public GameToken SelectTokenByAccountId(int accountId) { return new GameToken(); } + public GameToken SelectToken(string tokenStr, DbConnection? connectionIn = null) { return new GameToken(); } + public bool ReplaceToken(GameToken token, DbConnection? connectionIn = null) { return true; } + public bool DeleteTokenByAccountId(int accountId, DbConnection? connectionIn = null) { return true; } public List SelectEquipItemByCharacter(uint characterCommonId) { return new List(); } public Storages SelectAllStoragesByCharacterId(uint characterId) { return new Storages(new Dictionary()); } public bool SetMeta(DatabaseMeta meta) { return true; } - public bool SetToken(GameToken token) { return true; } public bool UpdateAccount(Account account) { return true; } public int UpdateBazaarExhibiton(BazaarExhibition exhibition) { return 1; } public bool UpdateCharacterArisenProfile(Character character) { return true; }