fork from 1.3
This commit is contained in:
26
FreeSR.Gateserver/FreeSR.Gateserver.csproj
Normal file
26
FreeSR.Gateserver/FreeSR.Gateserver.csproj
Normal file
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNetty.Handlers" Version="0.7.5" />
|
||||
<PackageReference Include="Nito.AsyncEx.Context" Version="5.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FreeSR.Proto\FreeSR.Proto.csproj" />
|
||||
<ProjectReference Include="..\FreeSR.Shared\FreeSR.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="GateServer.example.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
47
FreeSR.Gateserver/GateServer.cs
Normal file
47
FreeSR.Gateserver/GateServer.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
namespace FreeSR.Gateserver
|
||||
{
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Shared.Configuration;
|
||||
using FreeSR.Shared.Exceptions;
|
||||
using NLog;
|
||||
|
||||
internal static class GateServer
|
||||
{
|
||||
private const string Title = "FreeSR Gate Server (EXPERIMENTAL OPEN SOURCE BUILD)";
|
||||
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Directory.SetCurrentDirectory(AppContext.BaseDirectory);
|
||||
AppDomain.CurrentDomain.UnhandledException += OnFatalException;
|
||||
|
||||
Console.Title = Title;
|
||||
s_log.Info("Initializing...");
|
||||
|
||||
ConfigurationManager<GateServerConfiguration>.Instance.Initialize("GateServer.json");
|
||||
var serverConfiguration = ConfigurationManager<GateServerConfiguration>.Instance.Model;
|
||||
NetworkManager.Instance.Initialize(serverConfiguration.Network).GetAwaiter().GetResult();
|
||||
|
||||
s_log.Info("Server is ready!");
|
||||
Thread.Sleep(-1); // TODO: Console handler
|
||||
}
|
||||
|
||||
private static void OnFatalException(object sender, UnhandledExceptionEventArgs args)
|
||||
{
|
||||
if (args.ExceptionObject is ServerInitializationException initException)
|
||||
{
|
||||
Console.WriteLine("Server initialization failed, unhandled exception!");
|
||||
Console.WriteLine(initException);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unhandled exception in runtime!");
|
||||
Console.WriteLine(args.ExceptionObject);
|
||||
}
|
||||
|
||||
Console.WriteLine("Press enter to close this window...");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
6
FreeSR.Gateserver/GateServer.example.json
Normal file
6
FreeSR.Gateserver/GateServer.example.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"Network": {
|
||||
"Host": "0.0.0.0",
|
||||
"Port": 22301
|
||||
}
|
||||
}
|
||||
9
FreeSR.Gateserver/GateServerConfiguration.cs
Normal file
9
FreeSR.Gateserver/GateServerConfiguration.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace FreeSR.Gateserver
|
||||
{
|
||||
using FreeSR.Shared.Configuration;
|
||||
|
||||
internal class GateServerConfiguration
|
||||
{
|
||||
public NetworkConfiguration Network { get; set; }
|
||||
}
|
||||
}
|
||||
40
FreeSR.Gateserver/Manager/Handlers/AvatarReqGroup.cs
Normal file
40
FreeSR.Gateserver/Manager/Handlers/AvatarReqGroup.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal static class AvatarReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetAvatarDataCsReq)]
|
||||
public static void OnGetAvatarDataCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as GetAvatarDataCsReq;
|
||||
|
||||
var response = new GetAvatarDataScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
IsAll = request.IsGetAll,
|
||||
AvatarList = new List<Avatar>()
|
||||
};
|
||||
|
||||
int[] characters = new int[] { 8001, 1005, 1003 };
|
||||
|
||||
foreach (int id in characters)
|
||||
{
|
||||
response.AvatarList.Add(new Avatar
|
||||
{
|
||||
BaseAvatarId = id,
|
||||
Exp = 0,
|
||||
Level = 1,
|
||||
Promotion = 0,
|
||||
Rank = 6,
|
||||
SkilltreeList = new List<AvatarSkillTree>(),
|
||||
EquipmentUniqueId = 0
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetAvatarDataScRsp, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
7
FreeSR.Gateserver/Manager/Handlers/ChallengeReqGroup.cs
Normal file
7
FreeSR.Gateserver/Manager/Handlers/ChallengeReqGroup.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
internal static class ChallengeReqGroup
|
||||
{
|
||||
// ChallengeReqGroup.
|
||||
}
|
||||
}
|
||||
18
FreeSR.Gateserver/Manager/Handlers/Core/HandlerAttribute.cs
Normal file
18
FreeSR.Gateserver/Manager/Handlers/Core/HandlerAttribute.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers.Core
|
||||
{
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
internal class HandlerAttribute : Attribute
|
||||
{
|
||||
public int CmdID { get; }
|
||||
|
||||
public HandlerAttribute(CmdType cmdID)
|
||||
{
|
||||
this.CmdID = (int)cmdID;
|
||||
}
|
||||
|
||||
public delegate void HandlerDelegate(NetSession session, int cmdId, object data);
|
||||
}
|
||||
}
|
||||
343
FreeSR.Gateserver/Manager/Handlers/GachaReqGroup.cs
Normal file
343
FreeSR.Gateserver/Manager/Handlers/GachaReqGroup.cs
Normal file
@@ -0,0 +1,343 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
using static System.Net.WebRequestMethods;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http.Headers;
|
||||
using System.ComponentModel.Design;
|
||||
|
||||
internal static class GachaReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetGachaInfoCsReq)]
|
||||
public static void OnGetGachaInfoCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var Gacha1List = new List<int>();
|
||||
session.Send(CmdType.GetGachaInfoScRsp, new GetGachaInfoScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
GachaRandom = 0,
|
||||
GachaInfoList = new List<GachaInfo>
|
||||
{
|
||||
new GachaInfo
|
||||
{
|
||||
//ENJHJHKNGOG = "https://webstatic-sea.hoyoverse.com/hkrpg/event/e20211215gacha-v2/index.html?authkey_ver=1&sign_type=2&auth_appid=webview_gacha&win_mode=fullscreen#/log",
|
||||
Dmdldgldfdj = new List<int>(1208),
|
||||
//JDMIIMJFAPK = "https://webstatic-sea.hoyoverse.com/hkrpg/event/e20211215gacha-v2/index.html?authkey_ver=1&sign_type=2&auth_appid=webview_gacha&win_mode=fullscreen&gacha_id=ad9815cdf2308104c377aac42c7f0cdd8d×tamp=1689725163",
|
||||
Pldioknjpjj = new List<int>{1208, 1110, 1109, 1106},
|
||||
BeginTime = 1689719400,
|
||||
EndTime = 4070880000,
|
||||
GachaId = 2010
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.DoGachaCsReq)]
|
||||
public static void OnDoGachaCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var gachaReq = data as DoGachaCsReq;
|
||||
if (gachaReq.GachaNum == 1)
|
||||
{
|
||||
session.Send(CmdType.DoGachaScRsp, new DoGachaScRsp
|
||||
{
|
||||
GachaId = gachaReq.GachaId,
|
||||
Nmaojeiedak = gachaReq.GachaRandom + 1,
|
||||
GachaNum = gachaReq.GachaNum,
|
||||
GachaItemList = new List<GachaItem>
|
||||
{
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1107,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (gachaReq.GachaNum == 10)
|
||||
{
|
||||
session.Send(CmdType.DoGachaScRsp, new DoGachaScRsp
|
||||
{
|
||||
GachaId = gachaReq.GachaId,
|
||||
Nmaojeiedak = gachaReq.GachaRandom + 10,
|
||||
GachaNum = gachaReq.GachaNum,
|
||||
GachaItemList = new List<GachaItem>
|
||||
{
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
FreeSR.Gateserver/Manager/Handlers/ItemReqGroup.cs
Normal file
30
FreeSR.Gateserver/Manager/Handlers/ItemReqGroup.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
internal static class ItemReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetBagCsReq)]
|
||||
public static void OnGetBagCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
session.Send(CmdType.GetBagScRsp, new GetBagScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
MaterialList = new List<Material>
|
||||
{
|
||||
new Material
|
||||
{
|
||||
Tid = 101,
|
||||
Num = 10
|
||||
},
|
||||
new Material
|
||||
{
|
||||
Tid = 102,
|
||||
Num = 10
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
92
FreeSR.Gateserver/Manager/Handlers/LineupReqGroup.cs
Normal file
92
FreeSR.Gateserver/Manager/Handlers/LineupReqGroup.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal static class LineupReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetCurLineupDataCsReq)]
|
||||
public static void OnGetCurLineupDataCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
var response = new GetCurLineupDataScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC
|
||||
};
|
||||
|
||||
response.Lineup = new LineupInfo
|
||||
{
|
||||
ExtraLineupType = ExtraLineupType.LINEUP_NONE,
|
||||
Name = "Squad 1",
|
||||
AvatarList = new List<LineupAvatar>(),
|
||||
LeaderSlot = 5,
|
||||
Foafdgjflmc = 5
|
||||
};
|
||||
|
||||
var characters = new int[] { 8001, 1005, 1003 };
|
||||
|
||||
foreach (int id in characters)
|
||||
{
|
||||
response.Lineup.AvatarList.Add(new LineupAvatar
|
||||
{
|
||||
AvatarType = AvatarType.AVATAR_FORMAL_TYPE,
|
||||
CurHealth = new HealthBarInfo { CurHp = 10000, MaxHp = 10000 },
|
||||
Sp = 10000,
|
||||
Satiety = 100,
|
||||
Id = id,
|
||||
Slot = response.Lineup.AvatarList.Count
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetCurLineupDataScRsp, response);
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetAllLineupDataCsReq)]
|
||||
public static void OnGetAllLineupDataCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var response = new GetAllLineupDataScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
CurIndex = 0,
|
||||
LineupList = new List<LineupInfo>()
|
||||
};
|
||||
|
||||
response.LineupList.Add(new LineupInfo
|
||||
{
|
||||
ExtraLineupType = ExtraLineupType.LINEUP_NONE,
|
||||
Name = "Squad 1",
|
||||
AvatarList = new List<LineupAvatar>(),
|
||||
Foafdgjflmc = 5,
|
||||
LeaderSlot = 3
|
||||
});
|
||||
|
||||
var characters = new int[] { 8001, 1005, 1003 };
|
||||
|
||||
foreach (int id in characters)
|
||||
{
|
||||
response.LineupList[0].AvatarList.Add(new LineupAvatar
|
||||
{
|
||||
AvatarType = AvatarType.AVATAR_FORMAL_TYPE,
|
||||
CurHealth = new HealthBarInfo { CurHp = 10000, MaxHp = 10000 },
|
||||
Sp = 10000,
|
||||
Satiety = 100,
|
||||
Id = id,
|
||||
Slot = response.LineupList[0].AvatarList.Count
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetAllLineupDataScRsp, response);
|
||||
}
|
||||
|
||||
[Handler(CmdType.ChangeLineupLeaderCsReq)]
|
||||
public static void OnChangeLineupLeaderCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as ChangeLineupLeaderCsReq;
|
||||
session.Send(CmdType.ChangeLineupLeaderScRsp, new ChangeLineupLeaderScRsp
|
||||
{
|
||||
Slot = request.Slot,
|
||||
Retcode = Retcode.RETCODE_RET_SUCC
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
7
FreeSR.Gateserver/Manager/Handlers/MailReqGroup.cs
Normal file
7
FreeSR.Gateserver/Manager/Handlers/MailReqGroup.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
internal static class MailReqGroup
|
||||
{
|
||||
// MailReqGroup
|
||||
}
|
||||
}
|
||||
87
FreeSR.Gateserver/Manager/Handlers/MissionReqGroup.cs
Normal file
87
FreeSR.Gateserver/Manager/Handlers/MissionReqGroup.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal static class MissionReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetMissionStatusCsReq)]
|
||||
public static void OnGetMissionStatusCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as GetMissionStatusCsReq;
|
||||
GetMissionStatusScRsp response = new GetMissionStatusScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
|
||||
DisabledMainMissionIdList = new List<int>(),
|
||||
FinishedMainMissionIdList = new List<int>(),
|
||||
MissionEventStatusList = new List<Mission>(),
|
||||
SubMissionStatusList = new List<Mission>(),
|
||||
UnfinishedMainMissionIdList = new List<int>()
|
||||
};
|
||||
|
||||
response.FinishedMainMissionIdList = new List<int>
|
||||
{
|
||||
1000101,
|
||||
1000112,
|
||||
1000113,
|
||||
1000201,
|
||||
1000202,
|
||||
1000204,
|
||||
1000301,
|
||||
1000401,
|
||||
1000402,
|
||||
1000410,
|
||||
1000510,
|
||||
1000601,
|
||||
1010301,
|
||||
1010302,
|
||||
1010401,
|
||||
1010403,
|
||||
1010701,
|
||||
1011403,
|
||||
1010202,
|
||||
1010902,
|
||||
1011102,
|
||||
4010101
|
||||
};
|
||||
|
||||
if (request.MissionEventIdList != null)
|
||||
{
|
||||
foreach (int id in request.MissionEventIdList)
|
||||
{
|
||||
response.UnfinishedMainMissionIdList.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (request.SubMissionIdList != null)
|
||||
{
|
||||
foreach (int id in request.SubMissionIdList)
|
||||
{
|
||||
response.MissionEventStatusList.Add(new Mission()
|
||||
{
|
||||
Id = id,
|
||||
Progress = 0,
|
||||
Status = MissionStatus.MISSION_FINISH
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (request.MainMissionIdList != null)
|
||||
{
|
||||
foreach (int id in request.MainMissionIdList)
|
||||
{
|
||||
response.SubMissionStatusList.Add(new Mission()
|
||||
{
|
||||
Id = id,
|
||||
Progress = 0,
|
||||
Status = MissionStatus.MISSION_FINISH
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetMissionStatusScRsp, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
FreeSR.Gateserver/Manager/Handlers/NPCReqGroup.cs
Normal file
41
FreeSR.Gateserver/Manager/Handlers/NPCReqGroup.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
using System.ComponentModel.Design;
|
||||
|
||||
internal static class NPCReqGroup
|
||||
{
|
||||
//maybe useless
|
||||
[Handler(CmdType.GetNpcTakenRewardCsReq)]
|
||||
public static void OnGetNpcTakenRewardCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
|
||||
var npcRewardReq = data as GetNpcTakenRewardCsReq;
|
||||
|
||||
session.Send(CmdType.GetNpcTakenRewardScRsp, new GetNpcTakenRewardScRsp
|
||||
{
|
||||
NpcId = npcRewardReq.NpcId,
|
||||
Retcode = Retcode.RETCODE_RET_SUCC
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetFirstTalkByPerformanceNpcCsReq)]
|
||||
public static void OnGetFirstTalkByPerformanceNpcCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
session.Send(CmdType.GetFirstTalkByPerformanceNpcScRsp, new GetFirstTalkByPerformanceNpcScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
NpcMeetStatusList = new List<OCLEPLBNNPA>
|
||||
{
|
||||
new OCLEPLBNNPA
|
||||
{
|
||||
IsMeet = true,
|
||||
Jljhobhmaof = 1
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
113
FreeSR.Gateserver/Manager/Handlers/PlayerReqGroup.cs
Normal file
113
FreeSR.Gateserver/Manager/Handlers/PlayerReqGroup.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
using NLog;
|
||||
|
||||
internal static class PlayerReqGroup
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Handler(CmdType.PlayerHeartBeatCsReq)]
|
||||
public static void OnPlayerHeartBeatCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var heartbeatReq = data as PlayerHeartBeatCsReq;
|
||||
|
||||
session.Send(CmdType.PlayerHeartBeatScRsp, new PlayerHeartBeatScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
|
||||
DownloadData = new ClientDownloadData(),
|
||||
ClientTimeMs = heartbeatReq.ClientTimeMs,
|
||||
ServerTimeMs = DateTimeOffset.Now.ToUnixTimeMilliseconds()
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetHeroBasicTypeInfoCsReq)]
|
||||
public static void OnGetHeroBasicTypeInfoCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
session.Send(CmdType.GetHeroBasicTypeInfoScRsp, new GetHeroBasicTypeInfoScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
Gender = Gender.GenderMan,
|
||||
BasicTypeInfoList = new List<HeroBasicTypeInfo>
|
||||
{
|
||||
new HeroBasicTypeInfo
|
||||
{
|
||||
BasicType = HeroBasicType.BoyWarrior,
|
||||
Rank = 1,
|
||||
SkillTreeList = new List<AvatarSkillTree>()
|
||||
}
|
||||
},
|
||||
CurBasicType = HeroBasicType.BoyWarrior,
|
||||
IsPlayerInfoModified = false,
|
||||
IsGenderModified = false
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetBasicInfoCsReq)]
|
||||
public static void OnGetBasicInfoCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
session.Send(CmdType.GetBasicInfoScRsp, new GetBasicInfoScRsp
|
||||
{
|
||||
CurDay = 1,
|
||||
ExchangeTimes = 0,
|
||||
Retcode = 0,
|
||||
NextRecoverTime = 2281337,
|
||||
WeekCocoonFinishedCount = 0
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.PlayerLoginCsReq)]
|
||||
public static void OnPlayerLoginCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as PlayerLoginCsReq;
|
||||
|
||||
session.Send(CmdType.PlayerLoginScRsp, new PlayerLoginScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
IsNewPlayer = false,
|
||||
LoginRandom = request.LoginRandom,
|
||||
Stamina = 100,
|
||||
ServerTimestampMs = DateTimeOffset.Now.ToUnixTimeSeconds() * 1000,
|
||||
BasicInfo = new PlayerBasicInfo
|
||||
{
|
||||
Nickname = "xeondev",
|
||||
Level = 30,
|
||||
Exp = 0,
|
||||
Stamina = 100,
|
||||
MCoin = 0,
|
||||
HCoin = 0,
|
||||
SCoin = 0,
|
||||
WorldLevel = 0
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.PlayerGetTokenCsReq)]
|
||||
public static void OnPlayerGetTokenCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as PlayerGetTokenCsReq;
|
||||
|
||||
session.Send(CmdType.PlayerGetTokenScRsp, new PlayerGetTokenScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
Uid = int.Parse(request.AccountUid),
|
||||
BlackInfo = null,
|
||||
Msg = null,
|
||||
SecretKeySeed = 0
|
||||
});
|
||||
|
||||
session.Send(CmdType.BattlePassInfoNotify, new BattlePassInfoNotify
|
||||
{
|
||||
Ibkdaabmege = ILGFODEJBBH.BP_TIER_TYPE_PREMIUM_2,
|
||||
Caajdlolcml = 0,
|
||||
Ipneaeepcmk = 4,
|
||||
Okffhjicndl = 0,
|
||||
Exp = 1000,
|
||||
Level = 50
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
7
FreeSR.Gateserver/Manager/Handlers/QuestReqGroup.cs
Normal file
7
FreeSR.Gateserver/Manager/Handlers/QuestReqGroup.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
internal static class QuestReqGroup
|
||||
{
|
||||
// QuestReqGroup
|
||||
}
|
||||
}
|
||||
45
FreeSR.Gateserver/Manager/Handlers/SceneReqGroup.cs
Normal file
45
FreeSR.Gateserver/Manager/Handlers/SceneReqGroup.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
|
||||
internal static class SceneReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetCurSceneInfoCsReq)]
|
||||
public static void OnGetCurSceneInfoCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
SceneInfo scene = new SceneInfo
|
||||
{
|
||||
GameModeType = 1,
|
||||
Bkmbkahohif = 1,
|
||||
Admbbnbnibk = 1,
|
||||
EntryId = 1000101,
|
||||
PlaneId = 10001,
|
||||
FloorId = 10001001,
|
||||
EntityList = new List<SceneEntityInfo>(),
|
||||
EnvBuffList = new List<BuffInfo>(),
|
||||
LightenSectionList = new List<int>()
|
||||
};
|
||||
|
||||
scene.EntityList.Add(new SceneEntityInfo
|
||||
{
|
||||
EntityId = 0,
|
||||
GroupId = 0,
|
||||
InstId = 0,
|
||||
Motion = new MotionInfo()
|
||||
{
|
||||
Pos = new Vector(),
|
||||
Rot = new Vector()
|
||||
}
|
||||
});
|
||||
|
||||
session.Send(CmdType.GetCurSceneInfoScRsp, new GetCurSceneInfoScRsp
|
||||
{
|
||||
Scene = scene,
|
||||
Retcode = Retcode.RETCODE_RET_SUCC
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
70
FreeSR.Gateserver/Manager/Handlers/TutorialReqGroup.cs
Normal file
70
FreeSR.Gateserver/Manager/Handlers/TutorialReqGroup.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
using NLog;
|
||||
|
||||
internal static class TutorialReqGroup
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Handler(CmdType.GetTutorialGuideCsReq)]
|
||||
public static void OnGetTutorialGuideCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
var response = new GetTutorialGuideScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
TutorialGuideList = new List<TutorialGuide>()
|
||||
};
|
||||
|
||||
int[] guides = new int[]
|
||||
{
|
||||
1101, 1102, 1104, 1105, 1116, 1117, 2006, 2007, 2101, 2105, 2106, 2107, 3007, 3105, 3106, 4001, 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 5101, 5102, 5103, 5104, 5105, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 9101, 9102, 9103, 9104, 9105, 9106, 9107, 9108
|
||||
};
|
||||
|
||||
foreach (int id in guides)
|
||||
{
|
||||
response.TutorialGuideList.Add(new TutorialGuide
|
||||
{
|
||||
Id = id,
|
||||
Status = TutorialStatus.TUTORIAL_FINISH
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetTutorialGuideScRsp, response);
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetTutorialCsReq)]
|
||||
public static void OnGetTutorialCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
int[] completedTutorials = new int[]
|
||||
{
|
||||
1001, 1002, 1003, 1004, 1005, 1007, 1008, 1010, 1011,
|
||||
2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
|
||||
3001, 3002, 3003, 3004, 3005, 3006,
|
||||
4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009,
|
||||
5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008, 5009, 5010, 5011, 5012,
|
||||
7001,
|
||||
9001, 9002, 9003, 9004, 9005, 9006
|
||||
};
|
||||
|
||||
var response = new GetTutorialScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
TutorialList = new List<Tutorial>()
|
||||
};
|
||||
|
||||
foreach (int id in completedTutorials)
|
||||
{
|
||||
response.TutorialList.Add(new Tutorial
|
||||
{
|
||||
Id = id,
|
||||
Status = TutorialStatus.TUTORIAL_FINISH
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetTutorialScRsp, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
68
FreeSR.Gateserver/Manager/NotifyManager.cs
Normal file
68
FreeSR.Gateserver/Manager/NotifyManager.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
namespace FreeSR.Gateserver.Manager
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using Nito.AsyncEx;
|
||||
using NLog;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
internal static class NotifyManager
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static List<Type> s_handlerTypes = new List<Type>();
|
||||
private static ImmutableDictionary<int, (HandlerAttribute, HandlerAttribute.HandlerDelegate)> s_notifyReqGroup;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
var handlers = ImmutableDictionary.CreateBuilder<int, (HandlerAttribute, HandlerAttribute.HandlerDelegate)>();
|
||||
|
||||
foreach (var type in s_handlerTypes)
|
||||
{
|
||||
foreach (var method in type.GetMethods())
|
||||
{
|
||||
var attribute = method.GetCustomAttribute<HandlerAttribute>();
|
||||
if (attribute == null)
|
||||
continue;
|
||||
|
||||
var parameterInfo = method.GetParameters();
|
||||
|
||||
var sessionParameter = Expression.Parameter(typeof(NetSession));
|
||||
var cmdIdParameter = Expression.Parameter(typeof(int));
|
||||
var dataParameter = Expression.Parameter(typeof(object));
|
||||
|
||||
var call = Expression.Call(method,
|
||||
Expression.Convert(sessionParameter, parameterInfo[0].ParameterType),
|
||||
Expression.Convert(cmdIdParameter, parameterInfo[1].ParameterType),
|
||||
Expression.Convert(dataParameter, parameterInfo[2].ParameterType));
|
||||
|
||||
var lambda = Expression.Lambda<HandlerAttribute.HandlerDelegate>(call, sessionParameter, cmdIdParameter, dataParameter);
|
||||
|
||||
if (!handlers.TryGetKey(attribute.CmdID, out _))
|
||||
handlers.Add(attribute.CmdID, (attribute, lambda.Compile()));
|
||||
}
|
||||
}
|
||||
|
||||
s_notifyReqGroup = handlers.ToImmutable();
|
||||
}
|
||||
|
||||
public static void Notify(NetSession session, int cmdId, object data)
|
||||
{
|
||||
if (s_notifyReqGroup.TryGetValue(cmdId, out var handler))
|
||||
{
|
||||
AsyncContext.Run(() => handler.Item2.Invoke(session, cmdId, data));
|
||||
}
|
||||
else
|
||||
{
|
||||
s_log.Warn($"Can't find handler, cmdId: {cmdId}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddReqGroupHandler(Type type)
|
||||
{
|
||||
s_handlerTypes.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
FreeSR.Gateserver/Network/Factory/ProtoFactory.cs
Normal file
53
FreeSR.Gateserver/Network/Factory/ProtoFactory.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
namespace FreeSR.Gateserver.Network.Factory
|
||||
{
|
||||
using FreeSR.Proto;
|
||||
using ProtoBuf;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
internal static class ProtoFactory
|
||||
{
|
||||
private static readonly ImmutableDictionary<CmdType, Type> s_types;
|
||||
|
||||
static ProtoFactory()
|
||||
{
|
||||
var builder = ImmutableDictionary.CreateBuilder<CmdType, Type>();
|
||||
builder.AddRange(new Dictionary<CmdType, Type>()
|
||||
{
|
||||
{CmdType.PlayerGetTokenCsReq, typeof(PlayerGetTokenCsReq)},
|
||||
{CmdType.PlayerLoginCsReq, typeof(PlayerLoginCsReq)},
|
||||
{CmdType.GetAvatarDataCsReq, typeof(GetAvatarDataCsReq)},
|
||||
|
||||
{CmdType.GetAllLineupDataCsReq, typeof(GetAllLineupDataCsReq)},
|
||||
{CmdType.GetCurLineupDataCsReq, typeof(GetCurLineupDataCsReq)},
|
||||
{CmdType.ChangeLineupLeaderCsReq, typeof(ChangeLineupLeaderCsReq)},
|
||||
|
||||
{CmdType.GetMissionStatusCsReq, typeof(GetMissionStatusCsReq)},
|
||||
{CmdType.GetQuestDataCsReq, typeof(GetQuestDataCsReq)},
|
||||
{CmdType.GetChallengeCsReq, typeof(GetChallengeCsReq)},
|
||||
{CmdType.GetCurSceneInfoCsReq, typeof(GetCurSceneInfoCsReq)},
|
||||
|
||||
{CmdType.GetBasicInfoCsReq, typeof(GetBasicInfoCsReq)},
|
||||
{CmdType.GetHeroBasicTypeInfoCsReq, typeof(GetHeroBasicTypeInfoCsReq)},
|
||||
{CmdType.PlayerHeartBeatCsReq, typeof(PlayerHeartBeatCsReq)},
|
||||
|
||||
{CmdType.GetGachaInfoCsReq, typeof(GetGachaInfoCsReq)},
|
||||
{CmdType.DoGachaCsReq, typeof(DoGachaCsReq)},
|
||||
|
||||
{CmdType.GetNpcTakenRewardCsReq, typeof(GetNpcTakenRewardCsReq)},
|
||||
{CmdType.GetFirstTalkByPerformanceNpcCsReq, typeof(GetFirstTalkByPerformanceNpcCsReq)},
|
||||
|
||||
{CmdType.GetBagCsReq, typeof(GetBagCsReq)}
|
||||
});
|
||||
|
||||
s_types = builder.ToImmutable();
|
||||
}
|
||||
|
||||
public static object Deserialize(int id, byte[] rawData)
|
||||
{
|
||||
if (s_types.TryGetValue((CmdType)id, out var type))
|
||||
return Serializer.Deserialize(type, new MemoryStream(rawData));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
FreeSR.Gateserver/Network/Handlers/Decoder/PacketDecoder.cs
Normal file
29
FreeSR.Gateserver/Network/Handlers/Decoder/PacketDecoder.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace FreeSR.Gateserver.Network.Handlers.Decoder
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Codecs;
|
||||
using DotNetty.Transport.Channels;
|
||||
using FreeSR.Gateserver.Network.Packet;
|
||||
using NLog;
|
||||
|
||||
internal class PacketDecoder : MessageToMessageDecoder<IByteBuffer>
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
protected override void Decode(IChannelHandlerContext context, IByteBuffer message, List<object> output)
|
||||
{
|
||||
var netPacket = new NetPacket();
|
||||
|
||||
DeserializationResult result;
|
||||
if ((result = netPacket.Deserialize(message)) != DeserializationResult.SUCC)
|
||||
{
|
||||
context.CloseAsync();
|
||||
s_log.Info("Closing connection, reason: " + result);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
output.Add(netPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
namespace FreeSR.Gateserver.Network.Handlers.Decoder
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Codecs;
|
||||
using DotNetty.Transport.Channels;
|
||||
|
||||
internal class StarRailHeaderDecoder : ByteToMessageDecoder
|
||||
{
|
||||
private IByteBuffer _current;
|
||||
|
||||
public StarRailHeaderDecoder()
|
||||
{
|
||||
_current = Unpooled.Buffer();
|
||||
}
|
||||
|
||||
protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
|
||||
{
|
||||
var allocated = Unpooled.Buffer();
|
||||
allocated.WriteBytes(_current);
|
||||
allocated.WriteBytes(input);
|
||||
_current = allocated;
|
||||
|
||||
byte[] lands = new byte[_current.ReadableBytes];
|
||||
_current.ReadBytes(lands);
|
||||
_current.ResetReaderIndex();
|
||||
|
||||
IByteBuffer packet;
|
||||
while ((packet = Process()) != null)
|
||||
output.Add(packet);
|
||||
}
|
||||
|
||||
private IByteBuffer Process()
|
||||
{
|
||||
if (_current.ReadableBytes < 12)
|
||||
return null;
|
||||
|
||||
_current.ReadInt(); // headMagic
|
||||
_current.ReadShort(); // CmdID
|
||||
int headerLength = _current.ReadShort();
|
||||
int payloadLength = _current.ReadInt();
|
||||
|
||||
int totalLength = 12 + headerLength + payloadLength + 4;
|
||||
_current.ResetReaderIndex();
|
||||
if (_current.ReadableBytes < totalLength)
|
||||
return null;
|
||||
|
||||
IByteBuffer result = _current.ReadBytes(totalLength);
|
||||
_current = _current.ReadBytes(_current.ReadableBytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
FreeSR.Gateserver/Network/Handlers/Encoder/PacketEncoder.cs
Normal file
19
FreeSR.Gateserver/Network/Handlers/Encoder/PacketEncoder.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace FreeSR.Gateserver.Network.Handlers.Encoder
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Codecs;
|
||||
using DotNetty.Transport.Channels;
|
||||
using FreeSR.Gateserver.Network.Packet;
|
||||
using NLog;
|
||||
|
||||
internal class PacketEncoder : MessageToByteEncoder<NetPacket>
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
protected override void Encode(IChannelHandlerContext context, NetPacket message, IByteBuffer output)
|
||||
{
|
||||
output.WriteBytes(message.Buf);
|
||||
s_log.Info($"Sent packet with cmdId {message.CmdId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
103
FreeSR.Gateserver/Network/Handlers/Manager/PacketHandler.cs
Normal file
103
FreeSR.Gateserver/Network/Handlers/Manager/PacketHandler.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
namespace FreeSR.Gateserver.Network.Handlers.Manager
|
||||
{
|
||||
using DotNetty.Transport.Channels;
|
||||
using FreeSR.Gateserver.Manager;
|
||||
using FreeSR.Gateserver.Network.Packet;
|
||||
using FreeSR.Proto;
|
||||
using NLog;
|
||||
using ProtoBuf;
|
||||
|
||||
internal class PacketHandler : ChannelHandlerAdapter
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
private readonly NetSession _session;
|
||||
|
||||
public PacketHandler(NetSession session)
|
||||
{
|
||||
_session = session;
|
||||
}
|
||||
|
||||
public override void ChannelRead(IChannelHandlerContext context, object message)
|
||||
{
|
||||
NetPacket packet = message as NetPacket;
|
||||
if (packet.Data == null)
|
||||
{
|
||||
if (!SendDummyResponse(packet.CmdId))
|
||||
s_log.Warn($"CmdID {packet.CmdId} is undefined.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
s_log.Info($"Received packet {packet.CmdId}!");
|
||||
NotifyManager.Notify(_session, packet.CmdId, packet.Data);
|
||||
}
|
||||
|
||||
private bool SendDummyResponse(int id)
|
||||
{
|
||||
if (s_dummyTable.TryGetValue((CmdType)id, out CmdType rspId))
|
||||
{
|
||||
_session.Send(rspId, new DummyPacket());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Dictionary<CmdType, CmdType> s_dummyTable = new Dictionary<CmdType, CmdType>
|
||||
{
|
||||
{CmdType.GetLevelRewardTakenListCsReq, CmdType.GetLevelRewardTakenListScRsp},
|
||||
{CmdType.GetRogueScoreRewardInfoCsReq, CmdType.GetRogueScoreRewardInfoScRsp},
|
||||
{CmdType.GetGachaInfoCsReq, CmdType.GetGachaInfoScRsp},
|
||||
{CmdType.QueryProductInfoCsReq, CmdType.QueryProductInfoScRsp},
|
||||
{CmdType.GetQuestDataCsReq, CmdType.GetQuestDataScRsp},
|
||||
{CmdType.GetQuestRecordCsReq, CmdType.GetQuestRecordScRsp},
|
||||
{CmdType.GetFriendListInfoCsReq, CmdType.GetFriendListInfoScRsp},
|
||||
{CmdType.GetFriendApplyListInfoCsReq, CmdType.GetFriendApplyListInfoScRsp},
|
||||
{CmdType.GetCurAssistCsReq, CmdType.GetCurAssistScRsp},
|
||||
{CmdType.GetRogueHandbookDataCsReq, CmdType.GetRogueHandbookDataScRsp},
|
||||
{CmdType.GetDailyActiveInfoCsReq, CmdType.GetDailyActiveInfoScRsp},
|
||||
{CmdType.GetFightActivityDataCsReq, CmdType.GetFightActivityDataScRsp},
|
||||
{CmdType.GetMultipleDropInfoCsReq, CmdType.GetMultipleDropInfoScRsp},
|
||||
{CmdType.GetPlayerReturnMultiDropInfoCsReq, CmdType.GetPlayerReturnMultiDropInfoScRsp},
|
||||
{CmdType.GetShareDataCsReq, CmdType.GetShareDataScRsp},
|
||||
{CmdType.GetTreasureDungeonActivityDataCsReq, CmdType.GetTreasureDungeonActivityDataScRsp},
|
||||
{CmdType.PlayerReturnInfoQueryCsReq, CmdType.PlayerReturnInfoQueryScRsp},
|
||||
{CmdType.GetBasicInfoCsReq, CmdType.GetBasicInfoScRsp},
|
||||
{CmdType.GetHeroBasicTypeInfoCsReq, CmdType.GetHeroBasicTypeInfoScRsp},
|
||||
{CmdType.GetBagCsReq, CmdType.GetBagScRsp},
|
||||
{CmdType.GetPlayerBoardDataCsReq, CmdType.GetPlayerBoardDataScRsp},
|
||||
{CmdType.GetAvatarDataCsReq, CmdType.GetAvatarDataScRsp},
|
||||
{CmdType.GetAllLineupDataCsReq, CmdType.GetAllLineupDataScRsp},
|
||||
{CmdType.GetActivityScheduleConfigCsReq, CmdType.GetActivityScheduleConfigScRsp},
|
||||
{CmdType.GetMissionDataCsReq, CmdType.GetMissionDataScRsp},
|
||||
{CmdType.GetMissionEventDataCsReq, CmdType.GetMissionEventDataScRsp},
|
||||
{CmdType.GetChallengeCsReq, CmdType.GetChallengeScRsp},
|
||||
{CmdType.GetCurChallengeCsReq, CmdType.GetCurChallengeScRsp},
|
||||
{CmdType.GetRogueInfoCsReq, CmdType.GetRogueInfoScRsp},
|
||||
{CmdType.GetExpeditionDataCsReq, CmdType.GetExpeditionDataScRsp},
|
||||
{CmdType.GetRogueDialogueEventDataCsReq, CmdType.GetRogueDialogueEventDataScRsp},
|
||||
{CmdType.GetJukeboxDataCsReq, CmdType.GetJukeboxDataScRsp},
|
||||
{CmdType.SyncClientResVersionCsReq, CmdType.SyncClientResVersionScRsp},
|
||||
{CmdType.DailyFirstMeetPamCsReq, CmdType.DailyFirstMeetPamScRsp},
|
||||
{CmdType.GetMuseumInfoCsReq, CmdType.GetMuseumInfoScRsp},
|
||||
{CmdType.GetLoginActivityCsReq, CmdType.GetLoginActivityScRsp},
|
||||
{CmdType.GetRaidInfoCsReq, CmdType.GetRaidInfoScRsp},
|
||||
{CmdType.GetTrialActivityDataCsReq, CmdType.GetTrialActivityDataScRsp},
|
||||
{CmdType.GetBoxingClubInfoCsReq, CmdType.GetBoxingClubInfoScRsp},
|
||||
{CmdType.GetNpcStatusCsReq, CmdType.GetNpcStatusScRsp},
|
||||
{CmdType.TextJoinQueryCsReq, CmdType.TextJoinQueryScRsp},
|
||||
{CmdType.GetSpringRecoverDataCsReq, CmdType.GetSpringRecoverDataScRsp},
|
||||
{CmdType.GetChatFriendHistoryCsReq, CmdType.GetChatFriendHistoryScRsp},
|
||||
{CmdType.GetSecretKeyInfoCsReq, CmdType.GetSecretKeyInfoScRsp},
|
||||
{CmdType.GetVideoVersionKeyCsReq, CmdType.GetVideoVersionKeyScRsp},
|
||||
{CmdType.GetCurLineupDataCsReq, CmdType.GetCurLineupDataScRsp},
|
||||
{CmdType.GetCurBattleInfoCsReq, CmdType.GetCurBattleInfoScRsp},
|
||||
{CmdType.GetCurSceneInfoCsReq, CmdType.GetCurSceneInfoScRsp},
|
||||
{CmdType.GetPhoneDataCsReq, CmdType.GetPhoneDataScRsp},
|
||||
{CmdType.PlayerLoginFinishCsReq, CmdType.PlayerLoginFinishScRsp}
|
||||
};
|
||||
|
||||
[ProtoContract]
|
||||
private class DummyPacket { }
|
||||
}
|
||||
}
|
||||
32
FreeSR.Gateserver/Network/NetSession.cs
Normal file
32
FreeSR.Gateserver/Network/NetSession.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace FreeSR.Gateserver.Network
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Transport.Channels;
|
||||
using FreeSR.Gateserver.Network.Packet;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal class NetSession
|
||||
{
|
||||
private IChannel _channel;
|
||||
|
||||
public NetSession(IChannel channel)
|
||||
{
|
||||
_channel = channel;
|
||||
}
|
||||
|
||||
public async void Send<T>(CmdType cmdId, T data) where T : class
|
||||
{
|
||||
var packet = new NetPacket()
|
||||
{
|
||||
CmdId = (int)cmdId,
|
||||
Data = data
|
||||
};
|
||||
|
||||
var buffer = Unpooled.Buffer();
|
||||
packet.Serialize<T>(buffer);
|
||||
packet.Buf = buffer;
|
||||
|
||||
await _channel.WriteAndFlushAsync(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
FreeSR.Gateserver/Network/NetworkManager.cs
Normal file
65
FreeSR.Gateserver/Network/NetworkManager.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
namespace FreeSR.Gateserver.Network
|
||||
{
|
||||
using DotNetty.Transport.Bootstrapping;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
using FreeSR.Gateserver.Manager;
|
||||
using FreeSR.Gateserver.Manager.Handlers;
|
||||
using FreeSR.Gateserver.Network.Handlers.Decoder;
|
||||
using FreeSR.Gateserver.Network.Handlers.Encoder;
|
||||
using FreeSR.Gateserver.Network.Handlers.Manager;
|
||||
using FreeSR.Shared;
|
||||
using FreeSR.Shared.Configuration;
|
||||
using System.Net;
|
||||
|
||||
internal sealed class NetworkManager : Singleton<NetworkManager>
|
||||
{
|
||||
private ServerBootstrap _bootstrap;
|
||||
private IChannel _serverChannel;
|
||||
|
||||
public async Task Initialize(NetworkConfiguration config)
|
||||
{
|
||||
// Notify handlers
|
||||
{
|
||||
NotifyManager.AddReqGroupHandler(typeof(PlayerReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(MailReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(TutorialReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(ItemReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(AvatarReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(LineupReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(MissionReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(QuestReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(ChallengeReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(SceneReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(GachaReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(NPCReqGroup));
|
||||
|
||||
NotifyManager.Init();
|
||||
}
|
||||
|
||||
var bossGroup = new MultithreadEventLoopGroup();
|
||||
var workerGroup = new MultithreadEventLoopGroup();
|
||||
|
||||
_bootstrap = new ServerBootstrap()
|
||||
.Group(bossGroup, workerGroup)
|
||||
.Channel<TcpServerSocketChannel>()
|
||||
.Option(ChannelOption.SoBacklog, 120)
|
||||
.Option(ChannelOption.TcpNodelay, true)
|
||||
.Option(ChannelOption.SoKeepalive, true)
|
||||
.ChildHandler(
|
||||
new ActionChannelInitializer<IChannel>(channel =>
|
||||
{
|
||||
var session = new NetSession(channel);
|
||||
var pipeline = channel.Pipeline;
|
||||
|
||||
pipeline.AddFirst(new StarRailHeaderDecoder());
|
||||
pipeline.AddLast(new PacketDecoder());
|
||||
pipeline.AddLast(new PacketEncoder());
|
||||
pipeline.AddLast(new PacketHandler(session));
|
||||
})
|
||||
);
|
||||
|
||||
_serverChannel = await _bootstrap.BindAsync(IPAddress.Parse(config.Host), config.Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
77
FreeSR.Gateserver/Network/Packet/NetPacket.cs
Normal file
77
FreeSR.Gateserver/Network/Packet/NetPacket.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
namespace FreeSR.Gateserver.Network.Packet
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using FreeSR.Gateserver.Network.Factory;
|
||||
using ProtoBuf;
|
||||
|
||||
internal class NetPacket
|
||||
{
|
||||
private const uint HeadMagicConst = 0x9d74c714;
|
||||
private const uint TailMagicConst = 0xd7a152c8;
|
||||
|
||||
public int CmdId { get; set; }
|
||||
public int HeadLen { get; set; }
|
||||
public uint HeadMagic { get; set; }
|
||||
public int PacketLen { get; set; }
|
||||
public byte[] RawData { get; set; }
|
||||
public uint TailMagic { get; set; }
|
||||
public object Data { get; set; }
|
||||
public IByteBuffer Buf { get; set; }
|
||||
|
||||
public NetPacket()
|
||||
{
|
||||
// NetPacket.
|
||||
}
|
||||
|
||||
public DeserializationResult Deserialize(IByteBuffer buf)
|
||||
{
|
||||
HeadMagic = buf.ReadUnsignedInt();
|
||||
if (HeadMagic != HeadMagicConst)
|
||||
return DeserializationResult.MAGIC_MISMATCH;
|
||||
|
||||
CmdId = buf.ReadShort();
|
||||
HeadLen = buf.ReadShort();
|
||||
PacketLen = buf.ReadInt();
|
||||
|
||||
if (buf.ReadableBytes < HeadLen + PacketLen + 4)
|
||||
return DeserializationResult.INVALID_LENGTH;
|
||||
|
||||
RawData = new byte[PacketLen];
|
||||
|
||||
_ = buf.ReadBytes(HeadLen);
|
||||
buf.ReadBytes(RawData);
|
||||
|
||||
TailMagic = buf.ReadUnsignedInt();
|
||||
if (TailMagic != TailMagicConst)
|
||||
return DeserializationResult.MAGIC_MISMATCH;
|
||||
|
||||
Data = ProtoFactory.Deserialize(CmdId, RawData);
|
||||
|
||||
return DeserializationResult.SUCC;
|
||||
}
|
||||
|
||||
public void Serialize<T>(IByteBuffer buf) where T : class
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
Serializer.Serialize(stream, Data as T);
|
||||
RawData = stream.ToArray();
|
||||
PacketLen = RawData.Length;
|
||||
|
||||
buf.WriteUnsignedShort((ushort)(HeadMagicConst >> 16));
|
||||
buf.WriteUnsignedShort(0xc714);
|
||||
buf.WriteShort(CmdId);
|
||||
buf.WriteShort(HeadLen);
|
||||
buf.WriteInt(PacketLen);
|
||||
buf.WriteBytes(RawData);
|
||||
buf.WriteUnsignedShort((ushort)(TailMagicConst >> 16));
|
||||
buf.WriteUnsignedShort(0x52c8);
|
||||
}
|
||||
}
|
||||
|
||||
internal enum DeserializationResult
|
||||
{
|
||||
SUCC = 1,
|
||||
INVALID_LENGTH,
|
||||
MAGIC_MISMATCH
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user