lobby part 1, idk what i'm doing

This commit is contained in:
rafi1212122
2023-06-10 07:27:06 +07:00
parent f2e83c93dd
commit f9e0aa8e1f
17 changed files with 494 additions and 53 deletions

View File

@@ -195,7 +195,8 @@ namespace Common.Database
}
else
{
avatarSubSkill.Level++;
if (avatarSubSkill.Level < subSkillData.MaxLv)
avatarSubSkill.Level++;
}
}
else

View File

@@ -0,0 +1,84 @@
using Newtonsoft.Json;
namespace Common.Utils.ExcelReader
{
public class GeneralActivity : BaseExcelReader<GeneralActivity, GeneralActivityExcel>
{
public override string FileName { get { return "GeneralActivity.json"; } }
public List<GeneralActivityExcel> GetAllDistinct()
{
return All.Distinct(new GeneralActivityDisplayComparer()).ToList();
}
}
public class GeneralActivityDisplayComparer : IEqualityComparer<GeneralActivityExcel>
{
#pragma warning disable CS8767
public bool Equals(GeneralActivityExcel x, GeneralActivityExcel y)
{
return x.DisplayData == y.DisplayData;
}
#pragma warning restore CS8767
public int GetHashCode(GeneralActivityExcel obj)
{
return obj.DisplayData;
}
}
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public partial class GeneralActivityExcel
{
[JsonProperty("Series")]
public int Series { get; set; }
[JsonProperty("AcitivityType")]
public int AcitivityType { get; set; }
[JsonProperty("MinLevel")]
public int MinLevel { get; set; }
[JsonProperty("MaxLevel")]
public int MaxLevel { get; set; }
[JsonProperty("LinkData")]
public int LinkData { get; set; }
[JsonProperty("DisplayData")]
public int DisplayData { get; set; }
[JsonProperty("ScoreData")]
public int ScoreData { get; set; }
[JsonProperty("RankData")]
public int RankData { get; set; }
[JsonProperty("ShowRank")]
public int ShowRank { get; set; }
[JsonProperty("TeamListID")]
public int TeamListId { get; set; }
[JsonProperty("PreCondType")]
public int PreCondType { get; set; }
[JsonProperty("PreCondParaStr")]
public string PreCondParaStr { get; set; }
[JsonProperty("PreUnlockHint")]
public HashName PreUnlockHint { get; set; }
[JsonProperty("ActivityBuffID")]
public int ActivityBuffId { get; set; }
[JsonProperty("TicketIDList")]
public int[] TicketIdList { get; set; }
[JsonProperty("DataImpl")]
public object DataImpl { get; set; }
[JsonProperty("AcitivityID")]
public int AcitivityId { get; set; }
}
}

View File

@@ -1,4 +1,6 @@
using Common.Database;
using Common.Resources.Proto;
using Common.Utils.ExcelReader;
namespace PemukulPaku.GameServer.Game
{
@@ -12,7 +14,7 @@ namespace PemukulPaku.GameServer.Game
{
User = user;
Equipment = Common.Database.Equipment.FromUid(user.Uid);
AvatarList = Avatar.AvatarsFromUid(user.Uid);
AvatarList = Common.Database.Avatar.AvatarsFromUid(user.Uid);
}
public void SaveAll()
@@ -33,5 +35,33 @@ namespace PemukulPaku.GameServer.Game
avatar.TodayHasAddGoodfeel = 0;
}
}
public PlayerCardData GetCardData()
{
return new()
{
Uid = User.Uid,
MsgData = new()
{
MsgIndex = 0,
MsgConfig = 1
},
OnPhonePendantId = 350005
};
}
public PlayerDetailData GetDetailData()
{
return new()
{
Uid = User.Uid,
Nickname = User.Nick,
Level = (uint)PlayerLevelData.GetInstance().CalculateLevel(User.Exp).Level,
SelfDesc = User.SelfDesc,
CustomHeadId = (uint)User.CustomHeadId,
FrameId = User.FrameId < 200001 ? 200001 : (uint)User.FrameId,
LeaderAvatar = AvatarList.FirstOrDefault(x => x.AvatarId == User.AvatarTeamList.FirstOrDefault()?.AvatarIdLists[0])?.ToDetailData(Equipment) ?? new() { AvatarId = 101 }
};
}
}
}

View File

@@ -0,0 +1,19 @@
using Common.Resources.Proto;
namespace PemukulPaku.GameServer.Handlers.Activity
{
[PacketCmdId(CmdId.ChapterActivityTakeDailyRewardReq)]
internal class ChapterActivityTakeDailyRewardReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
ChapterActivityTakeDailyRewardReq Data = packet.GetDecodedBody<ChapterActivityTakeDailyRewardReq>();
session.Send(Packet.FromProto(new ChapterActivityTakeDailyRewardRsp()
{
retcode = ChapterActivityTakeDailyRewardRsp.Retcode.HasTake,
ChapterId = Data.ChapterId
}, CmdId.ChapterActivityTakeDailyRewardRsp));
}
}
}

View File

@@ -0,0 +1,27 @@
using Common.Resources.Proto;
using PemukulPaku.GameServer.MPModule;
namespace PemukulPaku.GameServer.Handlers.One
{
[PacketCmdId(CmdId.CreateLobbyReq)]
internal class CreateLobbyReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
CreateLobbyReq Data = packet.GetDecodedBody<CreateLobbyReq>();
Team team = Lobby.GetInstance().CreateTeam(new(Data.StageId, Data.MinLevel, Data.LobbyEnterType, session, Data.TeamName));
CreateLobbyRsp Rsp = new()
{
retcode = CreateLobbyRsp.Retcode.Succ,
LobbyId = team.LeaderUid,
StageId = team.StageId,
MinLevel = team.MinLevel,
LobbyEnterType = team.LobbyEnterType,
MaxLevel = 0,
TeamName = team.Name
};
session.Send(Packet.FromProto(Rsp, CmdId.CreateLobbyRsp));
}
}
}

View File

@@ -0,0 +1,24 @@
using Common.Resources.Proto;
namespace PemukulPaku.GameServer.Handlers.One
{
[PacketCmdId(CmdId.GetMpDataReq)]
internal class GetMpDataReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
GetMpDataRsp Rsp = new()
{
retcode = GetMpDataRsp.Retcode.Succ,
DataType = MpDataType.MpDataAll,
op_type = GetMpDataRsp.OpType.InitData,
MpLevel = 1,
MpExp = 0,
TeamAvatarId = session.Player.GetDetailData().LeaderAvatar.AvatarId,
PunishEndTime = 0
};
session.Send(Packet.FromProto(Rsp, CmdId.GetMpDataRsp));
}
}
}

View File

@@ -0,0 +1,27 @@
using Common;
using Common.Resources.Proto;
namespace PemukulPaku.GameServer.Handlers.One
{
[PacketCmdId(CmdId.GetWeekDayActivityDataReq)]
internal class GetWeekDayActivityDataReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
GetWeekDayActivityDataRsp Rsp = new() { retcode = GetWeekDayActivityDataRsp.Retcode.Succ };
Rsp.ActivityLists.Add(new()
{
ActivityId = 1003,
StageIdLists = new uint[] { 101302, 101303, 101304, 101305 },
EnterTimes = 1,
BeginTime = 0,
EndTime = (uint)Global.GetUnixInSeconds() + 3600 * 24 * 7,
ActivityEndTime = (uint)Global.GetUnixInSeconds() * (10 / 8),
ForceOpenTime = 0
});
session.Send(Packet.FromProto(Rsp, CmdId.GetWeekDayActivityDataRsp));
}
}
}

View File

@@ -0,0 +1,13 @@
using Common.Resources.Proto;
namespace PemukulPaku.GameServer.Handlers.One
{
[PacketCmdId(CmdId.MpGetTeamReq)]
internal class MpGetTeamReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
session.Send(Packet.FromProto(new MpGetTeamRsp() { retcode = MpGetTeamRsp.Retcode.NotInTeam }, CmdId.GetMpDataRsp));
}
}
}

View File

@@ -0,0 +1,13 @@
using Common.Resources.Proto;
namespace PemukulPaku.GameServer.Handlers.One
{
[PacketCmdId(CmdId.MpMemberSetClientStatusReq)]
internal class MpMemberSetClientStatusReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
session.Send(Packet.FromProto(new MpMemberSetClientStatusRsp() { retcode = MpMemberSetClientStatusRsp.Retcode.Succ }, CmdId.MpMemberSetClientStatusRsp));
}
}
}

View File

@@ -0,0 +1,27 @@
using Common.Resources.Proto;
using PemukulPaku.GameServer.MPModule;
namespace PemukulPaku.GameServer.Handlers.One
{
[PacketCmdId(CmdId.MpTeamEnterLobbyReq)]
public class MpTeamEnterLobbyReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
MpTeamEnterLobbyReq Data = packet.GetDecodedBody<MpTeamEnterLobbyReq>();
Lobby.GetInstance().Teams.TryGetValue(session.Player.User.Uid, out Team? team);
MpTeamEnterLobbyRsp Rsp = new() { retcode = MpTeamEnterLobbyRsp.Retcode.NotInTeam };
if (team is not null)
{
team.StageId = Data.StageId;
Lobby.GetInstance().SyncTeam(session.Player.User.Uid);
Rsp.retcode = MpTeamEnterLobbyRsp.Retcode.Succ;
Rsp.StageId = team.StageId;
Rsp.TeamId = team.LeaderUid;
Rsp.TeamName = team.Name;
}
session.Send(Packet.FromProto(Rsp, CmdId.MpTeamEnterLobbyRsp));
}
}
}

View File

@@ -0,0 +1,19 @@
using Common.Resources.Proto;
namespace PemukulPaku.GameServer.Handlers.Three
{
[PacketCmdId(CmdId.GetPhotoDataReq)]
internal class GetPhotoDataReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
GetPhotoDataReq Data = packet.GetDecodedBody<GetPhotoDataReq>();
session.Send(Packet.FromProto(new GetPhotoDataRsp()
{
retcode = GetPhotoDataRsp.Retcode.Succ,
Type = Data.Type
}, CmdId.GetPhotoDataRsp));
}
}
}

View File

@@ -0,0 +1,16 @@
using Common.Resources.Proto;
namespace PemukulPaku.GameServer.Handlers.Three
{
[PacketCmdId(CmdId.GetTeamListReq)]
internal class GetTeamListReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
GetTeamListReq Data = packet.GetDecodedBody<GetTeamListReq>();
GetTeamListRsp Rsp = new() { retcode = GetTeamListRsp.Retcode.Succ };
session.Send(Packet.FromProto(Rsp, CmdId.GetTeamListRsp));
}
}
}

View File

@@ -0,0 +1,21 @@
using Common.Resources.Proto;
namespace PemukulPaku.GameServer.Handlers.Two
{
[PacketCmdId(CmdId.GetExtraStoryChallengeModeDataReq)]
internal class GetExtraStoryChallengeModeDataReqHandler : IPacketHandler
{
public void Handle(Session session, Packet packet)
{
GetExtraStoryChallengeModeDataReq Data = packet.GetDecodedBody<GetExtraStoryChallengeModeDataReq>();
session.Send(Packet.FromProto(new GetExtraStoryChallengeModeDataRsp()
{
retcode = GetExtraStoryChallengeModeDataRsp.Retcode.Succ,
ChooseDifficulty = 0,
IsCanReset = true,
ChapterId = Data.ChapterId
}, CmdId.GetExtraStoryChallengeModeDataRsp));
}
}
}

View File

@@ -19,26 +19,8 @@ namespace PemukulPaku.GameServer.Handlers.Two
Player? player = Session.FromUid(user.Uid)?.Player;
player ??= new(user);
Rsp.CardData = new()
{
Uid = player.User.Uid,
MsgData = new()
{
MsgIndex = 0,
MsgConfig = 1
},
OnPhonePendantId = 350005
};
Rsp.PlayerData = new()
{
Uid = player.User.Uid,
Nickname = player.User.Nick,
Level = (uint)PlayerLevelData.GetInstance().CalculateLevel(player.User.Exp).Level,
SelfDesc = player.User.SelfDesc,
CustomHeadId = (uint)player.User.CustomHeadId,
FrameId = player.User.FrameId < 200001 ? 200001 : (uint)player.User.FrameId,
LeaderAvatar = player.AvatarList.FirstOrDefault(x => x.AvatarId == player.User.AvatarTeamList.FirstOrDefault()?.AvatarIdLists[0])?.ToDetailData(player.Equipment) ?? new() { AvatarId = 101 }
};
Rsp.CardData = player.GetCardData();
Rsp.PlayerData = player.GetDetailData();
}
else
{

View File

@@ -0,0 +1,116 @@
using System;
using Common;
using Common.Resources.Proto;
namespace PemukulPaku.GameServer.MPModule
{
public class Lobby
{
private static Lobby? Instance;
public readonly Dictionary<uint, Team> Teams = new();
public static Lobby GetInstance()
{
return Instance ??= new Lobby();
}
public Team CreateTeam(Team team)
{
if (Teams.GetValueOrDefault(team.LeaderUid) is null)
Teams.Add(team.LeaderUid, team);
SyncTeam(team.LeaderUid);
return team;
}
public void SyncTeam(uint teamId)
{
Teams.TryGetValue(teamId, out Team? team);
if (team is null)
return;
MpTeamSyncNotify teamSyncNotify = new()
{
TeamData = new()
{
LeaderUid = team.LeaderUid,
TeamId = teamId,
LobbyEnterType = team.LobbyEnterType,
LobbyStatus = team.LobbyStatus,
MinLevel = team.MinLevel,
MaxLevel = 0,
StageId = team.StageId,
TeamName = team.Name,
Status = MpTeamStatus.TeamStatusInLobby
}
};
teamSyncNotify.TeamData.MemberLists.AddRange(team.Members.Select(member =>
{
return new MpTeamMember()
{
Index = member.Index,
Uid = member.Session.Player.User.Uid,
MpExp = 0,
Stamina = (uint)member.Session.Player.User.Stamina,
HeadAvatarId = member.Session.Player.GetDetailData().LeaderAvatar.AvatarId,
DressId = member.Session.Player.GetDetailData().LeaderAvatar.DressId,
PunishEndTime = 0,
MemberInfo = new()
{
Card = member.Session.Player.GetCardData(),
Detail = member.Session.Player.GetDetailData()
},
Status = member.Status,
ClientStatus = member.ClientStatus,
AvatarTrialId = 0,
IsWild = true,
RegionName = Global.config.Gameserver.RegionName,
FrameId = member.Session.Player.GetDetailData().FrameId,
CustomHeadId = member.Session.Player.GetDetailData().CustomHeadId,
NewbieId = 0
};
}));
foreach (Session session in team.Members.Select(x => x.Session))
{
session.Send(Packet.FromProto(teamSyncNotify, CmdId.MpTeamSyncNotify));
}
}
}
public class Team
{
public uint StageId { get; set; }
public uint MinLevel;
public uint LeaderUid;
public LobbyEnterType LobbyEnterType;
public LobbyStatus LobbyStatus = LobbyStatus.LobbyPreparing;
public List<TeamMember> Members;
public string Name;
public Team(uint stageId, uint minLevel, LobbyEnterType lobbyEnterType, in Session leader, string name)
{
StageId = stageId;
MinLevel = minLevel;
LobbyEnterType = lobbyEnterType;
Members = new List<TeamMember> { new(leader) };
LeaderUid = leader.Player.User.Uid;
Name = name;
}
}
public class TeamMember
{
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)
{
Session = session;
Index = index;
}
}
}

View File

@@ -33,50 +33,59 @@ namespace PemukulPaku.GameServer
while (Client.Connected)
{
Array.Clear(msg, 0, msg.Length);
int len = stream.Read(msg, 0, msg.Length);
if (len > 0)
try
{
List<byte[]> packets = new ();
Array.Clear(msg, 0, msg.Length);
int len = stream.Read(msg, 0, msg.Length);
ReadOnlySpan<byte> prefix = new byte[] { 0x01, 0x23, 0x45, 0x67 };
ReadOnlySpan<byte> suffix = new byte[] { 0x89, 0xAB, 0xCD, 0xEF };
Span<byte> message = msg.AsSpan();
for (int offset = 0; offset < message.Length;)
if (len > 0)
{
var segment = message[offset..];
int start = segment.IndexOf(prefix);
List<byte[]> packets = new ();
if (start == -1)
break;
ReadOnlySpan<byte> prefix = new byte[] { 0x01, 0x23, 0x45, 0x67 };
ReadOnlySpan<byte> suffix = new byte[] { 0x89, 0xAB, 0xCD, 0xEF };
int end = segment.IndexOf(suffix);
Span<byte> message = msg.AsSpan();
if (end == -1)
break;
end += suffix.Length;
packets.Add(segment[start..end].ToArray());
offset += end;
}
foreach (byte[] packet in packets)
{
if (Packet.IsValid(packet))
for (int offset = 0; offset < message.Length;)
{
ProcessPacket(new Packet(packet), true);
var segment = message[offset..];
int start = segment.IndexOf(prefix);
if (start == -1)
break;
int end = segment.IndexOf(suffix);
if (end == -1)
break;
end += suffix.Length;
packets.Add(segment[start..end].ToArray());
offset += end;
}
else
foreach (byte[] packet in packets)
{
c.Error("Invalid packet received:", BitConverter.ToString(packet).Replace("-", ""));
if (Packet.IsValid(packet))
{
ProcessPacket(new Packet(packet), true);
}
else
{
c.Error("Invalid packet received:", BitConverter.ToString(packet).Replace("-", ""));
}
}
}
}
catch (Exception)
{
break;
}
}
DisconnectProtocol();
}
public void KeepAliveLoop()
@@ -94,6 +103,11 @@ namespace PemukulPaku.GameServer
Thread.Sleep(3000);
}
DisconnectProtocol();
}
public void DisconnectProtocol()
{
Player.SaveAll();
c.Debug("Player data saved to database");
c.Warn($"{Id} disconnected");
@@ -143,6 +157,10 @@ namespace PemukulPaku.GameServer
Client.GetStream().Write(packet.Raw, 0, packet.Raw.Length);
c.Log(PacketName);
}
catch (ObjectDisposedException)
{
DisconnectProtocol();
}
catch (Exception ex)
{
c.Error($"Failed to send {PacketName}:" + ex.Message);

View File

@@ -24,4 +24,8 @@
<ProjectReference Include="HttpServer\HttpServer.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="GameServer\Handlers\Generalactivity\" />
</ItemGroup>
</Project>