├── .github
├── FUNDING.yml
└── workflows
│ └── dotnet.yml
├── .gitignore
├── Docs
└── README.md
├── LICENSE
├── PlagueButtonAPI
├── ExampleButtonAPIUsage
│ ├── ExampleButtonAPIUsage.csproj
│ ├── ExampleButtonAPIUsageMain.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── Utils.cs
├── PlagueButtonAPI.sln
└── PlagueButtonAPI
│ ├── Controls
│ ├── Base Classes
│ │ ├── Button.cs
│ │ ├── ControlWithText.cs
│ │ ├── GenericControl.cs
│ │ └── Toggle.cs
│ ├── Buttons
│ │ ├── Label.cs
│ │ ├── SimpleSingleButton.cs
│ │ ├── SingleButton.cs
│ │ ├── Toggles
│ │ │ └── ToggleButton.cs
│ │ └── WingSingleButton.cs
│ ├── Grouping
│ │ ├── ButtonGroup.cs
│ │ └── CollapsibleButtonGroup.cs
│ ├── Slider.cs
│ └── Tab.cs
│ ├── External Libraries
│ ├── ConfigLib.cs
│ ├── IL2CPPAssetBundle.cs
│ └── VRCUtils
│ │ └── VRCUtils.cs
│ ├── Hooks
│ └── Hooks.cs
│ ├── Main
│ ├── ButtonAPI.cs
│ └── TransformHelper.cs
│ ├── Misc
│ ├── ComponentManager.cs
│ ├── CustomInputPickup.cs
│ ├── Extensions.cs
│ ├── MelonLoaderEvents.cs
│ ├── PriorityAttribute.cs
│ ├── QuickMenuPopup.cs
│ └── Utils.cs
│ ├── Mod.cs
│ ├── Pages
│ └── MenuPage.cs
│ ├── PlagueButtonAPI.csproj
│ ├── Properties
│ └── AssemblyInfo.cs
│ └── Resources
│ └── keyboard.asset
├── README.md
└── References
├── ExampleButtonAPIUsage
├── Assembly-CSharp-firstpass.dll
├── Assembly-CSharp.dll
├── DataModel.dll
├── Il2CppSystem.Core.dll
├── Il2CppSystem.dll
├── Il2Cppmscorlib.dll
├── MelonLoader.dll
├── UIExpansionKit.dll
├── UnhollowerBaseLib.dll
├── UnhollowerRuntimeLib.dll
├── Unity.TextMeshPro.dll
├── UnityEngine.AssetBundleModule.dll
├── UnityEngine.CoreModule.dll
├── UnityEngine.Il2CppImageConversionManager.dll
├── UnityEngine.InputLegacyModule.dll
├── UnityEngine.TextRenderingModule.dll
├── UnityEngine.UI.dll
├── UnityEngine.UIElementsModule.dll
├── UnityEngine.UIModule.dll
├── UnityEngine.dll
├── VRC.UI.Core.dll
├── VRC.UI.Elements.dll
├── VRC.UI.Shared.dll
├── VRCCore-Editor.dll
├── VRCCore-Standalone.dll
├── VRCSDK2.dll
├── VRCSDK3A.dll
├── VRCSDKBase.dll
└── VRChatUtilityKit.dll
└── PlagueButtonAPI
├── Assembly-CSharp-firstpass.dll
├── Assembly-CSharp.dll
├── DataModel.dll
├── Il2CppSystem.Core.dll
├── Il2CppSystem.dll
├── Il2Cppmscorlib.dll
├── MelonLoader.dll
├── Newtonsoft.Json.dll
├── System.Windows.Forms.dll
├── UnhollowerBaseLib.dll
├── UnhollowerRuntimeLib.dll
├── Unity.TextMeshPro.dll
├── UnityEngine.AssetBundleModule.dll
├── UnityEngine.CoreModule.dll
├── UnityEngine.Il2CppImageConversionManager.dll
├── UnityEngine.InputLegacyModule.dll
├── UnityEngine.TextRenderingModule.dll
├── UnityEngine.UI.dll
├── UnityEngine.UIElementsModule.dll
├── UnityEngine.UIModule.dll
├── UnityEngine.VRModule.dll
├── UnityEngine.XRModule.dll
├── UnityEngine.dll
├── VRC.UI.Core.dll
├── VRC.UI.Elements.dll
├── VRC.UI.Shared.dll
├── VRCCore-Editor.dll
├── VRCCore-Standalone.dll
├── VRCSDK2.dll
└── VRCSDKBase.dll
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: https://VRCAntiCrash.com/Pay
2 |
--------------------------------------------------------------------------------
/.github/workflows/dotnet.yml:
--------------------------------------------------------------------------------
1 | name: .NET
2 |
3 | on:
4 | push:
5 | branches: new-ui
6 | paths:
7 | - 'PlagueButtonAPI/**'
8 | - 'References/**'
9 | - '.github/workflows/**'
10 |
11 | jobs:
12 | build:
13 | runs-on: windows-latest
14 |
15 | steps:
16 | - uses: actions/checkout@v2
17 |
18 | - name: Setup MSBuild
19 | uses: microsoft/setup-msbuild@v1
20 |
21 | - name: Build Solution
22 | run: |
23 | msbuild.exe PlagueButtonAPI/PlagueButtonAPI.sln /p:DeleteExistingFiles=True /p:platform="Any CPU" /p:configuration="Normal"
24 |
25 | - name: Upload PlagueButtonAPI Artifact
26 | uses: actions/upload-artifact@v2
27 | with:
28 | name: PlagueButtonAPI.dll
29 | path: PlagueButtonAPI/PlagueButtonAPI/bin/Debug/PlagueButtonAPI.dll
30 |
31 | - name: Upload PlagueButtonAPI PDB Artifact
32 | uses: actions/upload-artifact@v2
33 | with:
34 | name: PlagueButtonAPI.pdb
35 | path: PlagueButtonAPI/PlagueButtonAPI/bin/Debug/PlagueButtonAPI.pdb
36 |
37 | - name: Upload ExampleButtonAPIUsage Artifact
38 | uses: actions/upload-artifact@v2
39 | with:
40 | name: ExampleButtonAPIUsage.dll
41 | path: PlagueButtonAPI/ExampleButtonAPIUsage/bin/Debug/ExampleButtonAPIUsage.dll
42 |
43 | - name: Delete Old Releases
44 | uses: dev-drprasad/delete-older-releases@v0.2.0
45 | with:
46 | keep_latest: 0
47 | delete_tags: true
48 | env:
49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50 |
51 | - name: Get current date
52 | id: date
53 | run: echo "::set-output name=date::$(date +'%d/%m/%Y %H:%M')"
54 |
55 | - name: Create A Release
56 | uses: actions/create-release@v1
57 | id: create_release
58 | with:
59 | draft: false
60 | prerelease: false
61 | release_name: Latest Build [${{ steps.date.outputs.date }}]
62 | tag_name: ${{ github.run_id }}
63 | env:
64 | GITHUB_TOKEN: ${{ github.token }}
65 |
66 | - name: Add PlagueButtonAPI.dll To Release
67 | uses: actions/upload-release-asset@v1
68 | env:
69 | GITHUB_TOKEN: ${{ github.token }}
70 | with:
71 | upload_url: ${{ steps.create_release.outputs.upload_url }}
72 | asset_path: PlagueButtonAPI/PlagueButtonAPI/bin/Debug/PlagueButtonAPI.dll
73 | asset_name: PlagueButtonAPI.dll
74 | asset_content_type: application/x-msdownload
75 |
76 | - name: Add PlagueButtonAPI.dll To Release
77 | uses: actions/upload-release-asset@v1
78 | env:
79 | GITHUB_TOKEN: ${{ github.token }}
80 | with:
81 | upload_url: ${{ steps.create_release.outputs.upload_url }}
82 | asset_path: PlagueButtonAPI/ExampleButtonAPIUsage/bin/Debug/ExampleButtonAPIUsage.dll
83 | asset_name: ExampleButtonAPIUsage.dll
84 | asset_content_type: application/x-msdownload
85 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | PlagueButtonAPIExample/.vs/PlagueButtonAPIExample/v15/.suo
3 | *.lock
4 | *.ide
5 | *.ide-shm
6 | *.ide-wal
7 | *.cache
8 | PlagueButtonAPIExample/PlagueButtonAPIExample/obj/Normal/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs
9 | PlagueButtonAPIExample/PlagueButtonAPIExample/obj/Normal/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
10 | PlagueButtonAPIExample/PlagueButtonAPIExample/obj/Normal/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs
11 | PlagueButtonAPIExample/PlagueButtonAPIExample/obj/VRChat Mods Folder/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs
12 | PlagueButtonAPIExample/PlagueButtonAPIExample/obj/VRChat Mods Folder/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
13 | PlagueButtonAPIExample/PlagueButtonAPIExample/obj/VRChat Mods Folder/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs
14 | PlagueButtonAPIExample/PlagueButtonAPIExample/PlagueButtonAPIExample.csproj
15 | *.pdb
16 | PlagueButtonAPIExample/PlagueButtonAPIExample/obj/Normal/PlagueButtonAPIExample.csproj.FileListAbsolute.txt
17 | PlagueButtonAPIExample/PlagueButtonAPIExample/obj/VRChat Mods Folder/PlagueButtonAPIExample.csproj.FileListAbsolute.txt
18 | PlagueButtonAPIExample/PlagueButtonAPIExample/obj/VRChat Mods Folder/build.force
19 | /PlagueButtonAPIExample/ExampleButtonAPIUsage/obj/Release
20 | *.suo
21 | /PlagueButtonAPIExample/PlagueButtonAPI/obj
22 | /PlagueButtonAPI/ExampleButtonAPIUsage/obj/Release
23 | /PlagueButtonAPI/PlagueButtonAPI/obj
24 | /PlagueButtonAPI/PlagueButtonAPI/bin/Debug
25 | /PlagueButtonAPI/ExampleButtonAPIUsage/obj/Debug
26 | /PlagueButtonAPI/ExampleButtonAPIUsage/obj/VRChat Mods Folder
27 | *.htm
28 | /PlagueButtonAPI/ExampleButtonAPIUsage/obj/Normal
29 | /PlagueButtonAPI/ExampleButtonAPIUsage/ExampleButtonAPIUsage.csproj.user
30 | /PlagueButtonAPI/PlagueButtonAPI/PlagueButtonAPI.csproj.user
31 | /PlagueButtonAPI/.vs/PlagueButtonAPI
32 |
--------------------------------------------------------------------------------
/Docs/README.md:
--------------------------------------------------------------------------------
1 | # See The Example Mod's Code For A Quick Example Of Usage: [Click Here](https://github.com/PlagueVRC/PlagueButtonAPI/blob/new-ui/PlagueButtonAPI/ExampleButtonAPIUsage/ExampleButtonAPIUsageMain.cs#L60)
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Use-Only License
2 |
3 | Copyright (c) 2021 Plague
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to use and/or distribute copies of the Software, and to permit persons to whom the Software is
7 | furnished to do so, subject to the following conditions:
8 |
9 | The above copyright notice and this permission notice shall be included in all
10 | copies or substantial portions of the Software.
11 |
12 | The software you develop must fall within non-malicious terms.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/PlagueButtonAPI/ExampleButtonAPIUsage/ExampleButtonAPIUsage.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | VRChat Mods Folder
6 | AnyCPU
7 | {4090D6AD-C19F-4E2A-9F7B-17128113E139}
8 | Library
9 | Properties
10 | ExampleButtonAPIUsage
11 | ExampleButtonAPIUsage
12 | v4.7.2
13 | 512
14 | true
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | TRACE
22 | prompt
23 | 4
24 |
25 |
26 | true
27 | full
28 | false
29 | G:\Games\SteamLibrary\steamapps\common\VRChat\Mods\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 | ..\..\References\ExampleButtonAPIUsage\Assembly-CSharp.dll
37 | False
38 |
39 |
40 | ..\..\References\ExampleButtonAPIUsage\Assembly-CSharp-firstpass.dll
41 | False
42 |
43 |
44 | ..\..\References\ExampleButtonAPIUsage\DataModel.dll
45 | False
46 |
47 |
48 | ..\..\References\ExampleButtonAPIUsage\Il2Cppmscorlib.dll
49 | False
50 |
51 |
52 | ..\..\References\ExampleButtonAPIUsage\Il2CppSystem.dll
53 | False
54 |
55 |
56 | ..\..\References\ExampleButtonAPIUsage\Il2CppSystem.Core.dll
57 | False
58 |
59 |
60 | ..\..\References\ExampleButtonAPIUsage\MelonLoader.dll
61 | False
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | False
73 | ..\..\References\ExampleButtonAPIUsage\UIExpansionKit.dll
74 | False
75 |
76 |
77 | ..\..\References\ExampleButtonAPIUsage\UnhollowerBaseLib.dll
78 | False
79 |
80 |
81 | ..\..\References\ExampleButtonAPIUsage\UnhollowerRuntimeLib.dll
82 | False
83 |
84 |
85 | ..\..\References\ExampleButtonAPIUsage\Unity.TextMeshPro.dll
86 | False
87 |
88 |
89 | ..\..\References\ExampleButtonAPIUsage\UnityEngine.dll
90 | False
91 |
92 |
93 | ..\..\References\ExampleButtonAPIUsage\UnityEngine.AssetBundleModule.dll
94 | False
95 |
96 |
97 | ..\..\References\ExampleButtonAPIUsage\UnityEngine.CoreModule.dll
98 | False
99 |
100 |
101 | ..\..\References\ExampleButtonAPIUsage\UnityEngine.Il2CppImageConversionManager.dll
102 | False
103 |
104 |
105 | ..\..\References\ExampleButtonAPIUsage\UnityEngine.InputLegacyModule.dll
106 | False
107 |
108 |
109 | ..\..\References\ExampleButtonAPIUsage\UnityEngine.TextRenderingModule.dll
110 | False
111 |
112 |
113 | ..\..\References\ExampleButtonAPIUsage\UnityEngine.UI.dll
114 | False
115 |
116 |
117 | ..\..\References\ExampleButtonAPIUsage\UnityEngine.UIElementsModule.dll
118 | False
119 |
120 |
121 | ..\..\References\ExampleButtonAPIUsage\UnityEngine.UIModule.dll
122 | False
123 |
124 |
125 | ..\..\References\ExampleButtonAPIUsage\VRC.UI.Core.dll
126 | False
127 |
128 |
129 | ..\..\References\ExampleButtonAPIUsage\VRC.UI.Elements.dll
130 | False
131 |
132 |
133 | ..\..\References\ExampleButtonAPIUsage\VRC.UI.Shared.dll
134 | False
135 |
136 |
137 | ..\..\References\ExampleButtonAPIUsage\VRCCore-Editor.dll
138 | False
139 |
140 |
141 | ..\..\References\ExampleButtonAPIUsage\VRCCore-Standalone.dll
142 | False
143 |
144 |
145 | False
146 | ..\..\References\ExampleButtonAPIUsage\VRChatUtilityKit.dll
147 | False
148 |
149 |
150 | ..\..\References\ExampleButtonAPIUsage\VRCSDK2.dll
151 | False
152 |
153 |
154 | ..\..\References\ExampleButtonAPIUsage\VRCSDK3A.dll
155 | False
156 |
157 |
158 | ..\..\References\ExampleButtonAPIUsage\VRCSDKBase.dll
159 | False
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 | {1067ac86-8417-4f30-a9d0-ee8027bfb134}
170 | PlagueButtonAPI
171 | False
172 |
173 |
174 |
175 |
--------------------------------------------------------------------------------
/PlagueButtonAPI/ExampleButtonAPIUsage/ExampleButtonAPIUsageMain.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 | using ExampleButtonAPIUsage;
6 | using HarmonyLib;
7 | using MelonLoader;
8 | using PlagueButtonAPI;
9 | using PlagueButtonAPI.Controls;
10 | using PlagueButtonAPI.Controls.Grouping;
11 | using PlagueButtonAPI.Main;
12 | using PlagueButtonAPI.Misc;
13 | using PlagueButtonAPI.Pages;
14 | using UnityEngine;
15 | using VRC;
16 | using VRC.Core;
17 | using VRChatUtilityKit.Ui;
18 | using VRChatUtilityKit.Utilities;
19 |
20 | [assembly: MelonInfo(typeof(ExampleButtonAPIUsageMain), "Example PlagueButtonAPI Usage", "1.0", "Plague")]
21 | [assembly: MelonGame("VRChat", "VRChat")]
22 |
23 | namespace ExampleButtonAPIUsage
24 | {
25 | public class ExampleButtonAPIUsageMain : MelonMod
26 | {
27 | private bool DoPlayerListRefresh = false;
28 |
29 | private Dictionary UserImages = new Dictionary();
30 |
31 | public override void OnApplicationStart()
32 | {
33 | try
34 | {
35 | ButtonImage = (Environment.CurrentDirectory + "\\ImageToLoad.png").LoadSpriteFromDisk();
36 | }
37 | catch {}
38 |
39 | NetworkEvents.OnAvatarInstantiated += NetworkEvents_OnAvatarInstantiated;
40 |
41 | HarmonyInstance.Patch(typeof(PortalInternal).GetMethod(nameof(PortalInternal.ConfigurePortal), AccessTools.all), new HarmonyMethod(typeof(ExampleButtonAPIUsageMain).GetMethod(nameof(ConfigurePortal), BindingFlags.NonPublic | BindingFlags.Static)));
42 | }
43 |
44 | private static bool ConfigurePortal(ref string __0, ref string __1, ref int __2, ref Player __3)
45 | {
46 | return __3 == Player.prop_Player_0 || !DisablePortals;
47 | }
48 |
49 | private void NetworkEvents_OnAvatarInstantiated(VRCAvatarManager arg1, ApiAvatar arg2, GameObject arg3)
50 | {
51 | var tex = Utils.TakePictureOfPlayer(arg1.field_Private_VRCPlayer_0);
52 |
53 | var sprite = PlagueButtonAPI.Misc.Utils.CreateSpriteFromTex(tex);
54 |
55 | UserImages[arg1.field_Private_VRCPlayer_0.gameObject.GetOrAddComponent().field_Private_APIUser_0.id] = sprite;
56 |
57 | DoPlayerListRefresh = true;
58 | }
59 |
60 | public override void OnSceneWasLoaded(int buildIndex, string sceneName)
61 | {
62 | if (sceneName == "ui") // If VRC UI Init
63 | {
64 | ButtonAPI.OnInit += () => // Assign, This Will Happen BEFORE QuickMenu Init, ButtonAPI Will Call OnInit On QuickMenu Init. - This is assigning to an event; eventname += delegatehere
65 | {
66 | var Combi = MenuPage.CreatePage(WingSingleButton.Wing.Left, ButtonImage, "TestMenu_1", "Main Menu");
67 |
68 | var Page = Combi.Item1;
69 |
70 | var FunctionalGroup = Page.AddButtonGroup("Functional Options");
71 |
72 | FunctionalGroup.AddToggleButton("Disable Portals", "Disables Portals Entirely", "Re-Enables Portals", val => { DisablePortals = val; }).SetToggleState(false, true);
73 |
74 | var NonFunctionalGroup = Page.AddCollapsibleButtonGroup("Non-Functional Options");
75 |
76 | var PlayerListMenu = NonFunctionalGroup.AddSubMenu(ButtonImage, "PlayersList_1", "Player List");
77 |
78 | var PlayersGroup = PlayerListMenu.Item1.AddButtonGroup("", true, TextAnchor.UpperLeft);
79 | var Handler = PlayersGroup.gameObject.GetOrAddComponent();
80 |
81 | Handler.OnUpdateEachSecond += (obj, IsEnabled) =>
82 | {
83 | if (IsEnabled && DoPlayerListRefresh)
84 | {
85 | PlayersGroup.gameObject.transform.DestroyChildren();
86 |
87 | foreach (var player in PlagueButtonAPI.Misc.Utils.GetAllPlayers())
88 | {
89 | var image = UserImages.ContainsKey(player.field_Private_APIUser_0.id) ? UserImages[player.field_Private_APIUser_0.id] : null;
90 |
91 | if (player?.field_Private_APIUser_0 == null || image == null)
92 | {
93 | MelonLogger.Error("Null Player Or Image!");
94 | continue;
95 | }
96 |
97 | PlayersGroup.AddSingleButton(player.field_Private_APIUser_0.displayName, "Selects This Player", () => { UiManager.OpenUserInQuickMenu(player.field_Private_APIUser_0); }, true, image);
98 | }
99 |
100 | DoPlayerListRefresh = false;
101 | }
102 | };
103 |
104 | NonFunctionalGroup.AddSimpleSingleButton("Show Alerts", "Simple Button", () =>
105 | {
106 | ButtonAPI.GetQuickMenuInstance().ShowAlert("Alert Test");
107 |
108 | ButtonAPI.GetQuickMenuInstance().ShowOKDialog("Title", "Message", () =>
109 | {
110 | MelonLogger.Msg("Okay Clicked! Showing Yes/No Popup..");
111 |
112 | MelonCoroutines.Start(RunMe());
113 |
114 | IEnumerator RunMe()
115 | {
116 | yield return new WaitForSeconds(3f);
117 |
118 | ButtonAPI.GetQuickMenuInstance().ShowConfirmDialog("Title", "Message", () => { MelonLogger.Msg("Yes Clicked!"); }, () => { MelonLogger.Msg("No Clicked!"); });
119 |
120 | yield break;
121 | }
122 | });
123 | });
124 |
125 | NonFunctionalGroup.AddToggleButton("Toggle", "Toggle On", "Toggle Off", val => { MelonLogger.Msg("Toggle Button Clicked! -> State: " + val); }).SetToggleState(true, true);
126 |
127 | NonFunctionalGroup.AddSlider("Slider", "Slider", val => { MelonLogger.Msg("Slider Adjusted! -> State: " + val); });
128 |
129 | Page.AddSlider("Slider", "Slider", val => { MelonLogger.Msg("Slider Adjusted! -> State: " + val); });
130 |
131 | var Dropdown = Page.AddCollapsibleButtonGroup("Dropdown");
132 |
133 | Dropdown.AddSingleButton("KB", "KB", () =>
134 | {
135 | var Pos = ButtonAPI.GetEyeCamera().transform.position + ButtonAPI.GetEyeCamera().transform.forward * 1f;
136 |
137 | CustomInputPickup.Spawn(Pos, ButtonAPI.GetEyeCamera().transform.LookAtThisWithoutRef(Pos), s =>
138 | {
139 | MelonLogger.Warning($"Text Confirmed: {s}");
140 | });
141 | }, false, ButtonImage);
142 |
143 | Dropdown.AddLabel("Label", "Label", () => { MelonLogger.Msg("Label Clicked!"); });
144 |
145 | Page.AddLabel("Thanks For Looking. :)", null);
146 |
147 | // Constructor Is Needed For Raw Transforms For Now
148 | var UserGroup = new CollapsibleButtonGroup(TransformHelper.SelectedUser_Local, "Example User Options");
149 |
150 | UserGroup.AddSingleButton("Button", "Button", () =>
151 | {
152 | var SelectedPlayer = PlagueButtonAPI.Misc.Utils.GetCurrentlySelectedPlayer();
153 |
154 | MelonLogger.Msg("Button Clicked! - Selected Player: " + (SelectedPlayer != null ? SelectedPlayer.field_Private_APIUser_0.displayName : ""));
155 | });
156 | };
157 | }
158 | }
159 |
160 | #region Variables
161 |
162 | internal static bool DisablePortals = false;
163 | internal static Sprite ButtonImage = null;
164 |
165 | #endregion
166 | }
167 | }
--------------------------------------------------------------------------------
/PlagueButtonAPI/ExampleButtonAPIUsage/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("ExampleButtonAPIUsage")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ExampleButtonAPIUsage")]
13 | [assembly: AssemblyCopyright("Copyright © 2021")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("4090d6ad-c19f-4e2a-9f7b-17128113e139")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/PlagueButtonAPI/ExampleButtonAPIUsage/Utils.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using UnityEngine;
4 | using VRC;
5 | using VRC.UI.Elements.Menus;
6 | using PlagueButtonAPI.Misc;
7 |
8 | namespace ExampleButtonAPIUsage
9 | {
10 | internal class Utils
11 | {
12 | private static GameObject AvatarPicTaker;
13 | internal static Texture2D TakePictureOfPlayer(VRCPlayer player)
14 | {
15 | var avatar = player.transform.Find("ForwardDirection/Avatar").gameObject;
16 | var manager = player.prop_VRCAvatarManager_0;
17 |
18 | var OldLayer = player == VRCPlayer.field_Internal_Static_VRCPlayer_0
19 | ? (1 << LayerMask.NameToLayer("PlayerLocal"))
20 | : (1 << LayerMask.NameToLayer("Player"));
21 |
22 | var layer = new System.Random().Next(0, 9999);
23 |
24 | avatar.layer = layer;
25 |
26 | if (AvatarPicTaker == null)
27 | {
28 | AvatarPicTaker = new GameObject("AvatarPicTaker");
29 | }
30 |
31 | AvatarPicTaker.SetActive(false);
32 |
33 | var CamComp = AvatarPicTaker.GetOrAddComponent();
34 |
35 | CamComp.clearFlags = CameraClearFlags.SolidColor;
36 | CamComp.backgroundColor = new Color(0f, 0f, 0f, 0f);
37 |
38 | /* Enable camera */
39 | AvatarPicTaker.SetActive(true);
40 |
41 | /* Move camera infront of head */
42 | var descriptor = (manager.prop_VRCAvatarDescriptor_0 ?? manager.prop_VRC_AvatarDescriptor_1 ?? manager.prop_VRC_AvatarDescriptor_0);
43 | var head_height = descriptor.ViewPosition.y;
44 | var head = avatar.transform.position + new Vector3(0, head_height, 0);
45 | var target = head + avatar.transform.forward * 0.3f;
46 | var camera = CamComp;
47 |
48 | camera.useOcclusionCulling = false;
49 | camera.farClipPlane = 0.6f;
50 | camera.nearClipPlane = 0.05f;
51 | camera.transform.position = target;
52 | camera.transform.LookAt(head);
53 |
54 | camera.cullingMask = layer;
55 | camera.orthographic = true;
56 | camera.orthographicSize = head_height / 8;
57 |
58 | if (camera.targetTexture == null)
59 | {
60 | camera.targetTexture = new RenderTexture(256, 256, 0);
61 | }
62 |
63 | var currentRT = RenderTexture.active;
64 | RenderTexture.active = camera.targetTexture;
65 |
66 | camera.Render();
67 |
68 | var image = new Texture2D(camera.targetTexture.width, camera.targetTexture.height,
69 | TextureFormat.RGBA32, false, true)
70 | { name = $"{player.field_Private_ApiAvatar_0.id}" };
71 | image.ReadPixels(new Rect(0, 0, camera.targetTexture.width, camera.targetTexture.height), 0, 0);
72 | image.Apply();
73 | image.hideFlags = HideFlags.DontUnloadUnusedAsset;
74 |
75 | RenderTexture.active = currentRT;
76 |
77 | AvatarPicTaker.SetActive(false);
78 |
79 | avatar.layer = OldLayer;
80 |
81 | return image;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/PlagueButtonAPI/PlagueButtonAPI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.852
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlagueButtonAPI", "PlagueButtonAPI\PlagueButtonAPI.csproj", "{1067AC86-8417-4F30-A9D0-EE8027BFB134}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleButtonAPIUsage", "ExampleButtonAPIUsage\ExampleButtonAPIUsage.csproj", "{4090D6AD-C19F-4E2A-9F7B-17128113E139}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Normal|Any CPU = Normal|Any CPU
13 | VRChat Mods Folder|Any CPU = VRChat Mods Folder|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {1067AC86-8417-4F30-A9D0-EE8027BFB134}.Normal|Any CPU.ActiveCfg = Normal|Any CPU
17 | {1067AC86-8417-4F30-A9D0-EE8027BFB134}.Normal|Any CPU.Build.0 = Normal|Any CPU
18 | {1067AC86-8417-4F30-A9D0-EE8027BFB134}.VRChat Mods Folder|Any CPU.ActiveCfg = VRChat Mods Folder|Any CPU
19 | {1067AC86-8417-4F30-A9D0-EE8027BFB134}.VRChat Mods Folder|Any CPU.Build.0 = VRChat Mods Folder|Any CPU
20 | {4090D6AD-C19F-4E2A-9F7B-17128113E139}.Normal|Any CPU.ActiveCfg = Normal|Any CPU
21 | {4090D6AD-C19F-4E2A-9F7B-17128113E139}.Normal|Any CPU.Build.0 = Normal|Any CPU
22 | {4090D6AD-C19F-4E2A-9F7B-17128113E139}.VRChat Mods Folder|Any CPU.ActiveCfg = VRChat Mods Folder|Any CPU
23 | {4090D6AD-C19F-4E2A-9F7B-17128113E139}.VRChat Mods Folder|Any CPU.Build.0 = VRChat Mods Folder|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {56B333B1-7344-486F-8B4B-65B7696DD4DF}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/PlagueButtonAPI/PlagueButtonAPI/Controls/Base Classes/Button.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using UnityEngine;
7 | using UnityEngine.UI;
8 |
9 | namespace PlagueButtonAPI.Controls.Base_Classes
10 | {
11 | public class Button : ControlWithText
12 | {
13 | public Image subMenuIcon => transform?.Find("Badge_MMJump")?.GetComponentInChildren(true) ?? transform?.Find("Container/Icon_Arrow")?.GetComponentInChildren(true);
14 |
15 | public Image buttonImage => transform?.Find("Icon")?.GetComponentInChildren(true) ?? transform?.Find("Container/Icon")?.GetComponentInChildren(true);
16 |
17 | public UnityEngine.UI.Button button => gameObject?.GetComponentInChildren(true);
18 |
19 | public VRC.UI.Elements.Tooltips.UiTooltip tooltip => gameObject?.GetComponentsInChildren(true).FirstOrDefault(o => !string.IsNullOrEmpty(o.field_Public_String_0) || !string.IsNullOrEmpty(o.field_Public_String_1));
20 |
21 | public void SetAction(Action newAction)
22 | {
23 | button.onClick = new UnityEngine.UI.Button.ButtonClickedEvent();
24 | button.onClick.AddListener(newAction);
25 | }
26 |
27 | public void SetInteractable(bool val)
28 | {
29 | button.interactable = val;
30 | }
31 |
32 | public void SetIcon(Sprite newIcon, bool preserveColor = false)
33 | {
34 | if (newIcon == null)
35 | {
36 | buttonImage.gameObject.SetActive(false);
37 | return;
38 | }
39 | buttonImage.sprite = newIcon;
40 | buttonImage.overrideSprite = newIcon;
41 | buttonImage.gameObject.SetActive(true);
42 | if (preserveColor)
43 | {
44 | buttonImage.color = Color.white;
45 | }
46 | }
47 |
48 | public void SetIconColor(Color color)
49 | {
50 | buttonImage.color = color;
51 | }
52 |
53 | public void SetTooltip(string newTooltip)
54 | {
55 | if (tooltip == null)
56 | {
57 | return;
58 | }
59 |
60 | tooltip.field_Public_String_0 = newTooltip;
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/PlagueButtonAPI/PlagueButtonAPI/Controls/Base Classes/ControlWithText.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using UnityEngine;
7 | using UnityEngine.UI;
8 |
9 | namespace PlagueButtonAPI.Controls.Base_Classes
10 | {
11 | public class ControlWithText : GenericControl
12 | {
13 | public Image buttonBackground => transform?.Find("Background")?.GetComponentInChildren(true) ?? transform?.Find("Container/Background")?.GetComponentInChildren(true);
14 |
15 | public TMPro.TextMeshProUGUI text => gameObject?.GetComponentInChildren(true);
16 |
17 | [Obsolete]
18 | public TMPro.TextMeshProUGUI buttonText => text;
19 |
20 | public void SetText(string newText)
21 | {
22 | text.text = newText;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/PlagueButtonAPI/PlagueButtonAPI/Controls/Base Classes/GenericControl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using UnityEngine;
7 |
8 | namespace PlagueButtonAPI.Controls.Base_Classes
9 | {
10 | public class GenericControl
11 | {
12 | public GameObject gameObject;
13 |
14 | public bool IsNull => gameObject == null;
15 |
16 | public bool active => gameObject?.active ?? false;
17 |
18 | public bool activeSelf => gameObject?.activeSelf ?? false;
19 |
20 | public Transform transform => gameObject?.transform;
21 |
22 | public void SetActive(bool state)
23 | {
24 | gameObject?.SetActive(state);
25 | }
26 |
27 | public void Destroy()
28 | {
29 | UnityEngine.Object.Destroy(gameObject);
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/PlagueButtonAPI/PlagueButtonAPI/Controls/Base Classes/Toggle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using MelonLoader;
8 | using UnhollowerRuntimeLib.XrefScans;
9 | using UnityEngine;
10 | using UnityEngine.UI;
11 | using VRC.UI.Elements.Controls;
12 | using VRC.UI.Elements.Tooltips;
13 |
14 | namespace PlagueButtonAPI.Controls.Base_Classes
15 | {
16 | public class Toggle : ControlWithText
17 | {
18 | public UnityEngine.UI.Toggle toggle => gameObject?.GetComponentInChildren(true);
19 |
20 | [Obsolete]
21 | public UnityEngine.UI.Toggle buttontoggle => toggle;
22 |
23 | public UiToggleTooltip tooltip => gameObject?.GetComponentInChildren(true);
24 |
25 | public Image OnImage => transform?.Find("Icon_On")?.GetComponentInChildren(true);
26 | public Image OffImage => transform?.Find("Icon_Off")?.GetComponentInChildren(true);
27 |
28 | public bool? ToggleState => toggle?.isOn;
29 |
30 | internal bool NextState = false;
31 |
32 | public void SetAction(Action newAction)
33 | {
34 | toggle.onValueChanged = new UnityEngine.UI.Toggle.ToggleEvent();
35 | toggle.onValueChanged.AddListener((Action)delegate (bool val)
36 | {
37 | newAction?.Invoke(val);
38 | });
39 | }
40 |
41 | public void SetInteractable(bool val)
42 | {
43 | toggle.interactable = val;
44 | }
45 |
46 | internal bool AllowUserInvoke = true;
47 |
48 | public void SetToggleState(bool newState, bool invoke = false)
49 | {
50 | NextState = newState;
51 |
52 | if (gameObject.active)
53 | {
54 | AllowUserInvoke = false;
55 |
56 | toggle.isOn = newState;
57 |
58 | AllowUserInvoke = true;
59 |
60 | if (tooltip != null)
61 | {
62 | tooltip.field_Private_Boolean_1 = !newState;
63 | }
64 | }
65 |
66 | if (invoke)
67 | {
68 | toggle.onValueChanged.Invoke(newState);
69 | }
70 | }
71 |
72 | internal bool ToolTipOne = false;
73 | public void SetTooltip(string newOffTooltip, string newOnTooltip)
74 | {
75 | if (!ToolTipOne)
76 | {
77 | tooltip.field_Public_String_0 = newOnTooltip;
78 | tooltip.field_Public_String_1 = newOffTooltip;
79 | }
80 | else
81 | {
82 | tooltip.field_Public_String_0 = newOffTooltip;
83 | tooltip.field_Public_String_1 = newOnTooltip;
84 | }
85 | }
86 |
87 | public void SetOnIcon(Sprite newIcon)
88 | {
89 | if (newIcon == null)
90 | {
91 | OnImage.gameObject.SetActive(false);
92 | return;
93 | }
94 |
95 | OnImage.sprite = newIcon;
96 | OnImage.overrideSprite = newIcon;
97 | OnImage.gameObject.SetActive(true);
98 | }
99 |
100 | public void SetOffIcon(Sprite newIcon)
101 | {
102 | if (newIcon == null)
103 | {
104 | OffImage.gameObject.SetActive(false);
105 | return;
106 | }
107 |
108 | OffImage.sprite = newIcon;
109 | OffImage.overrideSprite = newIcon;
110 | OffImage.gameObject.SetActive(true);
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/PlagueButtonAPI/PlagueButtonAPI/Controls/Buttons/Label.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using MelonLoader;
4 | using PlagueButtonAPI.Controls.Grouping;
5 | using PlagueButtonAPI.Misc;
6 | using PlagueButtonAPI.Pages;
7 | using UnityEngine;
8 | using UnityEngine.UI;
9 | using VRC.UI.Core.Styles;
10 |
11 | namespace PlagueButtonAPI.Controls
12 | {
13 | public class Label
14 | {
15 | public readonly SimpleSingleButton LabelButton;
16 |
17 | public Label(Transform parent, string text, string tooltip, Action onClick = null)
18 | {
19 | LabelButton = new SimpleSingleButton(parent, text, tooltip, onClick);
20 |
21 | LabelButton.buttonBackground.color = new Color(0f, 0f, 0f, 0f);
22 |
23 | var Handler = LabelButton.gameObject.AddComponent();
24 |
25 | Handler.OnUpdateEachSecond += (a, b) =>
26 | {
27 | LabelButton.text.transform.localPosition = new Vector3(0f, -19f, 0f);
28 | };
29 |
30 | if (onClick == null)
31 | {
32 | LabelButton.gameObject.GetOrAddComponent