diff --git a/Common/Database/OpenWorld.cs b/Common/Database/OpenWorld.cs new file mode 100644 index 0000000..82e5131 --- /dev/null +++ b/Common/Database/OpenWorld.cs @@ -0,0 +1,54 @@ +using Common.Utils.ExcelReader; +using MongoDB.Bson; +using MongoDB.Driver; + +namespace Common.Database +{ + public class OpenWorld + { + public static readonly IMongoCollection collection = Global.db.GetCollection("OpenWorlds"); + public static readonly uint[] ShowMapList = new uint[] { 1, 2, 301, 401, 601, 701, 801, 1001 }; + + public static void InitData(uint uid) + { + collection.InsertMany(OpenWorldMap.GetInstance().All.Select(x => (uint)x.MapId).Select(mapId => + { + return new OpenWorldScheme() + { + MapId = mapId, + Cycle = OpenWorldCycleData.GetInstance().GetInitCycle(mapId), + OwnerUid = uid, + QuestLevel = 1, + HasTakeFinishRewardCycle = 0, + SpawnPoint = "" + }; + })); + } + + public static List FromUid(uint uid) + { + List Data = collection.AsQueryable().Where(x => x.OwnerUid == uid && ShowMapList.Contains(x.MapId)).ToList(); + if(Data.Count > 0) + return Data; + InitData(uid); + return collection.AsQueryable().Where(x => x.OwnerUid == uid && ShowMapList.Contains(x.MapId)).ToList(); ; + } + } + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public class OpenWorldScheme + { + public ObjectId Id { get; set; } + public uint OwnerUid { get; set; } + public uint MapId { get; set; } + public uint Cycle { get; set; } + public uint QuestLevel { get; set; } + public uint HasTakeFinishRewardCycle { get; set; } + public string SpawnPoint { get; set; } + + public void Save() + { + OpenWorld.collection.ReplaceOne(Builders.Filter.Eq(x => x.Id, Id), this); + } + } +} diff --git a/Common/Database/User.cs b/Common/Database/User.cs index bdaec13..5de3b05 100644 --- a/Common/Database/User.cs +++ b/Common/Database/User.cs @@ -89,6 +89,7 @@ namespace Common.Database public uint AbyssGroupLevel { get; set; } public List AvatarTeamList { get; set; } public List CustomAvatarTeamList { get; set; } + public List OpenWorldStory { get; set; } = new(); public void Save() { @@ -108,6 +109,32 @@ namespace Common.Database Exp = PlayerLevelData.GetInstance().GetMaxPossibleExp(); } } + + public void AddOWStory(uint storyId) + { + OpenWorldStory.Add(new() + { + StoryId = storyId, + StoryProgress = 0, + AcceptTime = (uint)Global.GetUnixInSeconds(), + IsDone = false + }); + } + + public class OpenWorldStoryScheme : OpenworldStory + { + public bool IsDone; + + public OpenworldStory ToProto() + { + return new() + { + StoryId = StoryId, + StoryProgress = StoryProgress, + AcceptTime = AcceptTime + }; + } + } } #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. diff --git a/Common/Program.cs b/Common/Program.cs index 4713476..a500ba5 100644 --- a/Common/Program.cs +++ b/Common/Program.cs @@ -13,6 +13,7 @@ namespace Common public static readonly MongoClient MongoClient = new(config.DatabaseUri); public static readonly IMongoDatabase db = MongoClient.GetDatabase("PemukulPaku"); public static long GetUnixInSeconds() => ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds(); + public static uint GetRandomSeed() => (uint)(GetUnixInSeconds() * new Random().Next(1, 10) / 10); } public interface IConfig diff --git a/Common/Utils/ExcelReader/OpenWorldCycleData.cs b/Common/Utils/ExcelReader/OpenWorldCycleData.cs new file mode 100644 index 0000000..f4fb5ff --- /dev/null +++ b/Common/Utils/ExcelReader/OpenWorldCycleData.cs @@ -0,0 +1,53 @@ +using Newtonsoft.Json; + +namespace Common.Utils.ExcelReader +{ + public class OpenWorldCycleData : BaseExcelReader + { + public override string FileName { get { return "OpenWorldCycleData.json"; } } + + public uint GetInitCycle(uint mapId) + { + return (uint?)All.Where(x => x.CycleMap == mapId).OrderBy(x => x.Cycle).FirstOrDefault()?.Cycle ?? 0; + } + + public uint GetNextCycle(uint mapId, uint cycle) + { + return (uint?)All.Where(x => x.CycleMap == mapId && x.Cycle > cycle).OrderBy(x => x.Cycle).FirstOrDefault()?.Cycle ?? cycle; + } + } + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public partial class OpenWorldCycleDataExcel + { + [JsonProperty("level")] + public int Level { get; set; } + + [JsonProperty("needstory")] + public int Needstory { get; set; } + + [JsonProperty("finishreward")] + public int Finishreward { get; set; } + + [JsonProperty("cycleMap")] + public int CycleMap { get; set; } + + [JsonProperty("hardLvKey")] + public string HardLvKey { get; set; } + + [JsonProperty("CycleName")] + public HashName CycleName { get; set; } + + [JsonProperty("EntranceScene")] + public int EntranceScene { get; set; } + + [JsonProperty("EntranceImg1")] + public string EntranceImg1 { get; set; } + + [JsonProperty("DataImpl")] + public object DataImpl { get; set; } + + [JsonProperty("cycle")] + public int Cycle { get; set; } + } +} diff --git a/Common/Utils/ExcelReader/OpenWorldMap.cs b/Common/Utils/ExcelReader/OpenWorldMap.cs new file mode 100644 index 0000000..7bfcbc6 --- /dev/null +++ b/Common/Utils/ExcelReader/OpenWorldMap.cs @@ -0,0 +1,77 @@ +using Newtonsoft.Json; + +namespace Common.Utils.ExcelReader +{ + public class OpenWorldMap : BaseExcelReader + { + public override string FileName { get { return "OpenWorldMap.json"; } } + } + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public partial class OpenWorldMapExcel + { + [JsonProperty("MapType")] + public int MapType { get; set; } + + [JsonProperty("UnlockLv")] + public int UnlockLv { get; set; } + + [JsonProperty("UnlockStoryId")] + public int UnlockStoryId { get; set; } + + [JsonProperty("ShowTime")] + public string ShowTime { get; set; } + + [JsonProperty("UnlockTime")] + public string UnlockTime { get; set; } + + [JsonProperty("QuestSlotNum")] + public int QuestSlotNum { get; set; } + + [JsonProperty("QuestSettleType")] + public int QuestSettleType { get; set; } + + [JsonProperty("MapNameText")] + public HashName MapNameText { get; set; } + + [JsonProperty("MapContentText")] + public HashName MapContentText { get; set; } + + [JsonProperty("HpRecoverInterval")] + public int HpRecoverInterval { get; set; } + + [JsonProperty("HpRecoverPercent")] + public int HpRecoverPercent { get; set; } + + [JsonProperty("QuestMapUIManager")] + public string QuestMapUiManager { get; set; } + + [JsonProperty("SelectDailyQuestPage")] + public string SelectDailyQuestPage { get; set; } + + [JsonProperty("SettlementPage")] + public string SettlementPage { get; set; } + + [JsonProperty("ShopOpenWorldPage")] + public string ShopOpenWorldPage { get; set; } + + [JsonProperty("ShopTypeList")] + public object[] ShopTypeList { get; set; } + + [JsonProperty("MapInfoText")] + public HashName MapInfoText { get; set; } + + [JsonProperty("QuestInfoText")] + public HashName QuestInfoText { get; set; } + + [JsonProperty("MapSelectPath")] + public string MapSelectPath { get; set; } + + [JsonProperty("DataImpl")] + public object DataImpl { get; set; } + + [JsonProperty("MapId")] + public int MapId { get; set; } + } + +} diff --git a/GameServer/Commands/Command.cs b/GameServer/Commands/Command.cs index 4ab8d50..ce92d4b 100644 --- a/GameServer/Commands/Command.cs +++ b/GameServer/Commands/Command.cs @@ -110,7 +110,7 @@ namespace PemukulPaku.GameServer.Commands } } - c.Log("Finished loading Commands"); + c.Log("Finished Loading Commands"); } } } diff --git a/GameServer/Game/Player.cs b/GameServer/Game/Player.cs index bae8b8b..27965a6 100644 --- a/GameServer/Game/Player.cs +++ b/GameServer/Game/Player.cs @@ -9,12 +9,14 @@ namespace PemukulPaku.GameServer.Game public UserScheme User; public AvatarScheme[] AvatarList; public EquipmentScheme Equipment; + public List OpenWorlds; public Player(UserScheme user) { User = user; Equipment = Common.Database.Equipment.FromUid(user.Uid); AvatarList = Common.Database.Avatar.AvatarsFromUid(user.Uid); + OpenWorlds = OpenWorld.FromUid(user.Uid); } public void SaveAll() @@ -26,6 +28,10 @@ namespace PemukulPaku.GameServer.Game { Avatar.Save(); } + foreach (OpenWorldScheme OpenWorld in OpenWorlds) + { + OpenWorld.Save(); + } } public void ResetAvatarsTodayGoodfeel() diff --git a/GameServer/Handlers/One/GetMpDataReqHandler.cs b/GameServer/Handlers/One/GetMpDataReqHandler.cs index bf3e167..827f8d1 100644 --- a/GameServer/Handlers/One/GetMpDataReqHandler.cs +++ b/GameServer/Handlers/One/GetMpDataReqHandler.cs @@ -12,7 +12,7 @@ namespace PemukulPaku.GameServer.Handlers.One retcode = GetMpDataRsp.Retcode.Succ, DataType = MpDataType.MpDataAll, op_type = GetMpDataRsp.OpType.InitData, - MpLevel = 1, + MpLevel = 0, MpExp = 0, TeamAvatarId = session.Player.GetDetailData().LeaderAvatar.AvatarId, PunishEndTime = 0 diff --git a/GameServer/Handlers/One/GetPlayerTokenReqHandler.cs b/GameServer/Handlers/One/GetPlayerTokenReqHandler.cs index 7136cd9..cea3b06 100644 --- a/GameServer/Handlers/One/GetPlayerTokenReqHandler.cs +++ b/GameServer/Handlers/One/GetPlayerTokenReqHandler.cs @@ -39,8 +39,8 @@ namespace PemukulPaku.GameServer.Handlers AccountUid = Packet.AccountUid, UserType = 4, HoyolabAccountUid = Packet.AccountUid, - FightserverIp = 186782306, - FightserverPort = 2096693423 + FightserverIp = 0, + FightserverPort = 0 }; } diff --git a/GameServer/Handlers/One/MpGetTeamReqHandler.cs b/GameServer/Handlers/One/MpGetTeamReqHandler.cs index b363d2b..342a07c 100644 --- a/GameServer/Handlers/One/MpGetTeamReqHandler.cs +++ b/GameServer/Handlers/One/MpGetTeamReqHandler.cs @@ -7,7 +7,7 @@ namespace PemukulPaku.GameServer.Handlers.One { public void Handle(Session session, Packet packet) { - session.Send(Packet.FromProto(new MpGetTeamRsp() { retcode = MpGetTeamRsp.Retcode.NotInTeam }, CmdId.GetMpDataRsp)); + session.Send(Packet.FromProto(new MpGetTeamRsp() { retcode = MpGetTeamRsp.Retcode.NotInTeam }, CmdId.MpGetTeamRsp)); } } } diff --git a/GameServer/Handlers/One/ReportClientDataVersionReqHandler.cs b/GameServer/Handlers/One/ReportClientDataVersionReqHandler.cs new file mode 100644 index 0000000..eee5857 --- /dev/null +++ b/GameServer/Handlers/One/ReportClientDataVersionReqHandler.cs @@ -0,0 +1,15 @@ +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.One +{ + [PacketCmdId(CmdId.ReportClientDataVersionReq)] + internal class ReportClientDataVersionReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + ReportClientDataVersionReq Data = packet.GetDecodedBody(); + + session.Send(Packet.FromProto(new ReportClientDataVersionRsp() { ServerVersion = Data.Version }, CmdId.ReportClientDataVersionRsp)); + } + } +} diff --git a/GameServer/Handlers/Openworld/AcceptOpenworldStoryReqHandler.cs b/GameServer/Handlers/Openworld/AcceptOpenworldStoryReqHandler.cs new file mode 100644 index 0000000..9105635 --- /dev/null +++ b/GameServer/Handlers/Openworld/AcceptOpenworldStoryReqHandler.cs @@ -0,0 +1,22 @@ +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.AcceptOpenworldStoryReq)] + internal class AcceptOpenworldStoryReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + AcceptOpenworldStoryReq Data = packet.GetDecodedBody(); + AcceptOpenworldStoryRsp Rsp = new() + { + retcode = AcceptOpenworldStoryRsp.Retcode.Succ, + StoryId = Data.StoryId + }; + session.Player.User.AddOWStory(Data.StoryId); + + session.Send(Packet.FromProto(Rsp, CmdId.AcceptOpenworldStoryRsp)); + session.ProcessPacket(Packet.FromProto(new GetOpenworldStoryReq() { }, CmdId.GetOpenworldStoryReq)); + } + } +} diff --git a/GameServer/Handlers/Openworld/GetNewOpenworldReqHandler.cs b/GameServer/Handlers/Openworld/GetNewOpenworldReqHandler.cs new file mode 100644 index 0000000..5d72436 --- /dev/null +++ b/GameServer/Handlers/Openworld/GetNewOpenworldReqHandler.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using Common; +using Common.Database; +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.GetNewOpenworldReq)] + internal class GetNewOpenworldReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + GetNewOpenworldRsp Rsp = new() + { + retcode = GetNewOpenworldRsp.Retcode.Succ, + DataType = OpenworldDataType.OpenworldDataAll, + QuestLevel = 1, + QuestStar = 0, + MaxQuestLevel = 1, + NextRefreshTime = (uint)Global.GetUnixInSeconds() + 3600 * 24 * 3, + CloseTime = (uint)Global.GetUnixInSeconds() + 3600 * 24 * 3, + GlobalRandomSeed = Global.GetRandomSeed() + }; + Rsp.Techs.AddRange(OpenWorld.ShowMapList.Select(x => new OpenworldTechData() { MapId = x })); + Rsp.MapLists.AddRange(session.Player.OpenWorlds.Select(ow => new OpenworldMapBriefData() { + MapId = ow.MapId, + Status = 3, + Cycle = ow.Cycle, + QuestLevel = ow.QuestLevel, + HasTakeFinishRewardCycle = ow.HasTakeFinishRewardCycle + })); + + session.Send(Packet.FromProto(Rsp, CmdId.GetNewOpenworldRsp)); + } + } +} diff --git a/GameServer/Handlers/Openworld/GetOpenworldMapReqHandler.cs b/GameServer/Handlers/Openworld/GetOpenworldMapReqHandler.cs new file mode 100644 index 0000000..463a84e --- /dev/null +++ b/GameServer/Handlers/Openworld/GetOpenworldMapReqHandler.cs @@ -0,0 +1,45 @@ +using Common; +using Common.Database; +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.GetOpenworldMapReq)] + internal class GetOpenworldMapReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + GetOpenworldMapReq Data = packet.GetDecodedBody(); + OpenWorldScheme? OpenWorldData = session.Player.OpenWorlds.FirstOrDefault(x => x.MapId == Data.MapId); + if (OpenWorldData is null) + return; + GetOpenworldMapRsp Rsp = new() + { + retcode = GetOpenworldMapRsp.Retcode.Succ, + MapId = Data.MapId, + Cycle = OpenWorldData.Cycle, + EventRandomSeed = Global.GetRandomSeed(), + SpawnPoint = OpenWorldData.SpawnPoint, + Status = 3, + QuestData = new() + { + IsOpen = false, + DayOpenTimes = 0, + RefreshLeftTimes = 0, + NextRefreshCost = 0, + IsCanAbandon = true, + ChallengeScore = 0, + IsQuestFinish = false, + OpenQuestTime = 0 + }, + TechData = new() + { + MapId = Data.MapId + }, + HasTakeFinishRewardCycle = OpenWorldData.HasTakeFinishRewardCycle + }; + + session.Send(Packet.FromProto(Rsp, CmdId.GetOpenworldMapRsp)); + } + } +} diff --git a/GameServer/Handlers/Openworld/GetOpenworldStageReqHandler.cs b/GameServer/Handlers/Openworld/GetOpenworldStageReqHandler.cs new file mode 100644 index 0000000..7003a62 --- /dev/null +++ b/GameServer/Handlers/Openworld/GetOpenworldStageReqHandler.cs @@ -0,0 +1,24 @@ +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.GetOpenworldStageReq)] + internal class GetOpenworldStageReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + GetOpenworldStageReq Data = packet.GetDecodedBody(); + + session.Send(Packet.FromProto(new GetOpenworldStageRsp() + { + retcode = GetOpenworldStageRsp.Retcode.Succ, + MapId = Data.MapId, + MechaLostHpPercent = 0, + MechaLostSpPercent = 0, + MapEnergy = 0, + ScDlcFeverScore = 0, + ScDlcClimaxScore = 0 + }, CmdId.GetOpenworldStageRsp)); + } + } +} diff --git a/GameServer/Handlers/Openworld/GetOpenworldStoryReqHandler.cs b/GameServer/Handlers/Openworld/GetOpenworldStoryReqHandler.cs new file mode 100644 index 0000000..2e48fe0 --- /dev/null +++ b/GameServer/Handlers/Openworld/GetOpenworldStoryReqHandler.cs @@ -0,0 +1,21 @@ +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.GetOpenworldStoryReq)] + internal class GetOpenworldStoryReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + GetOpenworldStoryRsp Rsp = new() + { + retcode = GetOpenworldStoryRsp.Retcode.Succ, + FinishStoryIdLists = session.Player.User.OpenWorldStory.Where(x => x.IsDone).Select(x => x.StoryId).ToArray(), + IsAll = true + }; + Rsp.CurStoryLists.AddRange(session.Player.User.OpenWorldStory.Where(x => !x.IsDone).Select(x => x.ToProto())); + + session.Send(Packet.FromProto(Rsp, CmdId.GetOpenworldStoryRsp)); + } + } +} diff --git a/GameServer/Handlers/Openworld/OpenworldStageBeginReqHandler.cs b/GameServer/Handlers/Openworld/OpenworldStageBeginReqHandler.cs new file mode 100644 index 0000000..27394f3 --- /dev/null +++ b/GameServer/Handlers/Openworld/OpenworldStageBeginReqHandler.cs @@ -0,0 +1,19 @@ +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.OpenworldStageBeginReq)] + internal class OpenworldStageBeginReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + OpenworldStageBeginReq Data = packet.GetDecodedBody(); + + session.Send(Packet.FromProto(new OpenworldStageBeginRsp() + { + retcode = OpenworldStageBeginRsp.Retcode.Succ, + MapId = Data.MapId + }, CmdId.OpenworldStageBeginRsp)); + } + } +} diff --git a/GameServer/Handlers/Openworld/ReportOpenworldSpawnPointReqHandler.cs b/GameServer/Handlers/Openworld/ReportOpenworldSpawnPointReqHandler.cs new file mode 100644 index 0000000..4f72cd1 --- /dev/null +++ b/GameServer/Handlers/Openworld/ReportOpenworldSpawnPointReqHandler.cs @@ -0,0 +1,25 @@ +using Common.Database; +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.ReportOpenworldSpawnPointReq)] + internal class ReportOpenworldSpawnPointReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + ReportOpenworldSpawnPointReq Data = packet.GetDecodedBody(); + ReportOpenworldSpawnPointRsp Rsp = new() + { + retcode = ReportOpenworldSpawnPointRsp.Retcode.Succ, + MapId = Data.MapId, + PointInfo = Data.PointInfo + }; + OpenWorldScheme? OpenWorldData = session.Player.OpenWorlds.FirstOrDefault(x => x.MapId == Data.MapId); + if (OpenWorldData is not null) + OpenWorldData.SpawnPoint = Data.PointInfo; + + session.Send(Packet.FromProto(Rsp, CmdId.ReportOpenworldSpawnPointRsp)); + } + } +} diff --git a/GameServer/Handlers/Openworld/SetOpenworldStoryProgressReqHandler.cs b/GameServer/Handlers/Openworld/SetOpenworldStoryProgressReqHandler.cs new file mode 100644 index 0000000..cbf6302 --- /dev/null +++ b/GameServer/Handlers/Openworld/SetOpenworldStoryProgressReqHandler.cs @@ -0,0 +1,20 @@ +using Common.Resources.Proto; +using Common.Database; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.SetOpenworldStoryProgressReq)] + internal class SetOpenworldStoryProgressReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + SetOpenworldStoryProgressReq Data = packet.GetDecodedBody(); + UserScheme.OpenWorldStoryScheme? ow = session.Player.User.OpenWorldStory.FirstOrDefault(x => x.StoryId == Data.StoryId); + if (ow is not null) + ow.StoryProgress = Data.StoryProgress; + + session.Send(Packet.FromProto(new SetOpenworldStoryProgressRsp() { retcode = SetOpenworldStoryProgressRsp.Retcode.Succ, StoryId = Data.StoryId }, CmdId.SetOpenworldStoryProgressRsp)); + session.ProcessPacket(Packet.FromProto(new GetOpenworldStoryReq() { }, CmdId.GetOpenworldStoryReq)); + } + } +} diff --git a/GameServer/Handlers/Openworld/TakeOpenworldCycleFinishRewardReqHandler.cs b/GameServer/Handlers/Openworld/TakeOpenworldCycleFinishRewardReqHandler.cs new file mode 100644 index 0000000..aca7e74 --- /dev/null +++ b/GameServer/Handlers/Openworld/TakeOpenworldCycleFinishRewardReqHandler.cs @@ -0,0 +1,28 @@ +using Common.Database; +using Common.Resources.Proto; +using Common.Utils.ExcelReader; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.TakeOpenworldCycleFinishRewardReq)] + internal class TakeOpenworldCycleFinishRewardReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + TakeOpenworldCycleFinishRewardReq Data = packet.GetDecodedBody(); + OpenWorldScheme? ow = session.Player.OpenWorlds.Where(x => x.MapId == Data.MapId).FirstOrDefault(); + if (ow is not null) + { + ow.Cycle = OpenWorldCycleData.GetInstance().GetNextCycle(Data.MapId, Data.Cycle); + ow.HasTakeFinishRewardCycle = OpenWorldCycleData.GetInstance().GetNextCycle(Data.MapId, Data.Cycle); + } + + session.Send(Packet.FromProto(new TakeOpenworldCycleFinishRewardRsp() + { + retcode = TakeOpenworldCycleFinishRewardRsp.Retcode.Succ, + MapId = Data.MapId, + Cycle = Data.Cycle + }, CmdId.TakeOpenworldCycleFinishRewardRsp)); + } + } +} diff --git a/GameServer/Handlers/Openworld/TakeOpenworldStoryRewardReqHandler.cs b/GameServer/Handlers/Openworld/TakeOpenworldStoryRewardReqHandler.cs new file mode 100644 index 0000000..e4226c2 --- /dev/null +++ b/GameServer/Handlers/Openworld/TakeOpenworldStoryRewardReqHandler.cs @@ -0,0 +1,20 @@ +using Common.Database; +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Openworld +{ + [PacketCmdId(CmdId.TakeOpenworldStoryRewardReq)] + internal class TakeOpenworldStoryRewardReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + TakeOpenworldStoryRewardReq Data = packet.GetDecodedBody(); + UserScheme.OpenWorldStoryScheme? ow = session.Player.User.OpenWorldStory.FirstOrDefault(x => x.StoryId == Data.StoryId); + if (ow is not null) + ow.IsDone = true; + + session.Send(Packet.FromProto(new TakeOpenworldStoryRewardRsp() { retcode = TakeOpenworldStoryRewardRsp.Retcode.Succ, StoryId = Data.StoryId }, CmdId.TakeOpenworldStoryRewardRsp)); + session.ProcessPacket(Packet.FromProto(new GetOpenworldStoryReq() { }, CmdId.GetOpenworldStoryReq)); + } + } +} diff --git a/GameServer/Handlers/Two/GetTrialAvatarReqHandler.cs b/GameServer/Handlers/Two/GetTrialAvatarReqHandler.cs new file mode 100644 index 0000000..b458af4 --- /dev/null +++ b/GameServer/Handlers/Two/GetTrialAvatarReqHandler.cs @@ -0,0 +1,13 @@ +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Two +{ + [PacketCmdId(CmdId.GetTrialAvatarReq)] + internal class GetTrialAvatarReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + session.Send(Packet.FromProto(new GetTrialAvatarRsp() { retcode = GetTrialAvatarRsp.Retcode.Succ, IsAllUpdate = true }, CmdId.GetTrialAvatarRsp)); + } + } +} diff --git a/GameServer/Handlers/Two/MpGetMatchInfoReqHandler.cs b/GameServer/Handlers/Two/MpGetMatchInfoReqHandler.cs new file mode 100644 index 0000000..45139e7 --- /dev/null +++ b/GameServer/Handlers/Two/MpGetMatchInfoReqHandler.cs @@ -0,0 +1,13 @@ +using Common.Resources.Proto; + +namespace PemukulPaku.GameServer.Handlers.Two +{ + [PacketCmdId(CmdId.MpGetMatchInfoReq)] + internal class MpGetMatchInfoReqHandler : IPacketHandler + { + public void Handle(Session session, Packet packet) + { + session.Send(Packet.FromProto(new MpGetMatchInfoRsp() { retcode = MpGetMatchInfoRsp.Retcode.Succ, LobbyIdx = 1 }, CmdId.MpGetMatchInfoRsp)); + } + } +} diff --git a/GameServer/MPModule/Lobby.cs b/GameServer/MPModule/Lobby.cs index 941d8b5..b2ee9f3 100644 --- a/GameServer/MPModule/Lobby.cs +++ b/GameServer/MPModule/Lobby.cs @@ -47,6 +47,9 @@ namespace PemukulPaku.GameServer.MPModule teamSyncNotify.TeamData.MemberLists.AddRange(team.Members.Select(member => { + if (member.Session is null) + return new MpTeamMember() { Index = member.Index, DressId = 0 }; + return new MpTeamMember() { Index = member.Index, @@ -72,9 +75,9 @@ namespace PemukulPaku.GameServer.MPModule }; })); - foreach (Session session in team.Members.Select(x => x.Session)) + foreach (Session? session in team.Members.Where(x => x.Session is not null).Select(x => x.Session)) { - session.Send(Packet.FromProto(teamSyncNotify, CmdId.MpTeamSyncNotify)); + session?.Send(Packet.FromProto(teamSyncNotify, CmdId.MpTeamSyncNotify)); } } } @@ -94,7 +97,7 @@ namespace PemukulPaku.GameServer.MPModule StageId = stageId; MinLevel = minLevel; LobbyEnterType = lobbyEnterType; - Members = new List { new(leader) }; + Members = new List { new(leader), new(null, 2), new(null, 3) }; LeaderUid = leader.Player.User.Uid; Name = name; } @@ -102,12 +105,12 @@ namespace PemukulPaku.GameServer.MPModule public class TeamMember { - public Session Session; + public Session? Session; public uint Index; public LobbyClientStatus ClientStatus { get; set; } = LobbyClientStatus.LobbyClientNone; public LobbyMemberStatus Status { get; set; } = LobbyMemberStatus.LobbyMemberReady; - public TeamMember(Session session, uint index = 1) + public TeamMember(Session? session = null, uint index = 1) { Session = session; Index = index; diff --git a/GameServer/Session.cs b/GameServer/Session.cs index 7adf0f5..9c87dda 100644 --- a/GameServer/Session.cs +++ b/GameServer/Session.cs @@ -95,6 +95,7 @@ namespace PemukulPaku.GameServer try { Send(Packet.FromProto(new KeepAliveNotify() { }, CmdId.KeepAliveNotify)); + LastServerKeepAlive = Global.GetUnixInSeconds(); } catch { @@ -108,6 +109,9 @@ namespace PemukulPaku.GameServer public void DisconnectProtocol() { + if (Server.GetInstance().Sessions.GetValueOrDefault(Id) is null) + return; + Player.SaveAll(); c.Debug("Player data saved to database"); c.Warn($"{Id} disconnected"); diff --git a/Program.cs b/Program.cs index 77f0ff4..75caa4a 100644 --- a/Program.cs +++ b/Program.cs @@ -26,8 +26,6 @@ namespace PemukulPaku new Thread(HttpServer.Program.Main).Start(); _ = Server.GetInstance(); - Player Player = new(User.FromName("test")); - ReadLine.GetInstance().Start(); } }