Feature: I18n for common output & Bug Fix

- Fix 8002 in Raid will cause problems
- Fix Group loading
This commit is contained in:
Somebody
2024-07-11 17:30:53 +08:00
parent 816fb39441
commit 3993435070
16 changed files with 215 additions and 75 deletions

View File

@@ -120,7 +120,7 @@ namespace EggLink.DanhengServer.Command.Cmd
var itemData = new ItemData()
{
ItemId = int.Parse(arg.BasicArgs[0]),
Level = Math.Max(Math.Min(level, 15), 1),
Level = Math.Max(Math.Min(level, 9999), 1),
UniqueId = ++player.InventoryManager!.Data.NextUniqueId,
MainAffix = mainAffixId,
Count = 1,

View File

@@ -38,7 +38,8 @@ namespace EggLink.DanhengServer.Command
}
}
}
Logger.Info($"Register {Commands.Count} commands.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.RegisterItem", Commands.Count.ToString(), I18nManager.Translate("Word.Command")));
}
public void Start()

View File

@@ -39,6 +39,10 @@ namespace EggLink.DanhengServer.Configuration
public string GameServerName { get; set; } = "DanhengServer";
public string GameServerDescription { get; set; } = "A re-implementation of StarRail server";
public int KcpInterval { get; set; } = 40;
public string GetDisplayAddress()
{
return PublicAddress + ":" + PublicPort;
}
}
public class PathConfig

View File

@@ -10,6 +10,7 @@ using Newtonsoft.Json.Linq;
using EggLink.DanhengServer.Data.Custom;
using EggLink.DanhengServer.Data.Excel;
using EggLink.DanhengServer.Enums.Rogue;
using EggLink.DanhengServer.Internationalization;
namespace EggLink.DanhengServer.Data
{
@@ -54,7 +55,7 @@ namespace EggLink.DanhengServer.Data
var file = new FileInfo(path);
if (!file.Exists)
{
Logger.Warn($"File {path} not found");
Logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", fileName, I18nManager.Translate("Word.NotFound")));
continue;
}
var json = file.OpenText().ReadToEnd();
@@ -109,10 +110,10 @@ namespace EggLink.DanhengServer.Data
}
catch (Exception ex)
{
Logger.Error($"Error in reading {fileName}", ex);
Logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", fileName, I18nManager.Translate("Word.Error")), ex);
}
}
Logger.Info($"Loaded {count} {cls.Name}s.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", count.ToString(), cls.Name));
}
}
foreach (var cls in resList)
@@ -123,13 +124,13 @@ namespace EggLink.DanhengServer.Data
public static void LoadFloorInfo()
{
Logger.Info("Loading floor files...");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.FloorInfo")));
DirectoryInfo directory = new(ConfigManager.Config.Path.ResourcePath + "/Config/LevelOutput/RuntimeFloor/");
bool missingGroupInfos = false;
if (!directory.Exists)
{
Logger.Warn($"Floor infos are missing, please check your resources folder: {ConfigManager.Config.Path.ResourcePath}/Config/LevelOutput/RuntimeFloor. Teleports and natural world spawns may not work!");
Logger.Warn(I18nManager.Translate("Server.ServerInfo.ConfigMissing", I18nManager.Translate("Word.FloorInfo"), $"{ConfigManager.Config.Path.ResourcePath}/Config/LevelOutput/RuntimeFloor", I18nManager.Translate("Word.FloorMissingResult")));
return;
}
// Load floor infos
@@ -145,7 +146,7 @@ namespace EggLink.DanhengServer.Data
GameData.FloorInfoData.Add(name, info!);
} catch (Exception ex)
{
Logger.Error("Error in reading" + file.Name, ex);
Logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", file.Name, I18nManager.Translate("Word.Error")), ex);
}
}
@@ -165,13 +166,12 @@ namespace EggLink.DanhengServer.Data
if (group != null)
{
group.Id = groupInfo.ID;
if (!info.Groups.ContainsKey(groupInfo.ID))
info.Groups.Add(groupInfo.ID, group);
info.Groups.TryAdd(groupInfo.ID, group);
group.Load();
}
} catch (Exception ex)
{
Logger.Error("Error in reading " + file.Name, ex);
Logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", file.Name, I18nManager.Translate("Word.Error")), ex);
}
if (info.Groups.Count == 0)
{
@@ -181,18 +181,18 @@ namespace EggLink.DanhengServer.Data
info.OnLoad();
}
if (missingGroupInfos)
Logger.Warn($"Group infos are missing, please check your resources folder: {ConfigManager.Config.Path.ResourcePath}/Config/LevelOutput/SharedRuntimeGroup. Teleports, monster battles, and natural world spawns may not work!");
Logger.Warn(I18nManager.Translate("Server.ServerInfo.ConfigMissing", I18nManager.Translate("Word.FloorGroupInfo"), $"{ConfigManager.Config.Path.ResourcePath}/Config/LevelOutput/SharedRuntimeGroup", I18nManager.Translate("Word.FloorGroupMissingResult")));
Logger.Info("Loaded " + GameData.FloorInfoData.Count + " floor infos.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", GameData.FloorInfoData.Count.ToString(), I18nManager.Translate("Word.FloorInfo")));
}
public static void LoadMissionInfo()
{
Logger.Info("Loading mission files...");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.MissionInfo")));
DirectoryInfo directory = new(ConfigManager.Config.Path.ResourcePath + "/Config/Level/Mission");
if (!directory.Exists)
{
Logger.Warn($"Mission infos are missing, please check your resources folder: {ConfigManager.Config.Path.ResourcePath}/Config/Level/Mission. Missions may not work!");
Logger.Warn(I18nManager.Translate("Server.ServerInfo.ConfigMissing", I18nManager.Translate("Word.MissionInfo"), $"{ConfigManager.Config.Path.ResourcePath}/Config/Level/Mission", I18nManager.Translate("Word.Mission")));
return;
}
bool missingMissionInfos = false;
@@ -250,7 +250,7 @@ namespace EggLink.DanhengServer.Data
}
} catch (Exception ex)
{
Logger.Error("Error in reading " + missionJsonPath, ex);
Logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", missionJsonPath, I18nManager.Translate("Word.Error")), ex);
}
}
}
@@ -261,18 +261,18 @@ namespace EggLink.DanhengServer.Data
}
}
if (missingMissionInfos)
Logger.Warn($"Mission infos are missing, please check your resources folder: {ConfigManager.Config.Path.ResourcePath}/Config/Level/Mission. Missions may not work!");
Logger.Info("Loaded " + count + " mission infos.");
Logger.Warn(I18nManager.Translate("Server.ServerInfo.ConfigMissing", I18nManager.Translate("Word.MissionInfo"), $"{ConfigManager.Config.Path.ResourcePath}/Config/Level/Mission", I18nManager.Translate("Word.Mission")));
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", count.ToString(), I18nManager.Translate("Word.MissionInfo")));
}
public static T? LoadCustomFile<T>(string filetype, string filename)
{
Logger.Info($"Loading {filetype} files...");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", filetype));
FileInfo file = new(ConfigManager.Config.Path.ConfigPath + $"/{filename}.json");
T? customFile = default;
if (!file.Exists)
{
Logger.Warn($"Banner infos are missing, please check your resources folder: {ConfigManager.Config.Path.ConfigPath}/{filename}.json. {filetype} may not work!");
Logger.Warn(I18nManager.Translate("Server.ServerInfo.ConfigMissing", filetype, $"{ConfigManager.Config.Path.ConfigPath}/{filename}.json", filetype));
return customFile;
}
try
@@ -289,23 +289,23 @@ namespace EggLink.DanhengServer.Data
if (customFile is Dictionary<int, int> d)
{
Logger.Info("Loaded " + d.Count + $" {filetype}s.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", d.Count.ToString(), filetype));
} else if (customFile is Dictionary<int, List<int>> di)
{
Logger.Info("Loaded " + di.Count + $" {filetype}s.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", di.Count.ToString(), filetype));
} else if (customFile is BannersConfig c)
{
Logger.Info("Loaded " + c.Banners.Count + $" {filetype}s.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", c.Banners.Count.ToString(), filetype));
} else if (customFile is RogueMiracleEffectConfig r)
{
Logger.Info("Loaded " + r.Miracles.Count + $" {filetype}s.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", r.Miracles.Count.ToString(), filetype));
} else if (customFile is ActivityConfig a)
{
Logger.Info("Loaded " + a.ScheduleData.Count + $" {filetype}s.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", a.ScheduleData.Count.ToString(), filetype));
}
else
{
Logger.Info("Loaded " + filetype + " file.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItem", filetype));
}
return customFile;
@@ -313,6 +313,7 @@ namespace EggLink.DanhengServer.Data
public static void LoadMazeSkill()
{
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.MazeSkillInfo")));
var count = 0;
foreach (var adventure in GameData.AdventurePlayerData.Values)
{
@@ -332,18 +333,20 @@ namespace EggLink.DanhengServer.Data
}
catch (Exception ex)
{
Logger.Error("Error in reading " + file.Name, ex);
Logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", adventurePath, I18nManager.Translate("Word.Error")), ex);
}
}
if (count < GameData.AdventurePlayerData.Count)
{
Logger.Warn("Maze skill infos are missing, please check your resources folder: " + ConfigManager.Config.Path.ResourcePath + "/Config/ConfigAdventureAbility/LocalPlayer. Maze skills may not work!");
Logger.Warn(I18nManager.Translate("Server.ServerInfo.ConfigMissing", I18nManager.Translate("Word.MazeSkillInfo"), $"{ConfigManager.Config.Path.ResourcePath}/Config/Level/AdventureAbility", I18nManager.Translate("Word.MazeSkill")));
}
Logger.Info("Loaded " + count + " maze skill infos.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", count.ToString(), I18nManager.Translate("Word.MazeSkillInfo")));
}
public static void LoadDialogueInfo()
{
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.DialogueInfo")));
var count = 0;
foreach (var dialogue in GameData.RogueNPCDialogueData)
{
@@ -369,21 +372,22 @@ namespace EggLink.DanhengServer.Data
}
} catch (Exception ex)
{
Logger.Error("Error in reading " + file.Name, ex);
Logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", file.Name, I18nManager.Translate("Word.Error")), ex);
}
}
if (count < GameData.RogueNPCDialogueData.Count)
{
Logger.Warn("Dialogue infos are missing, please check your resources folder: " + ConfigManager.Config.Path.ResourcePath + "/Config/Level/RogueDialogue/RogueDialogueEvent. Dialogues may not work!");
Logger.Warn(I18nManager.Translate("Server.ServerInfo.ConfigMissing", I18nManager.Translate("Word.DialogueInfo"), $"{ConfigManager.Config.Path.ResourcePath}/Config/Level/Rogue/Dialogue", I18nManager.Translate("Word.Dialogue")));
}
Logger.Info("Loaded " + count + " dialogue infos.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", count.ToString(), I18nManager.Translate("Word.DialogueInfo")));
}
public static void LoadPerformanceInfo()
{
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.PerformanceInfo")));
var count = 0;
foreach (var performance in GameData.PerformanceEData.Values)
{
@@ -410,7 +414,7 @@ namespace EggLink.DanhengServer.Data
}
catch (Exception ex)
{
Logger.Error("Error in reading " + file.Name, ex);
Logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", file.Name, I18nManager.Translate("Word.Error")), ex);
}
}
@@ -421,11 +425,12 @@ namespace EggLink.DanhengServer.Data
//Logger.Warn("Performance infos are missing, please check your resources folder: " + ConfigManager.Config.Path.ResourcePath + "/Config/Level/Mission/*/Act. Performances may not work!");
}
Logger.Info("Loaded " + count + " performance infos.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", count.ToString(), I18nManager.Translate("Word.PerformanceInfo")));
}
public static void LoadRogueChestMapInfo()
{
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.RogueChestMapInfo")));
var count = 0;
var boardList = new List<RogueDLCChessBoardExcel>();
foreach (var nousMap in GameData.RogueNousChessBoardData.Values)
@@ -464,27 +469,29 @@ namespace EggLink.DanhengServer.Data
}
catch (Exception ex)
{
Logger.Error("Error in reading " + file.Name, ex);
Logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", file.Name, I18nManager.Translate("Word.Error")), ex);
}
}
if (count < boardList.Count)
{
Logger.Warn("Chess board infos are missing, please check your resources folder: " + ConfigManager.Config.Path.ResourcePath + "/Config/Gameplays/RogueDLC. Chess rogue may not work!");
Logger.Warn(I18nManager.Translate("Server.ServerInfo.ConfigMissing", I18nManager.Translate("Word.RogueChestMapInfo"), $"{ConfigManager.Config.Path.ResourcePath}/Config/Gameplays/RogueDLC", I18nManager.Translate("Word.RogueChestMap")));
}
Logger.Info("Loaded " + count + " board infos.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", count.ToString(), I18nManager.Translate("Word.RogueChestMapInfo")));
}
public static void LoadChessRogueRoomData()
{
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.ChessRogueRoomInfo")));
var count = 0;
FileInfo file = new(ConfigManager.Config.Path.ConfigPath + $"/ChessRogueRoomGen.json");
List<ChessRogueRoomConfig>? customFile = default;
List<ChessRogueRoomConfig>? customFile;
if (!file.Exists)
{
Logger.Warn($"Banner infos are missing, please check your resources folder: {ConfigManager.Config.Path.ConfigPath}/ChessRogueRoomGen.json. Chess Rogue may not work!");
Logger.Warn(I18nManager.Translate("Server.ServerInfo.ConfigMissing", I18nManager.Translate("Word.ChessRogueRoomInfo"), $"{ConfigManager.Config.Path.ConfigPath}/ChessRogueRoomGen.json", I18nManager.Translate("Word.ChessRogueRoom")));
return;
}
try
@@ -538,7 +545,7 @@ namespace EggLink.DanhengServer.Data
Logger.Error("Error in reading " + file.Name, ex);
}
Logger.Info("Loaded " + count + " room infos.");
Logger.Info(I18nManager.Translate("Server.ServerInfo.LoadedItems", count.ToString(), I18nManager.Translate("Word.ChessRogueRoomInfo")));
}
public static void AddRoomToGameData(RogueDLCBlockTypeEnum type, ChessRogueRoomConfig room)

View File

@@ -1,6 +1,7 @@
using EggLink.DanhengServer.Database.Inventory;
using EggLink.DanhengServer.Database.Mission;
using EggLink.DanhengServer.Database.Scene;
using EggLink.DanhengServer.Internationalization;
using EggLink.DanhengServer.Util;
using SqlSugar;
@@ -23,7 +24,7 @@ namespace EggLink.DanhengServer.Database
public void Initialize()
{
logger.Info("Initializing database...");
logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.Database")));
var config = ConfigManager.Config;
DbType type;
string connectionString;
@@ -293,7 +294,7 @@ namespace EggLink.DanhengServer.Database
}
}
logger.Info($"Save database. Using {(DateTime.Now - prev).TotalSeconds.ToString()[..4]} seconds.");
logger.Info(I18nManager.Translate("Server.ServerInfo.SaveDatabase", (DateTime.Now - prev).TotalSeconds.ToString()[..4]));
ToSaveUidList.Clear();
}

View File

@@ -9,7 +9,8 @@ namespace EggLink.DanhengServer.Enums.Rogue
public enum BossDecayEffectTypeEnum
{
None = 0,
AddMazeBuffList = 1,
RemoveMazeBuffList = 2,
AddMazeBuff = 1,
AddMazeBuffList = 2,
RemoveMazeBuffList = 3,
}
}

View File

@@ -28,7 +28,7 @@ namespace EggLink.DanhengServer.Internationalization
var language = Activator.CreateInstance(languageType) ?? throw new Exception("Language not found");
Language = language;
Logger.Info("Language loaded");
Logger.Info(Translate("Server.ServerInfo.LoadedItem", Translate("Word.Language")));
}
public static string Translate(string key, params string[] args)

View File

@@ -33,6 +33,7 @@ namespace EggLink.DanhengServer.Internationalization.Message
public class ServerTextCHS
{
public WebTextCHS Web { get; } = new();
public ServerInfoTextCHS ServerInfo { get; } = new();
}
/// <summary>
@@ -51,6 +52,38 @@ namespace EggLink.DanhengServer.Internationalization.Message
public string Buff { get; } = "祝福";
public string Miracle { get; } = "奇物";
public string Unlock { get; } = "奢侈品";
// server info
public string Config { get; } = "配置文件";
public string Language { get; } = "语言";
public string Log { get; } = "日志";
public string GameData { get; } = "游戏数据";
public string Database { get; } = "数据库";
public string Command { get; } = "命令";
public string WebServer { get; } = "Web服务器";
public string Plugin { get; } = "插件";
public string Handler { get; } = "包处理器";
public string Dispatch { get; } = "全局分发";
public string Game { get; } = "游戏";
public string Handbook { get; } = "手册";
public string NotFound { get; } = "未找到";
public string Error { get; } = "错误";
public string FloorInfo { get; } = "区域文件";
public string FloorGroupInfo { get; } = "区域组文件";
public string FloorMissingResult { get; } = "传送与世界生成";
public string FloorGroupMissingResult { get; } = "传送、怪物战斗与世界生成";
public string Mission { get; } = "任务";
public string MissionInfo { get; } = "任务文件";
public string MazeSkill { get; } = "角色秘技";
public string MazeSkillInfo { get; } = "角色秘技文件";
public string Dialogue { get; } = "模拟宇宙事件";
public string DialogueInfo { get; } = "模拟宇宙事件文件";
public string Performance { get; } = "剧情操作";
public string PerformanceInfo { get; } = "剧情操作文件";
public string RogueChestMap { get; } = "模拟宇宙地图";
public string RogueChestMapInfo { get; } = "模拟宇宙地图文件";
public string ChessRogueRoom { get; } = "模拟宇宙DLC";
public string ChessRogueRoomInfo { get; } = "模拟宇宙DLC文件";
}
#endregion
@@ -93,6 +126,31 @@ namespace EggLink.DanhengServer.Internationalization.Message
{
}
/// <summary>
/// path: Server.ServerInfo
/// </summary>
public class ServerInfoTextCHS
{
public string Shutdown { get; } = "关闭中…";
public string CancelKeyPressed { get; } = "已按下取消键 (Ctrl + C),服务器即将关闭…";
public string StartingServer { get; } = "正在启动 DanhengServer…";
public string LoadingItem { get; } = "正在加载 {0}…";
public string RegisterItem { get; } = "注册了 {0} 个 {1}。";
public string FailedToLoadItem { get; } = "加载 {0} 失败。";
public string FailedToInitializeItem { get; } = "初始化 {0} 失败。";
public string FailedToReadItem { get; } = "读取 {0} 失败,文件{1}";
public string GeneratedItem { get; } = "已生成 {0}。";
public string LoadedItem { get; } = "已加载 {0}。";
public string LoadedItems { get; } = "已加载 {0} 个 {1}。";
public string ServerRunning { get; } = "{0} 服务器正在监听 {1}";
public string ServerStarted { get; } = "启动完成!用时 {0}s击败了99%的用户,输入 help 来获取命令帮助"; // 玩梗,考虑英语版本将其本土化
public string MissionEnabled { get; } = "任务系统已启用此功能仍在开发中且可能不会按预期工作如果遇见任何bug请汇报给开发者。";
public string ConfigMissing { get; } = "{0} 缺失,请检查你的资源文件夹:{1}{2} 可能不能使用。";
public string UnloadedItems { get; } = "卸载了所有 {0}。";
public string SaveDatabase { get; } = "已保存数据库,用时 {0}s";
}
#endregion
#endregion

View File

@@ -579,7 +579,7 @@ namespace EggLink.DanhengServer.Game.Player
{
SendPacket(new PacketEnterSceneByServerScNotify(instance, storyLineAction));
}
else if (!notSendMove)
else if (sendPacket && !notSendMove) // send move packet
{
SendPacket(new PacketSceneEntityMoveScNotify(this));
}

View File

@@ -74,7 +74,41 @@ namespace EggLink.DanhengServer.GameServer.Game.Raid
else if (excel.TeamType == Enums.Scene.RaidTeamTypeEnum.TrialOnly)
{
// set lineup
Player.LineupManager!.SetExtraLineup(ExtraLineupType.LineupHeliobus, excel.TrialAvatarList);
List<int> list = [..excel.TrialAvatarList];
if (list.Count > 0)
{
if (Player.Data.CurrentGender == Gender.Man)
{
foreach (var avatar in excel.TrialAvatarList)
{
if (avatar > 10000) // else is Base Avatar
{
if (avatar.ToString().EndsWith("8002") ||
avatar.ToString().EndsWith("8004") ||
avatar.ToString().EndsWith("8006"))
{
list.Remove(avatar);
}
}
}
}
else
{
foreach (var avatar in excel.TrialAvatarList)
{
if (avatar > 10000) // else is Base Avatar
{
if (avatar.ToString().EndsWith("8001") ||
avatar.ToString().EndsWith("8003") ||
avatar.ToString().EndsWith("8005"))
{
list.Remove(avatar);
}
}
}
}
}
Player.LineupManager!.SetExtraLineup(ExtraLineupType.LineupHeliobus, list);
Player.SendPacket(new PacketSyncLineupNotify(Player.LineupManager!.GetCurLineup()!));
}
else

View File

@@ -33,6 +33,8 @@ namespace EggLink.DanhengServer.Game.Scene
public void SyncEntity()
{
if (Scene.Excel.PlaneType == PlaneTypeEnum.Raid) return;
bool refreshed = false;
var oldGroupId = new List<int>();
foreach (var entity in Scene.Entities.Values)
@@ -69,6 +71,7 @@ namespace EggLink.DanhengServer.Game.Scene
refreshed = true;
}
}
Scene.Groups.Remove(group.Id);
}
else if (group.OwnerMainMissionID != 0 && Scene.Player.MissionManager!.GetMainMissionStatus(group.OwnerMainMissionID) != Enums.MissionPhaseEnum.Accept)
{
@@ -81,6 +84,7 @@ namespace EggLink.DanhengServer.Game.Scene
refreshed = true;
}
}
Scene.Groups.Remove(group.Id);
}
} else // check if it should be loaded
{
@@ -89,32 +93,46 @@ namespace EggLink.DanhengServer.Game.Scene
addList.AddRange(groupList ?? []);
}
}
if (refreshed)
if (refreshed && (addList.Count > 0 || removeList.Count > 0))
{
Scene.Player.SendPacket(new PacketSceneGroupRefreshScNotify(null, removeList));
Scene.Player.SendPacket(new PacketSceneGroupRefreshScNotify(addList, null));
Scene.Player.SendPacket(new PacketSceneGroupRefreshScNotify(addList, removeList));
}
}
public virtual List<IGameEntity>? LoadGroup(GroupInfo info, bool forceLoad = false)
{
var missionData = Scene.Player.MissionManager!.Data;
if (!(info.OwnerMainMissionID == 0 || Scene.Player.MissionManager!.GetMainMissionStatus(info.OwnerMainMissionID) == Enums.MissionPhaseEnum.Accept))
if (info.LoadSide == GroupLoadSideEnum.Client)
{
return null;
}
if ((!info.LoadCondition.IsTrue(missionData) || info.UnloadCondition.IsTrue(missionData, false) || info.ForceUnloadCondition.IsTrue(missionData, false)) && !forceLoad)
if (info.GroupName.Contains("TrainVisitor"))
{
return null;
}
if (Scene.Excel.PlaneType != PlaneTypeEnum.Raid)
{
if (!(info.OwnerMainMissionID == 0 || Scene.Player.MissionManager!.GetMainMissionStatus(info.OwnerMainMissionID) == Enums.MissionPhaseEnum.Accept))
{
return null;
}
if ((!info.LoadCondition.IsTrue(missionData) || info.UnloadCondition.IsTrue(missionData, false) || info.ForceUnloadCondition.IsTrue(missionData, false)) && !forceLoad)
{
return null;
}
}
if (Scene.Entities.Values.ToList().FindIndex(x => x.GroupID == info.Id) != -1) // check if group is already loaded
{
return null;
}
// load
Scene.Groups.Add(info.Id);
var entityList = new List<IGameEntity>();
foreach (var npc in info.NPCList)
{
@@ -184,6 +202,7 @@ namespace EggLink.DanhengServer.Game.Scene
refreshed = true;
}
}
Scene.Groups.Remove(group.Id);
if (refreshed)
{

View File

@@ -35,6 +35,7 @@ namespace EggLink.DanhengServer.Game.Scene
public Dictionary<int, AvatarSceneInfo> AvatarInfo = [];
public int LeaderEntityId;
public Dictionary<int, IGameEntity> Entities = [];
public List<int> Groups = [];
public List<EntityProp> HealingSprings = [];
public SceneEntityLoader? EntityLoader;
@@ -270,6 +271,17 @@ namespace EggLink.DanhengServer.Game.Scene
groups[groups.FindIndex(x => x.GroupId == entity.Value.GroupID)].EntityList.Add(entity.Value.ToProto());
}
foreach (var groupId in Groups) // Add for empty group
{
if (groups.FindIndex(x => x.GroupId == groupId) == -1)
{
groups.Add(new SceneEntityGroupInfo()
{
GroupId = (uint)groupId
});
}
}
foreach (var group in groups)
{
sceneInfo.EntityGroupList.Add(group);

View File

@@ -1,4 +1,5 @@
using EggLink.DanhengServer.Plugin.Constructor;
using EggLink.DanhengServer.Internationalization;
using EggLink.DanhengServer.Plugin.Constructor;
using EggLink.DanhengServer.Util;
using McMaster.NETCore.Plugins;
using Newtonsoft.Json;
@@ -137,7 +138,7 @@ namespace EggLink.DanhengServer.Plugin
UnloadPlugin(plugin);
}
logger.Info("Unloaded all plugins");
logger.Info(I18nManager.Translate("Server.ServerInfo.UnloadedItems", I18nManager.Translate("Word.Plugin")));
}
#endregion

View File

@@ -1,9 +1,11 @@
using System.Net;
using System.Net.Sockets;
using EggLink.DanhengServer.Common.Enums;
using EggLink.DanhengServer.Internationalization;
using EggLink.DanhengServer.KcpSharp;
using EggLink.DanhengServer.Util;
using KcpSharp;
using Microsoft.Extensions.Logging;
namespace EggLink.DanhengServer.Server
{
@@ -38,7 +40,7 @@ namespace EggLink.DanhengServer.Server
if (UDPListener == null) return;
KCPTransport = KcpSocketTransport.CreateMultiplexConnection(UDPClient, 1400);
KCPTransport.Start();
Logger.Info($"Game Server started. Listening on port: {PORT}");
Logger.Info(I18nManager.Translate("Server.ServerInfo.ServerRunning", I18nManager.Translate("Word.Game"), ConfigManager.Config.GameServer.GetDisplayAddress()));
}
private static void RegisterConnection(Connection con)

View File

@@ -21,14 +21,14 @@ namespace EggLink.DanhengServer.Handbook
var textMapPath = config.Path.ResourcePath + "/TextMap/TextMap" + config.ServerOption.Language + ".json";
if (!File.Exists(textMapPath))
{
Logger.GetByClassName().Error("TextMap file not found: " + textMapPath);
Logger.GetByClassName().Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem", textMapPath, I18nManager.Translate("Word.NotFound")));
return;
}
var textMap = JsonConvert.DeserializeObject<Dictionary<long, string>>(File.ReadAllText(textMapPath));
if (textMap == null)
{
Logger.GetByClassName().Error("Failed to load TextMap file: " + textMapPath);
Logger.GetByClassName().Error(I18nManager.Translate("Server.ServerInfo.FailedToReadItem",textMapPath, I18nManager.Translate("Word.Error")));
return;
}
@@ -76,7 +76,7 @@ namespace EggLink.DanhengServer.Handbook
builder.AppendLine();
WriteToFile(builder.ToString());
Logger.GetByClassName().Info("Handbook generated successfully.");
Logger.GetByClassName().Info(I18nManager.Translate("Server.ServerInfo.GeneratedItem", I18nManager.Translate("Word.Handbook")));
}
public static void GenerateCmd(StringBuilder builder)

View File

@@ -27,11 +27,11 @@ namespace EggLink.DanhengServer.Program
public static void Main(string[] args)
{
AppDomain.CurrentDomain.ProcessExit += (sender, eventArgs) => {
Console.WriteLine("Shutting down...");
logger.Info(I18nManager.Translate("Server.ServerInfo.Shutdown"));
PerformCleanup();
};
Console.CancelKeyPress += (sender, eventArgs) => {
Console.WriteLine("Cancel key pressed. Shutting down...");
logger.Info(I18nManager.Translate("Server.ServerInfo.CancelKeyPressed"));
eventArgs.Cancel = true;
Environment.Exit(0);
};
@@ -51,40 +51,40 @@ namespace EggLink.DanhengServer.Program
Logger.SetLogFile(file);
// Starting the server
logger.Info("Starting DanhengServer...");
logger.Info(I18nManager.Translate("Server.ServerInfo.StartingServer"));
// Load the config
logger.Info("Loading config...");
logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.Config")));
try
{
ConfigManager.LoadConfig();
} catch (Exception e)
{
logger.Error("Failed to load config", e);
logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToLoadItem", I18nManager.Translate("Word.Config")), e);
Console.ReadLine();
return;
}
// Load the language
logger.Info("Loading language...");
logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.Language")));
try
{
I18nManager.LoadLanguage();
} catch (Exception e)
{
logger.Error("Failed to load language", e);
logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToLoadItem", I18nManager.Translate("Word.Language")), e);
Console.ReadLine();
return;
}
// Load the game data
logger.Info("Loading game data...");
logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.GameData")));
try
{
ResourceManager.LoadGameData();
} catch (Exception e)
{
logger.Error("Failed to load game data", e);
logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToLoadItem", I18nManager.Translate("Word.GameData")), e);
Console.ReadLine();
return;
}
@@ -105,7 +105,7 @@ namespace EggLink.DanhengServer.Program
}
} catch (Exception e)
{
logger.Error("Failed to initialize database", e);
logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToLoadItem", I18nManager.Translate("Word.Database")), e);
Console.ReadLine();
return;
}
@@ -116,20 +116,20 @@ namespace EggLink.DanhengServer.Program
CommandManager.RegisterCommand();
} catch (Exception e)
{
logger.Error("Failed to initialize command manager", e);
logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToInitializeItem", I18nManager.Translate("Word.Command")), e);
Console.ReadLine();
return;
}
// Load the plugins
logger.Info("Loading plugins...");
logger.Info(I18nManager.Translate("Server.ServerInfo.LoadingItem", I18nManager.Translate("Word.Plugin")));
try
{
PluginManager.LoadPlugins();
}
catch (Exception e)
{
logger.Error("Failed to load plugins", e);
logger.Error(I18nManager.Translate("Server.ServerInfo.FailedToLoadItem", I18nManager.Translate("Word.Plugin")), e);
Console.ReadLine();
return;
}
@@ -212,18 +212,18 @@ namespace EggLink.DanhengServer.Program
HandlerManager.Init();
WebProgram.Main([], GetConfig().HttpServer.PublicPort, GetConfig().HttpServer.GetDisplayAddress());
logger.Info($"Dispatch Server is running on {GetConfig().HttpServer.GetDisplayAddress()}");
logger.Info(I18nManager.Translate("Server.ServerInfo.ServerRunning", I18nManager.Translate("Word.Dispatch"), GetConfig().HttpServer.GetDisplayAddress()));
Listener.StartListener();
var elapsed = DateTime.Now - time;
logger.Info($"Done in {elapsed.TotalSeconds.ToString()[..4]}s! Type '/help' to get help of commands.");
logger.Info(I18nManager.Translate("Server.ServerInfo.ServerStarted", elapsed.TotalSeconds.ToString()[..4]));
GenerateLogMap();
if (GetConfig().ServerOption.EnableMission)
{
logger.Warn("Mission system is enabled. This is a feature that is still in development and may not work as expected. If you encounter any issues, please report them to the developers.");
logger.Warn(I18nManager.Translate("Server.ServerInfo.MissionEnabled"));
}
CommandManager.Start();
}