private static IHandlerActionCache GetCache(MinecraftUserStatus status, IEnumerable <Assembly> assemblies) { var handlerCacheEntries = new Dictionary <object, HandlerActionModel>(); IEnumerable <Type> handlerTypes = from x in assemblies.SelectMany(a => a.GetTypes()) where x.GetMethods().Any(m => m.GetCustomAttributes(GetPacketHandlerAttributeType(status)).Any()) select x; foreach (Type handlerType in handlerTypes) { TypeInfo handlerTypeInfo = handlerType.GetTypeInfo(); IEnumerable <HandlerActionModel> handlerActions = from x in handlerType.GetMethods(BindingFlags.Instance | BindingFlags.Public) let attribute = x.GetCustomAttribute(GetPacketHandlerAttributeType(status)) as PacketHandlerAttribute where attribute != null select new HandlerActionModel(attribute.Action, x, handlerTypeInfo); foreach (HandlerActionModel handlerAction in handlerActions) { if (!handlerCacheEntries.ContainsKey(handlerAction.ActionType)) { handlerCacheEntries.Add(handlerAction.ActionType, handlerAction); } } } return(new HandlerActionCache(handlerCacheEntries)); }
/// <summary> /// Creates a new <see cref="HandshakePacket"/> instance. /// </summary> /// <param name="packet">Incoming packet from client.</param> public HandshakePacket(IMinecraftPacket packet) { ProtocolVersion = packet.ReadVarInt32(); ServerAddress = packet.ReadString(); ServerPort = packet.ReadUInt16(); NextState = (MinecraftUserStatus)packet.ReadVarInt32(); }
private static Type GetPacketHandlerAttributeType(MinecraftUserStatus status) { return(status switch { MinecraftUserStatus.Handshaking => typeof(HandshakePacketHandlerAttribute), MinecraftUserStatus.Status => typeof(StatusPacketHandlerAttribute), MinecraftUserStatus.Login => typeof(LoginPacketHandlerAttribute), MinecraftUserStatus.Play => typeof(PlayPacketHandlerAttribute), _ => throw new NotImplementedException() });
public object Invoke(MinecraftUserStatus status, object handler, params object[] parameters) { if (!_invokerCache.TryGetValue(status, out HandlerActionInvokerCache cache)) { throw new InvalidOperationException($"Failed to find invoker cache for status: '{status}'."); } HandlerActionInvokerCacheEntry handlerActionInvoker = cache.GetCachedHandlerAction(handler); if (handlerActionInvoker is null) { throw new HandlerActionNotFoundException(handler); } var targetHandler = handlerActionInvoker.HandlerFactory(handlerActionInvoker.HandlerType); if (targetHandler is null) { throw new HandlerTargetCreationFailedException(handlerActionInvoker.HandlerType); } object handlerResult = null; try { object[] handlerActionParameters = PrepareParameters(parameters, handlerActionInvoker.HandlerExecutor); handlerResult = handlerActionInvoker.HandlerExecutor.Execute(targetHandler, handlerActionParameters); } catch { throw; } finally { handlerActionInvoker.HandlerReleaser(targetHandler); } return(handlerResult); }
/// <summary> /// Creates a new <see cref="PacketHandlerAttribute"/> instance. /// </summary> /// <param name="status">Minecraft user status when the handler can be invoked.</param> /// <param name="action">Handler action.</param> protected PacketHandlerAttribute(MinecraftUserStatus status, object action) { Status = status; Action = action; }
public void UpdateStatus(MinecraftUserStatus newStatus) { // TODO: do additionnal checks. Status = newStatus; }