Congratulation! The cutscene works now!

This commit is contained in:
Somebody
2024-03-24 15:38:49 +08:00
parent 5233762bd1
commit b312b7ddde
45 changed files with 836 additions and 106 deletions

View File

@@ -16,7 +16,9 @@ namespace EggLink.DanhengServer.Data.Config
public float PosZ { get; set; }
public bool IsDelete { get; set; }
public string Name { get; set; } = "";
public float RotX { get; set; }
public float RotY { get; set; }
public float RotZ { get; set; }
public Position ToPositionProto()
{
@@ -33,8 +35,8 @@ namespace EggLink.DanhengServer.Data.Config
return new()
{
Y = (int)(RotY * 1000f),
X = 0,
Z = 0,
X = (int)(RotX * 1000f),
Z = (int)(RotZ * 1000f),
};
}
}

View File

@@ -8,8 +8,6 @@ namespace EggLink.DanhengServer.Data.Config
{
public class PropInfo : PositionInfo
{
public float RotX { get; set; }
public float RotZ { get; set; }
public int MappingInfoID { get; set; }
public int AnchorGroupID { get; set; }
public int AnchorID { get; set; }

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Data.Excel
namespace EggLink.DanhengServer.Data.Excel
{
[ResourceEntity("AvatarSkillTreeConfig.json")]
public class AvatarSkillTreeConfigExcel : ExcelResource
@@ -18,7 +12,7 @@ namespace EggLink.DanhengServer.Data.Excel
public override int GetId()
{
return (PointID << 4) + Level;
return (PointID * 10) + Level;
}
public override void AfterAllDone()
@@ -28,6 +22,7 @@ namespace EggLink.DanhengServer.Data.Excel
{
excel.DefaultSkillTree.Add(this);
}
GameData.AvatarSkillTreeConfigData.Add(GetId(), this);
}
}
}

View File

@@ -18,6 +18,7 @@ namespace EggLink.DanhengServer.Data.Excel
public List<MissionParam> TakeParam { get; set; } = [];
public List<MissionParam> BeginParam { get; set; } = [];
public int RewardID { get; set; }
public List<int> SubRewardList { get; set; } = [];
[JsonIgnore()]
private MissionInfo? InnerMissionInfo { get; set; }

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Data.Excel
{
[ResourceEntity("PlayerLevelConfig.json")]
public class PlayerLevelConfigExcel : ExcelResource
{
public int Level { get; set; }
public int PlayerExp { get; set; }
public int StaminaLimit { get; set; }
public int LevelRewardID { get; set; }
public override int GetId()
{
return Level;
}
public override void Loaded()
{
GameData.PlayerLevelConfigData.Add(Level, this);
}
}
}

View File

@@ -18,7 +18,7 @@ namespace EggLink.DanhengServer.Data.Excel
return QuestID;
}
public override void AfterAllDone()
public override void Loaded()
{
GameData.QuestDataData.Add(QuestID, this);
}

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Data.Excel
{
[ResourceEntity("RewardData.json")]
public class RewardDataExcel : ExcelResource
{
public int RewardID { get; set; }
public int Hcoin { get; set; }
public int ItemID_1 { get; set; }
public int Count_1 { get; set; }
public int ItemID_2 { get; set; }
public int Count_2 { get; set; }
public int ItemID_3 { get; set; }
public int Count_3 { get; set; }
public int ItemID_4 { get; set; }
public int Count_4 { get; set; }
public int ItemID_5 { get; set; }
public int Count_5 { get; set; }
public int ItemID_6 { get; set; }
public int Count_6 { get; set; }
public override int GetId()
{
return RewardID;
}
public override void Loaded()
{
GameData.RewardDataData[RewardID] = this;
}
public List<(int, int)> GetItems()
{
var items = new List<(int, int)>();
if (ItemID_1 != 0)
{
items.Add((ItemID_1, Count_1));
}
if (ItemID_2 != 0)
{
items.Add((ItemID_2, Count_2));
}
if (ItemID_3 != 0)
{
items.Add((ItemID_3, Count_3));
}
if (ItemID_4 != 0)
{
items.Add((ItemID_4, Count_4));
}
if (ItemID_5 != 0)
{
items.Add((ItemID_5, Count_5));
}
if (ItemID_6 != 0)
{
items.Add((ItemID_6, Count_6));
}
return items;
}
}
}

View File

@@ -7,6 +7,7 @@ namespace EggLink.DanhengServer.Data
public static class GameData
{
public static Dictionary<int, AvatarConfigExcel> AvatarConfigData { get; private set; } = [];
public static Dictionary<int, AvatarSkillTreeConfigExcel> AvatarSkillTreeConfigData { get; private set; } = [];
public static Dictionary<int, CocoonConfigExcel> CocoonConfigData { get; private set; } = [];
public static Dictionary<int, StageConfigExcel> StageConfigData { get; private set; } = [];
public static Dictionary<int, MapEntranceExcel> MapEntranceData { get; private set; } = [];
@@ -16,6 +17,7 @@ namespace EggLink.DanhengServer.Data
public static Dictionary<int, NPCMonsterDataExcel> NpcMonsterDataData { get; private set; } = [];
public static Dictionary<int, NPCDataExcel> NpcDataData { get; private set; } = [];
public static Dictionary<int, QuestDataExcel> QuestDataData { get; private set; } = [];
public static Dictionary<int, PlayerLevelConfigExcel> PlayerLevelConfigData { get; private set; } = [];
public static Dictionary<string, FloorInfo> FloorInfoData { get; private set; } = [];
public static Dictionary<int, ItemConfigExcel> ItemConfigData { get; private set; } = [];
@@ -28,6 +30,7 @@ namespace EggLink.DanhengServer.Data
public static Dictionary<int, MainMissionExcel> MainMissionData { get; private set; } = [];
public static Dictionary<int, SubMissionExcel> SubMissionData { get; private set; } = [];
public static Dictionary<int, RewardDataExcel> RewardDataData { get; private set; } = [];
public static void GetFloorInfo(int planeId, int floorId, out FloorInfo outer)
{

View File

@@ -25,6 +25,7 @@ namespace EggLink.DanhengServer.Data
{
var classes = Assembly.GetExecutingAssembly().GetTypes(); // Get all classes in the assembly
var resList = new List<ExcelResource>();
foreach (var cls in classes)
{
var attribute = (ResourceEntity)Attribute.GetCustomAttribute(cls, typeof(ResourceEntity))!;
@@ -62,6 +63,7 @@ namespace EggLink.DanhengServer.Data
foreach (var item in jArray)
{
var res = JsonConvert.DeserializeObject(item.ToString(), cls);
resList.Add((ExcelResource)res!);
((ExcelResource?)res)?.Loaded();
count++;
}
@@ -84,12 +86,14 @@ namespace EggLink.DanhengServer.Data
foreach (var nestedItem in nestedObject ?? [])
{
var nestedInstance = JsonConvert.DeserializeObject(nestedItem.Value!.ToString(), cls);
resList.Add((ExcelResource)nestedInstance!);
((ExcelResource?)nestedInstance)?.Loaded();
count++;
}
}
else
{
resList.Add((ExcelResource)instance!);
((ExcelResource)instance).Loaded();
}
count++;
@@ -106,15 +110,9 @@ namespace EggLink.DanhengServer.Data
Logger.Info($"Loaded {count} {cls.Name}s.");
}
}
foreach (var cls in classes)
foreach (var cls in resList)
{
var attribute = (ResourceEntity)Attribute.GetCustomAttribute(cls, typeof(ResourceEntity))!;
if (attribute != null)
{
var resource = (ExcelResource)Activator.CreateInstance(cls)!;
resource.AfterAllDone();
}
cls.AfterAllDone();
}
}

View File

@@ -15,7 +15,9 @@ namespace EggLink.DanhengServer.Database.Avatar
[SugarColumn(IsNullable = true, IsJson = true)]
public List<AvatarInfo>? Avatars { get; set; }
[SugarColumn(IsJson = true)]
public List<int> AssistAvatars { get; set; } = [];
[SugarColumn(IsJson = true)]
public List<int> DisplayAvatars { get; set; } = [];
}

View File

@@ -130,6 +130,20 @@ namespace EggLink.DanhengServer.Database.Inventory
};
}
public Item ToProto()
{
return new()
{
ItemId = (uint)ItemId,
Num = (uint)Count,
Level = (uint)Level,
MainAffixId = (uint)MainAffix,
Rank = (uint)Rank,
Promotion = (uint)Promotion,
UniqueId = (uint)UniqueId,
};
}
#endregion
}

View File

@@ -1,9 +1,15 @@
namespace EggLink.DanhengServer.Database.Player
using SqlSugar;
namespace EggLink.DanhengServer.Database.Player
{
[SugarTable("UnlockData")]
public class PlayerUnlockData : BaseDatabaseData
{
[SugarColumn(IsJson = true)]
public List<int> HeadIcons { get; set; } = [];
[SugarColumn(IsJson = true)]
public List<int> ChatBubbles { get; set; } = [];
[SugarColumn(IsJson = true)]
public List<int> PhoneThemes { get; set; } = [];
}
}

View File

@@ -26,8 +26,8 @@ namespace EggLink.DanhengServer.Proto {
string.Concat(
"Cg9FcXVpcG1lbnQucHJvdG8ilgEKCUVxdWlwbWVudBILCgN0aWQYAyABKA0S",
"CwoDZXhwGAYgASgNEhQKDGlzX3Byb3RlY3RlZBgFIAEoCBINCgVsZXZlbBgO",
"IAEoDRIWCg5iYXNlX2F2YXRhcl9pZBgPIAEoDRIMCgRyYW5rGAwgASgNEhEK",
"CXByb21vdGlvbhgEIAEoDRIRCgl1bmlxdWVfaWQYCyABKA1CHqoCG0VnZ0xp",
"IAEoDRIWCg5iYXNlX2F2YXRhcl9pZBgPIAEoDRIMCgRyYW5rGAQgASgNEhEK",
"CXByb21vdGlvbhgMIAEoDRIRCgl1bmlxdWVfaWQYCyABKA1CHqoCG0VnZ0xp",
"bmsuRGFuaGVuZ1NlcnZlci5Qcm90b2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
@@ -152,7 +152,7 @@ namespace EggLink.DanhengServer.Proto {
}
/// <summary>Field number for the "rank" field.</summary>
public const int RankFieldNumber = 12;
public const int RankFieldNumber = 4;
private uint rank_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
@@ -164,7 +164,7 @@ namespace EggLink.DanhengServer.Proto {
}
/// <summary>Field number for the "promotion" field.</summary>
public const int PromotionFieldNumber = 4;
public const int PromotionFieldNumber = 12;
private uint promotion_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
@@ -247,9 +247,9 @@ namespace EggLink.DanhengServer.Proto {
output.WriteRawTag(24);
output.WriteUInt32(Tid);
}
if (Promotion != 0) {
if (Rank != 0) {
output.WriteRawTag(32);
output.WriteUInt32(Promotion);
output.WriteUInt32(Rank);
}
if (IsProtected != false) {
output.WriteRawTag(40);
@@ -263,9 +263,9 @@ namespace EggLink.DanhengServer.Proto {
output.WriteRawTag(88);
output.WriteUInt32(UniqueId);
}
if (Rank != 0) {
if (Promotion != 0) {
output.WriteRawTag(96);
output.WriteUInt32(Rank);
output.WriteUInt32(Promotion);
}
if (Level != 0) {
output.WriteRawTag(112);
@@ -289,9 +289,9 @@ namespace EggLink.DanhengServer.Proto {
output.WriteRawTag(24);
output.WriteUInt32(Tid);
}
if (Promotion != 0) {
if (Rank != 0) {
output.WriteRawTag(32);
output.WriteUInt32(Promotion);
output.WriteUInt32(Rank);
}
if (IsProtected != false) {
output.WriteRawTag(40);
@@ -305,9 +305,9 @@ namespace EggLink.DanhengServer.Proto {
output.WriteRawTag(88);
output.WriteUInt32(UniqueId);
}
if (Rank != 0) {
if (Promotion != 0) {
output.WriteRawTag(96);
output.WriteUInt32(Rank);
output.WriteUInt32(Promotion);
}
if (Level != 0) {
output.WriteRawTag(112);
@@ -407,7 +407,7 @@ namespace EggLink.DanhengServer.Proto {
break;
}
case 32: {
Promotion = input.ReadUInt32();
Rank = input.ReadUInt32();
break;
}
case 40: {
@@ -423,7 +423,7 @@ namespace EggLink.DanhengServer.Proto {
break;
}
case 96: {
Rank = input.ReadUInt32();
Promotion = input.ReadUInt32();
break;
}
case 112: {
@@ -454,7 +454,7 @@ namespace EggLink.DanhengServer.Proto {
break;
}
case 32: {
Promotion = input.ReadUInt32();
Rank = input.ReadUInt32();
break;
}
case 40: {
@@ -470,7 +470,7 @@ namespace EggLink.DanhengServer.Proto {
break;
}
case 96: {
Rank = input.ReadUInt32();
Promotion = input.ReadUInt32();
break;
}
case 112: {

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Util
namespace EggLink.DanhengServer.Util
{
public static class GameConstants
{
@@ -16,5 +10,7 @@ namespace EggLink.DanhengServer.Util
public const int INVENTORY_MAX_EQUIPMENT = 1500;
public const int INVENTORY_MAX_RELIC = 1500;
public const int INVENTORY_MAX_MATERIAL = 2000;
public static readonly List<int> UpgradeWorldLevel = [20, 30, 40, 50, 60, 65];
}
}

View File

@@ -8,36 +8,41 @@ using System.Threading.Tasks;
namespace EggLink.DanhengServer.Util
{
public class Logger
public class Logger(string moduleName)
{
private readonly string ModuleName;
private readonly string ModuleName = moduleName;
private static FileInfo? LogFile;
public Logger(string moduleName)
{
ModuleName = moduleName;
}
private static object _lock = new();
public void Log(string message, LoggerLevel level)
{
Console.Write("[");
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.Write(DateTime.Now.ToString("HH:mm:ss"));
Console.ResetColor();
Console.Write("] ");
Console.Write("[");
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.Write(ModuleName);
Console.ResetColor();
Console.Write("] ");
Console.Write("[");
Console.ForegroundColor = (ConsoleColor)level;
Console.Write(level);
Console.ResetColor();
Console.WriteLine("] " + message);
lock (_lock)
{
Console.Write("[");
var logMessage = $"[{DateTime.Now:HH:mm:ss}] [{ModuleName}] [{level}] {message}";
WriteToFile(logMessage);
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.Write(DateTime.Now.ToString("HH:mm:ss"));
Console.ResetColor();
Console.Write("] ");
Console.Write("[");
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.Write(ModuleName);
Console.ResetColor();
Console.Write("] ");
Console.Write("[");
Console.ForegroundColor = (ConsoleColor)level;
Console.Write(level);
Console.ResetColor();
Console.WriteLine("] " + message);
var logMessage = $"[{DateTime.Now:HH:mm:ss}] [{ModuleName}] [{level}] {message}";
WriteToFile(logMessage);
}
}
public void Info(string message, Exception? e = null)

View File

@@ -30,7 +30,7 @@ namespace EggLink.DanhengServer.Command.Cmd
{
var scene = arg.Target!.Player!.SceneInstance!;
EntityProp? prop = null;
foreach (var entity in scene.GetEntitiesInGroup<EntityProp>(arg.GetInt(1)))
foreach (var entity in scene.GetEntitiesInGroup<EntityProp>(arg.GetInt(0)))
{
if (entity.PropInfo.ID == arg.GetInt(1))
{

View File

@@ -20,14 +20,22 @@ namespace EggLink.DanhengServer.Command.Cmd
foreach (var mission in GameData.SubMissionData.Values)
{
missionManager.AcceptMainMission(mission.MainMissionID);
missionManager.FinishSubMission(mission.SubMissionID);
if (!missionManager.Data.MissionInfo.TryGetValue(mission.MainMissionID, out Dictionary<int, Database.Mission.MissionInfo>? value))
{
value = ([]);
missionManager.Data.MissionInfo[mission.MainMissionID] = value;
}
value[mission.SubMissionID] = new Database.Mission.MissionInfo()
{
Status = Enums.MissionPhaseEnum.Finish,
MissionId = mission.SubMissionID,
};
}
foreach (var mission in GameData.MainMissionData.Values)
{
missionManager.AcceptMainMission(mission.MainMissionID);
missionManager.FinishMainMission(mission.MainMissionID);
missionManager.Data.MainMissionInfo[mission.MainMissionID] = Enums.MissionPhaseEnum.Finish;
}
arg.SendMsg("All missions unlocked!");

View File

@@ -25,10 +25,10 @@ namespace EggLink.DanhengServer.Game.Inventory
Data = inventory!;
}
public void AddItem(int itemId, int count, bool notify = false)
public ItemData? AddItem(int itemId, int count, bool notify = true)
{
GameData.ItemConfigData.TryGetValue(itemId, out var itemConfig);
if (itemConfig == null) return;
if (itemConfig == null) return null;
ItemData? itemData = null;
@@ -58,6 +58,35 @@ namespace EggLink.DanhengServer.Game.Inventory
Data.RelicItems.Find(x => x.UniqueId == item.UniqueId)!.SubAffixes = item.SubAffixes;
itemData = item;
break;
case ItemMainTypeEnum.Virtual:
switch (itemConfig.ID)
{
case 1:
Player.Data.Hcoin += count;
break;
case 2:
Player.Data.Scoin += count;
break;
case 3:
Player.Data.Mcoin += count;
break;
case 11:
Player.Data.Stamina += count;
break;
case 22:
Player.Data.Exp += count;
Player.OnAddExp();
break;
case 32:
Player.Data.TalentPoints += count;
// TODO : send VirtualItemPacket instead of PlayerSyncPacket
break;
}
if (count != 0)
{
Player.SendPacket(new PacketPlayerSyncScNotify(Player.ToProto()));
}
break;
default:
itemData = PutItem(itemId, Math.Min(count, itemConfig.PileLimit));
break;
@@ -66,9 +95,15 @@ namespace EggLink.DanhengServer.Game.Inventory
if (itemData != null)
{
Player.SendPacket(new PacketPlayerSyncScNotify(itemData));
if (notify)
{
Player.SendPacket(new PacketScenePlaneEventScNotify(itemData));
}
}
DatabaseHelper.Instance?.UpdateInstance(Data);
return itemData;
}
public ItemData PutItem(int itemId, int count, int rank = 0, int promotion = 0, int level = 0, int exp = 0, int totalExp = 0, int mainAffix = 0, List<ItemSubAffix>? subAffixes = null, int uniqueId = 0)
@@ -107,8 +142,82 @@ namespace EggLink.DanhengServer.Game.Inventory
return item;
}
public void RemoveItem(int itemId, int count)
{
GameData.ItemConfigData.TryGetValue(itemId, out var itemConfig);
if (itemConfig == null) return;
ItemData? itemData = null;
switch (itemConfig.ItemMainType)
{
case ItemMainTypeEnum.Material:
var item = Data.MaterialItems.Find(x => x.ItemId == itemId);
if (item == null) return;
item.Count -= count;
if (item.Count <= 0)
{
Data.MaterialItems.Remove(item);
item.Count = 0;
}
itemData = item;
break;
case ItemMainTypeEnum.Virtual:
switch (itemConfig.ID)
{
case 1:
Player.Data.Hcoin -= count;
break;
case 2:
Player.Data.Scoin -= count;
break;
case 3:
Player.Data.Mcoin -= count;
break;
case 32:
Player.Data.TalentPoints -= count;
break;
}
break;
}
if (itemData != null)
{
Player.SendPacket(new PacketPlayerSyncScNotify(itemData));
}
DatabaseHelper.Instance?.UpdateInstance(Data);
}
#region Equip
public void EquipAvatar(int baseAvatarId, int equipmentUniqueId)
{
var itemData = Data.EquipmentItems.Find(x => x.UniqueId == equipmentUniqueId);
var avatarData = Player.AvatarManager!.GetAvatar(baseAvatarId);
if (itemData == null || avatarData == null) return;
var oldItem = Data.EquipmentItems.Find(x => x.UniqueId == avatarData.EquipId);
if (itemData.EquipAvatar > 0) // already be dressed
{
var equipAvatar = Player.AvatarManager.GetAvatar(itemData.EquipAvatar);
if (equipAvatar != null && oldItem != null)
{
// switch
equipAvatar.EquipId = oldItem.UniqueId;
oldItem.EquipAvatar = equipAvatar.GetAvatarId();
Player.SendPacket(new PacketPlayerSyncScNotify(equipAvatar, oldItem));
}
} else
{
if (oldItem != null)
{
oldItem.EquipAvatar = 0;
}
}
itemData.EquipAvatar = avatarData.GetAvatarId();
avatarData.EquipId = itemData.UniqueId;
// save
DatabaseHelper.Instance!.UpdateInstance(Data);
DatabaseHelper.Instance!.UpdateInstance(Player.AvatarManager.AvatarData!);
Player.SendPacket(new PacketPlayerSyncScNotify(avatarData, itemData));
}
public void EquipRelic(int baseAvatarId, int relicUniqueId, int slot)
{
var itemData = Data.RelicItems.Find(x => x.UniqueId == relicUniqueId);

View File

@@ -1,5 +1,6 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Database;
using EggLink.DanhengServer.Database.Inventory;
using EggLink.DanhengServer.Database.Mission;
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Game.Mission.FinishAction;
@@ -136,6 +137,7 @@ namespace EggLink.DanhengServer.Game.Mission
Player.SendPacket(new PacketPlayerSyncScNotify(sync));
Player.SendPacket(new PacketStartFinishMainMissionScNotify(missionId));
HandleMissionReward(missionId);
DatabaseHelper.Instance?.UpdateInstance(Data);
}
@@ -231,6 +233,37 @@ namespace EggLink.DanhengServer.Game.Mission
handler?.OnHandle(actionInfo.FinishActionPara, Player);
}
public void HandleMissionReward(int mainMissionId)
{
GameData.MainMissionData.TryGetValue(mainMissionId, out var mainMission);
if (mainMission == null) return;
GameData.RewardDataData.TryGetValue(mainMission.RewardID, out var reward);
var ItemList = new Proto.ItemList();
reward?.GetItems().ForEach(i =>
{
var res = Player.InventoryManager!.AddItem(i.Item1, i.Item2, false);
if (res != null)
{
ItemList.ItemList_.Add(res.ToProto());
}
});
mainMission.SubRewardList.ForEach(i =>
{
GameData.RewardDataData.TryGetValue(i, out var reward);
reward?.GetItems().ForEach(j =>
{
var res = Player.InventoryManager!.AddItem(j.Item1, j.Item2, false);
if (res != null)
{
ItemList.ItemList_.Add(res.ToProto());
}
});
});
Player.SendPacket(new PacketMissionRewardScNotify(mainMissionId, 0, ItemList));
}
#endregion
#region Mission Status

View File

@@ -157,17 +157,21 @@ namespace EggLink.DanhengServer.Game.Player
}
public Task OnLogoutAsync()
public void OnLogoutAsync()
{
DatabaseHelper.Instance?.UpdateInstance(LineupManager!.LineupData);
DatabaseHelper.Instance?.UpdateInstance(InventoryManager!.Data);
DatabaseHelper.Instance?.UpdateInstance(MissionManager!.Data);
DatabaseHelper.Instance?.UpdateInstance(AvatarManager!.AvatarData!);
DatabaseHelper.Instance?.UpdateInstance(Data);
DatabaseHelper.Instance?.UpdateInstance(PlayerUnlockData!);
DatabaseHelper.Instance?.UpdateInstance(SceneData!);
DatabaseHelper.Instance?.UpdateInstance(TutorialData!);
return Task.CompletedTask;
try
{
DatabaseHelper.Instance?.UpdateInstance(LineupManager!.LineupData);
DatabaseHelper.Instance?.UpdateInstance(InventoryManager!.Data);
DatabaseHelper.Instance?.UpdateInstance(MissionManager!.Data);
DatabaseHelper.Instance?.UpdateInstance(AvatarManager!.AvatarData!);
DatabaseHelper.Instance?.UpdateInstance(Data);
DatabaseHelper.Instance?.UpdateInstance(PlayerUnlockData!);
DatabaseHelper.Instance?.UpdateInstance(SceneData!);
DatabaseHelper.Instance?.UpdateInstance(TutorialData!);
} catch
{
}
}
public void SendPacket(BasePacket packet)
@@ -189,6 +193,42 @@ namespace EggLink.DanhengServer.Game.Player
SendPacket(new PacketStaminaInfoScNotify(this));
}
public void OnAddExp()
{
GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out var config);
if (config == null) return;
var nextExp = config.PlayerExp;
while (Data.Exp >= nextExp)
{
Data.Exp -= nextExp;
Data.Level++;
GameData.PlayerLevelConfigData.TryGetValue(Data.Level + 1, out config);
if (config == null) break;
nextExp = config.PlayerExp;
}
OnLevelChange();
}
public void OnLevelChange()
{
if (!ConfigManager.Config.ServerOption.AutoUpgradeWorldLevel) return;
int worldLevel = 0;
foreach (var level in GameConstants.UpgradeWorldLevel)
{
if (level <= Data.Level)
{
worldLevel++;
}
}
if (Data.WorldLevel != worldLevel)
{
Data.WorldLevel = worldLevel;
}
}
#endregion
#region Scene Actions
@@ -272,7 +312,7 @@ namespace EggLink.DanhengServer.Game.Player
{
if (id == p.PropInfo.ID)
{
p.SetState(newState);
p.SetState(PropStateEnum.Open);
MissionManager!.OnPlayerInteractWithProp(p.PropInfo);
}
}
@@ -473,6 +513,16 @@ namespace EggLink.DanhengServer.Game.Player
};
}
public PlayerSimpleInfo ToSimpleProto()
{
return new()
{
Nickname = Data.Name,
Level = (uint)Data.Level,
Signature = Data.Signature,
};
}
#endregion
}
}

View File

@@ -20,12 +20,10 @@
<Folder Include="Server\Packet\Recv\ChessRogue\" />
<Folder Include="Server\Packet\Recv\Mail\" />
<Folder Include="Server\Packet\Recv\Friend\" />
<Folder Include="Server\Packet\Recv\Others\" />
<Folder Include="Server\Packet\Send\Achievement\" />
<Folder Include="Server\Packet\Send\ChessRogue\" />
<Folder Include="Server\Packet\Send\Friend\" />
<Folder Include="Server\Packet\Send\Mail\" />
<Folder Include="Server\Packet\Send\Others\" />
<Folder Include="Server\Packet\Send\Rogue\" />
</ItemGroup>

View File

@@ -43,12 +43,9 @@ public partial class Connection
State = SessionState.WAITING_FOR_TOKEN;
await ReceiveLoop();
}
public async void Stop()
public void Stop()
{
if (Player != null)
{
await Player.OnLogoutAsync();
}
Player?.OnLogoutAsync();
Listener.UnregisterConnection(this);
Conversation.Dispose();
try

View File

@@ -0,0 +1,23 @@
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Avatar
{
[Opcode(CmdIds.DressAvatarCsReq)]
public class HandlerDressAvatarCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = DressAvatarCsReq.Parser.ParseFrom(data);
var player = connection.Player!;
player.InventoryManager!.EquipAvatar((int)req.BaseAvatarId, (int)req.EquipmentUniqueId);
connection.SendPacket(CmdIds.DressAvatarScRsp);
}
}
}

View File

@@ -0,0 +1,18 @@
using EggLink.DanhengServer.Server.Packet.Send.Avatar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Avatar
{
[Opcode(CmdIds.GetAssistListCsReq)]
public class HandlerGetAssistListCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
connection.SendPacket(new PacketGetAssistListScRsp());
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Avatar
{
[Opcode(CmdIds.GetCurAssistCsReq)]
public class HandlerGetCurAssistCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
connection.SendPacket(CmdIds.GetCurAssistScRsp);
}
}
}

View File

@@ -0,0 +1,30 @@
using EggLink.DanhengServer.Database;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Avatar;
namespace EggLink.DanhengServer.Server.Packet.Recv.Avatar
{
[Opcode(CmdIds.SetAssistAvatarCsReq)]
public class HandlerSetAssistAvatarCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = SetAssistAvatarCsReq.Parser.ParseFrom(data);
var player = connection.Player!;
var avatars = player.AvatarManager!.AvatarData!.AssistAvatars;
if (avatars.Count >= 3)
{
connection.SendPacket(new PacketSetAssistAvatarScRsp());
return;
}
avatars.Clear();
foreach (var id in req.AvatarIdList)
{
if (id == 0) continue;
avatars.Add((int)id);
}
DatabaseHelper.Instance!.UpdateInstance(player.AvatarManager.AvatarData!);
connection.SendPacket(new PacketSetAssistAvatarScRsp(req.AvatarIdList));
}
}
}

View File

@@ -0,0 +1,45 @@
using EggLink.DanhengServer.Data;
using EggLink.DanhengServer.Database;
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Avatar;
using EggLink.DanhengServer.Server.Packet.Send.Player;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Avatar
{
[Opcode(CmdIds.UnlockSkilltreeCsReq)]
public class HandlerUnlockSkilltreeCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = UnlockSkilltreeCsReq.Parser.ParseFrom(data);
var player = connection.Player!;
GameData.AvatarSkillTreeConfigData.TryGetValue((int)(req.PointId * 10 + req.Level), out var config);
if (config == null)
{
connection.SendPacket(new PacketUnlockSkilltreeScRsp());
return;
}
var avatar = player.AvatarManager!.GetAvatar(config.AvatarID);
if (avatar == null)
{
connection.SendPacket(new PacketUnlockSkilltreeScRsp());
return;
}
foreach (var cost in req.ItemList)
{
connection.Player!.InventoryManager!.RemoveItem((int)cost.PileItem.ItemId, (int)cost.PileItem.ItemNum);
}
avatar.SkillTree.TryGetValue((int)req.PointId, out var level);
avatar.SkillTree[(int)req.PointId] = level + (int)req.Level;
DatabaseHelper.Instance!.UpdateInstance(player.AvatarManager.AvatarData!);
connection.SendPacket(new PacketPlayerSyncScNotify(avatar));
connection.SendPacket(new PacketUnlockSkilltreeScRsp((uint)avatar.AvatarId, req.PointId, req.Level));
}
}
}

View File

@@ -0,0 +1,14 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Lineup;
namespace EggLink.DanhengServer.Server.Packet.Recv.Lineup
{
[Opcode(CmdIds.GetLineupAvatarDataCsReq)]
public class HandlerGetLineupAvatarDataCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
connection.SendPacket(new PacketGetLineupAvatarDataScRsp(connection.Player!));
}
}
}

View File

@@ -0,0 +1,21 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Mission;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Mission
{
[Opcode(CmdIds.GetMainMissionCustomValueCsReq)]
public class HandlerGetMainMissionCustomValueCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
var req = GetMainMissionCustomValueCsReq.Parser.ParseFrom(data);
var player = connection.Player!;
connection.SendPacket(new PacketGetMainMissionCustomValueScRsp(req, player));
}
}
}

View File

@@ -0,0 +1,13 @@
using EggLink.DanhengServer.Server.Packet.Send.Others;
namespace EggLink.DanhengServer.Server.Packet.Recv.Others
{
[Opcode(CmdIds.GetSecretKeyInfoCsReq)]
public class HandlerGetSecretKeyInfoCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
connection.SendPacket(new PacketGetSecretKeyInfoScRsp());
}
}
}

View File

@@ -0,0 +1,18 @@
using EggLink.DanhengServer.Server.Packet.Send.Others;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Others
{
[Opcode(CmdIds.GetVideoVersionKeyCsReq)]
public class HandlerGetVideoVersionKeyCsReq : Handler
{
public override void OnHandle(Connection connection, byte[] header, byte[] data)
{
connection.SendPacket(new PacketGetVideoVersionKeyScRsp());
}
}
}

View File

@@ -18,17 +18,16 @@ namespace EggLink.DanhengServer.Server.Packet.Recv.Scene
{
foreach (var motion in req.EntityMotionList)
{
var avatar = connection?.Player?.SceneInstance!.AvatarInfo.ToList().Find(x => x.Value.AvatarInfo.EntityId == motion.EntityId);
if (avatar != null)
if (connection.Player!.SceneInstance!.AvatarInfo.ContainsKey((int)motion.EntityId))
{
connection!.Player!.Data.Pos = motion.Motion.Pos.ToPosition();
connection.Player!.Data.Pos = motion.Motion.Pos.ToPosition();
connection.Player.Data.Rot = motion.Motion.Rot.ToPosition();
connection.Player.OnMove();
}
}
}
connection!.SendPacket(CmdIds.SceneEntityMoveScRsp);
connection.SendPacket(CmdIds.SceneEntityMoveScRsp);
}
}
}

View File

@@ -1,10 +1,5 @@
using EggLink.DanhengServer.Proto;
using EggLink.DanhengServer.Server.Packet.Send.Tutorial;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Recv.Tutorial
{
@@ -15,9 +10,13 @@ namespace EggLink.DanhengServer.Server.Packet.Recv.Tutorial
{
var req = FinishTutorialCsReq.Parser.ParseFrom(data);
var player = connection.Player!;
if (player.TutorialData!.Tutorials.TryGetValue((int)req.TutorialId, out var _))
if (player.TutorialData!.Tutorials.TryGetValue((int)req.TutorialId, out var res))
{
player.TutorialData!.Tutorials[(int)req.TutorialId] = TutorialStatus.TutorialFinish;
if (res != TutorialStatus.TutorialFinish)
{
player.InventoryManager!.AddItem(1, 1);
player.TutorialData!.Tutorials[(int)req.TutorialId] = TutorialStatus.TutorialFinish;
}
}
connection.SendPacket(new PacketFinishTutorialScRsp(req.TutorialId));

View File

@@ -1,4 +1,5 @@
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -11,7 +12,12 @@ namespace EggLink.DanhengServer.Server.Packet.Send.Avatar
{
public PacketGetAssistHistoryScRsp(PlayerInstance player) : base(CmdIds.GetAssistHistoryScRsp)
{
var proto = new GetAssistHistoryScRsp
{
UseTimes = 0,
};
SetData(proto);
}
}
}

View File

@@ -0,0 +1,19 @@
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Send.Avatar
{
public class PacketGetAssistListScRsp : BasePacket
{
public PacketGetAssistListScRsp() : base(CmdIds.GetAssistListScRsp)
{
var proto = new GetAssistListScRsp();
SetData(proto);
}
}
}

View File

@@ -0,0 +1,26 @@
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Proto;
using Google.Protobuf.Collections;
namespace EggLink.DanhengServer.Server.Packet.Send.Avatar
{
public class PacketSetAssistAvatarScRsp : BasePacket
{
public PacketSetAssistAvatarScRsp(RepeatedField<uint> avatarId) : base(CmdIds.SetAssistAvatarScRsp)
{
var proto = new SetAssistAvatarScRsp();
proto.AvatarIdList.AddRange(avatarId);
SetData(proto);
}
public PacketSetAssistAvatarScRsp() : base(CmdIds.SetAssistAvatarScRsp)
{
var proto = new SetAssistAvatarScRsp
{
Retcode = 1,
};
SetData(proto);
}
}
}

View File

@@ -0,0 +1,34 @@
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Send.Avatar
{
public class PacketUnlockSkilltreeScRsp : BasePacket
{
public PacketUnlockSkilltreeScRsp() : base(CmdIds.UnlockSkilltreeScRsp)
{
var proto = new UnlockSkilltreeScRsp
{
Retcode = 1,
};
SetData(proto);
}
public PacketUnlockSkilltreeScRsp(uint avatarId, uint pointId, uint level) : base(CmdIds.UnlockSkilltreeScRsp)
{
var proto = new UnlockSkilltreeScRsp
{
BaseAvatarId = avatarId,
PointId = pointId,
Level = level,
};
SetData(proto);
}
}
}

View File

@@ -0,0 +1,26 @@
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.Server.Packet.Send.Lineup
{
public class PacketGetLineupAvatarDataScRsp : BasePacket
{
public PacketGetLineupAvatarDataScRsp(PlayerInstance player) : base(CmdIds.GetLineupAvatarDataScRsp)
{
var rsp = new GetLineupAvatarDataScRsp();
player.AvatarManager?.AvatarData?.Avatars?.ForEach(avatar =>
{
var data = new LineupAvatarData()
{
Id = (uint)avatar.AvatarId,
Hp = (uint)avatar.CurrentHp,
AvatarType = AvatarType.AvatarFormalType
};
rsp.AvatarDataList.Add(data);
});
SetData(rsp);
}
}
}

View File

@@ -0,0 +1,24 @@
using EggLink.DanhengServer.Enums;
using EggLink.DanhengServer.Game.Player;
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.Server.Packet.Send.Mission
{
public class PacketGetMainMissionCustomValueScRsp : BasePacket
{
public PacketGetMainMissionCustomValueScRsp(GetMainMissionCustomValueCsReq req, PlayerInstance player) : base(CmdIds.GetMainMissionCustomValueScRsp)
{
var proto = new GetMainMissionCustomValueScRsp();
foreach (var mission in req.MainMissionIdList)
{
proto.MissionDataList.Add(new MissionData
{
Id = mission,
Status = player.MissionManager!.GetMainMissionStatus((int)mission).ToProto()
});
}
SetData(proto);
}
}
}

View File

@@ -0,0 +1,19 @@
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.Server.Packet.Send.Mission
{
public class PacketMissionRewardScNotify : BasePacket
{
public PacketMissionRewardScNotify(int mainMissionId, int subMissionId, ItemList item) : base(CmdIds.MissionRewardScNotify)
{
var proto = new MissionRewardScNotify
{
MainMissionId = (uint)mainMissionId,
SubMissionId = (uint)subMissionId,
Reward = item
};
SetData(proto);
}
}
}

View File

@@ -0,0 +1,19 @@
using EggLink.DanhengServer.Proto;
namespace EggLink.DanhengServer.Server.Packet.Send.Others
{
public class PacketGetSecretKeyInfoScRsp : BasePacket
{
public PacketGetSecretKeyInfoScRsp() : base(CmdIds.GetSecretKeyInfoScRsp)
{
var proto = new GetSecretKeyInfoScRsp();
proto.MCPPMIAFDBE.Add(new DGAKGPPBJIG()
{
Type = SecretKeyType.SecretKeyVideo,
FFBANANOHPB = "10120425825329403",
});
SetData(proto);
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Send.Others
{
public class PacketGetVideoVersionKeyScRsp : BasePacket
{
public PacketGetVideoVersionKeyScRsp() : base(CmdIds.GetVideoVersionKeyScRsp)
{
// FIND A BETTER WAY
SetData(Convert.FromBase64String("QggwkhhgrOXSCUIIMIgYYKzl0glCCDD+F2Cs5dIJQggw9Bdg7+bSCUIIMOAXYKzl0glCCDDMF2DuzqEHQggwyBVgisSnBkIIML4VYIrEpwZCCDC0FWCKxKcGQggwqhVgisSnBkIIMJYVYO7OoQdCCDCNFWDuzqEHQggwjBVgus+hB0IIMPgUYO7OoQdCCDDuFGDuzqEHQggw5BRg7s6hB0IIMIoUYP2+6gVCCDCAFGD9vuoFQggw9hNg47/qBUIIMLoTYP/SgitCCDCwE2D/0oIrQggw/AJg4dTeB0IIMOgCYOHU3gdCCDDUAmDh1N4HQggwtgJgv/36IUIIMOITYKe3rQVCBzAIYPf4vSFCCDDiGGCs5dIJQggwzglgqvvjBkIIMNAUYKr74wZCBzAVYP/4vSFCBzBmYMm/6gVCBzAFYP/U1R1CCDDpAmDh1N4HQggwnBhg7+bSCUIIMIgJYLf9+iFCCDCwGGCs5dIJQggwnAlgqvvjBkIHMBBg9/i9IUIIMJwTYP/SgitCCDDGFGCXxKcGQggwrgJgkNTeB0IIMLwUYIrEpwZCBzABYPfL2xxCCDDKAmDh1N4HQggw3gJg4dTeB0IIMMcJYKr74wZCCDDyAmDh1N4HQggwrQJgkNTeB0IIMMgJYKr74wZCCDDmGWD25tIJQggwoBVg7s6hB0IHMARg/9TVHUIHMGVgyb/qBUIHMAdg/9TVHUIIMOUZYPbm0glCCDDCF2DuzqEHQgcwA2D/1NUdQgcwZGDJv+oFQggwkhNg99KCK0IIMMACYKe3rQVCBzACYPfL2xxCCDCGA2Dh1N4HQggwkANg4dTeB0IIMJoDYOHU3gdCCDDWF2DuzqEHQggwmwNg4dTeB0IIMM4YYKzl0glCCDC6CWCq++MGQggw6hdgrOXSCUIIMJgKYPLEpwZCCDCkA2Dh1N4HQggwphhgrOXSCUIIMJIJYKr74wZCCDC6GGCs5dIJQggwpglgqvvjBkIIMMQYYO/m0glCCDCwCWCq++MGQggw2BhgrOXSCUIIMMQJYKr74wZCCDDFCWCq++MGQggwghVg7s6hB0IIMP4RYPLEpwZCCDCUFGDjv+oFQggwxglgqvvjBkIIMOwYYPHm0glCCDDYCWCq++MGQggw9BJg/9KCK0IIMIgTYP/Sgis="));
}
}
}

View File

@@ -30,6 +30,7 @@ namespace EggLink.DanhengServer.Server.Packet.Send.Player
};
proto.DisplayAvatarVec.DisplayAvatarList.Add(displayAvatar);
});
player.AvatarManager?.AvatarData!.AssistAvatars.ForEach(x => proto.DIGIPEMAOFA.Add((uint)x));
SetData(proto);
}

View File

@@ -8,7 +8,7 @@ namespace EggLink.DanhengServer.Server.Packet.Send.Player
{
var proto = new PlayerKickOutScNotify()
{
KickType = KickType.KickByGm,
KickType = KickType.KickSqueezed,
};
SetData(proto);
}

View File

@@ -0,0 +1,33 @@
using EggLink.DanhengServer.Database.Inventory;
using EggLink.DanhengServer.Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EggLink.DanhengServer.Server.Packet.Send.Player
{
public class PacketScenePlaneEventScNotify : BasePacket
{
public PacketScenePlaneEventScNotify(ItemData item) : this([item])
{
}
public PacketScenePlaneEventScNotify(List<ItemData> itemDatas) : base(CmdIds.ScenePlaneEventScNotify)
{
var itemList = new ItemList();
foreach (var item in itemDatas)
{
itemList.ItemList_.Add(item.ToProto());
}
var data = new ScenePlaneEventScNotify()
{
GetItemList = itemList,
};
SetData(data);
}
}
}