/Utilities/WCell.PacketAnalyzer/Xml/XmlPacketDefinitions.cs

https://github.com/enjoii/WCell · C# · 334 lines · 288 code · 39 blank · 7 comment · 11 complexity · 703619fc489b07a81e5ef38e7f933b11 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using WCell.Constants.Misc;
  6. using WCell.Core.Network;
  7. using System.Xml.Serialization;
  8. using WCell.Core;
  9. using WCell.Constants;
  10. using WCell.Constants.Spells;
  11. using WCell.Util;
  12. namespace WCell.PacketAnalysis.Xml
  13. {
  14. [XmlRoot("Definitions")]
  15. public class XmlPacketDefinitions : XmlFile<XmlPacketDefinitions>
  16. {
  17. /// <summary>
  18. /// Used for compliancy
  19. /// </summary>
  20. public const int CurrentVersion = 4;
  21. int m_version;
  22. public XmlPacketDefinitions()
  23. : base("")
  24. {
  25. }
  26. public XmlPacketDefinitions(string filename)
  27. : base(filename)
  28. {
  29. m_version = CurrentVersion;
  30. }
  31. public XmlPacketDefinitions(string filename, PacketDefinition[] defs)
  32. : this(filename)
  33. {
  34. Definitions = new XmlPacketDefinition[defs.Length];
  35. for (var i = 0; i < defs.Length; i++)
  36. {
  37. Definitions[i] = defs[i].Serialize();
  38. }
  39. Version = CurrentVersion;
  40. }
  41. [XmlAttribute]
  42. public int Version
  43. {
  44. get
  45. {
  46. return m_version;
  47. }
  48. set
  49. {
  50. m_version = value;
  51. }
  52. }
  53. [XmlAttribute("schemaLocation", Namespace = "xsi")]
  54. public string SchemaLocation
  55. {
  56. get;
  57. set;
  58. }
  59. [XmlElement("RealmPacket", typeof(RealmPacketDefinition))]
  60. [XmlElement("AuthPacket", typeof(AuthPacketDefinition))]
  61. public XmlPacketDefinition[] Definitions
  62. {
  63. get;
  64. set;
  65. }
  66. protected override void OnLoad()
  67. {
  68. if (Version != CurrentVersion)
  69. {
  70. string changes;
  71. if (Version < CurrentVersion)
  72. {
  73. changes = ChangeLog.GetChangeLog(Version, CurrentVersion);
  74. }
  75. else
  76. {
  77. changes = "XML Packet Definition probably requires a newer version of the PacketAnalyzer.";
  78. }
  79. var msg = string.Format("Could not load definitions from \"" + FileName + "\"."
  80. + " Found Version: {0} - Expected Version: {1}\n{2}", Version, CurrentVersion, changes);
  81. Console.WriteLine(msg);
  82. throw new Exception(msg);
  83. }
  84. }
  85. void SaveTest()
  86. {
  87. var msgSegment = new PacketSegmentStructure(SimpleType.CString, "Message");
  88. var targetMsgSegment = new PacketSegmentStructure[] {
  89. new PacketSegmentStructure(SimpleType.CString, "Target"),
  90. new PacketSegmentStructure(SimpleType.CString, "Message")
  91. }.ToList();
  92. SwitchPacketSegmentStructure msgTypeSwitch;
  93. var defs = new RealmPacketDefinition();
  94. Definitions = new XmlPacketDefinition[] {
  95. new RealmPacketDefinition(RealmServerOpCode.CMSG_CAST_SPELL,
  96. //new ComplexPacketSegmentStructure(
  97. //new PacketSegmentStructure[] {
  98. new PacketSegmentStructure(SimpleType.UInt, "Spell Id", typeof(SpellId))
  99. //})
  100. ),
  101. defs
  102. };
  103. defs.OpCodes = new[] { RealmServerOpCode.CMSG_MESSAGECHAT };
  104. defs.Structure = new[] {
  105. new PacketSegmentStructure(SimpleType.UInt, "Type", typeof(ChatMsgType)),
  106. new PacketSegmentStructure(SimpleType.UInt, "Language", typeof(ChatLanguage)),
  107. msgTypeSwitch = new SwitchPacketSegmentStructure("TargetAndMessage", "Type",
  108. new SwitchCase(ComparisonType.Equal, ChatMsgType.Say, msgSegment),
  109. new SwitchCase(ComparisonType.Equal, ChatMsgType.Yell, msgSegment),
  110. new SwitchCase(ComparisonType.Equal, ChatMsgType.Emote, msgSegment),
  111. new SwitchCase(ComparisonType.Equal, ChatMsgType.Party, msgSegment),
  112. new SwitchCase(ComparisonType.Equal, ChatMsgType.Raid, msgSegment),
  113. new SwitchCase(ComparisonType.Equal, ChatMsgType.RaidLeader, msgSegment),
  114. new SwitchCase(ComparisonType.Equal, ChatMsgType.RaidWarn, msgSegment),
  115. new SwitchCase(ComparisonType.Equal, ChatMsgType.Whisper, targetMsgSegment),
  116. new SwitchCase(ComparisonType.Equal, ChatMsgType.Channel, targetMsgSegment)
  117. )
  118. }.ToList();
  119. //defs.Structure.Init();
  120. Save();
  121. }
  122. public static PacketDefinition[] LoadDefinitions(string file)
  123. {
  124. var defs = Load(file);
  125. if (defs != null && defs.Definitions != null)
  126. {
  127. var packetDefs = new PacketDefinition[defs.Definitions.Length];
  128. for (int i = 0; i < packetDefs.Length; i++)
  129. {
  130. var def = defs.Definitions[i];
  131. var packetDef = new PacketDefinition(def.GetPacketIds(), def.Sender, def.Structure);
  132. packetDef.Init();
  133. packetDefs[i] = packetDef;
  134. }
  135. return packetDefs;
  136. }
  137. return PacketDefinition.Empty;
  138. }
  139. public IEnumerator<XmlPacketDefinition> GetEnumerator()
  140. {
  141. return (IEnumerator<XmlPacketDefinition>)Definitions.GetEnumerator();
  142. }
  143. }
  144. public class RealmPacketDefinition : XmlPacketDefinition
  145. {
  146. public RealmPacketDefinition()
  147. {
  148. }
  149. public RealmPacketDefinition(RealmServerOpCode opCode, ComplexPacketSegmentStructure segments)
  150. {
  151. OpCode = opCode;
  152. Structure = segments.Segments.ToList();
  153. }
  154. public RealmPacketDefinition(RealmServerOpCode opCode, params PacketSegmentStructure[] segments)
  155. {
  156. OpCode = opCode;
  157. Structure = segments.ToList();
  158. }
  159. public RealmPacketDefinition(RealmServerOpCode[] opCodes, ComplexPacketSegmentStructure segments)
  160. {
  161. OpCodes = opCodes;
  162. Structure = segments.Segments.ToList();
  163. }
  164. public RealmPacketDefinition(RealmServerOpCode[] opCodes, params PacketSegmentStructure[] segments)
  165. {
  166. OpCodes = opCodes;
  167. Structure = segments.ToList();
  168. }
  169. RealmServerOpCode OpCode
  170. {
  171. get
  172. {
  173. return (RealmServerOpCode)Enum.Parse(typeof(RealmServerOpCode), OpCode_);
  174. }
  175. set
  176. {
  177. OpCode_ = value.ToString();
  178. }
  179. }
  180. [XmlIgnore]
  181. public RealmServerOpCode[] OpCodes
  182. {
  183. get
  184. {
  185. if (OpCodes_ == null)
  186. {
  187. return new[] { OpCode };
  188. }
  189. return OpCodes_.TransformArray(opcode => (RealmServerOpCode)Enum.Parse(typeof(RealmServerOpCode), opcode));
  190. }
  191. set
  192. {
  193. OpCodes_ = value.TransformArray(opcode => opcode.ToString());
  194. }
  195. }
  196. public override PacketId[] GetPacketIds()
  197. {
  198. return OpCodes.TransformArray(opcode => (PacketId)opcode);
  199. }
  200. }
  201. public class AuthPacketDefinition : XmlPacketDefinition
  202. {
  203. public AuthPacketDefinition()
  204. {
  205. }
  206. public AuthPacketDefinition(AuthServerOpCode opCode, ComplexPacketSegmentStructure segments)
  207. {
  208. OpCode = opCode;
  209. Structure = segments.Segments.ToList();
  210. }
  211. public AuthPacketDefinition(AuthServerOpCode opCode, params PacketSegmentStructure[] segments)
  212. {
  213. OpCode = opCode;
  214. Structure = segments.ToList();
  215. }
  216. [XmlIgnore]
  217. public AuthServerOpCode OpCode
  218. {
  219. get
  220. {
  221. return (AuthServerOpCode)Enum.Parse(typeof(AuthServerOpCode), base.OpCode_);
  222. }
  223. set
  224. {
  225. base.OpCode_ = value.ToString();
  226. }
  227. }
  228. [XmlIgnore]
  229. public AuthServerOpCode[] OpCodes
  230. {
  231. get
  232. {
  233. return OpCodes_.TransformArray(opcode => (AuthServerOpCode)Enum.Parse(typeof(AuthServerOpCode), opcode));
  234. }
  235. set
  236. {
  237. OpCodes_ = value.TransformArray(opcode => opcode.ToString());
  238. }
  239. }
  240. public override PacketId[] GetPacketIds()
  241. {
  242. return OpCodes.TransformArray(opcode => (PacketId)opcode);
  243. }
  244. }
  245. [XmlInclude(typeof(RealmServerOpCode))]
  246. [XmlInclude(typeof(AuthServerOpCode))]
  247. public abstract class XmlPacketDefinition
  248. {
  249. protected string _opcode;
  250. protected string[] _opcodes;
  251. [XmlAttribute("OpCode")]
  252. public string OpCode_
  253. {
  254. get
  255. {
  256. return _opcode;
  257. }
  258. set
  259. {
  260. _opcode = value;
  261. }
  262. }
  263. [XmlArray("OpCodes", Order = 1)]
  264. [XmlArrayItem("OpCode")]
  265. public string[] OpCodes_
  266. {
  267. get
  268. {
  269. return _opcodes;
  270. }
  271. set
  272. {
  273. _opcodes = value;
  274. }
  275. }
  276. [XmlElement("StaticList", typeof(StaticListPacketSegmentStructure), Order = 2)]
  277. [XmlElement("List", typeof(ListPacketSegmentStructure), Order = 2)]
  278. [XmlElement("FinalList", typeof(FinalListPacketSegmentStructure))]
  279. [XmlElement("Complex", typeof(ComplexPacketSegmentStructure), Order = 2)]
  280. [XmlElement("Switch", typeof(SwitchPacketSegmentStructure), Order = 2)]
  281. [XmlElement("Simple", typeof(PacketSegmentStructure), Order = 2)]
  282. public List<PacketSegmentStructure> Structure
  283. {
  284. get;
  285. set;
  286. }
  287. [XmlAttribute()]
  288. public PacketSender Sender
  289. {
  290. get;
  291. set;
  292. }
  293. public abstract PacketId[] GetPacketIds();
  294. }
  295. }