Skip to content

Commit 9a4b78b

Browse files
authored
Merge pull request #578 from pacampbell/bonus_dungeon_support
feat: Add support for bonus dungeons
2 parents 293a89a + b640c1a commit 9a4b78b

34 files changed

Lines changed: 1790 additions & 15 deletions
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
using Arrowgene.Ddon.GameServer.Party;
2+
using Arrowgene.Ddon.GameServer.Quests;
3+
using Arrowgene.Ddon.Server;
4+
using Arrowgene.Ddon.Server.Network;
5+
using Arrowgene.Ddon.Shared.Asset;
6+
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
7+
using Arrowgene.Ddon.Shared.Entity.Structure;
8+
using Arrowgene.Ddon.Shared.Model;
9+
using Arrowgene.Logging;
10+
using System.Collections.Generic;
11+
12+
namespace Arrowgene.Ddon.GameServer.Characters
13+
{
14+
public class BonusDungeonManager
15+
{
16+
private Dictionary<uint, Dictionary<uint, bool>> _ReadyStatus;
17+
private Dictionary<uint, uint> _ContentId;
18+
private BonusDungeonAsset _BonusDungeonAsset;
19+
private DdonGameServer _Server;
20+
21+
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(PartyQuestContentManager));
22+
23+
public BonusDungeonManager(DdonGameServer server)
24+
{
25+
_Server = server;
26+
_ReadyStatus = new Dictionary<uint, Dictionary<uint, bool>>();
27+
_ContentId = new Dictionary<uint, uint>();
28+
_BonusDungeonAsset = server.AssetRepository.BonusDungeonAsset;
29+
}
30+
31+
public void StartDungeon(PartyGroup party)
32+
{
33+
lock (_ReadyStatus)
34+
{
35+
if (!_ContentId.ContainsKey(party.Id))
36+
{
37+
return;
38+
}
39+
40+
var dungeonId = _ContentId[party.Id];
41+
var dungeonInfo = _BonusDungeonAsset.DungeonInfo[dungeonId];
42+
43+
foreach (var memberClient in party.Clients)
44+
{
45+
var itemUpdateList = new List<CDataItemUpdateResult>();
46+
foreach (var item in dungeonInfo.EntryCostList)
47+
{
48+
itemUpdateList.Add(_Server.ItemManager.ConsumeItemByIdFromMultipleStorages(_Server, memberClient.Character, ItemManager.BothStorageTypes, item.ItemId, item.Num));
49+
}
50+
51+
memberClient.Send(new S2CItemUpdateCharacterItemNtc()
52+
{
53+
UpdateType = 0,
54+
UpdateItemList = itemUpdateList
55+
});
56+
}
57+
58+
EndPartyReadyCheck(party);
59+
60+
var ntc = new S2CStageTicketDungeonStartNtc()
61+
{
62+
Unk0 = dungeonId,
63+
StageId = dungeonInfo.StageId,
64+
StartPos = dungeonInfo.StartingPos,
65+
Unk4 = true,
66+
};
67+
party.SendToAll(ntc);
68+
}
69+
}
70+
71+
public uint GetPartyDungeonId(PartyGroup party)
72+
{
73+
lock (_ReadyStatus)
74+
{
75+
if (!_ContentId.ContainsKey(party.Id))
76+
{
77+
return 0;
78+
}
79+
return _ContentId[party.Id];
80+
}
81+
}
82+
83+
public bool InitiatePartyReadyCheck(PartyGroup party, uint dungeonId)
84+
{
85+
lock (_ReadyStatus)
86+
{
87+
if (_ReadyStatus.ContainsKey(party.Id))
88+
{
89+
Logger.Error($"(PartyReadyCheck) Party ready check is already in progress for PartyId={party.Id}.");
90+
return false;
91+
}
92+
93+
_ContentId[party.Id] = dungeonId;
94+
95+
_ReadyStatus[party.Id] = new Dictionary<uint, bool>();
96+
foreach (var memberClient in party.Clients)
97+
{
98+
_ReadyStatus[party.Id][memberClient.Character.CharacterId] = false;
99+
}
100+
Logger.Info($"(PartyReadyCheck) Started party ready check for PartyId={party.Id}");
101+
}
102+
103+
return true;
104+
}
105+
106+
public void MarkReady(PartyGroup party, Character character, uint dungeonId)
107+
{
108+
lock (_ReadyStatus)
109+
{
110+
if (!_ReadyStatus.ContainsKey(party.Id) && !InitiatePartyReadyCheck(party, dungeonId))
111+
{
112+
return;
113+
}
114+
115+
_ReadyStatus[party.Id][character.CharacterId] = true;
116+
}
117+
}
118+
119+
public void MarkNotReady(PartyGroup party, Character character)
120+
{
121+
lock (_ReadyStatus)
122+
{
123+
if (_ReadyStatus.ContainsKey(party.Id))
124+
{
125+
return;
126+
}
127+
128+
_ReadyStatus[party.Id][character.CharacterId] = false;
129+
}
130+
}
131+
132+
public bool PartyIsReady(PartyGroup party)
133+
{
134+
lock (_ReadyStatus)
135+
{
136+
if (!_ReadyStatus.ContainsKey(party.Id))
137+
{
138+
return false;
139+
}
140+
141+
bool allMembersReady = true;
142+
foreach (var (characterId, answer) in _ReadyStatus[party.Id])
143+
{
144+
allMembersReady &= answer;
145+
}
146+
return allMembersReady;
147+
}
148+
}
149+
150+
public void EndPartyReadyCheck(PartyGroup party)
151+
{
152+
lock (_ReadyStatus)
153+
{
154+
if (_ReadyStatus.ContainsKey(party.Id))
155+
{
156+
_ReadyStatus.Remove(party.Id);
157+
}
158+
159+
if (_ContentId.ContainsKey(party.Id))
160+
{
161+
_ContentId.Remove(party.Id);
162+
}
163+
}
164+
}
165+
}
166+
}

Arrowgene.Ddon.GameServer/DdonGameServer.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi
7777
GpCourseManager = new GpCourseManager(this);
7878
WeatherManager = new WeatherManager(this);
7979
PartyQuestContentManager = new PartyQuestContentManager(this);
80+
BonusDungeonManager = new BonusDungeonManager(this);
8081
BoardManager = new BoardManager(this);
8182
TimerManager = new TimerManager(this);
8283

@@ -110,6 +111,7 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi
110111
public GpCourseManager GpCourseManager { get; }
111112
public WeatherManager WeatherManager { get; }
112113
public PartyQuestContentManager PartyQuestContentManager { get; }
114+
public BonusDungeonManager BonusDungeonManager { get; }
113115
public BoardManager BoardManager { get; }
114116
public TimerManager TimerManager { get; }
115117

@@ -590,6 +592,12 @@ private void LoadPacketHandler()
590592

591593
AddHandler(new StageAreaChangeHandler(this));
592594
AddHandler(new StageGetStageListHandler(this));
595+
AddHandler(new StageGetTicketDungeonCategoryListHandler(this));
596+
AddHandler(new StageGetTicketDungeonInfoListHandler(this));
597+
AddHandler(new StageUnisonAreaChangeBeginRecruitmentHandler(this));
598+
AddHandler(new StageUnisonAreaChangeGetRecruitmentStateHandler(this));
599+
AddHandler(new StageUnisonAreaChangeReadyHandler(this));
600+
AddHandler(new StageUnisonAreaChangeReadyCancelHandler(this));
593601

594602
AddHandler(new StampBonusCheckHandler(this));
595603
AddHandler(new StampBonusGetListHandler(this));
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Arrowgene.Ddon.Server;
2+
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
3+
using Arrowgene.Ddon.Shared.Entity.Structure;
4+
using Arrowgene.Logging;
5+
6+
namespace Arrowgene.Ddon.GameServer.Handler
7+
{
8+
public class StageGetTicketDungeonCategoryListHandler : GameRequestPacketHandler<C2SStageGetTicketDungeonCategoryListReq, S2CStageGetTicketDungeonCategoryListRes>
9+
{
10+
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(StageGetTicketDungeonCategoryListHandler));
11+
12+
public StageGetTicketDungeonCategoryListHandler(DdonGameServer server) : base(server)
13+
{
14+
}
15+
16+
public override S2CStageGetTicketDungeonCategoryListRes Handle(GameClient client, C2SStageGetTicketDungeonCategoryListReq request)
17+
{
18+
var result = new S2CStageGetTicketDungeonCategoryListRes();
19+
20+
foreach (var category in Server.AssetRepository.BonusDungeonAsset.DungeonCategories.Values)
21+
{
22+
result.CategoryList.Add(new CDataStageTicketDungeonCategory()
23+
{
24+
CategoryId = category.CategoryId,
25+
CategoryName = category.CategoryName
26+
});
27+
}
28+
29+
return result;
30+
}
31+
}
32+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using Arrowgene.Ddon.Server;
2+
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
3+
using Arrowgene.Ddon.Shared.Entity.Structure;
4+
using Arrowgene.Logging;
5+
6+
namespace Arrowgene.Ddon.GameServer.Handler
7+
{
8+
public class StageGetTicketDungeonInfoListHandler : GameRequestPacketHandler<C2SStageGetTicketDungeonInfoListReq, S2CStageGetTicketDungeonInfoListRes>
9+
{
10+
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(StageGetTicketDungeonInfoListHandler));
11+
12+
public StageGetTicketDungeonInfoListHandler(DdonGameServer server) : base(server)
13+
{
14+
}
15+
16+
public override S2CStageGetTicketDungeonInfoListRes Handle(GameClient client, C2SStageGetTicketDungeonInfoListReq request)
17+
{
18+
var result = new S2CStageGetTicketDungeonInfoListRes();
19+
20+
foreach (var dungeon in Server.AssetRepository.BonusDungeonAsset.DungeonCategories[request.CategoryId].DungeonInformation.Values)
21+
{
22+
result.CategoryInfoList.Add(new CDataStageTicketDungeonCategoryInfo()
23+
{
24+
DungeonId = dungeon.DungeonId,
25+
DungeonName = dungeon.EventName,
26+
EntryFeeList = dungeon.EntryCostList,
27+
Unk0 = dungeon.DungeonId,
28+
});
29+
}
30+
31+
return result;
32+
}
33+
}
34+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Arrowgene.Ddon.GameServer.Characters;
2+
using Arrowgene.Ddon.Server;
3+
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
4+
using Arrowgene.Ddon.Shared.Entity.Structure;
5+
using Arrowgene.Logging;
6+
using System.Collections.Generic;
7+
8+
namespace Arrowgene.Ddon.GameServer.Handler
9+
{
10+
public class StageUnisonAreaChangeBeginRecruitmentHandler : GameRequestPacketHandler<C2SStageUnisonAreaChangeBeginRecruitmentReq, S2CStageUnisonAreaChangeBeginRecruitmentRes>
11+
{
12+
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(StageUnisonAreaChangeBeginRecruitmentHandler));
13+
14+
public StageUnisonAreaChangeBeginRecruitmentHandler(DdonGameServer server) : base(server)
15+
{
16+
}
17+
18+
public override S2CStageUnisonAreaChangeBeginRecruitmentRes Handle(GameClient client, C2SStageUnisonAreaChangeBeginRecruitmentReq request)
19+
{
20+
Server.BonusDungeonManager.MarkReady(client.Party, client.Character, request.Unk0);
21+
if (Server.BonusDungeonManager.PartyIsReady(client.Party))
22+
{
23+
Server.BonusDungeonManager.StartDungeon(client.Party);
24+
}
25+
26+
return new S2CStageUnisonAreaChangeBeginRecruitmentRes();
27+
}
28+
}
29+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using Arrowgene.Ddon.GameServer.Characters;
2+
using Arrowgene.Ddon.Server;
3+
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
4+
using Arrowgene.Ddon.Shared.Entity.Structure;
5+
using Arrowgene.Logging;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
9+
namespace Arrowgene.Ddon.GameServer.Handler
10+
{
11+
public class StageUnisonAreaChangeGetRecruitmentStateHandler : GameRequestPacketHandler<C2SStageUnisonAreaChangeGetRecruitmentStateReq, S2CStageUnisonAreaChangeGetRecruitmentStateRes>
12+
{
13+
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(StageUnisonAreaChangeGetRecruitmentStateHandler));
14+
15+
public StageUnisonAreaChangeGetRecruitmentStateHandler(DdonGameServer server) : base(server)
16+
{
17+
}
18+
19+
public override S2CStageUnisonAreaChangeGetRecruitmentStateRes Handle(GameClient client, C2SStageUnisonAreaChangeGetRecruitmentStateReq request)
20+
{
21+
var result = new S2CStageUnisonAreaChangeGetRecruitmentStateRes();
22+
23+
uint dungeonId = Server.BonusDungeonManager.GetPartyDungeonId(client.Party);
24+
if (dungeonId != 0)
25+
{
26+
var dungeonInfo = Server.AssetRepository.BonusDungeonAsset.DungeonInfo[dungeonId];
27+
result.Unk0 = dungeonInfo.DungeonId;
28+
result.StageId = dungeonInfo.StageId;
29+
result.StartPos = dungeonInfo.StartingPos;
30+
result.Unk4 = true;
31+
result.EntryCostList = dungeonInfo.EntryCostList;
32+
}
33+
34+
return result;
35+
}
36+
}
37+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Arrowgene.Ddon.GameServer.Characters;
2+
using Arrowgene.Ddon.Server;
3+
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
4+
using Arrowgene.Ddon.Shared.Entity.Structure;
5+
using Arrowgene.Logging;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
9+
namespace Arrowgene.Ddon.GameServer.Handler
10+
{
11+
public class StageUnisonAreaChangeReadyCancelHandler : GameRequestPacketHandler<C2SStageUnisonAreaChangeReadyCancelReq, S2CStageUnisonAreaChangeReadyCancelRes>
12+
{
13+
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(StageUnisonAreaChangeReadyCancelHandler));
14+
15+
public StageUnisonAreaChangeReadyCancelHandler(DdonGameServer server) : base(server)
16+
{
17+
}
18+
19+
public override S2CStageUnisonAreaChangeReadyCancelRes Handle(GameClient client, C2SStageUnisonAreaChangeReadyCancelReq request)
20+
{
21+
Server.BonusDungeonManager.EndPartyReadyCheck(client.Party);
22+
23+
client.Party.SendToAll(new S2CStageUnisonAreaReadyCancelNtc());
24+
return new S2CStageUnisonAreaChangeReadyCancelRes();
25+
}
26+
}
27+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Arrowgene.Ddon.GameServer.Characters;
2+
using Arrowgene.Ddon.Server;
3+
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
4+
using Arrowgene.Ddon.Shared.Entity.Structure;
5+
using Arrowgene.Logging;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
9+
namespace Arrowgene.Ddon.GameServer.Handler
10+
{
11+
public class StageUnisonAreaChangeReadyHandler : GameRequestPacketHandler<C2SStageUnisonAreaChangeReadyReq, S2CStageUnisonAreaChangeReadyRes>
12+
{
13+
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(StageUnisonAreaChangeReadyHandler));
14+
15+
public StageUnisonAreaChangeReadyHandler(DdonGameServer server) : base(server)
16+
{
17+
}
18+
19+
public override S2CStageUnisonAreaChangeReadyRes Handle(GameClient client, C2SStageUnisonAreaChangeReadyReq request)
20+
{
21+
var dungeonId = Server.BonusDungeonManager.GetPartyDungeonId(client.Party);
22+
23+
Server.BonusDungeonManager.MarkReady(client.Party, client.Character, dungeonId);
24+
if (Server.BonusDungeonManager.PartyIsReady(client.Party))
25+
{
26+
Server.BonusDungeonManager.StartDungeon(client.Party);
27+
}
28+
29+
return new S2CStageUnisonAreaChangeReadyRes();
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)