From 50aa315f16a21c4386ee6ae28c9dd2d13f8b03a4 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Thu, 2 Dec 2021 20:17:52 +0000 Subject: [PATCH] Initial commit --- .gitignore | 1 + LICENSE.md | 596 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ README | 4 ++++ src/io/github/jordandoyle/helpers/classloader/Loader.java | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/helpers/classloader/package-info.java | 4 ++++ src/io/github/jordandoyle/helpers/reflection/Mapping.java | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/helpers/reflection/Package.java | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/helpers/reflection/package-info.java | 4 ++++ src/io/github/jordandoyle/mcinject/Main.java | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/Wrapper.java | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/asm/ClassTransformer.java | 29 +++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/asm/TransformerManager.java | 22 ++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/asm/transformers/EntityPlayerTransformer.java | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/asm/transformers/EntityRendererTransformer.java | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/asm/transformers/InGameTransformer.java | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/asm/transformers/MinecraftTransformer.java | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/event/Event.java | 4 ++++ src/io/github/jordandoyle/mcinject/event/EventFactory.java | 31 +++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/event/EventHandler.java | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/event/EventSubscribe.java | 13 +++++++++++++ src/io/github/jordandoyle/mcinject/event/Listener.java | 4 ++++ src/io/github/jordandoyle/mcinject/event/events/EventDamageEntity.java | 31 +++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/event/events/EventKeyPressed.java | 34 ++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/event/events/EventRenderHand.java | 7 +++++++ src/io/github/jordandoyle/mcinject/event/events/EventRenderOverlay.java | 8 ++++++++ src/io/github/jordandoyle/mcinject/event/events/EventTick.java | 7 +++++++ src/io/github/jordandoyle/mcinject/gui/FontRenderer.java | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/handler/Handler.java | 30 ++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/handler/HandlerManager.java | 37 +++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/handler/handlers/KeyPressHandler.java | 30 ++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/helpers/Mapper.java | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/helpers/ObfuscatedMapping.java | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/helpers/Player.java | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/helpers/RenderHelper.java | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/mod/Category.java | 18 ++++++++++++++++++ src/io/github/jordandoyle/mcinject/mod/Mod.java | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/mod/ModManager.java | 42 ++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/mod/mods/movement/Fly.java | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/mod/mods/movement/Sprint.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/mod/mods/music/Player.java | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/mod/mods/player/AutoRespawn.java | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/mod/mods/render/ESP.java | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/mod/mods/render/FullBright.java | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/github/jordandoyle/mcinject/proxy/Proxy.java | 7 +++++++ src/io/github/jordandoyle/mcinject/proxy/interfaces/Minecraft.java | 5 +++++ src/io/github/jordandoyle/mcinject/proxy/proxies/MinecraftProxy.java | 45 +++++++++++++++++++++++++++++++++++++++++++++ 46 files changed, 3500 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.md create mode 100644 README create mode 100644 src/io/github/jordandoyle/helpers/classloader/Loader.java create mode 100644 src/io/github/jordandoyle/helpers/classloader/package-info.java create mode 100644 src/io/github/jordandoyle/helpers/reflection/Mapping.java create mode 100644 src/io/github/jordandoyle/helpers/reflection/Package.java create mode 100644 src/io/github/jordandoyle/helpers/reflection/package-info.java create mode 100644 src/io/github/jordandoyle/mcinject/Main.java create mode 100644 src/io/github/jordandoyle/mcinject/Wrapper.java create mode 100644 src/io/github/jordandoyle/mcinject/asm/ClassTransformer.java create mode 100644 src/io/github/jordandoyle/mcinject/asm/TransformerManager.java create mode 100644 src/io/github/jordandoyle/mcinject/asm/transformers/EntityPlayerTransformer.java create mode 100644 src/io/github/jordandoyle/mcinject/asm/transformers/EntityRendererTransformer.java create mode 100644 src/io/github/jordandoyle/mcinject/asm/transformers/InGameTransformer.java create mode 100644 src/io/github/jordandoyle/mcinject/asm/transformers/MinecraftTransformer.java create mode 100644 src/io/github/jordandoyle/mcinject/event/Event.java create mode 100644 src/io/github/jordandoyle/mcinject/event/EventFactory.java create mode 100644 src/io/github/jordandoyle/mcinject/event/EventHandler.java create mode 100644 src/io/github/jordandoyle/mcinject/event/EventSubscribe.java create mode 100644 src/io/github/jordandoyle/mcinject/event/Listener.java create mode 100644 src/io/github/jordandoyle/mcinject/event/events/EventDamageEntity.java create mode 100644 src/io/github/jordandoyle/mcinject/event/events/EventKeyPressed.java create mode 100644 src/io/github/jordandoyle/mcinject/event/events/EventRenderHand.java create mode 100644 src/io/github/jordandoyle/mcinject/event/events/EventRenderOverlay.java create mode 100644 src/io/github/jordandoyle/mcinject/event/events/EventTick.java create mode 100644 src/io/github/jordandoyle/mcinject/gui/FontRenderer.java create mode 100644 src/io/github/jordandoyle/mcinject/handler/Handler.java create mode 100644 src/io/github/jordandoyle/mcinject/handler/HandlerManager.java create mode 100644 src/io/github/jordandoyle/mcinject/handler/handlers/KeyPressHandler.java create mode 100644 src/io/github/jordandoyle/mcinject/helpers/Mapper.java create mode 100644 src/io/github/jordandoyle/mcinject/helpers/ObfuscatedMapping.java create mode 100644 src/io/github/jordandoyle/mcinject/helpers/Player.java create mode 100644 src/io/github/jordandoyle/mcinject/helpers/RenderHelper.java create mode 100644 src/io/github/jordandoyle/mcinject/mod/Category.java create mode 100644 src/io/github/jordandoyle/mcinject/mod/Mod.java create mode 100644 src/io/github/jordandoyle/mcinject/mod/ModManager.java create mode 100644 src/io/github/jordandoyle/mcinject/mod/mods/movement/Fly.java create mode 100644 src/io/github/jordandoyle/mcinject/mod/mods/movement/Sprint.java create mode 100644 src/io/github/jordandoyle/mcinject/mod/mods/music/Player.java create mode 100644 src/io/github/jordandoyle/mcinject/mod/mods/player/AutoRespawn.java create mode 100644 src/io/github/jordandoyle/mcinject/mod/mods/render/ESP.java create mode 100644 src/io/github/jordandoyle/mcinject/mod/mods/render/FullBright.java create mode 100644 src/io/github/jordandoyle/mcinject/proxy/Proxy.java create mode 100644 src/io/github/jordandoyle/mcinject/proxy/interfaces/Minecraft.java create mode 100644 src/io/github/jordandoyle/mcinject/proxy/proxies/MinecraftProxy.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f11b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..82048f2 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,596 @@ +GNU GENERAL PUBLIC LICENSE +========================== + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <> + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +## Preamble + +The GNU General Public License is a free, copyleft license for software and other +kinds of works. + +The licenses for most software and other practical works are designed to take away +your freedom to share and change the works. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change all versions of a +program--to make sure it remains free software for all its users. We, the Free +Software Foundation, use the GNU General Public License for most of our software; it +applies also to any other work released this way by its authors. You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General +Public Licenses are designed to make sure that you have the freedom to distribute +copies of free software (and charge for them if you wish), that you receive source +code or can get it if you want it, that you can change the software or use pieces of +it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or +asking you to surrender the rights. Therefore, you have certain responsibilities if +you distribute copies of the software, or if you modify it: responsibilities to +respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, +you must pass on to the recipients the same freedoms that you received. You must make +sure that they, too, receive or can get the source code. And you must show them these +terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert +copyright on the software, and (2) offer you this License giving you legal permission +to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is +no warranty for this free software. For both users' and authors' sake, the GPL +requires that modified versions be marked as changed, so that their problems will not +be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of +the software inside them, although the manufacturer can do so. This is fundamentally +incompatible with the aim of protecting users' freedom to change the software. The +systematic pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we have designed +this version of the GPL to prohibit the practice for those products. If such problems +arise substantially in other domains, we stand ready to extend this provision to +those domains in future versions of the GPL, as needed to protect the freedom of +users. + +Finally, every program is threatened constantly by software patents. States should +not allow patents to restrict development and use of software on general-purpose +computers, but in those that do, we wish to avoid the special danger that patents +applied to a free program could make it effectively proprietary. To prevent this, the +GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +## TERMS AND CONDITIONS + +### 0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this +License. Each licensee is addressed as “you”. “Licensees” and +“recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in +a fashion requiring copyright permission, other than the making of an exact copy. The +resulting work is called a “modified version” of the earlier work or a +work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on +the Program. + +To “propagate” a work means to do anything with it that, without +permission, would make you directly or secondarily liable for infringement under +applicable copyright law, except executing it on a computer or modifying a private +copy. Propagation includes copying, distribution (with or without modification), +making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through a computer +network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the +extent that it includes a convenient and prominently visible feature that (1) +displays an appropriate copyright notice, and (2) tells the user that there is no +warranty for the work (except to the extent that warranties are provided), that +licensees may convey the work under this License, and how to view a copy of this +License. If the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + +### 1. Source Code. + +The “source code” for a work means the preferred form of the work for +making modifications to it. “Object code” means any non-source form of a +work. + +A “Standard Interface” means an interface that either is an official +standard defined by a recognized standards body, or, in the case of interfaces +specified for a particular programming language, one that is widely used among +developers working in that language. + +The “System Libraries” of an executable work include anything, other than +the work as a whole, that (a) is included in the normal form of packaging a Major +Component, but which is not part of that Major Component, and (b) serves only to +enable use of the work with that Major Component, or to implement a Standard +Interface for which an implementation is available to the public in source code form. +A “Major Component”, in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system (if any) on which +the executable work runs, or a compiler used to produce the work, or an object code +interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the +source code needed to generate, install, and (for an executable work) run the object +code and to modify the work, including scripts to control those activities. However, +it does not include the work's System Libraries, or general-purpose tools or +generally available free programs which are used unmodified in performing those +activities but which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for the work, and +the source code for shared libraries and dynamically linked subprograms that the work +is specifically designed to require, such as by intimate data communication or +control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate +automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +### 2. Basic Permissions. + +All rights granted under this License are granted for the term of copyright on the +Program, and are irrevocable provided the stated conditions are met. This License +explicitly affirms your unlimited permission to run the unmodified Program. The +output from running a covered work is covered by this License only if the output, +given its content, constitutes a covered work. This License acknowledges your rights +of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without +conditions so long as your license otherwise remains in force. You may convey covered +works to others for the sole purpose of having them make modifications exclusively +for you, or provide you with facilities for running those works, provided that you +comply with the terms of this License in conveying all material for which you do not +control copyright. Those thus making or running the covered works for you must do so +exclusively on your behalf, under your direction and control, on terms that prohibit +them from making any copies of your copyrighted material outside their relationship +with you. + +Conveying under any other circumstances is permitted solely under the conditions +stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +### 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological measure under any +applicable law fulfilling obligations under article 11 of the WIPO copyright treaty +adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention +of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of +technological measures to the extent such circumvention is effected by exercising +rights under this License with respect to the covered work, and you disclaim any +intention to limit operation or modification of the work as a means of enforcing, +against the work's users, your or third parties' legal rights to forbid circumvention +of technological measures. + +### 4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you receive it, in any +medium, provided that you conspicuously and appropriately publish on each copy an +appropriate copyright notice; keep intact all notices stating that this License and +any non-permissive terms added in accord with section 7 apply to the code; keep +intact all notices of the absence of any warranty; and give all recipients a copy of +this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer +support or warranty protection for a fee. + +### 5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to produce it from +the Program, in the form of source code under the terms of section 4, provided that +you also meet all of these conditions: + +* **a)** The work must carry prominent notices stating that you modified it, and giving a +relevant date. +* **b)** The work must carry prominent notices stating that it is released under this +License and any conditions added under section 7. This requirement modifies the +requirement in section 4 to “keep intact all notices”. +* **c)** You must license the entire work, as a whole, under this License to anyone who +comes into possession of a copy. This License will therefore apply, along with any +applicable section 7 additional terms, to the whole of the work, and all its parts, +regardless of how they are packaged. This License gives no permission to license the +work in any other way, but it does not invalidate such permission if you have +separately received it. +* **d)** If the work has interactive user interfaces, each must display Appropriate Legal +Notices; however, if the Program has interactive interfaces that do not display +Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are +not by their nature extensions of the covered work, and which are not combined with +it such as to form a larger program, in or on a volume of a storage or distribution +medium, is called an “aggregate” if the compilation and its resulting +copyright are not used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work in an aggregate +does not cause this License to apply to the other parts of the aggregate. + +### 6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of sections 4 and +5, provided that you also convey the machine-readable Corresponding Source under the +terms of this License, in one of these ways: + +* **a)** Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by the Corresponding Source fixed on a +durable physical medium customarily used for software interchange. +* **b)** Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by a written offer, valid for at least +three years and valid for as long as you offer spare parts or customer support for +that product model, to give anyone who possesses the object code either (1) a copy of +the Corresponding Source for all the software in the product that is covered by this +License, on a durable physical medium customarily used for software interchange, for +a price no more than your reasonable cost of physically performing this conveying of +source, or (2) access to copy the Corresponding Source from a network server at no +charge. +* **c)** Convey individual copies of the object code with a copy of the written offer to +provide the Corresponding Source. This alternative is allowed only occasionally and +noncommercially, and only if you received the object code with such an offer, in +accord with subsection 6b. +* **d)** Convey the object code by offering access from a designated place (gratis or for +a charge), and offer equivalent access to the Corresponding Source in the same way +through the same place at no further charge. You need not require recipients to copy +the Corresponding Source along with the object code. If the place to copy the object +code is a network server, the Corresponding Source may be on a different server +(operated by you or a third party) that supports equivalent copying facilities, +provided you maintain clear directions next to the object code saying where to find +the Corresponding Source. Regardless of what server hosts the Corresponding Source, +you remain obligated to ensure that it is available for as long as needed to satisfy +these requirements. +* **e)** Convey the object code using peer-to-peer transmission, provided you inform +other peers where the object code and Corresponding Source of the work are being +offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the +Corresponding Source as a System Library, need not be included in conveying the +object code work. + +A “User Product” is either (1) a “consumer product”, which +means any tangible personal property which is normally used for personal, family, or +household purposes, or (2) anything designed or sold for incorporation into a +dwelling. In determining whether a product is a consumer product, doubtful cases +shall be resolved in favor of coverage. For a particular product received by a +particular user, “normally used” refers to a typical or common use of +that class of product, regardless of the status of the particular user or of the way +in which the particular user actually uses, or expects or is expected to use, the +product. A product is a consumer product regardless of whether the product has +substantial commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, +procedures, authorization keys, or other information required to install and execute +modified versions of a covered work in that User Product from a modified version of +its Corresponding Source. The information must suffice to ensure that the continued +functioning of the modified object code is in no case prevented or interfered with +solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for +use in, a User Product, and the conveying occurs as part of a transaction in which +the right of possession and use of the User Product is transferred to the recipient +in perpetuity or for a fixed term (regardless of how the transaction is +characterized), the Corresponding Source conveyed under this section must be +accompanied by the Installation Information. But this requirement does not apply if +neither you nor any third party retains the ability to install modified object code +on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to +continue to provide support service, warranty, or updates for a work that has been +modified or installed by the recipient, or for the User Product in which it has been +modified or installed. Access to a network may be denied when the modification itself +materially and adversely affects the operation of the network or violates the rules +and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with +this section must be in a format that is publicly documented (and with an +implementation available to the public in source code form), and must require no +special password or key for unpacking, reading or copying. + +### 7. Additional Terms. + +“Additional permissions” are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. Additional +permissions that are applicable to the entire Program shall be treated as though they +were included in this License, to the extent that they are valid under applicable +law. If additional permissions apply only to part of the Program, that part may be +used separately under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any +additional permissions from that copy, or from any part of it. (Additional +permissions may be written to require their own removal in certain cases when you +modify the work.) You may place additional permissions on material, added by you to a +covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a +covered work, you may (if authorized by the copyright holders of that material) +supplement the terms of this License with terms: + +* **a)** Disclaiming warranty or limiting liability differently from the terms of +sections 15 and 16 of this License; or +* **b)** Requiring preservation of specified reasonable legal notices or author +attributions in that material or in the Appropriate Legal Notices displayed by works +containing it; or +* **c)** Prohibiting misrepresentation of the origin of that material, or requiring that +modified versions of such material be marked in reasonable ways as different from the +original version; or +* **d)** Limiting the use for publicity purposes of names of licensors or authors of the +material; or +* **e)** Declining to grant rights under trademark law for use of some trade names, +trademarks, or service marks; or +* **f)** Requiring indemnification of licensors and authors of that material by anyone +who conveys the material (or modified versions of it) with contractual assumptions of +liability to the recipient, for any liability that these contractual assumptions +directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further +restrictions” within the meaning of section 10. If the Program as you received +it, or any part of it, contains a notice stating that it is governed by this License +along with a term that is a further restriction, you may remove that term. If a +license document contains a further restriction but permits relicensing or conveying +under this License, you may add to a covered work material governed by the terms of +that license document, provided that the further restriction does not survive such +relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in +the relevant source files, a statement of the additional terms that apply to those +files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a +separately written license, or stated as exceptions; the above requirements apply +either way. + +### 8. Termination. + +You may not propagate or modify a covered work except as expressly provided under +this License. Any attempt otherwise to propagate or modify it is void, and will +automatically terminate your rights under this License (including any patent licenses +granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a +particular copyright holder is reinstated (a) provisionally, unless and until the +copyright holder explicitly and finally terminates your license, and (b) permanently, +if the copyright holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently +if the copyright holder notifies you of the violation by some reasonable means, this +is the first time you have received notice of violation of this License (for any +work) from that copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of +parties who have received copies or rights from you under this License. If your +rights have been terminated and not permanently reinstated, you do not qualify to +receive new licenses for the same material under section 10. + +### 9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or run a copy of the +Program. Ancillary propagation of a covered work occurring solely as a consequence of +using peer-to-peer transmission to receive a copy likewise does not require +acceptance. However, nothing other than this License grants you permission to +propagate or modify any covered work. These actions infringe copyright if you do not +accept this License. Therefore, by modifying or propagating a covered work, you +indicate your acceptance of this License to do so. + +### 10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically receives a license +from the original licensors, to run, modify and propagate that work, subject to this +License. You are not responsible for enforcing compliance by third parties with this +License. + +An “entity transaction” is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an organization, or +merging organizations. If propagation of a covered work results from an entity +transaction, each party to that transaction who receives a copy of the work also +receives whatever licenses to the work the party's predecessor in interest had or +could give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if the predecessor +has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or +affirmed under this License. For example, you may not impose a license fee, royalty, +or other charge for exercise of rights granted under this License, and you may not +initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging +that any patent claim is infringed by making, using, selling, offering for sale, or +importing the Program or any portion of it. + +### 11. Patents. + +A “contributor” is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The work thus +licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or +controlled by the contributor, whether already acquired or hereafter acquired, that +would be infringed by some manner, permitted by this License, of making, using, or +selling its contributor version, but do not include claims that would be infringed +only as a consequence of further modification of the contributor version. For +purposes of this definition, “control” includes the right to grant patent +sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license +under the contributor's essential patent claims, to make, use, sell, offer for sale, +import and otherwise run, modify and propagate the contents of its contributor +version. + +In the following three paragraphs, a “patent license” is any express +agreement or commitment, however denominated, not to enforce a patent (such as an +express permission to practice a patent or covenant not to sue for patent +infringement). To “grant” such a patent license to a party means to make +such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the +Corresponding Source of the work is not available for anyone to copy, free of charge +and under the terms of this License, through a publicly available network server or +other readily accessible means, then you must either (1) cause the Corresponding +Source to be so available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner consistent with +the requirements of this License, to extend the patent license to downstream +recipients. “Knowingly relying” means you have actual knowledge that, but +for the patent license, your conveying the covered work in a country, or your +recipient's use of the covered work in a country, would infringe one or more +identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you +convey, or propagate by procuring conveyance of, a covered work, and grant a patent +license to some of the parties receiving the covered work authorizing them to use, +propagate, modify or convey a specific copy of the covered work, then the patent +license you grant is automatically extended to all recipients of the covered work and +works based on it. + +A patent license is “discriminatory” if it does not include within the +scope of its coverage, prohibits the exercise of, or is conditioned on the +non-exercise of one or more of the rights that are specifically granted under this +License. You may not convey a covered work if you are a party to an arrangement with +a third party that is in the business of distributing software, under which you make +payment to the third party based on the extent of your activity of conveying the +work, and under which the third party grants, to any of the parties who would receive +the covered work from you, a discriminatory patent license (a) in connection with +copies of the covered work conveyed by you (or copies made from those copies), or (b) +primarily for and in connection with specific products or compilations that contain +the covered work, unless you entered into that arrangement, or that patent license +was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied +license or other defenses to infringement that may otherwise be available to you +under applicable patent law. + +### 12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or otherwise) +that contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot convey a covered work so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not convey it at all. For example, if you +agree to terms that obligate you to collect a royalty for further conveying from +those to whom you convey the Program, the only way you could satisfy both those terms +and this License would be to refrain entirely from conveying the Program. + +### 13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have permission to link or +combine any covered work with a work licensed under version 3 of the GNU Affero +General Public License into a single combined work, and to convey the resulting work. +The terms of this License will continue to apply to the part which is the covered +work, but the special requirements of the GNU Affero General Public License, section +13, concerning interaction through a network will apply to the combination as such. + +### 14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of the GNU +General Public License from time to time. Such new versions will be similar in spirit +to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that +a certain numbered version of the GNU General Public License “or any later +version” applies to it, you have the option of following the terms and +conditions either of that numbered version or of any later version published by the +Free Software Foundation. If the Program does not specify a version number of the GNU +General Public License, you may choose any version ever published by the Free +Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU +General Public License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no +additional obligations are imposed on any author or copyright holder as a result of +your choosing to follow a later version. + +### 15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE +QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE +DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +### 16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY +COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS +PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, +INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE +OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE +WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +### 17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided above cannot be +given local legal effect according to their terms, reviewing courts shall apply local +law that most closely approximates an absolute waiver of all civil liability in +connection with the Program, unless a warranty or assumption of liability accompanies +a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +## How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to +the public, the best way to achieve this is to make it free software which everyone +can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them +to the start of each source file to most effectively state the exclusion of warranty; +and each file should have at least the “copyright” line and a pointer to +where the full notice is found. + + mcinject - makes developing minecraft mods easier than ever + Copyright (C) 2013 Jordan Doyle + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this +when it starts in an interactive mode: + + mcinject Copyright (C) 2013 Jordan Doyle + This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate parts of +the General Public License. Of course, your program's commands might be different; +for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to +sign a “copyright disclaimer” for the program, if necessary. For more +information on this, and how to apply and follow the GNU GPL, see +<>. + +The GNU General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may consider it +more useful to permit linking proprietary applications with the library. If this is +what you want to do, use the GNU Lesser General Public License instead of this +License. But first, please read +<>. diff --git a/README b/README new file mode 100644 index 0000000..7a04e74 --- /dev/null +++ b/README @@ -0,0 +1,4 @@ +Written in early 2013 by a young https://github.com/w4, to have a go +at injecting code into an obfuscated game using ASM and reflection. + +ASM: https://asm.ow2.io/ diff --git a/src/io/github/jordandoyle/helpers/classloader/Loader.java b/src/io/github/jordandoyle/helpers/classloader/Loader.java new file mode 100644 index 0000000..8466a08 --- /dev/null +++ b/src/io/github/jordandoyle/helpers/classloader/Loader.java @@ -0,0 +1,103 @@ +package io.github.jordandoyle.helpers.classloader; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Vector; + +import org.apache.commons.io.FilenameUtils; + +/** + * This class helps you load JARs and folders onto the system classloader. This + * makes the classloader also look through these JAR files (or folders) for + * classes. + * + * @author Jordan Doyle + * + */ +public class Loader { + /** + * Adds a JAR file to the classpath + * + * @param f + * Link to JAR File + * @throws Exception + */ + public static void addJar(String f) throws Exception { + addJar(new File(f)); + } + + /** + * Adds a JAR file to the classpath + * + * @param f + * Link to JAR File + * @throws Exception + */ + public static void addJar(File f) throws Exception { + String ext = FilenameUtils.getExtension(f.getName()); + + if (ext == "") + throw new Exception("Could not find extension of file"); + + if (ext.toLowerCase() != "jar") + throw new Exception("Cannot inject non-jar file into classpath"); + + addURL(f.toURI().toURL()); + } + + /** + * This method allows you add a folder to the classpath + * + * @param u + * URL to add to the classpath + * @throws Exception + */ + public static void addURL(URL u) throws Exception { + File f = new File(u.toURI()); + + if (!f.isDirectory() + && !FilenameUtils.getExtension(f.getName()).equalsIgnoreCase( + "jar")) { + throw new Exception( + "addURL requires a directory to add to classpath"); + } + + Method m = URLClassLoader.class.getDeclaredMethod("addURL", + new Class[] { URL.class }); + m.setAccessible(true); + + m.invoke(ClassLoader.getSystemClassLoader(), new Object[] { u }); + } + + /** + * Returns all classes loaded in the system class loader + * + * @return all loaded classes + * @throws Exception + */ + public static Vector getAllClasses(ClassLoader classLoader) + throws Exception { + Field f = ClassLoader.class.getDeclaredField("classes"); + f.setAccessible(true); + + Vector classes = (Vector) f.get(classLoader); + + return classes; + } + + /** + * Returns all classes loaded in the system class loader + * + * @return all loaded classes + * @throws Exception + */ + public static Vector getAllClasses() throws Exception { + return getAllClasses(ClassLoader.getSystemClassLoader()); + } +} diff --git a/src/io/github/jordandoyle/helpers/classloader/package-info.java b/src/io/github/jordandoyle/helpers/classloader/package-info.java new file mode 100644 index 0000000..d7ba9be --- /dev/null +++ b/src/io/github/jordandoyle/helpers/classloader/package-info.java @@ -0,0 +1,4 @@ +/** + * io.github.jordandoyle.helpers.classloader is a collection of classes to assist in loading classes to the system classloader + */ +package io.github.jordandoyle.helpers.classloader; \ No newline at end of file diff --git a/src/io/github/jordandoyle/helpers/reflection/Mapping.java b/src/io/github/jordandoyle/helpers/reflection/Mapping.java new file mode 100644 index 0000000..314153b --- /dev/null +++ b/src/io/github/jordandoyle/helpers/reflection/Mapping.java @@ -0,0 +1,214 @@ +package io.github.jordandoyle.helpers.reflection; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.io.Resources; + +import au.com.bytecode.opencsv.CSVReader; + +/** + * This class helps you use reflection and ASM in Minecraft. + * + * It will provide you with tools to get obfuscated/compiled names for methods, + * classes and fields. + * + * + * @author Jordan Doyle + * + */ +public class Mapping { + private static List fields, methods, obfuscated; + + static { + // Fields + try { + CSVReader reader = new CSVReader(new InputStreamReader(Resources + .getResource("fields.csv").openStream())); + fields = reader.readAll(); + reader.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + // Methods + try { + CSVReader reader = new CSVReader(new InputStreamReader(Resources + .getResource("methods.csv").openStream())); + methods = reader.readAll(); + reader.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + // Packaged + try { + InputStream stream = Resources.getResource("client.srg") + .openStream(); + + StringBuilder sb = new StringBuilder(); + String line; + + BufferedReader br = new BufferedReader( + new InputStreamReader(stream)); + + obfuscated = new ArrayList(); + + while ((line = br.readLine()) != null) { + String[] l = line.split("\\s+"); + obfuscated.add(l); + } + + br.close(); + stream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Returns the compiled name of a field + * + * @param f + * The name of the uncompiled field + * @return The compiled name of a field + */ + public static String getCompiledField(String f) { + for (String[] field : fields) { + if (field[1].equals(f)) { + return field[0]; + } + } + + return f; + } + + /** + * Returns the compiled name of a method + * + * @param m + * The name of the uncompiled method + * @return The compiled name of a method + */ + public static String getCompiledMethod(String m) { + for (String[] method : methods) { + if (method[1].equals(m)) { + return method[0]; + } + } + + return m; + } + + /** + * Returns the obfuscated name of a class + * + * @param c + * The class of which you require the obfuscated name for + * @return The obfuscated name of a class + */ + public static String getMappedClass(String c) { + String name = c.replace(".", "/"); + + for (String[] obf : obfuscated) { + if (obf[0].startsWith("CL") && obf[2].equals(name)) { + return obf[1]; + } + } + + return c; + } + + /** + * Returns the obfuscated name of a method + * + * @param c + * The class of which the method is contained + * @param m + * The name of the unobfuscated method + * @return The obfuscated name of a method + */ + public static String getMappedMethod(String c, String m) { + return getMappedMethod(c, m, null, null); + } + + /** + * + * @param c + * The class of which the method is contained + * @param m + * The name of the unobfuscated method + * @param d + * The decompiled descriptor types for the method + * @param od + * The compiled descriptor types for the method + * @return The obfuscated name of a method + */ + public static String getMappedMethod(String c, String m, String d, String od) { + String name = c.replace(".", "/"); + + String methodName = getCompiledMethod(m); + + if (methodName == null) + methodName = m; + + for (String[] obf : obfuscated) { + if (obf[0].startsWith("MD") && obf[1].startsWith(getMappedClass(c)) + && obf[3].equals(name + "/" + methodName)) { + if (od != null) + if (!obf[2].equals(od)) + return methodName; + + if (d != null) + if (!obf[4].equals(d)) + return methodName; + + String method = obf[1].substring(StringUtils + .length(getMappedClass(c) + "/")); + return method; + } + } + + return methodName; + } + + /** + * Returns the obfuscated name of a field + * + * @param c + * The class of which the variable is contained + * @param f + * The name of the unobfuscated field + * @return The obfuscated name of a field + */ + public static String getMappedField(String className, String f) { + String name = className.replace(".", "/"); + + String fieldName = getCompiledField(f); + + if (fieldName == null) + fieldName = f; + + for (String[] obf : obfuscated) { + if (obf[0].startsWith("FD") + && obf[1].startsWith(getMappedClass(className)) + && obf[2].equals(name + "/" + fieldName)) { + String field = obf[1].substring(StringUtils + .length(getMappedClass(className) + "/")); + return field; + } + } + + return fieldName; + } +} \ No newline at end of file diff --git a/src/io/github/jordandoyle/helpers/reflection/Package.java b/src/io/github/jordandoyle/helpers/reflection/Package.java new file mode 100644 index 0000000..6db9bac --- /dev/null +++ b/src/io/github/jordandoyle/helpers/reflection/Package.java @@ -0,0 +1,79 @@ +package io.github.jordandoyle.helpers.reflection; + +import io.github.jordandoyle.helpers.classloader.Loader; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + +/** + * This class provides you with package functions to better manage your packages + * and perform functions such as retrieving all classes from a package and more. + * + * @author Jordan Doyle + * + */ +public class Package { + /** + * Returns all the classes from a package + * + * @param p + * The Package object to get classes from + * @return all classes from a Package object + * @throws Exception + */ + public static List getClassesInPackage(java.lang.Package p, ClassLoader classLoader) + throws Exception { + return getClassesInPackage(p.getName(), classLoader); + } + + /** + * Returns all the classes from a package + * + * @param p + * The Package object to get classes from + * @return all classes from a Package object + * @throws Exception + */ + public static List getClassesInPackage(java.lang.Package p) + throws Exception { + return getClassesInPackage(p.getName()); + } + + /** + * Returns all the classes from a package + * + * @param name + * The fully-qualified name of the package + * @return all the classes from a package + * @throws Exception + */ + public static List getClassesInPackage(String name) throws Exception { + return getClassesInPackage(name, ClassLoader.getSystemClassLoader()); + } + + /** + * Returns all the classes from a package + * + * @param name + * The fully-qualified name of the package + * @return all the classes from a package + * @throws Exception + */ + public static List getClassesInPackage(String name, ClassLoader classLoader) throws Exception { + Vector classes = Loader.getAllClasses(classLoader); + + List inPackage = new ArrayList(); + + for (Class c : classes) { + java.lang.Package p = c.getPackage(); + + if (p != null && p.getName() != null + && p.getName().startsWith(name)) + inPackage.add(c); + } + + return inPackage; + } +} diff --git a/src/io/github/jordandoyle/helpers/reflection/package-info.java b/src/io/github/jordandoyle/helpers/reflection/package-info.java new file mode 100644 index 0000000..fd8e62e --- /dev/null +++ b/src/io/github/jordandoyle/helpers/reflection/package-info.java @@ -0,0 +1,4 @@ +/** + * io.github.jordandoyle.helpers.reflection is a collection of classes to assist in reflection and ASM + */ +package io.github.jordandoyle.helpers.reflection; \ No newline at end of file diff --git a/src/io/github/jordandoyle/mcinject/Main.java b/src/io/github/jordandoyle/mcinject/Main.java new file mode 100644 index 0000000..5cef2aa --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/Main.java @@ -0,0 +1,80 @@ +package io.github.jordandoyle.mcinject; + +import io.github.jordandoyle.mcinject.asm.TransformerManager; +import io.github.jordandoyle.mcinject.handler.HandlerManager; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FileUtils; + +import net.lingala.zip4j.core.ZipFile; +import net.lingala.zip4j.model.FileHeader; +import net.minecraft.src.Minecraft; + +public class Main { + private static Main instance = null; + public static final String VERSION = "Alpha 2"; + public static File minecraft; + + public void start() { + TransformerManager.runTransformers(); + HandlerManager.registerHandlers(); + } + + public static Main downloadDependencies(File f) { + System.out.println("[mcinject] Downloading dependencies"); + minecraft = f; + try { + URL font = new URL("https://cdn.jsdelivr.net/npm/roboto-font@0.1.0/fonts/Roboto/roboto-thin-webfont.ttf"); + File localFont = new File(f, "mcinject"); + localFont.mkdirs(); + + FileUtils.copyURLToFile(font, new File(localFont, "font.ttf")); + + URL u = new URL("http://mcinject.uphero.com/deps.zip"); + String tmp = System.getProperty("java.io.tempdir"); + String path = tmp + "injection_deps.zip"; + File c = new File(path); + c.deleteOnExit(); + FileUtils.copyURLToFile(u, c); + + ZipFile file = new ZipFile(c); + + File folder = new File(minecraft, "mcinject/deps"); + + file.extractAll(folder.getPath()); + + URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); + Class sysclass = URLClassLoader.class; + Method method = sysclass.getDeclaredMethod("addURL", new Class[] { URL.class }); + method.setAccessible(true); + + for (Object entry : file.getFileHeaders()) { + FileHeader h = (FileHeader) entry; + File jar = new File(folder, h.getFileName()); + + System.out.println("[mcinject] Injected " + h.getFileName() + " into system class loader"); + + method.invoke(sysloader, new Object[] { jar.toURI().toURL() }); + } + } catch(Exception e) { + e.printStackTrace(); + } + + return Main.getInstance(); + } + + public static Main getInstance() { + if(instance == null) + instance = new Main(); + + return instance; + } + +} diff --git a/src/io/github/jordandoyle/mcinject/Wrapper.java b/src/io/github/jordandoyle/mcinject/Wrapper.java new file mode 100644 index 0000000..a5a93a4 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/Wrapper.java @@ -0,0 +1,51 @@ +package io.github.jordandoyle.mcinject; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import io.github.jordandoyle.mcinject.gui.FontRenderer; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; +import io.github.jordandoyle.mcinject.proxy.interfaces.EntityPlayerSP; +import io.github.jordandoyle.mcinject.proxy.interfaces.Minecraft; +import io.github.jordandoyle.mcinject.proxy.proxies.EntityPlayerSPProxy; +import io.github.jordandoyle.mcinject.proxy.proxies.MinecraftProxy; + +public class Wrapper { + private static FontRenderer fontRenderer = null; + private static Minecraft minecraft = null; + private static EntityPlayerSP player; + + public static FontRenderer getFontRenderer() { + if(fontRenderer == null) + fontRenderer = new FontRenderer(); + + return fontRenderer; + } + + public static Minecraft getMinecraft() { + if(minecraft == null) + minecraft = (Minecraft) new MinecraftProxy().proxy(); + + return minecraft; + } + + public static EntityPlayerSP getPlayer() { + if(player == null) + player = (EntityPlayerSP) new EntityPlayerSPProxy().proxy(); + + return player; + } + + public static void sendPacket(Object o) { + //net.minecraft.src.Minecraft.getMinecraft().getNetHandler().addToSendQueue(o); + Object mc = getMinecraft().getMinecraft(); + try { + Method netHandler = mc.getClass().getMethod(new ObfuscatedMapping("net/minecraft/src/Minecraft", "getNetHandler", "(").getMapping()); + Object nh = netHandler.invoke(mc); + Method sendQueue = nh.getClass().getMethod(new ObfuscatedMapping("net/minecraft/src/NetClientHandler", "addToSendQueue", "(").getMapping(), Class.forName(new ObfuscatedMapping("net/minecraft/src/Packet").getMapping())); + sendQueue.invoke(nh, o); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/io/github/jordandoyle/mcinject/asm/ClassTransformer.java b/src/io/github/jordandoyle/mcinject/asm/ClassTransformer.java new file mode 100644 index 0000000..527c0f6 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/asm/ClassTransformer.java @@ -0,0 +1,29 @@ +package io.github.jordandoyle.mcinject.asm; + +public abstract class ClassTransformer { + public abstract void transform(); + + protected Class loadClass(byte[] b, String className) { + Class clazz = null; + try { + ClassLoader loader = ClassLoader.getSystemClassLoader(); + Class cls = Class.forName("java.lang.ClassLoader"); + java.lang.reflect.Method method = cls.getDeclaredMethod( + "defineClass", new Class[] { String.class, byte[].class, + int.class, int.class }); + + method.setAccessible(true); + try { + Object[] args = new Object[] { className, b, new Integer(0), + new Integer(b.length) }; + clazz = (Class) method.invoke(loader, args); + } finally { + method.setAccessible(false); + } + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + return clazz; + } +} diff --git a/src/io/github/jordandoyle/mcinject/asm/TransformerManager.java b/src/io/github/jordandoyle/mcinject/asm/TransformerManager.java new file mode 100644 index 0000000..2e3bc58 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/asm/TransformerManager.java @@ -0,0 +1,22 @@ +package io.github.jordandoyle.mcinject.asm; + +import java.util.ArrayList; +import java.util.List; + +import io.github.jordandoyle.mcinject.asm.transformers.*; + +public class TransformerManager { + private static List transformers = new ArrayList(); + + static { + transformers.add(new InGameTransformer()); + transformers.add(new MinecraftTransformer()); + transformers.add(new EntityRendererTransformer()); + transformers.add(new EntityPlayerTransformer()); + } + + public static void runTransformers() { + for(ClassTransformer transformer : transformers) + transformer.transform(); + } +} diff --git a/src/io/github/jordandoyle/mcinject/asm/transformers/EntityPlayerTransformer.java b/src/io/github/jordandoyle/mcinject/asm/transformers/EntityPlayerTransformer.java new file mode 100644 index 0000000..c7ba180 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/asm/transformers/EntityPlayerTransformer.java @@ -0,0 +1,76 @@ +package io.github.jordandoyle.mcinject.asm.transformers; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.VarInsnNode; + +import io.github.jordandoyle.mcinject.asm.ClassTransformer; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; + +public class EntityPlayerTransformer extends ClassTransformer { + + @Override + public void transform() { + ObfuscatedMapping cl = new ObfuscatedMapping("net/minecraft/src/EntityPlayer"); + + InputStream in = getClass().getResourceAsStream("/" + cl.toString().replace(".", "/") + ".class"); + + // mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/src/EntityPlayer", "applyArmorCalculations", "(Lnet/minecraft/src/DamageSource;F)F"); + + try { + ClassReader cr = new ClassReader(in); + ClassNode cn = new ClassNode(); + cr.accept(cn, 0); + + for (MethodNode mn : cn.methods) { + if (!mn.name.equals(new ObfuscatedMapping("net/minecraft/src/EntityLivingBase", "damageEntity", "(").getMapping())) + continue; + + Iterator insnNodes = mn.instructions + .iterator(); + + while (insnNodes.hasNext()) { + AbstractInsnNode insn = insnNodes.next(); + + if (insn.getType() == insn.METHOD_INSN) { + MethodInsnNode node = (MethodInsnNode) insn; + + // TODO: Fix ObfuscatedMapping to work with obfuscated parameter types + if (node.name.equals(new ObfuscatedMapping("net/minecraft/src/EntityLivingBase", "applyArmorCalculations", "(").getMapping())) { + InsnList list = new InsnList(); + + list.add(new VarInsnNode(Opcodes.ALOAD, 1)); + list.add(new VarInsnNode(Opcodes.FLOAD, 2)); + list.add(new MethodInsnNode( + Opcodes.INVOKESTATIC, + "io/github/jordandoyle/mcinject/event/EventFactory", + "damageEntity", "(Ljava/lang/Object;F)V")); + + mn.instructions.insert(insn, list); + } + } + } + } + + ClassWriter cw = new ClassWriter(0); + cn.accept(cw); + + loadClass(cw.toByteArray(), new ObfuscatedMapping("net/minecraft/src/EntityPlayer").getMapping()); + + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/io/github/jordandoyle/mcinject/asm/transformers/EntityRendererTransformer.java b/src/io/github/jordandoyle/mcinject/asm/transformers/EntityRendererTransformer.java new file mode 100644 index 0000000..f6d71fb --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/asm/transformers/EntityRendererTransformer.java @@ -0,0 +1,75 @@ +package io.github.jordandoyle.mcinject.asm.transformers; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +import io.github.jordandoyle.mcinject.asm.ClassTransformer; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; + +public class EntityRendererTransformer extends ClassTransformer { + + @Override + public void transform() { + ObfuscatedMapping cl = new ObfuscatedMapping("net/minecraft/src/EntityRenderer"); + ObfuscatedMapping renderWorld = new ObfuscatedMapping("net/minecraft/src/EntityRenderer", "renderWorld", "(FJ)V"); + ObfuscatedMapping renderHand = new ObfuscatedMapping("net/minecraft/src/EntityRenderer", "renderHand", "(FI)V"); + + InputStream in = getClass().getResourceAsStream("/" + cl.toString().replace(".", "/") + ".class"); + + // mv.visitMethodInsn(INVOKESPECIAL, "net/minecraft/src/EntityRenderer", "renderHand", "(FI)V"); + + try { + ClassReader cr = new ClassReader(in); + ClassNode cn = new ClassNode(); + cr.accept(cn, 0); + + for (MethodNode mn : cn.methods) { + if (!renderWorld.equals(mn)) + continue; + + Iterator insnNodes = mn.instructions + .iterator(); + + while (insnNodes.hasNext()) { + AbstractInsnNode insn = insnNodes.next(); + + if (insn.getType() == insn.METHOD_INSN) { + MethodInsnNode node = (MethodInsnNode) insn; + + if (renderHand.equals(node)) { + InsnList list = new InsnList(); + + list.add(new MethodInsnNode( + Opcodes.INVOKESTATIC, + "io/github/jordandoyle/mcinject/event/EventFactory", + "renderHand", "()V")); + + mn.instructions.insertBefore(insn, list); + } + } + } + } + + ClassWriter cw = new ClassWriter(0); + cn.accept(cw); + + loadClass(cw.toByteArray(), new ObfuscatedMapping("net/minecraft/src/EntityRenderer").getMapping()); + + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/io/github/jordandoyle/mcinject/asm/transformers/InGameTransformer.java b/src/io/github/jordandoyle/mcinject/asm/transformers/InGameTransformer.java new file mode 100644 index 0000000..4d09ca1 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/asm/transformers/InGameTransformer.java @@ -0,0 +1,79 @@ +package io.github.jordandoyle.mcinject.asm.transformers; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import javax.swing.JOptionPane; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.InsnNode; +import org.objectweb.asm.tree.LabelNode; +import org.objectweb.asm.tree.LdcInsnNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.TypeInsnNode; +import org.objectweb.asm.tree.VarInsnNode; + +import io.github.jordandoyle.mcinject.asm.*; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; + +public class InGameTransformer extends ClassTransformer { + + public void transform() { + ObfuscatedMapping cl = new ObfuscatedMapping("net/minecraft/src/GuiIngame"); + ObfuscatedMapping renderOverlay = new ObfuscatedMapping("net/minecraft/src/GuiIngame", "renderGameOverlay", Type.getMethodDescriptor(Type.VOID_TYPE, Type.FLOAT_TYPE, Type.BOOLEAN_TYPE, Type.INT_TYPE, Type.INT_TYPE)); + ObfuscatedMapping gameSettings = new ObfuscatedMapping("net/minecraft/src/GameSettings", "showDebugInfo"); + + InputStream in = getClass().getResourceAsStream("/" + cl.toString().replace(".", "/") + ".class"); + + try { + ClassReader cr = new ClassReader(in); + ClassNode cn = new ClassNode(); + cr.accept(cn, 0); + + for (MethodNode mn : cn.methods) { + if (!renderOverlay.equals(mn)) + continue; + + Iterator insnNodes = mn.instructions + .iterator(); + + while (insnNodes.hasNext()) { + AbstractInsnNode insn = insnNodes.next(); + + if (insn.getType() == insn.FIELD_INSN) { + FieldInsnNode node = (FieldInsnNode) insn; + + if (gameSettings.equals(node)) { + InsnList list = new InsnList(); + + list.add(new MethodInsnNode( + Opcodes.INVOKESTATIC, + "io/github/jordandoyle/mcinject/event/EventFactory", + "renderOverlay", "()V")); + + mn.instructions.insertBefore(insn, list); + } + } + } + break; + } + + ClassWriter cw = new ClassWriter(0); + cn.accept(cw); + + loadClass(cw.toByteArray(), new ObfuscatedMapping("net/minecraft/src/GuiIngame").getMapping()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/io/github/jordandoyle/mcinject/asm/transformers/MinecraftTransformer.java b/src/io/github/jordandoyle/mcinject/asm/transformers/MinecraftTransformer.java new file mode 100644 index 0000000..db2b931 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/asm/transformers/MinecraftTransformer.java @@ -0,0 +1,108 @@ +package io.github.jordandoyle.mcinject.asm.transformers; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.VarInsnNode; + +import io.github.jordandoyle.mcinject.asm.ClassTransformer; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; + +public class MinecraftTransformer extends ClassTransformer { + + @Override + public void transform() { + ObfuscatedMapping cl = new ObfuscatedMapping( + "net/minecraft/src/Minecraft"); + ObfuscatedMapping runTick = new ObfuscatedMapping( + "net/minecraft/src/Minecraft", "runTick", "()V"); + ObfuscatedMapping updateController = new ObfuscatedMapping( + "net/minecraft/src/PlayerControllerMP", "updateController", + "()V"); + + InputStream in = getClass().getResourceAsStream( + "/" + cl.toString().replace(".", "/") + ".class"); + + try { + ClassReader cr = new ClassReader(in); + ClassNode cn = new ClassNode(); + cr.accept(cn, 0); + + boolean keyHooked = false; + + for (MethodNode mn : cn.methods) { + if (!runTick.equals(mn)) + continue; + + Iterator insnNodes = mn.instructions + .iterator(); + + while (insnNodes.hasNext()) { + AbstractInsnNode insn = insnNodes.next(); + + if (insn.getType() == insn.METHOD_INSN) { + MethodInsnNode node = (MethodInsnNode) insn; + + if (updateController.equals(node)) { + InsnList list = new InsnList(); + + list.add(new MethodInsnNode( + Opcodes.INVOKESTATIC, + "io/github/jordandoyle/mcinject/event/EventFactory", + "runTick", "()V")); + + mn.instructions.insertBefore(insn, list); + } + + if (node.owner.equals("org/lwjgl/input/Keyboard") + && node.name.equals("getEventKeyState") + && node.desc.equals("()Z") + && !keyHooked) { + keyHooked = true; + + InsnList list = new InsnList(); + + list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, + "org/lwjgl/input/Keyboard", "getEventKey", + "()I")); + list.add(new VarInsnNode(Opcodes.ISTORE, 1)); + list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, + "org/lwjgl/input/Keyboard", + "getEventKeyState", "()Z")); + list.add(new VarInsnNode(Opcodes.ISTORE, 2)); + list.add(new VarInsnNode(Opcodes.ILOAD, 1)); + list.add(new VarInsnNode(Opcodes.ILOAD, 2)); + list.add(new MethodInsnNode( + Opcodes.INVOKESTATIC, + "io/github/jordandoyle/mcinject/event/EventFactory", + "onKeyPressed", "(IZ)V")); + + mn.instructions.insertBefore(insn, list); + } + } + } + } + + ClassWriter cw = new ClassWriter(0); + cn.accept(cw); + + loadClass(cw.toByteArray(), new ObfuscatedMapping( + "net/minecraft/src/Minecraft").getMapping()); + + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/io/github/jordandoyle/mcinject/event/Event.java b/src/io/github/jordandoyle/mcinject/event/Event.java new file mode 100644 index 0000000..5fc414b --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/Event.java @@ -0,0 +1,4 @@ +package io.github.jordandoyle.mcinject.event; + +public abstract class Event { +} diff --git a/src/io/github/jordandoyle/mcinject/event/EventFactory.java b/src/io/github/jordandoyle/mcinject/event/EventFactory.java new file mode 100644 index 0000000..58f43fe --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/EventFactory.java @@ -0,0 +1,31 @@ +package io.github.jordandoyle.mcinject.event; + +import java.lang.reflect.Field; + +import org.lwjgl.input.Keyboard; + +import io.github.jordandoyle.mcinject.event.events.*; + +public final class EventFactory { + public static void renderOverlay() { + EventHandler.getInstance().triggerEvent(new EventRenderOverlay()); + } + + public static void runTick() { + EventHandler.getInstance().triggerEvent(new EventTick()); + } + + + public static void onKeyPressed(int eventKey, boolean keyState) { + EventHandler.getInstance().triggerEvent(new EventKeyPressed(eventKey, keyState)); + } + + public static void renderHand() { + // TODO: Implement partial ticks + EventHandler.getInstance().triggerEvent(new EventRenderHand()); + } + + public static void damageEntity(Object source, float amount) { + EventHandler.getInstance().triggerEvent(new EventDamageEntity(source, amount)); + } +} diff --git a/src/io/github/jordandoyle/mcinject/event/EventHandler.java b/src/io/github/jordandoyle/mcinject/event/EventHandler.java new file mode 100644 index 0000000..0a8397a --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/EventHandler.java @@ -0,0 +1,179 @@ +package io.github.jordandoyle.mcinject.event; + +import io.github.jordandoyle.mcinject.Main; +import io.github.jordandoyle.mcinject.Wrapper; +import io.github.jordandoyle.mcinject.event.events.EventRenderOverlay; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; +import io.github.jordandoyle.mcinject.mod.Mod; +import io.github.jordandoyle.mcinject.mod.ModManager; +import io.github.jordandoyle.mcinject.proxy.interfaces.Minecraft; + +import java.awt.Font; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.lwjgl.opengl.GL11; +import org.newdawn.slick.UnicodeFont; + +/** + * Handles everything to do with events + * + * @author Jordan Doyle + * + */ +public class EventHandler implements Listener { + private List listeners = new CopyOnWriteArrayList(); + + /** + * Singleton instance of this class + */ + private static EventHandler instance; + + static { + try { + instance = EventHandler.class.newInstance(); + instance.registerListener(instance); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Gets the singleton instance of this class + * + * @return singleton instance of this class + */ + public static EventHandler getInstance() { + return instance; + } + + public Field gameSettings; + + private Field guiScale, + displayWidth; + + public Field debug; + + private float titlePosition = -150; + private Map positions = new HashMap(); + + @EventSubscribe + public void renderOverlay(EventRenderOverlay e) { + // TODO: yeah, I should probably move this into its own class + try { + Minecraft mc = Wrapper.getMinecraft(); + + if(gameSettings == null) + gameSettings = mc.getMinecraft().getClass().getField(new ObfuscatedMapping("net/minecraft/src/Minecraft", "gameSettings").getMapping()); + + Object settings = gameSettings.get(mc.getMinecraft()); + + if(debug == null) + debug = settings.getClass().getField(new ObfuscatedMapping("net/minecraft/src/GameSettings", "showDebugInfo").getMapping()); + + if(displayWidth == null) + displayWidth = mc.getMinecraft().getClass().getField(new ObfuscatedMapping("net/minecraft/src/Minecraft", "displayWidth").getMapping()); + + int width = displayWidth.getInt(mc.getMinecraft()); + int nextPosition = 0; + + if(!debug.getBoolean(settings)) { + if(Math.round(titlePosition) != 2) { + titlePosition += 0.5; + } + + Wrapper.getFontRenderer().drawStringWithShadow("mcinject \u00a76" + Main.VERSION, titlePosition, 2, 0xffffff); + + for(Mod m : ModManager.getMods()) { + if(m.isEnabled()) { + if(!positions.containsKey(m.getName())) + positions.put(m.getName(), Wrapper.getFontRenderer().getWidth(m.getName()) + 2); + + if(Math.round(positions.get(m.getName())) != -2) + positions.put(m.getName(), positions.get(m.getName()) - 0.5F); + + Wrapper.getFontRenderer().drawStringWithShadow(m.getName(), width / 2 - Wrapper.getFontRenderer().getWidth(m.getName()) + positions.get(m.getName()), nextPosition + 2, 0xffffff); + nextPosition += Wrapper.getFontRenderer().getHeight(m.getName()); + } else { + if(!positions.containsKey(m.getName())) + continue; + + if(Math.round(positions.get(m.getName())) != Math.round(Wrapper.getFontRenderer().getWidth(m.getName()) + 2)) { + positions.put(m.getName(), positions.get(m.getName()) + 0.5F); + Wrapper.getFontRenderer().drawStringWithShadow(m.getName(), width / 2 - Wrapper.getFontRenderer().getWidth(m.getName()) + positions.get(m.getName()), nextPosition + 2, 0xffffff); + nextPosition += Wrapper.getFontRenderer().getHeight(m.getName()); + } else + positions.remove(m.getName()); + } + } + } + + if(guiScale == null) + guiScale = settings.getClass().getField(new ObfuscatedMapping("net/minecraft/src/GameSettings", "guiScale").getMapping()); + + guiScale.setInt(settings, 2); + } catch(Exception ex) { + ex.printStackTrace(); + } + } + + /** + * Registers a listener + * + * @param l An instance of a class that extends Listener + */ + public void registerListener(Listener l) { + if(listeners.contains(l)) return; + + listeners.add(l); + } + + /** + * Unregisters a listener + * + * @param l An instance of a class that extends Listener + */ + public void unregisterListener(Listener l) { + if(!listeners.contains(l)) return; + + listeners.remove(l); + } + + /** + * Passes an event to all registered listeners + * + * @param e Event that will be sent to listeners + */ + private void alertListeners(Event e) { + for(Listener listener : listeners) { + for(Method m : listener.getClass().getMethods()) { + if (m.getParameterTypes().length > 0 + && m.isAnnotationPresent(EventSubscribe.class) + && m.getParameterTypes()[0].isAssignableFrom(e.getClass())) + try { + m.setAccessible(true); + m.invoke(listener, e); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + } + } + + /** + * Fires an event to all listeners + * + * @param e an instance of an event + */ + public void triggerEvent(Event e) { + alertListeners(e); + } +} diff --git a/src/io/github/jordandoyle/mcinject/event/EventSubscribe.java b/src/io/github/jordandoyle/mcinject/event/EventSubscribe.java new file mode 100644 index 0000000..8dac62a --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/EventSubscribe.java @@ -0,0 +1,13 @@ +package io.github.jordandoyle.mcinject.event; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.RetentionPolicy.*; +import static java.lang.annotation.ElementType.*; + +@Target(value = METHOD) +@Retention(value = RUNTIME) +public @interface EventSubscribe { + +} diff --git a/src/io/github/jordandoyle/mcinject/event/Listener.java b/src/io/github/jordandoyle/mcinject/event/Listener.java new file mode 100644 index 0000000..198eb1c --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/Listener.java @@ -0,0 +1,4 @@ +package io.github.jordandoyle.mcinject.event; + +public interface Listener { +} diff --git a/src/io/github/jordandoyle/mcinject/event/events/EventDamageEntity.java b/src/io/github/jordandoyle/mcinject/event/events/EventDamageEntity.java new file mode 100644 index 0000000..fa5a29a --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/events/EventDamageEntity.java @@ -0,0 +1,31 @@ +package io.github.jordandoyle.mcinject.event.events; + +import io.github.jordandoyle.mcinject.event.Event; + +public class EventDamageEntity extends Event { + private Object source; + private float damage; + + public EventDamageEntity(Object source, float damage) { + this.source = source; + this.damage = damage; + } + + /** + * Gets the source of the damage + * + * @return instance of DamageSource + */ + public Object getSource() { + return source; + } + + /** + * Gets amount of damage that was dealt + * + * @return amount of damage to entity caused + */ + public float getDamage() { + return damage; + } +} diff --git a/src/io/github/jordandoyle/mcinject/event/events/EventKeyPressed.java b/src/io/github/jordandoyle/mcinject/event/events/EventKeyPressed.java new file mode 100644 index 0000000..d6f5bf0 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/events/EventKeyPressed.java @@ -0,0 +1,34 @@ +package io.github.jordandoyle.mcinject.event.events; + +import io.github.jordandoyle.mcinject.event.Event; + +public class EventKeyPressed extends Event { + private int key; + private boolean state; + + public EventKeyPressed(int key, boolean state) { + this.key = key; + this.state = state; + } + + /** + * Gets the key that was pressed + * + * @return key that was pressed + */ + public int getKey() { + return key; + } + + /** + * Returns the state of the key press + * + * false = key down + * true = key up + * + * @return state of key + */ + public boolean getState() { + return state; + } +} diff --git a/src/io/github/jordandoyle/mcinject/event/events/EventRenderHand.java b/src/io/github/jordandoyle/mcinject/event/events/EventRenderHand.java new file mode 100644 index 0000000..750cbf3 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/events/EventRenderHand.java @@ -0,0 +1,7 @@ +package io.github.jordandoyle.mcinject.event.events; + +import io.github.jordandoyle.mcinject.event.Event; + +public class EventRenderHand extends Event { + +} diff --git a/src/io/github/jordandoyle/mcinject/event/events/EventRenderOverlay.java b/src/io/github/jordandoyle/mcinject/event/events/EventRenderOverlay.java new file mode 100644 index 0000000..dc8d13c --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/events/EventRenderOverlay.java @@ -0,0 +1,8 @@ +package io.github.jordandoyle.mcinject.event.events; + +import io.github.jordandoyle.mcinject.event.Event; + +public class EventRenderOverlay extends Event { + public EventRenderOverlay() { + } +} diff --git a/src/io/github/jordandoyle/mcinject/event/events/EventTick.java b/src/io/github/jordandoyle/mcinject/event/events/EventTick.java new file mode 100644 index 0000000..0dc99b1 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/event/events/EventTick.java @@ -0,0 +1,7 @@ +package io.github.jordandoyle.mcinject.event.events; + +import io.github.jordandoyle.mcinject.event.Event; + +public class EventTick extends Event { + +} diff --git a/src/io/github/jordandoyle/mcinject/gui/FontRenderer.java b/src/io/github/jordandoyle/mcinject/gui/FontRenderer.java new file mode 100644 index 0000000..684ec82 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/gui/FontRenderer.java @@ -0,0 +1,164 @@ +package io.github.jordandoyle.mcinject.gui; + +import static org.lwjgl.opengl.GL11.*; +import io.github.jordandoyle.mcinject.Main; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.GraphicsEnvironment; +import java.awt.RenderingHints; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.regex.Pattern; + +import org.lwjgl.opengl.GL11; +import org.newdawn.slick.TrueTypeFont; +import org.newdawn.slick.UnicodeFont; +import org.newdawn.slick.font.GlyphPage; +import org.newdawn.slick.font.effects.ColorEffect; + +import com.google.common.io.Resources; + +public class FontRenderer { + private Pattern patternControlCode = Pattern.compile("(?i)\\u00A7[0-9A-FK-OR]"); + + public FontRenderer() { + URL fontUrl = null; + try { + fontUrl = new File(Main.minecraft, "mcinject/font.ttf").toURI().toURL(); + } catch (MalformedURLException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + Font font = null; + try { + font = Font.createFont(Font.TRUETYPE_FONT, + fontUrl.openStream()); + } catch (Exception e) { + e.printStackTrace(); + } + + this.unicodeFont = new UnicodeFont(font.deriveFont(27F)); + + try { + this.unicodeFont.addAsciiGlyphs(); + this.unicodeFont.getEffects().add( + new ColorEffect(java.awt.Color.WHITE)); + this.unicodeFont.loadGlyphs(); + } catch (Exception e) { + e.printStackTrace(); + } + + for (int i = 0; i < 32; i++) { + int shadow = (i >> 3 & 1) * 85; + int red = (i >> 2 & 1) * 170 + shadow; + int green = (i >> 1 & 1) * 170 + shadow; + int blue = (i >> 0 & 1) * 170 + shadow; + + if (i == 6) { + red += 85; + } + + if (i >= 16) { + red /= 4; + green /= 4; + blue /= 4; + } + + this.colorCodes[i] = (red & 255) << 16 | (green & 255) << 8 | blue + & 255; + } + } + + private final UnicodeFont unicodeFont; + private final int[] colorCodes = new int[32]; + + public void drawString(String text, float x, float y, int color) { + x *= 2.0F; + y *= 2.0F; + float originalX = x; + + glPushMatrix(); + glScaled(0.5, 0.5, 0.5); + glEnable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + int currentColor = color; + char[] characters = text.toCharArray(); + + int index = 0; + for (char c : characters) { + if (c == '\r') { + x = originalX; + } + if (c == '\n') { + y += getHeight(Character.toString(c)) * 2.0F; + } + if (c != '\247' + && (index == 0 || index == characters.length - 1 || characters[index - 1] != '\247')) { + unicodeFont.drawString(x, y, Character.toString(c), + new org.newdawn.slick.Color(currentColor)); + x += getWidth(Character.toString(c)) * 2.0F; + } else if (c == ' ') { + x += unicodeFont.getSpaceWidth(); + } else if (c == '\247' && index != characters.length - 1) { + int codeIndex = "0123456789abcdef".indexOf(text + .charAt(index + 1)); + if (codeIndex < 0) + continue; + int col = this.colorCodes[codeIndex]; + currentColor = col; + } + + index++; + } + + glEnable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glPopMatrix(); + } + + public void drawStringWithShadow(String text, float x, float y, int color) { + drawString(stripControlCodes(text), x + 0.5F, y + 0.75F, + 0x55000000); + drawString(text, x, y, color); + } + + public void drawCenteredString(String text, float x, float y, int color) { + drawString(text, x / 2.0F - getWidth(text) / 2.0F, y, color); + } + + public void drawCenteredStringWithShadow(String text, float x, float y, + int color) { + drawCenteredString(stripControlCodes(text), x + 0.5F, + y + 0.5F, color); + drawCenteredString(text, x, y, color); + } + + public float getWidth(String s) { + float width = 0.0F; + + String s1 = s; + for (char c : s1.toCharArray()) { + width += unicodeFont.getWidth(Character.toString(c)); + } + + return width / 2.0F; + } + + public float getHeight(String s) { + return unicodeFont.getHeight(s) / 2.0F; + } + + public UnicodeFont getFont() { + return this.unicodeFont; + } + + private String stripControlCodes(String par0Str) + { + return patternControlCode.matcher(par0Str).replaceAll(""); + } +} diff --git a/src/io/github/jordandoyle/mcinject/handler/Handler.java b/src/io/github/jordandoyle/mcinject/handler/Handler.java new file mode 100644 index 0000000..c8ed16d --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/handler/Handler.java @@ -0,0 +1,30 @@ +package io.github.jordandoyle.mcinject.handler; + +public abstract class Handler { + // TODO: Add some better functionality in here in the future + + private boolean registered = false; + private String name; + + public Handler(String name) { + this.name = name; + } + + protected abstract void onRegister(); + + public boolean hasRegistered() { + return registered; + } + + public void register() throws Exception { + if(hasRegistered()) + throw new Exception("Cannot register an already registered handler"); + + registered = true; + onRegister(); + } + + public String getName() { + return name; + } +} diff --git a/src/io/github/jordandoyle/mcinject/handler/HandlerManager.java b/src/io/github/jordandoyle/mcinject/handler/HandlerManager.java new file mode 100644 index 0000000..0a92b20 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/handler/HandlerManager.java @@ -0,0 +1,37 @@ +package io.github.jordandoyle.mcinject.handler; + +import io.github.jordandoyle.mcinject.handler.handlers.KeyPressHandler; + +import java.util.ArrayList; +import java.util.List; + +public class HandlerManager { + private static List handlers = new ArrayList(); + + static { + handlers.add(new KeyPressHandler()); + } + + public static Handler getHandler(String name) { + for(Handler h : handlers) { + if(h.getName().equalsIgnoreCase(name)) + return h; + } + + return null; + } + + public static List getHandlers() { + return handlers; + } + + public static void registerHandlers() { + try { + for(Handler h : getHandlers()) + if(!h.hasRegistered()) + h.register(); + } catch(Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/io/github/jordandoyle/mcinject/handler/handlers/KeyPressHandler.java b/src/io/github/jordandoyle/mcinject/handler/handlers/KeyPressHandler.java new file mode 100644 index 0000000..11e9357 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/handler/handlers/KeyPressHandler.java @@ -0,0 +1,30 @@ +package io.github.jordandoyle.mcinject.handler.handlers; + +import io.github.jordandoyle.mcinject.event.EventHandler; +import io.github.jordandoyle.mcinject.event.EventSubscribe; +import io.github.jordandoyle.mcinject.event.Listener; +import io.github.jordandoyle.mcinject.event.events.EventKeyPressed; +import io.github.jordandoyle.mcinject.handler.Handler; +import io.github.jordandoyle.mcinject.mod.Mod; +import io.github.jordandoyle.mcinject.mod.ModManager; + +public final class KeyPressHandler extends Handler implements Listener { + public KeyPressHandler() { + super("KeyPress"); + } + + public void onRegister() { + EventHandler.getInstance().registerListener(this); + } + + @EventSubscribe + public void onKeyDown(EventKeyPressed e) { + if(e.getState() == false) + return; + + for(Mod m : ModManager.getMods()) { + if(e.getKey() == m.getKey()) + m.toggle(); + } + } +} diff --git a/src/io/github/jordandoyle/mcinject/helpers/Mapper.java b/src/io/github/jordandoyle/mcinject/helpers/Mapper.java new file mode 100644 index 0000000..bd7407e --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/helpers/Mapper.java @@ -0,0 +1,123 @@ +package io.github.jordandoyle.mcinject.helpers; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +public class Mapper { + private static List classes, methods, fields; + + static { + // Classes + { + try { + URL url = new URL("http://mcinject.uphero.com/1.7.2/classes.html"); + InputStream is = url.openStream(); + + InputStreamReader reader = new InputStreamReader(is); + BufferedReader bufferedReader = new BufferedReader(reader); + + String line; + + classes = new ArrayList(); + + while((line = bufferedReader.readLine()) != null) { + String[] l = line.split("\\s+"); + classes.add(l); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + // Methods + { + try { + URL url = new URL("http://mcinject.uphero.com/1.7.2/methods.html"); + InputStream is = url.openStream(); + + InputStreamReader reader = new InputStreamReader(is); + BufferedReader bufferedReader = new BufferedReader(reader); + + String line; + + methods = new ArrayList(); + + while((line = bufferedReader.readLine()) != null) { + String[] l = line.split("\\s+"); + methods.add(l); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // Fields + { + try { + URL url = new URL("http://mcinject.uphero.com/1.7.2/fields.html"); + InputStream is = url.openStream(); + + InputStreamReader reader = new InputStreamReader(is); + BufferedReader bufferedReader = new BufferedReader(reader); + + String line; + + fields = new ArrayList(); + + while((line = bufferedReader.readLine()) != null) { + String[] l = line.split("\\s+"); + fields.add(l); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static String getClass(String unobfuscated) { + for(String[] cl : classes) { + if(StringUtils.equalsIgnoreCase(cl[1], unobfuscated)) { + return cl[0]; + } + } + + return unobfuscated; + } + + public static String getMethod(String class1, String unobfuscated) { + for(String[] cl : methods) { + if(StringUtils.equalsIgnoreCase(cl[1], unobfuscated) + && StringUtils.equalsIgnoreCase(cl[2], class1)) { + return cl[0]; + } + } + + return unobfuscated; + } + + public static String getField(String class1, String unobfuscated) { + for(String[] cl : fields) { + if(StringUtils.equalsIgnoreCase(cl[1], unobfuscated) + && StringUtils.containsIgnoreCase(cl[2], class1)) { + return cl[0]; + } + } + + return unobfuscated; + } +} diff --git a/src/io/github/jordandoyle/mcinject/helpers/ObfuscatedMapping.java b/src/io/github/jordandoyle/mcinject/helpers/ObfuscatedMapping.java new file mode 100644 index 0000000..1a67d04 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/helpers/ObfuscatedMapping.java @@ -0,0 +1,104 @@ +package io.github.jordandoyle.mcinject.helpers; + +import static org.apache.commons.lang3.StringUtils.*; + +import javax.swing.JOptionPane; + +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +public class ObfuscatedMapping { + private String owner, name, desc, obfOwner, obfName; + + private static boolean obfuscated = false; + + static { + try { + Class test = ObfuscatedMapping.class.getClassLoader().loadClass( + "net.minecraft.src.Block"); + } catch (Exception e) { + obfuscated = true; + } + } + + public ObfuscatedMapping(String owner, String name, String desc) { + this.owner = owner; + this.name = name; + this.desc = desc; + + if (!isClass()) { + this.obfName = getMapping(); + this.obfOwner = new ObfuscatedMapping(owner).getMapping(); + } + + if (contains(owner, ".")) + throw new IllegalArgumentException(owner); + } + + public ObfuscatedMapping(String owner) { + this(owner, "", ""); + } + + public ObfuscatedMapping(String owner, String name) { + this(owner, name, ""); + } + + public boolean equals(MethodInsnNode node) { + return (obfName.equals(node.name) || name.equals(node.name)) + && desc.equals(node.desc) + && (obfOwner.equals(node.owner) || owner.equals(node.owner)); + } + + public boolean equals(FieldInsnNode node) { + return (obfName.equals(node.name) || name.equals(node.name)) + && (obfOwner.equals(node.owner) || owner.equals(node.owner)); + } + + public boolean equals(MethodNode node) { + return (obfName.equals(node.name) || name.equals(node.name)) + && desc.equals(node.desc); + } + + public boolean equals(FieldNode node) { + return (obfName.equals(node.name) || name.equals(node.name)); + } + + public String getRealOwner() { + return replace(owner, "/", "."); + } + + @Override + public String toString() { + return getMapping(); + } + + public boolean isClass() { + return name.length() == 0; + } + + public boolean isMethod() { + return desc.contains("("); + } + + public boolean isField() { + return !isClass() && !isMethod(); + } + + public String getMapping() { + if (!obfuscated) + return (isClass()) ? getRealOwner() : name; + + if (isClass()) + return Mapper.getClass(getRealOwner()); + + if (isMethod()) + return Mapper.getMethod(Mapper.getClass(getRealOwner()), name); + + if (isField()) + return Mapper.getField(Mapper.getClass(getRealOwner()), name); + + return getRealOwner(); + } +} diff --git a/src/io/github/jordandoyle/mcinject/helpers/Player.java b/src/io/github/jordandoyle/mcinject/helpers/Player.java new file mode 100644 index 0000000..9b4c321 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/helpers/Player.java @@ -0,0 +1,88 @@ +package io.github.jordandoyle.mcinject.helpers; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.player.advanced.AdvancedPlayer; +import javazoom.jl.player.advanced.PlaybackEvent; +import javazoom.jl.player.advanced.PlaybackListener; +import javazoom.jlgui.basicplayer.BasicController; +import javazoom.jlgui.basicplayer.BasicPlayer; +import javazoom.jlgui.basicplayer.BasicPlayerEvent; +import javazoom.jlgui.basicplayer.BasicPlayerException; +import javazoom.jlgui.basicplayer.BasicPlayerListener; + +public class Player implements BasicPlayerListener { + private BasicPlayer player; + public boolean songFinished = false; + private boolean shouldStop = false, shouldStart = false; + private double gain = 0.5; + private long progress; + + public Player(BasicPlayer player) { + this.player = player; + this.player.addBasicPlayerListener(this); + } + + public void play() { + try { + player.play(); + player.setGain(0.5); + shouldStart = true; + } catch (BasicPlayerException e) { + e.printStackTrace(); + } + } + + public void stop() { + try { + player.stop(); + } catch (BasicPlayerException e) { + e.printStackTrace(); + } + } + + public void changeGain(double g) { + try { + player.setGain((double) g / 100D); + + this.gain = g / 100; + } catch (BasicPlayerException e) { + e.printStackTrace(); + } + } + + public double getGain() { + return gain; + } + + public String getProgress() { + return String.format( + "%d:%02d", + TimeUnit.MICROSECONDS.toMinutes(progress), + TimeUnit.MICROSECONDS.toSeconds(progress) + - TimeUnit.MINUTES.toSeconds(TimeUnit.MICROSECONDS + .toMinutes(progress))); + } + + @Override + public void opened(Object stream, Map properties) { + } + + @Override + public void progress(int bytesread, long microseconds, byte[] pcmdata, + Map properties) { + progress = microseconds; + } + + @Override + public void stateUpdated(BasicPlayerEvent event) { + if (event.getCode() == BasicPlayerEvent.STOPPED) + songFinished = true; + } + + @Override + public void setController(BasicController controller) { + } +} diff --git a/src/io/github/jordandoyle/mcinject/helpers/RenderHelper.java b/src/io/github/jordandoyle/mcinject/helpers/RenderHelper.java new file mode 100644 index 0000000..c827a33 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/helpers/RenderHelper.java @@ -0,0 +1,260 @@ +package io.github.jordandoyle.mcinject.helpers; + +import static org.lwjgl.opengl.GL11.*; + +import org.lwjgl.opengl.GL11; +import org.newdawn.slick.Color; + +public class RenderHelper { + public static void drawBoundingBox(Object o, int colour) { + double minX = 0, minY = 0, minZ = 0, maxX = 0, maxY = 0, maxZ = 0; + + try { + minX = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "minX") + .getMapping()).getDouble(o); + minY = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "minY") + .getMapping()).getDouble(o); + minZ = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "minZ") + .getMapping()).getDouble(o); + + maxX = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "maxX") + .getMapping()).getDouble(o); + maxY = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "maxY") + .getMapping()).getDouble(o); + maxZ = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "maxZ") + .getMapping()).getDouble(o); + } catch (Exception e) { + e.printStackTrace(); + } + + glPushMatrix(); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_LINE_SMOOTH); + glDepthMask(false); + glLineWidth(1.8F); + + Color c = new Color(colour); + glColor4f(c.r, c.g, c.b, c.a); + + glBegin(GL_QUADS); + { + glVertex3d(minX, minY, minZ); + glVertex3d(minX, maxY, minZ); + glVertex3d(maxX, minY, minZ); + glVertex3d(maxX, maxY, minZ); + + glVertex3d(maxX, minY, maxZ); + glVertex3d(maxX, maxY, maxZ); + glVertex3d(minX, minY, maxZ); + glVertex3d(minX, maxY, maxZ); + } + glEnd(); + + glBegin(GL_QUADS); + { + glVertex3d(maxX, maxY, minZ); + glVertex3d(maxX, minY, minZ); + glVertex3d(minX, maxY, minZ); + glVertex3d(minX, minY, minZ); + + glVertex3d(minX, maxY, maxZ); + glVertex3d(minX, minY, maxZ); + glVertex3d(maxX, maxY, maxZ); + glVertex3d(maxX, minY, maxZ); + } + glEnd(); + + glBegin(GL_QUADS); + { + glVertex3d(minX, maxY, minZ); + glVertex3d(maxX, maxY, minZ); + glVertex3d(maxX, maxY, maxZ); + glVertex3d(minX, maxY, maxZ); + + glVertex3d(minX, maxY, minZ); + glVertex3d(minX, maxY, maxZ); + glVertex3d(maxX, maxY, maxZ); + glVertex3d(maxX, maxY, minZ); + } + glEnd(); + + glBegin(GL_QUADS); + { + glVertex3d(minX, minY, minZ); + glVertex3d(maxX, minY, minZ); + glVertex3d(maxX, minY, maxZ); + glVertex3d(minX, minY, maxZ); + + glVertex3d(minX, minY, minZ); + glVertex3d(minX, minY, maxZ); + glVertex3d(maxX, minY, maxZ); + glVertex3d(maxX, minY, minZ); + } + glEnd(); + + glBegin(GL_QUADS); + { + glVertex3d(minX, minY, minZ); + glVertex3d(minX, maxY, minZ); + glVertex3d(minX, minY, maxZ); + glVertex3d(minX, maxY, maxZ); + + glVertex3d(maxX, minY, maxZ); + glVertex3d(maxX, maxY, maxZ); + glVertex3d(maxX, minY, minZ); + glVertex3d(maxX, maxY, minZ); + } + glEnd(); + + glBegin(GL_QUADS); + { + glVertex3d(minX, maxY, maxZ); + glVertex3d(minX, minY, maxZ); + glVertex3d(minX, maxY, minZ); + glVertex3d(minX, minY, minZ); + glVertex3d(maxX, maxY, minZ); + glVertex3d(maxX, minY, minZ); + glVertex3d(maxX, maxY, maxZ); + glVertex3d(maxX, minY, maxZ); + } + glEnd(); + + glDepthMask(true); + glEnable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); + glPopMatrix(); + } + + public static void drawOutlineBoundingBox(Object o, int colour) { + double minX = 0, minY = 0, minZ = 0, maxX = 0, maxY = 0, maxZ = 0; + + try { + minX = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "minX") + .getMapping()).getDouble(o); + minY = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "minY") + .getMapping()).getDouble(o); + minZ = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "minZ") + .getMapping()).getDouble(o); + + maxX = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "maxX") + .getMapping()).getDouble(o); + maxY = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "maxY") + .getMapping()).getDouble(o); + maxZ = o.getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "maxZ") + .getMapping()).getDouble(o); + } catch (Exception e) { + e.printStackTrace(); + } + + glPushMatrix(); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_LINE_SMOOTH); + glDepthMask(false); + glLineWidth(1.8F); + + Color c = new Color(colour); + glColor4f(c.r, c.g, c.b, c.a); + + glBegin(GL_LINE_STRIP); + { + glVertex3d(minX, minY, minZ); + glVertex3d(maxX, minY, minZ); + glVertex3d(maxX, minY, maxZ); + glVertex3d(minX, minY, maxZ); + glVertex3d(minX, minY, minZ); + } + glEnd(); + + glBegin(GL_LINE_STRIP); + { + glVertex3d(minX, maxY, minZ); + glVertex3d(maxX, maxY, minZ); + glVertex3d(maxX, maxY, maxZ); + glVertex3d(minX, maxY, maxZ); + glVertex3d(minX, maxY, minZ); + } + glEnd(); + + glBegin(GL_LINES); + { + glVertex3d(minX, minY, minZ); + glVertex3d(minX, maxY, minZ); + glVertex3d(maxX, minY, minZ); + glVertex3d(maxX, maxY, minZ); + glVertex3d(maxX, minY, maxZ); + glVertex3d(maxX, maxY, maxZ); + glVertex3d(minX, minY, maxZ); + glVertex3d(minX, maxY, maxZ); + } + glEnd(); + + glDepthMask(true); + glEnable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); + glPopMatrix(); + } + + public static String toHex(org.lwjgl.util.Color c) { + return getHexValue(c.getAlpha()) + getHexValue(c.getRed()) + getHexValue(c.getGreen()) + getHexValue(c.getBlue()); + } + + private static String getHexValue(int n) { + StringBuilder builder = new StringBuilder(Integer.toHexString(n & 0xff)); + while (builder.length() < 2) { + builder.append("0"); + } + return builder.toString().toUpperCase(); + } +} diff --git a/src/io/github/jordandoyle/mcinject/mod/Category.java b/src/io/github/jordandoyle/mcinject/mod/Category.java new file mode 100644 index 0000000..ec6cdd9 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/mod/Category.java @@ -0,0 +1,18 @@ +package io.github.jordandoyle.mcinject.mod; + +public enum Category { + MOVEMENT("Movement"), + PLAYER("Player"), + RENDER("Render"), + MUSIC("Music"); + + private String name; + + private Category(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } +} diff --git a/src/io/github/jordandoyle/mcinject/mod/Mod.java b/src/io/github/jordandoyle/mcinject/mod/Mod.java new file mode 100644 index 0000000..11e5f60 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/mod/Mod.java @@ -0,0 +1,78 @@ +package io.github.jordandoyle.mcinject.mod; + +import java.lang.reflect.Method; + +import org.objectweb.asm.Type; + +import io.github.jordandoyle.mcinject.Wrapper; +import io.github.jordandoyle.mcinject.proxy.interfaces.Minecraft; + +public abstract class Mod { + private String name; + private int key; + private boolean enabled; + private Category category; + + protected Minecraft mc = Wrapper.getMinecraft(); + + public Mod(String name, int key, Category category) { + this.name = name; + this.key = key; + this.category = category; + } + + public Mod(String name, Category category) { + this.name = name; + this.key = -1; + this.category = category; + } + + public void toggle() { + if (enabled) + disable(); + else + enable(); + } + + public boolean isEnabled() { + return enabled; + } + + protected abstract void onEnable(); + + protected abstract void onDisable(); + + public void enable() { + if(enabled) + return; + + enabled = true; + sendMessage(name + " \u00a7aenabled"); + onEnable(); + } + + public void disable() { + if(!enabled) + return; + + enabled = false; + sendMessage(name + " \u00a7cdisabled"); + onDisable(); + } + + public String getName() { + return name; + } + + public Category getCategory() { + return category; + } + + public int getKey() { + return key; + } + + protected void sendMessage(String message) { + Wrapper.getPlayer().addChatMessage("\u00a76[mcinject] \u00a7f" + message); + } +} diff --git a/src/io/github/jordandoyle/mcinject/mod/ModManager.java b/src/io/github/jordandoyle/mcinject/mod/ModManager.java new file mode 100644 index 0000000..8cd33b5 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/mod/ModManager.java @@ -0,0 +1,42 @@ +package io.github.jordandoyle.mcinject.mod; + +import io.github.jordandoyle.mcinject.mod.mods.movement.*; +import io.github.jordandoyle.mcinject.mod.mods.music.Player; +import io.github.jordandoyle.mcinject.mod.mods.player.AutoRespawn; +import io.github.jordandoyle.mcinject.mod.mods.render.ESP; +import io.github.jordandoyle.mcinject.mod.mods.render.FullBright; + +import java.util.ArrayList; +import java.util.List; + +public class ModManager { + private static List mods = new ArrayList(); + + static { + // Movement + mods.add(new Sprint()); + mods.add(new Fly()); + + // Player + mods.add(new AutoRespawn()); + + // Render + mods.add(new ESP()); + mods.add(new FullBright()); + + mods.add(new Player()); + } + + public static Mod getMod(String name) { + for(Mod m : mods) { + if(m.getName().equalsIgnoreCase(name)) + return m; + } + + return null; + } + + public static List getMods() { + return mods; + } +} diff --git a/src/io/github/jordandoyle/mcinject/mod/mods/movement/Fly.java b/src/io/github/jordandoyle/mcinject/mod/mods/movement/Fly.java new file mode 100644 index 0000000..60a2b1e --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/mod/mods/movement/Fly.java @@ -0,0 +1,56 @@ +package io.github.jordandoyle.mcinject.mod.mods.movement; + +import java.lang.reflect.Field; + +import org.lwjgl.input.Keyboard; + +import io.github.jordandoyle.mcinject.Wrapper; +import io.github.jordandoyle.mcinject.event.EventHandler; +import io.github.jordandoyle.mcinject.event.EventSubscribe; +import io.github.jordandoyle.mcinject.event.Listener; +import io.github.jordandoyle.mcinject.event.events.EventTick; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; +import io.github.jordandoyle.mcinject.mod.Category; +import io.github.jordandoyle.mcinject.mod.Mod; + +public class Fly extends Mod implements Listener { + private boolean couldFly = false; + + public Fly() { + super("Fly", Keyboard.KEY_F, Category.MOVEMENT); + } + + @Override + protected void onEnable() { + EventHandler.getInstance().registerListener(this); + } + + @EventSubscribe + public void onTick(EventTick e) { + Object player = Wrapper.getPlayer().getInstance(); + try { + Field capabilities = player.getClass().getField(new ObfuscatedMapping("net/minecraft/src/EntityPlayer", "capabilities").getMapping()); + Object c = capabilities.get(player); + Field isFlying = c.getClass().getField(new ObfuscatedMapping("net/minecraft/src/PlayerCapabilities", "isFlying").getMapping()); + isFlying.setBoolean(c, true); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + @Override + protected void onDisable() { + EventHandler.getInstance().unregisterListener(this); + + Object player = Wrapper.getPlayer().getInstance(); + try { + Field capabilities = player.getClass().getField(new ObfuscatedMapping("net/minecraft/src/EntityPlayer", "capabilities").getMapping()); + Object c = capabilities.get(player); + Field isFlying = c.getClass().getField(new ObfuscatedMapping("net/minecraft/src/PlayerCapabilities", "isFlying").getMapping()); + isFlying.setBoolean(c, false); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/src/io/github/jordandoyle/mcinject/mod/mods/movement/Sprint.java b/src/io/github/jordandoyle/mcinject/mod/mods/movement/Sprint.java new file mode 100644 index 0000000..378902f --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/mod/mods/movement/Sprint.java @@ -0,0 +1,49 @@ +package io.github.jordandoyle.mcinject.mod.mods.movement; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.lwjgl.input.Keyboard; + +import io.github.jordandoyle.mcinject.Wrapper; +import io.github.jordandoyle.mcinject.event.EventHandler; +import io.github.jordandoyle.mcinject.event.EventSubscribe; +import io.github.jordandoyle.mcinject.event.Listener; +import io.github.jordandoyle.mcinject.event.events.EventTick; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; +import io.github.jordandoyle.mcinject.mod.Category; +import io.github.jordandoyle.mcinject.mod.Mod; + +public class Sprint extends Mod implements Listener { + + public Sprint() { + super("Sprint", Keyboard.KEY_P, Category.MOVEMENT); + } + + @Override + protected void onEnable() { + EventHandler.getInstance().registerListener(this); + } + + @Override + protected void onDisable() { + EventHandler.getInstance().unregisterListener(this); + } + + @EventSubscribe + public void onTick(EventTick e) { + try { + Class p = Wrapper.getPlayer().getInstance().getClass(); + Object o = p.getField(new ObfuscatedMapping("net/minecraft/src/EntityPlayerSP", "movementInput").getMapping()).get(Wrapper.getPlayer().getInstance()); + + boolean b = (Boolean) Wrapper.getPlayer().isSneaking(); + + Wrapper.getPlayer().setSprinting((o.getClass().getField(new ObfuscatedMapping("net/minecraft/src/MovementInput", "moveForward").getMapping()).getFloat(o) > 0 && !b)); + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + +} diff --git a/src/io/github/jordandoyle/mcinject/mod/mods/music/Player.java b/src/io/github/jordandoyle/mcinject/mod/mods/music/Player.java new file mode 100644 index 0000000..a8220c7 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/mod/mods/music/Player.java @@ -0,0 +1,192 @@ +package io.github.jordandoyle.mcinject.mod.mods.music; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; + +import org.apache.commons.lang3.StringUtils; +import org.lwjgl.input.Keyboard; + +import com.google.common.base.CaseFormat; +import com.mpatric.mp3agic.Mp3File; + +import javazoom.jl.decoder.JavaLayerException; +import javazoom.jl.player.AudioDevice; +import javazoom.jl.player.advanced.AdvancedPlayer; +import javazoom.jlgui.basicplayer.BasicPlayer; +import javazoom.jlgui.basicplayer.BasicPlayerException; +import io.github.jordandoyle.mcinject.Main; +import io.github.jordandoyle.mcinject.Wrapper; +import io.github.jordandoyle.mcinject.event.EventHandler; +import io.github.jordandoyle.mcinject.event.EventSubscribe; +import io.github.jordandoyle.mcinject.event.Listener; +import io.github.jordandoyle.mcinject.event.events.EventKeyPressed; +import io.github.jordandoyle.mcinject.event.events.EventRenderOverlay; +import io.github.jordandoyle.mcinject.event.events.EventTick; +import io.github.jordandoyle.mcinject.mod.Category; +import io.github.jordandoyle.mcinject.mod.Mod; + +public class Player extends Mod implements Listener { + private BasicPlayer player; + private io.github.jordandoyle.mcinject.helpers.Player threadHandler; + private List songs; + private long lastRan = System.currentTimeMillis(); + private File song; + private String name; + + public Player() { + super("Music Player", Keyboard.KEY_RBRACKET, Category.MUSIC); + } + + public void newSong() { + if(songs == null || songs.isEmpty()) { + if(System.currentTimeMillis() - lastRan < 20000) return; + lastRan = System.currentTimeMillis(); + getMusic(); + if(songs == null || songs.isEmpty()) { + System.out.println("No music!"); + } + } + + if(player != null) + try { + player.stop(); + } catch (BasicPlayerException e1) { + e1.printStackTrace(); + } + + try { + song = songs.get(0); + BufferedInputStream file = new BufferedInputStream(new FileInputStream(song)); + + if(song.exists()) { + System.out.println("test"); + } + + System.out.println(song.getName()); + + player = new BasicPlayer(); + player.open(file); + threadHandler = new io.github.jordandoyle.mcinject.helpers.Player(player); + threadHandler.play(); + songs.remove(0); + + name = toNiceName(song); + sendMessage("Now playing \u00a7b" + name + "\u00a7r!"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private String toNiceName(File f) { + Mp3File song = null; + try { + song = new Mp3File(f.getPath()); + } catch (Exception e) { + e.printStackTrace(); + } + + if(song.hasId3v2Tag()) { + return song.getId3v2Tag().getArtist() + " - " + song.getId3v2Tag().getTitle(); + } + + if(song.hasId3v1Tag()) { + return song.getId3v1Tag().getArtist() + " - " + song.getId3v1Tag().getTitle(); + } + + return song.getFilename(); + } + + protected void getMusic() { + try { + File f = new File(Main.minecraft, "mcinject"); + f = new File(f, "music"); + + if (!f.exists()) + f.mkdirs(); + + songs = new LinkedList(Arrays.asList(f.listFiles())); + + Collections.shuffle(songs); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + protected void onEnable() { + try { + getMusic(); + newSong(); + + EventHandler.getInstance().registerListener(this); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + protected void onDisable() { + if (threadHandler != null) threadHandler.stop(); + + EventHandler.getInstance().unregisterListener(this); + } + + @EventSubscribe + public void onTick(EventTick e) { + if(songs == null || songs.isEmpty()) { + getMusic(); + } + + if (threadHandler != null && threadHandler.songFinished) + newSong(); + } + + @EventSubscribe + public void onKeyPressed(EventKeyPressed e) { + if (!e.getState()) { + if (e.getKey() == Keyboard.KEY_RIGHT) + newSong(); + + if (e.getKey() == Keyboard.KEY_UP) { + if (Math.round(threadHandler.getGain()) > 1) + return; + threadHandler + .changeGain(Math.round(threadHandler.getGain() * 100 + 1D)); + sendMessage("Gain now at " + + Math.round(threadHandler.getGain() * 100)); + } + + if (e.getKey() == Keyboard.KEY_DOWN) { + if (Math.round(threadHandler.getGain()) < 0) + return; + threadHandler + .changeGain(Math.round(threadHandler.getGain() * 100 - 1D)); + sendMessage("Gain now at " + + Math.round(threadHandler.getGain() * 100)); + } + } + } + + @EventSubscribe + public void onRender(EventRenderOverlay e) { + try { + if(name != null && threadHandler != null) + Wrapper.getFontRenderer().drawStringWithShadow(StringUtils.abbreviate(name.substring(name.indexOf('-') + 2), 20) + " (" + threadHandler.getProgress() + ")", 2, 17, 0xffffffff); + } catch(Exception ex) { + ex.printStackTrace(); + } + } +} diff --git a/src/io/github/jordandoyle/mcinject/mod/mods/player/AutoRespawn.java b/src/io/github/jordandoyle/mcinject/mod/mods/player/AutoRespawn.java new file mode 100644 index 0000000..42062a4 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/mod/mods/player/AutoRespawn.java @@ -0,0 +1,54 @@ +package io.github.jordandoyle.mcinject.mod.mods.player; + +import java.lang.reflect.Method; + +import org.lwjgl.input.Keyboard; + +import io.github.jordandoyle.mcinject.Wrapper; +import io.github.jordandoyle.mcinject.event.EventHandler; +import io.github.jordandoyle.mcinject.event.EventSubscribe; +import io.github.jordandoyle.mcinject.event.Listener; +import io.github.jordandoyle.mcinject.event.events.EventTick; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; +import io.github.jordandoyle.mcinject.mod.Category; +import io.github.jordandoyle.mcinject.mod.Mod; + +public class AutoRespawn extends Mod implements Listener { + private Method isAlive = null; + + public AutoRespawn() { + super("AutoRespawn", Keyboard.KEY_O, Category.PLAYER); + } + + @Override + protected void onEnable() { + EventHandler.getInstance().registerListener(this); + } + + @Override + protected void onDisable() { + EventHandler.getInstance().unregisterListener(this); + } + + @EventSubscribe + public void tick(EventTick e) { + try { + Object player = Wrapper.getPlayer().getInstance(); + if(isAlive == null) { + Class entityLivingBase = Class.forName(new ObfuscatedMapping("net/minecraft/src/EntityLivingBase").getMapping()); + Object elb = entityLivingBase.cast(player); + isAlive = elb.getClass().getMethod(new ObfuscatedMapping("net/minecraft/src/EntityLivingBase", "isEntityAlive", "()V").getMapping()); + } + boolean alive = (Boolean) isAlive.invoke(player); + + if(!alive) { + Object packet = Class.forName(new ObfuscatedMapping("net/minecraft/src/Packet205ClientCommand").getMapping()).getConstructor(int.class).newInstance(1); + Wrapper.sendPacket(packet); + } + } catch (Exception e1) { + e1.printStackTrace(); + } + + } + +} diff --git a/src/io/github/jordandoyle/mcinject/mod/mods/render/ESP.java b/src/io/github/jordandoyle/mcinject/mod/mods/render/ESP.java new file mode 100644 index 0000000..613bd98 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/mod/mods/render/ESP.java @@ -0,0 +1,169 @@ +package io.github.jordandoyle.mcinject.mod.mods.render; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import org.lwjgl.input.Keyboard; +import org.lwjgl.util.Color; + +import io.github.jordandoyle.mcinject.Wrapper; +import io.github.jordandoyle.mcinject.event.EventHandler; +import io.github.jordandoyle.mcinject.event.EventSubscribe; +import io.github.jordandoyle.mcinject.event.Listener; +import io.github.jordandoyle.mcinject.event.events.EventRenderHand; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; +import io.github.jordandoyle.mcinject.helpers.RenderHelper; +import io.github.jordandoyle.mcinject.mod.Category; +import io.github.jordandoyle.mcinject.mod.Mod; + +public class ESP extends Mod implements Listener { + private Class renderManager, player, entity, aabb; + private Field renderPosX, renderPosY, renderPosZ, loadedEntityList; + private Object theWorld; + private Color innerOpacity = new Color(69, 179, 235, 0), + outerOpacity = new Color(69, 179, 235, 0); + + public ESP() { + super("ESP", Keyboard.KEY_U, Category.RENDER); + } + + @Override + protected void onEnable() { + innerOpacity = new Color(69, 179, 235, 15); + outerOpacity = new Color(69, 179, 235, 15); + EventHandler.getInstance().registerListener(this); + } + + @Override + protected void onDisable() { + //EventHandler.getInstance().unregisterListener(this); + } + + @EventSubscribe + public void renderHand(EventRenderHand e) { + double rpx = 0; + double rpy = 0; + double rpz = 0; + List entityList = new ArrayList(); + + try { + if (renderManager == null) + renderManager = Class.forName(new ObfuscatedMapping( + "net/minecraft/src/RenderManager").getMapping()); + + if (player == null) + player = Class.forName(new ObfuscatedMapping( + "net/minecraft/src/EntityPlayer").getMapping()); + + if(aabb == null) + aabb = Class.forName(new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB").getMapping()); + + if (entity == null) + entity = Class.forName(new ObfuscatedMapping( + "net/minecraft/src/Entity").getMapping()); + + if (renderPosX == null) + renderPosX = renderManager.getField(new ObfuscatedMapping( + "net/minecraft/src/RenderManager", "renderPosX") + .getMapping()); + + if (renderPosY == null) + renderPosY = renderManager.getField(new ObfuscatedMapping( + "net/minecraft/src/RenderManager", "renderPosY") + .getMapping()); + + if (renderPosZ == null) + renderPosZ = renderManager.getField(new ObfuscatedMapping( + "net/minecraft/src/RenderManager", "renderPosZ") + .getMapping()); + + theWorld = Wrapper + .getMinecraft() + .getMinecraft() + .getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/Minecraft", + "theWorld").getMapping()) + .get(Wrapper.getMinecraft().getMinecraft()); + loadedEntityList = theWorld.getClass().getField( + new ObfuscatedMapping("net/minecraft/src/World", + "loadedEntityList").getMapping()); + + rpx = renderPosX.getDouble(null); + rpy = renderPosY.getDouble(null); + rpz = renderPosZ.getDouble(null); + entityList = (List) loadedEntityList.get(theWorld); + + if(this.isEnabled()) { + if(innerOpacity.getAlpha() != 0x26) + innerOpacity.setAlpha(innerOpacity.getAlpha() + 1); + + if(outerOpacity.getAlpha() != 0xFF) + outerOpacity.setAlpha(outerOpacity.getAlpha() + 1); + } else { + if(outerOpacity.getAlpha() != 0x10) { + if(innerOpacity.getAlpha() != 0x10) + innerOpacity.setAlpha(innerOpacity.getAlpha() - 1); + + outerOpacity.setAlpha(outerOpacity.getAlpha() - 1); + } else + EventHandler.getInstance().unregisterListener(this); + } + + for (Object o : entityList) { + if (player.isInstance(o) && !o.equals(Wrapper.getPlayer().getInstance())) { + Object p = entity.cast(o); + + double posX = p + .getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/Entity", "posX") + .getMapping()).getDouble(p) + - rpx; + double posY = p + .getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/Entity", "posY") + .getMapping()).getDouble(p) + - rpy; + double posZ = p + .getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/Entity", "posZ") + .getMapping()).getDouble(p) + - rpz; + double height = p + .getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/Entity", "height") + .getMapping()).getDouble(p); + double width = p + .getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/Entity", "width") + .getMapping()).getDouble(p) - 0.12; + + Object boundingBox = aabb.getMethod(new ObfuscatedMapping( + "net/minecraft/src/AxisAlignedBB", "getBoundingBox", "(") + .getMapping(), double.class, double.class, double.class, double.class, double.class, double.class).invoke(null, posX + - width, posY + 0.1, posZ - width, posX + width, posY + + height + 0.2, posZ + width); + + RenderHelper.drawBoundingBox(boundingBox, (int) Long.parseLong(RenderHelper.toHex(innerOpacity), 16)); + RenderHelper.drawOutlineBoundingBox(boundingBox, (int) Long.parseLong(RenderHelper.toHex(outerOpacity), 16)); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/src/io/github/jordandoyle/mcinject/mod/mods/render/FullBright.java b/src/io/github/jordandoyle/mcinject/mod/mods/render/FullBright.java new file mode 100644 index 0000000..ef99d98 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/mod/mods/render/FullBright.java @@ -0,0 +1,106 @@ +package io.github.jordandoyle.mcinject.mod.mods.render; + +import java.lang.reflect.Field; + +import org.lwjgl.input.Keyboard; + +import io.github.jordandoyle.mcinject.Wrapper; +import io.github.jordandoyle.mcinject.event.EventHandler; +import io.github.jordandoyle.mcinject.event.EventSubscribe; +import io.github.jordandoyle.mcinject.event.Listener; +import io.github.jordandoyle.mcinject.event.events.EventTick; +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; +import io.github.jordandoyle.mcinject.mod.Category; +import io.github.jordandoyle.mcinject.mod.Mod; + +public class FullBright extends Mod implements Listener { + private long nextGammaChange; + private Field gameSettings, gammaSetting; + + public FullBright() { + super("Fullbright", Keyboard.KEY_M, Category.RENDER); + } + + @Override + public void onEnable() { + try { + if (gameSettings == null) + gameSettings = mc + .getMinecraft() + .getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/Minecraft", + "gameSettings").getMapping()); + + if (gammaSetting == null) + gammaSetting = gameSettings + .get(Wrapper.getMinecraft().getMinecraft()) + .getClass() + .getField( + new ObfuscatedMapping( + "net/minecraft/src/GameSettings", + "gammaSetting").getMapping()); + } catch (Exception e) { + e.printStackTrace(); + } + + EventHandler.getInstance().registerListener(this); + } + + @EventSubscribe + public void onTick(EventTick e) { + try { + if (this.isEnabled()) { + if (Math.floor(gammaSetting.getFloat(gameSettings.get(Wrapper + .getMinecraft().getMinecraft()))) < 10F) { + if (System.currentTimeMillis() > nextGammaChange) { + gammaSetting + .setFloat( + gameSettings.get(Wrapper.getMinecraft() + .getMinecraft()), + gammaSetting.getFloat(gameSettings + .get(Wrapper.getMinecraft() + .getMinecraft())) + 0.25F); + nextGammaChange = System.currentTimeMillis() + 5L; + } + } + + if (Math.floor(gammaSetting.getFloat(gameSettings.get(Wrapper + .getMinecraft().getMinecraft()))) > 10F) { + if (System.currentTimeMillis() > nextGammaChange) { + gammaSetting + .setFloat( + gameSettings.get(Wrapper.getMinecraft() + .getMinecraft()), + gammaSetting.getFloat(gameSettings + .get(Wrapper.getMinecraft() + .getMinecraft())) - 0.25F); + nextGammaChange = System.currentTimeMillis() + 5L; + } + } + } else { + if (gammaSetting.getFloat(gameSettings.get(Wrapper + .getMinecraft().getMinecraft())) > 1f) { + if (System.currentTimeMillis() > nextGammaChange) { + gammaSetting + .setFloat( + gameSettings.get(Wrapper.getMinecraft() + .getMinecraft()), + gammaSetting.getFloat(gameSettings + .get(Wrapper.getMinecraft() + .getMinecraft())) - 0.25F); + nextGammaChange = System.currentTimeMillis() + 5L; + } + } else + EventHandler.getInstance().unregisterListener(this); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + @Override + public void onDisable() { + } +} diff --git a/src/io/github/jordandoyle/mcinject/proxy/Proxy.java b/src/io/github/jordandoyle/mcinject/proxy/Proxy.java new file mode 100644 index 0000000..93b07a3 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/proxy/Proxy.java @@ -0,0 +1,7 @@ +package io.github.jordandoyle.mcinject.proxy; + +import java.lang.reflect.InvocationHandler; + +public interface Proxy extends InvocationHandler { + public Object proxy(); +} diff --git a/src/io/github/jordandoyle/mcinject/proxy/interfaces/Minecraft.java b/src/io/github/jordandoyle/mcinject/proxy/interfaces/Minecraft.java new file mode 100644 index 0000000..285b605 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/proxy/interfaces/Minecraft.java @@ -0,0 +1,5 @@ +package io.github.jordandoyle.mcinject.proxy.interfaces; + +public interface Minecraft { + public Object getMinecraft(); +} diff --git a/src/io/github/jordandoyle/mcinject/proxy/proxies/MinecraftProxy.java b/src/io/github/jordandoyle/mcinject/proxy/proxies/MinecraftProxy.java new file mode 100644 index 0000000..45d1a92 --- /dev/null +++ b/src/io/github/jordandoyle/mcinject/proxy/proxies/MinecraftProxy.java @@ -0,0 +1,45 @@ +package io.github.jordandoyle.mcinject.proxy.proxies; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.objectweb.asm.Type; + +import io.github.jordandoyle.mcinject.helpers.ObfuscatedMapping; +import io.github.jordandoyle.mcinject.proxy.Proxy; +import io.github.jordandoyle.mcinject.proxy.interfaces.Minecraft; + +public class MinecraftProxy implements Proxy { + private static Class c; + private static Object instance; + + static { + try { + String className = (new ObfuscatedMapping("net/minecraft/src/Minecraft")).getMapping(); + c = Class.forName(className); + Method m = c.getDeclaredMethod((new ObfuscatedMapping("net/minecraft/src/Minecraft", "getMinecraft", "()L" + className.replace(".", "/") + ";")).getMapping()); + instance = m.invoke(null); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public Object proxy() { + return java.lang.reflect.Proxy.newProxyInstance(Minecraft.class.getClassLoader(), new Class[] { Minecraft.class }, this); + } + + @Override + public Object invoke(Object proxy, Method m, Object[] args) + throws Throwable { + Object res = null; + String name = new ObfuscatedMapping("net/minecraft/src/Minecraft", m.getName(), Type.getMethodDescriptor(m)).getMapping(); + + m = c.getDeclaredMethod(name, m.getParameterTypes()); + m.setAccessible(true); + res = m.invoke(instance, args); + + return res; + } +} -- libgit2 1.7.2