public static void LoadHandlers() { var types = Assembly.GetExecutingAssembly().GetTypes(); var identifiedClientBuilds = new List <uint>(); _serverPacketHandlers = new HandlerMap(); _clientPacketHandlers = new HandlerMap(); _serverOpcodeMap = new OpcodeMap(); _clientOpcodeMap = new OpcodeMap(); foreach (var type in types) { if (!type.IsAbstract || !type.IsPublic) { continue; } // Require each handler class to define the client build. var classAttributes = (ClientBuildAttribute[])type.GetCustomAttributes(typeof(ClientBuildAttribute), false); if (classAttributes.Length == 0) { continue; } var clientBuild = classAttributes[0].ClientBuild; var methods = type.GetMethods(); foreach (var method in methods) { if (!method.IsPublic) { continue; } var parameters = method.GetParameters(); if (parameters.Length == 0 || parameters[0].ParameterType != typeof(Packet)) { continue; } var attributes = (ParserAttribute[])method.GetCustomAttributes(typeof(ParserAttribute), false); if (attributes.Length == 0) { continue; } var attribute = attributes[0]; if (attribute.OpcodeValue == 0) { continue; } var key = CreateKey(clientBuild, attribute.OpcodeValue); var handler = (PacketHandler)Delegate.CreateDelegate(typeof(PacketHandler), method); OpcodeMap opcodeMap; HandlerMap handlerMap; if (attribute.Direction == Direction.ClientToServer) { opcodeMap = _clientOpcodeMap; handlerMap = _clientPacketHandlers; } else { opcodeMap = _serverOpcodeMap; handlerMap = _serverPacketHandlers; } if (handlerMap.ContainsKey(key)) { Debug.Print("Handler already found for opcode 0x{0:X4} ({1}) of client build {2}.", attribute.OpcodeValue, attribute.Opcode, clientBuild); continue; } if (!identifiedClientBuilds.Contains(clientBuild)) { identifiedClientBuilds.Add(clientBuild); } handlerMap[key] = handler; opcodeMap[key] = attribute.Opcode; Debug.Print("Handler added for opcode 0x{0:X4} ({1}) of client build {2}.", attribute.OpcodeValue, attribute.Opcode, clientBuild); } } // Now look through the builds we've discovered and identify their versions. foreach (var clientBuild in identifiedClientBuilds) { ClientVersion.AddAvailableVersion(clientBuild); } }