Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for GP course effects #262

Merged
merged 3 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions Arrowgene.Ddon.GameServer/DdonGameServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi
public List<CDataStageInfo> StageList { get; }

public override GameClientLookup ClientLookup { get; }

// TODO: Maybe place somewhere else
public readonly Dictionary<uint, DateTime> LastRevivalPowerRechargeTime = new Dictionary<uint, DateTime>();

Expand Down Expand Up @@ -164,7 +164,7 @@ private void LoadPacketHandler()
AddHandler(new BazaarGetItemInfoHandler(this));
AddHandler(new BazaarGetItemListHandler(this));
AddHandler(new BazaarProceedsHandler(this));

AddHandler(new BinarySaveSetCharacterBinSavedataHandler(this));
AddHandler(new BlackListGetBlackListHandler(this));

Expand Down Expand Up @@ -216,7 +216,7 @@ private void LoadPacketHandler()
AddHandler(new CraftGetCraftSettingHandler(this));
AddHandler(new CraftRecipeGetCraftRecipeHandler(this));
AddHandler(new CraftStartCraftHandler(this));

AddHandler(new DailyMissionListGetHandler(this));

AddHandler(new EquipChangeCharacterEquipHandler(this));
Expand All @@ -239,8 +239,9 @@ private void LoadPacketHandler()
AddHandler(new Gp_28_2_1_Handler(this));
AddHandler(new GpGetUpdateAppCourseBonusFlagHandler(this));
AddHandler(new GpGetValidChatComGroupHandler(this));
AddHandler(new GpGpEditGetVoiceListHandler(this));
AddHandler(new GpGetGpHandler(this));
AddHandler(new GpGpEditGetVoiceListHandler(this));
AddHandler(new GpGetGpHandler(this));
AddHandler(new GpGpCourseGetAvailableListHandler(this));

AddHandler(new GroupChatGroupChatGetMemberListHandler(this));

Expand Down Expand Up @@ -333,10 +334,10 @@ private void LoadPacketHandler()
AddHandler(new PawnJoinPartyMypawnHandler(this));
AddHandler(new PawnPawnLostHandler(this));
AddHandler(new PawnTrainingGetPreparetionInfoToAdviceHandler(this));

AddHandler(new ProfileGetCharacterProfileHandler(this));
AddHandler(new ProfileGetMyCharacterProfileHandler(this));

AddHandler(new QuestEndDistributionQuestCancelHandler(this));
AddHandler(new QuestGetAdventureGuideQuestListHandler(this));
AddHandler(new QuestGetAdventureGuideQuestNoticeHandler(this));
Expand All @@ -363,7 +364,7 @@ private void LoadPacketHandler()
AddHandler(new QuestSendLeaderQuestOrderConditionInfoHandler(this));
AddHandler(new QuestSendLeaderWaitOrderQuestListHandler(this));
AddHandler(new QuestSetPriorityQuestHandler(this));

AddHandler(new EntryBoardEntryBoardList(this));
AddHandler(new EntryBoardEntryBoardItemCreate(this));
AddHandler(new EntryBoardEntryBoardItemForceStart(this));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Arrowgene.Ddon.GameServer.Dump;
using Arrowgene.Ddon.Server;
using Arrowgene.Ddon.Server.Network;
using Arrowgene.Ddon.Shared;
using Arrowgene.Ddon.Shared.Entity;
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
using Arrowgene.Ddon.Shared.Entity.Structure;
Expand All @@ -13,9 +14,11 @@ public class CharacterDecideCharacterIdHandler : PacketHandler<GameClient>
{
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(CharacterDecideCharacterIdHandler));

private AssetRepository _AssetRepo;

public CharacterDecideCharacterIdHandler(DdonGameServer server) : base(server)
{
_AssetRepo = server.AssetRepository;
}

public override PacketId Id => PacketId.C2S_CHARACTER_DECIDE_CHARACTER_ID_REQ;
Expand All @@ -27,12 +30,21 @@ public override void Handle(GameClient client, IPacket packet)
res.CharacterId = client.Character.CharacterId;
res.CharacterInfo = new CDataCharacterInfo(client.Character);
res.Unk0 = pcap.Unk0; // Removing this makes tons of tutorials pop up

client.Send(res);

// Unlocks menu options such as inventory, warping, etc.
S2CCharacterContentsReleaseElementNtc contentsReleaseElementNotice = EntitySerializer.Get<S2CCharacterContentsReleaseElementNtc>().Read(GameFull.data_Dump_20);
client.Send(contentsReleaseElementNotice);

foreach (var ValidCourse in _AssetRepo.GPCourseInfoAsset.ValidCourses)
{
client.Send(new S2CGPCourseStartNtc()
{
CourseID = ValidCourse.Value.Id,
ExpiryTimestamp = ValidCourse.Value.EndTime
});
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Arrowgene.Buffers;
using Arrowgene.Ddon.GameServer.Dump;
using Arrowgene.Ddon.Server;
using Arrowgene.Ddon.Server.Network;
using Arrowgene.Ddon.Shared;
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
using Arrowgene.Ddon.Shared.Network;
using Arrowgene.Logging;

namespace Arrowgene.Ddon.GameServer.Handler
{
public class GpGpCourseGetAvailableListHandler : PacketHandler<GameClient>
{
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(GpGpCourseGetAvailableListHandler));

private AssetRepository _AssetRepo;

public GpGpCourseGetAvailableListHandler(DdonGameServer server) : base(server)
{
_AssetRepo = server.AssetRepository;
}

public override PacketId Id => PacketId.C2S_GP_GP_COURSE_GET_AVAILABLE_LIST_REQ;

public override void Handle(GameClient client, IPacket packet)
{
S2CGpGpCourseGetAvailableListRes Response = new S2CGpGpCourseGetAvailableListRes();

// foreach (var Course in _AssetRepo.GPCourseInfoAsset.ValidCourses)
// {
//
// }

// TODO: Send back real data based on JSON contents?
// TODO: PCAP doesn't have sample packet contents to see what is in it.
client.Send(Response);
}
}
}
30 changes: 28 additions & 2 deletions Arrowgene.Ddon.LoginServer/Handler/GetCharacterListHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
using Arrowgene.Buffers;
using Arrowgene.Ddon.Server;
using Arrowgene.Ddon.Server.Network;
using Arrowgene.Ddon.Shared;
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.Network;
Expand All @@ -14,10 +16,13 @@ namespace Arrowgene.Ddon.LoginServer.Handler
public class GetCharacterListHandler : PacketHandler<LoginClient>
{
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(GetCharacterListHandler));
private AssetRepository _AssetRepo;



public GetCharacterListHandler(DdonLoginServer server) : base(server)
{
_AssetRepo = server.AssetRepository;
}

public override PacketId Id => PacketId.C2L_GET_CHARACTER_LIST_REQ;
Expand All @@ -39,6 +44,27 @@ public override void Handle(LoginClient client, IPacket packet)
cResponse.CharacterListElement.CommunityCharacterBaseInfo.CharacterName.LastName = c.LastName;
cResponse.CharacterListElement.CurrentJobBaseInfo.Job = c.Job;
cResponse.CharacterListElement.CurrentJobBaseInfo.Level = (byte) c.ActiveCharacterJobData.Lv;

List<CDataGPCourseValid> ValidCourses = new List<CDataGPCourseValid>();

foreach (var ValidCourse in _AssetRepo.GPCourseInfoAsset.ValidCourses)
{
CDataGPCourseValid cDataGPCourseValid = new CDataGPCourseValid()
{
Id = c.CharacterId,
CourseId = ValidCourse.Value.Id,
NameA = _AssetRepo.GPCourseInfoAsset.Courses[ValidCourse.Value.Id].Name, // Course Name
NameB = _AssetRepo.GPCourseInfoAsset.Courses[ValidCourse.Value.Id].IconPath, // Link to a icon
StartTime = ValidCourse.Value.StartTime,
EndTime = ValidCourse.Value.EndTime,
};

ValidCourses.Add(cDataGPCourseValid);
}

cResponse.GpCourseValidList = ValidCourses;
cResponse.NextFlowType = 1;
cResponse.IsClanMemberNotice = 1; // REMOVE
// maybe?
//cResponse.CharacterListElement.CurrentJobBaseInfo.Job = c.CharacterInfo.MatchingProfile.CurrentJob;
//cResponse.CharacterListElement.CurrentJobBaseInfo.Level = (byte) c.CharacterInfo.MatchingProfile.CurrentJobLevel;
Expand All @@ -48,11 +74,11 @@ public override void Handle(LoginClient client, IPacket packet)
cResponse.MatchingProfile = c.MatchingProfile;
cResponse.EquipItemInfo = c.Equipment.getEquipmentAsCDataEquipItemInfo(c.Job, EquipType.Performance)
.Union(c.Equipment.getEquipmentAsCDataEquipItemInfo(c.Job, EquipType.Visual))
.ToList();
.ToList();

characterListResponse.Add(cResponse);
}

EntitySerializer.Get<CDataCharacterListInfo>().WriteList(buffer, characterListResponse);
Packet response = new Packet(PacketId.L2C_GET_CHARACTER_LIST_RES, buffer.GetAllBytes());
client.Send(response);
Expand Down
41 changes: 39 additions & 2 deletions Arrowgene.Ddon.LoginServer/Handler/GpCourseGetInfoHandler.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,62 @@
using Arrowgene.Ddon.LoginServer.Dump;
using Arrowgene.Ddon.LoginServer.Dump;
using Arrowgene.Ddon.Server;
using Arrowgene.Ddon.Server.Network;
using Arrowgene.Ddon.Shared;
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
using Arrowgene.Ddon.Shared.Entity.Structure;
using Arrowgene.Ddon.Shared.Network;
using Arrowgene.Logging;
using System;
using System.Linq;

namespace Arrowgene.Ddon.LoginServer.Handler
{
public class GpCourseGetInfoHandler : PacketHandler<LoginClient>
{
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(GpCourseGetInfoHandler));

private L2CGpCourseGetInfoRes _Response;

public GpCourseGetInfoHandler(DdonLoginServer server) : base(server)
{
_Response = new L2CGpCourseGetInfoRes();

foreach (var Course in server.AssetRepository.GPCourseInfoAsset.Courses)
{
pacampbell marked this conversation as resolved.
Show resolved Hide resolved
CDataGPCourseInfo cDataGPCourseInfo = new CDataGPCourseInfo()
{
CourseId = Course.Value.Id,
CourseName = Course.Value.Name,
DoubleCourseTarget = Course.Value.Target,
PrioGroup = (byte)Course.Value.PriorityGroup,
PrioSameTime = (byte)Course.Value.PrioritySameTime,
AnnounceType = (byte)Course.Value.AnnounceType,
EffectUIDs = Course.Value.Effects
};

_Response.CourseInfo.Add(cDataGPCourseInfo);
}

foreach (var Effect in server.AssetRepository.GPCourseInfoAsset.Effects)
{
CDataGPCourseEffectParam cDataGPCourseEffectParam = new CDataGPCourseEffectParam()
{
EffectUID = Effect.Value.Uid,
EffectID = Effect.Value.Id,
Param0 = Effect.Value.Param0,
Param1 = Effect.Value.Param1
};

_Response.Effects.Add(cDataGPCourseEffectParam);
}
}

public override PacketId Id => PacketId.C2L_GP_COURSE_GET_INFO_REQ;

public override void Handle(LoginClient client, IPacket packet)
{
client.Send(LoginDump.Dump_22);
// client.Send(LoginDump.Dump_22);
client.Send(_Response);
}
}
}
18 changes: 18 additions & 0 deletions Arrowgene.Ddon.Shared/Asset/GPCourseInfoAsset.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Collections.Generic;
using Arrowgene.Ddon.Shared.Model;

namespace Arrowgene.Ddon.Shared.Asset
{
public class GPCourseInfoAsset
{
public GPCourseInfoAsset()
{
Courses = new Dictionary<uint, GPCourse>();
Effects = new Dictionary<uint, GpCourseEffect>();
ValidCourses = new Dictionary<uint, GPValidCourse>();
}
public Dictionary<uint, GPCourse> Courses { get; set; }
public Dictionary<uint, GpCourseEffect> Effects { get; set; }
public Dictionary<uint, GPValidCourse> ValidCourses { get; set; }
}
}
76 changes: 76 additions & 0 deletions Arrowgene.Ddon.Shared/AssetReader/GPCourseInfoDeserializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using Arrowgene.Ddon.Shared.Model;
using Arrowgene.Logging;
using Arrowgene.Ddon.Shared.Asset;

namespace Arrowgene.Ddon.Shared.Csv
{
public class GPCourseInfoDeserializer : IAssetDeserializer<GPCourseInfoAsset>
{
private static readonly ILogger Logger = LogProvider.Logger(typeof(GPCourseInfoDeserializer));

public GPCourseInfoAsset ReadPath(string path)
{
Logger.Info($"Reading {path}");

GPCourseInfoAsset asset = new GPCourseInfoAsset();

string json = File.ReadAllText(path);
JsonDocument document = JsonDocument.Parse(json);

var ValidCourses = document.RootElement.GetProperty("valid_courses").EnumerateArray().ToList();
foreach (var ValidCourse in ValidCourses)
{
GPValidCourse obj = new GPValidCourse();
obj.Id = ValidCourse.GetProperty("course_id").GetUInt32();
obj.StartTime = ValidCourse.GetProperty("start_time").GetUInt64();
obj.EndTime = ValidCourse.GetProperty("end_time").GetUInt64();
obj.Comment = ValidCourse.GetProperty("comment").GetString();

asset.ValidCourses.Add(obj.Id, obj);
}

var Courses = document.RootElement.GetProperty("courses").EnumerateArray().ToList();
foreach (var Course in Courses)
{
GPCourse obj = new GPCourse();
obj.Id = Course.GetProperty("id").GetUInt32();
obj.Name = Course.GetProperty("name").GetString();
obj.Target = Course.GetProperty("target").GetUInt32() == 1;
obj.PriorityGroup = Course.GetProperty("priority_grp").GetUInt32();
obj.PrioritySameTime = Course.GetProperty("priority_same_time").GetUInt32();
obj.AnnounceType = Course.GetProperty("announce_type").GetUInt32();
obj.Comment = Course.GetProperty("comment").GetString();
obj.Url = Course.GetProperty("url").GetString();
obj.IconPath = Course.GetProperty("icon_path").GetString();
obj.Description = Course.GetProperty("description").GetString();

var EffectUIDs = Course.GetProperty("effects").EnumerateArray().ToList();
foreach (var EffectUID in EffectUIDs)
{
obj.Effects.Add(EffectUID.GetUInt32());
}

asset.Courses.Add(obj.Id, obj);
}

var Effects = document.RootElement.GetProperty("effects").EnumerateArray().ToList();
foreach (var Effect in Effects)
{
GpCourseEffect obj = new GpCourseEffect();
obj.Uid = Effect.GetProperty("uid").GetUInt32();
obj.Id = Effect.GetProperty("id").GetUInt32();
obj.Param0 = Effect.GetProperty("param0").GetUInt32();
obj.Param1 = Effect.GetProperty("param1").GetUInt32();
obj.Comment = Effect.GetProperty("comment").GetString();

asset.Effects.Add(obj.Uid, obj);
}

return asset;
}
}
}
Loading
Loading