From 8ed1473c5da83efd068599f34cb7f2852b0d0e51 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Thu, 3 Oct 2024 23:08:44 -0400 Subject: [PATCH 1/2] feat: Equipment Presets Added the ability to save equipment presets. --- .../Arrowgene.Ddon.Database.csproj | 4 - .../Script/migration_equipment_preset.sql | 20 ++++ .../Files/Database/Script/schema_sqlite.sql | 22 +++- Arrowgene.Ddon.Database/IDatabase.cs | 10 ++ .../Sql/Core/DdonSqlDbEquipPresetTemplate.cs | 89 +++++++++++++++ .../Sql/Core/DdonSqlDbEquipmentPreset.cs | 106 ++++++++++++++++++ Arrowgene.Ddon.GameServer/DdonGameServer.cs | 3 + Arrowgene.Ddon.GameServer/GameClient.cs | 1 + .../Handler/EquipGetEquipPresetListHandler.cs | 64 +++++++++++ .../Handler/EquipUpdateEquipPresetHandler.cs | 50 +++++++++ .../EquipUpdateEquipPresetNameHandler.cs | 37 ++++++ .../Handler/PawnGetMypawnDataHandler.cs | 1 + .../ProfileGetMyCharacterProfileHandler.cs | 2 + .../Entity/EntitySerializer.cs | 10 ++ .../C2SEquipGetEquipPresetListReq.cs | 23 ++++ .../C2SEquipUpdateEquipPresetNameReq.cs | 34 ++++++ .../C2SEquipUpdateEquipPresetReq.cs | 41 +++++++ .../S2CEquipGetEquipPresetListRes.cs | 36 ++++++ .../S2CEquipUpdateEquipPresetNameRes.cs | 30 +++++ .../S2CEquipUpdateEquipPresetRes.cs | 35 ++++++ .../Entity/Structure/CDataEquipPreset.cs | 45 ++++++++ .../Entity/Structure/CDataPresetEquipInfo.cs | 52 +++++++++ .../Entity/Structure/CDatapresetEquipUnk0.cs | 35 ++++++ Arrowgene.Ddon.Shared/Model/Storages.cs | 20 +++- .../Database/DatabaseMigratorTest.cs | 12 +- docs/quests/quests.md | 28 +++++ 26 files changed, 802 insertions(+), 8 deletions(-) create mode 100644 Arrowgene.Ddon.Database/Files/Database/Script/migration_equipment_preset.sql create mode 100644 Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipPresetTemplate.cs create mode 100644 Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipmentPreset.cs create mode 100644 Arrowgene.Ddon.GameServer/Handler/EquipGetEquipPresetListHandler.cs create mode 100644 Arrowgene.Ddon.GameServer/Handler/EquipUpdateEquipPresetHandler.cs create mode 100644 Arrowgene.Ddon.GameServer/Handler/EquipUpdateEquipPresetNameHandler.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipGetEquipPresetListReq.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipUpdateEquipPresetNameReq.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipUpdateEquipPresetReq.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipGetEquipPresetListRes.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipUpdateEquipPresetNameRes.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipUpdateEquipPresetRes.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/Structure/CDataEquipPreset.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/Structure/CDataPresetEquipInfo.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/Structure/CDatapresetEquipUnk0.cs diff --git a/Arrowgene.Ddon.Database/Arrowgene.Ddon.Database.csproj b/Arrowgene.Ddon.Database/Arrowgene.Ddon.Database.csproj index 583b34e7c..4e47c9f78 100644 --- a/Arrowgene.Ddon.Database/Arrowgene.Ddon.Database.csproj +++ b/Arrowgene.Ddon.Database/Arrowgene.Ddon.Database.csproj @@ -33,10 +33,6 @@ - - - - diff --git a/Arrowgene.Ddon.Database/Files/Database/Script/migration_equipment_preset.sql b/Arrowgene.Ddon.Database/Files/Database/Script/migration_equipment_preset.sql new file mode 100644 index 000000000..adcb4244b --- /dev/null +++ b/Arrowgene.Ddon.Database/Files/Database/Script/migration_equipment_preset.sql @@ -0,0 +1,20 @@ +CREATE TABLE "ddon_equip_preset" +( + "character_common_id" INTEGER NOT NULL, + "preset_no" INTEGER NOT NULL, + "job_id" INTEGER NOT NULL, + "preset_name" TEXT NOT NULL, + CONSTRAINT "pk_ddon_equip_preset" PRIMARY KEY ("character_common_id", "job_id", "preset_no"), + CONSTRAINT "fk_ddon_equip_preset_character_common_id" FOREIGN KEY ("character_common_id") REFERENCES "ddon_character_common" ("character_common_id") ON DELETE CASCADE +); + +CREATE TABLE "ddon_equip_preset_template" +( + "character_common_id" INTEGER NOT NULL, + "preset_no" INTEGER NOT NULL, + "job_id" INTEGER NOT NULL, + "slot_no" INTEGER NOT NULL, + "item_uid" VARCHAR(8) NOT NULL, + CONSTRAINT "pk_ddon_equip_preset_template" PRIMARY KEY ("character_common_id", "job_id", "preset_no", "slot_no"), + CONSTRAINT "fk_ddon_equip_preset_template_character_common_id" FOREIGN KEY ("character_common_id", "job_id", "preset_no") REFERENCES "ddon_equip_preset" ("character_common_id", "job_id", "preset_no") ON DELETE CASCADE +); diff --git a/Arrowgene.Ddon.Database/Files/Database/Script/schema_sqlite.sql b/Arrowgene.Ddon.Database/Files/Database/Script/schema_sqlite.sql index 002193e35..e02273101 100644 --- a/Arrowgene.Ddon.Database/Files/Database/Script/schema_sqlite.sql +++ b/Arrowgene.Ddon.Database/Files/Database/Script/schema_sqlite.sql @@ -513,7 +513,6 @@ CREATE TABLE IF NOT EXISTS "ddon_contact_list" "requester_favorite" BOOLEAN NOT NULL, "requested_favorite" BOOLEAN NOT NULL, CONSTRAINT "fk_ddon_contact_list_requester_character_id" FOREIGN KEY ("requester_character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE, - CONSTRAINT "fk_ddon_contact_list_requested_character_id" FOREIGN KEY ("requested_character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE, CONSTRAINT "uq_ddon_contact_list_requester_character_id_requested_character_id" UNIQUE ("requester_character_id", "requested_character_id") ); @@ -750,3 +749,24 @@ CREATE TABLE IF NOT EXISTS "ddon_clan_membership" CONSTRAINT "fk_ddon_clan_membership_character_id" FOREIGN KEY ("character_id") REFERENCES "ddon_character" ("character_id") ON DELETE CASCADE, CONSTRAINT "fk_ddon_clan_membership_clan_id" FOREIGN KEY ("clan_id") REFERENCES "ddon_clan_param" ("clan_id") ON DELETE CASCADE ); + +CREATE TABLE IF NOT EXISTS "ddon_equip_preset" +( + "character_common_id" INTEGER NOT NULL, + "job_id" INTEGER NOT NULL, + "preset_no" INTEGER NOT NULL, + "preset_name" TEXT NOT NULL, + CONSTRAINT "pk_ddon_equip_preset" PRIMARY KEY ("character_common_id", "job_id", "preset_no"), + CONSTRAINT "fk_ddon_equip_preset_character_common_id" FOREIGN KEY ("character_common_id") REFERENCES "ddon_character_common" ("character_common_id") ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS "ddon_equip_preset_template" +( + "character_common_id" INTEGER NOT NULL, + "job_id" INTEGER NOT NULL, + "preset_no" INTEGER NOT NULL, + "slot_no" INTEGER NOT NULL, + "item_uid" VARCHAR(8) NOT NULL, + CONSTRAINT "pk_ddon_equip_preset_template" PRIMARY KEY ("character_common_id", "job_id", "preset_no", "slot_no"), + CONSTRAINT "fk_ddon_equip_preset_template_character_common_id" FOREIGN KEY ("character_common_id", "job_id", "preset_no") REFERENCES "ddon_equip_preset" ("character_common_id", "job_id", "preset_no") ON DELETE CASCADE +); diff --git a/Arrowgene.Ddon.Database/IDatabase.cs b/Arrowgene.Ddon.Database/IDatabase.cs index ad3d09165..898e77341 100644 --- a/Arrowgene.Ddon.Database/IDatabase.cs +++ b/Arrowgene.Ddon.Database/IDatabase.cs @@ -582,5 +582,15 @@ bool InsertBBMContentTreasure( List GetClanMemberList(uint clanId, DbConnection? connectionIn = null); CDataClanMemberInfo GetClanMember(uint characterId, DbConnection? connectionIn = null); bool UpdateClanMember(CDataClanMemberInfo memberInfo, uint clanId, DbConnection? connectionIn = null); + + // Equipment Preset + bool InsertEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName); + bool UpdateEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName); + List SelectEquipmentPresets(uint characterCommonId, JobId jobId); + bool DeleteEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo); + + bool InsertEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo, uint slotNo, string itemUId); + List SelectEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo); + bool DeleteEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo); } } diff --git a/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipPresetTemplate.cs b/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipPresetTemplate.cs new file mode 100644 index 000000000..5eb08776d --- /dev/null +++ b/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipPresetTemplate.cs @@ -0,0 +1,89 @@ +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Data.Common; +using System.Reflection.Metadata.Ecma335; +using System.Xml; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Model; + +namespace Arrowgene.Ddon.Database.Sql.Core +{ + public abstract partial class DdonSqlDb : SqlDb + where TCon : DbConnection + where TCom : DbCommand + where TReader : DbDataReader + { + protected static readonly string[] EquipmentTmeplateFields = new string[] + { + "character_common_id", "job_id", "preset_no", "slot_no", "item_uid" + }; + + private readonly string SqlInsertEquipmentPresetTemplate = $"INSERT INTO \"ddon_equip_preset_template\" ({BuildQueryField(EquipmentTmeplateFields)}) VALUES ({BuildQueryInsert(EquipmentTmeplateFields)});"; + private static readonly string SqlSelectEquipmentPresetTemplate = $"SELECT {BuildQueryField(EquipmentTmeplateFields)} FROM \"ddon_equip_preset_template\" WHERE \"character_common_id\" = @character_common_id AND \"job_id\" = @job_id AND \"preset_no\" = @preset_no;"; + private static readonly string SqlDeleteEquipmentPresetTemplate = $"DELETE FROM \"ddon_equip_preset_template\" WHERE \"character_common_id\"=@character_common_id AND \"job_id\"=@job_id AND \"preset_no\"=@preset_no;"; + + public bool InsertEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo, uint slotNo, string itemUId) + { + using TCon connection = OpenNewConnection(); + return InsertEquipmentPresetTemplate(connection, characterCommonId, jobId, presetNo, slotNo, itemUId); + } + + public bool InsertEquipmentPresetTemplate(TCon conn, uint characterCommonId, JobId jobId, uint presetNo, uint slotNo, string itemUId) + { + return ExecuteNonQuery(conn, SqlInsertEquipmentPresetTemplate, command => + { + AddParameter(command, "character_common_id", characterCommonId); + AddParameter(command, "job_id", (byte)jobId); + AddParameter(command, "preset_no", presetNo); + AddParameter(command, "slot_no", slotNo); + AddParameter(command, "item_uid", itemUId); + }) == 1; + } + + public List SelectEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo) + { + using TCon connection = OpenNewConnection(); + return SelectEquipmentPresetTemplate(connection, characterCommonId, jobId, presetNo); + } + + public List SelectEquipmentPresetTemplate(TCon conn, uint characterCommonId, JobId jobId, uint presetNo) + { + var results = new List(); + ExecuteInTransaction(conn => + { + ExecuteReader(conn, SqlSelectEquipmentPresetTemplate, + command => { + AddParameter(command, "character_common_id", characterCommonId); + AddParameter(command, "job_id", (byte)jobId); + AddParameter(command, "preset_no", presetNo); + }, reader => { + while (reader.Read()) + { + results.Add(new CDataPresetEquipInfo() + { + ItemUId = GetString(reader, "item_uid"), + EquipSlotNo = GetByte(reader, "slot_no") + }); + } + }); + }); + return results; + } + + public bool DeleteEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo) + { + using TCon connection = OpenNewConnection(); + return DeleteEquipmentPresetTemplate(connection, characterCommonId, jobId, presetNo); + } + + public bool DeleteEquipmentPresetTemplate(TCon conn, uint characterCommonId, JobId jobId, uint presetNo) + { + return ExecuteNonQuery(conn, SqlDeleteEquipmentPresetTemplate, command => + { + AddParameter(command, "character_common_id", characterCommonId); + AddParameter(command, "job_id", (byte)jobId); + AddParameter(command, "preset_no", presetNo); + }) == 1; + } + } +} diff --git a/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipmentPreset.cs b/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipmentPreset.cs new file mode 100644 index 000000000..26023239b --- /dev/null +++ b/Arrowgene.Ddon.Database/Sql/Core/DdonSqlDbEquipmentPreset.cs @@ -0,0 +1,106 @@ +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Data.Common; +using System.Reflection.Metadata.Ecma335; +using System.Xml; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Model; + +namespace Arrowgene.Ddon.Database.Sql.Core +{ + public abstract partial class DdonSqlDb : SqlDb + where TCon : DbConnection + where TCom : DbCommand + where TReader : DbDataReader + { + protected static readonly string[] EquipmentPresetFields = new string[] + { + "character_common_id", "job_id", "preset_no", "preset_name" + }; + + private readonly string SqlInsertEquipmentPreset = $"INSERT INTO \"ddon_equip_preset\" ({BuildQueryField(EquipmentPresetFields)}) VALUES ({BuildQueryInsert(EquipmentPresetFields)});"; + private static readonly string SqlSelectEquipmentPresets = $"SELECT {BuildQueryField(EquipmentPresetFields)} FROM \"ddon_equip_preset\" WHERE \"character_common_id\" = @character_common_id AND \"job_id\" = @job_id;"; + private static readonly string SqlUpdateEquipmentPreset = $"UPDATE \"ddon_equip_preset\" SET {BuildQueryUpdate(EquipmentPresetFields)} WHERE \"character_common_id\"=@character_common_id AND \"preset_no\"=@preset_no"; + private static readonly string SqlDeleteEquipmentPreset = $"DELETE FROM \"ddon_equip_preset\" WHERE \"character_common_id\"=@character_common_id AND \"job_id\"=@job_id AND \"preset_no\"=@preset_no;"; + + public bool InsertEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName) + { + using TCon connection = OpenNewConnection(); + return InsertEquipmentPreset(connection, characterCommonId, jobId, presetNo, presetName); + } + + public bool InsertEquipmentPreset(TCon conn, uint characterCommonId, JobId jobId, uint presetNo, string presetName) + { + return ExecuteNonQuery(conn, SqlInsertEquipmentPreset, command => + { + AddParameter(command, "character_common_id", characterCommonId); + AddParameter(command, "job_id", (byte)jobId); + AddParameter(command, "preset_no", presetNo); + AddParameter(command, "preset_name", presetName); + }) == 1; + } + + public bool UpdateEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName) + { + using TCon connection = OpenNewConnection(); + return UpdateEquipmentPreset(connection, characterCommonId, jobId, presetNo, presetName); + } + + public bool UpdateEquipmentPreset(TCon conn, uint characterCommonId, JobId jobId, uint presetNo, string presetName) + { + return ExecuteNonQuery(conn, SqlUpdateEquipmentPreset, command => + { + AddParameter(command, "character_common_id", characterCommonId); + AddParameter(command, "job_id", (byte)jobId); + AddParameter(command, "preset_no", presetNo); + AddParameter(command, "preset_name", presetName); + }) == 1; + } + + public List SelectEquipmentPresets(uint characterCommonId, JobId jobId) + { + using TCon connection = OpenNewConnection(); + return SelectEquipmentPresets(connection, characterCommonId, jobId); + } + + public List SelectEquipmentPresets(TCon conn, uint characterCommonId, JobId jobId) + { + var results = new List(); + ExecuteInTransaction(conn => + { + ExecuteReader(conn, SqlSelectEquipmentPresets, + command => { + AddParameter(command, "@character_common_id", characterCommonId); + AddParameter(command, "@job_id", (byte) jobId); + }, reader => { + while (reader.Read()) + { + results.Add(new CDataEquipPreset() + { + Job = (JobId)GetByte(reader, "job_id"), + PresetNo = GetUInt32(reader, "preset_no"), + PresetName = GetString(reader, "preset_name") + }); + } + }); + }); + return results; + } + + public bool DeleteEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo) + { + using TCon connection = OpenNewConnection(); + return DeleteEquipmentPreset(connection, characterCommonId, jobId, presetNo); + } + + public bool DeleteEquipmentPreset(TCon conn, uint characterCommonId, JobId jobId, uint presetNo) + { + return ExecuteNonQuery(conn, SqlDeleteEquipmentPreset, command => + { + AddParameter(command, "character_common_id", characterCommonId); + AddParameter(command, "job_id", (byte) jobId); + AddParameter(command, "preset_no", presetNo); + }) == 1; + } + } +} diff --git a/Arrowgene.Ddon.GameServer/DdonGameServer.cs b/Arrowgene.Ddon.GameServer/DdonGameServer.cs index 397c0698f..48e150765 100644 --- a/Arrowgene.Ddon.GameServer/DdonGameServer.cs +++ b/Arrowgene.Ddon.GameServer/DdonGameServer.cs @@ -340,6 +340,9 @@ private void LoadPacketHandler() AddHandler(new EquipUpdateHideCharacterLanternHandler(this)); AddHandler(new EquipUpdateHidePawnHeadArmorHandler(this)); AddHandler(new EquipUpdateHidePawnLanternHandler(this)); + AddHandler(new EquipGetEquipPresetListHandler(this)); + AddHandler(new EquipUpdateEquipPresetHandler(this)); + AddHandler(new EquipUpdateEquipPresetNameHandler(this)); AddHandler(new EventStartHandler(this)); AddHandler(new EventEndHandler(this)); diff --git a/Arrowgene.Ddon.GameServer/GameClient.cs b/Arrowgene.Ddon.GameServer/GameClient.cs index 970ee56de..0e2488e05 100644 --- a/Arrowgene.Ddon.GameServer/GameClient.cs +++ b/Arrowgene.Ddon.GameServer/GameClient.cs @@ -53,6 +53,7 @@ public void UpdateIdentity() public InstanceEventDropItemManager InstanceEventDropItemManager { get; } public GameMode GameMode { get; set; } + public uint EquipPresetIndex { get; set; } // TODO: Place somewhere else more sensible public uint LastWarpPointId { get; set; } diff --git a/Arrowgene.Ddon.GameServer/Handler/EquipGetEquipPresetListHandler.cs b/Arrowgene.Ddon.GameServer/Handler/EquipGetEquipPresetListHandler.cs new file mode 100644 index 000000000..8400a7884 --- /dev/null +++ b/Arrowgene.Ddon.GameServer/Handler/EquipGetEquipPresetListHandler.cs @@ -0,0 +1,64 @@ + +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.Logging; +using System.Drawing; +using System.Linq; + +namespace Arrowgene.Ddon.GameServer.Handler +{ + public class EquipGetEquipPresetListHandler : GameRequestPacketHandler + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(EquipGetEquipPresetListHandler)); + + public EquipGetEquipPresetListHandler(DdonGameServer server) : base(server) + { + } + + public override S2CEquipGetEquipPresetListRes Handle(GameClient client, C2SEquipGetEquipPresetListReq request) + { + var results = new S2CEquipGetEquipPresetListRes(); + + CharacterCommon characterCommon; + if (client.EquipPresetIndex == 0) + { + characterCommon = client.Character; + } + else + { + characterCommon = client.Character.PawnBySlotNo((byte)client.EquipPresetIndex); + } + + foreach (var presetInfo in Server.Database.SelectEquipmentPresets(characterCommon.CommonId, characterCommon.Job)) + { + var presetItems = Server.Database.SelectEquipmentPresetTemplate(characterCommon.CommonId, presetInfo.Job, presetInfo.PresetNo); + foreach (var presetItem in presetItems) + { + var matches = client.Character.Storage.FindItemByUIdInStorage(ItemManager.AllItemStorages, presetItem.ItemUId); + if (matches == null) + { + // Item was deleted or sold? + continue; + } + + var storageType = matches.Item1; + var item = matches.Item2.Item2; + + presetItem.ItemId = item.ItemId; + presetItem.Color = item.Color; + presetItem.PlusValue = item.PlusValue; + presetItem.EquipElementParamList = item.EquipElementParamList; + + presetInfo.PresetEquipInfoList.Add(presetItem); + } + + results.EquipPresetList.Add(presetInfo); + } + + return results; + } + } +} diff --git a/Arrowgene.Ddon.GameServer/Handler/EquipUpdateEquipPresetHandler.cs b/Arrowgene.Ddon.GameServer/Handler/EquipUpdateEquipPresetHandler.cs new file mode 100644 index 000000000..edaa83405 --- /dev/null +++ b/Arrowgene.Ddon.GameServer/Handler/EquipUpdateEquipPresetHandler.cs @@ -0,0 +1,50 @@ +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.Collections.Generic; + +namespace Arrowgene.Ddon.GameServer.Handler +{ + public class EquipUpdateEquipPresetHandler : GameRequestPacketHandler + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(EquipUpdateEquipPresetHandler)); + + public EquipUpdateEquipPresetHandler(DdonGameServer server) : base(server) + { + } + + public override S2CEquipUpdateEquipPresetRes Handle(GameClient client, C2SEquipUpdateEquipPresetReq request) + { + var result = new S2CEquipUpdateEquipPresetRes(); + + CharacterCommon characterCommon; + if (client.EquipPresetIndex == 0) + { + characterCommon = client.Character; + } + else + { + characterCommon = client.Character.PawnBySlotNo((byte) request.PawnId); + } + + result.EquipPreset.PresetName = request.PresetName; + result.EquipPreset.PresetNo = request.PresetNo; + result.EquipPreset.PresetEquipInfoList = characterCommon.Equipment.AsCDataPresetEquipInfo((EquipType) request.Type); + result.EquipPreset.Job = characterCommon.Job; + + // TODO: Make transaction + Server.Database.DeleteEquipmentPreset(characterCommon.CommonId, characterCommon.Job, request.PresetNo); + Server.Database.InsertEquipmentPreset(characterCommon.CommonId, characterCommon.Job, request.PresetNo, request.PresetName); + + foreach (var item in result.EquipPreset.PresetEquipInfoList) + { + Server.Database.InsertEquipmentPresetTemplate(characterCommon.CommonId, characterCommon.Job, request.PresetNo, item.EquipSlotNo, item.ItemUId); + } + + return result; + } + } +} + diff --git a/Arrowgene.Ddon.GameServer/Handler/EquipUpdateEquipPresetNameHandler.cs b/Arrowgene.Ddon.GameServer/Handler/EquipUpdateEquipPresetNameHandler.cs new file mode 100644 index 000000000..b228684cd --- /dev/null +++ b/Arrowgene.Ddon.GameServer/Handler/EquipUpdateEquipPresetNameHandler.cs @@ -0,0 +1,37 @@ +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.Collections.Generic; +using System.Linq; + +namespace Arrowgene.Ddon.GameServer.Handler +{ + public class EquipUpdateEquipPresetNameHandler : GameRequestPacketHandler + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(EquipUpdateEquipPresetNameHandler)); + + public EquipUpdateEquipPresetNameHandler(DdonGameServer server) : base(server) + { + } + + public override S2CEquipUpdateEquipPresetNameRes Handle(GameClient client, C2SEquipUpdateEquipPresetNameReq request) + { + CharacterCommon characterCommon; + if (client.EquipPresetIndex == 0) + { + characterCommon = client.Character; + } + else + { + characterCommon = client.Character.PawnBySlotNo((byte)client.EquipPresetIndex); + } + + var result = Server.Database.SelectEquipmentPresets(characterCommon.CommonId, characterCommon.Job).Where(x => x.PresetNo == request.PresetNo).FirstOrDefault(); + Server.Database.UpdateEquipmentPreset(characterCommon.CommonId, result.Job, result.PresetNo, request.PresetName); + return new S2CEquipUpdateEquipPresetNameRes(); + } + } +} + diff --git a/Arrowgene.Ddon.GameServer/Handler/PawnGetMypawnDataHandler.cs b/Arrowgene.Ddon.GameServer/Handler/PawnGetMypawnDataHandler.cs index 2eda945bc..0386ed132 100644 --- a/Arrowgene.Ddon.GameServer/Handler/PawnGetMypawnDataHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/PawnGetMypawnDataHandler.cs @@ -26,6 +26,7 @@ public override void Handle(GameClient client, StructurePacket().Read(new byte[] {0x0, 0x20, 0xB8, 0xF8, 0x0, 0xDB, 0x3B, 0xCF, 0x0, 0x20, 0xB8, 0xF8, 0x0, 0x5, 0x44, 0x69, 0x61, 0x6E, 0x61, 0x0, 0x6, 0x53, 0x65, 0x65, 0x6C, 0x69, 0x78, 0x0, 0x3, 0x53, 0x3B, 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xB8, 0xC0, 0xC1}); pcap33.CharacterId = client.Character.CharacterId; diff --git a/Arrowgene.Ddon.GameServer/Handler/ProfileGetMyCharacterProfileHandler.cs b/Arrowgene.Ddon.GameServer/Handler/ProfileGetMyCharacterProfileHandler.cs index 48f28b67b..fdb2abafa 100644 --- a/Arrowgene.Ddon.GameServer/Handler/ProfileGetMyCharacterProfileHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/ProfileGetMyCharacterProfileHandler.cs @@ -23,6 +23,8 @@ public ProfileGetMyCharacterProfileHandler(DdonGameServer server) : base(server) public override void Handle(GameClient client, StructurePacket packet) { + client.EquipPresetIndex = 0; + S2CProfileGetMyCharacterProfileRes Result = new S2CProfileGetMyCharacterProfileRes(); Result.OrbStatusList = _OrbUnlockManager.GetOrbPageStatus(client.Character); Result.AbilityCostMax = _CharacterManager.GetMaxAugmentAllocation(client.Character); diff --git a/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs b/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs index b3c040e41..ff2df6eba 100644 --- a/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs +++ b/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs @@ -129,6 +129,7 @@ static EntitySerializer() Create(new S2CCraftCraftRankUpNtc.Serializer()); Create(new CDataCurrentEquipInfo.Serializer()); Create(new CDataEquipSlot.Serializer()); + Create(new CDataEquipPreset.Serializer()); Create(new CDataDeliveredItem.Serializer()); Create(new CDataDeliveredItemRecord.Serializer()); Create(new CDataDeliveryItem.Serializer()); @@ -278,6 +279,8 @@ static EntitySerializer() Create(new CDataPlayPointDataSerializer()); Create(new CDataPresetAbilityParam.Serializer()); + Create(new CDataPresetEquipInfo.Serializer()); + Create(new CDatapresetEquipUnk0.Serializer()); Create(new CDataPriorityQuest.Serializer()); Create(new CDataPriorityQuestSetting.Serializer()); @@ -522,6 +525,9 @@ static EntitySerializer() Create(new C2SEquipUpdateHideCharacterLanternReq.Serializer()); Create(new C2SEquipUpdateHidePawnHeadArmorReq.Serializer()); Create(new C2SEquipUpdateHidePawnLanternReq.Serializer()); + Create(new C2SEquipGetEquipPresetListReq.Serializer()); + Create(new C2SEquipUpdateEquipPresetReq.Serializer()); + Create(new C2SEquipUpdateEquipPresetNameReq.Serializer()); Create(new C2SEntryBoardEntryBoardListReq.Serializer()); Create(new C2SEntryBoardEntryBoardItemCreateReq.Serializer()); @@ -1020,6 +1026,10 @@ static EntitySerializer() Create(new S2CEquipUpdateHideCharacterLanternRes.Serializer()); Create(new S2CEquipUpdateHidePawnHeadArmorRes.Serializer()); Create(new S2CEquipUpdateHidePawnLanternRes.Serializer()); + Create(new S2CEquipGetEquipPresetListRes.Serializer()); + Create(new S2CEquipUpdateEquipPresetRes.Serializer()); + Create(new S2CEquipUpdateEquipPresetNameRes.Serializer()); + Create(new S2CExtendEquipSlotNtc.Serializer()); Create(new S2CGpGetGpRes.Serializer()); Create(new S2CGpGetGpDetailRes.Serializer()); diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipGetEquipPresetListReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipGetEquipPresetListReq.cs new file mode 100644 index 000000000..55c026aca --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipGetEquipPresetListReq.cs @@ -0,0 +1,23 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class C2SEquipGetEquipPresetListReq : IPacketStructure + { + public PacketId Id => PacketId.C2S_EQUIP_GET_EQUIP_PRESET_LIST_REQ; + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, C2SEquipGetEquipPresetListReq obj) + { + } + + public override C2SEquipGetEquipPresetListReq Read(IBuffer buffer) + { + C2SEquipGetEquipPresetListReq obj = new C2SEquipGetEquipPresetListReq(); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipUpdateEquipPresetNameReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipUpdateEquipPresetNameReq.cs new file mode 100644 index 000000000..6916f9d9e --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipUpdateEquipPresetNameReq.cs @@ -0,0 +1,34 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class C2SEquipUpdateEquipPresetNameReq : IPacketStructure + { + public PacketId Id => PacketId.C2S_EQUIP_UPDATE_EQUIP_PRESET_NAME_REQ; + + public C2SEquipUpdateEquipPresetNameReq() + { + } + + public uint PresetNo { get; set; } + public string PresetName { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, C2SEquipUpdateEquipPresetNameReq obj) + { + WriteUInt32(buffer, obj.PresetNo); + WriteMtString(buffer, obj.PresetName); + } + + public override C2SEquipUpdateEquipPresetNameReq Read(IBuffer buffer) + { + C2SEquipUpdateEquipPresetNameReq obj = new C2SEquipUpdateEquipPresetNameReq(); + obj.PresetNo = ReadUInt32(buffer); + obj.PresetName = ReadMtString(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipUpdateEquipPresetReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipUpdateEquipPresetReq.cs new file mode 100644 index 000000000..1db4e09e5 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEquipUpdateEquipPresetReq.cs @@ -0,0 +1,41 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class C2SEquipUpdateEquipPresetReq : IPacketStructure + { + public C2SEquipUpdateEquipPresetReq() + { + PresetName = string.Empty; + } + + public PacketId Id => PacketId.C2S_EQUIP_UPDATE_EQUIP_PRESET_REQ; + + public uint PresetNo { get; set; } + public uint PawnId { get; set; } + public uint Type { get; set; } + public string PresetName { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, C2SEquipUpdateEquipPresetReq obj) + { + WriteUInt32(buffer, obj.PresetNo); + WriteUInt32(buffer, obj.PawnId); + WriteUInt32(buffer, obj.Type); + WriteMtString(buffer, obj.PresetName); + } + + public override C2SEquipUpdateEquipPresetReq Read(IBuffer buffer) + { + C2SEquipUpdateEquipPresetReq obj = new C2SEquipUpdateEquipPresetReq(); + obj.PresetNo = ReadUInt32(buffer); + obj.PawnId = ReadUInt32(buffer); + obj.Type = ReadUInt32(buffer); + obj.PresetName = ReadMtString(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipGetEquipPresetListRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipGetEquipPresetListRes.cs new file mode 100644 index 000000000..b39013e8d --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipGetEquipPresetListRes.cs @@ -0,0 +1,36 @@ +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 S2CEquipGetEquipPresetListRes : ServerResponse + { + public override PacketId Id => PacketId.S2C_EQUIP_GET_EQUIP_PRESET_LIST_RES; + + public S2CEquipGetEquipPresetListRes() + { + EquipPresetList = new List(); + } + + public List EquipPresetList; + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CEquipGetEquipPresetListRes obj) + { + WriteServerResponse(buffer, obj); + WriteEntityList(buffer, obj.EquipPresetList); + } + + public override S2CEquipGetEquipPresetListRes Read(IBuffer buffer) + { + S2CEquipGetEquipPresetListRes obj = new S2CEquipGetEquipPresetListRes(); + ReadServerResponse(buffer, obj); + obj.EquipPresetList = ReadEntityList(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipUpdateEquipPresetNameRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipUpdateEquipPresetNameRes.cs new file mode 100644 index 000000000..78d199d16 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipUpdateEquipPresetNameRes.cs @@ -0,0 +1,30 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CEquipUpdateEquipPresetNameRes : ServerResponse + { + public override PacketId Id => PacketId.S2C_EQUIP_UPDATE_EQUIP_PRESET_NAME_RES; + + public S2CEquipUpdateEquipPresetNameRes() + { + } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CEquipUpdateEquipPresetNameRes obj) + { + WriteServerResponse(buffer, obj); + } + + public override S2CEquipUpdateEquipPresetNameRes Read(IBuffer buffer) + { + S2CEquipUpdateEquipPresetNameRes obj = new S2CEquipUpdateEquipPresetNameRes(); + ReadServerResponse(buffer, obj); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipUpdateEquipPresetRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipUpdateEquipPresetRes.cs new file mode 100644 index 000000000..2a0819d38 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEquipUpdateEquipPresetRes.cs @@ -0,0 +1,35 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CEquipUpdateEquipPresetRes : ServerResponse + { + public override PacketId Id => PacketId.S2C_EQUIP_UPDATE_EQUIP_PRESET_RES; + + public S2CEquipUpdateEquipPresetRes() + { + EquipPreset = new CDataEquipPreset(); + } + + public CDataEquipPreset EquipPreset { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CEquipUpdateEquipPresetRes obj) + { + WriteServerResponse(buffer, obj); + WriteEntity(buffer, obj.EquipPreset); + } + + public override S2CEquipUpdateEquipPresetRes Read(IBuffer buffer) + { + S2CEquipUpdateEquipPresetRes obj = new S2CEquipUpdateEquipPresetRes(); + ReadServerResponse(buffer, obj); + obj.EquipPreset = ReadEntity(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/Structure/CDataEquipPreset.cs b/Arrowgene.Ddon.Shared/Entity/Structure/CDataEquipPreset.cs new file mode 100644 index 000000000..2f1505823 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/Structure/CDataEquipPreset.cs @@ -0,0 +1,45 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Model; +using System.Collections.Generic; + +namespace Arrowgene.Ddon.Shared.Entity.Structure +{ + public class CDataEquipPreset + { + public CDataEquipPreset() + { + PresetName = string.Empty; + PresetEquipInfoList = new List(); + PresetJobItemList = new List(); + } + + public uint PresetNo { get; set; } + public string PresetName { get; set; } + public JobId Job { get; set; } + public List PresetEquipInfoList { get; set; } + public List PresetJobItemList { get; set; } + + public class Serializer : EntitySerializer + { + public override void Write(IBuffer buffer, CDataEquipPreset obj) + { + WriteUInt32(buffer, obj.PresetNo); + WriteMtString(buffer, obj.PresetName); + WriteByte(buffer, (byte) obj.Job); + WriteEntityList(buffer, obj.PresetEquipInfoList); + WriteEntityList(buffer, obj.PresetJobItemList); + } + + public override CDataEquipPreset Read(IBuffer buffer) + { + CDataEquipPreset obj = new CDataEquipPreset(); + obj.PresetNo = ReadUInt32(buffer); + obj.PresetName = ReadMtString(buffer); + obj.Job = (JobId)ReadByte(buffer); + obj.PresetEquipInfoList = ReadEntityList(buffer); + obj.PresetJobItemList = ReadEntityList(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/Structure/CDataPresetEquipInfo.cs b/Arrowgene.Ddon.Shared/Entity/Structure/CDataPresetEquipInfo.cs new file mode 100644 index 000000000..d96e5ede3 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/Structure/CDataPresetEquipInfo.cs @@ -0,0 +1,52 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Model; +using System.Collections.Generic; + +namespace Arrowgene.Ddon.Shared.Entity.Structure +{ + public class CDataPresetEquipInfo + { + public CDataPresetEquipInfo() + { + ItemUId = string.Empty; + EquipElementParamList = new List(); + Unk0List = new List(); + } + + public string ItemUId { get; set; } + public uint ItemId { get; set; } + public byte EquipSlotNo { get; set; } + public byte Color { get; set; } + public List EquipElementParamList { get; set; } + public List Unk0List { get; set; } // Emblem? + public byte PlusValue { get; set; } + + + public class Serializer : EntitySerializer + { + public override void Write(IBuffer buffer, CDataPresetEquipInfo obj) + { + WriteMtString(buffer, obj.ItemUId); + WriteUInt32(buffer, obj.ItemId); + WriteByte(buffer, obj.EquipSlotNo); + WriteByte(buffer, obj.Color); + WriteEntityList(buffer, obj.EquipElementParamList); + WriteEntityList(buffer, obj.Unk0List); + WriteByte(buffer, obj.PlusValue); + } + + public override CDataPresetEquipInfo Read(IBuffer buffer) + { + CDataPresetEquipInfo obj = new CDataPresetEquipInfo(); + obj.ItemUId = ReadMtString(buffer); + obj.ItemId = ReadUInt32(buffer); + obj.EquipSlotNo = ReadByte(buffer); + obj.Color = ReadByte(buffer); + obj.EquipElementParamList = ReadEntityList(buffer); + obj.Unk0List = ReadEntityList(buffer); + obj.PlusValue = ReadByte(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/Structure/CDatapresetEquipUnk0.cs b/Arrowgene.Ddon.Shared/Entity/Structure/CDatapresetEquipUnk0.cs new file mode 100644 index 000000000..c14584add --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/Structure/CDatapresetEquipUnk0.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using Arrowgene.Buffers; + +namespace Arrowgene.Ddon.Shared.Entity.Structure +{ + public class CDatapresetEquipUnk0 + { + public CDatapresetEquipUnk0() + { + } + + public byte Unk0 { get; set; } + public byte Unk1 { get; set; } + public ushort Unk2 { get; set; } + + public class Serializer : EntitySerializer + { + public override void Write(IBuffer buffer, CDatapresetEquipUnk0 obj) + { + WriteByte(buffer, obj.Unk0); + WriteByte(buffer, obj.Unk1); + WriteUInt16(buffer, obj.Unk2); + } + + public override CDatapresetEquipUnk0 Read(IBuffer buffer) + { + CDatapresetEquipUnk0 obj = new CDatapresetEquipUnk0(); + obj.Unk0 = ReadByte(buffer); + obj.Unk1 = ReadByte(buffer); + obj.Unk2 = ReadUInt16(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Model/Storages.cs b/Arrowgene.Ddon.Shared/Model/Storages.cs index 176f8f5e3..b0a363f5c 100644 --- a/Arrowgene.Ddon.Shared/Model/Storages.cs +++ b/Arrowgene.Ddon.Shared/Model/Storages.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Security.Cryptography; using Arrowgene.Ddon.Shared.Entity.PacketStructure; using Arrowgene.Ddon.Shared.Entity.Structure; @@ -326,7 +327,24 @@ public List AsCDataCharacterEquipInfo(EquipType equipTy }) .ToList(); } - + + public List AsCDataPresetEquipInfo(EquipType equipType) + { + return GetItems(equipType) + .Select((x, index) => new { item = x, slot = (byte)(index + 1) }) + .Where(tuple => tuple.item != null) + .Select(tuple => new CDataPresetEquipInfo() + { + ItemId = tuple!.item.ItemId, + ItemUId = tuple!.item.UId, + EquipSlotNo = tuple!.slot, + Color = tuple!.item.Color, + PlusValue = tuple!.item.PlusValue, + EquipElementParamList = tuple!.item.EquipElementParamList + }) + .ToList(); + } + private int calculateEquipTypeOffset(EquipType equipType) { return equipType == EquipType.Performance ? 0 : EquipmentTemplate.TOTAL_EQUIP_SLOTS; diff --git a/Arrowgene.Ddon.Test/Database/DatabaseMigratorTest.cs b/Arrowgene.Ddon.Test/Database/DatabaseMigratorTest.cs index 8ed7cf237..d513fb7c5 100644 --- a/Arrowgene.Ddon.Test/Database/DatabaseMigratorTest.cs +++ b/Arrowgene.Ddon.Test/Database/DatabaseMigratorTest.cs @@ -393,6 +393,8 @@ public bool UpdateRentalPawnSlot(uint characterId, uint num) public List SelectRandomPlayerPawns(uint limit = 100) { return new List(); } public List SelectRandomPlayerPawns(DbConnection connection, uint limit = 100) { return new List(); } public uint GetPawnOwnerCharacterId(uint pawnId) { return 0; } + public List SelectRegisteredPawns(Character searchingCharacter, CDataPawnSearchParameter searchParams) { return new List(); } + public List SelectRegisteredPawns(DbConnection conn, Character searchingCharacter, CDataPawnSearchParameter searchParams) { return new List(); } public CDataCharacterSearchParam SelectCharacterNameById(uint characterId) { return new CDataCharacterSearchParam(); } public CDataCharacterSearchParam SelectCharacterNameById(DbConnection connection, uint characterId) { return new CDataCharacterSearchParam(); } @@ -408,6 +410,14 @@ public bool UpdateRentalPawnSlot(uint characterId, uint num) public CDataClanMemberInfo GetClanMember(uint characterId, DbConnection? connectionIn = null) { return new(); } public bool UpdateClanMember(CDataClanMemberInfo memberInfo, uint clanId, DbConnection? connectionIn = null) { return true; } + public bool InsertEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName) { return true; } + public bool UpdateEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo, string presetName) { return true; } + public List SelectEquipmentPresets(uint characterCommonId, JobId jobId) { return new List(); } + public bool DeleteEquipmentPreset(uint characterCommonId, JobId jobId, uint presetNo) { return true; } + public bool InsertEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo, uint slotNo, string itemUId) { return true; } + public List SelectEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo) { return new(); } + public bool DeleteEquipmentPresetTemplate(uint characterCommonId, JobId jobId, uint presetNo) { return true; } + public void AddParameter(DbCommand command, string name, object? value, DbType type) { } public void AddParameter(DbCommand command, string name, string value) { } public void AddParameter(DbCommand command, string name, Int32 value) { } @@ -430,8 +440,6 @@ public void AddParameter(DbCommand command, string name, bool value) { } public string GetString(DbDataReader reader, string column) { return ""; } public bool GetBoolean(DbDataReader reader, string column) { return false; } public byte[] GetBytes(DbDataReader reader, string column, int size) { return null; } - public List SelectRegisteredPawns(Character searchingCharacter, CDataPawnSearchParameter searchParams) { return new List(); } - public List SelectRegisteredPawns(DbConnection conn, Character searchingCharacter, CDataPawnSearchParameter searchParams) { return new List(); } } class MockMigrationStrategy : IMigrationStrategy diff --git a/docs/quests/quests.md b/docs/quests/quests.md index 3b59b06d4..87569524e 100644 --- a/docs/quests/quests.md +++ b/docs/quests/quests.md @@ -4,6 +4,34 @@ This document describes currently implemented quest information and known issues If you are interested in modifying or creating new quests, see the [generic quest state machine document](generic_quest_state_machine.md) for the details. +## Quest Types + +- Main story quests + - Quest IDs for S1 q00000001 to q00000030 + - Quest IDs for S2 q00020010 to q00020250 + - Quest IDs for S2 q00030010 to q00030440 +- Set Quests (World Quests) + - Quest IDs are q2xxxxxx +- Light Quests (Personal Quests from board) + - Quest IDs are q4xxxxxxx +- Extreme Missions + - Quest IDs are q5xxxxxxx +- Tutorial Quests (Personal Quests from NPCs) + - Quest IDs are q6xxxxxx +- World Manage Quest + - q7xxxxxx +- War Missions + - Quest IDs are q9xxxxxx + - Earlier quests look like grand missions +- Wild Hunt + - Quest IDs are q15xxxxxx +- Substory + - Quest IDs are q10xxxxxx + +- Unknown + - q3xxxxxxx (looks like more board quests?) + - q8xxxxxxx (cooking/crafting?) + ## What works in the current implementation - Currently only [Season 1.0 MSQ](#season-10), [Season 1.1 MSQ](#season-11) and a limited number of [World Quests](#world-quests) are activated. From beafd5621743fb683a1a189036e43a81d57a9a45 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 8 Oct 2024 22:52:37 -0400 Subject: [PATCH 2/2] Add migration --- .../DdonDatabaseBuilder.cs | 2 +- .../00000022_EquipPresetMigration.cs | 25 +++++++++++++++++++ Arrowgene.Ddon.Shared/Model/Storages.cs | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 Arrowgene.Ddon.Database/Sql/Core/Migration/00000022_EquipPresetMigration.cs diff --git a/Arrowgene.Ddon.Database/DdonDatabaseBuilder.cs b/Arrowgene.Ddon.Database/DdonDatabaseBuilder.cs index 1104bb88a..323770ee6 100644 --- a/Arrowgene.Ddon.Database/DdonDatabaseBuilder.cs +++ b/Arrowgene.Ddon.Database/DdonDatabaseBuilder.cs @@ -14,7 +14,7 @@ public static class DdonDatabaseBuilder private static readonly ILogger Logger = LogProvider.Logger(typeof(DdonDatabaseBuilder)); private const string DefaultSchemaFile = "Script/schema_sqlite.sql"; - public const uint Version = 21; + public const uint Version = 22; public static IDatabase Build(DatabaseSetting settings) { diff --git a/Arrowgene.Ddon.Database/Sql/Core/Migration/00000022_EquipPresetMigration.cs b/Arrowgene.Ddon.Database/Sql/Core/Migration/00000022_EquipPresetMigration.cs new file mode 100644 index 000000000..310ba0f8a --- /dev/null +++ b/Arrowgene.Ddon.Database/Sql/Core/Migration/00000022_EquipPresetMigration.cs @@ -0,0 +1,25 @@ +using System.Data.Common; + +namespace Arrowgene.Ddon.Database.Sql.Core.Migration +{ + public class EquipPresetMigration : IMigrationStrategy + { + public uint From => 21; + public uint To => 22; + + private readonly DatabaseSetting DatabaseSetting; + + public EquipPresetMigration(DatabaseSetting databaseSetting) + { + DatabaseSetting = databaseSetting; + } + + public bool Migrate(IDatabase db, DbConnection conn) + { + string adaptedSchema = DdonDatabaseBuilder.GetAdaptedSchema(DatabaseSetting, "Script/migration_equipment_preset.sql"); + db.Execute(conn, adaptedSchema); + return true; + } + } +} + diff --git a/Arrowgene.Ddon.Shared/Model/Storages.cs b/Arrowgene.Ddon.Shared/Model/Storages.cs index b0a363f5c..4cf8e5869 100644 --- a/Arrowgene.Ddon.Shared/Model/Storages.cs +++ b/Arrowgene.Ddon.Shared/Model/Storages.cs @@ -317,7 +317,7 @@ public List AsCDataEquipItemInfo(EquipType equipType) public List AsCDataCharacterEquipInfo(EquipType equipType) { return GetItems(equipType) - .Select((x, index) => new {item = x, slot = (byte)(index+1)}) + .Select((x, index) => new {item = x, slot = (byte)(index + 1)}) .Where(tuple => tuple.item != null) .Select(tuple => new CDataCharacterEquipInfo() {