예제 #1
0
        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));
        }
예제 #2
0
파일: Server.cs 프로젝트: DigitalData/Uchu
        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);
            }
        }
예제 #3
0
파일: Server.cs 프로젝트: DigitalData/Uchu
        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
                        };
                    }
                }
            }
        }
예제 #4
0
        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();
        }
예제 #6
0
        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);
            }
        }