├── .drone.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── settings.gradle └── src └── main ├── java └── dev │ └── boze │ └── api │ ├── BozeInstance.java │ ├── Globals.java │ ├── addon │ ├── Addon.java │ ├── AddonCommand.java │ ├── AddonDispatcher.java │ └── AddonModule.java │ ├── client │ ├── ChatHelper.java │ ├── FriendManager.java │ ├── ModuleHelper.java │ ├── ProfileHelper.java │ └── cape │ │ ├── CapeLoadResult.java │ │ ├── CapeSource.java │ │ └── CapesManager.java │ ├── config │ ├── JsonTools.java │ └── Serializable.java │ ├── event │ ├── EventHudRender.java │ ├── EventInput.java │ ├── EventPlayerUpdate.java │ ├── EventTick.java │ └── EventWorldRender.java │ ├── exception │ ├── AddonInitializationException.java │ └── ModuleNotFoundException.java │ ├── input │ ├── Bind.java │ └── InputNameProvider.java │ ├── internal │ ├── Instances.java │ └── interfaces │ │ ├── ICapes.java │ │ ├── IChat.java │ │ ├── IFriends.java │ │ ├── IInput.java │ │ ├── IJson.java │ │ ├── IModules.java │ │ └── IProfiles.java │ └── option │ ├── BindOption.java │ ├── ModeOption.java │ ├── Option.java │ ├── SliderOption.java │ └── ToggleOption.java └── resources ├── api.mixins.json └── fabric.mod.json /.drone.yml: -------------------------------------------------------------------------------- 1 | kind: pipeline 2 | type: docker 3 | name: javadocs-deploy 4 | 5 | trigger: 6 | event: 7 | - push 8 | - custom 9 | 10 | steps: 11 | - name: javadoc 12 | image: gradle:jdk21 13 | commands: 14 | - gradle javadoc 15 | when: 16 | branch: 17 | - ${DRONE_REPO_BRANCH} 18 | 19 | - name: deploy 20 | image: drillster/drone-rsync 21 | settings: 22 | source: build/docs/javadoc/ 23 | target: 24 | from_secret: deploy_target 25 | hosts: 26 | from_secret: deploy_host 27 | user: drone 28 | key: 29 | from_secret: ssh_key 30 | port: 22 31 | delete: true 32 | recursive: true 33 | when: 34 | branch: 35 | - ${DRONE_REPO_BRANCH} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | # mpeltonen/sbt-idea plugin 11 | .idea_modules/ 12 | 13 | # JIRA plugin 14 | atlassian-ide-plugin.xml 15 | 16 | # Compiled class file 17 | *.class 18 | 19 | # Log file 20 | *.log 21 | 22 | # BlueJ files 23 | *.ctxt 24 | 25 | # Package Files # 26 | *.jar 27 | *.war 28 | *.nar 29 | *.ear 30 | *.zip 31 | *.tar.gz 32 | *.rar 33 | 34 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 35 | hs_err_pid* 36 | 37 | *~ 38 | 39 | # temporary files which can be created if a process still has a handle open of a deleted file 40 | .fuse_hidden* 41 | 42 | # KDE directory preferences 43 | .directory 44 | 45 | # Linux trash folder which might appear on any partition or disk 46 | .Trash-* 47 | 48 | # .nfs files are created when an open file is removed but is still being accessed 49 | .nfs* 50 | 51 | # General 52 | .DS_Store 53 | .AppleDouble 54 | .LSOverride 55 | 56 | # Icon must end with two \r 57 | Icon 58 | 59 | # Thumbnails 60 | ._* 61 | 62 | # Files that might appear in the root of a volume 63 | .DocumentRevisions-V100 64 | .fseventsd 65 | .Spotlight-V100 66 | .TemporaryItems 67 | .Trashes 68 | .VolumeIcon.icns 69 | .com.apple.timemachine.donotpresent 70 | 71 | # Directories potentially created on remote AFP share 72 | .AppleDB 73 | .AppleDesktop 74 | Network Trash Folder 75 | Temporary Items 76 | .apdisk 77 | 78 | # Windows thumbnail cache files 79 | Thumbs.db 80 | Thumbs.db:encryptable 81 | ehthumbs.db 82 | ehthumbs_vista.db 83 | 84 | # Dump file 85 | *.stackdump 86 | 87 | # Folder config file 88 | [Dd]esktop.ini 89 | 90 | # Recycle Bin used on file shares 91 | $RECYCLE.BIN/ 92 | 93 | # Windows Installer files 94 | *.cab 95 | *.msi 96 | *.msix 97 | *.msm 98 | *.msp 99 | 100 | # Windows shortcuts 101 | *.lnk 102 | 103 | .gradle 104 | build/ 105 | 106 | # Ignore Gradle GUI config 107 | gradle-app.setting 108 | 109 | # Cache of project 110 | .gradletasknamecache 111 | 112 | **/build/ 113 | 114 | # Common working directory 115 | run/ 116 | 117 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 118 | !gradle-wrapper.jar 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 2 | 3 | This program is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see 15 | 16 | 17 | 18 | GNU GENERAL PUBLIC LICENSE 19 | Version 3, 29 June 2007 20 | 21 | Copyright (C) 2007 Free Software Foundation, Inc. 22 | Everyone is permitted to copy and distribute verbatim copies 23 | of this license document, but changing it is not allowed. 24 | 25 | Preamble 26 | 27 | The GNU General Public License is a free, copyleft license for 28 | software and other kinds of works. 29 | 30 | The licenses for most software and other practical works are designed 31 | to take away your freedom to share and change the works. By contrast, 32 | the GNU General Public License is intended to guarantee your freedom to 33 | share and change all versions of a program--to make sure it remains free 34 | software for all its users. We, the Free Software Foundation, use the 35 | GNU General Public License for most of our software; it applies also to 36 | any other work released this way by its authors. You can apply it to 37 | your programs, too. 38 | 39 | When we speak of free software, we are referring to freedom, not 40 | price. Our General Public Licenses are designed to make sure that you 41 | have the freedom to distribute copies of free software (and charge for 42 | them if you wish), that you receive source code or can get it if you 43 | want it, that you can change the software or use pieces of it in new 44 | free programs, and that you know you can do these things. 45 | 46 | To protect your rights, we need to prevent others from denying you 47 | these rights or asking you to surrender the rights. Therefore, you have 48 | certain responsibilities if you distribute copies of the software, or if 49 | you modify it: responsibilities to respect the freedom of others. 50 | 51 | For example, if you distribute copies of such a program, whether 52 | gratis or for a fee, you must pass on to the recipients the same 53 | freedoms that you received. You must make sure that they, too, receive 54 | or can get the source code. And you must show them these terms so they 55 | know their rights. 56 | 57 | Developers that use the GNU GPL protect your rights with two steps: 58 | (1) assert copyright on the software, and (2) offer you this License 59 | giving you legal permission to copy, distribute and/or modify it. 60 | 61 | For the developers' and authors' protection, the GPL clearly explains 62 | that there is no warranty for this free software. For both users' and 63 | authors' sake, the GPL requires that modified versions be marked as 64 | changed, so that their problems will not be attributed erroneously to 65 | authors of previous versions. 66 | 67 | Some devices are designed to deny users access to install or run 68 | modified versions of the software inside them, although the manufacturer 69 | can do so. This is fundamentally incompatible with the aim of 70 | protecting users' freedom to change the software. The systematic 71 | pattern of such abuse occurs in the area of products for individuals to 72 | use, which is precisely where it is most unacceptable. Therefore, we 73 | have designed this version of the GPL to prohibit the practice for those 74 | products. If such problems arise substantially in other domains, we 75 | stand ready to extend this provision to those domains in future versions 76 | of the GPL, as needed to protect the freedom of users. 77 | 78 | Finally, every program is threatened constantly by software patents. 79 | States should not allow patents to restrict development and use of 80 | software on general-purpose computers, but in those that do, we wish to 81 | avoid the special danger that patents applied to a free program could 82 | make it effectively proprietary. To prevent this, the GPL assures that 83 | patents cannot be used to render the program non-free. 84 | 85 | The precise terms and conditions for copying, distribution and 86 | modification follow. 87 | 88 | TERMS AND CONDITIONS 89 | 90 | 0. Definitions. 91 | 92 | "This License" refers to version 3 of the GNU General Public License. 93 | 94 | "Copyright" also means copyright-like laws that apply to other kinds of 95 | works, such as semiconductor masks. 96 | 97 | "The Program" refers to any copyrightable work licensed under this 98 | License. Each licensee is addressed as "you". "Licensees" and 99 | "recipients" may be individuals or organizations. 100 | 101 | To "modify" a work means to copy from or adapt all or part of the work 102 | in a fashion requiring copyright permission, other than the making of an 103 | exact copy. The resulting work is called a "modified version" of the 104 | earlier work or a work "based on" the earlier work. 105 | 106 | A "covered work" means either the unmodified Program or a work based 107 | on the Program. 108 | 109 | To "propagate" a work means to do anything with it that, without 110 | permission, would make you directly or secondarily liable for 111 | infringement under applicable copyright law, except executing it on a 112 | computer or modifying a private copy. Propagation includes copying, 113 | distribution (with or without modification), making available to the 114 | public, and in some countries other activities as well. 115 | 116 | To "convey" a work means any kind of propagation that enables other 117 | parties to make or receive copies. Mere interaction with a user through 118 | a computer network, with no transfer of a copy, is not conveying. 119 | 120 | An interactive user interface displays "Appropriate Legal Notices" 121 | to the extent that it includes a convenient and prominently visible 122 | feature that (1) displays an appropriate copyright notice, and (2) 123 | tells the user that there is no warranty for the work (except to the 124 | extent that warranties are provided), that licensees may convey the 125 | work under this License, and how to view a copy of this License. If 126 | the interface presents a list of user commands or options, such as a 127 | menu, a prominent item in the list meets this criterion. 128 | 129 | 1. Source Code. 130 | 131 | The "source code" for a work means the preferred form of the work 132 | for making modifications to it. "Object code" means any non-source 133 | form of a work. 134 | 135 | A "Standard Interface" means an interface that either is an official 136 | standard defined by a recognized standards body, or, in the case of 137 | interfaces specified for a particular programming language, one that 138 | is widely used among developers working in that language. 139 | 140 | The "System Libraries" of an executable work include anything, other 141 | than the work as a whole, that (a) is included in the normal form of 142 | packaging a Major Component, but which is not part of that Major 143 | Component, and (b) serves only to enable use of the work with that 144 | Major Component, or to implement a Standard Interface for which an 145 | implementation is available to the public in source code form. A 146 | "Major Component", in this context, means a major essential component 147 | (kernel, window system, and so on) of the specific operating system 148 | (if any) on which the executable work runs, or a compiler used to 149 | produce the work, or an object code interpreter used to run it. 150 | 151 | The "Corresponding Source" for a work in object code form means all 152 | the source code needed to generate, install, and (for an executable 153 | work) run the object code and to modify the work, including scripts to 154 | control those activities. However, it does not include the work's 155 | System Libraries, or general-purpose tools or generally available free 156 | programs which are used unmodified in performing those activities but 157 | which are not part of the work. For example, Corresponding Source 158 | includes interface definition files associated with source files for 159 | the work, and the source code for shared libraries and dynamically 160 | linked subprograms that the work is specifically designed to require, 161 | such as by intimate data communication or control flow between those 162 | subprograms and other parts of the work. 163 | 164 | The Corresponding Source need not include anything that users 165 | can regenerate automatically from other parts of the Corresponding 166 | Source. 167 | 168 | The Corresponding Source for a work in source code form is that 169 | same work. 170 | 171 | 2. Basic Permissions. 172 | 173 | All rights granted under this License are granted for the term of 174 | copyright on the Program, and are irrevocable provided the stated 175 | conditions are met. This License explicitly affirms your unlimited 176 | permission to run the unmodified Program. The output from running a 177 | covered work is covered by this License only if the output, given its 178 | content, constitutes a covered work. This License acknowledges your 179 | rights of fair use or other equivalent, as provided by copyright law. 180 | 181 | You may make, run and propagate covered works that you do not 182 | convey, without conditions so long as your license otherwise remains 183 | in force. You may convey covered works to others for the sole purpose 184 | of having them make modifications exclusively for you, or provide you 185 | with facilities for running those works, provided that you comply with 186 | the terms of this License in conveying all material for which you do 187 | not control copyright. Those thus making or running the covered works 188 | for you must do so exclusively on your behalf, under your direction 189 | and control, on terms that prohibit them from making any copies of 190 | your copyrighted material outside their relationship with you. 191 | 192 | Conveying under any other circumstances is permitted solely under 193 | the conditions stated below. Sublicensing is not allowed; section 10 194 | makes it unnecessary. 195 | 196 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 197 | 198 | No covered work shall be deemed part of an effective technological 199 | measure under any applicable law fulfilling obligations under article 200 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 201 | similar laws prohibiting or restricting circumvention of such 202 | measures. 203 | 204 | When you convey a covered work, you waive any legal power to forbid 205 | circumvention of technological measures to the extent such circumvention 206 | is effected by exercising rights under this License with respect to 207 | the covered work, and you disclaim any intention to limit operation or 208 | modification of the work as a means of enforcing, against the work's 209 | users, your or third parties' legal rights to forbid circumvention of 210 | technological measures. 211 | 212 | 4. Conveying Verbatim Copies. 213 | 214 | You may convey verbatim copies of the Program's source code as you 215 | receive it, in any medium, provided that you conspicuously and 216 | appropriately publish on each copy an appropriate copyright notice; 217 | keep intact all notices stating that this License and any 218 | non-permissive terms added in accord with section 7 apply to the code; 219 | keep intact all notices of the absence of any warranty; and give all 220 | recipients a copy of this License along with the Program. 221 | 222 | You may charge any price or no price for each copy that you convey, 223 | and you may offer support or warranty protection for a fee. 224 | 225 | 5. Conveying Modified Source Versions. 226 | 227 | You may convey a work based on the Program, or the modifications to 228 | produce it from the Program, in the form of source code under the 229 | terms of section 4, provided that you also meet all of these conditions: 230 | 231 | a) The work must carry prominent notices stating that you modified 232 | it, and giving a relevant date. 233 | 234 | b) The work must carry prominent notices stating that it is 235 | released under this License and any conditions added under section 236 | 7. This requirement modifies the requirement in section 4 to 237 | "keep intact all notices". 238 | 239 | c) You must license the entire work, as a whole, under this 240 | License to anyone who comes into possession of a copy. This 241 | License will therefore apply, along with any applicable section 7 242 | additional terms, to the whole of the work, and all its parts, 243 | regardless of how they are packaged. This License gives no 244 | permission to license the work in any other way, but it does not 245 | invalidate such permission if you have separately received it. 246 | 247 | d) If the work has interactive user interfaces, each must display 248 | Appropriate Legal Notices; however, if the Program has interactive 249 | interfaces that do not display Appropriate Legal Notices, your 250 | work need not make them do so. 251 | 252 | A compilation of a covered work with other separate and independent 253 | works, which are not by their nature extensions of the covered work, 254 | and which are not combined with it such as to form a larger program, 255 | in or on a volume of a storage or distribution medium, is called an 256 | "aggregate" if the compilation and its resulting copyright are not 257 | used to limit the access or legal rights of the compilation's users 258 | beyond what the individual works permit. Inclusion of a covered work 259 | in an aggregate does not cause this License to apply to the other 260 | parts of the aggregate. 261 | 262 | 6. Conveying Non-Source Forms. 263 | 264 | You may convey a covered work in object code form under the terms 265 | of sections 4 and 5, provided that you also convey the 266 | machine-readable Corresponding Source under the terms of this License, 267 | in one of these ways: 268 | 269 | a) Convey the object code in, or embodied in, a physical product 270 | (including a physical distribution medium), accompanied by the 271 | Corresponding Source fixed on a durable physical medium 272 | customarily used for software interchange. 273 | 274 | b) Convey the object code in, or embodied in, a physical product 275 | (including a physical distribution medium), accompanied by a 276 | written offer, valid for at least three years and valid for as 277 | long as you offer spare parts or customer support for that product 278 | model, to give anyone who possesses the object code either (1) a 279 | copy of the Corresponding Source for all the software in the 280 | product that is covered by this License, on a durable physical 281 | medium customarily used for software interchange, for a price no 282 | more than your reasonable cost of physically performing this 283 | conveying of source, or (2) access to copy the 284 | Corresponding Source from a network server at no charge. 285 | 286 | c) Convey individual copies of the object code with a copy of the 287 | written offer to provide the Corresponding Source. This 288 | alternative is allowed only occasionally and noncommercially, and 289 | only if you received the object code with such an offer, in accord 290 | with subsection 6b. 291 | 292 | d) Convey the object code by offering access from a designated 293 | place (gratis or for a charge), and offer equivalent access to the 294 | Corresponding Source in the same way through the same place at no 295 | further charge. You need not require recipients to copy the 296 | Corresponding Source along with the object code. If the place to 297 | copy the object code is a network server, the Corresponding Source 298 | may be on a different server (operated by you or a third party) 299 | that supports equivalent copying facilities, provided you maintain 300 | clear directions next to the object code saying where to find the 301 | Corresponding Source. Regardless of what server hosts the 302 | Corresponding Source, you remain obligated to ensure that it is 303 | available for as long as needed to satisfy these requirements. 304 | 305 | e) Convey the object code using peer-to-peer transmission, provided 306 | you inform other peers where the object code and Corresponding 307 | Source of the work are being offered to the general public at no 308 | charge under subsection 6d. 309 | 310 | A separable portion of the object code, whose source code is excluded 311 | from the Corresponding Source as a System Library, need not be 312 | included in conveying the object code work. 313 | 314 | A "User Product" is either (1) a "consumer product", which means any 315 | tangible personal property which is normally used for personal, family, 316 | or household purposes, or (2) anything designed or sold for incorporation 317 | into a dwelling. In determining whether a product is a consumer product, 318 | doubtful cases shall be resolved in favor of coverage. For a particular 319 | product received by a particular user, "normally used" refers to a 320 | typical or common use of that class of product, regardless of the status 321 | of the particular user or of the way in which the particular user 322 | actually uses, or expects or is expected to use, the product. A product 323 | is a consumer product regardless of whether the product has substantial 324 | commercial, industrial or non-consumer uses, unless such uses represent 325 | the only significant mode of use of the product. 326 | 327 | "Installation Information" for a User Product means any methods, 328 | procedures, authorization keys, or other information required to install 329 | and execute modified versions of a covered work in that User Product from 330 | a modified version of its Corresponding Source. The information must 331 | suffice to ensure that the continued functioning of the modified object 332 | code is in no case prevented or interfered with solely because 333 | modification has been made. 334 | 335 | If you convey an object code work under this section in, or with, or 336 | specifically for use in, a User Product, and the conveying occurs as 337 | part of a transaction in which the right of possession and use of the 338 | User Product is transferred to the recipient in perpetuity or for a 339 | fixed term (regardless of how the transaction is characterized), the 340 | Corresponding Source conveyed under this section must be accompanied 341 | by the Installation Information. But this requirement does not apply 342 | if neither you nor any third party retains the ability to install 343 | modified object code on the User Product (for example, the work has 344 | been installed in ROM). 345 | 346 | The requirement to provide Installation Information does not include a 347 | requirement to continue to provide support service, warranty, or updates 348 | for a work that has been modified or installed by the recipient, or for 349 | the User Product in which it has been modified or installed. Access to a 350 | network may be denied when the modification itself materially and 351 | adversely affects the operation of the network or violates the rules and 352 | protocols for communication across the network. 353 | 354 | Corresponding Source conveyed, and Installation Information provided, 355 | in accord with this section must be in a format that is publicly 356 | documented (and with an implementation available to the public in 357 | source code form), and must require no special password or key for 358 | unpacking, reading or copying. 359 | 360 | 7. Additional Terms. 361 | 362 | "Additional permissions" are terms that supplement the terms of this 363 | License by making exceptions from one or more of its conditions. 364 | Additional permissions that are applicable to the entire Program shall 365 | be treated as though they were included in this License, to the extent 366 | that they are valid under applicable law. If additional permissions 367 | apply only to part of the Program, that part may be used separately 368 | under those permissions, but the entire Program remains governed by 369 | this License without regard to the additional permissions. 370 | 371 | When you convey a copy of a covered work, you may at your option 372 | remove any additional permissions from that copy, or from any part of 373 | it. (Additional permissions may be written to require their own 374 | removal in certain cases when you modify the work.) You may place 375 | additional permissions on material, added by you to a covered work, 376 | for which you have or can give appropriate copyright permission. 377 | 378 | Notwithstanding any other provision of this License, for material you 379 | add to a covered work, you may (if authorized by the copyright holders of 380 | that material) supplement the terms of this License with terms: 381 | 382 | a) Disclaiming warranty or limiting liability differently from the 383 | terms of sections 15 and 16 of this License; or 384 | 385 | b) Requiring preservation of specified reasonable legal notices or 386 | author attributions in that material or in the Appropriate Legal 387 | Notices displayed by works containing it; or 388 | 389 | c) Prohibiting misrepresentation of the origin of that material, or 390 | requiring that modified versions of such material be marked in 391 | reasonable ways as different from the original version; or 392 | 393 | d) Limiting the use for publicity purposes of names of licensors or 394 | authors of the material; or 395 | 396 | e) Declining to grant rights under trademark law for use of some 397 | trade names, trademarks, or service marks; or 398 | 399 | f) Requiring indemnification of licensors and authors of that 400 | material by anyone who conveys the material (or modified versions of 401 | it) with contractual assumptions of liability to the recipient, for 402 | any liability that these contractual assumptions directly impose on 403 | those licensors and authors. 404 | 405 | All other non-permissive additional terms are considered "further 406 | restrictions" within the meaning of section 10. If the Program as you 407 | received it, or any part of it, contains a notice stating that it is 408 | governed by this License along with a term that is a further 409 | restriction, you may remove that term. If a license document contains 410 | a further restriction but permits relicensing or conveying under this 411 | License, you may add to a covered work material governed by the terms 412 | of that license document, provided that the further restriction does 413 | not survive such relicensing or conveying. 414 | 415 | If you add terms to a covered work in accord with this section, you 416 | must place, in the relevant source files, a statement of the 417 | additional terms that apply to those files, or a notice indicating 418 | where to find the applicable terms. 419 | 420 | Additional terms, permissive or non-permissive, may be stated in the 421 | form of a separately written license, or stated as exceptions; 422 | the above requirements apply either way. 423 | 424 | 8. Termination. 425 | 426 | You may not propagate or modify a covered work except as expressly 427 | provided under this License. Any attempt otherwise to propagate or 428 | modify it is void, and will automatically terminate your rights under 429 | this License (including any patent licenses granted under the third 430 | paragraph of section 11). 431 | 432 | However, if you cease all violation of this License, then your 433 | license from a particular copyright holder is reinstated (a) 434 | provisionally, unless and until the copyright holder explicitly and 435 | finally terminates your license, and (b) permanently, if the copyright 436 | holder fails to notify you of the violation by some reasonable means 437 | prior to 60 days after the cessation. 438 | 439 | Moreover, your license from a particular copyright holder is 440 | reinstated permanently if the copyright holder notifies you of the 441 | violation by some reasonable means, this is the first time you have 442 | received notice of violation of this License (for any work) from that 443 | copyright holder, and you cure the violation prior to 30 days after 444 | your receipt of the notice. 445 | 446 | Termination of your rights under this section does not terminate the 447 | licenses of parties who have received copies or rights from you under 448 | this License. If your rights have been terminated and not permanently 449 | reinstated, you do not qualify to receive new licenses for the same 450 | material under section 10. 451 | 452 | 9. Acceptance Not Required for Having Copies. 453 | 454 | You are not required to accept this License in order to receive or 455 | run a copy of the Program. Ancillary propagation of a covered work 456 | occurring solely as a consequence of using peer-to-peer transmission 457 | to receive a copy likewise does not require acceptance. However, 458 | nothing other than this License grants you permission to propagate or 459 | modify any covered work. These actions infringe copyright if you do 460 | not accept this License. Therefore, by modifying or propagating a 461 | covered work, you indicate your acceptance of this License to do so. 462 | 463 | 10. Automatic Licensing of Downstream Recipients. 464 | 465 | Each time you convey a covered work, the recipient automatically 466 | receives a license from the original licensors, to run, modify and 467 | propagate that work, subject to this License. You are not responsible 468 | for enforcing compliance by third parties with this License. 469 | 470 | An "entity transaction" is a transaction transferring control of an 471 | organization, or substantially all assets of one, or subdividing an 472 | organization, or merging organizations. If propagation of a covered 473 | work results from an entity transaction, each party to that 474 | transaction who receives a copy of the work also receives whatever 475 | licenses to the work the party's predecessor in interest had or could 476 | give under the previous paragraph, plus a right to possession of the 477 | Corresponding Source of the work from the predecessor in interest, if 478 | the predecessor has it or can get it with reasonable efforts. 479 | 480 | You may not impose any further restrictions on the exercise of the 481 | rights granted or affirmed under this License. For example, you may 482 | not impose a license fee, royalty, or other charge for exercise of 483 | rights granted under this License, and you may not initiate litigation 484 | (including a cross-claim or counterclaim in a lawsuit) alleging that 485 | any patent claim is infringed by making, using, selling, offering for 486 | sale, or importing the Program or any portion of it. 487 | 488 | 11. Patents. 489 | 490 | A "contributor" is a copyright holder who authorizes use under this 491 | License of the Program or a work on which the Program is based. The 492 | work thus licensed is called the contributor's "contributor version". 493 | 494 | A contributor's "essential patent claims" are all patent claims 495 | owned or controlled by the contributor, whether already acquired or 496 | hereafter acquired, that would be infringed by some manner, permitted 497 | by this License, of making, using, or selling its contributor version, 498 | but do not include claims that would be infringed only as a 499 | consequence of further modification of the contributor version. For 500 | purposes of this definition, "control" includes the right to grant 501 | patent sublicenses in a manner consistent with the requirements of 502 | this License. 503 | 504 | Each contributor grants you a non-exclusive, worldwide, royalty-free 505 | patent license under the contributor's essential patent claims, to 506 | make, use, sell, offer for sale, import and otherwise run, modify and 507 | propagate the contents of its contributor version. 508 | 509 | In the following three paragraphs, a "patent license" is any express 510 | agreement or commitment, however denominated, not to enforce a patent 511 | (such as an express permission to practice a patent or covenant not to 512 | sue for patent infringement). To "grant" such a patent license to a 513 | party means to make such an agreement or commitment not to enforce a 514 | patent against the party. 515 | 516 | If you convey a covered work, knowingly relying on a patent license, 517 | and the Corresponding Source of the work is not available for anyone 518 | to copy, free of charge and under the terms of this License, through a 519 | publicly available network server or other readily accessible means, 520 | then you must either (1) cause the Corresponding Source to be so 521 | available, or (2) arrange to deprive yourself of the benefit of the 522 | patent license for this particular work, or (3) arrange, in a manner 523 | consistent with the requirements of this License, to extend the patent 524 | license to downstream recipients. "Knowingly relying" means you have 525 | actual knowledge that, but for the patent license, your conveying the 526 | covered work in a country, or your recipient's use of the covered work 527 | in a country, would infringe one or more identifiable patents in that 528 | country that you have reason to believe are valid. 529 | 530 | If, pursuant to or in connection with a single transaction or 531 | arrangement, you convey, or propagate by procuring conveyance of, a 532 | covered work, and grant a patent license to some of the parties 533 | receiving the covered work authorizing them to use, propagate, modify 534 | or convey a specific copy of the covered work, then the patent license 535 | you grant is automatically extended to all recipients of the covered 536 | work and works based on it. 537 | 538 | A patent license is "discriminatory" if it does not include within 539 | the scope of its coverage, prohibits the exercise of, or is 540 | conditioned on the non-exercise of one or more of the rights that are 541 | specifically granted under this License. You may not convey a covered 542 | work if you are a party to an arrangement with a third party that is 543 | in the business of distributing software, under which you make payment 544 | to the third party based on the extent of your activity of conveying 545 | the work, and under which the third party grants, to any of the 546 | parties who would receive the covered work from you, a discriminatory 547 | patent license (a) in connection with copies of the covered work 548 | conveyed by you (or copies made from those copies), or (b) primarily 549 | for and in connection with specific products or compilations that 550 | contain the covered work, unless you entered into that arrangement, 551 | or that patent license was granted, prior to 28 March 2007. 552 | 553 | Nothing in this License shall be construed as excluding or limiting 554 | any implied license or other defenses to infringement that may 555 | otherwise be available to you under applicable patent law. 556 | 557 | 12. No Surrender of Others' Freedom. 558 | 559 | If conditions are imposed on you (whether by court order, agreement or 560 | otherwise) that contradict the conditions of this License, they do not 561 | excuse you from the conditions of this License. If you cannot convey a 562 | covered work so as to satisfy simultaneously your obligations under this 563 | License and any other pertinent obligations, then as a consequence you may 564 | not convey it at all. For example, if you agree to terms that obligate you 565 | to collect a royalty for further conveying from those to whom you convey 566 | the Program, the only way you could satisfy both those terms and this 567 | License would be to refrain entirely from conveying the Program. 568 | 569 | 13. Use with the GNU Affero General Public License. 570 | 571 | Notwithstanding any other provision of this License, you have 572 | permission to link or combine any covered work with a work licensed 573 | under version 3 of the GNU Affero General Public License into a single 574 | combined work, and to convey the resulting work. The terms of this 575 | License will continue to apply to the part which is the covered work, 576 | but the special requirements of the GNU Affero General Public License, 577 | section 13, concerning interaction through a network will apply to the 578 | combination as such. 579 | 580 | 14. Revised Versions of this License. 581 | 582 | The Free Software Foundation may publish revised and/or new versions of 583 | the GNU General Public License from time to time. Such new versions will 584 | be similar in spirit to the present version, but may differ in detail to 585 | address new problems or concerns. 586 | 587 | Each version is given a distinguishing version number. If the 588 | Program specifies that a certain numbered version of the GNU General 589 | Public License "or any later version" applies to it, you have the 590 | option of following the terms and conditions either of that numbered 591 | version or of any later version published by the Free Software 592 | Foundation. If the Program does not specify a version number of the 593 | GNU General Public License, you may choose any version ever published 594 | by the Free Software Foundation. 595 | 596 | If the Program specifies that a proxy can decide which future 597 | versions of the GNU General Public License can be used, that proxy's 598 | public statement of acceptance of a version permanently authorizes you 599 | to choose that version for the Program. 600 | 601 | Later license versions may give you additional or different 602 | permissions. However, no additional obligations are imposed on any 603 | author or copyright holder as a result of your choosing to follow a 604 | later version. 605 | 606 | 15. Disclaimer of Warranty. 607 | 608 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 609 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 610 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 611 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 612 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 613 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 614 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 615 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 616 | 617 | 16. Limitation of Liability. 618 | 619 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 620 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 621 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 622 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 623 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 624 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 625 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 626 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 627 | SUCH DAMAGES. 628 | 629 | 17. Interpretation of Sections 15 and 16. 630 | 631 | If the disclaimer of warranty and limitation of liability provided 632 | above cannot be given local legal effect according to their terms, 633 | reviewing courts shall apply local law that most closely approximates 634 | an absolute waiver of all civil liability in connection with the 635 | Program, unless a warranty or assumption of liability accompanies a 636 | copy of the Program in return for a fee. 637 | 638 | END OF TERMS AND CONDITIONS 639 | 640 | How to Apply These Terms to Your New Programs 641 | 642 | If you develop a new program, and you want it to be of the greatest 643 | possible use to the public, the best way to achieve this is to make it 644 | free software which everyone can redistribute and change under these terms. 645 | 646 | To do so, attach the following notices to the program. It is safest 647 | to attach them to the start of each source file to most effectively 648 | state the exclusion of warranty; and each file should have at least 649 | the "copyright" line and a pointer to where the full notice is found. 650 | 651 | {one line to give the program's name and a brief idea of what it does.} 652 | Copyright (C) {year} {name of author} 653 | 654 | This program is free software: you can redistribute it and/or modify 655 | it under the terms of the GNU General Public License as published by 656 | the Free Software Foundation, either version 3 of the License, or 657 | (at your option) any later version. 658 | 659 | This program is distributed in the hope that it will be useful, 660 | but WITHOUT ANY WARRANTY; without even the implied warranty of 661 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 662 | GNU General Public License for more details. 663 | 664 | You should have received a copy of the GNU General Public License 665 | along with this program. If not, see . 666 | 667 | Also add information on how to contact you by electronic and paper mail. 668 | 669 | If the program does terminal interaction, make it output a short 670 | notice like this when it starts in an interactive mode: 671 | 672 | {project} Copyright (C) {year} {fullname} 673 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 674 | This is free software, and you are welcome to redistribute it 675 | under certain conditions; type `show c' for details. 676 | 677 | The hypothetical commands `show w' and `show c' should show the appropriate 678 | parts of the General Public License. Of course, your program's commands 679 | might be different; for a GUI interface, you would use an "about box". 680 | 681 | You should also get your employer (if you work as a programmer) or school, 682 | if any, to sign a "copyright disclaimer" for the program, if necessary. 683 | For more information on this, and how to apply and follow the GNU GPL, see 684 | . 685 | 686 | The GNU General Public License does not permit incorporating your program 687 | into proprietary programs. If your program is a subroutine library, you 688 | may consider it more useful to permit linking proprietary applications with 689 | the library. If this is what you want to do, use the GNU Lesser General 690 | Public License instead of this License. But first, please read 691 | . 692 | 693 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Boze Addon API 2 | Boze API is an addon api for developers looking to create custom addons for the [Boze Utility Mod](https://boze.dev/), a versatile Minecraft anarchy utility mod. This API lets you to seamlessly integrate your own features (modules, commands, etc.) into the Boze Utility Mod. 3 | 4 | ## Compatibility 5 | Boze API supports the following Minecraft version: 1.21.4 6 | 7 | Older versions are no longer updated, see [tags](https://github.com/boze-dev/addon-api/tags) for the archived branches. 8 | 9 | ## Documentation 10 | All the information you need to get started with Boze API can be found in our comprehensive Javadocs. Visit [docs.boze.dev](https://docs.boze.dev/) to access the API documentation. The Javadocs provide detailed information about the API's classes, methods, and usage, making it easier for you to develop custom addons and utilities. 11 | 12 | ## Example Addon 13 | If you're new to Boze API and need a hands-on example to kickstart your development, check out our [example addon](https://github.com/boze-dev/example-addon). This repository serves as a practical reference, showcasing a boilerplate implementation of the API, demonstrating how to get started with creating addons for the Boze Utility Mod. Feel free to explore, modify, and learn from the example addon's source code. 14 | 15 | ## Getting Started 16 | To begin using the Boze API, follow these steps: 17 | 18 | 1. **Download Boze Utility Mod**: First, make sure you have the Boze Utility Mod installed in your Minecraft client. You can download it from the [boze.dev dashboard](https://boze.dev/dashboard). 19 | 20 | 2. **Setup your development environment**: Use the [example addon](https://github.com/boze-dev/example-addon) as a template, to get started, open it in IntellJ or the editor of your choice. 21 | 22 | 3. **Make your first build and test it ingame**: Run the gradle build task, and put the jar into your Minecraft mods folder. Launch Boze (make sure it's the right Minecraft version) and see if your addon gets loaded. 23 | 24 | ## Issues and Support 25 | If you encounter any issues, have questions, or need assistance, please visit our [discord server](https://discord.gg/unyhSbS5G6 26 | ) to report issues and seek support. Our active community and development team are here to help. 27 | 28 | We look forward to seeing the amazing addons you create with it! 29 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'fabric-loom' version '1.8-SNAPSHOT' 3 | id 'maven-publish' 4 | } 5 | 6 | version = project.mod_version 7 | group = project.maven_group 8 | 9 | repositories { 10 | // Add repositories to retrieve artifacts from in here. 11 | // You should only use this when depending on other mods because 12 | // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. 13 | // See https://docs.gradle.org/current/userguide/declaring_repositories.html 14 | // for more information about repositories. 15 | maven { 16 | name = "boze-maven" 17 | url = "https://maven.boze.dev/releases" 18 | } 19 | } 20 | 21 | dependencies { 22 | // To change the versions see the gradle.properties file 23 | minecraft "com.mojang:minecraft:${project.minecraft_version}" 24 | mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" 25 | modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" 26 | 27 | // Fabric API. This is technically optional, but you probably want it anyway. 28 | modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" 29 | 30 | // meteordevelopemt's Orbit. This is the event system used by the mod. 31 | implementation "meteordevelopment:orbit:${project.orbit_version}" 32 | } 33 | 34 | processResources { 35 | inputs.property "version", project.version 36 | filteringCharset "UTF-8" 37 | 38 | filesMatching("fabric.mod.json") { 39 | expand "version": project.version 40 | } 41 | } 42 | 43 | def targetJavaVersion = 21 44 | tasks.withType(JavaCompile).configureEach { 45 | // ensure that the encoding is set to UTF-8, no matter what the system default is 46 | // this fixes some edge cases with special characters not displaying correctly 47 | // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html 48 | // If Javadoc is generated, this must be specified in that task too. 49 | it.options.encoding = "UTF-8" 50 | if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { 51 | it.options.release = targetJavaVersion 52 | } 53 | } 54 | 55 | 56 | tasks.withType(Javadoc).configureEach { 57 | title = "addon-api $version" 58 | it.options.encoding = "UTF-8" 59 | } 60 | 61 | java { 62 | def javaVersion = JavaVersion.toVersion(targetJavaVersion) 63 | if (JavaVersion.current() < javaVersion) { 64 | toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) 65 | } 66 | archivesBaseName = project.archives_base_name 67 | // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task 68 | // if it is present. 69 | // If you remove this line, sources will not be generated. 70 | withSourcesJar() 71 | } 72 | 73 | jar { 74 | from("LICENSE") { 75 | rename { "${it}_${project.archivesBaseName}" } 76 | } 77 | } 78 | 79 | // configure the maven publication 80 | publishing { 81 | publications { 82 | mavenJava(MavenPublication) { 83 | from components.java 84 | } 85 | } 86 | 87 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. 88 | repositories { 89 | // Add repositories to publish to here. 90 | // Notice: This block does NOT have the same function as the block in the top level. 91 | // The repositories here will be used for publishing your artifact, not for 92 | // retrieving dependencies. 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Done to increase the memory available to gradle. 2 | org.gradle.jvmargs=-Xmx1G 3 | # Fabric Properties 4 | # check these on https://modmuss50.me/fabric.html 5 | minecraft_version=1.21.4 6 | yarn_mappings=1.21.4+build.8 7 | loader_version=0.16.10 8 | # Mod Properties 9 | mod_version=3.0.1 10 | maven_group=dev.boze 11 | archives_base_name=api 12 | # Dependencies 13 | # check this on https://modmuss50.me/fabric.html 14 | fabric_version=0.119.2+1.21.4 15 | orbit_version=0.2.5 16 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { 4 | name = 'Fabric' 5 | url = 'https://maven.fabricmc.net/' 6 | } 7 | gradlePluginPortal() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/BozeInstance.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api; 2 | 3 | import dev.boze.api.addon.Addon; 4 | import dev.boze.api.addon.AddonDispatcher; 5 | import dev.boze.api.addon.AddonModule; 6 | import dev.boze.api.exception.AddonInitializationException; 7 | import meteordevelopment.orbit.EventBus; 8 | import meteordevelopment.orbit.IEventBus; 9 | import net.minecraft.client.MinecraftClient; 10 | 11 | import java.lang.invoke.MethodHandles; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.stream.Collectors; 15 | 16 | /** 17 | * Boze (API) Instance 18 | *

19 | * This class keeps track of all the addons registered 20 | * It also provides addons a way to register packages and subscribe to events 21 | */ 22 | public final class BozeInstance { 23 | 24 | /** 25 | * The instance of Boze API 26 | */ 27 | public static final BozeInstance INSTANCE = new BozeInstance(); 28 | 29 | private final ArrayList addons = new ArrayList<>(); 30 | 31 | private IEventBus EVENT_BUS = new EventBus(); 32 | 33 | private BozeInstance() { 34 | 35 | } 36 | 37 | /** 38 | * Register an addon 39 | * 40 | * @param addon The addon to register 41 | * @throws AddonInitializationException If the addon fails to initialize 42 | */ 43 | public void registerAddon(Addon addon) throws AddonInitializationException { 44 | assert MinecraftClient.getInstance().isOnThread(); 45 | 46 | try { 47 | if (addon.initialize()) { 48 | addons.add(addon); 49 | } else { 50 | throw new AddonInitializationException("Error initialising addon"); 51 | } 52 | } catch (Exception e) { 53 | throw new AddonInitializationException("Error initializing addon", e); 54 | } 55 | } 56 | 57 | /** 58 | * Get all registered addons 59 | * 60 | * @return list of all registered addon metadata and addons 61 | */ 62 | public ArrayList getAddons() { 63 | return addons; 64 | } 65 | 66 | /** 67 | * Gets a list of all modules registered by addons 68 | * 69 | * @return A list of all modules registered by addons 70 | */ 71 | public List getModules() { 72 | return addons.stream() 73 | .map(addon -> addon.modules) 74 | .flatMap(List::stream) 75 | .collect(Collectors.toList()); 76 | } 77 | 78 | /** 79 | * Registers a (java) package into the event bus 80 | * 81 | * @param pkg The package to register 82 | */ 83 | public void registerPackage(String pkg) { 84 | EVENT_BUS.registerLambdaFactory(pkg, (lookupInMethod, klass) -> (MethodHandles.Lookup) lookupInMethod.invoke(null, klass, MethodHandles.lookup())); 85 | } 86 | 87 | /** 88 | * Subscribes an object to listen to events 89 | * 90 | * @param listener The object to subscribe 91 | */ 92 | public void subscribe(Object listener) { 93 | EVENT_BUS.subscribe(listener); 94 | } 95 | 96 | /** 97 | * Subscribes a class to listen to events 98 | * 99 | * @param listener The class to subscribe 100 | */ 101 | public void subscribe(Class listener) { 102 | EVENT_BUS.subscribe(listener); 103 | } 104 | 105 | /** 106 | * Unsubscribes an object to listen to events 107 | * 108 | * @param listener The object to unsubscribe 109 | */ 110 | public void unsubscribe(Object listener) { 111 | EVENT_BUS.unsubscribe(listener); 112 | } 113 | 114 | /** 115 | * Unsubscribes a class to listen to events 116 | * 117 | * @param listener The class to unsubscribe 118 | */ 119 | public void unsubscribe(Class listener) { 120 | EVENT_BUS.unsubscribe(listener); 121 | } 122 | 123 | /** 124 | * Post an event 125 | * 126 | * @param event The event to post 127 | */ 128 | public void post(Object event) { 129 | EVENT_BUS.post(event); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/Globals.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * Globals class 7 | */ 8 | public final class Globals { 9 | private static File addonDir; 10 | 11 | /** 12 | * @return Addon directory 13 | */ 14 | public static File getAddonDir() { 15 | return addonDir; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/addon/Addon.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.addon; 2 | 3 | import dev.boze.api.Globals; 4 | import dev.boze.api.config.JsonTools; 5 | import dev.boze.api.config.Serializable; 6 | 7 | import java.io.File; 8 | import java.util.ArrayList; 9 | 10 | import com.google.gson.JsonArray; 11 | import com.google.gson.JsonObject; 12 | 13 | /** 14 | * Base class for all Boze addons 15 | *

16 | * An addon is a self-contained extension that can add new functionality to Boze 17 | *

18 | * Each addon has a unique identifier, name, description, and version 19 | *

20 | * Addons can contain multiple modules and commands, which are managed through the addon's dispatcher 21 | */ 22 | public abstract class Addon implements Serializable { 23 | /** 24 | * Unique identifier for this addon 25 | */ 26 | public final String id; 27 | 28 | /** 29 | * Display name of this addon 30 | */ 31 | public final String name; 32 | 33 | /** 34 | * Description of what this addon does 35 | */ 36 | public final String description; 37 | 38 | /** 39 | * Version string of this addon 40 | */ 41 | public final String version; 42 | 43 | /** 44 | * List of modules provided by this addon 45 | */ 46 | public final ArrayList modules = new ArrayList<>(); 47 | 48 | /** 49 | * Command dispatcher for this addon 50 | */ 51 | public final AddonDispatcher dispatcher; 52 | 53 | /** 54 | * Creates a new addon with a default dispatcher 55 | * 56 | * @param id Unique identifier for this addon 57 | * @param name Display name of this addon 58 | * @param description Description of what this addon does 59 | * @param version Version string of this addon 60 | */ 61 | public Addon(String id, String name, String description, String version) { 62 | this(id, name, description, version, new AddonDispatcher()); 63 | } 64 | 65 | /** 66 | * Creates a new addon with a custom dispatcher 67 | * 68 | * @param id Unique identifier for this addon 69 | * @param name Display name of this addon 70 | * @param description Description of what this addon does 71 | * @param version Version string of this addon 72 | * @param dispatcher Custom command dispatcher for this addon 73 | */ 74 | public Addon(String id, String name, String description, String version, AddonDispatcher dispatcher) { 75 | this.id = id; 76 | this.name = name; 77 | this.description = description; 78 | this.version = version; 79 | this.dispatcher = dispatcher; 80 | } 81 | 82 | /** 83 | * Initializes this addon 84 | *

85 | * This is called when the addon is loaded. The default implementation loads the addon's 86 | * configuration from disk. 87 | * 88 | * @return true if initialization was successful, false otherwise 89 | */ 90 | public boolean initialize() { 91 | JsonTools.loadObject(this, "config", this); 92 | return true; 93 | } 94 | 95 | /** 96 | * Shuts down this addon 97 | *

98 | * This is called when the addon is unloaded. The default implementation saves the addon's 99 | * configuration to disk. 100 | */ 101 | public void shutdown() { 102 | JsonTools.saveObject(this, "config", this); 103 | } 104 | 105 | /** 106 | * Gets the addon's directory 107 | *

108 | * Creates the directory if it doesn't exist 109 | * 110 | * @return The addon's directory 111 | */ 112 | public File getDir() { 113 | File dir = new File(Globals.getAddonDir(), id); 114 | if (!dir.exists()) dir.mkdir(); 115 | return dir; 116 | } 117 | 118 | @Override 119 | public JsonObject toJson() { 120 | JsonObject object = new JsonObject(); 121 | 122 | // Add basic properties 123 | object.addProperty("id", id); 124 | object.addProperty("name", name); 125 | object.addProperty("description", description); 126 | object.addProperty("version", version); 127 | 128 | // Add modules as an object of JsonObjects with module names as keys 129 | if (!modules.isEmpty()) { 130 | JsonObject modulesObject = new JsonObject(); 131 | for (AddonModule module : modules) { 132 | modulesObject.add(module.getName(), module.toJson()); 133 | } 134 | object.add("modules", modulesObject); 135 | } 136 | 137 | return object; 138 | } 139 | 140 | @Override 141 | public Addon fromJson(JsonObject object) { 142 | // Modules (id, name, description, version are final and set in constructor) 143 | if (object.has("modules") && object.get("modules").isJsonObject()) { 144 | JsonObject modulesObject = object.getAsJsonObject("modules"); 145 | 146 | for (AddonModule module : modules) { 147 | String moduleName = module.getName(); 148 | if (modulesObject.has(moduleName)) { 149 | module.fromJson(modulesObject.getAsJsonObject(moduleName)); 150 | } 151 | } 152 | } 153 | 154 | return this; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/addon/AddonCommand.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.addon; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.arguments.ArgumentType; 5 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 6 | import com.mojang.brigadier.builder.RequiredArgumentBuilder; 7 | import net.minecraft.command.CommandSource; 8 | 9 | /** 10 | * Base class for addon commands. 11 | * All addon commands should extend this class. 12 | */ 13 | public abstract class AddonCommand { 14 | 15 | private final String name; 16 | private final String description; 17 | 18 | /** 19 | * Creates a new addon command. 20 | * 21 | * @param name The name of the command 22 | * @param description A short description of what the command does 23 | */ 24 | public AddonCommand(String name, String description) { 25 | this.name = name; 26 | this.description = description; 27 | } 28 | 29 | /** 30 | * Helper method to create an argument for the command builder. 31 | * 32 | * @param name The name of the argument 33 | * @param type The type of the argument 34 | * @return A new argument builder 35 | */ 36 | protected static RequiredArgumentBuilder argument(final String name, final ArgumentType type) { 37 | return RequiredArgumentBuilder.argument(name, type); 38 | } 39 | 40 | /** 41 | * Helper method to create a literal for the command builder. 42 | * 43 | * @param name The name of the literal 44 | * @return A new literal builder 45 | */ 46 | protected static LiteralArgumentBuilder literal(final String name) { 47 | return LiteralArgumentBuilder.literal(name); 48 | } 49 | 50 | /** 51 | * Registers this command to the dispatcher. 52 | * 53 | * @param dispatcher The dispatcher to register to 54 | */ 55 | public void register(CommandDispatcher dispatcher) { 56 | LiteralArgumentBuilder builder = LiteralArgumentBuilder.literal(name); 57 | build(builder); 58 | dispatcher.register(builder); 59 | } 60 | 61 | /** 62 | * Implement this method to build the command. 63 | * 64 | * @param builder The command builder 65 | */ 66 | public abstract void build(LiteralArgumentBuilder builder); 67 | 68 | /** 69 | * Gets the command name. 70 | * 71 | * @return The command name 72 | */ 73 | public String getName() { 74 | return name; 75 | } 76 | 77 | /** 78 | * Gets the command description. 79 | * 80 | * @return The command description 81 | */ 82 | public String getDescription() { 83 | return description; 84 | } 85 | } -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/addon/AddonDispatcher.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.addon; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.exceptions.CommandSyntaxException; 5 | import net.minecraft.client.MinecraftClient; 6 | import net.minecraft.client.network.ClientCommandSource; 7 | import net.minecraft.command.CommandSource; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * Container class for addon command dispatching 14 | *

15 | * Each addon has its own dispatcher that manages its commands 16 | *

17 | * The dispatcher handles command registration, execution, and provides access to all registered commands 18 | *

19 | * All addons must use this to register and handle commands 20 | */ 21 | public class AddonDispatcher { 22 | 23 | /** 24 | * The underlying command dispatcher 25 | */ 26 | public static final CommandDispatcher dispatcher = new CommandDispatcher<>(); 27 | 28 | /** 29 | * List of registered commands 30 | */ 31 | private final List commands = new ArrayList<>(); 32 | 33 | /** 34 | * Gets the underlying command dispatcher 35 | *

36 | * This can be used for advanced command handling 37 | * 38 | * @return The command dispatcher 39 | */ 40 | public CommandDispatcher getDispatcher() { 41 | return dispatcher; 42 | } 43 | 44 | /** 45 | * Dispatches a command using the default client command source 46 | *

47 | * This is the most common way to execute commands 48 | * 49 | * @param command The command to dispatch 50 | * @throws CommandSyntaxException If the command has a syntax error 51 | */ 52 | public void dispatch(String command) throws CommandSyntaxException { 53 | dispatch(command, new ClientCommandSource(null, MinecraftClient.getInstance())); 54 | } 55 | 56 | /** 57 | * Dispatches a command with a specific command source 58 | *

59 | * This allows for custom command execution contexts 60 | * 61 | * @param command The command to dispatch 62 | * @param source The command source to use 63 | * @throws CommandSyntaxException If the command has a syntax error 64 | */ 65 | public void dispatch(String command, CommandSource source) throws CommandSyntaxException { 66 | getDispatcher().execute(command, source); 67 | } 68 | 69 | /** 70 | * Registers a single command 71 | *

72 | * The command will be added to the list of commands and registered with the dispatcher 73 | * 74 | * @param command The command to register 75 | */ 76 | public void registerCommand(AddonCommand command) { 77 | commands.add(command); 78 | command.register(dispatcher); 79 | } 80 | 81 | /** 82 | * Registers multiple commands at once 83 | *

84 | * Each command will be added to the list of commands and registered with the dispatcher 85 | * 86 | * @param commands The commands to register 87 | */ 88 | public void registerCommands(AddonCommand... commands) { 89 | for (AddonCommand command : commands) { 90 | registerCommand(command); 91 | } 92 | } 93 | 94 | /** 95 | * Gets all registered commands 96 | *

97 | * This can be used to get information about available commands 98 | * 99 | * @return List of all registered commands 100 | */ 101 | public List getCommands() { 102 | return commands; 103 | } 104 | } -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/addon/AddonModule.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.addon; 2 | 3 | import com.google.gson.JsonObject; 4 | import dev.boze.api.BozeInstance; 5 | import dev.boze.api.config.Serializable; 6 | import dev.boze.api.input.Bind; 7 | import dev.boze.api.option.Option; 8 | import dev.boze.api.option.BindOption; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Base class for all addon modules 14 | *

15 | * A module is a self-contained piece of functionality that can be enabled or disabled 16 | *

17 | * Each module has a name, description, title (which can be changed), and a keybind 18 | *

19 | * Modules can have settings which are automatically serialized and deserialized 20 | */ 21 | public abstract class AddonModule implements Serializable { 22 | 23 | /** 24 | * Internal name of this module (cannot be changed) 25 | */ 26 | private final String name; 27 | 28 | /** 29 | * Description of what this module does 30 | */ 31 | private final String description; 32 | 33 | /** 34 | * Display title of this module (can be changed) 35 | */ 36 | private String title; 37 | 38 | /** 39 | * Whether this module is currently enabled 40 | */ 41 | private boolean state; 42 | 43 | /** 44 | * Keybind for toggling this module 45 | */ 46 | private final BindOption bind; 47 | 48 | /** 49 | * List of settings for this module 50 | */ 51 | public final ArrayList> settings = new ArrayList<>(); 52 | 53 | /** 54 | * Creates a new module 55 | * 56 | * @param name Internal name of this module 57 | * @param description Description of what this module does 58 | */ 59 | protected AddonModule(String name, String description) { 60 | this.name = name; 61 | this.description = description; 62 | 63 | this.title = name; 64 | this.state = false; 65 | this.bind = new BindOption(this, "Bind", "Keybind for " + name); 66 | } 67 | 68 | /** 69 | * Gets the internal name of this module 70 | * 71 | * @return The module's name 72 | */ 73 | public String getName() { 74 | return name; 75 | } 76 | 77 | /** 78 | * Gets the display title of this module 79 | * 80 | * @return The module's title 81 | */ 82 | public String getTitle() { 83 | return title; 84 | } 85 | 86 | /** 87 | * Sets the display title of this module 88 | * 89 | * @param newTitle The new title 90 | */ 91 | public void setTitle(String newTitle) { 92 | this.title = newTitle; 93 | } 94 | 95 | /** 96 | * Gets the description of this module 97 | * 98 | * @return The module's description 99 | */ 100 | public String getDescription() { 101 | return description; 102 | } 103 | 104 | /** 105 | * Gets whether this module is enabled 106 | * 107 | * @return true if the module is enabled, false otherwise 108 | */ 109 | public boolean getState() { 110 | return state; 111 | } 112 | 113 | /** 114 | * Sets whether this module is enabled 115 | *

116 | * This will call onEnable() or onDisable() as appropriate 117 | * 118 | * @param newState The new state 119 | * @return true if the state changed, false if it was already in that state 120 | */ 121 | public boolean setState(boolean newState) { 122 | if (newState == state) return false; 123 | 124 | state = newState; 125 | 126 | if (state) { 127 | onEnable(); 128 | BozeInstance.INSTANCE.subscribe(this); 129 | } else { 130 | BozeInstance.INSTANCE.unsubscribe(this); 131 | onDisable(); 132 | } 133 | 134 | return true; 135 | } 136 | 137 | /** 138 | * Called when this module is enabled 139 | *

140 | * Override this to add custom enable behavior 141 | */ 142 | protected void onEnable() { 143 | } 144 | 145 | /** 146 | * Called when this module is disabled 147 | *

148 | * Override this to add custom disable behavior 149 | */ 150 | protected void onDisable() { 151 | } 152 | 153 | /** 154 | * Gets the current keybind 155 | * 156 | * @return The module's keybind 157 | */ 158 | public Bind getBind() { 159 | return bind.getValue(); 160 | } 161 | 162 | /** 163 | * Gets the keybind option 164 | * 165 | * @return The module's keybind option 166 | */ 167 | public BindOption getBindOption() { 168 | return bind; 169 | } 170 | 171 | /** 172 | * Sets the keybind 173 | * 174 | * @param newBind The new keybind 175 | */ 176 | public void setBind(Bind newBind) { 177 | this.bind.setBind(newBind); 178 | } 179 | 180 | @Override 181 | public JsonObject toJson() { 182 | JsonObject object = new JsonObject(); 183 | object.addProperty("title", title); 184 | object.addProperty("state", state); 185 | 186 | for (Option setting : settings) { 187 | object.add(setting.name, setting.toJson()); 188 | } 189 | 190 | return object; 191 | } 192 | 193 | @Override 194 | public AddonModule fromJson(JsonObject object) { 195 | title = object.get("title").getAsString(); 196 | setState(object.get("state").getAsBoolean()); 197 | 198 | for (Option setting : settings) { 199 | setting.fromJson(object.get(setting.name).getAsJsonObject()); 200 | } 201 | 202 | return this; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/client/ChatHelper.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.client; 2 | 3 | import dev.boze.api.internal.Instances; 4 | 5 | /** 6 | * A helper for sending messages to the client chat 7 | *

8 | * This only sends messages client-side, it does not send messages to the server! 9 | */ 10 | public final class ChatHelper { 11 | 12 | /** 13 | * Send a message to the chat 14 | * 15 | * @param message The message 16 | */ 17 | public static void sendMsg(String message) { 18 | Instances.getChat().sendMsg(message); 19 | } 20 | 21 | /** 22 | * Send a message to the chat with a title 23 | *

24 | * It's recommended to use this method when sending messages from a module 25 | * 26 | * @param title The title of the message/the module name 27 | * @param message The message 28 | */ 29 | public static void sendMsg(String title, String message) { 30 | Instances.getChat().sendMsg(title, message); 31 | } 32 | 33 | /** 34 | * Send a warning to the chat 35 | * 36 | * @param warning The warning 37 | */ 38 | public static void sendWarning(String warning) { 39 | Instances.getChat().sendWarning(warning); 40 | } 41 | 42 | /** 43 | * Send a warning to the chat with a title 44 | *

45 | * It's recommended to use this method when sending warnings from a module 46 | * 47 | * @param title The title of the warning/the module name 48 | * @param warning The warning 49 | */ 50 | public static void sendWarning(String title, String warning) { 51 | Instances.getChat().sendWarning(title, warning); 52 | } 53 | 54 | /** 55 | * Send an error to the chat 56 | * 57 | * @param error The error 58 | */ 59 | public static void sendError(String error) { 60 | Instances.getChat().sendError(error); 61 | } 62 | 63 | /** 64 | * Send an error to the chat with a title 65 | *

66 | * It's recommended to use this method when sending errors from a module 67 | * 68 | * @param title The title of the error/the module name 69 | * @param error The error 70 | */ 71 | public static void sendError(String title, String error) { 72 | Instances.getChat().sendError(title, error); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/client/FriendManager.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.client; 2 | 3 | import dev.boze.api.internal.Instances; 4 | 5 | /** 6 | * Friend manager 7 | */ 8 | public final class FriendManager { 9 | 10 | /** 11 | * @param name Name of friend to check 12 | * @return true if friend is added, false if friend is not added 13 | */ 14 | public static boolean isFriend(String name) { 15 | return Instances.getFriends().isFriend(name); 16 | } 17 | 18 | /** 19 | * @param name Name of friend to add 20 | * @return true if friend was added, false if friend was already added 21 | */ 22 | public static boolean addFriend(String name) { 23 | return Instances.getFriends().addFriend(name); 24 | } 25 | 26 | /** 27 | * @param friend Friend to delete 28 | */ 29 | public static void delFriend(String friend) { 30 | Instances.getFriends().delFriend(friend); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/client/ModuleHelper.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.client; 2 | 3 | import dev.boze.api.exception.ModuleNotFoundException; 4 | import dev.boze.api.internal.Instances; 5 | 6 | /** 7 | * ModuleHelper provides a way to interact with Boze modules 8 | */ 9 | public class ModuleHelper { 10 | 11 | /** 12 | * Get the state of a module 13 | * 14 | * @param module The name of the module to get the state of 15 | * @return The state of the module 16 | * @throws ModuleNotFoundException If the module is not found 17 | */ 18 | public static boolean getState(String module) throws ModuleNotFoundException { 19 | return Instances.getModules().getState(module); 20 | } 21 | 22 | /** 23 | * Set the state of a module 24 | * 25 | * @param module The name of the module to set the state of 26 | * @param state The state to set the module to 27 | * @throws ModuleNotFoundException If the module is not found 28 | */ 29 | public static void setState(String module, boolean state) throws ModuleNotFoundException { 30 | Instances.getModules().setState(module, state); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/client/ProfileHelper.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.client; 2 | 3 | import dev.boze.api.internal.Instances; 4 | 5 | /** 6 | * ProfileHelper provides a way to interact with Boze profiles 7 | */ 8 | public class ProfileHelper { 9 | 10 | /** 11 | * Enum representing the four categories of profiles 12 | */ 13 | public enum ProfileCategory { 14 | MAIN, 15 | VISUALS, 16 | BINDS, 17 | CLIENT 18 | } 19 | 20 | /** 21 | * Get the selected profile name for a specified category 22 | * 23 | * @param category The profile category 24 | * @return The selected profile name 25 | */ 26 | public static String getSelectedProfile(ProfileCategory category) { 27 | return Instances.getProfiles().getSelectedProfile(category); 28 | } 29 | 30 | /** 31 | * Get the available profiles for a specified category 32 | * 33 | * @param category The profile category 34 | * @return Array of available profile names 35 | */ 36 | public static String[] getAvailableProfiles(ProfileCategory category) { 37 | return Instances.getProfiles().getAvailableProfiles(category); 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/client/cape/CapeLoadResult.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.client.cape; 2 | 3 | /** 4 | * Enum for cape load results 5 | * 6 | */ 7 | public enum CapeLoadResult { 8 | /** 9 | * Cape loaded successfully 10 | */ 11 | Success, 12 | 13 | /** 14 | * Server/website did not respond with a cape texture 15 | */ 16 | InvalidResponse, 17 | 18 | /** 19 | * Server/website did not respond at all, or there was an error parsing the response 20 | */ 21 | Error 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/client/cape/CapeSource.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.client.cape; 2 | 3 | import com.mojang.authlib.GameProfile; 4 | import net.minecraft.util.Identifier; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | import java.net.URL; 8 | import java.util.Objects; 9 | 10 | public abstract class CapeSource { 11 | 12 | public final String name; 13 | 14 | public CapeSource(String name) { 15 | this.name = name; 16 | } 17 | 18 | /** 19 | * Returns url (to a png) for a given profile 20 | * 21 | * @param profile Profile to get cape url for 22 | * @return the url of the cape, or null if player has no cape 23 | */ 24 | public abstract URL getUrl(GameProfile profile); 25 | 26 | /** 27 | * Gets called once a profile's cape gets loaded (if URL not null) 28 | * 29 | * @param profile Profile which got loaded 30 | * @param result Cape load result 31 | * @param identifier Identifier of the cape (null if not loaded successfully) 32 | */ 33 | public abstract void callback(GameProfile profile, CapeLoadResult result, @Nullable Identifier identifier); 34 | 35 | @Override 36 | public boolean equals(Object o) { 37 | if (this == o) return true; 38 | if (o == null || getClass() != o.getClass()) return false; 39 | CapeSource that = (CapeSource) o; 40 | return Objects.equals(name, that.name); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/client/cape/CapesManager.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.client.cape; 2 | 3 | import dev.boze.api.internal.Instances; 4 | 5 | /** 6 | * Capes manager 7 | *

8 | * Used to add and remove external cape sources 9 | */ 10 | public final class CapesManager { 11 | 12 | /** 13 | * Add a cape source 14 | * 15 | * @param source Cape source 16 | */ 17 | public static void addSource(CapeSource source) { 18 | Instances.getCapes().addSource(source); 19 | } 20 | 21 | /** 22 | * Remove a cape source 23 | * 24 | * @param source Cape source 25 | */ 26 | public static void removeSource(CapeSource source) { 27 | Instances.getCapes().removeSource(source); 28 | } 29 | 30 | /** 31 | * Get all cape sources, from all addons 32 | * 33 | * @return Cape sources 34 | */ 35 | public static String[] getSources() { 36 | return Instances.getCapes().getSources(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/config/JsonTools.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.config; 2 | 3 | import dev.boze.api.addon.Addon; 4 | import dev.boze.api.internal.Instances; 5 | 6 | /** 7 | * Helper class for saving and loading json objects 8 | */ 9 | public final class JsonTools { 10 | 11 | /** 12 | * Saves an object to a file 13 | * 14 | * @param addon The addon to save the object for 15 | * @param fileName The name of the file to save the object to 16 | * @param object The object to save 17 | * @return If the object was saved successfully 18 | */ 19 | public static boolean saveObject(Addon addon, String fileName, Serializable object) { 20 | return Instances.getJson().saveObject(addon, fileName, object); 21 | } 22 | 23 | /** 24 | * Loads to object from a file 25 | * 26 | * @param addon The addon to load the object for 27 | * @param fileName The name of the file to load the object from 28 | * @param object The object to load to 29 | * @return The loaded object, or null if the object failed to load 30 | */ 31 | public static > T loadObject(Addon addon, String fileName, Serializable object) { 32 | return Instances.getJson().loadObject(addon, fileName, object); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/config/Serializable.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.config; 2 | 3 | import com.google.gson.JsonObject; 4 | 5 | /** 6 | * Interface for serializable objects (settings, modules, etc.) 7 | * 8 | * @param The type of the object 9 | */ 10 | public interface Serializable { 11 | 12 | /** 13 | * @return The object as a JsonObject 14 | */ 15 | JsonObject toJson(); 16 | 17 | /** 18 | * @param object The JsonObject to deserialize 19 | * @return The deserialized object 20 | */ 21 | T fromJson(JsonObject object); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/event/EventHudRender.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.event; 2 | 3 | import net.minecraft.client.gui.DrawContext; 4 | 5 | /** 6 | * Event called when the HUD is being rendered 7 | *

8 | * Used for 2D rendering 9 | */ 10 | public class EventHudRender { 11 | private static final EventHudRender INSTANCE = new EventHudRender(); 12 | 13 | /** 14 | * The current draw context 15 | */ 16 | public DrawContext context; 17 | 18 | /** 19 | * The current tick delta 20 | */ 21 | public float tickDelta; 22 | 23 | /** 24 | * Gets the event instance - this is called when the HUD is being rendered by Boze, and should not be called by addons 25 | * 26 | * @param context The current draw context 27 | * @param tickDelta The current tick delta 28 | * @return The event instance 29 | */ 30 | public static EventHudRender get(DrawContext context, float tickDelta) { 31 | INSTANCE.context = context; 32 | INSTANCE.tickDelta = tickDelta; 33 | return INSTANCE; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/event/EventInput.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.event; 2 | 3 | /** 4 | * EventInput 5 | *

6 | * Event called once a tick 7 | *

8 | * Use this event to modify player movement input 9 | */ 10 | public class EventInput { 11 | private static final EventInput INSTANCE = new EventInput(); 12 | 13 | /** 14 | * Horizontal movement tags 15 | */ 16 | public boolean forward; 17 | public boolean backward; 18 | public boolean left; 19 | public boolean right; 20 | 21 | /** 22 | * Jumping and sneaking flags 23 | */ 24 | public boolean jumping; 25 | public boolean sneaking; 26 | 27 | /** 28 | * Gets the event instance - this is called by Boze, and should not be called by addons 29 | * 30 | * @param forward Current forward movement 31 | * @param backward Current backward movement 32 | * @param left Current leftward movement 33 | * @param right Current rightward movement 34 | * @param jumping If the player is jumping 35 | * @param sneaking IF the player is sneaking 36 | * @return The event instance 37 | */ 38 | public static EventInput get(boolean forward, boolean backward, boolean left, boolean right, boolean jumping, boolean sneaking) { 39 | INSTANCE.forward = forward; 40 | INSTANCE.backward = backward; 41 | INSTANCE.left = left; 42 | INSTANCE.right = right; 43 | INSTANCE.jumping = jumping; 44 | INSTANCE.sneaking = sneaking; 45 | return INSTANCE; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/event/EventPlayerUpdate.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.event; 2 | 3 | /** 4 | * EventPlayerUpdate 5 | *

6 | * Event called when the player updates, once a tick 7 | */ 8 | public class EventPlayerUpdate { 9 | private static final EventPlayerUpdate INSTANCE = new EventPlayerUpdate(); 10 | 11 | public static EventPlayerUpdate get() { 12 | return INSTANCE; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/event/EventTick.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.event; 2 | 3 | /** 4 | * EventTick 5 | *

6 | * Tick event 7 | *

8 | * This event should be used for features that need to be called at the start/end of ticks 9 | * 10 | */ 11 | public class EventTick { 12 | 13 | public static class Pre extends EventTick { 14 | 15 | private static final Pre INSTANCE = new Pre(); 16 | 17 | /** 18 | * Gets the event instance - this is called at the start of a tick by Boze, and should not be called by addons 19 | * 20 | * @return The event instance 21 | */ 22 | public static Pre get() { 23 | return INSTANCE; 24 | } 25 | } 26 | 27 | public static class Post extends EventTick { 28 | 29 | private static final Post INSTANCE = new Post(); 30 | 31 | /** 32 | * Gets the event instance - this is called at the end of a tick by Boze, and should not be called by addons 33 | * 34 | * @return The event instance 35 | */ 36 | public static Post get() { 37 | return INSTANCE; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/event/EventWorldRender.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.event; 2 | 3 | 4 | import net.minecraft.client.render.Camera; 5 | import net.minecraft.client.util.math.MatrixStack; 6 | 7 | /** 8 | * EventWorldRender 9 | *

10 | * Called on world render, used for 3D rendering 11 | */ 12 | public class EventWorldRender { 13 | private static final EventWorldRender INSTANCE = new EventWorldRender(); 14 | 15 | public MatrixStack matrices; 16 | public Camera camera; 17 | public float tickDelta; 18 | 19 | /** 20 | * Get the event instance - this is called onm world render by Boze, and should not be called by addons 21 | * 22 | * @param matrices MatrixStack 23 | * @param camera Camera 24 | * @param tickDelta Tick delta 25 | * @return The event instance 26 | */ 27 | public static EventWorldRender get(MatrixStack matrices, Camera camera, float tickDelta) { 28 | INSTANCE.matrices = matrices; 29 | INSTANCE.camera = camera; 30 | INSTANCE.tickDelta = tickDelta; 31 | return INSTANCE; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/exception/AddonInitializationException.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.exception; 2 | 3 | public class AddonInitializationException extends Exception { 4 | public AddonInitializationException(String message) { 5 | super(message); 6 | } 7 | 8 | public AddonInitializationException(String message, Throwable cause) { 9 | super(message, cause); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/exception/ModuleNotFoundException.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.exception; 2 | 3 | public class ModuleNotFoundException extends Exception { 4 | public ModuleNotFoundException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/input/Bind.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.input; 2 | 3 | /** 4 | * Represents a keyboard or mouse button binding 5 | *

6 | * A bind can be either a keyboard key or a mouse button, identified by its GLFW code 7 | *

8 | * This class is used throughout Boze to handle input bindings for modules and other features 9 | */ 10 | public class Bind { 11 | /** 12 | * Whether this bind is a mouse button (true) or keyboard key (false) 13 | */ 14 | private boolean isButton; 15 | 16 | /** 17 | * The GLFW code for this bind 18 | *

19 | * For keyboard keys, this is a GLFW_KEY_* constant 20 | *

21 | * For mouse buttons, this is a GLFW_MOUSE_BUTTON_* constant 22 | */ 23 | private int bind; 24 | 25 | /** 26 | * Creates a new bind 27 | * 28 | * @param isButton Whether this bind is a mouse button (true) or keyboard key (false) 29 | * @param bind The GLFW code for the key or button 30 | */ 31 | public Bind(boolean isButton, int bind) { 32 | this.isButton = isButton; 33 | this.bind = bind; 34 | } 35 | 36 | /** 37 | * Gets the GLFW code for this bind 38 | *

39 | * For keyboard keys, this returns a GLFW_KEY_* constant 40 | *

41 | * For mouse buttons, this returns a GLFW_MOUSE_BUTTON_* constant 42 | * 43 | * @return The GLFW code for this bind 44 | */ 45 | public int getBind() { 46 | return bind; 47 | } 48 | 49 | /** 50 | * Checks if this bind is a mouse button 51 | * 52 | * @return true if this bind is a mouse button, false if it's a keyboard key 53 | */ 54 | public boolean isButton() { 55 | return isButton; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/input/InputNameProvider.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.input; 2 | 3 | import dev.boze.api.internal.Instances; 4 | 5 | /** 6 | * Input Name Provider, used to get the name of a key or button 7 | */ 8 | public final class InputNameProvider { 9 | 10 | /** 11 | * Get the name of a bind 12 | * 13 | * @param bind 14 | * @return the name of the bind 15 | */ 16 | public static String getBindName(Bind bind) { 17 | return bind.isButton() ? getButtonName(bind.getBind()) : getKeyName(bind.getBind()); 18 | } 19 | 20 | /** 21 | * Get the name of a (keyboard) key 22 | * 23 | * @param key 24 | * @return the name of the key 25 | */ 26 | public static String getKeyName(int key) { 27 | return Instances.getInput().getKeyName(key); 28 | } 29 | 30 | /** 31 | * Get the name of a (mouse) button 32 | * 33 | * @param button 34 | * @return the name of the button 35 | */ 36 | public static String getButtonName(int button) { 37 | return Instances.getInput().getButtonName(button); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/internal/Instances.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.internal; 2 | 3 | import dev.boze.api.internal.interfaces.*; 4 | 5 | public class Instances { 6 | 7 | private static ICapes capes; 8 | private static IChat chat; 9 | private static IFriends friends; 10 | private static IInput input; 11 | private static IJson json; 12 | private static IModules modules; 13 | private static IProfiles profiles; 14 | 15 | public static ICapes getCapes() { 16 | return capes; 17 | } 18 | 19 | public static IChat getChat() { 20 | return chat; 21 | } 22 | 23 | public static IFriends getFriends() { 24 | return friends; 25 | } 26 | 27 | public static IInput getInput() { 28 | return input; 29 | } 30 | 31 | public static IJson getJson() { 32 | return json; 33 | } 34 | 35 | public static IModules getModules() { 36 | return modules; 37 | } 38 | 39 | public static IProfiles getProfiles() { 40 | return profiles; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/internal/interfaces/ICapes.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.internal.interfaces; 2 | 3 | import dev.boze.api.client.cape.CapeSource; 4 | 5 | public interface ICapes { 6 | void addSource(CapeSource source); 7 | 8 | void removeSource(CapeSource source); 9 | 10 | String[] getSources(); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/internal/interfaces/IChat.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.internal.interfaces; 2 | 3 | public interface IChat { 4 | void sendMsg(String message); 5 | 6 | void sendMsg(String title, String message); 7 | 8 | void sendWarning(String warning); 9 | 10 | void sendWarning(String title, String warning); 11 | 12 | void sendError(String error); 13 | 14 | void sendError(String title, String error); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/internal/interfaces/IFriends.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.internal.interfaces; 2 | 3 | public interface IFriends { 4 | boolean isFriend(String name); 5 | 6 | boolean addFriend(String name); 7 | 8 | void delFriend(String friend); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/internal/interfaces/IInput.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.internal.interfaces; 2 | 3 | public interface IInput { 4 | String getKeyName(int key); 5 | 6 | String getButtonName(int button); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/internal/interfaces/IJson.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.internal.interfaces; 2 | 3 | import dev.boze.api.addon.Addon; 4 | import dev.boze.api.config.Serializable; 5 | 6 | public interface IJson { 7 | boolean saveObject(Addon addon, String fileName, Serializable object); 8 | 9 | > T loadObject(Addon addon, String fileName, Serializable object); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/internal/interfaces/IModules.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.internal.interfaces; 2 | 3 | import dev.boze.api.exception.ModuleNotFoundException; 4 | 5 | public interface IModules { 6 | boolean getState(String module) throws ModuleNotFoundException; 7 | 8 | void setState(String module, boolean state) throws ModuleNotFoundException; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/internal/interfaces/IProfiles.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.internal.interfaces; 2 | 3 | import dev.boze.api.client.ProfileHelper.ProfileCategory; 4 | 5 | public interface IProfiles { 6 | 7 | String getSelectedProfile(ProfileCategory category); 8 | 9 | String[] getAvailableProfiles(ProfileCategory category); 10 | } -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/option/BindOption.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.option; 2 | 3 | import com.google.gson.JsonObject; 4 | import dev.boze.api.addon.AddonModule; 5 | import dev.boze.api.input.Bind; 6 | 7 | /** 8 | * An option for keyboard/mouse bindings 9 | *

10 | * BindOption provides a way to store and modify key or mouse button bindings 11 | *

12 | * Can be bound to either a keyboard key or mouse button 13 | */ 14 | public class BindOption extends Option { 15 | 16 | private Bind bindInstance; 17 | private final Bind defaultBindInstance; 18 | 19 | /** 20 | * Creates a new bind option with no default binding 21 | * 22 | * @param owner The module that owns this option 23 | * @param name The name of this option 24 | * @param description The description of this option 25 | */ 26 | public BindOption(AddonModule owner, String name, String description) { 27 | this(owner, name, description, -1, false); 28 | } 29 | 30 | /** 31 | * Creates a new bind option with a specified default binding 32 | * 33 | * @param owner The module that owns this option 34 | * @param name The name of this option 35 | * @param description The description of this option 36 | * @param bind The key/button code to bind to 37 | * @param isButton Whether this is a mouse button (true) or keyboard key (false) 38 | */ 39 | public BindOption(AddonModule owner, String name, String description, int bind, boolean isButton) { 40 | super(owner, name, description); 41 | this.bindInstance = new Bind(isButton, bind); 42 | this.defaultBindInstance = new Bind(isButton, bind); 43 | } 44 | 45 | @Override 46 | public Bind getValue() { 47 | return bindInstance; 48 | } 49 | 50 | @Override 51 | public Bind setValue(Bind newValue) { 52 | bindInstance = new Bind(newValue.isButton(), newValue.getBind()); 53 | return bindInstance; 54 | } 55 | 56 | @Override 57 | public Bind reset() { 58 | bindInstance = new Bind(defaultBindInstance.isButton(), defaultBindInstance.getBind()); 59 | return bindInstance; 60 | } 61 | 62 | /** 63 | * Gets the current key/button code 64 | * 65 | * @return The key/button code 66 | */ 67 | public int getBind() { 68 | return bindInstance.getBind(); 69 | } 70 | 71 | /** 72 | * Checks if this bind is for a mouse button 73 | * 74 | * @return true if this is a mouse button bind, false if it's a keyboard key 75 | */ 76 | public boolean isButton() { 77 | return bindInstance.isButton(); 78 | } 79 | 80 | /** 81 | * Sets the binding using a Bind object 82 | * 83 | * @param bind The new binding 84 | */ 85 | public void setBind(Bind bind) { 86 | bindInstance = new Bind(bind.isButton(), bind.getBind()); 87 | } 88 | 89 | /** 90 | * Sets the binding using a key/button code and type 91 | * 92 | * @param bind The key/button code 93 | * @param isButton Whether this is a mouse button (true) or keyboard key (false) 94 | */ 95 | public void setBind(int bind, boolean isButton) { 96 | bindInstance = new Bind(isButton, bind); 97 | } 98 | 99 | @Override 100 | public JsonObject toJson() { 101 | JsonObject object = new JsonObject(); 102 | object.addProperty("bind", bindInstance.getBind()); 103 | object.addProperty("isButton", bindInstance.isButton()); 104 | return object; 105 | } 106 | 107 | @Override 108 | public Bind fromJson(JsonObject object) { 109 | int bind = object.get("bind").getAsInt(); 110 | boolean isButton = object.get("isButton").getAsBoolean(); 111 | bindInstance = new Bind(isButton, bind); 112 | return bindInstance; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/option/ModeOption.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.option; 2 | 3 | import com.google.gson.JsonObject; 4 | import dev.boze.api.addon.AddonModule; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | /** 11 | * An option for selecting from a predefined set of modes 12 | *

13 | * ModeOption provides a way to store and modify enum values 14 | *

15 | * The available modes are defined by the enum type parameter 16 | * 17 | * @param The enum type defining the available modes 18 | */ 19 | public class ModeOption> extends Option { 20 | 21 | private T value; 22 | private final T defaultValue; 23 | 24 | /** 25 | * Creates a new mode option 26 | * 27 | * @param owner The module that owns this option 28 | * @param name The name of this option 29 | * @param description The description of this option 30 | * @param defaultValue The initial value and default value 31 | */ 32 | public ModeOption(AddonModule owner, String name, String description, T defaultValue) { 33 | super(owner, name, description); 34 | this.value = defaultValue; 35 | this.defaultValue = defaultValue; 36 | } 37 | 38 | /** 39 | * Gets the enum class of this mode option 40 | * 41 | * @return The enum class 42 | */ 43 | @SuppressWarnings("unchecked") 44 | public Class getEnumClass() { 45 | return (Class) value.getClass(); 46 | } 47 | 48 | /** 49 | * Gets a list of all available mode names 50 | * 51 | * @return List of mode names 52 | */ 53 | public List getModes() { 54 | return Arrays.stream(getEnumClass().getEnumConstants()) 55 | .map(Enum::name) 56 | .collect(Collectors.toList()); 57 | } 58 | 59 | /** 60 | * Gets the name of the current mode 61 | * 62 | * @return The current mode name 63 | */ 64 | public String getModeName() { 65 | return value.name(); 66 | } 67 | 68 | @Override 69 | public T getValue() { 70 | return value; 71 | } 72 | 73 | @Override 74 | public T setValue(T newValue) { 75 | this.value = newValue; 76 | return value; 77 | } 78 | 79 | @Override 80 | public T reset() { 81 | value = defaultValue; 82 | return value; 83 | } 84 | 85 | /** 86 | * Sets the current mode by name 87 | *

88 | * The name is case-insensitive 89 | * 90 | * @param name The name of the mode to set 91 | */ 92 | public void setValueByName(String name) { 93 | for (T constant : getEnumClass().getEnumConstants()) { 94 | if (constant.name().equalsIgnoreCase(name)) { 95 | value = constant; 96 | break; 97 | } 98 | } 99 | } 100 | 101 | @Override 102 | public JsonObject toJson() { 103 | JsonObject object = new JsonObject(); 104 | object.addProperty("mode", value.name()); 105 | return object; 106 | } 107 | 108 | @Override 109 | public T fromJson(JsonObject object) { 110 | if (object.has("mode")) { 111 | String modeName = object.get("mode").getAsString(); 112 | setValueByName(modeName); 113 | } 114 | return value; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/option/Option.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.option; 2 | 3 | import dev.boze.api.addon.AddonModule; 4 | import dev.boze.api.config.Serializable; 5 | 6 | /** 7 | * Base class for all module options 8 | *

9 | * Options are used to store configurable values for modules 10 | *

11 | * All options must implement getValue(), setValue(), and reset() methods 12 | *

13 | * Options also implement Serializable to allow for saving/loading from config files 14 | * 15 | * @param The type of value stored by this option 16 | */ 17 | public abstract class Option implements Serializable { 18 | 19 | /** 20 | * The module that owns this option 21 | */ 22 | public final AddonModule owner; 23 | 24 | /** 25 | * The name of this option 26 | */ 27 | public final String name; 28 | 29 | /** 30 | * The description of this option 31 | */ 32 | public final String description; 33 | 34 | /** 35 | * Creates a new option 36 | * 37 | * @param owner The module that owns this option 38 | * @param name The name of this option 39 | * @param description The description of this option 40 | */ 41 | public Option(AddonModule owner, String name, String description) { 42 | this.owner = owner; 43 | owner.settings.add(this); 44 | 45 | this.name = name; 46 | this.description = description; 47 | } 48 | 49 | /** 50 | * Gets the current value of this option 51 | * 52 | * @return The current value 53 | */ 54 | public abstract T getValue(); 55 | 56 | /** 57 | * Sets the value of this option 58 | * 59 | * @param newValue The new value to set 60 | * @return The value that was set (may be different from newValue if validation was performed) 61 | */ 62 | public abstract T setValue(T newValue); 63 | 64 | /** 65 | * Resets this option to its default value 66 | * 67 | * @return The default value 68 | */ 69 | public abstract T reset(); 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/option/SliderOption.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.option; 2 | 3 | import com.google.gson.JsonObject; 4 | import dev.boze.api.addon.AddonModule; 5 | import net.minecraft.util.math.MathHelper; 6 | 7 | /** 8 | * A numeric option that can be adjusted using a slider 9 | *

10 | * SliderOption provides a way to store and modify numeric values within a specified range 11 | *

12 | * The value is always clamped between min and max, and can only be set in increments of step 13 | */ 14 | public class SliderOption extends Option { 15 | 16 | private double value; 17 | 18 | private final double defaultValue; 19 | 20 | /** 21 | * The minimum value this slider can be set to 22 | */ 23 | public final double min; 24 | 25 | /** 26 | * The maximum value this slider can be set to 27 | */ 28 | public final double max; 29 | 30 | /** 31 | * The increment by which this slider's value changes 32 | */ 33 | public final double step; 34 | 35 | /** 36 | * Creates a new slider option 37 | * 38 | * @param owner The module that owns this option 39 | * @param name The name of this option 40 | * @param description The description of this option 41 | * @param value The initial value 42 | * @param min The minimum allowed value 43 | * @param max The maximum allowed value 44 | * @param step The increment between values 45 | */ 46 | public SliderOption(AddonModule owner, String name, String description, double value, double min, double max, double step) { 47 | super(owner, name, description); 48 | this.value = value; 49 | this.min = min; 50 | this.max = max; 51 | this.step = step; 52 | 53 | this.defaultValue = value; 54 | } 55 | 56 | @Override 57 | public Double getValue() { 58 | return value; 59 | } 60 | 61 | @Override 62 | public Double setValue(Double newValue) { 63 | this.value = MathHelper.clamp(newValue, min, max); 64 | return value; 65 | } 66 | 67 | @Override 68 | public Double reset() { 69 | value = defaultValue; 70 | return value; 71 | } 72 | 73 | @Override 74 | public JsonObject toJson() { 75 | JsonObject object = new JsonObject(); 76 | object.addProperty("value", value); 77 | return object; 78 | } 79 | 80 | @Override 81 | public Double fromJson(JsonObject object) { 82 | value = object.get("value").getAsDouble(); 83 | return value; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/dev/boze/api/option/ToggleOption.java: -------------------------------------------------------------------------------- 1 | package dev.boze.api.option; 2 | 3 | import com.google.gson.JsonObject; 4 | import dev.boze.api.addon.AddonModule; 5 | 6 | /** 7 | * A boolean option that can be toggled on or off 8 | *

9 | * ToggleOption provides a simple way to store and modify boolean values 10 | *

11 | * The value can only be true or false 12 | */ 13 | public class ToggleOption extends Option { 14 | 15 | private boolean value; 16 | 17 | private final boolean defaultValue; 18 | 19 | /** 20 | * Creates a new toggle option with a default value of false 21 | * 22 | * @param owner The module that owns this option 23 | * @param name The name of this option 24 | * @param description The description of this option 25 | */ 26 | public ToggleOption(AddonModule owner, String name, String description) { 27 | this(owner, name, description, false); 28 | } 29 | 30 | /** 31 | * Creates a new toggle option with a specified default value 32 | * 33 | * @param owner The module that owns this option 34 | * @param name The name of this option 35 | * @param description The description of this option 36 | * @param value The initial value 37 | */ 38 | public ToggleOption(AddonModule owner, String name, String description, boolean value) { 39 | super(owner, name, description); 40 | this.value = value; 41 | 42 | this.defaultValue = value; 43 | } 44 | 45 | @Override 46 | public Boolean getValue() { 47 | return value; 48 | } 49 | 50 | @Override 51 | public Boolean setValue(Boolean newValue) { 52 | this.value = newValue; 53 | return value; 54 | } 55 | 56 | @Override 57 | public Boolean reset() { 58 | this.value = defaultValue; 59 | return value; 60 | } 61 | 62 | @Override 63 | public JsonObject toJson() { 64 | JsonObject object = new JsonObject(); 65 | object.addProperty("value", value); 66 | return object; 67 | } 68 | 69 | @Override 70 | public Boolean fromJson(JsonObject object) { 71 | value = object.get("value").getAsBoolean(); 72 | return value; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/resources/api.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "dev.boze.api.mixin", 5 | "compatibilityLevel": "JAVA_17", 6 | "mixins": [ 7 | ], 8 | "client": [ 9 | ], 10 | "injectors": { 11 | "defaultRequire": 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "api", 4 | "version": "${version}", 5 | "name": "Boze API", 6 | "description": "Boze Utility Mod API", 7 | "authors": ["Boze Developers"], 8 | "contact": { 9 | "website": "https://boze.dev", 10 | "repo": "https://github.com/boze-dev/addon-api" 11 | }, 12 | "license": "GPL-3.0", 13 | "environment": "*", 14 | "entrypoints": {}, 15 | "mixins": [ 16 | "api.mixins.json" 17 | ], 18 | "depends": { 19 | "fabricloader": ">=0.15.1", 20 | "fabric": "*", 21 | "minecraft": "1.20.4" 22 | } 23 | } 24 | --------------------------------------------------------------------------------