瀏覽代碼

格式化一下代码

tanghai 11 年之前
父節點
當前提交
6bb6d933b8
共有 100 個文件被更改,包括 4941 次插入4921 次删除
  1. 7 8
      CSharp/App/BossBase/CommonDefines.cs
  2. 11 11
      CSharp/App/BossBase/IMessageChannel.cs
  3. 8 8
      CSharp/App/BossBase/LoginOKEvent.cs
  4. 312 311
      CSharp/App/BossBase/Messages.cs
  5. 5 2
      CSharp/App/BossBase/Properties/AssemblyInfo.cs
  6. 8 8
      CSharp/App/BossBase/ReLoginEvent.cs
  7. 58 59
      CSharp/App/BossClient/BossClient.cs
  8. 24 24
      CSharp/App/BossClient/BossException.cs
  9. 70 67
      CSharp/App/BossClient/ENetChannel.cs
  10. 93 96
      CSharp/App/BossClient/GateSession.cs
  11. 37 34
      CSharp/App/BossClient/Properties/AssemblyInfo.cs
  12. 188 189
      CSharp/App/BossClient/RealmSession.cs
  13. 287 286
      CSharp/App/BossClient/SRP6Client.cs
  14. 88 84
      CSharp/App/BossClient/TcpChannel.cs
  15. 53 53
      CSharp/App/BossCommand/ABossCommand.cs
  16. 22 22
      CSharp/App/BossCommand/BCCommand.cs
  17. 25 25
      CSharp/App/BossCommand/BCForbidLogin.cs
  18. 25 25
      CSharp/App/BossCommand/BCForbiddenCharacter.cs
  19. 50 48
      CSharp/App/BossCommand/BCGetCharacterInfo.cs
  20. 18 18
      CSharp/App/BossCommand/BCReloadWorld.cs
  21. 26 27
      CSharp/App/BossCommand/BCSendMail.cs
  22. 19 19
      CSharp/App/BossCommand/BCServerInfo.cs
  23. 5 2
      CSharp/App/BossCommand/Properties/AssemblyInfo.cs
  24. 19 19
      CSharp/App/Editor/App.xaml.cs
  25. 48 45
      CSharp/App/Editor/Bootstrapper.cs
  26. 22 22
      CSharp/App/Editor/Shell.xaml.cs
  27. 10 10
      CSharp/App/Editor/ShellViewModel.cs
  28. 64 62
      CSharp/App/Infrastructure/AutoPopulateExportedViewsBehavior.cs
  29. 23 23
      CSharp/App/Infrastructure/IViewRegionRegistration.cs
  30. 35 35
      CSharp/App/Infrastructure/ViewExportAttribute.cs
  31. 12 12
      CSharp/App/Modules/Login/LoginModule.cs
  32. 5 5
      CSharp/App/Modules/Login/LoginView.xaml
  33. 36 36
      CSharp/App/Modules/Login/LoginView.xaml.cs
  34. 121 118
      CSharp/App/Modules/Login/LoginViewModel.cs
  35. 8 9
      CSharp/App/Modules/Robot/ComboBoxForbiddenType.cs
  36. 28 27
      CSharp/App/Modules/Robot/NumValidation.cs
  37. 5 5
      CSharp/App/Modules/Robot/Robot.cs
  38. 12 12
      CSharp/App/Modules/Robot/RobotModule.cs
  39. 6 6
      CSharp/App/Modules/Robot/RobotView.xaml
  40. 176 171
      CSharp/App/Modules/Robot/RobotView.xaml.cs
  41. 433 433
      CSharp/App/Modules/Robot/RobotViewModel.cs
  42. 24 24
      CSharp/App/Modules/Robot/ServerViewModel.cs
  43. 176 177
      CSharp/App/Modules/Tree/BehaviorTreeLayout.cs
  44. 12 12
      CSharp/App/Modules/Tree/BehaviorTreeModule.cs
  45. 3 3
      CSharp/App/Modules/Tree/BehaviorTreeView.xaml
  46. 211 205
      CSharp/App/Modules/Tree/BehaviorTreeView.xaml.cs
  47. 209 206
      CSharp/App/Modules/Tree/BehaviorTreeViewModel.cs
  48. 23 22
      CSharp/App/Modules/Tree/FolderVisiableConverter.cs
  49. 29 28
      CSharp/App/Modules/Tree/ListToStringConverter.cs
  50. 1 1
      CSharp/App/Modules/Tree/NodeDataEditor.xaml
  51. 38 48
      CSharp/App/Modules/Tree/NodeDataEditor.xaml.cs
  52. 14 14
      CSharp/App/Modules/Tree/NodeType.cs
  53. 35 36
      CSharp/App/Modules/Tree/NodeTypeColorConverter.cs
  54. 18 19
      CSharp/App/Modules/Tree/NodeTypeToStringConverter.cs
  55. 43 43
      CSharp/App/Modules/Tree/TreeNodeData.cs
  56. 34 33
      CSharp/App/Modules/Tree/TreeNodeDataArray.cs
  57. 385 385
      CSharp/App/Modules/Tree/TreeNodeViewModel.cs
  58. 11 13
      CSharp/App/Modules/WCFClient/Properties/AssemblyInfo.cs
  59. 13 13
      CSharp/App/Modules/WCFClient/WCFClientModule.cs
  60. 16 15
      CSharp/App/Modules/WCFClient/WCFClientView.xaml.cs
  61. 10 10
      CSharp/App/Modules/WCFClient/WCFClientViewModel.cs
  62. 17 17
      CSharp/Game/BehaviorTree/BehaviorTree.cs
  63. 55 54
      CSharp/Game/BehaviorTree/BehaviorTreeFactory.cs
  64. 8 8
      CSharp/Game/BehaviorTree/BlackBoard.cs
  65. 38 38
      CSharp/Game/BehaviorTree/Config.cs
  66. 18 18
      CSharp/Game/BehaviorTree/Node.cs
  67. 23 22
      CSharp/Game/BehaviorTree/Not.cs
  68. 5 2
      CSharp/Game/BehaviorTree/Properties/AssemblyInfo.cs
  69. 22 22
      CSharp/Game/BehaviorTree/Selector.cs
  70. 22 22
      CSharp/Game/BehaviorTree/Sequence.cs
  71. 69 69
      CSharp/Game/BehaviorTreeTest/BehaviorTreeFactoryTest.cs
  72. 71 70
      CSharp/Game/BehaviorTreeTest/ConfigTest.cs
  73. 5 2
      CSharp/Game/BehaviorTreeTest/Properties/AssemblyInfo.cs
  74. 7 8
      CSharp/Game/Component/Buff.cs
  75. 112 112
      CSharp/Game/Component/BuffManager.cs
  76. 8 10
      CSharp/Game/Component/Character.cs
  77. 15 15
      CSharp/Game/Component/ConfigAttribute.cs
  78. 58 58
      CSharp/Game/Component/ConfigCategory.cs
  79. 96 96
      CSharp/Game/Component/ConfigManager.cs
  80. 11 11
      CSharp/Game/Component/EventAttribute.cs
  81. 12 13
      CSharp/Game/Component/EventType.cs
  82. 17 18
      CSharp/Game/Component/GameObject.cs
  83. 70 70
      CSharp/Game/Component/GameObjectManager.cs
  84. 11 11
      CSharp/Game/Component/HandlerAttribute.cs
  85. 8 9
      CSharp/Game/Component/IConfigInitialize.cs
  86. 7 8
      CSharp/Game/Component/IEvent.cs
  87. 7 8
      CSharp/Game/Component/IHandler.cs
  88. 7 8
      CSharp/Game/Component/ILogic.cs
  89. 7 10
      CSharp/Game/Component/IType.cs
  90. 7 8
      CSharp/Game/Component/KeyDefine.cs
  91. 139 137
      CSharp/Game/Component/LogicManager.cs
  92. 19 20
      CSharp/Game/Component/Message.cs
  93. 10 10
      CSharp/Game/Component/MessageAttribute.cs
  94. 5 6
      CSharp/Game/Component/MessageEnv.cs
  95. 64 64
      CSharp/Game/Component/Object.cs
  96. 14 14
      CSharp/Game/Logic/Event/BeforeLoginWorldEvent.cs
  97. 14 14
      CSharp/Game/Logic/Event/BeforeUseItemEvent.cs
  98. 21 21
      CSharp/Game/Logic/Handler/ChatHandler.cs
  99. 11 11
      CSharp/Game/Logic/Handler/LoginWorldHandler.cs
  100. 24 24
      CSharp/Game/Logic/Handler/ReloadHandler.cs

+ 7 - 8
CSharp/App/BossBase/CommonDefines.cs

@@ -1,8 +1,7 @@
-
-namespace BossBase
-{
-	public static class BuffId
-	{
-		public const int BUFF_FORBIDDEN_PLAYER_BUY_ITEM = 660100;
-	}
-}
+namespace BossBase
+{
+    public static class BuffId
+    {
+        public const int BUFF_FORBIDDEN_PLAYER_BUY_ITEM = 660100;
+    }
+}

+ 11 - 11
CSharp/App/BossBase/IMessageChannel.cs

@@ -1,11 +1,11 @@
-using System;
-using System.Threading.Tasks;
-
-namespace BossBase
-{
-	public interface IMessageChannel : IDisposable
-	{
-		void SendMessage<T>(ushort opcode, T message, byte channelID = 0);
-		Task<Tuple<ushort, byte[]>> RecvMessage();
-	}
-}
+using System;
+using System.Threading.Tasks;
+
+namespace BossBase
+{
+    public interface IMessageChannel: IDisposable
+    {
+        void SendMessage<T>(ushort opcode, T message, byte channelID = 0);
+        Task<Tuple<ushort, byte[]>> RecvMessage();
+    }
+}

+ 8 - 8
CSharp/App/BossBase/LoginOKEvent.cs

@@ -1,8 +1,8 @@
-using Microsoft.Practices.Prism.Events;
-
-namespace BossBase
-{
-	public class LoginOKEvent : CompositePresentationEvent<IMessageChannel>
-	{
-	}
-}
+using Microsoft.Practices.Prism.Events;
+
+namespace BossBase
+{
+    public class LoginOKEvent: CompositePresentationEvent<IMessageChannel>
+    {
+    }
+}

+ 312 - 311
CSharp/App/BossBase/Messages.cs

@@ -1,312 +1,313 @@
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-
-namespace BossBase
-{
-	public static class MessageOpcode
-	{
-		// realm message opcode
-		public const ushort CMSG_REALM_LIST = 16;
-		public const ushort CMSG_BOSS_GM = 17;
-		public const ushort CMSG_AUTH_LOGON_PERMIT = 800;
-		public const ushort CMSG_OTP_PASSWORD = 801;
-		public const ushort CMSG_PPC_PASSWORD = 802;
-		public const ushort CMSG_AUTH_LOGON_CHALLENGE = 803;
-		public const ushort CMSG_AUTH_LOGON_PROOF = 805;
-		public const ushort SMSG_AUTH_LOGON_CHALLENGE_RESPONSE = 900;
-		public const ushort SMSG_REALM_LOGON_RESPONSE = 901;
-		public const ushort SMSG_REALM_LIST = 902;
-		public const ushort SMSG_LOCK_FOR_SAFE_TIME = 903;
-		public const ushort SMSG_PASSWORD_PROTECT_TYPE = 904;
-		public const ushort SMSG_AUTH_LOGON_PROOF_M2 = 905;
-
-		// gate message opcode
-		public const ushort CMSG_AUTH_SESSION = 2;
-		public const ushort SMSG_AUTH_CHALLENGE = 502;
-		public const ushort SMSG_AUTH_RESPONSE = 503;
-
-		public const ushort SMSG_SERVERTIME = 510;
-
-		public const ushort SMSG_BOSS_SERVERSINFO = 22000;
-		public const ushort SMSG_BOSS_COMMAND_RESPONSE = 22001;
-	}
-
-	public static class ErrorCode
-	{
-		// realm error code
-		public const int REALM_AUTH_SUCCESS = 0;
-		// Unable to connect
-		public const int REALM_AUTH_FAILURE = 1;
-		// Unable to connect
-		public const int REALM_AUTH_UNKNOWN1 = 2;
-		// This game> account has been closed and is no longer available for use.
-		// Please go to site>/banned.html for further information.
-		public const int REALM_AUTH_ACCOUNT_BANNED = 3;
-		// The information you have entered is not valid.
-		// Please check the spelling of the account name and password.
-		// If you need help in retrieving a lost or stolen password,
-		// see site> for more information
-		public const int REALM_AUTH_NO_MATCH = 4;
-		// The information you have entered is not valid.
-		// Please check the spelling of the account name and password.
-		// If you need help in retrieving a lost or stolen password,
-		// see site> for more information
-		public const int REALM_AUTH_UNKNOWN2 = 5;
-		// This account is already logged into game.
-		// Please check the spelling and try again.
-		public const int REALM_AUTH_ACCOUNT_IN_USE = 6;
-		// You have used up your prepaid time for this account.
-		// Please purchase more to continue playing
-		public const int REALM_AUTH_PREPAID_TIME_LIMIT = 7;
-		// Could not log in to game> at this time. Please try again later.
-		public const int REALM_AUTH_SERVER_FULL = 8;
-		// Unable to validate game version.
-		// This may be caused by file corruption or interference of another program.
-		// Please visit site for more information and possible solutions to this
-		// issue.
-		public const int REALM_AUTH_WRONG_BUILD_NUMBER = 9;
-		// Downloading
-		public const int REALM_AUTH_UPDATE_CLIENT = 10;
-		// Unable to connect
-		public const int REALM_AUTH_UNKNOWN3 = 11;
-		// This game account has been temporarily suspended.
-		// Please go to site further information.
-		public const int REALM_AUTH_ACCOUNT_FREEZED = 12;
-		// Unable to connect
-		public const int REALM_AUTH_UNKNOWN4 = 13;
-		// Connected.
-		public const int REALM_AUTH_UNKNOWN5 = 14;
-		// Access to this account has been blocked by parental controls.
-		// Your settings may be changed in your account preferences at site.
-		public const int REALM_AUTH_PARENTAL_CONTROL = 15;
-
-
-		// 其它error code
-		public const int RESPONSE_SUCCESS = 0;
-		public const int AUTH_OK = 12;
-		public const int BOSS_PLAYER_NOT_FOUND = 164000;
-	}
-
-	[DataContract]
-	public class CMSG_Auth_Logon_Permit
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public byte[] Account { get; set; }
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public byte[] PasswordMd5 { get; set; }
-	}
-
-	[DataContract]
-	public class SMSG_Password_Protect_Type
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public uint Code { get; set; }
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public uint SubCode { get; set; }
-
-		[DataMember(Order = 3, IsRequired = true)]
-		public uint PasswordProtectType { get; set; }
-
-		[DataMember(Order = 4, IsRequired = true)]
-		public byte[] PpcCoordinate { get; set; }
-	}
-
-	[DataContract]
-	public class CMSG_Auth_Logon_Challenge
-	{
-	}
-
-	[DataContract]
-	public class SMSG_Auth_Logon_Challenge_Response
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public int ErrorCode { get; set; }
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public byte[] B { get; set; }
-
-		[DataMember(Order = 3, IsRequired = true)]
-		public byte[] G { get; set; }
-
-		[DataMember(Order = 4, IsRequired = true)]
-		public byte[] N { get; set; }
-
-		[DataMember(Order = 5, IsRequired = true)]
-		public byte[] S { get; set; }
-	}
-
-	[DataContract]
-	public class CMSG_Auth_Logon_Proof
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public byte[] A { get; set; }
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public byte[] M { get; set; }
-	}
-
-	[DataContract]
-	public class CMSG_Realm_List
-	{
-	}
-
-	[DataContract]
-	public class SMSG_Auth_Logon_Proof_M2
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public int ErrorCode { get; set; }
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public byte[] M { get; set; }
-	}
-
-	[DataContract]
-	public class Realm_List_Gate
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public byte[] Name { get; set; }
-		[DataMember(Order = 2, IsRequired = true)]
-		public byte[] Address { get; set; }
-		[DataMember(Order = 3, IsRequired = true)]
-		public float CityLoad { get; set; }
-	}
-
-	[DataContract]
-	public class Realm_List_City
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public string Name { get; set; } 
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public float CityLoad { get; set; } 
-
-		[DataMember(Order = 3, IsRequired = true)]
-		public bool IsEnable { get; set; } 
-	}
-
-	[DataContract]
-	public class SMSG_Realm_List
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public string GateIP { get; set; } 
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public int GatePort { get; set; } 
-
-		[DataMember(Order = 3, IsRequired = true)]
-		public List<Realm_List_City> GateList { get; set; } 
-	}
-
-	[DataContract]
-	public class CMSG_Auth_Session 
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public uint ClientBuild { get; set; }
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public uint Unk2 { get; set; }
-
-		[DataMember(Order = 3, IsRequired = true)]
-		public byte[] Username { get; set; }
-
-		[DataMember(Order = 4, IsRequired = true)]
-		public uint Unk3 { get; set; }
-
-		[DataMember(Order = 5, IsRequired = true)]
-		public uint ClientSeed { get; set; }
-
-		[DataMember(Order = 6, IsRequired = true)]
-		public uint Unk4 { get; set; }
-
-		[DataMember(Order = 7, IsRequired = true)]
-		public byte[] Digest { get; set; }
-
-		[DataMember(Order = 8, IsRequired = false)]
-		public byte[] Mac { get; set; }
-
-		[DataMember(Order = 9, IsRequired = false)]
-		public byte[] Hd { get; set; }
-	}
-
-	// gate message
-	[DataContract]
-	public class SMSG_Auth_Challenge
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public uint Num { get; set; }
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public uint Seed { get; set; }
-
-		[DataMember(Order = 3)]
-		public List<uint> Random { get; set; }
-	}
-
-	[DataContract]
-	public class SMSG_Auth_Response
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public uint ErrorCode { get; set; }
-	}
-
-	[DataContract]
-	public class CMSG_Boss_Gm
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public string Message { get; set; }
-	}
-	
-	[DataContract]
-	public class SMSG_Boss_ServersInfo
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public List<string> Name { get; set; }
-	}
-
-	[DataContract]
-	public class SMSG_Boss_Command_Response
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public uint ErrorCode { get; set; }
-
-		[DataMember(Order = 2, IsRequired = false)]
-		public string Content { get; set; }
-	}
-
-	[DataContract]
-	public class BossMailItem
-	{
-		[DataMember(Order = 1, IsRequired = false)]
-		public uint item_id { get; set; }
-
-		[DataMember(Order = 2, IsRequired = false)]
-		public uint item_count { get; set; }
-	}
-
-	[DataContract]
-	public class BossMail
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		public string sender_name { get; set; }
-
-		[DataMember(Order = 2, IsRequired = true)]
-		public ulong receiver_guid { get; set; }
-
-		[DataMember(Order = 3, IsRequired = true)]
-		public string subject { get; set; }
-
-		[DataMember(Order = 4, IsRequired = true)]
-		public string content { get; set; }
-
-		[DataMember(Order = 5, IsRequired = false)]
-		public uint free_gold { get; set; }
-
-		[DataMember(Order = 6, IsRequired = false)]
-		public uint silver { get; set; }
-
-		[DataMember(Order = 7, IsRequired = false)]
-		public Dictionary<int, int> item_dict { get; set; }
-	}
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace BossBase
+{
+    public static class MessageOpcode
+    {
+        // realm message opcode
+        public const ushort CMSG_REALM_LIST = 16;
+        public const ushort CMSG_BOSS_GM = 17;
+        public const ushort CMSG_AUTH_LOGON_PERMIT = 800;
+        public const ushort CMSG_OTP_PASSWORD = 801;
+        public const ushort CMSG_PPC_PASSWORD = 802;
+        public const ushort CMSG_AUTH_LOGON_CHALLENGE = 803;
+        public const ushort CMSG_AUTH_LOGON_PROOF = 805;
+        public const ushort SMSG_AUTH_LOGON_CHALLENGE_RESPONSE = 900;
+        public const ushort SMSG_REALM_LOGON_RESPONSE = 901;
+        public const ushort SMSG_REALM_LIST = 902;
+        public const ushort SMSG_LOCK_FOR_SAFE_TIME = 903;
+        public const ushort SMSG_PASSWORD_PROTECT_TYPE = 904;
+        public const ushort SMSG_AUTH_LOGON_PROOF_M2 = 905;
+
+        // gate message opcode
+        public const ushort CMSG_AUTH_SESSION = 2;
+        public const ushort SMSG_AUTH_CHALLENGE = 502;
+        public const ushort SMSG_AUTH_RESPONSE = 503;
+
+        public const ushort SMSG_SERVERTIME = 510;
+
+        public const ushort SMSG_BOSS_SERVERSINFO = 22000;
+        public const ushort SMSG_BOSS_COMMAND_RESPONSE = 22001;
+    }
+
+    public static class ErrorCode
+    {
+        // realm error code
+        public const int REALM_AUTH_SUCCESS = 0;
+        // Unable to connect
+        public const int REALM_AUTH_FAILURE = 1;
+        // Unable to connect
+        public const int REALM_AUTH_UNKNOWN1 = 2;
+        // This game> account has been closed and is no longer available for use.
+        // Please go to site>/banned.html for further information.
+        public const int REALM_AUTH_ACCOUNT_BANNED = 3;
+        // The information you have entered is not valid.
+        // Please check the spelling of the account name and password.
+        // If you need help in retrieving a lost or stolen password,
+        // see site> for more information
+        public const int REALM_AUTH_NO_MATCH = 4;
+        // The information you have entered is not valid.
+        // Please check the spelling of the account name and password.
+        // If you need help in retrieving a lost or stolen password,
+        // see site> for more information
+        public const int REALM_AUTH_UNKNOWN2 = 5;
+        // This account is already logged into game.
+        // Please check the spelling and try again.
+        public const int REALM_AUTH_ACCOUNT_IN_USE = 6;
+        // You have used up your prepaid time for this account.
+        // Please purchase more to continue playing
+        public const int REALM_AUTH_PREPAID_TIME_LIMIT = 7;
+        // Could not log in to game> at this time. Please try again later.
+        public const int REALM_AUTH_SERVER_FULL = 8;
+        // Unable to validate game version.
+        // This may be caused by file corruption or interference of another program.
+        // Please visit site for more information and possible solutions to this
+        // issue.
+        public const int REALM_AUTH_WRONG_BUILD_NUMBER = 9;
+        // Downloading
+        public const int REALM_AUTH_UPDATE_CLIENT = 10;
+        // Unable to connect
+        public const int REALM_AUTH_UNKNOWN3 = 11;
+        // This game account has been temporarily suspended.
+        // Please go to site further information.
+        public const int REALM_AUTH_ACCOUNT_FREEZED = 12;
+        // Unable to connect
+        public const int REALM_AUTH_UNKNOWN4 = 13;
+        // Connected.
+        public const int REALM_AUTH_UNKNOWN5 = 14;
+        // Access to this account has been blocked by parental controls.
+        // Your settings may be changed in your account preferences at site.
+        public const int REALM_AUTH_PARENTAL_CONTROL = 15;
+
+        // 其它error code
+        public const int RESPONSE_SUCCESS = 0;
+        public const int AUTH_OK = 12;
+        public const int BOSS_PLAYER_NOT_FOUND = 164000;
+    }
+
+    [DataContract]
+    public class CMSG_Auth_Logon_Permit
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public byte[] Account { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public byte[] PasswordMd5 { get; set; }
+    }
+
+    [DataContract]
+    public class SMSG_Password_Protect_Type
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public uint Code { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public uint SubCode { get; set; }
+
+        [DataMember(Order = 3, IsRequired = true)]
+        public uint PasswordProtectType { get; set; }
+
+        [DataMember(Order = 4, IsRequired = true)]
+        public byte[] PpcCoordinate { get; set; }
+    }
+
+    [DataContract]
+    public class CMSG_Auth_Logon_Challenge
+    {
+    }
+
+    [DataContract]
+    public class SMSG_Auth_Logon_Challenge_Response
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public int ErrorCode { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public byte[] B { get; set; }
+
+        [DataMember(Order = 3, IsRequired = true)]
+        public byte[] G { get; set; }
+
+        [DataMember(Order = 4, IsRequired = true)]
+        public byte[] N { get; set; }
+
+        [DataMember(Order = 5, IsRequired = true)]
+        public byte[] S { get; set; }
+    }
+
+    [DataContract]
+    public class CMSG_Auth_Logon_Proof
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public byte[] A { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public byte[] M { get; set; }
+    }
+
+    [DataContract]
+    public class CMSG_Realm_List
+    {
+    }
+
+    [DataContract]
+    public class SMSG_Auth_Logon_Proof_M2
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public int ErrorCode { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public byte[] M { get; set; }
+    }
+
+    [DataContract]
+    public class Realm_List_Gate
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public byte[] Name { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public byte[] Address { get; set; }
+
+        [DataMember(Order = 3, IsRequired = true)]
+        public float CityLoad { get; set; }
+    }
+
+    [DataContract]
+    public class Realm_List_City
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public string Name { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public float CityLoad { get; set; }
+
+        [DataMember(Order = 3, IsRequired = true)]
+        public bool IsEnable { get; set; }
+    }
+
+    [DataContract]
+    public class SMSG_Realm_List
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public string GateIP { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public int GatePort { get; set; }
+
+        [DataMember(Order = 3, IsRequired = true)]
+        public List<Realm_List_City> GateList { get; set; }
+    }
+
+    [DataContract]
+    public class CMSG_Auth_Session
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public uint ClientBuild { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public uint Unk2 { get; set; }
+
+        [DataMember(Order = 3, IsRequired = true)]
+        public byte[] Username { get; set; }
+
+        [DataMember(Order = 4, IsRequired = true)]
+        public uint Unk3 { get; set; }
+
+        [DataMember(Order = 5, IsRequired = true)]
+        public uint ClientSeed { get; set; }
+
+        [DataMember(Order = 6, IsRequired = true)]
+        public uint Unk4 { get; set; }
+
+        [DataMember(Order = 7, IsRequired = true)]
+        public byte[] Digest { get; set; }
+
+        [DataMember(Order = 8, IsRequired = false)]
+        public byte[] Mac { get; set; }
+
+        [DataMember(Order = 9, IsRequired = false)]
+        public byte[] Hd { get; set; }
+    }
+
+    // gate message
+    [DataContract]
+    public class SMSG_Auth_Challenge
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public uint Num { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public uint Seed { get; set; }
+
+        [DataMember(Order = 3)]
+        public List<uint> Random { get; set; }
+    }
+
+    [DataContract]
+    public class SMSG_Auth_Response
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public uint ErrorCode { get; set; }
+    }
+
+    [DataContract]
+    public class CMSG_Boss_Gm
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public string Message { get; set; }
+    }
+
+    [DataContract]
+    public class SMSG_Boss_ServersInfo
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public List<string> Name { get; set; }
+    }
+
+    [DataContract]
+    public class SMSG_Boss_Command_Response
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public uint ErrorCode { get; set; }
+
+        [DataMember(Order = 2, IsRequired = false)]
+        public string Content { get; set; }
+    }
+
+    [DataContract]
+    public class BossMailItem
+    {
+        [DataMember(Order = 1, IsRequired = false)]
+        public uint item_id { get; set; }
+
+        [DataMember(Order = 2, IsRequired = false)]
+        public uint item_count { get; set; }
+    }
+
+    [DataContract]
+    public class BossMail
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        public string sender_name { get; set; }
+
+        [DataMember(Order = 2, IsRequired = true)]
+        public ulong receiver_guid { get; set; }
+
+        [DataMember(Order = 3, IsRequired = true)]
+        public string subject { get; set; }
+
+        [DataMember(Order = 4, IsRequired = true)]
+        public string content { get; set; }
+
+        [DataMember(Order = 5, IsRequired = false)]
+        public uint free_gold { get; set; }
+
+        [DataMember(Order = 6, IsRequired = false)]
+        public uint silver { get; set; }
+
+        [DataMember(Order = 7, IsRequired = false)]
+        public Dictionary<int, int> item_dict { get; set; }
+    }
 }

+ 5 - 2
CSharp/App/BossBase/Properties/AssemblyInfo.cs

@@ -1,10 +1,10 @@
 using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 // 有关程序集的常规信息通过以下
 // 特性集控制。更改这些特性值可修改
 // 与程序集关联的信息。
+
 [assembly: AssemblyTitle("Events")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
@@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
 // 将 ComVisible 设置为 false 使此程序集中的类型
 // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
 // 则将该类型上的 ComVisible 特性设置为 true。
+
 [assembly: ComVisible(false)]
 
 // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+
 [assembly: Guid("288940c7-28fd-45cd-a5f7-87eaeef4740d")]
 
 // 程序集的版本信息由下面四个值组成:
@@ -32,5 +34,6 @@ using System.Runtime.InteropServices;
 // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
 // 方法是按如下所示使用“*”:
 // [assembly: AssemblyVersion("1.0.*")]
+
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 8 - 8
CSharp/App/BossBase/ReLoginEvent.cs

@@ -1,8 +1,8 @@
-using Microsoft.Practices.Prism.Events;
-
-namespace BossBase
-{
-	public class ReLoginEvent : CompositePresentationEvent<object>
-	{
-	}
-}
+using Microsoft.Practices.Prism.Events;
+
+namespace BossBase
+{
+    public class ReLoginEvent: CompositePresentationEvent<object>
+    {
+    }
+}

+ 58 - 59
CSharp/App/BossClient/BossClient.cs

@@ -1,59 +1,58 @@
-using System;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-using ENet;
-using Logger;
-
-namespace BossClient
-{
-	public class BossClient : IDisposable
-	{
-		private int sessionId;
-
-		private readonly EService ioService = new EService();
-
-		public BossClient()
-		{
-			this.ioService.EnableCrc();
-		}
-
-		public void Dispose()
-		{
-			this.ioService.Dispose();
-		}
-
-		public void RunOnce()
-		{
-			this.ioService.RunOnce();
-		}
-
-		public void Start(int timeout)
-		{
-			this.ioService.Start(timeout);
-		}
-
-		public GateSession GateSession { get; private set; }
-
-		public async Task Login(
-			string hostName, ushort port, string account, string password)
-		{
-			int loginSessionId = ++this.sessionId;
-
-			// 登录realm
-			var tcpClient = new TcpClient();
-			await tcpClient.ConnectAsync(hostName, port);
-			Tuple<string, ushort, SRP6Client> realmInfo = null; // ip, port, K
-			using (var realmSession = new RealmSession(loginSessionId, new TcpChannel(tcpClient)))
-			{
-				realmInfo = await realmSession.Login(account, password);
-				Log.Trace("session: {0}, login success!", realmSession.ID);
-			}
-
-			// 登录gate
-			var eSocket = new ESocket(this.ioService);
-			await eSocket.ConnectAsync(realmInfo.Item1, realmInfo.Item2);
-			this.GateSession = new GateSession(loginSessionId, new ENetChannel(eSocket));
-			await this.GateSession.Login(realmInfo.Item3);
-		}
-	}
-}
+using System;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+using ENet;
+using Logger;
+
+namespace BossClient
+{
+    public class BossClient: IDisposable
+    {
+        private int sessionId;
+
+        private readonly EService ioService = new EService();
+
+        public BossClient()
+        {
+            this.ioService.EnableCrc();
+        }
+
+        public void Dispose()
+        {
+            this.ioService.Dispose();
+        }
+
+        public void RunOnce()
+        {
+            this.ioService.RunOnce();
+        }
+
+        public void Start(int timeout)
+        {
+            this.ioService.Start(timeout);
+        }
+
+        public GateSession GateSession { get; private set; }
+
+        public async Task Login(string hostName, ushort port, string account, string password)
+        {
+            int loginSessionId = ++this.sessionId;
+
+            // 登录realm
+            var tcpClient = new TcpClient();
+            await tcpClient.ConnectAsync(hostName, port);
+            Tuple<string, ushort, SRP6Client> realmInfo = null; // ip, port, K
+            using (var realmSession = new RealmSession(loginSessionId, new TcpChannel(tcpClient)))
+            {
+                realmInfo = await realmSession.Login(account, password);
+                Log.Trace("session: {0}, login success!", realmSession.ID);
+            }
+
+            // 登录gate
+            var eSocket = new ESocket(this.ioService);
+            await eSocket.ConnectAsync(realmInfo.Item1, realmInfo.Item2);
+            this.GateSession = new GateSession(loginSessionId, new ENetChannel(eSocket));
+            await this.GateSession.Login(realmInfo.Item3);
+        }
+    }
+}

+ 24 - 24
CSharp/App/BossClient/BossException.cs

@@ -1,25 +1,25 @@
-using System;
-using System.Runtime.Serialization;
-
-namespace BossClient
-{
-	[Serializable]
-	public class BossException: Exception
-	{
-		public BossException()
-		{
-		}
-
-		public BossException(string message): base(message)
-		{
-		}
-
-		public BossException(string message, Exception inner): base(message, inner)
-		{
-		}
-
-		protected BossException(SerializationInfo info, StreamingContext context)
-		{
-		}
-	}
+using System;
+using System.Runtime.Serialization;
+
+namespace BossClient
+{
+    [Serializable]
+    public class BossException: Exception
+    {
+        public BossException()
+        {
+        }
+
+        public BossException(string message): base(message)
+        {
+        }
+
+        public BossException(string message, Exception inner): base(message, inner)
+        {
+        }
+
+        protected BossException(SerializationInfo info, StreamingContext context)
+        {
+        }
+    }
 }

+ 70 - 67
CSharp/App/BossClient/ENetChannel.cs

@@ -1,67 +1,70 @@
-using System;
-using System.IO;
-using System.Threading.Tasks;
-using BossBase;
-using ENet;
-using Helper;
-using System.IO.Compression;
-
-namespace BossClient
-{
-	class ENetChannel: IMessageChannel
-	{
-		private readonly ESocket eSocket;
-
-		public ENetChannel(ESocket eSocket)
-		{
-			this.eSocket = eSocket;
-		}
-
-		public async void Dispose()
-		{
-			await this.eSocket.DisconnectLaterAsync();
-			this.eSocket.Dispose();
-		}
-
-		public void SendMessage<T>(ushort opcode, T message, byte channelID = 0)
-		{
-			byte[] protoBytes = ProtobufHelper.ToBytes(message);
-			var neworkBytes = new byte[sizeof(ushort) + protoBytes.Length];
-
-			var opcodeBytes = BitConverter.GetBytes(opcode);
-			opcodeBytes.CopyTo(neworkBytes, 0);
-			protoBytes.CopyTo(neworkBytes, sizeof(ushort));
-			this.eSocket.WriteAsync(neworkBytes, channelID);
-		}
-
-		public async Task<Tuple<ushort, byte[]>> RecvMessage()
-		{
-			var bytes = await this.eSocket.ReadAsync();
-			const int opcodeSize = sizeof(ushort);
-			ushort opcode = BitConverter.ToUInt16(bytes, 0);
-			byte flag = bytes[2];
-
-			switch (flag)
-			{
-				case 0:
-				{
-					var messageBytes = new byte[bytes.Length - opcodeSize - 1];
-					Array.Copy(bytes, opcodeSize + 1, messageBytes, 0, messageBytes.Length);
-					return Tuple.Create(opcode, messageBytes);
-				}
-				default:
-				{
-					var decompressStream = new MemoryStream();
-					using (var zipStream = new GZipStream(
-						new MemoryStream(bytes, opcodeSize + 5, bytes.Length - opcodeSize - 5),
-							CompressionMode.Decompress))
-					{
-						zipStream.CopyTo(decompressStream);
-					}
-					var decompressBytes = decompressStream.ToArray();
-					return Tuple.Create(opcode, decompressBytes);
-				}
-			}
-		}
-	}
-}
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Threading.Tasks;
+using BossBase;
+using ENet;
+using Helper;
+
+namespace BossClient
+{
+    internal class ENetChannel: IMessageChannel
+    {
+        private readonly ESocket eSocket;
+
+        public ENetChannel(ESocket eSocket)
+        {
+            this.eSocket = eSocket;
+        }
+
+        public async void Dispose()
+        {
+            await this.eSocket.DisconnectLaterAsync();
+            this.eSocket.Dispose();
+        }
+
+        public void SendMessage<T>(ushort opcode, T message, byte channelID = 0)
+        {
+            byte[] protoBytes = ProtobufHelper.ToBytes(message);
+            var neworkBytes = new byte[sizeof (ushort) + protoBytes.Length];
+
+            var opcodeBytes = BitConverter.GetBytes(opcode);
+            opcodeBytes.CopyTo(neworkBytes, 0);
+            protoBytes.CopyTo(neworkBytes, sizeof (ushort));
+            this.eSocket.WriteAsync(neworkBytes, channelID);
+        }
+
+        public async Task<Tuple<ushort, byte[]>> RecvMessage()
+        {
+            var bytes = await this.eSocket.ReadAsync();
+            const int opcodeSize = sizeof (ushort);
+            ushort opcode = BitConverter.ToUInt16(bytes, 0);
+            byte flag = bytes[2];
+
+            switch (flag)
+            {
+                case 0:
+                {
+                    var messageBytes = new byte[bytes.Length - opcodeSize - 1];
+                    Array.Copy(bytes, opcodeSize + 1, messageBytes, 0, messageBytes.Length);
+                    return Tuple.Create(opcode, messageBytes);
+                }
+                default:
+                {
+                    var decompressStream = new MemoryStream();
+                    using (
+                            var zipStream =
+                                    new GZipStream(
+                                            new MemoryStream(bytes, opcodeSize + 5,
+                                                    bytes.Length - opcodeSize - 5),
+                                            CompressionMode.Decompress))
+                    {
+                        zipStream.CopyTo(decompressStream);
+                    }
+                    var decompressBytes = decompressStream.ToArray();
+                    return Tuple.Create(opcode, decompressBytes);
+                }
+            }
+        }
+    }
+}

+ 93 - 96
CSharp/App/BossClient/GateSession.cs

@@ -1,96 +1,93 @@
-using System;
-using System.Threading.Tasks;
-using BossBase;
-using Helper;
-using Logger;
-
-namespace BossClient
-{
-	public class GateSession: IDisposable
-	{
-		public int ID { get; set; }
-
-		public IMessageChannel IMessageChannel { get; set; }
-
-		public GateSession(int id, IMessageChannel eNetChannel)
-		{
-			this.ID = id;
-			this.IMessageChannel = eNetChannel;
-		}
-
-		public void Dispose()
-		{
-			this.IMessageChannel.Dispose();
-		}
-
-		public void SendMessage<T>(ushort opcode, T message, byte channelID = 0)
-		{
-			this.IMessageChannel.SendMessage(opcode, message, channelID);
-		}
-
-		public async Task Login(SRP6Client srp6Client)
-		{
-			var smsgAuthChallenge = await this.Handle_SMSG_Auth_Challenge();
-
-			var clientSeed = (uint)TimeHelper.EpochTimeSecond();
-			byte[] digest = srp6Client.CalculateGateDigest(clientSeed, smsgAuthChallenge.Seed);
-
-			var cmsgAuthSession = new CMSG_Auth_Session
-			{
-				ClientBuild = 11723,
-				ClientSeed = clientSeed,
-				Digest = digest,
-				Hd = new byte[0],
-				Mac = new byte[0],
-				Unk2 = 0,
-				Unk3 = 0,
-				Unk4 = 0,
-				Username = srp6Client.Account
-			};
-			this.IMessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_SESSION, cmsgAuthSession);
-
-			var smsgAuthResponse = await Handle_SMSG_Auth_Response();
-
-			if (smsgAuthResponse.ErrorCode != ErrorCode.AUTH_OK)
-			{
-				throw new BossException(string.Format(
-					"session: {0}, SMSG_Auth_Response: {1}",
-					this.ID, MongoHelper.ToJson(smsgAuthResponse)));
-			}
-
-			Log.Trace("session: {0}, login gate OK!", this.ID);
-		}
-
-		public async Task<SMSG_Auth_Challenge> Handle_SMSG_Auth_Challenge()
-		{
-			var result = await this.IMessageChannel.RecvMessage();
-			ushort opcode = result.Item1;
-			byte[] message = result.Item2;
-			Log.Debug("message: {0}", message.ToHex());
-			if (opcode != MessageOpcode.SMSG_AUTH_CHALLENGE)
-			{
-				throw new BossException(string.Format(
-					"session: {0}, opcode: {1}", this.ID, opcode));
-			}
-
-			var smsgAuthChallenge = ProtobufHelper.FromBytes<SMSG_Auth_Challenge>(message);
-			return smsgAuthChallenge;
-		}
-
-		public async Task<SMSG_Auth_Response> Handle_SMSG_Auth_Response()
-		{
-			var result = await this.IMessageChannel.RecvMessage();
-			ushort opcode = result.Item1;
-			byte[] message = result.Item2;
-
-			if (opcode != MessageOpcode.SMSG_AUTH_RESPONSE)
-			{
-				throw new BossException(string.Format(
-					"session: {0}, opcode: {1}", this.ID, opcode));
-			}
-
-			var smsgAuthResponse = ProtobufHelper.FromBytes<SMSG_Auth_Response>(message);
-			return smsgAuthResponse;
-		}
-	}
-}
+using System;
+using System.Threading.Tasks;
+using BossBase;
+using Helper;
+using Logger;
+
+namespace BossClient
+{
+    public class GateSession: IDisposable
+    {
+        public int ID { get; set; }
+
+        public IMessageChannel IMessageChannel { get; set; }
+
+        public GateSession(int id, IMessageChannel eNetChannel)
+        {
+            this.ID = id;
+            this.IMessageChannel = eNetChannel;
+        }
+
+        public void Dispose()
+        {
+            this.IMessageChannel.Dispose();
+        }
+
+        public void SendMessage<T>(ushort opcode, T message, byte channelID = 0)
+        {
+            this.IMessageChannel.SendMessage(opcode, message, channelID);
+        }
+
+        public async Task Login(SRP6Client srp6Client)
+        {
+            var smsgAuthChallenge = await this.Handle_SMSG_Auth_Challenge();
+
+            var clientSeed = (uint) TimeHelper.EpochTimeSecond();
+            byte[] digest = srp6Client.CalculateGateDigest(clientSeed, smsgAuthChallenge.Seed);
+
+            var cmsgAuthSession = new CMSG_Auth_Session
+            {
+                ClientBuild = 11723,
+                ClientSeed = clientSeed,
+                Digest = digest,
+                Hd = new byte[0],
+                Mac = new byte[0],
+                Unk2 = 0,
+                Unk3 = 0,
+                Unk4 = 0,
+                Username = srp6Client.Account
+            };
+            this.IMessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_SESSION, cmsgAuthSession);
+
+            var smsgAuthResponse = await this.Handle_SMSG_Auth_Response();
+
+            if (smsgAuthResponse.ErrorCode != ErrorCode.AUTH_OK)
+            {
+                throw new BossException(string.Format("session: {0}, SMSG_Auth_Response: {1}",
+                        this.ID, MongoHelper.ToJson(smsgAuthResponse)));
+            }
+
+            Log.Trace("session: {0}, login gate OK!", this.ID);
+        }
+
+        public async Task<SMSG_Auth_Challenge> Handle_SMSG_Auth_Challenge()
+        {
+            var result = await this.IMessageChannel.RecvMessage();
+            ushort opcode = result.Item1;
+            byte[] message = result.Item2;
+            Log.Debug("message: {0}", message.ToHex());
+            if (opcode != MessageOpcode.SMSG_AUTH_CHALLENGE)
+            {
+                throw new BossException(string.Format("session: {0}, opcode: {1}", this.ID, opcode));
+            }
+
+            var smsgAuthChallenge = ProtobufHelper.FromBytes<SMSG_Auth_Challenge>(message);
+            return smsgAuthChallenge;
+        }
+
+        public async Task<SMSG_Auth_Response> Handle_SMSG_Auth_Response()
+        {
+            var result = await this.IMessageChannel.RecvMessage();
+            ushort opcode = result.Item1;
+            byte[] message = result.Item2;
+
+            if (opcode != MessageOpcode.SMSG_AUTH_RESPONSE)
+            {
+                throw new BossException(string.Format("session: {0}, opcode: {1}", this.ID, opcode));
+            }
+
+            var smsgAuthResponse = ProtobufHelper.FromBytes<SMSG_Auth_Response>(message);
+            return smsgAuthResponse;
+        }
+    }
+}

+ 37 - 34
CSharp/App/BossClient/Properties/AssemblyInfo.cs

@@ -1,36 +1,39 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 有关程序集的常规信息通过以下
-// 特性集控制。更改这些特性值可修改
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// 有关程序集的常规信息通过以下
+// 特性集控制。更改这些特性值可修改
 // 与程序集关联的信息。
-[assembly: AssemblyTitle("BossClient")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
+
+[assembly: AssemblyTitle("BossClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("BossClient")]
-[assembly: AssemblyCopyright("Copyright ©  2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 将 ComVisible 设置为 false 使此程序集中的类型
-// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
-// 则将该类型上的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("46a9e699-b647-4fde-bcc1-5bb0aead64ff")]
-
-// 程序集的版本信息由下面四个值组成:
-//
-//      主版本
-//      次版本 
-//      生成号
-//      修订号
-//
-// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
-// 方法是按如下所示使用“*”:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyProduct("BossClient")]
+[assembly: AssemblyCopyright("Copyright ©  2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 使此程序集中的类型
+// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
+// 则将该类型上的 ComVisible 特性设置为 true。
+
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+
+[assembly: Guid("46a9e699-b647-4fde-bcc1-5bb0aead64ff")]
+
+// 程序集的版本信息由下面四个值组成:
+//
+//      主版本
+//      次版本 
+//      生成号
+//      修订号
+//
+// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
+// 方法是按如下所示使用“*”:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 188 - 189
CSharp/App/BossClient/RealmSession.cs

@@ -1,190 +1,189 @@
-using System;
-using System.Security.Cryptography;
-using System.Threading.Tasks;
-using BossBase;
-using Helper;
-using Logger;
-
-namespace BossClient
-{
-	public class RealmSession: IDisposable
-	{
-		public int ID { get; set; }
-
-		public IMessageChannel MessageChannel { get; set; }
-
-		public RealmSession(int id, IMessageChannel messageChannel)
-		{
-			this.ID = id;
-			this.MessageChannel = messageChannel;
-		}
-
-		public void Dispose()
-		{
-			this.MessageChannel.Dispose();
-		}
-
-		public async Task<SMSG_Password_Protect_Type> Handle_SMSG_Password_Protect_Type()
-		{
-			var result = await this.MessageChannel.RecvMessage();
-			ushort opcode = result.Item1;
-			byte[] message = result.Item2;
-
-			if (opcode != MessageOpcode.SMSG_PASSWORD_PROTECT_TYPE)
-			{
-				throw new BossException(string.Format(
-					"session: {0}, opcode: {1}", this.ID, opcode));
-			}
-
-			var smsgPasswordProtectType = 
-				ProtobufHelper.FromBytes<SMSG_Password_Protect_Type>(message);
-
-			return smsgPasswordProtectType;
-		}
-
-		public async Task<SMSG_Auth_Logon_Challenge_Response>
-			Handle_SMSG_Auth_Logon_Challenge_Response()
-		{
-			var result = await this.MessageChannel.RecvMessage();
-			ushort opcode = result.Item1;
-			byte[] message = result.Item2;
-
-			if (opcode != MessageOpcode.SMSG_AUTH_LOGON_CHALLENGE_RESPONSE)
-			{
-				Log.Trace("opcode: {0}", opcode);
-				throw new BossException(string.Format(
-					"session: {0}, opcode: {1}", this.ID, opcode));
-			}
-			
-			var smsgAuthLogonChallengeResponse =
-				ProtobufHelper.FromBytes<SMSG_Auth_Logon_Challenge_Response>(message);
-
-			return smsgAuthLogonChallengeResponse;
-		}
-
-		public async Task<SMSG_Auth_Logon_Proof_M2> Handle_SMSG_Auth_Logon_Proof_M2()
-		{
-			var result = await this.MessageChannel.RecvMessage();
-			ushort opcode = result.Item1;
-			byte[] message = result.Item2;
-
-			if (opcode != MessageOpcode.SMSG_AUTH_LOGON_PROOF_M2)
-			{
-				throw new BossException(string.Format(
-					"session: {0}, error opcode: {1}", this.ID, opcode));
-			}
-
-			var smsgAuthLogonProofM2 = ProtobufHelper.FromBytes<SMSG_Auth_Logon_Proof_M2>(message);
-			return smsgAuthLogonProofM2;
-		}
-
-		public async Task<SMSG_Realm_List> Handle_SMSG_Realm_List()
-		{
-			var result = await this.MessageChannel.RecvMessage();
-			ushort opcode = result.Item1;
-			byte[] message = result.Item2;
-
-			if (opcode != MessageOpcode.SMSG_REALM_LIST)
-			{
-				throw new BossException(string.Format(
-					"session: {0}, error opcode: {1}", this.ID, opcode));
-			}
-
-			var smsgRealmList = ProtobufHelper.FromBytes<SMSG_Realm_List>(message);
-
-			return smsgRealmList;
-		}
-
-		public async Task<Tuple<string, ushort, SRP6Client>> Login(string account, string password)
-		{
-			byte[] passwordBytes = password.ToByteArray();
-			MD5 md5 = MD5.Create();
-			byte[] passwordMd5 = md5.ComputeHash(passwordBytes);
-			byte[] passwordMd5Hex = passwordMd5.ToHex().ToLower().ToByteArray();
-
-			// 发送帐号和密码MD5
-			var cmsgAuthLogonPermit = new CMSG_Auth_Logon_Permit
-			{ 
-				Account = account.ToByteArray(),
-				PasswordMd5 = passwordMd5Hex
-			};
-			
-			Log.Trace("session: {0}, account: {1}, password: {2}", this.ID,
-				cmsgAuthLogonPermit.Account.ToStr(), cmsgAuthLogonPermit.PasswordMd5.ToHex());
-
-			this.MessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_LOGON_PERMIT, cmsgAuthLogonPermit);
-
-			var smsgPasswordProtectType = await this.Handle_SMSG_Password_Protect_Type();
-			if (smsgPasswordProtectType.Code != 200)
-			{
-				throw new BossException(string.Format(
-					"session: {0}, SMSG_Password_Protect_Type: {1}",
-					this.ID, MongoHelper.ToJson(smsgPasswordProtectType)));
-			}
-
-			// 这个消息已经没有作用,只用来保持原有的代码流程
-			var cmsgAuthLogonChallenge = new CMSG_Auth_Logon_Challenge();
-			this.MessageChannel.SendMessage(
-				MessageOpcode.CMSG_AUTH_LOGON_CHALLENGE, cmsgAuthLogonChallenge);
-
-			var smsgAuthLogonChallengeResponse = 
-				await this.Handle_SMSG_Auth_Logon_Challenge_Response();
-			if (smsgAuthLogonChallengeResponse.ErrorCode != ErrorCode.REALM_AUTH_SUCCESS)
-			{
-				throw new BossException(
-					string.Format("session: {0}, SMSG_Auth_Logon_Challenge_Response: {1}",
-					this.ID, MongoHelper.ToJson(smsgAuthLogonChallengeResponse)));
-			}
-
-			Log.Trace("session: {0}, SMSG_Auth_Logon_Challenge_Response OK", this.ID);
-
-			// 以下是SRP6处理过程
-			var n = smsgAuthLogonChallengeResponse.N.ToUBigInteger();
-			var g = smsgAuthLogonChallengeResponse.G.ToUBigInteger();
-			var b = smsgAuthLogonChallengeResponse.B.ToUBigInteger();
-			var salt = smsgAuthLogonChallengeResponse.S.ToUBigInteger();
-
-			var srp6Client = new SRP6Client(
-				new SHA1Managed(), n, g, b, salt, account.ToByteArray(), passwordMd5Hex);
-
-			Log.Debug("s: {0}\nN: {1}\nG: {2}\nB: {3}\nA: {4}\nS: {5}\nK: {6}\nm: {7}\na: {8}",
-				srp6Client.Salt.ToUBigIntegerArray().ToHex(),
-				srp6Client.N.ToUBigIntegerArray().ToHex(), 
-				srp6Client.G.ToUBigIntegerArray().ToHex(),
-				srp6Client.B.ToUBigIntegerArray().ToHex(),
-				srp6Client.A.ToUBigIntegerArray().ToHex(), 
-				srp6Client.S.ToUBigIntegerArray().ToHex(),
-				srp6Client.K.ToUBigIntegerArray().ToHex(), 
-				srp6Client.M.ToUBigIntegerArray().ToHex(),
-				srp6Client.SmallA.ToUBigIntegerArray().ToHex());
-
-			var cmsgAuthLogonProof = new CMSG_Auth_Logon_Proof
-			{
-				A = srp6Client.A.ToUBigIntegerArray(),
-				M = srp6Client.M.ToUBigIntegerArray()
-			};
-			this.MessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_LOGON_PROOF, cmsgAuthLogonProof);
-
-			var smsgAuthLogonProofM2 = await this.Handle_SMSG_Auth_Logon_Proof_M2();
-			if (smsgAuthLogonProofM2.ErrorCode != ErrorCode.REALM_AUTH_SUCCESS)
-			{
-				throw new BossException(string.Format(
-					"session: {0}, SMSG_Auth_Logon_Proof_M2: {1}",
-					this.ID, MongoHelper.ToJson(smsgAuthLogonProofM2)));
-			}
-
-			Log.Trace("session: {0}, SMSG_Auth_Logon_Proof_M2 OK", this.ID);
-
-			// 请求realm list
-			var cmsgRealmList = new CMSG_Realm_List();
-			this.MessageChannel.SendMessage(MessageOpcode.CMSG_REALM_LIST, cmsgRealmList);
-			var smsgRealmList = await this.Handle_SMSG_Realm_List();
-
-			Log.Trace("session: {0}, SMSG_Realm_List OK", this.ID);
-
-			string gateIP = smsgRealmList.GateIP;
-			ushort gatePort = (ushort)smsgRealmList.GatePort;
-			return Tuple.Create(gateIP, gatePort, srp6Client);
-		}
-	}
+using System;
+using System.Security.Cryptography;
+using System.Threading.Tasks;
+using BossBase;
+using Helper;
+using Logger;
+
+namespace BossClient
+{
+    public class RealmSession: IDisposable
+    {
+        public int ID { get; set; }
+
+        public IMessageChannel MessageChannel { get; set; }
+
+        public RealmSession(int id, IMessageChannel messageChannel)
+        {
+            this.ID = id;
+            this.MessageChannel = messageChannel;
+        }
+
+        public void Dispose()
+        {
+            this.MessageChannel.Dispose();
+        }
+
+        public async Task<SMSG_Password_Protect_Type> Handle_SMSG_Password_Protect_Type()
+        {
+            var result = await this.MessageChannel.RecvMessage();
+            ushort opcode = result.Item1;
+            byte[] message = result.Item2;
+
+            if (opcode != MessageOpcode.SMSG_PASSWORD_PROTECT_TYPE)
+            {
+                throw new BossException(string.Format("session: {0}, opcode: {1}", this.ID, opcode));
+            }
+
+            var smsgPasswordProtectType =
+                    ProtobufHelper.FromBytes<SMSG_Password_Protect_Type>(message);
+
+            return smsgPasswordProtectType;
+        }
+
+        public async Task<SMSG_Auth_Logon_Challenge_Response>
+                Handle_SMSG_Auth_Logon_Challenge_Response()
+        {
+            var result = await this.MessageChannel.RecvMessage();
+            ushort opcode = result.Item1;
+            byte[] message = result.Item2;
+
+            if (opcode != MessageOpcode.SMSG_AUTH_LOGON_CHALLENGE_RESPONSE)
+            {
+                Log.Trace("opcode: {0}", opcode);
+                throw new BossException(string.Format("session: {0}, opcode: {1}", this.ID, opcode));
+            }
+
+            var smsgAuthLogonChallengeResponse =
+                    ProtobufHelper.FromBytes<SMSG_Auth_Logon_Challenge_Response>(message);
+
+            return smsgAuthLogonChallengeResponse;
+        }
+
+        public async Task<SMSG_Auth_Logon_Proof_M2> Handle_SMSG_Auth_Logon_Proof_M2()
+        {
+            var result = await this.MessageChannel.RecvMessage();
+            ushort opcode = result.Item1;
+            byte[] message = result.Item2;
+
+            if (opcode != MessageOpcode.SMSG_AUTH_LOGON_PROOF_M2)
+            {
+                throw new BossException(string.Format("session: {0}, error opcode: {1}", this.ID,
+                        opcode));
+            }
+
+            var smsgAuthLogonProofM2 = ProtobufHelper.FromBytes<SMSG_Auth_Logon_Proof_M2>(message);
+            return smsgAuthLogonProofM2;
+        }
+
+        public async Task<SMSG_Realm_List> Handle_SMSG_Realm_List()
+        {
+            var result = await this.MessageChannel.RecvMessage();
+            ushort opcode = result.Item1;
+            byte[] message = result.Item2;
+
+            if (opcode != MessageOpcode.SMSG_REALM_LIST)
+            {
+                throw new BossException(string.Format("session: {0}, error opcode: {1}", this.ID,
+                        opcode));
+            }
+
+            var smsgRealmList = ProtobufHelper.FromBytes<SMSG_Realm_List>(message);
+
+            return smsgRealmList;
+        }
+
+        public async Task<Tuple<string, ushort, SRP6Client>> Login(string account, string password)
+        {
+            byte[] passwordBytes = password.ToByteArray();
+            MD5 md5 = MD5.Create();
+            byte[] passwordMd5 = md5.ComputeHash(passwordBytes);
+            byte[] passwordMd5Hex = passwordMd5.ToHex().ToLower().ToByteArray();
+
+            // 发送帐号和密码MD5
+            var cmsgAuthLogonPermit = new CMSG_Auth_Logon_Permit
+            {
+                Account = account.ToByteArray(),
+                PasswordMd5 = passwordMd5Hex
+            };
+
+            Log.Trace("session: {0}, account: {1}, password: {2}", this.ID,
+                    cmsgAuthLogonPermit.Account.ToStr(), cmsgAuthLogonPermit.PasswordMd5.ToHex());
+
+            this.MessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_LOGON_PERMIT,
+                    cmsgAuthLogonPermit);
+
+            var smsgPasswordProtectType = await this.Handle_SMSG_Password_Protect_Type();
+            if (smsgPasswordProtectType.Code != 200)
+            {
+                throw new BossException(
+                        string.Format("session: {0}, SMSG_Password_Protect_Type: {1}", this.ID,
+                                MongoHelper.ToJson(smsgPasswordProtectType)));
+            }
+
+            // 这个消息已经没有作用,只用来保持原有的代码流程
+            var cmsgAuthLogonChallenge = new CMSG_Auth_Logon_Challenge();
+            this.MessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_LOGON_CHALLENGE,
+                    cmsgAuthLogonChallenge);
+
+            var smsgAuthLogonChallengeResponse =
+                    await this.Handle_SMSG_Auth_Logon_Challenge_Response();
+            if (smsgAuthLogonChallengeResponse.ErrorCode != ErrorCode.REALM_AUTH_SUCCESS)
+            {
+                throw new BossException(
+                        string.Format("session: {0}, SMSG_Auth_Logon_Challenge_Response: {1}",
+                                this.ID, MongoHelper.ToJson(smsgAuthLogonChallengeResponse)));
+            }
+
+            Log.Trace("session: {0}, SMSG_Auth_Logon_Challenge_Response OK", this.ID);
+
+            // 以下是SRP6处理过程
+            var n = smsgAuthLogonChallengeResponse.N.ToUBigInteger();
+            var g = smsgAuthLogonChallengeResponse.G.ToUBigInteger();
+            var b = smsgAuthLogonChallengeResponse.B.ToUBigInteger();
+            var salt = smsgAuthLogonChallengeResponse.S.ToUBigInteger();
+
+            var srp6Client = new SRP6Client(new SHA1Managed(), n, g, b, salt, account.ToByteArray(),
+                    passwordMd5Hex);
+
+            Log.Debug("s: {0}\nN: {1}\nG: {2}\nB: {3}\nA: {4}\nS: {5}\nK: {6}\nm: {7}\na: {8}",
+                    srp6Client.Salt.ToUBigIntegerArray().ToHex(),
+                    srp6Client.N.ToUBigIntegerArray().ToHex(),
+                    srp6Client.G.ToUBigIntegerArray().ToHex(),
+                    srp6Client.B.ToUBigIntegerArray().ToHex(),
+                    srp6Client.A.ToUBigIntegerArray().ToHex(),
+                    srp6Client.S.ToUBigIntegerArray().ToHex(),
+                    srp6Client.K.ToUBigIntegerArray().ToHex(),
+                    srp6Client.M.ToUBigIntegerArray().ToHex(),
+                    srp6Client.SmallA.ToUBigIntegerArray().ToHex());
+
+            var cmsgAuthLogonProof = new CMSG_Auth_Logon_Proof
+            {
+                A = srp6Client.A.ToUBigIntegerArray(),
+                M = srp6Client.M.ToUBigIntegerArray()
+            };
+            this.MessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_LOGON_PROOF, cmsgAuthLogonProof);
+
+            var smsgAuthLogonProofM2 = await this.Handle_SMSG_Auth_Logon_Proof_M2();
+            if (smsgAuthLogonProofM2.ErrorCode != ErrorCode.REALM_AUTH_SUCCESS)
+            {
+                throw new BossException(string.Format(
+                                                      "session: {0}, SMSG_Auth_Logon_Proof_M2: {1}",
+                        this.ID, MongoHelper.ToJson(smsgAuthLogonProofM2)));
+            }
+
+            Log.Trace("session: {0}, SMSG_Auth_Logon_Proof_M2 OK", this.ID);
+
+            // 请求realm list
+            var cmsgRealmList = new CMSG_Realm_List();
+            this.MessageChannel.SendMessage(MessageOpcode.CMSG_REALM_LIST, cmsgRealmList);
+            var smsgRealmList = await this.Handle_SMSG_Realm_List();
+
+            Log.Trace("session: {0}, SMSG_Realm_List OK", this.ID);
+
+            string gateIP = smsgRealmList.GateIP;
+            ushort gatePort = (ushort) smsgRealmList.GatePort;
+            return Tuple.Create(gateIP, gatePort, srp6Client);
+        }
+    }
 }

+ 287 - 286
CSharp/App/BossClient/SRP6Client.cs

@@ -1,286 +1,287 @@
-using System;
-using System.Linq;
-using System.Numerics;
-using System.Security.Cryptography;
-using Helper;
-
-namespace BossClient
-{
-	public class SRP6Client
-	{
-		private readonly BigInteger n;    // N
-		private readonly BigInteger g;    // g
-		private readonly BigInteger b;    // B
-		private readonly BigInteger a;    // A
-		private readonly BigInteger x;    // X
-		private readonly BigInteger u;    // U
-		private readonly BigInteger s;    // S
-		private readonly BigInteger k;    // K
-		private readonly BigInteger m;        // M
-		private readonly byte[] p;
-		private readonly byte[] account;
-		private readonly BigInteger salt; // s, 服务端发过来的salt
-		private const int lowerK = 3;
-		private readonly BigInteger smallA ;
-		private readonly HashAlgorithm hashAlgorithm;
-
-		public SRP6Client(
-			HashAlgorithm hashAlgorithm, BigInteger n, BigInteger g, BigInteger b,
-			BigInteger salt, byte[] account, byte[] passwordMd5Hex)
-		{
-			this.smallA = BigIntegerHelper.RandUnsignedBigInteger(19);
-
-			this.hashAlgorithm = hashAlgorithm;
-			this.n = n;
-			this.g = g;
-			this.b = b;
-			this.salt = salt;
-			this.account = account;
-			this.p = hashAlgorithm.ComputeHash(new byte[0]
-				.Concat(account)
-				.Concat(new[] { (byte)':' })
-				.Concat(passwordMd5Hex)
-				.ToArray());
-
-			this.a = this.CalculateA();  // A = g ^ a % N
-			this.x = this.CalculateX();  // X = H(s, P)
-			this.u = this.CalculateU();  // U = H(A, B)
-			this.s = this.CalculateS();  // S = (B - (k * g.ModExp(x, N))).ModExp(a + (u * x), N)
-			this.k = this.CalculateK();
-			this.m = this.CalculateM();  // H(H(N) ^ H(g), H(P), s, A, B, K)
-		}
-
-		public BigInteger N
-		{
-			get
-			{
-				return this.n;
-			}
-		}
-
-		public BigInteger G
-		{
-			get
-			{
-				return this.g;
-			}
-		}
-
-		public BigInteger B
-		{
-			get
-			{
-				return this.b;
-			}
-		}
-
-		public BigInteger A
-		{
-			get
-			{
-				return this.a;
-			}
-		}
-
-		public BigInteger X
-		{
-			get
-			{
-				return this.x;
-			}
-		}
-
-		public BigInteger U
-		{
-			get
-			{
-				return this.u;
-			}
-		}
-
-		public BigInteger S
-		{
-			get
-			{
-				return this.s;
-			}
-		}
-
-		public BigInteger K
-		{
-			get
-			{
-				return this.k;
-			}
-		}
-
-		public BigInteger M
-		{
-			get
-			{
-				return this.m;
-			}
-		}
-
-		public byte[] P
-		{
-			get
-			{
-				return this.p;
-			}
-		}
-
-		public BigInteger Salt
-		{
-			get
-			{
-				return this.salt;
-			}
-		}
-
-		public BigInteger SmallA
-		{
-			get
-			{
-				return this.smallA;
-			}
-		}
-
-		public byte[] Account
-		{
-			get
-			{
-				return this.account;
-			}
-		}
-
-		/// <summary>
-		/// 计算X: X = H(s, P)
-		/// </summary>
-		/// <returns></returns>
-		private BigInteger CalculateX()
-		{
-			hashAlgorithm.Initialize();
-			var joinBytes = new byte[0]
-				.Concat(this.Salt.ToUBigIntegerArray())
-				.Concat(this.P)
-				.ToArray();
-			return hashAlgorithm.ComputeHash(joinBytes).ToUBigInteger();
-		}
-
-		/// <summary>
-		/// 计算A: A = g ^ a % N
-		/// </summary>
-		/// <returns></returns>
-		private BigInteger CalculateA()
-		{
-			return BigIntegerHelper.UModPow(this.G, this.SmallA, this.N);
-		}
-
-		/// <summary>
-		/// 计算U: U = H(A, B)
-		/// </summary>
-		/// <returns></returns>
-		private BigInteger CalculateU()
-		{
-			hashAlgorithm.Initialize();
-
-			var joinBytes = new byte[0]
-				.Concat(this.A.ToUBigIntegerArray(32))
-				.Concat(this.B.ToUBigIntegerArray(32))
-				.ToArray();
-			return hashAlgorithm.ComputeHash(joinBytes).ToUBigInteger();
-		}
-
-		/// <summary>
-		/// 计算S: S = (B - (k * g.ModExp(x, N))).ModExp(a + (u * x), N);
-		/// </summary>
-		/// <returns></returns>
-		private BigInteger CalculateS()
-		{
-			BigInteger s1 = this.B - BigIntegerHelper.UModPow(this.G, this.X, this.N) * lowerK;
-			BigInteger s2 = this.SmallA + (this.U * this.X);
-			BigInteger s3 = BigIntegerHelper.UModPow(s1, s2, this.N);
-			return s3;
-		}
-
-		/// <summary>
-		/// 
-		/// </summary>
-		/// <returns></returns>
-		private BigInteger CalculateK()
-		{
-			hashAlgorithm.Initialize();
-			byte[] sBytes = this.S.ToUBigIntegerArray();
-			int halfLength = sBytes.Length / 2;
-			var kBytes = new byte[40];
-			var halfS = new byte[halfLength];
-
-			for (int i = 0; i < halfLength; ++i)
-			{
-				halfS[i] = sBytes[i * 2];
-			}
-			var p1 = hashAlgorithm.ComputeHash(halfS);
-			for (int i = 0; i < 20; ++i)
-			{
-				kBytes[i * 2] = p1[i];
-			}
-
-			for (int i = 0; i < halfLength; ++i)
-			{
-				halfS[i] = sBytes[i * 2 + 1];
-			}
-			var p2 = hashAlgorithm.ComputeHash(halfS);
-			for (int i = 0; i < 20; ++i)
-			{
-				kBytes[i * 2 + 1] = p2[i];
-			}
-
-			return kBytes.ToUBigInteger();
-		}
-
-		/// <summary>
-		/// 
-		/// </summary>
-		/// <returns></returns>
-		private BigInteger CalculateM()
-		{
-			hashAlgorithm.Initialize();
-			var hashN = hashAlgorithm.ComputeHash(this.N.ToUBigIntegerArray());
-			var hashG = hashAlgorithm.ComputeHash(this.G.ToUBigIntegerArray());
-
-			// 这里与标准srp6不一样,只异或了20个byte,实际上有32个byte
-			for (var i = 0; i < 20; ++i)
-			{
-				hashN[i] ^= hashG[i];
-			}
-
-			var hashGXorhashN = hashN; // H(N) ^ H(g)
-			var hashedIdentity = hashAlgorithm.ComputeHash(this.Account); // H(I)
-
-			// H(H(N) ^ H(g), H(P), s, A, B, K_c)
-			var mBytes = hashAlgorithm.ComputeHash(new byte[0]
-				.Concat(hashGXorhashN)
-				.Concat(hashedIdentity)
-				.Concat(this.Salt.ToUBigIntegerArray(32))
-				.Concat(this.A.ToUBigIntegerArray(32))
-				.Concat(this.B.ToUBigIntegerArray(32))
-				.Concat(this.K.ToUBigIntegerArray(40))
-				.ToArray());
-			return mBytes.ToUBigInteger();
-		}
-
-		public byte[] CalculateGateDigest(uint clientSeed, uint serverSeed)
-		{
-			hashAlgorithm.Initialize();
-			var digest = hashAlgorithm.ComputeHash(new byte[0]
-				.Concat(this.Account)
-				.Concat(new byte[4] { 0, 0, 0, 0 })
-				.Concat(BitConverter.GetBytes(clientSeed))
-				.Concat(BitConverter.GetBytes(serverSeed))
-				.Concat(k.ToUBigIntegerArray())
-				.ToArray());
-			return digest;
-		}
-	}
-}
+using System;
+using System.Linq;
+using System.Numerics;
+using System.Security.Cryptography;
+using Helper;
+
+namespace BossClient
+{
+    public class SRP6Client
+    {
+        private readonly BigInteger n; // N
+        private readonly BigInteger g; // g
+        private readonly BigInteger b; // B
+        private readonly BigInteger a; // A
+        private readonly BigInteger x; // X
+        private readonly BigInteger u; // U
+        private readonly BigInteger s; // S
+        private readonly BigInteger k; // K
+        private readonly BigInteger m; // M
+        private readonly byte[] p;
+        private readonly byte[] account;
+        private readonly BigInteger salt; // s, 服务端发过来的salt
+        private const int lowerK = 3;
+        private readonly BigInteger smallA;
+        private readonly HashAlgorithm hashAlgorithm;
+
+        public SRP6Client(
+                HashAlgorithm hashAlgorithm, BigInteger n, BigInteger g, BigInteger b,
+                BigInteger salt, byte[] account, byte[] passwordMd5Hex)
+        {
+            this.smallA = BigIntegerHelper.RandUnsignedBigInteger(19);
+
+            this.hashAlgorithm = hashAlgorithm;
+            this.n = n;
+            this.g = g;
+            this.b = b;
+            this.salt = salt;
+            this.account = account;
+            this.p =
+                    hashAlgorithm.ComputeHash(
+                                              new byte[0].Concat(account)
+                                                      .Concat(new[] { (byte) ':' })
+                                                      .Concat(passwordMd5Hex)
+                                                      .ToArray());
+
+            this.a = this.CalculateA(); // A = g ^ a % N
+            this.x = this.CalculateX(); // X = H(s, P)
+            this.u = this.CalculateU(); // U = H(A, B)
+            this.s = this.CalculateS(); // S = (B - (k * g.ModExp(x, N))).ModExp(a + (u * x), N)
+            this.k = this.CalculateK();
+            this.m = this.CalculateM(); // H(H(N) ^ H(g), H(P), s, A, B, K)
+        }
+
+        public BigInteger N
+        {
+            get
+            {
+                return this.n;
+            }
+        }
+
+        public BigInteger G
+        {
+            get
+            {
+                return this.g;
+            }
+        }
+
+        public BigInteger B
+        {
+            get
+            {
+                return this.b;
+            }
+        }
+
+        public BigInteger A
+        {
+            get
+            {
+                return this.a;
+            }
+        }
+
+        public BigInteger X
+        {
+            get
+            {
+                return this.x;
+            }
+        }
+
+        public BigInteger U
+        {
+            get
+            {
+                return this.u;
+            }
+        }
+
+        public BigInteger S
+        {
+            get
+            {
+                return this.s;
+            }
+        }
+
+        public BigInteger K
+        {
+            get
+            {
+                return this.k;
+            }
+        }
+
+        public BigInteger M
+        {
+            get
+            {
+                return this.m;
+            }
+        }
+
+        public byte[] P
+        {
+            get
+            {
+                return this.p;
+            }
+        }
+
+        public BigInteger Salt
+        {
+            get
+            {
+                return this.salt;
+            }
+        }
+
+        public BigInteger SmallA
+        {
+            get
+            {
+                return this.smallA;
+            }
+        }
+
+        public byte[] Account
+        {
+            get
+            {
+                return this.account;
+            }
+        }
+
+        /// <summary>
+        /// 计算X: X = H(s, P)
+        /// </summary>
+        /// <returns></returns>
+        private BigInteger CalculateX()
+        {
+            this.hashAlgorithm.Initialize();
+            var joinBytes =
+                    new byte[0].Concat(this.Salt.ToUBigIntegerArray()).Concat(this.P).ToArray();
+            return this.hashAlgorithm.ComputeHash(joinBytes).ToUBigInteger();
+        }
+
+        /// <summary>
+        /// 计算A: A = g ^ a % N
+        /// </summary>
+        /// <returns></returns>
+        private BigInteger CalculateA()
+        {
+            return BigIntegerHelper.UModPow(this.G, this.SmallA, this.N);
+        }
+
+        /// <summary>
+        /// 计算U: U = H(A, B)
+        /// </summary>
+        /// <returns></returns>
+        private BigInteger CalculateU()
+        {
+            this.hashAlgorithm.Initialize();
+
+            var joinBytes =
+                    new byte[0].Concat(this.A.ToUBigIntegerArray(32))
+                            .Concat(this.B.ToUBigIntegerArray(32))
+                            .ToArray();
+            return this.hashAlgorithm.ComputeHash(joinBytes).ToUBigInteger();
+        }
+
+        /// <summary>
+        /// 计算S: S = (B - (k * g.ModExp(x, N))).ModExp(a + (u * x), N);
+        /// </summary>
+        /// <returns></returns>
+        private BigInteger CalculateS()
+        {
+            BigInteger s1 = this.B - BigIntegerHelper.UModPow(this.G, this.X, this.N) * lowerK;
+            BigInteger s2 = this.SmallA + (this.U * this.X);
+            BigInteger s3 = BigIntegerHelper.UModPow(s1, s2, this.N);
+            return s3;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns></returns>
+        private BigInteger CalculateK()
+        {
+            this.hashAlgorithm.Initialize();
+            byte[] sBytes = this.S.ToUBigIntegerArray();
+            int halfLength = sBytes.Length / 2;
+            var kBytes = new byte[40];
+            var halfS = new byte[halfLength];
+
+            for (int i = 0; i < halfLength; ++i)
+            {
+                halfS[i] = sBytes[i * 2];
+            }
+            var p1 = this.hashAlgorithm.ComputeHash(halfS);
+            for (int i = 0; i < 20; ++i)
+            {
+                kBytes[i * 2] = p1[i];
+            }
+
+            for (int i = 0; i < halfLength; ++i)
+            {
+                halfS[i] = sBytes[i * 2 + 1];
+            }
+            var p2 = this.hashAlgorithm.ComputeHash(halfS);
+            for (int i = 0; i < 20; ++i)
+            {
+                kBytes[i * 2 + 1] = p2[i];
+            }
+
+            return kBytes.ToUBigInteger();
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns></returns>
+        private BigInteger CalculateM()
+        {
+            this.hashAlgorithm.Initialize();
+            var hashN = this.hashAlgorithm.ComputeHash(this.N.ToUBigIntegerArray());
+            var hashG = this.hashAlgorithm.ComputeHash(this.G.ToUBigIntegerArray());
+
+            // 这里与标准srp6不一样,只异或了20个byte,实际上有32个byte
+            for (var i = 0; i < 20; ++i)
+            {
+                hashN[i] ^= hashG[i];
+            }
+
+            var hashGXorhashN = hashN; // H(N) ^ H(g)
+            var hashedIdentity = this.hashAlgorithm.ComputeHash(this.Account); // H(I)
+
+            // H(H(N) ^ H(g), H(P), s, A, B, K_c)
+            var mBytes =
+                    this.hashAlgorithm.ComputeHash(
+                                                   new byte[0].Concat(hashGXorhashN)
+                                                           .Concat(hashedIdentity)
+                                                           .Concat(this.Salt.ToUBigIntegerArray(32))
+                                                           .Concat(this.A.ToUBigIntegerArray(32))
+                                                           .Concat(this.B.ToUBigIntegerArray(32))
+                                                           .Concat(this.K.ToUBigIntegerArray(40))
+                                                           .ToArray());
+            return mBytes.ToUBigInteger();
+        }
+
+        public byte[] CalculateGateDigest(uint clientSeed, uint serverSeed)
+        {
+            this.hashAlgorithm.Initialize();
+            var digest =
+                    this.hashAlgorithm.ComputeHash(
+                                                   new byte[0].Concat(this.Account)
+                                                           .Concat(new byte[4] { 0, 0, 0, 0 })
+                                                           .Concat(BitConverter.GetBytes(clientSeed))
+                                                           .Concat(BitConverter.GetBytes(serverSeed))
+                                                           .Concat(this.k.ToUBigIntegerArray())
+                                                           .ToArray());
+            return digest;
+        }
+    }
+}

+ 88 - 84
CSharp/App/BossClient/TcpChannel.cs

@@ -1,84 +1,88 @@
-using System;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-using BossBase;
-using Helper;
-using Logger;
-
-namespace BossClient
-{
-	public class TcpChannel: IMessageChannel
-	{
-		private readonly NetworkStream networkStream;
-
-		public TcpChannel(TcpClient tcpClient)
-		{
-			this.networkStream = tcpClient.GetStream();
-		}
-
-		public void Dispose()
-		{
-			this.networkStream.Dispose();
-		}
-
-		public async void SendMessage<T>(ushort opcode, T message, byte channelID = 0)
-		{
-			byte[] protoBytes = ProtobufHelper.ToBytes(message);
-			var neworkBytes = new byte[sizeof(int) + sizeof(ushort) + protoBytes.Length];
-
-			int totalSize = sizeof(ushort) + protoBytes.Length;
-
-			var totalSizeBytes = BitConverter.GetBytes(totalSize);
-			totalSizeBytes.CopyTo(neworkBytes, 0);
-
-			var opcodeBytes = BitConverter.GetBytes(opcode);
-			opcodeBytes.CopyTo(neworkBytes, sizeof(int));
-
-			protoBytes.CopyTo(neworkBytes, sizeof(int) + sizeof(ushort));
-
-			await this.networkStream.WriteAsync(neworkBytes, 0, neworkBytes.Length);
-		}
-
-		public async Task<Tuple<ushort, byte[]>> RecvMessage()
-		{
-			int totalReadSize = 0;
-			int needReadSize = sizeof(int);
-			var packetBytes = new byte[needReadSize];
-			while (totalReadSize != needReadSize)
-			{
-				int readSize = await this.networkStream.ReadAsync(
-					packetBytes, totalReadSize, packetBytes.Length);
-				if (readSize == 0)
-				{
-					throw new BossException("connection closed");
-				}
-				totalReadSize += readSize;
-			}
-
-			int packetSize = BitConverter.ToInt32(packetBytes, 0);
-			Log.Debug("packetSize: {0}", packetSize);
-
-			// 读opcode和message
-			totalReadSize = 0;
-			needReadSize = packetSize;
-			var contentBytes = new byte[needReadSize];
-			while (totalReadSize != needReadSize)
-			{
-				int readSize = await this.networkStream.ReadAsync(
-					contentBytes, totalReadSize, contentBytes.Length);
-				if (readSize == 0)
-				{
-					throw new BossException("connection closed");
-				}
-				totalReadSize += readSize;
-			}
-
-			ushort opcode = BitConverter.ToUInt16(contentBytes, 0);
-
-			var messageBytes = new byte[needReadSize - sizeof(ushort)];
-			Array.Copy(contentBytes, sizeof(ushort), messageBytes, 0, messageBytes.Length);
-
-			return Tuple.Create(opcode, messageBytes);
-		}
-	}
-}
+using System;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+using BossBase;
+using Helper;
+using Logger;
+
+namespace BossClient
+{
+    public class TcpChannel: IMessageChannel
+    {
+        private readonly NetworkStream networkStream;
+
+        public TcpChannel(TcpClient tcpClient)
+        {
+            this.networkStream = tcpClient.GetStream();
+        }
+
+        public void Dispose()
+        {
+            this.networkStream.Dispose();
+        }
+
+        public async void SendMessage<T>(ushort opcode, T message, byte channelID = 0)
+        {
+            byte[] protoBytes = ProtobufHelper.ToBytes(message);
+            var neworkBytes = new byte[sizeof (int) + sizeof (ushort) + protoBytes.Length];
+
+            int totalSize = sizeof (ushort) + protoBytes.Length;
+
+            var totalSizeBytes = BitConverter.GetBytes(totalSize);
+            totalSizeBytes.CopyTo(neworkBytes, 0);
+
+            var opcodeBytes = BitConverter.GetBytes(opcode);
+            opcodeBytes.CopyTo(neworkBytes, sizeof (int));
+
+            protoBytes.CopyTo(neworkBytes, sizeof (int) + sizeof (ushort));
+
+            await this.networkStream.WriteAsync(neworkBytes, 0, neworkBytes.Length);
+        }
+
+        public async Task<Tuple<ushort, byte[]>> RecvMessage()
+        {
+            int totalReadSize = 0;
+            int needReadSize = sizeof (int);
+            var packetBytes = new byte[needReadSize];
+            while (totalReadSize != needReadSize)
+            {
+                int readSize =
+                        await
+                                this.networkStream.ReadAsync(packetBytes, totalReadSize,
+                                        packetBytes.Length);
+                if (readSize == 0)
+                {
+                    throw new BossException("connection closed");
+                }
+                totalReadSize += readSize;
+            }
+
+            int packetSize = BitConverter.ToInt32(packetBytes, 0);
+            Log.Debug("packetSize: {0}", packetSize);
+
+            // 读opcode和message
+            totalReadSize = 0;
+            needReadSize = packetSize;
+            var contentBytes = new byte[needReadSize];
+            while (totalReadSize != needReadSize)
+            {
+                int readSize =
+                        await
+                                this.networkStream.ReadAsync(contentBytes, totalReadSize,
+                                        contentBytes.Length);
+                if (readSize == 0)
+                {
+                    throw new BossException("connection closed");
+                }
+                totalReadSize += readSize;
+            }
+
+            ushort opcode = BitConverter.ToUInt16(contentBytes, 0);
+
+            var messageBytes = new byte[needReadSize - sizeof (ushort)];
+            Array.Copy(contentBytes, sizeof (ushort), messageBytes, 0, messageBytes.Length);
+
+            return Tuple.Create(opcode, messageBytes);
+        }
+    }
+}

+ 53 - 53
CSharp/App/BossCommand/ABossCommand.cs

@@ -1,53 +1,53 @@
-using System;
-using System.Threading.Tasks;
-using BossBase;
-using Helper;
-using Logger;
-
-namespace BossCommand
-{
-	public abstract class ABossCommand
-	{
-		protected IMessageChannel IMessageChannel { get; set; }
-
-		protected void SendMessage(CMSG_Boss_Gm cmsgBossGm)
-		{
-			this.IMessageChannel.SendMessage(MessageOpcode.CMSG_BOSS_GM, cmsgBossGm);
-		}
-
-		public string CommandString { get; set; }
-
-		protected async Task<T> RecvMessage<T>()
-		{
-			var result = await this.IMessageChannel.RecvMessage();
-			ushort opcode = result.Item1;
-			byte[] content = result.Item2;
-
-			try
-			{
-				var message = ProtobufHelper.FromBytes<T>(content);
-				return message;
-			}
-			catch (Exception)
-			{
-				Log.Trace("parse message fail, opcode: {0}", opcode);
-				throw;
-			}
-		}
-
-		protected ABossCommand(IMessageChannel iMessageChannel)
-		{
-			this.IMessageChannel = iMessageChannel;
-		}
-
-		public virtual Task<object> DoAsync()
-		{
-			throw new NotImplementedException();
-		}
-
-		public void UndoAsync()
-		{
-			throw new NotImplementedException();
-		}
-	}
-}
+using System;
+using System.Threading.Tasks;
+using BossBase;
+using Helper;
+using Logger;
+
+namespace BossCommand
+{
+    public abstract class ABossCommand
+    {
+        protected IMessageChannel IMessageChannel { get; set; }
+
+        protected void SendMessage(CMSG_Boss_Gm cmsgBossGm)
+        {
+            this.IMessageChannel.SendMessage(MessageOpcode.CMSG_BOSS_GM, cmsgBossGm);
+        }
+
+        public string CommandString { get; set; }
+
+        protected async Task<T> RecvMessage<T>()
+        {
+            var result = await this.IMessageChannel.RecvMessage();
+            ushort opcode = result.Item1;
+            byte[] content = result.Item2;
+
+            try
+            {
+                var message = ProtobufHelper.FromBytes<T>(content);
+                return message;
+            }
+            catch (Exception)
+            {
+                Log.Trace("parse message fail, opcode: {0}", opcode);
+                throw;
+            }
+        }
+
+        protected ABossCommand(IMessageChannel iMessageChannel)
+        {
+            this.IMessageChannel = iMessageChannel;
+        }
+
+        public virtual Task<object> DoAsync()
+        {
+            throw new NotImplementedException();
+        }
+
+        public void UndoAsync()
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 22 - 22
CSharp/App/BossCommand/BCCommand.cs

@@ -1,22 +1,22 @@
-using System.Threading.Tasks;
-using BossBase;
-
-namespace BossCommand
-{
-	public class BCCommand : ABossCommand
-	{
-		public string Command { get; set; }
-
-		public BCCommand(IMessageChannel iMessageChannel) : base(iMessageChannel)
-		{
-		}
-
-		public override async Task<object> DoAsync()
-		{
-			this.SendMessage(new CMSG_Boss_Gm { Message = this.Command });
-
-			var smsgBossCommandResponse = await this.RecvMessage<SMSG_Boss_Command_Response>();
-			return smsgBossCommandResponse;
-		}
-	}
-}
+using System.Threading.Tasks;
+using BossBase;
+
+namespace BossCommand
+{
+    public class BCCommand: ABossCommand
+    {
+        public string Command { get; set; }
+
+        public BCCommand(IMessageChannel iMessageChannel): base(iMessageChannel)
+        {
+        }
+
+        public override async Task<object> DoAsync()
+        {
+            this.SendMessage(new CMSG_Boss_Gm { Message = this.Command });
+
+            var smsgBossCommandResponse = await this.RecvMessage<SMSG_Boss_Command_Response>();
+            return smsgBossCommandResponse;
+        }
+    }
+}

+ 25 - 25
CSharp/App/BossCommand/BCForbidLogin.cs

@@ -1,25 +1,25 @@
-using System.Threading.Tasks;
-using BossBase;
-
-namespace BossCommand
-{
-	public class BCForbidLogin: ABossCommand
-	{
-		public string Command { get; set; }
-		public string Content { get; set; }
-		public string ForbiddenLoginTime { get; set; }
-
-		public BCForbidLogin(IMessageChannel iMessageChannel): base(iMessageChannel)
-		{
-		}
-
-		public override async Task<object> DoAsync()
-		{
-			this.CommandString = string.Format(
-				"{0} {1} {2}", this.Command, this.Content, this.ForbiddenLoginTime);
-			this.SendMessage(new CMSG_Boss_Gm { Message = this.CommandString });
-			var smsgBossCommandResponse = await RecvMessage<SMSG_Boss_Command_Response>();
-			return smsgBossCommandResponse.ErrorCode;
-		}
-	}
-}
+using System.Threading.Tasks;
+using BossBase;
+
+namespace BossCommand
+{
+    public class BCForbidLogin: ABossCommand
+    {
+        public string Command { get; set; }
+        public string Content { get; set; }
+        public string ForbiddenLoginTime { get; set; }
+
+        public BCForbidLogin(IMessageChannel iMessageChannel): base(iMessageChannel)
+        {
+        }
+
+        public override async Task<object> DoAsync()
+        {
+            this.CommandString = string.Format("{0} {1} {2}", this.Command, this.Content,
+                    this.ForbiddenLoginTime);
+            this.SendMessage(new CMSG_Boss_Gm { Message = this.CommandString });
+            var smsgBossCommandResponse = await this.RecvMessage<SMSG_Boss_Command_Response>();
+            return smsgBossCommandResponse.ErrorCode;
+        }
+    }
+}

+ 25 - 25
CSharp/App/BossCommand/BCForbiddenCharacter.cs

@@ -1,25 +1,25 @@
-using System.Threading.Tasks;
-using BossBase;
-
-namespace BossCommand
-{
-	public class BCForbiddenCharacter: ABossCommand
-	{
-		public BCForbiddenCharacter(IMessageChannel iMessageChannel): 
-			base(iMessageChannel)
-		{
-		}
-
-		public string Guid { get; set; }
-		public string Command { get; set; }
-		public string ForbiddenTime { get; set; }
-
-		public override async Task<object> DoAsync()
-		{
-			this.CommandString = string.Format("{0} {1} {2}", this.Command, this.Guid, this.ForbiddenTime);
-			this.SendMessage(new CMSG_Boss_Gm { Message = CommandString });
-			var smsgBossCommandResponse = await this.RecvMessage<SMSG_Boss_Command_Response>();
-			return smsgBossCommandResponse.ErrorCode;
-		}
-	}
-}
+using System.Threading.Tasks;
+using BossBase;
+
+namespace BossCommand
+{
+    public class BCForbiddenCharacter: ABossCommand
+    {
+        public BCForbiddenCharacter(IMessageChannel iMessageChannel): base(iMessageChannel)
+        {
+        }
+
+        public string Guid { get; set; }
+        public string Command { get; set; }
+        public string ForbiddenTime { get; set; }
+
+        public override async Task<object> DoAsync()
+        {
+            this.CommandString = string.Format("{0} {1} {2}", this.Command, this.Guid,
+                    this.ForbiddenTime);
+            this.SendMessage(new CMSG_Boss_Gm { Message = this.CommandString });
+            var smsgBossCommandResponse = await this.RecvMessage<SMSG_Boss_Command_Response>();
+            return smsgBossCommandResponse.ErrorCode;
+        }
+    }
+}

+ 50 - 48
CSharp/App/BossCommand/BCGetCharacterInfo.cs

@@ -1,48 +1,50 @@
-using System;
-using System.Runtime.Serialization;
-using System.Threading.Tasks;
-using BossBase;
-using Helper;
-using Logger;
-
-namespace BossCommand
-{
-	public class BCGetCharacterInfo: ABossCommand
-	{
-		public BCGetCharacterInfo(IMessageChannel iMessageChannel): base(iMessageChannel)
-		{
-		}
-
-		public int FindTypeIndex { get; set; }
-
-		public string FindType { get; set; }
-
-		public override async Task<object> DoAsync()
-		{
-			this.CommandString = string.Format("get_character_info {0} {1} ", this.FindTypeIndex, this.FindType);
-			this.SendMessage(new CMSG_Boss_Gm { Message = CommandString });
-			var smsgBossCommandResponse = await this.RecvMessage<SMSG_Boss_Command_Response>();
-			if (smsgBossCommandResponse.ErrorCode != ErrorCode.RESPONSE_SUCCESS)
-			{
-				Log.Trace("get character info fail, error code: {0}", smsgBossCommandResponse.ErrorCode);
-				return null;
-			}
-
-			var characterInfo = MongoHelper.FromJson<CharacterInfo>(smsgBossCommandResponse.Content);
-			return characterInfo;
-		}
-	}
-
-	[DataContract]
-	public class CharacterInfo
-	{
-		[DataMember(Order = 0, IsRequired = false)]
-		public string Account { get; set; }
-
-		[DataMember(Order = 1, IsRequired = false)]
-		public string Name { get; set; }
-
-		[DataMember(Order = 2, IsRequired = false)]
-		public UInt64 Guid { get; set; }
-	}
-}
+using System;
+using System.Runtime.Serialization;
+using System.Threading.Tasks;
+using BossBase;
+using Helper;
+using Logger;
+
+namespace BossCommand
+{
+    public class BCGetCharacterInfo: ABossCommand
+    {
+        public BCGetCharacterInfo(IMessageChannel iMessageChannel): base(iMessageChannel)
+        {
+        }
+
+        public int FindTypeIndex { get; set; }
+
+        public string FindType { get; set; }
+
+        public override async Task<object> DoAsync()
+        {
+            this.CommandString = string.Format("get_character_info {0} {1} ", this.FindTypeIndex,
+                    this.FindType);
+            this.SendMessage(new CMSG_Boss_Gm { Message = this.CommandString });
+            var smsgBossCommandResponse = await this.RecvMessage<SMSG_Boss_Command_Response>();
+            if (smsgBossCommandResponse.ErrorCode != ErrorCode.RESPONSE_SUCCESS)
+            {
+                Log.Trace("get character info fail, error code: {0}",
+                        smsgBossCommandResponse.ErrorCode);
+                return null;
+            }
+
+            var characterInfo = MongoHelper.FromJson<CharacterInfo>(smsgBossCommandResponse.Content);
+            return characterInfo;
+        }
+    }
+
+    [DataContract]
+    public class CharacterInfo
+    {
+        [DataMember(Order = 0, IsRequired = false)]
+        public string Account { get; set; }
+
+        [DataMember(Order = 1, IsRequired = false)]
+        public string Name { get; set; }
+
+        [DataMember(Order = 2, IsRequired = false)]
+        public UInt64 Guid { get; set; }
+    }
+}

+ 18 - 18
CSharp/App/BossCommand/BCReloadWorld.cs

@@ -1,18 +1,18 @@
-using System.Threading.Tasks;
-using BossBase;
-
-namespace BossCommand
-{
-	public class BCReloadWorld: ABossCommand
-	{
-		public BCReloadWorld(IMessageChannel iMessageChannel): base(iMessageChannel)
-		{
-		}
-
-		public override Task<object> DoAsync()
-		{
-			this.SendMessage(new CMSG_Boss_Gm { Message = "reload" });
-			return null;
-		}
-	}
-}
+using System.Threading.Tasks;
+using BossBase;
+
+namespace BossCommand
+{
+    public class BCReloadWorld: ABossCommand
+    {
+        public BCReloadWorld(IMessageChannel iMessageChannel): base(iMessageChannel)
+        {
+        }
+
+        public override Task<object> DoAsync()
+        {
+            this.SendMessage(new CMSG_Boss_Gm { Message = "reload" });
+            return null;
+        }
+    }
+}

+ 26 - 27
CSharp/App/BossCommand/BCSendMail.cs

@@ -1,27 +1,26 @@
-
-using System.Threading.Tasks;
-using BossBase;
-using Helper;
-using Logger;
-
-namespace BossCommand
-{
-	public class BCSendMail: ABossCommand
-	{
-		public BossMail BossMail { get; set; }
-
-		public BCSendMail(IMessageChannel iMessageChannel): base(iMessageChannel)
-		{
-		}
-
-		public override async Task<object> DoAsync()
-		{
-			this.CommandString = string.Format(
-				"send_mail --json {0} ", MongoHelper.ToJson(this.BossMail));
-			Log.Trace(this.CommandString);
-			this.SendMessage(new CMSG_Boss_Gm { Message = CommandString });
-			var smsgBossCommandResponse = await this.RecvMessage<SMSG_Boss_Command_Response>();
-			return smsgBossCommandResponse.ErrorCode;
-		}
-	}
-}
+using System.Threading.Tasks;
+using BossBase;
+using Helper;
+using Logger;
+
+namespace BossCommand
+{
+    public class BCSendMail: ABossCommand
+    {
+        public BossMail BossMail { get; set; }
+
+        public BCSendMail(IMessageChannel iMessageChannel): base(iMessageChannel)
+        {
+        }
+
+        public override async Task<object> DoAsync()
+        {
+            this.CommandString = string.Format("send_mail --json {0} ",
+                    MongoHelper.ToJson(this.BossMail));
+            Log.Trace(this.CommandString);
+            this.SendMessage(new CMSG_Boss_Gm { Message = this.CommandString });
+            var smsgBossCommandResponse = await this.RecvMessage<SMSG_Boss_Command_Response>();
+            return smsgBossCommandResponse.ErrorCode;
+        }
+    }
+}

+ 19 - 19
CSharp/App/BossCommand/BCServerInfo.cs

@@ -1,19 +1,19 @@
-using System.Threading.Tasks;
-using BossBase;
-
-namespace BossCommand
-{
-	public class BCServerInfo: ABossCommand
-	{
-		public BCServerInfo(IMessageChannel iMessageChannel): base(iMessageChannel)
-		{
-		}
-
-		public override async Task<object> DoAsync()
-		{
-			this.SendMessage(new CMSG_Boss_Gm { Message = "servers"});
-			var smsgBossServersInfo = await this.RecvMessage<SMSG_Boss_ServersInfo>();
-			return smsgBossServersInfo;
-		}
-	}
-}
+using System.Threading.Tasks;
+using BossBase;
+
+namespace BossCommand
+{
+    public class BCServerInfo: ABossCommand
+    {
+        public BCServerInfo(IMessageChannel iMessageChannel): base(iMessageChannel)
+        {
+        }
+
+        public override async Task<object> DoAsync()
+        {
+            this.SendMessage(new CMSG_Boss_Gm { Message = "servers" });
+            var smsgBossServersInfo = await this.RecvMessage<SMSG_Boss_ServersInfo>();
+            return smsgBossServersInfo;
+        }
+    }
+}

+ 5 - 2
CSharp/App/BossCommand/Properties/AssemblyInfo.cs

@@ -1,10 +1,10 @@
 using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 // 有关程序集的常规信息通过以下
 // 特性集控制。更改这些特性值可修改
 // 与程序集关联的信息。
+
 [assembly: AssemblyTitle("BossCommand")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
@@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
 // 将 ComVisible 设置为 false 使此程序集中的类型
 // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
 // 则将该类型上的 ComVisible 特性设置为 true。
+
 [assembly: ComVisible(false)]
 
 // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+
 [assembly: Guid("5a08753f-2724-4f97-a254-9d64f6faff13")]
 
 // 程序集的版本信息由下面四个值组成:
@@ -32,5 +34,6 @@ using System.Runtime.InteropServices;
 // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
 // 方法是按如下所示使用“*”:
 // [assembly: AssemblyVersion("1.0.*")]
+
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 19 - 19
CSharp/App/Editor/App.xaml.cs

@@ -1,20 +1,20 @@
-using System.Windows;
-
-namespace Editor
-{
-	public partial class App: Application
-	{
-		protected override void OnStartup(StartupEventArgs e)
-		{
-			base.OnStartup(e);
-			RunInDebugMode();
-			this.ShutdownMode = ShutdownMode.OnMainWindowClose;
-		}
-
-		private static void RunInDebugMode()
-		{
-			var bootstrapper = new Bootstrapper();
-			bootstrapper.Run();
-		}
-	}
+using System.Windows;
+
+namespace Editor
+{
+    public partial class App: Application
+    {
+        protected override void OnStartup(StartupEventArgs e)
+        {
+            base.OnStartup(e);
+            RunInDebugMode();
+            this.ShutdownMode = ShutdownMode.OnMainWindowClose;
+        }
+
+        private static void RunInDebugMode()
+        {
+            var bootstrapper = new Bootstrapper();
+            bootstrapper.Run();
+        }
+    }
 }

+ 48 - 45
CSharp/App/Editor/Bootstrapper.cs

@@ -1,46 +1,49 @@
-using System.ComponentModel.Composition.Hosting;
-using System.Windows;
-using Infrastructure;
-using Microsoft.Practices.Prism.MefExtensions;
-using Microsoft.Practices.Prism.Regions;
-using Tree;
-using Robot;
-using Login;
-using WCFClient;
-
-namespace Editor
-{
-	public class Bootstrapper: MefBootstrapper
-	{
-		protected override void ConfigureAggregateCatalog()
-		{
-			this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (Bootstrapper).Assembly));
-			this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (ViewExportAttribute).Assembly));
-			this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (BehaviorTreeModule).Assembly));
-			this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (RobotModule).Assembly));
-			this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (LoginModule).Assembly));
-			this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (WCFClientModule).Assembly));
-		}
-
-		protected override void InitializeShell()
-		{
-			base.InitializeShell();
-			Application.Current.MainWindow = (Shell) this.Shell;
-			Application.Current.MainWindow.Show();
-		}
-
-		protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
-		{
-			IRegionBehaviorFactory factory = base.ConfigureDefaultRegionBehaviors();
-			factory.AddIfMissing(
-				"AutoPopulateExportedViewsBehavior", 
-				typeof (AutoPopulateExportedViewsBehavior));
-			return factory;
-		}
-
-		protected override DependencyObject CreateShell()
-		{
-			return this.Container.GetExportedValue<Shell>();
-		}
-	}
+using System.ComponentModel.Composition.Hosting;
+using System.Windows;
+using Infrastructure;
+using Login;
+using Microsoft.Practices.Prism.MefExtensions;
+using Microsoft.Practices.Prism.Regions;
+using Robot;
+using Tree;
+using WCFClient;
+
+namespace Editor
+{
+    public class Bootstrapper: MefBootstrapper
+    {
+        protected override void ConfigureAggregateCatalog()
+        {
+            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (Bootstrapper).Assembly));
+            this.AggregateCatalog.Catalogs.Add(
+                                               new AssemblyCatalog(
+                                                       typeof (ViewExportAttribute).Assembly));
+            this.AggregateCatalog.Catalogs.Add(
+                                               new AssemblyCatalog(
+                                                       typeof (BehaviorTreeModule).Assembly));
+            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (RobotModule).Assembly));
+            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (LoginModule).Assembly));
+            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof (WCFClientModule).Assembly));
+        }
+
+        protected override void InitializeShell()
+        {
+            base.InitializeShell();
+            Application.Current.MainWindow = (Shell) this.Shell;
+            Application.Current.MainWindow.Show();
+        }
+
+        protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
+        {
+            IRegionBehaviorFactory factory = base.ConfigureDefaultRegionBehaviors();
+            factory.AddIfMissing("AutoPopulateExportedViewsBehavior",
+                    typeof (AutoPopulateExportedViewsBehavior));
+            return factory;
+        }
+
+        protected override DependencyObject CreateShell()
+        {
+            return this.Container.GetExportedValue<Shell>();
+        }
+    }
 }

+ 22 - 22
CSharp/App/Editor/Shell.xaml.cs

@@ -1,23 +1,23 @@
-using System.ComponentModel.Composition;
-using System.Windows;
-
-namespace Editor
-{
-	[Export]
-	public partial class Shell: Window
-	{
-		public Shell()
-		{
-			this.InitializeComponent();
-		}
-
-		[Import]
-		private ShellViewModel ViewModel
-		{
-			set
-			{
-				this.DataContext = value;
-			}
-		}
-	}
+using System.ComponentModel.Composition;
+using System.Windows;
+
+namespace Editor
+{
+    [Export]
+    public partial class Shell: Window
+    {
+        public Shell()
+        {
+            this.InitializeComponent();
+        }
+
+        [Import]
+        private ShellViewModel ViewModel
+        {
+            set
+            {
+                this.DataContext = value;
+            }
+        }
+    }
 }

+ 10 - 10
CSharp/App/Editor/ShellViewModel.cs

@@ -1,11 +1,11 @@
-using System.ComponentModel.Composition;
-using Microsoft.Practices.Prism.Mvvm;
-
-namespace Editor
-{
-	[Export]
-	public class ShellViewModel: BindableBase
-	{
-		// This is where any view model logic for the shell would go.
-	}
+using System.ComponentModel.Composition;
+using Microsoft.Practices.Prism.Mvvm;
+
+namespace Editor
+{
+    [Export]
+    public class ShellViewModel: BindableBase
+    {
+        // This is where any view model logic for the shell would go.
+    }
 }

+ 64 - 62
CSharp/App/Infrastructure/AutoPopulateExportedViewsBehavior.cs

@@ -1,63 +1,65 @@
-//===================================================================================
-// Microsoft patterns & practices
-// Composite Application Guidance for Windows Presentation Foundation and Silverlight
-//===================================================================================
-// Copyright (c) Microsoft Corporation.  All rights reserved.
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
-// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE.
-//===================================================================================
-// The example companies, organizations, products, domain names,
-// e-mail addresses, logos, people, places, and events depicted
-// herein are fictitious.  No association with any real company,
-// organization, product, domain name, email address, logo, person,
-// places, or events is intended or should be inferred.
-//===================================================================================
-
-using System;
-using System.ComponentModel.Composition;
-using Microsoft.Practices.Prism.Regions;
-
-namespace Infrastructure
-{
-	[Export(typeof (AutoPopulateExportedViewsBehavior)), PartCreationPolicy(CreationPolicy.NonShared)]
-	public class AutoPopulateExportedViewsBehavior: RegionBehavior, IPartImportsSatisfiedNotification
-	{
-		[ImportMany(AllowRecomposition = true)]
-		public Lazy<object, IViewRegionRegistration>[] RegisteredViews { get; set; }
-
-		public void OnImportsSatisfied()
-		{
-			this.AddRegisteredViews();
-		}
-
-		protected override void OnAttach()
-		{
-			this.AddRegisteredViews();
-		}
-
-		private void AddRegisteredViews()
-		{
-			if (this.Region == null)
-			{
-				return;
-			}
-
-			foreach (var viewEntry in this.RegisteredViews)
-			{
-				if (viewEntry.Metadata.RegionName != this.Region.Name)
-				{
-					continue;
-				}
-
-				object view = viewEntry.Value;
-
-				if (!this.Region.Views.Contains(view))
-				{
-					this.Region.Add(view);
-				}
-			}
-		}
-	}
+//===================================================================================
+// Microsoft patterns & practices
+// Composite Application Guidance for Windows Presentation Foundation and Silverlight
+//===================================================================================
+// Copyright (c) Microsoft Corporation.  All rights reserved.
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE.
+//===================================================================================
+// The example companies, organizations, products, domain names,
+// e-mail addresses, logos, people, places, and events depicted
+// herein are fictitious.  No association with any real company,
+// organization, product, domain name, email address, logo, person,
+// places, or events is intended or should be inferred.
+//===================================================================================
+
+using System;
+using System.ComponentModel.Composition;
+using Microsoft.Practices.Prism.Regions;
+
+namespace Infrastructure
+{
+    [Export(typeof (AutoPopulateExportedViewsBehavior)),
+     PartCreationPolicy(CreationPolicy.NonShared)]
+    public class AutoPopulateExportedViewsBehavior: RegionBehavior,
+            IPartImportsSatisfiedNotification
+    {
+        [ImportMany(AllowRecomposition = true)]
+        public Lazy<object, IViewRegionRegistration>[] RegisteredViews { get; set; }
+
+        public void OnImportsSatisfied()
+        {
+            this.AddRegisteredViews();
+        }
+
+        protected override void OnAttach()
+        {
+            this.AddRegisteredViews();
+        }
+
+        private void AddRegisteredViews()
+        {
+            if (this.Region == null)
+            {
+                return;
+            }
+
+            foreach (var viewEntry in this.RegisteredViews)
+            {
+                if (viewEntry.Metadata.RegionName != this.Region.Name)
+                {
+                    continue;
+                }
+
+                object view = viewEntry.Value;
+
+                if (!this.Region.Views.Contains(view))
+                {
+                    this.Region.Add(view);
+                }
+            }
+        }
+    }
 }

+ 23 - 23
CSharp/App/Infrastructure/IViewRegionRegistration.cs

@@ -1,24 +1,24 @@
-//===================================================================================
-// Microsoft patterns & practices
-// Composite Application Guidance for Windows Presentation Foundation and Silverlight
-//===================================================================================
-// Copyright (c) Microsoft Corporation.  All rights reserved.
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
-// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE.
-//===================================================================================
-// The example companies, organizations, products, domain names,
-// e-mail addresses, logos, people, places, and events depicted
-// herein are fictitious.  No association with any real company,
-// organization, product, domain name, email address, logo, person,
-// places, or events is intended or should be inferred.
-//===================================================================================
-
-namespace Infrastructure
-{
-	public interface IViewRegionRegistration
-	{
-		string RegionName { get; }
-	}
+//===================================================================================
+// Microsoft patterns & practices
+// Composite Application Guidance for Windows Presentation Foundation and Silverlight
+//===================================================================================
+// Copyright (c) Microsoft Corporation.  All rights reserved.
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE.
+//===================================================================================
+// The example companies, organizations, products, domain names,
+// e-mail addresses, logos, people, places, and events depicted
+// herein are fictitious.  No association with any real company,
+// organization, product, domain name, email address, logo, person,
+// places, or events is intended or should be inferred.
+//===================================================================================
+
+namespace Infrastructure
+{
+    public interface IViewRegionRegistration
+    {
+        string RegionName { get; }
+    }
 }

+ 35 - 35
CSharp/App/Infrastructure/ViewExportAttribute.cs

@@ -1,36 +1,36 @@
-//===================================================================================
-// Microsoft patterns & practices
-// Composite Application Guidance for Windows Presentation Foundation and Silverlight
-//===================================================================================
-// Copyright (c) Microsoft Corporation.  All rights reserved.
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
-// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-// FITNESS FOR A PARTICULAR PURPOSE.
-//===================================================================================
-// The example companies, organizations, products, domain names,
-// e-mail addresses, logos, people, places, and events depicted
-// herein are fictitious.  No association with any real company,
-// organization, product, domain name, email address, logo, person,
-// places, or events is intended or should be inferred.
-//===================================================================================
-
-using System;
-using System.ComponentModel.Composition;
-
-namespace Infrastructure
-{
-	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false), MetadataAttribute]
-	public class ViewExportAttribute: ExportAttribute, IViewRegionRegistration
-	{
-		public ViewExportAttribute(): base(typeof (object))
-		{
-		}
-
-		public ViewExportAttribute(string viewName): base(viewName, typeof (object))
-		{
-		}
-
-		public string RegionName { get; set; }
-	}
+//===================================================================================
+// Microsoft patterns & practices
+// Composite Application Guidance for Windows Presentation Foundation and Silverlight
+//===================================================================================
+// Copyright (c) Microsoft Corporation.  All rights reserved.
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
+// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE.
+//===================================================================================
+// The example companies, organizations, products, domain names,
+// e-mail addresses, logos, people, places, and events depicted
+// herein are fictitious.  No association with any real company,
+// organization, product, domain name, email address, logo, person,
+// places, or events is intended or should be inferred.
+//===================================================================================
+
+using System;
+using System.ComponentModel.Composition;
+
+namespace Infrastructure
+{
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false), MetadataAttribute]
+    public class ViewExportAttribute: ExportAttribute, IViewRegionRegistration
+    {
+        public ViewExportAttribute(): base(typeof (object))
+        {
+        }
+
+        public ViewExportAttribute(string viewName): base(viewName, typeof (object))
+        {
+        }
+
+        public string RegionName { get; set; }
+    }
 }

+ 12 - 12
CSharp/App/Modules/Login/LoginModule.cs

@@ -1,13 +1,13 @@
-using Microsoft.Practices.Prism.MefExtensions.Modularity;
-using Microsoft.Practices.Prism.Modularity;
-
-namespace Login
-{
-	[ModuleExport(moduleType: typeof (LoginModule))]
-	public class LoginModule: IModule
-	{
-		public void Initialize()
-		{
-		}
-	}
+using Microsoft.Practices.Prism.MefExtensions.Modularity;
+using Microsoft.Practices.Prism.Modularity;
+
+namespace Login
+{
+    [ModuleExport(moduleType: typeof (LoginModule))]
+    public class LoginModule: IModule
+    {
+        public void Initialize()
+        {
+        }
+    }
 }

+ 5 - 5
CSharp/App/Modules/Login/LoginView.xaml

@@ -13,13 +13,13 @@
 				HorizontalAlignment="Center" VerticalAlignment="Center" CloseButtonVisibility="Hidden">
 			<Grid Name="gridLogin"  Width="200" Height="120" >
 				<Grid.RowDefinitions>
-					<RowDefinition></RowDefinition>
-					<RowDefinition></RowDefinition>
-					<RowDefinition></RowDefinition>
+					<RowDefinition/>
+					<RowDefinition/>
+					<RowDefinition/>
 				</Grid.RowDefinitions>
 				<Grid.ColumnDefinitions>
-					<ColumnDefinition Width="51*"></ColumnDefinition>
-					<ColumnDefinition Width="149*"></ColumnDefinition>
+					<ColumnDefinition Width="51*"/>
+					<ColumnDefinition Width="149*"/>
 				</Grid.ColumnDefinitions>
 				<Label Content="帐号: " Grid.Row="0" Grid.Column="0" Margin="0,8"/>
 				<TextBox Text="{Binding Account}" Grid.Row="0" Grid.Column="1" Margin="0,8,0,8" />

+ 36 - 36
CSharp/App/Modules/Login/LoginView.xaml.cs

@@ -1,36 +1,36 @@
-using System.ComponentModel.Composition;
-using System.Windows;
-using Infrastructure;
-
-namespace Login
-{
-	/// <summary>
-	/// LoginView.xaml 的交互逻辑
-	/// </summary>
-	[ViewExport(RegionName = "LoginRegion"), PartCreationPolicy(CreationPolicy.NonShared)]
-	public partial class LoginView
-	{
-		public LoginView()
-		{
-			InitializeComponent();
-		}
-
-		[Import]
-		private LoginViewModel ViewModel
-		{
-			get
-			{
-				return this.DataContext as LoginViewModel;
-			}
-			set
-			{
-				this.DataContext = value;
-			}
-		}
-
-		private async void btnLogin_Click(object sender, RoutedEventArgs e)
-		{
-			await this.ViewModel.Login();
-		}
-	}
-}
+using System.ComponentModel.Composition;
+using System.Windows;
+using Infrastructure;
+
+namespace Login
+{
+    /// <summary>
+    /// LoginView.xaml 的交互逻辑
+    /// </summary>
+    [ViewExport(RegionName = "LoginRegion"), PartCreationPolicy(CreationPolicy.NonShared)]
+    public partial class LoginView
+    {
+        public LoginView()
+        {
+            this.InitializeComponent();
+        }
+
+        [Import]
+        private LoginViewModel ViewModel
+        {
+            get
+            {
+                return this.DataContext as LoginViewModel;
+            }
+            set
+            {
+                this.DataContext = value;
+            }
+        }
+
+        private async void btnLogin_Click(object sender, RoutedEventArgs e)
+        {
+            await this.ViewModel.Login();
+        }
+    }
+}

+ 121 - 118
CSharp/App/Modules/Login/LoginViewModel.cs

@@ -1,119 +1,122 @@
-using System;
-using System.ComponentModel.Composition;
-using System.Configuration;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Threading;
-using BossBase;
-using Logger;
-using Microsoft.Practices.Prism.Mvvm;
-using Microsoft.Practices.Prism.PubSubEvents;
-
-namespace Login
-{
-	[Export(contractType: typeof (LoginViewModel)),
-		PartCreationPolicy(creationPolicy: CreationPolicy.NonShared)]
-	internal class LoginViewModel : BindableBase
-	{
-		private IEventAggregator EventAggregator { get; set; }
-		private string account = "";
-		private string password = "";
-		private string errorInfo = "";
-		private Visibility loginWindowVisiable = Visibility.Visible;
-		private readonly BossClient.BossClient bossClient = new BossClient.BossClient();
-		private readonly DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Normal) 
-		{ Interval = new TimeSpan(0, 0, 0, 0, 50) };
-
-		public Visibility LoginWindowVisiable
-		{
-			get
-			{
-				return this.loginWindowVisiable;
-			}
-			set
-			{
-				this.SetProperty(ref this.loginWindowVisiable, value);
-			}
-		}
-
-		public string Account
-		{
-			get
-			{
-				return this.account;
-			}
-			set
-			{
-				this.SetProperty(ref this.account, value);
-			}
-		}
-
-		public string Password
-		{
-			get
-			{
-				return this.password;
-			}
-			set
-			{
-				this.SetProperty(ref this.password, value);
-			}
-		}
-
-		public string ErrorInfo
-		{
-			get
-			{
-				return this.errorInfo;
-			}
-			set
-			{
-				this.SetProperty(ref this.errorInfo, value);
-			}
-		}
-
-		[ImportingConstructor]
-		public LoginViewModel(IEventAggregator eventAggregator)
-		{
-			this.EventAggregator = eventAggregator;
-			this.EventAggregator.GetEvent<ReLoginEvent>().Subscribe(this.OnReLoginEvent);
-			this.timer.Tick += delegate { this.bossClient.RunOnce(); };
-			this.timer.Start();
-		}
-
-		public void OnReLoginEvent(object obj)
-		{
-			this.LoginWindowVisiable = Visibility.Visible;
-		}
-
-		public async Task Login()
-		{
-			string ip = ConfigurationManager.AppSettings["IP"];
-			ushort port = UInt16.Parse(ConfigurationManager.AppSettings["Port"]);
-
-			if (this.Account == "")
-			{
-				this.Account = ConfigurationManager.AppSettings["Account"];
-			}
-			if (this.Password == "")
-			{
-				this.Password = ConfigurationManager.AppSettings["Password"];
-			}
-
-			try
-			{
-				await this.bossClient.Login(ip, port, this.Account, this.Password);
-			}
-			catch (Exception e)
-			{
-				this.ErrorInfo = "登录失败";
-				Log.Trace(e.ToString());
-				return;
-			}
-			
-			this.LoginWindowVisiable = Visibility.Hidden;
-			this.EventAggregator.GetEvent<LoginOKEvent>().Publish(
-				bossClient.GateSession.IMessageChannel);
-		}
-	}
+using System;
+using System.ComponentModel.Composition;
+using System.Configuration;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Threading;
+using BossBase;
+using Logger;
+using Microsoft.Practices.Prism.Mvvm;
+using Microsoft.Practices.Prism.PubSubEvents;
+
+namespace Login
+{
+    [Export(contractType: typeof (LoginViewModel)),
+     PartCreationPolicy(creationPolicy: CreationPolicy.NonShared)]
+    internal class LoginViewModel: BindableBase
+    {
+        private IEventAggregator EventAggregator { get; set; }
+        private string account = "";
+        private string password = "";
+        private string errorInfo = "";
+        private Visibility loginWindowVisiable = Visibility.Visible;
+        private readonly BossClient.BossClient bossClient = new BossClient.BossClient();
+
+        private readonly DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Normal)
+        {
+            Interval = new TimeSpan(0, 0, 0, 0, 50)
+        };
+
+        public Visibility LoginWindowVisiable
+        {
+            get
+            {
+                return this.loginWindowVisiable;
+            }
+            set
+            {
+                this.SetProperty(ref this.loginWindowVisiable, value);
+            }
+        }
+
+        public string Account
+        {
+            get
+            {
+                return this.account;
+            }
+            set
+            {
+                this.SetProperty(ref this.account, value);
+            }
+        }
+
+        public string Password
+        {
+            get
+            {
+                return this.password;
+            }
+            set
+            {
+                this.SetProperty(ref this.password, value);
+            }
+        }
+
+        public string ErrorInfo
+        {
+            get
+            {
+                return this.errorInfo;
+            }
+            set
+            {
+                this.SetProperty(ref this.errorInfo, value);
+            }
+        }
+
+        [ImportingConstructor]
+        public LoginViewModel(IEventAggregator eventAggregator)
+        {
+            this.EventAggregator = eventAggregator;
+            this.EventAggregator.GetEvent<ReLoginEvent>().Subscribe(this.OnReLoginEvent);
+            this.timer.Tick += delegate { this.bossClient.RunOnce(); };
+            this.timer.Start();
+        }
+
+        public void OnReLoginEvent(object obj)
+        {
+            this.LoginWindowVisiable = Visibility.Visible;
+        }
+
+        public async Task Login()
+        {
+            string ip = ConfigurationManager.AppSettings["IP"];
+            ushort port = UInt16.Parse(ConfigurationManager.AppSettings["Port"]);
+
+            if (this.Account == "")
+            {
+                this.Account = ConfigurationManager.AppSettings["Account"];
+            }
+            if (this.Password == "")
+            {
+                this.Password = ConfigurationManager.AppSettings["Password"];
+            }
+
+            try
+            {
+                await this.bossClient.Login(ip, port, this.Account, this.Password);
+            }
+            catch (Exception e)
+            {
+                this.ErrorInfo = "登录失败";
+                Log.Trace(e.ToString());
+                return;
+            }
+
+            this.LoginWindowVisiable = Visibility.Hidden;
+            this.EventAggregator.GetEvent<LoginOKEvent>()
+                    .Publish(this.bossClient.GateSession.IMessageChannel);
+        }
+    }
 }

+ 8 - 9
CSharp/App/Modules/Robot/ComboBoxForbiddenType.cs

@@ -1,9 +1,8 @@
-
-namespace Robot
-{
-	public class ComboBoxForbiddenType
-	{
-		public string Name { get; set; }
-		public string Value { get; set; }
-	}
-}
+namespace Robot
+{
+    public class ComboBoxForbiddenType
+    {
+        public string Name { get; set; }
+        public string Value { get; set; }
+    }
+}

+ 28 - 27
CSharp/App/Modules/Robot/NumValidation.cs

@@ -1,27 +1,28 @@
-using System;
-using System.Globalization;
-using System.Windows.Controls;
-
-namespace Robot
-{
-	public class NumValidation : ValidationRule
-	{
-		public override ValidationResult Validate(object value, CultureInfo cultureInfo)
-		{
-			if ((string) value == "")
-			{
-				return new ValidationResult(true, null);
-			}
-			try
-			{
-				int.Parse((string) value);
-			}
-			catch (Exception e)
-			{
-				return new ValidationResult(false, string.Format("Illegal characters or {0}", e.Message));
-			}
-
-			return new ValidationResult(true, null);
-		}
-	}
-}
+using System;
+using System.Globalization;
+using System.Windows.Controls;
+
+namespace Robot
+{
+    public class NumValidation: ValidationRule
+    {
+        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
+        {
+            if ((string) value == "")
+            {
+                return new ValidationResult(true, null);
+            }
+            try
+            {
+                int.Parse((string) value);
+            }
+            catch (Exception e)
+            {
+                return new ValidationResult(false,
+                        string.Format("Illegal characters or {0}", e.Message));
+            }
+
+            return new ValidationResult(true, null);
+        }
+    }
+}

+ 5 - 5
CSharp/App/Modules/Robot/Robot.cs

@@ -1,6 +1,6 @@
-namespace Robot
-{
-	public class Robot
-	{
-	}
+namespace Robot
+{
+    public class Robot
+    {
+    }
 }

+ 12 - 12
CSharp/App/Modules/Robot/RobotModule.cs

@@ -1,13 +1,13 @@
-using Microsoft.Practices.Prism.MefExtensions.Modularity;
-using Microsoft.Practices.Prism.Modularity;
-
-namespace Robot
-{
-	[ModuleExport(moduleType: typeof (RobotModule))]
-	public class RobotModule: IModule
-	{
-		public void Initialize()
-		{
-		}
-	}
+using Microsoft.Practices.Prism.MefExtensions.Modularity;
+using Microsoft.Practices.Prism.Modularity;
+
+namespace Robot
+{
+    [ModuleExport(moduleType: typeof (RobotModule))]
+    public class RobotModule: IModule
+    {
+        public void Initialize()
+        {
+        }
+    }
 }

+ 6 - 6
CSharp/App/Modules/Robot/RobotView.xaml

@@ -8,13 +8,13 @@
 		mc:Ignorable="d" d:DataContext="{d:DesignInstance {x:Type Robot:RobotViewModel}}" Height="723.134" Width="1218.806">
 	<UserControl.Resources>
 		<x:Array x:Key="ComboBoxForbiddenTypeKey" Type="Robot:ComboBoxForbiddenType">
-			<Robot:ComboBoxForbiddenType Name="帐号" Value="forbid_buy_item"></Robot:ComboBoxForbiddenType>
-			<Robot:ComboBoxForbiddenType Name="IP" Value="forbid_match"></Robot:ComboBoxForbiddenType>
+			<Robot:ComboBoxForbiddenType Name="帐号" Value="forbid_buy_item"/>
+			<Robot:ComboBoxForbiddenType Name="IP" Value="forbid_match"/>
 		</x:Array>
 		<x:Array x:Key="ComboBoxCharacterForbiddenTypeKey" Type="Robot:ComboBoxForbiddenType">
-			<Robot:ComboBoxForbiddenType Name="购买" Value="forbid_buy_item"></Robot:ComboBoxForbiddenType>
-			<Robot:ComboBoxForbiddenType Name="匹配" Value="forbid_match"></Robot:ComboBoxForbiddenType>
-			<Robot:ComboBoxForbiddenType Name="聊天" Value="forbid_chat"></Robot:ComboBoxForbiddenType>
+			<Robot:ComboBoxForbiddenType Name="购买" Value="forbid_buy_item"/>
+			<Robot:ComboBoxForbiddenType Name="匹配" Value="forbid_match"/>
+			<Robot:ComboBoxForbiddenType Name="聊天" Value="forbid_chat"/>
 		</x:Array>
 
 		<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
@@ -157,7 +157,7 @@
 						<TabItem Header="工具">
 							<Canvas>
 								<Button Content="excel转换" Canvas.Left="10" Canvas.Top="10" Width="75" Click="btnExcel_Click"/>
-								<Label Name="lblShowResult" Canvas.Left="90" Canvas.Top="10" Height="23" Width="54" RenderTransformOrigin="-0.35,0.567"></Label>
+								<Label Name="lblShowResult" Canvas.Left="90" Canvas.Top="10" Height="23" Width="54" RenderTransformOrigin="-0.35,0.567"/>
 							</Canvas>
 						</TabItem>
 					</TabControl>

+ 176 - 171
CSharp/App/Modules/Robot/RobotView.xaml.cs

@@ -3,179 +3,184 @@ using System.Collections;
 using System.Collections.Generic;
 using System.ComponentModel.Composition;
 using System.IO;
-using System.Windows;
+using System.Windows;
 using Infrastructure;
 using NPOI.HSSF.UserModel;
 using NPOI.SS.UserModel;
 
-namespace Robot
-{
-	/// <summary>
-	/// RobotView.xaml 的交互逻辑
-	/// </summary>
-	[ViewExport(RegionName = "RobotRegion"), PartCreationPolicy(CreationPolicy.NonShared)]
-	public partial class RobotView
-	{
-		public RobotView()
-		{
-			this.InitializeComponent();
-		}
-
-		[Import]
-		private RobotViewModel ViewModel
-		{
-			get
-			{
-				return this.DataContext as RobotViewModel;
-			}
-			set
-			{
-				this.DataContext = value;
-			}
-		}
-
-		private void menuReload_Click(object sender, RoutedEventArgs e)
-		{
-			this.ViewModel.Reload();
-		}
-
-		private async void btnFindPlayer_Click(object sender, RoutedEventArgs e)
-		{
-			await this.ViewModel.GetCharacterInfo();
-			this.tcCharacterInfo.IsEnabled = true;
-			this.btnForbidCharacter.IsEnabled = true;
-			this.btnAllowCharacter.IsEnabled = true;
-			this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
-			this.tbLog.ScrollToEnd();
-		}
-
-		private void menuLogin_Click(object sender, RoutedEventArgs e)
-		{
-			this.ViewModel.ReLogin();
-		}
-
-		private async void menuServers_Click(object sender, RoutedEventArgs e)
-		{
-			await this.ViewModel.Servers();
-			this.tcAll.SelectedIndex = 0;
-			this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
-			this.tbLog.ScrollToEnd();
-		}
-
-		private async void btnForbidCharacter_Click(object sender, RoutedEventArgs e)
-		{
-			await this.ViewModel.ForbidCharacter(cbForbiddenType.SelectedValue.ToString(), tbForbiddenTime.Text);
-			this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
-			this.tbLog.ScrollToEnd();
-		}
-
-		private async void btnAllowCharacter_Click(object sender, RoutedEventArgs e)
-		{
-			await this.ViewModel.ForbidCharacter(cbForbiddenType.SelectedValue.ToString(), "-1");
-			this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
-			this.tbLog.ScrollToEnd();
-		}
-
-		private async void btnSendCommand_Click(object sender, RoutedEventArgs e)
-		{
-			await this.ViewModel.SendCommand();
-			this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
-			this.tbLog.ScrollToEnd();
-		}
-
-		private async void btnForbiddenLogin_Click(object sender, RoutedEventArgs e)
-		{
-			await this.ViewModel.ForbiddenLogin(
-				cbForbiddenLogin.SelectedValue.ToString(), 
-				tbForbiddenLoginContent.Text, tbForbiddenLoginTime.Text);
-			this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
-			this.tbLog.ScrollToEnd();
-		}
-
-		private async void btnAllowLogin_Click(object sender, RoutedEventArgs e)
-		{
-			await this.ViewModel.ForbiddenLogin(
-				cbForbiddenLogin.SelectedValue.ToString(), tbForbiddenLoginContent.Text, "-1");
-			this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
-			this.tbLog.ScrollToEnd();
-		}
-
-		private async void btnSendMail_Click(object sender, RoutedEventArgs e)
-		{
-			await this.ViewModel.SendMail();
-			this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
-			this.tbLog.ScrollToEnd();
-		}
-
-		private void btnExcel_Click(object sender, RoutedEventArgs e)
-		{
-			var dict = new Dictionary<string, int>
-			{
-				{ "英雄令", 1 },
-				{ "英雄令材料", 2 },
-				{ "双倍", 3 },
-				{ "会员", 4 },
-				{ "聊天", 5 },
-				{ "材料", 6 },
-				{ "印记页", 7 },
-				{ "血统页", 8 },
-				{ "坐骑", 9 },
-				{ "染色", 10 },
-				{ "星之魂玉", 11 },
-				{ "月之魂玉", 12 },
-				{ "日之魂玉", 13 },
-				{ "技能书", 14 },
-				{ "混沌之玉", 15 },
-				{ "战绩", 16 },
-				{ "坐骑翅膀", 17 },
-				{ "变身", 18 },
-				{ "将星", 19 },
-				{ "平台装备", 20 },
-				{ "将星装备", 21 },
-				{ "血魄", 22 },
-				{ "装饰", 23 },
-				{ "烟花", 24 },
-				{ "英雄礼包", 25 },
-				{ "套装", 26 },
-			};
-
-			HSSFWorkbook hssfWorkbook;
-			const string path = @"F:\MallItemProto.xls";
-			using (var file = new FileStream(path, FileMode.Open, FileAccess.Read))
-			{
-				hssfWorkbook = new HSSFWorkbook(file);
-			}
-			var sheet = hssfWorkbook.GetSheetAt(0);
-			IEnumerator rows = sheet.GetRowEnumerator();
-
-			const int nameIndex = 'Z' - 'A';
-			rows.MoveNext();
-			rows.MoveNext();
-			rows.MoveNext();
-			rows.MoveNext();
-			while (rows.MoveNext())
-			{
-				var row = (HSSFRow)rows.Current;
-				if (row.GetCell(nameIndex) == null)
-				{
-					continue;
-				}
-				var name = row.GetCell(nameIndex).ToString();
-
-				if (!dict.ContainsKey(name))
-				{
-					continue;
-				}
-
-				ICell cell = row.GetCell(nameIndex - 1) ?? row.CreateCell(nameIndex - 1);
-				cell.SetCellValue(dict[name].ToString());
-			}
-
-			using (var file = new FileStream(path, FileMode.Open, FileAccess.Write))
-			{
-				hssfWorkbook.Write(file);
-			}
-			lblShowResult.Content = "OK";
-		}
-	}
+namespace Robot
+{
+    /// <summary>
+    /// RobotView.xaml 的交互逻辑
+    /// </summary>
+    [ViewExport(RegionName = "RobotRegion"), PartCreationPolicy(CreationPolicy.NonShared)]
+    public partial class RobotView
+    {
+        public RobotView()
+        {
+            this.InitializeComponent();
+        }
+
+        [Import]
+        private RobotViewModel ViewModel
+        {
+            get
+            {
+                return this.DataContext as RobotViewModel;
+            }
+            set
+            {
+                this.DataContext = value;
+            }
+        }
+
+        private void menuReload_Click(object sender, RoutedEventArgs e)
+        {
+            this.ViewModel.Reload();
+        }
+
+        private async void btnFindPlayer_Click(object sender, RoutedEventArgs e)
+        {
+            await this.ViewModel.GetCharacterInfo();
+            this.tcCharacterInfo.IsEnabled = true;
+            this.btnForbidCharacter.IsEnabled = true;
+            this.btnAllowCharacter.IsEnabled = true;
+            this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
+            this.tbLog.ScrollToEnd();
+        }
+
+        private void menuLogin_Click(object sender, RoutedEventArgs e)
+        {
+            this.ViewModel.ReLogin();
+        }
+
+        private async void menuServers_Click(object sender, RoutedEventArgs e)
+        {
+            await this.ViewModel.Servers();
+            this.tcAll.SelectedIndex = 0;
+            this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
+            this.tbLog.ScrollToEnd();
+        }
+
+        private async void btnForbidCharacter_Click(object sender, RoutedEventArgs e)
+        {
+            await
+                    this.ViewModel.ForbidCharacter(this.cbForbiddenType.SelectedValue.ToString(),
+                            this.tbForbiddenTime.Text);
+            this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
+            this.tbLog.ScrollToEnd();
+        }
+
+        private async void btnAllowCharacter_Click(object sender, RoutedEventArgs e)
+        {
+            await
+                    this.ViewModel.ForbidCharacter(this.cbForbiddenType.SelectedValue.ToString(),
+                            "-1");
+            this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
+            this.tbLog.ScrollToEnd();
+        }
+
+        private async void btnSendCommand_Click(object sender, RoutedEventArgs e)
+        {
+            await this.ViewModel.SendCommand();
+            this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
+            this.tbLog.ScrollToEnd();
+        }
+
+        private async void btnForbiddenLogin_Click(object sender, RoutedEventArgs e)
+        {
+            await
+                    this.ViewModel.ForbiddenLogin(this.cbForbiddenLogin.SelectedValue.ToString(),
+                            this.tbForbiddenLoginContent.Text, this.tbForbiddenLoginTime.Text);
+            this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
+            this.tbLog.ScrollToEnd();
+        }
+
+        private async void btnAllowLogin_Click(object sender, RoutedEventArgs e)
+        {
+            await
+                    this.ViewModel.ForbiddenLogin(this.cbForbiddenLogin.SelectedValue.ToString(),
+                            this.tbForbiddenLoginContent.Text, "-1");
+            this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
+            this.tbLog.ScrollToEnd();
+        }
+
+        private async void btnSendMail_Click(object sender, RoutedEventArgs e)
+        {
+            await this.ViewModel.SendMail();
+            this.tbLog.AppendText(Environment.NewLine + this.ViewModel.ErrorInfo);
+            this.tbLog.ScrollToEnd();
+        }
+
+        private void btnExcel_Click(object sender, RoutedEventArgs e)
+        {
+            var dict = new Dictionary<string, int>
+            {
+                { "英雄令", 1 },
+                { "英雄令材料", 2 },
+                { "双倍", 3 },
+                { "会员", 4 },
+                { "聊天", 5 },
+                { "材料", 6 },
+                { "印记页", 7 },
+                { "血统页", 8 },
+                { "坐骑", 9 },
+                { "染色", 10 },
+                { "星之魂玉", 11 },
+                { "月之魂玉", 12 },
+                { "日之魂玉", 13 },
+                { "技能书", 14 },
+                { "混沌之玉", 15 },
+                { "战绩", 16 },
+                { "坐骑翅膀", 17 },
+                { "变身", 18 },
+                { "将星", 19 },
+                { "平台装备", 20 },
+                { "将星装备", 21 },
+                { "血魄", 22 },
+                { "装饰", 23 },
+                { "烟花", 24 },
+                { "英雄礼包", 25 },
+                { "套装", 26 },
+            };
+
+            HSSFWorkbook hssfWorkbook;
+            const string path = @"F:\MallItemProto.xls";
+            using (var file = new FileStream(path, FileMode.Open, FileAccess.Read))
+            {
+                hssfWorkbook = new HSSFWorkbook(file);
+            }
+            var sheet = hssfWorkbook.GetSheetAt(0);
+            IEnumerator rows = sheet.GetRowEnumerator();
+
+            const int nameIndex = 'Z' - 'A';
+            rows.MoveNext();
+            rows.MoveNext();
+            rows.MoveNext();
+            rows.MoveNext();
+            while (rows.MoveNext())
+            {
+                var row = (HSSFRow) rows.Current;
+                if (row.GetCell(nameIndex) == null)
+                {
+                    continue;
+                }
+                var name = row.GetCell(nameIndex).ToString();
+
+                if (!dict.ContainsKey(name))
+                {
+                    continue;
+                }
+
+                ICell cell = row.GetCell(nameIndex - 1) ?? row.CreateCell(nameIndex - 1);
+                cell.SetCellValue(dict[name].ToString());
+            }
+
+            using (var file = new FileStream(path, FileMode.Open, FileAccess.Write))
+            {
+                hssfWorkbook.Write(file);
+            }
+            this.lblShowResult.Content = "OK";
+        }
+    }
 }

+ 433 - 433
CSharp/App/Modules/Robot/RobotViewModel.cs

@@ -1,434 +1,434 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel.Composition;
-using System.Globalization;
-using System.Threading.Tasks;
-using System.Windows;
-using BossCommand;
-using BossBase;
-using Helper;
-using Logger;
-using Microsoft.Practices.Prism.Mvvm;
-using Microsoft.Practices.Prism.PubSubEvents;
-
-namespace Robot
-{
-	[Export(contractType: typeof (RobotViewModel)),
-		PartCreationPolicy(creationPolicy: CreationPolicy.Shared)]
-	internal sealed class RobotViewModel : BindableBase, IDisposable
-	{
-		private readonly IEventAggregator eventAggregator;
-
-		private string errorInfo = "";
-		private int findTypeIndex;
-		private string account = "";
-		private string findType = "egametang@126.com";
-		private string name = "";
-		private string guid = "";
-		private string command = "";
-
-		private string subject = "";
-		private string content = "";
-		private string freeGold = "";
-		private string silver = "";
-		private string itemID = "";
-		private string itemCount = "";
-
-		private Visibility dockPanelVisiable = Visibility.Hidden;
-		private readonly BossClient.BossClient bossClient = new BossClient.BossClient();
-		private readonly ObservableCollection<ServerViewModel> serverInfos = 
-			new ObservableCollection<ServerViewModel>();
-
-		public IMessageChannel IMessageChannel { get; set; }
-
-		public int FindTypeIndex
-		{
-			get
-			{
-				return this.findTypeIndex;
-			}
-			set
-			{
-				this.SetProperty(ref this.findTypeIndex, value);
-			}
-		}
-
-		public string FindType
-		{
-			get
-			{
-				return this.findType;
-			}
-			set
-			{
-				this.SetProperty(ref this.findType, value);
-			}
-		}
-
-		public Visibility DockPanelVisiable
-		{
-			get
-			{
-				return this.dockPanelVisiable;
-			}
-			set
-			{
-				this.SetProperty(ref this.dockPanelVisiable, value);
-			}
-		}
-
-		public ObservableCollection<ServerViewModel> ServerInfos
-		{
-			get
-			{
-				return this.serverInfos;
-			}
-		}
-
-		public string Account
-		{
-			get
-			{
-				return this.account;
-			}
-			set
-			{
-				this.SetProperty(ref this.account, value);
-			}
-		}
-
-		public string Name
-		{
-			get
-			{
-				return this.name;
-			}
-			set
-			{
-				this.SetProperty(ref this.name, value);
-			}
-		}
-
-		public string Guid
-		{
-			get
-			{
-				return this.guid;
-			}
-			set
-			{
-				this.SetProperty(ref this.guid, value);
-			}
-		}
-
-		public string ErrorInfo
-		{
-			get
-			{
-				return this.errorInfo;
-			}
-			set
-			{
-				this.SetProperty(ref this.errorInfo, value);
-			}
-		}
-
-		public string Command
-		{
-			get
-			{
-				return this.command;
-			}
-			set
-			{
-				this.SetProperty(ref this.command, value);
-			}
-		}
-
-		public string Subject
-		{
-			get
-			{
-				return this.subject;
-			}
-			set
-			{
-				this.SetProperty(ref this.subject, value);
-			}
-		}
-
-		public string Content
-		{
-			get
-			{
-				return this.content;
-			}
-			set
-			{
-				this.SetProperty(ref this.content, value);
-			}
-		}
-
-		public string FreeGold
-		{
-			get
-			{
-				return this.freeGold;
-			}
-			set
-			{
-				this.SetProperty(ref this.freeGold, value);
-			}
-		}
-
-		public string Silver
-		{
-			get
-			{
-				return this.silver;
-			}
-			set
-			{
-				this.SetProperty(ref this.silver, value);
-			}
-		}
-
-		public string ItemID
-		{
-			get
-			{
-				return this.itemID;
-			}
-			set
-			{
-				this.SetProperty(ref this.itemID, value);
-			}
-		}
-
-		public string ItemCount
-		{
-			get
-			{
-				return this.itemCount;
-			}
-			set
-			{
-				this.SetProperty(ref this.itemCount, value);
-			}
-		}
-
-		[ImportingConstructor]
-		public RobotViewModel(IEventAggregator eventAggregator)
-		{
-			this.eventAggregator = eventAggregator;
-			eventAggregator.GetEvent<LoginOKEvent>().Subscribe(this.OnLoginOKEvent);
-		}
-
-		~RobotViewModel()
-		{
-			this.Disposing();
-		}
-
-		public void Dispose()
-		{
-			this.Disposing();
-			GC.SuppressFinalize(this);
-		}
-
-		private void Disposing()
-		{
-			this.bossClient.Dispose();
-		}
-
-		public void OnLoginOKEvent(IMessageChannel messageChannel)
-		{
-			this.DockPanelVisiable = Visibility.Visible;
-			this.IMessageChannel = messageChannel;
-		}
-
-		public void ReLogin()
-		{
-			this.DockPanelVisiable = Visibility.Hidden;
-			this.eventAggregator.GetEvent<ReLoginEvent>().Publish(null);
-		}
-
-		public void ShowErrorInfo(uint errorCode, string commandString)
-		{
-			if (errorCode == ErrorCode.RESPONSE_SUCCESS)
-			{
-				this.ErrorInfo = string.Format("{0} Succeed!", commandString);
-				return;
-			}
-			this.ErrorInfo = string.Format("{0} Fail, error code: {1}", commandString, errorCode);
-		}
-
-		public async Task Servers()
-		{
-			ABossCommand bossCommand = new BCServerInfo(this.IMessageChannel);
-			var result = await bossCommand.DoAsync();
-
-			var smsgBossServersInfo = result as SMSG_Boss_ServersInfo;
-			if (smsgBossServersInfo == null)
-			{
-				this.ErrorInfo = "查询服务器失败!";
-				return;
-			}
-
-			this.ServerInfos.Clear();
-			foreach (var nm in smsgBossServersInfo.Name)
-			{
-				this.ServerInfos.Add(new ServerViewModel { Name = nm });
-			}
-			this.ErrorInfo = "查询服务器成功!";
-		}
-
-		public void Reload()
-		{
-			ABossCommand bossCommand = new BCReloadWorld(this.IMessageChannel);
-			bossCommand.DoAsync();
-		}
-
-		public async Task GetCharacterInfo()
-		{
-			ABossCommand bossCommand = new BCGetCharacterInfo(this.IMessageChannel)
-			{
-				FindTypeIndex = this.FindTypeIndex,
-				FindType = this.FindType
-			};
-			var result = await bossCommand.DoAsync();
-			if (result == null)
-			{
-				this.ErrorInfo = string.Format("{0} Fail!", bossCommand.CommandString);
-				return;
-			}
-			var characterInfo = (CharacterInfo)result;
-
-			this.Account = characterInfo.Account;
-			this.Name = characterInfo.Name;
-			this.Guid = characterInfo.Guid.ToString();
-			this.ErrorInfo = string.Format("{0} Succeed!", bossCommand.CommandString);
-		}
-
-		public async Task ForbidCharacter(string forbiddenCommand, string forbiddenTime)
-		{
-			if (this.Guid == "")
-			{
-				this.ErrorInfo = "请先指定玩家";
-				return;
-			}
-			ulong ulongGuid = 0;
-			if (!ulong.TryParse(this.Guid, out ulongGuid))
-			{
-				this.ErrorInfo = "Guid必须是数字";
-				return;
-			}
-			
-			int time = 0;
-			if (!int.TryParse(forbiddenTime, out time))
-			{
-				this.ErrorInfo = "时间请输入数字";
-				return;
-			}
-
-			ABossCommand bossCommand = new BCForbiddenCharacter(this.IMessageChannel)
-			{
-				Command = forbiddenCommand,
-				Guid = this.Guid,
-				ForbiddenTime = forbiddenTime
-			};
-			var result = await bossCommand.DoAsync();
-
-			var errorCode = (uint)result;
-
-			ShowErrorInfo(errorCode, bossCommand.CommandString);
-		}
-
-		public async Task ForbiddenLogin(
-			string forbiddenCommand, string forbiddenContent, string forbiddenTime)
-		{
-			int time = 0;
-			if (!int.TryParse(forbiddenTime, out time))
-			{
-				this.ErrorInfo = "时间请输入数字";
-				return;
-			}
-
-			ABossCommand bossCommand = new BCForbidLogin(this.IMessageChannel)
-			{
-				Command = forbiddenCommand, 
-				Content = forbiddenContent, 
-				ForbiddenLoginTime = forbiddenTime
-			};
-			var result = await bossCommand.DoAsync();
-
-			var errorCode = (uint)result;
-
-			ShowErrorInfo(errorCode, bossCommand.CommandString);
-		}
-
-		public async Task SendMail()
-		{
-			BossMail bossMail = null;
-			try
-			{
-				bossMail = new BossMail
-				{
-					sender_name = "系统",
-					receiver_guid = ulong.Parse(this.Guid),
-					subject = this.Subject,
-					content = this.Content,
-					free_gold = uint.Parse(this.FreeGold),
-					silver = uint.Parse(this.Silver),
-					item_dict = new Dictionary<int, int>()
-				};
-
-				if (this.ItemID != "")
-				{
-					bossMail.item_dict.Add(int.Parse(this.ItemID), int.Parse(this.ItemCount));
-				}
-			}
-			catch (Exception e)
-			{
-				Log.Trace(e.ToString());
-				this.ErrorInfo = "输入错误!";
-				return;
-			}
-
-			ABossCommand bossCommand = new BCSendMail(this.IMessageChannel)
-			{
-				BossMail = bossMail
-			};
-
-			var result = await bossCommand.DoAsync();
-
-			var errorCode = (uint) result;
-
-			ShowErrorInfo(errorCode, bossCommand.CommandString);
-		}
-
-		public async Task SendCommand()
-		{
-			if (this.Command.StartsWith("gm ", true, CultureInfo.CurrentCulture))
-			{
-				this.Command = this.Command.Substring(3);
-			}
-			ABossCommand bossCommand = new BCCommand(this.IMessageChannel)
-			{ Command = this.Command };
-			string commandString = this.Command;
-			object result = null;
-			try
-			{
-				result = await bossCommand.DoAsync();
-			}
-			catch(Exception e)
-			{
-				Log.Trace(e.ToString());
-				return;
-			}
-			var smsgBossCommandResponse = (SMSG_Boss_Command_Response)result;
-			this.ErrorInfo = string.Format(" send command: {0}, error code: {1}",
-				commandString, MongoHelper.ToJson(smsgBossCommandResponse));
-		}
-	}
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition;
+using System.Globalization;
+using System.Threading.Tasks;
+using System.Windows;
+using BossBase;
+using BossCommand;
+using Helper;
+using Logger;
+using Microsoft.Practices.Prism.Mvvm;
+using Microsoft.Practices.Prism.PubSubEvents;
+
+namespace Robot
+{
+    [Export(contractType: typeof (RobotViewModel)),
+     PartCreationPolicy(creationPolicy: CreationPolicy.Shared)]
+    internal sealed class RobotViewModel: BindableBase, IDisposable
+    {
+        private readonly IEventAggregator eventAggregator;
+
+        private string errorInfo = "";
+        private int findTypeIndex;
+        private string account = "";
+        private string findType = "egametang@126.com";
+        private string name = "";
+        private string guid = "";
+        private string command = "";
+
+        private string subject = "";
+        private string content = "";
+        private string freeGold = "";
+        private string silver = "";
+        private string itemID = "";
+        private string itemCount = "";
+
+        private Visibility dockPanelVisiable = Visibility.Hidden;
+        private readonly BossClient.BossClient bossClient = new BossClient.BossClient();
+
+        private readonly ObservableCollection<ServerViewModel> serverInfos =
+                new ObservableCollection<ServerViewModel>();
+
+        public IMessageChannel IMessageChannel { get; set; }
+
+        public int FindTypeIndex
+        {
+            get
+            {
+                return this.findTypeIndex;
+            }
+            set
+            {
+                this.SetProperty(ref this.findTypeIndex, value);
+            }
+        }
+
+        public string FindType
+        {
+            get
+            {
+                return this.findType;
+            }
+            set
+            {
+                this.SetProperty(ref this.findType, value);
+            }
+        }
+
+        public Visibility DockPanelVisiable
+        {
+            get
+            {
+                return this.dockPanelVisiable;
+            }
+            set
+            {
+                this.SetProperty(ref this.dockPanelVisiable, value);
+            }
+        }
+
+        public ObservableCollection<ServerViewModel> ServerInfos
+        {
+            get
+            {
+                return this.serverInfos;
+            }
+        }
+
+        public string Account
+        {
+            get
+            {
+                return this.account;
+            }
+            set
+            {
+                this.SetProperty(ref this.account, value);
+            }
+        }
+
+        public string Name
+        {
+            get
+            {
+                return this.name;
+            }
+            set
+            {
+                this.SetProperty(ref this.name, value);
+            }
+        }
+
+        public string Guid
+        {
+            get
+            {
+                return this.guid;
+            }
+            set
+            {
+                this.SetProperty(ref this.guid, value);
+            }
+        }
+
+        public string ErrorInfo
+        {
+            get
+            {
+                return this.errorInfo;
+            }
+            set
+            {
+                this.SetProperty(ref this.errorInfo, value);
+            }
+        }
+
+        public string Command
+        {
+            get
+            {
+                return this.command;
+            }
+            set
+            {
+                this.SetProperty(ref this.command, value);
+            }
+        }
+
+        public string Subject
+        {
+            get
+            {
+                return this.subject;
+            }
+            set
+            {
+                this.SetProperty(ref this.subject, value);
+            }
+        }
+
+        public string Content
+        {
+            get
+            {
+                return this.content;
+            }
+            set
+            {
+                this.SetProperty(ref this.content, value);
+            }
+        }
+
+        public string FreeGold
+        {
+            get
+            {
+                return this.freeGold;
+            }
+            set
+            {
+                this.SetProperty(ref this.freeGold, value);
+            }
+        }
+
+        public string Silver
+        {
+            get
+            {
+                return this.silver;
+            }
+            set
+            {
+                this.SetProperty(ref this.silver, value);
+            }
+        }
+
+        public string ItemID
+        {
+            get
+            {
+                return this.itemID;
+            }
+            set
+            {
+                this.SetProperty(ref this.itemID, value);
+            }
+        }
+
+        public string ItemCount
+        {
+            get
+            {
+                return this.itemCount;
+            }
+            set
+            {
+                this.SetProperty(ref this.itemCount, value);
+            }
+        }
+
+        [ImportingConstructor]
+        public RobotViewModel(IEventAggregator eventAggregator)
+        {
+            this.eventAggregator = eventAggregator;
+            eventAggregator.GetEvent<LoginOKEvent>().Subscribe(this.OnLoginOKEvent);
+        }
+
+        ~RobotViewModel()
+        {
+            this.Disposing();
+        }
+
+        public void Dispose()
+        {
+            this.Disposing();
+            GC.SuppressFinalize(this);
+        }
+
+        private void Disposing()
+        {
+            this.bossClient.Dispose();
+        }
+
+        public void OnLoginOKEvent(IMessageChannel messageChannel)
+        {
+            this.DockPanelVisiable = Visibility.Visible;
+            this.IMessageChannel = messageChannel;
+        }
+
+        public void ReLogin()
+        {
+            this.DockPanelVisiable = Visibility.Hidden;
+            this.eventAggregator.GetEvent<ReLoginEvent>().Publish(null);
+        }
+
+        public void ShowErrorInfo(uint errorCode, string commandString)
+        {
+            if (errorCode == ErrorCode.RESPONSE_SUCCESS)
+            {
+                this.ErrorInfo = string.Format("{0} Succeed!", commandString);
+                return;
+            }
+            this.ErrorInfo = string.Format("{0} Fail, error code: {1}", commandString, errorCode);
+        }
+
+        public async Task Servers()
+        {
+            ABossCommand bossCommand = new BCServerInfo(this.IMessageChannel);
+            var result = await bossCommand.DoAsync();
+
+            var smsgBossServersInfo = result as SMSG_Boss_ServersInfo;
+            if (smsgBossServersInfo == null)
+            {
+                this.ErrorInfo = "查询服务器失败!";
+                return;
+            }
+
+            this.ServerInfos.Clear();
+            foreach (var nm in smsgBossServersInfo.Name)
+            {
+                this.ServerInfos.Add(new ServerViewModel { Name = nm });
+            }
+            this.ErrorInfo = "查询服务器成功!";
+        }
+
+        public void Reload()
+        {
+            ABossCommand bossCommand = new BCReloadWorld(this.IMessageChannel);
+            bossCommand.DoAsync();
+        }
+
+        public async Task GetCharacterInfo()
+        {
+            ABossCommand bossCommand = new BCGetCharacterInfo(this.IMessageChannel)
+            {
+                FindTypeIndex = this.FindTypeIndex,
+                FindType = this.FindType
+            };
+            var result = await bossCommand.DoAsync();
+            if (result == null)
+            {
+                this.ErrorInfo = string.Format("{0} Fail!", bossCommand.CommandString);
+                return;
+            }
+            var characterInfo = (CharacterInfo) result;
+
+            this.Account = characterInfo.Account;
+            this.Name = characterInfo.Name;
+            this.Guid = characterInfo.Guid.ToString();
+            this.ErrorInfo = string.Format("{0} Succeed!", bossCommand.CommandString);
+        }
+
+        public async Task ForbidCharacter(string forbiddenCommand, string forbiddenTime)
+        {
+            if (this.Guid == "")
+            {
+                this.ErrorInfo = "请先指定玩家";
+                return;
+            }
+            ulong ulongGuid = 0;
+            if (!ulong.TryParse(this.Guid, out ulongGuid))
+            {
+                this.ErrorInfo = "Guid必须是数字";
+                return;
+            }
+
+            int time = 0;
+            if (!int.TryParse(forbiddenTime, out time))
+            {
+                this.ErrorInfo = "时间请输入数字";
+                return;
+            }
+
+            ABossCommand bossCommand = new BCForbiddenCharacter(this.IMessageChannel)
+            {
+                Command = forbiddenCommand,
+                Guid = this.Guid,
+                ForbiddenTime = forbiddenTime
+            };
+            var result = await bossCommand.DoAsync();
+
+            var errorCode = (uint) result;
+
+            this.ShowErrorInfo(errorCode, bossCommand.CommandString);
+        }
+
+        public async Task ForbiddenLogin(
+                string forbiddenCommand, string forbiddenContent, string forbiddenTime)
+        {
+            int time = 0;
+            if (!int.TryParse(forbiddenTime, out time))
+            {
+                this.ErrorInfo = "时间请输入数字";
+                return;
+            }
+
+            ABossCommand bossCommand = new BCForbidLogin(this.IMessageChannel)
+            {
+                Command = forbiddenCommand,
+                Content = forbiddenContent,
+                ForbiddenLoginTime = forbiddenTime
+            };
+            var result = await bossCommand.DoAsync();
+
+            var errorCode = (uint) result;
+
+            this.ShowErrorInfo(errorCode, bossCommand.CommandString);
+        }
+
+        public async Task SendMail()
+        {
+            BossMail bossMail = null;
+            try
+            {
+                bossMail = new BossMail
+                {
+                    sender_name = "系统",
+                    receiver_guid = ulong.Parse(this.Guid),
+                    subject = this.Subject,
+                    content = this.Content,
+                    free_gold = uint.Parse(this.FreeGold),
+                    silver = uint.Parse(this.Silver),
+                    item_dict = new Dictionary<int, int>()
+                };
+
+                if (this.ItemID != "")
+                {
+                    bossMail.item_dict.Add(int.Parse(this.ItemID), int.Parse(this.ItemCount));
+                }
+            }
+            catch (Exception e)
+            {
+                Log.Trace(e.ToString());
+                this.ErrorInfo = "输入错误!";
+                return;
+            }
+
+            ABossCommand bossCommand = new BCSendMail(this.IMessageChannel) { BossMail = bossMail };
+
+            var result = await bossCommand.DoAsync();
+
+            var errorCode = (uint) result;
+
+            this.ShowErrorInfo(errorCode, bossCommand.CommandString);
+        }
+
+        public async Task SendCommand()
+        {
+            if (this.Command.StartsWith("gm ", true, CultureInfo.CurrentCulture))
+            {
+                this.Command = this.Command.Substring(3);
+            }
+            ABossCommand bossCommand = new BCCommand(this.IMessageChannel)
+            {
+                Command = this.Command
+            };
+            string commandString = this.Command;
+            object result = null;
+            try
+            {
+                result = await bossCommand.DoAsync();
+            }
+            catch (Exception e)
+            {
+                Log.Trace(e.ToString());
+                return;
+            }
+            var smsgBossCommandResponse = (SMSG_Boss_Command_Response) result;
+            this.ErrorInfo = string.Format(" send command: {0}, error code: {1}", commandString,
+                    MongoHelper.ToJson(smsgBossCommandResponse));
+        }
+    }
 }

+ 24 - 24
CSharp/App/Modules/Robot/ServerViewModel.cs

@@ -1,24 +1,24 @@
-using System.Runtime.Serialization;
-using Microsoft.Practices.Prism.Mvvm;
-
-namespace Robot
-{
-	[DataContract]
-	public class ServerViewModel : BindableBase
-	{
-		[DataMember(Order = 1, IsRequired = true)]
-		private string name;
-
-		public string Name
-		{
-			get
-			{
-				return this.name;
-			}
-			set
-			{
-				this.SetProperty(ref this.name, value);
-			}
-		}
-	}
-}
+using System.Runtime.Serialization;
+using Microsoft.Practices.Prism.Mvvm;
+
+namespace Robot
+{
+    [DataContract]
+    public class ServerViewModel: BindableBase
+    {
+        [DataMember(Order = 1, IsRequired = true)]
+        private string name;
+
+        public string Name
+        {
+            get
+            {
+                return this.name;
+            }
+            set
+            {
+                this.SetProperty(ref this.name, value);
+            }
+        }
+    }
+}

+ 176 - 177
CSharp/App/Modules/Tree/BehaviorTreeLayout.cs

@@ -1,179 +1,178 @@
-using Logger;
-
-namespace Tree
-{
-	public static class BehaviorTreeLayout
-	{
-		private const double XGap = 20;
-		private const double YGap = 10;
-		private static double rootOrigX;
-		private static double rootOrigY;
-		private static double rootOffsetX;
-		private static double rootOffsetY;
-
-		private static TreeNodeViewModel LeftMostOffspring(
-			TreeNodeViewModel treeNode, int currentLevel, int searchLevel)
-		{
-			if (currentLevel == searchLevel)
-			{
-				return treeNode;
-			}
-			for (int i = 0; i < treeNode.Children.Count; ++i)
-			{
-				var child = treeNode.Children[i];
-				child.AncestorModify = treeNode.Modify + treeNode.AncestorModify;
-				var offspring = LeftMostOffspring(child, currentLevel + 1, searchLevel);
-				if (offspring == null)
-				{
-					continue;
-				}
-				return offspring;
-			}
-			return null;
-		}
-
-		private static TreeNodeViewModel RightMostOffspring(
-			TreeNodeViewModel treeNode, int currentLevel, int searchLevel)
-		{
-			if (currentLevel == searchLevel)
-			{
-				return treeNode;
-			}
-			for (int i = treeNode.Children.Count - 1; i >= 0; --i)
-			{
-				var child = treeNode.Children[i];
-				child.AncestorModify = treeNode.Modify + treeNode.AncestorModify;
-				var offspring = RightMostOffspring(child, currentLevel + 1, searchLevel);
-				if (offspring == null)
-				{
-					continue;
-				}
-				return offspring;
-			}
-			return null;
-		}
-
-		private static void AjustSubTreeGap(TreeNodeViewModel left, TreeNodeViewModel right)
-		{
-			double offset = 0;
-			TreeNodeViewModel tLeft = left;
-			TreeNodeViewModel tRight = right;
-			left.AncestorModify = 0;
-			right.AncestorModify = 0;
-			for (int i = 0; tLeft != null && tRight != null; ++i)
-			{
-				double tGap = (tRight.Prelim + tRight.AncestorModify) - (tLeft.Prelim + tLeft.AncestorModify);
-				if (XGap + TreeNodeViewModel.Width - tGap > offset)
-				{
-					offset = XGap + TreeNodeViewModel.Width - tGap;
-				}
-				tLeft = RightMostOffspring(left, 0, i + 1);
-				tRight = LeftMostOffspring(right, 0, i + 1);
-			}
-			right.Modify += offset;
-			right.Prelim += offset;
-		}
-
-		private static void AjustTreeGap(TreeNodeViewModel treeNode)
-		{
-			for (int i = 0; i < treeNode.Children.Count - 1; ++i)
-			{
-				for (int j = i + 1; j < treeNode.Children.Count; ++j)
-				{
-					var left = treeNode.Children[i];
-					var right = treeNode.Children[j];
-					AjustSubTreeGap(left, right);
-				}
-			}
-		}
-
-		private static void CalculatePrelimAndModify(TreeNodeViewModel treeNode)
-		{
-			foreach (TreeNodeViewModel node in treeNode.Children)
-			{
-				CalculatePrelimAndModify(node);
-			}
+namespace Tree
+{
+    public static class BehaviorTreeLayout
+    {
+        private const double XGap = 20;
+        private const double YGap = 10;
+        private static double rootOrigX;
+        private static double rootOrigY;
+        private static double rootOffsetX;
+        private static double rootOffsetY;
 
-			double prelim = 0;
-			double modify = 0;
-
-			if (treeNode.IsLeaf)
-			{
-				if (treeNode.LeftSibling == null)
-				{
-					// 如果没有左邻居,不需要设置modify
-					prelim = 0;
-				}
-				else
-				{
-					prelim = treeNode.LeftSibling.Prelim + TreeNodeViewModel.Width + XGap;
-				}
-			}
-			else
-			{
-				// 调整子树间的间距
-				AjustTreeGap(treeNode);
-				double childrenCenter = (treeNode.FirstChild.Prelim + treeNode.LastChild.Prelim) / 2;
-				if (treeNode.LeftSibling == null)
-				{
-					// 如果没有左邻居,不需要设置modify
-					prelim = childrenCenter;
-				}
-				else
-				{
-					prelim = treeNode.LeftSibling.Prelim + TreeNodeViewModel.Width + XGap;
-					modify = prelim - childrenCenter;
-				}
-			}
-			treeNode.Prelim = prelim;
-			treeNode.Modify = modify;
-
-			// Log.Debug("Id: " + treeNode.Id + " Prelim: " + treeNode.Prelim + " Modify: " +
-			// 	treeNode.Modify);
-		}
-
-		private static void CalculateRelativeXAndY(
-			TreeNodeViewModel treeNode, int level, double totalModify)
-		{
-			foreach (TreeNodeViewModel node in treeNode.Children)
-			{
-				CalculateRelativeXAndY(node, level + 1, treeNode.Modify + totalModify);
-			}
-			if (treeNode.IsLeaf)
-			{
-				treeNode.X = treeNode.Prelim + totalModify;
-			}
-			else
-			{
-				treeNode.X = (treeNode.FirstChild.X + treeNode.LastChild.X) / 2;
-			}
-			treeNode.Y = level * (TreeNodeViewModel.Height + YGap);
-		}
-
-		private static void FixXAndY(TreeNodeViewModel treeNode)
-		{
-			treeNode.X += rootOffsetX;
-			treeNode.Y += rootOffsetY;
-			foreach (var node in treeNode.Children)
-			{
-				FixXAndY(node);
-			}
-		}
-
-		public static void ExcuteLayout(TreeNodeViewModel root)
-		{
-			if (root == null)
-			{
-				return;
-			}
-			rootOrigX = root.X;
-			rootOrigY = root.Y;
-			CalculatePrelimAndModify(root);
-			CalculateRelativeXAndY(root, 0, 0);
-
-			rootOffsetX = rootOrigX - root.X;
-			rootOffsetY = rootOrigY - root.Y;
-			FixXAndY(root);
-		}
-	}
+        private static TreeNodeViewModel LeftMostOffspring(
+                TreeNodeViewModel treeNode, int currentLevel, int searchLevel)
+        {
+            if (currentLevel == searchLevel)
+            {
+                return treeNode;
+            }
+            for (int i = 0; i < treeNode.Children.Count; ++i)
+            {
+                var child = treeNode.Children[i];
+                child.AncestorModify = treeNode.Modify + treeNode.AncestorModify;
+                var offspring = LeftMostOffspring(child, currentLevel + 1, searchLevel);
+                if (offspring == null)
+                {
+                    continue;
+                }
+                return offspring;
+            }
+            return null;
+        }
+
+        private static TreeNodeViewModel RightMostOffspring(
+                TreeNodeViewModel treeNode, int currentLevel, int searchLevel)
+        {
+            if (currentLevel == searchLevel)
+            {
+                return treeNode;
+            }
+            for (int i = treeNode.Children.Count - 1; i >= 0; --i)
+            {
+                var child = treeNode.Children[i];
+                child.AncestorModify = treeNode.Modify + treeNode.AncestorModify;
+                var offspring = RightMostOffspring(child, currentLevel + 1, searchLevel);
+                if (offspring == null)
+                {
+                    continue;
+                }
+                return offspring;
+            }
+            return null;
+        }
+
+        private static void AjustSubTreeGap(TreeNodeViewModel left, TreeNodeViewModel right)
+        {
+            double offset = 0;
+            TreeNodeViewModel tLeft = left;
+            TreeNodeViewModel tRight = right;
+            left.AncestorModify = 0;
+            right.AncestorModify = 0;
+            for (int i = 0; tLeft != null && tRight != null; ++i)
+            {
+                double tGap = (tRight.Prelim + tRight.AncestorModify) -
+                              (tLeft.Prelim + tLeft.AncestorModify);
+                if (XGap + TreeNodeViewModel.Width - tGap > offset)
+                {
+                    offset = XGap + TreeNodeViewModel.Width - tGap;
+                }
+                tLeft = RightMostOffspring(left, 0, i + 1);
+                tRight = LeftMostOffspring(right, 0, i + 1);
+            }
+            right.Modify += offset;
+            right.Prelim += offset;
+        }
+
+        private static void AjustTreeGap(TreeNodeViewModel treeNode)
+        {
+            for (int i = 0; i < treeNode.Children.Count - 1; ++i)
+            {
+                for (int j = i + 1; j < treeNode.Children.Count; ++j)
+                {
+                    var left = treeNode.Children[i];
+                    var right = treeNode.Children[j];
+                    AjustSubTreeGap(left, right);
+                }
+            }
+        }
+
+        private static void CalculatePrelimAndModify(TreeNodeViewModel treeNode)
+        {
+            foreach (TreeNodeViewModel node in treeNode.Children)
+            {
+                CalculatePrelimAndModify(node);
+            }
+
+            double prelim = 0;
+            double modify = 0;
+
+            if (treeNode.IsLeaf)
+            {
+                if (treeNode.LeftSibling == null)
+                {
+                    // 如果没有左邻居,不需要设置modify
+                    prelim = 0;
+                }
+                else
+                {
+                    prelim = treeNode.LeftSibling.Prelim + TreeNodeViewModel.Width + XGap;
+                }
+            }
+            else
+            {
+                // 调整子树间的间距
+                AjustTreeGap(treeNode);
+                double childrenCenter = (treeNode.FirstChild.Prelim + treeNode.LastChild.Prelim) / 2;
+                if (treeNode.LeftSibling == null)
+                {
+                    // 如果没有左邻居,不需要设置modify
+                    prelim = childrenCenter;
+                }
+                else
+                {
+                    prelim = treeNode.LeftSibling.Prelim + TreeNodeViewModel.Width + XGap;
+                    modify = prelim - childrenCenter;
+                }
+            }
+            treeNode.Prelim = prelim;
+            treeNode.Modify = modify;
+
+            // Log.Debug("Id: " + treeNode.Id + " Prelim: " + treeNode.Prelim + " Modify: " +
+            // 	treeNode.Modify);
+        }
+
+        private static void CalculateRelativeXAndY(
+                TreeNodeViewModel treeNode, int level, double totalModify)
+        {
+            foreach (TreeNodeViewModel node in treeNode.Children)
+            {
+                CalculateRelativeXAndY(node, level + 1, treeNode.Modify + totalModify);
+            }
+            if (treeNode.IsLeaf)
+            {
+                treeNode.X = treeNode.Prelim + totalModify;
+            }
+            else
+            {
+                treeNode.X = (treeNode.FirstChild.X + treeNode.LastChild.X) / 2;
+            }
+            treeNode.Y = level * (TreeNodeViewModel.Height + YGap);
+        }
+
+        private static void FixXAndY(TreeNodeViewModel treeNode)
+        {
+            treeNode.X += rootOffsetX;
+            treeNode.Y += rootOffsetY;
+            foreach (var node in treeNode.Children)
+            {
+                FixXAndY(node);
+            }
+        }
+
+        public static void ExcuteLayout(TreeNodeViewModel root)
+        {
+            if (root == null)
+            {
+                return;
+            }
+            rootOrigX = root.X;
+            rootOrigY = root.Y;
+            CalculatePrelimAndModify(root);
+            CalculateRelativeXAndY(root, 0, 0);
+
+            rootOffsetX = rootOrigX - root.X;
+            rootOffsetY = rootOrigY - root.Y;
+            FixXAndY(root);
+        }
+    }
 }

+ 12 - 12
CSharp/App/Modules/Tree/BehaviorTreeModule.cs

@@ -1,13 +1,13 @@
-using Microsoft.Practices.Prism.MefExtensions.Modularity;
-using Microsoft.Practices.Prism.Modularity;
-
-namespace Tree
-{
-	[ModuleExport(moduleType: typeof (BehaviorTreeModule))]
-	public class BehaviorTreeModule: IModule
-	{
-		public void Initialize()
-		{
-		}
-	}
+using Microsoft.Practices.Prism.MefExtensions.Modularity;
+using Microsoft.Practices.Prism.Modularity;
+
+namespace Tree
+{
+    [ModuleExport(moduleType: typeof (BehaviorTreeModule))]
+    public class BehaviorTreeModule: IModule
+    {
+        public void Initialize()
+        {
+        }
+    }
 }

+ 3 - 3
CSharp/App/Modules/Tree/BehaviorTreeView.xaml

@@ -78,10 +78,10 @@
 							PreviewMouseLeftButtonUp="ListBoxItem_PreviewMouseLeftButtonUp">
 						<Rectangle Name="rectNode" Width="{Binding Width}" Height="{Binding Height}" Cursor="Hand" StrokeThickness="2"
 								RadiusX="10" RadiusY="10" Stroke="{StaticResource treeNodeBorderBrush}" Fill="{StaticResource treeNodeSelectorFillBrush}"/>
-						<Label Content="+" Visibility="{Binding IsFolder, Converter={StaticResource FolderVisiableConverter}}" Canvas.Left="60" Canvas.Top="10"  ></Label>
+						<Label Content="+" Visibility="{Binding IsFolder, Converter={StaticResource FolderVisiableConverter}}" Canvas.Left="60" Canvas.Top="10"/>
 						<StackPanel>
-							<Label Content="{Binding Type, Converter={StaticResource NodeTypeToStringConverter}}" ></Label>
-							<Label Content="{Binding Comment}" ></Label>
+							<Label Content="{Binding Type, Converter={StaticResource NodeTypeToStringConverter}}"/>
+							<Label Content="{Binding Comment}"/>
 						</StackPanel>
 						<Line X1="{Binding ConnectorX1}" Y1="{Binding ConnectorY1}" X2="{Binding ConnectorX2}" Y2="{Binding ConnectorY2}"
 								Stroke="Black" StrokeThickness="2"  />

+ 211 - 205
CSharp/App/Modules/Tree/BehaviorTreeView.xaml.cs

@@ -1,209 +1,215 @@
-using System;
-using System.ComponentModel.Composition;
-using System.Windows;
-using System.Windows.Input;
+using System;
+using System.ComponentModel.Composition;
+using System.Windows;
+using System.Windows.Input;
 using Infrastructure;
 using Logger;
 
-namespace Tree
-{
-	/// <summary>
-	/// BehaviorTreeView.xaml 的交互逻辑
-	/// </summary>
-	[ViewExport(RegionName = "BehaviorTreeRegion"), PartCreationPolicy(CreationPolicy.NonShared)]
-	public partial class BehaviorTreeView
-	{
-		private const double DragThreshold = 5;
-		private bool isDragging;
-		private bool isLeftButtonDown;
-		private Point origMouseDownPoint;
-		private TreeNodeViewModel moveFromNode;
-
-		public BehaviorTreeView()
-		{
-			this.InitializeComponent();
-		}
-
-		[Import]
-		private BehaviorTreeViewModel ViewModel
-		{
-			get
-			{
-				return this.DataContext as BehaviorTreeViewModel;
-			}
-			set
-			{
-				this.DataContext = value;
-			}
-		}
-
-		private void MenuNode_New(object sender, ExecutedRoutedEventArgs e)
-		{
-			Point point = Mouse.GetPosition(this.listBox);
-
-			// one root node
-			if (this.ViewModel.TreeNodes.Count == 0)
-			{
-				var addTreeNode = new TreeNodeViewModel(point.X, point.Y) { Type = (int) NodeType.Selector };
-				this.ViewModel.Add(addTreeNode, null);
-			}
-			else
-			{
-				if (this.listBox.SelectedItem != null)
-				{
-					var parentNode = this.listBox.SelectedItem as TreeNodeViewModel;
-					var addTreeNode = new TreeNodeViewModel(parentNode) { Type = (int) NodeType.Selector };
-					this.ViewModel.Add(addTreeNode, parentNode);
-				}
-			}
-			this.listBox.SelectedItem = null;
-			e.Handled = true;
-		}
-
-		private void MenuNode_Delete(object sender, ExecutedRoutedEventArgs e)
-		{
-			if (this.listBox.SelectedItem == null)
-			{
-				return;
-			}
-			var treeNodeViewModel = this.listBox.SelectedItem as TreeNodeViewModel;
-			this.ViewModel.Remove(treeNodeViewModel);
-			this.listBox.SelectedItem = null;
-			e.Handled = true;
-		}
-
-		private void MenuNode_Save(object sender, ExecutedRoutedEventArgs e)
-		{
-			this.ViewModel.Save("node.bytes");
-		}
-
-		private void MenuNode_Open(object sender, ExecutedRoutedEventArgs e)
-		{
-			this.ViewModel.Load("node.bytes");
-		}
-
-		private void ListBoxItem_MouseDown(object sender, MouseButtonEventArgs e)
-		{
-			if (e.ChangedButton != MouseButton.Left)
-			{
-				return;
-			}
-
-			// 双击鼠标
-			if (e.ClickCount == 2 && e.ChangedButton == MouseButton.Left)
-			{
-				var item = (FrameworkElement) sender;
-				var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
-				if (treeNodeViewModel.IsFolder)
-				{
-					this.ViewModel.UnFold(treeNodeViewModel);
-				}
-				else
-				{
-					this.ViewModel.Fold(treeNodeViewModel);	
-				}
-			}
-			e.Handled = true;
-		}
-
-		private void ListBoxItem_MouseUp(object sender, MouseButtonEventArgs e)
-		{
-			if (!this.isLeftButtonDown)
-			{
-				this.isDragging = false;
-				return;
-			}
-
-			var item = (FrameworkElement) sender;
-			var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
-
-			if (!this.isDragging)
-			{
-				this.listBox.SelectedItem = treeNodeViewModel;
-			}
-
-			this.isLeftButtonDown = false;
-			this.isDragging = false;
-
-			item.ReleaseMouseCapture();
-			e.Handled = true;
-		}
-
-		private void ListBoxItem_MouseMove(object sender, MouseEventArgs e)
-		{
-			var item = (FrameworkElement) sender;
-			var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
-			if (treeNodeViewModel == null)
-			{
-				return;
-			}
-
-			Point curMouseDownPoint;
-			Vector dragDelta;
-			// 拖动根节点,移动整个树
-			if (this.isDragging && treeNodeViewModel.IsRoot)
-			{
-				if (this.moveFromNode == null || !this.moveFromNode.IsRoot)
-				{
-					return;
-				}
-				curMouseDownPoint = e.GetPosition(this);
-				dragDelta = curMouseDownPoint - this.origMouseDownPoint;
-
-				this.origMouseDownPoint = curMouseDownPoint;
-
-				this.ViewModel.MoveToPosition(dragDelta.X, dragDelta.Y);
-				return;
-			}
-
-			if (e.LeftButton != MouseButtonState.Pressed)
-			{
-				this.isDragging = false;
-				this.moveFromNode = null;
-				return;
-			}
-
-			curMouseDownPoint = e.GetPosition(this);
-			dragDelta = curMouseDownPoint - this.origMouseDownPoint;
-			double dragDistance = Math.Abs(dragDelta.Length);
-			if (dragDistance > DragThreshold)
-			{
-				this.isDragging = true;
-			}
-			e.Handled = true;
-		}
-
-		private void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseEventArgs e)
-		{
-			origMouseDownPoint = e.GetPosition(this);
-			var item = (FrameworkElement)sender;
-			var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
-
-			this.listBox.SelectedItem = treeNodeViewModel;
-			this.moveFromNode = treeNodeViewModel;
-
-			this.nodeDataEditor.DataContext = treeNodeViewModel;
-		}
-
-		private void ListBoxItem_PreviewMouseLeftButtonUp(object sender, MouseEventArgs e)
-		{
-			if (this.moveFromNode == null)
-			{
-				return;
-			}
-			if (this.moveFromNode.IsRoot)
-			{
-				return;
-			}
-			var item = (FrameworkElement)sender;
-			var moveToNode = item.DataContext as TreeNodeViewModel;
-			Log.Debug("move to node: {0} {1}", moveFromNode.Id, moveToNode.Id);
-			if (this.moveFromNode.Id == moveToNode.Id)
-			{
-				return;
-			}
-			this.ViewModel.MoveToNode(this.moveFromNode, moveToNode);
-			this.moveFromNode = null;
-		}
-	}
+namespace Tree
+{
+    /// <summary>
+    /// BehaviorTreeView.xaml 的交互逻辑
+    /// </summary>
+    [ViewExport(RegionName = "BehaviorTreeRegion"), PartCreationPolicy(CreationPolicy.NonShared)]
+    public partial class BehaviorTreeView
+    {
+        private const double DragThreshold = 5;
+        private bool isDragging;
+        private bool isLeftButtonDown;
+        private Point origMouseDownPoint;
+        private TreeNodeViewModel moveFromNode;
+
+        public BehaviorTreeView()
+        {
+            this.InitializeComponent();
+        }
+
+        [Import]
+        private BehaviorTreeViewModel ViewModel
+        {
+            get
+            {
+                return this.DataContext as BehaviorTreeViewModel;
+            }
+            set
+            {
+                this.DataContext = value;
+            }
+        }
+
+        private void MenuNode_New(object sender, ExecutedRoutedEventArgs e)
+        {
+            Point point = Mouse.GetPosition(this.listBox);
+
+            // one root node
+            if (this.ViewModel.TreeNodes.Count == 0)
+            {
+                var addTreeNode = new TreeNodeViewModel(point.X, point.Y)
+                {
+                    Type = (int) NodeType.Selector
+                };
+                this.ViewModel.Add(addTreeNode, null);
+            }
+            else
+            {
+                if (this.listBox.SelectedItem != null)
+                {
+                    var parentNode = this.listBox.SelectedItem as TreeNodeViewModel;
+                    var addTreeNode = new TreeNodeViewModel(parentNode)
+                    {
+                        Type = (int) NodeType.Selector
+                    };
+                    this.ViewModel.Add(addTreeNode, parentNode);
+                }
+            }
+            this.listBox.SelectedItem = null;
+            e.Handled = true;
+        }
+
+        private void MenuNode_Delete(object sender, ExecutedRoutedEventArgs e)
+        {
+            if (this.listBox.SelectedItem == null)
+            {
+                return;
+            }
+            var treeNodeViewModel = this.listBox.SelectedItem as TreeNodeViewModel;
+            this.ViewModel.Remove(treeNodeViewModel);
+            this.listBox.SelectedItem = null;
+            e.Handled = true;
+        }
+
+        private void MenuNode_Save(object sender, ExecutedRoutedEventArgs e)
+        {
+            this.ViewModel.Save("node.bytes");
+        }
+
+        private void MenuNode_Open(object sender, ExecutedRoutedEventArgs e)
+        {
+            this.ViewModel.Load("node.bytes");
+        }
+
+        private void ListBoxItem_MouseDown(object sender, MouseButtonEventArgs e)
+        {
+            if (e.ChangedButton != MouseButton.Left)
+            {
+                return;
+            }
+
+            // 双击鼠标
+            if (e.ClickCount == 2 && e.ChangedButton == MouseButton.Left)
+            {
+                var item = (FrameworkElement) sender;
+                var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
+                if (treeNodeViewModel.IsFolder)
+                {
+                    this.ViewModel.UnFold(treeNodeViewModel);
+                }
+                else
+                {
+                    this.ViewModel.Fold(treeNodeViewModel);
+                }
+            }
+            e.Handled = true;
+        }
+
+        private void ListBoxItem_MouseUp(object sender, MouseButtonEventArgs e)
+        {
+            if (!this.isLeftButtonDown)
+            {
+                this.isDragging = false;
+                return;
+            }
+
+            var item = (FrameworkElement) sender;
+            var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
+
+            if (!this.isDragging)
+            {
+                this.listBox.SelectedItem = treeNodeViewModel;
+            }
+
+            this.isLeftButtonDown = false;
+            this.isDragging = false;
+
+            item.ReleaseMouseCapture();
+            e.Handled = true;
+        }
+
+        private void ListBoxItem_MouseMove(object sender, MouseEventArgs e)
+        {
+            var item = (FrameworkElement) sender;
+            var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
+            if (treeNodeViewModel == null)
+            {
+                return;
+            }
+
+            Point curMouseDownPoint;
+            Vector dragDelta;
+            // 拖动根节点,移动整个树
+            if (this.isDragging && treeNodeViewModel.IsRoot)
+            {
+                if (this.moveFromNode == null || !this.moveFromNode.IsRoot)
+                {
+                    return;
+                }
+                curMouseDownPoint = e.GetPosition(this);
+                dragDelta = curMouseDownPoint - this.origMouseDownPoint;
+
+                this.origMouseDownPoint = curMouseDownPoint;
+
+                this.ViewModel.MoveToPosition(dragDelta.X, dragDelta.Y);
+                return;
+            }
+
+            if (e.LeftButton != MouseButtonState.Pressed)
+            {
+                this.isDragging = false;
+                this.moveFromNode = null;
+                return;
+            }
+
+            curMouseDownPoint = e.GetPosition(this);
+            dragDelta = curMouseDownPoint - this.origMouseDownPoint;
+            double dragDistance = Math.Abs(dragDelta.Length);
+            if (dragDistance > DragThreshold)
+            {
+                this.isDragging = true;
+            }
+            e.Handled = true;
+        }
+
+        private void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseEventArgs e)
+        {
+            this.origMouseDownPoint = e.GetPosition(this);
+            var item = (FrameworkElement) sender;
+            var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
+
+            this.listBox.SelectedItem = treeNodeViewModel;
+            this.moveFromNode = treeNodeViewModel;
+
+            this.nodeDataEditor.DataContext = treeNodeViewModel;
+        }
+
+        private void ListBoxItem_PreviewMouseLeftButtonUp(object sender, MouseEventArgs e)
+        {
+            if (this.moveFromNode == null)
+            {
+                return;
+            }
+            if (this.moveFromNode.IsRoot)
+            {
+                return;
+            }
+            var item = (FrameworkElement) sender;
+            var moveToNode = item.DataContext as TreeNodeViewModel;
+            Log.Debug("move to node: {0} {1}", this.moveFromNode.Id, moveToNode.Id);
+            if (this.moveFromNode.Id == moveToNode.Id)
+            {
+                return;
+            }
+            this.ViewModel.MoveToNode(this.moveFromNode, moveToNode);
+            this.moveFromNode = null;
+        }
+    }
 }

+ 209 - 206
CSharp/App/Modules/Tree/BehaviorTreeViewModel.cs

@@ -1,211 +1,214 @@
-using System.Collections.ObjectModel;
+using System.Collections.ObjectModel;
 using System.ComponentModel.Composition;
 using System.IO;
 using Helper;
 
-namespace Tree
-{
-	[Export(contractType: typeof (BehaviorTreeViewModel)),
-		PartCreationPolicy(creationPolicy: CreationPolicy.NonShared)]
-	internal class BehaviorTreeViewModel
-	{
-		private readonly ObservableCollection<TreeNodeViewModel> treeNodes =
-			new ObservableCollection<TreeNodeViewModel>();
-
-		public ObservableCollection<TreeNodeViewModel> TreeNodes
-		{
-			get
-			{
-				return this.treeNodes;
-			}
-		}
-
-		private TreeNodeViewModel Root
-		{
-			get
-			{
-				return this.treeNodes.Count == 0? null : this.treeNodes[0];
-			}
-		}
-
-		public void Add(TreeNodeViewModel treeNode, TreeNodeViewModel parent)
-		{
-			// 如果父节点是折叠的,需要先展开父节点
-			if (parent != null && parent.IsFolder)
-			{
-				UnFold(parent);
-			}
-			this.treeNodes.Add(treeNode);
-			if (parent != null)
-			{
-				parent.Children.Add(treeNode);
-			}
-			BehaviorTreeLayout.ExcuteLayout(this.Root);
-		}
-
-		private void RecursionRemove(TreeNodeViewModel treeNodeViewModel)
-		{
-			for (int i = 0; i < treeNodeViewModel.Children.Count; ++i)
-			{
-				this.RecursionRemove(treeNodeViewModel.Children[i]);
-			}
-			this.treeNodes.Remove(treeNodeViewModel);
-		}
-
-		public void Remove(TreeNodeViewModel treeNodeViewModel)
-		{
-			this.RecursionRemove(treeNodeViewModel);
-			treeNodeViewModel.Parent.Children.Remove(treeNodeViewModel);
-			BehaviorTreeLayout.ExcuteLayout(this.Root);
-		}
-
-		private void RecursionMove(TreeNodeViewModel treeNodeViewModel, double offsetX, double offsetY)
-		{
-			treeNodeViewModel.X += offsetX;
-			treeNodeViewModel.Y += offsetY;
-			foreach (var node in treeNodeViewModel.Children)
-			{
-				this.RecursionMove(node, offsetX, offsetY);
-			}
-		}
-
-		public void MoveToPosition(double offsetX, double offsetY)
-		{
-			this.RecursionMove(this.Root, offsetX, offsetY);
-		}
-
-		public void MoveToNode(TreeNodeViewModel from, TreeNodeViewModel to)
-		{
-			// from节点不能是to节点的父级节点
-			TreeNodeViewModel tmpNode = to;
-			while (tmpNode != null)
-			{
-				if (tmpNode.IsRoot)
-				{
-					break;
-				}
-				if (tmpNode.Id == from.Id)
-				{
-					return;
-				}
-				tmpNode = tmpNode.Parent;
-			}
-
-			if (from.IsFolder)
-			{
-				this.UnFold(from);
-			}
-
-			if (to.IsFolder)
-			{
-				this.UnFold(to);
-			}
-			from.Parent.Children.Remove(from);
-			to.Children.Add(from);
-			from.Parent = to;
-			BehaviorTreeLayout.ExcuteLayout(this.Root);
-		}
-
-		/// <summary>
-		/// 折叠节点
-		/// </summary>
-		/// <param name="treeNodeViewModel"></param>
-		public void Fold(TreeNodeViewModel treeNodeViewModel)
-		{
-			foreach (var node in treeNodeViewModel.Children)
-			{
-				this.RecursionRemove(node);
-			}
-			treeNodeViewModel.IsFolder = true;
-			BehaviorTreeLayout.ExcuteLayout(this.Root);
-		}
-
-		/// <summary>
-		/// 展开节点,一级一级展开,一次只展开下层子节点,比如下层节点是折叠的,那下下层节点不展开
-		/// </summary>
-		/// <param name="unFoldNode"></param>
-		public void UnFold(TreeNodeViewModel unFoldNode)
-		{
-			foreach (var tn in unFoldNode.Children)
-			{
-				this.RecursionAdd(tn);
-			}
-			unFoldNode.IsFolder = false;
-			BehaviorTreeLayout.ExcuteLayout(this.Root);
-		}
-
-		private void RecursionAdd(TreeNodeViewModel treeNodeViewModel)
-		{
-			if (!this.treeNodes.Contains(treeNodeViewModel))
-			{
-				this.treeNodes.Add(treeNodeViewModel);
-			}
-			ObservableCollection<TreeNodeViewModel> children = treeNodeViewModel.Children;
-
-			if (treeNodeViewModel.IsFolder)
-			{
-				return;
-			}
-			foreach (var tn in children)
-			{
-				this.RecursionAdd(tn);
-			}
-		}
-
-		/// <summary>
-		/// 序列化保存
-		/// </summary>
-		public void Save(string filePath)
-		{
-			var treeNodeDataArray = new TreeNodeDataArray();
-			RecursionSave(treeNodeDataArray, this.Root);
-			byte[] bytes = ProtobufHelper.ToBytes(treeNodeDataArray);
-			using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
-			{
-				stream.Write(bytes, 0, bytes.Length);
-			}
-		}
-
-		private void RecursionSave(TreeNodeDataArray treeNodeDataArray, TreeNodeViewModel node)
-		{
-			if (node == null)
-			{
-				return;
-			}
-			treeNodeDataArray.Add(node.TreeNodeData);
-			foreach (TreeNodeViewModel childNode in node.Children)
-			{
-				RecursionSave(treeNodeDataArray, childNode);
-			}
-		}
-
-		/// <summary>
-		/// 从配置中加载
-		/// </summary>
-		/// <param name="filePath"></param>
-		public void Load(string filePath)
-		{
-			this.TreeNodes.Clear();
-			byte[] bytes = File.ReadAllBytes(filePath);
-			var treeNodeDataArray = ProtobufHelper.FromBytes<TreeNodeDataArray>(bytes);
-			treeNodeDataArray.Init();
-			if (treeNodeDataArray.TreeNodeDatas.Count == 0)
-			{
-				return;
-			}
-			RecursionLoad(treeNodeDataArray, treeNodeDataArray.TreeNodeDatas[0], null);
-		}
-
-		private void RecursionLoad(TreeNodeDataArray treeNodeDataArray, TreeNodeData treeNodeData, TreeNodeViewModel parentNode)
-		{
-			var node = new TreeNodeViewModel(treeNodeData, parentNode);
-			this.Add(node, parentNode);
-			foreach (int id in treeNodeData.ChildrenId)
-			{
-				TreeNodeData childNodeData = treeNodeDataArray[id];
-				RecursionLoad(treeNodeDataArray, childNodeData, node);
-			}
-			BehaviorTreeLayout.ExcuteLayout(this.Root);
-		}
-	}
+namespace Tree
+{
+    [Export(contractType: typeof (BehaviorTreeViewModel)),
+     PartCreationPolicy(creationPolicy: CreationPolicy.NonShared)]
+    internal class BehaviorTreeViewModel
+    {
+        private readonly ObservableCollection<TreeNodeViewModel> treeNodes =
+                new ObservableCollection<TreeNodeViewModel>();
+
+        public ObservableCollection<TreeNodeViewModel> TreeNodes
+        {
+            get
+            {
+                return this.treeNodes;
+            }
+        }
+
+        private TreeNodeViewModel Root
+        {
+            get
+            {
+                return this.treeNodes.Count == 0? null : this.treeNodes[0];
+            }
+        }
+
+        public void Add(TreeNodeViewModel treeNode, TreeNodeViewModel parent)
+        {
+            // 如果父节点是折叠的,需要先展开父节点
+            if (parent != null && parent.IsFolder)
+            {
+                this.UnFold(parent);
+            }
+            this.treeNodes.Add(treeNode);
+            if (parent != null)
+            {
+                parent.Children.Add(treeNode);
+            }
+            BehaviorTreeLayout.ExcuteLayout(this.Root);
+        }
+
+        private void RecursionRemove(TreeNodeViewModel treeNodeViewModel)
+        {
+            for (int i = 0; i < treeNodeViewModel.Children.Count; ++i)
+            {
+                this.RecursionRemove(treeNodeViewModel.Children[i]);
+            }
+            this.treeNodes.Remove(treeNodeViewModel);
+        }
+
+        public void Remove(TreeNodeViewModel treeNodeViewModel)
+        {
+            this.RecursionRemove(treeNodeViewModel);
+            treeNodeViewModel.Parent.Children.Remove(treeNodeViewModel);
+            BehaviorTreeLayout.ExcuteLayout(this.Root);
+        }
+
+        private void RecursionMove(
+                TreeNodeViewModel treeNodeViewModel, double offsetX, double offsetY)
+        {
+            treeNodeViewModel.X += offsetX;
+            treeNodeViewModel.Y += offsetY;
+            foreach (var node in treeNodeViewModel.Children)
+            {
+                this.RecursionMove(node, offsetX, offsetY);
+            }
+        }
+
+        public void MoveToPosition(double offsetX, double offsetY)
+        {
+            this.RecursionMove(this.Root, offsetX, offsetY);
+        }
+
+        public void MoveToNode(TreeNodeViewModel from, TreeNodeViewModel to)
+        {
+            // from节点不能是to节点的父级节点
+            TreeNodeViewModel tmpNode = to;
+            while (tmpNode != null)
+            {
+                if (tmpNode.IsRoot)
+                {
+                    break;
+                }
+                if (tmpNode.Id == from.Id)
+                {
+                    return;
+                }
+                tmpNode = tmpNode.Parent;
+            }
+
+            if (from.IsFolder)
+            {
+                this.UnFold(from);
+            }
+
+            if (to.IsFolder)
+            {
+                this.UnFold(to);
+            }
+            from.Parent.Children.Remove(from);
+            to.Children.Add(from);
+            from.Parent = to;
+            BehaviorTreeLayout.ExcuteLayout(this.Root);
+        }
+
+        /// <summary>
+        /// 折叠节点
+        /// </summary>
+        /// <param name="treeNodeViewModel"></param>
+        public void Fold(TreeNodeViewModel treeNodeViewModel)
+        {
+            foreach (var node in treeNodeViewModel.Children)
+            {
+                this.RecursionRemove(node);
+            }
+            treeNodeViewModel.IsFolder = true;
+            BehaviorTreeLayout.ExcuteLayout(this.Root);
+        }
+
+        /// <summary>
+        /// 展开节点,一级一级展开,一次只展开下层子节点,比如下层节点是折叠的,那下下层节点不展开
+        /// </summary>
+        /// <param name="unFoldNode"></param>
+        public void UnFold(TreeNodeViewModel unFoldNode)
+        {
+            foreach (var tn in unFoldNode.Children)
+            {
+                this.RecursionAdd(tn);
+            }
+            unFoldNode.IsFolder = false;
+            BehaviorTreeLayout.ExcuteLayout(this.Root);
+        }
+
+        private void RecursionAdd(TreeNodeViewModel treeNodeViewModel)
+        {
+            if (!this.treeNodes.Contains(treeNodeViewModel))
+            {
+                this.treeNodes.Add(treeNodeViewModel);
+            }
+            ObservableCollection<TreeNodeViewModel> children = treeNodeViewModel.Children;
+
+            if (treeNodeViewModel.IsFolder)
+            {
+                return;
+            }
+            foreach (var tn in children)
+            {
+                this.RecursionAdd(tn);
+            }
+        }
+
+        /// <summary>
+        /// 序列化保存
+        /// </summary>
+        public void Save(string filePath)
+        {
+            var treeNodeDataArray = new TreeNodeDataArray();
+            this.RecursionSave(treeNodeDataArray, this.Root);
+            byte[] bytes = ProtobufHelper.ToBytes(treeNodeDataArray);
+            using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+            {
+                stream.Write(bytes, 0, bytes.Length);
+            }
+        }
+
+        private void RecursionSave(TreeNodeDataArray treeNodeDataArray, TreeNodeViewModel node)
+        {
+            if (node == null)
+            {
+                return;
+            }
+            treeNodeDataArray.Add(node.TreeNodeData);
+            foreach (TreeNodeViewModel childNode in node.Children)
+            {
+                this.RecursionSave(treeNodeDataArray, childNode);
+            }
+        }
+
+        /// <summary>
+        /// 从配置中加载
+        /// </summary>
+        /// <param name="filePath"></param>
+        public void Load(string filePath)
+        {
+            this.TreeNodes.Clear();
+            byte[] bytes = File.ReadAllBytes(filePath);
+            var treeNodeDataArray = ProtobufHelper.FromBytes<TreeNodeDataArray>(bytes);
+            treeNodeDataArray.Init();
+            if (treeNodeDataArray.TreeNodeDatas.Count == 0)
+            {
+                return;
+            }
+            this.RecursionLoad(treeNodeDataArray, treeNodeDataArray.TreeNodeDatas[0], null);
+        }
+
+        private void RecursionLoad(
+                TreeNodeDataArray treeNodeDataArray, TreeNodeData treeNodeData,
+                TreeNodeViewModel parentNode)
+        {
+            var node = new TreeNodeViewModel(treeNodeData, parentNode);
+            this.Add(node, parentNode);
+            foreach (int id in treeNodeData.Children)
+            {
+                TreeNodeData childNodeData = treeNodeDataArray[id];
+                this.RecursionLoad(treeNodeDataArray, childNodeData, node);
+            }
+            BehaviorTreeLayout.ExcuteLayout(this.Root);
+        }
+    }
 }

+ 23 - 22
CSharp/App/Modules/Tree/FolderVisiableConverter.cs

@@ -5,26 +5,27 @@ using System.Windows.Data;
 
 namespace Tree
 {
-	[ValueConversion(typeof(bool), typeof(Visibility))]
-	public class FolderVisiableConverter : IValueConverter
-	{
-		public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-		{
-			if (value == null)
-			{
-				return 0;
-			}
-			bool isFolder = (bool) value;
-			if (isFolder)
-			{
-				return Visibility.Visible;
-			}
-			return Visibility.Hidden;
-		}
+    [ValueConversion(typeof (bool), typeof (Visibility))]
+    public class FolderVisiableConverter: IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value == null)
+            {
+                return 0;
+            }
+            bool isFolder = (bool) value;
+            if (isFolder)
+            {
+                return Visibility.Visible;
+            }
+            return Visibility.Hidden;
+        }
 
-		public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-		{
-			return null;
-		}
-	}
-}
+        public object ConvertBack(
+                object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            return null;
+        }
+    }
+}

+ 29 - 28
CSharp/App/Modules/Tree/ListToStringConverter.cs

@@ -6,32 +6,33 @@ using System.Windows.Data;
 
 namespace Tree
 {
-	[ValueConversion(typeof(List<string>), typeof(string))]
-	public class ListToStringConverter : IValueConverter
-	{
-		public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-		{
-			if (value == null)
-			{
-				return "";
-			}
-			var list = (List<string>) value;
-			return String.Join(",", list);
-		}
+    [ValueConversion(typeof (List<string>), typeof (string))]
+    public class ListToStringConverter: IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value == null)
+            {
+                return "";
+            }
+            var list = (List<string>) value;
+            return String.Join(",", list);
+        }
 
-		public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-		{
-			if (value == null)
-			{
-				return new List<string>();
-			}
-			var s = (string) value;
-			string[] ss = s.Split(',');
-			for (int i = 0; i < ss.Length; ++i)
-			{
-				ss[i] = ss[i].Trim();
-			}
-			return ss.ToList();
-		}
-	}
-}
+        public object ConvertBack(
+                object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value == null)
+            {
+                return new List<string>();
+            }
+            var s = (string) value;
+            string[] ss = s.Split(',');
+            for (int i = 0; i < ss.Length; ++i)
+            {
+                ss[i] = ss[i].Trim();
+            }
+            return ss.ToList();
+        }
+    }
+}

+ 1 - 1
CSharp/App/Modules/Tree/NodeDataEditor.xaml

@@ -28,6 +28,6 @@
 		<ComboBox Name="cbType" Grid.Column="1" Grid.Row="1" Margin="2" SelectionChanged="CbType_OnSelectionChanged" />
 		<TextBox Name="tbArgs" Grid.Column="1" Grid.Row="2" Margin="2" Text="{Binding Args, Converter={StaticResource ListToStringConverter}}" />
 		<TextBox Name="tbComment" Grid.Column="1" Grid.Row="3" Margin="2" Text="{Binding Comment}" />
-		<Button Content="OK" Grid.Row="4" Grid.Column="1" Margin="1,1,40,1"></Button>
+		<Button Content="OK" Grid.Row="4" Grid.Column="1" Margin="1,1,40,1"/>
 	</Grid>
 </UserControl>

+ 38 - 48
CSharp/App/Modules/Tree/NodeDataEditor.xaml.cs

@@ -1,59 +1,49 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
 using Helper;
 
 namespace Tree
 {
-	/// <summary>
-	/// NodeDataEditor.xaml 的交互逻辑
-	/// </summary>
-	public partial class NodeDataEditor : UserControl
-	{
-		public NodeDataEditor()
-		{
-			InitializeComponent();
+    /// <summary>
+    /// NodeDataEditor.xaml 的交互逻辑
+    /// </summary>
+    public partial class NodeDataEditor: UserControl
+    {
+        public NodeDataEditor()
+        {
+            this.InitializeComponent();
 
-			string[] nodeTypes = Enum.GetNames(typeof(NodeType));
-			this.cbType.ItemsSource = nodeTypes;
-		}
+            string[] nodeTypes = Enum.GetNames(typeof (NodeType));
+            this.cbType.ItemsSource = nodeTypes;
+        }
 
-		public TreeNodeViewModel ViewModel
-		{
-			get
-			{
-				return this.DataContext as TreeNodeViewModel;
-			}
-		}
+        public TreeNodeViewModel ViewModel
+        {
+            get
+            {
+                return this.DataContext as TreeNodeViewModel;
+            }
+        }
 
-		private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
-		{
-			if (this.ViewModel == null)
-			{
-				return;
-			}
-			this.cbType.SelectedIndex = EnumHelper.EnumIndex<NodeType>(this.ViewModel.Type);
-		}
+        private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
+        {
+            if (this.ViewModel == null)
+            {
+                return;
+            }
+            this.cbType.SelectedIndex = EnumHelper.EnumIndex<NodeType>(this.ViewModel.Type);
+        }
 
-		private void CbType_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
-		{
-			if (this.cbType.SelectedValue == null)
-			{
-				this.ViewModel.Type = 0;
-				return;
-			}
-			this.ViewModel.Type = (int)Enum.Parse(typeof(NodeType), this.cbType.SelectedValue.ToString().Trim());
-		}
-	}
-}
+        private void CbType_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            if (this.cbType.SelectedValue == null)
+            {
+                this.ViewModel.Type = 0;
+                return;
+            }
+            this.ViewModel.Type =
+                    (int) Enum.Parse(typeof (NodeType), this.cbType.SelectedValue.ToString().Trim());
+        }
+    }
+}

+ 14 - 14
CSharp/App/Modules/Tree/NodeType.cs

@@ -1,17 +1,17 @@
-
-namespace Tree
+namespace Tree
 {
-	public enum NodeType
-	{
-		Selector = 1,
-		Sequence = 2,
-		Not = 10,
+    public enum NodeType
+    {
+        Selector = 1,
+        Sequence = 2,
+        Not = 10,
 
-		// condition节点 10000开始
-		SelectTarget = 10000,
-		Roll = 10001,
+        // condition节点 10000开始
+        SelectTarget = 10000,
+        Roll = 10001,
+        Compare = 10002,
 
-		// action节点 20000开始
-		CastSpell = 20000,
-	}
-}
+        // action节点 20000开始
+        CastSpell = 20000,
+    }
+}

+ 35 - 36
CSharp/App/Modules/Tree/NodeTypeColorConverter.cs

@@ -1,43 +1,42 @@
 using System;
-using System.Collections.Generic;
 using System.Globalization;
-using System.Linq;
 using System.Windows.Data;
 
 namespace Tree
 {
-	[ValueConversion(typeof(int), typeof(int))]
-	public class NodeTypeColorConverter : IValueConverter
-	{
-		public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-		{
-			if (value == null)
-			{
-				return 0;
-			}
-			int nodeType = (int) value;
-			if (nodeType == (int) NodeType.Selector)
-			{
-				return "selector";
-			}
-			if (nodeType == (int) NodeType.Sequence)
-			{
-				return "sequence";
-			}
-			if (nodeType < 20000 && nodeType >= 10000)
-			{
-				return "condition";
-			}
-			if (nodeType < 30000 && nodeType >= 20000)
-			{
-				return "action";
-			}
-			return "other";
-		}
+    [ValueConversion(typeof (int), typeof (int))]
+    public class NodeTypeColorConverter: IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value == null)
+            {
+                return 0;
+            }
+            int nodeType = (int) value;
+            if (nodeType == (int) NodeType.Selector)
+            {
+                return "selector";
+            }
+            if (nodeType == (int) NodeType.Sequence)
+            {
+                return "sequence";
+            }
+            if (nodeType < 20000 && nodeType >= 10000)
+            {
+                return "condition";
+            }
+            if (nodeType < 30000 && nodeType >= 20000)
+            {
+                return "action";
+            }
+            return "other";
+        }
 
-		public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-		{
-			return null;
-		}
-	}
-}
+        public object ConvertBack(
+                object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            return null;
+        }
+    }
+}

+ 18 - 19
CSharp/App/Modules/Tree/NodeTypeToStringConverter.cs

@@ -1,26 +1,25 @@
 using System;
-using System.Collections.Generic;
 using System.Globalization;
-using System.Linq;
 using System.Windows.Data;
 
 namespace Tree
 {
-	[ValueConversion(typeof(int), typeof(string))]
-	public class NodeTypeToStringConverter : IValueConverter
-	{
-		public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
-		{
-			if (value == null)
-			{
-				return "";
-			}
-			return ((NodeType)(int)value).ToString();
-		}
+    [ValueConversion(typeof (int), typeof (string))]
+    public class NodeTypeToStringConverter: IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value == null)
+            {
+                return "";
+            }
+            return ((NodeType) (int) value).ToString();
+        }
 
-		public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
-		{
-			return null;
-		}
-	}
-}
+        public object ConvertBack(
+                object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            return null;
+        }
+    }
+}

+ 43 - 43
CSharp/App/Modules/Tree/TreeNodeData.cs

@@ -1,53 +1,53 @@
 using System.Collections.Generic;
 using System.Runtime.Serialization;
 
-namespace Tree
+namespace Tree
 {
-	[DataContract]
-	public class TreeNodeData
-	{
-		private readonly List<int> childrenId = new List<int>();
+    [DataContract]
+    public class TreeNodeData
+    {
+        private readonly List<int> children = new List<int>();
 
-		/// <summary>
-		/// 节点唯一Id
-		/// </summary>
-		[DataMember(Order = 1)]
-		public int Id { get; set; }
-
-		/// <summary>
-		/// 节点类型
-		/// </summary>
-		[DataMember(Order = 2)]
-		public int Type { get; set; }
+        /// <summary>
+        /// 节点唯一Id
+        /// </summary>
+        [DataMember(Order = 1)]
+        public int Id { get; set; }
 
-		/// <summary>
-		/// 节点配置参数
-		/// </summary>
-		[DataMember(Order = 3)]
-		public List<string> Args { get; set; }
+        /// <summary>
+        /// 节点类型
+        /// </summary>
+        [DataMember(Order = 2)]
+        public int Type { get; set; }
 
-		/// <summary>
-		/// 父节点
-		/// </summary>
-		[DataMember(Order = 4)]
-		public int ParentId { get; set; }
+        /// <summary>
+        /// 节点配置参数
+        /// </summary>
+        [DataMember(Order = 3)]
+        public List<string> Args { get; set; }
 
-		/// <summary>
-		/// 子节点
-		/// </summary>
-		[DataMember(Order = 5)]
-		public List<int> ChildrenId
-		{
-			get
-			{
-				return this.childrenId;
-			}
-		}
+        /// <summary>
+        /// 父节点
+        /// </summary>
+        [DataMember(Order = 4)]
+        public int Parent { get; set; }
 
-		/// <summary>
-		/// 节点说明
-		/// </summary>
-		[DataMember(Order = 6)]
-		public string Comment { get; set; }
-	}
+        /// <summary>
+        /// 子节点
+        /// </summary>
+        [DataMember(Order = 5)]
+        public List<int> Children
+        {
+            get
+            {
+                return this.children;
+            }
+        }
+
+        /// <summary>
+        /// 节点说明
+        /// </summary>
+        [DataMember(Order = 6)]
+        public string Comment { get; set; }
+    }
 }

+ 34 - 33
CSharp/App/Modules/Tree/TreeNodeDataArray.cs

@@ -3,41 +3,42 @@ using System.Runtime.Serialization;
 
 namespace Tree
 {
-	[DataContract]
-	public class TreeNodeDataArray
-	{
-		private readonly List<TreeNodeData> treeNodeDatas = new List<TreeNodeData>();
+    [DataContract]
+    public class TreeNodeDataArray
+    {
+        private readonly List<TreeNodeData> treeNodeDatas = new List<TreeNodeData>();
 
-		[DataMember(Order = 1)]
-		public List<TreeNodeData> TreeNodeDatas
-		{
-			get
-			{
-				return this.treeNodeDatas;
-			}
-		}
+        [DataMember(Order = 1)]
+        public List<TreeNodeData> TreeNodeDatas
+        {
+            get
+            {
+                return this.treeNodeDatas;
+            }
+        }
 
-		private readonly Dictionary<int, TreeNodeData> treeNodeDict = new Dictionary<int, TreeNodeData>();
+        private readonly Dictionary<int, TreeNodeData> treeNodeDict =
+                new Dictionary<int, TreeNodeData>();
 
-		public void Init()
-		{
-			foreach (TreeNodeData nodeData in this.treeNodeDatas)
-			{
-				treeNodeDict[nodeData.Id] = nodeData;
-			}
-		}
+        public void Init()
+        {
+            foreach (TreeNodeData nodeData in this.treeNodeDatas)
+            {
+                this.treeNodeDict[nodeData.Id] = nodeData;
+            }
+        }
 
-		public void Add(TreeNodeData treeNodeData)
-		{
-			this.treeNodeDatas.Add(treeNodeData);
-		}
+        public void Add(TreeNodeData treeNodeData)
+        {
+            this.treeNodeDatas.Add(treeNodeData);
+        }
 
-		public TreeNodeData this[int id]
-		{
-			get
-			{
-				return this.treeNodeDict[id];
-			}
-		}
-	}
-}
+        public TreeNodeData this[int id]
+        {
+            get
+            {
+                return this.treeNodeDict[id];
+            }
+        }
+    }
+}

+ 385 - 385
CSharp/App/Modules/Tree/TreeNodeViewModel.cs

@@ -1,391 +1,391 @@
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
-using System.Windows.Documents;
 using Microsoft.Practices.Prism.Mvvm;
 
-namespace Tree
-{
-	public class TreeNodeViewModel : BindableBase
-	{
-		private static int globalNum;
-		private static double width = 80;
-		private static double height = 50;
-		private double x;
-		private double y;
-		private readonly TreeNodeData treeNodeData;
-		private double connectorX2;
-		private double connectorY2;
-		private double prelim;
-		private double modify;
-		private double ancestorModify;
-		private TreeNodeViewModel parent;
-		private bool isFolder;
-
-		private ObservableCollection<TreeNodeViewModel> children = new ObservableCollection<TreeNodeViewModel>();
-
-		/// <summary>
-		/// 用于初始化根节点
-		/// </summary>
-		/// <param name="x"></param>
-		/// <param name="y"></param>
-		public TreeNodeViewModel(double x, double y)
-		{
-			this.x = x;
-			this.y = y;
-			this.treeNodeData = new TreeNodeData();
-			this.treeNodeData.Id = globalNum++;
-			this.parent = parent ?? this;
-			this.connectorX2 = 0;
-			this.connectorY2 = Height / 2;
-		}
-
-		public TreeNodeViewModel(TreeNodeViewModel parent)
-		{
-			this.treeNodeData = new TreeNodeData();
-			this.treeNodeData.Id = globalNum++;
-			this.parent = parent ?? this;
-
-			this.connectorX2 = Width + this.Parent.X - this.X;
-			this.connectorY2 = Height / 2 + this.Parent.Y - this.Y;
-		}
-
-		public TreeNodeViewModel(TreeNodeData data, TreeNodeViewModel parent)
-		{
-			this.treeNodeData = data;
-			this.parent = parent ?? this;
-			if (this.parent == this)
-			{
-				this.x = 200;
-				this.y = 10;
-				this.connectorX2 = 0;
-				this.connectorY2 = Height / 2;
-			}
-			else
-			{
-				this.connectorX2 = Width + this.Parent.X - this.X;
-				this.connectorY2 = Height / 2 + this.Parent.Y - this.Y;
-			}
-		}
-
-		public TreeNodeData TreeNodeData
-		{
-			get
-			{
-				this.treeNodeData.ChildrenId.Clear();
-				foreach (TreeNodeViewModel child in children)
-				{
-					this.treeNodeData.ChildrenId.Add(child.Id);
-				}
-				this.treeNodeData.ParentId = this.IsRoot? 0 : this.Parent.Id;
-				return this.treeNodeData;
-			}
-		}
-
-		public int Id
-		{
-			get
-			{
-				return this.treeNodeData.Id;
-			}
-			set
-			{
-				this.treeNodeData.Id = value;
-				this.OnPropertyChanged("Id");
-			}
-		}
-
-		public string Comment
-		{
-			get
-			{
-				return this.treeNodeData.Comment;
-			}
-			set
-			{
-				this.treeNodeData.Comment = value;
-				this.OnPropertyChanged("Comment");
-			}
-		}
-
-		public static double Width
-		{
-			get
-			{
-				return width;
-			}
-			set
-			{
-				width = value;
-			}
-		}
-
-		public static double Height
-		{
-			get
-			{
-				return height;
-			}
-			set
-			{
-				height = value;
-			}
-		}
-
-		public bool IsRoot
-		{
-			get
-			{
-				return this.Parent == this;
-			}
-		}
-
-		public double Prelim
-		{
-			get
-			{
-				return this.prelim;
-			}
-			set
-			{
-				this.prelim = value;
-			}
-		}
-
-		public double Modify
-		{
-			get
-			{
-				return this.modify;
-			}
-			set
-			{
-				this.modify = value;
-			}
-		}
-
-		public double X
-		{
-			get
-			{
-				return this.x;
-			}
-			set
-			{
-				if (Math.Abs(this.x - value) < 0.1)
-				{
-					return;
-				}
-				this.x = value;
-				this.OnPropertyChanged("X");
-
-				this.ConnectorX2 = Width / 2 + this.Parent.X - this.X;
-
-				foreach (TreeNodeViewModel child in this.Children)
-				{
-					child.ConnectorX2 = Width / 2 + this.X - child.X;
-				}
-			}
-		}
-
-		public double Y
-		{
-			get
-			{
-				return this.y;
-			}
-			set
-			{
-				if (Math.Abs(this.Y - value) < 0.1)
-				{
-					return;
-				}
-
-				this.y = value;
-				this.OnPropertyChanged("Y");
-
-				this.ConnectorY2 = Height + this.Parent.Y - this.Y;
-
-				foreach (var child in this.Children)
-				{
-					child.ConnectorY2 = Height + this.Y - child.Y;
-				}
-			}
-		}
-
-		public double ConnectorX1
-		{
-			get
-			{
-				return Width / 2;
-			}
-		}
-
-		public double ConnectorY1
-		{
-			get
-			{
-				return 0;
-			}
-		}
-
-		public double ConnectorX2
-		{
-			get
-			{
-				return this.IsRoot? Width / 2 : this.connectorX2;
-			}
-			set
-			{
-				this.SetProperty(ref this.connectorX2, value);
-			}
-		}
-
-		public double ConnectorY2
-		{
-			get
-			{
-				return this.IsRoot? 0 : this.connectorY2;
-			}
-			set
-			{
-				this.SetProperty(ref this.connectorY2, value);
-			}
-		}
-
-		public int Type
-		{
-			get
-			{
-				return this.treeNodeData.Type;
-			}
-			set
-			{
-				if (this.treeNodeData.Type == value)
-				{
-					return;
-				}
-				this.treeNodeData.Type = value;
-				this.OnPropertyChanged("Type");
-			}
-		}
-
-		public List<string> Args
-		{
-			get
-			{
-				return this.treeNodeData.Args;
-			}
-			set
-			{
-				if (this.treeNodeData.Args == value)
-				{
-					return;
-				}
-				this.treeNodeData.Args = value;
-				this.OnPropertyChanged("Args");
-			}
-		}
-
-		public TreeNodeViewModel Parent
-		{
-			get
-			{
-				return this.parent;
-			}
-			set
-			{
-				this.parent = value;
-				this.OnPropertyChanged("ParentNum");
-			}
-		}
-
-		/// <summary>
-		/// 节点是否折叠
-		/// </summary>
-		public bool IsFolder
-		{
-			get
-			{
-				return this.isFolder;
-			}
-			set
-			{
-				if (isFolder == value)
-				{
-					return;
-				}
-				this.isFolder = value;
-				this.OnPropertyChanged("IsFolder");
-			}
-		}
-
-		public ObservableCollection<TreeNodeViewModel> Children
-		{
-			get
-			{
-				return this.children;
-			}
-			set
-			{
-				this.children = value;
-			}
-		}
-
-		public TreeNodeViewModel LeftSibling
-		{
-			get
-			{
-				if (this.IsRoot)
-				{
-					return null;
-				}
-
-				int index = this.Parent.Children.IndexOf(this);
-				return index == 0? null : this.Parent.Children[index - 1];
-			}
-		}
-
-		public TreeNodeViewModel LastChild
-		{
-			get
-			{
-				if (this.Children.Count == 0)
-				{
-					return null;
-				}
-
-				int maxIndex = this.Children.Count - 1;
-				return this.Children[maxIndex];
-			}
-		}
-
-		public TreeNodeViewModel FirstChild
-		{
-			get
-			{
-				return this.Children.Count == 0? null : this.Children[0];
-			}
-		}
-
-		public bool IsLeaf
-		{
-			get
-			{
-				return this.Children.Count == 0;
-			}
-		}
-
-		public double AncestorModify
-		{
-			get
-			{
-				return this.ancestorModify;
-			}
-			set
-			{
-				this.ancestorModify = value;
-			}
-		}
-	}
+namespace Tree
+{
+    public class TreeNodeViewModel: BindableBase
+    {
+        private static int globalNum;
+        private static double width = 80;
+        private static double height = 50;
+        private double x;
+        private double y;
+        private readonly TreeNodeData treeNodeData;
+        private double connectorX2;
+        private double connectorY2;
+        private double prelim;
+        private double modify;
+        private double ancestorModify;
+        private TreeNodeViewModel parent;
+        private bool isFolder;
+
+        private ObservableCollection<TreeNodeViewModel> children =
+                new ObservableCollection<TreeNodeViewModel>();
+
+        /// <summary>
+        /// 用于初始化根节点
+        /// </summary>
+        /// <param name="x"></param>
+        /// <param name="y"></param>
+        public TreeNodeViewModel(double x, double y)
+        {
+            this.x = x;
+            this.y = y;
+            this.treeNodeData = new TreeNodeData();
+            this.treeNodeData.Id = globalNum++;
+            this.parent = this.parent ?? this;
+            this.connectorX2 = 0;
+            this.connectorY2 = Height / 2;
+        }
+
+        public TreeNodeViewModel(TreeNodeViewModel parent)
+        {
+            this.treeNodeData = new TreeNodeData();
+            this.treeNodeData.Id = globalNum++;
+            this.parent = parent ?? this;
+
+            this.connectorX2 = Width + this.Parent.X - this.X;
+            this.connectorY2 = Height / 2 + this.Parent.Y - this.Y;
+        }
+
+        public TreeNodeViewModel(TreeNodeData data, TreeNodeViewModel parent)
+        {
+            this.treeNodeData = data;
+            this.parent = parent ?? this;
+            if (this.parent == this)
+            {
+                this.x = 200;
+                this.y = 10;
+                this.connectorX2 = 0;
+                this.connectorY2 = Height / 2;
+            }
+            else
+            {
+                this.connectorX2 = Width + this.Parent.X - this.X;
+                this.connectorY2 = Height / 2 + this.Parent.Y - this.Y;
+            }
+        }
+
+        public TreeNodeData TreeNodeData
+        {
+            get
+            {
+                this.treeNodeData.Children.Clear();
+                foreach (TreeNodeViewModel child in this.children)
+                {
+                    this.treeNodeData.Children.Add(child.Id);
+                }
+                this.treeNodeData.Parent = this.IsRoot? 0 : this.Parent.Id;
+                return this.treeNodeData;
+            }
+        }
+
+        public int Id
+        {
+            get
+            {
+                return this.treeNodeData.Id;
+            }
+            set
+            {
+                this.treeNodeData.Id = value;
+                this.OnPropertyChanged("Id");
+            }
+        }
+
+        public string Comment
+        {
+            get
+            {
+                return this.treeNodeData.Comment;
+            }
+            set
+            {
+                this.treeNodeData.Comment = value;
+                this.OnPropertyChanged("Comment");
+            }
+        }
+
+        public static double Width
+        {
+            get
+            {
+                return width;
+            }
+            set
+            {
+                width = value;
+            }
+        }
+
+        public static double Height
+        {
+            get
+            {
+                return height;
+            }
+            set
+            {
+                height = value;
+            }
+        }
+
+        public bool IsRoot
+        {
+            get
+            {
+                return this.Parent == this;
+            }
+        }
+
+        public double Prelim
+        {
+            get
+            {
+                return this.prelim;
+            }
+            set
+            {
+                this.prelim = value;
+            }
+        }
+
+        public double Modify
+        {
+            get
+            {
+                return this.modify;
+            }
+            set
+            {
+                this.modify = value;
+            }
+        }
+
+        public double X
+        {
+            get
+            {
+                return this.x;
+            }
+            set
+            {
+                if (Math.Abs(this.x - value) < 0.1)
+                {
+                    return;
+                }
+                this.x = value;
+                this.OnPropertyChanged("X");
+
+                this.ConnectorX2 = Width / 2 + this.Parent.X - this.X;
+
+                foreach (TreeNodeViewModel child in this.Children)
+                {
+                    child.ConnectorX2 = Width / 2 + this.X - child.X;
+                }
+            }
+        }
+
+        public double Y
+        {
+            get
+            {
+                return this.y;
+            }
+            set
+            {
+                if (Math.Abs(this.Y - value) < 0.1)
+                {
+                    return;
+                }
+
+                this.y = value;
+                this.OnPropertyChanged("Y");
+
+                this.ConnectorY2 = Height + this.Parent.Y - this.Y;
+
+                foreach (var child in this.Children)
+                {
+                    child.ConnectorY2 = Height + this.Y - child.Y;
+                }
+            }
+        }
+
+        public double ConnectorX1
+        {
+            get
+            {
+                return Width / 2;
+            }
+        }
+
+        public double ConnectorY1
+        {
+            get
+            {
+                return 0;
+            }
+        }
+
+        public double ConnectorX2
+        {
+            get
+            {
+                return this.IsRoot? Width / 2 : this.connectorX2;
+            }
+            set
+            {
+                this.SetProperty(ref this.connectorX2, value);
+            }
+        }
+
+        public double ConnectorY2
+        {
+            get
+            {
+                return this.IsRoot? 0 : this.connectorY2;
+            }
+            set
+            {
+                this.SetProperty(ref this.connectorY2, value);
+            }
+        }
+
+        public int Type
+        {
+            get
+            {
+                return this.treeNodeData.Type;
+            }
+            set
+            {
+                if (this.treeNodeData.Type == value)
+                {
+                    return;
+                }
+                this.treeNodeData.Type = value;
+                this.OnPropertyChanged("Type");
+            }
+        }
+
+        public List<string> Args
+        {
+            get
+            {
+                return this.treeNodeData.Args;
+            }
+            set
+            {
+                if (this.treeNodeData.Args == value)
+                {
+                    return;
+                }
+                this.treeNodeData.Args = value;
+                this.OnPropertyChanged("Args");
+            }
+        }
+
+        public TreeNodeViewModel Parent
+        {
+            get
+            {
+                return this.parent;
+            }
+            set
+            {
+                this.parent = value;
+                this.OnPropertyChanged("ParentNum");
+            }
+        }
+
+        /// <summary>
+        /// 节点是否折叠
+        /// </summary>
+        public bool IsFolder
+        {
+            get
+            {
+                return this.isFolder;
+            }
+            set
+            {
+                if (this.isFolder == value)
+                {
+                    return;
+                }
+                this.isFolder = value;
+                this.OnPropertyChanged("IsFolder");
+            }
+        }
+
+        public ObservableCollection<TreeNodeViewModel> Children
+        {
+            get
+            {
+                return this.children;
+            }
+            set
+            {
+                this.children = value;
+            }
+        }
+
+        public TreeNodeViewModel LeftSibling
+        {
+            get
+            {
+                if (this.IsRoot)
+                {
+                    return null;
+                }
+
+                int index = this.Parent.Children.IndexOf(this);
+                return index == 0? null : this.Parent.Children[index - 1];
+            }
+        }
+
+        public TreeNodeViewModel LastChild
+        {
+            get
+            {
+                if (this.Children.Count == 0)
+                {
+                    return null;
+                }
+
+                int maxIndex = this.Children.Count - 1;
+                return this.Children[maxIndex];
+            }
+        }
+
+        public TreeNodeViewModel FirstChild
+        {
+            get
+            {
+                return this.Children.Count == 0? null : this.Children[0];
+            }
+        }
+
+        public bool IsLeaf
+        {
+            get
+            {
+                return this.Children.Count == 0;
+            }
+        }
+
+        public double AncestorModify
+        {
+            get
+            {
+                return this.ancestorModify;
+            }
+            set
+            {
+                this.ancestorModify = value;
+            }
+        }
+    }
 }

+ 11 - 13
CSharp/App/Modules/WCFClient/Properties/AssemblyInfo.cs

@@ -1,12 +1,11 @@
 using System.Reflection;
-using System.Resources;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Windows;
 
 // 有关程序集的常规信息通过以下
 // 特性集控制。更改这些特性值可修改
 // 与程序集关联的信息。
+
 [assembly: AssemblyTitle("WCFClient")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
@@ -19,6 +18,7 @@ using System.Windows;
 // 将 ComVisible 设置为 false 使此程序集中的类型
 // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
 // 则将该类型上的 ComVisible 特性设置为 true。
+
 [assembly: ComVisible(false)]
 
 //若要开始生成可本地化的应用程序,请在 
@@ -30,16 +30,13 @@ using System.Windows;
 
 //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
 
-
-[assembly:ThemeInfo(
-    ResourceDictionaryLocation.None, //主题特定资源词典所处位置
-                             //(在页面或应用程序资源词典中 
-                             // 未找到某个资源的情况下使用)
-    ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
-                                      //(在页面、应用程序或任何主题特定资源词典中 
-                                      // 未找到某个资源的情况下使用)
-)]
-
+[assembly: ThemeInfo(ResourceDictionaryLocation.None, //主题特定资源词典所处位置
+        //(在页面或应用程序资源词典中 
+        // 未找到某个资源的情况下使用)
+        ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
+        //(在页面、应用程序或任何主题特定资源词典中 
+        // 未找到某个资源的情况下使用)
+        )]
 
 // 程序集的版本信息由下面四个值组成:
 //
@@ -51,5 +48,6 @@ using System.Windows;
 // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
 // 方法是按如下所示使用“*”:
 // [assembly: AssemblyVersion("1.0.*")]
+
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 13 - 13
CSharp/App/Modules/WCFClient/WCFClientModule.cs

@@ -1,13 +1,13 @@
-using Microsoft.Practices.Prism.MefExtensions.Modularity;
-using Microsoft.Practices.Prism.Modularity;
-
-namespace WCFClient
-{
-	[ModuleExport(moduleType: typeof(WCFClientModule))]
-	public class WCFClientModule : IModule
-	{
-		public void Initialize()
-		{
-		}
-	}
-}
+using Microsoft.Practices.Prism.MefExtensions.Modularity;
+using Microsoft.Practices.Prism.Modularity;
+
+namespace WCFClient
+{
+    [ModuleExport(moduleType: typeof (WCFClientModule))]
+    public class WCFClientModule: IModule
+    {
+        public void Initialize()
+        {
+        }
+    }
+}

+ 16 - 15
CSharp/App/Modules/WCFClient/WCFClientView.xaml.cs

@@ -1,21 +1,22 @@
 using System.ComponentModel.Composition;
+using System.Windows;
 using Infrastructure;
 
 namespace WCFClient
 {
-	/// <summary>
-	/// WCFClientView.xaml 的交互逻辑
-	/// </summary>
-	[ViewExport(RegionName = "WCFClientRegion"), PartCreationPolicy(CreationPolicy.NonShared)]
-	public partial class WCFClientView
-	{
-		public WCFClientView()
-		{
-			InitializeComponent();
-		}
+    /// <summary>
+    /// WCFClientView.xaml 的交互逻辑
+    /// </summary>
+    [ViewExport(RegionName = "WCFClientRegion"), PartCreationPolicy(CreationPolicy.NonShared)]
+    public partial class WCFClientView
+    {
+        public WCFClientView()
+        {
+            this.InitializeComponent();
+        }
 
-		private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
-		{
-		}
-	}
-}
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+        }
+    }
+}

+ 10 - 10
CSharp/App/Modules/WCFClient/WCFClientViewModel.cs

@@ -1,10 +1,10 @@
-using System.ComponentModel.Composition;
-
-namespace WCFClient
-{
-	[Export(contractType: typeof(WCFClientViewModel)),
-		PartCreationPolicy(creationPolicy: CreationPolicy.NonShared)]
-	public class WCFClientViewModel
-	{
-	}
-}
+using System.ComponentModel.Composition;
+
+namespace WCFClient
+{
+    [Export(contractType: typeof (WCFClientViewModel)),
+     PartCreationPolicy(creationPolicy: CreationPolicy.NonShared)]
+    public class WCFClientViewModel
+    {
+    }
+}

+ 17 - 17
CSharp/Game/BehaviorTree/BehaviorTree.cs

@@ -1,17 +1,17 @@
-namespace BehaviorTree
-{
-	public class BehaviorTree
-	{
-		private readonly Node node;
-
-		public BehaviorTree(Node node)
-		{
-			this.node = node;
-		}
-
-		public bool Run(BlackBoard blackBoard)
-		{
-			return this.node.Run(blackBoard);
-		}
-	}
-}
+namespace BehaviorTree
+{
+    public class BehaviorTree
+    {
+        private readonly Node node;
+
+        public BehaviorTree(Node node)
+        {
+            this.node = node;
+        }
+
+        public bool Run(BlackBoard blackBoard)
+        {
+            return this.node.Run(blackBoard);
+        }
+    }
+}

+ 55 - 54
CSharp/Game/BehaviorTree/BehaviorTreeFactory.cs

@@ -1,54 +1,55 @@
-using System;
-using System.Collections.Generic;
-
-namespace BehaviorTree
-{
-	public class BehaviorTreeFactory
-	{
-		private readonly Dictionary<string, Func<Config, Node>> dictionary =
-			new Dictionary<string, Func<Config, Node>>();
-
-		public BehaviorTreeFactory()
-		{
-			this.dictionary.Add("selector", config => new Selector(config));
-			this.dictionary.Add("sequence", config => new Sequence(config));
-			this.dictionary.Add("not", config => new Not(config));
-		}
-
-		public void Register(string name, Func<Config, Node> action)
-		{
-			this.dictionary.Add(name, action);
-		}
-
-		private Node CreateNode(Config config)
-		{
-			if (!this.dictionary.ContainsKey(config.Name))
-			{
-				throw new KeyNotFoundException(string.Format("CreateNode cannot found: {0}", config.Name));
-			}
-			return this.dictionary[config.Name](config);
-		}
-
-		private Node CreateTreeNode(Config config)
-		{
-			var node = this.CreateNode(config);
-			if (config.SubConfigs == null)
-			{
-				return node;
-			}
-
-			foreach (var subConfig in config.SubConfigs)
-			{
-				var subNode = this.CreateTreeNode(subConfig);
-				node.AddChild(subNode);
-			}
-			return node;
-		}
-
-		public BehaviorTree CreateTree(Config config)
-		{
-			var node = this.CreateTreeNode(config);
-			return new BehaviorTree(node);
-		}
-	}
-}
+using System;
+using System.Collections.Generic;
+
+namespace BehaviorTree
+{
+    public class BehaviorTreeFactory
+    {
+        private readonly Dictionary<string, Func<Config, Node>> dictionary =
+                new Dictionary<string, Func<Config, Node>>();
+
+        public BehaviorTreeFactory()
+        {
+            this.dictionary.Add("selector", config => new Selector(config));
+            this.dictionary.Add("sequence", config => new Sequence(config));
+            this.dictionary.Add("not", config => new Not(config));
+        }
+
+        public void Register(string name, Func<Config, Node> action)
+        {
+            this.dictionary.Add(name, action);
+        }
+
+        private Node CreateNode(Config config)
+        {
+            if (!this.dictionary.ContainsKey(config.Name))
+            {
+                throw new KeyNotFoundException(string.Format("CreateNode cannot found: {0}",
+                        config.Name));
+            }
+            return this.dictionary[config.Name](config);
+        }
+
+        private Node CreateTreeNode(Config config)
+        {
+            var node = this.CreateNode(config);
+            if (config.SubConfigs == null)
+            {
+                return node;
+            }
+
+            foreach (var subConfig in config.SubConfigs)
+            {
+                var subNode = this.CreateTreeNode(subConfig);
+                node.AddChild(subNode);
+            }
+            return node;
+        }
+
+        public BehaviorTree CreateTree(Config config)
+        {
+            var node = this.CreateTreeNode(config);
+            return new BehaviorTree(node);
+        }
+    }
+}

+ 8 - 8
CSharp/Game/BehaviorTree/BlackBoard.cs

@@ -1,8 +1,8 @@
-using Component;
-
-namespace BehaviorTree
-{
-	public class BlackBoard: Object
-	{
-	}
-}
+using Component;
+
+namespace BehaviorTree
+{
+    public class BlackBoard: Object
+    {
+    }
+}

+ 38 - 38
CSharp/Game/BehaviorTree/Config.cs

@@ -1,38 +1,38 @@
-using System.Collections.Generic;
-using MongoDB.Bson.Serialization.Attributes;
-
-namespace BehaviorTree
-{
-	public class Config
-	{
-		public uint Id { get; set; }
-
-		public string Name { get; set; }
-
-		[BsonIgnoreIfNull]
-		public List<string> Args { get; set; }
-
-		[BsonIgnoreIfNull]
-		public List<Config> SubConfigs { get; set; }
-
-		public void AddArgs(string arg)
-		{
-			if (this.Args == null)
-			{
-				this.Args = new List<string>();
-			}
-
-			this.Args.Add(arg);
-		}
-
-		public void AddSubConfig(Config subConfig)
-		{
-			if (this.SubConfigs == null)
-			{
-				this.SubConfigs = new List<Config>();
-			}
-
-			this.SubConfigs.Add(subConfig);
-		}
-	}
-}
+using System.Collections.Generic;
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace BehaviorTree
+{
+    public class Config
+    {
+        public uint Id { get; set; }
+
+        public string Name { get; set; }
+
+        [BsonIgnoreIfNull]
+        public List<string> Args { get; set; }
+
+        [BsonIgnoreIfNull]
+        public List<Config> SubConfigs { get; set; }
+
+        public void AddArgs(string arg)
+        {
+            if (this.Args == null)
+            {
+                this.Args = new List<string>();
+            }
+
+            this.Args.Add(arg);
+        }
+
+        public void AddSubConfig(Config subConfig)
+        {
+            if (this.SubConfigs == null)
+            {
+                this.SubConfigs = new List<Config>();
+            }
+
+            this.SubConfigs.Add(subConfig);
+        }
+    }
+}

+ 18 - 18
CSharp/Game/BehaviorTree/Node.cs

@@ -1,18 +1,18 @@
-using System.Collections.Generic;
-
-namespace BehaviorTree
-{
-	public abstract class Node
-	{
-		public string Name { get; protected set; }
-
-		protected readonly List<Node> children = new List<Node>();
-
-		public void AddChild(Node child)
-		{
-			this.children.Add(child);
-		}
-
-		public abstract bool Run(BlackBoard blackBoard);
-	}
-}
+using System.Collections.Generic;
+
+namespace BehaviorTree
+{
+    public abstract class Node
+    {
+        public string Name { get; protected set; }
+
+        protected readonly List<Node> children = new List<Node>();
+
+        public void AddChild(Node child)
+        {
+            this.children.Add(child);
+        }
+
+        public abstract bool Run(BlackBoard blackBoard);
+    }
+}

+ 23 - 22
CSharp/Game/BehaviorTree/Not.cs

@@ -1,22 +1,23 @@
-using System;
-
-namespace BehaviorTree
-{
-	public class Not: Node
-	{
-		public Not(Config config)
-		{
-			this.Name = config.Name;
-		}
-
-		public override bool Run(BlackBoard blackBoard)
-		{
-			if (children.Count != 1)
-			{
-				throw new Exception(string.Format("not node children count not eq 1: {0}", children.Count));
-			}
-
-			return !this.children[0].Run(blackBoard);
-		}
-	}
-}
+using System;
+
+namespace BehaviorTree
+{
+    public class Not: Node
+    {
+        public Not(Config config)
+        {
+            this.Name = config.Name;
+        }
+
+        public override bool Run(BlackBoard blackBoard)
+        {
+            if (this.children.Count != 1)
+            {
+                throw new Exception(string.Format("not node children count not eq 1: {0}",
+                        this.children.Count));
+            }
+
+            return !this.children[0].Run(blackBoard);
+        }
+    }
+}

+ 5 - 2
CSharp/Game/BehaviorTree/Properties/AssemblyInfo.cs

@@ -1,10 +1,10 @@
 using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 // 有关程序集的常规信息通过以下
 // 特性集控制。更改这些特性值可修改
 // 与程序集关联的信息。
+
 [assembly: AssemblyTitle("BehaviorTree")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
@@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
 // 将 ComVisible 设置为 false 使此程序集中的类型
 // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
 // 则将该类型上的 ComVisible 特性设置为 true。
+
 [assembly: ComVisible(false)]
 
 // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+
 [assembly: Guid("cde1ceab-c151-495d-845e-53d620807b40")]
 
 // 程序集的版本信息由下面四个值组成:
@@ -32,5 +34,6 @@ using System.Runtime.InteropServices;
 // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
 // 方法是按如下所示使用“*”:
 // [assembly: AssemblyVersion("1.0.*")]
+
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 22 - 22
CSharp/Game/BehaviorTree/Selector.cs

@@ -1,22 +1,22 @@
-namespace BehaviorTree
-{
-	public class Selector: Node
-	{
-		public Selector(Config config)
-		{
-			this.Name = config.Name;
-		}
-
-		public override bool Run(BlackBoard blackBoard)
-		{
-			foreach (var child in children)
-			{
-				if (child.Run(blackBoard))
-				{
-					return true;
-				}
-			}
-			return false;
-		}
-	}
-}
+namespace BehaviorTree
+{
+    public class Selector: Node
+    {
+        public Selector(Config config)
+        {
+            this.Name = config.Name;
+        }
+
+        public override bool Run(BlackBoard blackBoard)
+        {
+            foreach (var child in this.children)
+            {
+                if (child.Run(blackBoard))
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+}

+ 22 - 22
CSharp/Game/BehaviorTree/Sequence.cs

@@ -1,22 +1,22 @@
-namespace BehaviorTree
-{
-	class Sequence: Node
-	{
-		public Sequence(Config config)
-		{
-			this.Name = config.Name;
-		}
-
-		public override bool Run(BlackBoard blackBoard)
-		{
-			foreach (var child in children)
-			{
-				if (!child.Run(blackBoard))
-				{
-					return false;
-				}
-			}
-			return true;
-		}
-	}
-}
+namespace BehaviorTree
+{
+    internal class Sequence: Node
+    {
+        public Sequence(Config config)
+        {
+            this.Name = config.Name;
+        }
+
+        public override bool Run(BlackBoard blackBoard)
+        {
+            foreach (var child in this.children)
+            {
+                if (!child.Run(blackBoard))
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+}

+ 69 - 69
CSharp/Game/BehaviorTreeTest/BehaviorTreeFactoryTest.cs

@@ -1,69 +1,69 @@
-using System;
-using System.Collections.Generic;
-using BehaviorTree;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace BehaviorTreeTest
-{
-	[TestClass]
-	public class BehaviorTreeFactoryTest
-	{
-		[TestMethod]
-		public void TestCreateTree()
-		{
-			var config = new Config
-			{
-				Name = "selector",
-				Id = 1,
-				Args = new List<string> { "11" },
-				SubConfigs = new List<Config>
-				{
-					new Config
-					{
-						Name = "sequence",
-						Id = 2,
-						Args = new List<string> { "12" },
-						SubConfigs = new List<Config>
-						{
-							new Config
-							{
-								Name = "selector",
-								Id = 4,
-								Args = new List<string> { "14" },
-							},
-
-							new Config
-							{
-								Name = "selector",
-								Id = 5,
-								Args = new List<string> { "15", "17"},
-							}
-						}
-					},
-
-					new Config
-					{
-						Name = "not",
-						Id = 3,
-						Args = new List<string> { "13" },
-						SubConfigs = new List<Config>
-						{
-							new Config
-							{
-								Name = "selector",
-								Id = 6,
-								Args = new List<string> { "16" },
-							}
-						}
-					}
-				}
-			};
-
-			var behaviorTreeFactory = new BehaviorTreeFactory();
-			BehaviorTree.BehaviorTree behaviorTree = behaviorTreeFactory.CreateTree(config);
-			var blackBoard = new BlackBoard();
-
-			Assert.IsTrue(behaviorTree.Run(blackBoard));
-		}
-	}
-}
+using System.Collections.Generic;
+using BehaviorTree;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace BehaviorTreeTest
+{
+    [TestClass]
+    public class BehaviorTreeFactoryTest
+    {
+        [TestMethod]
+        public void TestCreateTree()
+        {
+            var config = new Config
+            {
+                Name = "selector",
+                Id = 1,
+                Args = new List<string> { "11" },
+                SubConfigs =
+                    new List<Config>
+                    {
+                        new Config
+                        {
+                            Name = "sequence",
+                            Id = 2,
+                            Args = new List<string> { "12" },
+                            SubConfigs =
+                                new List<Config>
+                                {
+                                    new Config
+                                    {
+                                        Name = "selector",
+                                        Id = 4,
+                                        Args = new List<string> { "14" },
+                                    },
+                                    new Config
+                                    {
+                                        Name = "selector",
+                                        Id = 5,
+                                        Args = new List<string> { "15", "17" },
+                                    }
+                                }
+                        },
+                        new Config
+                        {
+                            Name = "not",
+                            Id = 3,
+                            Args = new List<string> { "13" },
+                            SubConfigs =
+                                new List<Config>
+                                {
+                                    new Config
+                                    {
+                                        Name = "selector",
+                                        Id = 6,
+                                        Args = new List<string> { "16" },
+                                    }
+                                }
+                        }
+                    }
+            };
+
+            var behaviorTreeFactory = new BehaviorTreeFactory();
+            BehaviorTree.BehaviorTree behaviorTree = behaviorTreeFactory.CreateTree(config);
+            var blackBoard = new BlackBoard();
+
+            Assert.IsTrue(behaviorTree.Run(blackBoard));
+        }
+    }
+}

+ 71 - 70
CSharp/Game/BehaviorTreeTest/ConfigTest.cs

@@ -1,70 +1,71 @@
-using System;
-using System.Collections.Generic;
-using BehaviorTree;
-using Helper;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace BehaviorTreeTest
-{
-	[TestClass]
-	public class ConfigTest
-	{
-		[TestMethod]
-		public void TestJsonToConfig()
-		{
-			var config = new Config
-			{
-				Name = "selector",
-				Id = 1,
-				Args = new List<string> { "11" },
-				SubConfigs = new List<Config>
-				{
-					new Config
-					{
-						Name = "selector",
-						Id = 2,
-						Args = new List<string> { "12" },
-						SubConfigs = new List<Config>
-						{
-							new Config
-							{
-								Name = "selector",
-								Id = 4,
-								Args = new List<string> { "14" },
-							},
-
-							new Config
-							{
-								Name = "selector",
-								Id = 5,
-								Args = new List<string> { "15", "17"},
-							}
-						}
-					},
-
-					new Config
-					{
-						Name = "selector",
-						Id = 3,
-						Args = new List<string> { "13" },
-						SubConfigs = new List<Config>
-						{
-							new Config
-							{
-								Name = "selector",
-								Id = 6,
-								Args = new List<string> { "16" },
-							}
-						}
-					}
-				}
-			};
-
-			string json = MongoHelper.ToJson(config);
-			Console.WriteLine(json);
-
-			var newConfig = MongoHelper.FromJson<Config>(json);
-			Assert.AreEqual(json, MongoHelper.ToJson(newConfig));
-		}
-	}
-}
+using System;
+using System.Collections.Generic;
+using BehaviorTree;
+using Helper;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace BehaviorTreeTest
+{
+    [TestClass]
+    public class ConfigTest
+    {
+        [TestMethod]
+        public void TestJsonToConfig()
+        {
+            var config = new Config
+            {
+                Name = "selector",
+                Id = 1,
+                Args = new List<string> { "11" },
+                SubConfigs =
+                    new List<Config>
+                    {
+                        new Config
+                        {
+                            Name = "selector",
+                            Id = 2,
+                            Args = new List<string> { "12" },
+                            SubConfigs =
+                                new List<Config>
+                                {
+                                    new Config
+                                    {
+                                        Name = "selector",
+                                        Id = 4,
+                                        Args = new List<string> { "14" },
+                                    },
+                                    new Config
+                                    {
+                                        Name = "selector",
+                                        Id = 5,
+                                        Args = new List<string> { "15", "17" },
+                                    }
+                                }
+                        },
+                        new Config
+                        {
+                            Name = "selector",
+                            Id = 3,
+                            Args = new List<string> { "13" },
+                            SubConfigs =
+                                new List<Config>
+                                {
+                                    new Config
+                                    {
+                                        Name = "selector",
+                                        Id = 6,
+                                        Args = new List<string> { "16" },
+                                    }
+                                }
+                        }
+                    }
+            };
+
+            string json = MongoHelper.ToJson(config);
+            Console.WriteLine(json);
+
+            var newConfig = MongoHelper.FromJson<Config>(json);
+            Assert.AreEqual(json, MongoHelper.ToJson(newConfig));
+        }
+    }
+}

+ 5 - 2
CSharp/Game/BehaviorTreeTest/Properties/AssemblyInfo.cs

@@ -1,10 +1,10 @@
 using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 // 有关程序集的常规信息通过以下特性集 
 // 控制。更改这些特性值可修改
 // 与程序集关联的信息。
+
 [assembly: AssemblyTitle("BehaviorTreeTest")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
@@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
 // 将 ComVisible 设置为 false 会使此程序集中的类型 
 // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
 // 请将该类型上的 ComVisible 特性设置为 true。
+
 [assembly: ComVisible(false)]
 
 // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+
 [assembly: Guid("3db0a0ea-8916-4bb2-a6d8-8487a2c2d60c")]
 
 // 程序集的版本信息由以下四个值组成:
@@ -32,5 +34,6 @@ using System.Runtime.InteropServices;
 // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
 // 方法是按如下所示使用“*”:
 // [assembly: AssemblyVersion("1.0.*")]
+
 [assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 7 - 8
CSharp/Game/Component/Buff.cs

@@ -1,8 +1,7 @@
-
-namespace Component
-{
-	public class Buff: Object
-	{
-		public int Type { get; set; }
-	}
-}
+namespace Component
+{
+    public class Buff: Object
+    {
+        public int Type { get; set; }
+    }
+}

+ 112 - 112
CSharp/Game/Component/BuffManager.cs

@@ -1,112 +1,112 @@
-using System.Collections.Generic;
-using System.ComponentModel;
-using MongoDB.Bson;
-using MongoDB.Bson.Serialization.Attributes;
-
-namespace Component
-{
-	public class BuffManager: ISupportInitialize
-	{
-		public HashSet<Buff> Buffs { get; private set; }
-
-		[BsonIgnore]
-		public Dictionary<ObjectId, Buff> BuffGuidDict { get; private set; }
-
-		[BsonIgnore]
-		public Dictionary<int, Buff> BuffTypeDict { get; private set; }
-
-		public BuffManager()
-		{
-			this.Buffs = new HashSet<Buff>();
-			this.BuffGuidDict = new Dictionary<ObjectId, Buff>();
-			this.BuffTypeDict = new Dictionary<int, Buff>();
-		}
-
-		void ISupportInitialize.BeginInit()
-		{
-		}
-
-		void ISupportInitialize.EndInit()
-		{
-			foreach (var buff in Buffs)
-			{
-				this.BuffGuidDict.Add(buff.Id, buff);
-			}
-
-			foreach (var buff in Buffs)
-			{
-				this.BuffTypeDict.Add(buff.Type, buff);
-			}
-		}
-
-		public bool Add(Buff buff)
-		{
-			if (this.Buffs.Contains(buff))
-			{
-				return false;
-			}
-
-			if (this.BuffGuidDict.ContainsKey(buff.Id))
-			{
-				return false;
-			}
-
-			if (this.BuffTypeDict.ContainsKey(buff.Type))
-			{
-				return false;
-			}
-
-			this.Buffs.Add(buff);
-			this.BuffGuidDict.Add(buff.Id, buff);
-			this.BuffTypeDict.Add(buff.Type, buff);
-
-			return true;
-		}
-
-		public Buff GetById(ObjectId id)
-		{
-			if (!this.BuffGuidDict.ContainsKey(id))
-			{
-				return null;
-			}
-
-			return this.BuffGuidDict[id];
-		}
-
-		public Buff GetByType(int type)
-		{
-			if (!this.BuffTypeDict.ContainsKey(type))
-			{
-				return null;
-			}
-
-			return this.BuffTypeDict[type];
-		}
-
-		private bool Remove(Buff buff)
-		{
-			if (buff == null)
-			{
-				return false;
-			}
-
-			this.Buffs.Remove(buff);
-			this.BuffGuidDict.Remove(buff.Id);
-			this.BuffTypeDict.Remove(buff.Type);
-
-			return true;
-		}
-
-		public bool RemoveById(ObjectId id)
-		{
-			var buff = this.GetById(id);
-			return this.Remove(buff);
-		}
-
-		public bool RemoveByType(int type)
-		{
-			var buff = this.GetByType(type);
-			return this.Remove(buff);
-		}
-	}
-}
+using System.Collections.Generic;
+using System.ComponentModel;
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace Component
+{
+    public class BuffManager: ISupportInitialize
+    {
+        public HashSet<Buff> Buffs { get; private set; }
+
+        [BsonIgnore]
+        public Dictionary<ObjectId, Buff> BuffGuidDict { get; private set; }
+
+        [BsonIgnore]
+        public Dictionary<int, Buff> BuffTypeDict { get; private set; }
+
+        public BuffManager()
+        {
+            this.Buffs = new HashSet<Buff>();
+            this.BuffGuidDict = new Dictionary<ObjectId, Buff>();
+            this.BuffTypeDict = new Dictionary<int, Buff>();
+        }
+
+        void ISupportInitialize.BeginInit()
+        {
+        }
+
+        void ISupportInitialize.EndInit()
+        {
+            foreach (var buff in this.Buffs)
+            {
+                this.BuffGuidDict.Add(buff.Id, buff);
+            }
+
+            foreach (var buff in this.Buffs)
+            {
+                this.BuffTypeDict.Add(buff.Type, buff);
+            }
+        }
+
+        public bool Add(Buff buff)
+        {
+            if (this.Buffs.Contains(buff))
+            {
+                return false;
+            }
+
+            if (this.BuffGuidDict.ContainsKey(buff.Id))
+            {
+                return false;
+            }
+
+            if (this.BuffTypeDict.ContainsKey(buff.Type))
+            {
+                return false;
+            }
+
+            this.Buffs.Add(buff);
+            this.BuffGuidDict.Add(buff.Id, buff);
+            this.BuffTypeDict.Add(buff.Type, buff);
+
+            return true;
+        }
+
+        public Buff GetById(ObjectId id)
+        {
+            if (!this.BuffGuidDict.ContainsKey(id))
+            {
+                return null;
+            }
+
+            return this.BuffGuidDict[id];
+        }
+
+        public Buff GetByType(int type)
+        {
+            if (!this.BuffTypeDict.ContainsKey(type))
+            {
+                return null;
+            }
+
+            return this.BuffTypeDict[type];
+        }
+
+        private bool Remove(Buff buff)
+        {
+            if (buff == null)
+            {
+                return false;
+            }
+
+            this.Buffs.Remove(buff);
+            this.BuffGuidDict.Remove(buff.Id);
+            this.BuffTypeDict.Remove(buff.Type);
+
+            return true;
+        }
+
+        public bool RemoveById(ObjectId id)
+        {
+            var buff = this.GetById(id);
+            return this.Remove(buff);
+        }
+
+        public bool RemoveByType(int type)
+        {
+            var buff = this.GetByType(type);
+            return this.Remove(buff);
+        }
+    }
+}

+ 8 - 10
CSharp/Game/Component/Character.cs

@@ -1,11 +1,9 @@
-
-namespace Component
+namespace Component
 {
-	/// <summary>
-	/// 角色对象
-	/// </summary>
-	public class Character: GameObject
-	{
-
-	}
-}
+    /// <summary>
+    /// 角色对象
+    /// </summary>
+    public class Character: GameObject
+    {
+    }
+}

+ 15 - 15
CSharp/Game/Component/ConfigAttribute.cs

@@ -1,15 +1,15 @@
-using System;
-
-namespace Component
-{
-	[AttributeUsage(AttributeTargets.Class)]
-	public class ConfigAttribute: Attribute
-	{
-		public string RelativeDirectory { get; set; }
-
-		public ConfigAttribute()
-		{
-			this.RelativeDirectory = @"..\Config";
-		}
-	}
-}
+using System;
+
+namespace Component
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public class ConfigAttribute: Attribute
+    {
+        public string RelativeDirectory { get; set; }
+
+        public ConfigAttribute()
+        {
+            this.RelativeDirectory = @"..\Config";
+        }
+    }
+}

+ 58 - 58
CSharp/Game/Component/ConfigCategory.cs

@@ -1,58 +1,58 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.IO;
-using Helper;
-
-namespace Component
-{
-	public abstract class ConfigCategory<T> : ISupportInitialize, IConfigInitialize where T : IType
-	{
-		protected readonly Dictionary<int, T> dict = new Dictionary<int, T>();
-
-		public T this[int type]
-		{
-			get
-			{
-				return dict[type];
-			}
-		}
-
-		public string ConfigName
-		{
-			get
-			{
-				return typeof (T).Name;
-			}
-		}
-
-		public Dictionary<int, T> GetAll()
-		{
-			return this.dict;
-		}
-
-		public void Init(string configsDir)
-		{
-			string path = Path.Combine(configsDir, this.ConfigName);
-
-			if (!Directory.Exists(path))
-			{
-				throw new Exception(string.Format("not found config path: {0}", path));
-			}
-
-			foreach (var file in Directory.GetFiles(path))
-			{
-				var t = MongoHelper.FromJson<T>(File.ReadAllText(file));
-				this.dict.Add(t.Type, t);
-			}
-		}
-
-		public void BeginInit()
-		{
-		}
-
-		public void EndInit()
-		{
-		}
-	}
-}
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using Helper;
+
+namespace Component
+{
+    public abstract class ConfigCategory<T>: ISupportInitialize, IConfigInitialize where T : IType
+    {
+        protected readonly Dictionary<int, T> dict = new Dictionary<int, T>();
+
+        public T this[int type]
+        {
+            get
+            {
+                return this.dict[type];
+            }
+        }
+
+        public string ConfigName
+        {
+            get
+            {
+                return typeof (T).Name;
+            }
+        }
+
+        public Dictionary<int, T> GetAll()
+        {
+            return this.dict;
+        }
+
+        public void Init(string configsDir)
+        {
+            string path = Path.Combine(configsDir, this.ConfigName);
+
+            if (!Directory.Exists(path))
+            {
+                throw new Exception(string.Format("not found config path: {0}", path));
+            }
+
+            foreach (var file in Directory.GetFiles(path))
+            {
+                var t = MongoHelper.FromJson<T>(File.ReadAllText(file));
+                this.dict.Add(t.Type, t);
+            }
+        }
+
+        public void BeginInit()
+        {
+        }
+
+        public void EndInit()
+        {
+        }
+    }
+}

+ 96 - 96
CSharp/Game/Component/ConfigManager.cs

@@ -1,96 +1,96 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.IO;
-
-namespace Component
-{
-	public class ConfigManager
-	{
-		private static readonly ConfigManager instance = new ConfigManager();
-
-		public static ConfigManager Instance
-		{
-			get
-			{
-				return instance;
-			}
-		}
-
-		public Dictionary<string, object> allConfig;
-
-		private ConfigManager()
-		{
-			this.Load();
-		}
-
-		private void Load()
-		{
-			var localAllConfig = new Dictionary<string, object>();
-			string currentDir = AppDomain.CurrentDomain.BaseDirectory;
-			Type[] types = typeof(ConfigManager).Assembly.GetTypes();
-			foreach (var type in types)
-			{
-				object[] attrs = type.GetCustomAttributes(typeof(ConfigAttribute), false);
-				if (attrs.Length == 0)
-				{
-					continue;
-				}
-
-				object obj = (Activator.CreateInstance(type));
-
-				var iInit = obj as IConfigInitialize;
-				if (iInit == null)
-				{
-					throw new Exception(string.Format("class {0} is not IConfigInitialize", type.Name));
-				}
-
-				var iSupportInitialize = obj as ISupportInitialize;
-				if (iSupportInitialize != null)
-				{
-					iSupportInitialize.BeginInit();
-				}
-
-				string configDir = Path.Combine(
-					currentDir, ((ConfigAttribute)attrs[0]).RelativeDirectory);
-
-				if (!Directory.Exists(configDir))
-				{
-					throw new Exception(string.Format("not found config dir: {0}", configDir));
-				}
-				iInit.Init(configDir);
-
-
-				if (iSupportInitialize != null)
-				{
-					iSupportInitialize.EndInit();
-				}
-
-				localAllConfig[iInit.ConfigName] = obj;
-			}
-			this.allConfig = localAllConfig;
-		}
-
-		public void Reload()
-		{
-			this.Load();
-		}
- 
-		public T Get<T>(int type) where T : IType
-		{
-			var configManager = (ConfigCategory<T>)allConfig[typeof (T).Name];
-			return configManager[type];
-		}
-
-		public Dictionary<int, T> GetAll<T>() where T : IType
-		{
-			var configManager = (ConfigCategory<T>)allConfig[typeof (T).Name];
-			return configManager.GetAll();
-		}
-
-		public ConfigCategory<T> GetConfigManager<T>() where T : IType
-		{
-			return (ConfigCategory<T>)allConfig[typeof(T).Name];
-		}
-	}
-}
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+
+namespace Component
+{
+    public class ConfigManager
+    {
+        private static readonly ConfigManager instance = new ConfigManager();
+
+        public static ConfigManager Instance
+        {
+            get
+            {
+                return instance;
+            }
+        }
+
+        public Dictionary<string, object> allConfig;
+
+        private ConfigManager()
+        {
+            this.Load();
+        }
+
+        private void Load()
+        {
+            var localAllConfig = new Dictionary<string, object>();
+            string currentDir = AppDomain.CurrentDomain.BaseDirectory;
+            Type[] types = typeof (ConfigManager).Assembly.GetTypes();
+            foreach (var type in types)
+            {
+                object[] attrs = type.GetCustomAttributes(typeof (ConfigAttribute), false);
+                if (attrs.Length == 0)
+                {
+                    continue;
+                }
+
+                object obj = (Activator.CreateInstance(type));
+
+                var iInit = obj as IConfigInitialize;
+                if (iInit == null)
+                {
+                    throw new Exception(string.Format("class {0} is not IConfigInitialize",
+                            type.Name));
+                }
+
+                var iSupportInitialize = obj as ISupportInitialize;
+                if (iSupportInitialize != null)
+                {
+                    iSupportInitialize.BeginInit();
+                }
+
+                string configDir = Path.Combine(currentDir,
+                        ((ConfigAttribute) attrs[0]).RelativeDirectory);
+
+                if (!Directory.Exists(configDir))
+                {
+                    throw new Exception(string.Format("not found config dir: {0}", configDir));
+                }
+                iInit.Init(configDir);
+
+                if (iSupportInitialize != null)
+                {
+                    iSupportInitialize.EndInit();
+                }
+
+                localAllConfig[iInit.ConfigName] = obj;
+            }
+            this.allConfig = localAllConfig;
+        }
+
+        public void Reload()
+        {
+            this.Load();
+        }
+
+        public T Get<T>(int type) where T : IType
+        {
+            var configManager = (ConfigCategory<T>) this.allConfig[typeof (T).Name];
+            return configManager[type];
+        }
+
+        public Dictionary<int, T> GetAll<T>() where T : IType
+        {
+            var configManager = (ConfigCategory<T>) this.allConfig[typeof (T).Name];
+            return configManager.GetAll();
+        }
+
+        public ConfigCategory<T> GetConfigManager<T>() where T : IType
+        {
+            return (ConfigCategory<T>) this.allConfig[typeof (T).Name];
+        }
+    }
+}

+ 11 - 11
CSharp/Game/Component/EventAttribute.cs

@@ -1,11 +1,11 @@
-using System;
-
-namespace Component
-{
-	[AttributeUsage(AttributeTargets.Class)]
-	public class EventAttribute : Attribute
-	{
-		public EventType Type { get; set; }
-		public int Order { get; set; }
-	}
-}
+using System;
+
+namespace Component
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public class EventAttribute: Attribute
+    {
+        public EventType Type { get; set; }
+        public int Order { get; set; }
+    }
+}

+ 12 - 13
CSharp/Game/Component/EventType.cs

@@ -1,16 +1,15 @@
-
-namespace Component
+namespace Component
 {
-	// 定义事件类型
-	public enum EventType: short
-	{
-		// 默认的event
-		DefaultEvent,
+    // 定义事件类型
+    public enum EventType: short
+    {
+        // 默认的event
+        DefaultEvent,
 
-		// 登录world前触发
-		BeforeLoginWorldEvent,
+        // 登录world前触发
+        BeforeLoginWorldEvent,
 
-		// 使用物品前触发
-		BeforeUseItemEvent,
-	}
-}
+        // 使用物品前触发
+        BeforeUseItemEvent,
+    }
+}

+ 17 - 18
CSharp/Game/Component/GameObject.cs

@@ -1,18 +1,17 @@
-
-namespace Component
-{
-	public class GameObject: Object
-	{
-		private readonly BuffManager buffManager = new BuffManager();
-
-		public int Type { get; set; }
-
-		public BuffManager BuffManager
-		{
-			get
-			{
-				return this.buffManager;
-			}
-		}
-	}
-}
+namespace Component
+{
+    public class GameObject: Object
+    {
+        private readonly BuffManager buffManager = new BuffManager();
+
+        public int Type { get; set; }
+
+        public BuffManager BuffManager
+        {
+            get
+            {
+                return this.buffManager;
+            }
+        }
+    }
+}

+ 70 - 70
CSharp/Game/Component/GameObjectManager.cs

@@ -1,70 +1,70 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using MongoDB.Bson;
-
-namespace Component
-{
-	public class GameObjectManager
-	{
-		private readonly Dictionary<ObjectId, GameObject> gameObjects = 
-				new Dictionary<ObjectId, GameObject>();
-
-		private readonly Dictionary<int, Dictionary<ObjectId, GameObject>> typeGameObjects = 
-				new Dictionary<int, Dictionary<ObjectId, GameObject>>();
-
-		public void Add(GameObject gameObject)
-		{
-			this.gameObjects.Add(gameObject.Id, gameObject);
-			if (!this.typeGameObjects.ContainsKey(gameObject.Type))
-			{
-				this.typeGameObjects.Add(gameObject.Type, new Dictionary<ObjectId, GameObject>());
-			}
-			this.typeGameObjects[gameObject.Type].Add(gameObject.Id, gameObject);
-		}
-
-		public GameObject Get(ObjectId id)
-		{
-			GameObject gameObject = null;
-			this.gameObjects.TryGetValue(id, out gameObject);
-			return gameObject;
-		}
-
-		public GameObject[] GetOneType(int type)
-		{
-			Dictionary<ObjectId, GameObject> oneTypeGameObjects = null;
-			if (!this.typeGameObjects.TryGetValue(type, out oneTypeGameObjects))
-			{
-				return new GameObject[0];
-			}
-			return oneTypeGameObjects.Values.ToArray();
-		}
-
-		public bool Remove(GameObject gameObject)
-		{
-			if (gameObject == null)
-			{
-				throw new ArgumentNullException("gameObject");
-			}
-			if (!this.gameObjects.Remove(gameObject.Id))
-			{
-				return false;
-			}
-			if (!this.typeGameObjects[gameObject.Type].Remove(gameObject.Id))
-			{
-				return false;
-			}
-			return true;
-		}
-
-		public bool Remove(ObjectId id)
-		{
-			GameObject gameObject = this.Get(id);
-			if (gameObject == null)
-			{
-				return false;
-			}
-			return this.Remove(gameObject);
-		}
-	}
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MongoDB.Bson;
+
+namespace Component
+{
+    public class GameObjectManager
+    {
+        private readonly Dictionary<ObjectId, GameObject> gameObjects =
+                new Dictionary<ObjectId, GameObject>();
+
+        private readonly Dictionary<int, Dictionary<ObjectId, GameObject>> typeGameObjects =
+                new Dictionary<int, Dictionary<ObjectId, GameObject>>();
+
+        public void Add(GameObject gameObject)
+        {
+            this.gameObjects.Add(gameObject.Id, gameObject);
+            if (!this.typeGameObjects.ContainsKey(gameObject.Type))
+            {
+                this.typeGameObjects.Add(gameObject.Type, new Dictionary<ObjectId, GameObject>());
+            }
+            this.typeGameObjects[gameObject.Type].Add(gameObject.Id, gameObject);
+        }
+
+        public GameObject Get(ObjectId id)
+        {
+            GameObject gameObject = null;
+            this.gameObjects.TryGetValue(id, out gameObject);
+            return gameObject;
+        }
+
+        public GameObject[] GetOneType(int type)
+        {
+            Dictionary<ObjectId, GameObject> oneTypeGameObjects = null;
+            if (!this.typeGameObjects.TryGetValue(type, out oneTypeGameObjects))
+            {
+                return new GameObject[0];
+            }
+            return oneTypeGameObjects.Values.ToArray();
+        }
+
+        public bool Remove(GameObject gameObject)
+        {
+            if (gameObject == null)
+            {
+                throw new ArgumentNullException("gameObject");
+            }
+            if (!this.gameObjects.Remove(gameObject.Id))
+            {
+                return false;
+            }
+            if (!this.typeGameObjects[gameObject.Type].Remove(gameObject.Id))
+            {
+                return false;
+            }
+            return true;
+        }
+
+        public bool Remove(ObjectId id)
+        {
+            GameObject gameObject = this.Get(id);
+            if (gameObject == null)
+            {
+                return false;
+            }
+            return this.Remove(gameObject);
+        }
+    }
+}

+ 11 - 11
CSharp/Game/Component/HandlerAttribute.cs

@@ -1,11 +1,11 @@
-using System;
-
-namespace Component
-{
-	[AttributeUsage(AttributeTargets.Class)]
-	public class HandlerAttribute : Attribute
-	{
-		public Type Type { get; set; }
-		public int Opcode { get; set; }
-	}
-}
+using System;
+
+namespace Component
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public class HandlerAttribute: Attribute
+    {
+        public Type Type { get; set; }
+        public int Opcode { get; set; }
+    }
+}

+ 8 - 9
CSharp/Game/Component/IConfigInitialize.cs

@@ -1,9 +1,8 @@
-
-namespace Component
-{
-	public interface IConfigInitialize
-	{
-		string ConfigName { get; }
-		void Init(string dir);
-	}
-}
+namespace Component
+{
+    public interface IConfigInitialize
+    {
+        string ConfigName { get; }
+        void Init(string dir);
+    }
+}

+ 7 - 8
CSharp/Game/Component/IEvent.cs

@@ -1,8 +1,7 @@
-
-namespace Component
-{
-	public interface IEvent
-	{
-		void Trigger(MessageEnv messageEnv);
-	}
-}
+namespace Component
+{
+    public interface IEvent
+    {
+        void Trigger(MessageEnv messageEnv);
+    }
+}

+ 7 - 8
CSharp/Game/Component/IHandler.cs

@@ -1,8 +1,7 @@
-
-namespace Component
-{
-	public interface IHandler
-	{
-		void Handle(MessageEnv messageEnv);
-	}
-}
+namespace Component
+{
+    public interface IHandler
+    {
+        void Handle(MessageEnv messageEnv);
+    }
+}

+ 7 - 8
CSharp/Game/Component/ILogic.cs

@@ -1,8 +1,7 @@
-
-namespace Component
-{
-	public interface ILogic
-	{
-		void Handle(short opcode, byte[] content);
-	}
-}
+namespace Component
+{
+    public interface ILogic
+    {
+        void Handle(short opcode, byte[] content);
+    }
+}

+ 7 - 10
CSharp/Game/Component/IType.cs

@@ -1,10 +1,7 @@
-namespace Component
-{
-	public interface IType
-	{
-		int Type
-		{
-			get;
-		}
-	}
-}
+namespace Component
+{
+    public interface IType
+    {
+        int Type { get; }
+    }
+}

+ 7 - 8
CSharp/Game/Component/KeyDefine.cs

@@ -1,8 +1,7 @@
-
-namespace Component
-{
-	public static class KeyDefine
-	{
-		public const string KMessage = "message";
-	}
-}
+namespace Component
+{
+    public static class KeyDefine
+    {
+        public const string KMessage = "message";
+    }
+}

+ 139 - 137
CSharp/Game/Component/LogicManager.cs

@@ -1,137 +1,139 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Helper;
-using Logger;
-
-namespace Component
-{
-	public class LogicManager : ILogic
-    {
-		private static readonly LogicManager instance = new LogicManager();
-
-		private Dictionary<int, Tuple<IHandler, Type>> handlers;
-
-		private Dictionary<EventType, SortedDictionary<int, IEvent>> events;
-
-		public static LogicManager Instance
-		{
-			get
-			{
-				return instance;
-			}
-		}
-
-		private LogicManager()
-		{
-			this.Load();
-		}
-
-		private void Load()
-		{
-			string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logic.dll");
-			var assembly = LoaderHelper.Load(dllPath);
-			Type[] types = assembly.GetTypes();
-
-			// 加载封包处理器
-			var localHandlers = new Dictionary<int, Tuple<IHandler, Type>>();
-			foreach (var type in types)
-			{
-				object[] attrs = type.GetCustomAttributes(typeof(HandlerAttribute), false);
-				if (attrs.Length == 0)
-				{
-					continue;
-				}
-				var handler = (IHandler)Activator.CreateInstance(type);
-				int opcode = ((HandlerAttribute)attrs[0]).Opcode;
-				Type messageType = ((HandlerAttribute)attrs[0]).Type;
-				if (opcode == 0 || messageType == null)
-				{
-					throw new Exception(string.Format("not set opcode or type, handler name: {0}", type.Name));
-				}
-				if (localHandlers.ContainsKey(opcode))
-				{
-					throw new Exception(string.Format(
-						"same handler opcode, opcode: {0}, name: {1}", 
-						opcode, type.Name));
-				}
-				localHandlers[opcode] = new Tuple<IHandler, Type>(handler, messageType);
-			}
-
-			// 加载事件处理器
-			var localEvents = new Dictionary<EventType, SortedDictionary<int, IEvent>>();
-			foreach (var type in types)
-			{
-				object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
-				if (attrs.Length == 0)
-				{
-					continue;
-				}
-				var evt = (IEvent)Activator.CreateInstance(type);
-				EventType eventType = ((EventAttribute)attrs[0]).Type;
-				int eventOrder = ((EventAttribute)attrs[0]).Order;
-
-				if (eventOrder == 0 || eventType == EventType.DefaultEvent)
-				{
-					throw new Exception(string.Format("not set order or type, event name: {0}", type.Name));
-				}
-
-				if (!localEvents.ContainsKey(eventType))
-				{
-					localEvents[eventType] = new SortedDictionary<int, IEvent>();
-				}
-				if (localEvents[eventType].ContainsKey(eventOrder))
-				{
-					throw new Exception(string.Format(
-						"same event number, type: {0}, number: {1}, name: {2}", 
-						eventType, eventOrder, type.Name));
-				}
-				localEvents[eventType][eventOrder] = evt;
-			}
-
-			// 
-			this.handlers = localHandlers;
-			this.events = localEvents;
-		}
-
-		public void Reload()
-		{
-			this.Load();
-		}
-
-		public void Handle(short opcode, byte[] content)
-	    {
-			Tuple<IHandler, Type> tuple = null;
-			if (!handlers.TryGetValue(opcode, out tuple))
-			{
-				throw new Exception(string.Format("not found handler opcode {0}", opcode));
-			}
-
-			try
-			{
-				object message = MongoHelper.FromBson(content, tuple.Item2);
-				var messageEnv = new MessageEnv();
-				messageEnv[KeyDefine.KMessage] = message;
-				tuple.Item1.Handle(messageEnv);
-			}
-			catch (Exception e)
-			{
-				Log.Trace("message handle error: {0}", e.Message);
-			}
-	    }
-
-		public void Trigger(MessageEnv messageEnv, EventType type)
-		{
-			SortedDictionary<int, IEvent> iEventDict = null;
-			if (!this.events.TryGetValue(type, out iEventDict))
-			{
-				return;
-			}
-
-			foreach (var iEvent in iEventDict)
-			{
-				iEvent.Value.Trigger(messageEnv);
-			}
-		}
-	}
-}
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Helper;
+using Logger;
+
+namespace Component
+{
+    public class LogicManager: ILogic
+    {
+        private static readonly LogicManager instance = new LogicManager();
+
+        private Dictionary<int, Tuple<IHandler, Type>> handlers;
+
+        private Dictionary<EventType, SortedDictionary<int, IEvent>> events;
+
+        public static LogicManager Instance
+        {
+            get
+            {
+                return instance;
+            }
+        }
+
+        private LogicManager()
+        {
+            this.Load();
+        }
+
+        private void Load()
+        {
+            string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logic.dll");
+            var assembly = LoaderHelper.Load(dllPath);
+            Type[] types = assembly.GetTypes();
+
+            // 加载封包处理器
+            var localHandlers = new Dictionary<int, Tuple<IHandler, Type>>();
+            foreach (var type in types)
+            {
+                object[] attrs = type.GetCustomAttributes(typeof (HandlerAttribute), false);
+                if (attrs.Length == 0)
+                {
+                    continue;
+                }
+                var handler = (IHandler) Activator.CreateInstance(type);
+                int opcode = ((HandlerAttribute) attrs[0]).Opcode;
+                Type messageType = ((HandlerAttribute) attrs[0]).Type;
+                if (opcode == 0 || messageType == null)
+                {
+                    throw new Exception(string.Format("not set opcode or type, handler name: {0}",
+                            type.Name));
+                }
+                if (localHandlers.ContainsKey(opcode))
+                {
+                    throw new Exception(string.Format(
+                                                      "same handler opcode, opcode: {0}, name: {1}",
+                            opcode, type.Name));
+                }
+                localHandlers[opcode] = new Tuple<IHandler, Type>(handler, messageType);
+            }
+
+            // 加载事件处理器
+            var localEvents = new Dictionary<EventType, SortedDictionary<int, IEvent>>();
+            foreach (var type in types)
+            {
+                object[] attrs = type.GetCustomAttributes(typeof (EventAttribute), false);
+                if (attrs.Length == 0)
+                {
+                    continue;
+                }
+                var evt = (IEvent) Activator.CreateInstance(type);
+                EventType eventType = ((EventAttribute) attrs[0]).Type;
+                int eventOrder = ((EventAttribute) attrs[0]).Order;
+
+                if (eventOrder == 0 || eventType == EventType.DefaultEvent)
+                {
+                    throw new Exception(string.Format("not set order or type, event name: {0}",
+                            type.Name));
+                }
+
+                if (!localEvents.ContainsKey(eventType))
+                {
+                    localEvents[eventType] = new SortedDictionary<int, IEvent>();
+                }
+                if (localEvents[eventType].ContainsKey(eventOrder))
+                {
+                    throw new Exception(
+                            string.Format("same event number, type: {0}, number: {1}, name: {2}",
+                                    eventType, eventOrder, type.Name));
+                }
+                localEvents[eventType][eventOrder] = evt;
+            }
+
+            // 
+            this.handlers = localHandlers;
+            this.events = localEvents;
+        }
+
+        public void Reload()
+        {
+            this.Load();
+        }
+
+        public void Handle(short opcode, byte[] content)
+        {
+            Tuple<IHandler, Type> tuple = null;
+            if (!this.handlers.TryGetValue(opcode, out tuple))
+            {
+                throw new Exception(string.Format("not found handler opcode {0}", opcode));
+            }
+
+            try
+            {
+                object message = MongoHelper.FromBson(content, tuple.Item2);
+                var messageEnv = new MessageEnv();
+                messageEnv[KeyDefine.KMessage] = message;
+                tuple.Item1.Handle(messageEnv);
+            }
+            catch (Exception e)
+            {
+                Log.Trace("message handle error: {0}", e.Message);
+            }
+        }
+
+        public void Trigger(MessageEnv messageEnv, EventType type)
+        {
+            SortedDictionary<int, IEvent> iEventDict = null;
+            if (!this.events.TryGetValue(type, out iEventDict))
+            {
+                return;
+            }
+
+            foreach (var iEvent in iEventDict)
+            {
+                iEvent.Value.Trigger(messageEnv);
+            }
+        }
+    }
+}

+ 19 - 20
CSharp/Game/Component/Message.cs

@@ -1,20 +1,19 @@
-
-namespace Component
-{
-	public class CChat
-	{
-		public string Content { get; set; }
-	}
-
-	public class CLoginWorld
-	{
-	}
-
-	public class CReloadHandler
-	{
-	}
-
-	public class CReloadConfig
-	{
-	}
-}
+namespace Component
+{
+    public class CChat
+    {
+        public string Content { get; set; }
+    }
+
+    public class CLoginWorld
+    {
+    }
+
+    public class CReloadHandler
+    {
+    }
+
+    public class CReloadConfig
+    {
+    }
+}

+ 10 - 10
CSharp/Game/Component/MessageAttribute.cs

@@ -1,10 +1,10 @@
-using System;
-
-namespace Component
-{
-	[AttributeUsage(AttributeTargets.Class)]
-	public class MessageAttribute : Attribute
-	{
-		public short Opcode { get; set; }
-	}
-}
+using System;
+
+namespace Component
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public class MessageAttribute: Attribute
+    {
+        public short Opcode { get; set; }
+    }
+}

+ 5 - 6
CSharp/Game/Component/MessageEnv.cs

@@ -1,7 +1,6 @@
-
-namespace Component
-{
-	public class MessageEnv: Object
-	{
-	}
+namespace Component
+{
+    public class MessageEnv: Object
+    {
+    }
 }

+ 64 - 64
CSharp/Game/Component/Object.cs

@@ -1,64 +1,64 @@
-using System.Collections.Generic;
-using MongoDB.Bson;
-
-namespace Component
-{
-	public class Object
-	{
-		public ObjectId Id { get; set; }
-
-		public Dictionary<string, object> Dict { get; private set; }
-
-		protected Object()
-		{
-			this.Id = ObjectId.GenerateNewId();
-			this.Dict = new Dictionary<string, object>();
-		}
-
-		public object this[string key]
-		{
-			set
-			{
-				this.Dict[key] = value;	
-			}
-			get
-			{
-				return this.Dict[key];
-			}
-		}
-
-		public T Get<T>(string key)
-		{
-			if (!this.Dict.ContainsKey(key))
-			{
-				throw new KeyNotFoundException(string.Format("not found key: {0}", key));
-			}
-			return (T)this.Dict[key];
-		}
-
-		public T Get<T>()
-		{
-			return this.Get<T>(typeof(T).Name);
-		}
-
-		public void Set(string key, object obj)
-		{
-			this.Dict[key] = obj;
-		}
-
-		public void Set<T>(T obj)
-		{
-			this.Dict[typeof(T).Name] = obj;
-		}
-
-		public bool Contain(string key)
-		{
-			return this.Dict.ContainsKey(key);
-		}
-
-		public bool Remove(string key)
-		{
-			return this.Dict.Remove(key);
-		}
-	}
-}
+using System.Collections.Generic;
+using MongoDB.Bson;
+
+namespace Component
+{
+    public class Object
+    {
+        public ObjectId Id { get; set; }
+
+        public Dictionary<string, object> Dict { get; private set; }
+
+        protected Object()
+        {
+            this.Id = ObjectId.GenerateNewId();
+            this.Dict = new Dictionary<string, object>();
+        }
+
+        public object this[string key]
+        {
+            set
+            {
+                this.Dict[key] = value;
+            }
+            get
+            {
+                return this.Dict[key];
+            }
+        }
+
+        public T Get<T>(string key)
+        {
+            if (!this.Dict.ContainsKey(key))
+            {
+                throw new KeyNotFoundException(string.Format("not found key: {0}", key));
+            }
+            return (T) this.Dict[key];
+        }
+
+        public T Get<T>()
+        {
+            return this.Get<T>(typeof (T).Name);
+        }
+
+        public void Set(string key, object obj)
+        {
+            this.Dict[key] = obj;
+        }
+
+        public void Set<T>(T obj)
+        {
+            this.Dict[typeof (T).Name] = obj;
+        }
+
+        public bool Contain(string key)
+        {
+            return this.Dict.ContainsKey(key);
+        }
+
+        public bool Remove(string key)
+        {
+            return this.Dict.Remove(key);
+        }
+    }
+}

+ 14 - 14
CSharp/Game/Logic/Event/BeforeLoginWorldEvent.cs

@@ -1,14 +1,14 @@
-using Component;
-using Logger;
-
-namespace Logic
-{
-	[EventAttribute(Type = EventType.BeforeLoginWorldEvent, Order = 1)]
-	public class CheckPlayerEvent : IEvent
-	{
-		public void Trigger(MessageEnv messageEnv)
-		{
-			Log.Trace("check player");
-		}
-	}
-}
+using Component;
+using Logger;
+
+namespace Logic
+{
+    [Event(Type = EventType.BeforeLoginWorldEvent, Order = 1)]
+    public class CheckPlayerEvent: IEvent
+    {
+        public void Trigger(MessageEnv messageEnv)
+        {
+            Log.Trace("check player");
+        }
+    }
+}

+ 14 - 14
CSharp/Game/Logic/Event/BeforeUseItemEvent.cs

@@ -1,14 +1,14 @@
-using Component;
-using Logger;
-
-namespace Logic
-{
-	[EventAttribute(Type = EventType.BeforeUseItemEvent, Order = 1)]
-	public class UseCountStatisticsEvent : IEvent
-	{
-		public void Trigger(MessageEnv messageEnv)
-		{
-			Log.Trace("check player");
-		}
-	}
-}
+using Component;
+using Logger;
+
+namespace Logic
+{
+    [Event(Type = EventType.BeforeUseItemEvent, Order = 1)]
+    public class UseCountStatisticsEvent: IEvent
+    {
+        public void Trigger(MessageEnv messageEnv)
+        {
+            Log.Trace("check player");
+        }
+    }
+}

+ 21 - 21
CSharp/Game/Logic/Handler/ChatHandler.cs

@@ -1,21 +1,21 @@
-using Component.Config;
-using Helper;
-using Logger;
-using Component;
-
-namespace Logic
-{
-	[Handler(Type = typeof(CChat), Opcode = 1)]
-	class ChatHandler: IHandler
-	{
-		public void Handle(MessageEnv messageEnv)
-		{
-			var chat = (CChat)messageEnv[KeyDefine.KMessage];
-
-			var world = World.World.Instance;
-			var globalConfig = world.ConfigManager.Get<GlobalConfig>(1);
-			Log.Debug(MongoHelper.ToJson(globalConfig));
-			Log.Debug("chat content: {0}", chat.Content);
-		}
-	}
-}
+using Component;
+using Component.Config;
+using Helper;
+using Logger;
+
+namespace Logic
+{
+    [Handler(Type = typeof (CChat), Opcode = 1)]
+    internal class ChatHandler: IHandler
+    {
+        public void Handle(MessageEnv messageEnv)
+        {
+            var chat = (CChat) messageEnv[KeyDefine.KMessage];
+
+            var world = World.World.Instance;
+            var globalConfig = world.ConfigManager.Get<GlobalConfig>(1);
+            Log.Debug(MongoHelper.ToJson(globalConfig));
+            Log.Debug("chat content: {0}", chat.Content);
+        }
+    }
+}

+ 11 - 11
CSharp/Game/Logic/Handler/LoginWorldHandler.cs

@@ -2,14 +2,14 @@
 
 namespace Logic.Handler
 {
-	[Handler(Type = typeof(CLoginWorld), Opcode = 2)]
-	public class LoginWorldHandler: IHandler
-	{
-		public void Handle(MessageEnv messageEnv)
-		{
-			var world = World.World.Instance;
-			// 登录world前触发事件
-			world.LogicManager.Trigger(messageEnv, EventType.BeforeLoginWorldEvent);
-		}
-	}
-}
+    [Handler(Type = typeof (CLoginWorld), Opcode = 2)]
+    public class LoginWorldHandler: IHandler
+    {
+        public void Handle(MessageEnv messageEnv)
+        {
+            var world = World.World.Instance;
+            // 登录world前触发事件
+            world.LogicManager.Trigger(messageEnv, EventType.BeforeLoginWorldEvent);
+        }
+    }
+}

+ 24 - 24
CSharp/Game/Logic/Handler/ReloadHandler.cs

@@ -1,24 +1,24 @@
-using Component;
-
-namespace Logic
-{
-	[Handler(Type = typeof(CReloadHandler), Opcode = 3)]
-	class ReloadHandlerHandler : IHandler
-	{
-		public void Handle(MessageEnv messageEnv)
-		{
-			var world = World.World.Instance;
-			world.LogicManager.Reload();
-		}
-	}
-
-	[Handler(Type = typeof(CReloadConfig), Opcode = 4)]
-	class ReloadConfigHandler: IHandler
-	{
-		public void Handle(MessageEnv messageEnv)
-		{
-			var world = World.World.Instance;
-			world.ConfigManager.Reload();
-		}
-	}
-}
+using Component;
+
+namespace Logic
+{
+    [Handler(Type = typeof (CReloadHandler), Opcode = 3)]
+    internal class ReloadHandlerHandler: IHandler
+    {
+        public void Handle(MessageEnv messageEnv)
+        {
+            var world = World.World.Instance;
+            world.LogicManager.Reload();
+        }
+    }
+
+    [Handler(Type = typeof (CReloadConfig), Opcode = 4)]
+    internal class ReloadConfigHandler: IHandler
+    {
+        public void Handle(MessageEnv messageEnv)
+        {
+            var world = World.World.Instance;
+            world.ConfigManager.Reload();
+        }
+    }
+}

Some files were not shown because too many files changed in this diff