Sfoglia il codice sorgente

起服配置变成多份,使用命令行参数选择使用哪份起服配置, 例如
dotnet Server.dll --Process=1 --StartConfig=StartConfig/Release --Console=1
这样每个开发人员都可以配置自己的起服配置,再也不会冲突了

导表工具进化:
1.增加了表合并功能,UnitConfig.xlsx跟UnitConfig_Monster.xlsx会合并成一张表
2.多线程导表
3.表格名里面带@后面加上cs#等,c表示导出客户端,s表示导出服务端,#表示该表不导出
4.json导出放到Excel中,这样提交到svn方便策划对比变化

tanghai 3 anni fa
parent
commit
536eccacbc
75 ha cambiato i file con 682 aggiunte e 535 eliminazioni
  1. 4 0
      Apps/Hotfix/Config/ConfigLoader.cs
  2. 13 2
      Apps/Model/Generate/Config/AIConfig.cs
  3. 11 1
      Apps/Model/Generate/Config/StartMachineConfig.cs
  4. 10 1
      Apps/Model/Generate/Config/StartProcessConfig.cs
  5. 13 1
      Apps/Model/Generate/Config/StartSceneConfig.cs
  6. 10 1
      Apps/Model/Generate/Config/StartZoneConfig.cs
  7. 19 6
      Apps/Model/Generate/Config/UnitConfig.cs
  8. 355 141
      Apps/Tool/ExcelExporter/ExcelExporter.cs
  9. 7 1
      Apps/Tool/Template.txt
  10. 5 6
      Book/1.1RunGuide.md
  11. 4 3
      Book/1.1运行指南.md
  12. 0 0
      Config/StartConfig/Localhost/StartMachineConfigCategory.bytes
  13. 0 0
      Config/StartConfig/Localhost/StartProcessConfigCategory.bytes
  14. 0 0
      Config/StartConfig/Localhost/StartSceneConfigCategory.bytes
  15. 0 0
      Config/StartConfig/Localhost/StartZoneConfigCategory.bytes
  16. 2 0
      Config/StartConfig/Release/StartMachineConfigCategory.bytes
  17. 3 0
      Config/StartConfig/Release/StartProcessConfigCategory.bytes
  18. 8 0
      Config/StartConfig/Release/StartSceneConfigCategory.bytes
  19. 3 0
      Config/StartConfig/Release/StartZoneConfigCategory.bytes
  20. 1 1
      Config/UnitConfigCategory.bytes
  21. 5 0
      Excel/Json/c/AIConfig.txt
  22. 3 0
      Excel/Json/c/StartConfig/Localhost/StartMachineConfig.txt
  23. 4 0
      Excel/Json/c/StartConfig/Localhost/StartProcessConfig.txt
  24. 9 0
      Excel/Json/c/StartConfig/Localhost/StartSceneConfig.txt
  25. 4 0
      Excel/Json/c/StartConfig/Localhost/StartZoneConfig.txt
  26. 3 0
      Excel/Json/c/StartConfig/Release/StartMachineConfig.txt
  27. 4 0
      Excel/Json/c/StartConfig/Release/StartProcessConfig.txt
  28. 9 0
      Excel/Json/c/StartConfig/Release/StartSceneConfig.txt
  29. 4 0
      Excel/Json/c/StartConfig/Release/StartZoneConfig.txt
  30. 3 0
      Excel/Json/c/StartMachineConfig.txt
  31. 4 0
      Excel/Json/c/StartProcessConfig.txt
  32. 9 0
      Excel/Json/c/StartSceneConfig.txt
  33. 4 0
      Excel/Json/c/StartZoneConfig.txt
  34. 3 0
      Excel/Json/c/UnitConfig.txt
  35. 5 0
      Excel/Json/s/AIConfig.txt
  36. 3 0
      Excel/Json/s/StartConfig/Localhost/StartMachineConfig.txt
  37. 4 0
      Excel/Json/s/StartConfig/Localhost/StartProcessConfig.txt
  38. 9 0
      Excel/Json/s/StartConfig/Localhost/StartSceneConfig.txt
  39. 4 0
      Excel/Json/s/StartConfig/Localhost/StartZoneConfig.txt
  40. 3 0
      Excel/Json/s/StartConfig/Release/StartMachineConfig.txt
  41. 4 0
      Excel/Json/s/StartConfig/Release/StartProcessConfig.txt
  42. 9 0
      Excel/Json/s/StartConfig/Release/StartSceneConfig.txt
  43. 4 0
      Excel/Json/s/StartConfig/Release/StartZoneConfig.txt
  44. 3 0
      Excel/Json/s/StartMachineConfig.txt
  45. 4 0
      Excel/Json/s/StartProcessConfig.txt
  46. 9 0
      Excel/Json/s/StartSceneConfig.txt
  47. 4 0
      Excel/Json/s/StartZoneConfig.txt
  48. 3 0
      Excel/Json/s/UnitConfig.txt
  49. 0 0
      Excel/StartConfig/Localhost/StartMachineConfig@s.xlsx
  50. 0 0
      Excel/StartConfig/Localhost/StartProcessConfig@s.xlsx
  51. 0 0
      Excel/StartConfig/Localhost/StartSceneConfig@s.xlsx
  52. 0 0
      Excel/StartConfig/Localhost/StartZoneConfig@s.xlsx
  53. BIN
      Excel/StartConfig/Release/StartMachineConfig@s.xlsx
  54. BIN
      Excel/StartConfig/Release/StartProcessConfig@s.xlsx
  55. BIN
      Excel/StartConfig/Release/StartSceneConfig@s.xlsx
  56. BIN
      Excel/StartConfig/Release/StartZoneConfig@s.xlsx
  57. BIN
      Excel/StartMachineConfig@s.xlsx
  58. BIN
      Excel/StartProcessConfig@s.xlsx
  59. BIN
      Excel/StartSceneConfig@s.xlsx
  60. BIN
      Excel/StartZoneConfig@s.xlsx
  61. 0 7
      Unity/Assets/Bundles/Config/StartMachineConfigCategory.bytes.meta
  62. 0 7
      Unity/Assets/Bundles/Config/StartProcessConfigCategory.bytes.meta
  63. 0 7
      Unity/Assets/Bundles/Config/StartSceneConfigCategory.bytes.meta
  64. 0 7
      Unity/Assets/Bundles/Config/StartZoneConfigCategory.bytes.meta
  65. 1 1
      Unity/Assets/Bundles/Config/UnitConfigCategory.bytes
  66. 1 1
      Unity/Assets/Editor/BuildEditor/BuildEditor.cs
  67. 34 5
      Unity/Assets/Editor/ServerCommandLineEditor/ServerCommandLineEditor.cs
  68. 3 0
      Unity/Assets/Mono/Core/Options.cs
  69. 13 2
      Unity/Codes/Model/Generate/Config/AIConfig.cs
  70. 0 82
      Unity/Codes/Model/Generate/Config/StartMachineConfig.cs
  71. 0 80
      Unity/Codes/Model/Generate/Config/StartProcessConfig.cs
  72. 0 86
      Unity/Codes/Model/Generate/Config/StartSceneConfig.cs
  73. 0 80
      Unity/Codes/Model/Generate/Config/StartZoneConfig.cs
  74. 19 6
      Unity/Codes/Model/Generate/Config/UnitConfig.cs
  75. 7 0
      Unity/Codes/Model/Module/Config/IMerge.cs

+ 4 - 0
Apps/Hotfix/Config/ConfigLoader.cs

@@ -12,6 +12,10 @@ namespace ET.Client
                 string key = Path.GetFileNameWithoutExtension(file);
                 output[key] = File.ReadAllBytes(file);
             }
+            output["StartMachineConfigCategory"] = File.ReadAllBytes($"../Config/{Game.Options.StartConfig}/StartMachineConfigCategory.bytes");
+            output["StartProcessConfigCategory"] = File.ReadAllBytes($"../Config/{Game.Options.StartConfig}/StartProcessConfigCategory.bytes");
+            output["StartSceneConfigCategory"] = File.ReadAllBytes($"../Config/{Game.Options.StartConfig}/StartSceneConfigCategory.bytes");
+            output["StartZoneConfigCategory"] = File.ReadAllBytes($"../Config/{Game.Options.StartConfig}/StartZoneConfigCategory.bytes");
         }
         
         public byte[] GetOneConfigBytes(string configName)

+ 13 - 2
Apps/Model/Generate/Config/AIConfig.cs

@@ -7,7 +7,7 @@ namespace ET
 {
     [ProtoContract]
     [Config]
-    public partial class AIConfigCategory : ProtoObject
+    public partial class AIConfigCategory : ProtoObject, IMerge
     {
         public static AIConfigCategory Instance;
 		
@@ -23,6 +23,12 @@ namespace ET
         {
             Instance = this;
         }
+        
+        public void Merge(object o)
+        {
+            AIConfigCategory s = o as AIConfigCategory;
+            this.list.AddRange(s.list);
+        }
 		
         public override void EndInit()
         {
@@ -69,15 +75,20 @@ namespace ET
     [ProtoContract]
 	public partial class AIConfig: ProtoObject, IConfig
 	{
+		/// <summary>Id</summary>
 		[ProtoMember(1)]
 		public int Id { get; set; }
+		/// <summary>所属ai</summary>
 		[ProtoMember(2)]
 		public int AIConfigId { get; set; }
+		/// <summary>此ai中的顺序</summary>
 		[ProtoMember(3)]
 		public int Order { get; set; }
+		/// <summary>节点名字</summary>
 		[ProtoMember(4)]
 		public string Name { get; set; }
-		[ProtoMember(6)]
+		/// <summary>节点参数</summary>
+		[ProtoMember(5)]
 		public int[] NodeParams { get; set; }
 
 	}

+ 11 - 1
Apps/Model/Generate/Config/StartMachineConfig.cs

@@ -7,7 +7,7 @@ namespace ET
 {
     [ProtoContract]
     [Config]
-    public partial class StartMachineConfigCategory : ProtoObject
+    public partial class StartMachineConfigCategory : ProtoObject, IMerge
     {
         public static StartMachineConfigCategory Instance;
 		
@@ -23,6 +23,12 @@ namespace ET
         {
             Instance = this;
         }
+        
+        public void Merge(object o)
+        {
+            StartMachineConfigCategory s = o as StartMachineConfigCategory;
+            this.list.AddRange(s.list);
+        }
 		
         public override void EndInit()
         {
@@ -69,12 +75,16 @@ namespace ET
     [ProtoContract]
 	public partial class StartMachineConfig: ProtoObject, IConfig
 	{
+		/// <summary>Id</summary>
 		[ProtoMember(1)]
 		public int Id { get; set; }
+		/// <summary>内网地址</summary>
 		[ProtoMember(2)]
 		public string InnerIP { get; set; }
+		/// <summary>外网地址</summary>
 		[ProtoMember(3)]
 		public string OuterIP { get; set; }
+		/// <summary>守护进程端口</summary>
 		[ProtoMember(4)]
 		public string WatcherPort { get; set; }
 

+ 10 - 1
Apps/Model/Generate/Config/StartProcessConfig.cs

@@ -7,7 +7,7 @@ namespace ET
 {
     [ProtoContract]
     [Config]
-    public partial class StartProcessConfigCategory : ProtoObject
+    public partial class StartProcessConfigCategory : ProtoObject, IMerge
     {
         public static StartProcessConfigCategory Instance;
 		
@@ -23,6 +23,12 @@ namespace ET
         {
             Instance = this;
         }
+        
+        public void Merge(object o)
+        {
+            StartProcessConfigCategory s = o as StartProcessConfigCategory;
+            this.list.AddRange(s.list);
+        }
 		
         public override void EndInit()
         {
@@ -69,10 +75,13 @@ namespace ET
     [ProtoContract]
 	public partial class StartProcessConfig: ProtoObject, IConfig
 	{
+		/// <summary>Id</summary>
 		[ProtoMember(1)]
 		public int Id { get; set; }
+		/// <summary>所属机器</summary>
 		[ProtoMember(2)]
 		public int MachineId { get; set; }
+		/// <summary>内网端口</summary>
 		[ProtoMember(3)]
 		public int InnerPort { get; set; }
 

+ 13 - 1
Apps/Model/Generate/Config/StartSceneConfig.cs

@@ -7,7 +7,7 @@ namespace ET
 {
     [ProtoContract]
     [Config]
-    public partial class StartSceneConfigCategory : ProtoObject
+    public partial class StartSceneConfigCategory : ProtoObject, IMerge
     {
         public static StartSceneConfigCategory Instance;
 		
@@ -23,6 +23,12 @@ namespace ET
         {
             Instance = this;
         }
+        
+        public void Merge(object o)
+        {
+            StartSceneConfigCategory s = o as StartSceneConfigCategory;
+            this.list.AddRange(s.list);
+        }
 		
         public override void EndInit()
         {
@@ -69,16 +75,22 @@ namespace ET
     [ProtoContract]
 	public partial class StartSceneConfig: ProtoObject, IConfig
 	{
+		/// <summary>Id</summary>
 		[ProtoMember(1)]
 		public int Id { get; set; }
+		/// <summary>所属进程</summary>
 		[ProtoMember(2)]
 		public int Process { get; set; }
+		/// <summary>所属区</summary>
 		[ProtoMember(3)]
 		public int Zone { get; set; }
+		/// <summary>类型</summary>
 		[ProtoMember(4)]
 		public string SceneType { get; set; }
+		/// <summary>名字</summary>
 		[ProtoMember(5)]
 		public string Name { get; set; }
+		/// <summary>外网端口</summary>
 		[ProtoMember(6)]
 		public int OuterPort { get; set; }
 

+ 10 - 1
Apps/Model/Generate/Config/StartZoneConfig.cs

@@ -7,7 +7,7 @@ namespace ET
 {
     [ProtoContract]
     [Config]
-    public partial class StartZoneConfigCategory : ProtoObject
+    public partial class StartZoneConfigCategory : ProtoObject, IMerge
     {
         public static StartZoneConfigCategory Instance;
 		
@@ -23,6 +23,12 @@ namespace ET
         {
             Instance = this;
         }
+        
+        public void Merge(object o)
+        {
+            StartZoneConfigCategory s = o as StartZoneConfigCategory;
+            this.list.AddRange(s.list);
+        }
 		
         public override void EndInit()
         {
@@ -69,10 +75,13 @@ namespace ET
     [ProtoContract]
 	public partial class StartZoneConfig: ProtoObject, IConfig
 	{
+		/// <summary>Id</summary>
 		[ProtoMember(1)]
 		public int Id { get; set; }
+		/// <summary>数据库地址</summary>
 		[ProtoMember(2)]
 		public string DBConnection { get; set; }
+		/// <summary>数据库名</summary>
 		[ProtoMember(3)]
 		public string DBName { get; set; }
 

+ 19 - 6
Apps/Model/Generate/Config/UnitConfig.cs

@@ -7,7 +7,7 @@ namespace ET
 {
     [ProtoContract]
     [Config]
-    public partial class UnitConfigCategory : ProtoObject
+    public partial class UnitConfigCategory : ProtoObject, IMerge
     {
         public static UnitConfigCategory Instance;
 		
@@ -23,6 +23,12 @@ namespace ET
         {
             Instance = this;
         }
+        
+        public void Merge(object o)
+        {
+            UnitConfigCategory s = o as UnitConfigCategory;
+            this.list.AddRange(s.list);
+        }
 		
         public override void EndInit()
         {
@@ -69,19 +75,26 @@ namespace ET
     [ProtoContract]
 	public partial class UnitConfig: ProtoObject, IConfig
 	{
+		/// <summary>Id</summary>
 		[ProtoMember(1)]
 		public int Id { get; set; }
+		/// <summary>Type</summary>
 		[ProtoMember(2)]
 		public int Type { get; set; }
-		[ProtoMember(4)]
+		/// <summary>名字</summary>
+		[ProtoMember(3)]
 		public string Name { get; set; }
-		[ProtoMember(5)]
+		/// <summary>描述</summary>
+		[ProtoMember(4)]
 		public string Desc { get; set; }
-		[ProtoMember(6)]
+		/// <summary>位置</summary>
+		[ProtoMember(5)]
 		public int Position { get; set; }
-		[ProtoMember(7)]
+		/// <summary>身高</summary>
+		[ProtoMember(6)]
 		public int Height { get; set; }
-		[ProtoMember(8)]
+		/// <summary>体重</summary>
+		[ProtoMember(7)]
 		public int Weight { get; set; }
 
 	}

+ 355 - 141
Apps/Tool/ExcelExporter/ExcelExporter.cs

@@ -4,10 +4,10 @@ using System.IO;
 using System.Linq;
 using System.Reflection;
 using System.Text;
+using System.Threading.Tasks;
 using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.CSharp;
 using Microsoft.CodeAnalysis.Emit;
-using MongoDB.Bson;
 using MongoDB.Bson.Serialization;
 using OfficeOpenXml;
 using ProtoBuf;
@@ -17,10 +17,10 @@ namespace ET
 {
     public enum ConfigType
     {
-        c,
-        s,
+        c = 0,
+        s = 1,
     }
-    
+
     class HeadInfo
     {
         public string FieldAttribute;
@@ -38,21 +38,58 @@ namespace ET
             this.FieldIndex = index;
         }
     }
+
+    // 这里加个标签是为了防止编译时裁剪掉protobuf,因为整个tool工程没有用到protobuf,编译会去掉引用,然后动态编译就会出错
+    [ProtoContract]
+    class Table
+    {
+        public bool C;
+        public bool S;
+        public int Index;
+        public Dictionary<string, HeadInfo> HeadInfos = new Dictionary<string, HeadInfo>();
+    }
     
     public static class ExcelExporter
     {
         private static string template;
 
-        private const string clientClassDir = "../Unity/Codes/Model/Generate/Config";
-        private const string serverClassDir = "../Apps/Model/Generate/Config";
-        
+        public const string ClientClassDir = "../Unity/Codes/Model/Generate/Config";
+        public const string ServerClassDir = "../Apps/Model/Generate/Config";
+
         private const string excelDir = "../Excel";
-        
-        private const string jsonDir = "./Json/{0}";
-        
-        private const string clientProtoDir = "../Unity/Assets/Bundles/Config";
-        private const string serverProtoDir = "../Config";
-        
+
+        private const string jsonDir = "../Excel/Json/{0}/{1}";
+
+        private const string clientProtoDir = "../Unity/Assets/Bundles/Config/{0}";
+        private const string serverProtoDir = "../Config/{0}";
+        private static Assembly[] configAssemblies = new Assembly[2];
+
+        private static Dictionary<string, Table> tables = new Dictionary<string, Table>();
+        private static Dictionary<string, ExcelPackage> packages = new Dictionary<string, ExcelPackage>();
+
+        private static Table GetTable(string protoName)
+        {
+            if (!tables.TryGetValue(protoName, out var table))
+            {
+                table = new Table();
+                tables[protoName] = table;
+            }
+
+            return table;
+        }
+
+        public static ExcelPackage GetPackage(string filePath)
+        {
+            if (!packages.TryGetValue(filePath, out var package))
+            {
+                using Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+                package = new ExcelPackage(stream);
+                packages[filePath] = package;
+            }
+
+            return package;
+        }
+
         public static void Export()
         {
             try
@@ -60,91 +97,268 @@ namespace ET
                 template = File.ReadAllText("Template.txt");
                 ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
 
-                if (Directory.Exists(clientClassDir))
+                if (Directory.Exists(ClientClassDir))
                 {
-                    Directory.Delete(clientClassDir, true);
+                    Directory.Delete(ClientClassDir, true);
                 }
 
-                if (Directory.Exists(serverClassDir))
+                if (Directory.Exists(ServerClassDir))
                 {
-                    Directory.Delete(serverClassDir, true);
+                    Directory.Delete(ServerClassDir, true);
                 }
 
                 foreach (string path in Directory.GetFiles(excelDir))
                 {
                     string fileName = Path.GetFileName(path);
-                    if (!fileName.EndsWith(".xlsx") || fileName.StartsWith("~$"))
+                    if (!fileName.EndsWith(".xlsx") || fileName.StartsWith("~$") || fileName.Contains("#"))
                     {
                         continue;
                     }
-                    using Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
-                    using ExcelPackage p = new ExcelPackage(stream);
-                    string name = Path.GetFileNameWithoutExtension(path);
 
-                    string cs = p.Workbook.Worksheets[0].Cells[1, 1].Text.Trim();
-                    if (cs.Contains("#"))
+                    string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
+                    string fileNameWithoutCS = fileNameWithoutExtension;
+                    string cs = "cs";
+                    if (fileNameWithoutExtension.Contains("@"))
                     {
-                        continue;
+                        string[] ss = fileNameWithoutExtension.Split("@");
+                        fileNameWithoutCS = ss[0];
+                        cs = ss[1];
                     }
+
                     if (cs == "")
                     {
                         cs = "cs";
                     }
+
+                    ExcelPackage p = GetPackage(Path.GetFullPath(path));
+
+                    string protoName = fileNameWithoutCS;
+                    if (fileNameWithoutCS.Contains('_'))
+                    {
+                        protoName = fileNameWithoutCS.Substring(0, fileNameWithoutCS.LastIndexOf('_'));
+                    }
+
+                    Table table = GetTable(protoName);
+
                     if (cs.Contains("c"))
                     {
-                        ExportExcelClass(p, name, ConfigType.c);    
+                        table.C = true;
                     }
+
                     if (cs.Contains("s"))
                     {
-                        ExportExcelClass(p, name, ConfigType.s);    
+                        table.S = true;
+                    }
+
+                    ExportExcelClass(p, protoName, table);
+                }
+
+                foreach (var kv in tables)
+                {
+                    if (kv.Value.C)
+                    {
+                        ExportClass(kv.Key, kv.Value.HeadInfos, ConfigType.c);
+                    }
+
+                    if (kv.Value.S)
+                    {
+                        ExportClass(kv.Key, kv.Value.HeadInfos, ConfigType.s);
                     }
                 }
-            
-                ExportExcelProtobuf(ConfigType.c);
-                ExportExcelProtobuf(ConfigType.s);
+
+                // 动态编译生成的配置代码
+                configAssemblies[(int) ConfigType.c] = DynamicBuild(ConfigType.c);
+                configAssemblies[(int) ConfigType.s] = DynamicBuild(ConfigType.s);
+
+                foreach (string path in Directory.GetFiles(excelDir))
+                {
+                    ExportExcel(path);
+                }
                 
+                // 多线程导出
+                //List<Task> tasks = new List<Task>();
+                //foreach (string path in Directory.GetFiles(excelDir))
+                //{
+                //    Task task = Task.Run(() => ExportExcel(path));
+                //    tasks.Add(task);
+                //}
+                //Task.WaitAll(tasks.ToArray());
+
+                // 导出StartConfig
+                string startConfigPath = Path.Combine(excelDir, "StartConfig");
+                DirectoryInfo directoryInfo = new DirectoryInfo(startConfigPath);
+                foreach (FileInfo subStartConfig in directoryInfo.GetFiles("*", SearchOption.AllDirectories))
+                {
+                    ExportExcel(subStartConfig.FullName);
+                }
+
                 Log.Console("Export Excel Sucess!");
             }
             catch (Exception e)
             {
                 Log.Console(e.ToString());
             }
+            finally
+            {
+                tables.Clear();
+                foreach (var kv in packages)
+                {
+                    kv.Value.Dispose();
+                }
+
+                packages.Clear();
+            }
         }
 
-        private static string GetProtoDir(ConfigType configType)
+        private static void ExportExcel(string path)
+        {
+            string dir = Path.GetDirectoryName(path);
+            string relativePath = Path.GetRelativePath(excelDir, dir);
+            string fileName = Path.GetFileName(path);
+            if (!fileName.EndsWith(".xlsx") || fileName.StartsWith("~$") || fileName.Contains("#"))
+            {
+                return;
+            }
+
+            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
+            string fileNameWithoutCS = fileNameWithoutExtension;
+            string cs = "cs";
+            if (fileNameWithoutExtension.Contains("@"))
+            {
+                string[] ss = fileNameWithoutExtension.Split("@");
+                fileNameWithoutCS = ss[0];
+                cs = ss[1];
+            }
+
+            if (cs == "")
+            {
+                cs = "cs";
+            }
+
+            string protoName = fileNameWithoutCS;
+            if (fileNameWithoutCS.Contains('_'))
+            {
+                protoName = fileNameWithoutCS.Substring(0, fileNameWithoutCS.LastIndexOf('_'));
+            }
+
+            Table table = GetTable(protoName);
+
+            ExcelPackage p = GetPackage(Path.GetFullPath(path));
+
+            if (cs.Contains("c"))
+            {
+                ExportExcelJson(p, fileNameWithoutCS, table, ConfigType.c, relativePath);
+                ExportExcelProtobuf(ConfigType.c, protoName, relativePath);
+            }
+
+            if (cs.Contains("s"))
+            {
+                ExportExcelJson(p, fileNameWithoutCS, table, ConfigType.s, relativePath);
+                ExportExcelProtobuf(ConfigType.s, protoName, relativePath);
+            }
+        }
+
+        private static string GetProtoDir(ConfigType configType, string relativeDir)
         {
             if (configType == ConfigType.c)
             {
-                return clientProtoDir;
+                return string.Format(clientProtoDir, relativeDir);
             }
-            return serverProtoDir;
+
+            return string.Format(serverProtoDir, relativeDir);
         }
-        
+
+        private static Assembly GetAssembly(ConfigType configType)
+        {
+            return configAssemblies[(int) configType];
+        }
+
         private static string GetClassDir(ConfigType configType)
         {
             if (configType == ConfigType.c)
             {
-                return clientClassDir;
+                return ClientClassDir;
             }
-            return serverClassDir;
+
+            return ServerClassDir;
         }
         
-        
-#region 导出class
-        static void ExportExcelClass(ExcelPackage p, string name, ConfigType configType)
+        // 动态编译生成的cs代码
+        private static Assembly DynamicBuild(ConfigType configType)
+        {
+            string classPath = GetClassDir(configType);
+            List<SyntaxTree> syntaxTrees = new List<SyntaxTree>();
+            List<string> protoNames = new List<string>();
+            foreach (string classFile in Directory.GetFiles(classPath, "*.cs"))
+            {
+                protoNames.Add(Path.GetFileNameWithoutExtension(classFile));
+                syntaxTrees.Add(CSharpSyntaxTree.ParseText(File.ReadAllText(classFile)));
+            }
+
+            List<PortableExecutableReference> references = new List<PortableExecutableReference>();
+            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
+            foreach (Assembly assembly in assemblies)
+            {
+                try
+                {
+                    if (assembly.IsDynamic)
+                    {
+                        continue;
+                    }
+
+                    if (assembly.Location == "")
+                    {
+                        continue;
+                    }
+                }
+                catch (Exception e)
+                {
+                    Console.WriteLine(e);
+                    throw;
+                }
+
+                PortableExecutableReference reference = MetadataReference.CreateFromFile(assembly.Location);
+                references.Add(reference);
+            }
+
+            CSharpCompilation compilation = CSharpCompilation.Create(null,
+                syntaxTrees.ToArray(),
+                references.ToArray(),
+                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
+
+            using MemoryStream memSteam = new MemoryStream();
+
+            EmitResult emitResult = compilation.Emit(memSteam);
+            if (!emitResult.Success)
+            {
+                StringBuilder stringBuilder = new StringBuilder();
+                foreach (Diagnostic t in emitResult.Diagnostics)
+                {
+                    stringBuilder.AppendLine(t.GetMessage());
+                }
+
+                throw new Exception($"动态编译失败:\n{stringBuilder}");
+            }
+
+            memSteam.Seek(0, SeekOrigin.Begin);
+
+            Assembly ass = Assembly.Load(memSteam.ToArray());
+            return ass;
+        }
+
+
+        #region 导出class
+
+        static void ExportExcelClass(ExcelPackage p, string name, Table table)
         {
-            Dictionary<string, HeadInfo> classField = new Dictionary<string, HeadInfo>();
             foreach (ExcelWorksheet worksheet in p.Workbook.Worksheets)
             {
-                ExportSheetClass(worksheet, classField, configType);
+                ExportSheetClass(worksheet, table);
             }
-            ExportClass(name, classField, configType);
-            ExportExcelJson(p, name, classField, configType);
         }
-        
-        static void ExportSheetClass(ExcelWorksheet worksheet, Dictionary<string, HeadInfo> classField, ConfigType configType)
+
+        static void ExportSheetClass(ExcelWorksheet worksheet, Table table)
         {
-            string configTypeStr = configType.ToString();
             const int row = 2;
             for (int col = 3; col <= worksheet.Dimension.End.Column; ++col)
             {
@@ -152,22 +366,22 @@ namespace ET
                 {
                     continue;
                 }
-                
+
                 string fieldName = worksheet.Cells[row + 2, col].Text.Trim();
                 if (fieldName == "")
                 {
                     continue;
                 }
 
-                if (classField.ContainsKey(fieldName))
+                if (table.HeadInfos.ContainsKey(fieldName))
                 {
                     continue;
                 }
-                
+
                 string fieldCS = worksheet.Cells[row, col].Text.Trim().ToLower();
                 if (fieldCS.Contains("#"))
                 {
-                    classField[fieldName] = null;
+                    table.HeadInfos[fieldName] = null;
                     continue;
                 }
 
@@ -176,16 +390,20 @@ namespace ET
                     fieldCS = "cs";
                 }
 
-                if (!fieldCS.Contains(configTypeStr))
+                if (table.HeadInfos.TryGetValue(fieldName, out var oldClassField))
                 {
-                    classField[fieldName] = null;
+                    if (oldClassField.FieldAttribute != fieldCS)
+                    {
+                        Log.Console($"field cs not same: {worksheet.Name} {fieldName} oldcs: {oldClassField.FieldAttribute} {fieldCS}");
+                    }
+
                     continue;
                 }
-                
+
                 string fieldDesc = worksheet.Cells[row + 1, col].Text.Trim();
                 string fieldType = worksheet.Cells[row + 3, col].Text.Trim();
 
-                classField[fieldName] = new HeadInfo(fieldCS, fieldDesc, fieldName, fieldType, col);
+                table.HeadInfos[fieldName] = new HeadInfo(fieldCS, fieldDesc, fieldName, fieldType, ++table.Index);
             }
         }
 
@@ -196,11 +414,12 @@ namespace ET
             {
                 Directory.CreateDirectory(dir);
             }
+
             string exportPath = Path.Combine(dir, $"{protoName}.cs");
-            
+
             using FileStream txt = new FileStream(exportPath, FileMode.Create);
             using StreamWriter sw = new StreamWriter(txt);
-            
+
             StringBuilder sb = new StringBuilder();
             foreach ((string _, HeadInfo headInfo) in classField)
             {
@@ -208,16 +427,38 @@ namespace ET
                 {
                     continue;
                 }
-                sb.Append($"\t\t[ProtoMember({headInfo.FieldIndex - 2})]\n");
-                sb.Append($"\t\tpublic {headInfo.FieldType} {headInfo.FieldName} {{ get; set; }}\n");
+
+                if (headInfo.FieldType == "json")
+                {
+                    continue;
+                }
+
+                if (!headInfo.FieldAttribute.Contains(configType.ToString()))
+                {
+                    continue;
+                }
+
+                sb.Append($"\t\t/// <summary>{headInfo.FieldDesc}</summary>\n");
+                sb.Append($"\t\t[ProtoMember({headInfo.FieldIndex})]\n");
+                string fieldType = headInfo.FieldType;
+                if (fieldType == "int[][]")
+                {
+                    fieldType = "string[]";
+                }
+
+                sb.Append($"\t\tpublic {fieldType} {headInfo.FieldName} {{ get; set; }}\n");
             }
+
             string content = template.Replace("(ConfigName)", protoName).Replace(("(Fields)"), sb.ToString());
             sw.Write(content);
         }
-#endregion
 
-#region 导出json
-        static void ExportExcelJson(ExcelPackage p, string name, Dictionary<string, HeadInfo> classField, ConfigType configType)
+        #endregion
+
+        #region 导出json
+
+
+        static void ExportExcelJson(ExcelPackage p, string name, Table table, ConfigType configType, string relativeDir)
         {
             StringBuilder sb = new StringBuilder();
             sb.AppendLine("{\"list\":[");
@@ -227,23 +468,26 @@ namespace ET
                 {
                     continue;
                 }
-                ExportSheetJson(worksheet, name, classField, configType, sb);
+
+                ExportSheetJson(worksheet, name, table.HeadInfos, configType, sb);
             }
+
             sb.AppendLine("]}");
-            
-            string dir = string.Format(jsonDir, configType.ToString());
+
+            string dir = string.Format(jsonDir, configType.ToString(), relativeDir);
             if (!Directory.Exists(dir))
             {
                 Directory.CreateDirectory(dir);
             }
-            
+
             string jsonPath = Path.Combine(dir, $"{name}.txt");
             using FileStream txt = new FileStream(jsonPath, FileMode.Create);
             using StreamWriter sw = new StreamWriter(txt);
             sw.Write(sb.ToString());
         }
-        
-        static void ExportSheetJson(ExcelWorksheet worksheet, string name, Dictionary<string, HeadInfo> classField, ConfigType configType, StringBuilder sb)
+
+        static void ExportSheetJson(ExcelWorksheet worksheet, string name, 
+                Dictionary<string, HeadInfo> classField, ConfigType configType, StringBuilder sb)
         {
             string configTypeStr = configType.ToString();
             for (int row = 6; row <= worksheet.Dimension.End.Row; ++row)
@@ -263,11 +507,12 @@ namespace ET
                 {
                     continue;
                 }
-                
+
                 if (worksheet.Cells[row, 3].Text.Trim() == "")
                 {
                     continue;
                 }
+
                 sb.Append("{");
                 sb.Append($"\"_t\":\"{name}\"");
                 for (int col = 3; col <= worksheet.Dimension.End.Column; ++col)
@@ -284,29 +529,39 @@ namespace ET
                     {
                         continue;
                     }
-                    
+
+                    if (headInfo.FieldType == "json")
+                    {
+                        continue;
+                    }
+
                     string fieldN = headInfo.FieldName;
                     if (fieldN == "Id")
                     {
                         fieldN = "_id";
                     }
+
                     sb.Append($",\"{fieldN}\":{Convert(headInfo.FieldType, worksheet.Cells[row, col].Text.Trim())}");
                 }
+
                 sb.Append("},\n");
             }
         }
-        
+
         private static string Convert(string type, string value)
         {
             switch (type)
             {
+                case "uint[]":
                 case "int[]":
                 case "int32[]":
                 case "long[]":
                     return $"[{value}]";
                 case "string[]":
+                case "int[][]":
                     return $"[{value}]";
                 case "int":
+                case "uint":
                 case "int32":
                 case "int64":
                 case "long":
@@ -316,98 +571,57 @@ namespace ET
                     {
                         return "0";
                     }
+
                     return value;
                 case "string":
                     return $"\"{value}\"";
+                case "AttrConfig":
+                    string[] ss = value.Split(':');
+                    return "{\"_t\":\"AttrConfig\"," + "\"Ks\":" + ss[0] + ",\"Vs\":" + ss[1] + "}";
                 default:
                     throw new Exception($"不支持此类型: {type}");
             }
         }
-#endregion
 
-        // 根据生成的类,动态编译把json转成protobuf
-        private static void ExportExcelProtobuf(ConfigType configType)
+        #endregion
+
+
+        // 根据生成的类,把json转成protobuf
+        private static void ExportExcelProtobuf(ConfigType configType, string protoName, string relativeDir)
         {
-            string classPath = GetClassDir(configType);
-            List<SyntaxTree> syntaxTrees = new List<SyntaxTree>();
-            List<string> protoNames = new List<string>();
-            foreach (string classFile in Directory.GetFiles(classPath, "*.cs"))
+            string dir = GetProtoDir(configType, relativeDir);
+            if (!Directory.Exists(dir))
             {
-                protoNames.Add(Path.GetFileNameWithoutExtension(classFile));
-                syntaxTrees.Add(CSharpSyntaxTree.ParseText(File.ReadAllText(classFile)));
+                Directory.CreateDirectory(dir);
             }
-            
-            List<PortableExecutableReference> references = new List<PortableExecutableReference>();
-            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
-            foreach (Assembly assembly in assemblies)
-            {
-                try
-                {
-                    if (assembly.IsDynamic)
-                    {
-                        continue;
-                    }
 
-                    if (assembly.Location == "")
-                    {
-                        continue;
-                    }
-                }
-                catch (Exception e)
-                {
-                    Console.WriteLine(e);
-                    throw;
-                }
+            Assembly ass = GetAssembly(configType);
+            Type type = ass.GetType($"ET.{protoName}Category");
+            Type subType = ass.GetType($"ET.{protoName}");
 
-                PortableExecutableReference reference = MetadataReference.CreateFromFile(assembly.Location);
-                references.Add(reference);
-            }
+            Serializer.NonGeneric.PrepareSerializer(type);
+            Serializer.NonGeneric.PrepareSerializer(subType);
 
-            CSharpCompilation compilation = CSharpCompilation.Create(
-                null, 
-                syntaxTrees.ToArray(), 
-                references.ToArray(), 
-                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
+            IMerge final = Activator.CreateInstance(type) as IMerge;
 
-            using MemoryStream memSteam = new MemoryStream();
-            
-            EmitResult emitResult = compilation.Emit(memSteam);
-            if (!emitResult.Success)
-            {
-                StringBuilder stringBuilder = new StringBuilder();
-                foreach (Diagnostic t in emitResult.Diagnostics)
-                {
-                    stringBuilder.AppendLine(t.GetMessage());
-                }
-                throw new Exception($"动态编译失败:\n{stringBuilder}");
-            }
-            
-            memSteam.Seek(0, SeekOrigin.Begin);
-
-            Assembly ass = Assembly.Load(memSteam.ToArray());
+            string p = Path.Combine(string.Format(jsonDir, configType, relativeDir));
+            string[] ss = Directory.GetFiles(p, $"{protoName}_*.txt");
+            List<string> jsonPaths = ss.ToList();
+            jsonPaths.Add(Path.Combine(string.Format(jsonDir, configType, relativeDir), $"{protoName}.txt"));
 
-            string dir = GetProtoDir(configType);
-            if (!Directory.Exists(dir))
+            jsonPaths.Sort();
+            jsonPaths.Reverse();
+            foreach (string jsonPath in jsonPaths)
             {
-                Directory.CreateDirectory(dir);
-            }
-            
-            foreach (string protoName in protoNames)
-            {
-                Type type = ass.GetType($"ET.{protoName}Category");
-                Type subType = ass.GetType($"ET.{protoName}");
-                Serializer.NonGeneric.PrepareSerializer(type);
-                Serializer.NonGeneric.PrepareSerializer(subType);
-                
-                
-                string json = File.ReadAllText(Path.Combine(string.Format(jsonDir, configType), $"{protoName}.txt"));
+                string json = File.ReadAllText(jsonPath);
                 object deserialize = BsonSerializer.Deserialize(json, type);
+                final.Merge(deserialize);
+            }
 
-                string path = Path.Combine(dir, $"{protoName}Category.bytes");
+            string path = Path.Combine(dir, $"{protoName}Category.bytes");
 
-                using FileStream file = File.Create(path);
-                Serializer.Serialize(file, deserialize);
-            }
+            using FileStream file = File.Create(path);
+            Serializer.Serialize(file, final);
         }
     }
 }

+ 7 - 1
Apps/Tool/Template.txt

@@ -7,7 +7,7 @@ namespace ET
 {
     [ProtoContract]
     [Config]
-    public partial class (ConfigName)Category : ProtoObject
+    public partial class (ConfigName)Category : ProtoObject, IMerge
     {
         public static (ConfigName)Category Instance;
 		
@@ -23,6 +23,12 @@ namespace ET
         {
             Instance = this;
         }
+        
+        public void Merge(object o)
+        {
+            (ConfigName)Category s = o as (ConfigName)Category;
+            this.list.AddRange(s.list);
+        }
 		
         public override void EndInit()
         {

+ 5 - 6
Book/1.1RunGuide.md

@@ -27,15 +27,14 @@
    copy the Unity libraries it depends on into Unity/Temp/Debug. Unity.ModelView UnityHotfix.View will all depend on the libraries 
    under Unity/Temp/Debug. If you still burst red, close vs or rider, open unity first, then Client-Server.sln, then Compile Client-Server  
 
-Translated with www.DeepL.com/Translator (free version)
+8. export table tools, compile the command line then Unity menu: Tools->ExcelExporter  
 
-1. export table tools, compile the command line into the Bin directory after completion, execute dotnet Tools.dll --AppType=ExcelExporter  
+9. export protocol tool, compile  then Unity menu: Tools->Proto2CS  
 
-2. export protocol tool, compile and enter Bin directory, execute dotnet Tools.dll --AppType=Proto2CS  
+10. start server: dotnet App.dll --Process=1 --Console=1 --StartConfig=StartConfig/Release  
+    windows can use unity menu (tools->servertools) start server app  
 
-3.  start server: dotnet Server.dll --Process=1 --Console=1  
-
-4.  Double-click the Init scene in the Scenes directory in Unity and click Play to run it.
+11.  Double-click the Init scene in the Scenes directory in Unity and click Play to run it.
 
 # Test state synchronization demo
 1. If you want to modify the configuration, go to the Excel directory and modify the corresponding table, do step 6 of the running steps, and then re-run the Server.App project to start the server.

+ 4 - 3
Book/1.1运行指南.md

@@ -27,11 +27,12 @@
    Unity.ModelView UnityHotfix.View都会依赖Unity/Temp/Debug下的库。如果还是爆红,关闭vs或者rider,先打开unity,再打开Client-Server.sln,再
    编译Client-Server   
 
-8.  导表工具,编译完成后命令行进入 Bin 目录,执行 dotnet Tools.dll --AppType=ExcelExporter  
+8.  导表工具,编译完成后Unity菜单 Tools->ExcelExporter  
 
-9.  导出协议工具,编译完成后进入 Bin 目录,执行 dotnet Tools.dll --AppType=Proto2CS  
+9.  导出协议工具,编译完成后Unity菜单 Tools->Proto2CS  
 
-10. 启动服务器: dotnet Server.dll --Process=1 --Console=1
+10. 启动服务器: dotnet App.dll --Process=1 --Console=1 --StartConfig=StartConfig/Release  
+    windows可以从Unity菜单Tools->ServerTools启动  
 
 11.  Unity中双击Scenes目录中的Init场景,点击Play即可运行
 

+ 0 - 0
Unity/Assets/Bundles/Config/StartMachineConfigCategory.bytes → Config/StartConfig/Localhost/StartMachineConfigCategory.bytes


+ 0 - 0
Unity/Assets/Bundles/Config/StartProcessConfigCategory.bytes → Config/StartConfig/Localhost/StartProcessConfigCategory.bytes


+ 0 - 0
Unity/Assets/Bundles/Config/StartSceneConfigCategory.bytes → Config/StartConfig/Localhost/StartSceneConfigCategory.bytes


+ 0 - 0
Unity/Assets/Bundles/Config/StartZoneConfigCategory.bytes → Config/StartConfig/Localhost/StartZoneConfigCategory.bytes


+ 2 - 0
Config/StartConfig/Release/StartMachineConfigCategory.bytes

@@ -0,0 +1,2 @@
+
+'
192.168.1.111
192.168.1.111"10000

+ 3 - 0
Config/StartConfig/Release/StartProcessConfigCategory.bytes

@@ -0,0 +1,3 @@
+
+�
+�

+ 8 - 0
Config/StartConfig/Release/StartSceneConfigCategory.bytes

@@ -0,0 +1,8 @@
+
+"Realm*Realm0’N
+"Gate*Gate10“N
+"Gate*Gate20”N
+"Location*Location
+"Map*Map1
+"Map*Map2
+È"Robot*Robot01

+ 3 - 0
Config/StartConfig/Release/StartZoneConfigCategory.bytes

@@ -0,0 +1,3 @@
+
+mongodb://127.0.0.1ET1
+mongodb://127.0.0.1ET2

+ 1 - 1
Config/UnitConfigCategory.bytes

@@ -1,2 +1,2 @@
 
-1é"	米克尔*带有强力攻击技能08²@D
+1é	米克尔"带有强力攻击技能(0²8D

+ 5 - 0
Excel/Json/c/AIConfig.txt

@@ -0,0 +1,5 @@
+{"list":[
+{"_t":"AIConfig","_id":101,"AIConfigId":1,"Order":1,"Name":"AI_Attack","NodeParams":[]},
+{"_t":"AIConfig","_id":102,"AIConfigId":1,"Order":2,"Name":"AI_XunLuo","NodeParams":[]},
+{"_t":"AIConfig","_id":201,"AIConfigId":2,"Order":1,"Name":"AI_XunLuo","NodeParams":[]},
+]}

+ 3 - 0
Excel/Json/c/StartConfig/Localhost/StartMachineConfig.txt

@@ -0,0 +1,3 @@
+{"list":[
+{"_t":"StartMachineConfig","_id":1,"InnerIP":"127.0.0.1","OuterIP":"127.0.0.1","WatcherPort":"10000"},
+]}

+ 4 - 0
Excel/Json/c/StartConfig/Localhost/StartProcessConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartProcessConfig","_id":1,"MachineId":1,"InnerPort":20001},
+{"_t":"StartProcessConfig","_id":2,"MachineId":1,"InnerPort":20002},
+]}

+ 9 - 0
Excel/Json/c/StartConfig/Localhost/StartSceneConfig.txt

@@ -0,0 +1,9 @@
+{"list":[
+{"_t":"StartSceneConfig","_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002},
+{"_t":"StartSceneConfig","_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003},
+{"_t":"StartSceneConfig","_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004},
+{"_t":"StartSceneConfig","_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location","OuterPort":0},
+{"_t":"StartSceneConfig","_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map1","OuterPort":0},
+{"_t":"StartSceneConfig","_id":6,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map2","OuterPort":0},
+{"_t":"StartSceneConfig","_id":200,"Process":1,"Zone":2,"SceneType":"Robot","Name":"Robot01","OuterPort":0},
+]}

+ 4 - 0
Excel/Json/c/StartConfig/Localhost/StartZoneConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartZoneConfig","_id":1,"DBConnection":"mongodb://127.0.0.1","DBName":"ET1"},
+{"_t":"StartZoneConfig","_id":2,"DBConnection":"mongodb://127.0.0.1","DBName":"ET2"},
+]}

+ 3 - 0
Excel/Json/c/StartConfig/Release/StartMachineConfig.txt

@@ -0,0 +1,3 @@
+{"list":[
+{"_t":"StartMachineConfig","_id":1,"InnerIP":"192.168.1.111","OuterIP":"192.168.1.111","WatcherPort":"10000"},
+]}

+ 4 - 0
Excel/Json/c/StartConfig/Release/StartProcessConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartProcessConfig","_id":1,"MachineId":1,"InnerPort":20001},
+{"_t":"StartProcessConfig","_id":2,"MachineId":1,"InnerPort":20002},
+]}

+ 9 - 0
Excel/Json/c/StartConfig/Release/StartSceneConfig.txt

@@ -0,0 +1,9 @@
+{"list":[
+{"_t":"StartSceneConfig","_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002},
+{"_t":"StartSceneConfig","_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003},
+{"_t":"StartSceneConfig","_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004},
+{"_t":"StartSceneConfig","_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location","OuterPort":0},
+{"_t":"StartSceneConfig","_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map1","OuterPort":0},
+{"_t":"StartSceneConfig","_id":6,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map2","OuterPort":0},
+{"_t":"StartSceneConfig","_id":200,"Process":1,"Zone":2,"SceneType":"Robot","Name":"Robot01","OuterPort":0},
+]}

+ 4 - 0
Excel/Json/c/StartConfig/Release/StartZoneConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartZoneConfig","_id":1,"DBConnection":"mongodb://127.0.0.1","DBName":"ET1"},
+{"_t":"StartZoneConfig","_id":2,"DBConnection":"mongodb://127.0.0.1","DBName":"ET2"},
+]}

+ 3 - 0
Excel/Json/c/StartMachineConfig.txt

@@ -0,0 +1,3 @@
+{"list":[
+{"_t":"StartMachineConfig","_id":1,"InnerIP":"127.0.0.1","OuterIP":"127.0.0.1","WatcherPort":"10000"},
+]}

+ 4 - 0
Excel/Json/c/StartProcessConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartProcessConfig","_id":1,"MachineId":1,"InnerPort":20001},
+{"_t":"StartProcessConfig","_id":2,"MachineId":1,"InnerPort":20002},
+]}

+ 9 - 0
Excel/Json/c/StartSceneConfig.txt

@@ -0,0 +1,9 @@
+{"list":[
+{"_t":"StartSceneConfig","_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002},
+{"_t":"StartSceneConfig","_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003},
+{"_t":"StartSceneConfig","_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004},
+{"_t":"StartSceneConfig","_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location","OuterPort":0},
+{"_t":"StartSceneConfig","_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map1","OuterPort":0},
+{"_t":"StartSceneConfig","_id":6,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map2","OuterPort":0},
+{"_t":"StartSceneConfig","_id":200,"Process":1,"Zone":2,"SceneType":"Robot","Name":"Robot01","OuterPort":0},
+]}

+ 4 - 0
Excel/Json/c/StartZoneConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartZoneConfig","_id":1,"DBConnection":"mongodb://127.0.0.1","DBName":"ET1"},
+{"_t":"StartZoneConfig","_id":2,"DBConnection":"mongodb://127.0.0.1","DBName":"ET2"},
+]}

+ 3 - 0
Excel/Json/c/UnitConfig.txt

@@ -0,0 +1,3 @@
+{"list":[
+{"_t":"UnitConfig","_id":1001,"Type":1,"Name":"米克尔","Desc":"带有强力攻击技能","Position":1,"Height":178,"Weight":68},
+]}

+ 5 - 0
Excel/Json/s/AIConfig.txt

@@ -0,0 +1,5 @@
+{"list":[
+{"_t":"AIConfig","_id":101,"AIConfigId":1,"Order":1,"Name":"AI_Attack","NodeParams":[]},
+{"_t":"AIConfig","_id":102,"AIConfigId":1,"Order":2,"Name":"AI_XunLuo","NodeParams":[]},
+{"_t":"AIConfig","_id":201,"AIConfigId":2,"Order":1,"Name":"AI_XunLuo","NodeParams":[]},
+]}

+ 3 - 0
Excel/Json/s/StartConfig/Localhost/StartMachineConfig.txt

@@ -0,0 +1,3 @@
+{"list":[
+{"_t":"StartMachineConfig","_id":1,"InnerIP":"127.0.0.1","OuterIP":"127.0.0.1","WatcherPort":"10000"},
+]}

+ 4 - 0
Excel/Json/s/StartConfig/Localhost/StartProcessConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartProcessConfig","_id":1,"MachineId":1,"InnerPort":20001},
+{"_t":"StartProcessConfig","_id":2,"MachineId":1,"InnerPort":20002},
+]}

+ 9 - 0
Excel/Json/s/StartConfig/Localhost/StartSceneConfig.txt

@@ -0,0 +1,9 @@
+{"list":[
+{"_t":"StartSceneConfig","_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002},
+{"_t":"StartSceneConfig","_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003},
+{"_t":"StartSceneConfig","_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004},
+{"_t":"StartSceneConfig","_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location","OuterPort":0},
+{"_t":"StartSceneConfig","_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map1","OuterPort":0},
+{"_t":"StartSceneConfig","_id":6,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map2","OuterPort":0},
+{"_t":"StartSceneConfig","_id":200,"Process":1,"Zone":2,"SceneType":"Robot","Name":"Robot01","OuterPort":0},
+]}

+ 4 - 0
Excel/Json/s/StartConfig/Localhost/StartZoneConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartZoneConfig","_id":1,"DBConnection":"mongodb://127.0.0.1","DBName":"ET1"},
+{"_t":"StartZoneConfig","_id":2,"DBConnection":"mongodb://127.0.0.1","DBName":"ET2"},
+]}

+ 3 - 0
Excel/Json/s/StartConfig/Release/StartMachineConfig.txt

@@ -0,0 +1,3 @@
+{"list":[
+{"_t":"StartMachineConfig","_id":1,"InnerIP":"192.168.1.111","OuterIP":"192.168.1.111","WatcherPort":"10000"},
+]}

+ 4 - 0
Excel/Json/s/StartConfig/Release/StartProcessConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartProcessConfig","_id":1,"MachineId":1,"InnerPort":20001},
+{"_t":"StartProcessConfig","_id":2,"MachineId":1,"InnerPort":20002},
+]}

+ 9 - 0
Excel/Json/s/StartConfig/Release/StartSceneConfig.txt

@@ -0,0 +1,9 @@
+{"list":[
+{"_t":"StartSceneConfig","_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002},
+{"_t":"StartSceneConfig","_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003},
+{"_t":"StartSceneConfig","_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004},
+{"_t":"StartSceneConfig","_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location","OuterPort":0},
+{"_t":"StartSceneConfig","_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map1","OuterPort":0},
+{"_t":"StartSceneConfig","_id":6,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map2","OuterPort":0},
+{"_t":"StartSceneConfig","_id":200,"Process":1,"Zone":2,"SceneType":"Robot","Name":"Robot01","OuterPort":0},
+]}

+ 4 - 0
Excel/Json/s/StartConfig/Release/StartZoneConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartZoneConfig","_id":1,"DBConnection":"mongodb://127.0.0.1","DBName":"ET1"},
+{"_t":"StartZoneConfig","_id":2,"DBConnection":"mongodb://127.0.0.1","DBName":"ET2"},
+]}

+ 3 - 0
Excel/Json/s/StartMachineConfig.txt

@@ -0,0 +1,3 @@
+{"list":[
+{"_t":"StartMachineConfig","_id":1,"InnerIP":"127.0.0.1","OuterIP":"127.0.0.1","WatcherPort":"10000"},
+]}

+ 4 - 0
Excel/Json/s/StartProcessConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartProcessConfig","_id":1,"MachineId":1,"InnerPort":20001},
+{"_t":"StartProcessConfig","_id":2,"MachineId":1,"InnerPort":20002},
+]}

+ 9 - 0
Excel/Json/s/StartSceneConfig.txt

@@ -0,0 +1,9 @@
+{"list":[
+{"_t":"StartSceneConfig","_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002},
+{"_t":"StartSceneConfig","_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003},
+{"_t":"StartSceneConfig","_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004},
+{"_t":"StartSceneConfig","_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location","OuterPort":0},
+{"_t":"StartSceneConfig","_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map1","OuterPort":0},
+{"_t":"StartSceneConfig","_id":6,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map2","OuterPort":0},
+{"_t":"StartSceneConfig","_id":200,"Process":1,"Zone":2,"SceneType":"Robot","Name":"Robot01","OuterPort":0},
+]}

+ 4 - 0
Excel/Json/s/StartZoneConfig.txt

@@ -0,0 +1,4 @@
+{"list":[
+{"_t":"StartZoneConfig","_id":1,"DBConnection":"mongodb://127.0.0.1","DBName":"ET1"},
+{"_t":"StartZoneConfig","_id":2,"DBConnection":"mongodb://127.0.0.1","DBName":"ET2"},
+]}

+ 3 - 0
Excel/Json/s/UnitConfig.txt

@@ -0,0 +1,3 @@
+{"list":[
+{"_t":"UnitConfig","_id":1001,"Type":1,"Name":"米克尔","Desc":"带有强力攻击技能","Position":1,"Height":178,"Weight":68},
+]}

+ 0 - 0
Excel/StartMachineConfig.xlsx → Excel/StartConfig/Localhost/StartMachineConfig@s.xlsx


+ 0 - 0
Excel/StartProcessConfig.xlsx → Excel/StartConfig/Localhost/StartProcessConfig@s.xlsx


+ 0 - 0
Excel/StartSceneConfig.xlsx → Excel/StartConfig/Localhost/StartSceneConfig@s.xlsx


+ 0 - 0
Excel/StartZoneConfig.xlsx → Excel/StartConfig/Localhost/StartZoneConfig@s.xlsx


BIN
Excel/StartConfig/Release/StartMachineConfig@s.xlsx


BIN
Excel/StartConfig/Release/StartProcessConfig@s.xlsx


BIN
Excel/StartConfig/Release/StartSceneConfig@s.xlsx


BIN
Excel/StartConfig/Release/StartZoneConfig@s.xlsx


BIN
Excel/StartMachineConfig@s.xlsx


BIN
Excel/StartProcessConfig@s.xlsx


BIN
Excel/StartSceneConfig@s.xlsx


BIN
Excel/StartZoneConfig@s.xlsx


+ 0 - 7
Unity/Assets/Bundles/Config/StartMachineConfigCategory.bytes.meta

@@ -1,7 +0,0 @@
-fileFormatVersion: 2
-guid: 40aebe92b34144ab187964caf41b2104
-TextScriptImporter:
-  externalObjects: {}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 0 - 7
Unity/Assets/Bundles/Config/StartProcessConfigCategory.bytes.meta

@@ -1,7 +0,0 @@
-fileFormatVersion: 2
-guid: f62068aa635af4f189781cb7900fa538
-TextScriptImporter:
-  externalObjects: {}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 0 - 7
Unity/Assets/Bundles/Config/StartSceneConfigCategory.bytes.meta

@@ -1,7 +0,0 @@
-fileFormatVersion: 2
-guid: f5aaffc264fbd427f907e6180178fa65
-TextScriptImporter:
-  externalObjects: {}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 0 - 7
Unity/Assets/Bundles/Config/StartZoneConfigCategory.bytes.meta

@@ -1,7 +0,0 @@
-fileFormatVersion: 2
-guid: 2f76d9d7f3caf49b89a8292eb2ee302c
-TextScriptImporter:
-  externalObjects: {}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 1 - 1
Unity/Assets/Bundles/Config/UnitConfigCategory.bytes

@@ -1,2 +1,2 @@
 
-1é"	米克尔*带有强力攻击技能08²@D
+1é	米克尔"带有强力攻击技能(0²8D

+ 1 - 1
Unity/Assets/Editor/BuildEditor/BuildEditor.cs

@@ -35,7 +35,7 @@ namespace ET
 		private BuildOptions buildOptions;
 		private BuildAssetBundleOptions buildAssetBundleOptions = BuildAssetBundleOptions.None;
 
-		[MenuItem("Tools/打包工具")]
+		[MenuItem("Tools/Build Tool")]
 		public static void ShowWindow()
 		{
 			GetWindow(typeof (BuildEditor));

+ 34 - 5
Unity/Assets/Editor/ServerCommandLineEditor/ServerCommandLineEditor.cs

@@ -1,15 +1,44 @@
-using UnityEditor;
+using System;
+using System.IO;
+using System.Linq;
+using UnityEditor;
 using UnityEngine;
 
 namespace ET
 {
-    public static class ServerCommandLineEditor
+    public class ServerCommandLineEditor: EditorWindow
     {
-        [MenuItem("Tools/启动单进程服务器(仅windows可用)")]
+        [MenuItem("Tools/ServerTools")]
         public static void ShowWindow()
         {
-            string arguments = $"App.dll --Process=1 --Console=1";
-            ProcessHelper.Run("dotnet.exe", arguments, "../Bin/");
+            GetWindow(typeof (ServerCommandLineEditor));
+        }
+        
+        private int selectStartConfigIndex;
+        private string[] startConfigs;
+        private string startConfig;
+
+        public void OnEnable()
+        {
+            DirectoryInfo directoryInfo = new DirectoryInfo("../Config/StartConfig");
+            this.startConfigs = directoryInfo.GetDirectories().Select(x => x.Name).ToArray();
+        }
+
+        public void OnGUI()
+        {
+            selectStartConfigIndex = EditorGUILayout.Popup(selectStartConfigIndex, this.startConfigs);
+            this.startConfig = this.startConfigs[this.selectStartConfigIndex];
+            
+            if (GUILayout.Button("Start Server(Single Srocess)"))
+            {
+                string arguments = $"App.dll --Process=1 --StartConfig=StartConfig/{this.startConfig} --Console=1";
+                ProcessHelper.Run("dotnet.exe", arguments, "../Bin/");
+            }
+
+            if (GUILayout.Button("Start Mongo"))
+            {
+                ProcessHelper.Run("mongod", @"--dbpath=db", "../Database/bin/");
+            }
         }
     }
 }

+ 3 - 0
Unity/Assets/Mono/Core/Options.cs

@@ -31,6 +31,9 @@ namespace ET
         
         [Option("Console", Required = false, Default = 0)]
         public int Console { get; set; } = 0;
+
+        [Option("StartConfig", Required = false, Default = "")]
+        public string StartConfig { get; set; } = "";
         
         // 进程启动是否创建该进程的scenes
         [Option("CreateScenes", Required = false, Default = 1)]

+ 13 - 2
Unity/Codes/Model/Generate/Config/AIConfig.cs

@@ -7,7 +7,7 @@ namespace ET
 {
     [ProtoContract]
     [Config]
-    public partial class AIConfigCategory : ProtoObject
+    public partial class AIConfigCategory : ProtoObject, IMerge
     {
         public static AIConfigCategory Instance;
 		
@@ -23,6 +23,12 @@ namespace ET
         {
             Instance = this;
         }
+        
+        public void Merge(object o)
+        {
+            AIConfigCategory s = o as AIConfigCategory;
+            this.list.AddRange(s.list);
+        }
 		
         public override void EndInit()
         {
@@ -69,15 +75,20 @@ namespace ET
     [ProtoContract]
 	public partial class AIConfig: ProtoObject, IConfig
 	{
+		/// <summary>Id</summary>
 		[ProtoMember(1)]
 		public int Id { get; set; }
+		/// <summary>所属ai</summary>
 		[ProtoMember(2)]
 		public int AIConfigId { get; set; }
+		/// <summary>此ai中的顺序</summary>
 		[ProtoMember(3)]
 		public int Order { get; set; }
+		/// <summary>节点名字</summary>
 		[ProtoMember(4)]
 		public string Name { get; set; }
-		[ProtoMember(6)]
+		/// <summary>节点参数</summary>
+		[ProtoMember(5)]
 		public int[] NodeParams { get; set; }
 
 	}

+ 0 - 82
Unity/Codes/Model/Generate/Config/StartMachineConfig.cs

@@ -1,82 +0,0 @@
-using System;
-using System.Collections.Generic;
-using MongoDB.Bson.Serialization.Attributes;
-using ProtoBuf;
-
-namespace ET
-{
-    [ProtoContract]
-    [Config]
-    public partial class StartMachineConfigCategory : ProtoObject
-    {
-        public static StartMachineConfigCategory Instance;
-		
-        [ProtoIgnore]
-        [BsonIgnore]
-        private Dictionary<int, StartMachineConfig> dict = new Dictionary<int, StartMachineConfig>();
-		
-        [BsonElement]
-        [ProtoMember(1)]
-        private List<StartMachineConfig> list = new List<StartMachineConfig>();
-		
-        public StartMachineConfigCategory()
-        {
-            Instance = this;
-        }
-		
-        public override void EndInit()
-        {
-            foreach (StartMachineConfig config in list)
-            {
-                config.EndInit();
-                this.dict.Add(config.Id, config);
-            }            
-            this.AfterEndInit();
-        }
-		
-        public StartMachineConfig Get(int id)
-        {
-            this.dict.TryGetValue(id, out StartMachineConfig item);
-
-            if (item == null)
-            {
-                throw new Exception($"配置找不到,配置表名: {nameof (StartMachineConfig)},配置id: {id}");
-            }
-
-            return item;
-        }
-		
-        public bool Contain(int id)
-        {
-            return this.dict.ContainsKey(id);
-        }
-
-        public Dictionary<int, StartMachineConfig> GetAll()
-        {
-            return this.dict;
-        }
-
-        public StartMachineConfig GetOne()
-        {
-            if (this.dict == null || this.dict.Count <= 0)
-            {
-                return null;
-            }
-            return this.dict.Values.GetEnumerator().Current;
-        }
-    }
-
-    [ProtoContract]
-	public partial class StartMachineConfig: ProtoObject, IConfig
-	{
-		[ProtoMember(1)]
-		public int Id { get; set; }
-		[ProtoMember(2)]
-		public string InnerIP { get; set; }
-		[ProtoMember(3)]
-		public string OuterIP { get; set; }
-		[ProtoMember(4)]
-		public string WatcherPort { get; set; }
-
-	}
-}

+ 0 - 80
Unity/Codes/Model/Generate/Config/StartProcessConfig.cs

@@ -1,80 +0,0 @@
-using System;
-using System.Collections.Generic;
-using MongoDB.Bson.Serialization.Attributes;
-using ProtoBuf;
-
-namespace ET
-{
-    [ProtoContract]
-    [Config]
-    public partial class StartProcessConfigCategory : ProtoObject
-    {
-        public static StartProcessConfigCategory Instance;
-		
-        [ProtoIgnore]
-        [BsonIgnore]
-        private Dictionary<int, StartProcessConfig> dict = new Dictionary<int, StartProcessConfig>();
-		
-        [BsonElement]
-        [ProtoMember(1)]
-        private List<StartProcessConfig> list = new List<StartProcessConfig>();
-		
-        public StartProcessConfigCategory()
-        {
-            Instance = this;
-        }
-		
-        public override void EndInit()
-        {
-            foreach (StartProcessConfig config in list)
-            {
-                config.EndInit();
-                this.dict.Add(config.Id, config);
-            }            
-            this.AfterEndInit();
-        }
-		
-        public StartProcessConfig Get(int id)
-        {
-            this.dict.TryGetValue(id, out StartProcessConfig item);
-
-            if (item == null)
-            {
-                throw new Exception($"配置找不到,配置表名: {nameof (StartProcessConfig)},配置id: {id}");
-            }
-
-            return item;
-        }
-		
-        public bool Contain(int id)
-        {
-            return this.dict.ContainsKey(id);
-        }
-
-        public Dictionary<int, StartProcessConfig> GetAll()
-        {
-            return this.dict;
-        }
-
-        public StartProcessConfig GetOne()
-        {
-            if (this.dict == null || this.dict.Count <= 0)
-            {
-                return null;
-            }
-            return this.dict.Values.GetEnumerator().Current;
-        }
-    }
-
-    [ProtoContract]
-	public partial class StartProcessConfig: ProtoObject, IConfig
-	{
-		[ProtoMember(1)]
-		public int Id { get; set; }
-		[ProtoMember(2)]
-		public int MachineId { get; set; }
-		[ProtoMember(3)]
-		public int InnerPort { get; set; }
-
-	}
-}

+ 0 - 86
Unity/Codes/Model/Generate/Config/StartSceneConfig.cs

@@ -1,86 +0,0 @@
-using System;
-using System.Collections.Generic;
-using MongoDB.Bson.Serialization.Attributes;
-using ProtoBuf;
-
-namespace ET
-{
-    [ProtoContract]
-    [Config]
-    public partial class StartSceneConfigCategory : ProtoObject
-    {
-        public static StartSceneConfigCategory Instance;
-		
-        [ProtoIgnore]
-        [BsonIgnore]
-        private Dictionary<int, StartSceneConfig> dict = new Dictionary<int, StartSceneConfig>();
-		
-        [BsonElement]
-        [ProtoMember(1)]
-        private List<StartSceneConfig> list = new List<StartSceneConfig>();
-		
-        public StartSceneConfigCategory()
-        {
-            Instance = this;
-        }
-		
-        public override void EndInit()
-        {
-            foreach (StartSceneConfig config in list)
-            {
-                config.EndInit();
-                this.dict.Add(config.Id, config);
-            }            
-            this.AfterEndInit();
-        }
-		
-        public StartSceneConfig Get(int id)
-        {
-            this.dict.TryGetValue(id, out StartSceneConfig item);
-
-            if (item == null)
-            {
-                throw new Exception($"配置找不到,配置表名: {nameof (StartSceneConfig)},配置id: {id}");
-            }
-
-            return item;
-        }
-		
-        public bool Contain(int id)
-        {
-            return this.dict.ContainsKey(id);
-        }
-
-        public Dictionary<int, StartSceneConfig> GetAll()
-        {
-            return this.dict;
-        }
-
-        public StartSceneConfig GetOne()
-        {
-            if (this.dict == null || this.dict.Count <= 0)
-            {
-                return null;
-            }
-            return this.dict.Values.GetEnumerator().Current;
-        }
-    }
-
-    [ProtoContract]
-	public partial class StartSceneConfig: ProtoObject, IConfig
-	{
-		[ProtoMember(1)]
-		public int Id { get; set; }
-		[ProtoMember(2)]
-		public int Process { get; set; }
-		[ProtoMember(3)]
-		public int Zone { get; set; }
-		[ProtoMember(4)]
-		public string SceneType { get; set; }
-		[ProtoMember(5)]
-		public string Name { get; set; }
-		[ProtoMember(6)]
-		public int OuterPort { get; set; }
-
-	}
-}

+ 0 - 80
Unity/Codes/Model/Generate/Config/StartZoneConfig.cs

@@ -1,80 +0,0 @@
-using System;
-using System.Collections.Generic;
-using MongoDB.Bson.Serialization.Attributes;
-using ProtoBuf;
-
-namespace ET
-{
-    [ProtoContract]
-    [Config]
-    public partial class StartZoneConfigCategory : ProtoObject
-    {
-        public static StartZoneConfigCategory Instance;
-		
-        [ProtoIgnore]
-        [BsonIgnore]
-        private Dictionary<int, StartZoneConfig> dict = new Dictionary<int, StartZoneConfig>();
-		
-        [BsonElement]
-        [ProtoMember(1)]
-        private List<StartZoneConfig> list = new List<StartZoneConfig>();
-		
-        public StartZoneConfigCategory()
-        {
-            Instance = this;
-        }
-		
-        public override void EndInit()
-        {
-            foreach (StartZoneConfig config in list)
-            {
-                config.EndInit();
-                this.dict.Add(config.Id, config);
-            }            
-            this.AfterEndInit();
-        }
-		
-        public StartZoneConfig Get(int id)
-        {
-            this.dict.TryGetValue(id, out StartZoneConfig item);
-
-            if (item == null)
-            {
-                throw new Exception($"配置找不到,配置表名: {nameof (StartZoneConfig)},配置id: {id}");
-            }
-
-            return item;
-        }
-		
-        public bool Contain(int id)
-        {
-            return this.dict.ContainsKey(id);
-        }
-
-        public Dictionary<int, StartZoneConfig> GetAll()
-        {
-            return this.dict;
-        }
-
-        public StartZoneConfig GetOne()
-        {
-            if (this.dict == null || this.dict.Count <= 0)
-            {
-                return null;
-            }
-            return this.dict.Values.GetEnumerator().Current;
-        }
-    }
-
-    [ProtoContract]
-	public partial class StartZoneConfig: ProtoObject, IConfig
-	{
-		[ProtoMember(1)]
-		public int Id { get; set; }
-		[ProtoMember(2)]
-		public string DBConnection { get; set; }
-		[ProtoMember(3)]
-		public string DBName { get; set; }
-
-	}
-}

+ 19 - 6
Unity/Codes/Model/Generate/Config/UnitConfig.cs

@@ -7,7 +7,7 @@ namespace ET
 {
     [ProtoContract]
     [Config]
-    public partial class UnitConfigCategory : ProtoObject
+    public partial class UnitConfigCategory : ProtoObject, IMerge
     {
         public static UnitConfigCategory Instance;
 		
@@ -23,6 +23,12 @@ namespace ET
         {
             Instance = this;
         }
+        
+        public void Merge(object o)
+        {
+            UnitConfigCategory s = o as UnitConfigCategory;
+            this.list.AddRange(s.list);
+        }
 		
         public override void EndInit()
         {
@@ -69,19 +75,26 @@ namespace ET
     [ProtoContract]
 	public partial class UnitConfig: ProtoObject, IConfig
 	{
+		/// <summary>Id</summary>
 		[ProtoMember(1)]
 		public int Id { get; set; }
+		/// <summary>Type</summary>
 		[ProtoMember(2)]
 		public int Type { get; set; }
-		[ProtoMember(4)]
+		/// <summary>名字</summary>
+		[ProtoMember(3)]
 		public string Name { get; set; }
-		[ProtoMember(5)]
+		/// <summary>描述</summary>
+		[ProtoMember(4)]
 		public string Desc { get; set; }
-		[ProtoMember(6)]
+		/// <summary>位置</summary>
+		[ProtoMember(5)]
 		public int Position { get; set; }
-		[ProtoMember(7)]
+		/// <summary>身高</summary>
+		[ProtoMember(6)]
 		public int Height { get; set; }
-		[ProtoMember(8)]
+		/// <summary>体重</summary>
+		[ProtoMember(7)]
 		public int Weight { get; set; }
 
 	}

+ 7 - 0
Unity/Codes/Model/Module/Config/IMerge.cs

@@ -0,0 +1,7 @@
+namespace ET
+{
+    public interface IMerge
+    {
+        void Merge(object o);
+    }
+}