Skip to content

Commit eda86d4

Browse files
authored
Merge pull request #587 from RyanYappert/feat/box-full-error-codes
Feat: Actual errors when doing things with a full storage chest.
2 parents ff1b2a2 + 348b186 commit eda86d4

5 files changed

Lines changed: 95 additions & 16 deletions

File tree

Arrowgene.Ddon.GameServer/Characters/JobManager.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,21 @@ public JobManager(DdonGameServer server)
3131
_Server = server;
3232
}
3333

34-
public (IPacketStructure jobRes, IPacketStructure itemNtc, IPacketStructure jobNtc) SetJob(GameClient client, CharacterCommon common, JobId jobId, DbConnection? connectionIn = null)
34+
public (IPacketStructure jobRes, IPacketStructure? itemNtc, IPacketStructure? jobNtc) SetJob(GameClient client, CharacterCommon common, JobId jobId, DbConnection? connectionIn = null)
3535
{
3636
// TODO: Reject job change if there's no primary and secondary weapon for the new job in storage
3737
// (or give a lvl 1 weapon for free?)
3838

39+
if (!HasEmptySlotsForTemplateSwap(client, common, common.Job, jobId))
40+
{
41+
return (new S2CJobChangeJobRes()
42+
{
43+
Error = (uint)ErrorCode.ERROR_CODE_JOBCHANGE_ITEM_CAPACITY_OVER
44+
},
45+
null,
46+
null);
47+
}
48+
3949
JobId oldJobId = common.Job;
4050
common.Job = jobId;
4151

@@ -278,6 +288,36 @@ private List<CDataItemUpdateResult> SwapEquipmentAndStorage(GameClient client, C
278288
return itemUpdateResultList;
279289
}
280290

291+
private static bool HasEmptySlotsForTemplateSwap(GameClient client, CharacterCommon common, JobId oldJobId, JobId newJobId)
292+
{
293+
var availableSlots = client.Character.Storage.GetStorage(StorageType.StorageBoxNormal).EmptySlots();
294+
295+
var neededSlots = common.Equipment.GetItems(EquipType.Performance)
296+
.Concat(common.Equipment.GetItems(EquipType.Visual))
297+
.Where(x => x != null)
298+
.ToList()
299+
.Count;
300+
301+
// If the item isn't moving, it doesn't need a space in the box.
302+
foreach (var equipType in new List<EquipType>(){ EquipType.Performance, EquipType.Visual })
303+
{
304+
List<Item?> oldEquipment = common.Equipment.GetItems(equipType);
305+
List<Item?> newEquipmentTemplate = common.EquipmentTemplate.GetEquipment(newJobId, equipType);
306+
307+
for (int i = 0; i < oldEquipment.Count; i++)
308+
{
309+
if (oldEquipment[i] != null && newEquipmentTemplate[i] != null && oldEquipment[i] == newEquipmentTemplate[i])
310+
{
311+
neededSlots--;
312+
}
313+
}
314+
}
315+
316+
// TODO: Account for one-to-one swaps, as well as jewelry shuffling order.
317+
318+
return neededSlots <= availableSlots;
319+
}
320+
281321
public void UnlockSkill(IDatabase database, GameClient client, CharacterCommon character, JobId job, uint skillId, byte skillLv)
282322
{
283323
// Check if there is a learned skill of the same ID (This unlock is a level upgrade)
Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1+
using Arrowgene.Ddon.GameServer.Characters;
12
using Arrowgene.Ddon.Server;
2-
using Arrowgene.Ddon.Server.Network;
33
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
44
using Arrowgene.Logging;
5-
using Arrowgene.Ddon.Shared.Network;
6-
using Arrowgene.Ddon.GameServer.Characters;
7-
using Arrowgene.Ddon.Shared.Entity.Structure;
8-
using Arrowgene.Ddon.Shared.Entity;
95

106
namespace Arrowgene.Ddon.GameServer.Handler
117
{
12-
public class JobChangeJobHandler : StructurePacketHandler<GameClient, C2SJobChangeJobReq>
8+
public class JobChangeJobHandler : GameRequestPacketHandler<C2SJobChangeJobReq, S2CJobChangeJobRes>
139
{
1410
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(JobChangeJobHandler));
1511

@@ -20,22 +16,30 @@ public JobChangeJobHandler(DdonGameServer server) : base(server)
2016
jobManager = server.JobManager;
2117
}
2218

23-
public override void Handle(GameClient client, StructurePacket<C2SJobChangeJobReq> packet)
19+
public override S2CJobChangeJobRes Handle(GameClient client, C2SJobChangeJobReq request)
2420
{
2521
(S2CJobChangeJobRes jobRes, S2CItemUpdateCharacterItemNtc itemNtc, S2CJobChangeJobNtc jobNtc) jobResult = (null, null, null);
2622

2723
Server.Database.ExecuteInTransaction(connection =>
2824
{
2925
jobResult = ((S2CJobChangeJobRes, S2CItemUpdateCharacterItemNtc, S2CJobChangeJobNtc))
30-
jobManager.SetJob(client, client.Character, packet.Structure.JobId, connection);
26+
jobManager.SetJob(client, client.Character, request.JobId, connection);
3127
});
3228

33-
foreach (GameClient otherClient in Server.ClientLookup.GetAll())
29+
if (jobResult.jobNtc != null)
3430
{
35-
otherClient.Send(jobResult.jobNtc);
31+
foreach (GameClient otherClient in Server.ClientLookup.GetAll())
32+
{
33+
otherClient.Send(jobResult.jobNtc);
34+
}
3635
}
37-
client.Send(jobResult.itemNtc);
38-
client.Send(jobResult.jobRes);
36+
37+
if (jobResult.itemNtc != null)
38+
{
39+
client.Send(jobResult.itemNtc);
40+
}
41+
42+
return jobResult.jobRes;
3943
}
4044
}
4145
}

Arrowgene.Ddon.GameServer/Handler/JobChangePawnJobHandler.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,19 @@ public override void Handle(GameClient client, StructurePacket<C2SJobChangePawnJ
3030
jobManager.SetJob(client, pawn, packet.Structure.JobId, connection);
3131
});
3232

33-
foreach (GameClient otherClient in Server.ClientLookup.GetAll())
33+
if (jobResult.jobNtc != null)
3434
{
35-
otherClient.Send(jobResult.jobNtc);
35+
foreach (GameClient otherClient in Server.ClientLookup.GetAll())
36+
{
37+
otherClient.Send(jobResult.jobNtc);
38+
}
3639
}
37-
client.Send(jobResult.itemNtc);
40+
41+
if (jobResult.itemNtc != null)
42+
{
43+
client.Send(jobResult.itemNtc);
44+
}
45+
3846
client.Send(jobResult.jobRes);
3947
}
4048
}

Arrowgene.Ddon.GameServer/Handler/PawnCreatePawnHandler.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ public PawnCreatePawnHandler(DdonGameServer server) : base(server)
2222

2323
public override S2CPawnCreatePawnRes Handle(GameClient client, C2SPawnCreatePawnReq request)
2424
{
25+
// I hate hardcoding this but people legitimately keep finding ways to break this.
26+
if (request.SlotNo > 3)
27+
{
28+
throw new ResponseErrorException(ErrorCode.ERROR_CODE_PAWN_CREATE_NUM_OVER);
29+
}
30+
2531
if (request.SlotNo == 1)
2632
{
2733
const byte myPawnSlotNum = 2;
@@ -62,6 +68,17 @@ public override S2CPawnCreatePawnRes Handle(GameClient client, C2SPawnCreatePawn
6268
Error = (uint)ErrorCode.ERROR_CODE_CHARACTER_ITEM_NOT_FOUND
6369
};
6470
}
71+
else
72+
{
73+
client.Send(new S2CItemUpdateCharacterItemNtc()
74+
{
75+
UpdateType = ItemNoticeType.CreatePawn,
76+
UpdateItemList = new()
77+
{
78+
result
79+
}
80+
});
81+
}
6582
}
6683

6784
Pawn pawn = new Pawn(client.Character.CharacterId)

Arrowgene.Ddon.GameServer/Handler/QuestGetRewardBoxItemHandler.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ public override S2CQuestGetRewardBoxItemRes Handle(GameClient client, C2SQuestGe
6262
}
6363
}
6464

65+
var slotCount = coalescedRewards
66+
.Where(x => !Server.ItemManager.IsItemWalletPoint(x.Value.ItemId) && x.Value.Num > 0)
67+
.ToList()
68+
.Count;
69+
70+
if (slotCount > client.Character.Storage.GetStorage(StorageType.StorageBoxNormal).EmptySlots())
71+
{
72+
throw new ResponseErrorException(ErrorCode.ERROR_CODE_ITEM_STORAGE_OVERFLOW);
73+
}
74+
6575
foreach (var rewardUID in packet.GetRewardBoxItemList.Select(x => x.UID).Distinct().ToList())
6676
{
6777
var reward = coalescedRewards[rewardUID];

0 commit comments

Comments
 (0)