private void CreateButton()
 {
     ExpansionKitApi.GetExpandedMenu(ExpandedMenu.UserQuickMenu).AddSimpleButton("Get\nToys", () => {
         string name = GameObject.Find("UserInterface/Canvas_QuickMenu(Clone)/Container/Window/QMParent/Menu_SelectedUser_Local").GetComponent <VRC.UI.Elements.Menus.SelectedUserMenuQM>().field_Private_IUser_0.prop_String_0;
         VRCWSIntegration.SendMessage(new VibratorControllerMessage(name, Commands.GetToys));
     });
 }
        public override void OnApplicationStart()
        {
            if (MelonHandler.Mods.Any(mod => mod.Info.Name == "VibeGoesBrrr"))
            {
                MelonLogger.Warning("VibeGoesBrrr detected. Disabling Vibrator Controller since these mods are incompatible");
                return;
            }


            NativeMethods.LoadUnmanagedLibraryFromResource(Assembly.GetExecutingAssembly(), "Vibrator_Controller.buttplug_rs_ffi.dll", "buttplug_rs_ffi.dll");

            vibratorController = MelonPreferences.CreateCategory("VibratorController");

            MelonPreferences.CreateEntry(vibratorController.Identifier, "ActionMenu", true, "action menu integration");
            MelonPreferences.CreateEntry(vibratorController.Identifier, "buttonStep", 5, "What % to change when pressing button");

            useActionMenu = MelonPreferences.GetEntryValue <bool>(vibratorController.Identifier, "ActionMenu");
            buttonStep    = MelonPreferences.GetEntryValue <int>(vibratorController.Identifier, "buttonStep");

            if (useActionMenu && MelonHandler.Mods.Any(mod => mod.Info.Name == "ActionMenuApi"))
            {
                try {
                    new ToyActionMenu();
                } catch (Exception) {
                    MelonLogger.Warning("Failed to add action menu button");
                }
            }

            VRCWSIntegration.Init();
            MelonCoroutines.Start(UiManagerInitializer());
            CreateButton();

            VRCUtils.OnUiManagerInit += createMenu;
        }
Esempio n. 3
0
 internal void disable()
 {
     if (isActive)
     {
         isActive = false;
         MelonLogger.Msg("Disabled toy: " + name);
         hand = Hand.none;
         toys.rectTransform.gameObject.active = false;
         toys.Header.gameObject.active        = false;
         if (isLocal())
         {
             VRCWSIntegration.SendMessage(new VibratorControllerMessage(connectedTo, Commands.RemoveToy, this));
         }
     }
 }
Esempio n. 4
0
 internal void rotate()
 {
     if (isLocal())
     {
         try {
             clockwise = !clockwise;
             device.SendRotateCmd(lastSpeed, clockwise);
         } catch (ButtplugDeviceException) {
             MelonLogger.Error("Toy not connected");
         }
     }
     else
     {
         VRCWSIntegration.SendMessage(new VibratorControllerMessage(connectedTo, Commands.SetRotate, this));
     }
 }
Esempio n. 5
0
        internal void setSpeed(int speed)
        {
            if (speed != lastSpeed)
            {
                lastSpeed  = speed;
                label.Text = $"Current Speed: {speed}";

                if (connectedTo == "all")
                {
                    foreach (var toy in allToys.Where(x => x.connectedTo != "all"))
                    {
                        toy.setSpeed(speed);
                        if (toy.supportsTwoVibrators)
                        {
                            toy.setEdgeSpeed(speed);
                        }
                    }
                    return;
                }
                if (isLocal())
                {
                    try
                    {
                        if (supportsTwoVibrators)
                        {
                            device.SendVibrateCmd(new List <double> {
                                (double)lastSpeed / maxSpeed, (double)lastEdgeSpeed / maxSpeed2
                            });
                        }
                        else
                        {
                            device.SendVibrateCmd((double)speed / maxSpeed);
                        }

                        //MelonLogger.Msg("set device speed to " + ((double)speed / maxSpeed));
                    } catch (ButtplugDeviceException) {
                        MelonLogger.Error("Toy not connected");
                    }
                }
                else
                {
                    VRCWSIntegration.SendMessage(new VibratorControllerMessage(connectedTo, Commands.SetSpeed, this, speed));
                }
            }
        }
Esempio n. 6
0
        internal void enable()
        {
            if (!isActive)
            {
                isActive = true;
                toys.rectTransform.gameObject.active = true;
                toys.Header.gameObject.active        = true;

                if (device != null && device.AllowedMessages.ContainsKey(ServerMessage.Types.MessageAttributeType.BatteryLevelCmd))
                {
                    supportsBatteryLVL = true;
                    UpdateBattery();
                }
                if (isLocal() && hand == Hand.shared)
                {
                    VRCWSIntegration.SendMessage(new VibratorControllerMessage(connectedTo, Commands.AddToy, this));
                }
                MelonLogger.Msg("Enabled toy: " + name);
            }
        }
Esempio n. 7
0
        internal void setContraction(int speed)
        {
            if (lastContraction != speed)
            {
                lastContraction = speed;

                if (isLocal())
                {
                    try {
                        //moves to new position in 1 second
                        device.SendLinearCmd(1000, (double)speed / maxLinear);
                    } catch (ButtplugDeviceException) {
                        MelonLogger.Error("Toy not connected");
                    }
                }
                else
                {
                    VRCWSIntegration.SendMessage(new VibratorControllerMessage(connectedTo, Commands.SetAir, this, speed));
                }
            }
        }
Esempio n. 8
0
        internal void changeHand()
        {
            if (!isActive)
            {
                return;
            }

            hand++;
            if (hand > Enum.GetValues(typeof(Hand)).Cast <Hand>().Max())
            {
                hand = 0;
            }

            if (hand == Hand.shared && !isLocal())
            {
                hand++;
            }
            if (hand == Hand.both && !supportsTwoVibrators)
            {
                hand++;
            }

            if (!XRDevice.isPresent && (hand == Hand.both || hand == Hand.either || hand == Hand.left || hand == Hand.right))
            {
                hand = Hand.actionmenu;
            }

            if (isLocal())
            {
                if (hand == Hand.shared)
                {
                    VRCWSIntegration.SendMessage(new VibratorControllerMessage(connectedTo, Commands.AddToy, this));
                }
                else
                {
                    VRCWSIntegration.SendMessage(new VibratorControllerMessage(connectedTo, Commands.RemoveToy, this));
                }
            }
            changeMode.Text = "Mode\n" + hand;
        }
Esempio n. 9
0
        internal void setEdgeSpeed(int speed)
        {
            if (speed != lastEdgeSpeed)
            {
                lastEdgeSpeed = speed;

                if (isLocal())
                {
                    try {
                        device.SendVibrateCmd(new List <double> {
                            (double)lastSpeed / maxSpeed, (double)lastEdgeSpeed / maxSpeed2
                        });
                    } catch (ButtplugDeviceException) {
                        MelonLogger.Error("Toy not connected");
                    }
                }
                else
                {
                    VRCWSIntegration.SendMessage(new VibratorControllerMessage(connectedTo, Commands.SetSpeedEdge, this, speed));
                }
            }
        }
        private static void handleGetToys(string userID)
        {
            MelonLogger.Msg("Control Client requested toys");
            VibratorControllerMessage messageToSend = null;

            foreach (KeyValuePair <ulong, Toy> entry in Toy.myToys.Where(x => x.Value.hand == Hand.shared))
            {
                entry.Value.connectedTo = userID;
                if (messageToSend == null)
                {
                    messageToSend = new VibratorControllerMessage(userID, Commands.AddToy, entry.Value);
                }
                else
                {
                    messageToSend.Merge(new VibratorControllerMessage(userID, Commands.AddToy, entry.Value));
                }
            }

            if (messageToSend != null)
            {
                VRCWSIntegration.SendMessage(messageToSend);
            }
        }
Esempio n. 11
0
        internal Toy(ButtplugClientDevice device, SubMenu menu)
        {
            this.menu   = menu;
            id          = (device.Index + (ulong)Player.prop_Player_0.prop_String_0.GetHashCode()) % long.MaxValue;
            hand        = Hand.shared;
            name        = device.Name;
            this.device = device;

            //remove company name
            if (name.Split(' ').Length > 1)
            {
                name = name.Split(' ')[1];
            }

            if (myToys.ContainsKey(id))
            {
                MelonLogger.Msg("Device reconnected: " + name + " [" + id + "]");
                myToys[id].name   = name; //id should be uniquie but just to be sure
                myToys[id].device = device;
                myToys[id].enable();
                return;
            }



            MelonLogger.Msg("Device connected: " + name + " [" + id + "]");

            if (device.AllowedMessages.ContainsKey(ServerMessage.Types.MessageAttributeType.LinearCmd))
            {
                supportsLinear = true;
            }

            if (device.AllowedMessages.ContainsKey(ServerMessage.Types.MessageAttributeType.RotateCmd))
            {
                supportsRotate = true;
            }


            if (device.AllowedMessages.ContainsKey(ServerMessage.Types.MessageAttributeType.BatteryLevelCmd))
            {
                supportsBatteryLVL = true;
                UpdateBattery();
            }

            //prints info about the device
            foreach (KeyValuePair <ServerMessage.Types.MessageAttributeType, ButtplugMessageAttributes> entry in device.AllowedMessages)
            {
                MelonLogger.Msg("[" + id + "] Allowed Message: " + entry.Key);
            }

            if (device.AllowedMessages.ContainsKey(ServerMessage.Types.MessageAttributeType.VibrateCmd))
            {
                ButtplugMessageAttributes attributes = device.AllowedMessages[ServerMessage.Types.MessageAttributeType.VibrateCmd];

                if (attributes.ActuatorType != null && attributes.ActuatorType.Length > 0)
                {
                    MelonLogger.Msg("[" + id + "] ActuatorType " + string.Join(", ", attributes.ActuatorType));
                }

                if (attributes.StepCount != null && attributes.StepCount.Length > 0)
                {
                    MelonLogger.Msg("[" + id + "] StepCount " + string.Join(", ", attributes.StepCount));
                    maxSpeed = (int)attributes.StepCount[0];
                }
                if (attributes.StepCount != null && attributes.StepCount.Length == 2)
                {
                    supportsTwoVibrators = true;
                    maxSpeed2            = (int)attributes.StepCount[1];
                }

                if (attributes.Endpoints != null && attributes.Endpoints.Length > 0)
                {
                    MelonLogger.Msg("[" + id + "] Endpoints " + string.Join(", ", attributes.Endpoints));
                }

                if (attributes.MaxDuration != null && attributes.MaxDuration.Length > 0)
                {
                    MelonLogger.Msg("[" + id + "] MaxDuration " + string.Join(", ", attributes.MaxDuration));
                }

                if (attributes.Patterns != null && attributes.Patterns.Length > 0)
                {
                    foreach (string[] pattern in attributes.Patterns)
                    {
                        MelonLogger.Msg("[" + id + "] Pattern " + string.Join(", ", pattern));
                    }
                }
            }

            myToys.Add(id, this);
            createMenu();

            if (hand == Hand.shared)
            {
                VRCWSIntegration.SendMessage(new VibratorControllerMessage(connectedTo, Commands.AddToy, this));
            }
        }