/// <summary> /// Fired when a <see cref="RegistrationPacket"/> is received /// </summary> /// <param name="rp">The <see cref="RegistrationPacket"/> containing the information received</param> /// <param name="receivedFrom">The host from which the packet was received</param> /// <param name="extraLogInfo">Any additional information to log after the request has been processed</param> /// <remarks> /// </remarks> protected virtual void OnRegistrationPacketReceived(RegistrationPacket rp, string receivedFrom, ref List <string> extraLogInfo) { if (this.RegistrationReceived != null) { this.RegistrationReceived(rp, receivedFrom, ref extraLogInfo); } }
/// <summary> /// Registers the application with Growl /// </summary> /// <param name="notificationTypes">Array of <see cref="NotificationType"/>s that the application will be sending</param> /// <remarks> /// An application must register before it can send notifications. If notifications are send and the application is not /// registered, the notifications will be ignored and discarded. If an application is already registered and calls /// <c>Register</c> again, the list of notifications that the application is allowed to send will be updated. Remote /// applications can only send notifications if they register remotely, requiring the user to 'Allow Remote Registrations'. /// </remarks> public void Register(ref NotificationType[] notificationTypes) { if (notificationTypes != null && notificationTypes.Length > 0) { List <NotificationType> ntList = new List <NotificationType>(); ntList.AddRange(notificationTypes); RegistrationPacket packet = new RegistrationPacket(protocolVersion, this.applicationName, this.password, ntList); Send(packet); } }
/// <summary> /// Given the raw packet data, converts the data back into a <see cref="RegistrationPacket"/> /// </summary> /// <param name="bytes">The raw packet data</param> /// <param name="passwordManager">The list of client passwords</param> /// <param name="passwordRequired">Indicates if the request must supply a valid password</param> /// <returns><see cref="RegistrationPacket"/></returns> /// <remarks> /// If the client password does not match the password used to validate the sent notification, /// or if the packet is malformed in any way, a <c>null</c> object will be returned. /// </remarks> public static RegistrationPacket FromPacket(byte[] bytes, PasswordManager passwordManager, bool passwordRequired) { RegistrationPacket rp = null; // parse the packet if (bytes != null && bytes.Length > 18) { // check md5 hash first string password = null; bool valid = BasePacket.IsPasswordValid(bytes, passwordManager, passwordRequired, out password); if (!valid) { return(rp); } int protocolVersion = (int)bytes[0]; PacketType packetType = (PacketType)bytes[1]; if (packetType == PacketType.Registration) { int index = 6; List <NotificationType> notificationTypes = new List <NotificationType>(); short applicationNameLength = BitConverter.ToInt16(new byte[] { bytes[3], bytes[2] }, 0); int notificationCount = (int)bytes[4]; int defaultNotificationCount = (int)bytes[5]; string applicationName = Encoding.UTF8.GetString(bytes, index, applicationNameLength); index += applicationNameLength; for (int n = 0; n < notificationCount; n++) { short notificationNameLength = BitConverter.ToInt16(new byte[] { bytes[index + 1], bytes[index] }, 0); string notificationName = Encoding.UTF8.GetString(bytes, index + 2, notificationNameLength); index += 2 + notificationNameLength; NotificationType nt = new NotificationType(notificationName, false); notificationTypes.Add(nt); } for (int d = 0; d < defaultNotificationCount; d++) { int notificationIndex = (int)bytes[index++]; notificationTypes[notificationIndex].Enabled = true; } rp = new RegistrationPacket(protocolVersion, applicationName, password, notificationTypes); } } return(rp); }
/// <summary> /// Registers the application with Growl /// </summary> /// <param name="notificationTypes">Array of <see cref="NotificationType"/>s that the application will be sending</param> /// <remarks> /// An application must register before it can send notifications. If notifications are send and the application is not /// registered, the notifications will be ignored and discarded. If an application is already registered and calls /// <c>Register</c> again, the list of notifications that the application is allowed to send will be updated. Remote /// applications can only send notifications if they register remotely, requiring the user to 'Allow Remote Registrations'. /// </remarks> public void Register(ref NotificationType[] notificationTypes) { if (notificationTypes != null && notificationTypes.Length > 0) { List<NotificationType> ntList = new List<NotificationType>(); ntList.AddRange(notificationTypes); RegistrationPacket packet = new RegistrationPacket(protocolVersion, this.applicationName, this.password, ntList); Send(packet); } }
/// <summary> /// Handles incoming packet data when a message is received /// </summary> /// <param name="bytes">The raw packet data</param> /// <param name="receivedFrom">The host that sent the packet</param> /// <param name="isLocal">Indicates if the request came from the local machine</param> /// <param name="isLAN">Indicates if the request came from the LAN</param> protected virtual void udp_PacketReceived(byte[] bytes, string receivedFrom, bool isLocal, bool isLAN) { // if this is a network request and we dont allow them, stop here if (!isLocal && !this.AllowNetworkNotifications) { return; } StringBuilder sb = new StringBuilder(); bool processed = false; List <string> extraLogInfo = new List <string>(); // parse the packet if (bytes != null && bytes.Length > 18) { int protocolVersion = (int)bytes[0]; PacketType packetType = (PacketType)bytes[1]; bool passwordRequired = true; if (isLocal && !this.RequireLocalPassword) { passwordRequired = false; } else if (isLAN && !this.RequireLANPassword) { passwordRequired = false; } if (packetType == PacketType.Registration) { RegistrationPacket rp = RegistrationPacket.FromPacket(bytes, this.passwordManager, passwordRequired); if (rp != null) { this.OnRegistrationPacketReceived(rp, receivedFrom, ref extraLogInfo); processed = true; sb.AppendFormat("Protocol Version: {0}\r\n", rp.ProtocolVersion); sb.AppendFormat("Packet Type: {0}\r\n", rp.PacketType); sb.AppendFormat("Application Name: {0}\r\n", rp.ApplicationName); sb.AppendFormat("Notifications Registered: {0}\r\n\r\n", rp.NotificationTypes.Length); foreach (NotificationType nt in rp.NotificationTypes) { sb.AppendFormat(" Notification Type: {0}\r\n", nt.Name); sb.AppendFormat(" Enabled: {0}\r\n\r\n", nt.Enabled); } } else { sb.Append("Invalid message - either the message format was incorrect or the password was incorrect"); } } else if (packetType == PacketType.Notification) { NotificationPacket np = NotificationPacket.FromPacket(bytes, this.passwordManager, passwordRequired); if (np != null) { this.OnNotificationPacketReceived(np, receivedFrom, ref extraLogInfo); processed = true; sb.AppendFormat("Protocol Version: {0}\r\n", np.ProtocolVersion); sb.AppendFormat("Packet Type: {0}\r\n", np.PacketType); sb.AppendFormat("Application Name: {0}\r\n", np.ApplicationName); sb.AppendFormat("Notification Type: {0}\r\n", np.NotificationType.Name); sb.AppendFormat("Title: {0}\r\n", np.Title); sb.AppendFormat("Description: {0}\r\n", np.Description); sb.AppendFormat("Sticky: {0}\r\n", np.Sticky); sb.AppendFormat("Priority: {0}\r\n", np.Priority); } else { sb.Append("Invalid message - either the message format was incorrect or the password was incorrect"); } } else { sb.Append("Malformed packet - unrecognized data"); } } else { sb.Append("Malformed packet - not enough bytes"); } Log(sb.ToString(), bytes, receivedFrom, processed, extraLogInfo); }
/// <summary> /// Given the raw packet data, converts the data back into a <see cref="RegistrationPacket"/> /// </summary> /// <param name="bytes">The raw packet data</param> /// <param name="passwordManager">The list of client passwords</param> /// <param name="passwordRequired">Indicates if the request must supply a valid password</param> /// <returns><see cref="RegistrationPacket"/></returns> /// <remarks> /// If the client password does not match the password used to validate the sent notification, /// or if the packet is malformed in any way, a <c>null</c> object will be returned. /// </remarks> public static RegistrationPacket FromPacket(byte[] bytes, PasswordManager passwordManager, bool passwordRequired) { RegistrationPacket rp = null; // parse the packet if (bytes != null && bytes.Length > 18) { // check md5 hash first string password = null; bool valid = BasePacket.IsPasswordValid(bytes, passwordManager, passwordRequired, out password); if (!valid) return rp; int protocolVersion = (int)bytes[0]; PacketType packetType = (PacketType)bytes[1]; if (packetType == PacketType.Registration) { int index = 6; List<NotificationType> notificationTypes = new List<NotificationType>(); short applicationNameLength = BitConverter.ToInt16(new byte[] { bytes[3], bytes[2] }, 0); int notificationCount = (int)bytes[4]; int defaultNotificationCount = (int)bytes[5]; string applicationName = Encoding.UTF8.GetString(bytes, index, applicationNameLength); index += applicationNameLength; for (int n = 0; n < notificationCount; n++ ) { short notificationNameLength = BitConverter.ToInt16(new byte[] { bytes[index + 1], bytes[index] }, 0); string notificationName = Encoding.UTF8.GetString(bytes, index + 2, notificationNameLength); index += 2 + notificationNameLength; NotificationType nt = new NotificationType(notificationName, false); notificationTypes.Add(nt); } for (int d = 0; d < defaultNotificationCount; d++) { int notificationIndex = (int) bytes[index++]; notificationTypes[notificationIndex].Enabled = true; } rp = new RegistrationPacket(protocolVersion, applicationName, password, notificationTypes); } } return rp; }
/// <summary> /// Fired when a <see cref="RegistrationPacket"/> is received /// </summary> /// <param name="rp">The <see cref="RegistrationPacket"/> containing the information received</param> /// <param name="receivedFrom">The host from which the packet was received</param> /// <param name="extraLogInfo">Any additional information to log after the request has been processed</param> /// <remarks> /// </remarks> protected virtual void OnRegistrationPacketReceived(RegistrationPacket rp, string receivedFrom, ref List<string> extraLogInfo) { if (this.RegistrationReceived != null) this.RegistrationReceived(rp, receivedFrom, ref extraLogInfo); }