コード例 #1
0
        public static void Wrap(Vessel parent, Action <BaseEvent, bool> pass)
        {
            UIPartActionController controller = UIPartActionController.Instance;

            if (!controller)
            {
                return;
            }

            // Get the open context menus
            FieldInfo listFieldInfo = controller.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
                                      .First(fi => fi.FieldType == typeof(List <UIPartActionWindow>));

            List <UIPartActionWindow> openWindows = (List <UIPartActionWindow>)listFieldInfo.GetValue(controller);

            foreach (UIPartActionWindow window in openWindows.Where(l => l.part.vessel == parent))
            {
                // Get the list of all UIPartActionItem's
                FieldInfo itemsFieldInfo = typeof(UIPartActionWindow).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
                                           .First(fi => fi.FieldType == typeof(List <UIPartActionItem>));

                List <UIPartActionItem> item = (List <UIPartActionItem>)itemsFieldInfo.GetValue(window);
                // We only need the UIPartActionEventItem's
                IEnumerable <UIPartActionItem> actionEventButtons = item.Where(l => (l as UIPartActionEventItem) != null);

                foreach (UIPartActionEventItem button in actionEventButtons)
                {
                    BaseEvent originalEvent = button.Evt;
                    // Get the BaseEventDelegate object from the button
                    FieldInfo partEventFieldInfo = typeof(BaseEvent).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
                                                   .First(fi => fi.FieldType == typeof(BaseEventDelegate));

                    BaseEventDelegate partEvent        = (BaseEventDelegate)partEventFieldInfo.GetValue(originalEvent);
                    object[]          customAttributes = partEvent.Method.GetCustomAttributes(typeof(KSPEvent), true);

                    // Look for the custom attribute skip_control
                    bool skip_control = customAttributes.Any(a => ((KSPEvent)a).category.Contains("skip_control"));

                    if (!skip_control)
                    {
                        // Look for the custom attribute skip_delay
                        bool ignore_delay = customAttributes.Any(a => ((KSPEvent)a).category.Contains("skip_delay"));

                        // Override the old BaseEvent with our BaseEvent to the button
                        FieldInfo eventField = typeof(UIPartActionEventItem).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
                                               .First(fi => fi.FieldType == typeof(BaseEvent));

                        BaseEventList eventList = originalEvent.listParent;
                        int           listIndex = eventList.IndexOf(originalEvent);

                        // create the new BaseEvent
                        BaseEvent hookedEvent = Wrapper.CreateWrapper(originalEvent, pass, ignore_delay);
                        eventList.RemoveAt(listIndex);
                        eventList.Add(hookedEvent);

                        eventField.SetValue(button, hookedEvent);
                    }
                }
            }
        }
コード例 #2
0
        public static void WrapPartActionEventItem(Part part, Action <BaseEvent, bool> passthrough)
        {
            var controller = UIPartActionController.Instance;

            if (!controller)
            {
                return;
            }

            // get the part action window corresponding to the part
            var window = controller.GetItem(part);

            if (window == null)
            {
                return;
            }

            // get all the items that makes this window (toggle buttons, sliders, etc.)
            var partActionItems = window.ListItems;

            // loop through all of those UI components
            for (var i = 0; i < partActionItems.Count(); i++)
            {
                // check that the part action item is actually a UIPartActionFieldItem (it could be a UIPartActionEventItem)
                var uiPartActionEventItem = (partActionItems[i] as UIPartActionEventItem);
                if (uiPartActionEventItem == null)
                {
                    continue;
                }

                // get event from button
                BaseEvent originalEvent = uiPartActionEventItem.Evt;

                // Search for the BaseEventDelegate (BaseEvent.onEvent) field defined for the current BaseEvent type.
                // Note that 'onEvent' is protected, so we have to go through reflection.
                FieldInfo partEventFieldInfo = typeof(BaseEvent).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
                                               .First(fi => fi.FieldType == typeof(BaseEventDelegate));

                // Get the actual value of the 'onEvent' field
                BaseEventDelegate partEvent = (BaseEventDelegate)partEventFieldInfo.GetValue(originalEvent);

                // Gets the method represented by the delegate and from this method returns an array of custom attributes applied to this member.
                // Simply put, we want all [KSPEvent] attributes applied to the BaseEventDelegate.Method field.
                object[] customAttributes = partEvent.Method.GetCustomAttributes(typeof(KSPEvent), true);

                // Look for the custom attribute skip_control
                bool skipControl = customAttributes.Any(a => ((KSPEvent)a).category.Contains("skip_control"));
                if (skipControl)
                {
                    continue;
                }

                /*
                 * Override the old BaseEvent with our BaseEvent to the button
                 */

                // fix problems with other mods (behavior not seen with KSP) when the customAttributes list is empty.
                KSPEvent kspEvent = !customAttributes.Any() ? WrappedEvent.KspEventFromBaseEvent(originalEvent) : (KSPEvent)customAttributes[0];

                // Look for the custom attribute skip_delay
                bool ignoreDelay = customAttributes.Any(a => ((KSPEvent)a).category.Contains("skip_delay"));

                // create the new BaseEvent
                BaseEvent hookedEvent = EventWrapper.CreateWrapper(originalEvent, passthrough, ignoreDelay, kspEvent);

                // get the original event index in the event list
                BaseEventList eventList = originalEvent.listParent;
                int           listIndex = eventList.IndexOf(originalEvent);

                // remove the original event in the event list and add our hooked event
                eventList.RemoveAt(listIndex);
                eventList.Add(hookedEvent);

                // get the baseEvent field from UIPartActionEventItem (note: this is uiPartActionEventItem.Evt, but we can't set its value...)
                FieldInfo baseEventField = typeof(UIPartActionEventItem).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
                                           .First(fi => fi.FieldType == typeof(BaseEvent));

                // replace the button baseEvent value with our hooked event
                baseEventField.SetValue(uiPartActionEventItem, hookedEvent);
            }
        }