diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6913315 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ + +.vs +[Pp]ackages +[Oo]bj +[Bb]in +*.user +.git +.gita +!Binaries/*.zip +Binaries +*.lnk + +*.db +League-of-Legends-Bot/Binaries/LeagueAI.zip +League-of-Legends-Bot/ServiceLeagueAI/Data/LeagueAI.Libraries.Embed.dll +Data +ServiceLeagueAI.xml diff --git a/LICENSE b/LICENSE index ecf12db..e72bfdd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,9 +1,674 @@ -ĐIỀU KHOẢN SỬ DỤNG. -1. Bằng cách sử dụng phần mềm này, người dùng hoàn toàn chấp thuận các điều khoản của phần mềm. -2. Điều khoản có thể sửa đổi phù hợp với phát luật hiện hành. -3. Phần mềm cam kết không thu thập dữ liệu cá nhân. - -LICENCE. -1. By using this software, the user fully accepts the terms of the software. -2. Terms may be modified in accordance with applicable law. -3. The software commits not to collect personal data. + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 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. + + + Copyright (C) + + 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: + + Copyright (C) + 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 +. \ No newline at end of file diff --git a/Source/Api/ActivePlayerApi.cs b/Source/Api/ActivePlayerApi.cs new file mode 100644 index 0000000..9b93ebf --- /dev/null +++ b/Source/Api/ActivePlayerApi.cs @@ -0,0 +1,177 @@ +using LeagueAI.Libraries.Entities; +using LeagueAI.Libraries.Game; +using LeagueAI.Libraries.Helper; +using LeagueAI.Libraries.Interfaces; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Text; +using System.Threading; + +namespace LeagueAI.Libraries.Api +{ + public sealed class ActivePlayerApi : BaseApiMember + { + private readonly Dictionary upgradeSkillMap; + public ActivePlayerApi(GameApi api) : base(api) + { + // Khởi tạo thứ tự cộng kỹ năng + if (File.Exists(DEFINE.ConfigPath)) + { + var content = ""; + using (FileStream fileStream = new FileStream(DEFINE.ConfigPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + using (StreamReader streamReader = new StreamReader(fileStream, Encoding.Default)) + { + content = streamReader.ReadToEnd(); + } + } + JObject jobj = JObject.Parse(content); + Dictionary dictation = jobj?["SettingGame"]?["upgrandSkillMap"]?.ToObject>(); + upgradeSkillMap = dictation; + return; + } + + upgradeSkillMap = new Dictionary() + { + { "1", "Q" }, + { "2", "W" }, + { "3", "E" }, + { "4", "Q" }, + { "5", "W" }, + { "6", "R" }, + { "7", "Q" }, + { "8", "W" }, + { "9", "Q" }, + { "10", "W" }, + { "11", "R" }, + { "12", "Q" }, + { "13", "W" }, + { "14", "E" }, + { "15", "E" }, + { "16", "R" }, + { "17", "E" }, + { "18", "E" }, + { "19", "Q" }, + { "20", "W" }, + { "21", "E" }, + { "22", "R" }, + }; + } + + public IEntity GetNearEnemyPosition() + { + var handle = Program.GameHandle; + if (handle == null || handle == IntPtr.Zero) return null; + + // Lấy toạ độ của kẻ địch đang tấn công + Point? target = ScreenHelper.GetColorPosition(DEFINE.ColorEnemyFocus.ToColorRGB().Value, handle); + if (target != null) return new Minion(new Point(target.Value.X, target.Value.Y)); + + // Lấy toạ độ của kẻ địch trên màn hinh + target = ScreenHelper.GetColorPosition(DEFINE.ColorEnemyLevelBox.ToColorRGB().Value, handle, deviantX: 30, deviantY: 30); + if (target != null) return new Minion(new Point(target.Value.X, target.Value.Y)); + + // Lấy toạ độ của creep địch + target = ScreenHelper.GetColorPosition(DEFINE.ColorEnemyCreep.ToColorRGB().Value, handle); + if (target != null) return new Minion(new Point(target.Value.X, target.Value.Y)); + + return null; + } + + public void TryCastSpellOnTarget( + string skill, + int delay + ) + { + // Tung kỹ năng vào vị trí kẻ địch gần nhất + IEntity target = GetNearEnemyPosition(); + + if (target == null) return; + + skill = skill.ToUpper(); + InputHelper.MoveMouse(target.Position.X, target.Position.Y); + InputHelper.PressKey(skill, delay); + Thread.Sleep(BotApi.IDLE_DELAY); + } + + public void TryNormalAttack(char keyAttack = 'a', int delay = 100) + { + IEntity target = GetNearEnemyPosition(); + + if (target == null) return; + + InputHelper.PressKey(keyAttack.ToString(), delay); + InputHelper.MoveMouse(target.Position.X, target.Position.Y); + Thread.Sleep(BotApi.IDLE_DELAY); + } + + public void UpgradeSpell( + string skill + ) + { + // Lên cấp skill bằng phím tắt ctrl + skill + InputHelper.KeyDown("ControlKey", 50); + InputHelper.KeyDown(skill, 50); + Thread.Sleep(BotApi.IDLE_DELAY); + InputHelper.KeyUp(skill, 50); + InputHelper.KeyUp("ControlKey", 50); + Thread.Sleep(BotApi.IDLE_DELAY); + } + + public void UpgradeSpellOnLevelUp(double level = -1) + { + if (level <= 0) + return; + + if (upgradeSkillMap.TryGetValue(level.ToString(), out string skill)) + UpgradeSpell(skill); + } + + public double GetHealthPercent() + { + // Lấy ra % máu hiện tại. + ChampionStat stats = GameLCU.GetStats(); + if (stats?.currentHealth != null + && stats?.maxHealth != null) + { + return (stats?.currentHealth ?? 10) / (stats?.maxHealth ?? 100); + } + + return -1; + } + + public double GetManaPercent() + { + // Lấy ra % mana hiện tại. + ChampionStat stats = GameLCU.GetStats(); + if (stats?.resourceValue != null + && stats?.resourceMax != null) + { + return (stats?.resourceValue ?? 10) / (stats?.resourceMax ?? 100); + } + + return -1; + } + + public double GetLevel() => GameLCU.GetPlayerLevel(); + + public double GetGolds() => GameLCU.GetPlayerGolds(); + + public List GetItemBuyed(string summonerName) => GameLCU.GetPlayerItems(summonerName); + + public string GetName() => GameLCU.GetPlayerName(); + + public bool IsDead() => GameLCU.IsPlayerDead(); + + public void Recall(int delay) + { + InputHelper.PressKey("B", 50); + Thread.Sleep(delay); + } + + public void TryCastSpellOnTarget(char skill, int delay) => TryCastSpellOnTarget(skill.ToString(), delay); + } +} diff --git a/Source/Api/BaseApiMember.cs b/Source/Api/BaseApiMember.cs new file mode 100644 index 0000000..30ada9b --- /dev/null +++ b/Source/Api/BaseApiMember.cs @@ -0,0 +1,15 @@ +using LeagueAI.Libraries.Interfaces; + +namespace LeagueAI.Libraries.Api +{ + public abstract class BaseApiMember where T : IApi + { + protected T Api { get; private set; } + + + public BaseApiMember(T api) + { + Api = api; + } + } +} diff --git a/Source/Api/BotApi.cs b/Source/Api/BotApi.cs new file mode 100644 index 0000000..cdfb523 --- /dev/null +++ b/Source/Api/BotApi.cs @@ -0,0 +1,33 @@ +using LeagueAI.Libraries.Enums; +using LeagueAI.Libraries.Helper; +using LeagueAI.Libraries.Interfaces; +using System.Threading; + +namespace LeagueAI.Libraries.Api +{ + public sealed class BotApi : IApi + { + public static int IDLE_DELAY { get; set; } = 150; + + public void Log(object message) + { + Logger.WriteLine(message); + } + public void Warn(object message) + { + Logger.WriteLine(message, EMessageState.WARNING); + } + public void Error(object message) + { + Logger.WriteLine(message, EMessageState.ERROR); + } + public void Wait(int ms) + { + Thread.Sleep(ms); + } + public void ExecutePattern(string name) + { + PatternsUlti.Execute(name); + } + } +} diff --git a/Source/Api/CameraApi.cs b/Source/Api/CameraApi.cs new file mode 100644 index 0000000..7d13f1d --- /dev/null +++ b/Source/Api/CameraApi.cs @@ -0,0 +1,52 @@ +using InputManager; +using LeagueAI.Libraries.Helper; +using System.Drawing; +using System.Threading; + +namespace LeagueAI.Libraries.Api +{ + public sealed class CameraApi : BaseApiMember + { + public bool isLocked { get; set; } + public CameraApi(GameApi api) : base(api) + { + isLocked = false; + } + + public void Toggle() + { + // Khoá/mở camera + string key = Configuration.Instance.SettingGame?.hotKeys?.evtCameraLockToggle?.ToString() ?? "y"; + key = key?.Replace("[", "")?.Replace("]", "")?.ToUpper(); + InputHelper.PressKey(key, 50); + isLocked = !isLocked; + } + + public void LockAlly( + int allyIndice + ) + { + // Khoá camera vào đồng minh + string key = "F" + allyIndice; + InputHelper.KeyUp(key, 50); + InputHelper.KeyDown(key, 50); + Thread.Sleep(BotApi.IDLE_DELAY); + } + + public void PingComing() + { + // Ping đang tới + var startPoint = new Point(DEFINE.TargetClick[0], DEFINE.TargetClick[1]); + var endPoint = new Point(DEFINE.TargetClick[0] + 100, DEFINE.TargetClick[1]); + + Mouse.Move(startPoint.X, startPoint.Y); + InputHelper.PressKey("V", 100); + Mouse.ButtonDown(Mouse.MouseKeys.Left); + Thread.Sleep(200); + Mouse.Move(endPoint.X, endPoint.Y); + Thread.Sleep(100); + Mouse.ButtonUp(Mouse.MouseKeys.Left); + Thread.Sleep(BotApi.IDLE_DELAY); + } + } +} diff --git a/Source/Api/ChatApi.cs b/Source/Api/ChatApi.cs new file mode 100644 index 0000000..d4ecd48 --- /dev/null +++ b/Source/Api/ChatApi.cs @@ -0,0 +1,39 @@ +using LeagueAI.Libraries.Helper; +using System.Drawing; +using System.Threading; +using System.Windows.Forms; + +namespace LeagueAI.Libraries.Api +{ + public sealed class ChatApi : BaseApiMember + { + public ChatApi(GameApi api) : base(api) { } + + public void TalkInGame(string message, int delayPressKey = 40, int delay = 200) + { + Thread.Sleep(300); + + InputHelper.PressKey(Keys.Enter, delay); + InputHelper.InputWords(message, delayPressKey, delay); + InputHelper.PressKey(Keys.Enter, delay); + } + + public void TalkInClient(string message, int delayPressKey = 20, int delay = 200) + { + Thread.Sleep(1500); + + var locationSafe = DEFINE.ColorBoxChatBanPick; + var color = Color.FromArgb(locationSafe[0], locationSafe[1], locationSafe[2]); + + var handle = Program.ClientHandle; + if (handle == null || handle == System.IntPtr.Zero) return; + + Point? target = ScreenHelper.GetColorPosition(color, handle, deviantX: 0, deviantY: 0); + if (target == null) return; + + InputHelper.LeftClick(target.Value.X, target.Value.Y, delay); + InputHelper.InputWords(message, delayPressKey, delay); + InputHelper.PressKey(Keys.Enter, delay); + } + } +} diff --git a/Source/Api/ClientApi.cs b/Source/Api/ClientApi.cs new file mode 100644 index 0000000..5c55945 --- /dev/null +++ b/Source/Api/ClientApi.cs @@ -0,0 +1,56 @@ +using LeagueAI.Libraries.Entities; +using LeagueAI.Libraries.Enums; +using LeagueAI.Libraries.Game; +using LeagueAI.Libraries.Helper; +using LeagueAI.Libraries.Interfaces; +using System.Threading; + +namespace LeagueAI.Libraries.Api +{ + public sealed class ClientApi : IApi + { + public void WaitClientOpen( + int timeout = 60 + ) + { + while (!IsClientOpen()) + { + if (timeout <= 0) + { + Logger.WriteLine(DEFINE.NotOpenGameClientYetLog, EMessageState.ERROR); + Program.Exit(1); + } + timeout -= 5; + Thread.Sleep(5000); + } + } + + public bool IsClientOpen() => ClientLCU.IsClientOpen(); + + public void Initialize() => ClientLCU.Initialize(); + public void BringToFont() => ClientLCU.BringToFont(); + public void CenterScreen() => ClientLCU.CenterScreen(); + public void CloseClient() => ClientLCU.CloseClient(); + public void KillProcessRenderUxClient() => ClientLCU.KillProcessRenderUxClient(); + + public void OpenClient() => ClientLCU.OpenClient(); + + public Summoner LoadSummoner() => ClientLCU.GetCurrentSummoner(); + + public void CreateLobby(EQueueRoom queueId) => ClientLCU.CreateLobby(queueId); + + public ESearchMatchResult SearchMatch() => ClientLCU.SearchMatch(); + + public void Reconnect() => ClientLCU.Reconnect(); + + public void AcceptMatch() => ClientLCU.AcceptMatch(); + + public bool IsMatchFound() => ClientLCU.IsMatchFound(); + + public EGameflowPhase GetGameflowPhase() => ClientLCU.GetGameflowPhase(); + + public EChampionPickResult PickChampion(EChampion champion) => ClientLCU.PickChampion(champion); + public bool PickSkin(Summoner player) => ClientLCU.PickSkin(player); + public string HonorPlayer() => ClientLCU.PostHonorAfterGameDone(); + } +} diff --git a/Source/Api/GameApi.cs b/Source/Api/GameApi.cs new file mode 100644 index 0000000..714bffe --- /dev/null +++ b/Source/Api/GameApi.cs @@ -0,0 +1,286 @@ +using LeagueAI.Libraries.Entities; +using LeagueAI.Libraries.Enums; +using LeagueAI.Libraries.Game; +using LeagueAI.Libraries.Helper; +using LeagueAI.Libraries.Interfaces; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Threading; + +namespace LeagueAI.Libraries.Api +{ + public sealed class GameApi : IApi + { + private static readonly Random rand = new Random(); + public ShopApi shop { get; private set; } + public CameraApi camera { get; private set; } + public ChatApi chat { get; private set; } + public ActivePlayerApi player { get; private set; } + private ESideTeam? side { get; set; } + + public GameApi() + { + shop = new ShopApi(this); + camera = new CameraApi(this); + chat = new ChatApi(this); + player = new ActivePlayerApi(this); + } + + public void WaitGameStart(int timeout = 60) + { + while (timeout >= 0) + { + if (GameLCU.IsApiReady() + && GameLCU.GetGameTime() > 2d + && CheckColorExist(DEFINE.ColorSafePlan.ToColorRGB().Value) + ) + { + return; + } + timeout -= 5; + Thread.Sleep(5000); + } + } + + public void SetupHandleGame( + int timeout = 300 + ) + { + while (timeout >= 0) + { + Program.GameHandle = HandleExtention.GetGameHandle(""); + if (Program.GameHandle != null && Program.GameHandle != IntPtr.Zero) return; + + timeout -= 10; + Thread.Sleep(10000); + } + Logger.WriteLine(DEFINE.CantStartGame, EMessageState.ERROR); + Program.Exit(1); + } + + public bool IsGameOpen() => GameLCU.IsGameOpen(); + + public bool IsAPIReady() => GameLCU.IsApiReady(); + + public void BringGameToFront() + { + // Gán tiến trình game lên đầu (focus). + if (!GameLCU.BringToFont()) + { + Logger.WriteLine(DEFINE.ErrorBringToFrontLog, EMessageState.WARNING); + } + } + + public void CenterGameToScreen() + { + // Căn giữa màn hình. + if (!GameLCU.CenterScreen()) + { + Logger.WriteLine(DEFINE.ErrorCenterScreenLog, EMessageState.WARNING); + } + } + + public List GetAllies() => GameLCU.GetAllies(); + + public int GetAllyIdToFollow() + { + // Chọn lấy thằng khoẻ nhất + const int StartIndex = 2; + int max = -1; + int index = StartIndex; + int i = index; + + List allies = GameLCU.GetAllies(); + PlayerList followAlly = null; + + if (allies == null || allies.Count <= 0) return -1; + + foreach (PlayerList ally in allies) + { + if (i - StartIndex == 4) break; + + if (ally.summonerName == player.GetName()) continue; + + if (ally.scores.kills > max && ally.isDead == false) + { + if (!ally.summonerSpells.summonerSpellOne.displayName.ToString().ToLower().Contains("smite") && // not jungler + !ally.summonerSpells.summonerSpellTwo.displayName.ToString().ToLower().Contains("smite")) + { + max = (int)ally.scores.kills + (int)ally.scores.assists + ally.level.Value; + followAlly = ally; + index = i; + } + } + i++; + } + + Logger.WriteLine(string.Format(DEFINE.FollowLog, $"[{followAlly.summonerName}]")); + return index; + + } + + public ESideTeam GetSide() + { + if (side == null) side = GameLCU.GetPlayerSide(); + return side.Value; + } + + public void MoveRandomCenter( + int delay, + bool isRandom = true + ) + { + int x = DEFINE.TargetClick[0]; + int y = DEFINE.TargetClick[1]; + if (isRandom) + { + x += rand.Next(-100, 100); + y += rand.Next(-100, 100); + } + InputHelper.RightClick(x, y, delay); + Thread.Sleep(BotApi.IDLE_DELAY); + } + + public void MoveToSafePlace(int moveTime = 10000) + { + var handle = Program.GameHandle; + if (handle == null || handle == IntPtr.Zero) return; + + var locationSafe = DEFINE.ColorSafePlan; + var color = Color.FromArgb(locationSafe[0], locationSafe[1], locationSafe[2]); + Point? target = ScreenHelper.GetColorPosition(color, handle, deviantX: 0, deviantY: 0); + if (target == null) return; + InputHelper.RightClick(target.Value.X, target.Value.Y, 100); + Thread.Sleep(moveTime); + } + + public void MoveToBlackJung(int moveTime = 10000) + { + var handle = Program.GameHandle; + if (handle == null || handle == IntPtr.Zero) return; + + Point? target = ScreenHelper.GetColorPosition(DEFINE.ColorBlackJungle.ToColorRGB().Value, handle, deviantX: 0, deviantY: 0); + if (target == null) return; + InputHelper.RightClick(target.Value.X, target.Value.Y, 100); + Thread.Sleep(moveTime); + } + + public void MoveToPoint( + Point target, + int delay, + bool random = true + ) + { + if (random) + { + target.X += rand.Next(40, 150); + target.Y += rand.Next(40, 150); + } + InputHelper.RightClick(target.X, target.Y, delay); + Thread.Sleep(BotApi.IDLE_DELAY); + } + + public void MoveToAllyCreep( + int checkEvery = 3000, + int loopSearch = 20, + Point? target = null + ) + { + var handle = Program.GameHandle; + if (handle == null || handle == IntPtr.Zero || loopSearch < 0) return; + + InputHelper.PressKey(System.Windows.Forms.Keys.Space, BotApi.IDLE_DELAY); + + if (FoundEnemy()) return; + + Point? allyCreep = ScreenHelper.GetColorPosition(DEFINE.ColorAllyCreep.ToColorRGB().Value, handle, 0, 0); + if (allyCreep != null) + { + InputHelper.RightClick(allyCreep.Value.X, allyCreep.Value.Y, 1000); + return; + } + + // tim ally creep tren man hinh + if (target == null) target = ScreenHelper.GetColorPosition(DEFINE.ColorAllyCreepMiniMap.ToColorRGB().Value, handle, 0, 0); + if (target == null) return; + InputHelper.RightClick(target.Value.X, target.Value.Y, BotApi.IDLE_DELAY); + Thread.Sleep(checkEvery); + MoveToAllyCreep(checkEvery, --loopSearch, target); + } + + public void MoveToAlly(bool moveInto = true) + { + var handle = Program.GameHandle; + if (handle == null || handle == IntPtr.Zero) return; + + InputHelper.PressKey(System.Windows.Forms.Keys.Space, BotApi.IDLE_DELAY); + Point? ally = ScreenHelper.GetColorPosition(DEFINE.ColorAllyLevelBox.ToColorRGB().Value, handle, 0, 0); + if (ally != null) + { + if (moveInto) InputHelper.RightClick(ally.Value.X, ally.Value.Y, 1000); + return; + } + ally = ScreenHelper.GetColorPosition(DEFINE.ColorAllyCreep.ToColorRGB().Value, handle, 0, 0); + if (ally != null) + { + if (moveInto) InputHelper.RightClick(ally.Value.X, ally.Value.Y, 1000); + return; + } + } + + public bool FoundEnemy() + { + var handle = Program.GameHandle; + if (handle == null || handle == IntPtr.Zero) return false; + + InputHelper.PressKey(System.Windows.Forms.Keys.Space, BotApi.IDLE_DELAY); + Point? ally = ScreenHelper.GetColorPosition(DEFINE.ColorEnemyLevelBox.ToColorRGB().Value, handle, 0, 0); + if (ally != null) return true; + + ally = ScreenHelper.GetColorPosition(DEFINE.ColorEnemyFocus.ToColorRGB().Value, handle, 0, 0); + if (ally != null) return true; + + ally = ScreenHelper.GetColorPosition(DEFINE.ColorEnemyCreep.ToColorRGB().Value, handle, 0, 0); + if (ally != null) return true; + + return false; + } + + public void CloseWarning( + int delay = 100 + ) + { + var handle = Program.GameHandle; + if (handle == null || handle == IntPtr.Zero) return; + + Point? target = ScreenHelper.GetColorPosition(DEFINE.ColorWarningAfk.ToColorRGB().Value, handle, 0, 0); + if (target == null) return; + InputHelper.LeftClick(target.Value.X, target.Value.Y, delay); + Thread.Sleep(BotApi.IDLE_DELAY); + } + + public void CloseShopIfOpen( + int delay = 100 + ) + { + var handle = Program.GameHandle; + if (handle == null || handle == IntPtr.Zero) return; + + Point? target = ScreenHelper.GetColorPosition(DEFINE.ColorCloseShop.ToColorRGB().Value, handle, 0, 0); + if (target == null) return; + InputHelper.LeftClick(target.Value.X, target.Value.Y, delay); + Thread.Sleep(BotApi.IDLE_DELAY); + } + + public bool CheckColorExist(Color color) + { + var handle = Program.GameHandle; + if (handle == null || handle == IntPtr.Zero) return false; + + Point? target = ScreenHelper.GetColorPosition(color, handle, 0, 0); + if (target == null) return false; + return true; + } + } +} diff --git a/Source/Api/ShopApi.cs b/Source/Api/ShopApi.cs new file mode 100644 index 0000000..75a686d --- /dev/null +++ b/Source/Api/ShopApi.cs @@ -0,0 +1,56 @@ +using LeagueAI.Libraries.Helper; +using System.Threading; + +namespace LeagueAI.Libraries.Api +{ + public sealed class ShopApi : BaseApiMember + { + public bool Opened { get; set; } + public ShopApi(GameApi api) : base(api) + { + Opened = false; + } + + public void Toogle( + int delay) + { + // Tắt mở cửa hàng + Thread.Sleep(200); + if (Opened) + { + InputHelper.PressKey("Escape", delay); + } + else + { + InputHelper.PressKey("P", delay); + } + + Opened = !Opened; + } + + public void SearchItem( + string keyword, + int keyDelay, + int delay) + { + // Mở hộp tìm kiếm và tìm kiếm chữ + Thread.Sleep(200); + InputHelper.KeyDown("LControlKey", 20); + InputHelper.KeyDown("L", 20); + InputHelper.KeyUp("LControlKey", 20); + InputHelper.KeyUp("L", 20); + Thread.Sleep(delay); + + InputHelper.InputWords(keyword, keyDelay, delay); + //Logger.WriteLine("Buyed " + keyword); + } + + public void BuySearchedItem(int delay) + { + // Enter 2 lần để mua (sau khi gõ xong) + Thread.Sleep(200); + InputHelper.PressKey("Enter", delay); + InputHelper.PressKey("Enter", delay); + } + } +} diff --git a/Source/App.config b/Source/App.config new file mode 100644 index 0000000..ecdcf8a --- /dev/null +++ b/Source/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/Source/Configuration.cs b/Source/Configuration.cs new file mode 100644 index 0000000..e7a856a --- /dev/null +++ b/Source/Configuration.cs @@ -0,0 +1,69 @@ +using LeagueAI.Libraries.Enums; +using LeagueAI.Libraries.Helper; +using System; +using System.IO; +using System.Text; + +namespace LeagueAI.Libraries +{ + public sealed class Configuration + { + public string Version { get; set; } + public string ClientProcessName { get; set; } + public string ClientHostProcessName { get; set; } + public string GameProcessName { get; set; } + public string ClientExecutablePath { get; set; } + public string DefaultLeaguePath { get; set; } + public string LeagueGameconfigPath { get; set; } + public string LockfilePath { get; set; } + public string LeaguePersistedSettingsPath { get; set; } + public dynamic SettingGame { get; set; } + + public static Configuration Instance { get; private set; } = new Configuration(); + public static bool Initialize() + { + try + { + var content = ""; + using (FileStream fileStream = new FileStream(DEFINE.ConfigPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + using (StreamReader streamReader = new StreamReader(fileStream, Encoding.Default)) + { + content = streamReader.ReadToEnd(); + } + } + + Instance = DataConvertUlti.DeserializeJson(content); + return true; + } + catch (Exception ex) + { + Logger.WriteLine(ex.Message, EMessageState.ERROR); + Logger.WriteLine(string.Format(DEFINE.CantLoadConfigLog, DEFINE.ConfigPath)); + } + Program.Exit(1); + return false; + } + + public void Init() + { + Instance = new Configuration() + { + DefaultLeaguePath = null, + ClientExecutablePath = null, + ClientHostProcessName = null, + ClientProcessName = null, + GameProcessName = null, + LeagueGameconfigPath = null, + LockfilePath = null, + LeaguePersistedSettingsPath = null, + SettingGame = null, + }; + } + + public void Save(string path = DEFINE.ConfigPath) + { + File.WriteAllText(path, DataConvertUlti.SerializeJson(this)); + } + } +} diff --git a/Source/Data64.dat b/Source/Data64.dat new file mode 100644 index 0000000..ed74329 Binary files /dev/null and b/Source/Data64.dat differ diff --git a/Source/Define.cs b/Source/Define.cs new file mode 100644 index 0000000..8c1ac87 --- /dev/null +++ b/Source/Define.cs @@ -0,0 +1,135 @@ +using LeagueAI.Libraries.Entities; +using LeagueAI.Libraries.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace LeagueAI.Libraries +{ + public sealed partial class DEFINE + { + public static Encoding HttpRequestEncoding = Encoding.UTF8; + public const string ConfigPath = "config.json"; + public const int KeyboardLanguage = 1033; + public const string LogPath = "log.txt"; + public const string DatetimeFormat = "dd-MM-yyyy"; + + #region Game file + public static string ClientExecutableName { get; set; } = "League of Legends"; + public static string GameExecutableName { get; set; } = "League of Legends (TM) Client"; + public static string LeagueClientUxRender { get; set; } = "LeagueClientUxRender.exe"; + public static string LeagueGameconfigPath { get; set; } = "game.cfg"; + public static string LockfilePath { get; set; } = "lockfile"; + public static string LeaguePersistedSettingsPath { get; set; } = "PersistedSettings.json"; + + #endregion + + public static string ArgumentClient { get; set; } = "--output-base-dir="; + + #region message log + public static string InitSettingLog { get; set; } = "** Bắt đầu cài đặt **"; + public static string FinishSettingLog { get; set; } = "Khởi tạo thành công"; + public static string SettingKeyboardLog { get; set; } = "Cài đặt phím tắt trong game thành công."; + public static string SettingScreenLog { get; set; } = "Cài đặt màn hình thành công."; + public static string InputLicenseLog { get; set; } = "Nhập mã kích hoạt (bấm enter nếu đang có sự kiện miễn phí): "; + public static string WrongLicense2Log { get; set; } = "Khoá sai định dạng hoặc hết thời gian sử dụng."; + public static string ServerErrorLog { get; set; } = "Đã có lỗi khi chuyển đổi định dạng ngày tháng. Lỗi hệ thống!"; + public static string SettingError { get; set; } = "Cấu hình đường dẫn sai. Không thể lấy thông tin kết nối Client API."; + public static string TrustCerLog { get; set; } = "Không thể tải chứng chỉ tin cậy. Ấn phím bất kỳ để thoát."; + public static string UnknowServerLog { get; set; } = "Không có server nào đang hoạt động, xin hãy kiểm tra lại cấu hình."; + public static string UnknowServer2Log { get; set; } = "Không có server nào đang hoạt động, vui lòng nhập địa chỉ server: "; + public static string UnknowEventLog { get; set; } = "Không có sự kiện miễn phí nào đang khả dụng."; + public static string RequestEventLog { get; set; } = "Đã gửi yêu cầu kích hoạt. Nếu được chấp thuận, bạn có thể sử dụng như bình thường."; + public static string ErrorLog { get; set; } = "Lỗi không xác định (T.T). Nếu bạn liên tục gặp vấn đề này, xin hãy báo cáo một vấn đề mới."; + public static string WaitGameLog { get; set; } = "Chờ đợi {0}s để mở game ..."; + public static string EndGameLog { get; set; } = "Hoàn thành game: {0}."; + public static string EndMission { get; set; } = "Tự động đóng - hoàn thành tiến trình game."; + public static string ErrorCenterScreenLog { get; set; } = "Không thể căn chỉnh cửa sổ trò chơi."; + public static string ErrorBringToFrontLog { get; set; } = "Không thể gán cửa sổ trò chơi lên đầu."; + public static string FollowLog { get; set; } = "Đi theo: {0}."; + public static string CantLoadConfigLog { get; set; } = "Tệp tin cấu hình {0} không thể tải."; + public static string CantLoadGameAPILog { get; set; } = "Không thể đọc API client"; + public static string NotOpenGameClientYetLog { get; set; } = "Chưa mở game League Client."; + public static string CantFindGameLog { get; set; } = "Không thể tìm trận: {0}."; + public static string CantStartGame { get; set; } = "Không thể mở game do hết thời gian chờ."; + public static string ExecuteUpdate { get; set; } = "Đang cập nhật..."; + public static string PatternErrorLog { get; set; } = "Không tìm thấy kịch bản {0}."; + public static string Reconnected { get; set; } = "Kết nối lại."; + public static string WriteAccessAPI { get; set; } = "Client API: {0}, {1}"; + public static string LogCantGetUsername { get; set; } = "Không thể gọi đến api để lấy được tên người chơi."; + public static string BeginGameLog { get; set; } = "Bắt đầu kịch bản chơi ..."; + public static string BeginCantLoadUserInfoLog { get; set; } = "Không thể tải thông tin người chơi. Thử lại sau 10s."; + public static string BeginMaximumLevelLog { get; set; } = "Đã đạt tới giới hạn level (maxLevel)."; + public static string BeginUserInfoLog { get; set; } = "Xác định người chơi {0}."; + public static string BeginLogError1 { get; set; } = "Đã có lỗi trong quá trình khởi chạy game ..."; + public static string BeginLogError2 { get; set; } = "Không thể tìm trận. Tạo phòng lại ..."; + public static string BeginLogError3 { get; set; } = "Không thể tìm trận. Người chơi chưa sẵn sàng hoặc phòng không tồn tại. Thử lại sau 10s."; + public static string BeginLogError4 { get; set; } = "Lỗi không xác định trong quá trình tìm kiếm trận. Thử lại sau 10s."; + public static string BeginLogError5 { get; set; } = "Không thể tiếp tục, không có tướng để chọn."; + public static string BeginLogError6 { get; set; } = "Không thể chọn tướng chưa sở hữu."; + public static string BeginLogError7 { get; set; } = "Không thể chọn tướng. Đã có người chọn tướng của bạn."; + public static string BeginLog1 { get; set; } = "Đang tìm trận..."; + public static string BeginLog2 { get; set; } = "Không thể tìm trận. Đang trong hàng đợi. Thử lại sau 30s."; + public static string BeginLog3 { get; set; } = "Đã tìm thấy trận."; + public static string BeginLog4 { get; set; } = "Chọn tướng [{0}] thành công."; + public static string BeginLog5 { get; set; } = "Đợi người chơi khác sẵn sàng...."; + public static string BeginLog6 { get; set; } = "Phòng bị huỷ, tìm kiếm trận đấu khác ..."; + public static string InGameLog { get; set; } = "Bắt đầu tiến trình trong game ..."; + public static string InGameLog2 { get; set; } = "Không thể lấy trạng thái của game..."; + public static string InGameLog4 { get; set; } = "Bạn đang ở đội [xanh]!"; + public static string InGameLog5 { get; set; } = "Bạn đang ở đội [đỏ]!"; + public static string InGameTalkFirst { get; set; } = "LeagueAI - Github Kgemas."; + public static string EndGameLog2 { get; set; } = "Bắt đầu tiến trình kết thúc game."; + public static string Logo2 { get; set; } = @" +- Hướng dẫn cài đặt: https://github.com/kgemas/League-AI +- Nhóm hỗ trợ sửa lỗi: https://t.me/+HBclRDdmP4pjYjNl +- Xem các vấn đề đã được xử lý: https://github.com/kgemas/League-AI/issues?q=is%3Aissue+is%3Aclosed +> Chúc may mắn :3"; + public static string Logo1 { get; set; } = @" + + _._ _,-'""`-._ +(,-.`._,'( |\`-/| + `-.-' \ )-`( , o o) + `- \`_`""'- + +> League AI - Kgemas"; + + #endregion + + public static int[] ColorEnemyFocus { get; set; } = new int[] { 216, 41, 41 }; + public static int[] ColorEnemyLevelBox { get; set; } = new int[] { 51, 3, 0 }; + public static int[] ColorAllyLevelBox { get; set; } = new int[] { 0, 28, 44 }; + public static int[] ColorAllyCreep { get; set; } = new int[] { 73, 142, 197 }; + public static int[] ColorEnemyCreep { get; set; } = new int[] { 208, 94, 94 }; + public static int[] ColorAllyCreepMiniMap { get; set; } = new int[] { 76, 152, 216 }; + public static int[] ColorEnemyMiniMap { get; set; } = new int[] { 217, 57, 47 }; + public static int[] ColorSafePlan { get; set; } = new int[] { 47, 126, 155 }; + public static int[] ColorRiver { get; set; } = new int[] { 7, 57, 71 }; + public static int[] ColorWarningAfk { get; set; } = new int[] { 60, 45, 24 }; + public static int[] ColorCloseShop { get; set; } = new int[] { 165, 162, 148 }; + public static int[] ColorBlackJungle { get; set; } = new int[] { 52, 55, 40 }; + public static int[] ColorBoxChatBanPick { get; set; } = new int[] { 62, 53, 1 }; + public static int[] TargetClick { get; set; } = new int[] { 800, 500 }; + public static string DefaultChampion { get; set; } = "Veigar"; + public static string DefaultRoom { get; set; } = "CoopVsAIIntroBot"; + public static string AutoAcquireTarget { get; set; } = "1"; + public static string WindowMode { get; set; } = "2"; + + public static List DefaultItem { get; set; } = new List() + { + new ItemDto("Doran Ring",400), + new ItemDto("Sorcere",1100), + new ItemDto("Lost Chapter",1300), + new ItemDto("Luden Tempest",2100), + new ItemDto("Needlessly Large Rod",1250), + new ItemDto("Needlessly Large Rod",1250), + new ItemDto("Rabadon Deathcap",1100), + }; + + #region Champion list + public static EChampion[] Champions { get; set; } = Enum.GetValues(typeof(EChampion)).Cast().ToArray(); + #endregion + + } +} diff --git a/Source/Define2.cs b/Source/Define2.cs new file mode 100644 index 0000000..7dca0bd --- /dev/null +++ b/Source/Define2.cs @@ -0,0 +1,430 @@ +namespace LeagueAI.Libraries +{ + public sealed partial class DEFINE + { + #region GameCfg Template + public static string GameCfgTemplate { get; set; } = @" +[FloatingText] +Special_Enabled=1 +Score_Enabled=1 +QuestReceived_Enabled=1 +ManaDamage_Enabled=1 +Level_Enabled=1 +Invulnerable_Enabled=1 +Heal_Enabled=1 +Gold_Enabled=1 +Experience_Enabled=0 +EnemyDamage_Enabled=1 +Dodge_Enabled=1 +Damage_Enabled=1 + +[General] +ClampCastTargetLocationWithinMaxRange=0 +SystemMouseSpeed=0 +Height=1080 +Width=1920 +TargetChampionsOnlyAsToggle=0 +MinimizeCameraMotion=0 +EnableScreenShake=1 +EnableLeftMouseButtonAttackMove=0 +EnableLightFx=0 +EnableCustomAnnouncer=1 +AlwaysShowExtendedTooltip=1 +CfgVersion=13.13.518.539 +WindowMode=1 +WaitForVerticalSync=0 +ThemeMusic=0 +SnapCameraOnRespawn=0 +ShowTurretRangeIndicators=1 +ShowGodray=1 +ShowCursorLocator=0 +RelativeTeamColors=1 +RecommendJunglePaths=1 +PreferOpenGLLegacyMode=0 +PreferDX9LegacyMode=0 +PredictMovement=1 +OSXMouseAcceleration=0 +HideEyeCandy=0 +GameMouseSpeed=10 +EnableTargetedAttackMove=1 +EnableAudio=1 +CursorScale=0.5000 +CursorOverride=0 +BindSysKeys=0 +AutoAcquireTarget=0 +UserSetResolution=1 + +[HUD] +ObjectiveVoteScale=1.0000 +ShopScale=0.4444 +PracticeToolScale=1.0000 +MiddleMouseScrollSpeed=0.5000 +DeathRecapScale=1.0000 +NameTagDisplay=1 +ChatChannelVisibility=1 +ShowStatsPanel_StatStones=0 +ShowPlayerStats=1 +ShowPlayerPerks=0 +ShowFPSAndLatency=1 +ShowSpellRecommendation=1 +ShowHealthBarShake=1 +ShowChampionIndicator=0 +ShowAllChannelChatSpectator=0 +HideEnemySummonerEmotes=0 +SmartCastWithIndicator_CastWhenNewSpellSelected=1 +SmartCastOnKeyRelease=0 +ShowTimestamps=0 +ShowTeamFramesOnLeft=1 +ShowSummonerNamesInScoreboard=0 +ShowSummonerNames=1 +ShowSpellRecommendations=1 +ShowSpellCosts=0 +ShowOffScreenPointsOfInterest=1 +ShowNeutralCamps=1 +ShowAttackRadius=1 +ShowAlliedChat=1 +ShowAllChannelChat=0 +ScrollSmoothingEnabled=0 +NumericCooldownFormat=1 +MirroredScoreboard=1 +MinimapScale=1.0000 +MinimapMoveSelf=1 +MiddleClickDragScrollEnabled=0 +MapScrollSpeed=0.5000 +KeyboardScrollSpeed=0.6600 +GlobalScale=0.0000 +FlipMiniMap=0 +FlashScreenWhenStunned=1 +FlashScreenWhenDamaged=1 +EternalsMilestoneDisplayMode=0 +EnableLineMissileVis=1 +EmoteSize=0 +EmotePopupUIDisplayMode=0 +DrawHealthBars=1 +DisableHudSpellClick=0 +ChatScale=36 +CameraLockMode=0 +AutoDisplayTarget=1 + +[LossOfControl] +ShowSlows=0 +LossOfControlEnabled=1 + +[Performance] +ShadowQuality=4 +FrameCapType=2 +EnvironmentQuality=4 +EffectsQuality=4 +CharacterQuality=4 +EnableGrassSwaying=1 +EnableFXAA=1 +EnableHUDAnimations=0 +AutoPerformanceSettings=0 + +[Voice] +InputDevice=Default System Device +InputVolume=0.5000 +ActivationSensitivity=0.6500 +InputMode=0 +ShowVoicePanelWithScoreboard=1 +ShowVoiceChatHalos=1 + +[Volume] +VoiceVolume=0.7500 +VoiceMute=0 +SfxVolume=0.7500 +SfxMute=0 +PingsVolume=0.7500 +PingsMute=0 +MusicVolume=0.3000 +MusicMute=0 +MasterVolume=0.4800 +MasterMute=0 +AnnouncerVolume=0.7500 +AnnouncerMute=0 +AmbienceVolume=0.7500 +AmbienceMute=0 + +[ColorPalette] +ColorPalette=0 + +[MapSkinOptions] +MapSkinOptionDisableWorlds=0 +MapSkinOptionDisableURF=0 +MapSkinOptionDisableStarGuardian=0 +MapSkinOptionDisableSnowdown=0 +MapSkinOptionDisableProject=0 +MapSkinOptionDisablePopstar=0 +MapSkinOptionDisablePoolParty=0 +MapSkinOptionDisableOdyssey=0 +MapSkinOptionDisableMSI=0 +MapSkinOptionDisableLunarRevel=0 +MapSkinOptionDisableArcade=0 + +[Chat] +ReplayNativeOffsetY=0.0000 +ReplayNativeOffsetX=0.0000 +NativeOffsetY=0.0000 +NativeOffsetX=0.0000 +EnableChatFilter=1 + +[TFTHUD] +EnableChat=1 + +[ItemShop] +NativeOffsetY=0.0046 +NativeOffsetX=-0.0021 +CurrentTab=1 +InvertDisplayOrder=0 +InventoryPanelPinned=0 +ConsumablesPanelPinned=0 +BootsPanelPinned=0 + +[Replay] +EnableDirectedCamera=1 + +[Mobile] +LastTickerTime= +AppRegion= +SelectedQueue=1090 +iOSMetalUserId=-1 +iOSMetalPercentEnabled=0 +Camera Height=0 +OfferedTutorial=0 + +[Highlights] +VideoQuality=0 +VideoFrameRate=60 +ScaleVideo=720 +AudioQuality=1 + +[TFTChat] +NativeOffsetY=0.0000 +NativeOffsetX=0.0000 + +[Accessibility] +ColorLevel=0.5000 +ColorGamma=0.5000 +ColorContrast=0.5000 +ColorBrightness=0.5000 + + +[Ftux] +SenOffscreenPing=1 +"; + #endregion + #region InputINI Template + public static string InputINITemplate { get; set; } = @" +[GameEvents] +evtToggleReplayTimeControls=[] +evtPracticeToolTurretInv=null +evtPracticeToolToggleTurrets=null +evtPracticeToolToggleMinions=null +evtPracticeToolTeleport=null +evtPracticeToolSpawnJunglePlants=null +evtPracticeToolSpawnJungle=null +evtPracticeToolSpawnDragonOcean=null +evtPracticeToolSpawnDragonEarth=null +evtPracticeToolSpawnDragonFire=null +evtPracticeToolSpawnDragonElder=null +evtPracticeToolSpawnDragonAir=null +evtPracticeToolRemoveTargetDummy=null +evtPracticeToolSpawnEnemyTargetDummy=null +evtPracticeToolSpawnAlliedTargetDummy=null +evtPracticeToolRevive=null +evtPracticeToolResetPAR=null +evtPracticeToolResetHP=null +evtPracticeToolResetGame=null +evtPracticeToolResetCooldown=null +evtPracticeToolLockLevel=null +evtPracticeToolIncLevel=null +evtPracticeToolIncGold=null +evtPracticeToolIncGameClock=null +evtToggleReplayPause=[] +evtUseVisionItem=[4] +evtUseItem7=[b] +evtUseItem6=[7] +evtUseItem5=[6] +evtUseItem4=[5] +evtUseItem3=[3] +evtUseItem2=[2] +evtUseItem1=[1] +evtToggleMinionHealthBars= +evtSysMenu=[Esc] +evtSmartPlusSelfCastWithIndicatorVisionItem= +evtSmartPlusSelfCastWithIndicatorSpell4= +evtSmartPlusSelfCastWithIndicatorSpell3= +evtSmartPlusSelfCastWithIndicatorSpell2= +evtSmartPlusSelfCastWithIndicatorSpell1= +evtSmartPlusSelfCastWithIndicatorItem6= +evtSmartPlusSelfCastWithIndicatorItem5= +evtSmartPlusSelfCastWithIndicatorItem4= +evtSmartPlusSelfCastWithIndicatorItem3= +evtSmartPlusSelfCastWithIndicatorItem2= +evtSmartPlusSelfCastWithIndicatorItem1= +evtSmartPlusSelfCastWithIndicatorAvatarSpell2= +evtSmartPlusSelfCastWithIndicatorAvatarSpell1= +evtSmartPlusSelfCastVisionItem= +evtSmartPlusSelfCastSpell4= +evtSmartPlusSelfCastSpell3= +evtSmartPlusSelfCastSpell2= +evtSmartPlusSelfCastSpell1= +evtSmartPlusSelfCastItem6= +evtSmartPlusSelfCastItem5= +evtSmartPlusSelfCastItem4= +evtSmartPlusSelfCastItem3= +evtSmartPlusSelfCastItem2= +evtSmartPlusSelfCastItem1= +evtSmartPlusSelfCastAvatarSpell2= +evtSmartPlusSelfCastAvatarSpell1= +evtSmartCastWithIndicatorVisionItem= +evtSmartCastWithIndicatorSpell4= +evtSmartCastWithIndicatorSpell3= +evtSmartCastWithIndicatorSpell2= +evtSmartCastWithIndicatorSpell1= +evtSmartCastWithIndicatorItem6= +evtSmartCastWithIndicatorItem5= +evtSmartCastWithIndicatorItem4= +evtSmartCastWithIndicatorItem3= +evtSmartCastWithIndicatorItem2= +evtSmartCastWithIndicatorItem1= +evtSmartCastWithIndicatorAvatarSpell2= +evtSmartCastWithIndicatorAvatarSpell1= +evtSmartCastVisionItem=[Shift][4] +evtSmartCastSpell4=[Shift][r] +evtSmartCastSpell3=[Shift][e] +evtSmartCastSpell2=[Shift][w] +evtSmartCastSpell1=[Shift][q] +evtSmartCastItem6=[Shift][7] +evtSmartCastItem5=[Shift][6] +evtSmartCastItem4=[Shift][5] +evtSmartCastItem3=[Shift][3] +evtSmartCastItem2=[Shift][2] +evtSmartCastItem1=[Shift][1] +evtSmartCastAvatarSpell2=[Shift][f] +evtSmartCastAvatarSpell1=[Shift][d] +evtShowVoicePanel=[m] +evtShowSummonerNames= +evtShowScoreBoard=[] +evtShowHealthBars= +evtShowCharacterMenu=[c] +evtSelfCastVisionItem=[Alt][4] +evtSelfCastSpell4=[Alt][r], +evtSelfCastSpell3=[Alt][e], +evtSelfCastSpell2=[Alt][w], +evtSelfCastSpell1=[Alt][q], +evtSelfCastItem6=[Alt][7] +evtSelfCastItem5=[Alt][6] +evtSelfCastItem4=[Alt][5] +evtSelfCastItem3=[Alt][3] +evtSelfCastItem2=[Alt][2] +evtSelfCastItem1=[Alt][1] +evtSelfCastAvatarSpell2=[Alt][f], +evtSelfCastAvatarSpell1=[Alt][d], +evtSelectSelf=[F1] +evtSelectAlly4=[F5] +evtSelectAlly3=[F4] +evtSelectAlly2=[F3] +evtSelectAlly1=[F2] +evtScrollUp=[Up Arrow] +evtScrollRight=[Right Arrow] +evtScrollLeft=[Left Arrow] +evtScrollDown=[Down Arrow] +evtRadialEmotePlaySlot4= +evtRadialEmotePlaySlot3= +evtRadialEmotePlaySlot2= +evtRadialEmotePlaySlot1= +evtRadialEmotePlaySlot0= +evtRadialEmoteOpen= +evtRadialEmoteInstantOpen=[t] +evtPushToTalk=[] +evtPlayerStopPosition=[s] +evtPlayerPingVisionNeeded= +evtPlayerPingVisionCleared= +evtPlayerPingRadialDanger= +evtPlayerPingPush= +evtPlayerPingOMW= +evtPlayerPingMIA= +evtPlayerPingHold= +evtPlayerPingComeHere= +evtPlayerPingBait= +evtPlayerPingAreaIsWarded=[h] +evtPlayerPingAllIn= +evtPlayerMoveClick=[Button 2] +evtPlayerHoldPosition=[h] +evtPlayerCursorPingAreaIsWarded=[u] +evtPlayerAttackOnlyClick= +evtPlayerAttackMoveClick=[Shift][Button 2] +evtPlayerAttackMove=[a],[x] +evtPetMoveClick=[Alt][Button 2],[Ctrl][Button 2] +evtOpenShop=[p],[o] +evtOnUIMouse4Pan=[Button 3] +evtNormalCastVisionItem= +evtNormalCastSpell4= +evtNormalCastSpell3= +evtNormalCastSpell2= +evtNormalCastSpell1= +evtNormalCastItem6= +evtNormalCastItem5= +evtNormalCastItem4= +evtNormalCastItem3= +evtNormalCastItem2= +evtNormalCastItem1= +evtNormalCastAvatarSpell2= +evtNormalCastAvatarSpell1= +evtLevelSpell4=[Ctrl][r] +evtLevelSpell3=[Ctrl][e] +evtLevelSpell2=[Ctrl][w] +evtLevelSpell1=[Ctrl][q] +evtEmoteToggle=[Ctrl][5] +evtEmoteTaunt=[Ctrl][2] +evtEmoteLaugh=[Ctrl][4] +evtEmoteJoke=[Ctrl][1] +evtEmoteDance=[Ctrl][3] +evtDrawHud= +evtDragScrollLock= +evtChatHistory=[z] +evtChampionOnly=[`] +evtChampMasteryDisplay=[Ctrl][6] +evtCastSpell4=[r] +evtCastSpell3=[e] +evtCastSpell2=[w] +evtCastSpell1=[q] +evtCastAvatarSpell2=[f] +evtCastAvatarSpell1=[d] +evtCameraSnap=[Space] +evtCameraLockToggle=[y] +evntPlayerPingDanger=[Ctrl][Button 1] +evntPlayerPingCursorDanger=[v] +evntPlayerPingCursor=[g] +evntPlayerPing=[Alt][Button 1] + +[HUDEvents] +evtTogglePlayerStats=[Ctrl][c] +evtToggleMouseClip=[F9] +evtToggleFPSAndLatency=[Ctrl][f] +evtToggleDeathRecapShowcase=[n] +evtHoldShowScoreBoard=[Tab] + +[Quickbinds] +evtUseVisionItemsmart=1 +evtUseItem6smart=1 +evtUseItem5smart=1 +evtUseItem4smart=1 +evtUseItem3smart=1 +evtUseItem2smart=1 +evtUseItem1smart=1 +evtCastSpell4smart=1 +evtCastSpell3smart=1 +evtCastSpell2smart=1 +evtCastSpell1smart=1 +evtCastAvatarSpell2smart=1 +evtCastAvatarSpell1smart=1 + +[ShopEvents] +evtShopSwitchTabs=[Ctrl][Tab] +evtShopFocusSearch=[Ctrl][l],[Ctrl][Return] +"; + #endregion + } +} diff --git a/Source/Entities/ActionGame.cs b/Source/Entities/ActionGame.cs new file mode 100644 index 0000000..d2b6efa --- /dev/null +++ b/Source/Entities/ActionGame.cs @@ -0,0 +1,14 @@ +namespace LeagueAI.Libraries.Entities +{ + public sealed class ActionGame + { + public int? actorCellId { get; set; } + public int? championId { get; set; } + public bool? completed { get; set; } + public int? id { get; set; } + public bool? isAllyAction { get; set; } + public bool? isInProgress { get; set; } + public double? pickTurn { get; set; } + public string type { get; set; } + } +} diff --git a/Source/Entities/Activeplayer.cs b/Source/Entities/Activeplayer.cs new file mode 100644 index 0000000..cb109ff --- /dev/null +++ b/Source/Entities/Activeplayer.cs @@ -0,0 +1,96 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class Activeplayer + { + public ChampionStat championStats { get; set; } + public Abilities abilities { get; set; } + public double? currentGold { get; set; } + public FullRune fullRunes { get; set; } + public double? level { get; set; } + public string summonerName { get; set; } + public bool? teamRelativeColors { get; set; } + } + + public sealed class FullRune + { + public List generalRunes { get; set; } + public Abilities keystone { get; set; } + public Abilities primaryRuneTree { get; set; } + public Abilities secondaryRuneTree { get; set; } + public List statRunes { get; set; } + } + + public sealed class Abilities + { + [JsonProperty("E")] + public Ability e { get; set; } + + [JsonProperty("Passive")] + public Ability passive { get; set; } + + [JsonProperty("Q")] + public Ability q { get; set; } + + [JsonProperty("R")] + public Ability r { get; set; } + + [JsonProperty("W")] + public Ability w { get; set; } + } + + public sealed class Ability + { + [JsonProperty("abilityLevel")] + public double? abilityLevel { get; set; } + + [JsonProperty("displayName")] + public string displayName { get; set; } + + [JsonProperty("id")] + public string id { get; set; } + + [JsonProperty("rawDescription")] + public string rawDescription { get; set; } + + [JsonProperty("rawDisplayName")] + public string rawDisplayName { get; set; } + } + + public sealed class ChampionStat + { + public double? abilityHaste { get; set; } + public double? abilityPower { get; set; } + public double? armor { get; set; } + public double? armorPenetrationFlat { get; set; } + public double? armorPenetrationPercent { get; set; } + public double? attackDamage { get; set; } + public double? attackRange { get; set; } + public double? attackSpeed { get; set; } + public double? bonusArmorPenetrationPercent { get; set; } + public double? bonusMagicPenetrationPercent { get; set; } + public double? critChance { get; set; } + public double? critDamage { get; set; } + public double? currentHealth { get; set; } + public double? healShieldPower { get; set; } + public double? healthRegenRate { get; set; } + public double? lifeSteal { get; set; } + public double? magicLethality { get; set; } + public double? magicPenetrationFlat { get; set; } + public double? magicPenetrationPercent { get; set; } + public double? magicResist { get; set; } + public double? maxHealth { get; set; } + public double? moveSpeed { get; set; } + public double? omnivamp { get; set; } + public double? physicalLethality { get; set; } + public double? physicalVamp { get; set; } + public double? resourceMax { get; set; } + public double? resourceRegenRate { get; set; } + public string resourceType { get; set; } + public double? resourceValue { get; set; } + public double? spellVamp { get; set; } + public double? tenacity { get; set; } + } +} diff --git a/Source/Entities/Availability.cs b/Source/Entities/Availability.cs new file mode 100644 index 0000000..9500df3 --- /dev/null +++ b/Source/Entities/Availability.cs @@ -0,0 +1,13 @@ +namespace LeagueAI.Libraries.Entities +{ + public sealed class Availability + { + public bool? isAvailable { get; set; } + + /// + /// + /// + /// InGameFlow + public string state { get; set; } + } +} diff --git a/Source/Entities/Champion.cs b/Source/Entities/Champion.cs new file mode 100644 index 0000000..e603722 --- /dev/null +++ b/Source/Entities/Champion.cs @@ -0,0 +1,26 @@ +using LeagueAI.Libraries.Interfaces; +using System.Drawing; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class Champion : IEntity + { + public bool Ally + { + get; + private set; + } + public Point Position + { + get; + private set; + } + + public Champion(bool ally, Point position) + { + Ally = ally; + Position = position; + } + + } +} diff --git a/Source/Entities/EligiblePlayers.cs b/Source/Entities/EligiblePlayers.cs new file mode 100644 index 0000000..d4407b4 --- /dev/null +++ b/Source/Entities/EligiblePlayers.cs @@ -0,0 +1,32 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace LeagueAI.Libraries.Entities +{ + public class HonorGame + { + [JsonProperty("eligiblePlayers")] + public List EligiblePlayers { get; set; } + + [JsonProperty("gameId")] + public double? GameId { get; set; } + } + + public sealed class EligiblePlayers + { + [JsonProperty("championId")] + public int? championId { get; set; } + + [JsonProperty("skinIndex")] + public int? skinIndex { get; set; } + + [JsonProperty("skinName")] + public string skinName { get; set; } + + [JsonProperty("summonerId")] + public double? summonerId { get; set; } + + [JsonProperty("summonerName")] + public string summonerName { get; set; } + } +} diff --git a/Source/Entities/GameStat.cs b/Source/Entities/GameStat.cs new file mode 100644 index 0000000..dd4ec07 --- /dev/null +++ b/Source/Entities/GameStat.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class GameStat + { + [JsonProperty("gameMode")] + public string gameMode { get; set; } + + [JsonProperty("gameTime")] + public double? gameTime { get; set; } + + [JsonProperty("mapName")] + public string mapName { get; set; } + + [JsonProperty("mapNumber")] + public double? mapNumber { get; set; } + + [JsonProperty("mapTerrain")] + public string mapTerrain { get; set; } + } +} diff --git a/Source/Entities/IpInfoDto.cs b/Source/Entities/IpInfoDto.cs new file mode 100644 index 0000000..97a688c --- /dev/null +++ b/Source/Entities/IpInfoDto.cs @@ -0,0 +1,80 @@ +using Newtonsoft.Json; + +namespace LeagueAI.Libraries.Entities +{ + public class IpInfoDto + { + + [JsonProperty("status")] + public string Status { get; set; } + + [JsonProperty("continent")] + public string Continent { get; set; } + + [JsonProperty("continentCode")] + public string ContinentCode { get; set; } + + [JsonProperty("country")] + public string Country { get; set; } + + [JsonProperty("countryCode")] + public string CountryCode { get; set; } + + [JsonProperty("region")] + public string Region { get; set; } + + [JsonProperty("regionName")] + public string RegionName { get; set; } + + [JsonProperty("city")] + public string City { get; set; } + + [JsonProperty("district")] + public string District { get; set; } + + [JsonProperty("zip")] + public string Zip { get; set; } + + [JsonProperty("lat")] + public double? Lat { get; set; } + + [JsonProperty("lon")] + public double? Lon { get; set; } + + [JsonProperty("timezone")] + public string Timezone { get; set; } + + [JsonProperty("offset")] + public int? Offset { get; set; } + + [JsonProperty("currency")] + public string Currency { get; set; } + + [JsonProperty("isp")] + public string Isp { get; set; } + + [JsonProperty("org")] + public string Org { get; set; } + + [JsonProperty("as")] + public string As { get; set; } + + [JsonProperty("asname")] + public string Asname { get; set; } + + [JsonProperty("reverse")] + public string Reverse { get; set; } + + [JsonProperty("mobile")] + public bool? Mobile { get; set; } + + [JsonProperty("proxy")] + public bool? Proxy { get; set; } + + [JsonProperty("hosting")] + public bool? Hosting { get; set; } + + [JsonProperty("query")] + public string Query { get; set; } + } +} diff --git a/Source/Entities/ItemDto.cs b/Source/Entities/ItemDto.cs new file mode 100644 index 0000000..2ebd91e --- /dev/null +++ b/Source/Entities/ItemDto.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class ItemDto + { + [JsonProperty("name")] + public string Name { get; private set; } + + [JsonProperty("cost")] + public int Cost { get; private set; } + + public bool Buyed { get; set; } + public ItemDto(string name, int cost) + { + Name = name; + Cost = cost; + Buyed = false; + } + } +} diff --git a/Source/Entities/KeyValue.cs b/Source/Entities/KeyValue.cs new file mode 100644 index 0000000..92832d3 --- /dev/null +++ b/Source/Entities/KeyValue.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace LeagueAI.Libraries.Entities +{ + public class KeyValue + { + [JsonProperty("key")] + public string key { get; set; } + + [JsonProperty("value")] + public string value { get; set; } + } +} diff --git a/Source/Entities/LobbySession.cs b/Source/Entities/LobbySession.cs new file mode 100644 index 0000000..e8a4fbf --- /dev/null +++ b/Source/Entities/LobbySession.cs @@ -0,0 +1,173 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class LobbySession + { + [JsonProperty("actions")] + public List> actions { get; set; } + + [JsonProperty("allowBattleBoost")] + public bool? allowBattleBoost { get; set; } + + [JsonProperty("allowDuplicatePicks")] + public bool? allowDuplicatePicks { get; set; } + + [JsonProperty("allowLockedEvents")] + public bool? allowLockedEvents { get; set; } + + [JsonProperty("allowRerolling")] + public bool? allowRerolling { get; set; } + + [JsonProperty("allowSkinSelection")] + public bool? allowSkinSelection { get; set; } + + [JsonProperty("bans")] + public Bans bans { get; set; } + + [JsonProperty("benchChampionIds")] + public List benchChampionIds { get; set; } + + [JsonProperty("benchEnabled")] + public bool? benchEnabled { get; set; } + + [JsonProperty("boostableSkinCount")] + public double? boostableSkinCount { get; set; } + + [JsonProperty("chatDetails")] + public ChatDetails chatDetails { get; set; } + + [JsonProperty("counter")] + public double? counter { get; set; } + + [JsonProperty("entitledFeatureState")] + public EntitledFeatureState entitledFeatureState { get; set; } + + [JsonProperty("gameId")] + public double? gameId { get; set; } + + [JsonProperty("hasSimultaneousBans")] + public bool? hasSimultaneousBans { get; set; } + + [JsonProperty("hasSimultaneousPicks")] + public bool? hasSimultaneousPicks { get; set; } + + [JsonProperty("isCustomGame")] + public bool? isCustomGame { get; set; } + + [JsonProperty("isSpectating")] + public bool? isSpectating { get; set; } + + [JsonProperty("localPlayerCellId")] + public double? localPlayerCellId { get; set; } + + [JsonProperty("lockedEventIndex")] + public double? lockedEventIndex { get; set; } + + [JsonProperty("myTeam")] + public List myTeam { get; set; } + + [JsonProperty("recoveryCounter")] + public double? recoveryCounter { get; set; } + + [JsonProperty("rerollsRemaining")] + public double? rerollsRemaining { get; set; } + + [JsonProperty("skipChampionSelect")] + public bool? skipChampionSelect { get; set; } + + [JsonProperty("theirTeam")] + public List theirTeam { get; set; } + + [JsonProperty("timer")] + public Timer timer { get; set; } + + [JsonProperty("trades")] + public List trades { get; set; } + } + + public sealed class Bans + { + [JsonProperty("myTeamBans")] + public List myTeamBans { get; set; } + + [JsonProperty("numBans")] + public double? numBans { get; set; } + + [JsonProperty("theirTeamBans")] + public List theirTeamBans { get; set; } + } + + public sealed class ChatDetails + { + [JsonProperty("chatRoomName")] + public string chatRoomName { get; set; } + + [JsonProperty("chatRoomPassword")] + public string chatRoomPassword { get; set; } + } + + public sealed class EntitledFeatureState + { + [JsonProperty("additionalRerolls")] + public double? additionalRerolls { get; set; } + + [JsonProperty("unlockedSkinIds")] + public List unlockedSkinIds { get; set; } + } + + public sealed class TeamInGame + { + [JsonProperty("assignedPosition")] + public string assignedPosition { get; set; } + + [JsonProperty("cellId")] + public double? cellId { get; set; } + + [JsonProperty("championId")] + public double? championId { get; set; } + + [JsonProperty("championPickdoubleent")] + public double? championPickdoubleent { get; set; } + + [JsonProperty("entitledFeatureType")] + public string entitledFeatureType { get; set; } + + [JsonProperty("selectedSkinId")] + public double? selectedSkinId { get; set; } + + [JsonProperty("spell1Id")] + public double? spell1Id { get; set; } + + [JsonProperty("spell2Id")] + public double? spell2Id { get; set; } + + [JsonProperty("summonerId")] + public double? summonerId { get; set; } + + [JsonProperty("team")] + public double? team { get; set; } + + [JsonProperty("wardSkinId")] + public double? wardSkinId { get; set; } + } + + public sealed class Timer + { + [JsonProperty("adjustedTimeLeftInPhase")] + public double? adjustedTimeLeftInPhase { get; set; } + + [JsonProperty("doubleernalNowInEpochMs")] + public long? doubleernalNowInEpochMs { get; set; } + + [JsonProperty("isInfinite")] + public bool? isInfinite { get; set; } + + [JsonProperty("phase")] + public string phase { get; set; } + + [JsonProperty("totalTimeInPhase")] + public double? totalTimeInPhase { get; set; } + } +} diff --git a/Source/Entities/Minion.cs b/Source/Entities/Minion.cs new file mode 100644 index 0000000..42335fa --- /dev/null +++ b/Source/Entities/Minion.cs @@ -0,0 +1,19 @@ +using LeagueAI.Libraries.Interfaces; +using System.Drawing; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class Minion : IEntity + { + public Point Position + { + get; + private set; + } + + public Minion(Point position) + { + Position = position; + } + } +} diff --git a/Source/Entities/POINT.cs b/Source/Entities/POINT.cs new file mode 100644 index 0000000..8abc2ba --- /dev/null +++ b/Source/Entities/POINT.cs @@ -0,0 +1,17 @@ +using System.Drawing; +using System.Runtime.InteropServices; + +namespace LeagueAI.Libraries.Entities +{ + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public int X; + public int Y; + + public static implicit operator Point(POINT point) + { + return new Point(point.X, point.Y); + } + } +} diff --git a/Source/Entities/PlayerList.cs b/Source/Entities/PlayerList.cs new file mode 100644 index 0000000..0bf849e --- /dev/null +++ b/Source/Entities/PlayerList.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class PlayerList + { + public string championName { get; set; } + public bool? isBot { get; set; } + public bool? isDead { get; set; } + public List items { get; set; } + public int? level { get; set; } + public string position { get; set; } + public string rawChampionName { get; set; } + public double? respawnTimer { get; set; } + public FullRune runes { get; set; } + public Score scores { get; set; } + public int? skinID { get; set; } + public string summonerName { get; set; } + public SummonerSpell summonerSpells { get; set; } + public string team { get; set; } + } + + public sealed class SummonerSpell + { + public Ability summonerSpellOne { get; set; } + public Ability summonerSpellTwo { get; set; } + } + + public sealed class Score + { + public double? assists { get; set; } + public double? creepScore { get; set; } + public double? deaths { get; set; } + public double? kills { get; set; } + public double? wardScore { get; set; } + } + + public sealed class Item + { + public bool? canUse { get; set; } + public bool? consumable { get; set; } + public int? count { get; set; } + public string displayName { get; set; } + public int? itemID { get; set; } + public int? price { get; set; } + public string rawDescription { get; set; } + public string rawDisplayName { get; set; } + public int? slot { get; set; } + } +} diff --git a/Source/Entities/RECT.cs b/Source/Entities/RECT.cs new file mode 100644 index 0000000..cb2b14f --- /dev/null +++ b/Source/Entities/RECT.cs @@ -0,0 +1,19 @@ +using System.Runtime.InteropServices; + +namespace LeagueAI.Libraries.Entities +{ + + [StructLayout(LayoutKind.Sequential)] + public struct RECT + { + public int Left; // x position of upper-left corner + public int Top; // y position of upper-left corner + public int Right; // x position of lower-right corner + public int Bottom; // y position of lower-right corner + + public override string ToString() + { + return string.Format("Left: {0} Top: {1} Right: {2} Bottom: {3}", Left, Top, Right, Bottom); + } + } +} diff --git a/Source/Entities/RerollPoints.cs b/Source/Entities/RerollPoints.cs new file mode 100644 index 0000000..b9ec7da --- /dev/null +++ b/Source/Entities/RerollPoints.cs @@ -0,0 +1,15 @@ +namespace LeagueAI.Libraries.Entities +{ + public sealed class RerollPoints + { + public int currentPoints { get; set; } + + public int maxRolls { get; set; } + + public int numberOfRolls { get; set; } + + public int pointsCostToRoll { get; set; } + + public int pointsToReroll { get; set; } + } +} diff --git a/Source/Entities/SkinRes.cs b/Source/Entities/SkinRes.cs new file mode 100644 index 0000000..274dd41 --- /dev/null +++ b/Source/Entities/SkinRes.cs @@ -0,0 +1,119 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class SkinRes + { + [JsonProperty("championId")] + public long? ChampionId { get; set; } + + [JsonProperty("childSkins")] + public List ChildSkins { get; set; } + + [JsonProperty("chromaPreviewPath")] + public string ChromaPreviewPath { get; set; } + + [JsonProperty("disabled")] + public bool? Disabled { get; set; } + + [JsonProperty("emblems")] + public List Emblems { get; set; } + + [JsonProperty("groupSplash")] + public string GroupSplash { get; set; } + + [JsonProperty("id")] + public long? Id { get; set; } + + [JsonProperty("isBase")] + public bool? IsBase { get; set; } + + [JsonProperty("isChampionUnlocked")] + public bool? IsChampionUnlocked { get; set; } + + [JsonProperty("isUnlockedFromEntitledFeature")] + public bool? IsUnlockedFromEntitledFeature { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("ownership")] + public Ownership Ownership { get; set; } + + [JsonProperty("rarityGemPath")] + public string RarityGemPath { get; set; } + + [JsonProperty("splashPath")] + public string SplashPath { get; set; } + + [JsonProperty("splashVideoPath")] + public string SplashVideoPath { get; set; } + + [JsonProperty("stillObtainable")] + public bool? StillObtainable { get; set; } + + [JsonProperty("tilePath")] + public string TilePath { get; set; } + + [JsonProperty("unlocked")] + public bool? Unlocked { get; set; } + } + + public class ChildSkin + { + [JsonProperty("championId")] + public long? ChampionId { get; set; } + + [JsonProperty("chromaPreviewPath")] + public string ChromaPreviewPath { get; set; } + + [JsonProperty("colors")] + public List Colors { get; set; } + + [JsonProperty("disabled")] + public bool? Disabled { get; set; } + + [JsonProperty("id")] + public long? Id { get; set; } + + [JsonProperty("isBase")] + public bool? IsBase { get; set; } + + [JsonProperty("isChampionUnlocked")] + public bool? IsChampionUnlocked { get; set; } + + [JsonProperty("isUnlockedFromEntitledFeature")] + public bool? IsUnlockedFromEntitledFeature { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("ownership")] + public Ownership Ownership { get; set; } + + [JsonProperty("parentSkinId")] + public long? ParentSkinId { get; set; } + + [JsonProperty("shortName")] + public string ShortName { get; set; } + + [JsonProperty("splashPath")] + public string SplashPath { get; set; } + + [JsonProperty("splashVideoPath")] + public object SplashVideoPath { get; set; } + + [JsonProperty("stage")] + public long? Stage { get; set; } + + [JsonProperty("stillObtainable")] + public bool? StillObtainable { get; set; } + + [JsonProperty("tilePath")] + public string TilePath { get; set; } + + [JsonProperty("unlocked")] + public bool? Unlocked { get; set; } + } +} diff --git a/Source/Entities/SpellRes.cs b/Source/Entities/SpellRes.cs new file mode 100644 index 0000000..e19c87f --- /dev/null +++ b/Source/Entities/SpellRes.cs @@ -0,0 +1,15 @@ +using LeagueAI.Libraries.Enums; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class SpellRes + { + [JsonProperty("spells")] + public List Spells { get; set; } + + [JsonProperty("summonerId")] + public long? SummonerId { get; set; } + } +} diff --git a/Source/Entities/StatusInGame.cs b/Source/Entities/StatusInGame.cs new file mode 100644 index 0000000..01ed6ad --- /dev/null +++ b/Source/Entities/StatusInGame.cs @@ -0,0 +1,25 @@ +namespace LeagueAI.Libraries.Entities +{ + public sealed class StatusInGame + { + /// + /// Máu hiện tại + /// + public double currentHealth { get; set; } + + /// + /// Tổng số máu + /// + public double maxHealth { get; set; } + + /// + /// Mana hiện tại + /// + public double resourceValue { get; set; } + + /// + /// Tổng số mana + /// + public double resourceMax { get; set; } + } +} diff --git a/Source/Entities/Summoner.cs b/Source/Entities/Summoner.cs new file mode 100644 index 0000000..2ea291e --- /dev/null +++ b/Source/Entities/Summoner.cs @@ -0,0 +1,32 @@ +namespace LeagueAI.Libraries.Entities +{ + public sealed class Summoner + { + public long accountId { get; set; } + + public string displayName { get; set; } + + public string internalName { get; set; } + + public bool nameChangeFlag { get; set; } + + public byte percentCompleteForNextLevel { get; set; } + + public short profileIconId { get; set; } + + public string puuid { get; set; } + + public RerollPoints RerollPoints { get; set; } + + public long summonerId { get; set; } + + public short summonerLevel { get; set; } + + public bool unnamed { get; set; } + + public int xpSinceLastLevel { get; set; } + + public int xpUntilNextLevel { get; set; } + + } +} diff --git a/Source/Entities/UserSettings.cs b/Source/Entities/UserSettings.cs new file mode 100644 index 0000000..8574595 --- /dev/null +++ b/Source/Entities/UserSettings.cs @@ -0,0 +1,41 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace LeagueAI.Libraries.Entities +{ + public class PersistedSetting + { + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("files")] + public List Files { get; set; } + } + + public class FileConfig + { + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("sections")] + public List
Sections { get; set; } + } + + public class Section + { + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("settings")] + public List Settings { get; set; } + } + + public class Setting + { + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("value")] + public string Value { get; set; } + } +} diff --git a/Source/Entities/WardSkinRes.cs b/Source/Entities/WardSkinRes.cs new file mode 100644 index 0000000..97f271f --- /dev/null +++ b/Source/Entities/WardSkinRes.cs @@ -0,0 +1,52 @@ +using Newtonsoft.Json; + +namespace LeagueAI.Libraries.Entities +{ + public sealed class WardSkinRes + { + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("id")] + public long? Id { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("ownership")] + public Ownership Ownership { get; set; } + + [JsonProperty("wardImagePath")] + public string WardImagePath { get; set; } + + [JsonProperty("wardShadowImagePath")] + public string WardShadowImagePath { get; set; } + } + + public sealed class Ownership + { + [JsonProperty("freeToPlayReward")] + public bool? FreeToPlayReward { get; set; } + + [JsonProperty("owned")] + public bool? Owned { get; set; } + + [JsonProperty("rental")] + public Rental Rental { get; set; } + } + + public sealed class Rental + { + [JsonProperty("endDate")] + public long? EndDate { get; set; } + + [JsonProperty("purchaseDate")] + public long? PurchaseDate { get; set; } + + [JsonProperty("rented")] + public bool? Rented { get; set; } + + [JsonProperty("winCountRemaining")] + public long? WinCountRemaining { get; set; } + } +} diff --git a/Source/Enums/EChampion.cs b/Source/Enums/EChampion.cs new file mode 100644 index 0000000..a8aea00 --- /dev/null +++ b/Source/Enums/EChampion.cs @@ -0,0 +1,169 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum EChampion : int + { + Aatrox = 266, + Ahri = 103, + Akali = 84, + Akshan = 166, + Alistar = 12, + Amumu = 32, + Anivia = 34, + Annie = 1, + Aphelios = 523, + Ashe = 22, + AurelionSol = 136, + Azir = 268, + Bard = 432, + Belveth = 200, + Blitzcrank = 53, + Brand = 63, + Braum = 201, + Caitlyn = 51, + Camille = 164, + Cassiopeia = 69, + Chogath = 31, + Corki = 42, + Darius = 122, + Diana = 131, + Draven = 119, + DrMundo = 36, + Ekko = 245, + Elise = 60, + Evelynn = 28, + Ezreal = 81, + FiddleSticks = 9, + Fiora = 114, + Fizz = 105, + Galio = 3, + Gangplank = 41, + Garen = 86, + Gnar = 150, + Gragas = 79, + Graves = 104, + Gwen = 887, + Hecarim = 120, + Heimerdinger = 74, + Illaoi = 420, + Irelia = 39, + Ivern = 427, + Janna = 40, + JarvanIV = 59, + Jax = 24, + Jayce = 126, + Jhin = 202, + Jinx = 222, + Kaisa = 145, + Kalista = 429, + Karma = 43, + Karthus = 30, + Kassadin = 38, + Katarina = 55, + Kayle = 10, + Kayn = 141, + Kennen = 85, + Khazix = 121, + Kindred = 203, + Kled = 240, + KogMaw = 96, + KSante = 897, + Leblanc = 7, + LeeSin = 64, + Leona = 89, + Lillia = 876, + Lissandra = 127, + Lucian = 236, + Lulu = 117, + Lux = 99, + Malphite = 54, + Malzahar = 90, + Maokai = 57, + MasterYi = 11, + Milio = 902, + MissFortune = 21, + MonkeyKing = 62, + Mordekaiser = 82, + Morgana = 25, + Nami = 267, + Nasus = 75, + Nautilus = 111, + Neeko = 518, + Nidalee = 76, + Nilah = 895, + Nocturne = 56, + Nunu = 20, + Olaf = 2, + Orianna = 61, + Ornn = 516, + Pantheon = 80, + Poppy = 78, + Pyke = 555, + Qiyana = 246, + Quinn = 133, + Rakan = 497, + Rammus = 33, + Reksai = 421, + Rell = 526, + Renata = 888, + Renekton = 58, + Rengar = 107, + Riven = 92, + Rumble = 68, + Ryze = 13, + Samira = 360, + Sejuani = 113, + Senna = 235, + Seraphine = 147, + Sett = 875, + Shaco = 35, + Shen = 98, + Shyvana = 102, + Singed = 27, + Sion = 14, + Sivir = 15, + Skarner = 72, + Sona = 37, + Soraka = 16, + Swain = 50, + Sylas = 517, + Syndra = 134, + TahmKench = 223, + Taliyah = 163, + Talon = 91, + Taric = 44, + Teemo = 17, + Thresh = 412, + Tristana = 18, + Trundle = 48, + Tryndamere = 23, + TwistedFate = 4, + Twitch = 29, + Udyr = 77, + Urgot = 6, + Varus = 110, + Vayne = 67, + Veigar = 45, + Velkoz = 161, + Vex = 711, + Vi = 254, + Viego = 234, + Viktor = 112, + Vladimir = 8, + Volibear = 106, + Warwick = 19, + Xayah = 498, + Xerath = 101, + XinZhao = 5, + Yasuo = 157, + Yone = 777, + Yorick = 83, + Yuumi = 350, + Zac = 154, + Zed = 238, + Zeri = 221, + Ziggs = 115, + Zilean = 26, + Zoe = 142, + Zyra = 143, + } +} diff --git a/Source/Enums/EChampionPickResult.cs b/Source/Enums/EChampionPickResult.cs new file mode 100644 index 0000000..103caf9 --- /dev/null +++ b/Source/Enums/EChampionPickResult.cs @@ -0,0 +1,9 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum EChampionPickResult + { + Ok, + ChampionNotOwned, + ChampionPicked, + } +} diff --git a/Source/Enums/EGameflowPhase.cs b/Source/Enums/EGameflowPhase.cs new file mode 100644 index 0000000..742d904 --- /dev/null +++ b/Source/Enums/EGameflowPhase.cs @@ -0,0 +1,44 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum EGameflowPhase + { + /// Đang ở ngoài sảnh chờ, không chọn gì cả + None, + + /// Đang ở trong phòng + Lobby, + + /// Đang tìm trận + Matchmaking, + + /// Hiện hộp thoại chấp thuận + ReadyCheck, + + /// Đang chọn tướng + ChampSelect, + + /// + GameStart, + + /// Không thể khởi chạy game + FailedToLaunch, + + /// Đang tải game / chơi + InProgress, + + /// Chờ kết nối lại + Reconnect, + + /// Chờ bảng điểm + WaitingForStats, + + /// + EndOfGame, + + /// + PreEndOfGame, + + /// Lỗi + TerminatedInError + } +} diff --git a/Source/Enums/EMessageState.cs b/Source/Enums/EMessageState.cs new file mode 100644 index 0000000..0a3c968 --- /dev/null +++ b/Source/Enums/EMessageState.cs @@ -0,0 +1,13 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum EMessageState + { + TIP_HELP = 0, + INFO = 1, + PROCESS = 2, + WARNING = 3, + SUCCES = 4, + ERROR = 5, + ERROR_FATAL = 6, + } +} diff --git a/Source/Enums/EQueueRoom.cs b/Source/Enums/EQueueRoom.cs new file mode 100644 index 0000000..6d47c36 --- /dev/null +++ b/Source/Enums/EQueueRoom.cs @@ -0,0 +1,125 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum EQueueRoom + { + /// + /// "queueId": 0, + /// "map": "Custom games", + /// "description": null, + /// "notes": null + /// + Custom = 0, + + /// + /// "queueId": 75, + /// "map": "Summoner's Rift", + /// "description": "6v6 Hexakill games", + /// "notes": null + /// + Hexakill = 75, + + /// + /// "queueId": 76, + /// "map": "Summoner's Rift", + /// "description": "Ultra Rapid Fire games", + /// "notes": null + /// + UltraRapidFire = 76, + + /// + /// "queueId": 420, + /// "map": "Summoner's Rift", + /// "description": "5v5 Ranked Solo games", + /// "notes": null + /// + RankedSolo = 420, + + /// + /// "queueId": 430, + /// "map": "Summoner's Rift", + /// "description": "5v5 Blind Pick games", + /// "notes": null + /// + BlindPick = 430, + + /// + /// "queueId": 440, + /// "map": "Summoner's Rift", + /// "description": "5v5 Ranked Flex games", + /// "notes": null + /// + RankedFlex = 440, + + /// + /// "queueId": 450, + /// "map": "Howling Abyss", + /// "description": "5v5 ARAM games", + /// "notes": null + /// + ARAM = 450, + + /// + /// "queueId": 870, + /// "map": "Summoner's Rift", + /// "description": "Co-op vs. AI Intro Bot games", + /// "notes": null + /// + CoopVsAIIntroBot = 870, + + /// + /// "queueId": 880, + /// "map": "Summoner's Rift", + /// "description": "Co-op vs. AI Beginner Bot games", + /// "notes": null + /// + CoopVsAIBeginnerBot = 880, + + /// + /// "queueId": 890, + /// "map": "Summoner's Rift", + /// "description": "Co-op vs. AI Intermediate Bot games", + /// "notes": null + /// + CoopVsAIIntermediateBot = 890, + + /// + /// "queueId": 1900, + /// "map": "Summoner's Rift", + /// "description": "URF games", + /// "notes": null + /// + URF = 1900, + + /// + /// "queueId": 1010, + /// "map": "Summoner's Rift", + /// "description": "Snow ARURF games", + /// "notes": null + /// + SnowARURF = 1010, + + /// + /// "queueId": 1020, + /// "map": "Summoner's Rift", + /// "description": "One for All games", + /// "notes": null + /// + OneForAll = 1020, + + /// + /// "queueId": 1090, + /// "map": "Summoner's Rift", + /// "description": "Teamfight Tactics games", + /// "notes": null + /// + TeamfightTactics = 1090, + + /// + /// "queueId": 1100, + /// "map": "Convergence", + /// "description": "Ranked Teamfight Tactics games", + /// "notes": null + /// + RankedTeamfightTactics = 1100, + } +} diff --git a/Source/Enums/ESearchMatchResult.cs b/Source/Enums/ESearchMatchResult.cs new file mode 100644 index 0000000..8ecab92 --- /dev/null +++ b/Source/Enums/ESearchMatchResult.cs @@ -0,0 +1,11 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum ESearchMatchResult + { + Unknown, + Ok, + GatekeeperRestricted, + QueueNotEnabled, + InvalidLobby, + } +} diff --git a/Source/Enums/EShopItemType.cs b/Source/Enums/EShopItemType.cs new file mode 100644 index 0000000..0696d27 --- /dev/null +++ b/Source/Enums/EShopItemType.cs @@ -0,0 +1,11 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum EShopItemType + { + Starting, + Early, + Essential, + Offensive, + Defensive + } +} diff --git a/Source/Enums/EShowWindow.cs b/Source/Enums/EShowWindow.cs new file mode 100644 index 0000000..8fa41bd --- /dev/null +++ b/Source/Enums/EShowWindow.cs @@ -0,0 +1,11 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum EShowWindow + { + Hide = 0, + ShowNormal = 1, ShowMinimized = 2, ShowMaximized = 3, + Maximize = 3, ShowNormalNoActivate = 4, Show = 5, + Minimize = 6, ShowMinNoActivate = 7, ShowNoActivate = 8, + Restore = 9, ShowDefault = 10, ForceMinimized = 11 + }; +} diff --git a/Source/Enums/ESideTeam.cs b/Source/Enums/ESideTeam.cs new file mode 100644 index 0000000..145e88e --- /dev/null +++ b/Source/Enums/ESideTeam.cs @@ -0,0 +1,8 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum ESideTeam + { + ORDER, // Blue + CHAOS, // Red + } +} diff --git a/Source/Enums/ESpell.cs b/Source/Enums/ESpell.cs new file mode 100644 index 0000000..e5087e4 --- /dev/null +++ b/Source/Enums/ESpell.cs @@ -0,0 +1,62 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum ESpell : int + { + None = -1, + + /// + /// Thanh tấy. + /// + Cleanse = 1, + + /// + /// Kiệt sức. + /// + Exhaust = 3, + + /// + /// Tốc biến. + /// + Flash = 4, + + /// + /// Tốc hành / chạy nhanh. + /// + Ghost = 6, + + /// + /// Hồi máu. + /// + Heal = 7, + + /// + /// Trừng phạt. + /// + Smite = 11, + + /// + /// Dịch chuyển + /// + Teleport = 12, + + /// + /// Minh mẫn. Hồi mana cho mình và đồng đội. + /// + Clarity = 13, + + /// + /// Thiêu đốt. + /// + Ignite = 14, + + /// + /// Lá chắn. + /// + Barrier = 21, + + /// + /// Đánh dấu (bắn poro trong aram) + /// + Mark = 32, + } +} diff --git a/Source/Enums/EStartupInvokePriority.cs b/Source/Enums/EStartupInvokePriority.cs new file mode 100644 index 0000000..97e5124 --- /dev/null +++ b/Source/Enums/EStartupInvokePriority.cs @@ -0,0 +1,13 @@ +namespace LeagueAI.Libraries.Enums +{ + public enum EStartupInvokePriority + { + Initial = 0, + SecondPass = 2, + ThirdPass = 3, + FourthPass = 4, + FifthPass = 5, + SixthPath = 6, + Last = 7, + } +} diff --git a/Source/Game/ClientLCU.cs b/Source/Game/ClientLCU.cs new file mode 100644 index 0000000..acb44cb --- /dev/null +++ b/Source/Game/ClientLCU.cs @@ -0,0 +1,539 @@ +using Leaf.xNet; +using LeagueAI.Libraries.Entities; +using LeagueAI.Libraries.Enums; +using LeagueAI.Libraries.Helper; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.NetworkInformation; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; + +namespace LeagueAI.Libraries.Game +{ + public sealed class ClientLCU + { + private static string Auth; + private static int Port; + + private static string Url => "https://127.0.0.1:" + Port + "/"; + private static string LoginUrl => Url + "lol-login/v1/session"; + private static string CreateLobbyURL => Url + "lol-lobby/v2/lobby"; + private static string SearchURL => Url + "lol-lobby/v2/lobby/matchmaking/search"; + private static string ReconnectUrl => Url + "lol-gameflow/v1/reconnect"; + private static string AcceptURL => Url + "lol-matchmaking/v1/ready-check/accept"; + private static string PickURL => Url + "lol-champ-select/v1/session/actions/"; + private static string PickSkinSpellWardSkinURL => Url + "lol-champ-select/v1/session/my-selection"; + private static string SessionURL => Url + "lol-champ-select/v1/session"; + private static string LoginURL => Url + "rso-auth/v1/session/credentials"; + private static string HonorURL => Url + "lol-honor-v2/v1/honor-player"; + private static string GetHonorDataUrl => Url + "lol-honor-v2/v1/ballot"; + private static string PickRandomChampionsUrl => Url + "lol-champ-select/v1/session/simple-inventory"; + private static string PickableSkinIdUrl => Url + "lol-champ-select/v1/skin-carousel-skins"; + private static string PickableSpellIdUrl => Url + "lol-collections/v1/inventories/{0}/spells"; + private static string PickableWardSkinIdUrl => Url + "lol-collections/v1/inventories/{0}/ward-skins"; + private static string PickableChampionsUrl => Url + "lol-champ-select/v1/pickable-champion-ids"; + private static string BannableChampionIdUrl => Url + "lol-champ-select/v1/bannable-champion-ids"; + private static string DisableChampionIdUrl => Url + "lol-champ-select/v1/disabled-champions"; + private static string KillUXUrl => Url + "riotclient/kill-ux"; + private static string GameflowAvailabilityUrl => Url + "lol-gameflow/v1/availability"; + private static string GameflowPhaseUrl => Url + "lol-gameflow/v1/gameflow-phase"; + private static string CurrentSummonerUrl => Url + "lol-summoner/v1/current-summoner"; + + public static void NetworkChanged(object sender, NetworkAvailabilityEventArgs e) + { + try + { + if (!e.IsAvailable || !IsApiReady()) + { + Thread.Sleep(12000); + NetworkChanged(sender, e); + return; + } + using (HttpRequest request = CreateRequest()) + { + var response = request.Post(ReconnectUrl); + if (response?.IsOK == true) Logger.WriteLine(DEFINE.Reconnected, EMessageState.SUCCES); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + static ClientLCU() + { + NetworkChange.NetworkAvailabilityChanged += NetworkChanged; + } + + public static bool IsApiReady() + { + try + { + using (HttpRequest request = CreateRequest()) + { + HttpResponse response = request.Get(GameflowAvailabilityUrl); + + if (response.StatusCode == HttpStatusCode.OK) + { + Availability obj = JsonConvert.DeserializeObject(response.ToString()); + return obj?.isAvailable ?? false; + } + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return false; + } + + public static bool BringToFont() + { + try + { + var handle = Program.ClientHandle; + handle.BringToFront(); + return true; + } + catch (Exception ex) { Logger.WriteLine(ex); } + return false; + } + public static bool CenterScreen() + { + try + { + var handle = Program.ClientHandle; + return handle.CenterScreen(); + } + catch (Exception ex) { Logger.WriteLine(ex); } + return false; + } + + public static bool IsClientOpen() + { + try + { + var handle = Program.ClientHandle; + if (handle != null && handle != IntPtr.Zero) return true; + } + catch (Exception ex) { Logger.WriteLine(ex, EMessageState.WARNING); } + return false; + } + + public static void Initialize() + { + try + { + // Tạo môi trường để sử dụng API Client + string path = Configuration.Instance.LockfilePath; + + if (!File.Exists(path)) + { + Logger.WriteLine(DEFINE.NotOpenGameClientYetLog, EMessageState.ERROR); + Program.Exit(1); + } + + using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + using (StreamReader streamReader = new StreamReader(fileStream, Encoding.Default)) + { + string line; + while ((line = streamReader.ReadLine()) != null) + { + string[] lines = line.Split(':'); + // string pid = lines[1]; + Port = int.Parse(lines[2]); + string riot_pass = lines[3]; + // string protocalTranfer = lines[4]; + Auth = Convert.ToBase64String(Encoding.UTF8.GetBytes("riot:" + riot_pass)); + Logger.WriteLine(string.Format(DEFINE.WriteAccessAPI, Port, riot_pass), EMessageState.SUCCES); + + if (Port == 0) Logger.WriteLine(DEFINE.CantLoadGameAPILog, EMessageState.ERROR); + } + } + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + public static bool IsMatchFound() => GetGameflowPhase() == EGameflowPhase.ReadyCheck; + + public static bool CreateLobby(EQueueRoom queueId) + { + try + { + using (HttpRequest request = CreateRequest()) + { + string response = request.Post(CreateLobbyURL, "{\"queueId\": " + (int)queueId + "}", "application/json").StatusCode.ToString(); + + if (response == "OK") + { + return true; + } + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return false; + } + + public static ESearchMatchResult SearchMatch() + { + try + { + using (HttpRequest request = CreateRequest()) + { + string response = request.Post(SearchURL).ToString(); + + if (string.IsNullOrWhiteSpace(response)) + return ESearchMatchResult.Ok; + + ESearchMatchResult result = ESearchMatchResult.Unknown; + dynamic obj = JsonConvert.DeserializeObject(response); + string message = obj.message; + switch (message) + { + case "GATEKEEPER_RESTRICTED": + result = ESearchMatchResult.GatekeeperRestricted; + break; + case "QUEUE_NOT_ENABLED": + result = ESearchMatchResult.QueueNotEnabled; + break; + case "INVALID_LOBBY": + result = ESearchMatchResult.InvalidLobby; + break; + default: + Logger.WriteLine(string.Format(DEFINE.CantFindGameLog, obj?.message), EMessageState.WARNING); + break; + } + + return result; + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return ESearchMatchResult.Unknown; + } + public static EGameflowPhase GetGameflowPhase() + { + try + { + using (HttpRequest request = CreateRequest()) + { + string result = request.Get(GameflowPhaseUrl)?.ToString(); + result = Regex.Match(result, "\"(.*)\"").Groups[1].Value; + return (EGameflowPhase)Enum.Parse(typeof(EGameflowPhase), result); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return EGameflowPhase.None; + } + + public static Summoner GetCurrentSummoner() + { + try + { + using (HttpRequest request = CreateRequest()) + { + string result = request.Get(CurrentSummonerUrl).ToString(); + return JsonConvert.DeserializeObject(result); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return null; + } + + public static LobbySession GetChampSelectSession() + { + try + { + using (HttpRequest request = CreateRequest()) + { + string result = request.Get(SessionURL).ToString(); + return JsonConvert.DeserializeObject(result); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return default; + } + + public static void Reconnect() + { + try + { + using (HttpRequest request = CreateRequest()) + { + request.Post(ReconnectUrl); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + public static void AcceptMatch() + { + try + { + using (HttpRequest request = CreateRequest()) + { + request.Post(AcceptURL); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + public static int[] GetPickableChampions() + { + try + { + // Lấy danh sách tướng có thể chọn + using (HttpRequest request = CreateRequest()) + { + string result = request.Get(PickableChampionsUrl).ToString(); + result = Regex.Match(result, @"\[(.*)\]").Groups[1].Value; + return result.Split(',').Select(int.Parse).ToArray(); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return default; + } + + public static int[] GetBannableChampions() + { + try + { + // Lấy danh sách tướng có thể chọn + using (HttpRequest request = CreateRequest()) + { + string result = request.Get(BannableChampionIdUrl).ToString(); + result = Regex.Match(result, @"\[(.*)\]").Groups[1].Value; + return result.Split(',').Select(int.Parse).ToArray(); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return default; + } + + public static HonorGame GetHonorAfterGameDone() + { + try + { + // Lấy danh sách tướng có thể chọn + using (HttpRequest request = CreateRequest()) + { + string result = request.Get(GetHonorDataUrl).ToString(); + return JsonConvert.DeserializeObject(result); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return default; + } + + public static string PostHonorAfterGameDone() + { + try + { + HonorGame data = GetHonorAfterGameDone(); + if (data == null || data.GameId == null || data.EligiblePlayers?.Count <= 0) return null; + + var idHonor = data.EligiblePlayers[new Random().Next(0, data.EligiblePlayers.Count)]; + if (idHonor?.summonerId == null) return null; + + using (HttpRequest request = CreateRequest()) + { + string result = request.Post(HonorURL, JsonConvert.SerializeObject(new + { + gameId = data.GameId, + honorCategory = "Friendly", + summonerId = idHonor.summonerId, + })).ToString(); + return result; + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return default; + } + + public static int[] GetDisableChampions() + { + try + { + // Lấy danh sách tướng có thể chọn + using (HttpRequest request = CreateRequest()) + { + string result = request.Get(DisableChampionIdUrl).ToString(); + result = Regex.Match(result, @"\[(.*)\]").Groups[1].Value; + return result.Split(',').Select(int.Parse).ToArray(); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return default; + } + + public static EChampionPickResult PickChampion( + EChampion champion) + { + try + { + // Lựa chọn tướng + LobbySession session = ClientLCU.GetChampSelectSession(); + + foreach (ActionGame summoner in session.actions[0]) + { + if (summoner.championId == (int)champion) + { + return EChampionPickResult.ChampionPicked; + } + } + + int[] pickableChampions = GetPickableChampions(); + + if (!pickableChampions.Contains((int)champion)) + { + return EChampionPickResult.ChampionNotOwned; + } + + int championId = (int)champion; + + for (int id = 0; id < 10; id++) + { + using (HttpRequest request = CreateRequest()) + { + string result = request.Patch( + address: PickURL + id, + str: JsonConvert.SerializeObject(new + { + actorCellId = 0, + championId = championId, + completed = true, + id = id, + isAllyAction = true, + type = "string", + }), + contentType: "application/json").ToString(); + } + } + + return EChampionPickResult.Ok; + } + catch (Exception ex) { Logger.WriteLine(ex); } + return EChampionPickResult.ChampionNotOwned; + } + + public static bool PickSkin(Summoner player) + { + try + { + var random = new Random(); + + // get available skin + var skins = new List(); + using (HttpRequest request = CreateRequest()) + { + var res = request.Get( + address: PickableSkinIdUrl)?.ToString(); + skins = JsonConvert.DeserializeObject>(res)?.Where(m => m.Unlocked == true)?.ToList(); + if (skins?.Count < 1) return false; + } + + // get available spell + var spells = new SpellRes(); + using (HttpRequest request = CreateRequest()) + { + var res = request.Get( + address: string.Format(PickableSpellIdUrl, player.summonerId))?.ToString(); + spells = JsonConvert.DeserializeObject(res); + } + + // get available ward skin + var wardSkins = new List(); + using (HttpRequest request = CreateRequest()) + { + var res = request.Get( + address: string.Format(PickableWardSkinIdUrl, player.summonerId))?.ToString(); + wardSkins = JsonConvert.DeserializeObject>(res); + } + + // submit + using (HttpRequest request = CreateRequest()) + { + var result = request.Patch( + address: PickSkinSpellWardSkinURL, + str: JsonConvert.SerializeObject(new + { + selectedSkinId = skins[random.Next(0, skins.Count)].Id, + spell1Id = ESpell.Exhaust.ToInt(), + spell2Id = ESpell.Ignite.ToInt(), + wardSkinId = wardSkins[random.Next(0, wardSkins.Count)].Id, + }), + contentType: "application/json"); + if (result.StatusCode.IsSuccess()) return true; + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + return false; + } + + public static void KillProcessRenderUxClient() + { + var process = Process.GetProcesses(); + foreach (var item in process) + { + try + { + if (item?.MainModule?.FileName?.Contains(DEFINE.LeagueClientUxRender) == true) item.Kill(); + } + catch (Exception) { } + } + } + + public static void CloseClient() + { + try + { + using (HttpRequest request = CreateRequest()) + { + request.Post(KillUXUrl); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + public static void ForceKillClient() + { + try + { + Process[] process = Process.GetProcessesByName(Configuration.Instance.ClientHostProcessName); + foreach (Process item in process) + { + item.Kill(); + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + public static void OpenClient() + { + try + { + if (IsClientOpen()) return; + + ProcessStartInfo psi = new ProcessStartInfo + { + FileName = Configuration.Instance.ClientExecutablePath + }; + Process.Start(psi); + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + private static HttpRequest CreateRequest() + { + HttpRequest request = new HttpRequest + { + IgnoreProtocolErrors = true, + CharacterSet = DEFINE.HttpRequestEncoding, + }; + request.AddHeader("Authorization", "Basic " + Auth); + return request; + } + + } +} diff --git a/Source/Game/GameLCU.cs b/Source/Game/GameLCU.cs new file mode 100644 index 0000000..9622039 --- /dev/null +++ b/Source/Game/GameLCU.cs @@ -0,0 +1,224 @@ +using Leaf.xNet; +using LeagueAI.Libraries.Entities; +using LeagueAI.Libraries.Enums; +using LeagueAI.Libraries.Helper; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; + +namespace LeagueAI.Libraries.Game +{ + public sealed class GameLCU + { + public static string ApiUrl { get; set; } = $"https://127.0.0.1:{Configuration.Instance.SettingGame.portApiGame.ToString()}/liveclientdata"; + + public static string ActivePlayerUrl { get; set; } = ApiUrl + "/activeplayer"; + + public static string PlayerListUrl { get; set; } = ApiUrl + "/playerlist"; + + public static string GameStatsUrl { get; set; } = ApiUrl + "/gamestats"; + + public static string PlayerItems { get; set; } = ApiUrl + "/playeritems"; + + public static bool IsApiReady() + { + try + { + using (HttpRequest request = CreateRequest()) + { + HttpResponse response = request.Get(PlayerListUrl); + var statusCode = (int)response.StatusCode; + if (statusCode >= 200 && statusCode < 300) return true; + } + } + catch (Exception ex) { Logger.WriteLine(ex, EMessageState.WARNING); } + return false; + } + + public static bool IsGameOpen() + { + try + { + var handle = Program.GameHandle; + if (handle != null && handle != IntPtr.Zero) return true; + } + catch (Exception ex) { Logger.WriteLine(ex, EMessageState.WARNING); } + return false; + } + + public static bool IsPlayerDead() + { + try + { + ChampionStat stat = GetStats(); + if (stat?.currentHealth == null) + { + return false; + } + + return stat.currentHealth <= 0; + } + catch (Exception ex) { Logger.WriteLine(ex); } + return false; + } + + public static bool BringToFont() + { + try + { + var handle = Program.GameHandle; + handle.BringToFront(); + return true; + } + catch (Exception ex) { Logger.WriteLine(ex); } + return false; + } + + public static bool CenterScreen() + { + try + { + var handle = Program.GameHandle; + return handle.CenterScreen(); + } + catch (Exception ex) { Logger.WriteLine(ex); } + return false; + } + + public static double GetPlayerLevel() + { + try + { + string resultStr = CreateRequest().Get(ActivePlayerUrl)?.ToString(); + Activeplayer dyn = JsonConvert.DeserializeObject(resultStr); + return dyn?.level ?? -1; + } + catch (Exception ex) { Logger.WriteLine(ex, EMessageState.WARNING); } + return -1; + } + public static string GetPlayerName() + { + try + { + string resultStr = CreateRequest().Get(ActivePlayerUrl)?.ToString(); + Activeplayer dyn = JsonConvert.DeserializeObject(resultStr); + return dyn?.summonerName; + } + catch (Exception ex) { Logger.WriteLine(ex, EMessageState.WARNING); } + return DEFINE.LogCantGetUsername; + } + + public static double GetGameTime() + { + try + { + string resultStr = CreateRequest().Get(GameStatsUrl)?.ToString(); + GameStat dyn = JsonConvert.DeserializeObject(resultStr); + return dyn?.gameTime ?? -1; + } + catch (Exception ex) { Logger.WriteLine(ex); } + return -1; + } + + public static PlayerList GetAlly(int id) + { + try + { + string resultStr = CreateRequest().Get(PlayerListUrl)?.ToString(); + List dyn = JsonConvert.DeserializeObject>(resultStr); + return dyn[id - 1]; + } + catch (Exception ex) { Logger.WriteLine(ex); } + return null; + } + + public static ESideTeam GetPlayerSide() + { + try + { + string playerName = GetPlayerName(); + string resultStr = CreateRequest().Get(PlayerListUrl)?.ToString(); + var dyn = JsonConvert.DeserializeObject>(resultStr); + foreach (PlayerList element in dyn) + { + if (element.summonerName == playerName) + { + if (element.team == "ORDER") + return ESideTeam.ORDER; + return ESideTeam.CHAOS; + } + } + } + catch (Exception ex) { Logger.WriteLine(ex, EMessageState.WARNING); } + return ESideTeam.ORDER; + } + + public static List GetPlayerItems(string summonerName) + { + try + { + string resultStr = CreateRequest().Get($"{PlayerItems}?summonerName={System.Web.HttpUtility.HtmlEncode(summonerName)}")?.ToString(); + List dyn = JsonConvert.DeserializeObject>(resultStr); + return dyn; + } + catch (Exception ex) { Logger.WriteLine(ex); } + return null; + } + + public static double GetPlayerGolds() + { + try + { + string resultStr = CreateRequest().Get(ActivePlayerUrl)?.ToString(); + Activeplayer dyn = JsonConvert.DeserializeObject(resultStr); + return dyn?.currentGold ?? -1; + } + catch (Exception ex) { Logger.WriteLine(ex, EMessageState.WARNING); } + return -1; + } + + public static List GetAllies() + { + try + { + string resultStr = CreateRequest().Get(PlayerListUrl)?.ToString(); + List dyn = JsonConvert.DeserializeObject>(resultStr); + return dyn; + } + catch (Exception ex) { Logger.WriteLine(ex, EMessageState.WARNING); } + return null; + } + + public static ChampionStat GetStats() + { + try + { + string resultStr = CreateRequest().Get(ActivePlayerUrl)?.ToString(); + Activeplayer dyn = JsonConvert.DeserializeObject(resultStr); + return dyn?.championStats; + } + catch (Exception ex) { Logger.WriteLine(ex, EMessageState.WARNING); } + return null; + } + + public static void CloseGameProcess() + { + try + { + var process = Program.GameHandle.GetProcess(); + process.Kill(); + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + private static HttpRequest CreateRequest() + { + HttpRequest request = new HttpRequest + { + IgnoreProtocolErrors = true, + CharacterSet = DEFINE.HttpRequestEncoding, + }; + return request; + } + } +} diff --git a/Source/Helper/DataConvertUlti.cs b/Source/Helper/DataConvertUlti.cs new file mode 100644 index 0000000..e15ba95 --- /dev/null +++ b/Source/Helper/DataConvertUlti.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json; +using System.Drawing; + +namespace LeagueAI.Libraries.Helper +{ + public static class DataConvertUlti + { + public static string SerializeJson(T obj) + { + return JsonConvert.SerializeObject(obj, Formatting.Indented); + } + + public static T DeserializeJson(string content) where T : class + { + return JsonConvert.DeserializeObject(content); + } + + public static Color? ToColorRGB(this int[] colorArr) + { + if (colorArr?.Length != 3) return null; + return Color.FromArgb(colorArr[0], colorArr[1], colorArr[2]); + } + } +} diff --git a/Source/Helper/EnumExtention.cs b/Source/Helper/EnumExtention.cs new file mode 100644 index 0000000..7641115 --- /dev/null +++ b/Source/Helper/EnumExtention.cs @@ -0,0 +1,9 @@ +using LeagueAI.Libraries.Enums; + +namespace LeagueAI.Libraries.Helper +{ + public static class EnumExtention + { + public static int ToInt(this ESpell data) => (int)data; + } +} diff --git a/Source/Helper/FastBitmapUlti.cs b/Source/Helper/FastBitmapUlti.cs new file mode 100644 index 0000000..39aca5c --- /dev/null +++ b/Source/Helper/FastBitmapUlti.cs @@ -0,0 +1,871 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; + +namespace LeagueAI.Libraries.Helper +{ + /// + /// Encapsulates a Bitmap for fast bitmap pixel operations using 32bpp images + /// https://github.com/LuizZak/FastBitmap + /// + public unsafe class FastBitmapUlti : IDisposable + { + /// + /// Specifies the number of bytes available per pixel of the bitmap object being manipulated + /// + public const int BytesPerPixel = 4; + + /// + /// The Bitmap object encapsulated on this FastBitmap + /// + private readonly Bitmap _bitmap; + + /// + /// The BitmapData resulted from the lock operation + /// + private BitmapData _bitmapData; + + /// + /// The first pixel of the bitmap + /// + private int* _scan0; + + /// + /// Gets the width of this FastBitmap object + /// + public int Width { get; } + + /// + /// Gets the height of this FastBitmap object + /// + public int Height { get; } + + /// + /// Gets the pointer to the first pixel of the bitmap + /// + public IntPtr Scan0 => _bitmapData.Scan0; + + /// + /// Gets the stride width (in int32-sized values) of the bitmap + /// + public int Stride { get; private set; } + + /// + /// Gets the stride width (in bytes) of the bitmap + /// + public int StrideInBytes { get; private set; } + + /// + /// Gets a boolean value that states whether this FastBitmap is currently locked in memory + /// + public bool Locked { get; private set; } + + /// + /// Gets an array of 32-bit color pixel values that represent this FastBitmap + /// + /// The locking operation required to extract the values off from the underlying bitmap failed + /// The bitmap is already locked outside this fast bitmap + public int[] DataArray + { + get + { + bool unlockAfter = false; + if (!Locked) + { + Lock(); + unlockAfter = true; + } + + // Declare an array to hold the bytes of the bitmap + int bytes = Math.Abs(_bitmapData.Stride) * _bitmap.Height; + int[] argbValues = new int[bytes / BytesPerPixel]; + + // Copy the RGB values into the array + Marshal.Copy(_bitmapData.Scan0, argbValues, 0, bytes / BytesPerPixel); + + if (unlockAfter) + { + Unlock(); + } + + return argbValues; + } + } + + /// + /// Creates a new instance of the FastBitmap class with a specified Bitmap. + /// The bitmap provided must have a 32bpp depth + /// + /// The Bitmap object to encapsulate on this FastBitmap object + /// The bitmap provided does not have a 32bpp pixel format + public FastBitmapUlti(Bitmap bitmap) + { + if (Image.GetPixelFormatSize(bitmap.PixelFormat) != 32) + { + throw new ArgumentException(@"The provided bitmap must have a 32bpp depth", nameof(bitmap)); + } + + _bitmap = bitmap; + + Width = bitmap.Width; + Height = bitmap.Height; + } + + /// + /// Disposes of this fast bitmap object and releases any pending resources. + /// The underlying bitmap is not disposes, and is unlocked, if currently locked + /// + public void Dispose() + { + if (Locked) + { + Unlock(); + } + } + + /// + /// Locks the bitmap to start the bitmap operations. If the bitmap is already locked, + /// an exception is thrown + /// + /// A fast bitmap locked struct that will unlock the underlying bitmap after disposal + /// The bitmap is already locked + /// The locking operation in the underlying bitmap failed + /// The bitmap is already locked outside this fast bitmap + public FastBitmapLocker Lock() + { + return Lock((FastBitmapLockFormat)_bitmap.PixelFormat); + } + + /// + /// Locks the bitmap to start the bitmap operations. If the bitmap is already locked, + /// an exception is thrown. + /// + /// The provided pixel format should be a 32bpp format. + /// + /// A pixel format to use when locking the underlying bitmap + /// A fast bitmap locked struct that will unlock the underlying bitmap after disposal + /// The bitmap is already locked + /// The locking operation in the underlying bitmap failed + /// The bitmap is already locked outside this fast bitmap + public FastBitmapLocker Lock(FastBitmapLockFormat pixelFormat) + { + if (Locked) + { + throw new InvalidOperationException("Unlock must be called before a Lock operation"); + } + + return Lock(ImageLockMode.ReadWrite, (PixelFormat)pixelFormat); + } + + /// + /// Locks the bitmap to start the bitmap operations + /// + /// The lock mode to use on the bitmap + /// A pixel format to use when locking the underlying bitmap + /// A fast bitmap locked struct that will unlock the underlying bitmap after disposal + /// The locking operation in the underlying bitmap failed + /// The bitmap is already locked outside this fast bitmap + /// is not a 32bpp format + private FastBitmapLocker Lock(ImageLockMode lockMode, PixelFormat pixelFormat) + { + Rectangle rect = new Rectangle(0, 0, _bitmap.Width, _bitmap.Height); + + return Lock(lockMode, rect, pixelFormat); + } + + /// + /// Locks the bitmap to start the bitmap operations + /// + /// The lock mode to use on the bitmap + /// The rectangle to lock + /// A pixel format to use when locking the underlying bitmap + /// A fast bitmap locked struct that will unlock the underlying bitmap after disposal + /// The provided region is invalid + /// The locking operation in the underlying bitmap failed + /// The bitmap region is already locked + /// is not a 32bpp format + private FastBitmapLocker Lock(ImageLockMode lockMode, Rectangle rect, PixelFormat pixelFormat) + { + // Lock the bitmap's bits + _bitmapData = _bitmap.LockBits(rect, lockMode, pixelFormat); + + _scan0 = (int*)_bitmapData.Scan0; + Stride = _bitmapData.Stride / BytesPerPixel; + StrideInBytes = _bitmapData.Stride; + + Locked = true; + + return new FastBitmapLocker(this); + } + + /// + /// Unlocks the bitmap and applies the changes made to it. If the bitmap was not locked + /// beforehand, an exception is thrown + /// + /// The bitmap is already unlocked + /// The unlocking operation in the underlying bitmap failed + public void Unlock() + { + if (!Locked) + { + throw new InvalidOperationException("Lock must be called before an Unlock operation"); + } + + _bitmap.UnlockBits(_bitmapData); + + Locked = false; + } + + /// + /// Sets the pixel color at the given coordinates. If the bitmap was not locked beforehands, + /// an exception is thrown + /// + /// The X coordinate of the pixel to set + /// The Y coordinate of the pixel to set + /// The new color of the pixel to set + /// The fast bitmap is not locked + /// The provided coordinates are out of bounds of the bitmap + public void SetPixel(int x, int y, Color color) + { + SetPixel(x, y, color.ToArgb()); + } + + /// + /// Sets the pixel color at the given coordinates. If the bitmap was not locked beforehands, + /// an exception is thrown + /// + /// The X coordinate of the pixel to set + /// The Y coordinate of the pixel to set + /// The new color of the pixel to set + /// The fast bitmap is not locked + /// The provided coordinates are out of bounds of the bitmap + public void SetPixel(int x, int y, int color) + { + SetPixel(x, y, unchecked((uint)color)); + } + + /// + /// Sets the pixel color at the given coordinates. If the bitmap was not locked beforehands, + /// an exception is thrown + /// + /// The X coordinate of the pixel to set + /// The Y coordinate of the pixel to set + /// The new color of the pixel to set + /// The fast bitmap is not locked + /// The provided coordinates are out of bounds of the bitmap + public void SetPixel(int x, int y, uint color) + { + if (!Locked) + { + throw new InvalidOperationException("The FastBitmap must be locked before any pixel operations are made"); + } + + if (x < 0 || x >= Width) + { + throw new ArgumentOutOfRangeException(nameof(x), @"The X component must be >= 0 and < width"); + } + if (y < 0 || y >= Height) + { + throw new ArgumentOutOfRangeException(nameof(y), @"The Y component must be >= 0 and < height"); + } + + *(uint*)(_scan0 + x + y * Stride) = color; + } + + /// + /// Gets the pixel color at the given coordinates. If the bitmap was not locked beforehands, + /// an exception is thrown + /// + /// The X coordinate of the pixel to get + /// The Y coordinate of the pixel to get + /// The fast bitmap is not locked + /// The provided coordinates are out of bounds of the bitmap + public Color GetPixel(int x, int y) + { + return Color.FromArgb(GetPixelInt(x, y)); + } + + /// + /// Gets the pixel color at the given coordinates as an integer value. If the bitmap + /// was not locked beforehands, an exception is thrown + /// + /// The X coordinate of the pixel to get + /// The Y coordinate of the pixel to get + /// The fast bitmap is not locked + /// The provided coordinates are out of bounds of the bitmap + public int GetPixelInt(int x, int y) + { + if (!Locked) + { + throw new InvalidOperationException("The FastBitmap must be locked before any pixel operations are made"); + } + + if (x < 0 || x >= Width) + { + throw new ArgumentOutOfRangeException(nameof(x), @"The X component must be >= 0 and < width"); + } + if (y < 0 || y >= Height) + { + throw new ArgumentOutOfRangeException(nameof(y), @"The Y component must be >= 0 and < height"); + } + + return *(_scan0 + x + y * Stride); + } + + /// + /// Gets the pixel color at the given coordinates as an unsigned integer value. + /// If the bitmap was not locked beforehands, an exception is thrown + /// + /// The X coordinate of the pixel to get + /// The Y coordinate of the pixel to get + /// The fast bitmap is not locked + /// The provided coordinates are out of bounds of the bitmap + public uint GetPixelUInt(int x, int y) + { + if (!Locked) + { + throw new InvalidOperationException("The FastBitmap must be locked before any pixel operations are made"); + } + + if (x < 0 || x >= Width) + { + throw new ArgumentOutOfRangeException(nameof(x), @"The X component must be >= 0 and < width"); + } + if (y < 0 || y >= Height) + { + throw new ArgumentOutOfRangeException(nameof(y), @"The Y component must be >= 0 and < height"); + } + + return *((uint*)_scan0 + x + y * Stride); + } + + /// + /// Copies the contents of the given array of colors into this FastBitmap. + /// Throws an ArgumentException if the count of colors on the array mismatches the pixel count from this FastBitmap + /// + /// The array of colors to copy + /// Whether to ignore zeroes when copying the data + public void CopyFromArray(int[] colors, bool ignoreZeroes = false) + { + if (colors.Length != Width * Height) + { + throw new ArgumentException(@"The number of colors of the given array mismatch the pixel count of the bitmap", nameof(colors)); + } + + // Simply copy the argb values array + // ReSharper disable once InconsistentNaming + int* s0t = _scan0; + + fixed (int* source = colors) + { + // ReSharper disable once InconsistentNaming + int* s0s = source; + + int count = Width * Height; + + if (!ignoreZeroes) + { + // Unfold the loop + const int sizeBlock = 8; + int rem = count % sizeBlock; + + count /= sizeBlock; + + while (count-- > 0) + { + *(s0t++) = *(s0s++); + *(s0t++) = *(s0s++); + *(s0t++) = *(s0s++); + *(s0t++) = *(s0s++); + + *(s0t++) = *(s0s++); + *(s0t++) = *(s0s++); + *(s0t++) = *(s0s++); + *(s0t++) = *(s0s++); + } + + while (rem-- > 0) + { + *(s0t++) = *(s0s++); + } + } + else + { + while (count-- > 0) + { + if (*(s0s) == 0) { s0t++; s0s++; continue; } + *(s0t++) = *(s0s++); + } + } + } + } + + /// + /// Clears the bitmap with the given color + /// + /// The color to clear the bitmap with + public void Clear(Color color) + { + Clear(color.ToArgb()); + } + + /// + /// Clears the bitmap with the given color + /// + /// The color to clear the bitmap with + public void Clear(int color) + { + bool unlockAfter = false; + if (!Locked) + { + Lock(); + unlockAfter = true; + } + + // Clear all the pixels + int count = Width * Height; + int* curScan = _scan0; + + // Uniform color pixel values can be mem-set straight away + int component = (color & 0xFF); + if (component == ((color >> 8) & 0xFF) && component == ((color >> 16) & 0xFF) && component == ((color >> 24) & 0xFF)) + { + memset(_scan0, component, (ulong)(Height * Stride * BytesPerPixel)); + } + else + { + // Defines the ammount of assignments that the main while() loop is performing per loop. + // The value specified here must match the number of assignment statements inside that loop + const int assignsPerLoop = 8; + + int rem = count % assignsPerLoop; + count /= assignsPerLoop; + + while (count-- > 0) + { + *(curScan++) = color; + *(curScan++) = color; + *(curScan++) = color; + *(curScan++) = color; + + *(curScan++) = color; + *(curScan++) = color; + *(curScan++) = color; + *(curScan++) = color; + } + while (rem-- > 0) + { + *(curScan++) = color; + } + + if (unlockAfter) + { + Unlock(); + } + } + } + + /// + /// Clears a square region of this image w/ a given color + /// + /// + /// + public void ClearRegion(Rectangle region, Color color) + { + ClearRegion(region, color.ToArgb()); + } + + /// + /// Clears a square region of this image w/ a given color + /// + /// + /// + public void ClearRegion(Rectangle region, int color) + { + Rectangle thisReg = new Rectangle(0, 0, Width, Height); + if (!region.IntersectsWith(thisReg)) + { + return; + } + + // If the region covers the entire image, use faster Clear(). + if (region == thisReg) + { + Clear(color); + return; + } + + int minX = region.X; + int maxX = region.X + region.Width; + + int minY = region.Y; + int maxY = region.Y + region.Height; + + // Bail out of optimization if there's too few rows to make this worth it + if (maxY - minY < 16) + { + for (int y = minY; y < maxY; y++) + { + for (int x = minX; x < maxX; x++) + { + *(_scan0 + x + y * Stride) = color; + } + } + return; + } + + ulong strideWidth = (ulong)region.Width * BytesPerPixel; + + // Uniform color pixel values can be mem-set straight away + int component = (color & 0xFF); + if (component == ((color >> 8) & 0xFF) && component == ((color >> 16) & 0xFF) && + component == ((color >> 24) & 0xFF)) + { + for (int y = minY; y < maxY; y++) + { + memset(_scan0 + minX + y * Stride, component, strideWidth); + } + } + else + { + // Prepare a horizontal slice of pixels that will be copied over each horizontal row down. + int[] row = new int[region.Width]; + + fixed (int* pRow = row) + { + int count = region.Width; + int rem = count % 8; + count /= 8; + int* pSrc = pRow; + while (count-- > 0) + { + *pSrc++ = color; + *pSrc++ = color; + *pSrc++ = color; + *pSrc++ = color; + + *pSrc++ = color; + *pSrc++ = color; + *pSrc++ = color; + *pSrc++ = color; + } + while (rem-- > 0) + { + *pSrc++ = color; + } + + int* sx = _scan0 + minX; + for (int y = minY; y < maxY; y++) + { + memcpy(sx + y * Stride, pRow, strideWidth); + } + } + } + } + + /// + /// Copies a region of the source bitmap into this fast bitmap + /// + /// The source image to copy + /// The region on the source bitmap that will be copied over + /// The region on this fast bitmap that will be changed + /// The provided source bitmap is the same bitmap locked in this FastBitmap + public void CopyRegion(Bitmap source, Rectangle srcRect, Rectangle destRect) + { + // Throw exception when trying to copy same bitmap over + if (source == _bitmap) + { + throw new ArgumentException(@"Copying regions across the same bitmap is not supported", nameof(source)); + } + + Rectangle srcBitmapRect = new Rectangle(0, 0, source.Width, source.Height); + Rectangle destBitmapRect = new Rectangle(0, 0, Width, Height); + + // Check if the rectangle configuration doesn't generate invalid states or does not affect the target image + if (srcRect.Width <= 0 || srcRect.Height <= 0 || destRect.Width <= 0 || destRect.Height <= 0 || + !srcBitmapRect.IntersectsWith(srcRect) || !destRect.IntersectsWith(destBitmapRect)) + { + return; + } + + // Find the areas of the first and second bitmaps that are going to be affected + srcBitmapRect = Rectangle.Intersect(srcRect, srcBitmapRect); + + // Clip the source rectangle on top of the destination rectangle in a way that clips out the regions of the original bitmap + // that will not be drawn on the destination bitmap for being out of bounds + srcBitmapRect = Rectangle.Intersect(srcBitmapRect, new Rectangle(srcRect.X, srcRect.Y, destRect.Width, destRect.Height)); + + destBitmapRect = Rectangle.Intersect(destRect, destBitmapRect); + + // Clip the source bitmap region yet again here + srcBitmapRect = Rectangle.Intersect(srcBitmapRect, new Rectangle(-destRect.X + srcRect.X, -destRect.Y + srcRect.Y, Width, Height)); + + // Calculate the rectangle containing the maximum possible area that is supposed to be affected by the copy region operation + int copyWidth = Math.Min(srcBitmapRect.Width, destBitmapRect.Width); + int copyHeight = Math.Min(srcBitmapRect.Height, destBitmapRect.Height); + + if (copyWidth == 0 || copyHeight == 0) + { + return; + } + + int srcStartX = srcBitmapRect.Left; + int srcStartY = srcBitmapRect.Top; + + int destStartX = destBitmapRect.Left; + int destStartY = destBitmapRect.Top; + + using (FastBitmapUlti fastSource = source.FastLock()) + { + ulong strideWidth = (ulong)copyWidth * BytesPerPixel; + + // Perform copies of whole pixel rows + for (int y = 0; y < copyHeight; y++) + { + int destX = destStartX; + int destY = destStartY + y; + + int srcX = srcStartX; + int srcY = srcStartY + y; + + long offsetSrc = (srcX + srcY * fastSource.Stride); + long offsetDest = (destX + destY * Stride); + + memcpy(_scan0 + offsetDest, fastSource._scan0 + offsetSrc, strideWidth); + } + } + } + + /// + /// Performs a copy operation of the pixels from the Source bitmap to the Target bitmap. + /// If the dimensions or pixel depths of both images don't match, the copy is not performed + /// + /// The bitmap to copy the pixels from + /// The bitmap to copy the pixels to + /// Whether the copy proceedure was successful + /// The provided source and target bitmaps are the same + public static bool CopyPixels(Bitmap source, Bitmap target) + { + if (source == target) + { + throw new ArgumentException(@"Copying pixels across the same bitmap is not supported", nameof(source)); + } + + if (source.Width != target.Width || source.Height != target.Height || source.PixelFormat != target.PixelFormat) + { + return false; + } + + using (FastBitmapUlti fastSource = source.FastLock(), + fastTarget = target.FastLock()) + { + memcpy(fastTarget.Scan0, fastSource.Scan0, (ulong)(fastSource.Height * fastSource.Stride * BytesPerPixel)); + } + + return true; + } + + /// + /// Clears the given bitmap with the given color + /// + /// The bitmap to clear + /// The color to clear the bitmap with + public static void ClearBitmap(Bitmap bitmap, Color color) + { + ClearBitmap(bitmap, color.ToArgb()); + } + + /// + /// Clears the given bitmap with the given color + /// + /// The bitmap to clear + /// The color to clear the bitmap with + public static void ClearBitmap(Bitmap bitmap, int color) + { + using (FastBitmapUlti fb = bitmap.FastLock()) + { + fb.Clear(color); + } + } + + /// + /// Copies a region of the source bitmap to a target bitmap + /// + /// The source image to copy + /// The target image to be altered + /// The region on the source bitmap that will be copied over + /// The region on the target bitmap that will be changed + /// The provided source and target bitmaps are the same bitmap + public static void CopyRegion(Bitmap source, Bitmap target, Rectangle srcRect, Rectangle destRect) + { + Rectangle srcBitmapRect = new Rectangle(0, 0, source.Width, source.Height); + Rectangle destBitmapRect = new Rectangle(0, 0, target.Width, target.Height); + + // If the copy operation results in an entire copy, use CopyPixels instead + if (srcBitmapRect == srcRect && destBitmapRect == destRect && srcBitmapRect == destBitmapRect) + { + CopyPixels(source, target); + return; + } + + using (FastBitmapUlti fastTarget = target.FastLock()) + { + fastTarget.CopyRegion(source, srcRect, destRect); + } + } + + /// + /// Returns a bitmap that is a slice of the original provided 32bpp Bitmap. + /// The region must have a width and a height > 0, and must lie inside the source bitmap's area + /// + /// The source bitmap to slice + /// The region of the source bitmap to slice + /// A Bitmap that represents the rectangle region slice of the source bitmap + /// The provided bimap is not 32bpp + /// The provided region is invalid + public static Bitmap SliceBitmap(Bitmap source, Rectangle region) + { + if (region.Width <= 0 || region.Height <= 0) + { + throw new ArgumentException(@"The provided region must have a width and a height > 0", nameof(region)); + } + + Rectangle sliceRectangle = Rectangle.Intersect(new Rectangle(Point.Empty, source.Size), region); + + if (sliceRectangle.IsEmpty) + { + throw new ArgumentException(@"The provided region must not lie outside of the bitmap's region completely", nameof(region)); + } + + Bitmap slicedBitmap = new Bitmap(sliceRectangle.Width, sliceRectangle.Height); + CopyRegion(source, slicedBitmap, sliceRectangle, new Rectangle(0, 0, sliceRectangle.Width, sliceRectangle.Height)); + + return slicedBitmap; + } + +#if NETSTANDARD + public static void memcpy(IntPtr dest, IntPtr src, ulong count) + { + Buffer.MemoryCopy(src.ToPointer(), dest.ToPointer(), count, count); + } + + public static void memcpy(void* dest, void* src, ulong count) + { + Buffer.MemoryCopy(src, dest, count, count); + } + + public static void memset(void* dest, int value, ulong count) + { + Unsafe.InitBlock(dest, (byte)value, (uint)count); + } +#else + /// + /// .NET wrapper to native call of 'memcpy'. Requires Microsoft Visual C++ Runtime installed + /// + [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)] + public static extern IntPtr memcpy(IntPtr dest, IntPtr src, ulong count); + + /// + /// .NET wrapper to native call of 'memcpy'. Requires Microsoft Visual C++ Runtime installed + /// + [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)] + public static extern IntPtr memcpy(void* dest, void* src, ulong count); + + /// + /// .NET wrapper to native call of 'memset'. Requires Microsoft Visual C++ Runtime installed + /// + [DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)] + public static extern IntPtr memset(void* dest, int value, ulong count); +#endif + + /// + /// Represents a disposable structure that is returned during Lock() calls, and unlocks the bitmap on Dispose calls + /// + public struct FastBitmapLocker : IDisposable + { + /// + /// Gets the fast bitmap instance attached to this locker + /// + public FastBitmapUlti FastBitmap { get; } + + /// + /// Initializes a new instance of the FastBitmapLocker struct with an initial fast bitmap object. + /// The fast bitmap object passed will be unlocked after calling Dispose() on this struct + /// + /// A fast bitmap to attach to this locker which will be released after a call to Dispose + public FastBitmapLocker(FastBitmapUlti fastBitmap) + { + FastBitmap = fastBitmap; + } + + /// + /// Disposes of this FastBitmapLocker, essentially unlocking the underlying fast bitmap + /// + public void Dispose() + { + if (FastBitmap.Locked) + { + FastBitmap.Unlock(); + } + } + } + } + + /// + /// Describes a pixel format to use when locking a bitmap using . + /// + public enum FastBitmapLockFormat + { + /// Specifies that the format is 32 bits per pixel; 8 bits each are used for the red, green, and blue components. The remaining 8 bits are not used. + Format32bppRgb = 139273, + /// Specifies that the format is 32 bits per pixel; 8 bits each are used for the alpha, red, green, and blue components. The red, green, and blue components are premultiplied, according to the alpha component. + Format32bppPArgb = 925707, + /// Specifies that the format is 32 bits per pixel; 8 bits each are used for the alpha, red, green, and blue components. + Format32bppArgb = 2498570, + } + + /// + /// Static class that contains fast bitmap extension methdos for the Bitmap class + /// + public static class FastBitmapExtensions + { + /// + /// Locks this bitmap into memory and returns a FastBitmap that can be used to manipulate its pixels + /// + /// The bitmap to lock + /// A locked FastBitmap + public static FastBitmapUlti FastLock(this Bitmap bitmap) + { + FastBitmapUlti fast = new FastBitmapUlti(bitmap); + fast.Lock(); + + return fast; + } + + /// + /// Locks this bitmap into memory and returns a FastBitmap that can be used to manipulate its pixels + /// + /// The bitmap to lock + /// The underlying pixel format to use when locking the bitmap + /// A locked FastBitmap + public static FastBitmapUlti FastLock(this Bitmap bitmap, FastBitmapLockFormat lockFormat) + { + FastBitmapUlti fast = new FastBitmapUlti(bitmap); + fast.Lock(lockFormat); + + return fast; + } + + /// + /// Returns a deep clone of this Bitmap object, with all the data copied over. + /// After a deep clone, the new bitmap is completely independent from the original + /// + /// The bitmap to clone + /// A deep clone of this Bitmap object, with all the data copied over + public static Bitmap DeepClone(this Bitmap bitmap) + { + return bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), bitmap.PixelFormat); + } + } +} diff --git a/Source/Helper/HandleExtention.cs b/Source/Helper/HandleExtention.cs new file mode 100644 index 0000000..3e3fb8f --- /dev/null +++ b/Source/Helper/HandleExtention.cs @@ -0,0 +1,70 @@ +using LeagueAI.Libraries.Entities; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace LeagueAI.Libraries.Helper +{ + public static class HandleExtention + { + public static IntPtr GetGameHandle(this string nameProcess) + { + try + { + var activeWindows = GetOpenWindows() + .FirstOrDefault(m => m.Value?.Contains(DEFINE.GameExecutableName) == true); + return activeWindows.Key; + } + catch (Exception) { } + return IntPtr.Zero; + } + + public static IDictionary GetOpenWindows() + { + IntPtr shellWindow = User32.GetShellWindow(); + Dictionary windows = new Dictionary(); + + User32.EnumWindows(delegate (IntPtr hWnd, int lParam) + { + if (hWnd == shellWindow) return true; + if (!User32.IsWindowVisible(hWnd)) return true; + + int length = User32.GetWindowTextLength(hWnd); + if (length == 0) return true; + + var builder = new StringBuilder(length); + User32.GetWindowText(hWnd, builder, length + 1); + + windows[hWnd] = builder.ToString(); + return true; + + }, 0); + + return windows; + } + + public static Process GetProcess(this IntPtr hwnd) + { + User32.GetWindowThreadProcessId(hwnd, out uint pid); + Process proc = Process.GetProcessById((int)pid); + return proc; + } + + public static int BringToFront(this IntPtr hwnd) => User32.SetForegroundWindow(hwnd); + public static bool CenterScreen(this IntPtr hwnd) + { + const int SWP_NOSIZE = 0x0001; + //const int SWP_NOZORDER = 0x0004; + const int SWP_SHOWWINDOW = 0x0040; + const int SWP_NOMOVE = 0x0200; + if (!User32.GetWindowRect(hwnd, out RECT rct)) return false; + Rectangle screen = Screen.FromHandle(hwnd).Bounds; + Point pt = new Point(screen.Left + screen.Width / 2 - (rct.Right - rct.Left) / 2, screen.Top + screen.Height / 2 - (rct.Bottom - rct.Top) / 2); + return User32.SetWindowPos(hwnd, IntPtr.Zero, pt.X, pt.Y, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + } + } +} diff --git a/Source/Helper/HttpStatusCodeExtention.cs b/Source/Helper/HttpStatusCodeExtention.cs new file mode 100644 index 0000000..b0ff47d --- /dev/null +++ b/Source/Helper/HttpStatusCodeExtention.cs @@ -0,0 +1,13 @@ +using Leaf.xNet; + +namespace LeagueAI.Libraries.Helper +{ + public static class HttpStatusCodeExtention + { + public static bool IsSuccess(this HttpStatusCode httpStatusCode) + { + var code = (int)httpStatusCode; + return 200 <= code && code < 300; + } + } +} diff --git a/Source/Helper/InputHelper.cs b/Source/Helper/InputHelper.cs new file mode 100644 index 0000000..ba11ad9 --- /dev/null +++ b/Source/Helper/InputHelper.cs @@ -0,0 +1,74 @@ +using InputManager; +using System; +using System.Threading; +using System.Windows.Forms; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class InputHelper + { + public static void InputWords(string message, int delayPressKey, int delay) + { + Thread.Sleep(300); + foreach (char character in message) + { + Thread.Sleep(delayPressKey); + Keys[] keys = KeyboardMapper.GetKey(character, delayPressKey); + + if (keys == null) continue; + + if (keys.Length == 1) + { + Keyboard.KeyPress(keys[0]); + continue; + } + + if (keys.Length >= 2) + { + Keyboard.KeyDown(keys[0]); + Thread.Sleep(delayPressKey); + Keyboard.KeyDown(keys[1]); + Thread.Sleep(delayPressKey); + Keyboard.KeyUp(keys[1]); + Thread.Sleep(delayPressKey); + Keyboard.KeyUp(keys[0]); + continue; + } + } + Thread.Sleep(delay); + } + + public static void KeyUp(string key, int delay) + { + Keyboard.KeyUp((Keys)Enum.Parse(typeof(Keys), key)); + Thread.Sleep(delay); + } + + public static void KeyDown(string key, int delay) + { + Keyboard.KeyDown((Keys)Enum.Parse(typeof(Keys), key)); + Thread.Sleep(delay); + } + + public static void PressKey(string key, int delay) + => Keyboard.KeyPress((Keys)Enum.Parse(typeof(Keys), key), delay); + + public static void PressKey(Keys key, int delay) => Keyboard.KeyPress(key, delay); + + public static void PressKey(char key, int delay) => PressKey(key.ToString(), delay); + + public static void RightClick(int x, int y, int delay) + { + Mouse.Move(x, y); + Mouse.PressButton(Mouse.MouseKeys.Right, delay); + } + + public static void LeftClick(int x, int y, int delay) + { + Mouse.Move(x, y); + Mouse.PressButton(Mouse.MouseKeys.Left, delay); + } + + public static void MoveMouse(int x, int y) => Mouse.Move(x, y); + } +} diff --git a/Source/Helper/InterceptKeys.cs b/Source/Helper/InterceptKeys.cs new file mode 100644 index 0000000..2709eeb --- /dev/null +++ b/Source/Helper/InterceptKeys.cs @@ -0,0 +1,57 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using System.Windows.Forms; +using static LeagueAI.Libraries.Helper.User32; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class InterceptKeys + { + public delegate IntPtr LowLevelKeyboardProc( + int nCode, IntPtr wParam, IntPtr lParam); + + private const int WH_KEYBOARD_LL = 13; + private const int WM_KEYDOWN = 0x0100; + private static readonly LowLevelKeyboardProc _proc = HookCallback; + private static IntPtr _hookID = IntPtr.Zero; + + public static void Init() + { + Task.Run(() => + { + _hookID = SetHook(_proc); + Application.Run(); + UnhookWindowsHookEx(_hookID); + }); + } + + public static IntPtr SetHook(LowLevelKeyboardProc proc) + { + using (Process curProcess = Process.GetCurrentProcess()) + using (ProcessModule curModule = curProcess.MainModule) + { + return SetWindowsHookEx(WH_KEYBOARD_LL, proc, + GetModuleHandle(curModule.ModuleName), 0); + } + } + + + private static IntPtr HookCallback( + int nCode, IntPtr wParam, IntPtr lParam) + { + if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) + { + int vkCode = Marshal.ReadInt32(lParam); + Keys key = (Keys)vkCode; + + if (key == Keys.Oem7) // ` key + { + Program.Exit(0); + } + } + return CallNextHookEx(_hookID, nCode, wParam, lParam); + } + } +} diff --git a/Source/Helper/KeyboardMapper.cs b/Source/Helper/KeyboardMapper.cs new file mode 100644 index 0000000..4da4e10 --- /dev/null +++ b/Source/Helper/KeyboardMapper.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.Windows.Forms; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class KeyboardMapper + { + private static readonly Dictionary keyMap = new Dictionary() + { + { 'a', new Keys[] { Keys.A } }, { 'A', new Keys[] { Keys.RShiftKey, Keys.A } }, + { 'b', new Keys[] { Keys.B } }, { 'B', new Keys[] { Keys.RShiftKey, Keys.B } }, + { 'c', new Keys[] { Keys.C } }, { 'C', new Keys[] { Keys.RShiftKey, Keys.C } }, + { 'd', new Keys[] { Keys.D } }, { 'D', new Keys[] { Keys.RShiftKey, Keys.D } }, + { 'e', new Keys[] { Keys.E } }, { 'E', new Keys[] { Keys.RShiftKey, Keys.E } }, + { 'f', new Keys[] { Keys.F } }, { 'F', new Keys[] { Keys.RShiftKey, Keys.F } }, + { 'g', new Keys[] { Keys.G } }, { 'G', new Keys[] { Keys.RShiftKey, Keys.G } }, + { 'h', new Keys[] { Keys.H } }, { 'H', new Keys[] { Keys.RShiftKey, Keys.H } }, + { 'i', new Keys[] { Keys.I } }, { 'I', new Keys[] { Keys.RShiftKey, Keys.I } }, + { 'j', new Keys[] { Keys.J } }, { 'J', new Keys[] { Keys.RShiftKey, Keys.J } }, + { 'k', new Keys[] { Keys.K } }, { 'K', new Keys[] { Keys.RShiftKey, Keys.K } }, + { 'l', new Keys[] { Keys.L } }, { 'L', new Keys[] { Keys.RShiftKey, Keys.L } }, + { 'm', new Keys[] { Keys.M } }, { 'M', new Keys[] { Keys.RShiftKey, Keys.M } }, + { 'n', new Keys[] { Keys.N } }, { 'N', new Keys[] { Keys.RShiftKey, Keys.N } }, + { 'o', new Keys[] { Keys.O } }, { 'O', new Keys[] { Keys.RShiftKey, Keys.O } }, + { 'p', new Keys[] { Keys.P } }, { 'P', new Keys[] { Keys.RShiftKey, Keys.P } }, + { 'q', new Keys[] { Keys.Q } }, { 'Q', new Keys[] { Keys.RShiftKey, Keys.Q } }, + { 'r', new Keys[] { Keys.R } }, { 'R', new Keys[] { Keys.RShiftKey, Keys.R } }, + { 's', new Keys[] { Keys.S } }, { 'S', new Keys[] { Keys.RShiftKey, Keys.S } }, + { 't', new Keys[] { Keys.T } }, { 'T', new Keys[] { Keys.RShiftKey, Keys.T } }, + { 'u', new Keys[] { Keys.U } }, { 'U', new Keys[] { Keys.RShiftKey, Keys.U } }, + { 'v', new Keys[] { Keys.V } }, { 'V', new Keys[] { Keys.RShiftKey, Keys.V } }, + { 'w', new Keys[] { Keys.W } }, { 'W', new Keys[] { Keys.RShiftKey, Keys.W } }, + { 'x', new Keys[] { Keys.X } }, { 'X', new Keys[] { Keys.RShiftKey, Keys.X } }, + { 'y', new Keys[] { Keys.Y } }, { 'Y', new Keys[] { Keys.RShiftKey, Keys.Y } }, + { 'z', new Keys[] { Keys.Z } }, { 'Z', new Keys[] { Keys.RShiftKey, Keys.Z } }, + { ' ', new Keys[] { Keys.Space } }, + + { ',', new Keys[] { Keys.Oemcomma } }, { '<', new Keys[] { Keys.RShiftKey, Keys.Oemcomma } }, + { '.', new Keys[] { Keys.OemPeriod } }, { '>', new Keys[] { Keys.RShiftKey, Keys.OemPeriod } }, + { '/', new Keys[] { Keys.OemQuestion } }, { '?', new Keys[] { Keys.RShiftKey, Keys.OemQuestion } }, + { ';', new Keys[] { Keys.OemSemicolon } }, { ':', new Keys[] { Keys.RShiftKey, Keys.OemSemicolon } }, + { '\'', new Keys[] { Keys.OemQuotes } }, { '"', new Keys[] { Keys.RShiftKey, Keys.OemQuotes } }, + { '[', new Keys[] { Keys.OemOpenBrackets } }, { '{', new Keys[] { Keys.RShiftKey, Keys.OemOpenBrackets } }, + { ']', new Keys[] { Keys.OemCloseBrackets } }, { '}', new Keys[] { Keys.RShiftKey, Keys.OemCloseBrackets } }, + { '\\', new Keys[] { Keys.OemPipe } }, { '|', new Keys[] { Keys.RShiftKey, Keys.OemPipe } }, + { '`', new Keys[] { Keys.Oemtilde } }, { '~', new Keys[] { Keys.RShiftKey, Keys.Oemtilde } }, + { '-', new Keys[] { Keys.OemMinus } }, { '_', new Keys[] { Keys.RShiftKey, Keys.OemMinus } }, + { '+', new Keys[] { Keys.Oemplus } }, { '=', new Keys[] { Keys.RShiftKey, Keys.Oemplus } }, + + { '1', new Keys[] { Keys.D1 } }, { '!', new Keys[] { Keys.RShiftKey, Keys.D1 } }, + { '2', new Keys[] { Keys.D2 } }, { '@', new Keys[] { Keys.RShiftKey, Keys.D2 } }, + { '3', new Keys[] { Keys.D3 } }, { '#', new Keys[] { Keys.RShiftKey, Keys.D3 } }, + { '4', new Keys[] { Keys.D4 } }, { '$', new Keys[] { Keys.RShiftKey, Keys.D4 } }, + { '5', new Keys[] { Keys.D5 } }, { '%', new Keys[] { Keys.RShiftKey, Keys.D5 } }, + { '6', new Keys[] { Keys.D6 } }, { '^', new Keys[] { Keys.RShiftKey, Keys.D6 } }, + { '7', new Keys[] { Keys.D7 } }, { '&', new Keys[] { Keys.RShiftKey, Keys.D7 } }, + { '8', new Keys[] { Keys.D8 } }, { '*', new Keys[] { Keys.RShiftKey, Keys.D8 } }, + { '9', new Keys[] { Keys.D9 } }, { '(', new Keys[] { Keys.RShiftKey, Keys.D9 } }, + { '0', new Keys[] { Keys.D0 } }, { ')', new Keys[] { Keys.RShiftKey, Keys.D0 } }, + }; + + public static Keys[] GetKey(char key, int delayPress) + { + if (keyMap.TryGetValue(key, out Keys[] value)) + { + return value; + } + + return default; + } + } +} diff --git a/Source/Helper/LeagueSettingsUlti.cs b/Source/Helper/LeagueSettingsUlti.cs new file mode 100644 index 0000000..af60ded --- /dev/null +++ b/Source/Helper/LeagueSettingsUlti.cs @@ -0,0 +1,132 @@ +using LeagueAI.Libraries.Entities; +using LeagueAI.Libraries.Enums; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class LeagueSettingsUlti + { + public static void ApplySettings() + { + // Cài đặt cửa sổ game + string gamCFG = Configuration.Instance.LeagueGameconfigPath; + ConfigCFGFile config = new ConfigCFGFile(gamCFG); + JToken settings = (JToken)Configuration.Instance.SettingGame?.inGame; + foreach (JProperty x in settings) + { + config.ReplaceSetting(x.Name, x.Value?.ToString()); + } + + config.ReplaceSetting(nameof(DEFINE.AutoAcquireTarget), DEFINE.AutoAcquireTarget); + config.ReplaceSetting(nameof(DEFINE.WindowMode), DEFINE.WindowMode); + + config.Save(); + Logger.WriteLine(DEFINE.SettingScreenLog, EMessageState.SUCCES); + + // Cài đặt riêng của người dùng + PersistedSetting setting = null; + PersistedSetting(ref setting, DEFINE.LeagueGameconfigPath, "General", nameof(DEFINE.AutoAcquireTarget), DEFINE.AutoAcquireTarget); + PersistedSetting(ref setting, DEFINE.LeagueGameconfigPath, "HUD", "CameraLockMode", "0"); + PersistedSetting(ref setting, DEFINE.LeagueGameconfigPath, "HUD", "MinimapScale", "1.0000"); + File.WriteAllText( + Configuration.Instance.LeaguePersistedSettingsPath, + JsonConvert.SerializeObject(setting, Formatting.Indented)); + + Logger.WriteLine(DEFINE.SettingKeyboardLog, EMessageState.SUCCES); + } + + private static void PersistedSetting(ref PersistedSetting setting, string fileName, string sectionName, string settingName, string settingValue) + { + if (setting == null) + { + var persistedSetting = SystemHelper.SafeReadFile(Configuration.Instance.LeaguePersistedSettingsPath); + setting = JsonConvert.DeserializeObject(persistedSetting); + } + var indexGameCFG = setting.Files.FindIndex(m => m.Name == fileName); + if (indexGameCFG >= 0) + { + var gamecfg = setting.Files[indexGameCFG]; + var indexGenerel = gamecfg.Sections.FindIndex(m => m.Name == sectionName); + + if (indexGenerel >= 0) + { + var generel = gamecfg.Sections[indexGenerel]; + var item = generel.Settings.FirstOrDefault(m => m.Name == settingName); + if (item == default) generel.Settings.Add(new Setting() + { + Name = settingName, + Value = settingValue + }); + else + item.Value = settingValue; + } + else + { + gamecfg.Sections.Add(new Section() + { + Name = sectionName, + Settings = new List() + { + new Setting() + { + Name = settingName, + Value = settingValue + } + } + }); + } + + } + else + { + setting.Files.Add(new FileConfig() + { + Name = fileName, + Sections = new List
() + { + new Section() { Name = sectionName, Settings = new List() + { + new Setting() + { + Name = settingName, + Value = settingValue + } + } + } } + }); + } + } + } + + public sealed class ConfigCFGFile + { + private string Filepath { get; set; } = null; + private string[] Content { get; set; } = null; + + public ConfigCFGFile(string filePath) + { + Content = File.ReadAllLines(filePath); + Filepath = filePath; + } + + public void ReplaceSetting(string key, string value) + { + for (int i = 0; i < Content.Length; i++) + { + if (Content[i].StartsWith($"{key}=")) + { + Content[i] = $"{key}={value}"; + } + } + } + + public void Save() + { + File.WriteAllLines(Filepath, Content); + } + } +} diff --git a/Source/Helper/Logger.cs b/Source/Helper/Logger.cs new file mode 100644 index 0000000..ff6b846 --- /dev/null +++ b/Source/Helper/Logger.cs @@ -0,0 +1,108 @@ +using LeagueAI.Libraries.Enums; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class Logger + { + private static readonly Dictionary Colors; + private static readonly Dictionary errorCache = new Dictionary(); + + static Logger() + { + Colors = new Dictionary() + { + { EMessageState.TIP_HELP, ConsoleColor.Gray }, + { EMessageState.INFO, ConsoleColor.DarkCyan }, + { EMessageState.PROCESS, ConsoleColor.DarkGray }, + { EMessageState.WARNING, ConsoleColor.DarkYellow }, + { EMessageState.SUCCES, ConsoleColor.Green }, + { EMessageState.ERROR , ConsoleColor.DarkRed}, + { EMessageState.ERROR_FATAL , ConsoleColor.Magenta}, + }; + } + public static void Initialize() + { + if (!File.Exists(DEFINE.LogPath)) + { + File.Create(DEFINE.LogPath); + } + } + + public static void LogToFile(object message) + { + string value = DateTime.Now + " : " + message.ToString(); + File.AppendAllLines(DEFINE.LogPath, new string[] { value }, Encoding.UTF8); + } + + public static void OnStartup() + { + WriteLine(DEFINE.Logo1, EMessageState.TIP_HELP); + Console.Title = Guid.NewGuid().ToString("N") + " (" + Program.GameCount + " games)"; + } + + public static void PrintInfo() + { + WriteLine(DEFINE.Logo2, EMessageState.TIP_HELP); + } + + public static void WriteLine( + Exception e, EMessageState state = EMessageState.ERROR_FATAL, bool showLog = true) + { + if (showLog) WriteColored($"{state} - {DateTime.Now} - {e.Message}.\n", Colors[state]); + if (state >= EMessageState.ERROR) + { + LogToFile(e.Message + "\n" + e.StackTrace); + AddErrorLog(e.Message + "\n" + e.StackTrace, state); + } + } + + public static void WriteLine(object value, EMessageState state = EMessageState.INFO, bool showLog = true) => Write($"{value}\n", state, showLog); + + public static void Write( + object value, + EMessageState state = EMessageState.INFO, + bool showLog = true + ) + { + if (showLog) + { + WriteColored($"{state} - {DateTime.Now} - {value}", Colors[state]); + } + + if (state >= EMessageState.ERROR) + { + LogToFile(value); + } + + if (state >= EMessageState.ERROR_FATAL) + { + System.Reflection.MethodBase frame = new StackFrame(1).GetMethod(); + AddErrorLog($"[{frame.DeclaringType.FullName}.{frame.Name}]: " + value?.ToString(), state); + } + } + + private static void WriteColored(object value, ConsoleColor color) + { + Console.ForegroundColor = color; + Console.Write(value); + } + + private static void AddErrorLog( + string message, + EMessageState state = EMessageState.ERROR_FATAL + ) + { + try + { + if (errorCache.ContainsKey(message)) errorCache[message] += 1; + else errorCache.Add(message, 1); + } + catch (Exception) { } + } + } +} diff --git a/Source/Helper/PatternsUlti.cs b/Source/Helper/PatternsUlti.cs new file mode 100644 index 0000000..95da37e --- /dev/null +++ b/Source/Helper/PatternsUlti.cs @@ -0,0 +1,63 @@ +using LeagueAI.Libraries.Api; +using LeagueAI.Libraries.Patterns; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class PatternsUlti + { + private static readonly Dictionary Scripts = new Dictionary(); + public static List ScriptsPattern => Scripts.Keys.ToList(); + + public static void Initialize() + { + Type baseType = typeof(BasePatternScript); + Assembly assembly = Assembly.GetAssembly(baseType); + + // Lấy tất cả các Type của assembly + Type[] types = assembly.GetTypes(); + + // Lọc các Type của class kế thừa từ class cha + IEnumerable derivedTypes = types.Where(t => t.IsSubclassOf(baseType)); + + foreach (Type type in derivedTypes) + { + Scripts.Add(type.Name, type); + } + } + public static bool Contains(string name) => Scripts.ContainsKey(name); + + public static void Execute(string name) + { + if (!Scripts.ContainsKey(name)) + { + Logger.WriteLine(string.Format(DEFINE.PatternErrorLog, name)); + return; + } + + BasePatternScript script = null; + try + { + script = Activator.CreateInstance(Scripts[name]) as BasePatternScript; + script.bot = new BotApi(); + script.client = new ClientApi(); + script.game = new GameApi(); + script.Execute(); + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + public static new string ToString() + { + StringBuilder sb = new StringBuilder(); + foreach (KeyValuePair script in Scripts) + { + sb.AppendLine("-" + script.Key); + } + return sb.ToString(); + } + } +} diff --git a/Source/Helper/ScreenHelper.cs b/Source/Helper/ScreenHelper.cs new file mode 100644 index 0000000..642e2c3 --- /dev/null +++ b/Source/Helper/ScreenHelper.cs @@ -0,0 +1,77 @@ +using LeagueAI.Libraries.Entities; +using System; +using System.Drawing; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class ScreenHelper + { + public static Point? GetColorPosition( + Color color, + IntPtr handle, + int deviantX = 10, + int deviantY = 10) + { + Point? result = null; + try + { + FindColorPosition( + color, + handle, + (point) => + { + result = point; + }, + deviantX: deviantX, + deviantY: deviantY, + existWhenFound: true + ); + } + catch (Exception) { } + return result; + } + + public static void FindColorPosition( + Color color, + IntPtr handle, + Action whenFound = null, + int deviantX = 10, + int deviantY = 10, + bool existWhenFound = true + ) + { + if (handle == null || handle == IntPtr.Zero || + !User32.GetWindowRect(handle, out RECT rect)) return; + + var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); + if (bounds.IsEmpty || bounds.Width <= 0 || bounds.Height <= 0) return; + + var bitmap = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top); + using (Graphics graphics = Graphics.FromImage(bitmap)) + { + graphics.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size); + + for (int x = bitmap.Width - 1; x >= 0; x--) + { + for (int y = bitmap.Height - 1; y >= 0; y--) + { + Color pixelColor = bitmap.GetPixel(x, y); + + if (pixelColor.R == color.R && pixelColor.G == color.G && pixelColor.B == color.B) + { + var result = new Point(x + rect.Left + deviantX, y + rect.Top + deviantY); + if (existWhenFound) + { + whenFound(result); + graphics.Dispose(); + return; + } + whenFound(result); + } + } + } + graphics.Dispose(); + } + } + } +} diff --git a/Source/Helper/StartupManager.cs b/Source/Helper/StartupManager.cs new file mode 100644 index 0000000..c89e01c --- /dev/null +++ b/Source/Helper/StartupManager.cs @@ -0,0 +1,14 @@ +using System.Reflection; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class StartupManager + { + public static void Initialize(Assembly startupAssembly) + { + InterceptKeys.Init(); + PatternsUlti.Initialize(); + LeagueSettingsUlti.ApplySettings(); + } + } +} diff --git a/Source/Helper/SystemHelper.cs b/Source/Helper/SystemHelper.cs new file mode 100644 index 0000000..344b4e1 --- /dev/null +++ b/Source/Helper/SystemHelper.cs @@ -0,0 +1,82 @@ +using System.Collections.Generic; +using System.IO; +using System.Management; +using System.Net; +using System.Text; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class SystemHelper + { + private static readonly WebClient client; + + static SystemHelper() + { + client = new WebClient(); + client.Headers.Add("Accept", "application/json"); + } + + public static void Shutdown() + { + // https://stackoverflow.com/a/102583/12354701 + + ManagementBaseObject mboShutdown = null; + ManagementClass mcWin32 = new ManagementClass("Win32_OperatingSystem"); + mcWin32.Get(); + + // You can't shutdown without security privileges + mcWin32.Scope.Options.EnablePrivileges = true; + ManagementBaseObject mboShutdownParams = + mcWin32.GetMethodParameters("Win32Shutdown"); + + // Flag 1 means we want to shut down the system. Use "2" to reboot. + mboShutdownParams["Flags"] = "1"; + mboShutdownParams["Reserved"] = "0"; + foreach (ManagementObject manObj in mcWin32.GetInstances()) + { + mboShutdown = manObj.InvokeMethod("Win32Shutdown", + mboShutdownParams, null); + } + } + + public static List SearchFiles(string startingDirectory, string fileName) + { + var files = new List(); + if (!Directory.Exists(startingDirectory)) return files; + + var subDirectories = Directory.GetDirectories(startingDirectory); + foreach (var subDirectory in subDirectories) + { + var searchResult = SearchFiles(subDirectory, fileName); + if (searchResult == null || searchResult.Count <= 0) continue; + + files.AddRange(searchResult); + } + + string[] matchingFiles = Directory.GetFiles(startingDirectory, fileName); + + if (matchingFiles?.Length > 0) + files.AddRange(matchingFiles); + + return files; + } + + public static string SafeReadFile(string path) + { + using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + using (var streamReader = new StreamReader(fileStream, Encoding.Default)) + { + var result = streamReader.ReadToEnd(); + + streamReader.Close(); + streamReader.Dispose(); + + fileStream.Close(); + fileStream.Dispose(); + return result; + } + } + } + } +} diff --git a/Source/Helper/User32.cs b/Source/Helper/User32.cs new file mode 100644 index 0000000..5cd7bac --- /dev/null +++ b/Source/Helper/User32.cs @@ -0,0 +1,117 @@ +using LeagueAI.Libraries.Entities; +using System; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Text; +using static LeagueAI.Libraries.Helper.InterceptKeys; + +namespace LeagueAI.Libraries.Helper +{ + public sealed class User32 + { + + public const int WH_KEYBOARD_LL = 13; + public const int WM_KEYDOWN = 0x0100; + + [DllImport("user32.dll")] + public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect); + + [DllImport("user32.dll")] + public static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern IntPtr GetDesktopWindow(); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool UnhookWindowsHookEx(IntPtr hhk); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + public static extern IntPtr GetModuleHandle(string lpModuleName); + + [DllImport("user32.dll")] + public static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo); + + [DllImport("user32.dll")] + public static extern int GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); + + [DllImport("user32.dll")] + public static extern IntPtr GetDC(IntPtr hwnd); + + [DllImport("user32.dll")] + public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc); + + [DllImport("gdi32.dll")] + public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos); + + [DllImport("user32.dll")] + public static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("user32.dll")] + public static extern bool GetCursorPos(out POINT lpPoint); + + [DllImport("user32.dll")] + public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); + + [DllImport("user32.dll")] + public static extern int GetWindowTextLength(IntPtr hWnd); + + public static Point GetMousePosition() + { + GetCursorPos(out POINT lpPoint); + return lpPoint; + } + + [DllImport("user32.dll")] + public static extern int SetForegroundWindow(IntPtr hwnd); + + [DllImport("user32.dll")] + public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow); + + [DllImport("user32.dll", SetLastError = true)] + public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); + + [DllImport("user32.dll", + CallingConvention = CallingConvention.StdCall, + CharSet = CharSet.Unicode, + EntryPoint = "LoadKeyboardLayout", + SetLastError = true, + ThrowOnUnmappableChar = false)] + public static extern uint LoadKeyboardLayout(StringBuilder pwszKLID, uint flags); + + [DllImport("user32.dll", + CallingConvention = CallingConvention.StdCall, + CharSet = CharSet.Unicode, + EntryPoint = "GetKeyboardLayout", + SetLastError = true, + ThrowOnUnmappableChar = false)] + public static extern uint GetKeyboardLayout(uint idThread); + + [DllImport("user32.dll", + CallingConvention = CallingConvention.StdCall, + CharSet = CharSet.Unicode, + EntryPoint = "ActivateKeyboardLayout", + SetLastError = true, + ThrowOnUnmappableChar = false)] + public static extern uint ActivateKeyboardLayout(uint hkl, uint Flags); + + [DllImport("USER32.DLL")] + public static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam); + public delegate bool EnumWindowsProc(IntPtr hWnd, int lParam); + + [DllImport("USER32.DLL")] + public static extern IntPtr GetShellWindow(); + + [DllImport("user32.dll")] + public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdc, uint nFlags); + } +} diff --git a/Source/Interfaces/IApi.cs b/Source/Interfaces/IApi.cs new file mode 100644 index 0000000..243b81e --- /dev/null +++ b/Source/Interfaces/IApi.cs @@ -0,0 +1,6 @@ +namespace LeagueAI.Libraries.Interfaces +{ + public interface IApi + { + } +} diff --git a/Source/Interfaces/IEntity.cs b/Source/Interfaces/IEntity.cs new file mode 100644 index 0000000..4ccf81e --- /dev/null +++ b/Source/Interfaces/IEntity.cs @@ -0,0 +1,9 @@ +using System.Drawing; + +namespace LeagueAI.Libraries.Interfaces +{ + public interface IEntity + { + Point Position { get; } + } +} diff --git a/Source/Interfaces/IProgram.cs b/Source/Interfaces/IProgram.cs new file mode 100644 index 0000000..9f847a1 --- /dev/null +++ b/Source/Interfaces/IProgram.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace LeagueAI.Libraries.Interfaces +{ + public interface IProgram + { + Task Main(string[] args); + } +} diff --git a/Source/LeagueAI.Libraries.csproj b/Source/LeagueAI.Libraries.csproj new file mode 100644 index 0000000..9a92e4e --- /dev/null +++ b/Source/LeagueAI.Libraries.csproj @@ -0,0 +1,220 @@ + + + + + Debug + AnyCPU + {E2BA0D27-EADE-4C89-83C1-47BCE629FB54} + Exe + LeagueAI.Libraries + LeagueAI.Libraries + v4.7.2 + 512 + true + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + AnyCPU + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + true + + + x64 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + + + + + + x64 + bin\x64\Debug\ + + + x64 + bin\Release\ + true + true + + + hextech.ico + + + + False + Resources\InputManager.dll + + + False + Resources\Leaf.xNet.dll + + + False + Resources\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + if $(ConfigurationName) == Release ( + echo "Delete useless file." + cd $(TargetDir) + del /F /Q *.* +) + + \ No newline at end of file diff --git a/Source/Patterns/BasePatternScript.cs b/Source/Patterns/BasePatternScript.cs new file mode 100644 index 0000000..f2ff743 --- /dev/null +++ b/Source/Patterns/BasePatternScript.cs @@ -0,0 +1,15 @@ +using LeagueAI.Libraries.Api; + +namespace LeagueAI.Libraries.Patterns +{ + public abstract class BasePatternScript + { + public BotApi bot { protected get; set; } + public GameApi game { protected get; set; } + public ClientApi client { protected get; set; } + + public abstract void Execute(); + + public virtual void Dispose() { } + } +} diff --git a/Source/Patterns/Begin.cs b/Source/Patterns/Begin.cs new file mode 100644 index 0000000..54c0a33 --- /dev/null +++ b/Source/Patterns/Begin.cs @@ -0,0 +1,221 @@ +using LeagueAI.Libraries.Entities; +using LeagueAI.Libraries.Enums; +using LeagueAI.Libraries.Helper; +using LeagueAI.Libraries.Patterns; +using System; + +namespace LeagueAI.Libraries +{ + public class Begin : BasePatternScript + { + private EQueueRoom gameMode { get; set; } = EQueueRoom.CoopVsAIIntroBot; + private Summoner currentPlayer { get; set; } + + public override void Execute() + { + try + { + bot.Log(DEFINE.BeginGameLog); + Program.GameHandle = IntPtr.Zero; + client.WaitClientOpen(); + client.Initialize(); + currentPlayer = client.LoadSummoner(); + if (string.IsNullOrWhiteSpace(currentPlayer?.displayName)) + { + bot.Warn(DEFINE.BeginCantLoadUserInfoLog); + } + + LimitLevel(); + + if (Enum.TryParse(DEFINE.DefaultRoom, out EQueueRoom selectedRoom)) + gameMode = selectedRoom; + else gameMode = EQueueRoom.CoopVsAIIntroBot; + + EGameflowPhase statusGame = client.GetGameflowPhase(); + switch (statusGame) + { + case EGameflowPhase.FailedToLaunch: + case EGameflowPhase.TerminatedInError: + bot.Log(DEFINE.BeginLogError1); + return; + case EGameflowPhase.InProgress: + Dispose(); + return; + case EGameflowPhase.Reconnect: + client.Reconnect(); + bot.Wait(10000); + Dispose(); + break; + case EGameflowPhase.PreEndOfGame: + bot.Log("Pre-end of game state."); + client.Initialize(); + try + { + client.CreateLobby(gameMode); + } + catch { } + Execute(); + return; + case EGameflowPhase.EndOfGame: + bot.Log("End of game state."); + client.Initialize(); + try + { + client.CreateLobby(gameMode); + } + catch { } + Execute(); + return; + default: + client.CreateLobby(gameMode); + ProcessMatch(); + break; + } + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + private void LimitLevel() + { + try + { + var maxLevel = (int)Configuration.Instance.SettingGame?.maxLevell; + if (maxLevel <= currentPlayer?.summonerLevel) + { + bot.Warn(DEFINE.BeginMaximumLevelLog); + bot.Wait(5000); + Program.Exit(0); + } + } + catch (Exception) { } + } + + private void ProcessMatch() + { + bot.Log(DEFINE.BeginLog1); + bot.Wait(3000); + + ESearchMatchResult result = client.SearchMatch(); + while (result != ESearchMatchResult.Ok) + { + switch (result) + { + case ESearchMatchResult.GatekeeperRestricted: + bot.Warn(DEFINE.BeginLog2); + bot.Wait(30000); + break; + case ESearchMatchResult.QueueNotEnabled: + client.CreateLobby(gameMode); + bot.Warn(DEFINE.BeginLogError2); + bot.Wait(10000); + break; + case ESearchMatchResult.InvalidLobby: + bot.Warn(DEFINE.BeginLogError3); + bot.Wait(10000); + break; + default: + bot.Warn(DEFINE.BeginLogError4); + bot.Wait(10000); + break; + } + + result = client.SearchMatch(); + } + + while (!client.IsMatchFound()) + { + bot.Wait(2000); + } + + bot.Log(DEFINE.BeginLog3); + while (client.GetGameflowPhase() != EGameflowPhase.ChampSelect) + { + client.AcceptMatch(); + bot.Wait(1000); + } + + PickChampion(); + client.PickSkin(currentPlayer); + + bot.Log(DEFINE.BeginLog5); + + client.BringToFont(); + client.CenterScreen(); + + // game.chat.TalkInClient(DEFINE.InGameTalkFirst); + EGameflowPhase currentPhase = client.GetGameflowPhase(); + + while (currentPhase != EGameflowPhase.InProgress) + { + if (currentPhase != EGameflowPhase.ChampSelect) + { + bot.Log(DEFINE.BeginLog6); + ProcessMatch(); + return; + } + bot.Wait(1000); + currentPhase = client.GetGameflowPhase(); + } + Dispose(); + } + + private void PickChampion() + { + if (Enum.TryParse(DEFINE.DefaultChampion, out EChampion champion)) + { + var result1 = client.PickChampion(champion); + switch (result1) + { + case EChampionPickResult.Ok: + bot.Log(string.Format(DEFINE.BeginLog4, champion)); + return; + case EChampionPickResult.ChampionNotOwned: + bot.Warn(DEFINE.BeginLogError6); + break; + case EChampionPickResult.ChampionPicked: + bot.Warn(DEFINE.BeginLogError7); + break; + default: + break; + } + } + + bool picked = false; + int championIndex = 0; + while (!picked) + { + if (championIndex > DEFINE.Champions.Length - 1) + { + bot.Warn(DEFINE.BeginLogError5); + return; + } + EChampionPickResult pickResult = client.PickChampion(DEFINE.Champions[championIndex]); + + switch (pickResult) + { + case EChampionPickResult.Ok: + bot.Log(string.Format(DEFINE.BeginLog4, DEFINE.Champions[championIndex])); + picked = true; + break; + case EChampionPickResult.ChampionNotOwned: + bot.Warn(DEFINE.BeginLogError6); + break; + case EChampionPickResult.ChampionPicked: + bot.Warn(DEFINE.BeginLogError7); + break; + default: + break; + } + + championIndex++; + bot.Wait(1000); + } + } + + public override void Dispose() + { + bot.ExecutePattern("InGame"); + base.Dispose(); + } + } +} diff --git a/Source/Patterns/EndGame.cs b/Source/Patterns/EndGame.cs new file mode 100644 index 0000000..7669209 --- /dev/null +++ b/Source/Patterns/EndGame.cs @@ -0,0 +1,50 @@ +using LeagueAI.Libraries.Helper; +using System; + +namespace LeagueAI.Libraries.Patterns +{ + public class End : BasePatternScript + { + public override void Execute() + { + try + { + bot.Log(DEFINE.EndGameLog2); + Program.GameHandle = IntPtr.Zero; + ChangeInfo(); + client.HonorPlayer(); + client.KillProcessRenderUxClient(); + bot.Wait(5000); + client.WaitClientOpen(); + Dispose(); + } + catch (Exception ex) { Logger.WriteLine(ex); } + } + + public override void Dispose() + { + bot.ExecutePattern("Begin"); + base.Dispose(); + } + + public void ChangeInfo() + { + // Sự kiện sau khi kết thúc game. + Program.GameCount++; + Console.Title = Guid.NewGuid().ToString("N") + " (" + Program.GameCount + " games)"; + Logger.LogToFile(string.Format(DEFINE.EndGameLog, Program.GameCount)); + if ((int)Configuration.Instance.SettingGame.maxGame <= Program.GameCount) + { + Logger.LogToFile(DEFINE.EndMission); + if (int.TryParse((Configuration.Instance.SettingGame?.autoShutdown?.ToString() ?? "0"), + out int autoShutdown) + && autoShutdown == 1) + { + SystemHelper.Shutdown(); + return; + } + Program.Exit(0); + } + } + } +} diff --git a/Source/Patterns/InGame.cs b/Source/Patterns/InGame.cs new file mode 100644 index 0000000..61b4f02 --- /dev/null +++ b/Source/Patterns/InGame.cs @@ -0,0 +1,247 @@ +using LeagueAI.Libraries.Entities; +using LeagueAI.Libraries.Enums; +using LeagueAI.Libraries.Helper; +using LeagueAI.Libraries.Patterns; +using System; +using System.Collections.Generic; + +namespace LeagueAI.Libraries +{ + public class InGame : BasePatternScript + { + private readonly List Items = DEFINE.DefaultItem; + private readonly Random rand = new Random(); + private int AllyIndex { get; set; } + + public InGame() + { + Items = DEFINE.DefaultItem; + rand = new Random(); + } + + public override void Execute() + { + try + { + bot.Log(DEFINE.InGameLog); + + client.Initialize(); + game.SetupHandleGame(); + + bot.Wait(200); + + game.BringGameToFront(); + game.CenterGameToScreen(); + game.WaitGameStart(120); + + if (game.GetSide() == ESideTeam.ORDER) bot.Log(DEFINE.InGameLog4); + else bot.Log(DEFINE.InGameLog5); + + game.BringGameToFront(); + + FollowStrongest(); + GameLoop(); + Dispose(); + } + catch (Exception ex) { Logger.WriteLine(ex); } + Dispose(); + } + + private void GameLoop() + { + var level = 0d; + var followStrongestTime = Environment.TickCount; + + int timeOut; + while (game.IsGameOpen()) + { + if (Environment.TickCount - followStrongestTime >= 60000) + { + Program.GameHandle = HandleExtention.GetGameHandle(""); + game.BringGameToFront(); + game.CenterGameToScreen(); + game.CloseWarning(100); + game.CloseShopIfOpen(100); + + followStrongestTime = Environment.TickCount; + FollowStrongest(); + } + + timeOut = 0; + EGameflowPhase status = client.GetGameflowPhase(); + while (status != EGameflowPhase.InProgress || !game.IsAPIReady()) + { + timeOut += 5000; + bot.Wait(5000); + if (timeOut >= 30000) + { + bot.Warn(DEFINE.InGameLog2); + bot.Wait(5000); + return; + } + status = client.GetGameflowPhase(); + } + + game.BringGameToFront(); + + var newLevel = game.player.GetLevel(); + while (newLevel >= level) + { + game.player.UpgradeSpellOnLevelUp(level++); + bot.Wait(200); + } + + if (game.player.IsDead()) + { + BuyItems(); + continue; + } + + double health = game.player.GetHealthPercent(); + if (0 <= health && health <= 0.35d) + { + game.MoveToSafePlace(); + OnRecall(); + continue; + } + + CastAndMove(); + + if (CanBuy()) + { + game.MoveToSafePlace(); + OnRecall(); + continue; + } + } + } + private void BuyItems() + { + double golds = game.player.GetGolds(); + if (golds < 0) return; + + bot.Wait(300); + game.shop.Toogle(500); + List buyedItem = new List(); + foreach (ItemDto item in Items) + { + bot.Wait(200); + if (item.Cost <= golds + && !item.Buyed) + { + game.shop.SearchItem(item.Name, 40, 200); + game.shop.BuySearchedItem(80); + + double newGold = game.player.GetGolds(); + if (newGold < 0) return; + + if (newGold < golds) golds = newGold; + item.Buyed = true; + buyedItem.Add(item); + } + } + game.shop.Toogle(200); + bot.Wait(200); + } + + private bool CanBuy() + { + double golds = game.player.GetGolds(); + if (golds < 0) return false; + + foreach (ItemDto item in Items) + { + if (item.Cost <= golds && !item.Buyed) return true; + } + return false; + } + + private void OnRecall(int timeWait = 8500) + { + game.player.Recall(timeWait); + BuyItems(); + var health = game.player.GetHealthPercent(); + if (health >= 0d && health <= 0.70d) + { + OnRecall(timeWait); + return; + } + FollowStrongest(); + } + + private void SmartGoToSafePlace() + { + game.MoveToSafePlace(); + for (int i = 0; i < 5; i++) + { + if (!game.FoundEnemy()) break; + game.MoveToSafePlace(); + } + } + + private void SmartRecall(int timeWait = 9000) + { + InputHelper.PressKey("B", 50); + for (int i = 0; i < 9; i++) + { + if (game.FoundEnemy()) + { + game.MoveToSafePlace(4000); + SmartRecall(timeWait); + return; + } + bot.Wait(1000); + } + BuyItems(); + var health = game.player.GetHealthPercent(); + if (health >= 0d && health <= 0.70d) game.player.Recall(timeWait); + } + + private void FollowStrongest() + { + try + { + var newAllyFollow = game.GetAllyIdToFollow(); + if (newAllyFollow >= 1) + { + AllyIndex = newAllyFollow; + game.camera.LockAlly(AllyIndex); + game.camera.PingComing(); + } + } + catch (Exception ex) { Logger.WriteLine(ex, showLog: false); } + } + + private void CastAndMove() + { + try + { + game.MoveRandomCenter(300); + string skills = "QWERDFA"; + var attackSkill = skills[rand.Next(0, skills.Length)]; + game.player.TryCastSpellOnTarget(attackSkill, 800); + } + catch (Exception ex) { Logger.WriteLine(ex, showLog: false); } + } + + private void Attack(int count = 3) + { + try + { + if (count < 0) return; + string skills = "QWERDFA"; + var attackSkill = skills[rand.Next(0, skills.Length)]; + InputHelper.PressKey(System.Windows.Forms.Keys.Space, 150); + game.player.TryCastSpellOnTarget(attackSkill, 800); + Attack(--count); + } + catch (Exception ex) { Logger.WriteLine(ex, showLog: false); } + } + + public override void Dispose() + { + bot.ExecutePattern("End"); + base.Dispose(); + } + } +} diff --git a/Source/Program.cs b/Source/Program.cs new file mode 100644 index 0000000..10fecd1 --- /dev/null +++ b/Source/Program.cs @@ -0,0 +1,320 @@ +using LeagueAI.Libraries.Enums; +using LeagueAI.Libraries.Game; +using LeagueAI.Libraries.Helper; +using System; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace LeagueAI.Libraries +{ + public sealed class Program + { + public static int GameCount { get; set; } = 0; + public static IntPtr ClientHandle { get; private set; } = IntPtr.Zero; + public static IntPtr GameHandle { get; set; } = IntPtr.Zero; + + static Program() + { + Console.OutputEncoding = Encoding.UTF8; + Logger.Initialize(); + ServicePointManager.Expect100Continue = true; + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3; + ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; + } + + public static async Task Main(string[] args) + { + Logger.OnStartup(); + + // Tải tệp tin cấu hình + Configuration.Initialize(); + + Logger.PrintInfo(); + int watch = Environment.TickCount; + Logger.WriteLine(DEFINE.InitSettingLog, EMessageState.PROCESS); + + // Tự cài đặt đường dẫn cấu hình bằng cách đọc tiến trình + AutoSetting(); + + // Khởi tạo giá trị mặc định + byte[] encrypt = new byte[] { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, + 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, + 0x4d, 0x49, 0x49, 0x46, 0x31, 0x54, 0x43, 0x43, 0x41, 0x37, 0x32, 0x67, 0x41, 0x77, + 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, 0x45, 0x52, 0x55, 0x59, 0x68, 0x66, 0x4c, 0x31, + 0x78, 0x75, 0x48, 0x47, 0x65, 0x49, 0x34, 0x4e, 0x2b, 0x42, 0x79, 0x6e, 0x46, 0x4f, + 0x4e, 0x7a, 0x6e, 0x64, 0x77, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, + 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x0a, 0x42, 0x51, 0x41, 0x77, 0x65, + 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, + 0x43, 0x56, 0x6b, 0x34, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56, 0x42, + 0x41, 0x67, 0x4d, 0x43, 0x30, 0x68, 0x68, 0x49, 0x45, 0x35, 0x76, 0x61, 0x53, 0x42, + 0x44, 0x61, 0x58, 0x52, 0x35, 0x4d, 0x52, 0x51, 0x77, 0x45, 0x67, 0x59, 0x44, 0x56, + 0x51, 0x51, 0x48, 0x0a, 0x44, 0x41, 0x74, 0x49, 0x59, 0x53, 0x42, 0x4f, 0x62, 0x32, + 0x6b, 0x67, 0x51, 0x32, 0x6c, 0x30, 0x65, 0x54, 0x45, 0x59, 0x4d, 0x42, 0x59, 0x47, + 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x50, 0x54, 0x6d, 0x56, 0x74, 0x49, 0x46, + 0x4a, 0x68, 0x62, 0x69, 0x42, 0x44, 0x54, 0x79, 0x77, 0x75, 0x54, 0x46, 0x52, 0x45, + 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x0a, 0x44, + 0x41, 0x4a, 0x4a, 0x56, 0x44, 0x45, 0x59, 0x4d, 0x42, 0x59, 0x47, 0x41, 0x31, 0x55, + 0x45, 0x41, 0x77, 0x77, 0x50, 0x54, 0x6d, 0x56, 0x74, 0x49, 0x46, 0x4a, 0x68, 0x62, + 0x69, 0x42, 0x44, 0x54, 0x79, 0x34, 0x73, 0x54, 0x46, 0x52, 0x45, 0x4d, 0x42, 0x34, + 0x58, 0x44, 0x54, 0x49, 0x78, 0x4d, 0x54, 0x45, 0x77, 0x4f, 0x44, 0x41, 0x78, 0x4d, + 0x7a, 0x45, 0x31, 0x4f, 0x56, 0x6f, 0x58, 0x0a, 0x44, 0x54, 0x4d, 0x78, 0x4d, 0x54, + 0x45, 0x77, 0x4e, 0x6a, 0x41, 0x78, 0x4d, 0x7a, 0x45, 0x31, 0x4f, 0x56, 0x6f, 0x77, + 0x65, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, + 0x4d, 0x43, 0x56, 0x6b, 0x34, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56, + 0x42, 0x41, 0x67, 0x4d, 0x43, 0x30, 0x68, 0x68, 0x49, 0x45, 0x35, 0x76, 0x61, 0x53, + 0x42, 0x44, 0x0a, 0x61, 0x58, 0x52, 0x35, 0x4d, 0x52, 0x51, 0x77, 0x45, 0x67, 0x59, + 0x44, 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x74, 0x49, 0x59, 0x53, 0x42, 0x4f, 0x62, + 0x32, 0x6b, 0x67, 0x51, 0x32, 0x6c, 0x30, 0x65, 0x54, 0x45, 0x59, 0x4d, 0x42, 0x59, + 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x50, 0x54, 0x6d, 0x56, 0x74, 0x49, + 0x46, 0x4a, 0x68, 0x62, 0x69, 0x42, 0x44, 0x54, 0x79, 0x77, 0x75, 0x0a, 0x54, 0x46, + 0x52, 0x45, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, + 0x44, 0x41, 0x4a, 0x4a, 0x56, 0x44, 0x45, 0x59, 0x4d, 0x42, 0x59, 0x47, 0x41, 0x31, + 0x55, 0x45, 0x41, 0x77, 0x77, 0x50, 0x54, 0x6d, 0x56, 0x74, 0x49, 0x46, 0x4a, 0x68, + 0x62, 0x69, 0x42, 0x44, 0x54, 0x79, 0x34, 0x73, 0x54, 0x46, 0x52, 0x45, 0x4d, 0x49, + 0x49, 0x43, 0x49, 0x6a, 0x41, 0x4e, 0x0a, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, + 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, + 0x67, 0x38, 0x41, 0x4d, 0x49, 0x49, 0x43, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x67, 0x45, + 0x41, 0x7a, 0x4d, 0x69, 0x33, 0x58, 0x51, 0x54, 0x70, 0x6b, 0x68, 0x55, 0x65, 0x78, + 0x38, 0x75, 0x42, 0x7a, 0x69, 0x6f, 0x61, 0x63, 0x36, 0x67, 0x6a, 0x56, 0x61, 0x37, + 0x52, 0x0a, 0x46, 0x54, 0x67, 0x37, 0x62, 0x63, 0x71, 0x4b, 0x55, 0x54, 0x45, 0x47, + 0x42, 0x4b, 0x5a, 0x56, 0x30, 0x59, 0x72, 0x58, 0x70, 0x63, 0x66, 0x31, 0x46, 0x68, + 0x70, 0x78, 0x43, 0x66, 0x71, 0x37, 0x33, 0x71, 0x37, 0x70, 0x7a, 0x78, 0x34, 0x6c, + 0x41, 0x78, 0x38, 0x64, 0x7a, 0x33, 0x6f, 0x72, 0x4a, 0x4e, 0x6f, 0x64, 0x6b, 0x41, + 0x75, 0x57, 0x4d, 0x69, 0x2b, 0x69, 0x57, 0x33, 0x6d, 0x6b, 0x0a, 0x31, 0x44, 0x68, + 0x50, 0x63, 0x79, 0x5a, 0x35, 0x71, 0x71, 0x54, 0x62, 0x6c, 0x63, 0x70, 0x79, 0x47, + 0x35, 0x4f, 0x6a, 0x35, 0x36, 0x59, 0x4c, 0x75, 0x43, 0x6a, 0x33, 0x2f, 0x36, 0x74, + 0x31, 0x6a, 0x5a, 0x66, 0x50, 0x4d, 0x35, 0x53, 0x69, 0x50, 0x33, 0x58, 0x52, 0x61, + 0x72, 0x75, 0x55, 0x43, 0x31, 0x4d, 0x58, 0x36, 0x35, 0x69, 0x6e, 0x74, 0x78, 0x5a, + 0x35, 0x2b, 0x70, 0x79, 0x72, 0x0a, 0x75, 0x71, 0x67, 0x76, 0x74, 0x67, 0x43, 0x39, + 0x39, 0x32, 0x71, 0x38, 0x59, 0x37, 0x66, 0x6c, 0x6f, 0x72, 0x34, 0x54, 0x35, 0x2b, + 0x6c, 0x38, 0x75, 0x66, 0x37, 0x61, 0x67, 0x53, 0x48, 0x78, 0x50, 0x49, 0x31, 0x4e, + 0x36, 0x2b, 0x67, 0x51, 0x41, 0x31, 0x38, 0x4e, 0x50, 0x2f, 0x78, 0x64, 0x55, 0x31, + 0x34, 0x4c, 0x77, 0x62, 0x2f, 0x76, 0x64, 0x37, 0x73, 0x2b, 0x2f, 0x32, 0x65, 0x61, + 0x0a, 0x65, 0x66, 0x4b, 0x45, 0x31, 0x6f, 0x35, 0x41, 0x4f, 0x53, 0x35, 0x47, 0x4d, + 0x4c, 0x6e, 0x77, 0x75, 0x6f, 0x44, 0x55, 0x43, 0x44, 0x68, 0x71, 0x5a, 0x35, 0x72, + 0x4f, 0x45, 0x6e, 0x36, 0x41, 0x36, 0x6e, 0x52, 0x48, 0x59, 0x59, 0x7a, 0x78, 0x6c, + 0x75, 0x52, 0x6e, 0x57, 0x58, 0x2f, 0x36, 0x66, 0x62, 0x77, 0x47, 0x35, 0x64, 0x5a, + 0x61, 0x49, 0x4a, 0x39, 0x45, 0x43, 0x45, 0x6c, 0x58, 0x0a, 0x49, 0x4f, 0x76, 0x33, + 0x63, 0x44, 0x38, 0x7a, 0x79, 0x50, 0x7a, 0x33, 0x63, 0x32, 0x37, 0x48, 0x30, 0x66, + 0x39, 0x59, 0x2b, 0x6e, 0x62, 0x36, 0x44, 0x62, 0x30, 0x31, 0x4d, 0x6e, 0x58, 0x30, + 0x4a, 0x68, 0x70, 0x39, 0x48, 0x69, 0x69, 0x44, 0x48, 0x4e, 0x6a, 0x78, 0x43, 0x4b, + 0x50, 0x47, 0x6a, 0x63, 0x6f, 0x4f, 0x69, 0x78, 0x51, 0x4b, 0x57, 0x2f, 0x61, 0x31, + 0x4b, 0x4f, 0x34, 0x39, 0x0a, 0x37, 0x30, 0x46, 0x67, 0x54, 0x53, 0x52, 0x6c, 0x2f, + 0x6c, 0x64, 0x76, 0x33, 0x56, 0x73, 0x66, 0x7a, 0x65, 0x6f, 0x2f, 0x4d, 0x37, 0x7a, + 0x4e, 0x44, 0x61, 0x4e, 0x38, 0x36, 0x37, 0x31, 0x64, 0x69, 0x43, 0x61, 0x52, 0x56, + 0x36, 0x6e, 0x42, 0x6a, 0x6a, 0x74, 0x69, 0x51, 0x53, 0x70, 0x63, 0x52, 0x51, 0x30, + 0x59, 0x31, 0x6a, 0x55, 0x43, 0x55, 0x5a, 0x41, 0x2b, 0x2b, 0x64, 0x2f, 0x74, 0x0a, + 0x72, 0x4d, 0x41, 0x39, 0x4e, 0x35, 0x58, 0x44, 0x77, 0x31, 0x61, 0x70, 0x47, 0x43, + 0x41, 0x71, 0x57, 0x33, 0x71, 0x42, 0x4e, 0x4e, 0x55, 0x68, 0x38, 0x48, 0x6a, 0x6a, + 0x48, 0x36, 0x6e, 0x69, 0x76, 0x6f, 0x2f, 0x76, 0x36, 0x30, 0x77, 0x76, 0x39, 0x61, + 0x30, 0x59, 0x56, 0x78, 0x68, 0x33, 0x59, 0x65, 0x2b, 0x61, 0x4f, 0x64, 0x53, 0x43, + 0x2b, 0x48, 0x50, 0x67, 0x69, 0x72, 0x51, 0x49, 0x0a, 0x4d, 0x33, 0x32, 0x31, 0x71, + 0x6a, 0x30, 0x4c, 0x4b, 0x38, 0x65, 0x63, 0x2b, 0x51, 0x79, 0x69, 0x59, 0x46, 0x4a, + 0x67, 0x52, 0x68, 0x76, 0x75, 0x37, 0x77, 0x71, 0x53, 0x48, 0x75, 0x47, 0x73, 0x52, + 0x79, 0x43, 0x79, 0x69, 0x37, 0x32, 0x51, 0x33, 0x33, 0x76, 0x4f, 0x72, 0x35, 0x57, + 0x33, 0x58, 0x74, 0x66, 0x45, 0x2b, 0x7a, 0x58, 0x52, 0x32, 0x4d, 0x4b, 0x64, 0x74, + 0x68, 0x46, 0x4e, 0x0a, 0x58, 0x2b, 0x76, 0x42, 0x46, 0x6e, 0x36, 0x57, 0x4b, 0x64, + 0x4c, 0x39, 0x56, 0x51, 0x63, 0x4e, 0x44, 0x6a, 0x63, 0x38, 0x64, 0x50, 0x46, 0x51, + 0x52, 0x4d, 0x42, 0x45, 0x43, 0x48, 0x76, 0x50, 0x43, 0x46, 0x71, 0x42, 0x41, 0x32, + 0x4e, 0x57, 0x4d, 0x36, 0x6c, 0x36, 0x6b, 0x63, 0x50, 0x48, 0x2f, 0x65, 0x4e, 0x44, + 0x4c, 0x56, 0x47, 0x6d, 0x63, 0x73, 0x55, 0x46, 0x51, 0x6a, 0x32, 0x2f, 0x0a, 0x5a, + 0x4c, 0x66, 0x43, 0x51, 0x7a, 0x65, 0x38, 0x58, 0x79, 0x31, 0x79, 0x77, 0x77, 0x62, + 0x71, 0x6d, 0x4f, 0x69, 0x58, 0x38, 0x51, 0x6f, 0x74, 0x61, 0x48, 0x31, 0x6b, 0x78, + 0x33, 0x65, 0x78, 0x42, 0x38, 0x4c, 0x46, 0x56, 0x52, 0x6f, 0x41, 0x36, 0x4b, 0x61, + 0x30, 0x6c, 0x31, 0x77, 0x70, 0x78, 0x2f, 0x69, 0x37, 0x58, 0x6c, 0x58, 0x64, 0x56, + 0x74, 0x6a, 0x72, 0x77, 0x4a, 0x54, 0x61, 0x0a, 0x64, 0x6d, 0x6c, 0x42, 0x6f, 0x59, + 0x37, 0x71, 0x74, 0x67, 0x79, 0x45, 0x64, 0x45, 0x63, 0x43, 0x41, 0x77, 0x45, 0x41, + 0x41, 0x61, 0x4e, 0x54, 0x4d, 0x46, 0x45, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, 0x52, + 0x30, 0x4f, 0x42, 0x42, 0x59, 0x45, 0x46, 0x50, 0x6f, 0x65, 0x4f, 0x7a, 0x6d, 0x38, + 0x41, 0x56, 0x38, 0x6c, 0x31, 0x51, 0x50, 0x73, 0x37, 0x48, 0x44, 0x53, 0x34, 0x71, + 0x34, 0x56, 0x0a, 0x30, 0x55, 0x6f, 0x54, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, + 0x64, 0x49, 0x77, 0x51, 0x59, 0x4d, 0x42, 0x61, 0x41, 0x46, 0x50, 0x6f, 0x65, 0x4f, + 0x7a, 0x6d, 0x38, 0x41, 0x56, 0x38, 0x6c, 0x31, 0x51, 0x50, 0x73, 0x37, 0x48, 0x44, + 0x53, 0x34, 0x71, 0x34, 0x56, 0x30, 0x55, 0x6f, 0x54, 0x4d, 0x41, 0x38, 0x47, 0x41, + 0x31, 0x55, 0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x46, 0x0a, 0x4d, 0x41, + 0x4d, 0x42, 0x41, 0x66, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, + 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, + 0x49, 0x42, 0x41, 0x44, 0x32, 0x4f, 0x69, 0x5a, 0x72, 0x53, 0x73, 0x57, 0x69, 0x35, + 0x46, 0x39, 0x4b, 0x56, 0x2f, 0x71, 0x75, 0x68, 0x69, 0x47, 0x6b, 0x48, 0x63, 0x58, + 0x6b, 0x34, 0x62, 0x79, 0x70, 0x47, 0x0a, 0x78, 0x53, 0x49, 0x61, 0x7a, 0x2f, 0x39, + 0x54, 0x56, 0x58, 0x35, 0x59, 0x69, 0x6a, 0x6b, 0x53, 0x4e, 0x32, 0x59, 0x78, 0x72, + 0x54, 0x57, 0x67, 0x36, 0x64, 0x53, 0x51, 0x67, 0x52, 0x5a, 0x47, 0x58, 0x32, 0x49, + 0x70, 0x48, 0x73, 0x65, 0x43, 0x46, 0x46, 0x76, 0x46, 0x49, 0x30, 0x64, 0x74, 0x68, + 0x48, 0x68, 0x37, 0x4f, 0x61, 0x6a, 0x78, 0x5a, 0x71, 0x78, 0x4e, 0x7a, 0x52, 0x74, + 0x6d, 0x0a, 0x54, 0x6b, 0x72, 0x44, 0x35, 0x51, 0x45, 0x69, 0x59, 0x31, 0x68, 0x76, + 0x76, 0x37, 0x79, 0x7a, 0x4f, 0x70, 0x39, 0x49, 0x4f, 0x53, 0x36, 0x50, 0x64, 0x61, + 0x66, 0x57, 0x31, 0x62, 0x50, 0x43, 0x31, 0x78, 0x6b, 0x45, 0x5a, 0x68, 0x78, 0x55, + 0x6c, 0x34, 0x74, 0x70, 0x45, 0x2f, 0x31, 0x69, 0x57, 0x32, 0x72, 0x67, 0x6b, 0x61, + 0x66, 0x2f, 0x4e, 0x74, 0x77, 0x68, 0x2b, 0x64, 0x4a, 0x75, 0x0a, 0x2f, 0x2f, 0x62, + 0x57, 0x30, 0x6e, 0x47, 0x32, 0x48, 0x59, 0x65, 0x6d, 0x68, 0x38, 0x79, 0x67, 0x54, + 0x76, 0x61, 0x67, 0x48, 0x76, 0x37, 0x37, 0x4c, 0x70, 0x53, 0x30, 0x63, 0x50, 0x75, + 0x5a, 0x32, 0x43, 0x6b, 0x54, 0x70, 0x2b, 0x57, 0x2b, 0x77, 0x59, 0x46, 0x59, 0x59, + 0x71, 0x6a, 0x58, 0x44, 0x54, 0x2f, 0x6a, 0x56, 0x70, 0x38, 0x6d, 0x52, 0x52, 0x57, + 0x36, 0x55, 0x4b, 0x62, 0x65, 0x0a, 0x53, 0x4f, 0x56, 0x4b, 0x30, 0x52, 0x37, 0x4f, + 0x6e, 0x46, 0x34, 0x6f, 0x6d, 0x41, 0x6c, 0x66, 0x56, 0x32, 0x62, 0x53, 0x78, 0x34, + 0x32, 0x4e, 0x77, 0x6c, 0x55, 0x65, 0x32, 0x49, 0x41, 0x77, 0x67, 0x2f, 0x39, 0x5a, + 0x70, 0x78, 0x77, 0x43, 0x71, 0x6b, 0x69, 0x30, 0x48, 0x4f, 0x72, 0x32, 0x5a, 0x30, + 0x31, 0x45, 0x49, 0x75, 0x42, 0x34, 0x56, 0x52, 0x74, 0x58, 0x32, 0x6f, 0x65, 0x37, + 0x0a, 0x62, 0x34, 0x51, 0x77, 0x30, 0x30, 0x7a, 0x75, 0x6d, 0x2b, 0x44, 0x68, 0x66, + 0x4e, 0x54, 0x41, 0x76, 0x6b, 0x52, 0x61, 0x63, 0x33, 0x58, 0x4f, 0x46, 0x4b, 0x64, + 0x2f, 0x39, 0x49, 0x4e, 0x70, 0x57, 0x31, 0x4b, 0x32, 0x31, 0x57, 0x58, 0x35, 0x64, + 0x48, 0x4c, 0x59, 0x66, 0x65, 0x61, 0x68, 0x6a, 0x4e, 0x6d, 0x49, 0x44, 0x4c, 0x38, + 0x6d, 0x71, 0x48, 0x33, 0x56, 0x56, 0x57, 0x44, 0x6f, 0x0a, 0x46, 0x2b, 0x36, 0x33, + 0x51, 0x53, 0x50, 0x32, 0x54, 0x66, 0x2f, 0x35, 0x44, 0x64, 0x74, 0x2f, 0x4c, 0x67, + 0x37, 0x7a, 0x6b, 0x30, 0x55, 0x79, 0x42, 0x32, 0x6c, 0x73, 0x49, 0x66, 0x68, 0x73, + 0x54, 0x43, 0x4b, 0x74, 0x41, 0x72, 0x33, 0x58, 0x43, 0x62, 0x51, 0x4e, 0x69, 0x77, + 0x6e, 0x6b, 0x32, 0x6c, 0x32, 0x43, 0x63, 0x70, 0x51, 0x6a, 0x30, 0x4c, 0x30, 0x42, + 0x33, 0x54, 0x6b, 0x50, 0x0a, 0x41, 0x61, 0x36, 0x31, 0x6f, 0x57, 0x66, 0x5a, 0x34, + 0x4d, 0x52, 0x6e, 0x39, 0x45, 0x74, 0x61, 0x7a, 0x61, 0x73, 0x79, 0x6d, 0x6f, 0x42, + 0x6e, 0x38, 0x2f, 0x53, 0x71, 0x66, 0x48, 0x4a, 0x66, 0x2f, 0x38, 0x67, 0x4b, 0x61, + 0x47, 0x31, 0x2b, 0x66, 0x35, 0x39, 0x49, 0x54, 0x6c, 0x66, 0x77, 0x74, 0x61, 0x77, + 0x54, 0x48, 0x72, 0x39, 0x61, 0x47, 0x4c, 0x57, 0x4c, 0x56, 0x79, 0x4e, 0x57, 0x0a, + 0x5a, 0x41, 0x47, 0x47, 0x55, 0x72, 0x4a, 0x71, 0x78, 0x53, 0x7a, 0x53, 0x34, 0x46, + 0x37, 0x4f, 0x32, 0x33, 0x66, 0x53, 0x73, 0x55, 0x4c, 0x53, 0x61, 0x50, 0x35, 0x41, + 0x57, 0x46, 0x4d, 0x44, 0x69, 0x62, 0x72, 0x37, 0x43, 0x4f, 0x76, 0x36, 0x31, 0x75, + 0x79, 0x65, 0x54, 0x38, 0x4d, 0x6c, 0x77, 0x4f, 0x5a, 0x36, 0x48, 0x64, 0x4e, 0x32, + 0x42, 0x6b, 0x6f, 0x6c, 0x2b, 0x6f, 0x65, 0x33, 0x0a, 0x4e, 0x79, 0x69, 0x75, 0x45, + 0x6b, 0x4f, 0x67, 0x2f, 0x6e, 0x38, 0x57, 0x52, 0x48, 0x4f, 0x37, 0x37, 0x6f, 0x53, + 0x45, 0x4e, 0x6e, 0x73, 0x49, 0x4f, 0x38, 0x30, 0x42, 0x50, 0x76, 0x6f, 0x73, 0x4a, + 0x4e, 0x61, 0x68, 0x6b, 0x6c, 0x41, 0x49, 0x59, 0x42, 0x5a, 0x71, 0x61, 0x68, 0x4b, + 0x50, 0x65, 0x50, 0x36, 0x35, 0x30, 0x50, 0x7a, 0x39, 0x45, 0x31, 0x41, 0x4d, 0x65, + 0x36, 0x36, 0x46, 0x0a, 0x69, 0x32, 0x48, 0x4b, 0x37, 0x32, 0x66, 0x4d, 0x6a, 0x59, + 0x59, 0x2f, 0x32, 0x4c, 0x4a, 0x74, 0x73, 0x59, 0x34, 0x4c, 0x4e, 0x63, 0x49, 0x64, + 0x55, 0x2b, 0x37, 0x64, 0x44, 0x71, 0x32, 0x33, 0x62, 0x6a, 0x43, 0x32, 0x35, 0x69, + 0x65, 0x56, 0x38, 0x4a, 0x35, 0x4a, 0x72, 0x47, 0x72, 0x33, 0x55, 0x6f, 0x77, 0x31, + 0x57, 0x69, 0x4b, 0x6a, 0x6d, 0x52, 0x39, 0x56, 0x2b, 0x56, 0x6a, 0x34, 0x0a, 0x70, + 0x64, 0x38, 0x4c, 0x2f, 0x6d, 0x62, 0x38, 0x2b, 0x30, 0x75, 0x30, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, + 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d + }; + X509Certificate2 certificate = new X509Certificate2(encrypt); + RSA publicKey = certificate.GetRSAPublicKey(); + + Logger.WriteLine($"** {DEFINE.FinishSettingLog} (" + (Environment.TickCount - watch) + "ms) **", EMessageState.SUCCES); + + try + { + if (!await InsertCertificates(certificate)) + { + Logger.WriteLine(DEFINE.TrustCerLog); + Program.Exit(1); + } + // Nạp nội dung config, pattern + StartupManager.Initialize(Assembly.GetExecutingAssembly()); + UserInterfaces(); + Program.Exit(0); + } + catch (Exception e) + { + Logger.WriteLine(e); + } + Program.Exit(1); + return 1; + } + + public static void AutoSetting() + { + try + { + if (bool.TryParse(Configuration.Instance.SettingGame?.autoConfig?.ToString(), out bool autoConfig) + && !autoConfig) return; + + // Đọc tiến trình, nếu không có tiến trình client thì thoát + var openProcess = HandleExtention.GetOpenWindows(); + ClientHandle = openProcess.FirstOrDefault(m => m.Value.Contains(DEFINE.ClientExecutableName)).Key; + if (ClientHandle == null || ClientHandle == IntPtr.Zero) + { + Logger.WriteLine(DEFINE.NotOpenGameClientYetLog, EMessageState.WARNING); + Program.Exit(1); + } + + // nếu không phải là tiến trình 64bit thì bỏ qua. + if (IntPtr.Size != 8) return; + + Logger.WriteLine($"DefaultLeaguePath: [{Configuration.Instance.DefaultLeaguePath}]"); + Logger.WriteLine($"ClientExecutablePath: [{Configuration.Instance.ClientExecutablePath}]"); + Logger.WriteLine($"LockfilePath: [{Configuration.Instance.LockfilePath}]"); + Logger.WriteLine($"LeagueGameconfigPath: [{Configuration.Instance.LeagueGameconfigPath}]"); + Logger.WriteLine($"LeaguePersistedSettingsPath: [{Configuration.Instance.LeaguePersistedSettingsPath}]"); + } + catch (Exception e) + { + Logger.WriteLine(e); + } + } + + private static void UserInterfaces(int timeout = 90) + { + if (bool.TryParse(Configuration.Instance.SettingGame?.autoDetectStateGame?.ToString() ?? "true", out bool autoDetectStateGame) + && autoDetectStateGame) + { + ClientLCU.Initialize(); + + if (GameLCU.IsApiReady()) // nếu api trong game khả dụng -> chạy pattern trong game + { + string pattern = PatternsUlti.ScriptsPattern?.FirstOrDefault(m => m.ToLower().Contains("ingame")); + PatternsUlti.Execute(pattern); + UserInterfaces(); + return; + } + + if (ClientLCU.IsApiReady()) // nếu api trong game không khả dụng và api client khả dụng -> tạo trận chơi ngay + { + string pattern = PatternsUlti.ScriptsPattern?.FirstOrDefault(m => m.ToLower().Contains("begin")); + PatternsUlti.Execute(pattern); + UserInterfaces(); + return; + } + + Logger.WriteLine(string.Format(DEFINE.WaitGameLog, timeout)); + Thread.Sleep(TimeSpan.FromSeconds(30)); + timeout -= 30; + if (timeout <= 0) + { + Logger.WriteLine(DEFINE.NotOpenGameClientYetLog); + Program.Exit(1); + } + + UserInterfaces(timeout); + return; + } + Program.Exit(1); + } + + public static void Exit(int code, bool forceExit = false) + { + if (code != 0 && !forceExit) + { + Console.ReadKey(); + } + Environment.Exit(code); + } + + public static Task InsertCertificates( + X509Certificate2 certificate + ) + { + // Chứng chỉ tin cậy vào máy người dùng + return Task.Run(() => + { + try + { + X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine); + store.Open(OpenFlags.ReadWrite); + store.Add(certificate); + store.Close(); + return true; + } + catch (Exception) { } + return false; + }); + } + } +} diff --git a/Source/Properties/AssemblyInfo.cs b/Source/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4644efc --- /dev/null +++ b/Source/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("LeagueAI.Libraries")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("LeagueAI.Libraries")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e2ba0d27-eade-4c89-83c1-47bce629fb54")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Source/Properties/Resources.Designer.cs b/Source/Properties/Resources.Designer.cs new file mode 100644 index 0000000..a778839 --- /dev/null +++ b/Source/Properties/Resources.Designer.cs @@ -0,0 +1,93 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace LeagueAI.Libraries.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LeagueAI.Libraries.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] InputManager { + get { + object obj = ResourceManager.GetObject("InputManager", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Leaf_xNet { + get { + object obj = ResourceManager.GetObject("Leaf_xNet", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Newtonsoft_Json { + get { + object obj = ResourceManager.GetObject("Newtonsoft_Json", resourceCulture); + return ((byte[])(obj)); + } + } + } +} diff --git a/Source/Properties/Resources.resx b/Source/Properties/Resources.resx new file mode 100644 index 0000000..d641d3c --- /dev/null +++ b/Source/Properties/Resources.resx @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\InputManager.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Leaf.xNet.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Newtonsoft.Json.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Source/Resources/InputManager.dll b/Source/Resources/InputManager.dll new file mode 100644 index 0000000..0a14718 Binary files /dev/null and b/Source/Resources/InputManager.dll differ diff --git a/Source/Resources/Leaf.xNet.dll b/Source/Resources/Leaf.xNet.dll new file mode 100644 index 0000000..e92c3a2 Binary files /dev/null and b/Source/Resources/Leaf.xNet.dll differ diff --git a/Source/Resources/Newtonsoft.Json.dll b/Source/Resources/Newtonsoft.Json.dll new file mode 100644 index 0000000..7af125a Binary files /dev/null and b/Source/Resources/Newtonsoft.Json.dll differ diff --git a/Source/hextech.ico b/Source/hextech.ico new file mode 100644 index 0000000..25ade74 Binary files /dev/null and b/Source/hextech.ico differ