public void MultipleHandlersForATypeWithOtherHandlersAreSupported() { Func <Message, Task <bool> > fn1 = m => Task.FromResult(true); Func <Message, Task <bool> > fn2 = m => Task.FromResult(false); Func <Message, Task <bool> > fn3 = m => Task.FromResult(true); var map = new HandlerMap(); map.Add(typeof(GenericMessage), fn1); map.Add(typeof(GenericMessage), fn2); map.Add(typeof(AnotherGenericMessage), fn3); var handlers1 = map.Get(typeof(GenericMessage)); Assert.That(handlers1, Is.Not.Null); Assert.That(handlers1.Count, Is.EqualTo(2)); Assert.That(handlers1[0], Is.EqualTo(fn1)); Assert.That(handlers1[1], Is.EqualTo(fn2)); var handlers2 = map.Get(typeof(AnotherGenericMessage)); Assert.That(handlers2, Is.Not.Null); Assert.That(handlers2.Count, Is.EqualTo(1)); }
public async Task HandlePacketAsync(IPEndPoint endPoint, byte[] data, Reliability reliability) { var connection = RakNetServer.GetConnection(endPoint); await using var stream = new MemoryStream(data); using var reader = new BitReader(stream); var header = new PacketHeader(); reader.Read(header); if (header.MessageId != MessageIdentifier.UserPacketEnum) { throw new ArgumentOutOfRangeException($"Packet is not {nameof(MessageIdentifier.UserPacketEnum)}"); } if (header.PacketId == 0x05) { // // Game Message // var objectId = reader.Read <long>(); var messageId = reader.Read <ushort>(); try { if (GameMessageReceived != null) { await GameMessageReceived(objectId, messageId, reader, connection).ConfigureAwait(false); } } catch (Exception e) { Logger.Error(e); } return; } // // Regular Packet // if (!HandlerMap.TryGetValue(header.RemoteConnectionType, out var temp) || !temp.TryGetValue(header.PacketId, out var handler)) { Logger.Warning($"No handler registered for Packet ({header.RemoteConnectionType}:0x{header.PacketId:x})!"); return; } ; Logger.Debug($"Received {handler.Packet.GetType().FullName}"); reader.BaseStream.Position = 8; try { reader.Read(handler.Packet); await InvokeHandlerAsync(handler, connection).ConfigureAwait(false); } catch (Exception e) { Logger.Error(e); } }
public virtual void RegisterAssembly(Assembly assembly) { var groups = assembly.GetTypes().Where(c => c.IsSubclassOf(typeof(HandlerGroup))); foreach (var group in groups) { var instance = (HandlerGroup)Activator.CreateInstance(group); instance.SetServer(this); foreach (var method in group.GetMethods().Where(m => !m.IsStatic && !m.IsAbstract)) { var attr = method.GetCustomAttribute <PacketHandlerAttribute>(); if (attr != null) { var parameters = method.GetParameters(); if (parameters.Length == 0 || !typeof(IPacket).IsAssignableFrom(parameters[0].ParameterType)) { continue; } var packet = (IPacket)Activator.CreateInstance(parameters[0].ParameterType); var remoteConnectionType = attr.RemoteConnectionType ?? packet.RemoteConnectionType; var packetId = attr.PacketId ?? packet.PacketId; if (!HandlerMap.ContainsKey(remoteConnectionType)) { HandlerMap[remoteConnectionType] = new Dictionary <uint, Handler>(); } var handlers = HandlerMap[remoteConnectionType]; Logger.Debug(!handlers.ContainsKey(packetId) ? $"Registered handler for packet {packet}" : $"Handler for packet {packet} overwritten" ); handlers[packetId] = new Handler { Group = instance, Info = method, Packet = packet }; } else { var cmdAttr = method.GetCustomAttribute <CommandHandlerAttribute>(); if (cmdAttr == null) { continue; } if (!CommandHandleMap.ContainsKey(cmdAttr.Prefix)) { CommandHandleMap[cmdAttr.Prefix] = new Dictionary <string, CommandHandler>(); } CommandHandleMap[cmdAttr.Prefix][cmdAttr.Signature] = new CommandHandler { Group = instance, Info = method, GameMasterLevel = cmdAttr.GameMasterLevel, Help = cmdAttr.Help, Signature = cmdAttr.Signature, ConsoleCommand = method.GetParameters().Length != 2 }; } } } }
public void EmptyMapDoesNotContainKey() { var map = new HandlerMap(); Assert.That(map.ContainsKey(typeof(GenericMessage)), Is.False); }
public void EmptyMapDoesNotContainKey() { var map = new HandlerMap(); map.ContainsKey(typeof(SimpleMessage)).ShouldBeFalse(); }
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); } }