Compare commits

..

No commits in common. "f0f954f10c83ba364305f879b6eae574a09cb718" and "d2181093545d7954b24918a0af233f7dcdef9f77" have entirely different histories.

19 changed files with 84 additions and 395 deletions

View File

@ -52,10 +52,6 @@ You need to fill in the Export Presets > Resources > Filter to export non-resour
data/* data/*
``` ```
#### Custom feature
- **disableVersionIsolation** Disable version isolation.
## Configuring Openobserve ## Configuring Openobserve
> This is optional, and the game will work even if you do not configure Openobserve. > This is optional, and the game will work even if you do not configure Openobserve.

View File

@ -50,10 +50,6 @@ git clone https://github.com/Cold-Mint/Traveller.git
data/* data/*
``` ```
#### 風習特徴
- **disableVersionIsolation** 版孤立を無効化する。
## はいちOpenobserve ## はいちOpenobserve
> これはオプションなので、Openobserveを設定しなくてもゲームは正常に動作します。 > これはオプションなので、Openobserveを設定しなくてもゲームは正常に動作します。

View File

@ -52,10 +52,6 @@ git clone https://github.com/Cold-Mint/Traveller.git
data/* data/*
``` ```
#### 自定义特性
- **disableVersionIsolation** 禁用版本隔离。
## 配置Openobserve ## 配置Openobserve
> 这是可选的操作即使您不配置Openobserve游戏也能正常运行。 > 这是可选的操作即使您不配置Openobserve游戏也能正常运行。

View File

@ -33,7 +33,7 @@ log_start_item_register_from_file,开始从文件注册物品信息,Start regist
log_found_files,找到{0}个文件,Found {0} files,{0}ファイルが見つかりました log_found_files,找到{0}个文件,Found {0} files,{0}ファイルが見つかりました
log_found_item_types,从文件中找到{0}个物品类型,Found {0} item types in files,ファイルから{0}個のアイテム・タイプが見つかった log_found_item_types,从文件中找到{0}个物品类型,Found {0} item types in files,ファイルから{0}個のアイテム・タイプが見つかった
log_register_item,注册物品类型{0}结果为{1},Registered item type {0}; results in {1},登録されたアイテム・タイプ {0} の結果は {1} です。 log_register_item,注册物品类型{0}结果为{1},Registered item type {0}; results in {1},登録されたアイテム・タイプ {0} の結果は {1} です。
log_error_when_open_item_regs_dir,尝试打开物品信息目录{0}时发生错误,错误代码:{1},"An error occurred when trying to open the item information directory {0}, error code: {1}",アイテム情報ディレクトリ{0}を開こうとしてエラーが発生しました、エラーコード:{1} log_error_when_open_item_regs_dir,尝试打开物品信息目录时发生错误,错误代码:{1},"An error occurred when trying to open the item information directory, error code: {1}",アイテム情報ディレクトリを開こうとしてエラーが発生しました、エラーコード:{1}
log_wrong_custom_arg,不匹配的参数:类型为{0}而值为{1},Mismatched parameter: type {0} and value {1},パラメータの不一致:型{0}と値{1}。 log_wrong_custom_arg,不匹配的参数:类型为{0}而值为{1},Mismatched parameter: type {0} and value {1},パラメータの不一致:型{0}と値{1}。
log_item_container_is_null,物品容器为空,Item container is null,アイテム・コンテナが空です log_item_container_is_null,物品容器为空,Item container is null,アイテム・コンテナが空です
log_item_has_no_owner,物品没有所有者,Item has no owner,アイテムに所有者がいません log_item_has_no_owner,物品没有所有者,Item has no owner,アイテムに所有者がいません
@ -98,14 +98,3 @@ log_load_dll_file_load_exception,加载DLL文件{0}失败。,Failed to load the
log_load_dll_bad_image_format_exception,{0}不是有效的程序集。,{0} is not a valid assembly.,{0}は有効なアセンブリではありません。 log_load_dll_bad_image_format_exception,{0}不是有效的程序集。,{0} is not a valid assembly.,{0}は有効なアセンブリではありません。
log_load_dll_success,成功加载位于{0}的dll文件。,Successfully loaded the dll file located at {0}.,{0}にあるDLLファイルを正常にロードしました。 log_load_dll_success,成功加载位于{0}的dll文件。,Successfully loaded the dll file located at {0}.,{0}にあるDLLファイルを正常にロードしました。
log_mod_folder_does_not_exist,位于{0}的模组文件夹不存在。,The module folder at {0} does not exist.,{0}に位置するモジュールフォルダは存在しません。 log_mod_folder_does_not_exist,位于{0}的模组文件夹不存在。,The module folder at {0} does not exist.,{0}に位置するモジュールフォルダは存在しません。
log_mod_not_contain_dll,模组{0}不包含DLL文件。,The module {0} does not contain a DLL file.,モジュール{0}にDLLファイルが含まれていません。
log_mod_not_contain_pck,模组{0}不包含PCK文件。,The module {0} does not contain a PCK file.,モジュール{0}にPCKファイルが含まれていません。
log_load_pck_success,成功加载位于{0}的PCK文件。,Successfully loaded the PCK file located at {0}.,{0}にあるPCKファイルを正常にロードしました。
log_load_pck_failed,加载PCK文件{0}失败。,Failed to load the PCK file {0}.,PCKファイル{0}のロードに失敗しました。
log_projectile_container_is_null,抛射体容器为空。,Projectile container is null.,射出体コンテナが空です。
log_marker2d_is_null,Marker2D为空。,Marker2D is null.,Marker2Dが空です。
log_owner_is_null,所有者为空。,Owner is null.,所有者が空です。
log_dll_name,已加载{0}。,Loaded {0}.,{0}をロードしました。
log_dll_does_not_register_lifecycle_processor,位于{0}的dll文件未注册生命周期处理器{1}。,"The DLL file located at {0} does not register the lifecycle processor {1}.",{0}にあるDLLファイルは、ライフサイクルプロセッサ{1}を登録していません。
log_mod_lifecycle_handler_not_implement_interface,位于{0}的dll文件生命周期处理器未实现IModLifecycleHandler接口。,"The DLL file located at {0}, the lifecycle processor does not implement the IModLifecycleHandler interface.",{0}にあるDLLファイル、ライフサイクルプロセッサはIModLifecycleHandlerインターフェースを実装していません。
log_dll_no_parameterless_constructor,位于{0}的dll文件没有无参构造函数。,"The DLL file located at {0} does not have a parameterless constructor.",{0}にあるDLLファイルにはパラメータのないコンストラクタがありません。
1 id zh en ja
33 log_found_files 找到{0}个文件 Found {0} files {0}ファイルが見つかりました
34 log_found_item_types 从文件中找到{0}个物品类型 Found {0} item types in files ファイルから{0}個のアイテム・タイプが見つかった
35 log_register_item 注册物品类型{0}结果为{1} Registered item type {0}; results in {1} 登録されたアイテム・タイプ {0} の結果は {1} です。
36 log_error_when_open_item_regs_dir 尝试打开物品信息目录{0}时发生错误,错误代码:{1} 尝试打开物品信息目录时发生错误,错误代码:{1} An error occurred when trying to open the item information directory {0}, error code: {1} An error occurred when trying to open the item information directory, error code: {1} アイテム情報ディレクトリ{0}を開こうとしてエラーが発生しました、エラーコード:{1} アイテム情報ディレクトリを開こうとしてエラーが発生しました、エラーコード:{1}
37 log_wrong_custom_arg 不匹配的参数:类型为{0}而值为{1} Mismatched parameter: type {0} and value {1} パラメータの不一致:型{0}と値{1}。
38 log_item_container_is_null 物品容器为空 Item container is null アイテム・コンテナが空です
39 log_item_has_no_owner 物品没有所有者 Item has no owner アイテムに所有者がいません
98 log_load_dll_bad_image_format_exception {0}不是有效的程序集。 {0} is not a valid assembly. {0}は有効なアセンブリではありません。
99 log_load_dll_success 成功加载位于{0}的dll文件。 Successfully loaded the dll file located at {0}. {0}にあるDLLファイルを正常にロードしました。
100 log_mod_folder_does_not_exist 位于{0}的模组文件夹不存在。 The module folder at {0} does not exist. {0}に位置するモジュールフォルダは存在しません。
log_mod_not_contain_dll 模组{0}不包含DLL文件。 The module {0} does not contain a DLL file. モジュール{0}にDLLファイルが含まれていません。
log_mod_not_contain_pck 模组{0}不包含PCK文件。 The module {0} does not contain a PCK file. モジュール{0}にPCKファイルが含まれていません。
log_load_pck_success 成功加载位于{0}的PCK文件。 Successfully loaded the PCK file located at {0}. {0}にあるPCKファイルを正常にロードしました。
log_load_pck_failed 加载PCK文件{0}失败。 Failed to load the PCK file {0}. PCKファイル{0}のロードに失敗しました。
log_projectile_container_is_null 抛射体容器为空。 Projectile container is null. 射出体コンテナが空です。
log_marker2d_is_null Marker2D为空。 Marker2D is null. Marker2Dが空です。
log_owner_is_null 所有者为空。 Owner is null. 所有者が空です。
log_dll_name 已加载{0}。 Loaded {0}. {0}をロードしました。
log_dll_does_not_register_lifecycle_processor 位于{0}的dll文件,未注册生命周期处理器{1}。 The DLL file located at {0} does not register the lifecycle processor {1}. {0}にあるDLLファイルは、ライフサイクルプロセッサ{1}を登録していません。
log_mod_lifecycle_handler_not_implement_interface 位于{0}的dll文件,生命周期处理器未实现IModLifecycleHandler接口。 The DLL file located at {0}, the lifecycle processor does not implement the IModLifecycleHandler interface. {0}にあるDLLファイル、ライフサイクルプロセッサはIModLifecycleHandlerインターフェースを実装していません。
log_dll_no_parameterless_constructor 位于{0}的dll文件,没有无参构造函数。 The DLL file located at {0} does not have a parameterless constructor. {0}にあるDLLファイルにはパラメータのないコンストラクタがありません。

View File

@ -96,17 +96,11 @@ public static class Config
/// </summary> /// </summary>
public const string CompanyName = "ColdMint"; public const string CompanyName = "ColdMint";
/// <summary>
/// <para>Module life handler name</para>
/// <para>模组生命周期处理器名称</para>
/// </summary>
public const string ModLifecycleHandlerName = "ModLifecycleHandler";
/// <summary> /// <summary>
/// <para>Solution Name</para> /// <para>Solution Name</para>
/// <para>解决方案名称</para> /// <para>解决方案名称</para>
/// </summary> /// </summary>
public const string SolutionName = "ColdMint.Traveler"; public static string SolutionName = "ColdMint.Traveler";
/// <summary> /// <summary>
/// <para>How many item slots are there on the shortcut bar</para> /// <para>How many item slots are there on the shortcut bar</para>
@ -125,12 +119,7 @@ public static class Config
/// <para>Whether version isolation is enabled</para> /// <para>Whether version isolation is enabled</para>
/// <para>是否启用版本隔离</para> /// <para>是否启用版本隔离</para>
/// </summary> /// </summary>
public static bool EnableVersionIsolation() public const bool EnableVersionIsolation = true;
{
//By default, we enable version isolation, but special feature identifiers can be set to disable version isolation.
//默认情况,我们启用版本隔离,但是可以设置特殊的功能标识来禁用版本隔离。
return !OS.HasFeature("disableVersionIsolation");
}
/// <summary> /// <summary>
/// <para>Default version name</para> /// <para>Default version name</para>
@ -221,14 +210,10 @@ public static class Config
/// <para>Get what platform is currently running on</para> /// <para>Get what platform is currently running on</para>
/// <para>获取当前在什么平台上运行</para> /// <para>获取当前在什么平台上运行</para>
/// </summary> /// </summary>
/// <param name="containEditor">
///<para>Whether to include an editor environment</para>
///<para>是否包含编辑器环境</para>
/// </param>
/// <returns></returns> /// <returns></returns>
public static OsEnum GetOs(bool containEditor = false) public static OsEnum GetOs()
{ {
if (containEditor && OS.HasFeature("editor")) if (OS.HasFeature("editor"))
{ {
return OsEnum.Editor; return OsEnum.Editor;
} }
@ -286,7 +271,7 @@ public static class Config
/// <returns></returns> /// <returns></returns>
public static string GetGameDataDirectory() public static string GetGameDataDirectory()
{ {
if (EnableVersionIsolation()) if (EnableVersionIsolation)
{ {
return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName, return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), CompanyName,
ProjectSettings.GetSetting("application/config/name").AsString(), UserId, ProjectSettings.GetSetting("application/config/name").AsString(), UserId,
@ -300,15 +285,6 @@ public static class Config
} }
} }
/// <summary>
/// <para>GetModDataDirectory</para>
/// <para>获取模组文件夹</para>
/// </summary>
/// <returns></returns>
public static string GetModDataDirectory()
{
return Path.Join(GetGameDataDirectory(), "Mods");
}
/// <summary> /// <summary>
/// <para>Get the export directory for the level graph</para> /// <para>Get the export directory for the level graph</para>

View File

@ -35,12 +35,6 @@ public static class GameSceneNodeHolder
} }
} }
/// <summary>
/// <para>ProjectileContainer</para>
/// <para>抛射体容器</para>
/// </summary>
public static Node2D? ProjectileContainer { get; set; }
/// <summary> /// <summary>
/// <para>WeaponContainer</para> /// <para>WeaponContainer</para>
/// <para>武器容器</para> /// <para>武器容器</para>

View File

@ -249,14 +249,11 @@ public static class LogCat
switch (level) switch (level)
{ {
case WarningLogLevel:
GD.PrintRich("[color=#FFDE66]"+concreteLog+"[/color]");
break;
case ErrorLogLevel: case ErrorLogLevel:
GD.PrintRich("[color=#FF4E39]"+concreteLog+"[/color]"); GD.PrintErr(concreteLog);
break; break;
default: default:
GD.PrintRich("[color=#CCCED1]"+concreteLog+"[/color]"); GD.Print(concreteLog);
break; break;
} }
} }
@ -296,7 +293,7 @@ public static class LogCat
upload); upload);
} }
public static void LogWarningWithFormat(string message, string label, bool upload, params object?[] args) public static void LogWarningWithFormat(string message, bool upload, string label, params object?[] args)
{ {
PrintLog(WarningLogLevel, string.Format(HandleMessage(WarningLogLevel, message, label).ToString(), args), label, PrintLog(WarningLogLevel, string.Format(HandleMessage(WarningLogLevel, message, label).ToString(), args), label,
upload); upload);

View File

@ -31,14 +31,12 @@ public static class ItemTypeRegister
LogCat.Log("start_item_register_from_file"); LogCat.Log("start_item_register_from_file");
//初始化文件目录 //初始化文件目录
//initialize file dir //initialize file dir
var itemRegsDirPath = "res://data/itemRegs"; var itemRegsDirPath = "res://data/itemRegs/";
var itemRegsDir = DirAccess.Open(itemRegsDirPath); var itemRegsDir = DirAccess.Open(itemRegsDirPath);
var error = DirAccess.GetOpenError(); var error = DirAccess.GetOpenError();
if (error is not Error.Ok) if (error is not Error.Ok)
{ {
LogCat.LogErrorWithFormat("error_when_open_item_regs_dir", LogCat.LogLabel.Default, true, itemRegsDirPath, LogCat.LogError("error_when_open_item_regs_dir", error.ToString());
error.ToString());
return;
} }
//找到文件 //找到文件
@ -71,7 +69,7 @@ public static class ItemTypeRegister
/// </summary> /// </summary>
/// <param name="filePath"></param> /// <param name="filePath"></param>
/// <returns></returns> /// <returns></returns>
private static IList<ItemTypeInfo>? ParseFile(string filePath) private static IList<ItemTypeInfo> ParseFile(string filePath)
{ {
var yamlFile = FileAccess.Open(filePath, FileAccess.ModeFlags.Read); var yamlFile = FileAccess.Open(filePath, FileAccess.ModeFlags.Read);

View File

@ -39,10 +39,6 @@ public partial class GameSceneLoader : SceneLoaderTemplate
//加载武器容器 //加载武器容器
var weaponContainer = GetNode<Node2D>("WeaponContainer"); var weaponContainer = GetNode<Node2D>("WeaponContainer");
GameSceneNodeHolder.WeaponContainer = weaponContainer; GameSceneNodeHolder.WeaponContainer = weaponContainer;
//Load projectile container
//加载抛射体容器
var projectileContainer = GetNode<Node2D>("ProjectileContainer");
GameSceneNodeHolder.ProjectileContainer = projectileContainer;
//Load Packsack container //Load Packsack container
//加载背包容器 //加载背包容器
var packsackContainer = GetNode<Node2D>("PacksackContainer"); var packsackContainer = GetNode<Node2D>("PacksackContainer");

View File

@ -82,6 +82,7 @@ public partial class SplashScreenLoader : UiLoaderTemplate
//Disable all logs in the release version. //Disable all logs in the release version.
//在发行版禁用所有日志。 //在发行版禁用所有日志。
LogCat.MinLogLevel = Config.IsDebug() ? LogCat.InfoLogLevel : LogCat.DisableAllLogLevel; LogCat.MinLogLevel = Config.IsDebug() ? LogCat.InfoLogLevel : LogCat.DisableAllLogLevel;
ModLoader.Init();
ContributorDataManager.RegisterAllContributorData(); ContributorDataManager.RegisterAllContributorData();
DeathInfoGenerator.RegisterDeathInfoHandler(new SelfDeathInfoHandler()); DeathInfoGenerator.RegisterDeathInfoHandler(new SelfDeathInfoHandler());
MapGenerator.RegisterRoomInjectionProcessor(new ChanceRoomInjectionProcessor()); MapGenerator.RegisterRoomInjectionProcessor(new ChanceRoomInjectionProcessor());
@ -89,7 +90,6 @@ public partial class SplashScreenLoader : UiLoaderTemplate
//Register the corresponding encoding provider to solve the problem of garbled Chinese path of the compressed package //Register the corresponding encoding provider to solve the problem of garbled Chinese path of the compressed package
//注册对应的编码提供程序,解决压缩包中文路径乱码问题 //注册对应的编码提供程序,解决压缩包中文路径乱码问题
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
//Create a game data folder
//创建游戏数据文件夹 //创建游戏数据文件夹
var dataPath = Config.GetGameDataDirectory(); var dataPath = Config.GetGameDataDirectory();
if (!Directory.Exists(dataPath)) if (!Directory.Exists(dataPath))
@ -116,15 +116,6 @@ public partial class SplashScreenLoader : UiLoaderTemplate
ItemTypeRegister.StaticRegister(); ItemTypeRegister.StaticRegister();
//静态注册掉落表 //静态注册掉落表
LootRegister.StaticRegister(); LootRegister.StaticRegister();
//Load mod
//加载模组
var modPath = Config.GetModDataDirectory();
if (!Directory.Exists(modPath))
{
Directory.CreateDirectory(modPath);
}
ModLoader.Init();
ModLoader.LoadAllMods(modPath);
await Task.Delay(TimeSpan.FromMilliseconds(500)); await Task.Delay(TimeSpan.FromMilliseconds(500));
} }
} }

View File

@ -330,7 +330,7 @@ public static class MapGenerator
if (!await _roomPlacementStrategy.PlaceRoom(_mapRoot, roomPlacementData)) if (!await _roomPlacementStrategy.PlaceRoom(_mapRoot, roomPlacementData))
{ {
LogCat.LogWarningWithFormat("room_placement_failed", LogCat.LogLabel.Default, LogCat.UploadFormat, LogCat.LogWarningWithFormat("room_placement_failed", LogCat.UploadFormat, LogCat.LogLabel.Default,
roomNodeDataId); roomNodeDataId);
return false; return false;
} }

View File

@ -1,14 +0,0 @@
namespace ColdMint.scripts.mod;
/// <summary>
/// <para>Mod life cycle handler</para>
/// <para>模组生命周期处理器</para>
/// </summary>
public interface IModLifecycleHandler
{
/// <summary>
/// <para>When loading the Mod</para>
/// <para>当加载Mod时</para>
/// </summary>
void OnModLoaded();
}

View File

@ -1,11 +1,8 @@
using System; using System;
using System.Data;
using System.IO; using System.IO;
using System.Reflection;
using System.Runtime.Loader; using System.Runtime.Loader;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot;
namespace ColdMint.scripts.mod; namespace ColdMint.scripts.mod;
@ -21,16 +18,8 @@ public class ModLoader
/// </summary> /// </summary>
private static AssemblyLoadContext? _assemblyLoadContext; private static AssemblyLoadContext? _assemblyLoadContext;
private static readonly string[] RequiredDllList = [Config.SolutionName]; private static string[] _requiredDllList = new[] { Config.SolutionName };
/// <summary>
/// <para>Initializes the mod loader</para>
/// <para>初始化模组加载器</para>
/// </summary>
/// <exception cref="FileNotFoundException">
///<para>This exception is thrown if the built-in dll file cannot be found when it is loaded.</para>
///<para>如果加载内置dll文件时找不到文件则抛出此异常。</para>
/// </exception>
public static void Init() public static void Init()
{ {
//Initialize the context. //Initialize the context.
@ -50,7 +39,7 @@ public class ModLoader
return; return;
} }
foreach (var requiredDll in RequiredDllList) foreach (var requiredDll in _requiredDllList)
{ {
var dllPath = Path.Join(dllFolder, requiredDll + ".dll"); var dllPath = Path.Join(dllFolder, requiredDll + ".dll");
//Load the necessary dll files. //Load the necessary dll files.
@ -60,30 +49,7 @@ public class ModLoader
//When the dll that must be loaded does not exist, an error is reported immediately. //When the dll that must be loaded does not exist, an error is reported immediately.
//当必须加载的dll不存在时立即报错。 //当必须加载的dll不存在时立即报错。
LogCat.LogErrorWithFormat("dll_not_exist", LogCat.LogLabel.ModLoader, true, dllPath); LogCat.LogErrorWithFormat("dll_not_exist", LogCat.LogLabel.ModLoader, true, dllPath);
throw new FileNotFoundException("dll not exist:" + dllPath); throw new NullReferenceException("dll not exist:" + dllPath);
}
LoadDllFile(dllPath);
}
}
/// <summary>
/// <para>Load Dll file</para>
/// <para>加载Dll文件</para>
/// </summary>
/// <param name="dllPath">
///<para>dll file path</para>
///<para>dll的文件路径</para>
/// </param>
/// <exception cref="NullReferenceException">
///<para>Throw this error if the assemblyLoadContext has not been initialized.</para>
///<para>如果assemblyLoadContext尚未初始化那么抛出此错误。</para>
/// </exception>
private static void LoadDllFile(string dllPath)
{
if (_assemblyLoadContext == null)
{
throw new NullReferenceException("assemblyLoadContext is null.");
} }
//Load the dll. //Load the dll.
@ -91,60 +57,7 @@ public class ModLoader
LogCat.LogWithFormat("load_dll", LogCat.LogLabel.ModLoader, true, dllPath); LogCat.LogWithFormat("load_dll", LogCat.LogLabel.ModLoader, true, dllPath);
try try
{ {
var assembly = _assemblyLoadContext.LoadFromAssemblyPath(dllPath); _assemblyLoadContext.LoadFromAssemblyPath(dllPath);
var assemblyName = assembly.GetName().Name;
if (assemblyName == null)
{
return;
}
LogCat.LogWithFormat("dll_name", LogCat.LogLabel.ModLoader, true, assemblyName);
// if (assemblyName != Config.SolutionName)
// {
// //If the load is not its own Dll file.
// //如果加载的不是自身的Dll文件.
// }
//Call the method of the entry class.
//调用入口类的方法
var modLifecycleHandlerFullName = assemblyName + "." + Config.ModLifecycleHandlerName;
var modLifecycleHandlerType = assembly.GetType(modLifecycleHandlerFullName);
if (modLifecycleHandlerType == null)
{
//The module does not register a lifecycle processor.
//模组没有注册生命周期处理器。
LogCat.LogWarningWithFormat("dll_does_not_register_lifecycle_processor", LogCat.LogLabel.ModLoader,
LogCat.UploadFormat,
dllPath, modLifecycleHandlerFullName);
}
else
{
var constructor = modLifecycleHandlerType.GetConstructor(Type.EmptyTypes);
if (constructor == null)
{
//No parameterless constructor found.
//未找到无参构造方法。
LogCat.LogWarningWithFormat("dll_no_parameterless_constructor", LogCat.LogLabel.ModLoader,
LogCat.UploadFormat,
dllPath);
}
else
{
var modLifecycleHandler = constructor.Invoke(null) as IModLifecycleHandler;
if (modLifecycleHandler == null)
{
//The ModLifecycleHandler class in the dll does not yet implement the IModLifecycleHandler interface.
//dll内的ModLifecycleHandler类尚未实现IModLifecycleHandler接口。
LogCat.LogWarningWithFormat("mod_lifecycle_handler_not_implement_interface",
LogCat.LogLabel.ModLoader,
LogCat.UploadFormat, dllPath);
}
else
{
modLifecycleHandler.OnModLoaded();
}
}
}
} }
catch (ArgumentNullException argumentNullException) catch (ArgumentNullException argumentNullException)
{ {
@ -184,145 +97,37 @@ public class ModLoader
//加载dll成功。 //加载dll成功。
LogCat.LogWithFormat("load_dll_success", LogCat.LogLabel.ModLoader, true, dllPath); LogCat.LogWithFormat("load_dll_success", LogCat.LogLabel.ModLoader, true, dllPath);
} }
/// <summary>
/// <para>Load all mods</para>
/// <para>加载全部模组</para>
/// </summary>
/// <remarks>
///<para>This method scans the incoming subfolders and loads them as module folders.</para>
///<para>此方法会将扫描传入的子文件夹,并将其子文件夹看作模组文件夹加载。</para>
/// </remarks>
/// <param name="modFolder">
///<para>Mod folder</para>
///<para>模组文件夹</para>
/// </param>
/// <exception cref="DirectoryNotFoundException">
///<para>If the given folder does not exist, throw this exception.</para>
///<para>如果给定的文件夹不存在,则抛出此异常。</para>
/// </exception>
public static void LoadAllMods(string modFolder)
{
if (!Directory.Exists(modFolder))
{
//The mod directory does not exist.
//模组目录不存在。
throw new DirectoryNotFoundException("mod folder not exist:" + modFolder);
}
var directoryInfo = new DirectoryInfo(modFolder);
foreach (var directory in directoryInfo.GetDirectories())
{
LoadSingleMod(directory.FullName);
}
} }
/// <summary> /// <summary>
/// <para>Load a single mod</para> /// <para>Load a module for a directory</para>
/// <para>加载单个模组</para> /// <para>加载某个目录的模组</para>
/// </summary> /// </summary>
/// <param name="modFolderPath"> /// <param name="modFolderPath">
///<para>Mod path</para> ///<para>Mod path</para>
///<para>模组路径</para> ///<para>模组路径</para>
/// </param> /// </param>
/// <exception cref="DirectoryNotFoundException"> public static void LoadMod(string modFolderPath)
/// <para>If the given directory does not exist, throw this exception.</para>
///<para>如果给定的目录不存在,那么抛出此异常。</para>
/// </exception>
/// <exception cref="NullReferenceException">
///<para>Throw this exception if the manifest file creation deserialization fails.</para>
///<para>如果清单文件创建反序列化失败,则抛出此异常。</para>
/// </exception>
private static void LoadSingleMod(string modFolderPath)
{ {
if (!Directory.Exists(modFolderPath)) if (!Directory.Exists(modFolderPath))
{ {
//The module folder does not exist. //The module folder does not exist.
//模组文件夹不存在。 //模组文件夹不存在。
throw new DirectoryNotFoundException("Mod folder does not exist:" + modFolderPath); LogCat.LogErrorWithFormat("mod_folder_does_not_exist", LogCat.LogLabel.ModLoader, true, modFolderPath);
return;
} }
var modManifestPath = Path.Join(modFolderPath, Config.ModManifestFileName); try
{
var modManifest = var modManifest =
ModManifest.CreateModManifestFromPath(modManifestPath); ModManifest.CreateModManifestFromPath(Path.Join(modFolderPath, Config.ModManifestFileName));
if (modManifest == null) }
catch (FileNotFoundException fileNotFoundException)
{ {
throw new NullReferenceException("mod manifest is null:" + modManifestPath); //Do not continue to load the file when it does not exist.
} //当文件不存在时就不要继续加载了。
LogCat.WhenCaughtException(fileNotFoundException, LogCat.LogLabel.ModLoader);
var dllList = modManifest.DllList; return;
if (dllList == null || dllList.Length == 0)
{
//The module does not contain a dll file.
//模组不包含dll文件。
LogCat.LogWarningWithFormat("mod_not_contain_dll", LogCat.LogLabel.ModLoader, LogCat.UploadFormat,
modFolderPath);
}
else
{
//The module contains dll files, load the dll files.
//包含dll文件加载dll文件。
foreach (var dll in dllList)
{
var dllPath = Path.GetFullPath(dll, modFolderPath);
LoadDllFile(dllPath);
}
}
var pakList = modManifest.PckList;
if (pakList == null || pakList.Length == 0)
{
//The module does not contain a pck file.
//模组不包含pck文件。
LogCat.LogWarningWithFormat("mod_not_contain_pck", LogCat.LogLabel.ModLoader, LogCat.UploadFormat,
modFolderPath);
}
else
{
//The module contains pck files, load the pck files.
//包含pck文件加载pck文件。
foreach (var pak in pakList)
{
var pakPath = Path.GetFullPath(pak, modFolderPath);
LoadPckFile(pakPath);
}
}
}
/// <summary>
/// <para>Load the Pck file</para>
/// <para>加载Pck文件</para>
/// </summary>
/// <param name="pckPath">
///<para>Pck path</para>
///<para>Pck路径</para>
/// </param>
/// <exception cref="FileNotFoundException">
///<para>If the given path does not exist, throw this exception.</para>
///<para>如果给定的路径不存在,那么抛出此异常。</para>
/// </exception>
/// <exception cref="Exception">
///<para>Throw this exception if the pck package fails to load.</para>
///<para>如果pck包加载失败了抛出此异常。</para>
/// </exception>
private static void LoadPckFile(string pckPath)
{
if (!File.Exists(pckPath))
{
throw new FileNotFoundException("pck file not exist:" + pckPath);
}
var success = ProjectSettings.LoadResourcePack(pckPath);
if (success)
{
LogCat.LogWithFormat("load_pck_success", LogCat.LogLabel.ModLoader, true, pckPath);
}
else
{
LogCat.LogErrorWithFormat("load_pck_failed", LogCat.LogLabel.ModLoader, true, pckPath);
//Throw a suitable exception here for handling at the caller.
//为这里抛出合适的异常,以便在调用方处理。
throw new DataException("load pck failed:" + pckPath);
} }
} }
} }

View File

@ -25,20 +25,12 @@ public class ModManifest
/// <para>Dll path list of the mod</para> /// <para>Dll path list of the mod</para>
/// <para>模组的Dll路径列表</para> /// <para>模组的Dll路径列表</para>
/// </summary> /// </summary>
/// <remarks>
///<para>Allow relative paths, such as:... / Points to the parent directory.</para>
///<para>允许使用相对路径,例如: ../指向上级目录。</para>
/// </remarks>
public string[]? DllList { get; set; } public string[]? DllList { get; set; }
/// <summary> /// <summary>
/// <para>Pck path list of mod</para> /// <para>Pck path list of mod</para>
/// <para>模组的Pck路径列表</para> /// <para>模组的Pck路径列表</para>
/// </summary> /// </summary>
/// <remarks>
///<para>Allow relative paths, such as:... / Points to the parent directory.</para>
///<para>允许使用相对路径,例如: ../指向上级目录。</para>
/// </remarks>
public string[]? PckList { get; set; } public string[]? PckList { get; set; }
/// <summary> /// <summary>
@ -58,7 +50,7 @@ public class ModManifest
///<para>当给定的路径不存在时,抛出此异常。</para> ///<para>当给定的路径不存在时,抛出此异常。</para>
/// </exception> /// </exception>
/// <returns></returns> /// <returns></returns>
public static ModManifest? CreateModManifestFromPath(string filePath) public static ModManifest CreateModManifestFromPath(string filePath)
{ {
if (!filePath.EndsWith(Config.ModManifestFileName)) if (!filePath.EndsWith(Config.ModManifestFileName))
{ {

View File

@ -51,10 +51,8 @@ public static class YamlSerialization
/// <param name="yaml"></param> /// <param name="yaml"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
// ReSharper disable ReturnTypeCanBeNotNullable public static T Deserialize<T>(string yaml)
public static T? Deserialize<T>(string yaml)
{ {
return YamlDeserializer.Deserialize<T>(yaml); return YamlDeserializer.Deserialize<T>(yaml);
} }
// ReSharper restore ReturnTypeCanBeNotNullable
} }

View File

@ -58,7 +58,6 @@ public static class ExplorerUtils
case Config.OsEnum.Macos: case Config.OsEnum.Macos:
case Config.OsEnum.Ios: case Config.OsEnum.Ios:
case Config.OsEnum.Web: case Config.OsEnum.Web:
case Config.OsEnum.Editor:
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.projectile;
using Godot; using Godot;
using Packsack = ColdMint.scripts.inventory.Packsack; using Packsack = ColdMint.scripts.inventory.Packsack;
using PacksackUi = ColdMint.scripts.loader.uiLoader.PacksackUi; using PacksackUi = ColdMint.scripts.loader.uiLoader.PacksackUi;
@ -236,11 +235,6 @@ public static class NodeUtils
/// <returns></returns> /// <returns></returns>
public static Node FindContainerNode(Node childNode, Node defaultParentNode) public static Node FindContainerNode(Node childNode, Node defaultParentNode)
{ {
if (GameSceneNodeHolder.ProjectileContainer != null && childNode is Projectile)
{
return GameSceneNodeHolder.ProjectileContainer;
}
if (GameSceneNodeHolder.WeaponContainer != null && childNode is WeaponTemplate) if (GameSceneNodeHolder.WeaponContainer != null && childNode is WeaponTemplate)
{ {
return GameSceneNodeHolder.WeaponContainer; return GameSceneNodeHolder.WeaponContainer;
@ -284,7 +278,7 @@ public static class NodeUtils
if (node is T result) return result; if (node is T result) return result;
// If the transformation fails, release the created node // If the transformation fails, release the created node
//如果转型失败,释放所创建的节点 //如果转型失败,释放所创建的节点
LogCat.LogWarningWithFormat("warning_node_cannot_cast_to", LogCat.LogLabel.Default,LogCat.UploadFormat, node, LogCat.LogWarningWithFormat("warning_node_cannot_cast_to", LogCat.UploadFormat, LogCat.LogLabel.Default, node,
nameof(T)); nameof(T));
node.QueueFree(); node.QueueFree();
return null; return null;

View File

@ -23,22 +23,20 @@ public static class ResUtils
public static string? GetSelfDllFolder() public static string? GetSelfDllFolder()
{ {
var currentDirectory = Environment.CurrentDirectory; var currentDirectory = Environment.CurrentDirectory;
var osEnum = Config.GetOs(true); if (Config.GetOs() == Config.OsEnum.Editor)
if (osEnum == Config.OsEnum.Editor)
{ {
return Path.Join(currentDirectory, ".godot", "mono", "temp", "bin", "Debug"); return Path.Join(currentDirectory, ".godot", "mono", "temp", "bin", "Debug");
} }
if (osEnum == Config.OsEnum.Windows) if (Config.GetOs() == Config.OsEnum.Windows)
{ {
return Path.Join(currentDirectory, "data_" + Config.SolutionName + "_windows_x86_64"); return Path.Join(currentDirectory, "data_" + Config.SolutionName + "_windows_x86_64");
} }
if (osEnum == Config.OsEnum.Linux) if (Config.GetOs() == Config.OsEnum.Linux)
{ {
return Path.Join(currentDirectory, "data_" + Config.SolutionName + "_linuxbsd_x86_64"); return Path.Join(currentDirectory, "data_" + Config.SolutionName + "_linuxbsd_x86_64");
} }
return null; return null;
} }

View File

@ -23,33 +23,21 @@ public partial class ProjectileWeapon : WeaponTemplate
[Export] protected PackedScene[] ProjectileScenes { get; set; } = []; [Export] protected PackedScene[] ProjectileScenes { get; set; } = [];
private Node2D? _projectileContainer;
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
_marker2D = GetNode<Marker2D>("Marker2D"); _marker2D = GetNode<Marker2D>("Marker2D");
_projectileContainer = GetNode("/root/Game/ProjectileContainer") as Node2D;
} }
protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition) protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition)
{ {
if (owner == null) if (owner == null || _projectileContainer == null || _marker2D == null) return;
{
LogCat.LogError("owner_is_null");
return;
}
if (_marker2D == null)
{
LogCat.LogError("marker2d_is_null");
return;
}
if (GameSceneNodeHolder.ProjectileContainer == null)
{
LogCat.LogError("projectile_container_is_null");
return;
}
//Empty list check
//空列表检查 //空列表检查
if (ProjectileScenes is []) if (ProjectileScenes is [])
{ {
@ -63,7 +51,7 @@ public partial class ProjectileWeapon : WeaponTemplate
// var projectileScene = _projectileCache[_projectiles[0]]; // var projectileScene = _projectileCache[_projectiles[0]];
var projectile = NodeUtils.InstantiatePackedScene<ProjectileTemplate>(projectileScene); var projectile = NodeUtils.InstantiatePackedScene<ProjectileTemplate>(projectileScene);
if (projectile == null) return; if (projectile == null) return;
NodeUtils.CallDeferredAddChild(GameSceneNodeHolder.ProjectileContainer, projectile); NodeUtils.CallDeferredAddChild(_projectileContainer, projectile);
projectile.Owner = owner; projectile.Owner = owner;
projectile.Velocity = (enemyGlobalPosition - _marker2D.GlobalPosition).Normalized() * projectile.Speed; projectile.Velocity = (enemyGlobalPosition - _marker2D.GlobalPosition).Normalized() * projectile.Speed;
projectile.Position = _marker2D.GlobalPosition; projectile.Position = _marker2D.GlobalPosition;