diff --git a/hypnonema.db b/hypnonema.db index 498b87b36..af17a62ef 100644 Binary files a/hypnonema.db and b/hypnonema.db differ diff --git a/resources/Fire-Script/whitelist.json b/resources/Fire-Script/whitelist.json index 6dbcc3bfb..aa94f7298 100644 --- a/resources/Fire-Script/whitelist.json +++ b/resources/Fire-Script/whitelist.json @@ -1 +1 @@ -{"steam:110000112db6102":true,"steam:110000147619e76":true,"steam:110000131ff8eae":true,"steam:11000010e6980a7":true} \ No newline at end of file +{"steam:110000112db6102":true,"steam:110000147619e76":true,"steam:110000131ff8eae":true,"steam:11000010e6980a7":true,"steam:11000013c64f700":true} \ No newline at end of file diff --git a/resources/Interaction-Menu/.gitignore b/resources/Interaction-Menu/.gitignore new file mode 100644 index 000000000..6fd0a376d --- /dev/null +++ b/resources/Interaction-Menu/.gitignore @@ -0,0 +1,41 @@ +# Compiled Lua sources +luac.out + +# luarocks build files +*.src.rock +*.zip +*.tar.gz + +# Object files +*.o +*.os +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo +*.def +*.exp + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + diff --git a/resources/Interaction-Menu/LICENSE b/resources/Interaction-Menu/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/resources/Interaction-Menu/LICENSE @@ -0,0 +1,674 @@ + 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 +. diff --git a/resources/Interaction-Menu/README.md b/resources/Interaction-Menu/README.md new file mode 100644 index 000000000..eb98e6a91 --- /dev/null +++ b/resources/Interaction-Menu/README.md @@ -0,0 +1,30 @@ +[![Discord](https://semdevelopment.com/img/discord.png)](https://semdevelopment.com/discord) + +# SEM_InteractionMenu +*Multi Purpose FiveM Interaction Menu* + +This resource is a menu with actions for LEO, Fire and Civ including Vehicle Controls and Emotes! + +Each section has features that would be used by each of the professions, for example the LEO Menu has Cuff, Drag, Seat, etc. +Some menu features also have commands out of ease during RP. + +SEM_InteractionMenu was created using NativeUI [LUA] + + +### Information: +Current Version: **v1.7.1** + +Changes: **• Fixes menu item skipping** + +**THIS UPDATE *ONLY* AFFECTS THE DEPENDENCY NATIVEUI - YOU CAN JUST UPDATE THAT FILE *(NO OTHER FILES WERE CHANGED!)*** + + +### Links: + +Support/Discord: [Click Here](https://semdevelopment.com/discord) + +Information: [Click Here](https://semdevelopment.com/releases/interactionmenu) + +Instruction/Docs: [Click here](https://semdevelopment.com/releases/interactionmenu/docs) + +*For full changes checkout [here](https://semdevelopment.com/releases/interactionmenu/docs/changelog)* diff --git a/resources/Interaction-Menu/client.lua b/resources/Interaction-Menu/client.lua new file mode 100644 index 000000000..12f8e1f6d --- /dev/null +++ b/resources/Interaction-Menu/client.lua @@ -0,0 +1,898 @@ +--[[ +────────────────────────────────────────────────────────────── + + SEM_InteractionMenu (client.lua) - Created by Scott M + Current Version: v1.7.1 (Sep 2021) + + Support: https://semdevelopment.com/discord + + !!! Change vaules in the 'config.lua' !!! + DO NOT EDIT THIS IF YOU DON'T KNOW WHAT YOU ARE DOING + +────────────────────────────────────────────────────────────── +]] + + + +--Cuffing Event +local isCuffed = false +RegisterNetEvent('SEM_InteractionMenu:Cuff') +AddEventHandler('SEM_InteractionMenu:Cuff', function() + local Ped = PlayerPedId() + if (DoesEntityExist(Ped)) then + Citizen.CreateThread(function() + RequestAnimDict('mp_arresting') + while not HasAnimDictLoaded('mp_arresting') do + Citizen.Wait(0) + end + + if isCuffed then + isCuffed = false + Citizen.Wait(500) + SetEnableHandcuffs(Ped, false) + ClearPedTasksImmediately(Ped) + else + isCuffed = true + SetEnableHandcuffs(Ped, true) + TaskPlayAnim(Ped, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0) + end + end) + end +end) + +--Cuff Animation & Restructions +Citizen.CreateThread(function() + while true do + Citizen.Wait(1) + + if isCuffed then + if not IsEntityPlayingAnim(GetPlayerPed(PlayerId()), 'mp_arresting', 'idle', 3) then + TaskPlayAnim(GetPlayerPed(PlayerId()), 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0) + end + + SetCurrentPedWeapon(PlayerPedId(), 'weapon_unarmed', true) + + if not Config.VehEnterCuffed then + DisableControlAction(1, 23, true) --F | Enter Vehicle + DisableControlAction(1, 75, true) --F | Exit Vehicle + end + DisableControlAction(1, 140, true) --R + DisableControlAction(1, 141, true) --Q + DisableControlAction(1, 142, true) --LMB + SetPedPathCanUseLadders(GetPlayerPed(PlayerId()), false) + if IsPedInAnyVehicle(GetPlayerPed(PlayerId()), false) then + DisableControlAction(0, 59, true) --Vehicle Driving + end + end + end +end) + + + +--Dragging Event +local Drag = false +local OfficerDrag = -1 +RegisterNetEvent('SEM_InteractionMenu:Drag') +AddEventHandler('SEM_InteractionMenu:Drag', function(ID) + Drag = not Drag + OfficerDrag = ID + + if not Drag then + DetachEntity(PlayerPedId(), true, false) + end +end) + +--Drag Attachment +Citizen.CreateThread(function() + while true do + Citizen.Wait(1) + + if Drag then + local Ped = GetPlayerPed(GetPlayerFromServerId(OfficerDrag)) + local Ped2 = PlayerPedId() + AttachEntityToEntity(Ped2, Ped, 4103, 0.35, 0.38, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true) + DisableControlAction(1, 140, true) --R + DisableControlAction(1, 141, true) --Q + DisableControlAction(1, 142, true) --LMB + end + end +end) + + + +--Force Seat Player Event +RegisterNetEvent('SEM_InteractionMenu:Seat') +AddEventHandler('SEM_InteractionMenu:Seat', function(Veh) + local Pos = GetEntityCoords(PlayerPedId()) + local EntityWorld = GetOffsetFromEntityInWorldCoords(PlayerPedId(), 0.0, 20.0, 0.0) + local RayHandle = CastRayPointToPoint(Pos.x, Pos.y, Pos.z, EntityWorld.x, EntityWorld.y, EntityWorld.z, 10, PlayerPedId(), 0) + local _, _, _, _, VehicleHandle = GetRaycastResult(RayHandle) + if VehicleHandle ~= nil then + SetPedIntoVehicle(PlayerPedId(), VehicleHandle, 1) + end +end) + + + +--Force Unseat Player Event +RegisterNetEvent('SEM_InteractionMenu:Unseat') +AddEventHandler('SEM_InteractionMenu:Unseat', function(ID) + local Ped = GetPlayerPed(ID) + ClearPedTasksImmediately(Ped) + PlayerPos = GetEntityCoords(PlayerPedId(), true) + local X = PlayerPos.x - 0 + local Y = PlayerPos.y - 0 + + SetEntityCoords(PlayerPedId(), X, Y, PlayerPos.z) +end) + + + +--Spike Strip Spawn Event +local SpawnedSpikes = {} +RegisterNetEvent('SEM_InteractionMenu:Spikes-SpawnSpikes') +AddEventHandler('SEM_InteractionMenu:Spikes-SpawnSpikes', function(Length) + if IsPedInAnyVehicle(PlayerPedId(), false) then + Notify('~r~You can\'t set spikes while in a vehicle!') + return + end + + local SpawnCoords = GetOffsetFromEntityInWorldCoords(GetPlayerPed(PlayerId()) , 0.0, 2.0, 0.0) + for a = 1, Length do + local Spike = CreateObject(GetHashKey('P_ld_stinger_s'), SpawnCoords.x, SpawnCoords.y, SpawnCoords.z, 1, 1, 1) + local NetID = NetworkGetNetworkIdFromEntity(Spike) + SetNetworkIdExistsOnAllMachines(NetID, true) + SetNetworkIdCanMigrate(NetID, false) + SetEntityHeading(Spike, GetEntityHeading(GetPlayerPed(PlayerId()) )) + PlaceObjectOnGroundProperly(Spike) + FreezeEntityPosition(Spike, true) + SpawnCoords = GetOffsetFromEntityInWorldCoords(Spike, 0.0, 4.0, 0.0) + table.insert(SpawnedSpikes, NetID) + end +end) + +--Spike Strip Delete Event +RegisterNetEvent('SEM_InteractionMenu:Spikes-DeleteSpikes') +AddEventHandler('SEM_InteractionMenu:Spikes-DeleteSpikes', function() + for a = 1, #SpawnedSpikes do + local Spike = NetworkGetEntityFromNetworkId(SpawnedSpikes[a]) + DeleteEntity(Spike) + end + Notify('~r~Spikes Strips Removed!') + SpawnedSpikes = {} +end) + +--Spike Strip Tire Popping +Citizen.CreateThread(function() + while true do + Citizen.Wait(25) + + if IsPedInAnyVehicle(PlayerPedId() , false) then + local Vehicle = GetVehiclePedIsIn(PlayerPedId() , false) + + if GetPedInVehicleSeat(Vehicle, -1) == PlayerPedId() then + local VehiclePos = GetEntityCoords(Vehicle, false) + local Spike = GetClosestObjectOfType(VehiclePos.x, VehiclePos.y, VehiclePos.z, 2.0, GetHashKey('P_ld_stinger_s'), 1, 1, 1) + + if Spike ~= 0 then + local Tires = { + {bone = 'wheel_lf', index = 0}, + {bone = 'wheel_rf', index = 1}, + {bone = 'wheel_lm', index = 2}, + {bone = 'wheel_rm', index = 3}, + {bone = 'wheel_lr', index = 4}, + {bone = 'wheel_rr', index = 5} + } + + for a = 1, #Tires do + local TirePos = GetWorldPositionOfEntityBone(Vehicle, GetEntityBoneIndexByName(Vehicle, Tires[a].bone)) + local Spike = GetClosestObjectOfType(TirePos.x, TirePos.y, TirePos.z, 2.0, GetHashKey('P_ld_stinger_s'), 1, 1, 1) + local SpikePos = GetEntityCoords(Spike, false) + local Distance = Vdist(TirePos.x, TirePos.y, TirePos.z, SpikePos.x, SpikePos.y, SpikePos.z) + + if Distance < 1.8 then + if not IsVehicleTyreBurst(Vehicle, Tires[a].index, true) or IsVehicleTyreBurst(Vehicle, Tires[a].index, false) then + SetVehicleTyreBurst(Vehicle, Tires[a].index, false, 1000.0) + end + end + end + end + end + end + end +end) + + + +--Backup +RegisterNetEvent('SEM_InteractionMenu:CallBackup') +AddEventHandler('SEM_InteractionMenu:CallBackup', function(Code, StreetName, Coords) + if LEORestrict() then + local BackupBlip = nil + local BackupBlips = {} + + local function CreateBlip(x, y, z, Name, Sprite, Size, Colour) + BackupBlip = AddBlipForCoord(x, y, z) + SetBlipSprite(BackupBlip, Sprite) + SetBlipDisplay(BackupBlip, 4) + SetBlipScale(BackupBlip, Size) + SetBlipColour(BackupBlip, Colour) + SetBlipAsShortRange(BackupBlip, true) + + BeginTextCommandSetBlipName('STRING') + AddTextComponentString(Name) + EndTextCommandSetBlipName(BackupBlip) + table.insert(BackupBlips, BackupBlip) + Citizen.Wait(Config.BackupBlipTimeout * 60000) + for _, Blip in pairs(BackupBlips) do + RemoveBlip(Blip) + end + end + + if Code == 1 then + Notify('An officer is requesting ~g~Code 1 ~w~backup at ~b~' .. StreetName) + CreateBlip(Coords.x, Coords.y, Coords.z, 'Code 1 Backup Requested', 56, 0.8, 2) + elseif Code == 2 then + Notify('An officer is requesting ~y~Code 2 ~w~backup at ~b~' .. StreetName) + CreateBlip(Coords.x, Coords.y, Coords.z, 'Code 2 Backup Requested', 56, 0.8, 17) + elseif Code == 3 then + Notify('An officer is requesting ~r~Code 3 ~w~backup at ~b~' .. StreetName) + CreateBlip(Coords.x, Coords.y, Coords.z, 'Code 3 Backup Requested', 56, 1.0, 49) + elseif Code == 99 then + Notify('An officer is requesting ~r~Code 99 ~w~backup at ~b~' .. StreetName) + CreateBlip(Coords.x, Coords.y, Coords.z, 'Code 99 Backup Requested', 56, 1.2, 49) + elseif Code == 'panic' then + Notify('An officer has pressed their ~r~Panic Button ~w~at ~b~' .. StreetName) + CreateBlip(Coords.x, Coords.y, Coords.z, 'Panic Button Pressed', 103, 1.2, 49) + end + end +end) + + + +--Jail +CurrentlyJailed = false +EarlyRelease = false +OriginalJailTime = 0 +RegisterNetEvent('SEM_InteractionMenu:JailPlayer') +AddEventHandler('SEM_InteractionMenu:JailPlayer', function(JailTime) + if CurrentlyJailed then + return + end + if CurrentlyHospitaled then + return + end + + OriginalJailTime = JailTime + + local Ped = PlayerPedId() + if DoesEntityExist(Ped) then + Citizen.CreateThread(function() + SetEntityCoords(Ped, Config.JailLocation.Jail.x, Config.JailLocation.Jail.y, Config.JailLocation.Jail.z) + SetEntityHeading(Ped, Config.JailLocation.Jail.h) + CurrentlyJailed = true + + while JailTime >= 0 and not EarlyRelease do + SetEntityInvincible(Ped, true) + if IsPedInAnyVehicle(Ped, false) then + ClearPedTasksImmediately(Ped) + end + + if JailTime % 30 == 0 and JailTime ~= 0 then + TriggerEvent('chat:addMessage', { + multiline = true, + color = {86, 96, 252}, + args = {'Judge', JailTime .. ' months until release.'}, + }) + end + + Citizen.Wait(1000) + + local Location = GetEntityCoords(Ped, true) + local Distance = Vdist(Config.JailLocation.Jail.x, Config.JailLocation.Jail.y, Config.JailLocation.Jail.z, Location['x'], Location['y'], Location['z']) + if Distance > 100 then + SetEntityCoords(Ped, Config.JailLocation.Jail.x, Config.JailLocation.Jail.y, Config.JailLocation.Jail.z) + SetEntityHeading(Ped, Config.JailLocation.Jail.h) + TriggerEvent('chat:addMessage', { + multiline = true, + color = {86, 96, 252}, + args = {'Judge', 'Don\'t try escape, its impossible'}, + }) + end + + JailTime = JailTime - 1 + end + + if EarlyRelease then + TriggerServerEvent('SEM_InteractionMenu:GlobalChat', {86, 96, 252}, 'Judge', GetPlayerName(PlayerId()) .. ' was released from Jail on Parole') + else + TriggerServerEvent('SEM_InteractionMenu:GlobalChat', {86, 96, 252}, 'Judge', GetPlayerName(PlayerId()) .. ' was released from Jail after ' .. OriginalJailTime .. ' months(s).') + end + SetEntityCoords(Ped, Config.JailLocation.Release.x, Config.JailLocation.Release.y, Config.JailLocation.Release.z) + SetEntityHeading(Ped, Config.JailLocation.Release.h) + CurrentlyJailed = false + EarlyRelease = false + end) + end +end) + +RegisterNetEvent('SEM_InteractionMenu:UnjailPlayer') +AddEventHandler('SEM_InteractionMenu:UnjailPlayer', function() + EarlyRelease = true +end) + + + +--Toggle LEO Weapons +CarbineEquipped = false +ShotgunEquipped = false +Citizen.CreateThread(function() + while true do + Citizen.Wait(50) + + if Config.UnrackWeapons == 1 then + local Ped = PlayerPedId() + local CurrentWeapon = GetSelectedPedWeapon(Ped) + + if CarbineEquipped then + SetCurrentPedWeapon(Ped, 'weapon_carbinerifle', true) + else + if tostring(CurrentWeapon) == '-2084633992' then + Notify('~o~You need to unrack your rifle before you can use it') + SetCurrentPedWeapon(Ped, 'weapon_unarmed', true) + end + end + + if ShotgunEquipped then + SetCurrentPedWeapon(Ped, 'weapon_pumpshotgun', true) + else + if tostring(CurrentWeapon) == '487013001' then + Notify('~o~You need to unrack your shotgun before you can use it') + SetCurrentPedWeapon(Ped, 'weapon_unarmed', true) + end + end + end + end +end) + + + +--Civilian Adverts +RegisterNetEvent('SEM_InteractionMenu:SyncAds') +AddEventHandler('SEM_InteractionMenu:SyncAds',function(Text, Name, Loc, File, ID) + Ad(Text, Name, Loc, File, ID) +end) + + + +--Inventory +RegisterNetEvent('SEM_InteractionMenu:InventoryResult') +AddEventHandler('SEM_InteractionMenu:InventoryResult', function(Inventory) + Citizen.Wait(5000) + + if Inventory == nil then + Inventory = 'Empty' + end + + Notify('~b~Inventory Items: ~g~' .. Inventory) +end) + + + +--BAC +RegisterNetEvent('SEM_InteractionMenu:BACResult') +AddEventHandler('SEM_InteractionMenu:BACResult', function(BACLevel) + Citizen.Wait(5000) + + if BACLevel == nil then + BACLevel = 0.00 + end + + if tonumber(BACLevel) < 0.08 then + Notify('~b~BAC Level: ~g~' .. tostring(BACLevel)) + else + Notify('~b~BAC Level: ~r~' .. tostring(BACLevel)) + end +end) + + + + +--Hospital +CurrentlyHospitalized = false +EarlyDischarge = false +OriginalHospitalTime = 0 +RegisterNetEvent('SEM_InteractionMenu:HospitalizePlayer') +AddEventHandler('SEM_InteractionMenu:HospitalizePlayer', function(HospitalTime, HospitalLocation) + if CurrentlyHospitaled then + return + end + if CurrentlyJailed then + return + end + + OriginalHospitalTime = HospitalTime + + local Ped = PlayerPedId() + if DoesEntityExist(Ped) then + Citizen.CreateThread(function() + SetEntityCoords(Ped, HospitalLocation.Hospital.x, HospitalLocation.Hospital.y, HospitalLocation.Hospital.z) + SetEntityHeading(Ped, HospitalLocation.Hospital.h) + CurrentlyHospitaled = true + + while HospitalTime >= 0 and not EarlyDischarge do + SetEntityInvincible(Ped, true) + if IsPedInAnyVehicle(Ped, false) then + ClearPedTasksImmediately(Ped) + end + + if HospitalTime % 30 == 0 and HospitalTime ~= 0 then + TriggerEvent('chat:addMessage', { + multiline = true, + color = {86, 96, 252}, + args = {'Doctor', HospitalTime .. ' months until release.'}, + }) + end + + Citizen.Wait(1000) + + local Location = GetEntityCoords(Ped, true) + local Distance = Vdist(HospitalLocation.Hospital.x, HospitalLocation.Hospital.y, HospitalLocation.Hospital.z, Location['x'], Location['y'], Location['z']) + if Distance > 30 then + SetEntityCoords(Ped, HospitalLocation.Hospital.x, HospitalLocation.Hospital.y, HospitalLocation.Hospital.z) + SetEntityHeading(Ped, HospitalLocation.Hospital.h) + TriggerEvent('chat:addMessage', { + multiline = true, + color = {86, 96, 252}, + args = {'Doctor', 'You cannot discharge yourself!'}, + }) + end + + HospitalTime = HospitalTime - 1 + end + + if EarlyDischarge then + TriggerServerEvent('SEM_InteractionMenu:GlobalChat', {86, 96, 252}, 'Doctor', GetPlayerName(PlayerId()) .. ' was discharged from Hospital early') + else + TriggerServerEvent('SEM_InteractionMenu:GlobalChat', {86, 96, 252}, 'Doctor', GetPlayerName(PlayerId()) .. ' was discharged from Hospital after ' .. OriginalHospitalTime .. ' months(s).') + end + SetEntityCoords(Ped, HospitalLocation.Release.x, HospitalLocation.Release.y, HospitalLocation.Release.z) + SetEntityHeading(Ped, HospitalLocation.Release.h) + CurrentlyHospitaled = false + EarlyDischarge = false + end) + end +end) + +RegisterNetEvent('SEM_InteractionMenu:UnhospitalizePlayer') +AddEventHandler('SEM_InteractionMenu:UnhospitalizePlayer', function() + EarlyDischarge = true +end) + + + +--Station Blips +Citizen.CreateThread(function() + if Config.DisplayStationBlips then + local function CreateBlip(x, y, z, Name, Colour, Sprite) + StationBlip = AddBlipForCoord(x, y, z) + SetBlipSprite(StationBlip, Sprite) + if Config.StationBlipsDispalyed == 1 then + SetBlipDisplay(StationBlip, 3) + elseif Config.StationBlipsDispalyed == 2 then + SetBlipDisplay(StationBlip, 5) + else + SetBlipDisplay(StationBlip, 2) + end + SetBlipScale(StationBlip, 1.0) + SetBlipColour(StationBlip, Colour) + SetBlipAsShortRange(StationBlip, true) + + BeginTextCommandSetBlipName('STRING') + AddTextComponentString(Name) + EndTextCommandSetBlipName(StationBlip) + end + + for _, Station in pairs(Config.LEOStations) do + CreateBlip(Station.coords.x, Station.coords.y, Station.coords.z, 'Police Station', 38, 60) + end + for _, Station in pairs(Config.FireStations) do + CreateBlip(Station.coords.x, Station.coords.y, Station.coords.z, 'Fire Station', 1, 60) + end + for _, Station in pairs(Config.HospitalStations) do + CreateBlip(Station.coords.x, Station.coords.y, Station.coords.z, 'Hospital', 2, 61) + end + end +end) + + + +--Permissions +LEOAce = false +TriggerServerEvent('SEM_InteractionMenu:LEOPerms') +RegisterNetEvent('SEM_InteractionMenu:LEOPermsResult') +AddEventHandler('SEM_InteractionMenu:LEOPermsResult', function(Allowed) + if Allowed then + LEOAce = true + else + LEOAce = false + end +end) + +FireAce = false +TriggerServerEvent('SEM_InteractionMenu:FirePerms') +RegisterNetEvent('SEM_InteractionMenu:FirePermsResult') +AddEventHandler('SEM_InteractionMenu:FirePermsResult', function(Allowed) + if Allowed then + FireAce = true + else + FireAce = false + end +end) + +UnjailAllowed = false +TriggerServerEvent('SEM_InteractionMenu:UnjailPerms') +RegisterNetEvent('SEM_InteractionMenu:UnjailPermsResult') +AddEventHandler('SEM_InteractionMenu:UnjailPermsResult', function(Allowed) + if Allowed then + UnjailAllowed = true + else + UnjailAllowed = false + end +end) + +UnhospitalAllowed = false +TriggerServerEvent('SEM_InteractionMenu:UnhospitalPerms') +RegisterNetEvent('SEM_InteractionMenu:UnhospitalPermsResult') +AddEventHandler('SEM_InteractionMenu:UnhospitalPermsResult', function(Allowed) + if Allowed then + UnhospitalAllowed = true + else + UnhospitalAllowed = false + end +end) + + + +--Emote +Citizen.CreateThread(function() + while true do + Citizen.Wait(1) + + if EmotePlaying then + if Config.EmoteHelp then + NotifyHelp('You are playing an Emote, ~b~Move to Cancel') + end + + -- Spacebar W S A D + if (IsControlPressed(0, 22) or IsControlPressed(0, 32) or IsControlPressed(0, 33) or IsControlPressed(0, 34) or IsControlPressed(0, 35)) then + CancelEmote() + end + end + end +end) + + + +--Commands +Citizen.CreateThread(function() + if EmoteRestrict() then + local Index = 0 + local Emotes = '' + for _, Emote in pairs(Config.EmotesList) do + Index = Index + 1 + if Index == 1 then + Emotes = Emotes .. Emote.name + else + Emotes = Emotes .. ', ' .. Emote.name + end + end + + TriggerEvent('chat:addSuggestion', '/emotes', 'List of Current Avaliable Emotes') + TriggerEvent('chat:addSuggestion', '/emote', 'Play Emote', {{name = 'Emote Name', help = 'Emotes: ' .. Emotes}}) + else + TriggerEvent('chat:removeSuggestion', '/emotes') + TriggerEvent('chat:removeSuggestion', '/emote') + end + + TriggerEvent('chat:addSuggestion', '/eng', 'Toggles Engine') + TriggerEvent('chat:addSuggestion', '/hood', 'Toggles Vehicle\'s Hood') + TriggerEvent('chat:addSuggestion', '/trunk', 'Toggles Vehicle\'s Trunk') + TriggerEvent('chat:addSuggestion', '/clear', 'Clears all Weapons') + TriggerEvent('chat:addSuggestion', '/cuff', 'Cuff Player', {{name = 'ID', help = 'Players Server ID'}}) + TriggerEvent('chat:addSuggestion', '/drag', 'Drag Player', {{name = 'ID', help = 'Players Server ID'}}) + TriggerEvent('chat:addSuggestion', '/dropweapon', 'Drops Weapon in Hand') + TriggerEvent('chat:addSuggestion', '/loadout', 'Equips LEO Weapon Loadout') + TriggerEvent('chat:addSuggestion', '/coords', 'Shows Current Player Coords and Heading') + + if Config.Radar ~= 0 then + TriggerEvent('chat:addSuggestion', '/radar', 'Toggle Radar Menu') + end + + if Config.LEOAccess == 3 or Config.FireAccess == 3 then + if Config.OndutyPSWDActive then + TriggerEvent('chat:addSuggestion', '/onduty', 'Enable LEO/Fire Menu', {{name = 'Department', help = 'LEO or Fire'}, {name = 'Password', help = 'Onduty Password'}}) + else + TriggerEvent('chat:addSuggestion', '/onduty', 'Enable LEO/Fire Menu', {{name = 'Department', help = 'LEO or Fire'}}) + end + else + TriggerEvent('chat:removeSuggestion', '/onduty') + end +end) + +LEOOnduty = false +FireOnduty = false +RegisterCommand('onduty', function(source, args, rawCommand) + if Config.LEOAccess == 3 or Config.FireAccess == 3 then + if Config.OndutyPSWDActive then + if args[2] == Config.OndutyPSWD then + local Department = args[1]:lower() + if Department == 'leo' then + LEOOnduty = not LEOOnduty + if LEOOnduty then + Notify('~g~You are onduty as an LEO') + else + Notify('~o~You are no longer onduty as an LEO') + end + elseif Department == 'fire' then + FireOnduty = not FireOnduty + if FireOnduty == true then + Notify('~g~You are onduty as an Firefighter') + else + Notify('~o~You are no longer onduty as an Firefighter') + end + else + Notify('~r~Invalid Department!') + end + else + Notify('~r~Incorrect Password') + end + else + local Department = args[1]:lower() + if Department == 'leo' then + LEOOnduty = not LEOOnduty + if LEOOnduty then + Notify('~g~You are onduty as an LEO') + else + Notify('~o~You are no longer onduty as an LEO') + end + elseif Department == 'fire' then + FireOnduty = not FireOnduty + if FireOnduty == true then + Notify('~g~You are onduty as an Firefighter') + else + Notify('~o~You are no longer onduty as an Firefighter') + end + else + Notify('~r~Invalid Department!') + end + end + end +end) + +function IsOndutyLEO() + return LEOOnduty +end +function IsOndutyFire() + return FireOnduty +end + +RegisterCommand('cuff', function(source, args, rawCommand) + if LEORestrict() or FireRestrict() then + if args[1] ~= nil then + local ID = tonumber(args[1]) + if Config.CommandDistanceChecked then + if GetDistance(source) < Config.CommandDistance then + TriggerServerEvent('SEM_InteractionMenu:CuffNear', ID) + else + Notify('~r~That player is too far away') + end + else + TriggerServerEvent('SEM_InteractionMenu:CuffNear', ID) + end + else + TriggerServerEvent('SEM_InteractionMenu:CuffNear', GetClosestPlayer()) + end + else + Notify('~r~Insufficient Permissions') + end +end) + +RegisterCommand('drag', function(source, args, rawCommand) + if LEORestrict() or FireRestrict() then + if args[1] ~= nil then + local ID = tonumber(args[1]) + if Config.CommandDistanceChecked then + if GetDistance(source) < Config.CommandDistance then + TriggerServerEvent('SEM_InteractionMenu:DragNear', ID) + else + Notify('~r~That player is too far away') + end + else + TriggerServerEvent('SEM_InteractionMenu:DragNear', ID) + end + else + TriggerServerEvent('SEM_InteractionMenu:DragNear', GetClosestPlayer()) + end + else + Notify('~r~Insufficient Permissions') + end +end) + +RegisterCommand('radar', function(source, args, rawCommand) + if Config.Radar ~= 0 then + if LEORestrict() or FireRestrict() then + ToggleRadar() + else + Notify('~r~Insufficient Permissions') + end + end +end) + +RegisterCommand('loadout', function(source, args, rawCommand) + if LEORestrict() then + if args[1] then + local RequestedLoadout = args[1] + + for Name, Loadout in pairs(Config.LEOLoadouts) do + if Name:lower() == RequestedLoadout:lower() then + SetEntityHealth(GetPlayerPed(-1), 200) + RemoveAllPedWeapons(GetPlayerPed(-1), true) + AddArmourToPed(GetPlayerPed(-1), 100) + + for _, Weapon in pairs(Loadout) do + GiveWeapon(Weapon.weapon) + + for _, Component in pairs(Weapon.components) do + AddWeaponComponent(Weapon.weapon, Component) + end + end + return + end + end + + Notify('~r~Invalid Loadout') + else + SetEntityHealth(PlayerPedId(), 200) + RemoveAllPedWeapons(PlayerPedId(), true) + AddArmourToPed(PlayerPedId(), 100) + GiveWeapon('weapon_nightstick') + GiveWeapon('weapon_flashlight') + GiveWeapon('weapon_fireextinguisher') + GiveWeapon('weapon_flare') + GiveWeapon('weapon_stungun') + GiveWeapon('weapon_combatpistol') + AddWeaponComponent('weapon_combatpistol', 'component_at_pi_flsh') + Notify('~g~Loadout Spawned') + end + else + Notify('~r~You aren\'t an LEO') + end +end) + +RegisterCommand('hu', function(source, args, rawCommand) + local Ped = PlayerPedId() + if DoesEntityExist(Ped) and not HandCuffed then + Citizen.CreateThread(function() + LoadAnimation('random@mugging3') + if IsEntityPlayingAnim(Ped, 'random@mugging3', 'handsup_standing_base', 3) or HandCuffed then + ClearPedSecondaryTask(Ped) + SetEnableHandcuffs(Ped, false) + elseif not IsEntityPlayingAnim(Ped, 'random@mugging3', 'handsup_standing_base', 3) or not HandCuffed then + TaskPlayAnim(Ped, 'random@mugging3', 'handsup_standing_base', 8.0, -8, -1, 49, 0, 0, 0, 0) + SetEnableHandcuffs(Ped, true) + end + end) + end +end) + +RegisterCommand('huk', function(source, args, rawCommand) + local Ped = PlayerPedId() + if (DoesEntityExist(Ped) and not IsEntityDead(Ped)) and not HandCuffed then + Citizen.CreateThread(function() + LoadAnimation('random@arrests') + if (IsEntityPlayingAnim(Ped, 'random@arrests', 'kneeling_arrest_idle', 3)) then + TaskPlayAnim(Ped, 'random@arrests', 'kneeling_arrest_get_up', 8.0, 1.0, -1, 128, 0, 0, 0, 0) + else + TaskPlayAnim(Ped, 'random@arrests', 'idle_2_hands_up', 8.0, 1.0, -1, 2, 0, 0, 0, 0) + Wait (4000) + TaskPlayAnim(Ped, 'random@arrests', 'kneeling_arrest_idle', 8.0, 1.0, -1, 2, 0, 0, 0, 0) + end + end) + end +end) + +RegisterCommand('dropweapon', function(source, args, rawCommand) + local CurrentWeapon = GetSelectedPedWeapon(PlayerPedId()) + SetPedDropsInventoryWeapon(PlayerPedId(), CurrentWeapon, -2.0, 0.0, 0.5, 30) + Notify('~r~Weapon Dropped!') +end) + +RegisterCommand('clear', function(source, args, rawCommand) + SetEntityHealth(PlayerPedId(), 200) + RemoveAllPedWeapons(PlayerPedId(), true) + Notify('~r~All Weapons Cleared!') +end) + +RegisterCommand('eng', function(source, args, rawCommand) + local Veh = GetVehiclePedIsIn(PlayerPedId(), false) + if Veh ~= nil and Veh ~= 0 and GetPedInVehicleSeat(Veh, 0) then + SetVehicleEngineOn(Veh, (not GetIsVehicleEngineRunning(Veh)), false, true) + Notify('~g~Engine Toggled!') + end +end) + +RegisterCommand('hood', function(source, args, rawCommand) + local Veh = GetVehiclePedIsIn(PlayerPedId(), false) + + if Veh ~= nil and Veh ~= 0 and Veh ~= 1 then + if GetVehicleDoorAngleRatio(Veh, 4) > 0 then + SetVehicleDoorShut(Veh, 4, false) + else + SetVehicleDoorOpen(Veh, 4, false, false) + end + end + + Notify('~g~Hood Toggled!') +end) + +RegisterCommand('trunk', function(source, args, rawCommand) + local Veh = GetVehiclePedIsIn(PlayerPedId(), false) + + if Veh ~= nil and Veh ~= 0 and Veh ~= 1 then + if GetVehicleDoorAngleRatio(Veh, 5) > 0 then + SetVehicleDoorShut(Veh, 5, false) + else + SetVehicleDoorOpen(Veh, 5, false, false) + end + end + + Notify('~g~Trunk Toggled!') +end) + +RegisterCommand('emotes', function(source, args, rawCommand) + if EmoteRestrict() then + local Index = 0 + local Emotes = '' + for _, Emote in pairs(Config.EmotesList) do + Index = Index + 1 + if Index == 1 then + Emotes = Emotes .. Emote.name + else + Emotes = Emotes .. ', ' .. Emote.name + end + end + + TriggerEvent('chat:addMessage', { + multiline = true, + color = {255, 0 ,0}, + args = {'Emotes', '\n^r^7' .. Emotes}, + }) + end +end) + +RegisterCommand('emote', function(source, args, rawCommand) + if EmoteRestrict() then + local SelectedEmote = args[1] + + for _, Emote in pairs(Config.EmotesList) do + if Emote.name == SelectedEmote then + PlayEmote(Emote.emote, Emote.name) + return + end + end + + TriggerEvent('chat:addMessage', { + multiline = true, + color = {255, 0, 0}, + args = {'Emotes', 'Invalid Emote!'}, + }) + end +end) + +RegisterCommand('coords', function(source, args, rawCommand) + local Coords = GetEntityCoords(PlayerPedId()) + local Heading = GetEntityHeading(PlayerPedId()) + + TriggerEvent('chatMessage', 'Coords', {255, 255, 0}, '\nX: ' .. Coords.x .. '\nY: ' .. Coords.y .. '\nZ: ' .. Coords.z .. '\nHeading: ' .. Heading) +end) diff --git a/resources/Interaction-Menu/config.lua b/resources/Interaction-Menu/config.lua new file mode 100644 index 000000000..99ad89db5 --- /dev/null +++ b/resources/Interaction-Menu/config.lua @@ -0,0 +1,615 @@ +--[[ +─────────────────────────────────────────────────────────────── + + SEM_InteractionMenu (config.lua) - Created by Scott M + Current Version: v1.7.1 (Sep 2021) + + Support: https://semdevelopment.com/discord + +─────────────────────────────────────────────────────────────── +]] + + + +Config = {} + + + +--------------------------------------------------------------- +-- -- +-- Menu Features -- +-- -- +--------------------------------------------------------------- + +--This is how the version check will be displayed in the server console +--Full = 0 [Default] | Simple = 1 | Disabled = 2 +Config.VersionChecker = 1 + +--This is how you open the menu either via a command or button +--Button = 0 [Default] | Command = 1 +Config.OpenMenu = 0 + +--This is the button that will open the menu (If chosen at Config.OpenMenu) +--Default = 244 [M] | To change the button check out https://docs.fivem.net/game-references/controls/ +--Controller Support for this resource is DISABLED! +Config.MenuButton = 166 + +--This is the command that will open the menu (If chosen at Config.OpenMenu) +Config.Command = 'policemenu' + +--This is the width of the menu when open +--Default = 80 +Config.MenuWidth = 80 + +--This is the position of the menu when open +--Left = 0 [Default] | Right = 1 +Config.MenuOrientation = 0 + +--This is the title of the menu dispalyed +--Default = The default title of the menu is 'Interaction Menu' +--Player Name = This is the name of the player +--Custom = This is a custom title set by you at Config.MenuTitleCustom +--Default = 0 [Default] | Player Name = 1 | Custom = 2 +Config.MenuTitle = 0 + +--This is the custom title you can set for the menu (If chosen at Config.MenuTitle) +Config.MenuTitleCustom = 'Custom Menu Title' + + + + + + + + + + + + + + + + + +--------------------------------------------------------------- +-- -- +-- General/Shared Features -- +-- -- +--------------------------------------------------------------- + +--This determines if the onduty password is active, if false the password will NOT be required when doing the command +Config.OndutyPSWDActive = false + +--This is the onduty password, only people with the password can access the menu if chosen at Config.LEOAccess/Config.FireAccess +Config.OndutyPSWD = 'OndutyPSWD' + +--This determines if the distance between the player using the command and the person being cuffed/dragged is checked +Config.CommandDistanceChecked = true + +--This determines how close you need to be to cuff/drag someone using their ID +--Default = 50 +Config.CommandDistance = 50 + +--This determines if the stations section of the LEO & Fire menu will be visible +--Station Locations can be set at Config.LEOStations & Config.FireStations +Config.ShowStations = true + +--This determines if the stations menu will have a teleport section, if set to false ONLY the waypoint option will be visible +Config.AllowStationTeleport = true + +--This determines if the stations set in the Config.LEOStations & Config.FireStations have blips on the map +Config.DisplayStationBlips = true + +--This sets where the station blips will be displayed (Mini Map / Main Map) +--On Mini Map & Main Map = 0 [Default] | Only on Main Map = 1 | Only on Mini Map = 2 +Config.StationBlipsDispalyed = 0 + +--These are the props avaliable via the LEO & Fire menus +Config.Props = { + --[[ + EXAMPLE: + {name = 'a', spawncode = 'b'}, + ──────────────────────────────────────────────────────────────── + 'a' is the title that shows in the menu + 'b' is the spawn code for prop that will be spawned + ]] + {name = 'Police Barrier', spawncode = 'prop_barrier_work05'}, + {name = 'Barrier', spawncode = 'prop_barrier_work06a'}, + {name = 'Traffic Cone', spawncode = 'prop_roadcone01a'}, + {name = 'Cone', spawncode = 'prop_roadcone02b'}, + {name = 'Work Barrier', spawncode = 'prop_mp_barrier_02b'}, + {name = 'Work Barrier 2', spawncode = 'prop_barrier_work01a'}, + {name = 'Lighting', spawncode = 'prop_worklight_03b'}, + {name = 'Tent', spawncode = 'prop_gazebo_02'}, +} + + + + + + + + + + + + + + + + + +--------------------------------------------------------------- +-- -- +-- LEO Features -- +-- -- +--------------------------------------------------------------- + +--This sets who can access the LEO menu +--!!! NOTE: If LEO Peds is selected then onlys peds from the Config.LEOUniforms will have access to the menu +--Disabled = 0 | Everyone = 1 [Default] | LEO Peds = 2 | Onduty Command = 3 | Ace Permissions = 4 +Config.LEOAccess = 1 + +--This determines if the radar button will be displayed +--NOTE: Wraith Radar is the ONLY radar script that works with the menu at the moment (This also includes any editied version) - Both his old and new radar are compatiable, link below +--[[ + Links: + WraithRS | Advanced Radar System: https://forum.cfx.re/t/release-wraithrs-advanced-radar-system-1-0-2/48543 + Ascaped Plate Reader Edit: https://forum.cfx.re/t/release-edit-wraithrs-new-plate-reader/147269 + + Wraith ARS 2X Radar & Plate Reader: https://forum.cfx.re/t/release-wraith-ars-2x-police-radar-and-plate-reader-v1-2-4/1058277 + + **Other modified version of these resoruce should work** +]] +--Disabled = 0 [Default] | Wraith ARS 2x = 1 | WraithRS = 2 +Config.Radar = 0 + +--This determines when someone if cuffed if they can enter or exit a vehicle +Config.VehEnterCuffed = false + +--This determines if you need to unrack the carbine rifle of pumpshotun from a vehicle to obtain it +--Disabled = 0 | Constant = 1 | Free-hand = 2 [Default] +--Constant = Once unracked it is unable to be removed from hand until racked again in a vehicle +--Free-hand = Once unracked it is able to be removed from hand +Config.UnrackWeapons = 2 + +--This sets if the Jail functions will be visible in the menu +Config.LEOJail = true + +--This is the max time that someone can be jailed for (Seconds) +Config.MaxJailTime = 300 + +--These is the location of the jail and release point +Config.JailLocation = { + Jail = {x = 1675.28, y = 2648.55, z = 45.56, h = 49.50}, + Release = {x = 1851.24, y = 2585.77, z = 45.67, h = 271.44}, +} + +--This determines if the backup section of the LEO menu will be visible +Config.DisplayBackup = true + +--This sets the time between the blip being created and removed (Minutes) +--Default = 5 +Config.BackupBlipTimeout = 5 + +--This determines if the LEO props menu will be available +Config.DisplayProps = true + +--These are the station available via the station menu +Config.LEOStations = { + {name = 'Sandy Shores', coords = {x = 1850.04, y = 3679.36, z = 34.26 , h = 208.84}}, + {name = 'Paleto Bay', coords = {x = -438.51, y = 6017.93, z = 31.49 , h = 352.90}}, + + {name = 'Mission Row', coords = {x = 432.08, y = -985.25, z = 30.71 , h = 44.02}}, + {name = 'Davis', coords = {x = 373.99, y = -1607.59, z = 29.29 , h = 192.15}}, + {name = 'Vinewood', coords = {x = 638.03, y = -1.85, z = 82.78 , h = 290.18}}, + {name = 'Vespucci', coords = {x = -1090.87, y = -807.29, z = 19.26 , h = 64.92}}, + + {name = 'NOOSE Headquarters', coords = {x = 2504.29, y = -384.11, z = 94.12, h = 264.01}}, +} + +--This determines if the LEO Unfiroms section will be visible +Config.DisplayLEOUniforms = true + +--These are the LEO uniforms that are available via the loadouts - these will also be the uniforms which will give access to the LEO menu if that option if chosen at Config.LEOAccess +Config.LEOUniforms = { + --[[ + EXAMPLE: + {name = 'a', spawncode = 'b'}, + ──────────────────────────────────────────────────────────────── + 'a' is the title that shows in the menu + 'b' is the spawn code for uniform that will be spawned + ]] + {name = 'LSPD', spawncode = 's_m_y_cop_01'}, + {name = 'BCSO', spawncode = 's_m_y_sheriff_01'}, + {name = 'SAHP', spawncode = 's_m_y_hwaycop_01'}, + {name = 'SWAT', spawncode = 's_m_y_swat_01'}, + {name = 'Undercover', spawncode = 's_m_m_ciasec_01'}, +} + +--This determines if the LEO Loadouts section will be visible +Config.DisplayLEOLoadouts = true + +--These are the weapon loadouts available via the loadouts +Config.LEOLoadouts = { + --[[ + EXAMPLE: + a = { + {weapon = 'b', components = 'c', 'c'}, + }, + ──────────────────────────────────────────────────────────────── + 'a' is the title of the Loadout + 'b' is the weapon which you want to be added [A link to weapon names can be found below] + 'c' is the components which you want to be added to the weapon [A link to available weapon components can be found below] + + Weapon Names https://forum.fivem.net/t/list-of-weapon-spawn-names-after-hours/90750 + Weapon Components https://wiki.rage.mp/index.php?title=Weapons_Components + ]] + ['Standard'] = { + {weapon = 'weapon_flashlight', components = {''}}, + {weapon = 'weapon_combatpistol', components = {'component_at_pi_flsh'}}, + {weapon = 'weapon_stungun', components = {''}}, + {weapon = 'weapon_carbinerifle', components = {'component_at_ar_flsh', 'component_at_scope_medium', 'component_at_ar_afgrip'}}, + {weapon = 'weapon_pumpshotgun', components = {'component_at_ar_flsh'}}, + {weapon = 'weapon_fireextinguisher', components = {''}}, + {weapon = 'weapon_flare', components = {''}}, + }, + + ['SWAT'] = { + {weapon = 'weapon_flashlight', components = {''}}, + {weapon = 'weapon_combatpistol', components = {'component_at_pi_flsh'}}, + {weapon = 'weapon_stungun', components = {''}}, + {weapon = 'weapon_smg', components = {'component_at_ar_flsh', 'component_ar_scope_macro_02'}}, + {weapon = 'weapon_carbinerifle', components = {'component_at_ar_flsh', 'component_at_scope_medium', 'component_at_ar_afgrip'}}, + {weapon = 'weapon_pumpshotgun', components = {'component_at_ar_flsh'}}, + {weapon = 'weapon_sniperrifle', components = {'comonent_at_scope_max'}}, + {weapon = 'weapon_bzgas', components = {''}}, + {weapon = 'weapon_fireextinguisher', components = {''}}, + {weapon = 'weapon_flare', components = {''}}, + } +} + +--This determines if the LEO vehicles section if available +Config.ShowLEOVehicles = true + +--This determines if the vehicle spawn codes are displayed next to the name +Config.ShowLEOSpawnCode = true + +--These are the LEO vehicles which are avaiable via the menu +Config.LEOVehiclesCategories = { + --[[ + EXAMPLE: + ['a'] = { + {name = 'b', spawncode = 'c', livery = d, extras = {e, e}}, + } + ──────────────────────────────────────────────────────────────── + 'a' is the title of the Category + 'b' is the title of the vehicle that shows in the menu + 'c' is the spawn code for vehicle that will be spawned + d is the number of the livery which you want it to spawn with + e is the number(s) of extra(s) which you want it to spawn with + + **NOTE: Sometimes the sections do NOT display if the order in the config below** + ]] + + ['Police'] = { + {name = 'Police', spawncode = 'police'}, + {name = 'Police', spawncode = 'police2'}, + {name = 'Police', spawncode = 'police3'}, + }, + + ['Sheriff'] = { + {name = 'Sheriff', spawncode = 'sheriff'}, + {name = 'Sheriff', spawncode = 'sheriff2'}, + }, + + ['Unmarked'] = { + {name = 'Unmarked', spawncode = 'police4'}, + }, +} + +--This determines if the ai traffic manager will can accessible +Config.DisplayTrafficManager = true + + + + + + + + + + + + + + + + + +--------------------------------------------------------------- +-- -- +-- Fire Features -- +-- -- +--------------------------------------------------------------- + +--This sets who can access the Fire menu +--!!! NOTE: If Fire Peds is selected then onlys peds from the Config.FireUniforms will have access to the menu +--Disabled = 0 | Everyone = 1 [Default] | Fire Peds = 2 | Onduty Command = 3 | Ace Permissions = 4 +Config.FireAccess = 1 + +--This sets if the Hospitalize functions will be visible in the menu +Config.FireHospital = true + +--This is the max time that someone can be hospitalized for (Seconds) +Config.MaxHospitalTime = 300 + +--These is the location of the hospital and release point +--I would recommend using a MLO Interior/Ymap for the hospital +Config.HospitalLocation = { + ['Pillbox Hill'] = { + Hospital = {x = 358.34, y = -589.98, z = 28.79, h = 257.19}, + Release = {x = 372.78, y = -595.04, z = 28.84, h = 248.29}, + }, + ['Paleto Bay'] = { + Hospital = {x = -247.34, y = 6332.39, z = 32.42 , h = 226.90}, + Release = {x = -247.34, y = 6332.39, z = 32.42 , h = 226.90}, + } +} + +--These are the station available via the station menu +Config.FireStations = { + {name = 'Sandy Shores', coords = {x = 1693.57, y = 3582.68, z = 35.62 , h = 227.29}}, + {name = 'Paleto Bay', coords = {x = -382.50, y = 6116.76, z = 31.47 , h = 7.29}}, + + {name = 'Davis', coords = {x = 201.16, y = -1631.67, z = 29.75, h = 296.67}}, + {name = 'Rockford Hill', coords = {x = -636.47, y = -117.02, z = 38.02, h = 79.64}}, + {name = 'El Burro Heights', coords = {x = 1191.83, y = -1461.74, z = 34.88, h = 329.54}}, +} + +--These are the locations of hospitals avaiable via the hospital menu +Config.HospitalStations = { + {name = 'Sandy Shores', coords = {x = 1839.13, y = 3673.26, z = 34.27 , h = 210.83}}, + {name = 'Paleto Bay', coords = {x = -247.34, y = 6332.39, z = 32.42 , h = 226.90}}, + + {name = 'Pillbox', coords = {x = 357.19, y = -593.46, z = 28.78, h = 260.70}}, + {name = 'Davis', coords = {x = 294.59, y = -1448.17, z = 29.96, h = 320.92}}, +} + +--This determines if the LEO Unfiroms section will be visible +Config.DisplayFireUniforms = true + +--These are the Fire uniforms that are available via the loadouts - these will also be the uniforms which will give access to the Fire menu if that option if chosen at Config.FireAccess +Config.FireUniforms = { + --[[ + EXAMPLE: + {name = 'a', spawncode = 'b'}, + ──────────────────────────────────────────────────────────────── + 'a' is the title that shows in the menu + 'b' is the spawn code for uniform that will be spawned + ]] + {name = 'Firefighter', spawncode = 's_m_y_fireman_01'}, + {name = 'Paramedic', spawncode = 's_m_m_paramedic_01'}, +} + +--This determines if the LEO Loadouts section will be visible +Config.DisplayFireLoadouts = true + +--This determines if the Fire vehicles section if available +Config.ShowFireVehicles = true + +--This determines if the vehicle spawn codes are displayed next to the name +Config.ShowFireSpawnCode = true + +--These are the Fire vehicles which are avaiable via the menu +Config.FireVehicles = { + --[[ + EXAMPLE: + {name = 'a', spawncode = 'b', livery = c, extras = {d, d}}, + ──────────────────────────────────────────────────────────────── + 'a' is the title of the vehicle that shows in the menu + 'b' is the spawn code for vehicle that will be spawned + 'c' is the number of the livery which you want it to spawn with + 'd' is the number(s) of extra(s) which you want it to spawn with + + **NOTE: Sometimes the sections do NOT display if the order in the config below** + ]] + + --These are the Vehicles that will show in the Category and there spawn codes + {name = 'Fire Engine', spawncode = 'firetruk'}, + {name = 'Ambulance', spawncode = 'ambulance'}, +} + + + + + + + + + + + + + + + + + +--------------------------------------------------------------- +-- -- +-- Civilian Features -- +-- -- +--------------------------------------------------------------- + +--This sets who can access the Civlian menu +--!!! NOTE: If Fire Peds is selected then onlys peds from the Config.FireUniforms will have access to the menu +--Disabled = 0 | Everyone = 1 [Default] +Config.CivAccess = 1 + +--This determines if the Civilian vehicles section if available +Config.ShowCivVehicles = true + +--This determines if the vehicle spawn codes are displayed next to the name +Config.ShowCivSpawnCode = true + +--These are the Civilian vehicles which are avaiable via the menu +Config.CivVehicles = { + --[[ + EXAMPLE: + {name = 'a', spawncode = 'b'}, + ──────────────────────────────────────────────────────────────── + 'a' is the title of the vehicle that shows in the menu + 'b' is the spawn code for vehicle that will be spawned + ]] + + --These are the Vehicles that will show in the Category and there spawn codes + {name = 'Adder', spawncode = 'adder'}, + {name = 'Baller', spawncode = 'baller'}, +} + +--This determines if the civilian adverts sections of the menu if visible +--NOTE: When someone sends an advert it will display the company name and then "Advertisement ##", this is the Server ID of the person that sent the advert +Config.ShowCivAdverts = true + +--These are the adverts that are avaiable via the ads menu +--NOTE: You can add additional adverts from https://wiki.gtanet.work/index.php?title=Notification_Pictures +Config.CivAdverts = { + --[[ + EXAMPLE: + {name = 'a', loc = 'b', file = 'c'}, + ──────────────────────────────────────────────────────────────── + 'a' is the title of the Adverts + 'b' is the location for the Advert's Image + 'c' is the file name for the Advert's Image + ]] + + + + -- !!!!! Wouldn't Recommend Changing These Unless You Know What You're Doing !!!!! + -- !!!!! Wouldn't Recommend Changing These Unless You Know What You're Doing !!!!! + -- !!!!! Wouldn't Recommend Changing These Unless You Know What You're Doing !!!!! + + {name = '24/7', loc = 'CHAR_FLOYD', file = '247'}, + {name = 'Ammunation', loc = 'CHAR_AMMUNATION', file = 'CHAR_AMMUNATION'}, + {name = 'Bugstars', loc = 'CHAR_BUGSTARS', file = 'CHAR_BUGSTARS'}, + {name = 'Cluckin\' Bell', loc = 'CHAR_FLOYD', file = 'BELL'}, + {name = 'Downtown Cab Co.', loc = 'CHAR_TAXI', file = 'CHAR_TAXI'}, + {name = 'Dynasty 8', loc = 'CHAR_FLOYD', file = 'D8'}, + {name = 'Fleeca Bank', loc = 'CHAR_BANK_FLEECA', file = 'CHAR_BANK_FLEECA'}, + {name = 'Gruppe6', loc = 'CHAR_FLOYD', file = 'GRUPPE6'}, + {name = 'Merry Weather', loc = 'CHAR_MP_MERRYWEATHER', file = 'CHAR_MP_MERRYWEATHER'}, + {name = 'Limited Gasoline', loc = 'CHAR_FLOYD', file = 'LTD'}, + {name = 'Liquor Ace', loc = 'CHAR_FLOYD', file = 'ACE'}, + {name = 'Smoke on the Water', loc = 'CHAR_FLOYD', file = 'SOTW'}, + {name = 'Pegasus', loc = 'CHAR_PEGASUS_DELIVERY', file = 'CHAR_PEGASUS_DELIVERY'}, + {name = 'Los Santos Customs', loc = 'CHAR_LS_CUSTOMS', file = 'CHAR_LS_CUSTOMS'}, + {name = 'Los Santos Traffic Info', loc = 'CHAR_LS_TOURIST_BOARD', file = 'CHAR_LS_TOURIST_BOARD'}, + {name = 'Los Santos Water and Power', loc = 'CHAR_FLOYD', file = 'LSWP'}, + {name = 'Mors Mutual Insurance', loc = 'CHAR_MP_MORS_MUTUAL', file = 'CHAR_MP_MORS_MUTUAL'}, + {name = 'PostOP', loc = 'CHAR_FLOYD', file = 'OP'}, + {name = 'Vanilla Unicorn', loc = 'CHAR_MP_STRIPCLUB_PR', file = 'CHAR_MP_STRIPCLUB_PR'}, + {name = 'Weazel News', loc = 'CHAR_FLOYD', file = 'NEWS'}, + {name = 'Facebook', loc = 'CHAR_FACEBOOK', file = 'CHAR_FACEBOOK'}, + {name = 'Life Invader', loc = 'CHAR_LIFEINVADER', file = 'CHAR_LIFEINVADER'}, + {name = 'YouTube', loc = 'CHAR_YOUTUBE', file = 'CHAR_YOUTUBE'}, +} + + + + + + + + + + + + + + + + + +--------------------------------------------------------------- +-- -- +-- Vehicle Features -- +-- -- +--------------------------------------------------------------- + +--This sets when players can access the vehicle menu +--Disabled = 0 | All the Time = 1 [Default] | When in Vehicle = 2 +Config.VehicleAccess = 1 + +--This determines if the vehicle options are avaiable, these include: Fix, Clean, Delete +Config.VehicleOptions = true + + + + + + + + + + + + + + + + + +--------------------------------------------------------------- +-- -- +-- Emote Features -- +-- -- +--------------------------------------------------------------- + +--This sets which players can access the emote menu +--Disabled = 0 | Everyone = 1 [Default] +Config.EmoteAccess = 1 + +--This sets if a help message is displayed when playing an emote +Config.EmoteHelp = true + +--These are the emotes avaiable via the menu and the '/emotes' & '/emote [Emote]' commands +Config.EmotesList = { + {name = 'binoculars', emote = 'WORLD_HUMAN_BINOCULARS'}, + {name = 'camera', emote = 'WORLD_HUMAN_PAPARAZZI'}, + {name = 'clean', emote = 'WORLD_HUMAN_MAID_CLEAN'}, + {name = 'clipboard', emote = 'WORLD_HUMAN_CLIPBOARD'}, + {name = 'coffee', emote = 'WORLD_HUMAN_AA_COFFEE'}, + {name = 'cheer', emote = 'WORLD_HUMAN_CHEERING'}, + {name = 'cop', emote = 'WORLD_HUMAN_COP_IDLES'}, + {name = 'film', emote = 'WORLD_HUMAN_MOBILE_FILM_SHOCKING'}, + {name = 'fish', emote = 'WORLD_HUMAN_STAND_FISHING'}, + {name = 'flex', emote = 'WORLD_HUMAN_MUSCLE_FLEX'}, + {name = 'guard', emote = 'WORLD_HUMAN_GUARD_STAND'}, + {name = 'hammer', emote = 'WORLD_HUMAN_HAMMERING'}, + {name = 'homeless', emote = 'WORLD_HUMAN_BUM_FREEWAY'}, + {name = 'impatient', emote = 'WORLD_HUMAN_STAND_IMPATIENT'}, + {name = 'jog', emote = 'WORLD_HUMAN_JOG_STANDING'}, + {name = 'kneel', emote = 'CODE_HUMAN_MEDIC_KNEEL'}, + {name = 'lean', emote = 'WORLD_HUMAN_LEANING'}, + {name = 'mechanic', emote = 'WORLD_HUMAN_VEHICLE_MECHANIC'}, + {name = 'medic', emote = 'CODE_HUMAN_MEDIC_TEND_TO_DEAD'}, + {name = 'music', emote = 'WORLD_HUMAN_MUSICIAN'}, + {name = 'notepad', emote = 'CODE_HUMAN_MEDIC_TIME_OF_DEATH'}, + {name = 'party', emote = 'WORLD_HUMAN_PARTYING'}, + {name = 'phone', emote = 'WORLD_HUMAN_STAND_MOBILE'}, + {name = 'phonecall', emote = 'WORLD_HUMAN_STAND_MOBILE_UPRIGHT'}, + {name = 'selfie', emote = 'WORLD_HUMAN_TOURIST_MOBILE'}, + {name = 'sit', emote = 'WORLD_HUMAN_PICNIC'}, + {name = 'sleep', emote = 'WORLD_HUMAN_BUM_SLUMPED'}, + {name = 'smoke', emote = 'WORLD_HUMAN_SMOKING'}, + {name = 'statue', emote = 'WORLD_HUMAN_HUMAN_STATUE'}, + {name = 'stupor', emote = 'WORLD_HUMAN_STUPOR'}, + {name = 'sunbathe', emote = 'WORLD_HUMAN_SUNBATHE'}, + {name = 'sunbathe2', emote = 'WORLD_HUMAN_SUNBATHE_BACK'}, + {name = 'traffic', emote = 'WORLD_HUMAN_CAR_PARK_ATTENDANT'}, + {name = 'weed', emote = 'WORLD_HUMAN_SMOKING_POT'}, + {name = 'weights', emote = 'WORLD_HUMAN_MUSCLE_FREE_WEIGHTS'}, + {name = 'weld', emote = 'WORLD_HUMAN_WELDING'}, + {name = 'yoga', emote = 'WORLD_HUMAN_YOGA'}, +} diff --git a/resources/Interaction-Menu/dependencies/NativeUI.lua b/resources/Interaction-Menu/dependencies/NativeUI.lua new file mode 100644 index 000000000..f574b20bd --- /dev/null +++ b/resources/Interaction-Menu/dependencies/NativeUI.lua @@ -0,0 +1,3884 @@ +UIResRectangle = setmetatable({}, UIResRectangle) +UIResRectangle.__index = UIResRectangle +UIResRectangle.__call = function() return "Rectangle" end + +UIResText = setmetatable({}, UIResText) +UIResText.__index = UIResText +UIResText.__call = function() return "Text" end + +Sprite = setmetatable({}, Sprite) +Sprite.__index = Sprite +Sprite.__call = function() return "Sprite" end + +UIMenuItem = setmetatable({}, UIMenuItem) +UIMenuItem.__index = UIMenuItem +UIMenuItem.__call = function() return "UIMenuItem", "UIMenuItem" end + +UIMenuCheckboxItem = setmetatable({}, UIMenuCheckboxItem) +UIMenuCheckboxItem.__index = UIMenuCheckboxItem +UIMenuCheckboxItem.__call = function() return "UIMenuItem", "UIMenuCheckboxItem" end + +UIMenuListItem = setmetatable({}, UIMenuListItem) +UIMenuListItem.__index = UIMenuListItem +UIMenuListItem.__call = function() return "UIMenuItem", "UIMenuListItem" end + +UIMenuSliderItem = setmetatable({}, UIMenuSliderItem) +UIMenuSliderItem.__index = UIMenuSliderItem +UIMenuSliderItem.__call = function() return "UIMenuItem", "UIMenuSliderItem" end + +UIMenuColouredItem = setmetatable({}, UIMenuColouredItem) +UIMenuColouredItem.__index = UIMenuColouredItem +UIMenuColouredItem.__call = function() return "UIMenuItem", "UIMenuColouredItem" end + +UIMenuProgressItem = setmetatable({}, UIMenuProgressItem) +UIMenuProgressItem.__index = UIMenuProgressItem +UIMenuProgressItem.__call = function() return "UIMenuItem", "UIMenuProgressItem" end + +UIMenuHeritageWindow = setmetatable({}, UIMenuHeritageWindow) +UIMenuHeritageWindow.__index = UIMenuHeritageWindow +UIMenuHeritageWindow.__call = function() return "UIMenuWindow", "UIMenuHeritageWindow" end + +UIMenuGridPanel = setmetatable({}, UIMenuGridPanel) +UIMenuGridPanel.__index = UIMenuGridPanel +UIMenuGridPanel.__call = function() return "UIMenuPanel", "UIMenuGridPanel" end + +UIMenuColourPanel = setmetatable({}, UIMenuColourPanel) +UIMenuColourPanel.__index = UIMenuColourPanel +UIMenuColourPanel.__call = function() return "UIMenuPanel", "UIMenuColourPanel" end + +UIMenuPercentagePanel = setmetatable({}, UIMenuPercentagePanel) +UIMenuPercentagePanel.__index = UIMenuPercentagePanel +UIMenuPercentagePanel.__call = function() return "UIMenuPanel", "UIMenuPercentagePanel" end + +UIMenu = setmetatable({}, UIMenu) +UIMenu.__index = UIMenu +UIMenu.__call = function() return "UIMenu" end + +MenuPool = setmetatable({}, MenuPool) +MenuPool.__index = MenuPool + +NativeUI = {} + +CharacterMap = { [' '] = 6, ['!'] = 6, ['"'] = 6, ['#'] = 11,['$'] = 10, ['%'] = 17,['&'] = 13, ['\\'] = 4,['('] = 6, [')'] = 6,['*'] = 7, ['+'] = 10, [','] = 4, ['-'] = 6, ['.'] = 4, ['/'] = 7, ['0'] = 12, ['1'] = 7, ['2'] = 11, ['3'] = 11, ['4'] = 11, ['5'] = 11, ['6'] = 12, ['7'] = 10, ['8'] = 11, ['9'] = 11, [':'] = 5, [';'] = 4, ['<'] = 9, ['='] = 9, ['>'] = 9, ['?'] = 10, ['@'] = 15, ['A'] = 12, ['B'] = 13, ['C'] = 14, ['D'] = 14, ['E'] = 12, ['F'] = 12, ['G'] = 15, ['H'] = 14, ['I'] = 5, ['J'] = 11, ['K'] = 13, ['L'] = 11, ['M'] = 16, ['N'] = 14, ['O'] = 16, ['P'] = 12, ['Q'] = 15, ['R'] = 13, ['S'] = 12, ['T'] = 11, ['U'] = 13, ['V'] = 12, ['W'] = 18, ['X'] = 11, ['Y'] = 11, ['Z'] = 12, ['['] = 6, [']'] = 6, ['^'] = 9, ['_'] = 18, ['`'] = 8, ['a'] = 11, ['b'] = 12, ['c'] = 11, ['d'] = 12, ['e'] = 12, ['f'] = 5, ['g'] = 13, ['h'] = 11, ['i'] = 4, ['j'] = 4, ['k'] = 10, ['l'] = 4, ['m'] = 18, ['n'] = 11, ['o'] = 12, ['p'] = 12, ['q'] = 12, ['r'] = 7, ['s'] = 9, ['t'] = 5, ['u'] = 11, ['v'] = 10, ['w'] = 14, ['x'] = 9, ['y'] = 10, ['z'] = 9, ['{'] = 6, ['|'] = 3, ['}'] = 6 } + +BadgeStyle = { None = 0, BronzeMedal = 1, GoldMedal = 2, SilverMedal = 3, Alert = 4, Crown = 5, Ammo = 6, Armour = 7, Barber = 8, Clothes = 9, Franklin = 10, Bike = 11, Car = 12, Gun = 13, Heart = 14, Makeup = 15, Mask = 16, Michael = 17, Star = 18, Tattoo = 19, Trevor = 20, Lock = 21, Tick = 22 } + +BadgeTexture = { + [0] = function() return "" end, + [1] = function() return "mp_medal_bronze" end, + [2] = function() return "mp_medal_gold" end, + [3] = function() return "medal_silver" end, + [4] = function() return "mp_alerttriangle" end, + [5] = function() return "mp_hostcrown" end, + [6] = function(Selected) if Selected then return "shop_ammo_icon_b" else return "shop_ammo_icon_a" end end, + [7] = function(Selected) if Selected then return "shop_armour_icon_b" else return "shop_armour_icon_a" end end, + [8] = function(Selected) if Selected then return "shop_barber_icon_b" else return "shop_barber_icon_a" end end, + [9] = function(Selected) if Selected then return "shop_clothing_icon_b" else return "shop_clothing_icon_a" end end, + [10] = function(Selected) if Selected then return "shop_franklin_icon_b" else return "shop_franklin_icon_a" end end, + [11] = function(Selected) if Selected then return "shop_garage_bike_icon_b" else return "shop_garage_bike_icon_a" end end, + [12] = function(Selected) if Selected then return "shop_garage_icon_b" else return "shop_garage_icon_a" end end, + [13] = function(Selected) if Selected then return "shop_gunclub_icon_b" else return "shop_gunclub_icon_a" end end, + [14] = function(Selected) if Selected then return "shop_health_icon_b" else return "shop_health_icon_a" end end, + [15] = function(Selected) if Selected then return "shop_makeup_icon_b" else return "shop_makeup_icon_a" end end, + [16] = function(Selected) if Selected then return "shop_mask_icon_b" else return "shop_mask_icon_a" end end, + [17] = function(Selected) if Selected then return "shop_michael_icon_b" else return "shop_michael_icon_a" end end, + [18] = function() return "shop_new_star" end, + [19] = function(Selected) if Selected then return "shop_tattoos_icon_b" else return "shop_tattoos_icon_a" end end, + [20] = function(Selected) if Selected then return "shop_trevor_icon_b" else return "shop_trevor_icon_a" end end, + [21] = function() return "shop_lock" end, + [22] = function() return "shop_tick_icon" end, +} + +BadgeDictionary = { + [0] = function(Selected) + if Selected then + return "commonmenu" + else + return "commonmenu" + end + end, +} + +BadgeColour = { + [5] = function(Selected) if Selected then return 0, 0, 0, 255 else return 255, 255, 255, 255 end end, + [21] = function(Selected) if Selected then return 0, 0, 0, 255 else return 255, 255, 255, 255 end end, + [22] = function(Selected) if Selected then return 0, 0, 0, 255 else return 255, 255, 255, 255 end end, +} + +Colours = { + PureWhite = {255, 255, 255, 255}, + White = {240, 240, 240, 255}, + Black = {0, 0, 0, 255}, + Grey = {155, 155, 155, 255}, + GreyLight = {205, 205, 205, 255}, + GreyDark = {77, 77, 77, 255}, + Red = {224, 50, 50, 255}, + RedLight = {240, 153, 153, 255}, + RedDark = {112, 25, 25, 255}, + Blue = {93, 182, 229, 255}, + BlueLight = {174, 219, 242, 255}, + BlueDark = {47, 92, 115, 255}, + Yellow = {240, 200, 80, 255}, + YellowLight = {254, 235, 169, 255}, + YellowDark = {126, 107, 41, 255}, + Orange = {255, 133, 85, 255}, + OrangeLight = {255, 194, 170, 255}, + OrangeDark = {127, 66, 42, 255}, + Green = {114, 204, 114, 255}, + GreenLight = {185, 230, 185, 255}, + GreenDark = {57, 102, 57, 255}, + Purple = {132, 102, 226, 255}, + PurpleLight = {192, 179, 239, 255}, + PurpleDark = {67, 57, 111, 255}, + Pink = {203, 54, 148, 255}, + RadarHealth = {53, 154, 71, 255}, + RadarArmour = {93, 182, 229, 255}, + RadarDamage = {235, 36, 39, 255}, + NetPlayer1 = {194, 80, 80, 255}, + NetPlayer2 = {156, 110, 175, 255}, + NetPlayer3 = {255, 123, 196, 255}, + NetPlayer4 = {247, 159, 123, 255}, + NetPlayer5 = {178, 144, 132, 255}, + NetPlayer6 = {141, 206, 167, 255}, + NetPlayer7 = {113, 169, 175, 255}, + NetPlayer8 = {211, 209, 231, 255}, + NetPlayer9 = {144, 127, 153, 255}, + NetPlayer10 = {106, 196, 191, 255}, + NetPlayer11 = {214, 196, 153, 255}, + NetPlayer12 = {234, 142, 80, 255}, + NetPlayer13 = {152, 203, 234, 255}, + NetPlayer14 = {178, 98, 135, 255}, + NetPlayer15 = {144, 142, 122, 255}, + NetPlayer16 = {166, 117, 94, 255}, + NetPlayer17 = {175, 168, 168, 255}, + NetPlayer18 = {232, 142, 155, 255}, + NetPlayer19 = {187, 214, 91, 255}, + NetPlayer20 = {12, 123, 86, 255}, + NetPlayer21 = {123, 196, 255, 255}, + NetPlayer22 = {171, 60, 230, 255}, + NetPlayer23 = {206, 169, 13, 255}, + NetPlayer24 = {71, 99, 173, 255}, + NetPlayer25 = {42, 166, 185, 255}, + NetPlayer26 = {186, 157, 125, 255}, + NetPlayer27 = {201, 225, 255, 255}, + NetPlayer28 = {240, 240, 150, 255}, + NetPlayer29 = {237, 140, 161, 255}, + NetPlayer30 = {249, 138, 138, 255}, + NetPlayer31 = {252, 239, 166, 255}, + NetPlayer32 = {240, 240, 240, 255}, + SimpleBlipDefault = {159, 201, 166, 255}, + MenuBlue = {140, 140, 140, 255}, + MenuGreyLight = {140, 140, 140, 255}, + MenuBlueExtraDark = {40, 40, 40, 255}, + MenuYellow = {240, 160, 0, 255}, + MenuYellowDark = {240, 160, 0, 255}, + MenuGreen = {240, 160, 0, 255}, + MenuGrey = {140, 140, 140, 255}, + MenuGreyDark = {60, 60, 60, 255}, + MenuHighlight = {30, 30, 30, 255}, + MenuStandard = {140, 140, 140, 255}, + MenuDimmed = {75, 75, 75, 255}, + MenuExtraDimmed = {50, 50, 50, 255}, + BriefTitle = {95, 95, 95, 255}, + MidGreyMp = {100, 100, 100, 255}, + NetPlayer1Dark = {93, 39, 39, 255}, + NetPlayer2Dark = {77, 55, 89, 255}, + NetPlayer3Dark = {124, 62, 99, 255}, + NetPlayer4Dark = {120, 80, 80, 255}, + NetPlayer5Dark = {87, 72, 66, 255}, + NetPlayer6Dark = {74, 103, 83, 255}, + NetPlayer7Dark = {60, 85, 88, 255}, + NetPlayer8Dark = {105, 105, 64, 255}, + NetPlayer9Dark = {72, 63, 76, 255}, + NetPlayer10Dark = {53, 98, 95, 255}, + NetPlayer11Dark = {107, 98, 76, 255}, + NetPlayer12Dark = {117, 71, 40, 255}, + NetPlayer13Dark = {76, 101, 117, 255}, + NetPlayer14Dark = {65, 35, 47, 255}, + NetPlayer15Dark = {72, 71, 61, 255}, + NetPlayer16Dark = {85, 58, 47, 255}, + NetPlayer17Dark = {87, 84, 84, 255}, + NetPlayer18Dark = {116, 71, 77, 255}, + NetPlayer19Dark = {93, 107, 45, 255}, + NetPlayer20Dark = {6, 61, 43, 255}, + NetPlayer21Dark = {61, 98, 127, 255}, + NetPlayer22Dark = {85, 30, 115, 255}, + NetPlayer23Dark = {103, 84, 6, 255}, + NetPlayer24Dark = {35, 49, 86, 255}, + NetPlayer25Dark = {21, 83, 92, 255}, + NetPlayer26Dark = {93, 98, 62, 255}, + NetPlayer27Dark = {100, 112, 127, 255}, + NetPlayer28Dark = {120, 120, 75, 255}, + NetPlayer29Dark = {152, 76, 93, 255}, + NetPlayer30Dark = {124, 69, 69, 255}, + NetPlayer31Dark = {10, 43, 50, 255}, + NetPlayer32Dark = {95, 95, 10, 255}, + Bronze = {180, 130, 97, 255}, + Silver = {150, 153, 161, 255}, + Gold = {214, 181, 99, 255}, + Platinum = {166, 221, 190, 255}, + Gang1 = {29, 100, 153, 255}, + Gang2 = {214, 116, 15, 255}, + Gang3 = {135, 125, 142, 255}, + Gang4 = {229, 119, 185, 255}, + SameCrew = {252, 239, 166, 255}, + Freemode = {45, 110, 185, 255}, + PauseBg = {0, 0, 0, 255}, + Friendly = {93, 182, 229, 255}, + Enemy = {194, 80, 80, 255}, + Location = {240, 200, 80, 255}, + Pickup = {114, 204, 114, 255}, + PauseSingleplayer = {114, 204, 114, 255}, + FreemodeDark = {22, 55, 92, 255}, + InactiveMission = {154, 154, 154, 255}, + Damage = {194, 80, 80, 255}, + PinkLight = {252, 115, 201, 255}, + PmMitemHighlight = {252, 177, 49, 255}, + ScriptVariable = {0, 0, 0, 255}, + Yoga = {109, 247, 204, 255}, + Tennis = {241, 101, 34, 255}, + Golf = {214, 189, 97, 255}, + ShootingRange = {112, 25, 25, 255}, + FlightSchool = {47, 92, 115, 255}, + NorthBlue = {93, 182, 229, 255}, + SocialClub = {234, 153, 28, 255}, + PlatformBlue = {11, 55, 123, 255}, + PlatformGreen = {146, 200, 62, 255}, + PlatformGrey = {234, 153, 28, 255}, + FacebookBlue = {66, 89, 148, 255}, + IngameBg = {0, 0, 0, 255}, + Darts = {114, 204, 114, 255}, + Waypoint = {164, 76, 242, 255}, + Michael = {101, 180, 212, 255}, + Franklin = {171, 237, 171, 255}, + Trevor = {255, 163, 87, 255}, + GolfP1 = {240, 240, 240, 255}, + GolfP2 = {235, 239, 30, 255}, + GolfP3 = {255, 149, 14, 255}, + GolfP4 = {246, 60, 161, 255}, + WaypointLight = {210, 166, 249, 255}, + WaypointDark = {82, 38, 121, 255}, + PanelLight = {0, 0, 0, 255}, + MichaelDark = {72, 103, 116, 255}, + FranklinDark = {85, 118, 85, 255}, + TrevorDark = {127, 81, 43, 255}, + ObjectiveRoute = {240, 200, 80, 255}, + PausemapTint = {0, 0, 0, 255}, + PauseDeselect = {100, 100, 100, 255}, + PmWeaponsPurchasable = {45, 110, 185, 255}, + PmWeaponsLocked = {240, 240, 240, 255}, + ScreenBg = {0, 0, 0, 255}, + Chop = {224, 50, 50, 255}, + PausemapTintHalf = {0, 0, 0, 255}, + NorthBlueOfficial = {0, 71, 133, 255}, + ScriptVariable2 = {0, 0, 0, 255}, + H = {33, 118, 37, 255}, + HDark = {37, 102, 40, 255}, + T = {234, 153, 28, 255}, + TDark = {225, 140, 8, 255}, + HShard = {20, 40, 0, 255}, + ControllerMichael = {48, 255, 255, 255}, + ControllerFranklin = {48, 255, 0, 255}, + ControllerTrevor = {176, 80, 0, 255}, + ControllerChop = {127, 0, 0, 255}, + VideoEditorVideo = {53, 166, 224, 255}, + VideoEditorAudio = {162, 79, 157, 255}, + VideoEditorText = {104, 192, 141, 255}, + HbBlue = {29, 100, 153, 255}, + HbYellow = {234, 153, 28, 255}, + VideoEditorScore = {240, 160, 1, 255}, + VideoEditorAudioFadeout = {59, 34, 57, 255}, + VideoEditorTextFadeout = {41, 68, 53, 255}, + VideoEditorScoreFadeout = {82, 58, 10, 255}, + HeistBackground = {37, 102, 40, 255}, + VideoEditorAmbient = {240, 200, 80, 255}, + VideoEditorAmbientFadeout = {80, 70, 34, 255}, + Gb = {255, 133, 85, 255}, + G = {255, 194, 170, 255}, + B = {255, 133, 85, 255}, + LowFlow = {240, 200, 80, 255}, + LowFlowDark = {126, 107, 41, 255}, + G1 = {247, 159, 123, 255}, + G2 = {226, 134, 187, 255}, + G3 = {239, 238, 151, 255}, + G4 = {113, 169, 175, 255}, + G5 = {160, 140, 193, 255}, + G6 = {141, 206, 167, 255}, + G7 = {181, 214, 234, 255}, + G8 = {178, 144, 132, 255}, + G9 = {0, 132, 114, 255}, + G10 = {216, 85, 117, 255}, + G11 = {30, 100, 152, 255}, + G12 = {43, 181, 117, 255}, + G13 = {233, 141, 79, 255}, + G14 = {137, 210, 215, 255}, + G15 = {134, 125, 141, 255}, + Adversary = {109, 34, 33, 255}, + DegenRed = {255, 0, 0, 255}, + DegenYellow = {255, 255, 0, 255}, + DegenGreen = {0, 255, 0, 255}, + DegenCyan = {0, 255, 255, 255}, + DegenBlue = {0, 0, 255, 255}, + DegenMagenta = {255, 0, 255, 255}, + Stunt1 = {38, 136, 234, 255}, + Stunt2 = {224, 50, 50, 255}, +} + +--[[ + Utils.lua + Utilities +--]] + +function GetResolution() + local W, H = GetActiveScreenResolution() + if (W/H) > 3.5 then + return GetScreenResolution() + else + return W, H + end +end + +function FormatXWYH(Value, Value2) + return Value/1920, Value2/1080 +end + +function math.round(num, numDecimalPlaces) + return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num)) +end + +function tobool(input) + if input == "true" or tonumber(input) == 1 or input == true then + return true + else + return false + end +end + +function string.split(inputstr, sep) + if sep == nil then + sep = "%s" + end + local t={} ; i=1 + for str in string.gmatch(inputstr, "([^"..sep.."]+)") do + t[i] = str + i = i + 1 + end + + return t +end + +function string.starts(String, Start) + return string.sub(String, 1, string.len(Start)) == Start +end + +function IsMouseInBounds(X, Y, Width, Height) + local MX, MY = math.round(GetControlNormal(0, 239) * 1920), math.round(GetControlNormal(0, 240) * 1080) + MX, MY = FormatXWYH(MX, MY) + X, Y = FormatXWYH(X, Y) + Width, Height = FormatXWYH(Width, Height) + return (MX >= X and MX <= X + Width) and (MY > Y and MY < Y + Height) +end + +function GetSafeZoneBounds() + local SafeSize = GetSafeZoneSize() + SafeSize = math.round(SafeSize, 2) + SafeSize = (SafeSize * 100) - 90 + SafeSize = 10 - SafeSize + + local W, H = 1920, 1080 + + return {X = math.round(SafeSize * ((W/H) * 5.4)), Y = math.round(SafeSize * 5.4)} +end + +function Controller() + return not IsInputDisabled(2) +end + +--[[ + UIResRectangle.lua + Elements +--]] + +function UIResRectangle.New(X, Y, Width, Height, R, G, B, A) + local _UIResRectangle = { + X = tonumber(X) or 0, + Y = tonumber(Y) or 0, + Width = tonumber(Width) or 0, + Height = tonumber(Height) or 0, + _Colour = {R = tonumber(R) or 255, G = tonumber(G) or 255, B = tonumber(B) or 255, A = tonumber(A) or 255}, + } + return setmetatable(_UIResRectangle, UIResRectangle) +end + +function UIResRectangle:Position(X, Y) + if tonumber(X) and tonumber(Y) then + self.X = tonumber(X) + self.Y = tonumber(Y) + else + return {X = self.X, Y = self.Y} + end +end + +function UIResRectangle:Size(Width, Height) + if tonumber(Width) and tonumber(Height) then + self.Width = tonumber(Width) + self.Height = tonumber(Height) + else + return {Width = self.Width, Height = self.Height} + end +end + +function UIResRectangle:Colour(R, G, B, A) + if tonumber(R) or tonumber(G) or tonumber(B) or tonumber(A) then + self._Colour.R = tonumber(R) or 255 + self._Colour.B = tonumber(B) or 255 + self._Colour.G = tonumber(G) or 255 + self._Colour.A = tonumber(A) or 255 + else + return self._Colour + end +end + +function UIResRectangle:Draw() + local Position = self:Position() + local Size = self:Size() + Size.Width, Size.Height = FormatXWYH(Size.Width, Size.Height) + Position.X, Position.Y = FormatXWYH(Position.X, Position.Y) + DrawRect(Position.X + Size.Width * 0.5, Position.Y + Size.Height * 0.5, Size.Width, Size.Height, self._Colour.R, self._Colour.G, self._Colour.B, self._Colour.A) +end + +function DrawRectangle(X, Y, Width, Height, R, G, B, A) + X, Y, Width, Height = X or 0, Y or 0, Width or 0, Height or 0 + X, Y = FormatXWYH(X, Y) + Width, Height = FormatXWYH(Width, Height) + DrawRect(X + Width * 0.5, Y + Height * 0.5, Width, Height, tonumber(R) or 255, tonumber(G) or 255, tonumber(B) or 255, tonumber(A) or 255) +end + +--[[ + UIResText.lua + Elements +--]] + +function GetCharacterCount(str) + local characters = 0 + for c in str:gmatch("[%z\1-\127\194-\244][\128-\191]*") do + local a = c:byte(1, -1) + if a ~= nil then + characters = characters + 1 + end + end + return characters +end + +function GetByteCount(str) + local bytes = 0 + + for c in str:gmatch("[%z\1-\127\194-\244][\128-\191]*") do + local a,b,c,d = c:byte(1, -1) + if a ~= nil then + bytes = bytes + 1 + end + if b ~= nil then + bytes = bytes + 1 + end + if c ~= nil then + bytes = bytes + 1 + end + if d ~= nil then + bytes = bytes + 1 + end + end + return bytes +end + +function AddLongStringForAscii(str) + local maxbytelength = 99 + for i = 0, GetCharacterCount(str), 99 do + AddTextComponentSubstringPlayerName(string.sub(str, i, math.min(maxbytelength, GetCharacterCount(str) - i))) --needs changed + end +end + +function AddLongStringForUtf8(str) + local maxbytelength = 99 + local bytecount = GetByteCount(str) + + if bytecount < maxbytelength then + AddTextComponentSubstringPlayerName(str) + return + end + + local startIndex = 0 + + for i = 0, GetCharacterCount(str), 1 do + local length = i - startIndex + if GetByteCount(string.sub(str, startIndex, length)) > maxbytelength then + AddTextComponentSubstringPlayerName(string.sub(str, startIndex, length - 1)) + i = i - 1 + startIndex = startIndex + (length - 1) + end + end + AddTextComponentSubstringPlayerName(string.sub(str, startIndex, GetCharacterCount(str) - startIndex)) +end + +function AddLongString(str) + local bytecount = GetByteCount(str) + if bytecount == GetCharacterCount(str) then + AddLongStringForAscii(str) + else + AddLongStringForUtf8(str) + end +end + +function MeasureStringWidthNoConvert(str, font, scale) + BeginTextCommandWidth("STRING") + AddLongString(str) + SetTextFont(font or 0) + SetTextScale(1.0, scale or 0) + return EndTextCommandGetWidth(true) +end + +function MeasureStringWidth(str, font, scale) + return MeasureStringWidthNoConvert(str, font, scale) * 1920 +end + +function UIResText.New(Text, X, Y, Scale, R, G, B, A, Font, Alignment, DropShadow, Outline, WordWrap) + local _UIResText = { + _Text = tostring(Text) or "", + X = tonumber(X) or 0, + Y = tonumber(Y) or 0, + Scale = tonumber(Scale) or 0, + _Colour = {R = tonumber(R) or 255, G = tonumber(G) or 255, B = tonumber(B) or 255, A = tonumber(A) or 255}, + Font = tonumber(Font) or 0, + Alignment = Alignment or nil, + DropShadow = Dropshadow or nil, + Outline = Outline or nil, + WordWrap = tonumber(WordWrap) or 0, + } + return setmetatable(_UIResText, UIResText) +end + +function UIResText:Position(X, Y) + if tonumber(X) and tonumber(Y) then + self.X = tonumber(X) + self.Y = tonumber(Y) + else + return {X = self.X, Y = self.Y} + end +end + +function UIResText:Colour(R, G, B, A) + if tonumber(R) and tonumber(G) and tonumber(B) and tonumber(A) then + self._Colour.R = tonumber(R) + self._Colour.B = tonumber(B) + self._Colour.G = tonumber(G) + self._Colour.A = tonumber(A) + else + return self._Colour + end +end + +function UIResText:Text(Text) + if tostring(Text) and Text ~= nil then + self._Text = tostring(Text) + else + return self._Text + end +end + +function UIResText:Draw() + local Position = self:Position() + Position.X, Position.Y = FormatXWYH(Position.X, Position.Y) + + SetTextFont(self.Font) + SetTextScale(1.0, self.Scale) + SetTextColour(self._Colour.R, self._Colour.G, self._Colour.B, self._Colour.A) + + if self.DropShadow then + SetTextDropShadow() + end + if self.Outline then + SetTextOutline() + end + + if self.Alignment ~= nil then + if self.Alignment == 1 or self.Alignment == "Center" or self.Alignment == "Centre" then + SetTextCentre(true) + elseif self.Alignment == 2 or self.Alignment == "Right" then + SetTextRightJustify(true) + SetTextWrap(0, Position.X) + end + end + + if tonumber(self.WordWrap) then + if tonumber(self.WordWrap) ~= 0 then + SetTextWrap(Position.X, Position.X + (tonumber(self.WordWrap) / Resolution.Width)) + end + end + + BeginTextCommandDisplayText("STRING") + AddLongString(self._Text) + EndTextCommandDisplayText(Position.X, Position.Y) +end + +function RenderText(Text, X, Y, Font, Scale, R, G, B, A, Alignment, DropShadow, Outline, WordWrap) + Text = tostring(Text) + X, Y = FormatXWYH(X, Y) + SetTextFont(Font or 0) + SetTextScale(1.0, Scale or 0) + SetTextColour(R or 255, G or 255, B or 255, A or 255) + + if DropShadow then + SetTextDropShadow() + end + if Outline then + SetTextOutline() + end + + if Alignment ~= nil then + if Alignment == 1 or Alignment == "Center" or Alignment == "Centre" then + SetTextCentre(true) + elseif Alignment == 2 or Alignment == "Right" then + SetTextRightJustify(true) + SetTextWrap(0, X) + end + end + + if tonumber(WordWrap) then + if tonumber(WordWrap) ~= 0 then + WordWrap, _ = FormatXWYH(WordWrap, 0) + SetTextWrap(WordWrap, X - WordWrap) + end + end + + BeginTextCommandDisplayText("STRING") + AddLongString(Text) + EndTextCommandDisplayText(X, Y) +end + +--[[ + Sprite.lua + Elements +--]] + +function Sprite.New(TxtDictionary, TxtName, X, Y, Width, Height, Heading, R, G, B, A) + local _Sprite = { + TxtDictionary = tostring(TxtDictionary), + TxtName = tostring(TxtName), + X = tonumber(X) or 0, + Y = tonumber(Y) or 0, + Width = tonumber(Width) or 0, + Height = tonumber(Height) or 0, + Heading = tonumber(Heading) or 0, + _Colour = {R = tonumber(R) or 255, G = tonumber(G) or 255, B = tonumber(B) or 255, A = tonumber(A) or 255}, + } + return setmetatable(_Sprite, Sprite) +end + +function Sprite:Position(X, Y) + if tonumber(X) and tonumber(Y) then + self.X = tonumber(X) + self.Y = tonumber(Y) + else + return {X = self.X, Y = self.Y} + end +end + +function Sprite:Size(Width, Height) + if tonumber(Width) and tonumber(Width) then + self.Width = tonumber(Width) + self.Height = tonumber(Height) + else + return {Width = self.Width, Height = self.Height} + end +end + +function Sprite:Colour(R, G, B, A) + if tonumber(R) or tonumber(G) or tonumber(B) or tonumber(A) then + self._Colour.R = tonumber(R) or 255 + self._Colour.B = tonumber(B) or 255 + self._Colour.G = tonumber(G) or 255 + self._Colour.A = tonumber(A) or 255 + else + return self._Colour + end +end + +function Sprite:Draw() + if not HasStreamedTextureDictLoaded(self.TxtDictionary) then + RequestStreamedTextureDict(self.TxtDictionary, true) + end + local Position = self:Position() + local Size = self:Size() + Size.Width, Size.Height = FormatXWYH(Size.Width, Size.Height) + Position.X, Position.Y = FormatXWYH(Position.X, Position.Y) + DrawSprite(self.TxtDictionary, self.TxtName, Position.X + Size.Width * 0.5, Position.Y + Size.Height * 0.5, Size.Width, Size.Height, self.Heading, self._Colour.R, self._Colour.G, self._Colour.B, self._Colour.A) +end + +function DrawTexture(TxtDictionary, TxtName, X, Y, Width, Height, Heading, R, G, B, A) + if not HasStreamedTextureDictLoaded(tostring(TxtDictionary) or "") then + RequestStreamedTextureDict(tostring(TxtDictionary) or "", true) + end + X, Y, Width, Height = X or 0, Y or 0, Width or 0, Height or 0 + X, Y = FormatXWYH(X, Y) + Width, Height = FormatXWYH(Width, Height) + DrawSprite(tostring(TxtDictionary) or "", tostring(TxtName) or "", X + Width * 0.5, Y + Height * 0.5, Width, Height, tonumber(Heading) or 0, tonumber(R) or 255, tonumber(G) or 255, tonumber(B) or 255, tonumber(A) or 255) +end + +--[[ + StringMeasurer.lua + Elements +--]] + +function MeasureString(str) + local output = 0 + for i = 1, GetCharacterCount(str), 1 do + if CharacterMap[string.sub(str, i, i)] then + output = output + CharacterMap[string.sub(str, i, i)] + 1 + end + end + return output +end + +--[[ + Badge.lua + Elements +--]] + +function GetBadgeTexture(Badge, Selected) + if BadgeTexture[Badge] then + return BadgeTexture[Badge](Selected) + else + return "" + end +end + +function GetBadgeDictionary(Badge, Selected) + if BadgeDictionary[Badge] then + return BadgeDictionary[Badge](Selected) + else + return "commonmenu" + end +end + +function GetBadgeColour(Badge, Selected) + if BadgeColour[Badge] then + return BadgeColour[Badge](Selected) + else + return 255, 255, 255, 255 + end +end + +--[[ + Colours.lua + Elements +--]] + +--[[ + UIMenuItem.lua + Items +--]] + +function UIMenuItem.New(Text, Description) + _UIMenuItem = { + Rectangle = UIResRectangle.New(0, 0, 431, 38, 255, 255, 255, 20), + Text = UIResText.New(tostring(Text) or "", 8, 0, 0.33, 245, 245, 245, 255, 0), + _Description = tostring(Description) or ""; + SelectedSprite = Sprite.New("commonmenu", "gradient_nav", 0, 0, 431, 38), + LeftBadge = { Sprite = Sprite.New("commonmenu", "", 0, 0, 40, 40), Badge = 0}, + RightBadge = { Sprite = Sprite.New("commonmenu", "", 0, 0, 40, 40), Badge = 0}, + Label = { + Text = UIResText.New("", 0, 0, 0.35, 245, 245, 245, 255, 0, "Right"), + MainColour = {R = 255, G = 255, B = 255, A = 255}, + HighlightColour = {R = 0, G = 0, B = 0, A = 255}, + }, + _Selected = false, + _Hovered = false, + _Enabled = true, + _Offset = {X = 0, Y = 0}, + ParentMenu = nil, + Panels = {}, + Activated = function(menu, item, panels) end, + ActivatedPanel = function(menu, item, panel, panelvalue) end, + } + return setmetatable(_UIMenuItem, UIMenuItem) +end + +function UIMenuItem:SetParentMenu(Menu) + if Menu ~= nil and Menu() == "UIMenu" then + self.ParentMenu = Menu + else + return self.ParentMenu + end +end + +function UIMenuItem:Selected(bool) + if bool ~= nil then + self._Selected = tobool(bool) + else + return self._Selected + end +end + +function UIMenuItem:Hovered(bool) + if bool ~= nil then + self._Hovered = tobool(bool) + else + return self._Hovered + end +end + +function UIMenuItem:Enabled(bool) + if bool ~= nil then + self._Enabled = tobool(bool) + else + return self._Enabled + end +end + +function UIMenuItem:Description(str) + if tostring(str) and str ~= nil then + self._Description = tostring(str) + else + return self._Description + end +end + +function UIMenuItem:Offset(X, Y) + if tonumber(X) or tonumber(Y) then + if tonumber(X) then + self._Offset.X = tonumber(X) + end + if tonumber(Y) then + self._Offset.Y = tonumber(Y) + end + else + return self._Offset + end +end + +function UIMenuItem:Position(Y) + if tonumber(Y) then + self.Rectangle:Position(self._Offset.X, Y + 144 + self._Offset.Y) + self.SelectedSprite:Position(0 + self._Offset.X, Y + 144 + self._Offset.Y) + self.Text:Position(8 + self._Offset.X, Y + 147 + self._Offset.Y) + self.LeftBadge.Sprite:Position(0 + self._Offset.X, Y + 142 + self._Offset.Y) + self.RightBadge.Sprite:Position(385 + self._Offset.X, Y + 142 + self._Offset.Y) + self.Label.Text:Position(420 + self._Offset.X, Y + 148 + self._Offset.Y) + end +end + +function UIMenuItem:RightLabel(Text, MainColour, HighlightColour) + if tostring(Text) and Text ~= nil then + if type(MainColour) == "table" then + self.Label.MainColour = MainColour + end + if type(HighlightColour) == "table" then + self.Label.HighlightColour = HighlightColour + end + self.Label.Text:Text(tostring(Text)) + else + return self.Label.Text:Text() + end +end + +function UIMenuItem:SetLeftBadge(Badge) + if tonumber(Badge) then + self.LeftBadge.Badge = tonumber(Badge) + end +end + +function UIMenuItem:SetRightBadge(Badge) + if tonumber(Badge) then + self.RightBadge.Badge = tonumber(Badge) + end +end + +function UIMenuItem:Text(Text) + if tostring(Text) and Text ~= nil then + self.Text:Text(tostring(Text)) + else + return self.Text:Text() + end +end + +function UIMenuItem:AddPanel(Panel) + if Panel() == "UIMenuPanel" then + table.insert(self.Panels, Panel) + Panel:SetParentItem(self) + end +end + +function UIMenuItem:RemovePanelAt(Index) + if tonumber(Index) then + if self.Panels[Index] then + table.remove(self.Panels, tonumber(Index)) + end + end +end + +function UIMenuItem:FindPanelIndex(Panel) + if Panel() == "UIMenuPanel" then + for Index = 1, #self.Panels do + if self.Panels[Index] == Panel then + return Index + end + end + end + return nil +end + +function UIMenuItem:FindPanelItem() + for Index = #self.Items, 1, -1 do + if self.Items[Index].Panel then + return Index + end + end + return nil +end + +function UIMenuItem:Draw() + self.Rectangle:Size(431 + self.ParentMenu.WidthOffset, self.Rectangle.Height) + self.SelectedSprite:Size(431 + self.ParentMenu.WidthOffset, self.SelectedSprite.Height) + + if self._Hovered and not self._Selected then + self.Rectangle:Draw() + end + + if self._Selected then + self.SelectedSprite:Draw() + end + + if self._Enabled then + if self._Selected then + self.Text:Colour(0, 0, 0, 255) + self.Label.Text:Colour(self.Label.HighlightColour.R, self.Label.HighlightColour.G, self.Label.HighlightColour.B, self.Label.HighlightColour.A) + else + self.Text:Colour(245, 245, 245, 255) + self.Label.Text:Colour(self.Label.MainColour.R, self.Label.MainColour.G, self.Label.MainColour.B, self.Label.MainColour.A) + end + else + self.Text:Colour(163, 159, 148, 255) + self.Label.Text:Colour(163, 159, 148, 255) + end + + if self.LeftBadge.Badge == BadgeStyle.None then + self.Text:Position(8 + self._Offset.X, self.Text.Y) + else + self.Text:Position(35 + self._Offset.X, self.Text.Y) + self.LeftBadge.Sprite.TxtDictionary = GetBadgeDictionary(self.LeftBadge.Badge, self._Selected) + self.LeftBadge.Sprite.TxtName = GetBadgeTexture(self.LeftBadge.Badge, self._Selected) + self.LeftBadge.Sprite:Colour(GetBadgeColour(self.LeftBadge.Badge, self._Selected)) + self.LeftBadge.Sprite:Draw() + end + + if self.RightBadge.Badge ~= BadgeStyle.None then + self.RightBadge.Sprite:Position(385 + self._Offset.X + self.ParentMenu.WidthOffset, self.RightBadge.Sprite.Y) + self.RightBadge.Sprite.TxtDictionary = GetBadgeDictionary(self.RightBadge.Badge, self._Selected) + self.RightBadge.Sprite.TxtName = GetBadgeTexture(self.RightBadge.Badge, self._Selected) + self.RightBadge.Sprite:Colour(GetBadgeColour(self.RightBadge.Badge, self._Selected)) + self.RightBadge.Sprite:Draw() + end + + if self.Label.Text:Text() ~= "" and string.len(self.Label.Text:Text()) > 0 then + self.Label.Text:Position(420 + self._Offset.X + self.ParentMenu.WidthOffset, self.Label.Text.Y) + self.Label.Text:Draw() + end + + self.Text:Draw() +end + +--[[ + UIMenuCheckboxItem.lua + Items +--]] + +function UIMenuCheckboxItem.New(Text, Check, Description) + local _UIMenuCheckboxItem = { + Base = UIMenuItem.New(Text or "", Description or ""), + CheckedSprite = Sprite.New("commonmenu", "shop_box_blank", 410, 95, 50, 50), + Checked = tobool(Check), + CheckboxEvent = function(menu, item, checked) end, + } + return setmetatable(_UIMenuCheckboxItem, UIMenuCheckboxItem) +end + +function UIMenuCheckboxItem:SetParentMenu(Menu) + if Menu() == "UIMenu" then + self.Base.ParentMenu = Menu + else + return self.Base.ParentMenu + end +end + +function UIMenuCheckboxItem:Position(Y) + if tonumber(Y) then + self.Base:Position(Y) + self.CheckedSprite:Position(380 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, Y + 138 + self.Base._Offset.Y) + end +end + +function UIMenuCheckboxItem:Selected(bool) + if bool ~= nil then + self.Base._Selected = tobool(bool) + else + return self.Base._Selected + end +end + +function UIMenuCheckboxItem:Hovered(bool) + if bool ~= nil then + self.Base._Hovered = tobool(bool) + else + return self.Base._Hovered + end +end + +function UIMenuCheckboxItem:Enabled(bool) + if bool ~= nil then + self.Base._Enabled = tobool(bool) + else + return self.Base._Enabled + end +end + +function UIMenuCheckboxItem:Description(str) + if tostring(str) and str ~= nil then + self.Base._Description = tostring(str) + else + return self.Base._Description + end +end + +function UIMenuCheckboxItem:Offset(X, Y) + if tonumber(X) or tonumber(Y) then + if tonumber(X) then + self.Base._Offset.X = tonumber(X) + end + if tonumber(Y) then + self.Base._Offset.Y = tonumber(Y) + end + else + return self.Base._Offset + end +end + +function UIMenuCheckboxItem:Text(Text) + if tostring(Text) and Text ~= nil then + self.Base.Text:Text(tostring(Text)) + else + return self.Base.Text:Text() + end +end + +function UIMenuCheckboxItem:SetLeftBadge() + error("This item does not support badges") +end + +function UIMenuCheckboxItem:SetRightBadge() + error("This item does not support badges") +end + +function UIMenuCheckboxItem:RightLabel() + error("This item does not support a right label") +end + +function UIMenuCheckboxItem:Draw() + self.Base:Draw() + self.CheckedSprite:Position(380 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, self.CheckedSprite.Y) + if self.Base:Selected() then + if self.Checked then + self.CheckedSprite.TxtName = "shop_box_tickb" + else + self.CheckedSprite.TxtName = "shop_box_blankb" + end + else + if self.Checked then + self.CheckedSprite.TxtName = "shop_box_tick" + else + self.CheckedSprite.TxtName = "shop_box_blank" + end + end + self.CheckedSprite:Draw() +end + +--[[ + UIMenuListItem.lua + Items +--]] + +function UIMenuListItem.New(Text, Items, Index, Description) + if type(Items) ~= "table" then Items = {} end + if Index == 0 then Index = 1 end + local _UIMenuListItem = { + Base = UIMenuItem.New(Text or "", Description or ""), + Items = Items, + LeftArrow = Sprite.New("commonmenu", "arrowleft", 110, 105, 30, 30), + RightArrow = Sprite.New("commonmenu", "arrowright", 280, 105, 30, 30), + ItemText = UIResText.New("", 290, 104, 0.35, 255, 255, 255, 255, 0, "Right"), + _Index = tonumber(Index) or 1, + Panels = {}, + OnListChanged = function(menu, item, newindex) end, + OnListSelected = function(menu, item, newindex) end, + } + return setmetatable(_UIMenuListItem, UIMenuListItem) +end + +function UIMenuListItem:SetParentMenu(Menu) + if Menu ~= nil and Menu() == "UIMenu" then + self.Base.ParentMenu = Menu + else + return self.Base.ParentMenu + end +end + +function UIMenuListItem:Position(Y) + if tonumber(Y) then + self.LeftArrow:Position(300 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 147 + Y + self.Base._Offset.Y) + self.RightArrow:Position(400 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 147 + Y + self.Base._Offset.Y) + self.ItemText:Position(300 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 147 + Y + self.Base._Offset.Y) + self.Base:Position(Y) + end +end + +function UIMenuListItem:Selected(bool) + if bool ~= nil then + self.Base._Selected = tobool(bool) + else + return self.Base._Selected + end +end + +function UIMenuListItem:Hovered(bool) + if bool ~= nil then + self.Base._Hovered = tobool(bool) + else + return self.Base._Hovered + end +end + +function UIMenuListItem:Enabled(bool) + if bool ~= nil then + self.Base._Enabled = tobool(bool) + else + return self.Base._Enabled + end +end + +function UIMenuListItem:Description(str) + if tostring(str) and str ~= nil then + self.Base._Description = tostring(str) + else + return self.Base._Description + end +end + +function UIMenuListItem:Offset(X, Y) + if tonumber(X) or tonumber(Y) then + if tonumber(X) then + self.Base._Offset.X = tonumber(X) + end + if tonumber(Y) then + self.Base._Offset.Y = tonumber(Y) + end + else + return self.Base._Offset + end +end + +function UIMenuListItem:Text(Text) + if tostring(Text) and Text ~= nil then + self.Base.Text:Text(tostring(Text)) + else + return self.Base.Text:Text() + end +end + +function UIMenuListItem:Index(Index) + if tonumber(Index) then + if tonumber(Index) > #self.Items then + self._Index = 1 + elseif tonumber(Index) < 1 then + self._Index = #self.Items + else + self._Index = tonumber(Index) + end + else + return self._Index + end +end + +function UIMenuListItem:ItemToIndex(Item) + for i = 1, #self.Items do + if type(Item) == type(self.Items[i]) and Item == self.Items[i] then + return i + elseif type(self.Items[i]) == "table" and (type(Item) == type(self.Items[i].Name) or type(Item) == type(self.Items[i].Value)) and (Item == self.Items[i].Name or Item == self.Items[i].Value) then + return i + end + end +end + +function UIMenuListItem:IndexToItem(Index) + if tonumber(Index) then + if tonumber(Index) == 0 then Index = 1 end + if self.Items[tonumber(Index)] then + return self.Items[tonumber(Index)] + end + end +end + +function UIMenuListItem:SetLeftBadge() + error("This item does not support badges") +end + +function UIMenuListItem:SetRightBadge() + error("This item does not support badges") +end + +function UIMenuListItem:RightLabel() + error("This item does not support a right label") +end + +function UIMenuListItem:AddPanel(Panel) + if Panel() == "UIMenuPanel" then + table.insert(self.Panels, Panel) + Panel:SetParentItem(self) + end +end + +function UIMenuListItem:RemovePanelAt(Index) + if tonumber(Index) then + if self.Panels[Index] then + table.remove(self.Panels, tonumber(Index)) + end + end +end + +function UIMenuListItem:FindPanelIndex(Panel) + if Panel() == "UIMenuPanel" then + for Index = 1, #self.Panels do + if self.Panels[Index] == Panel then + return Index + end + end + end + return nil +end + +function UIMenuListItem:FindPanelItem() + for Index = #self.Items, 1, -1 do + if self.Items[Index].Panel then + return Index + end + end + return nil +end + +function UIMenuListItem:Draw() + self.Base:Draw() + + if self:Enabled() then + if self:Selected() then + self.ItemText:Colour(0, 0, 0, 255) + self.LeftArrow:Colour(0, 0, 0, 255) + self.RightArrow:Colour(0, 0, 0, 255) + else + self.ItemText:Colour(245, 245, 245, 255) + self.LeftArrow:Colour(245, 245, 245, 255) + self.RightArrow:Colour(245, 245, 245, 255) + end + else + self.ItemText:Colour(163, 159, 148, 255) + self.LeftArrow:Colour(163, 159, 148, 255) + self.RightArrow:Colour(163, 159, 148, 255) + end + + local Text = (type(self.Items[self._Index]) == "table") and tostring(self.Items[self._Index].Name) or tostring(self.Items[self._Index]) + local Offset = MeasureStringWidth(Text, 0, 0.35) + + self.ItemText:Text(Text) + self.LeftArrow:Position(378 - Offset + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, self.LeftArrow.Y) + + if self:Selected() then + self.LeftArrow:Draw() + self.RightArrow:Draw() + self.ItemText:Position(403 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, self.ItemText.Y) + else + self.ItemText:Position(418 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, self.ItemText.Y) + end + + self.ItemText:Draw() +end + +--[[ + UIMenuSliderItem.lua + Items +--]] + +function UIMenuSliderItem.New(Text, Items, Index, Description, Divider) + if type(Items) ~= "table" then Items = {} end + if Index == 0 then Index = 1 end + local _UIMenuSliderItem = { + Base = UIMenuItem.New(Text or "", Description or ""), + Items = Items, + ShowDivider = tobool(Divider), + LeftArrow = Sprite.New("commonmenutu", "arrowleft", 0, 105, 15, 15), + RightArrow = Sprite.New("commonmenutu", "arrowright", 0, 105, 15, 15), + Background = UIResRectangle.New(0, 0, 150, 9, 15, 24, 33, 255), + Slider = UIResRectangle.New(0, 0, 75, 9, 72,109,149, 255), + Divider = UIResRectangle.New(0, 0, 2.5, 20, 245, 245, 245, 255), + _Index = tonumber(Index) or 1, + OnSliderChanged = function(menu, item, newindex) end, + OnSliderSelected = function(menu, item, newindex) end, + } + return setmetatable(_UIMenuSliderItem, UIMenuSliderItem) +end + +function UIMenuSliderItem:SetParentMenu(Menu) + if Menu() == "UIMenu" then + self.Base.ParentMenu = Menu + else + return self.Base.ParentMenu + end +end + +function UIMenuSliderItem:Position(Y) + if tonumber(Y) then + self.Background:Position(250 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, Y + 158.5 + self.Base._Offset.Y) + self.Slider:Position(250 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, Y + 158.5 + self.Base._Offset.Y) + self.Divider:Position(323.5 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, Y + 153 + self.Base._Offset.Y) + self.LeftArrow:Position(235 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 155.5 + Y + self.Base._Offset.Y) + self.RightArrow:Position(400 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 155.5 + Y + self.Base._Offset.Y) + self.Base:Position(Y) + end +end + +function UIMenuSliderItem:Selected(bool) + if bool ~= nil then + self.Base._Selected = tobool(bool) + else + return self.Base._Selected + end +end + +function UIMenuSliderItem:Hovered(bool) + if bool ~= nil then + self.Base._Hovered = tobool(bool) + else + return self.Base._Hovered + end +end + +function UIMenuSliderItem:Enabled(bool) + if bool ~= nil then + self.Base._Enabled = tobool(bool) + else + return self.Base._Enabled + end +end + +function UIMenuSliderItem:Description(str) + if tostring(str) and str ~= nil then + self.Base._Description = tostring(str) + else + return self.Base._Description + end +end + +function UIMenuSliderItem:Offset(X, Y) + if tonumber(X) or tonumber(Y) then + if tonumber(X) then + self.Base._Offset.X = tonumber(X) + end + if tonumber(Y) then + self.Base._Offset.Y = tonumber(Y) + end + else + return self.Base._Offset + end +end + +function UIMenuSliderItem:Text(Text) + if tostring(Text) and Text ~= nil then + self.Base.Text:Text(tostring(Text)) + else + return self.Base.Text:Text() + end +end + +function UIMenuSliderItem:Index(Index) + if tonumber(Index) then + if tonumber(Index) > #self.Items then + self._Index = 1 + elseif tonumber(Index) < 1 then + self._Index = #self.Items + else + self._Index = tonumber(Index) + end + else + return self._Index + end +end + +function UIMenuSliderItem:ItemToIndex(Item) + for i = 1, #self.Items do + if type(Item) == type(self.Items[i]) and Item == self.Items[i] then + return i + end + end +end + +function UIMenuSliderItem:IndexToItem(Index) + if tonumber(Index) then + if tonumber(Index) == 0 then Index = 1 end + if self.Items[tonumber(Index)] then + return self.Items[tonumber(Index)] + end + end +end + +function UIMenuSliderItem:SetLeftBadge() + error("This item does not support badges") +end + +function UIMenuSliderItem:SetRightBadge() + error("This item does not support badges") +end + +function UIMenuSliderItem:RightLabel() + error("This item does not support a right label") +end + +function UIMenuSliderItem:Draw() + self.Base:Draw() + + if self:Enabled() then + if self:Selected() then + self.LeftArrow:Colour(0, 0, 0, 255) + self.RightArrow:Colour(0, 0, 0, 255) + else + self.LeftArrow:Colour(245, 245, 245, 255) + self.RightArrow:Colour(245, 245, 245, 255) + end + else + self.LeftArrow:Colour(163, 159, 148, 255) + self.RightArrow:Colour(163, 159, 148, 255) + end + + local Offset = ((self.Background.Width - self.Slider.Width)/(#self.Items - 1)) * (self._Index-1) + + self.Slider:Position(250 + self.Base._Offset.X + Offset + self.Base.ParentMenu.WidthOffset, self.Slider.Y) + + if self:Selected() then + self.LeftArrow:Draw() + self.RightArrow:Draw() + end + + self.Background:Draw() + self.Slider:Draw() + if self.ShowDivider then + self.Divider:Draw() + end +end + +--[[ + UIMenuColouredItem.lua + Items +--]] + +function UIMenuColouredItem.New(Text, Description, MainColour, HighlightColour) + if type(Colour) ~= "table" then Colour = {R = 0, G = 0, B = 0, A = 255} end + if type(HighlightColour) ~= "table" then Colour = {R = 255, G = 255, B = 255, A = 255} end + local _UIMenuColouredItem = { + Base = UIMenuItem.New(Text or "", Description or ""), + Rectangle = UIResRectangle.New(0, 0, 431, 38, MainColour.R, MainColour.G, MainColour.B, MainColour.A), + MainColour = MainColour, + HighlightColour = HighlightColour, + Activated = function(menu, item) end, + } + _UIMenuColouredItem.Base.SelectedSprite:Colour(HighlightColour.R, HighlightColour.G, HighlightColour.B, HighlightColour.A) + return setmetatable(_UIMenuColouredItem, UIMenuColouredItem) +end + +function UIMenuColouredItem:SetParentMenu(Menu) + if Menu() == "UIMenu" then + self.Base.ParentMenu = Menu + else + return self.Base.ParentMenu + end +end + +function UIMenuColouredItem:Position(Y) + if tonumber(Y) then + self.Base:Position(Y) + self.Rectangle:Position(self.Base._Offset.X, Y + 144 + self.Base._Offset.Y) + end +end + +function UIMenuColouredItem:Selected(bool) + if bool ~= nil then + self.Base._Selected = tobool(bool) + else + return self.Base._Selected + end +end + +function UIMenuColouredItem:Hovered(bool) + if bool ~= nil then + self.Base._Hovered = tobool(bool) + else + return self.Base._Hovered + end +end + +function UIMenuColouredItem:Enabled(bool) + if bool ~= nil then + self.Base._Enabled = tobool(bool) + else + return self.Base._Enabled + end +end + +function UIMenuColouredItem:Description(str) + if tostring(str) and str ~= nil then + self.Base._Description = tostring(str) + else + return self.Base._Description + end +end + +function UIMenuColouredItem:Offset(X, Y) + if tonumber(X) or tonumber(Y) then + if tonumber(X) then + self.Base._Offset.X = tonumber(X) + end + if tonumber(Y) then + self.Base._Offset.Y = tonumber(Y) + end + else + return self.Base._Offset + end +end + +function UIMenuColouredItem:Text(Text) + if tostring(Text) and Text ~= nil then + self.Base.Text:Text(tostring(Text)) + else + return self.Base.Text:Text() + end +end + +function UIMenuColouredItem:RightLabel(Text, MainColour, HighlightColour) + if tostring(Text) and Text ~= nil then + if type(MainColour) == "table" then + self.Base.Label.MainColour = MainColour + end + if type(HighlightColour) == "table" then + self.Base.Label.HighlightColour = HighlightColour + end + self.Base.Label.Text:Text(tostring(Text)) + else + return self.Base.Label.Text:Text() + end +end + +function UIMenuColouredItem:SetLeftBadge(Badge) + if tonumber(Badge) then + self.Base.LeftBadge.Badge = tonumber(Badge) + end +end + +function UIMenuColouredItem:SetRightBadge(Badge) + if tonumber(Badge) then + self.Base.RightBadge.Badge = tonumber(Badge) + end +end + +function UIMenuColouredItem:Draw() + self.Rectangle:Size(431 + self.ParentMenu.WidthOffset, self.Rectangle.Height) + self.Rectangle:Draw() + self.Base:Draw() +end + +--[[ + UIMenuProgressItem.lua + Items +--]] + +function UIMenuProgressItem.New(Text, Items, Index, Description, Counter) + if type(Items) ~= "table" then Items = {} end + if Index == 0 then Index = 1 end + local _UIMenuProgressItem = { + Base = UIMenuItem.New(Text or "", Description or ""), + Data = { + Items = Items, + Counter = tobool(Counter), + Max = 407.5, + Index = tonumber(Index) or 1, + }, + Background = UIResRectangle.New(0, 0, 415, 20), + Bar = UIResRectangle.New(0, 0, 407.5, 12.5), + OnProgressChanged = function(menu, item, newindex) end, + OnProgressSelected = function(menu, item, newindex) end, + } + + _UIMenuProgressItem.Base.Rectangle.Height = 60 + _UIMenuProgressItem.Base.SelectedSprite.Height = 60 + + if _UIMenuProgressItem.Data.Counter then + _UIMenuProgressItem.Base:RightLabel(_UIMenuProgressItem.Data.Index.."/"..#_UIMenuProgressItem.Data.Items) + else + _UIMenuProgressItem.Base:RightLabel((type(_UIMenuProgressItem.Data.Items[_UIMenuProgressItem.Data.Index]) == "table") and tostring(_UIMenuProgressItem.Data.Items[_UIMenuProgressItem.Data.Index].Name) or tostring(_UIMenuProgressItem.Data.Items[_UIMenuProgressItem.Data.Index])) + end + + _UIMenuProgressItem.Bar.Width = _UIMenuProgressItem.Data.Index/#_UIMenuProgressItem.Data.Items * _UIMenuProgressItem.Data.Max + + return setmetatable(_UIMenuProgressItem, UIMenuProgressItem) +end + +function UIMenuProgressItem:SetParentMenu(Menu) + if Menu() == "UIMenu" then + self.Base.ParentMenu = Menu + else + return self.Base.ParentMenu + end +end + +function UIMenuProgressItem:Position(Y) + if tonumber(Y) then + self.Base:Position(Y) + self.Background:Position(8 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 177 + Y + self.Base._Offset.Y) + self.Bar:Position(11.75 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 180.75 + Y + self.Base._Offset.Y) + end +end + +function UIMenuProgressItem:Selected(bool) + if bool ~= nil then + self.Base._Selected = tobool(bool) + else + return self.Base._Selected + end +end + +function UIMenuProgressItem:Hovered(bool) + if bool ~= nil then + self.Base._Hovered = tobool(bool) + else + return self.Base._Hovered + end +end + +function UIMenuProgressItem:Enabled(bool) + if bool ~= nil then + self.Base._Enabled = tobool(bool) + else + return self.Base._Enabled + end +end + +function UIMenuProgressItem:Description(str) + if tostring(str) and str ~= nil then + self.Base._Description = tostring(str) + else + return self.Base._Description + end +end + +function UIMenuProgressItem:Offset(X, Y) + if tonumber(X) or tonumber(Y) then + if tonumber(X) then + self.Base._Offset.X = tonumber(X) + end + if tonumber(Y) then + self.Base._Offset.Y = tonumber(Y) + end + else + return self.Base._Offset + end +end + +function UIMenuProgressItem:Text(Text) + if tostring(Text) and Text ~= nil then + self.Base.Text:Text(tostring(Text)) + else + return self.Base.Text:Text() + end +end + +function UIMenuProgressItem:Index(Index) + if tonumber(Index) then + if tonumber(Index) > #self.Data.Items then + self.Data.Index = 1 + elseif tonumber(Index) < 1 then + self.Data.Index = #self.Data.Items + else + self.Data.Index = tonumber(Index) + end + + if self.Data.Counter then + self.Base:RightLabel(self.Data.Index.."/"..#self.Data.Items) + else + self.Base:RightLabel((type(self.Data.Items[self.Data.Index]) == "table") and tostring(self.Data.Items[self.Data.Index].Name) or tostring(self.Data.Items[self.Data.Index])) + end + + self.Bar.Width = self.Data.Index/#self.Data.Items * self.Data.Max + else + return self.Data.Index + end +end + +function UIMenuProgressItem:ItemToIndex(Item) + for i = 1, #self.Data.Items do + if type(Item) == type(self.Data.Items[i]) and Item == self.Data.Items[i] then + return i + elseif type(self.Data.Items[i]) == "table" and (type(Item) == type(self.Data.Items[i].Name) or type(Item) == type(self.Data.Items[i].Value)) and (Item == self.Data.Items[i].Name or Item == self.Data.Items[i].Value) then + return i + end + end +end + +function UIMenuProgressItem:IndexToItem(Index) + if tonumber(Index) then + if tonumber(Index) == 0 then Index = 1 end + if self.Data.Items[tonumber(Index)] then + return self.Data.Items[tonumber(Index)] + end + end +end + +function UIMenuProgressItem:SetLeftBadge() + error("This item does not support badges") +end + +function UIMenuProgressItem:SetRightBadge() + error("This item does not support badges") +end + +function UIMenuProgressItem:RightLabel() + error("This item does not support a right label") +end + +function UIMenuProgressItem:CalculateProgress(CursorX) + local Progress = CursorX - self.Bar.X + self:Index(math.round(#self.Data.Items * (((Progress >= 0 and Progress <= self.Data.Max) and Progress or ((Progress < 0) and 0 or self.Data.Max))/self.Data.Max))) +end + +function UIMenuProgressItem:Draw() + self.Base:Draw() + + if self.Base._Selected then + self.Background:Colour(table.unpack(Colours.Black)) + self.Bar:Colour(table.unpack(Colours.White)) + else + self.Background:Colour(table.unpack(Colours.White)) + self.Bar:Colour(table.unpack(Colours.Black)) + end + + self.Background:Draw() + self.Bar:Draw() +end + +--[[ + UIMenuHeritageWindow.lua + Windows +--]] + +function UIMenuHeritageWindow.New(Mum, Dad) + if not tonumber(Mum) then Mum = 0 end + if not (Mum >= 0 and Mum <= 21) then Mum = 0 end + if not tonumber(Dad) then Dad = 0 end + if not (Dad >= 0 and Dad <= 23) then Dad = 0 end + _UIMenuHeritageWindow = { + Background = Sprite.New("pause_menu_pages_char_mom_dad", "mumdadbg", 0, 0, 431, 228), -- Background is required, must be a sprite or a rectangle. + MumSprite = Sprite.New("char_creator_portraits", ((Mum < 21) and "female_"..Mum or "special_female_"..(tonumber(string.sub(Mum, 2, 2)) - 1)), 0, 0, 228, 228), + DadSprite = Sprite.New("char_creator_portraits", ((Dad < 21) and "male_"..Dad or "special_male_"..(tonumber(string.sub(Dad, 2, 2)) - 1)), 0, 0, 228, 228), + Mum = Mum, + Dad = Dad, + _Offset = {X = 0, Y = 0}, -- required + ParentMenu = nil, -- required + } + return setmetatable(_UIMenuHeritageWindow, UIMenuHeritageWindow) +end + +function UIMenuHeritageWindow:SetParentMenu(Menu) -- required + if Menu() == "UIMenu" then + self.ParentMenu = Menu + else + return self.ParentMenu + end +end + +function UIMenuHeritageWindow:Offset(X, Y) -- required + if tonumber(X) or tonumber(Y) then + if tonumber(X) then + self._Offset.X = tonumber(X) + end + if tonumber(Y) then + self._Offset.Y = tonumber(Y) + end + else + return self._Offset + end +end + +function UIMenuHeritageWindow:Position(Y) -- required + if tonumber(Y) then + self.Background:Position(self._Offset.X, 144 + Y + self._Offset.Y) + self.MumSprite:Position(self._Offset.X + (self.ParentMenu.WidthOffset/2) + 25, 144 + Y + self._Offset.Y) + self.DadSprite:Position(self._Offset.X + (self.ParentMenu.WidthOffset/2) + 195, 144 + Y + self._Offset.Y) + end +end + +function UIMenuHeritageWindow:Index(Mum, Dad) + if not tonumber(Mum) then Mum = self.Mum end + if not (Mum >= 0 and Mum <= 21) then Mum = self.Mum end + if not tonumber(Dad) then Dad = self.Dad end + if not (Dad >= 0 and Dad <= 23) then Dad = self.Dad end + + self.Mum = Mum + self.Dad = Dad + + self.MumSprite.TxtName = ((self.Mum < 21) and "female_"..self.Mum or "special_female_"..(tonumber(string.sub(Mum, 2, 2)) - 1)) + self.DadSprite.TxtName = ((self.Dad < 21) and "male_"..self.Dad or "special_male_"..(tonumber(string.sub(Dad, 2, 2)) - 1)) +end + +function UIMenuHeritageWindow:Draw() -- required + self.Background:Size(431 + self.ParentMenu.WidthOffset, 228) + self.Background:Draw() + self.DadSprite:Draw() + self.MumSprite:Draw() +end + +--[[ + UIMenuGridPanel.lua + Panels +--]] + +UIMenuGridPanel = setmetatable({}, UIMenuGridPanel) +UIMenuGridPanel.__index = UIMenuGridPanel +UIMenuGridPanel.__call = function() return "UIMenuPanel", "UIMenuGridPanel" end + +function UIMenuGridPanel.New(TopText, LeftText, RightText, BottomText) + _UIMenuGridPanel = { + Data = { + Enabled = true, + }, + Background = Sprite.New("commonmenu", "gradient_bgd", 0, 0, 431, 275), + Grid = Sprite.New("pause_menu_pages_char_mom_dad", "nose_grid", 0, 0, 200, 200, 0), + Circle = Sprite.New("mpinventory","in_world_circle", 0, 0, 20, 20, 0), + Audio = {Slider = "CONTINUOUS_SLIDER", Library = "HUD_FRONTEND_DEFAULT_SOUNDSET", Id = nil}, + ParentItem = nil, + Text = { + Top = UIResText.New(TopText or "Top", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"), + Left = UIResText.New(LeftText or "Left", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"), + Right = UIResText.New(RightText or "Right", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"), + Bottom = UIResText.New(BottomText or "Bottom", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"), + }, + } + return setmetatable(_UIMenuGridPanel, UIMenuGridPanel) +end + +function UIMenuGridPanel:SetParentItem(Item) -- required + if Item() == "UIMenuItem" then + self.ParentItem = Item + else + return self.ParentItem + end +end + +function UIMenuGridPanel:Enabled(Enabled) + if type(Enabled) == "boolean" then + self.Data.Enabled = Enabled + else + return self.Data.Enabled + end +end + +function UIMenuGridPanel:CirclePosition(X, Y) + if tonumber(X) and tonumber(Y) then + self.Circle.X = (self.Grid.X + 20) + ((self.Grid.Width - 40) * ((X >= 0.0 and X <= 1.0) and X or 0.0)) - (self.Circle.Width/2) + self.Circle.Y = (self.Grid.Y + 20) + ((self.Grid.Height - 40) * ((Y >= 0.0 and Y <= 1.0) and Y or 0.0)) - (self.Circle.Height/2) + else + return math.round((self.Circle.X - (self.Grid.X + 20) + (self.Circle.Width/2))/(self.Grid.Width - 40), 2), math.round((self.Circle.Y - (self.Grid.Y + 20) + (self.Circle.Height/2))/(self.Grid.Height - 40), 2) + end +end + +function UIMenuGridPanel:Position(Y) -- required + if tonumber(Y) then + local ParentOffsetX, ParentOffsetWidth = self.ParentItem:Offset().X, self.ParentItem:SetParentMenu().WidthOffset + + self.Background:Position(ParentOffsetX, Y) + self.Grid:Position(ParentOffsetX + 115.5 + (ParentOffsetWidth/2), 37.5 + Y) + self.Text.Top:Position(ParentOffsetX + 215.5 + (ParentOffsetWidth/2), 5 + Y) + self.Text.Left:Position(ParentOffsetX + 57.75 + (ParentOffsetWidth/2), 120 + Y) + self.Text.Right:Position(ParentOffsetX + 373.25 + (ParentOffsetWidth/2), 120 + Y) + self.Text.Bottom:Position(ParentOffsetX + 215.5 + (ParentOffsetWidth/2), 240 + Y) + + if not self.CircleLocked then + self.CircleLocked = true + self:CirclePosition(0.5, 0.5) + end + end +end + +function UIMenuGridPanel:UpdateParent(X, Y) + local _, ParentType = self.ParentItem() + if ParentType == "UIMenuListItem" then + local PanelItemIndex = self.ParentItem:FindPanelItem() + if PanelItemIndex then + self.ParentItem.Items[PanelItemIndex].Value[self.ParentItem:FindPanelIndex(self)] = {X = X, Y = Y} + self.ParentItem:Index(PanelItemIndex) + self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + else + local PanelIndex = self.ParentItem:FindPanelIndex(self) + for Index = 1, #self.ParentItem.Items do + if type(self.ParentItem.Items[Index]) == "table" then + if not self.ParentItem.Items[Index].Panels then self.ParentItem.Items[Index].Panels = {} end + self.ParentItem.Items[Index].Panels[PanelIndex] = {X = X, Y = Y} + else + self.ParentItem.Items[Index] = {Name = tostring(self.ParentItem.Items[Index]), Value = self.ParentItem.Items[Index], Panels = {[PanelIndex] = {X = X, Y = Y}}} + end + end + self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + end + elseif ParentType == "UIMenuItem" then + self.ParentItem.ActivatedPanel(self.ParentItem.ParentMenu, self.ParentItem, self, {X = X, Y = Y}) + end +end + +function UIMenuGridPanel:Functions() + local SafeZone = {X = 0, Y = 0} + if self.ParentItem:SetParentMenu().Settings.ScaleWithSafezone then + SafeZone = GetSafeZoneBounds() + end + + if IsMouseInBounds(self.Grid.X + 20 + SafeZone.X, self.Grid.Y + 20 + SafeZone.Y, self.Grid.Width - 40, self.Grid.Height - 40) then + if IsDisabledControlJustPressed(1, 24) and IsInputDisabled(0) then + if not self.Pressed then + self.Pressed = true + Citizen.CreateThread(function() + self.Audio.Id = GetSoundId() + PlaySoundFrontend(self.Audio.Id, self.Audio.Slider, self.Audio.Library, 1) + while IsDisabledControlPressed(0, 24) and IsMouseInBounds(self.Grid.X + 20 + SafeZone.X, self.Grid.Y + 20 + SafeZone.Y, self.Grid.Width - 40, self.Grid.Height - 40) do + Citizen.Wait(0) + local CursorX, CursorY = math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X - (self.Circle.Width/2), math.round(GetControlNormal(0, 240) * 1080) - SafeZone.Y - (self.Circle.Height/2) + + self.Circle:Position(((CursorX > (self.Grid.X + 10 + self.Grid.Width - 40)) and (self.Grid.X + 10 + self.Grid.Width - 40) or ((CursorX < (self.Grid.X + 20 - (self.Circle.Width/2))) and (self.Grid.X + 20 - (self.Circle.Width/2)) or CursorX)), ((CursorY > (self.Grid.Y + 10 + self.Grid.Height - 40)) and (self.Grid.Y + 10 + self.Grid.Height - 40) or ((CursorY < (self.Grid.Y + 20 - (self.Circle.Height/2))) and (self.Grid.Y + 20 - (self.Circle.Height/2)) or CursorY))) + end + StopSound(self.Audio.Id) + ReleaseSoundId(self.Audio.Id) + self.Pressed = false + end) + Citizen.CreateThread(function() + while IsDisabledControlPressed(0, 24) and IsMouseInBounds(self.Grid.X + 20 + SafeZone.X, self.Grid.Y + 20 + SafeZone.Y, self.Grid.Width - 40, self.Grid.Height - 40) do + Citizen.Wait(75) + local ResultX, ResultY = math.round((self.Circle.X - (self.Grid.X + 20) + (self.Circle.Width/2))/(self.Grid.Width - 40), 2), math.round((self.Circle.Y - (self.Grid.Y + 20) + (self.Circle.Height/2))/(self.Grid.Height - 40), 2) + + self:UpdateParent((((ResultX >= 0.0 and ResultX <= 1.0) and ResultX or ((ResultX <= 0) and 0.0) or 1.0) * 2) - 1, (((ResultY >= 0.0 and ResultY <= 1.0) and ResultY or ((ResultY <= 0) and 0.0) or 1.0) * 2) - 1) + end + end) + end + end + end +end + +function UIMenuGridPanel:Draw() -- required + if self.Data.Enabled then + self.Background:Size(431 + self.ParentItem:SetParentMenu().WidthOffset, 275) + + self.Background:Draw() + self.Grid:Draw() + self.Circle:Draw() + self.Text.Top:Draw() + self.Text.Left:Draw() + self.Text.Right:Draw() + self.Text.Bottom:Draw() + self:Functions() + end +end + +--[[ + UIMenuColourPanel.lua + Panels +--]] + +UIMenuColourPanel = setmetatable({}, UIMenuColourPanel) +UIMenuColourPanel.__index = UIMenuColourPanel +UIMenuColourPanel.__call = function() return "UIMenuPanel", "UIMenuColourPanel" end + +function UIMenuColourPanel.New(Title, Colours) + _UIMenuColourPanel = { + Data = { + Pagination = { + Min = 1, + Max = 8, + Total = 8, + }, + Index = 1000, + Items = Colours, + Title = Title or "Title", + Enabled = true, + Value = 1, + }, + Background = Sprite.New("commonmenu", "gradient_bgd", 0, 0, 431, 112), + Bar = {}, + LeftArrow = Sprite.New("commonmenu", "arrowleft", 0, 0, 30, 30), + RightArrow = Sprite.New("commonmenu", "arrowright", 0, 0, 30, 30), + SelectedRectangle = UIResRectangle.New(0, 0, 44.5, 8), + Text = UIResText.New(Title.." (1 of "..#Colours..")" or "Title".." (1 of "..#Colours..")", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"), + ParentItem = nil, + } + + for Index = 1, #Colours do + if Index < 10 then + table.insert(_UIMenuColourPanel.Bar, UIResRectangle.New(0, 0, 44.5, 44.5, table.unpack(Colours[Index]))) + else + break + end + end + + if #_UIMenuColourPanel.Data.Items ~= 0 then + _UIMenuColourPanel.Data.Index = 1000 - (1000 % #_UIMenuColourPanel.Data.Items) + _UIMenuColourPanel.Data.Pagination.Max = _UIMenuColourPanel.Data.Pagination.Total + 1 + _UIMenuColourPanel.Data.Pagination.Min = 0 + end + return setmetatable(_UIMenuColourPanel, UIMenuColourPanel) +end + +function UIMenuColourPanel:SetParentItem(Item) -- required + if Item() == "UIMenuItem" then + self.ParentItem = Item + else + return self.ParentItem + end +end + +function UIMenuColourPanel:Enabled(Enabled) + if type(Enabled) == "boolean" then + self.Data.Enabled = Enabled + else + return self.Data.Enabled + end +end + +function UIMenuColourPanel:Position(Y) -- required + if tonumber(Y) then + local ParentOffsetX, ParentOffsetWidth = self.ParentItem:Offset().X, self.ParentItem:SetParentMenu().WidthOffset + + self.Background:Position(ParentOffsetX, Y) + for Index = 1, #self.Bar do + self.Bar[Index]:Position(15 + (44.5 * (Index - 1)) + ParentOffsetX + (ParentOffsetWidth/2), 55 + Y) + end + self.SelectedRectangle:Position(15 + (44.5 * ((self:CurrentSelection() - self.Data.Pagination.Min) - 1)) + ParentOffsetX + (ParentOffsetWidth/2), 47 + Y) + self.LeftArrow:Position(7.5 + ParentOffsetX + (ParentOffsetWidth/2), 15 + Y) + self.RightArrow:Position(393.5 + ParentOffsetX + (ParentOffsetWidth/2), 15 + Y) + self.Text:Position(215.5 + ParentOffsetX + (ParentOffsetWidth/2), 15 + Y) + end +end + +function UIMenuColourPanel:CurrentSelection(value, PreventUpdate) + if tonumber(value) then + if #self.Data.Items == 0 then + self.Data.Index = 0 + end + + self.Data.Index = 1000000 - (1000000 % #self.Data.Items) + tonumber(value) + + if self:CurrentSelection() > self.Data.Pagination.Max then + self.Data.Pagination.Min = self:CurrentSelection() - (self.Data.Pagination.Total + 1) + self.Data.Pagination.Max = self:CurrentSelection() + elseif self:CurrentSelection() < self.Data.Pagination.Min then + self.Data.Pagination.Min = self:CurrentSelection() - 1 + self.Data.Pagination.Max = self:CurrentSelection() + (self.Data.Pagination.Total + 1) + end + + self:UpdateSelection(PreventUpdate) + else + if #self.Data.Items == 0 then + return 1 + else + if self.Data.Index % #self.Data.Items == 0 then + return 1 + else + return self.Data.Index % #self.Data.Items + 1 + end + end + end +end + +function UIMenuColourPanel:UpdateParent(Colour) + local _, ParentType = self.ParentItem() + if ParentType == "UIMenuListItem" then + local PanelItemIndex = self.ParentItem:FindPanelItem() + local PanelIndex = self.ParentItem:FindPanelIndex(self) + if PanelItemIndex then + self.ParentItem.Items[PanelItemIndex].Value[PanelIndex] = Colour + self.ParentItem:Index(PanelItemIndex) + self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + else + for Index = 1, #self.ParentItem.Items do + if type(self.ParentItem.Items[Index]) == "table" then + if not self.ParentItem.Items[Index].Panels then self.ParentItem.Items[Index].Panels = {} end + self.ParentItem.Items[Index].Panels[PanelIndex] = Colour + else + self.ParentItem.Items[Index] = {Name = tostring(self.ParentItem.Items[Index]), Value = self.ParentItem.Items[Index], Panels = {[PanelIndex] = Colour}} + end + end + self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + end + elseif ParentType == "UIMenuItem" then + self.ParentItem.ActivatedPanel(self.ParentItem.ParentMenu, self.ParentItem, self, Colour) + end +end + +function UIMenuColourPanel:UpdateSelection(PreventUpdate) + local CurrentSelection = self:CurrentSelection() + if not PreventUpdate then + self:UpdateParent(CurrentSelection) + end + self.SelectedRectangle:Position(15 + (44.5 * ((CurrentSelection - self.Data.Pagination.Min) - 1)) + self.ParentItem:Offset().X, self.SelectedRectangle.Y) + for Index = 1, 9 do + self.Bar[Index]:Colour(table.unpack(self.Data.Items[self.Data.Pagination.Min + Index])) + end + self.Text:Text(self.Data.Title.." ("..CurrentSelection.." of "..#self.Data.Items..")") +end + +function UIMenuColourPanel:Functions() + + local SafeZone = {X = 0, Y = 0} + if self.ParentItem:SetParentMenu().Settings.ScaleWithSafezone then + SafeZone = GetSafeZoneBounds() + end + + + if IsMouseInBounds(self.LeftArrow.X + SafeZone.X, self.LeftArrow.Y + SafeZone.Y, self.LeftArrow.Width, self.LeftArrow.Height) then + if IsDisabledControlJustPressed(1, 24) and IsInputDisabled(0) then + if #self.Data.Items > self.Data.Pagination.Total + 1 then + if self:CurrentSelection() <= self.Data.Pagination.Min + 1 then + if self:CurrentSelection() == 1 then + self.Data.Pagination.Min = #self.Data.Items - (self.Data.Pagination.Total + 1) + self.Data.Pagination.Max = #self.Data.Items + self.Data.Index = 1000 - (1000 % #self.Data.Items) + self.Data.Index = self.Data.Index + (#self.Data.Items - 1) + self:UpdateSelection() + else + self.Data.Pagination.Min = self.Data.Pagination.Min - 1 + self.Data.Pagination.Max = self.Data.Pagination.Max - 1 + self.Data.Index = self.Data.Index - 1 + self:UpdateSelection() + end + else + self.Data.Index = self.Data.Index - 1 + self:UpdateSelection() + end + else + self.Data.Index = self.Data.Index - 1 + self:UpdateSelection() + end + end + end + + if IsMouseInBounds(self.RightArrow.X + SafeZone.X, self.RightArrow.Y + SafeZone.Y, self.RightArrow.Width, self.RightArrow.Height) then + if IsDisabledControlJustPressed(1, 24) and IsInputDisabled(0) then + if #self.Data.Items > self.Data.Pagination.Total + 1 then + if self:CurrentSelection() >= self.Data.Pagination.Max then + if self:CurrentSelection() == #self.Data.Items then + self.Data.Pagination.Min = 0 + self.Data.Pagination.Max = self.Data.Pagination.Total + 1 + self.Data.Index = 1000 - (1000 % #self.Data.Items) + self:UpdateSelection() + else + self.Data.Pagination.Max = self.Data.Pagination.Max + 1 + self.Data.Pagination.Min = self.Data.Pagination.Max - (self.Data.Pagination.Total + 1) + self.Data.Index = self.Data.Index + 1 + self:UpdateSelection() + end + else + self.Data.Index = self.Data.Index + 1 + self:UpdateSelection() + end + else + self.Data.Index = self.Data.Index + 1 + self:UpdateSelection() + end + end + end + + for Index = 1, #self.Bar do + if IsMouseInBounds(self.Bar[Index].X + SafeZone.X, self.Bar[Index].Y + SafeZone.Y, self.Bar[Index].Width, self.Bar[Index].Height) then + if IsDisabledControlJustPressed(1, 24) and IsInputDisabled(0) then + self:CurrentSelection(self.Data.Pagination.Min + Index - 1) + end + end + end +end + +function UIMenuColourPanel:Draw() -- required + if self.Data.Enabled then + self.Background:Size(431 + self.ParentItem:SetParentMenu().WidthOffset, 112) + + self.Background:Draw() + self.LeftArrow:Draw() + self.RightArrow:Draw() + self.Text:Draw() + self.SelectedRectangle:Draw() + for Index = 1, #self.Bar do + self.Bar[Index]:Draw() + end + self:Functions() + end +end + +--[[ + UIMenuPercentagePanel.lua + Panels +--]] + +UIMenuPercentagePanel = setmetatable({}, UIMenuPercentagePanel) +UIMenuPercentagePanel.__index = UIMenuPercentagePanel +UIMenuPercentagePanel.__call = function() return "UIMenuPanel", "UIMenuPercentagePanel" end + +function UIMenuPercentagePanel.New(MinText, MaxText) + _UIMenuPercentagePanel = { + Data = { + Enabled = true, + }, + Background = Sprite.New("commonmenu", "gradient_bgd", 0, 0, 431, 76), + ActiveBar = UIResRectangle.New(0, 0, 413, 10, 245, 245, 245, 255), + BackgroundBar = UIResRectangle.New(0, 0, 413, 10, 87, 87, 87, 255), + Text = { + Min = UIResText.New(MinText or "0%", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"), + Max = UIResText.New("100%", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"), + Title = UIResText.New(MaxText or "Opacity", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"), + }, + Audio = {Slider = "CONTINUOUS_SLIDER", Library = "HUD_FRONTEND_DEFAULT_SOUNDSET", Id = nil}, + ParentItem = nil, + } + + return setmetatable(_UIMenuPercentagePanel, UIMenuPercentagePanel) +end + +function UIMenuPercentagePanel:SetParentItem(Item) -- required + if Item() == "UIMenuItem" then + self.ParentItem = Item + else + return self.ParentItem + end +end + +function UIMenuPercentagePanel:Enabled(Enabled) + if type(Enabled) == "boolean" then + self.Data.Enabled = Enabled + else + return self.Data.Enabled + end +end + +function UIMenuPercentagePanel:Position(Y) -- required + if tonumber(Y) then + local ParentOffsetX, ParentOffsetWidth = self.ParentItem:Offset().X, self.ParentItem:SetParentMenu().WidthOffset + self.Background:Position(ParentOffsetX, Y) + self.ActiveBar:Position(ParentOffsetX + (ParentOffsetWidth/2) + 9, 50 + Y) + self.BackgroundBar:Position(ParentOffsetX + (ParentOffsetWidth/2) + 9, 50 + Y) + self.Text.Min:Position(ParentOffsetX + (ParentOffsetWidth/2) + 25, 15 + Y) + self.Text.Max:Position(ParentOffsetX + (ParentOffsetWidth/2) + 398, 15 + Y) + self.Text.Title:Position(ParentOffsetX + (ParentOffsetWidth/2) + 215.5, 15 + Y) + end +end + +function UIMenuPercentagePanel:Percentage(Value) + if tonumber(Value) then + local Percent = ((Value < 0.0) and 0.0) or ((Value > 1.0) and 1.0 or Value) + self.ActiveBar:Size(self.BackgroundBar.Width * Percent, self.ActiveBar.Height) + else + local SafeZone = {X = 0, Y = 0} + if self.ParentItem:SetParentMenu().Settings.ScaleWithSafezone then + SafeZone = GetSafeZoneBounds() + end + + local Progress = (math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X) - self.ActiveBar.X + return math.round(((Progress >= 0 and Progress <= 413) and Progress or ((Progress < 0) and 0 or 413))/self.BackgroundBar.Width, 2) + end +end + +function UIMenuPercentagePanel:UpdateParent(Percentage) + local _, ParentType = self.ParentItem() + if ParentType == "UIMenuListItem" then + local PanelItemIndex = self.ParentItem:FindPanelItem() + if PanelItemIndex then + self.ParentItem.Items[PanelItemIndex].Value[self.ParentItem:FindPanelIndex(self)] = Percentage + self.ParentItem:Index(PanelItemIndex) + self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + else + local PanelIndex = self.ParentItem:FindPanelIndex(self) + for Index = 1, #self.ParentItem.Items do + if type(self.ParentItem.Items[Index]) == "table" then + if not self.ParentItem.Items[Index].Panels then self.ParentItem.Items[Index].Panels = {} end + self.ParentItem.Items[Index].Panels[PanelIndex] = Percentage + else + self.ParentItem.Items[Index] = {Name = tostring(self.ParentItem.Items[Index]), Value = self.ParentItem.Items[Index], Panels = {[PanelIndex] = Percentage}} + end + end + self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index) + end + elseif ParentType == "UIMenuItem" then + self.ParentItem.ActivatedPanel(self.ParentItem.ParentMenu, self.ParentItem, self, Percentage) + end +end + +function UIMenuPercentagePanel:Functions() + + local SafeZone = {X = 0, Y = 0} + if self.ParentItem:SetParentMenu().Settings.ScaleWithSafezone then + SafeZone = GetSafeZoneBounds() + end + + if IsMouseInBounds(self.BackgroundBar.X + SafeZone.X, self.BackgroundBar.Y - 4 + SafeZone.Y, self.BackgroundBar.Width, self.BackgroundBar.Height + 8) then + if IsDisabledControlJustPressed(1, 24) and IsInputDisabled(0) then + if not self.Pressed then + self.Pressed = true + Citizen.CreateThread(function() + self.Audio.Id = GetSoundId() + PlaySoundFrontend(self.Audio.Id, self.Audio.Slider, self.Audio.Library, 1) + while IsDisabledControlPressed(0, 24) and IsMouseInBounds(self.BackgroundBar.X + SafeZone.X, self.BackgroundBar.Y - 4 + SafeZone.Y, self.BackgroundBar.Width, self.BackgroundBar.Height + 8) do + Citizen.Wait(0) + local Progress = (math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X) - self.ActiveBar.X + self.ActiveBar:Size(((Progress >= 0 and Progress <= 413) and Progress or ((Progress < 0) and 0 or 413)), self.ActiveBar.Height) + end + StopSound(self.Audio.Id) + ReleaseSoundId(self.Audio.Id) + self.Pressed = false + end) + Citizen.CreateThread(function() + while IsDisabledControlPressed(0, 24) and IsMouseInBounds(self.BackgroundBar.X + SafeZone.X, self.BackgroundBar.Y - 4 + SafeZone.Y, self.BackgroundBar.Width, self.BackgroundBar.Height + 8) do + Citizen.Wait(75) + local Progress = (math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X) - self.ActiveBar.X + self:UpdateParent(math.round(((Progress >= 0 and Progress <= 413) and Progress or ((Progress < 0) and 0 or 413))/self.BackgroundBar.Width, 2)) + end + end) + end + end + end +end + +function UIMenuPercentagePanel:Draw() -- required + if self.Data.Enabled then + self.Background:Size(431 + self.ParentItem:SetParentMenu().WidthOffset, 76) + self.Background:Draw() + self.BackgroundBar:Draw() + self.ActiveBar:Draw() + self.Text.Min:Draw() + self.Text.Max:Draw() + self.Text.Title:Draw() + self:Functions() + end +end + +--[[ + UIMenu.lua + Menus +--]] + +function UIMenu.New(Title, Subtitle, X, Y, TxtDictionary, TxtName, titleTxt) + local X, Y = tonumber(X) or 0, tonumber(Y) or 0 + if Title ~= nil then Title = tostring(Title) or "" else Title = "" end + if Subtitle ~= nil then Subtitle = tostring(Subtitle) or "" else Subtitle = "" end + if TxtDictionary ~= nil then TxtDictionary = tostring(TxtDictionary) or "commonmenu" else TxtDictionary = "commonmenu" end + if TxtName ~= nil then TxtName = tostring(TxtName) or "interaction_bgd" else TxtName = "interaction_bgd" end + if titleTxt then + thisTitle = Sprite.New(TxtDictionary, titleTxt, 0 + X, 0 + Y, 431, 107) + else + thisTitle = UIResText.New(Title, 215 + X, 20 + Y, 1.15, 255, 255, 255, 255, 1, 1) + end + local _UIMenu = { + Logo = Sprite.New(TxtDictionary, TxtName, 0 + X, 0 + Y, 431, 107), + Banner = nil, + Title = thisTitle, + Subtitle = {ExtraY = 0}, + WidthOffset = 0, + Position = {X = X, Y = Y}, + Pagination = {Min = 0, Max = 9, Total = 9}, + PageCounter = {PreText = ""}, + Extra = {}, + Description = {}, + Items = {}, + Windows = {}, + Children = {}, + TxtDictionary = TxtDictionary, + TxtName = TxtName, + titleTxt = titleTxt, + Controls = { + Back = { + Enabled = true, + }, + Select = { + Enabled = true, + }, + Left = { + Enabled = true, + }, + Right = { + Enabled = true, + }, + Up = { + Enabled = true, + }, + Down = { + Enabled = true, + }, + }, + ParentMenu = nil, + ParentItem = nil, + _Visible = false, + ActiveItem = 1000, + Dirty = false; + ReDraw = true, + InstructionalScaleform = RequestScaleformMovie("INSTRUCTIONAL_BUTTONS"), + InstructionalButtons = {}, + OnIndexChange = function(menu, newindex) end, + OnListChange = function(menu, list, newindex) end, + OnSliderChange = function(menu, slider, newindex) end, + OnProgressChange = function(menu, progress, newindex) end, + OnCheckboxChange = function(menu, item, checked) end, + OnListSelect = function(menu, list, index) end, + OnSliderSelect = function(menu, slider, index) end, + OnProgressSelect = function(menu, progress, index) end, + OnItemSelect = function(menu, item, index) end, + OnMenuChanged = function(menu, newmenu, forward) end, + OnMenuClosed = function(menu) end, + Settings = { + InstructionalButtons = true, + MultilineFormats = true, + ScaleWithSafezone = true, + ResetCursorOnOpen = true, + MouseControlsEnabled = true, + MouseEdgeEnabled = true, + ControlDisablingEnabled = true, + Audio = { + Library = "HUD_FRONTEND_DEFAULT_SOUNDSET", + UpDown = "NAV_UP_DOWN", + LeftRight = "NAV_LEFT_RIGHT", + Select = "SELECT", + Back = "BACK", + Error = "ERROR", + }, + EnabledControls = { + Controller = { + {0, 2}, -- Look Up and Down + {0, 1}, -- Look Left and Right + {0, 25}, -- Aim + {0, 24}, -- Attack + }, + Keyboard = { + {0, 201}, -- Select + {0, 195}, -- X axis + {0, 196}, -- Y axis + {0, 187}, -- Down + {0, 188}, -- Up + {0, 189}, -- Left + {0, 190}, -- Right + {0, 202}, -- Back + {0, 217}, -- Select + {0, 242}, -- Scroll down + {0, 241}, -- Scroll up + {0, 239}, -- Cursor X + {0, 240}, -- Cursor Y + {0, 31}, -- Move Up and Down + {0, 30}, -- Move Left and Right + {0, 21}, -- Sprint + {0, 22}, -- Jump + {0, 23}, -- Enter + {0, 75}, -- Exit Vehicle + {0, 71}, -- Accelerate Vehicle + {0, 72}, -- Vehicle Brake + {0, 59}, -- Move Vehicle Left and Right + {0, 89}, -- Fly Yaw Left + {0, 9}, -- Fly Left and Right + {0, 8}, -- Fly Up and Down + {0, 90}, -- Fly Yaw Right + {0, 76}, -- Vehicle Handbrake + }, + } + } + } + + if Subtitle ~= "" and Subtitle ~= nil then + _UIMenu.Subtitle.Rectangle = UIResRectangle.New(0 + _UIMenu.Position.X, 107 + _UIMenu.Position.Y, 431, 37, 0, 0, 0, 255) + _UIMenu.Subtitle.Text = UIResText.New(Subtitle, 8 + _UIMenu.Position.X, 110 + _UIMenu.Position.Y, 0.35, 245, 245, 245, 255, 0) + _UIMenu.Subtitle.BackupText = Subtitle + _UIMenu.Subtitle.Formatted = false + if string.starts(Subtitle, "~") then + _UIMenu.PageCounter.PreText = string.sub(Subtitle, 1, 3) + end + _UIMenu.PageCounter.Text = UIResText.New("", 425 + _UIMenu.Position.X, 110 + _UIMenu.Position.Y, 0.35, 245, 245, 245, 255, 0, "Right") + _UIMenu.Subtitle.ExtraY = 37 + end + + _UIMenu.ArrowSprite = Sprite.New("commonmenu", "shop_arrows_upanddown", 190 + _UIMenu.Position.X, 147 + 37 * (_UIMenu.Pagination.Total + 1) + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 50, 50) + _UIMenu.Extra.Up = UIResRectangle.New(0 + _UIMenu.Position.X, 144 + 38 * (_UIMenu.Pagination.Total + 1) + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 431, 18, 0, 0, 0, 200) + _UIMenu.Extra.Down = UIResRectangle.New(0 + _UIMenu.Position.X, 144 + 18 + 38 * (_UIMenu.Pagination.Total + 1) + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 431, 18, 0, 0, 0, 200) + + _UIMenu.Description.Bar = UIResRectangle.New(_UIMenu.Position.X, 123, 431, 4, 0, 0, 0, 255) + _UIMenu.Description.Rectangle = Sprite.New("commonmenu", "gradient_bgd", _UIMenu.Position.X, 127, 431, 30) + _UIMenu.Description.Text = UIResText.New("Description", _UIMenu.Position.X + 5, 125, 0.35) + + _UIMenu.Background = Sprite.New("commonmenu", "gradient_bgd", _UIMenu.Position.X, 144 + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 290, 25) + + Citizen.CreateThread(function() + if not HasScaleformMovieLoaded(_UIMenu.InstructionalScaleform) then + _UIMenu.InstructionalScaleform = RequestScaleformMovie("INSTRUCTIONAL_BUTTONS") + while not HasScaleformMovieLoaded(_UIMenu.InstructionalScaleform) do + Citizen.Wait(0) + end + end + end) + return setmetatable(_UIMenu, UIMenu) +end + +function UIMenu:SetMenuWidthOffset(Offset) + if tonumber(Offset) then + self.WidthOffset = math.floor(tonumber(Offset)) + self.Logo:Size(431 + self.WidthOffset, 107) + if self.Title.TxtName then + self.Title:Position(((self.WidthOffset + 0)/2) + self.Position.X, 0 + self.Position.Y) + else + self.Title:Position(((self.WidthOffset + 431)/2) + self.Position.X, 20 + self.Position.Y) + end + if self.Subtitle.Rectangle ~= nil then + self.Subtitle.Rectangle:Size(431 + self.WidthOffset + 100, 37) + self.PageCounter.Text:Position(425 + self.Position.X + self.WidthOffset, 110 + self.Position.Y) + end + if self.Banner ~= nil then + self.Banner:Size(431 + self.WidthOffset, 107) + end + end +end + +function UIMenu:DisEnableControls(bool) + if bool then + EnableAllControlActions(2) + else + DisableAllControlActions(2) + end + + if bool then + return + else + if Controller() then + for Index = 1, #self.Settings.EnabledControls.Controller do + EnableControlAction(self.Settings.EnabledControls.Controller[Index][1], self.Settings.EnabledControls.Controller[Index][2], true) + end + else + for Index = 1, #self.Settings.EnabledControls.Keyboard do + EnableControlAction(self.Settings.EnabledControls.Keyboard[Index][1], self.Settings.EnabledControls.Keyboard[Index][2], true) + end + end + end +end + +function UIMenu:InstructionalButtons(bool) + if bool ~= nil then + self.Settings.InstrucitonalButtons = tobool(bool) + end +end + +function UIMenu:SetBannerSprite(Sprite, IncludeChildren) + if Sprite() == "Sprite" then + self.Logo = Sprite + self.Logo:Size(431 + self.WidthOffset, 107) + self.Logo:Position(self.Position.X, self.Position.Y) + self.Banner = nil + if IncludeChildren then + for Item, Menu in pairs(self.Children) do + Menu.Logo = Sprite + Menu.Logo:Size(431 + self.WidthOffset, 107) + Menu.Logo:Position(self.Position.X, self.Position.Y) + Menu.Banner = nil + end + end + end +end + +function UIMenu:SetBannerRectangle(Rectangle, IncludeChildren) + if Rectangle() == "Rectangle" then + self.Banner = Rectangle + self.Banner:Size(431 + self.WidthOffset, 107) + self.Banner:Position(self.Position.X, self.Position.Y) + self.Logo = nil + if IncludeChildren then + for Item, Menu in pairs(self.Children) do + Menu.Banner = Rectangle + Menu.Banner:Size(431 + self.WidthOffset, 107) + Menu:Position(self.Position.X, self.Position.Y) + Menu.Logo = nil + end + end + end +end + +function UIMenu:CurrentSelection(value) + if tonumber(value) then + if #self.Items == 0 then + self.ActiveItem = 0 + end + + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = 1000000 - (1000000 % #self.Items) + tonumber(value) + + if self:CurrentSelection() > self.Pagination.Max then + self.Pagination.Min = self:CurrentSelection() - self.Pagination.Total + self.Pagination.Max = self:CurrentSelection() + elseif self:CurrentSelection() < self.Pagination.Min then + self.Pagination.Min = self:CurrentSelection() + self.Pagination.Max = self:CurrentSelection() + self.Pagination.Total + end + else + if #self.Items == 0 then + return 1 + else + if self.ActiveItem % #self.Items == 0 then + return 1 + else + return self.ActiveItem % #self.Items + 1 + end + end + end +end + +function UIMenu:CalculateWindowHeight() + local Height = 0 + for i = 1, #self.Windows do + Height = Height + self.Windows[i].Background:Size().Height + end + return Height +end + +function UIMenu:CalculateItemHeightOffset(Item) + if Item.Base then + return Item.Base.Rectangle.Height + else + return Item.Rectangle.Height + end +end + +function UIMenu:CalculateItemHeight() + local ItemOffset = 0 + self.Subtitle.ExtraY - 37 + for i = self.Pagination.Min + 1, self.Pagination.Max do + local Item = self.Items[i] + if Item ~= nil then + ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item) + end + end + return ItemOffset +end + +function UIMenu:RecalculateDescriptionPosition() + local WindowHeight = self:CalculateWindowHeight() + self.Description.Bar:Position(self.Position.X, 149 + self.Position.Y + WindowHeight) + self.Description.Rectangle:Position(self.Position.X, 149 + self.Position.Y + WindowHeight) + self.Description.Text:Position(self.Position.X + 8, 155 + self.Position.Y + WindowHeight) + + self.Description.Bar:Size(431 + self.WidthOffset, 4) + self.Description.Rectangle:Size(431 + self.WidthOffset, 30) + + self.Description.Bar:Position(self.Position.X, self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + self.Description.Bar:Position().Y) + self.Description.Rectangle:Position(self.Position.X, self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + self.Description.Rectangle:Position().Y) + self.Description.Text:Position(self.Position.X + 8, self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + self.Description.Text:Position().Y) +end + +function UIMenu:CaclulatePanelPosition(HasDescription) + local Height = self:CalculateWindowHeight() + 149 + self.Position.Y + + if HasDescription then + Height = Height + self.Description.Rectangle:Size().Height + 5 + end + + return self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + Height +end + +function UIMenu:AddWindow(Window) + if Window() == "UIMenuWindow" then + Window:SetParentMenu(self) + Window:Offset(self.Position.X, self.Position.Y) + table.insert(self.Windows, Window) + self.ReDraw = true + self:RecalculateDescriptionPosition() + end +end + +function UIMenu:RemoveWindowAt(Index) + if tonumber(Index) then + if self.Windows[Index] then + table.remove(self.Windows, Index) + self.ReDraw = true + self:RecalculateDescriptionPosition() + end + end +end + +function UIMenu:AddItem(Item) + if Item() == "UIMenuItem" then + local SelectedItem = self:CurrentSelection() + Item:SetParentMenu(self) + Item:Offset(self.Position.X, self.Position.Y) + Item:Position((#self.Items * 25) - 37 + self.Subtitle.ExtraY) + table.insert(self.Items, Item) + self:RecalculateDescriptionPosition() + self:CurrentSelection(SelectedItem) + end +end + +function UIMenu:RemoveItemAt(Index) + if tonumber(Index) then + if self.Items[Index] then + local SelectedItem = self:CurrentSelection() + if #self.Items > self.Pagination.Total and self.Pagination.Max == #self.Items - 1 then + self.Pagination.Min = self.Pagination.Min - 1 + self.Pagination.Max = self.Pagination.Max + 1 + end + table.remove(self.Items, tonumber(Index)) + self:RecalculateDescriptionPosition() + self:CurrentSelection(SelectedItem) + end + end +end + +function UIMenu:RefreshIndex() + if #self.Items == 0 then + self.ActiveItem = 1000 + self.Pagination.Max = self.Pagination.Total + 1 + self.Pagination.Min = 0 + return + end + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = 1000 - (1000 % #self.Items) + self.Pagination.Max = self.Pagination.Total + 1 + self.Pagination.Min = 0 + self.ReDraw = true +end + +function UIMenu:Clear() + self.Items = {} + self.ReDraw = true + self:RecalculateDescriptionPosition() +end + +function UIMenu:MultilineFormat(str) + if tostring(str) then + + local PixelPerLine = 425 + self.WidthOffset + local AggregatePixels = 0 + local output = "" + local words = string.split(tostring(str), " ") + + for i = 1, #words do + local offset = MeasureStringWidth(words[i], 0, 0.35) + AggregatePixels = AggregatePixels + offset + if AggregatePixels > PixelPerLine then + output = output .. "\n" .. words[i] .. " " + AggregatePixels = offset + MeasureString(" ") + else + output = output .. words[i] .. " " + AggregatePixels = AggregatePixels + MeasureString(" ") + end + end + return output + end +end + +function UIMenu:DrawCalculations() + local WindowHeight = self:CalculateWindowHeight() + + if self.Settings.MultilineFormats then + if self.Subtitle.Rectangle and not self.Subtitle.Formatted then + self.Subtitle.Formatted = true + self.Subtitle.Text:Text(self:MultilineFormat(self.Subtitle.Text:Text())) + + local Linecount = #string.split(self.Subtitle.Text:Text(), "\n") + self.Subtitle.ExtraY = ((Linecount == 1) and 37 or ((Linecount + 1) * 22)) + self.Subtitle.Rectangle:Size(431 + self.WidthOffset, self.Subtitle.ExtraY) + end + elseif self.Subtitle.Formatted then + self.Subtitle.Formatted = false + self.Subtitle.ExtraY = 37 + self.Subtitle.Rectangle:Size(431 + self.WidthOffset, self.Subtitle.ExtraY) + self.Subtitle.Text:Text(self.Subtitle.BackupText) + end + + self.Background:Size(431 + self.WidthOffset, self:CalculateItemHeight() + WindowHeight + ((self.Subtitle.ExtraY > 0) and 0 or 37)) + + self.Extra.Up:Size(431 + self.WidthOffset, 18) + self.Extra.Down:Size(431 + self.WidthOffset, 18) + + self.Extra.Up:Position(self.Position.X, 144 + self:CalculateItemHeight() + self.Position.Y + WindowHeight) + self.Extra.Down:Position(self.Position.X, 144 + 18 + self:CalculateItemHeight() + self.Position.Y + WindowHeight) + + if self.WidthOffset > 0 then + self.ArrowSprite:Position(190 + self.Position.X + (self.WidthOffset / 2), 137 + self:CalculateItemHeight() + self.Position.Y + WindowHeight) + else + self.ArrowSprite:Position(190 + self.Position.X + self.WidthOffset, 137 + self:CalculateItemHeight() + self.Position.Y + WindowHeight) + end + + self.ReDraw = false + + if #self.Items ~= 0 and self.Items[self:CurrentSelection()]:Description() ~= "" then + self:RecalculateDescriptionPosition() + + local description = self.Items[self:CurrentSelection()]:Description() + if self.Settings.MultilineFormats then + self.Description.Text:Text(self:MultilineFormat(description)) + else + self.Description.Text:Text(description) + end + + local Linecount = #string.split(self.Description.Text:Text(), "\n") + self.Description.Rectangle:Size(431 + self.WidthOffset, ((Linecount == 1) and 37 or ((Linecount + 1) * 22))) + end +end + +function UIMenu:Visible(bool) + if bool ~= nil then + menuOpen = bool + self._Visible = tobool(bool) + self.JustOpened = tobool(bool) + self.Dirty = tobool(bool) + self:UpdateScaleform() + if self.ParentMenu ~= nil or tobool(bool) == false then + return + end + if self.Settings.ResetCursorOnOpen then + local W, H = GetScreenResolution() + SetCursorLocation(W / 2, H / 2) + SetCursorSprite(1) + end + collectgarbage() + else + return self._Visible + end +end + +function UIMenu:ProcessControl() + if not self._Visible then + return + end + + if self.JustOpened then + self.JustOpened = false + return + end + + if self.Controls.Back.Enabled and (IsDisabledControlJustReleased(2, 177) or IsDisabledControlJustReleased(2, 199) ) and IsInputDisabled(0) then + self:GoBack() + end + + if #self.Items == 0 then + return + end + + if not self.UpPressed then + if self.Controls.Up.Enabled and (IsDisabledControlJustPressed(1, 172) or IsDisabledControlJustPressed(1, 241)) and IsInputDisabled(0) then + Citizen.CreateThread(function() + self.UpPressed = true + if #self.Items > self.Pagination.Total + 1 then + self:GoUpOverflow() + else + self:GoUp() + end + self:UpdateScaleform() + Citizen.Wait(175) + while self.Controls.Up.Enabled and (IsDisabledControlPressed(2, 172) or IsDisabledControlPressed(2, 241)) and IsInputDisabled(0) do + if #self.Items > self.Pagination.Total + 1 then + self:GoUpOverflow() + else + self:GoUp() + end + self:UpdateScaleform() + Citizen.Wait(125) + end + self.UpPressed = false + end) + end + end + + if not self.DownPressed then + if self.Controls.Down.Enabled and (IsDisabledControlJustPressed(1, 173) or IsDisabledControlJustPressed(1, 242)) and IsInputDisabled(0) then + Citizen.CreateThread(function() + self.DownPressed = true + if #self.Items > self.Pagination.Total + 1 then + self:GoDownOverflow() + else + self:GoDown() + end + self:UpdateScaleform() + Citizen.Wait(175) + while self.Controls.Down.Enabled and (IsDisabledControlPressed(2, 173) or IsDisabledControlPressed(2, 242)) and IsInputDisabled(0) do + if #self.Items > self.Pagination.Total + 1 then + self:GoDownOverflow() + else + self:GoDown() + end + self:UpdateScaleform() + Citizen.Wait(125) + end + self.DownPressed = false + end) + end + end + + if not self.LeftPressed then + if self.Controls.Left.Enabled and (IsDisabledControlPressed(2, 174)) and IsInputDisabled(0) then + Citizen.CreateThread(function() + if not self.LeftPressed then + self.LeftPressed = true + self:GoLeft() + Citizen.Wait(150) + while self.Controls.Left.Enabled and (IsDisabledControlPressed(2, 174)) and IsInputDisabled(0) do + self:GoLeft() + Citizen.Wait(200) + end + self.LeftPressed = false + end + end) + end + end + + if not self.RightPressed then + if self.Controls.Right.Enabled and (IsDisabledControlPressed(2, 175)) and IsInputDisabled(0) then + Citizen.CreateThread(function() + if not self.RightPressed then + self.RightPressed = true + self:GoRight() + Citizen.Wait(150) + while self.Controls.Right.Enabled and (IsDisabledControlPressed(2, 175)) and IsInputDisabled(0) do + self:GoRight() + Citizen.Wait(200) + end + self.RightPressed = false + end + end) + end + end + + if self.Controls.Select.Enabled and (IsDisabledControlJustPressed(1, 201) and IsInputDisabled(0)) then + self:SelectItem() + end +end + +function UIMenu:GoUpOverflow() + if #self.Items <= self.Pagination.Total + 1 then + return + end + + if self:CurrentSelection() <= self.Pagination.Min + 1 then + if self:CurrentSelection() == 1 then + self.Pagination.Min = #self.Items - (self.Pagination.Total + 1) + self.Pagination.Max = #self.Items + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = 1000 - (1000 % #self.Items) + self.ActiveItem = self.ActiveItem + (#self.Items - 1) + self.Items[self:CurrentSelection()]:Selected(true) + else + self.Pagination.Min = self.Pagination.Min - 1 + self.Pagination.Max = self.Pagination.Max - 1 + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = self.ActiveItem - 1 + self.Items[self:CurrentSelection()]:Selected(true) + end + else + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = self.ActiveItem - 1 + self.Items[self:CurrentSelection()]:Selected(true) + end + PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true) + self.OnIndexChange(self, self:CurrentSelection()) + self.ReDraw = true +end + +function UIMenu:GoUp() + if #self.Items > self.Pagination.Total + 1 then + return + end + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = self.ActiveItem - 1 + self.Items[self:CurrentSelection()]:Selected(true) + PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true) + self.OnIndexChange(self, self:CurrentSelection()) + self.ReDraw = true +end + +function UIMenu:GoDownOverflow() + if #self.Items <= self.Pagination.Total + 1 then + return + end + + if self:CurrentSelection() >= self.Pagination.Max then + if self:CurrentSelection() == #self.Items then + self.Pagination.Min = 0 + self.Pagination.Max = self.Pagination.Total + 1 + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = 1000 - (1000 % #self.Items) + self.Items[self:CurrentSelection()]:Selected(true) + else + self.Pagination.Max = self.Pagination.Max + 1 + self.Pagination.Min = self.Pagination.Max - (self.Pagination.Total + 1) + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = self.ActiveItem + 1 + self.Items[self:CurrentSelection()]:Selected(true) + end + else + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = self.ActiveItem + 1 + self.Items[self:CurrentSelection()]:Selected(true) + end + PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true) + self.OnIndexChange(self, self:CurrentSelection()) + self.ReDraw = true +end + +function UIMenu:GoDown() + if #self.Items > self.Pagination.Total + 1 then + return + end + + self.Items[self:CurrentSelection()]:Selected(false) + self.ActiveItem = self.ActiveItem + 1 + self.Items[self:CurrentSelection()]:Selected(true) + PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true) + self.OnIndexChange(self, self:CurrentSelection()) + self.ReDraw = true +end + +function UIMenu:GoLeft() + local type, subtype = self.Items[self:CurrentSelection()]() + if subtype ~= "UIMenuListItem" and subtype ~= "UIMenuSliderItem" and subtype ~= "UIMenuProgressItem" then + return + end + + if not self.Items[self:CurrentSelection()]:Enabled() then + PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true) + return + end + + if subtype == "UIMenuListItem" then + local Item = self.Items[self:CurrentSelection()] + Item:Index(Item._Index - 1) + self.OnListChange(self, Item, Item._Index) + Item.OnListChanged(self, Item, Item._Index) + PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true) + elseif subtype == "UIMenuSliderItem" then + local Item = self.Items[self:CurrentSelection()] + Item:Index(Item._Index - 1) + self.OnSliderChange(self, Item, Item:Index()) + Item.OnSliderChanged(self, Item, Item._Index) + PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true) + elseif subtype == "UIMenuProgressItem" then + local Item = self.Items[self:CurrentSelection()] + Item:Index(Item.Data.Index - 1) + self.OnProgressChange(self, Item, Item.Data.Index) + Item.OnProgressChanged(self, Item, Item.Data.Index) + PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true) + end +end + +function UIMenu:GoRight() + local type, subtype = self.Items[self:CurrentSelection()]() + if subtype ~= "UIMenuListItem" and subtype ~= "UIMenuSliderItem" and subtype ~= "UIMenuProgressItem" then + return + end + + if not self.Items[self:CurrentSelection()]:Enabled() then + PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true) + return + end + + if subtype == "UIMenuListItem" then + local Item = self.Items[self:CurrentSelection()] + Item:Index(Item._Index + 1) + self.OnListChange(self, Item, Item._Index) + Item.OnListChanged(self, Item, Item._Index) + PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true) + elseif subtype == "UIMenuSliderItem" then + local Item = self.Items[self:CurrentSelection()] + Item:Index(Item._Index + 1) + self.OnSliderChange(self, Item, Item:Index()) + Item.OnSliderChanged(self, Item, Item._Index) + PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true) + elseif subtype == "UIMenuProgressItem" then + local Item = self.Items[self:CurrentSelection()] + Item:Index(Item.Data.Index + 1) + self.OnProgressChange(self, Item, Item.Data.Index) + Item.OnProgressChanged(self, Item, Item.Data.Index) + PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true) + end +end + +function UIMenu:SelectItem() + if not self.Items[self:CurrentSelection()]:Enabled() then + PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true) + return + end + local Item = self.Items[self:CurrentSelection()] + local type, subtype = Item() + if subtype == "UIMenuCheckboxItem" then + Item.Checked = not Item.Checked + PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true) + self.OnCheckboxChange(self, Item, Item.Checked) + Item.CheckboxEvent(self, Item, Item.Checked) + elseif subtype == "UIMenuListItem" then + PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true) + self.OnListSelect(self, Item, Item._Index) + Item.OnListSelected(self, Item, Item._Index) + elseif subtype == "UIMenuSliderItem" then + PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true) + self.OnSliderSelect(self, Item, Item._Index) + Item.OnSliderSelected(Item._Index) + elseif subtype == "UIMenuProgressItem" then + PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true) + self.OnProgressSelect(self, Item, Item.Data.Index) + Item.OnProgressSelected(Item.Data.Index) + else + PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true) + self.OnItemSelect(self, Item, self:CurrentSelection()) + Item.Activated(self, Item) + if not self.Children[Item] then + return + end + self:Visible(false) + self.Children[Item]:Visible(true) + self.OnMenuChanged(self, self.Children[self.Items[self:CurrentSelection()]], true) + end +end + +function UIMenu:GoBack() + PlaySoundFrontend(-1, self.Settings.Audio.Back, self.Settings.Audio.Library, true) + self:Visible(false) + if self.ParentMenu ~= nil then + self.ParentMenu:Visible(true) + self.OnMenuChanged(self, self.ParentMenu, false) + if self.Settings.ResetCursorOnOpen then + local W, H = GetActiveScreenResolution() + SetCursorLocation(W / 2, H / 2) + end + end + self.OnMenuClosed(self) +end + +function UIMenu:BindMenuToItem(Menu, Item) + if Menu() == "UIMenu" and Item() == "UIMenuItem" then + Menu.ParentMenu = self + Menu.ParentItem = Item + self.Children[Item] = Menu + end +end + +function UIMenu:ReleaseMenuFromItem(Item) + if Item() == "UIMenuItem" then + if not self.Children[Item] then + return false + end + self.Children[Item].ParentMenu = nil + self.Children[Item].ParentItem = nil + self.Children[Item] = nil + return true + end +end + +function UIMenu:Draw() + if not self._Visible then + return + end + + HideHudComponentThisFrame(19) + + if self.Settings.ControlDisablingEnabled then + self:DisEnableControls(false) + end + + if self.Settings.InstructionalButtons then + DrawScaleformMovieFullscreen(self.InstructionalScaleform, 255, 255, 255, 255, 0) + end + + if self.Settings.ScaleWithSafezone then + ScreenDrawPositionBegin(76, 84) + ScreenDrawPositionRatio(0, 0, 0, 0) + end + + if self.ReDraw then + self:DrawCalculations() + end + + if self.Logo then + self.Logo:Draw() + elseif self.Banner then + self.Banner:Draw() + end + + self.Title:Draw() + + if self.Subtitle.Rectangle then + self.Subtitle.Rectangle:Draw() + self.Subtitle.Text:Draw() + end + + if #self.Items ~= 0 or #self.Windows ~= 0 then + self.Background:Draw() + end + + if #self.Windows ~= 0 then + local WindowOffset = 0 + for index = 1, #self.Windows do + if self.Windows[index - 1] then + WindowOffset = WindowOffset + self.Windows[index - 1].Background:Size().Height + end + local Window = self.Windows[index] + Window:Position(WindowOffset + self.Subtitle.ExtraY - 37) + Window:Draw() + end + end + + if #self.Items == 0 then + if self.Settings.ScaleWithSafezone then + ScreenDrawPositionEnd() + end + return + end + + local CurrentSelection = self:CurrentSelection() + self.Items[CurrentSelection]:Selected(true) + + if self.Items[CurrentSelection]:Description() ~= "" then + self.Description.Bar:Draw() + self.Description.Rectangle:Draw() + self.Description.Text:Draw() + end + + if self.Items[CurrentSelection].Panels ~= nil then + if #self.Items[CurrentSelection].Panels ~= 0 then + local PanelOffset = self:CaclulatePanelPosition(self.Items[CurrentSelection]:Description() ~= "") + for index = 1, #self.Items[CurrentSelection].Panels do + if self.Items[CurrentSelection].Panels[index - 1] then + PanelOffset = PanelOffset + self.Items[CurrentSelection].Panels[index - 1].Background:Size().Height + 5 + end + self.Items[CurrentSelection].Panels[index]:Position(PanelOffset) + self.Items[CurrentSelection].Panels[index]:Draw() + end + end + end + + local WindowHeight = self:CalculateWindowHeight() + + if #self.Items <= self.Pagination.Total + 1 then + local ItemOffset = self.Subtitle.ExtraY - 37 + WindowHeight + for index = 1, #self.Items do + Item = self.Items[index] + Item:Position(ItemOffset) + Item:Draw() + ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item) + end + else + local ItemOffset = self.Subtitle.ExtraY - 37 + WindowHeight + for index = self.Pagination.Min + 1, self.Pagination.Max, 1 do + if self.Items[index] then + Item = self.Items[index] + Item:Position(ItemOffset) + Item:Draw() + ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item) + end + end + + self.Extra.Up:Draw() + self.Extra.Down:Draw() + self.ArrowSprite:Draw() + + if self.PageCounter.Text ~= nil then + local Caption = self.PageCounter.PreText .. CurrentSelection .. " / " .. #self.Items + self.PageCounter.Text:Text(Caption) + self.PageCounter.Text:Draw() + end + end + + if self.Settings.ScaleWithSafezone then + ScreenDrawPositionEnd() + end +end + +function UIMenu:ProcessMouse() + if not self._Visible or self.JustOpened or #self.Items == 0 or tobool(Controller()) or not self.Settings.MouseControlsEnabled then + EnableControlAction(0, 2, true) + EnableControlAction(0, 1, true) + EnableControlAction(0, 25, true) + EnableControlAction(0, 24, true) + if self.Dirty then + for _, Item in pairs(self.Items) do + if Item:Hovered() then + Item:Hovered(false) + end + end + end + return + end + + local SafeZone = {X = 0, Y = 0} + local WindowHeight = self:CalculateWindowHeight() + if self.Settings.ScaleWithSafezone then + SafeZone = GetSafeZoneBounds() + end + + local Limit = #self.Items + local ItemOffset = 0 + + ShowCursorThisFrame() + + if #self.Items > self.Pagination.Total + 1 then + Limit = self.Pagination.Max + end + + if IsMouseInBounds(0, 0, 30, 1080) and self.Settings.MouseEdgeEnabled then + SetGameplayCamRelativeHeading(GetGameplayCamRelativeHeading() + 5) + SetCursorSprite(6) + elseif IsMouseInBounds(1920 - 30, 0, 30, 1080) and self.Settings.MouseEdgeEnabled then + SetGameplayCamRelativeHeading(GetGameplayCamRelativeHeading() - 5) + SetCursorSprite(7) + elseif self.Settings.MouseEdgeEnabled then + SetCursorSprite(1) + end + + for i = self.Pagination.Min + 1, Limit, 1 do + local X, Y = self.Position.X + SafeZone.X, self.Position.Y + 144 - 37 + self.Subtitle.ExtraY + ItemOffset + SafeZone.Y + WindowHeight + local Item = self.Items[i] + local Type, SubType = Item() + local Width, Height = 431 + self.WidthOffset, self:CalculateItemHeightOffset(Item) + + if IsMouseInBounds(X, Y, Width, Height) then + Item:Hovered(true) + if not self.Controls.MousePressed then + if IsDisabledControlJustPressed(1, 24) and IsInputDisabled(0) then + Citizen.CreateThread(function() + local _X, _Y, _Width, _Height = X, Y, Width, Height + self.Controls.MousePressed = true + if Item:Selected() and Item:Enabled() then + if SubType == "UIMenuListItem" then + if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then + self:GoLeft() + elseif not IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then + self:SelectItem() + end + if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then + self:GoRight() + elseif not IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then + self:SelectItem() + end + elseif SubType == "UIMenuSliderItem" then + if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then + self:GoLeft() + elseif not IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then + self:SelectItem() + end + if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then + self:GoRight() + elseif not IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then + self:SelectItem() + end + elseif SubType == "UIMenuProgressItem" then + if IsMouseInBounds(Item.Bar.X + SafeZone.X, Item.Bar.Y + SafeZone.Y - 12, Item.Data.Max, Item.Bar.Height + 24) then + Item:CalculateProgress(math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X) + self.OnProgressChange(self, Item, Item.Data.Index) + Item.OnProgressChanged(self, Item, Item.Data.Index) + else + self:SelectItem() + end + else + self:SelectItem() + end + elseif not Item:Selected() then + self:CurrentSelection(i-1) + PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true) + self.OnIndexChange(self, self:CurrentSelection()) + self.ReDraw = true + self:UpdateScaleform() + elseif not Item:Enabled() and Item:Selected() then + PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true) + end + Citizen.Wait(175) + while IsDisabledControlPressed(0, 24) and IsMouseInBounds(_X, _Y, _Width, _Height) do + if Item:Selected() and Item:Enabled() then + if SubType == "UIMenuListItem" then + if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then + self:GoLeft() + end + if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then + self:GoRight() + end + elseif SubType == "UIMenuSliderItem" then + if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then + self:GoLeft() + end + if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then + self:GoRight() + end + elseif SubType == "UIMenuProgressItem" then + if IsMouseInBounds(Item.Bar.X + SafeZone.X, Item.Bar.Y + SafeZone.Y - 12, Item.Data.Max, Item.Bar.Height + 24) then + Item:CalculateProgress(math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X) + self.OnProgressChange(self, Item, Item.Data.Index) + Item.OnProgressChanged(self, Item, Item.Data.Index) + else + self:SelectItem() + end + end + elseif not Item:Selected() then + self:CurrentSelection(i-1) + PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true) + self.OnIndexChange(self, self:CurrentSelection()) + self.ReDraw = true + self:UpdateScaleform() + elseif not Item:Enabled() and Item:Selected() then + PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true) + end + Citizen.Wait(125) + end + self.Controls.MousePressed = false + end) + end + end + else + Item:Hovered(false) + end + ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item) + end + + local ExtraX, ExtraY = self.Position.X + SafeZone.X, 144 + self:CalculateItemHeight() + self.Position.Y + SafeZone.Y + WindowHeight + + if #self.Items <= self.Pagination.Total + 1 then return end + + if IsMouseInBounds(ExtraX, ExtraY, 431 + self.WidthOffset, 18) then + self.Extra.Up:Colour(30, 30, 30, 255) + if not self.Controls.MousePressed then + if IsDisabledControlJustPressed(1, 24) and IsInputDisabled(0) then + Citizen.CreateThread(function() + local _ExtraX, _ExtraY = ExtraX, ExtraY + self.Controls.MousePressed = true + if #self.Items > self.Pagination.Total + 1 then + self:GoUpOverflow() + else + self:GoUp() + end + Citizen.Wait(175) + while IsDisabledControlPressed(0, 24) and IsMouseInBounds(_ExtraX, _ExtraY, 431 + self.WidthOffset, 18) do + if #self.Items > self.Pagination.Total + 1 then + self:GoUpOverflow() + else + self:GoUp() + end + Citizen.Wait(125) + end + self.Controls.MousePressed = false + end) + end + end + else + self.Extra.Up:Colour(0, 0, 0, 200) + end + + if IsMouseInBounds(ExtraX, ExtraY + 18, 431 + self.WidthOffset, 18) then + self.Extra.Down:Colour(30, 30, 30, 255) + if not self.Controls.MousePressed then + if IsDisabledControlJustPressed(1, 24) and IsInputDisabled(0) then + Citizen.CreateThread(function() + local _ExtraX, _ExtraY = ExtraX, ExtraY + self.Controls.MousePressed = true + if #self.Items > self.Pagination.Total + 1 then + self:GoDownOverflow() + else + self:GoDown() + end + Citizen.Wait(175) + while IsDisabledControlPressed(0, 24) and IsMouseInBounds(_ExtraX, _ExtraY + 18, 431 + self.WidthOffset, 18) do + if #self.Items > self.Pagination.Total + 1 then + self:GoDownOverflow() + else + self:GoDown() + end + Citizen.Wait(125) + end + self.Controls.MousePressed = false + end) + end + end + else + self.Extra.Down:Colour(0, 0, 0, 200) + end +end + +function UIMenu:AddInstructionButton(button) + if type(button) == "table" and #button == 2 then + table.insert(self.InstructionalButtons, button) + end +end + +function UIMenu:RemoveInstructionButton(button) + if type(button) == "table" then + for i = 1, #self.InstructionalButtons do + if button == self.InstructionalButtons[i] then + table.remove(self.InstructionalButtons, i) + break + end + end + else + if tonumber(button) then + if self.InstructionalButtons[tonumber(button)] then + table.remove(self.InstructionalButtons, tonumber(button)) + end + end + end +end + +function UIMenu:AddEnabledControl(Inputgroup, Control, Controller) + if tonumber(Inputgroup) and tonumber(Control) then + table.insert(self.Settings.EnabledControls[(Controller and "Controller" or "Keyboard")], {Inputgroup, Control}) + end +end + +function UIMenu:RemoveEnabledControl(Inputgroup, Control, Controller) + local Type = (Controller and "Controller" or "Keyboard") + for Index = 1, #self.Settings.EnabledControls[Type] do + if Inputgroup == self.Settings.EnabledControls[Type][Index][1] and Control == self.Settings.EnabledControls[Type][Index][2] then + table.remove(self.Settings.EnabledControls[Type], Index) + break + end + end +end + +function UIMenu:UpdateScaleform() + if not self._Visible or not self.Settings.InstructionalButtons then + return + end + + PushScaleformMovieFunction(self.InstructionalScaleform, "CLEAR_ALL") + PopScaleformMovieFunction() + + PushScaleformMovieFunction(self.InstructionalScaleform, "TOGGLE_MOUSE_BUTTONS") + PushScaleformMovieFunctionParameterInt(0) + PopScaleformMovieFunction() + + PushScaleformMovieFunction(self.InstructionalScaleform, "CREATE_CONTAINER") + PopScaleformMovieFunction() + + PushScaleformMovieFunction(self.InstructionalScaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(0) + PushScaleformMovieFunctionParameterString(GetControlInstructionalButton(2, 176, 0)) + PushScaleformMovieFunctionParameterString("Select") + PopScaleformMovieFunction() + + if self.Controls.Back.Enabled then + PushScaleformMovieFunction(self.InstructionalScaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(1) + PushScaleformMovieFunctionParameterString(GetControlInstructionalButton(2, 177, 0)) + PushScaleformMovieFunctionParameterString("Back") + PopScaleformMovieFunction() + end + + local count = 2 + + for i = 1, #self.InstructionalButtons do + if self.InstructionalButtons[i] then + if #self.InstructionalButtons[i] == 2 then + PushScaleformMovieFunction(self.InstructionalScaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(count) + PushScaleformMovieFunctionParameterString(self.InstructionalButtons[i][1]) + PushScaleformMovieFunctionParameterString(self.InstructionalButtons[i][2]) + PopScaleformMovieFunction() + count = count + 1 + end + end + end + + PushScaleformMovieFunction(self.InstructionalScaleform, "DRAW_INSTRUCTIONAL_BUTTONS") + PushScaleformMovieFunctionParameterInt(-1) + PopScaleformMovieFunction() +end + +--[[ + MenuPool.lua + Menus +--]] + +function MenuPool.New() + local _MenuPool = { + Menus = {} + } + return setmetatable(_MenuPool, MenuPool) +end + +function MenuPool:AddSubMenu(Menu, Text, Description, KeepPosition, KeepBanner) + if Menu() == "UIMenu" then + local Item = UIMenuItem.New(tostring(Text), Description or "") + Menu:AddItem(Item) + local SubMenu + + if KeepPosition then + if Menu.Title.TxtName then + SubMenu = UIMenu.New("", Text, Menu.Position.X, Menu.Position.Y, Menu.TxtDictionary, Menu.TxtName, Menu.titleTxt) + else + SubMenu = UIMenu.New(Menu.Title._Text, Text, Menu.Position.X, Menu.Position.Y, Menu.TxtDictionary, Menu.TxtName) + end + else + if Menu.Title.TxtName then + SubMenu = UIMenu.New("", Text, 0, 0, Menu.TxtDictionary, Menu.TxtName, Menu.titleTxt) + else + SubMenu = UIMenu.New(Menu.Title._Text, Text, 0, 0, Menu.TxtDictionary, Menu.TxtName, Menu.titleTxt) + end + end + if KeepBanner then + if Menu.Logo ~= nil then + SubMenu.Logo = Menu.Logo + else + SubMenu.Logo = nil + SubMenu.Banner = Menu.Banner + end + end + Item:RightLabel('→→→') + self:Add(SubMenu) + Menu:BindMenuToItem(SubMenu, Item) + return SubMenu + end +end + +function MenuPool:Add(Menu) + if Menu() == "UIMenu" then + table.insert(self.Menus, Menu) + end +end + +function MenuPool:Clear() + self = { + Menus = {} + } + collectgarbage() +end + +function MenuPool:Remove() + self = nil + collectgarbage() +end + +function MenuPool:MouseEdgeEnabled(bool) + if bool ~= nil then + for _, Menu in pairs(self.Menus) do + Menu.Settings.MouseEdgeEnabled = tobool(bool) + end + end +end + +function MenuPool:ControlDisablingEnabled(bool) + if bool ~= nil then + for _, Menu in pairs(self.Menus) do + Menu.Settings.ControlDisablingEnabled = tobool(bool) + end + end +end + +function MenuPool:ResetCursorOnOpen(bool) + if bool ~= nil then + for _, Menu in pairs(self.Menus) do + Menu.Settings.ResetCursorOnOpen = tobool(bool) + end + end +end + +function MenuPool:MultilineFormats(bool) + if bool ~= nil then + for _, Menu in pairs(self.Menus) do + Menu.Settings.MultilineFormats = tobool(bool) + end + end +end + +function MenuPool:Audio(Attribute, Setting) + if Attribute ~= nil and Setting ~= nil then + for _, Menu in pairs(self.Menus) do + if Menu.Settings.Audio[Attribute] then + Menu.Settings.Audio[Attribute] = Setting + end + end + end +end + +function MenuPool:WidthOffset(offset) + if tonumber(offset) then + for _, Menu in pairs(self.Menus) do + Menu:SetMenuWidthOffset(tonumber(offset)) + end + end +end + +function MenuPool:CounterPreText(str) + if str ~= nil then + for _, Menu in pairs(self.Menus) do + Menu.PageCounter.PreText = tostring(str) + end + end +end + +function MenuPool:DisableInstructionalButtons(bool) + if bool ~= nil then + for _, Menu in pairs(self.Menus) do + Menu.Settings.InstructionalButtons = tobool(bool) + end + end +end + +function MenuPool:MouseControlsEnabled(bool) + if bool ~= nil then + for _, Menu in pairs(self.Menus) do + Menu.Settings.MouseControlsEnabled = tobool(bool) + end + end +end + +function MenuPool:RefreshIndex() + for _, Menu in pairs(self.Menus) do + Menu:RefreshIndex() + end +end + +function MenuPool:ProcessMenus() + self:ProcessControl() + --self:ProcessMouse() + self:Draw() +end + +function MenuPool:ProcessControl() + for _, Menu in pairs(self.Menus) do + if Menu:Visible() then + Menu:ProcessControl() + end + end +end + +function MenuPool:ProcessMouse() + for _, Menu in pairs(self.Menus) do + if Menu:Visible() then + Menu:ProcessMouse() + end + end +end + +function MenuPool:Draw() + for _, Menu in pairs(self.Menus) do + if Menu:Visible() then + Menu:Draw() + end + end +end + +function MenuPool:IsAnyMenuOpen() + local open = false + for _, Menu in pairs(self.Menus) do + if Menu:Visible() then + open = true + break + end + end + return open +end + +function MenuPool:CloseAllMenus() + for _, Menu in pairs(self.Menus) do + if Menu:Visible() then + Menu:Visible(false) + Menu.OnMenuClosed(Menu) + end + end +end + +function MenuPool:SetBannerSprite(Sprite) + if Sprite() == "Sprite" then + for _, Menu in pairs(self.Menus) do + Menu:SetBannerSprite(Sprite) + end + end +end + +function MenuPool:SetBannerRectangle(Rectangle) + if Rectangle() == "Rectangle" then + for _, Menu in pairs(self.Menus) do + Menu:SetBannerRectangle(Rectangle) + end + end +end + +function MenuPool:TotalItemsPerPage(Value) + if tonumber(Value) then + for _, Menu in pairs(self.Menus) do + Menu.Pagination.Total = Value - 1 + end + end +end +--[[ + Wrappers +--]] + +function NativeUI.CreatePool() + return MenuPool.New() +end + +function NativeUI.CreateMenu(Title, Subtitle, X, Y, TxtDictionary, TxtName, titleTxt) + return UIMenu.New(Title, Subtitle, X, Y, TxtDictionary, TxtName, titleTxt) +end + +function NativeUI.CreateItem(Text, Description) + return UIMenuItem.New(Text, Description) +end + +function NativeUI.CreateColouredItem(Text, Description, MainColour, HighlightColour) + return UIMenuColouredItem.New(Text, Description, MainColour, HighlightColour) +end + +function NativeUI.CreateCheckboxItem(Text, Check, Description) + return UIMenuCheckboxItem.New(Text, Check, Description) +end + +function NativeUI.CreateListItem(Text, Items, Index, Description) + return UIMenuListItem.New(Text, Items, Index, Description) +end + +function NativeUI.CreateSliderItem(Text, Items, Index, Description, Divider) + return UIMenuSliderItem.New(Text, Items, Index, Description, Divider) +end + +function NativeUI.CreateProgressItem(Text, Items, Index, Description, Counter) + return UIMenuProgressItem.New(Text, Items, Index, Description, Counter) +end + +function NativeUI.CreateHeritageWindow(Mum, Dad) + return UIMenuHeritageWindow.New(Mum, Dad) +end + +function NativeUI.CreateGridPanel(TopText, LeftText, RightText, BottomText) + return UIMenuGridPanel.New(TopText, LeftText, RightText, BottomText) +end + +function NativeUI.CreateColourPanel(Title, Colours) + return UIMenuColourPanel.New(Title, Colours) +end + +function NativeUI.CreatePercentagePanel(MinText, MaxText) + return UIMenuPercentagePanel.New(MinText, MaxText) +end + +function NativeUI.CreateSprite(TxtDictionary, TxtName, X, Y, Width, Height, Heading, R, G, B, A) + return Sprite.New(TxtDictionary, TxtName, X, Y, Width, Height, Heading, R, G, B, A) +end + +function NativeUI.CreateRectangle(X, Y, Width, Height, R, G, B, A) + return UIResRectangle.New(X, Y, Width, Height, R, G, B, A) +end + +function NativeUI.CreateText(Text, X, Y, Scale, R, G, B, A, Font, Alignment, DropShadow, Outline, WordWrap) + return UIResText.New(Text, X, Y, Scale, R, G, B, A, Font, Alignment, DropShadow, Outline, WordWrap) +end diff --git a/resources/Interaction-Menu/functions.lua b/resources/Interaction-Menu/functions.lua new file mode 100644 index 000000000..322906a2c --- /dev/null +++ b/resources/Interaction-Menu/functions.lua @@ -0,0 +1,478 @@ +--[[ +───────────────────────────────────────────────────────────────── + + SEM_InteractionMenu (functions.lua) - Created by Scott M + Current Version: v1.7.1 (Sep 2021) + + Support: https://semdevelopment.com/discord + + !!! Change vaules in the 'config.lua' !!! + DO NOT EDIT THIS IF YOU DON'T KNOW WHAT YOU ARE DOING + +───────────────────────────────────────────────────────────────── +]] + + + +--General Functions +function Notify(Text) + SetNotificationTextEntry('STRING') + AddTextComponentString(Text) + DrawNotification(true, true) +end + +function NotifyHelp(Text) + SetTextComponentFormat('STRING') + AddTextComponentString(Text) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) +end + +function LoadAnimation(Dict) + while not HasAnimDictLoaded(Dict) do + RequestAnimDict(Dict) + Citizen.Wait(5) + end +end + +function KeyboardInput(TextEntry, MaxStringLenght) + AddTextEntry('FMMC_KEY_TIP1', TextEntry) + DisplayOnscreenKeyboard(1, 'FMMC_KEY_TIP1', '', '', '', '', '', MaxStringLenght) + BlockInput = true + + while UpdateOnscreenKeyboard() ~= 1 and UpdateOnscreenKeyboard() ~= 2 do + Citizen.Wait(0) + end + + if UpdateOnscreenKeyboard() ~= 2 then + local Result = GetOnscreenKeyboardResult() + Citizen.Wait(500) + BlockInput = false + return Result + else + Citizen.Wait(500) + BlockInput = false + return nil + end +end + +function GetClosestPlayer() + local Ped = PlayerPedId() + + for _, Player in ipairs(GetActivePlayers()) do + if GetPlayerPed(Player) ~= GetPlayerPed(-1) then + local Ped2 = GetPlayerPed(Player) + local x, y, z = table.unpack(GetEntityCoords(Ped)) + if (GetDistanceBetweenCoords(GetEntityCoords(Ped2), x, y, z) < 2) then + return GetPlayerServerId(Player) + end + end + end + + Notify('~r~No Player Nearby!') + return false +end + +function GetDistance(ID) + local Ped = GetPlayerPed(-1) + local Ped2 = GetPlayerPed(ID) + local x, y, z = table.unpack(GetEntityCoords(Ped)) + return GetDistanceBetweenCoords(GetEntityCoords(Ped2), x, y, z) +end + +--LEO Functions +function ToggleRadar() + if Config.Radar ~= 0 then + if IsPedInAnyVehicle(GetPlayerPed(-1)) then + if GetVehicleClass(GetVehiclePedIsIn(GetPlayerPed(-1))) == 18 then + if GetPedInVehicleSeat(GetVehiclePedIsIn(GetPlayerPed(-1)) == -1) then + _MenuPool:CloseAllMenus() + if Config.Radar == 1 then + TriggerEvent('wk:openRemote') + elseif Config.Radar == 2 then + TriggerEvent('wk:radarRC') + end + else + Notify('~o~You need to be in the driver seat') + end + else + Notify('~o~You need to be in a police vehicle') + end + else + Notify('~o~You need to be in a vehicle') + end + end +end + +function EnableShield() + ShieldActive = true + local Ped = GetPlayerPed(-1) + local PedPos = GetEntityCoords(Ped, false) + + if IsPedInAnyVehicle(GetPlayerPed(-1), true) then + Notify('~r~You cannot be in a vehicle when getting your shield out!') + ShieldActive = false + return + end + + RequestAnimDict('combat@gestures@gang@pistol_1h@beckon') + while not HasAnimDictLoaded('combat@gestures@gang@pistol_1h@beckon') do + Citizen.Wait(100) + end + + TaskPlayAnim(Ped, 'combat@gestures@gang@pistol_1h@beckon', '0', 8.0, -8.0, -1, (2 + 16 + 32), 0.0, 0, 0, 0) + + RequestModel(GetHashKey('prop_ballistic_shield')) + while not HasModelLoaded(GetHashKey('prop_ballistic_shield')) do + Citizen.Wait(100) + end + + local shield = CreateObject(GetHashKey('prop_ballistic_shield'), PedPos.x, PedPos.y, PedPos.z, 1, 1, 1) + shieldEntity = shield + AttachEntityToEntity(shieldEntity, Ped, GetEntityBoneIndexByName(Ped, 'IK_L_Hand'), 0.0, -0.05, -0.10, -30.0, 180.0, 40.0, 0, 0, 1, 0, 0, 1) + SetWeaponAnimationOverride(Ped, 'Gang1H') + + if HasPedGotWeapon(Ped, 'weapon_combatpistol', 0) or GetSelectedPedWeapon(Ped) == 'weapon_combatpistol' then + SetCurrentPedWeapon(Ped, 'weapon_combatpistol', 1) + HadPistol = true + else + GiveWeaponToPed(Ped, 'weapon_combatpistol', 300, 0, 1) + SetCurrentPedWeapon(Ped, 'weapon_combatpistol', 1) + HadPistol = false + end + SetEnableHandcuffs(Ped, true) +end + +Citizen.CreateThread(function() + while true do + Citizen.Wait(1) + + if ShieldActive == true then + DisableControlAction(1, 23, true) --F | Enter Vehicle + DisableControlAction(1, 75, true) --F | Exit Vehicle + end + end +end) + +function DisableShield() + local Ped = GetPlayerPed(-1) + DeleteEntity(shieldEntity) + ClearPedTasksImmediately(Ped) + SetWeaponAnimationOverride(Ped, 'Default') + SetCurrentPedWeapon(Ped, 'weapon_unarmed', 1) + + if not HadPistol then + RemoveWeaponFromPed(Ped, 'weapon_combatpistol') + end + SetEnableHandcuffs(Ped, false) + HadPistol = false + ShieldActive = false +end + + + +--Civ Functions +function Ad(Text, Name, Loc, File, ID) + SetNotificationTextEntry('STRING') + AddTextComponentString(Text) + EndTextCommandThefeedPostMessagetext(Loc, File, true, 1, Name, '~b~Advertisement #' .. ID) + DrawNotification(false, true) +end + + + +--Vehicle Functions +function SpawnVehicle(Veh, Name, Livery, Extras) + local Ped = GetPlayerPed( -1 ) + if (DoesEntityExist(Ped) and not IsEntityDead(Ped)) then + local pos = GetEntityCoords(Ped) + if (IsPedSittingInAnyVehicle(Ped)) then + local Vehicle = GetVehiclePedIsIn(Ped, false) + if (GetPedInVehicleSeat(Vehicle, -1) == Ped) then + SetEntityAsMissionEntity(Vehicle, true, true ) + DeleteVehicle(Vehicle) + end + end + end + + local WaitTime = 0 + local Model = GetHashKey(Veh) + RequestModel(Model) + while not HasModelLoaded(Model) do + CancelEvent() + RequestModel(Model) + Citizen.Wait(100) + + WaitTime = WaitTime + 1 + + if WaitTime == 600 then + CancelEvent() + Notify('~r~Unable to load vehicle, please contact development!') + return + end + end + local x, y, z = table.unpack(GetEntityCoords(PlayerPedId(), false)) + local Vehicle = CreateVehicle(Model, x + 2, y + 2, z + 1, GetEntityHeading(PlayerPedId()), true, false) + SetPedIntoVehicle(PlayerPedId(), Vehicle, -1) + SetVehicleDirtLevel(Vehicle, 0) + SetVehicleModKit(Vehicle, 0) + SetVehicleMod(Vehicle, 23, -1, false) + SetModelAsNoLongerNeeded(Model) + if Livery then + SetVehicleLivery(Vehicle, Livery) + end + if Extras then + for extraId = 0, 30 do + if DoesExtraExist(Vehicle, extraId) then + SetVehicleExtra(Vehicle, extraId, true) + end + end + for _, extra in pairs(Extras) do + SetVehicleExtra(Vehicle, extra, false) + end + end + + if Name then + Notify('~b~Vehicle Spawned: ~g~' .. Name) + else + Notify('~b~Vehicle Spawned!') + end +end + +function DeleteVehicle(entity) + Citizen.InvokeNative( 0xEA386986E786A54F, Citizen.PointerValueIntInitialized(entity)) +end + + + +--Ped Functions +function LoadPed(Hash) + Citizen.CreateThread(function() + local Model = GetHashKey(Hash) + RequestModel(Model) + + while not HasModelLoaded(Model) do + Wait(0) + end + + if HasModelLoaded(Model) then + SetPlayerModel(PlayerId(), Model) + else + Notify('The model could not load - please contact development.') + end + end) +end + + + +--Weapon Functions +function GiveWeapon(Hash) + GiveWeaponToPed(GetPlayerPed(-1), GetHashKey(Hash), 999, false) +end + +function AddWeaponComponent(WeaponHash, Component) + if HasPedGotWeapon(GetPlayerPed(-1), GetHashKey(WeaponHash), false) then + GiveWeaponComponentToPed(GetPlayerPed(-1), GetHashKey(WeaponHash), GetHashKey(Component)) + end +end + + + +--Prop Functions +function SpawnProp(Object, Name) + local Player = PlayerPedId() + local Coords = GetEntityCoords(Player) + local Heading = GetEntityHeading(Player) + + RequestModel(Object) + while not HasModelLoaded(Object) do + Citizen.Wait(0) + end + + local OffsetCoords = GetOffsetFromEntityInWorldCoords(Player, 0.0, 0.75, 0.0) + local Prop = CreateObjectNoOffset(Object, OffsetCoords, false, true, false) + SetEntityHeading(Prop, Heading) + PlaceObjectOnGroundProperly(Prop) + SetEntityCollision(Prop, false, true) + SetEntityAlpha(Prop, 100) + FreezeEntityPosition(Prop, true) + SetModelAsNoLongerNeeded(Object) + + Notify('Press ~g~E ~w~to place\nPress ~r~R ~w~to cancel') + + Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + + local OffsetCoords = GetOffsetFromEntityInWorldCoords(Player, 0.0, 0.75, 0.0) + local Heading = GetEntityHeading(Player) + + SetEntityCoordsNoOffset(Prop, OffsetCoords) + SetEntityHeading(Prop, Heading) + PlaceObjectOnGroundProperly(Prop) + DisableControlAction(1, 38, true) --E + DisableControlAction(1, 140, true) --R + + + if IsDisabledControlJustPressed(1, 38) then --E + local PropCoords = GetEntityCoords(Prop) + local PropHeading = GetEntityHeading(Prop) + DeleteObject(Prop) + + RequestModel(Object) + while not HasModelLoaded(Object) do + Citizen.Wait(0) + end + + local Prop = CreateObjectNoOffset(Object, PropCoords, true, true, true) + SetEntityHeading(Prop, PropHeading) + PlaceObjectOnGroundProperly(Prop) + FreezeEntityPosition(Prop, true) + SetEntityInvincible(Prop, true) + SetModelAsNoLongerNeeded(Object) + return + end + + if IsDisabledControlJustPressed(1, 140) then --R + DeleteObject(Prop) + return + end + end + end) +end + +function DeleteProp(Object) + local Hash = GetHashKey(Object) + local x, y, z = table.unpack(GetEntityCoords(PlayerPedId(), true)) + if DoesObjectOfTypeExistAtCoords(x, y, z, 1.5, Hash, true) then + local Prop = GetClosestObjectOfType(x, y, z, 1.5, Hash, false, false, false) + DeleteObject(Prop) + Notify('~r~Prop Removed!') + end +end + +function DeleteEntity(Entity) + Citizen.InvokeNative(0xAE3CBE5BF394C9C9, Citizen.PointerValueIntInitialized(Entity)) +end + + + +--Emote Functions +function PlayEmote(Emote, Name) + if not DoesEntityExist(GetPlayerPed(-1)) then + return + end + + if IsPedInAnyVehicle(GetPlayerPed(-1)) then + Notify('~r~Please exit the vehicle to use this emote!') + return + end + + TaskStartScenarioInPlace(GetPlayerPed(-1), Emote, 0, true) + Notify('~b~Playing Emote: ~g~' .. Name) + EmotePlaying = true +end + +function CancelEmote() + ClearPedTasks(GetPlayerPed(-1)) + Notify('~r~Stopping Emote') + EmotePlaying = false +end + + + + + + + +--Menu Restrictions +function LEORestrict() + if Config.LEOAccess == 0 then + return false + elseif Config.LEOAccess == 1 then + return true + elseif Config.LEOAccess == 2 then + local Ped = GetEntityModel(GetPlayerPed(-1)) + + for _, LEOPeds in pairs(Config.LEOUniforms) do + local AllowedPed = GetHashKey(LEOPeds.spawncode) + + if Ped == AllowedPed then + return true + end + end + elseif Config.LEOAccess == 3 then + return LEOOnduty + elseif Config.LEOAccess == 4 then + return LEOAce + else + return true + end +end + + + +function FireRestrict() + if Config.FireAccess == 0 then + return false + elseif Config.FireAccess == 1 then + return true + elseif Config.FireAccess == 2 then + local Ped = GetEntityModel(GetPlayerPed(-1)) + + for _, FirePeds in pairs(Config.FireUniforms) do + local AllowedPed = GetHashKey(FirePeds.spawncode) + + if Ped == AllowedPed then + return true + end + end + elseif Config.FireAccess == 3 then + return FireOnduty + elseif Config.FireAccess == 4 then + return FireAce + else + return true + end +end + + + +function CivRestrict() + if Config.CivAccess == 0 then + return false + elseif Config.CivAccess == 1 then + return true + else + return true + end +end + + + +function VehicleRestrict() + if Config.VehicleAccess == 0 then + return false + elseif Config.VehicleAccess == 1 then + return true + elseif Config.VehicleAccess == 2 then + if IsPedInAnyVehicle(GetPlayerPed(PlayerId()), false) then + return true + else + return false + end + else + return true + end +end + + + +function EmoteRestrict() + if Config.EmoteAccess == 0 then + return false + elseif Config.EmoteAccess == 1 then + return true + else + return true + end +end diff --git a/resources/Interaction-Menu/fxmanifest.lua b/resources/Interaction-Menu/fxmanifest.lua new file mode 100644 index 000000000..dcd4a8f0a --- /dev/null +++ b/resources/Interaction-Menu/fxmanifest.lua @@ -0,0 +1,43 @@ +--[[ +────────────────────────────────────────────────────────────────── + + SEM_InteractionMenu (fxmanifest.lua) - Created by Scott M + Current Version: v1.7.1 (Sep 2021) + + Support: https://semdevelopment.com/discord + + !!! Change vaules in the 'config.lua' !!! + DO NOT EDIT THIS IF YOU DON'T KNOW WHAT YOU ARE DOING + +────────────────────────────────────────────────────────────────── +]] + + + +fx_version 'cerulean' +games {'gta5'} + +--DO NOT REMOVE THESE +title 'SEM_InteractionMenu' +description 'Multi Purpose Interaction Menu' +author 'Scott M [SEM Development]' +version 'v1.7.1' --This is required for the version checker, DO NOT change or remove + +client_scripts { + 'dependencies/NativeUI.lua', + 'client.lua', + 'config.lua', + 'functions.lua', + 'menu.lua', +} + +server_scripts { + 'config.lua', + 'server.lua', + 'functions.lua', +} + +exports { + 'IsOndutyLEO', + 'IsOndutyFire', +} diff --git a/resources/Interaction-Menu/menu.lua b/resources/Interaction-Menu/menu.lua new file mode 100644 index 000000000..2bad19a07 --- /dev/null +++ b/resources/Interaction-Menu/menu.lua @@ -0,0 +1,1099 @@ +--[[ +─────────────────────────────────────────────────────────────── + + SEM_InteractionMenu (menu.lua) - Created by Scott M + Current Version: v1.7.1 (Sep 2021) + + Support | https://semdevelopment.com/discord + + !!! Change vaules in the 'config.lua' !!! + DO NOT EDIT THIS IF YOU DON'T KNOW WHAT YOU ARE DOING + +─────────────────────────────────────────────────────────────── +]] + + + +local MenuOri = 0 +if Config.MenuOrientation == 0 then + MenuOri = 0 +elseif Config.MenuOrientation == 1 then + MenuOri = 1320 +else + MenuOri = 0 +end + + +_MenuPool = NativeUI.CreatePool() +MainMenu = NativeUI.CreateMenu() + + + + + +function Menu() + local MenuTitle = '' + if Config.MenuTitle == 0 then + MenuTitle = 'Interaction Menu' + elseif Config.MenuTitle == 1 then + MenuTitle = GetPlayerName(source) + elseif Config.MenuTitle == 2 then + MenuTitle = Config.MenuTitleCustom + else + MenuTitle = 'Interaction Menu' + end + + + + _MenuPool:Remove() + _MenuPool = NativeUI.CreatePool() + MainMenu = NativeUI.CreateMenu(MenuTitle, GetResourceMetadata(GetCurrentResourceName(), 'title', 0) .. ' ~y~' .. GetResourceMetadata(GetCurrentResourceName(), 'version', 0), MenuOri) + _MenuPool:Add(MainMenu) + MainMenu:SetMenuWidthOffset(Config.MenuWidth) + collectgarbage() + + MainMenu:SetMenuWidthOffset(Config.MenuWidth) + _MenuPool:ControlDisablingEnabled(false) + _MenuPool:MouseControlsEnabled(false) + + + + + + if LEORestrict() then + local LEOMenu = _MenuPool:AddSubMenu(MainMenu, 'LEO Toolbox', 'Law Enforcement Related Menu', true) + LEOMenu:SetMenuWidthOffset(Config.MenuWidth) + local LEOActions = _MenuPool:AddSubMenu(LEOMenu, 'Actions', '', true) + LEOActions:SetMenuWidthOffset(Config.MenuWidth) + local Cuff = NativeUI.CreateItem('Cuff', 'Cuff/Uncuff the closest player') + local Drag = NativeUI.CreateItem('Drag', 'Drag/Undrag the closest player') + local Seat = NativeUI.CreateItem('Seat', 'Place a player in the closest vehicle') + local Unseat = NativeUI.CreateItem('Unseat', 'Remove a player from the closest vehicle') + local Radar = NativeUI.CreateItem('Radar', 'Toggle the radar menu') + local Inventory = NativeUI.CreateItem('Inventory', 'Search the closest player\'s inventory') + local BAC = NativeUI.CreateItem('BAC', 'Test the BAC level of the closest player') + local Jail = NativeUI.CreateItem('Jail', 'Jail a player') + local Unjail = NativeUI.CreateItem('Unjail', 'Unjail a player') + SpikeLengths = {1, 2, 3, 4, 5} + local Spikes = NativeUI.CreateListItem('Deploy Spikes', SpikeLengths, 1, 'Places spike strips on the ground') + local DelSpikes = NativeUI.CreateItem('Remove Spikes', 'Remove spike strips placed on the ground') + local Shield = NativeUI.CreateItem('Toggle Shield', 'Toggle the bulletproof shield') + local CarbineRifle = NativeUI.CreateItem('Toggle Carbine', 'Toggle your carbine rifle') + local Shotgun = NativeUI.CreateItem('Toggle Shotgun', 'Toggle your pump shotgun') + PropsList = {} + for _, Prop in pairs(Config.Props) do + table.insert(PropsList, Prop.name) + end + local Props = NativeUI.CreateListItem('Spawn Props', PropsList, 1, 'Spawn props on the ground') + local RemoveProps = NativeUI.CreateItem('Remove Props', 'Remove the closest prop') + LEOActions:AddItem(Cuff) + LEOActions:AddItem(Drag) + LEOActions:AddItem(Seat) + LEOActions:AddItem(Unseat) + if Config.Radar ~= 0 then + LEOActions:AddItem(Radar) + end + LEOActions:AddItem(Inventory) + LEOActions:AddItem(BAC) + if Config.LEOJail then + LEOActions:AddItem(Jail) + if UnjailAllowed then + LEOActions:AddItem(Unjail) + end + end + LEOActions:AddItem(Spikes) + LEOActions:AddItem(DelSpikes) + LEOActions:AddItem(Shield) + if Config.UnrackWeapons == 1 or Config.UnrackWeapons == 2 then + LEOActions:AddItem(CarbineRifle) + LEOActions:AddItem(Shotgun) + end + if Config.DisplayProps then + LEOActions:AddItem(Props) + LEOActions:AddItem(RemoveProps) + end + Cuff.Activated = function(ParentMenu, SelectedItem) + local player = GetClosestPlayer() + if player ~= false then + TriggerServerEvent('SEM_InteractionMenu:CuffNear', player) + end + end + Drag.Activated = function(ParentMenu, SelectedItem) + local player = GetClosestPlayer() + if player ~= false then + TriggerServerEvent('SEM_InteractionMenu:DragNear', player) + end + end + Seat.Activated = function(ParentMenu, SelectedItem) + local Veh = GetVehiclePedIsIn(Ped, true) + + local player = GetClosestPlayer() + if player ~= false then + TriggerServerEvent('SEM_InteractionMenu:SeatNear', player, Veh) + end + end + Unseat.Activated = function(ParentMenu, SelectedItem) + if IsPedInAnyVehicle(GetPlayerPed(-1), true) then + Notify('~o~You need to be outside of the vehicle') + return + end + + local player = GetClosestPlayer() + if player ~= false then + TriggerServerEvent('SEM_InteractionMenu:UnseatNear', player) + end + end + Radar.Activated = function(ParentMenu, SelectedItem) + ToggleRadar() + end + Inventory.Activated = function(ParentMenu, SelectedItem) + local player = GetClosestPlayer() + if player ~= false then + Notify('~b~Searching ...') + TriggerServerEvent('SEM_InteractionMenu:InventorySearch', player) + end + end + BAC.Activated = function(ParentMenu, SelectedItem) + local player = GetClosestPlayer() + if player ~= false then + Notify('~b~Testing ...') + TriggerServerEvent('SEM_InteractionMenu:BACTest', player) + end + end + Jail.Activated = function(ParentMenu, SelectedItem) + local PlayerID = tonumber(KeyboardInput('Player ID:', 10)) + if PlayerID == nil then + Notify('~r~Please enter a player ID') + return + end + + local JailTime = tonumber(KeyboardInput('Time: (Seconds) - Max Time: ' .. Config.MaxJailTime .. ' | Default Time: 30', string.len(Config.MaxJailTime))) + if JailTime == nil then + JailTime = 30 + end + if JailTime > Config.MaxJailTime then + Notify('~y~Exceeded Max Time\nMax Time: ' .. Config.MaxJailTime .. ' seconds') + JailTime = Config.MaxJailTime + end + + Notify('Player Jailed for ~b~' .. JailTime .. ' seconds') + TriggerServerEvent('SEM_InteractionMenu:Jail', PlayerID, JailTime) + end + Unjail.Activated = function(ParentMenu, SelectedItem) + local PlayerID = tonumber(KeyboardInput('Player ID:', 10)) + if PlayerID == nil then + Notify('~r~Please enter a player ID') + return + end + + TriggerServerEvent('SEM_InteractionMenu:Unjail', PlayerID) + end + DelSpikes.Activated = function(ParentMenu, SelectedItem) + TriggerEvent('SEM_InteractionMenu:Spikes-DeleteSpikes') + end + Shield.Activated = function(ParentMenu, SelectedItem) + if ShieldActive then + DisableShield() + else + EnableShield() + end + end + CarbineRifle.Activated = function(ParentMenu, SelectedItem) + if (GetVehicleClass(GetVehiclePedIsIn(GetPlayerPed(-1))) == 18) then + CarbineEquipped = not CarbineEquipped + ShotgunEquipped = false + elseif (GetVehicleClass(GetVehiclePedIsIn(GetPlayerPed(-1))) ~= 18) then + Notify('~r~You Must be in a Police Vehicle to rack/unrack your Carbine Rifle') + return + end + + if CarbineEquipped then + Notify('~g~Carbine Rifle Equipped') + GiveWeapon('weapon_carbinerifle') + AddWeaponComponent('weapon_carbinerifle', 'component_at_ar_flsh') + AddWeaponComponent('weapon_carbinerifle', 'component_at_ar_afgrip') + else + Notify('~y~Carbine Rifle Unequipped') + RemoveWeaponFromPed(GetPlayerPed(-1), 'weapon_carbinerifle') + end + end + Shotgun.Activated = function(ParentMenu, SelectedItem) + if (GetVehicleClass(GetVehiclePedIsIn(GetPlayerPed(-1))) == 18) then + ShotgunEquipped = not ShotgunEquipped + CarbineEquipped = false + elseif (GetVehicleClass(GetVehiclePedIsIn(GetPlayerPed(-1))) ~= 18) then + Notify('~r~You Must be in a Police Vehicle to rack/unrack your Shotgun') + return + end + + if ShotgunEquipped then + Notify('~g~Shotgun Equipped') + GiveWeapon('weapon_pumpshotgun') + AddWeaponComponent('weapon_pumpshotgun', 'component_at_ar_flsh') + else + Notify('~y~Shotgun Unequipped') + RemoveWeaponFromPed(GetPlayerPed(-1), 'weapon_pumpshotgun') + end + end + LEOActions.OnListSelect = function(sender, item, index) + if item == Spikes then + TriggerEvent('SEM_InteractionMenu:Spikes-SpawnSpikes', tonumber(index)) + elseif item == Props then + for _, Prop in pairs(Config.Props) do + if Prop.name == item:IndexToItem(index) then + SpawnProp(Prop.spawncode, Prop.name) + end + end + end + end + RemoveProps.Activated = function(ParentMenu, SelectedItem) + for _, Prop in pairs(Config.Props) do + DeleteProp(Prop.spawncode) + end + end + + if Config.DisplayBackup then + local LEOBackup = _MenuPool:AddSubMenu(LEOMenu, 'Backup', '', true) + LEOBackup:SetMenuWidthOffset(Config.MenuWidth) + --[[ + Code 1 Backup | No Lights or Siren + Code 2 Backup | Only Lights + Code 3 Backup | Lights and Siren + Code 99 Backup | All Available Unit Responde Code 3 + ]] + local BK1 = NativeUI.CreateItem('Code 1', 'Call Code 1 Backup to your location') + local BK2 = NativeUI.CreateItem('Code 2', 'Call Code 2 Backup to your location') + local BK3 = NativeUI.CreateItem('Code 3', 'Call Code 3 Backup to your location') + local BK99 = NativeUI.CreateItem('Code 99', 'Call Code 99 Backup to your location') + local PanicBTN = NativeUI.CreateItem('~r~Panic Button', 'Officer Panic Button') + LEOBackup:AddItem(BK1) + LEOBackup:AddItem(BK2) + LEOBackup:AddItem(BK3) + LEOBackup:AddItem(BK99) + LEOBackup:AddItem(PanicBTN) + BK1.Activated = function(ParentMenu, SelectedItem) + local Coords = GetEntityCoords(GetPlayerPed(-1)) + local Street1, Street2 = GetStreetNameAtCoord(Coords.x, Coords.y, Coords.z) + local StreetName = GetStreetNameFromHashKey(Street1) + + TriggerServerEvent('SEM_InteractionMenu:Backup', 1, StreetName, Coords) + end + BK2.Activated = function(ParentMenu, SelectedItem) + local Coords = GetEntityCoords(GetPlayerPed(-1)) + local Street1, Street2 = GetStreetNameAtCoord(Coords.x, Coords.y, Coords.z) + local StreetName = GetStreetNameFromHashKey(Street1) + + TriggerServerEvent('SEM_InteractionMenu:Backup', 2, StreetName, Coords) + end + BK3.Activated = function(ParentMenu, SelectedItem) + local Coords = GetEntityCoords(GetPlayerPed(-1)) + local Street1, Street2 = GetStreetNameAtCoord(Coords.x, Coords.y, Coords.z) + local StreetName = GetStreetNameFromHashKey(Street1) + + TriggerServerEvent('SEM_InteractionMenu:Backup', 3, StreetName, Coords) + end + BK99.Activated = function(ParentMenu, SelectedItem) + local Coords = GetEntityCoords(GetPlayerPed(-1)) + local Street1, Street2 = GetStreetNameAtCoord(Coords.x, Coords.y, Coords.z) + local StreetName = GetStreetNameFromHashKey(Street1) + + TriggerServerEvent('SEM_InteractionMenu:Backup', 99, StreetName, Coords) + end + PanicBTN.Activated = function(ParentMenu, SelectedItem) + local Coords = GetEntityCoords(GetPlayerPed(-1)) + local Street1, Street2 = GetStreetNameAtCoord(Coords.x, Coords.y, Coords.z) + local StreetName = GetStreetNameFromHashKey(Street1) + + TriggerServerEvent('SEM_InteractionMenu:Backup', 'panic', StreetName, Coords) + end + end + + if Config.ShowStations then + local LEOStation = _MenuPool:AddSubMenu(LEOMenu, 'Stations', '', true) + LEOStation:SetMenuWidthOffset(Config.MenuWidth) + for _, Station in pairs(Config.LEOStations) do + local StationCategory = _MenuPool:AddSubMenu(LEOStation, Station.name, '', true) + StationCategory:SetMenuWidthOffset(Config.MenuWidth) + local SetWaypoint = NativeUI.CreateItem('Set Waypoint', 'Set a waypoint to the station') + local Teleport = NativeUI.CreateItem('Teleport', 'Teleport to the station') + StationCategory:AddItem(SetWaypoint) + if Config.AllowStationTeleport then + StationCategory:AddItem(Teleport) + end + SetWaypoint.Activated = function(ParentMenu, SelectedItem) + SetNewWaypoint(Station.coords.x, Station.coords.y) + end + Teleport.Activated = function(ParentMenu, SelectedItem) + SetEntityCoords(PlayerPedId(), Station.coords.x, Station.coords.y, Station.coords.z) + SetEntityHeading(PlayerPedId(), Station.coords.h) + end + end + end + + if Config.DisplayLEOUniforms or Config.DisplayLEOLoadouts then + local LEOLoadouts = _MenuPool:AddSubMenu(LEOMenu, 'Loadouts', '', true) + LEOLoadouts:SetMenuWidthOffset(Config.MenuWidth) + UniformsList = {} + for _, Uniform in pairs(Config.LEOUniforms) do + table.insert(UniformsList, Uniform.name) + end + + LoadoutsList = {} + for Name, Loadout in pairs(Config.LEOLoadouts) do + table.insert(LoadoutsList, Name) + end + + local Uniforms = NativeUI.CreateListItem('Uniforms', UniformsList, 1, 'Spawn LEO uniforms') + local Loadouts = NativeUI.CreateListItem('Loadouts', LoadoutsList, 1, 'Spawn LEO weapon loadouts') + if Config.DisplayLEOUniforms then + LEOLoadouts:AddItem(Uniforms) + end + if Config.DisplayLEOLoadouts then + LEOLoadouts:AddItem(Loadouts) + end + LEOLoadouts.OnListSelect = function(sender, item, index) + if item == Uniforms then + for _, Uniform in pairs(Config.LEOUniforms) do + if Uniform.name == item:IndexToItem(index) then + LoadPed(Uniform.spawncode) + Notify('~b~Uniform Spawned: ~g~' .. Uniform.name) + end + end + end + + + + if item == Loadouts then + for Name, Loadout in pairs(Config.LEOLoadouts) do + if Name == item:IndexToItem(index) then + SetEntityHealth(GetPlayerPed(-1), 200) + RemoveAllPedWeapons(GetPlayerPed(-1), true) + AddArmourToPed(GetPlayerPed(-1), 100) + + for _, Weapon in pairs(Loadout) do + GiveWeapon(Weapon.weapon) + + for _, Component in pairs(Weapon.components) do + AddWeaponComponent(Weapon.weapon, Component) + end + end + + Notify('~b~Loadout Spawned: ~g~' .. Name) + end + end + end + end + end + + if Config.ShowLEOVehicles then + local LEOVehicles = _MenuPool:AddSubMenu(LEOMenu, 'Vehicles', '', true) + LEOVehicles:SetMenuWidthOffset(Config.MenuWidth) + + for Name, Category in pairs(Config.LEOVehiclesCategories) do + local LEOCategory = _MenuPool:AddSubMenu(LEOVehicles, Name, '', true) + LEOCategory:SetMenuWidthOffset(Config.MenuWidth) + for _, Vehicle in pairs(Category) do + local LEOVehicle = NativeUI.CreateItem(Vehicle.name, '') + LEOCategory:AddItem(LEOVehicle) + if Config.ShowLEOSpawnCode then + LEOVehicle:RightLabel(Vehicle.spawncode) + end + LEOVehicle.Activated = function(ParentMenu, SelectedItem) + SpawnVehicle(Vehicle.spawncode, Vehicle.name, Vehicle.livery, Vehicle.extras) + end + end + end + end + + if Config.DisplayTrafficManager then + local LEOTrafficManager = _MenuPool:AddSubMenu(LEOMenu, 'Traffic Manager', '', true) + LEOTrafficManager:SetMenuWidthOffset(Config.MenuWidth) + + TMSize = 10.0 + TMSpeed = 0.0 + RaduiesNames = {} + Raduies = { + {name = '10m', size = 10.0}, + {name = '20m', size = 20.0}, + {name = '30m', size = 30.0}, + {name = '40m', size = 40.0}, + {name = '50m', size = 50.0}, + {name = '60m', size = 60.0}, + {name = '70m', size = 70.0}, + {name = '80m', size = 80.0}, + {name = '90m', size = 90.0}, + {name = '100m', size = 100.0}, + } + SpeedsNames = {} + Speeds = { + {name = '0 mph', speed = 0.0}, + {name = '5 mph', speed = 5.0}, + {name = '10 mph', speed = 10.0}, + {name = '15 mph', speed = 15.0}, + {name = '20 mph', speed = 20.0}, + {name = '25 mph', speed = 25.0}, + {name = '30 mph', speed = 30.0}, + {name = '40 mph', speed = 40.0}, + {name = '50 mph', speed = 50.0}, + } + + for _, RaduisInfo in pairs(Raduies) do + table.insert(RaduiesNames, RaduisInfo.name) + end + for _, SpeedsInfo in pairs(Speeds) do + table.insert(SpeedsNames, SpeedsInfo.name) + end + + local Radius = NativeUI.CreateListItem('Radius', RaduiesNames, 1, '') + local Speed = NativeUI.CreateListItem('Speed', SpeedsNames, 1, '') + local TMCreate = NativeUI.CreateItem('Create Speed Zone', '') + local TMDelete = NativeUI.CreateItem('Delete Speed Zone', '') + LEOTrafficManager:AddItem(Radius) + LEOTrafficManager:AddItem(Speed) + LEOTrafficManager:AddItem(TMCreate) + LEOTrafficManager:AddItem(TMDelete) + Radius.OnListChanged = function(sender, item, index) + TMSize = Raduies[index].size + end + Speed.OnListChanged = function(sender, item, index) + TMSpeed = Speeds[index].speed + end + TMCreate.Activated = function(ParentMenu, SelectedItem) + if Zone == nil then + Zone = AddSpeedZoneForCoord(GetEntityCoords(PlayerPedId()), TMSize, TMSpeed, false) + Area = AddBlipForRadius(GetEntityCoords(PlayerPedId()), TMSize) + SetBlipAlpha(Area, 100) + Notify('~g~Speed Zone Created') + else + Notify('~y~You already have a Speed Zone created') + end + end + TMDelete.Activated = function(ParentMenu, SelectedItem) + if Zone ~= nil then + RemoveSpeedZone(Zone) + RemoveBlip(Area) + Zone = nil + Notify('~r~Speed Zone Deleted') + else + Notify('~y~You don\'t have a Speed Zone') + end + end + end + end + + + + + if FireRestrict() then + local FireMenu = _MenuPool:AddSubMenu(MainMenu, 'Fire Toolbox', 'Fire Related Menu', true) + FireMenu:SetMenuWidthOffset(Config.MenuWidth) + local FireActions = _MenuPool:AddSubMenu(FireMenu, 'Actions', '', true) + FireActions:SetMenuWidthOffset(Config.MenuWidth) + local Drag = NativeUI.CreateItem('Drag', 'Drag/Undrag the closest player') + local Seat = NativeUI.CreateItem('Seat', 'Place a player in the closest vehicle') + local Unseat = NativeUI.CreateItem('Unseat', 'Remove a player from the closest vehicle') + FireActions:AddItem(Drag) + FireActions:AddItem(Seat) + FireActions:AddItem(Unseat) + Drag.Activated = function(ParentMenu, SelectedItem) + local player = GetClosestPlayer() + if player ~= false then + TriggerServerEvent('SEM_InteractionMenu:DragNear', player) + end + end + Seat.Activated = function(ParentMenu, SelectedItem) + local player = GetClosestPlayer() + if player ~= false then + TriggerServerEvent('SEM_InteractionMenu:SeatNear', player, Veh) + end + end + Unseat.Activated = function(ParentMenu, SelectedItem) + if IsPedInAnyVehicle(GetPlayerPed(-1), true) then + Notify('~o~You need to be outside of the vehicle') + return + end + + local player = GetClosestPlayer() + if player ~= false then + TriggerServerEvent('SEM_InteractionMenu:UnseatNear', player) + end + end + if Config.FireHospital then + local HospitalLocations = _MenuPool:AddSubMenu(FireActions, 'Hospitalize', '', true) + HospitalLocations:SetMenuWidthOffset(Config.MenuWidth) + for HospitalName, HospitalInfo in pairs(Config.HospitalLocation) do + local Hospitalize = NativeUI.CreateItem(HospitalName, 'Hospitalize a player') + HospitalLocations:AddItem(Hospitalize) + Hospitalize.Activated = function(ParentMenu, SelectedItem) + local PlayerID = tonumber(KeyboardInput('Player ID:', 10)) + if PlayerID == nil then + Notify('~r~Please enter a player ID') + return + end + + local HospitalTime = tonumber(KeyboardInput('Time: (Seconds) - Max Time: ' .. Config.MaxHospitalTime .. ' | Default Time: 30', 3)) + if HospitalTime == nil then + HospitalTime = 30 + end + if HospitalTime > Config.MaxHospitalTime then + Notify('~y~Exceeded Max Time\nMax Time: ' .. Config.MaxHospitalTime .. ' seconds') + HospitalTime = Config.MaxHospitalTime + end + + Notify('Player Hospitalized for ~b~' .. HospitalTime .. ' seconds') + TriggerServerEvent('SEM_InteractionMenu:Hospitalize', PlayerID, HospitalTime, HospitalInfo) + end + end + local Unhospitalize = NativeUI.CreateItem('Unhospitalize', 'Unhospitalize a player') + if UnhospitalAllowed then + FireActions:AddItem(Unhospitalize) + end + Unhospitalize.Activated = function(ParentMenu, SelectedItem) + local PlayerID = tonumber(KeyboardInput('Player ID:', 10)) + if PlayerID == nil then + Notify('~r~Please enter a player ID') + return + end + + TriggerServerEvent('SEM_InteractionMenu:Unhospitalize', PlayerID) + end + end + PropsList = {} + for _, Prop in pairs(Config.Props) do + table.insert(PropsList, Prop.name) + end + local Props = NativeUI.CreateListItem('Spawn Props', PropsList, 1, 'Spawn props on the ground') + local RemoveProps = NativeUI.CreateItem('Remove Props', 'Remove the closest prop') + FireActions:AddItem(Props) + FireActions:AddItem(RemoveProps) + FireActions.OnListSelect = function(sender, item, index) + if item == Props then + for _, Prop in pairs(Config.Props) do + if Prop.name == item:IndexToItem(index) then + SpawnProp(Prop.spawncode, Prop.name) + end + end + end + end + RemoveProps.Activated = function(ParentMenu, SelectedItem) + for _, Prop in pairs(Config.Props) do + DeleteProp(Prop.spawncode) + end + end + + if Config.ShowStations then + local FireEMSStation = _MenuPool:AddSubMenu(FireMenu, 'Stations', '', true) + FireEMSStation:SetMenuWidthOffset(Config.MenuWidth) + local FireStation = _MenuPool:AddSubMenu(FireEMSStation, 'Fire Stations', '', true) + FireStation:SetMenuWidthOffset(Config.MenuWidth) + for _, Station in pairs(Config.FireStations) do + local StationCategory = _MenuPool:AddSubMenu(FireStation, Station.name, '', true) + StationCategory:SetMenuWidthOffset(Config.MenuWidth) + local SetWaypoint = NativeUI.CreateItem('Set Waypoint', 'Set a waypoint to the station') + local Teleport = NativeUI.CreateItem('Teleport', 'Teleport to the station') + StationCategory:AddItem(SetWaypoint) + if Config.AllowStationTeleport then + StationCategory:AddItem(Teleport) + end + SetWaypoint.Activated = function(ParentMenu, SelectedItem) + SetNewWaypoint(Station.coords.x, Station.coords.y) + end + Teleport.Activated = function(ParentMenu, SelectedItem) + SetEntityCoords(PlayerPedId(), Station.coords.x, Station.coords.y, Station.coords.z) + SetEntityHeading(PlayerPedId(), Station.coords.h) + end + end + + local EMSStation = _MenuPool:AddSubMenu(FireEMSStation, 'Hospitals', '', true) + EMSStation:SetMenuWidthOffset(Config.MenuWidth) + for _, Station in pairs(Config.HospitalStations) do + local StationCategory = _MenuPool:AddSubMenu(EMSStation, Station.name, '', true) + StationCategory:SetMenuWidthOffset(Config.MenuWidth) + local SetWaypoint = NativeUI.CreateItem('Set Waypoint', 'Set a waypoint to the hospital') + local Teleport = NativeUI.CreateItem('Teleport', 'Teleport to the hospital') + StationCategory:AddItem(SetWaypoint) + if Config.AllowStationTeleport then + StationCategory:AddItem(Teleport) + end + SetWaypoint.Activated = function(ParentMenu, SelectedItem) + SetNewWaypoint(Station.coords.x, Station.coords.y) + end + Teleport.Activated = function(ParentMenu, SelectedItem) + SetEntityCoords(PlayerPedId(), Station.coords.x, Station.coords.y, Station.coords.z) + SetEntityHeading(PlayerPedId(), Station.coords.h) + end + end + end + + if Config.DisplayFireUniforms or Config.DisplayFireLoadouts then + local FireLoadouts = _MenuPool:AddSubMenu(FireMenu, 'Loadouts', '', true) + FireLoadouts:SetMenuWidthOffset(Config.MenuWidth) + UniformsList = {} + for _, Uniform in pairs(Config.FireUniforms) do + table.insert(UniformsList, Uniform.name) + end + + LoadoutsList = { + 'Clear', + 'Standard', + } + local Uniforms = NativeUI.CreateListItem('Uniforms', UniformsList, 1, 'Spawn Fire uniforms') + local Loadouts = NativeUI.CreateListItem('Loadouts', LoadoutsList, 1, 'Spawns Fire weapon loadouts') + if Config.DisplayFireUniforms then + FireLoadouts:AddItem(Uniforms) + end + if Config.DisplayFireLoadouts then + FireLoadouts:AddItem(Loadouts) + end + FireLoadouts.OnListSelect = function(sender, item, index) + if item == Uniforms then + for _, Uniform in pairs(Config.FireUniforms) do + if Uniform.name == item:IndexToItem(index) then + LoadPed(Uniform.spawncode) + Notify('~b~Uniform Spawned: ~g~' .. Uniform.name) + end + end + end + + + + if item == Loadouts then + local SelectedLoadout = item:IndexToItem(index) + if SelectedLoadout == 'Clear' then + SetEntityHealth(GetPlayerPed(-1), 200) + RemoveAllPedWeapons(GetPlayerPed(-1), true) + Notify('~r~All Weapons Cleared!') + elseif SelectedLoadout == 'Standard' then + SetEntityHealth(GetPlayerPed(-1), 200) + RemoveAllPedWeapons(GetPlayerPed(-1), true) + AddArmourToPed(GetPlayerPed(-1), 100) + GiveWeapon('weapon_flashlight') + GiveWeapon('weapon_fireextinguisher') + GiveWeapon('weapon_flare') + GiveWeapon('weapon_stungun') + Notify('~b~Loadout Spawned: ~g~' .. SelectedLoadout) + end + end + end + end + + if Config.ShowFireVehicles then + local FireVehicles = _MenuPool:AddSubMenu(FireMenu, 'Vehicles', '', true) + FireVehicles:SetMenuWidthOffset(Config.MenuWidth) + + for _, Vehicle in pairs(Config.FireVehicles) do + local FireVehicle = NativeUI.CreateItem(Vehicle.name, '') + FireVehicles:AddItem(FireVehicle) + if Config.ShowFireSpawnCode then + FireVehicle:RightLabel(Vehicle.spawncode) + end + FireVehicle.Activated = function(ParentMenu, SelectedItem) + SpawnVehicle(Vehicle.spawncode, Vehicle.name, Vehicle.livery, Vehicle.extras) + end + end + end + end + + + + + if CivRestrict() then + local CivMenu = _MenuPool:AddSubMenu(MainMenu, 'Civ Toolbox', 'Civilian Related Menu', true) + CivMenu:SetMenuWidthOffset(Config.MenuWidth) + local CivActions = _MenuPool:AddSubMenu(CivMenu, 'Actions', '', true) + CivActions:SetMenuWidthOffset(Config.MenuWidth) + local HU = NativeUI.CreateItem('Hands Up', 'Put your hands up') + local HUK = NativeUI.CreateItem('Hand Up & Kneel', 'Put your hands up and kneel on the ground') + local Inventory = NativeUI.CreateItem('Inventory', 'Set your inventory') + local BAC = NativeUI.CreateItem('BAC', 'Set your BAC level') + local DropWeapon = NativeUI.CreateItem('Drop Weapon', 'Drop your current weapon on the ground') + CivActions:AddItem(HU) + CivActions:AddItem(HUK) + CivActions:AddItem(Inventory) + CivActions:AddItem(BAC) + CivActions:AddItem(DropWeapon) + HU.Activated = function(ParentMenu, SelectedItem) + local Ped = PlayerPedId() + if DoesEntityExist(Ped) and not HandCuffed then + Citizen.CreateThread(function() + LoadAnimation('random@mugging3') + if IsEntityPlayingAnim(Ped, 'random@mugging3', 'handsup_standing_base', 3) or HandCuffed then + ClearPedSecondaryTask(Ped) + SetEnableHandcuffs(Ped, false) + elseif not IsEntityPlayingAnim(Ped, 'random@mugging3', 'handsup_standing_base', 3) or not HandCuffed then + TaskPlayAnim(Ped, 'random@mugging3', 'handsup_standing_base', 8.0, -8, -1, 49, 0, 0, 0, 0) + SetEnableHandcuffs(Ped, true) + end + end) + end + end + HUK.Activated = function(ParentMenu, SelectedItem) + local Ped = PlayerPedId() + if (DoesEntityExist(Ped) and not IsEntityDead(Ped)) and not HandCuffed then + Citizen.CreateThread(function() + LoadAnimation('random@arrests') + if (IsEntityPlayingAnim(Ped, 'random@arrests', 'kneeling_arrest_idle', 3)) then + TaskPlayAnim(Ped, 'random@arrests', 'kneeling_arrest_get_up', 8.0, 1.0, -1, 128, 0, 0, 0, 0) + else + TaskPlayAnim(Ped, 'random@arrests', 'idle_2_hands_up', 8.0, 1.0, -1, 2, 0, 0, 0, 0) + Wait (4000) + TaskPlayAnim(Ped, 'random@arrests', 'kneeling_arrest_idle', 8.0, 1.0, -1, 2, 0, 0, 0, 0) + end + end) + end + end + Inventory.Activated = function(ParentMenu, SelectedItem) + local Items = KeyboardInput('Items:', 75) + if Items == nil or Items == '' then + Notify('~r~No Items Provided!') + return + end + + TriggerServerEvent('SEM_InteractionMenu:InventorySet', Items) + Notify('~g~Inventory Set!') + end + BAC.Activated = function(ParentMenu, SelectedItem) + local BACLevel = KeyboardInput('BAC Level - Legal Limit: 0.08', 5) + if BACLevel == nil or BACLevel == '' then + Notify('~r~No BAC Level Provided!') + return + end + + TriggerServerEvent('SEM_InteractionMenu:BACSet', tonumber(BACLevel)) + if tonumber(BACLevel) < 0.08 then + Notify('~b~BAC Level Set: ~g~' .. tostring(BACLevel)) + else + Notify('~b~BAC Level Set: ~r~' .. tostring(BACLevel)) + end + end + DropWeapon.Activated = function(ParentMenu, SelectedItem) + local CurrentWeapon = GetSelectedPedWeapon(PlayerPedId()) + SetCurrentPedWeapon(PlayerPedId(), 'weapon_unarmed', true) + SetPedDropsInventoryWeapon(GetPlayerPed(-1), CurrentWeapon, -2.0, 0.0, 0.5, 30) + Notify('~r~Weapon Dropped!') + end + if Config.ShowCivAdverts then + local CivAdverts = _MenuPool:AddSubMenu(CivMenu, 'Adverts', '', true) + CivAdverts:SetMenuWidthOffset(Config.MenuWidth) + for _, Ad in pairs(Config.CivAdverts) do + local Advert = NativeUI.CreateItem(Ad.name, 'Send an advert for ' .. Ad.name) + CivAdverts:AddItem(Advert) + Advert.Activated = function(ParentMenu, SelectedItem) + local Message = KeyboardInput('Message:', 128) + if Message == nil or Message == '' then + Notify('~r~No Advert Message Provided!') + return + end + + TriggerServerEvent('SEM_InteractionMenu:Ads', Message, Ad.name, Ad.loc, Ad.file) + end + end + end + if Config.ShowCivVehicles then + local CivVehicles = _MenuPool:AddSubMenu(CivMenu, 'Vehicles', '', true) + CivVehicles:SetMenuWidthOffset(Config.MenuWidth) + + for _, Vehicle in pairs(Config.CivVehicles) do + local CivVehicle = NativeUI.CreateItem(Vehicle.name, '') + CivVehicles:AddItem(CivVehicle) + if Config.ShowCivSpawnCode then + CivVehicle:RightLabel(Vehicle.spawncode) + end + CivVehicle.Activated = function(ParentMenu, SelectedItem) + SpawnVehicle(Vehicle.spawncode, Vehicle.name) + end + end + end + end + + + + + + if VehicleRestrict() then + local VehicleMenu = _MenuPool:AddSubMenu(MainMenu, 'Vehicle', 'Vehicle Related Menu', true) + VehicleMenu:SetMenuWidthOffset(Config.MenuWidth) + local Seats = {-1, 0, 1, 2} + local Windows = {'Front', 'Rear', 'All'} + local Doors = {'Driver', 'Passenger', 'Rear Right', 'Rear Left', 'Hood', 'Trunk', 'All'} + local Engine = NativeUI.CreateItem('Toggle Engine', 'Toggle your vehicle\'s engine') + local ILights = NativeUI.CreateItem('Toggle Interior Light', 'Toggle your vehicle\'s interior light') + local Seat = NativeUI.CreateSliderItem('Change Seats', Seats, 1, 'Switch to a different seat') + local Window = NativeUI.CreateListItem('Windows', Windows, 1, 'Open/Close your vehicle\'s windows') + local Door = NativeUI.CreateListItem('Doors', Doors, 1, 'Open/Close your vehicle\'s doors') + local FixVeh = NativeUI.CreateItem('Repair Vehicle', 'Repair your current vehicle') + local CleanVeh = NativeUI.CreateItem('Clean Vehicle', 'Clean your current vehicle') + local DelVeh = NativeUI.CreateItem('~r~Delete Vehicle', 'Delete your current vehicle') + VehicleMenu:AddItem(Engine) + VehicleMenu:AddItem(ILights) + VehicleMenu:AddItem(Seat) + VehicleMenu:AddItem(Window) + VehicleMenu:AddItem(Door) + if Config.VehicleOptions then + VehicleMenu:AddItem(FixVeh) + VehicleMenu:AddItem(CleanVeh) + VehicleMenu:AddItem(DelVeh) + end + Engine.Activated = function(ParentMenu, SelectedItem) + local Vehicle = GetVehiclePedIsIn(PlayerPedId(), false) + if Vehicle ~= nil and Vehicle ~= 0 and GetPedInVehicleSeat(Vehicle, 0) then + SetVehicleEngineOn(Vehicle, (not GetIsVehicleEngineRunning(Vehicle)), false, true) + Notify('~g~Engine Toggled!') + else + Notify('~r~You\'re not in a Vehicle!') + end + end + ILights.Activated = function(ParentMenu, SelectedItem) + local Vehicle = GetVehiclePedIsIn(PlayerPedId(), false) + + if IsPedInVehicle(PlayerPedId(), Vehicle, false) then + if IsVehicleInteriorLightOn(Vehicle) then + SetVehicleInteriorlight(Vehicle, false) + else + SetVehicleInteriorlight(Vehicle, true) + end + else + Notify('~r~You\'re not in a Vehicle!') + end + end + VehicleMenu.OnSliderChange = function(sender, item, index) + if item == Seat then + VehicleSeat = item:IndexToItem(index) + local Veh = GetVehiclePedIsIn(GetPlayerPed(-1),false) + SetPedIntoVehicle(PlayerPedId(), Veh, VehicleSeat) + end + end + VehicleMenu.OnListSelect = function(sender, item, index) + local Ped = GetPlayerPed(-1) + local Veh = GetVehiclePedIsIn(Ped, false) + + if item == Window then + VehicleWindow = item:IndexToItem(index) + if VehicleWindow == 'Front' then + if IsPedInAnyVehicle(Ped, false) then + if (GetPedInVehicleSeat(Veh, -1) == Ped) then + SetEntityAsMissionEntity(Veh, true, true) + if (WindowFrontRolled) then + RollDownWindow(Veh, 0) + RollDownWindow(Veh, 1) + WindowFrontRolled = false + else + RollUpWindow(Veh, 0) + RollUpWindow(Veh, 1) + WindowFrontRolled = true + end + end + end + elseif VehicleWindow == 'Rear' then + if IsPedInAnyVehicle(Ped, false) then + if (GetPedInVehicleSeat(Veh, -1) == Ped) then + SetEntityAsMissionEntity(Veh, true, true) + if (WindowFrontRolled) then + RollDownWindow(Veh, 2) + RollDownWindow(Veh, 3) + WindowFrontRolled = false + else + RollUpWindow(Veh, 2) + RollUpWindow(Veh, 3) + WindowFrontRolled = true + end + end + end + elseif VehicleWindow == 'All' then + if IsPedInAnyVehicle(Ped, false) then + if (GetPedInVehicleSeat(Veh, -1) == Ped) then + SetEntityAsMissionEntity(Veh, true, true) + if (WindowFrontRolled) then + RollDownWindow(Veh, 0) + RollDownWindow(Veh, 1) + RollDownWindow(Veh, 2) + RollDownWindow(Veh, 3) + WindowFrontRolled = false + else + RollUpWindow(Veh, 0) + RollUpWindow(Veh, 1) + RollUpWindow(Veh, 2) + RollUpWindow(Veh, 3) + WindowFrontRolled = true + end + end + end + end + elseif item == Door then + local Doors = {'Driver', 'Passenger', 'Rear Left', 'Rear Right', 'Hood', 'Trunk', 'All'} + VehicleDoor = item:IndexToItem(index) + if VehicleDoor == 'Driver' then + if Veh ~= nil and Veh ~= 0 and Veh ~= 1 then + if GetVehicleDoorAngleRatio(Veh, 0) > 0 then + SetVehicleDoorShut(Veh, 0, false) + else + SetVehicleDoorOpen(Veh, 0, false, false) + end + end + elseif VehicleDoor == 'Passenger' then + if Veh ~= nil and Veh ~= 0 and Veh ~= 1 then + if GetVehicleDoorAngleRatio(Veh, 1) > 0 then + SetVehicleDoorShut(Veh, 1, false) + else + SetVehicleDoorOpen(Veh, 1, false, false) + end + end + elseif VehicleDoor == 'Rear Left' then + if Veh ~= nil and Veh ~= 0 and Veh ~= 1 then + if GetVehicleDoorAngleRatio(Veh, 2) > 0 then + SetVehicleDoorShut(Veh, 2, false) + else + SetVehicleDoorOpen(Veh, 2, false, false) + end + end + elseif VehicleDoor == 'Rear Right' then + if Veh ~= nil and Veh ~= 0 and Veh ~= 1 then + if GetVehicleDoorAngleRatio(Veh, 3) > 0 then + SetVehicleDoorShut(Veh, 3, false) + else + SetVehicleDoorOpen(Veh, 3, false, false) + end + end + elseif VehicleDoor == 'Hood' then + if Veh ~= nil and Veh ~= 0 and Veh ~= 1 then + if GetVehicleDoorAngleRatio(Veh, 4) > 0 then + SetVehicleDoorShut(Veh, 4, false) + else + SetVehicleDoorOpen(Veh, 4, false, false) + end + end + elseif VehicleDoor == 'Trunk' then + if Veh ~= nil and Veh ~= 0 and Veh ~= 1 then + if GetVehicleDoorAngleRatio(Veh, 5) > 0 then + SetVehicleDoorShut(Veh, 5, false) + else + SetVehicleDoorOpen(Veh, 5, false, false) + end + end + elseif VehicleDoor == 'All' then + if Veh ~= nil and Veh ~= 0 and Veh ~= 1 then + if GetVehicleDoorAngleRatio(Veh, 0) > 0 then + SetVehicleDoorShut(Veh, 0, false) + SetVehicleDoorShut(Veh, 1, false) + SetVehicleDoorShut(Veh, 2, false) + SetVehicleDoorShut(Veh, 3, false) + SetVehicleDoorShut(Veh, 4, false) + SetVehicleDoorShut(Veh, 5, false) + else + SetVehicleDoorOpen(Veh, 0, false, false) + SetVehicleDoorOpen(Veh, 1, false, false) + SetVehicleDoorOpen(Veh, 2, false, false) + SetVehicleDoorOpen(Veh, 3, false, false) + SetVehicleDoorOpen(Veh, 4, false, false) + SetVehicleDoorOpen(Veh, 5, false, false) + end + end + end + end + end + FixVeh.Activated = function(ParentMenu, SelectedItem) + local Vehicle = GetVehiclePedIsIn(PlayerPedId(), false) + if Vehicle ~= nil and Vehicle ~= 0 then + SetVehicleEngineHealth(Vehicle, 100) + SetVehicleFixed(Vehicle) + Notify('~g~Vehicle Repaired!') + else + Notify('~r~You\'re not in a Vehicle!') + end + + end + CleanVeh.Activated = function(ParentMenu, SelectedItem) + local Vehicle = GetVehiclePedIsIn(PlayerPedId(), false) + if Vehicle ~= nil and Vehicle ~= 0 then + SetVehicleDirtLevel(Vehicle, 0) + Notify('~g~Vehicle Cleaned!') + else + Notify('~r~You\'re not in a Vehicle!') + end + end + DelVeh.Activated = function(ParentMenu, SelectedItem) + if (IsPedSittingInAnyVehicle(PlayerPedId())) then + local Vehicle = GetVehiclePedIsIn(PlayerPedId(), false) + + if (GetPedInVehicleSeat(Vehicle, -1) == PlayerPedId()) then + SetEntityAsMissionEntity(Vehicle, true, true) + DeleteVehicle(Vehicle) + + if (DoesEntityExist(Vehicle)) then + Notify('~o~Unable to delete vehicle, try again.') + else + Notify('~r~Vehicle Deleted!') + end + else + Notify('~r~You must be in the driver\'s seat!') + end + else + Notify('~r~You\'re not in a Vehicle!') + end + end + end + + + + + + if EmoteRestrict() then + local EmotesList = {} + for _, Emote in pairs(Config.EmotesList) do + table.insert(EmotesList, Emote.name) + end + + local EmotesMenu = NativeUI.CreateListItem('Emotes', EmotesList, 1, 'General RP Emotes') + MainMenu:AddItem(EmotesMenu) + + MainMenu.OnListSelect = function(sender, item, index) + if item == EmotesMenu then + for _, Emote in pairs(Config.EmotesList) do + if Emote.name == item:IndexToItem(index) then + PlayEmote(Emote.emote, Emote.name) + end + end + end + end + end + + + + _MenuPool:RefreshIndex() +end + + + +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + + _MenuPool:ProcessMenus() + _MenuPool:ControlDisablingEnabled(false) + _MenuPool:MouseControlsEnabled(false) + + if IsControlJustPressed(1, Config.MenuButton) and GetLastInputMethod(2) then + if not menuOpen then + Menu() + MainMenu:Visible(true) + else + _MenuPool:CloseAllMenus() + end + end + end +end) + + + +RegisterCommand(Config.Command, function(source, args, rawCommands) + if Config.OpenMenu == 1 then + Menu() + MainMenu:Visible(true) + end +end) + +Citizen.CreateThread(function() + if Config.OpenMenu == 1 then + TriggerEvent('chat:addSuggestion', '/' .. Config.Command, 'Used to open SEM_InteractionMenu') + end +end) diff --git a/resources/Interaction-Menu/server.lua b/resources/Interaction-Menu/server.lua new file mode 100644 index 000000000..abb055a30 --- /dev/null +++ b/resources/Interaction-Menu/server.lua @@ -0,0 +1,246 @@ +--[[ +─────────────────────────────────────────────────────────────── + + SEM_InteractionMenu (server.lua) - Created by Scott M + Current Version: v1.7.1 (Sep 2021) + + Support: https://semdevelopment.com/discord + + !!! Change vaules in the 'config.lua' !!! + DO NOT EDIT THIS IF YOU DON'T KNOW WHAT YOU ARE DOING + +─────────────────────────────────────────────────────────────── +]] + + + +RegisterServerEvent('SEM_InteractionMenu:GlobalChat') +AddEventHandler('SEM_InteractionMenu:GlobalChat', function(Color, Prefix, Message) + TriggerClientEvent('chatMessage', -1, Prefix, Color, Message) +end) + +RegisterServerEvent('SEM_InteractionMenu:CuffNear') +AddEventHandler('SEM_InteractionMenu:CuffNear', function(ID) + if ID == -1 or ID == '-1' then + if source ~= '' then + print('^1[#' .. source .. '] ' .. GetPlayerName(source) .. ' - attempted to cuff all players^7') + DropPlayer(source, '\n[SEM_InteractionMenu] Attempting to cuff all players') + else + print('^1Someone attempted to cuff all players^7') + end + + return + end + + if ID ~= false then + TriggerClientEvent('SEM_InteractionMenu:Cuff', ID) + end +end) + +RegisterServerEvent('SEM_InteractionMenu:DragNear') +AddEventHandler('SEM_InteractionMenu:DragNear', function(ID) + if ID == -1 or ID == '-1' then + if source ~= '' then + print('^1[#' .. source .. '] ' .. GetPlayerName(source) .. ' - attempted to drag all players^7') + DropPlayer(source, '\n[SEM_InteractionMenu] Attempting to drag all players') + else + print('^1Someone attempted to drag all players^7') + end + + return + end + + if ID ~= false and ID ~= source then + TriggerClientEvent('SEM_InteractionMenu:Drag', ID, source) + end +end) + +RegisterServerEvent('SEM_InteractionMenu:SeatNear') +AddEventHandler('SEM_InteractionMenu:SeatNear', function(ID, Vehicle) + TriggerClientEvent('SEM_InteractionMenu:Seat', ID, Vehicle) +end) + +RegisterServerEvent('SEM_InteractionMenu:UnseatNear') +AddEventHandler('SEM_InteractionMenu:UnseatNear', function(ID, Vehicle) + TriggerClientEvent('SEM_InteractionMenu:Unseat', ID, Vehicle) +end) + +RegisterServerEvent('SEM_InteractionMenu:Jail') +AddEventHandler('SEM_InteractionMenu:Jail', function(ID, Time) + if ID == -1 or ID == '-1' then + if source ~= '' then + print('^1[#' .. source .. '] ' .. GetPlayerName(source) .. ' - attempted to jail all players^7') + DropPlayer(source, '\n[SEM_InteractionMenu] Attempting to jail all players') + else + print('^1Someone attempted to jail all players^7') + end + + return + end + + TriggerClientEvent('SEM_InteractionMenu:JailPlayer', ID, Time) + TriggerClientEvent('chatMessage', -1, 'Judge', {86, 96, 252}, GetPlayerName(ID) .. ' has been Jailed for ' .. Time .. ' months(s)') +end) + +RegisterServerEvent('SEM_InteractionMenu:Unjail') +AddEventHandler('SEM_InteractionMenu:Unjail', function(ID) + TriggerClientEvent('SEM_InteractionMenu:UnjailPlayer', ID) +end) + +RegisterServerEvent('SEM_InteractionMenu:Backup') +AddEventHandler('SEM_InteractionMenu:Backup', function(Code, StreetName, Coords) + TriggerClientEvent('SEM_InteractionMenu:CallBackup', -1, Code, StreetName, Coords) +end) + +RegisterServerEvent('SEM_InteractionMenu:Ads') +AddEventHandler('SEM_InteractionMenu:Ads', function(Text, Name, Loc, File) + TriggerClientEvent('SEM_InteractionMenu:SyncAds', -1, Text, Name, Loc, File, source) +end) + +BACList = {} +RegisterServerEvent('SEM_InteractionMenu:BACSet') +AddEventHandler('SEM_InteractionMenu:BACSet', function(BACLevel) + BACList[source] = BACLevel +end) + +RegisterServerEvent('SEM_InteractionMenu:BACTest') +AddEventHandler('SEM_InteractionMenu:BACTest', function(ID) + local BACLevel = BACList[ID] + TriggerClientEvent('SEM_InteractionMenu:BACResult', source, BACLevel) +end) + +Inventories = {} +RegisterServerEvent('SEM_InteractionMenu:InventorySet') +AddEventHandler('SEM_InteractionMenu:InventorySet', function(Items) + Inventories[source] = Items +end) + +RegisterServerEvent('SEM_InteractionMenu:InventorySearch') +AddEventHandler('SEM_InteractionMenu:InventorySearch', function(ID) + local Inventory = Inventories[ID] + + TriggerClientEvent('SEM_InteractionMenu:InventoryResult', source, Inventory) +end) + +RegisterServerEvent('SEM_InteractionMenu:Hospitalize') +AddEventHandler('SEM_InteractionMenu:Hospitalize', function(ID, Time, Location) + if ID == -1 or ID == '-1' then + if source ~= '' then + print('^1[#' .. source .. '] ' .. GetPlayerName(source) .. ' - attempted to hospitalize all players^7') + DropPlayer(source, '\n[SEM_InteractionMenu] Attempting to hospitalize all players') + else + print('^1Someone attempted to hospitalize all players^7') + end + + return + end + + TriggerClientEvent('SEM_InteractionMenu:HospitalizePlayer', ID, Time, Location) + TriggerClientEvent('chatMessage', -1, 'Doctor', {86, 96, 252}, GetPlayerName(ID) .. ' has been Hospitalized for ' .. Time .. ' months(s)') +end) + +RegisterServerEvent('SEM_InteractionMenu:Unhospitalize') +AddEventHandler('SEM_InteractionMenu:Unhospitalize', function(ID) + TriggerClientEvent('SEM_InteractionMenu:UnhospitalizePlayer', ID) +end) + +RegisterServerEvent('SEM_InteractionMenu:LEOPerms') +AddEventHandler('SEM_InteractionMenu:LEOPerms', function() + if IsPlayerAceAllowed(source, 'sem_intmenu.leo') then + TriggerClientEvent('SEM_InteractionMenu:LEOPermsResult', source, true) + else + TriggerClientEvent('SEM_InteractionMenu:LEOPermsResult', source, false) + end +end) + +RegisterServerEvent('SEM_InteractionMenu:FirePerms') +AddEventHandler('SEM_InteractionMenu:FirePerms', function() + if IsPlayerAceAllowed(source, 'sem_intmenu.fire') then + TriggerClientEvent('SEM_InteractionMenu:FirePermsResult', source, true) + else + TriggerClientEvent('SEM_InteractionMenu:FirePermsResult', source, false) + end +end) + +RegisterServerEvent('SEM_InteractionMenu:UnjailPerms') +AddEventHandler('SEM_InteractionMenu:UnjailPerms', function() + if IsPlayerAceAllowed(source, 'sem_intmenu.unjail') then + TriggerClientEvent('SEM_InteractionMenu:UnjailPermsResult', source, true) + else + TriggerClientEvent('SEM_InteractionMenu:UnjailPermsResult', source, false) + end +end) + +RegisterServerEvent('SEM_InteractionMenu:UnhospitalPerms') +AddEventHandler('SEM_InteractionMenu:UnhospitalPerms', function() + if IsPlayerAceAllowed(source, 'sem_intmenu.unhospital') then + TriggerClientEvent('SEM_InteractionMenu:UnhospitalPermsResult', source, true) + else + TriggerClientEvent('SEM_InteractionMenu:UnhospitalPermsResult', source, false) + end +end) + + +local resourceName = +[[^3 + _____ ______ _____ _____ + / ____| | ___| | \ / | + | (___ | |___ | |\ \ / /| | + \___ \ | ___| | | \ \/ / | | + ____) | | |___ | | \ / | | + \_____/ |______| |__| \__/ |__|^7 + InteractionMenu + Created By Scott M +]] + +Citizen.CreateThread(function() + local currentVersion = GetResourceMetadata(GetCurrentResourceName(), 'version', 0) + + function VersionCheckHTTPRequest() + PerformHttpRequest('https://semdevelopment.com/releases/interactionmenu/info/version.json', VersionCheck, 'GET') + end + + function VersionCheck(err, response, headers) + Citizen.Wait(3000) + if err == 200 then + local data = json.decode(response) + + if Config.VersionChecker == 0 then + print(resourceName) + end + + if currentVersion ~= data.NewestVersion then + if Config.VersionChecker == 0 then + print('\n ^1SEM_InteractionMenu is outdated!^7') + print(' Latest Version: ^2' .. data.NewestVersion .. '^7') + print(' Your Version: ^1' .. currentVersion .. '^7') + print(' Please download the leastest version from ^5' .. data.DownloadLocation .. '^7') + + if data.Changes ~= '' then + print('\n ^5Changes: ^7' .. data.Changes) + end + elseif Config.VersionChecker == 1 then + print('\n^1SEM_InteractionMenu is outdated!^7') + print('Latest Version: ^2' .. data.NewestVersion .. '^7') + print('Please download the leastest version from ^5' .. data.DownloadLocation .. '^7\n') + end + else + print('\n ^2SEM_InteractionMenu is up to date!^7') + end + + print('\n') + else + print('^1SEM_InteractionMenu Version Check Failed!^7') + end + + SetTimeout(60000000, VersionCheckHTTPRequest) + end + + if Config.VersionChecker ~= 2 then + if currentVersion then + VersionCheckHTTPRequest() + else + print('^1SEM_InteractionMenu Version Check Failed!^7') + end + end +end) diff --git a/resources/Interaction-Menu/stream/char_floyd.ytd b/resources/Interaction-Menu/stream/char_floyd.ytd new file mode 100644 index 000000000..68efafd77 --- /dev/null +++ b/resources/Interaction-Menu/stream/char_floyd.ytd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f01c0e21d2134a67772d132e247918a3e494810ea64f939e108b7067eb7b165 +size 260166 diff --git a/resources/Timetrials/scores.txt b/resources/Timetrials/scores.txt index 55baa5dbd..28f9faada 100644 --- a/resources/Timetrials/scores.txt +++ b/resources/Timetrials/scores.txt @@ -1 +1 @@ -{"Airport Drag Race":{"NULL":{"player":"iwan.ralphs","car":"NULL","time":7030}},"Race | BCSO Training Course":{"NULL":{"player":"ThatGuyJacobee","car":"NULL","time":100457},"2013 Dodge Charger":{"player":"vJack","car":"2013 Dodge Charger","time":94246},"Neon":{"player":"ThunderBird","car":"Neon","time":105527},"Schafter V12 (Armored)":{"player":"Bulvederis","car":"Schafter V12 (Armored)","time":53363},"2016 Dodge Ram":{"player":"vJack","car":"2016 Dodge Ram","time":119099},"Nissan Skyline GTR":{"player":"ThatGuyJacobee","car":"Nissan Skyline GTR","time":105983},"Mercedes AMG GTS":{"player":"vJack","car":"Mercedes AMG GTS","time":78151}},"Lakeside Loop":{"NULL":{"player":"DR*KINGPORNHUB","car":"NULL","time":206147}},"Race | Sandy Airfield":{"NULL":{"time":4625,"car":"NULL","player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF"},"BMW M5 Plus":{"player":"King Rodriguez","car":"BMW M5 Plus","time":18019},"Neon":{"player":"ThunderBird","car":"Neon","time":28815},"Toyota Sienna 2021":{"player":"Max Rodriguez","car":"Toyota Sienna 2021","time":34685},"Audi S3 2015":{"player":"King Rodriguez","car":"Audi S3 2015","time":25742},"Jeep TrackHawk 2018":{"player":"King Rodriguez","car":"Jeep TrackHawk 2018","time":22887},"Dodge Charger 2014":{"player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","car":"Dodge Charger 2014","time":202399},"Verlierer":{"player":"kiyin","car":"Verlierer","time":31698},"2016 Ford Explorer":{"player":"King Rodriguez","car":"2016 Ford Explorer","time":26526},"Mini JCW 2020":{"player":"King Rodriguez","car":"Mini JCW 2020","time":29879},"2014 Dodge Charger":{"player":"King Rodriguez","car":"2014 Dodge Charger","time":29132},"BR8":{"player":"C-200 | Noki | Deputy 1 | CIV","car":"BR8","time":25853},"GMC Sierra Singlecab 2006":{"player":"herediaaldo4","car":"GMC Sierra Singlecab 2006","time":34750},"Nissan Skyline GTR":{"player":"ThatGuyJacobee","car":"Nissan Skyline GTR","time":29921},"Chevy Silverado 1500 4dr Cab 2006":{"player":"herediaaldo4","car":"Chevy Silverado 1500 4dr Cab 2006","time":29263},"Nero":{"player":"ThunderBird","car":"Nero","time":34210},"Mercedes AMG GTS":{"player":"vJack","car":"Mercedes AMG GTS","time":19029},"Dick Car":{"player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","car":"Dick Car","time":23469},"Formula 1":{"player":"vJack","car":"Formula 1","time":15914},"Ferrari 458":{"player":"Woltage.2","car":"Ferrari 458","time":25352},"BMW i8":{"player":"King Rodriguez","car":"BMW i8","time":24743},"Corvette C7":{"player":"shrekislove","car":"Corvette C7","time":31909},"Jeep Grand Cherokee TrackhawkPD 2018":{"time":36165,"car":"Jeep Grand Cherokee TrackhawkPD 2018","player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF"},"Scramjet":{"player":"C-199|T.Oneil|Deputy I","car":"Scramjet","time":8264},"F-22A":{"player":"Yalaina-DDR8","car":"F-22A","time":90697},"Chevy Camaro20":{"player":"Max Rodriguez","car":"Chevy Camaro20","time":32202},"Itali GTO":{"player":"ThunderBird","car":"Itali GTO","time":20103},"Projen-C Sports":{"time":93333,"car":"Projen-C Sports","player":"C-200 | Noki | Deputy 1 | CIV"},"Bugatti Chiron 2017":{"player":"King Rodriguez","car":"Bugatti Chiron 2017","time":22371},"EGRP Sheriff PD":{"player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","car":"EGRP Sheriff PD","time":32983},"Kawasaki Ninja ZX10R":{"time":3621,"car":"Kawasaki Ninja ZX10R","player":"C-200 | Noki | Deputy 1 | CIV"},"Dodge Ram 2dr 1500 srt 2010":{"player":"Max Rodriguez ","car":"Dodge Ram 2dr 1500 srt 2010","time":21999},"School Bus":{"time":81320,"car":"School Bus","player":"227 | Adam | Senior Officer"},"Chevrolet Silverado 2005 2dr":{"player":"herediaaldo4","car":"Chevrolet Silverado 2005 2dr","time":26183},"Yamaha R6":{"player":"ThatGuyJacobee","car":"Yamaha R6","time":28188},"Space Docker":{"player":"DyslexicStoner240.","car":"Space Docker","time":29122},"Cougar MRAP":{"player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","car":"Cougar MRAP","time":51309},"Dodge Challenger srt 2020 ":{"player":"herediaaldo4","car":"Dodge Challenger srt 2020 ","time":22940},"Dodge Charger 2018tr":{"player":"ThunderBird","car":"Dodge Charger 2018tr","time":26779},"Ford Raptor F-150":{"player":"King Rodriguez","car":"Ford Raptor F-150","time":28515},"Harley Davidson":{"player":"Max Rodriguez","car":"Harley Davidson","time":34914},"Oppressor":{"player":"C-200 | Noki | Deputy 1 | CIV","car":"Oppressor","time":19491}},"BCSO Training Course":{"NULL":{"player":"ThatGuyJacobee","car":"NULL","time":26915},"Jester":{"player":"michael82","car":"Jester","time":37835}},"North GP":{"NULL":{"player":"vJack","car":"NULL","time":191650},"Baller":{"player":"dcapone00","car":"Baller","time":410118},"Neon":{"player":"ThunderBird","car":"Neon","time":354856}},"Airport Circuit":{"NULL":{"player":"ThatGuyJacobee","car":"NULL","time":22916},"P-996 LAZER":{"player":"ThatGuyJacobee","car":"P-996 LAZER","time":59216},"Neon":{"player":"ThunderBird","car":"Neon","time":92652}},"Race | Highway Sprint":{"NULL":{"player":"Travis O'Neil","car":"NULL","time":27159},"Ferrari 488s":{"player":"shrekislove","car":"Ferrari 488s","time":188921},"Lamborghini Aventador AVJ":{"player":"Kaleb","car":"Lamborghini Aventador AVJ","time":240744},"Scramjet":{"player":"Travis O'Neil","car":"Scramjet","time":200543},"Deveste Eight":{"player":"jb3794339","car":"Deveste Eight","time":181173},"Ferrari 458":{"player":"ThatGuyJacobee","car":"Ferrari 458","time":138033}},"Cannonball Run":{"NULL":{"player":"ThatGuyJacobee","car":"NULL","time":81298}},"Race | Airport Circuit":{"Ferrari 458":{"player":"ThatGuyJacobee","car":"Ferrari 458","time":69880},"Formula 1":{"player":"vJack","car":"Formula 1","time":42751},"Nissan Skyline GTR":{"player":"ThatGuyJacobee","car":"Nissan Skyline GTR","time":83978}},"Race | Observatory Loop":{"Ford F-150 Lightning 2022":{"player":"ThatGuyJacobee","car":"Ford F-150 Lightning 2022","time":68440},"2013 Dodge Charger":{"player":"vJack","car":"2013 Dodge Charger","time":64004},"Porsche 911 GT3RS":{"player":"[YJ-18] Sinapsey","car":"Porsche 911 GT3RS","time":106410},"Mercedes AMG GTS":{"player":"vJack","car":"Mercedes AMG GTS","time":56747},"Gauntlet Classic Custom":{"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Gauntlet Classic Custom","time":76765},"Formula 1":{"player":"ThatGuyJacobee","car":"Formula 1","time":54744},"NULL":{"player":"[YJ-18] Sinapsey","car":"NULL","time":55388},"BMW M5 Plus":{"player":"[EGRP-02]King Rodriguez","car":"BMW M5 Plus","time":70752},"Nissan Skyline GTR":{"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Nissan Skyline GTR","time":67881},"BMW M5":{"player":"[C-291][GCF-34][MS-13] K. Lee","car":"BMW M5","time":81837},"Mazda Miata":{"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Mazda Miata","time":79814}},"Race | Hillside Loop":{"Bronco Wildtrak 2021":{"player":"ThatGuyJacobee","car":"Bronco Wildtrak 2021","time":210714},"Gauntlet Classic Custom":{"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Gauntlet Classic Custom","time":230432},"BMW M8 Widebody":{"player":"[C-291][GCF-34][MS-13] K. Lee","car":"BMW M8 Widebody","time":195442}},"Hollywood Hills":{"NULL":{"player":"Kryplos125","car":"NULL","time":120053}},"Race | Airport Drag":{"NULL":{"player":"B. LAO","car":"NULL","time":12630},"BMW M5 Plus":{"player":"King Rodriguez","car":"BMW M5 Plus","time":8652},"Nissan Skyline GTR":{"player":"ThatGuyJacobee","car":"Nissan Skyline GTR","time":9693},"Formula 1":{"player":"King Rodriguez","car":"Formula 1","time":7629},"2010 Chevy Tahoe":{"player":"King Rodriguez","car":"2010 Chevy Tahoe","time":12821},"Police Corvette 2019":{"player":"Woltage.2","car":"Police Corvette 2019","time":14484}},"Race | Timetrial Event - 04/04/21":{"Gauntlet Classic Custom":{"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Gauntlet Classic Custom","time":191695},"Chevrolet Silverado 1980":{"player":"King Rodriguez","car":"Chevrolet Silverado 1980","time":156244},"Ford Velociraptor 6x6":{"player":"ThatGuyJacobee","car":"Ford Velociraptor 6x6","time":132814}},"Highway Sprint":{"NULL":{"player":"vJack","car":"NULL","time":93300}},"North Rallycross ":{"Neon":{"player":"ThunderBird","car":"Neon","time":351612}},"Observatory Loop":{"NULL":{"player":"ThatGuyJacobee","car":"NULL","time":34126}},"Race | Airport Drag Race":{"NULL":{"player":"DR-KingRodriguez","car":"NULL","time":9270}},"Race | Lakeside Loop":{"Sheriff Cruiser":{"player":"Ole Stinky","car":"Sheriff Cruiser","time":153384},"Adder":{"player":"Oli","car":"Adder","time":30689},"Bifta":{"time":248420,"car":"Bifta","player":"Who Dat"},"Ferrari 458":{"player":"ThatGuyJacobee","car":"Ferrari 458","time":177461},"SNOWMOBILE 2020":{"player":"[C-146] E. Cartman","car":"SNOWMOBILE 2020","time":107015},"Kawasaki Ninja ZX10R":{"time":28696,"car":"Kawasaki Ninja ZX10R","player":"C-200 | Noki | Deputy 1 | CIV"},"Ford Crown Vic 2011":{"player":"AnySpiderBat","car":"Ford Crown Vic 2011","time":231931},"EGRP Staff Buggy":{"player":"[EGRP-02]King Rodriguez","car":"EGRP Staff Buggy","time":43710},"NULL":{"player":"ThatGuyJacobee","car":"NULL","time":196803},"Ford Explorer 2020":{"player":"shrekislove","car":"Ford Explorer 2020","time":260276}},"Race | Cannonball Run":{"Scramjet":{"player":"C-199|T.Oneil|Deputy I","car":"Scramjet","time":66921},"2013 Dodge Charger":{"player":"vJack","car":"2013 Dodge Charger","time":263368}},"Race | Hollywood Hills":{"NULL":{"player":"ThatGuyJacobee","car":"NULL","time":102048},"Ruiner 2000":{"player":"Travis O'Neil","car":"Ruiner 2000","time":140708},"Mercedes AMG GTS":{"player":"vJack","car":"Mercedes AMG GTS","time":85823},"Ford F-150 Lightning 2022":{"player":"ThatGuyJacobee","car":"Ford F-150 Lightning 2022","time":105278},"Audi R8 V10":{"player":"ThatGuyJacobee","car":"Audi R8 V10","time":100677}},"Sandy Airfield":{"RE-7B":{"player":"*ZbyniU*","car":"RE-7B","time":28456},"FH-1 Hunter":{"player":"*ZbyniU*","car":"FH-1 Hunter","time":36289},"Maverick":{"player":"vJack","car":"Maverick","time":29165},"NULL":{"player":"ThatGuyJacobee","car":"NULL","time":5607},"Neon":{"player":"ThunderBird","car":"Neon","time":30312},"Vigilante":{"player":"*ZbyniU*","car":"Vigilante","time":6172},"Jester":{"player":"michael82","car":"Jester","time":47982},"BMX":{"player":"vJack","car":"BMX","time":21014},"Oppressor":{"player":"michael82","car":"Oppressor","time":21360}},"Race | North GP":{"SNOWMOBILE 2020":{"player":"ThatGuyJacobee","car":"SNOWMOBILE 2020","time":387242},"BMW M5":{"player":"Stormzy","car":"BMW M5","time":115460},"Mercedes AMG GTS":{"player":"Srgt Splooje","car":"Mercedes AMG GTS","time":91546},"NULL":{"player":"SOGGYBEAN","car":"NULL","time":42917},"Windsor Drop":{"player":"[C-81][GCF-145] R. Freeman","car":"Windsor Drop","time":66673},"2014 Pierce prescue":{"player":"Klimek07","car":"2014 Pierce prescue","time":83300}}} \ No newline at end of file +{"Race | Hillside Loop":{"Bronco Wildtrak 2021":{"time":210714,"player":"ThatGuyJacobee","car":"Bronco Wildtrak 2021"},"BMW M8 Widebody":{"time":195442,"player":"[C-291][GCF-34][MS-13] K. Lee","car":"BMW M8 Widebody"},"Gauntlet Classic Custom":{"time":230432,"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Gauntlet Classic Custom"}},"Lakeside Loop":{"NULL":{"time":206147,"player":"DR*KINGPORNHUB","car":"NULL"}},"Race | Highway Sprint":{"Deveste Eight":{"time":181173,"player":"jb3794339","car":"Deveste Eight"},"Ferrari 488s":{"time":188921,"player":"shrekislove","car":"Ferrari 488s"},"Scramjet":{"time":200543,"player":"Travis O'Neil","car":"Scramjet"},"Formula 1":{"car":"Formula 1","player":"shrekislove","time":115451},"Ferrari 458":{"time":138033,"player":"ThatGuyJacobee","car":"Ferrari 458"},"Lamborghini Aventador AVJ":{"time":240744,"player":"Kaleb","car":"Lamborghini Aventador AVJ"},"NULL":{"time":27159,"player":"Travis O'Neil","car":"NULL"}},"Race | North GP":{"Mercedes AMG GTS":{"time":91546,"player":"Srgt Splooje","car":"Mercedes AMG GTS"},"BMW M5":{"time":115460,"player":"Stormzy","car":"BMW M5"},"Windsor Drop":{"time":66673,"player":"[C-81][GCF-145] R. Freeman","car":"Windsor Drop"},"2014 Pierce prescue":{"time":83300,"player":"Klimek07","car":"2014 Pierce prescue"},"NULL":{"time":42917,"player":"SOGGYBEAN","car":"NULL"},"SNOWMOBILE 2020":{"time":387242,"player":"ThatGuyJacobee","car":"SNOWMOBILE 2020"}},"Airport Drag Race":{"NULL":{"time":7030,"player":"iwan.ralphs","car":"NULL"}},"Race | Cannonball Run":{"Scramjet":{"time":66921,"player":"C-199|T.Oneil|Deputy I","car":"Scramjet"},"2013 Dodge Charger":{"time":263368,"player":"vJack","car":"2013 Dodge Charger"}},"Race | Hollywood Hills":{"Mercedes AMG GTS":{"time":85823,"player":"vJack","car":"Mercedes AMG GTS"},"Ford F-150 Lightning 2022":{"time":105278,"player":"ThatGuyJacobee","car":"Ford F-150 Lightning 2022"},"Audi R8 V10":{"time":100677,"player":"ThatGuyJacobee","car":"Audi R8 V10"},"NULL":{"time":102048,"player":"ThatGuyJacobee","car":"NULL"},"Ruiner 2000":{"time":140708,"player":"Travis O'Neil","car":"Ruiner 2000"}},"Race | Lakeside Loop":{"Bifta":{"car":"Bifta","player":"Who Dat","time":248420},"EGRP Staff Buggy":{"time":43710,"player":"[EGRP-02]King Rodriguez","car":"EGRP Staff Buggy"},"BMW S 1000 RR":{"time":21701,"player":"C-200 | Noki | Deputy 1 | CIV","car":"BMW S 1000 RR"},"Kawasaki Ninja ZX10R":{"car":"Kawasaki Ninja ZX10R","player":"C-200 | Noki | Deputy 1 | CIV","time":28696},"Adder":{"time":30689,"player":"Oli","car":"Adder"},"NULL":{"time":196803,"player":"ThatGuyJacobee","car":"NULL"},"Sheriff Cruiser":{"time":153384,"player":"Ole Stinky","car":"Sheriff Cruiser"},"Ford Crown Vic 2011":{"time":231931,"player":"AnySpiderBat","car":"Ford Crown Vic 2011"},"Ferrari 458":{"time":177461,"player":"ThatGuyJacobee","car":"Ferrari 458"},"Ford Explorer 2020":{"time":260276,"player":"shrekislove","car":"Ford Explorer 2020"},"SNOWMOBILE 2020":{"time":107015,"player":"[C-146] E. Cartman","car":"SNOWMOBILE 2020"}},"North GP":{"Neon":{"time":354856,"player":"ThunderBird","car":"Neon"},"NULL":{"time":191650,"player":"vJack","car":"NULL"},"Baller":{"time":410118,"player":"dcapone00","car":"Baller"}},"Race | Airport Circuit":{"Formula 1":{"time":42751,"player":"vJack","car":"Formula 1"},"Ferrari 458":{"time":69880,"player":"ThatGuyJacobee","car":"Ferrari 458"},"Nissan Skyline GTR":{"time":83978,"player":"ThatGuyJacobee","car":"Nissan Skyline GTR"}},"BCSO Training Course":{"NULL":{"time":26915,"player":"ThatGuyJacobee","car":"NULL"},"Jester":{"time":37835,"player":"michael82","car":"Jester"}},"Race | BCSO Training Course":{"Schafter V12 (Armored)":{"time":53363,"player":"Bulvederis","car":"Schafter V12 (Armored)"},"2013 Dodge Charger":{"time":94246,"player":"vJack","car":"2013 Dodge Charger"},"Mercedes AMG GTS":{"time":78151,"player":"vJack","car":"Mercedes AMG GTS"},"Nissan Skyline GTR":{"time":105983,"player":"ThatGuyJacobee","car":"Nissan Skyline GTR"},"2016 Dodge Ram":{"time":119099,"player":"vJack","car":"2016 Dodge Ram"},"NULL":{"time":100457,"player":"ThatGuyJacobee","car":"NULL"},"Neon":{"time":105527,"player":"ThunderBird","car":"Neon"}},"Race | Timetrial Event - 04/04/21":{"Ford Velociraptor 6x6":{"time":132814,"player":"ThatGuyJacobee","car":"Ford Velociraptor 6x6"},"Gauntlet Classic Custom":{"time":191695,"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Gauntlet Classic Custom"},"Chevrolet Silverado 1980":{"time":156244,"player":"King Rodriguez","car":"Chevrolet Silverado 1980"}},"Race | Sandy Airfield":{"Chevy Silverado 1500 4dr Cab 2006":{"time":29263,"player":"herediaaldo4","car":"Chevy Silverado 1500 4dr Cab 2006"},"EGRP Sheriff PD":{"time":32983,"player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","car":"EGRP Sheriff PD"},"Formula 1":{"time":15914,"player":"vJack","car":"Formula 1"},"Dick Car":{"time":23469,"player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","car":"Dick Car"},"Scramjet":{"time":8264,"player":"C-199|T.Oneil|Deputy I","car":"Scramjet"},"BMW M5 Plus":{"time":18019,"player":"King Rodriguez","car":"BMW M5 Plus"},"2014 Dodge Charger":{"time":29132,"player":"King Rodriguez","car":"2014 Dodge Charger"},"Dodge Charger 2018tr":{"time":26779,"player":"ThunderBird","car":"Dodge Charger 2018tr"},"BMW i8":{"time":24743,"player":"King Rodriguez","car":"BMW i8"},"Ford Raptor F-150":{"time":28515,"player":"King Rodriguez","car":"Ford Raptor F-150"},"Cliffhanger":{"car":"Cliffhanger","player":"Zoneil121","time":45601},"Audi S3 2015":{"time":25742,"player":"King Rodriguez","car":"Audi S3 2015"},"GMC Sierra Singlecab 2006":{"time":34750,"player":"herediaaldo4","car":"GMC Sierra Singlecab 2006"},"Chevrolet Silverado 2005 2dr":{"time":26183,"player":"herediaaldo4","car":"Chevrolet Silverado 2005 2dr"},"Toyota Sienna 2021":{"time":34685,"player":"Max Rodriguez","car":"Toyota Sienna 2021"},"BMW S 1000 RR":{"time":3221,"player":"C-200 | Noki | Deputy 1 | CIV","car":"BMW S 1000 RR"},"Cougar MRAP":{"time":51309,"player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","car":"Cougar MRAP"},"Harley Davidson":{"time":34914,"player":"Max Rodriguez","car":"Harley Davidson"},"Oppressor":{"time":19491,"player":"C-200 | Noki | Deputy 1 | CIV","car":"Oppressor"},"F-22A":{"time":90697,"player":"Yalaina-DDR8","car":"F-22A"},"Yamaha R6":{"time":28188,"player":"ThatGuyJacobee","car":"Yamaha R6"},"Space Docker":{"time":29122,"player":"DyslexicStoner240.","car":"Space Docker"},"BR8":{"time":25853,"player":"C-200 | Noki | Deputy 1 | CIV","car":"BR8"},"Mini JCW 2020":{"time":29879,"player":"King Rodriguez","car":"Mini JCW 2020"},"Jeep Grand Cherokee TrackhawkPD 2018":{"car":"Jeep Grand Cherokee TrackhawkPD 2018","player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","time":36165},"School Bus":{"car":"School Bus","player":"227 | Adam | Senior Officer","time":81320},"Nissan Skyline GTR":{"time":29921,"player":"ThatGuyJacobee","car":"Nissan Skyline GTR"},"Ferrari 458":{"time":25352,"player":"Woltage.2","car":"Ferrari 458"},"Dodge Challenger srt 2020 ":{"time":22940,"player":"herediaaldo4","car":"Dodge Challenger srt 2020 "},"Itali GTO":{"time":20103,"player":"ThunderBird","car":"Itali GTO"},"Mercedes AMG GTS":{"time":19029,"player":"vJack","car":"Mercedes AMG GTS"},"Bugatti Chiron 2017":{"time":22371,"player":"King Rodriguez","car":"Bugatti Chiron 2017"},"Dodge Charger 2014":{"time":202399,"player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","car":"Dodge Charger 2014"},"NULL":{"car":"NULL","player":"C-197 | FP-410 | Tristan M. | Deputy I | Probi. FF","time":4625},"Kawasaki Ninja ZX10R":{"car":"Kawasaki Ninja ZX10R","player":"C-200 | Noki | Deputy 1 | CIV","time":3621},"Projen-C Sports":{"car":"Projen-C Sports","player":"C-200 | Noki | Deputy 1 | CIV","time":93333},"Nero":{"time":34210,"player":"ThunderBird","car":"Nero"},"Chevy Camaro20":{"time":32202,"player":"Max Rodriguez","car":"Chevy Camaro20"},"Corvette C7":{"time":31909,"player":"shrekislove","car":"Corvette C7"},"Neon":{"time":28815,"player":"ThunderBird","car":"Neon"},"Kawasaki Ninja H2":{"time":4998,"player":"C-200 | Noki | Deputy 1 | CIV","car":"Kawasaki Ninja H2"},"Police Rancher":{"car":"Police Rancher","player":"~r~ ¦ 1A-80","time":8092},"2016 Ford Explorer":{"time":26526,"player":"King Rodriguez","car":"2016 Ford Explorer"},"Jeep TrackHawk 2018":{"time":22887,"player":"King Rodriguez","car":"Jeep TrackHawk 2018"},"Verlierer":{"time":31698,"player":"kiyin","car":"Verlierer"},"Dodge Ram 2dr 1500 srt 2010":{"time":21999,"player":"Max Rodriguez ","car":"Dodge Ram 2dr 1500 srt 2010"}},"Observatory Loop":{"NULL":{"time":34126,"player":"ThatGuyJacobee","car":"NULL"}},"North Rallycross ":{"Neon":{"time":351612,"player":"ThunderBird","car":"Neon"}},"Highway Sprint":{"NULL":{"time":93300,"player":"vJack","car":"NULL"}},"Sandy Airfield":{"RE-7B":{"time":28456,"player":"*ZbyniU*","car":"RE-7B"},"Maverick":{"time":29165,"player":"vJack","car":"Maverick"},"NULL":{"time":5607,"player":"ThatGuyJacobee","car":"NULL"},"FH-1 Hunter":{"time":36289,"player":"*ZbyniU*","car":"FH-1 Hunter"},"Neon":{"time":30312,"player":"ThunderBird","car":"Neon"},"BMX":{"time":21014,"player":"vJack","car":"BMX"},"Vigilante":{"time":6172,"player":"*ZbyniU*","car":"Vigilante"},"Oppressor":{"time":21360,"player":"michael82","car":"Oppressor"},"Jester":{"time":47982,"player":"michael82","car":"Jester"}},"Race | Airport Drag":{"2010 Chevy Tahoe":{"time":12821,"player":"King Rodriguez","car":"2010 Chevy Tahoe"},"BMW M5 Plus":{"time":8652,"player":"King Rodriguez","car":"BMW M5 Plus"},"Formula 1":{"time":7629,"player":"King Rodriguez","car":"Formula 1"},"Nissan Skyline GTR":{"time":9693,"player":"ThatGuyJacobee","car":"Nissan Skyline GTR"},"NULL":{"time":12630,"player":"B. LAO","car":"NULL"},"Police Corvette 2019":{"time":14484,"player":"Woltage.2","car":"Police Corvette 2019"}},"Cannonball Run":{"NULL":{"time":81298,"player":"ThatGuyJacobee","car":"NULL"}},"Hollywood Hills":{"NULL":{"time":120053,"player":"Kryplos125","car":"NULL"}},"Airport Circuit":{"Neon":{"time":92652,"player":"ThunderBird","car":"Neon"},"NULL":{"time":22916,"player":"ThatGuyJacobee","car":"NULL"},"P-996 LAZER":{"time":59216,"player":"ThatGuyJacobee","car":"P-996 LAZER"}},"Race | Observatory Loop":{"Mercedes AMG GTS":{"time":56747,"player":"vJack","car":"Mercedes AMG GTS"},"2013 Dodge Charger":{"time":64004,"player":"vJack","car":"2013 Dodge Charger"},"Gauntlet Classic Custom":{"time":76765,"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Gauntlet Classic Custom"},"BMW M5 Plus":{"time":70752,"player":"[EGRP-02]King Rodriguez","car":"BMW M5 Plus"},"Formula 1":{"time":54744,"player":"ThatGuyJacobee","car":"Formula 1"},"NULL":{"time":55388,"player":"[YJ-18] Sinapsey","car":"NULL"},"Porsche 911 GT3RS":{"time":106410,"player":"[YJ-18] Sinapsey","car":"Porsche 911 GT3RS"},"Mazda Miata":{"time":79814,"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Mazda Miata"},"BMW M5":{"time":81837,"player":"[C-291][GCF-34][MS-13] K. Lee","car":"BMW M5"},"Nissan Skyline GTR":{"time":67881,"player":"[C-291][GCF-34][MS-13] K. Lee","car":"Nissan Skyline GTR"},"Ford F-150 Lightning 2022":{"time":68440,"player":"ThatGuyJacobee","car":"Ford F-150 Lightning 2022"}},"Race | Airport Drag Race":{"NULL":{"time":9270,"player":"DR-KingRodriguez","car":"NULL"}}} \ No newline at end of file diff --git a/resources/ghmattimysql/__resource.lua b/resources/ghmattimysql/__resource.lua deleted file mode 100644 index a0722efa3..000000000 --- a/resources/ghmattimysql/__resource.lua +++ /dev/null @@ -1,6 +0,0 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' - -server_scripts { - 'ghmattimysql.js', - 'ghmattimysql.lua', -} diff --git a/resources/ghmattimysql/config.json b/resources/ghmattimysql/config.json deleted file mode 100644 index 3bb747360..000000000 --- a/resources/ghmattimysql/config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "user": "root", - "password": "Elite_Gaming_13", - "host": "localhost", - "port": 3306, - "database": "fivem", - "connectionLimit": 10, - "dateStrings": true -} diff --git a/resources/ghmattimysql/ghmattimysql.js b/resources/ghmattimysql/ghmattimysql.js deleted file mode 100644 index 1a3a911ae..000000000 --- a/resources/ghmattimysql/ghmattimysql.js +++ /dev/null @@ -1,608 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 30); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { - -module.exports = require("util"); - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -var buffer=__webpack_require__(39);var Buffer=buffer.Buffer;function copyProps(src,dst){for(var key in src){dst[key]=src[key];}}if(Buffer.from&&Buffer.alloc&&Buffer.allocUnsafe&&Buffer.allocUnsafeSlow){module.exports=buffer;}else{copyProps(buffer,exports);exports.Buffer=SafeBuffer;}function SafeBuffer(arg,encodingOrOffset,length){return Buffer(arg,encodingOrOffset,length);}copyProps(Buffer,SafeBuffer);SafeBuffer.from=function(arg,encodingOrOffset,length){if(typeof arg==='number'){throw new TypeError('Argument must not be a number');}return Buffer(arg,encodingOrOffset,length);};SafeBuffer.alloc=function(size,fill,encoding){if(typeof size!=='number'){throw new TypeError('Argument must be a number');}var buf=Buffer(size);if(fill!==undefined){if(typeof encoding==='string'){buf.fill(fill,encoding);}else{buf.fill(fill);}}else{buf.fill(0);}return buf;};SafeBuffer.allocUnsafe=function(size){if(typeof size!=='number'){throw new TypeError('Argument must be a number');}return Buffer(size);};SafeBuffer.allocUnsafeSlow=function(size){if(typeof size!=='number'){throw new TypeError('Argument must be a number');}return buffer.SlowBuffer(size);}; - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -exports.AuthSwitchRequestPacket=__webpack_require__(43);exports.AuthSwitchResponsePacket=__webpack_require__(44);exports.ClientAuthenticationPacket=__webpack_require__(45);exports.ComChangeUserPacket=__webpack_require__(46);exports.ComPingPacket=__webpack_require__(47);exports.ComQueryPacket=__webpack_require__(48);exports.ComQuitPacket=__webpack_require__(49);exports.ComStatisticsPacket=__webpack_require__(50);exports.EmptyPacket=__webpack_require__(51);exports.EofPacket=__webpack_require__(52);exports.ErrorPacket=__webpack_require__(53);exports.Field=__webpack_require__(17);exports.FieldPacket=__webpack_require__(54);exports.HandshakeInitializationPacket=__webpack_require__(55);exports.LocalDataFilePacket=__webpack_require__(56);exports.OkPacket=__webpack_require__(57);exports.OldPasswordPacket=__webpack_require__(58);exports.ResultSetHeaderPacket=__webpack_require__(59);exports.RowDataPacket=__webpack_require__(60);exports.SSLRequestPacket=__webpack_require__(61);exports.StatisticsPacket=__webpack_require__(62);exports.UseOldPasswordPacket=__webpack_require__(63); - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -var Util=__webpack_require__(0);var EventEmitter=__webpack_require__(4).EventEmitter;var Packets=__webpack_require__(2);var ErrorConstants=__webpack_require__(64);var listenerCount=EventEmitter.listenerCount||function(emitter,type){return emitter.listeners(type).length;};var LONG_STACK_DELIMITER='\n --------------------\n';module.exports=Sequence;Util.inherits(Sequence,EventEmitter);function Sequence(options,callback){if(typeof options==='function'){callback=options;options={};}EventEmitter.call(this);options=options||{};this._callback=callback;this._callSite=null;this._ended=false;this._timeout=options.timeout;this._idleNext=null;this._idlePrev=null;this._idleStart=null;this._idleTimeout=-1;this._repeat=null;}Sequence.determinePacket=function(byte){switch(byte){case 0x00:return Packets.OkPacket;case 0xfe:return Packets.EofPacket;case 0xff:return Packets.ErrorPacket;default:return undefined;}};Sequence.prototype.hasErrorHandler=function(){return Boolean(this._callback)||listenerCount(this,'error')>1;};Sequence.prototype._packetToError=function(packet){var code=ErrorConstants[packet.errno]||'UNKNOWN_CODE_PLEASE_REPORT';var err=new Error(code+': '+packet.message);err.code=code;err.errno=packet.errno;err.sqlMessage=packet.message;err.sqlState=packet.sqlState;return err;};Sequence.prototype.end=function(err){if(this._ended){return;}this._ended=true;if(err){this._addLongStackTrace(err);}this._callSite=null;try{if(err){this.emit('error',err);}}finally{try{if(this._callback){this._callback.apply(this,arguments);}}finally{this.emit('end');}}};Sequence.prototype['OkPacket']=function(packet){this.end(null,packet);};Sequence.prototype['ErrorPacket']=function(packet){this.end(this._packetToError(packet));};Sequence.prototype.start=function(){};Sequence.prototype._addLongStackTrace=function _addLongStackTrace(err){var callSiteStack=this._callSite&&this._callSite.stack;if(!callSiteStack||typeof callSiteStack!=='string'){return;}if(err.stack.indexOf(LONG_STACK_DELIMITER)!==-1){return;}var index=callSiteStack.indexOf('\n');if(index!==-1){err.stack+=LONG_STACK_DELIMITER+callSiteStack.substr(index+1);}};Sequence.prototype._onTimeout=function _onTimeout(){this.emit('timeout');}; - -/***/ }), -/* 4 */ -/***/ (function(module, exports) { - -module.exports = require("events"); - -/***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -var processNextTick=__webpack_require__(10);var objectKeys=Object.keys||function(obj){var keys=[];for(var key in obj){keys.push(key);}return keys;};module.exports=Duplex;var util=__webpack_require__(6);util.inherits=__webpack_require__(7);var Readable=__webpack_require__(20);var Writable=__webpack_require__(23);util.inherits(Duplex,Readable);var keys=objectKeys(Writable.prototype);for(var v=0;v>16);return[w2&0xFFFF,w1&0xFFFF];};Auth.mul32=function(a,b){var w1=a[1]*b[1],w2=(a[1]*b[1]>>16&0xFFFF)+(a[0]*b[1]&0xFFFF)+(a[1]*b[0]&0xFFFF);return[w2&0xFFFF,w1&0xFFFF];};Auth.and32=function(a,b){return[a[0]&b[0],a[1]&b[1]];};Auth.shl32=function(a,b){var w1=a[1]<>16;return[w2&0xFFFF,w1&0xFFFF];};Auth.int31Write=function(buffer,number,offset){buffer[offset]=number[0]>>8&0x7F;buffer[offset+1]=number[0]&0xFF;buffer[offset+2]=number[1]>>8&0xFF;buffer[offset+3]=number[1]&0xFF;};Auth.int32Read=function(buffer,offset){return(buffer[offset]<<24)+(buffer[offset+1]<<16)+(buffer[offset+2]<<8)+buffer[offset+3];}; - -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { - -var Sequence=__webpack_require__(3);var Util=__webpack_require__(0);var Packets=__webpack_require__(2);var ResultSet=__webpack_require__(67);var ServerStatus=__webpack_require__(68);var fs=__webpack_require__(69);var Readable=__webpack_require__(70);module.exports=Query;Util.inherits(Query,Sequence);function Query(options,callback){Sequence.call(this,options,callback);this.sql=options.sql;this.values=options.values;this.typeCast=options.typeCast===undefined?true:options.typeCast;this.nestTables=options.nestTables||false;this._resultSet=null;this._results=[];this._fields=[];this._index=0;this._loadError=null;}Query.prototype.start=function(){this.emit('packet',new Packets.ComQueryPacket(this.sql));};Query.prototype.determinePacket=function determinePacket(byte,parser){var resultSet=this._resultSet;if(!resultSet){switch(byte){case 0x00:return Packets.OkPacket;case 0xff:return Packets.ErrorPacket;default:return Packets.ResultSetHeaderPacket;}}if(resultSet.eofPackets.length===0){return resultSet.fieldPackets.length0?this._results:undefined;var fields=this._fields.length>0?this._fields:undefined;err.index=this._index;err.sql=this.sql;this.end(err,results,fields);};Query.prototype['ResultSetHeaderPacket']=function(packet){if(packet.fieldCount===null){this._sendLocalDataFile(packet.extra);}else{this._resultSet=new ResultSet(packet);}};Query.prototype['FieldPacket']=function(packet){this._resultSet.fieldPackets.push(packet);};Query.prototype['EofPacket']=function(packet){this._resultSet.eofPackets.push(packet);if(this._resultSet.eofPackets.length===1&&!this._callback){this.emit('fields',this._resultSet.fieldPackets,this._index);}if(this._resultSet.eofPackets.length!==2){return;}if(this._callback){this._results.push(this._resultSet.rows);this._fields.push(this._resultSet.fieldPackets);}this._index++;this._resultSet=null;this._handleFinalResultPacket(packet);};Query.prototype._handleFinalResultPacket=function(packet){if(packet.serverStatus&ServerStatus.SERVER_MORE_RESULTS_EXISTS){return;}var results=this._results.length>1?this._results:this._results[0];var fields=this._fields.length>1?this._fields:this._fields[0];this.end(this._loadError,results,fields);};Query.prototype['RowDataPacket']=function(packet,parser,connection){packet.parse(parser,this._resultSet.fieldPackets,this.typeCast,this.nestTables,connection);if(this._callback){this._resultSet.rows.push(packet);}else{this.emit('result',packet,this._index);}};Query.prototype._sendLocalDataFile=function(path){var self=this;var localStream=fs.createReadStream(path,{flag:'r',encoding:null,autoClose:true});this.on('pause',function(){localStream.pause();});this.on('resume',function(){localStream.resume();});localStream.on('data',function(data){self.emit('packet',new Packets.LocalDataFilePacket(data));});localStream.on('error',function(err){self._loadError=err;localStream.emit('end');});localStream.on('end',function(){self.emit('packet',new Packets.EmptyPacket());});};Query.prototype.stream=function(options){var self=this,stream;options=options||{};options.objectMode=true;stream=new Readable(options);stream._read=function(){self._connection&&self._connection.resume();};stream.once('end',function(){process.nextTick(function(){stream.emit('close');});});this.on('result',function(row,i){if(!stream.push(row))self._connection.pause();stream.emit('result',row,i);});this.on('error',function(err){stream.emit('error',err);});this.on('end',function(){stream.push(null);});this.on('fields',function(fields,i){stream.emit('fields',fields,i);});return stream;}; - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -var processNextTick=__webpack_require__(10);module.exports=Readable;var isArray=__webpack_require__(71);var Duplex;Readable.ReadableState=ReadableState;var EE=__webpack_require__(4).EventEmitter;var EElistenerCount=function(emitter,type){return emitter.listeners(type).length;};var Stream=__webpack_require__(21);var Buffer=__webpack_require__(1).Buffer;var OurUint8Array=global.Uint8Array||function(){};function _uint8ArrayToBuffer(chunk){return Buffer.from(chunk);}function _isUint8Array(obj){return Buffer.isBuffer(obj)||obj instanceof OurUint8Array;}var util=__webpack_require__(6);util.inherits=__webpack_require__(7);var debugUtil=__webpack_require__(0);var debug=void 0;if(debugUtil&&debugUtil.debuglog){debug=debugUtil.debuglog('stream');}else{debug=function(){};}var BufferList=__webpack_require__(73);var destroyImpl=__webpack_require__(22);var StringDecoder;util.inherits(Readable,Stream);var kProxyEvents=['error','close','destroy','pause','resume'];function prependListener(emitter,event,fn){if(typeof emitter.prependListener==='function'){return emitter.prependListener(event,fn);}else{if(!emitter._events||!emitter._events[event])emitter.on(event,fn);else if(isArray(emitter._events[event]))emitter._events[event].unshift(fn);else emitter._events[event]=[fn,emitter._events[event]];}}function ReadableState(options,stream){Duplex=Duplex||__webpack_require__(5);options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.readableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=Math.floor(this.highWaterMark);this.buffer=new BufferList();this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.destroyed=false;this.defaultEncoding=options.defaultEncoding||'utf8';this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(options.encoding){if(!StringDecoder)StringDecoder=__webpack_require__(24).StringDecoder;this.decoder=new StringDecoder(options.encoding);this.encoding=options.encoding;}}function Readable(options){Duplex=Duplex||__webpack_require__(5);if(!(this instanceof Readable))return new Readable(options);this._readableState=new ReadableState(options,this);this.readable=true;if(options){if(typeof options.read==='function')this._read=options.read;if(typeof options.destroy==='function')this._destroy=options.destroy;}Stream.call(this);}Object.defineProperty(Readable.prototype,'destroyed',{get:function(){if(this._readableState===undefined){return false;}return this._readableState.destroyed;},set:function(value){if(!this._readableState){return;}this._readableState.destroyed=value;}});Readable.prototype.destroy=destroyImpl.destroy;Readable.prototype._undestroy=destroyImpl.undestroy;Readable.prototype._destroy=function(err,cb){this.push(null);cb(err);};Readable.prototype.push=function(chunk,encoding){var state=this._readableState;var skipChunkCheck;if(!state.objectMode){if(typeof chunk==='string'){encoding=encoding||state.defaultEncoding;if(encoding!==state.encoding){chunk=Buffer.from(chunk,encoding);encoding='';}skipChunkCheck=true;}}else{skipChunkCheck=true;}return readableAddChunk(this,chunk,encoding,false,skipChunkCheck);};Readable.prototype.unshift=function(chunk){return readableAddChunk(this,chunk,null,true,false);};function readableAddChunk(stream,chunk,encoding,addToFront,skipChunkCheck){var state=stream._readableState;if(chunk===null){state.reading=false;onEofChunk(stream,state);}else{var er;if(!skipChunkCheck)er=chunkInvalid(state,chunk);if(er){stream.emit('error',er);}else if(state.objectMode||chunk&&chunk.length>0){if(typeof chunk!=='string'&&!state.objectMode&&Object.getPrototypeOf(chunk)!==Buffer.prototype){chunk=_uint8ArrayToBuffer(chunk);}if(addToFront){if(state.endEmitted)stream.emit('error',new Error('stream.unshift() after end event'));else addChunk(stream,state,chunk,true);}else if(state.ended){stream.emit('error',new Error('stream.push() after EOF'));}else{state.reading=false;if(state.decoder&&!encoding){chunk=state.decoder.write(chunk);if(state.objectMode||chunk.length!==0)addChunk(stream,state,chunk,false);else maybeReadMore(stream,state);}else{addChunk(stream,state,chunk,false);}}}else if(!addToFront){state.reading=false;}}return needMoreData(state);}function addChunk(stream,state,chunk,addToFront){if(state.flowing&&state.length===0&&!state.sync){stream.emit('data',chunk);stream.read(0);}else{state.length+=state.objectMode?1:chunk.length;if(addToFront)state.buffer.unshift(chunk);else state.buffer.push(chunk);if(state.needReadable)emitReadable(stream);}maybeReadMore(stream,state);}function chunkInvalid(state,chunk){var er;if(!_isUint8Array(chunk)&&typeof chunk!=='string'&&chunk!==undefined&&!state.objectMode){er=new TypeError('Invalid non-string/buffer chunk');}return er;}function needMoreData(state){return!state.ended&&(state.needReadable||state.length=MAX_HWM){n=MAX_HWM;}else{n--;n|=n>>>1;n|=n>>>2;n|=n>>>4;n|=n>>>8;n|=n>>>16;n++;}return n;}function howMuchToRead(n,state){if(n<=0||state.length===0&&state.ended)return 0;if(state.objectMode)return 1;if(n!==n){if(state.flowing&&state.length)return state.buffer.head.data.length;else return state.length;}if(n>state.highWaterMark)state.highWaterMark=computeNewHighWaterMark(n);if(n<=state.length)return n;if(!state.ended){state.needReadable=true;return 0;}return state.length;}Readable.prototype.read=function(n){debug('read',n);n=parseInt(n,10);var state=this._readableState;var nOrig=n;if(n!==0)state.emittedReadable=false;if(n===0&&state.needReadable&&(state.length>=state.highWaterMark||state.ended)){debug('read: emitReadable',state.length,state.ended);if(state.length===0&&state.ended)endReadable(this);else emitReadable(this);return null;}n=howMuchToRead(n,state);if(n===0&&state.ended){if(state.length===0)endReadable(this);return null;}var doRead=state.needReadable;debug('need readable',doRead);if(state.length===0||state.length-n0)ret=fromList(n,state);else ret=null;if(ret===null){state.needReadable=true;n=0;}else{state.length-=n;}if(state.length===0){if(!state.ended)state.needReadable=true;if(nOrig!==n&&state.ended)endReadable(this);}if(ret!==null)this.emit('data',ret);return ret;};function onEofChunk(stream,state){if(state.ended)return;if(state.decoder){var chunk=state.decoder.end();if(chunk&&chunk.length){state.buffer.push(chunk);state.length+=state.objectMode?1:chunk.length;}}state.ended=true;emitReadable(stream);}function emitReadable(stream){var state=stream._readableState;state.needReadable=false;if(!state.emittedReadable){debug('emitReadable',state.flowing);state.emittedReadable=true;if(state.sync)processNextTick(emitReadable_,stream);else emitReadable_(stream);}}function emitReadable_(stream){debug('emit readable');stream.emit('readable');flow(stream);}function maybeReadMore(stream,state){if(!state.readingMore){state.readingMore=true;processNextTick(maybeReadMore_,stream,state);}}function maybeReadMore_(stream,state){var len=state.length;while(!state.reading&&!state.flowing&&!state.ended&&state.length1&&indexOf(state.pipes,dest)!==-1)&&!cleanedUp){debug('false write response, pause',src._readableState.awaitDrain);src._readableState.awaitDrain++;increasedAwaitDrain=true;}src.pause();}}function onerror(er){debug('onerror',er);unpipe();dest.removeListener('error',onerror);if(EElistenerCount(dest,'error')===0)dest.emit('error',er);}prependListener(dest,'error',onerror);function onclose(){dest.removeListener('finish',onfinish);unpipe();}dest.once('close',onclose);function onfinish(){debug('onfinish');dest.removeListener('close',onclose);unpipe();}dest.once('finish',onfinish);function unpipe(){debug('unpipe');src.unpipe(dest);}dest.emit('pipe',src);if(!state.flowing){debug('pipe resume');src.resume();}return dest;};function pipeOnDrain(src){return function(){var state=src._readableState;debug('pipeOnDrain',state.awaitDrain);if(state.awaitDrain)state.awaitDrain--;if(state.awaitDrain===0&&EElistenerCount(src,'data')){state.flowing=true;flow(src);}};}Readable.prototype.unpipe=function(dest){var state=this._readableState;var unpipeInfo={hasUnpiped:false};if(state.pipesCount===0)return this;if(state.pipesCount===1){if(dest&&dest!==state.pipes)return this;if(!dest)dest=state.pipes;state.pipes=null;state.pipesCount=0;state.flowing=false;if(dest)dest.emit('unpipe',this,unpipeInfo);return this;}if(!dest){var dests=state.pipes;var len=state.pipesCount;state.pipes=null;state.pipesCount=0;state.flowing=false;for(var i=0;i=state.length){if(state.decoder)ret=state.buffer.join('');else if(state.buffer.length===1)ret=state.buffer.head.data;else ret=state.buffer.concat(state.length);state.buffer.clear();}else{ret=fromListPartial(n,state.buffer,state.decoder);}return ret;}function fromListPartial(n,list,hasStrings){var ret;if(nstr.length?str.length:n;if(nb===str.length)ret+=str;else ret+=str.slice(0,n);n-=nb;if(n===0){if(nb===str.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null;}else{list.head=p;p.data=str.slice(nb);}break;}++c;}list.length-=c;return ret;}function copyFromBuffer(n,list){var ret=Buffer.allocUnsafe(n);var p=list.head;var c=1;p.data.copy(ret);n-=p.data.length;while(p=p.next){var buf=p.data;var nb=n>buf.length?buf.length:n;buf.copy(ret,ret.length-n,0,nb);n-=nb;if(n===0){if(nb===buf.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null;}else{list.head=p;p.data=buf.slice(nb);}break;}++c;}list.length-=c;return ret;}function endReadable(stream){var state=stream._readableState;if(state.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!state.endEmitted){state.ended=true;processNextTick(endReadableNT,state,stream);}}function endReadableNT(state,stream){if(!state.endEmitted&&state.length===0){state.endEmitted=true;stream.readable=false;stream.emit('end');}}function forEach(xs,f){for(var i=0,l=xs.length;i-1?setImmediate:processNextTick;var Duplex;Writable.WritableState=WritableState;var util=__webpack_require__(6);util.inherits=__webpack_require__(7);var internalUtil={deprecate:__webpack_require__(74)};var Stream=__webpack_require__(21);var Buffer=__webpack_require__(1).Buffer;var OurUint8Array=global.Uint8Array||function(){};function _uint8ArrayToBuffer(chunk){return Buffer.from(chunk);}function _isUint8Array(obj){return Buffer.isBuffer(obj)||obj instanceof OurUint8Array;}var destroyImpl=__webpack_require__(22);util.inherits(Writable,Stream);function nop(){}function WritableState(options,stream){Duplex=Duplex||__webpack_require__(5);options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.writableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=Math.floor(this.highWaterMark);this.finalCalled=false;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;this.destroyed=false;var noDecode=options.decodeStrings===false;this.decodeStrings=!noDecode;this.defaultEncoding=options.defaultEncoding||'utf8';this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(er){onwrite(stream,er);};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this);}WritableState.prototype.getBuffer=function getBuffer(){var current=this.bufferedRequest;var out=[];while(current){out.push(current);current=current.next;}return out;};(function(){try{Object.defineProperty(WritableState.prototype,'buffer',{get:internalUtil.deprecate(function(){return this.getBuffer();},'_writableState.buffer is deprecated. Use _writableState.getBuffer '+'instead.','DEP0003')});}catch(_){}})();var realHasInstance;if(typeof Symbol==='function'&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==='function'){realHasInstance=Function.prototype[Symbol.hasInstance];Object.defineProperty(Writable,Symbol.hasInstance,{value:function(object){if(realHasInstance.call(this,object))return true;return object&&object._writableState instanceof WritableState;}});}else{realHasInstance=function(object){return object instanceof this;};}function Writable(options){Duplex=Duplex||__webpack_require__(5);if(!realHasInstance.call(Writable,this)&&!(this instanceof Duplex)){return new Writable(options);}this._writableState=new WritableState(options,this);this.writable=true;if(options){if(typeof options.write==='function')this._write=options.write;if(typeof options.writev==='function')this._writev=options.writev;if(typeof options.destroy==='function')this._destroy=options.destroy;if(typeof options.final==='function')this._final=options.final;}Stream.call(this);}Writable.prototype.pipe=function(){this.emit('error',new Error('Cannot pipe, not readable'));};function writeAfterEnd(stream,cb){var er=new Error('write after end');stream.emit('error',er);processNextTick(cb,er);}function validChunk(stream,state,chunk,cb){var valid=true;var er=false;if(chunk===null){er=new TypeError('May not write null values to stream');}else if(typeof chunk!=='string'&&chunk!==undefined&&!state.objectMode){er=new TypeError('Invalid non-string/buffer chunk');}if(er){stream.emit('error',er);processNextTick(cb,er);valid=false;}return valid;}Writable.prototype.write=function(chunk,encoding,cb){var state=this._writableState;var ret=false;var isBuf=_isUint8Array(chunk)&&!state.objectMode;if(isBuf&&!Buffer.isBuffer(chunk)){chunk=_uint8ArrayToBuffer(chunk);}if(typeof encoding==='function'){cb=encoding;encoding=null;}if(isBuf)encoding='buffer';else if(!encoding)encoding=state.defaultEncoding;if(typeof cb!=='function')cb=nop;if(state.ended)writeAfterEnd(this,cb);else if(isBuf||validChunk(this,state,chunk,cb)){state.pendingcb++;ret=writeOrBuffer(this,state,isBuf,chunk,encoding,cb);}return ret;};Writable.prototype.cork=function(){var state=this._writableState;state.corked++;};Writable.prototype.uncork=function(){var state=this._writableState;if(state.corked){state.corked--;if(!state.writing&&!state.corked&&!state.finished&&!state.bufferProcessing&&state.bufferedRequest)clearBuffer(this,state);}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(encoding){if(typeof encoding==='string')encoding=encoding.toLowerCase();if(!(['hex','utf8','utf-8','ascii','binary','base64','ucs2','ucs-2','utf16le','utf-16le','raw'].indexOf((encoding+'').toLowerCase())>-1))throw new TypeError('Unknown encoding: '+encoding);this._writableState.defaultEncoding=encoding;return this;};function decodeChunk(state,chunk,encoding){if(!state.objectMode&&state.decodeStrings!==false&&typeof chunk==='string'){chunk=Buffer.from(chunk,encoding);}return chunk;}function writeOrBuffer(stream,state,isBuf,chunk,encoding,cb){if(!isBuf){var newChunk=decodeChunk(state,chunk,encoding);if(chunk!==newChunk){isBuf=true;encoding='buffer';chunk=newChunk;}}var len=state.objectMode?1:chunk.length;state.length+=len;var ret=state.length>5===0x06)return 2;else if(byte>>4===0x0E)return 3;else if(byte>>3===0x1E)return 4;return-1;}function utf8CheckIncomplete(self,buf,i){var j=buf.length-1;if(j=0){if(nb>0)self.lastNeed=nb-1;return nb;}if(--j=0){if(nb>0)self.lastNeed=nb-2;return nb;}if(--j=0){if(nb>0){if(nb===2)nb=0;else self.lastNeed=nb-3;}return nb;}return 0;}function utf8CheckExtraBytes(self,buf,p){if((buf[0]&0xC0)!==0x80){self.lastNeed=0;return'\ufffd'.repeat(p);}if(self.lastNeed>1&&buf.length>1){if((buf[1]&0xC0)!==0x80){self.lastNeed=1;return'\ufffd'.repeat(p+1);}if(self.lastNeed>2&&buf.length>2){if((buf[2]&0xC0)!==0x80){self.lastNeed=2;return'\ufffd'.repeat(p+2);}}}}function utf8FillLast(buf){var p=this.lastTotal-this.lastNeed;var r=utf8CheckExtraBytes(this,buf,p);if(r!==undefined)return r;if(this.lastNeed<=buf.length){buf.copy(this.lastChar,p,0,this.lastNeed);return this.lastChar.toString(this.encoding,0,this.lastTotal);}buf.copy(this.lastChar,p,0,buf.length);this.lastNeed-=buf.length;}function utf8Text(buf,i){var total=utf8CheckIncomplete(this,buf,i);if(!this.lastNeed)return buf.toString('utf8',i);this.lastTotal=total;var end=buf.length-(total-this.lastNeed);buf.copy(this.lastChar,0,end);return buf.toString('utf8',i,end);}function utf8End(buf){var r=buf&&buf.length?this.write(buf):'';if(this.lastNeed)return r+'\ufffd'.repeat(this.lastTotal-this.lastNeed);return r;}function utf16Text(buf,i){if((buf.length-i)%2===0){var r=buf.toString('utf16le',i);if(r){var c=r.charCodeAt(r.length-1);if(c>=0xD800&&c<=0xDBFF){this.lastNeed=2;this.lastTotal=4;this.lastChar[0]=buf[buf.length-2];this.lastChar[1]=buf[buf.length-1];return r.slice(0,-1);}}return r;}this.lastNeed=1;this.lastTotal=2;this.lastChar[0]=buf[buf.length-1];return buf.toString('utf16le',i,buf.length-1);}function utf16End(buf){var r=buf&&buf.length?this.write(buf):'';if(this.lastNeed){var end=this.lastTotal-this.lastNeed;return r+this.lastChar.toString('utf16le',0,end);}return r;}function base64Text(buf,i){var n=(buf.length-i)%3;if(n===0)return buf.toString('base64',i);this.lastNeed=3-n;this.lastTotal=3;if(n===1){this.lastChar[0]=buf[buf.length-1];}else{this.lastChar[0]=buf[buf.length-2];this.lastChar[1]=buf[buf.length-1];}return buf.toString('base64',i,buf.length-n);}function base64End(buf){var r=buf&&buf.length?this.write(buf):'';if(this.lastNeed)return r+this.lastChar.toString('base64',0,3-this.lastNeed);return r;}function simpleWrite(buf){return buf.toString(this.encoding);}function simpleEnd(buf){return buf&&buf.length?this.write(buf):'';} - -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -module.exports=Transform;var Duplex=__webpack_require__(5);var util=__webpack_require__(6);util.inherits=__webpack_require__(7);util.inherits(Transform,Duplex);function TransformState(stream){this.afterTransform=function(er,data){return afterTransform(stream,er,data);};this.needTransform=false;this.transforming=false;this.writecb=null;this.writechunk=null;this.writeencoding=null;}function afterTransform(stream,er,data){var ts=stream._transformState;ts.transforming=false;var cb=ts.writecb;if(!cb){return stream.emit('error',new Error('write callback called multiple times'));}ts.writechunk=null;ts.writecb=null;if(data!==null&&data!==undefined)stream.push(data);cb(er);var rs=stream._readableState;rs.reading=false;if(rs.needReadable||rs.length0){connection=this._freeConnections.shift();this.acquireConnection(connection,cb);return;}if(this.config.connectionLimit===0||this._allConnections.length=this.config.queueLimit){process.nextTick(function(){var err=new Error('Queue limit reached.');err.code='POOL_ENQUEUELIMIT';callback(err);});return;}var cb=process.domain?process.domain.bind(callback):callback;this._connectionQueue.push(cb);this.emit('enqueue');};Pool.prototype._needsChangeUser=function _needsChangeUser(connection){var connConfig=connection.config;var poolConfig=this.config.connectionConfig;return connConfig.user!==poolConfig.user||connConfig.database!==poolConfig.database||connConfig.password!==poolConfig.password||connConfig.charsetNumber!==poolConfig.charsetNumber;};Pool.prototype._purgeConnection=function _purgeConnection(connection,callback){var cb=callback||function(){};if(connection.state==='disconnected'){connection.destroy();}this._removeConnection(connection);if(connection.state!=='disconnected'&&!connection._protocol._quitSequence){connection._realEnd(cb);return;}process.nextTick(cb);};Pool.prototype._removeConnection=function(connection){connection._pool=null;spliceConnection(this._allConnections,connection);spliceConnection(this._freeConnections,connection);this.releaseConnection(connection);};Pool.prototype.escape=function(value){return mysql.escape(value,this.config.connectionConfig.stringifyObjects,this.config.connectionConfig.timezone);};Pool.prototype.escapeId=function escapeId(value){return mysql.escapeId(value,false);};function spliceConnection(array,connection){var index;if((index=array.indexOf(connection))!==-1){array.splice(index,1);}} - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -var ConnectionConfig=__webpack_require__(11);module.exports=PoolConfig;function PoolConfig(options){if(typeof options==='string'){options=ConnectionConfig.parseUrl(options);}this.acquireTimeout=options.acquireTimeout===undefined?10*1000:Number(options.acquireTimeout);this.connectionConfig=new ConnectionConfig(options);this.waitForConnections=options.waitForConnections===undefined?true:Boolean(options.waitForConnections);this.connectionLimit=options.connectionLimit===undefined?10:Number(options.connectionLimit);this.queueLimit=options.queueLimit===undefined?0:Number(options.queueLimit);}PoolConfig.prototype.newConnectionConfig=function newConnectionConfig(){var connectionConfig=new ConnectionConfig(this.connectionConfig);connectionConfig.clientFlags=this.connectionConfig.clientFlags;connectionConfig.maxPacketSize=this.connectionConfig.maxPacketSize;return connectionConfig;}; - -/***/ }), -/* 29 */ -/***/ (function(module, exports) { - -var PoolSelector=module.exports={};PoolSelector.RR=function PoolSelectorRoundRobin(){var index=0;return function(clusterIds){if(index>=clusterIds.length){index=0;}var clusterId=clusterIds[index++];return clusterId;};};PoolSelector.RANDOM=function PoolSelectorRandom(){return function(clusterIds){return clusterIds[Math.floor(Math.random()*clusterIds.length)];};};PoolSelector.ORDER=function PoolSelectorOrder(){return function(clusterIds){return clusterIds[0];};}; - -/***/ }), -/* 30 */ -/***/ (function(module, exports, __webpack_require__) { - -const mysql=__webpack_require__(14);const config=JSON.parse(global.LoadResourceFile('ghmattimysql','config.json'));const configString=global.GetConvar('mysql_connection_string','mysql://localhost/fivem');const useBoolean=global.GetConvarInt('mysql_use_boolean',0);const showDebug=global.GetConvarInt('mysql_debug',0);const pool=mysql.createPool(config||configString);function prepareLegacyQuery(query,parameters){let sql=query;let params=parameters;if(params!==null&&typeof params==='object'&&!Array.isArray(params)){params=[];sql=sql.replace(/@(\w+)/g,(txt,key)=>{if(Object.prototype.hasOwnProperty.call(parameters,key)){params.push(parameters[key]);return'?';}return txt;});}return[sql,params];}function transformToBoolean(fields,result){const res=result;if(fields){fields.forEach(field=>{if(field.columnType===1&&field.columnLength===1){result.forEach((_,index)=>{res[index][field.name]=result[index][field.name]!==0;});}});}return res;}function sanitizeInput(query,parameters,callback){let sql=query;let params=parameters;let cb=callback;if(typeof parameters==='function'){cb=parameters;}[sql,params]=prepareLegacyQuery(query,params);if(!Array.isArray(params)){params=[];}return[sql,params,cb];}async function safeInvoke(callback,args){if(typeof callback==='function'){setImmediate(()=>{callback(args);});}}function execute(sql,params,connection){const orm=connection||pool;return new Promise((resolve,reject)=>{orm.query(sql,params,(error,result,fields)=>{if(showDebug)console.log(`[MySQL] ${sql} : ${JSON.stringify(params)}`);if(error)reject(error);resolve(useBoolean?transformToBoolean(fields,result):result);});});}global.exports('scalar',(query,parameters,callback)=>{let sql=query;let params=parameters;let cb=callback;[sql,params,cb]=sanitizeInput(sql,params,cb);execute(sql,params).then(result=>{safeInvoke(cb,Object.values(result[0]||{})[0]);});});global.exports('execute',(query,parameters,callback)=>{let sql=query;let params=parameters;let cb=callback;[sql,params,cb]=sanitizeInput(sql,params,cb);execute(sql,params).then(result=>{safeInvoke(cb,result);});});function onTransactionError(error,connection,callback){connection.rollback(()=>{console.error(error);safeInvoke(callback,false);});}global.exports('transaction',(querys,parameters,callback)=>{let sqls=[];let params=parameters;let cb=callback;if(!querys.every(element=>typeof element==='string')){sqls=querys;if(typeof parameters==='function')cb=parameters;}else{if(typeof parameters==='function'){cb=parameters;params=[];}querys.forEach(element=>{sqls.push({query:element,parameters:params});});}sqls.forEach((element,index)=>{const[stmt,stmtParams]=prepareLegacyQuery(element.query,element.parameters);sqls[index]={query:stmt,parameters:Array.isArray(stmtParams)?stmtParams:[]};});pool.getConnection((connectionError,connection)=>{if(connectionError){console.error(connectionError);safeInvoke(cb,false);return;}connection.beginTransaction(transactionError=>{if(transactionError){onTransactionError(transactionError,connection,callback);return;}const promises=[];sqls.forEach(element=>{promises.push(execute(element.query,element.parameters,connection));});Promise.all(promises).then(()=>{connection.commit(commitError=>{if(commitError){onTransactionError(commitError,connection,callback);}else safeInvoke(cb,true);});}).catch(executeError=>{onTransactionError(executeError,connection,callback);});});});}); - -/***/ }), -/* 31 */ -/***/ (function(module, exports) { - -module.exports = require("net"); - -/***/ }), -/* 32 */ -/***/ (function(module, exports) { - -module.exports = require("tls"); - -/***/ }), -/* 33 */ -/***/ (function(module, exports) { - -module.exports = require("url"); - -/***/ }), -/* 34 */ -/***/ (function(module, exports) { - -exports['Amazon RDS']={ca:['-----BEGIN CERTIFICATE-----\n'+'MIIDQzCCAqygAwIBAgIJAOd1tlfiGoEoMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV\n'+'BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRMw\n'+'EQYDVQQKEwpBbWF6b24uY29tMQwwCgYDVQQLEwNSRFMxHDAaBgNVBAMTE2F3cy5h\n'+'bWF6b24uY29tL3Jkcy8wHhcNMTAwNDA1MjI0NDMxWhcNMTUwNDA0MjI0NDMxWjB1\n'+'MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2Vh\n'+'dHRsZTETMBEGA1UEChMKQW1hem9uLmNvbTEMMAoGA1UECxMDUkRTMRwwGgYDVQQD\n'+'ExNhd3MuYW1hem9uLmNvbS9yZHMvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n'+'gQDKhXGU7tizxUR5WaFoMTFcxNxa05PEjZaIOEN5ctkWrqYSRov0/nOMoZjqk8bC\n'+'med9vPFoQGD0OTakPs0jVe3wwmR735hyVwmKIPPsGlaBYj1O6llIpZeQVyupNx56\n'+'UzqtiLaDzh1KcmfqP3qP2dInzBfJQKjiRudo1FWnpPt33QIDAQABo4HaMIHXMB0G\n'+'A1UdDgQWBBT/H3x+cqSkR/ePSIinPtc4yWKe3DCBpwYDVR0jBIGfMIGcgBT/H3x+\n'+'cqSkR/ePSIinPtc4yWKe3KF5pHcwdTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh\n'+'c2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxEzARBgNVBAoTCkFtYXpvbi5jb20x\n'+'DDAKBgNVBAsTA1JEUzEcMBoGA1UEAxMTYXdzLmFtYXpvbi5jb20vcmRzL4IJAOd1\n'+'tlfiGoEoMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAvguZy/BDT66x\n'+'GfgnJlyQwnFSeVLQm9u/FIvz4huGjbq9dqnD6h/Gm56QPFdyMEyDiZWaqY6V08lY\n'+'LTBNb4kcIc9/6pc0/ojKciP5QJRm6OiZ4vgG05nF4fYjhU7WClUx7cxq1fKjNc2J\n'+'UCmmYqgiVkAGWRETVo+byOSDZ4swb10=\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID9DCCAtygAwIBAgIBQjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUwOTExMzFaFw0y\n'+'MDAzMDUwOTExMzFaMIGKMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEbMBkGA1UEAwwSQW1hem9uIFJE\n'+'UyBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuD8nrZ8V\n'+'u+VA8yVlUipCZIKPTDcOILYpUe8Tct0YeQQr0uyl018StdBsa3CjBgvwpDRq1HgF\n'+'Ji2N3+39+shCNspQeE6aYU+BHXhKhIIStt3r7gl/4NqYiDDMWKHxHq0nsGDFfArf\n'+'AOcjZdJagOMqb3fF46flc8k2E7THTm9Sz4L7RY1WdABMuurpICLFE3oHcGdapOb9\n'+'T53pQR+xpHW9atkcf3pf7gbO0rlKVSIoUenBlZipUlp1VZl/OD/E+TtRhDDNdI2J\n'+'P/DSMM3aEsq6ZQkfbz/Ilml+Lx3tJYXUDmp+ZjzMPLk/+3beT8EhrwtcG3VPpvwp\n'+'BIOqsqVVTvw/CwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw\n'+'AwEB/zAdBgNVHQ4EFgQUTgLurD72FchM7Sz1BcGPnIQISYMwHwYDVR0jBBgwFoAU\n'+'TgLurD72FchM7Sz1BcGPnIQISYMwDQYJKoZIhvcNAQEFBQADggEBAHZcgIio8pAm\n'+'MjHD5cl6wKjXxScXKtXygWH2BoDMYBJF9yfyKO2jEFxYKbHePpnXB1R04zJSWAw5\n'+'2EUuDI1pSBh9BA82/5PkuNlNeSTB3dXDD2PEPdzVWbSKvUB8ZdooV+2vngL0Zm4r\n'+'47QPyd18yPHrRIbtBtHR/6CwKevLZ394zgExqhnekYKIqqEX41xsUV0Gm6x4vpjf\n'+'2u6O/+YE2U+qyyxHE5Wd5oqde0oo9UUpFETJPVb6Q2cEeQib8PBAyi0i6KnF+kIV\n'+'A9dY7IHSubtCK/i8wxMVqfd5GtbA8mmpeJFwnDvm9rBEsHybl08qlax9syEwsUYr\n'+'/40NawZfTUU=\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIIEATCCAumgAwIBAgIBRDANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMDZaFw0y\n'+'MDAzMDUyMjAzMDZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJE\n'+'UyBhcC1ub3J0aGVhc3QtMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n'+'ggEBAMmM2B4PfTXCZjbZMWiDPyxvk/eeNwIRJAhfzesiGUiLozX6CRy3rwC1ZOPV\n'+'AcQf0LB+O8wY88C/cV+d4Q2nBDmnk+Vx7o2MyMh343r5rR3Na+4izd89tkQVt0WW\n'+'vO21KRH5i8EuBjinboOwAwu6IJ+HyiQiM0VjgjrmEr/YzFPL8MgHD/YUHehqjACn\n'+'C0+B7/gu7W4qJzBL2DOf7ub2qszGtwPE+qQzkCRDwE1A4AJmVE++/FLH2Zx78Egg\n'+'fV1sUxPtYgjGH76VyyO6GNKM6rAUMD/q5mnPASQVIXgKbupr618bnH+SWHFjBqZq\n'+'HvDGPMtiiWII41EmGUypyt5AbysCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIG\n'+'A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFIiKM0Q6n1K4EmLxs3ZXxINbwEwR\n'+'MB8GA1UdIwQYMBaAFE4C7qw+9hXITO0s9QXBj5yECEmDMA0GCSqGSIb3DQEBBQUA\n'+'A4IBAQBezGbE9Rw/k2e25iGjj5n8r+M3dlye8ORfCE/dijHtxqAKasXHgKX8I9Tw\n'+'JkBiGWiuzqn7gO5MJ0nMMro1+gq29qjZnYX1pDHPgsRjUX8R+juRhgJ3JSHijRbf\n'+'4qNJrnwga7pj94MhcLq9u0f6dxH6dXbyMv21T4TZMTmcFduf1KgaiVx1PEyJjC6r\n'+'M+Ru+A0eM+jJ7uCjUoZKcpX8xkj4nmSnz9NMPog3wdOSB9cAW7XIc5mHa656wr7I\n'+'WJxVcYNHTXIjCcng2zMKd1aCcl2KSFfy56sRfT7J5Wp69QSr+jq8KM55gw8uqAwi\n'+'VPrXn2899T1rcTtFYFP16WXjGuc0\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIIEATCCAumgAwIBAgIBTDANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTExMDYwMDA1NDZaFw0y\n'+'MDAzMDUwMDA1NDZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJE\n'+'UyBhcC1ub3J0aGVhc3QtMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n'+'ggEBAKSwd+RVUzTRH0FgnbwoTK8TMm/zMT4+2BvALpAUe6YXbkisg2goycWuuWLg\n'+'jOpFBB3GtyvXZnkqi7MkDWUmj1a2kf8l2oLyoaZ+Hm9x/sV+IJzOqPvj1XVUGjP6\n'+'yYYnPJmUYqvZeI7fEkIGdFkP2m4/sgsSGsFvpD9FK1bL1Kx2UDpYX0kHTtr18Zm/\n'+'1oN6irqWALSmXMDydb8hE0FB2A1VFyeKE6PnoDj/Y5cPHwPPdEi6/3gkDkSaOG30\n'+'rWeQfL3pOcKqzbHaWTxMphd0DSL/quZ64Nr+Ly65Q5PRcTrtr55ekOUziuqXwk+o\n'+'9QpACMwcJ7ROqOznZTqTzSFVXFECAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIG\n'+'A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFM6Nox/QWbhzWVvzoJ/y0kGpNPK+\n'+'MB8GA1UdIwQYMBaAFE4C7qw+9hXITO0s9QXBj5yECEmDMA0GCSqGSIb3DQEBBQUA\n'+'A4IBAQCTkWBqNvyRf3Y/W21DwFx3oT/AIWrHt0BdGZO34tavummXemTH9LZ/mqv9\n'+'aljt6ZuDtf5DEQjdsAwXMsyo03ffnP7doWm8iaF1+Mui77ot0TmTsP/deyGwukvJ\n'+'tkxX8bZjDh+EaNauWKr+CYnniNxCQLfFtXYJsfOdVBzK3xNL+Z3ucOQRhr2helWc\n'+'CDQgwfhP1+3pRVKqHvWCPC4R3fT7RZHuRmZ38kndv476GxRntejh+ePffif78bFI\n'+'3rIZCPBGobrrUMycafSbyXteoGca/kA+/IqrAPlk0pWQ4aEL0yTWN2h2dnjoD7oX\n'+'byIuL/g9AGRh97+ssn7D6bDRPTbW\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIIEATCCAumgAwIBAgIBRTANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMTlaFw0y\n'+'MDAzMDUyMjAzMTlaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJE\n'+'UyBhcC1zb3V0aGVhc3QtMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n'+'ggEBANaXElmSEYt/UtxHFsARFhSUahTf1KNJzR0Dmay6hqOXQuRVbKRwPd19u5vx\n'+'DdF1sLT7D69IK3VDnUiQScaCv2Dpu9foZt+rLx+cpx1qiQd1UHrvqq8xPzQOqCdC\n'+'RFStq6yVYZ69yfpfoI67AjclMOjl2Vph3ftVnqP0IgVKZdzeC7fd+umGgR9xY0Qr\n'+'Ubhd/lWdsbNvzK3f1TPWcfIKQnpvSt85PIEDJir6/nuJUKMtmJRwTymJf0i+JZ4x\n'+'7dJa341p2kHKcHMgOPW7nJQklGBA70ytjUV6/qebS3yIugr/28mwReflg3TJzVDl\n'+'EOvi6pqbqNbkMuEwGDCmEQIVqgkCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIG\n'+'A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAu93/4k5xbWOsgdCdn+/KdiRuit\n'+'MB8GA1UdIwQYMBaAFE4C7qw+9hXITO0s9QXBj5yECEmDMA0GCSqGSIb3DQEBBQUA\n'+'A4IBAQBlcjSyscpPjf5+MgzMuAsCxByqUt+WFspwcMCpwdaBeHOPSQrXNqX2Sk6P\n'+'kth6oCivA64trWo8tFMvPYlUA1FYVD5WpN0kCK+P5pD4KHlaDsXhuhClJzp/OP8t\n'+'pOyUr5109RHLxqoKB5J5m1XA7rgcFjnMxwBSWFe3/4uMk/+4T53YfCVXuc6QV3i7\n'+'I/2LAJwFf//pTtt6fZenYfCsahnr2nvrNRNyAxcfvGZ/4Opn/mJtR6R/AjvQZHiR\n'+'bkRNKF2GW0ueK5W4FkZVZVhhX9xh1Aj2Ollb+lbOqADaVj+AT3PoJPZ3MPQHKCXm\n'+'xwG0LOLlRr/TfD6li1AfOVTAJXv9\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIIEATCCAumgAwIBAgIBRjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMjRaFw0y\n'+'MDAzMDUyMjAzMjRaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzElMCMGA1UEAwwcQW1hem9uIFJE\n'+'UyBhcC1zb3V0aGVhc3QtMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n'+'ggEBAJqBAJutz69hFOh3BtLHZTbwE8eejGGKayn9hu98YMDPzWzGXWCmW+ZYWELA\n'+'cY3cNWNF8K4FqKXFr2ssorBYim1UtYFX8yhydT2hMD5zgQ2sCGUpuidijuPA6zaq\n'+'Z3tdhVR94f0q8mpwpv2zqR9PcqaGDx2VR1x773FupRPRo7mEW1vC3IptHCQlP/zE\n'+'7jQiLl28bDIH2567xg7e7E9WnZToRnhlYdTaDaJsHTzi5mwILi4cihSok7Shv/ME\n'+'hnukvxeSPUpaVtFaBhfBqq055ePq9I+Ns4KGreTKMhU0O9fkkaBaBmPaFgmeX/XO\n'+'n2AX7gMouo3mtv34iDTZ0h6YCGkCAwEAAaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIG\n'+'A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFIlQnY0KHYWn1jYumSdJYfwj/Nfw\n'+'MB8GA1UdIwQYMBaAFE4C7qw+9hXITO0s9QXBj5yECEmDMA0GCSqGSIb3DQEBBQUA\n'+'A4IBAQA0wVU6/l41cTzHc4azc4CDYY2Wd90DFWiH9C/mw0SgToYfCJ/5Cfi0NT/Y\n'+'PRnk3GchychCJgoPA/k9d0//IhYEAIiIDjyFVgjbTkKV3sh4RbdldKVOUB9kumz/\n'+'ZpShplsGt3z4QQiVnKfrAgqxWDjR0I0pQKkxXa6Sjkicos9LQxVtJ0XA4ieG1E7z\n'+'zJr+6t80wmzxvkInSaWP3xNJK9azVRTrgQZQlvkbpDbExl4mNTG66VD3bAp6t3Wa\n'+'B49//uDdfZmPkqqbX+hsxp160OH0rxJppwO3Bh869PkDnaPEd/Pxw7PawC+li0gi\n'+'NRV8iCEx85aFxcyOhqn0WZOasxee\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID/zCCAuegAwIBAgIBRzANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMzFaFw0y\n'+'MDAzMDUyMjAzMzFaMIGSMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEjMCEGA1UEAwwaQW1hem9uIFJE\n'+'UyBldS1jZW50cmFsLTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n'+'AQDFtP2dhSLuaPOI4ZrrPWsK4OY9ocQBp3yApH1KJYmI9wpQKZG/KCH2E6Oo7JAw\n'+'QORU519r033T+FO2Z7pFPlmz1yrxGXyHpJs8ySx3Yo5S8ncDCdZJCLmtPiq/hahg\n'+'5/0ffexMFUCQaYicFZsrJ/cStdxUV+tSw2JQLD7UxS9J97LQWUPyyG+ZrjYVTVq+\n'+'zudnFmNSe4QoecXMhAFTGJFQXxP7nhSL9Ao5FGgdXy7/JWeWdQIAj8ku6cBDKPa6\n'+'Y6kP+ak+In+Lye8z9qsCD/afUozfWjPR2aA4JoIZVF8dNRShIMo8l0XfgfM2q0+n\n'+'ApZWZ+BjhIO5XuoUgHS3D2YFAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNV\n'+'HRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRm4GsWIA/M6q+tK8WGHWDGh2gcyTAf\n'+'BgNVHSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOC\n'+'AQEAHpMmeVQNqcxgfQdbDIi5UIy+E7zZykmtAygN1XQrvga9nXTis4kOTN6g5/+g\n'+'HCx7jIXeNJzAbvg8XFqBN84Quqgpl/tQkbpco9Jh1HDs558D5NnZQxNqH5qXQ3Mm\n'+'uPgCw0pYcPOa7bhs07i+MdVwPBsX27CFDtsgAIru8HvKxY1oTZrWnyIRo93tt/pk\n'+'WuItVMVHjaQZVfTCow0aDUbte6Vlw82KjUFq+n2NMSCJDiDKsDDHT6BJc4AJHIq3\n'+'/4Z52MSC9KMr0yAaaoWfW/yMEj9LliQauAgwVjArF4q78rxpfKTG9Rfd8U1BZANP\n'+'7FrFMN0ThjfA1IvmOYcgskY5bQ==\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID/DCCAuSgAwIBAgIBSDANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzMzVaFw0y\n'+'MDAzMDUyMjAzMzVaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE\n'+'UyBldS13ZXN0LTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx\n'+'PdbqQ0HKRj79Pmocxvjc+P6i4Ux24kgFIl+ckiir1vzkmesc3a58gjrMlCksEObt\n'+'Yihs5IhzEq1ePT0gbfS9GYFp34Uj/MtPwlrfCBWG4d2TcrsKRHr1/EXUYhWqmdrb\n'+'RhX8XqoRhVkbF/auzFSBhTzcGGvZpQ2KIaxRcQfcXlMVhj/pxxAjh8U4F350Fb0h\n'+'nX1jw4/KvEreBL0Xb2lnlGTkwVxaKGSgXEnOgIyOFdOQc61vdome0+eeZsP4jqeR\n'+'TGYJA9izJsRbe2YJxHuazD+548hsPlM3vFzKKEVURCha466rAaYAHy3rKur3HYQx\n'+'Yt+SoKcEz9PXuSGj96ejAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB\n'+'Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBTebg//h2oeXbZjQ4uuoiuLYzuiPDAfBgNV\n'+'HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA\n'+'TikPaGeZasTPw+4RBemlsyPAjtFFQLo7ddaFdORLgdEysVf8aBqndvbA6MT/v4lj\n'+'GtEtUdF59ZcbWOrVm+fBZ2h/jYJ59dYF/xzb09nyRbdMSzB9+mkSsnOMqluq5y8o\n'+'DY/PfP2vGhEg/2ZncRC7nlQU1Dm8F4lFWEiQ2fi7O1cW852Vmbq61RIfcYsH/9Ma\n'+'kpgk10VZ75b8m3UhmpZ/2uRY+JEHImH5WpcTJ7wNiPNJsciZMznGtrgOnPzYco8L\n'+'cDleOASIZifNMQi9PKOJKvi0ITz0B/imr8KBsW0YjZVJ54HMa7W1lwugSM7aMAs+\n'+'E3Sd5lS+SHwWaOCHwhOEVA==\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID/DCCAuSgAwIBAgIBSTANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzNDBaFw0y\n'+'MDAzMDUyMjAzNDBaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE\n'+'UyBzYS1lYXN0LTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCU\n'+'X4OBnQ5xA6TLJAiFEI6l7bUWjoVJBa/VbMdCCSs2i2dOKmqUaXu2ix2zcPILj3lZ\n'+'GMk3d/2zvTK/cKhcFrewHUBamTeVHdEmynhMQamqNmkM4ptYzFcvEUw1TGxHT4pV\n'+'Q6gSN7+/AJewQvyHexHo8D0+LDN0/Wa9mRm4ixCYH2CyYYJNKaZt9+EZfNu+PPS4\n'+'8iB0TWH0DgQkbWMBfCRgolLLitAZklZ4dvdlEBS7evN1/7ttBxUK6SvkeeSx3zBl\n'+'ww3BlXqc3bvTQL0A+RRysaVyFbvtp9domFaDKZCpMmDFAN/ntx215xmQdrSt+K3F\n'+'cXdGQYHx5q410CAclGnbAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB\n'+'Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBT6iVWnm/uakS+tEX2mzIfw+8JL0zAfBgNV\n'+'HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA\n'+'FmDD+QuDklXn2EgShwQxV13+txPRuVdOSrutHhoCgMwFWCMtPPtBAKs6KPY7Guvw\n'+'DpJoZSehDiOfsgMirjOWjvfkeWSNvKfjWTVneX7pZD9W5WPnsDBvTbCGezm+v87z\n'+'b+ZM2ZMo98m/wkMcIEAgdSKilR2fuw8rLkAjhYFfs0A7tDgZ9noKwgHvoE4dsrI0\n'+'KZYco6DlP/brASfHTPa2puBLN9McK3v+h0JaSqqm5Ro2Bh56tZkQh8AWy/miuDuK\n'+'3+hNEVdxosxlkM1TPa1DGj0EzzK0yoeerXuH2HX7LlCrrxf6/wdKnjR12PMrLQ4A\n'+'pCqkcWw894z6bV9MAvKe6A==\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID/DCCAuSgAwIBAgIBQzANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMTU0MDRaFw0y\n'+'MDAzMDUyMTU0MDRaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE\n'+'UyB1cy1lYXN0LTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDI\n'+'UIuwh8NusKHk1SqPXcP7OqxY3S/M2ZyQWD3w7Bfihpyyy/fc1w0/suIpX3kbMhAV\n'+'2ESwged2/2zSx4pVnjp/493r4luhSqQYzru78TuPt9bhJIJ51WXunZW2SWkisSaf\n'+'USYUzVN9ezR/bjXTumSUQaLIouJt3OHLX49s+3NAbUyOI8EdvgBQWD68H1epsC0n\n'+'CI5s+pIktyOZ59c4DCDLQcXErQ+tNbDC++oct1ANd/q8p9URonYwGCGOBy7sbCYq\n'+'9eVHh1Iy2M+SNXddVOGw5EuruvHoCIQyOz5Lz4zSuZA9dRbrfztNOpezCNYu6NKM\n'+'n+hzcvdiyxv77uNm8EaxAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB\n'+'Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBQSQG3TmMe6Sa3KufaPBa72v4QFDzAfBgNV\n'+'HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA\n'+'L/mOZfB3187xTmjOHMqN2G2oSKHBKiQLM9uv8+97qT+XR+TVsBT6b3yoPpMAGhHA\n'+'Pc7nxAF5gPpuzatx0OTLPcmYucFmfqT/1qA5WlgCnMNtczyNMH97lKFTNV7Njtek\n'+'jWEzAEQSyEWrkNpNlC4j6kMYyPzVXQeXUeZTgJ9FNnVZqmvfjip2N22tawMjrCn5\n'+'7KN/zN65EwY2oO9XsaTwwWmBu3NrDdMbzJnbxoWcFWj4RBwanR1XjQOVNhDwmCOl\n'+'/1Et13b8CPyj69PC8BOVU6cfTSx8WUVy0qvYOKHNY9Bqa5BDnIL3IVmUkeTlM1mt\n'+'enRpyBj+Bk9rh/ICdiRKmA==\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID/DCCAuSgAwIBAgIBSjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzNDVaFw0y\n'+'MDAzMDUyMjAzNDVaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE\n'+'UyB1cy13ZXN0LTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDE\n'+'Dhw+uw/ycaiIhhyu2pXFRimq0DlB8cNtIe8hdqndH8TV/TFrljNgR8QdzOgZtZ9C\n'+'zzQ2GRpInN/qJF6slEd6wO+6TaDBQkPY+07TXNt52POFUhdVkhJXHpE2BS7Xn6J7\n'+'7RFAOeG1IZmc2DDt+sR1BgXzUqHslQGfFYNS0/MBO4P+ya6W7IhruB1qfa4HiYQS\n'+'dbe4MvGWnv0UzwAqdR7OF8+8/5c58YXZIXCO9riYF2ql6KNSL5cyDPcYK5VK0+Q9\n'+'VI6vuJHSMYcF7wLePw8jtBktqAFE/wbdZiIHhZvNyiNWPPNTGUmQbaJ+TzQEHDs5\n'+'8en+/W7JKnPyBOkxxENbAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB\n'+'Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBS0nw/tFR9bCjgqWTPJkyy4oOD8bzAfBgNV\n'+'HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA\n'+'CXGAY3feAak6lHdqj6+YWjy6yyUnLK37bRxZDsyDVXrPRQaXRzPTzx79jvDwEb/H\n'+'Q/bdQ7zQRWqJcbivQlwhuPJ4kWPUZgSt3JUUuqkMsDzsvj/bwIjlrEFDOdHGh0mi\n'+'eVIngFEjUXjMh+5aHPEF9BlQnB8LfVtKj18e15UDTXFa+xJPFxUR7wDzCfo4WI1m\n'+'sUMG4q1FkGAZgsoyFPZfF8IVvgCuGdR8z30VWKklFxttlK0eGLlPAyIO0CQxPQlo\n'+'saNJrHf4tLOgZIWk+LpDhNd9Et5EzvJ3aURUsKY4pISPPF5WdvM9OE59bERwUErd\n'+'nuOuQWQeeadMceZnauRzJQ==\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID/DCCAuSgAwIBAgIBSzANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNTAyMDUyMjAzNTBaFw0y\n'+'MDAzMDUyMjAzNTBaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE\n'+'UyB1cy13ZXN0LTIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDM\n'+'H58SR48U6jyERC1vYTnub34smf5EQVXyzaTmspWGWGzT31NLNZGSDFaa7yef9kdO\n'+'mzJsgebR5tXq6LdwlIoWkKYQ7ycUaadtVKVYdI40QcI3cHn0qLFlg2iBXmWp/B+i\n'+'Z34VuVlCh31Uj5WmhaBoz8t/GRqh1V/aCsf3Wc6jCezH3QfuCjBpzxdOOHN6Ie2v\n'+'xX09O5qmZTvMoRBAvPkxdaPg/Mi7fxueWTbEVk78kuFbF1jHYw8U1BLILIAhcqlq\n'+'x4u8nl73t3O3l/soNUcIwUDK0/S+Kfqhwn9yQyPlhb4Wy3pfnZLJdkyHldktnQav\n'+'9TB9u7KH5Lk0aAYslMLxAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB\n'+'Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBT8roM4lRnlFHWMPWRz0zkwFZog1jAfBgNV\n'+'HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQUFAAOCAQEA\n'+'JwrxwgwmPtcdaU7O7WDdYa4hprpOMamI49NDzmE0s10oGrqmLwZygcWU0jT+fJ+Y\n'+'pJe1w0CVfKaeLYNsOBVW3X4ZPmffYfWBheZiaiEflq/P6t7/Eg81gaKYnZ/x1Dfa\n'+'sUYkzPvCkXe9wEz5zdUTOCptDt89rBR9CstL9vE7WYUgiVVmBJffWbHQLtfjv6OF\n'+'NMb0QME981kGRzc2WhgP71YS2hHd1kXtsoYP1yTu4vThSKsoN4bkiHsaC1cRkLoy\n'+'0fFA4wpB3WloMEvCDaUvvH1LZlBXTNlwi9KtcwD4tDxkkBt4tQczKLGpQ/nF/W9n\n'+'8YDWk3IIc1sd0bkZqoau2Q==\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID/TCCAuWgAwIBAgIBTTANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNjA1MDMyMTI5MjJaFw0y\n'+'MDAzMDUyMTI5MjJaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEhMB8GA1UEAwwYQW1hem9uIFJE\n'+'UyBhcC1zb3V0aC0xIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n'+'06eWGLE0TeqL9kyWOLkS8q0fXO97z+xyBV3DKSB2lg2GkgBz3B98MkmkeB0SZy3G\n'+'Ce4uCpCPbFKiFEdiUclOlhZsrBuCeaimxLM3Ig2wuenElO/7TqgaYHYUbT3d+VQW\n'+'GUbLn5GRZJZe1OAClYdOWm7A1CKpuo+cVV1vxbY2nGUQSJPpVn2sT9gnwvjdE60U\n'+'JGYU/RLCTm8zmZBvlWaNIeKDnreIc4rKn6gUnJ2cQn1ryCVleEeyc3xjYDSrjgdn\n'+'FLYGcp9mphqVT0byeQMOk0c7RHpxrCSA0V5V6/CreFV2LteK50qcDQzDSM18vWP/\n'+'p09FoN8O7QrtOeZJzH/lmwIDAQABo2YwZDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0T\n'+'AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU2i83QHuEl/d0keXF+69HNJph7cMwHwYD\n'+'VR0jBBgwFoAUTgLurD72FchM7Sz1BcGPnIQISYMwDQYJKoZIhvcNAQELBQADggEB\n'+'ACqnH2VjApoDqoSQOky52QBwsGaj+xWYHW5Gm7EvCqvQuhWMkeBuD6YJmMvNyA9G\n'+'I2lh6/o+sUk/RIsbYbxPRdhNPTOgDR9zsNRw6qxaHztq/CEC+mxDCLa3O1hHBaDV\n'+'BmB3nCZb93BvO0EQSEk7aytKq/f+sjyxqOcs385gintdHGU9uM7gTZHnU9vByJsm\n'+'/TL07Miq67X0NlhIoo3jAk+xHaeKJdxdKATQp0448P5cY20q4b8aMk1twcNaMvCP\n'+'dG4M5doaoUA8OQ/0ukLLae/LBxLeTw04q1/a2SyFaVUX2Twbb1S3xVWwLA8vsyGr\n'+'igXx7B5GgP+IHb6DTjPJAi0=\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID/zCCAuegAwIBAgIBTzANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNjA5MTUwMDEwMTFaFw0y\n'+'MDAzMDUwMDEwMTFaMIGSMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEjMCEGA1UEAwwaQW1hem9uIFJE\n'+'UyBjYS1jZW50cmFsLTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n'+'AQCZYI/iQ6DrS3ny3t1EwX1wAD+3LMgh7Fd01EW5LIuaK2kYIIQpsVKhxLCit/V5\n'+'AGc/1qiJS1Qz9ODLTh0Na6bZW6EakRzuHJLe32KJtoFYPC7Z09UqzXrpA/XL+1hM\n'+'P0ZmCWsU7Nn/EmvfBp9zX3dZp6P6ATrvDuYaVFr+SA7aT3FXpBroqBS1fyzUPs+W\n'+'c6zTR6+yc4zkHX0XQxC5RH6xjgpeRkoOajA/sNo7AQF7KlWmKHbdVF44cvvAhRKZ\n'+'XaoVs/C4GjkaAEPTCbopYdhzg+KLx9eB2BQnYLRrIOQZtRfbQI2Nbj7p3VsRuOW1\n'+'tlcks2w1Gb0YC6w6SuIMFkl1AgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNV\n'+'HRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBToYWxE1lawl6Ks6NsvpbHQ3GKEtzAf\n'+'BgNVHSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQsFAAOC\n'+'AQEAG/8tQ0ooi3hoQpa5EJz0/E5VYBsAz3YxA2HoIonn0jJyG16bzB4yZt4vNQMA\n'+'KsNlQ1uwDWYL1nz63axieUUFIxqxl1KmwfhsmLgZ0Hd2mnTPIl2Hw3uj5+wdgGBg\n'+'agnAZ0bajsBYgD2VGQbqjdk2Qn7Fjy3LEWIvGZx4KyZ99OJ2QxB7JOPdauURAtWA\n'+'DKYkP4LLJxtj07DSzG8kuRWb9B47uqUD+eKDIyjfjbnzGtd9HqqzYFau7EX3HVD9\n'+'9Qhnjl7bTZ6YfAEZ3nH2t3Vc0z76XfGh47rd0pNRhMV+xpok75asKf/lNh5mcUrr\n'+'VKwflyMkQpSbDCmcdJ90N2xEXQ==\n'+'-----END CERTIFICATE-----\n','-----BEGIN CERTIFICATE-----\n'+'MIID/DCCAuSgAwIBAgIBUDANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMCVVMx\n'+'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n'+'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n'+'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNjEwMTAxNzQ0NDJaFw0y\n'+'MDAzMDUxNzQ0NDJaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n'+'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n'+'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEgMB4GA1UEAwwXQW1hem9uIFJE\n'+'UyBldS13ZXN0LTIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDO\n'+'cttLJfubB4XMMIGWNfJISkIdCMGJyOzLiMJaiWB5GYoXKhEl7YGotpy0qklwW3BQ\n'+'a0fmVdcCLX+dIuVQ9iFK+ZcK7zwm7HtdDTCHOCKeOh2IcnU4c/VIokFi6Gn8udM6\n'+'N/Zi5M5OGpVwLVALQU7Yctsn3c95el6MdVx6mJiIPVu7tCVZn88Z2koBQ2gq9P4O\n'+'Sb249SHFqOb03lYDsaqy1NDsznEOhaRBw7DPJFpvmw1lA3/Y6qrExRI06H2VYR2i\n'+'7qxwDV50N58fs10n7Ye1IOxTVJsgEA7X6EkRRXqYaM39Z76R894548WHfwXWjUsi\n'+'MEX0RS0/t1GmnUQjvevDAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMB\n'+'Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBQBxmcuRSxERYCtNnSr5xNfySokHjAfBgNV\n'+'HSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQsFAAOCAQEA\n'+'UyCUQjsF3nUAABjfEZmpksTuUo07aT3KGYt+EMMFdejnBQ0+2lJJFGtT+CDAk1SD\n'+'RSgfEBon5vvKEtlnTf9a3pv8WXOAkhfxnryr9FH6NiB8obISHNQNPHn0ljT2/T+I\n'+'Y6ytfRvKHa0cu3V0NXbJm2B4KEOt4QCDiFxUIX9z6eB4Kditwu05OgQh6KcogOiP\n'+'JesWxBMXXGoDC1rIYTFO7szwDyOHlCcVXJDNsTJhc32oDWYdeIbW7o/5I+aQsrXZ\n'+'C96HykZcgWzz6sElrQxUaT3IoMw/5nmw4uWKKnZnxgI9bY4fpQwMeBZ96iHfFxvH\n'+'mqfEEuC7uUoPofXdBp2ObQ==\n'+'-----END CERTIFICATE-----\n']}; - -/***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { - -var Parser=__webpack_require__(36);var Sequences=__webpack_require__(41);var Packets=__webpack_require__(2);var Timers=__webpack_require__(78);var Stream=__webpack_require__(13).Stream;var Util=__webpack_require__(0);var PacketWriter=__webpack_require__(79);module.exports=Protocol;Util.inherits(Protocol,Stream);function Protocol(options){Stream.call(this);options=options||{};this.readable=true;this.writable=true;this._config=options.config||{};this._connection=options.connection;this._callback=null;this._fatalError=null;this._quitSequence=null;this._handshake=false;this._handshaked=false;this._ended=false;this._destroyed=false;this._queue=[];this._handshakeInitializationPacket=null;this._parser=new Parser({onError:this.handleParserError.bind(this),onPacket:this._parsePacket.bind(this),config:this._config});}Protocol.prototype.write=function(buffer){this._parser.write(buffer);return true;};Protocol.prototype.handshake=function handshake(options,callback){if(typeof options==='function'){callback=options;options={};}options=options||{};options.config=this._config;var sequence=this._enqueue(new Sequences.Handshake(options,callback));this._handshake=true;return sequence;};Protocol.prototype.query=function query(options,callback){return this._enqueue(new Sequences.Query(options,callback));};Protocol.prototype.changeUser=function changeUser(options,callback){return this._enqueue(new Sequences.ChangeUser(options,callback));};Protocol.prototype.ping=function ping(options,callback){if(typeof options==='function'){callback=options;options={};}return this._enqueue(new Sequences.Ping(options,callback));};Protocol.prototype.stats=function stats(options,callback){if(typeof options==='function'){callback=options;options={};}return this._enqueue(new Sequences.Statistics(options,callback));};Protocol.prototype.quit=function quit(options,callback){if(typeof options==='function'){callback=options;options={};}var self=this;var sequence=this._enqueue(new Sequences.Quit(options,callback));sequence.on('end',function(){self.end();});return this._quitSequence=sequence;};Protocol.prototype.end=function(){if(this._ended){return;}this._ended=true;if(this._quitSequence&&(this._quitSequence._ended||this._queue[0]===this._quitSequence)){this._quitSequence.end();this.emit('end');return;}var err=new Error('Connection lost: The server closed the connection.');err.fatal=true;err.code='PROTOCOL_CONNECTION_LOST';this._delegateError(err);};Protocol.prototype.pause=function(){this._parser.pause();var seq=this._queue[0];if(seq&&seq.emit){seq.emit('pause');}};Protocol.prototype.resume=function(){this._parser.resume();var seq=this._queue[0];if(seq&&seq.emit){seq.emit('resume');}};Protocol.prototype._enqueue=function(sequence){if(!this._validateEnqueue(sequence)){return sequence;}if(this._config.trace){sequence._callSite=sequence._callSite||new Error();}this._queue.push(sequence);this.emit('enqueue',sequence);var self=this;sequence.on('error',function(err){self._delegateError(err,sequence);}).on('packet',function(packet){Timers.active(sequence);self._emitPacket(packet);}).on('end',function(){self._dequeue(sequence);}).on('timeout',function(){var err=new Error(sequence.constructor.name+' inactivity timeout');err.code='PROTOCOL_SEQUENCE_TIMEOUT';err.fatal=true;err.timeout=sequence._timeout;self._delegateError(err,sequence);}).on('start-tls',function(){Timers.active(sequence);self._connection._startTLS(function(err){if(err){err.code='HANDSHAKE_SSL_ERROR';err.fatal=true;sequence.end(err);return;}Timers.active(sequence);sequence._tlsUpgradeCompleteHandler();});});if(this._queue.length===1){this._parser.resetPacketNumber();this._startSequence(sequence);}return sequence;};Protocol.prototype._validateEnqueue=function _validateEnqueue(sequence){var err;var prefix='Cannot enqueue '+sequence.constructor.name;if(this._fatalError){err=new Error(prefix+' after fatal error.');err.code='PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR';}else if(this._quitSequence){err=new Error(prefix+' after invoking quit.');err.code='PROTOCOL_ENQUEUE_AFTER_QUIT';}else if(this._destroyed){err=new Error(prefix+' after being destroyed.');err.code='PROTOCOL_ENQUEUE_AFTER_DESTROY';}else if((this._handshake||this._handshaked)&&sequence.constructor===Sequences.Handshake){err=new Error(prefix+' after already enqueuing a Handshake.');err.code='PROTOCOL_ENQUEUE_HANDSHAKE_TWICE';}else{return true;}var self=this;err.fatal=false;sequence.on('error',function(err){self._delegateError(err,sequence);});process.nextTick(function(){sequence.end(err);});return false;};Protocol.prototype._parsePacket=function(){var sequence=this._queue[0];if(!sequence){var err=new Error('Received packet with no active sequence.');err.code='PROTOCOL_STRAY_PACKET';err.fatal=true;this._delegateError(err);return;}var Packet=this._determinePacket(sequence);var packet=new Packet({protocol41:this._config.protocol41});var packetName=Packet.name;if(Packet===Packets.RowDataPacket){sequence.RowDataPacket(packet,this._parser,this._connection);if(this._config.debug){this._debugPacket(true,packet);}return;}if(this._config.debug){this._parsePacketDebug(packet);}else{packet.parse(this._parser);}if(Packet===Packets.HandshakeInitializationPacket){this._handshakeInitializationPacket=packet;}Timers.active(sequence);if(!sequence[packetName]){var err=new Error('Received packet in the wrong sequence.');err.code='PROTOCOL_INCORRECT_PACKET_SEQUENCE';err.fatal=true;this._delegateError(err);return;}sequence[packetName](packet);};Protocol.prototype._parsePacketDebug=function _parsePacketDebug(packet){try{packet.parse(this._parser);}finally{this._debugPacket(true,packet);}};Protocol.prototype._emitPacket=function(packet){var packetWriter=new PacketWriter();packet.write(packetWriter);this.emit('data',packetWriter.toBuffer(this._parser));if(this._config.debug){this._debugPacket(false,packet);}};Protocol.prototype._determinePacket=function(sequence){var firstByte=this._parser.peak();if(sequence.determinePacket){var Packet=sequence.determinePacket(firstByte,this._parser);if(Packet){return Packet;}}switch(firstByte){case 0x00:if(!this._handshaked){this._handshaked=true;this.emit('handshake',this._handshakeInitializationPacket);}return Packets.OkPacket;case 0xfe:return Packets.EofPacket;case 0xff:return Packets.ErrorPacket;}throw new Error('Could not determine packet, firstByte = '+firstByte);};Protocol.prototype._dequeue=function(sequence){Timers.unenroll(sequence);if(this._fatalError){return;}this._queue.shift();var sequence=this._queue[0];if(!sequence){this.emit('drain');return;}this._parser.resetPacketNumber();this._startSequence(sequence);};Protocol.prototype._startSequence=function(sequence){if(sequence._timeout>0&&isFinite(sequence._timeout)){Timers.enroll(sequence,sequence._timeout);Timers.active(sequence);}if(sequence.constructor===Sequences.ChangeUser){sequence.start(this._handshakeInitializationPacket);}else{sequence.start();}};Protocol.prototype.handleNetworkError=function(err){err.fatal=true;var sequence=this._queue[0];if(sequence){sequence.end(err);}else{this._delegateError(err);}};Protocol.prototype.handleParserError=function handleParserError(err){var sequence=this._queue[0];if(sequence){sequence.end(err);}else{this._delegateError(err);}};Protocol.prototype._delegateError=function(err,sequence){if(this._fatalError){return;}if(err.fatal){this._fatalError=err;}if(this._shouldErrorBubbleUp(err,sequence)){this.emit('unhandledError',err);}else if(err.fatal){var queue=this._queue;process.nextTick(function(){queue.forEach(function(sequence){sequence.end(err);});queue.length=0;});}if(err.fatal){this.emit('end',err);}};Protocol.prototype._shouldErrorBubbleUp=function(err,sequence){if(sequence){if(sequence.hasErrorHandler()){return false;}else if(!err.fatal){return true;}}return err.fatal&&!this._hasPendingErrorHandlers();};Protocol.prototype._hasPendingErrorHandlers=function(){return this._queue.some(function(sequence){return sequence.hasErrorHandler();});};Protocol.prototype.destroy=function(){this._destroyed=true;this._parser.pause();if(this._connection.state!=='disconnected'){if(!this._ended){this.end();}}};Protocol.prototype._debugPacket=function(incoming,packet){var headline=incoming?'<-- ':'--> ';headline=headline+packet.constructor.name;if(Array.isArray(this._config.debug)&&this._config.debug.indexOf(packet.constructor.name)===-1){return;}console.log(headline);console.log(packet);console.log('');}; - -/***/ }), -/* 36 */ -/***/ (function(module, exports, __webpack_require__) { - -var MAX_PACKET_LENGTH=Math.pow(2,24)-1;var MUL_32BIT=Math.pow(2,32);var PacketHeader=__webpack_require__(37);var BigNumber=__webpack_require__(38);var Buffer=__webpack_require__(1).Buffer;var BufferList=__webpack_require__(40);module.exports=Parser;function Parser(options){options=options||{};this._supportBigNumbers=options.config&&options.config.supportBigNumbers;this._buffer=Buffer.alloc(0);this._nextBuffers=new BufferList();this._longPacketBuffers=new BufferList();this._offset=0;this._packetEnd=null;this._packetHeader=null;this._packetOffset=null;this._onError=options.onError||function(err){throw err;};this._onPacket=options.onPacket||function(){};this._nextPacketNumber=0;this._encoding='utf-8';this._paused=false;}Parser.prototype.write=function write(chunk){this._nextBuffers.push(chunk);while(!this._paused){if(!this._packetHeader){if(!this._combineNextBuffers(4)){break;}this._packetHeader=new PacketHeader(this.parseUnsignedNumber(3),this.parseUnsignedNumber(1));if(this._packetHeader.number!==this._nextPacketNumber){var err=new Error('Packets out of order. Got: '+this._packetHeader.number+' '+'Expected: '+this._nextPacketNumber);err.code='PROTOCOL_PACKETS_OUT_OF_ORDER';err.fatal=true;this._onError(err);}this.incrementPacketNumber();}if(!this._combineNextBuffers(this._packetHeader.length)){break;}this._packetEnd=this._offset+this._packetHeader.length;this._packetOffset=this._offset;if(this._packetHeader.length===MAX_PACKET_LENGTH){this._longPacketBuffers.push(this._buffer.slice(this._packetOffset,this._packetEnd));this._advanceToNextPacket();continue;}this._combineLongPacketBuffers();var hadException=true;try{this._onPacket(this._packetHeader);hadException=false;}catch(err){if(!err||typeof err.code!=='string'||err.code.substr(0,7)!=='PARSER_'){throw err;}this._onError(err);hadException=false;}finally{this._advanceToNextPacket();if(hadException){process.nextTick(this.write.bind(this));}}}};Parser.prototype.append=function append(chunk){if(!chunk||chunk.length===0){return;}var sliceEnd=this._buffer.length;var sliceStart=this._packetOffset===null?this._offset:this._packetOffset;var sliceLength=sliceEnd-sliceStart;var buffer=null;var chunks=!(chunk instanceof Array||Array.isArray(chunk))?[chunk]:chunk;var length=0;var offset=0;for(var i=0;i1){buffer=Buffer.allocUnsafe(length);offset=0;for(var i=0;i4){var err=new Error('parseUnsignedNumber: Supports only up to 4 bytes');err.offset=this._offset-this._packetOffset-1;err.code='PARSER_UNSIGNED_TOO_LONG';throw err;}while(offset>=this._offset){value=(value<<8|buffer[offset])>>>0;offset--;}this._offset+=bytes;return value;};Parser.prototype.parseLengthCodedString=function(){var length=this.parseLengthCodedNumber();if(length===null){return null;}return this.parseString(length);};Parser.prototype.parseLengthCodedBuffer=function(){var length=this.parseLengthCodedNumber();if(length===null){return null;}return this.parseBuffer(length);};Parser.prototype.parseLengthCodedNumber=function parseLengthCodedNumber(){if(this._offset>=this._buffer.length){var err=new Error('Parser: read past end');err.offset=this._offset-this._packetOffset;err.code='PARSER_READ_PAST_END';throw err;}var bits=this._buffer[this._offset++];if(bits<=250){return bits;}switch(bits){case 251:return null;case 252:return this.parseUnsignedNumber(2);case 253:return this.parseUnsignedNumber(3);case 254:break;default:var err=new Error('Unexpected first byte'+(bits?': 0x'+bits.toString(16):''));err.offset=this._offset-this._packetOffset-1;err.code='PARSER_BAD_LENGTH_BYTE';throw err;}var low=this.parseUnsignedNumber(4);var high=this.parseUnsignedNumber(4);var value;if(high>>>21){value=new BigNumber(low).plus(new BigNumber(MUL_32BIT).times(high)).toString();if(this._supportBigNumbers){return value;}var err=new Error('parseLengthCodedNumber: JS precision range exceeded, '+'number is >= 53 bit: "'+value+'"');err.offset=this._offset-this._packetOffset-8;err.code='PARSER_JS_PRECISION_RANGE_EXCEEDED';throw err;}value=low+MUL_32BIT*high;return value;};Parser.prototype.parseFiller=function(length){return this.parseBuffer(length);};Parser.prototype.parseNullTerminatedBuffer=function(){var end=this._nullByteOffset();var value=this._buffer.slice(this._offset,end);this._offset=end+1;return value;};Parser.prototype.parseNullTerminatedString=function(){var end=this._nullByteOffset();var value=this._buffer.toString(this._encoding,this._offset,end);this._offset=end+1;return value;};Parser.prototype._nullByteOffset=function(){var offset=this._offset;while(this._buffer[offset]!==0x00){offset++;if(offset>=this._buffer.length){var err=new Error('Offset of null terminated string not found.');err.offset=this._offset-this._packetOffset;err.code='PARSER_MISSING_NULL_BYTE';throw err;}}return offset;};Parser.prototype.parsePacketTerminatedBuffer=function parsePacketTerminatedBuffer(){var length=this._packetEnd-this._offset;return this.parseBuffer(length);};Parser.prototype.parsePacketTerminatedString=function(){var length=this._packetEnd-this._offset;return this.parseString(length);};Parser.prototype.parseBuffer=function(length){var response=Buffer.alloc(length);this._buffer.copy(response,0,this._offset,this._offset+length);this._offset+=length;return response;};Parser.prototype.parseString=function(length){var offset=this._offset;var end=offset+length;var value=this._buffer.toString(this._encoding,offset,end);this._offset=end;return value;};Parser.prototype.parseGeometryValue=function(){var buffer=this.parseLengthCodedBuffer();var offset=4;if(buffer===null||!buffer.length){return null;}function parseGeometry(){var result=null;var byteOrder=buffer.readUInt8(offset);offset+=1;var wkbType=byteOrder?buffer.readUInt32LE(offset):buffer.readUInt32BE(offset);offset+=4;switch(wkbType){case 1:var x=byteOrder?buffer.readDoubleLE(offset):buffer.readDoubleBE(offset);offset+=8;var y=byteOrder?buffer.readDoubleLE(offset):buffer.readDoubleBE(offset);offset+=8;result={x:x,y:y};break;case 2:var numPoints=byteOrder?buffer.readUInt32LE(offset):buffer.readUInt32BE(offset);offset+=4;result=[];for(var i=numPoints;i>0;i--){var x=byteOrder?buffer.readDoubleLE(offset):buffer.readDoubleBE(offset);offset+=8;var y=byteOrder?buffer.readDoubleLE(offset):buffer.readDoubleBE(offset);offset+=8;result.push({x:x,y:y});}break;case 3:var numRings=byteOrder?buffer.readUInt32LE(offset):buffer.readUInt32BE(offset);offset+=4;result=[];for(var i=numRings;i>0;i--){var numPoints=byteOrder?buffer.readUInt32LE(offset):buffer.readUInt32BE(offset);offset+=4;var line=[];for(var j=numPoints;j>0;j--){var x=byteOrder?buffer.readDoubleLE(offset):buffer.readDoubleBE(offset);offset+=8;var y=byteOrder?buffer.readDoubleLE(offset):buffer.readDoubleBE(offset);offset+=8;line.push({x:x,y:y});}result.push(line);}break;case 4:case 5:case 6:case 7:var num=byteOrder?buffer.readUInt32LE(offset):buffer.readUInt32BE(offset);offset+=4;var result=[];for(var i=num;i>0;i--){result.push(parseGeometry());}break;}return result;}return parseGeometry();};Parser.prototype.reachedPacketEnd=function(){return this._offset===this._packetEnd;};Parser.prototype.incrementPacketNumber=function(){var currentPacketNumber=this._nextPacketNumber;this._nextPacketNumber=(this._nextPacketNumber+1)%256;return currentPacketNumber;};Parser.prototype.resetPacketNumber=function(){this._nextPacketNumber=0;};Parser.prototype.packetLength=function packetLength(){if(!this._packetHeader){return null;}return this._packetHeader.length+this._longPacketBuffers.size;};Parser.prototype._combineNextBuffers=function _combineNextBuffers(bytes){var length=this._buffer.length-this._offset;if(length>=bytes){return true;}if(length+this._nextBuffers.size0){var buffer=this._nextBuffers.shift();buffers.push(buffer);bytesNeeded-=buffer.length;}this.append(buffers);return true;};Parser.prototype._combineLongPacketBuffers=function _combineLongPacketBuffers(){if(!this._longPacketBuffers.size){return;}var remainingBytes=this._buffer.length-this._offset;var trailingPacketBytes=this._buffer.length-this._packetEnd;var buf=null;var buffer=Buffer.allocUnsafe(remainingBytes+this._longPacketBuffers.size);var offset=0;while(buf=this._longPacketBuffers.shift()){offset+=buf.copy(buffer,offset);}this._buffer.copy(buffer,offset,this._offset);this._buffer=buffer;this._offset=0;this._packetEnd=this._buffer.length-trailingPacketBytes;this._packetOffset=0;};Parser.prototype._advanceToNextPacket=function(){this._offset=this._packetEnd;this._packetHeader=null;this._packetEnd=null;this._packetOffset=null;}; - -/***/ }), -/* 37 */ -/***/ (function(module, exports) { - -module.exports=PacketHeader;function PacketHeader(length,number){this.length=length;this.number=number;} - -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { - -var __WEBPACK_AMD_DEFINE_RESULT__;;(function(globalObj){'use strict';var BigNumber,isNumeric=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,mathceil=Math.ceil,mathfloor=Math.floor,notBool=' not a boolean or binary digit',roundingMode='rounding mode',tooManyDigits='number type has more than 15 significant digits',ALPHABET='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_',BASE=1e14,LOG_BASE=14,MAX_SAFE_INTEGER=0x1fffffffffffff,POWS_TEN=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],SQRT_BASE=1e7,MAX=1E9;function constructorFactory(config){var div,parseNumeric,id=0,P=BigNumber.prototype,ONE=new BigNumber(1),DECIMAL_PLACES=20,ROUNDING_MODE=4,TO_EXP_NEG=-7,TO_EXP_POS=21,MIN_EXP=-1e7,MAX_EXP=1e7,ERRORS=true,isValidInt=intValidatorWithErrors,CRYPTO=false,MODULO_MODE=1,POW_PRECISION=0,FORMAT={decimalSeparator:'.',groupSeparator:',',groupSize:3,secondaryGroupSize:0,fractionGroupSeparator:'\xA0',fractionGroupSize:0};function BigNumber(n,b){var c,e,i,num,len,str,x=this;if(!(x instanceof BigNumber)){if(ERRORS)raise(26,'constructor call without new',n);return new BigNumber(n,b);}if(b==null||!isValidInt(b,2,64,id,'base')){if(n instanceof BigNumber){x.s=n.s;x.e=n.e;x.c=(n=n.c)?n.slice():n;id=0;return;}if((num=typeof n=='number')&&n*0==0){x.s=1/n<0?(n=-n,-1):1;if(n===~~n){for(e=0,i=n;i>=10;i/=10,e++);x.e=e;x.c=[n];id=0;return;}str=n+'';}else{if(!isNumeric.test(str=n+''))return parseNumeric(x,str,num);x.s=str.charCodeAt(0)===45?(str=str.slice(1),-1):1;}}else{b=b|0;str=n+'';if(b==10){x=new BigNumber(n instanceof BigNumber?n:str);return round(x,DECIMAL_PLACES+x.e+1,ROUNDING_MODE);}if((num=typeof n=='number')&&n*0!=0||!new RegExp('^-?'+(c='['+ALPHABET.slice(0,b)+']+')+'(?:\\.'+c+')?$',b<37?'i':'').test(str)){return parseNumeric(x,str,num,b);}if(num){x.s=1/n<0?(str=str.slice(1),-1):1;if(ERRORS&&str.replace(/^0\.0*|\./,'').length>15){raise(id,tooManyDigits,n);}num=false;}else{x.s=str.charCodeAt(0)===45?(str=str.slice(1),-1):1;}str=convertBase(str,10,b,x.s);}if((e=str.indexOf('.'))>-1)str=str.replace('.','');if((i=str.search(/e/i))>0){if(e<0)e=i;e+=+str.slice(i+1);str=str.substring(0,i);}else if(e<0){e=str.length;}for(i=0;str.charCodeAt(i)===48;i++);for(len=str.length;str.charCodeAt(--len)===48;);str=str.slice(i,len+1);if(str){len=str.length;if(num&&ERRORS&&len>15&&(n>MAX_SAFE_INTEGER||n!==mathfloor(n))){raise(id,tooManyDigits,x.s*n);}e=e-i-1;if(e>MAX_EXP){x.c=x.e=null;}else if(ei)return(v=a[i++])!=null;};if(has(p='DECIMAL_PLACES')&&isValidInt(v,0,MAX,2,p)){DECIMAL_PLACES=v|0;}r[p]=DECIMAL_PLACES;if(has(p='ROUNDING_MODE')&&isValidInt(v,0,8,2,p)){ROUNDING_MODE=v|0;}r[p]=ROUNDING_MODE;if(has(p='EXPONENTIAL_AT')){if(isArray(v)){if(isValidInt(v[0],-MAX,0,2,p)&&isValidInt(v[1],0,MAX,2,p)){TO_EXP_NEG=v[0]|0;TO_EXP_POS=v[1]|0;}}else if(isValidInt(v,-MAX,MAX,2,p)){TO_EXP_NEG=-(TO_EXP_POS=(v<0?-v:v)|0);}}r[p]=[TO_EXP_NEG,TO_EXP_POS];if(has(p='RANGE')){if(isArray(v)){if(isValidInt(v[0],-MAX,-1,2,p)&&isValidInt(v[1],1,MAX,2,p)){MIN_EXP=v[0]|0;MAX_EXP=v[1]|0;}}else if(isValidInt(v,-MAX,MAX,2,p)){if(v|0)MIN_EXP=-(MAX_EXP=(v<0?-v:v)|0);else if(ERRORS)raise(2,p+' cannot be zero',v);}}r[p]=[MIN_EXP,MAX_EXP];if(has(p='ERRORS')){if(v===!!v||v===1||v===0){id=0;isValidInt=(ERRORS=!!v)?intValidatorWithErrors:intValidatorNoErrors;}else if(ERRORS){raise(2,p+notBool,v);}}r[p]=ERRORS;if(has(p='CRYPTO')){if(v===true||v===false||v===1||v===0){if(v){v=typeof crypto=='undefined';if(!v&&crypto&&(crypto.getRandomValues||crypto.randomBytes)){CRYPTO=true;}else if(ERRORS){raise(2,'crypto unavailable',v?void 0:crypto);}else{CRYPTO=false;}}else{CRYPTO=false;}}else if(ERRORS){raise(2,p+notBool,v);}}r[p]=CRYPTO;if(has(p='MODULO_MODE')&&isValidInt(v,0,9,2,p)){MODULO_MODE=v|0;}r[p]=MODULO_MODE;if(has(p='POW_PRECISION')&&isValidInt(v,0,MAX,2,p)){POW_PRECISION=v|0;}r[p]=POW_PRECISION;if(has(p='FORMAT')){if(typeof v=='object'){FORMAT=v;}else if(ERRORS){raise(2,p+' not an object',v);}}r[p]=FORMAT;return r;};BigNumber.max=function(){return maxOrMin(arguments,P.lt);};BigNumber.min=function(){return maxOrMin(arguments,P.gt);};BigNumber.random=function(){var pow2_53=0x20000000000000;var random53bitInt=Math.random()*pow2_53&0x1fffff?function(){return mathfloor(Math.random()*pow2_53);}:function(){return(Math.random()*0x40000000|0)*0x800000+(Math.random()*0x800000|0);};return function(dp){var a,b,e,k,v,i=0,c=[],rand=new BigNumber(ONE);dp=dp==null||!isValidInt(dp,0,MAX,14)?DECIMAL_PLACES:dp|0;k=mathceil(dp/LOG_BASE);if(CRYPTO){if(crypto.getRandomValues){a=crypto.getRandomValues(new Uint32Array(k*=2));for(;i>>11);if(v>=9e15){b=crypto.getRandomValues(new Uint32Array(2));a[i]=b[0];a[i+1]=b[1];}else{c.push(v%1e14);i+=2;}}i=k/2;}else if(crypto.randomBytes){a=crypto.randomBytes(k*=7);for(;i=9e15){crypto.randomBytes(7).copy(a,i);}else{c.push(v%1e14);i+=7;}}i=k/7;}else{CRYPTO=false;if(ERRORS)raise(14,'crypto unavailable',crypto);}}if(!CRYPTO){for(;i=10;v/=10,i++);if(i=0){k=POW_PRECISION;POW_PRECISION=0;str=str.replace('.','');y=new BigNumber(baseIn);x=y.pow(str.length-i);POW_PRECISION=k;y.c=toBaseOut(toFixedPoint(coeffToString(x.c),x.e),10,baseOut);y.e=y.c.length;}xc=toBaseOut(str,baseIn,baseOut);e=k=xc.length;for(;xc[--k]==0;xc.pop());if(!xc[0])return'0';if(i<0){--e;}else{x.c=xc;x.e=e;x.s=sign;x=div(x,y,dp,rm,baseOut);xc=x.c;r=x.r;e=x.e;}d=e+dp+1;i=xc[d];k=baseOut/2;r=r||d<0||xc[d+1]!=null;r=rm<4?(i!=null||r)&&(rm==0||rm==(x.s<0?3:2)):i>k||i==k&&(rm==4||r||rm==6&&xc[d-1]&1||rm==(x.s<0?8:7));if(d<1||!xc[0]){str=r?toFixedPoint('1',-dp):'0';}else{xc.length=d;if(r){for(--baseOut;++xc[--d]>baseOut;){xc[d]=0;if(!d){++e;xc=[1].concat(xc);}}}for(k=xc.length;!xc[--k];);for(i=0,str='';i<=k;str+=ALPHABET.charAt(xc[i++]));str=toFixedPoint(str,e);}return str;}div=function(){function multiply(x,k,base){var m,temp,xlo,xhi,carry=0,i=x.length,klo=k%SQRT_BASE,khi=k/SQRT_BASE|0;for(x=x.slice();i--;){xlo=x[i]%SQRT_BASE;xhi=x[i]/SQRT_BASE|0;m=khi*xlo+xhi*klo;temp=klo*xlo+m%SQRT_BASE*SQRT_BASE+carry;carry=(temp/base|0)+(m/SQRT_BASE|0)+khi*xhi;x[i]=temp%base;}if(carry)x=[carry].concat(x);return x;}function compare(a,b,aL,bL){var i,cmp;if(aL!=bL){cmp=aL>bL?1:-1;}else{for(i=cmp=0;ib[i]?1:-1;break;}}}return cmp;}function subtract(a,b,aL,base){var i=0;for(;aL--;){a[aL]-=i;i=a[aL]1;a.splice(0,1));}return function(x,y,dp,rm,base){var cmp,e,i,more,n,prod,prodL,q,qc,rem,remL,rem0,xi,xL,yc0,yL,yz,s=x.s==y.s?1:-1,xc=x.c,yc=y.c;if(!xc||!xc[0]||!yc||!yc[0]){return new BigNumber(!x.s||!y.s||(xc?yc&&xc[0]==yc[0]:!yc)?NaN:xc&&xc[0]==0||!yc?s*0:s/0);}q=new BigNumber(s);qc=q.c=[];e=x.e-y.e;s=dp+e+1;if(!base){base=BASE;e=bitFloor(x.e/LOG_BASE)-bitFloor(y.e/LOG_BASE);s=s/LOG_BASE|0;}for(i=0;yc[i]==(xc[i]||0);i++);if(yc[i]>(xc[i]||0))e--;if(s<0){qc.push(1);more=true;}else{xL=xc.length;yL=yc.length;i=0;s+=2;n=mathfloor(base/(yc[0]+1));if(n>1){yc=multiply(yc,n,base);xc=multiply(xc,n,base);yL=yc.length;xL=xc.length;}xi=yL;rem=xc.slice(0,yL);remL=rem.length;for(;remL=base/2)yc0++;do{n=0;cmp=compare(yc,rem,yL,remL);if(cmp<0){rem0=rem[0];if(yL!=remL)rem0=rem0*base+(rem[1]||0);n=mathfloor(rem0/yc0);if(n>1){if(n>=base)n=base-1;prod=multiply(yc,n,base);prodL=prod.length;remL=rem.length;while(compare(prod,rem,prodL,remL)==1){n--;subtract(prod,yL=10;s/=10,i++);round(q,dp+(q.e=i+e*LOG_BASE-1)+1,rm,more);}else{q.e=e;q.r=+more;}return q;};}();function format(n,i,rm,caller){var c0,e,ne,len,str;rm=rm!=null&&isValidInt(rm,0,8,caller,roundingMode)?rm|0:ROUNDING_MODE;if(!n.c)return n.toString();c0=n.c[0];ne=n.e;if(i==null){str=coeffToString(n.c);str=caller==19||caller==24&&ne<=TO_EXP_NEG?toExponential(str,ne):toFixedPoint(str,ne);}else{n=round(new BigNumber(n),i,rm);e=n.e;str=coeffToString(n.c);len=str.length;if(caller==19||caller==24&&(i<=e||e<=TO_EXP_NEG)){for(;lenlen){if(--i>0)for(str+='.';i--;str+='0');}else{i+=e-len;if(i>0){if(e+1==len)str+='.';for(;i--;str+='0');}}}}return n.s<0&&c0?'-'+str:str;}function maxOrMin(args,method){var m,n,i=0;if(isArray(args[0]))args=args[0];m=new BigNumber(args[0]);for(;++imax||n!=truncate(n)){raise(caller,(name||'decimal places')+(nmax?' out of range':' not an integer'),n);}return true;}function normalise(n,c,e){var i=1,j=c.length;for(;!c[--j];c.pop());for(j=c[0];j>=10;j/=10,i++);if((e=i+e*LOG_BASE-1)>MAX_EXP){n.c=n.e=null;}else if(e=10;k/=10,d++);i=sd-d;if(i<0){i+=LOG_BASE;j=sd;n=xc[ni=0];rd=n/pows10[d-j-1]%10|0;}else{ni=mathceil((i+1)/LOG_BASE);if(ni>=xc.length){if(r){for(;xc.length<=ni;xc.push(0));n=rd=0;d=1;i%=LOG_BASE;j=i-LOG_BASE+1;}else{break out;}}else{n=k=xc[ni];for(d=1;k>=10;k/=10,d++);i%=LOG_BASE;j=i-LOG_BASE+d;rd=j<0?0:n/pows10[d-j-1]%10|0;}}r=r||sd<0||xc[ni+1]!=null||(j<0?n:n%pows10[d-j-1]);r=rm<4?(rd||r)&&(rm==0||rm==(x.s<0?3:2)):rd>5||rd==5&&(rm==4||r||rm==6&&(i>0?j>0?n/pows10[d-j]:0:xc[ni-1])%10&1||rm==(x.s<0?8:7));if(sd<1||!xc[0]){xc.length=0;if(r){sd-=x.e+1;xc[0]=pows10[(LOG_BASE-sd%LOG_BASE)%LOG_BASE];x.e=-sd||0;}else{xc[0]=x.e=0;}return x;}if(i==0){xc.length=ni;k=1;ni--;}else{xc.length=ni+1;k=pows10[LOG_BASE-i];xc[ni]=j>0?mathfloor(n/pows10[d-j]%pows10[j])*k:0;}if(r){for(;;){if(ni==0){for(i=1,j=xc[0];j>=10;j/=10,i++);j=xc[0]+=k;for(k=1;j>=10;j/=10,k++);if(i!=k){x.e++;if(xc[0]==BASE)xc[0]=1;}break;}else{xc[ni]+=k;if(xc[ni]!=BASE)break;xc[ni--]=0;k=1;}}}for(i=xc.length;xc[--i]===0;xc.pop());}if(x.e>MAX_EXP){x.c=x.e=null;}else if(x.e0;};P.greaterThanOrEqualTo=P.gte=function(y,b){id=7;return(b=compare(this,new BigNumber(y,b)))===1||b===0;};P.isFinite=function(){return!!this.c;};P.isInteger=P.isInt=function(){return!!this.c&&bitFloor(this.e/LOG_BASE)>this.c.length-2;};P.isNaN=function(){return!this.s;};P.isNegative=P.isNeg=function(){return this.s<0;};P.isZero=function(){return!!this.c&&this.c[0]==0;};P.lessThan=P.lt=function(y,b){id=8;return compare(this,new BigNumber(y,b))<0;};P.lessThanOrEqualTo=P.lte=function(y,b){id=9;return(b=compare(this,new BigNumber(y,b)))===-1||b===0;};P.minus=P.sub=function(y,b){var i,j,t,xLTy,x=this,a=x.s;id=10;y=new BigNumber(y,b);b=y.s;if(!a||!b)return new BigNumber(NaN);if(a!=b){y.s=-b;return x.plus(y);}var xe=x.e/LOG_BASE,ye=y.e/LOG_BASE,xc=x.c,yc=y.c;if(!xe||!ye){if(!xc||!yc)return xc?(y.s=-b,y):new BigNumber(yc?x:NaN);if(!xc[0]||!yc[0]){return yc[0]?(y.s=-b,y):new BigNumber(xc[0]?x:ROUNDING_MODE==3?-0:0);}}xe=bitFloor(xe);ye=bitFloor(ye);xc=xc.slice();if(a=xe-ye){if(xLTy=a<0){a=-a;t=xc;}else{ye=xe;t=yc;}t.reverse();for(b=a;b--;t.push(0));t.reverse();}else{j=(xLTy=(a=xc.length)<(b=yc.length))?a:b;for(a=b=0;b0)for(;b--;xc[i++]=0);b=BASE-1;for(;j>a;){if(xc[--j]0){ye=xe;t=yc;}else{a=-a;t=xc;}t.reverse();for(;a--;t.push(0));t.reverse();}a=xc.length;b=yc.length;if(a-b<0)t=yc,yc=xc,xc=t,b=a;for(a=0;b;){a=(xc[--b]=xc[b]+yc[b]+a)/BASE|0;xc[b]=BASE===xc[b]?0:xc[b]%BASE;}if(a){xc=[a].concat(xc);++ye;}return normalise(y,xc,ye);};P.precision=P.sd=function(z){var n,v,x=this,c=x.c;if(z!=null&&z!==!!z&&z!==1&&z!==0){if(ERRORS)raise(13,'argument'+notBool,z);if(z!=!!z)z=null;}if(!c)return null;v=c.length-1;n=v*LOG_BASE+1;if(v=c[v]){for(;v%10==0;v/=10,n--);for(v=c[0];v>=10;v/=10,n++);}if(z&&x.e+1>n)n=x.e+1;return n;};P.round=function(dp,rm){var n=new BigNumber(this);if(dp==null||isValidInt(dp,0,MAX,15)){round(n,~~dp+this.e+1,rm==null||!isValidInt(rm,0,8,15,roundingMode)?ROUNDING_MODE:rm|0);}return n;};P.shift=function(k){var n=this;return isValidInt(k,-MAX_SAFE_INTEGER,MAX_SAFE_INTEGER,16,'argument')?n.times('1e'+truncate(k)):new BigNumber(n.c&&n.c[0]&&(k<-MAX_SAFE_INTEGER||k>MAX_SAFE_INTEGER)?n.s*(k<0?0:1/0):n);};P.squareRoot=P.sqrt=function(){var m,n,r,rep,t,x=this,c=x.c,s=x.s,e=x.e,dp=DECIMAL_PLACES+4,half=new BigNumber('0.5');if(s!==1||!c||!c[0]){return new BigNumber(!s||s<0&&(!c||c[0])?NaN:c?x:1/0);}s=Math.sqrt(+x);if(s==0||s==1/0){n=coeffToString(c);if((n.length+e)%2==0)n+='0';s=Math.sqrt(n);e=bitFloor((e+1)/2)-(e<0||e%2);if(s==1/0){n='1e'+e;}else{n=s.toExponential();n=n.slice(0,n.indexOf('e')+1)+e;}r=new BigNumber(n);}else{r=new BigNumber(s+'');}if(r.c[0]){e=r.e;s=e+dp;if(s<3)s=0;for(;;){t=r;r=half.times(t.plus(div(x,t,dp,1)));if(coeffToString(t.c).slice(0,s)===(n=coeffToString(r.c)).slice(0,s)){if(r.e=0;){c=0;ylo=yc[i]%sqrtBase;yhi=yc[i]/sqrtBase|0;for(k=xcL,j=i+k;j>i;){xlo=xc[--k]%sqrtBase;xhi=xc[k]/sqrtBase|0;m=yhi*xlo+xhi*ylo;xlo=ylo*xlo+m%sqrtBase*sqrtBase+zc[j]+c;c=(xlo/base|0)+(m/sqrtBase|0)+yhi*xhi;zc[j--]=xlo%base;}zc[j]=c;}if(c){++e;}else{zc.splice(0,1);}return normalise(y,zc,e);};P.toDigits=function(sd,rm){var n=new BigNumber(this);sd=sd==null||!isValidInt(sd,1,MAX,18,'precision')?null:sd|0;rm=rm==null||!isValidInt(rm,0,8,18,roundingMode)?ROUNDING_MODE:rm|0;return sd?round(n,sd,rm):n;};P.toExponential=function(dp,rm){return format(this,dp!=null&&isValidInt(dp,0,MAX,19)?~~dp+1:null,rm,19);};P.toFixed=function(dp,rm){return format(this,dp!=null&&isValidInt(dp,0,MAX,20)?~~dp+this.e+1:null,rm,20);};P.toFormat=function(dp,rm){var str=format(this,dp!=null&&isValidInt(dp,0,MAX,21)?~~dp+this.e+1:null,rm,21);if(this.c){var i,arr=str.split('.'),g1=+FORMAT.groupSize,g2=+FORMAT.secondaryGroupSize,groupSeparator=FORMAT.groupSeparator,intPart=arr[0],fractionPart=arr[1],isNeg=this.s<0,intDigits=isNeg?intPart.slice(1):intPart,len=intDigits.length;if(g2)i=g1,g1=g2,g2=i,len-=i;if(g1>0&&len>0){i=len%g1||g1;intPart=intDigits.substr(0,i);for(;i0)intPart+=groupSeparator+intDigits.slice(i);if(isNeg)intPart='-'+intPart;}str=fractionPart?intPart+FORMAT.decimalSeparator+((g2=+FORMAT.fractionGroupSize)?fractionPart.replace(new RegExp('\\d{'+g2+'}\\B','g'),'$&'+FORMAT.fractionGroupSeparator):fractionPart):intPart;}return str;};P.toFraction=function(md){var arr,d0,d2,e,exp,n,n0,q,s,k=ERRORS,x=this,xc=x.c,d=new BigNumber(ONE),n1=d0=new BigNumber(ONE),d1=n0=new BigNumber(ONE);if(md!=null){ERRORS=false;n=new BigNumber(md);ERRORS=k;if(!(k=n.isInt())||n.lt(ONE)){if(ERRORS){raise(22,'max denominator '+(k?'out of range':'not an integer'),md);}md=!k&&n.c&&round(n,n.e+1,1).gte(ONE)?n:null;}}if(!xc)return x.toString();s=coeffToString(xc);e=d.e=s.length-x.e-1;d.c[0]=POWS_TEN[(exp=e%LOG_BASE)<0?LOG_BASE+exp:exp];md=!md||n.cmp(d)>0?e>0?d:n1:n;exp=MAX_EXP;MAX_EXP=1/0;n=new BigNumber(s);n0.c[0]=0;for(;;){q=div(n,d,0,1);d2=d0.plus(q.times(d1));if(d2.cmp(md)==1)break;d0=d1;d1=d2;n1=n0.plus(q.times(d2=n1));n0=d2;d=n.minus(q.times(d2=d));n=d2;}d2=div(md.minus(d0),d1,0,1);n0=n0.plus(d2.times(n1));d0=d0.plus(d2.times(d1));n0.s=n1.s=x.s;e*=2;arr=div(n1,d1,e,ROUNDING_MODE).minus(x).abs().cmp(div(n0,d0,e,ROUNDING_MODE).minus(x).abs())<1?[n1.toString(),d1.toString()]:[n0.toString(),d0.toString()];MAX_EXP=exp;return arr;};P.toNumber=function(){return+this;};P.toPower=P.pow=function(n,m){var k,y,z,i=mathfloor(n<0?-n:+n),x=this;if(m!=null){id=23;m=new BigNumber(m);}if(!isValidInt(n,-MAX_SAFE_INTEGER,MAX_SAFE_INTEGER,23,'exponent')&&(!isFinite(n)||i>MAX_SAFE_INTEGER&&(n/=0)||parseFloat(n)!=n&&!(n=NaN))||n==0){k=Math.pow(+x,n);return new BigNumber(m?k%m:k);}if(m){if(n>1&&x.gt(ONE)&&x.isInt()&&m.gt(ONE)&&m.isInt()){x=x.mod(m);}else{z=m;m=null;}}else if(POW_PRECISION){k=mathceil(POW_PRECISION/LOG_BASE+2);}y=new BigNumber(ONE);for(;;){if(i%2){y=y.times(x);if(!y.c)break;if(k){if(y.c.length>k)y.c.length=k;}else if(m){y=y.mod(m);}}i=mathfloor(i/2);if(!i)break;x=x.times(x);if(k){if(x.c&&x.c.length>k)x.c.length=k;}else if(m){x=x.mod(m);}}if(m)return y;if(n<0)y=ONE.div(y);return z?y.mod(z):k?round(y,POW_PRECISION,ROUNDING_MODE):y;};P.toPrecision=function(sd,rm){return format(this,sd!=null&&isValidInt(sd,1,MAX,24,'precision')?sd|0:null,rm,24);};P.toString=function(b){var str,n=this,s=n.s,e=n.e;if(e===null){if(s){str='Infinity';if(s<0)str='-'+str;}else{str='NaN';}}else{str=coeffToString(n.c);if(b==null||!isValidInt(b,2,64,25,'base')){str=e<=TO_EXP_NEG||e>=TO_EXP_POS?toExponential(str,e):toFixedPoint(str,e);}else{str=convertBase(toFixedPoint(str,e),b|0,10,s);}if(s<0&&n.c[0])str='-'+str;}return str;};P.truncated=P.trunc=function(){return round(new BigNumber(this),this.e+1,1);};P.valueOf=P.toJSON=function(){var str,n=this,e=n.e;if(e===null)return n.toString();str=coeffToString(n.c);str=e<=TO_EXP_NEG||e>=TO_EXP_POS?toExponential(str,e):toFixedPoint(str,e);return n.s<0?'-'+str:str;};P.isBigNumber=true;if(config!=null)BigNumber.config(config);return BigNumber;}function bitFloor(n){var i=n|0;return n>0||n===i?i:i-1;}function coeffToString(a){var s,z,i=1,j=a.length,r=a[0]+'';for(;il^a?1:-1;j=(k=xc.length)<(l=yc.length)?k:l;for(i=0;iyc[i]^a?1:-1;return k==l?0:k>l^a?1:-1;}function intValidatorNoErrors(n,min,max){return(n=truncate(n))>=min&&n<=max;}function isArray(obj){return Object.prototype.toString.call(obj)=='[object Array]';}function toBaseOut(str,baseIn,baseOut){var j,arr=[0],arrL,i=0,len=str.length;for(;ibaseOut-1){if(arr[j+1]==null)arr[j+1]=0;arr[j+1]+=arr[j]/baseOut|0;arr[j]%=baseOut;}}}return arr.reverse();}function toExponential(str,e){return(str.length>1?str.charAt(0)+'.'+str.slice(1):str)+(e<0?'e':'e+')+e;}function toFixedPoint(str,e){var len,z;if(e<0){for(z='0.';++e;z+='0');str=z+str;}else{len=str.length;if(++e>len){for(z='0',e-=len;--e;z+='0');str+=z;}else if(e0;if(this.protocol41){this.serverCapabilities2=parser.parseUnsignedNumber(2);this.scrambleLength=parser.parseUnsignedNumber(1);this.filler2=parser.parseFiller(10);this.scrambleBuff2=parser.parseBuffer(12);this.filler3=parser.parseFiller(1);}else{this.filler2=parser.parseFiller(13);}if(parser.reachedPacketEnd()){return;}this.pluginData=parser.parsePacketTerminatedString();var lastChar=this.pluginData.length-1;if(this.pluginData[lastChar]==='\0'){this.pluginData=this.pluginData.substr(0,lastChar);}};HandshakeInitializationPacket.prototype.write=function(writer){writer.writeUnsignedNumber(1,this.protocolVersion);writer.writeNullTerminatedString(this.serverVersion);writer.writeUnsignedNumber(4,this.threadId);writer.writeBuffer(this.scrambleBuff1);writer.writeFiller(1);writer.writeUnsignedNumber(2,this.serverCapabilities1);writer.writeUnsignedNumber(1,this.serverLanguage);writer.writeUnsignedNumber(2,this.serverStatus);if(this.protocol41){writer.writeUnsignedNumber(2,this.serverCapabilities2);writer.writeUnsignedNumber(1,this.scrambleLength);writer.writeFiller(10);}writer.writeNullTerminatedBuffer(this.scrambleBuff2);if(this.pluginData!==undefined){writer.writeNullTerminatedString(this.pluginData);}};HandshakeInitializationPacket.prototype.scrambleBuff=function(){var buffer=null;if(typeof this.scrambleBuff2==='undefined'){buffer=Buffer.from(this.scrambleBuff1);}else{buffer=Buffer.allocUnsafe(this.scrambleBuff1.length+this.scrambleBuff2.length);this.scrambleBuff1.copy(buffer,0);this.scrambleBuff2.copy(buffer,this.scrambleBuff1.length);}return buffer;}; - -/***/ }), -/* 56 */ -/***/ (function(module, exports) { - -module.exports=LocalDataFilePacket;function LocalDataFilePacket(data){this.data=data;}LocalDataFilePacket.prototype.write=function(writer){writer.writeBuffer(this.data);}; - -/***/ }), -/* 57 */ -/***/ (function(module, exports) { - -var ER_UPDATE_INFO_REGEXP=/^[^:0-9]+: [0-9]+[^:0-9]+: ([0-9]+)[^:0-9]+: [0-9]+[^:0-9]*$/;module.exports=OkPacket;function OkPacket(options){options=options||{};this.fieldCount=undefined;this.affectedRows=undefined;this.insertId=undefined;this.serverStatus=undefined;this.warningCount=undefined;this.message=undefined;this.protocol41=options.protocol41;}OkPacket.prototype.parse=function(parser){this.fieldCount=parser.parseUnsignedNumber(1);this.affectedRows=parser.parseLengthCodedNumber();this.insertId=parser.parseLengthCodedNumber();if(this.protocol41){this.serverStatus=parser.parseUnsignedNumber(2);this.warningCount=parser.parseUnsignedNumber(2);}this.message=parser.parsePacketTerminatedString();this.changedRows=0;var m=ER_UPDATE_INFO_REGEXP.exec(this.message);if(m!==null){this.changedRows=parseInt(m[1],10);}};OkPacket.prototype.write=function(writer){writer.writeUnsignedNumber(1,0x00);writer.writeLengthCodedNumber(this.affectedRows||0);writer.writeLengthCodedNumber(this.insertId||0);if(this.protocol41){writer.writeUnsignedNumber(2,this.serverStatus||0);writer.writeUnsignedNumber(2,this.warningCount||0);}writer.writeString(this.message);}; - -/***/ }), -/* 58 */ -/***/ (function(module, exports) { - -module.exports=OldPasswordPacket;function OldPasswordPacket(options){options=options||{};this.scrambleBuff=options.scrambleBuff;}OldPasswordPacket.prototype.parse=function(parser){this.scrambleBuff=parser.parseNullTerminatedBuffer();};OldPasswordPacket.prototype.write=function(writer){writer.writeBuffer(this.scrambleBuff);writer.writeFiller(1);}; - -/***/ }), -/* 59 */ -/***/ (function(module, exports) { - -module.exports=ResultSetHeaderPacket;function ResultSetHeaderPacket(options){options=options||{};this.fieldCount=options.fieldCount;this.extra=options.extra;}ResultSetHeaderPacket.prototype.parse=function(parser){this.fieldCount=parser.parseLengthCodedNumber();if(parser.reachedPacketEnd())return;this.extra=this.fieldCount===null?parser.parsePacketTerminatedString():parser.parseLengthCodedNumber();};ResultSetHeaderPacket.prototype.write=function(writer){writer.writeLengthCodedNumber(this.fieldCount);if(this.extra!==undefined){writer.writeLengthCodedNumber(this.extra);}}; - -/***/ }), -/* 60 */ -/***/ (function(module, exports, __webpack_require__) { - -var Types=__webpack_require__(12);var Charsets=__webpack_require__(16);var Field=__webpack_require__(17);var IEEE_754_BINARY_64_PRECISION=Math.pow(2,53);module.exports=RowDataPacket;function RowDataPacket(){}Object.defineProperty(RowDataPacket.prototype,'parse',{configurable:true,enumerable:false,value:parse});Object.defineProperty(RowDataPacket.prototype,'_typeCast',{configurable:true,enumerable:false,value:typeCast});function parse(parser,fieldPackets,typeCast,nestTables,connection){var self=this;var next=function(){return self._typeCast(fieldPacket,parser,connection.config.timezone,connection.config.supportBigNumbers,connection.config.bigNumberStrings,connection.config.dateStrings);};for(var i=0;i=IEEE_754_BINARY_64_PRECISION||Number(numberString)<=-IEEE_754_BINARY_64_PRECISION)?numberString:Number(numberString);case Types.BIT:return parser.parseLengthCodedBuffer();case Types.STRING:case Types.VAR_STRING:case Types.TINY_BLOB:case Types.MEDIUM_BLOB:case Types.LONG_BLOB:case Types.BLOB:return field.charsetNr===Charsets.BINARY?parser.parseLengthCodedBuffer():parser.parseLengthCodedString();case Types.GEOMETRY:return parser.parseGeometryValue();default:return parser.parseLengthCodedString();}}function typeMatch(type,list){if(Array.isArray(list)){for(var i=0;i0)this.tail.next=entry;else this.head=entry;this.tail=entry;++this.length;};BufferList.prototype.unshift=function unshift(v){var entry={data:v,next:this.head};if(this.length===0)this.tail=entry;this.head=entry;++this.length;};BufferList.prototype.shift=function shift(){if(this.length===0)return;var ret=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return ret;};BufferList.prototype.clear=function clear(){this.head=this.tail=null;this.length=0;};BufferList.prototype.join=function join(s){if(this.length===0)return'';var p=this.head;var ret=''+p.data;while(p=p.next){ret+=s+p.data;}return ret;};BufferList.prototype.concat=function concat(n){if(this.length===0)return Buffer.alloc(0);if(this.length===1)return this.head.data;var ret=Buffer.allocUnsafe(n>>>0);var p=this.head;var i=0;while(p){copyBuffer(p.data,ret,i);i+=p.data.length;p=p.next;}return ret;};return BufferList;}(); - -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports=__webpack_require__(0).deprecate; - -/***/ }), -/* 75 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -module.exports=PassThrough;var Transform=__webpack_require__(25);var util=__webpack_require__(6);util.inherits=__webpack_require__(7);util.inherits(PassThrough,Transform);function PassThrough(options){if(!(this instanceof PassThrough))return new PassThrough(options);Transform.call(this,options);}PassThrough.prototype._transform=function(chunk,encoding,cb){cb(null,chunk);}; - -/***/ }), -/* 76 */ -/***/ (function(module, exports, __webpack_require__) { - -var Sequence=__webpack_require__(3);var Util=__webpack_require__(0);var Packets=__webpack_require__(2);module.exports=Quit;Util.inherits(Quit,Sequence);function Quit(options,callback){if(!callback&&typeof options==='function'){callback=options;options={};}Sequence.call(this,options,callback);this._started=false;}Quit.prototype.end=function end(err){if(this._ended){return;}if(!this._started){Sequence.prototype.end.call(this,err);return;}if(err&&err.code==='ECONNRESET'&&err.syscall==='read'){Sequence.prototype.end.call(this);return;}Sequence.prototype.end.call(this,err);};Quit.prototype.start=function(){this._started=true;this.emit('packet',new Packets.ComQuitPacket());}; - -/***/ }), -/* 77 */ -/***/ (function(module, exports, __webpack_require__) { - -var Sequence=__webpack_require__(3);var Util=__webpack_require__(0);var Packets=__webpack_require__(2);module.exports=Statistics;Util.inherits(Statistics,Sequence);function Statistics(options,callback){if(!callback&&typeof options==='function'){callback=options;options={};}Sequence.call(this,options,callback);}Statistics.prototype.start=function(){this.emit('packet',new Packets.ComStatisticsPacket());};Statistics.prototype['StatisticsPacket']=function(packet){this.end(null,packet);};Statistics.prototype.determinePacket=function determinePacket(firstByte){if(firstByte===0x55){return Packets.StatisticsPacket;}return undefined;}; - -/***/ }), -/* 78 */ -/***/ (function(module, exports) { - -module.exports = require("timers"); - -/***/ }), -/* 79 */ -/***/ (function(module, exports, __webpack_require__) { - -var BIT_16=Math.pow(2,16);var BIT_24=Math.pow(2,24);var BUFFER_ALLOC_SIZE=Math.pow(2,8);var IEEE_754_BINARY_64_PRECISION=Math.pow(2,53);var MAX_PACKET_LENGTH=Math.pow(2,24)-1;var Buffer=__webpack_require__(1).Buffer;module.exports=PacketWriter;function PacketWriter(){this._buffer=null;this._offset=0;}PacketWriter.prototype.toBuffer=function toBuffer(parser){if(!this._buffer){this._buffer=Buffer.alloc(0);this._offset=0;}var buffer=this._buffer;var length=this._offset;var packets=Math.floor(length/MAX_PACKET_LENGTH)+1;this._buffer=Buffer.allocUnsafe(length+packets*4);this._offset=0;for(var packet=0;packet>i*8&0xff;}};PacketWriter.prototype.writeFiller=function(bytes){this._allocate(bytes);for(var i=0;iIEEE_754_BINARY_64_PRECISION){throw new Error('writeLengthCodedNumber: JS precision range exceeded, your '+'number is > 53 bit: "'+value+'"');}if(value>8&0xff;if(value>16&0xff;if(value>24&0xff;value=value.toString(2);value=value.substr(0,value.length-32);value=parseInt(value,2);this._buffer[this._offset++]=value&0xff;this._buffer[this._offset++]=value>>8&0xff;this._buffer[this._offset++]=value>>16&0xff;this._buffer[this._offset++]=0;};PacketWriter.prototype.writeLengthCodedBuffer=function(value){var bytes=value.length;this.writeLengthCodedNumber(bytes);this.writeBuffer(value);};PacketWriter.prototype.writeNullTerminatedBuffer=function(value){this.writeBuffer(value);this.writeFiller(1);};PacketWriter.prototype.writeLengthCodedString=function(value){if(value===null){this.writeLengthCodedNumber(null);return;}value=value===undefined?'':String(value);var bytes=Buffer.byteLength(value,'utf-8');this.writeLengthCodedNumber(bytes);if(!bytes){return;}this._allocate(bytes);this._buffer.write(value,this._offset,'utf-8');this._offset+=bytes;};PacketWriter.prototype._allocate=function _allocate(bytes){if(!this._buffer){this._buffer=Buffer.alloc(Math.max(BUFFER_ALLOC_SIZE,bytes));this._offset=0;return;}var bytesRemaining=this._buffer.length-this._offset;if(bytesRemaining>=bytes){return;}var newSize=this._buffer.length+Math.max(BUFFER_ALLOC_SIZE,bytes);var oldBuffer=this._buffer;this._buffer=Buffer.alloc(newSize);oldBuffer.copy(this._buffer);}; - -/***/ }), -/* 80 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports=__webpack_require__(81); - -/***/ }), -/* 81 */ -/***/ (function(module, exports) { - -var SqlString=exports;var ID_GLOBAL_REGEXP=/`/g;var QUAL_GLOBAL_REGEXP=/\./g;var CHARS_GLOBAL_REGEXP=/[\0\b\t\n\r\x1a\"\'\\]/g;var CHARS_ESCAPE_MAP={'\0':'\\0','\b':'\\b','\t':'\\t','\n':'\\n','\r':'\\r','\x1a':'\\Z','"':'\\"','\'':'\\\'','\\':'\\\\'};SqlString.escapeId=function escapeId(val,forbidQualified){if(Array.isArray(val)){var sql='';for(var i=0;ithis._removeNodeErrorCount){errorCount=this._removeNodeErrorCount;}if(errorCount<1){errorCount=1;}node.errorCount=errorCount-1;if(node._offlineUntil){node._offlineUntil=0;this.emit('online',node.id);}};PoolCluster.prototype._findNodeIds=function _findNodeIds(pattern,includeOffline){var currentTime=0;var foundNodeIds=this._findCaches[pattern];if(foundNodeIds===undefined){var expression=patternRegExp(pattern);var nodeIds=Object.keys(this._nodes);foundNodeIds=nodeIds.filter(function(id){return id.match(expression);});this._findCaches[pattern]=foundNodeIds;}if(includeOffline){return foundNodeIds;}return foundNodeIds.filter(function(nodeId){var node=this._getNode(nodeId);if(!node._offlineUntil){return true;}if(!currentTime){currentTime=getMonotonicMilliseconds();}return node._offlineUntil<=currentTime;},this);};PoolCluster.prototype._getNode=function _getNode(id){return this._nodes[id]||null;};PoolCluster.prototype._increaseErrorCount=function _increaseErrorCount(node){var errorCount=++node.errorCount;if(this._removeNodeErrorCount>errorCount){return;}if(this._restoreNodeTimeout>0){node._offlineUntil=getMonotonicMilliseconds()+this._restoreNodeTimeout;this.emit('offline',node.id);return;}this._removeNode(node);this.emit('remove',node.id);};PoolCluster.prototype._getConnection=function(node,cb){var self=this;node.pool.getConnection(function(err,connection){if(err){self._increaseErrorCount(node);cb(err);return;}else{self._decreaseErrorCount(node);}connection._clusterId=node.id;cb(null,connection);});};PoolCluster.prototype._removeNode=function _removeNode(node){delete this._nodes[node.id];this._clearFindCaches();node.pool.end(_noop);};function getMonotonicMilliseconds(){var ms;if(typeof process.hrtime==='function'){ms=process.hrtime();ms=ms[0]*1e3+ms[1]*1e-6;}else{ms=process.uptime()*1000;}return Math.floor(ms);}function isRegExp(val){return typeof val==='object'&&Object.prototype.toString.call(val)==='[object RegExp]';}function patternRegExp(pattern){if(isRegExp(pattern)){return pattern;}var source=pattern.replace(/([.+?^=!:${}()|\[\]\/\\])/g,'\\$1').replace(/\*/g,'.*');return new RegExp('^'+source+'$');}function _cb(err){if(err){throw err;}}function _noop(){} - -/***/ }), -/* 84 */ -/***/ (function(module, exports, __webpack_require__) { - -var Connection=__webpack_require__(8);var PoolSelector=__webpack_require__(29);module.exports=PoolNamespace;function PoolNamespace(cluster,pattern,selector){this._cluster=cluster;this._pattern=pattern;this._selector=new PoolSelector[selector]();}PoolNamespace.prototype.getConnection=function(cb){var clusterNode=this._getClusterNode();var cluster=this._cluster;var namespace=this;if(clusterNode===null){var err=null;if(this._cluster._findNodeIds(this._pattern,true).length!==0){err=new Error('Pool does not have online node.');err.code='POOL_NONEONLINE';}else{err=new Error('Pool does not exist.');err.code='POOL_NOEXIST';}cb(err);return;}cluster._getConnection(clusterNode,function(err,connection){var retry=err&&cluster._canRetry&&cluster._findNodeIds(namespace._pattern).length!==0;if(retry){namespace.getConnection(cb);return;}if(err){cb(err);return;}cb(null,connection);});};PoolNamespace.prototype.query=function(sql,values,cb){var cluster=this._cluster;var clusterNode=this._getClusterNode();var query=Connection.createQuery(sql,values,cb);var namespace=this;if(clusterNode===null){var err=null;if(this._cluster._findNodeIds(this._pattern,true).length!==0){err=new Error('Pool does not have online node.');err.code='POOL_NONEONLINE';}else{err=new Error('Pool does not exist.');err.code='POOL_NOEXIST';}process.nextTick(function(){query.on('error',function(){});query.end(err);});return query;}if(!(typeof sql==='object'&&'typeCast'in sql)){query.typeCast=clusterNode.pool.config.connectionConfig.typeCast;}if(clusterNode.pool.config.connectionConfig.trace){query._callSite=new Error();}cluster._getConnection(clusterNode,function(err,conn){var retry=err&&cluster._canRetry&&cluster._findNodeIds(namespace._pattern).length!==0;if(retry){namespace.query(query);return;}if(err){query.on('error',function(){});query.end(err);return;}query.once('end',function(){conn.release();});conn.query(query);});return query;};PoolNamespace.prototype._getClusterNode=function _getClusterNode(){var foundNodeIds=this._cluster._findNodeIds(this._pattern);var nodeId;switch(foundNodeIds.length){case 0:nodeId=null;break;case 1:nodeId=foundNodeIds[0];break;default:nodeId=this._selector(foundNodeIds);break;}return nodeId!==null?this._cluster._getNode(nodeId):null;}; - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/resources/ghmattimysql/ghmattimysql.lua b/resources/ghmattimysql/ghmattimysql.lua deleted file mode 100644 index b9fa2d817..000000000 --- a/resources/ghmattimysql/ghmattimysql.lua +++ /dev/null @@ -1,39 +0,0 @@ -local function safeParameters(parameters) - if parameters == nil then - return {[''] = ''} - end - return parameters -end - -exports('executeSync', function (query, parameters) - local res = {} - local finishedQuery = false - exports.ghmattimysql:execute(query, safeParameters(parameters), function (result) - res = result - finishedQuery = true - end) - repeat Citizen.Wait(0) until finishedQuery == true - return res -end) - -exports('scalarSync', function (query, parameters) - local res = {} - local finishedQuery = false - exports.ghmattimysql:scalar(query, safeParameters(parameters), function (result) - res = result - finishedQuery = true - end) - repeat Citizen.Wait(0) until finishedQuery == true - return res -end) - -exports('transactionSync', function (query, parameters) - local res = {} - local finishedTransaction = false - exports.ghmattimysql:transaction(query, safeParameters(parameters), function (result) - res = result - finishedTransaction = true - end) - repeat Citizen.Wait(0) until finishedTransaction == true - return res -end) diff --git a/resources/police/client/armory.lua b/resources/police/client/armory.lua deleted file mode 100644 index 7be3b67ee..000000000 --- a/resources/police/client/armory.lua +++ /dev/null @@ -1,164 +0,0 @@ ---[[ - Cops_FiveM - A cops script for FiveM RP servers. - Copyright (C) 2018 FiveM-Scripts - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero 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 Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with Cops_FiveM in the file "LICENSE". If not, see . -]] - -local buttonsCategories = {} -local buttonWeaponList = {} - -function load_armory() - for k in ipairs (buttonsCategories) do - buttonsCategories [k] = nil - end - - for k in ipairs (buttonWeaponList) do - buttonWeaponList [k] = nil - end - - buttonsCategories[#buttonsCategories+1] = {name = i18n.translate("armory_basic_kit"), func = "giveBasicKit", params = ""} - if config.enableOutfits then - buttonsCategories[#buttonsCategories+1] = {name = i18n.translate("armory_add_bulletproof_vest_title"), func = "addBulletproofVest", params = ""} - buttonsCategories[#buttonsCategories+1] = {name = i18n.translate("armory_remove_bulletproof_vest_title"), func = "removeBulletproofVest", params = ""} - end - buttonsCategories[#buttonsCategories+1] = {name = i18n.translate("armory_weapons_list"), func = "openWeaponListMenu", params = ""} - - buttonsCategories[#buttonsCategories+1] = {name = "Close", func = "CloseArmory", params = ""} - - for k,v in pairs(weapons) do - buttonWeaponList[#buttonWeaponList+1] = {name = tostring(v.name), func = 'GiveCustomWeapon', params = tostring(v.hash)} - end -end - -local hashSkin = GetHashKey("mp_m_freemode_01") - -function createArmoryPed() - if not DoesEntityExist(armoryPed) then - local model = GetHashKey("s_m_y_cop_01") - - RequestModel(model) - while not HasModelLoaded(model) do - Wait(0) - end - - local armoryPed = CreatePed(26, model, 454.165, -979.999, 30.690, 92.298, false, false) - SetEntityInvincible(armoryPed, true) - TaskTurnPedToFaceEntity(armoryPed, PlayerId(), -1) - - return armoryPed - end -end - -function giveBasicKit() - for k,v in pairs(basic_kit) do - GiveWeaponToPed(PlayerPedId(), GetHashKey(v), -1, true, false) - end - - SetCurrentPedWeapon(PlayerPedId(), GetHashKey("WEAPON_UNARMED"), true) - PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) -end - -function giveBasicPrisonKit() - GiveWeaponToPed(PlayerPedId(), GetHashKey("WEAPON_PISTOL50"), -1, true, true) - GiveWeaponToPed(PlayerPedId(), GetHashKey("WEAPON_STUNGUN"), -1, true, true) - GiveWeaponToPed(PlayerPedId(), GetHashKey("WEAPON_NIGHTSTICK"), 200, true, true) - GiveWeaponToPed(PlayerPedId(), GetHashKey("WEAPON_FLASHLIGHT"), 200, true, true) - - PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) -end - -function addBulletproofVest() - if(config.enableOutfits == true) then - if(GetEntityModel(PlayerPedId()) == hashSkin) then - SetPedComponentVariation(PlayerPedId(), 9, 4, 1, 2) - else - SetPedComponentVariation(PlayerPedId(), 9, 6, 1, 2) - end - end - - SetPedArmour(PlayerPedId(), 100) - PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) -end - -function removeBulletproofVest() - if(config.enableOutfits == true) then - SetPedComponentVariation(PlayerPedId(), 9, 0, 1, 2) - end - - SetPedArmour(PlayerPedId(), 0) - PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) -end - -function GiveCustomWeapon(weaponData) - GiveWeaponToPed(PlayerPedId(), GetHashKey(weaponData), -1, false, true) - SetCurrentPedWeapon(PlayerPedId(), GetHashKey("WEAPON_UNARMED"), true) - PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) -end - -function CloseArmory() - if not IsAnySpeechPlaying(armoryPed) then - PlayAmbientSpeechWithVoice(armoryPed, "WEPSEXPERT_BYESHOPGEN", "WEPSEXP", "SPEECH_PARAMS_FORCE", 0) - end - - Wait(850) - CloseMenu() - RenderScriptCams(false, 1, 1000, 1, 0, 0) - SetCamActive(ArmoryRoomCam, false) - DestroyCam(ArmoryRoomCam, true) - - DoScreenFadeOut(500) - Wait(600) - - if DoesEntityExist(armoryPed) then - DeleteEntity(armoryPed) - end - - FreezeEntityPosition(PlayerPedId(), false) - SetEntityCoords(PlayerPedId(), Lx, Ly, Lz) - - Citizen.Wait(500) - DoScreenFadeIn(500) -end - - -function openWeaponListMenu() - CloseMenu() - SendNUIMessage({ - title = i18n.translate("armory_global_title"), - subtitle = i18n.translate("armory_weapons_list"), - buttons = buttonWeaponList, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "armory-weapon_list" - anyMenuOpen.isActive = true -end - -function OpenArmory() - if((anyMenuOpen.menuName ~= "armory" and anyMenuOpen.menuName ~= "armory-weapon_list") and not anyMenuOpen.isActive) then - SendNUIMessage({ - title = i18n.translate("armory_global_title"), - subtitle = GetLabelText("PM_WEAPONS"), - buttons = buttonsCategories, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "armory" - anyMenuOpen.isActive = true - end -end - -function BackArmory() - CloseMenu() - OpenArmory() -end \ No newline at end of file diff --git a/resources/police/client/client.lua b/resources/police/client/client.lua deleted file mode 100644 index 18cea6433..000000000 --- a/resources/police/client/client.lua +++ /dev/null @@ -1,890 +0,0 @@ ---[[ - Cops_FiveM - A cops script for FiveM RP servers. - Copyright (C) 2018 FiveM-Scripts - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero 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 Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with Cops_FiveM in the file "LICENSE". If not, see . -]] - --- ---Local variables : Please do not touch theses variables --- - -if(config.useCopWhitelist == true) then - isCop = false -else - isCop = true -end - -local firstSpawn = true -local isInService = false -local policeHeli = nil -local handCuffed = false -local isAlreadyDead = false -local allServiceCops = {} -local blipsCops = {} -local drag = false -local officerDrag = -1 - -rank = -1 - -anyMenuOpen = { - menuName = "", - isActive = false -} - -SpawnedSpikes = {} - --- ---Events handlers --- - -AddEventHandler("playerSpawned", function() - if config.useCopWhitelist then - TriggerServerEvent("police:checkIsCop") - else - isCop = true - TriggerServerEvent("police:checkIsCop") - load_armory() - load_garage() - end - - if firstSpawn then - TriggerServerEvent("police:GetPayChecks") - firstSpawn = false - end -end) - -RegisterNetEvent('police:receiveIsCop') -AddEventHandler('police:receiveIsCop', function(svrank, svdept) - if(svrank == -1) then - if(config.useCopWhitelist == true) then - isCop = false - else - isCop = true - rank = 0 - dept = 1 - - load_armory() - load_garage() - end - else - isCop = true - rank = svrank - dept = svdept - if(isInService) then --and config.enableOutfits - if(GetEntityModel(PlayerPedId()) == GetHashKey("mp_m_freemode_01")) then - SetPedComponentVariation(PlayerPedId(), 10, 8, config.rank.outfit_badge[rank], 2) - else - SetPedComponentVariation(PlayerPedId(), 10, 7, config.rank.outfit_badge[rank], 2) - end - end - - load_armory() - load_garage() - end -end) - -if(config.useCopWhitelist == true) then - RegisterNetEvent('police:nowCop') - AddEventHandler('police:nowCop', function() - isCop = true - end) -end - -RegisterNetEvent('police:Update') -AddEventHandler('police:Update', function(boolState) - local data = GetResourceMetadata(GetCurrentResourceName(), 'resource_fname', 0) - - if boolState then - DisplayNotificationLabel("FMMC_ENDVERC1", "~y~" .. data .. "~s~") - end -end) - -if(config.useCopWhitelist == true) then - RegisterNetEvent('police:noLongerCop') - AddEventHandler('police:noLongerCop', function() - if(config.useCopWhitelist == true) then - isCop = false - end - - isInService = false - - if(config.enableOutfits == true) then - RemoveAllPedWeapons(PlayerPedId()) - TriggerServerEvent("skin_customization:SpawnPlayer") - else - local model = GetHashKey("a_m_y_mexthug_01") - - RequestModel(model) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end - - SetPlayerModel(PlayerId(), model) - SetModelAsNoLongerNeeded(model) - RemoveAllPedWeapons(PlayerPedId()) - end - - if(policeHeli ~= nil) then - SetEntityAsMissionEntity(policeHeli, true, true) - Citizen.InvokeNative(0xEA386986E786A54F, Citizen.PointerValueIntInitialized(policeHeli)) - policeHeli = nil - end - - ServiceOff() - end) -end - -RegisterNetEvent('police:getArrested') -AddEventHandler('police:getArrested', function() - handCuffed = not handCuffed - if(handCuffed) then - TriggerEvent("police:notify", "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("now_cuffed")) - else - TriggerEvent("police:notify", "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("now_uncuffed")) - cuffing = false - drag = false - ClearPedTasksImmediately(PlayerPedId()) - end -end) - ---Inspired from emergency for request system (by Jyben : https://forum.fivem.net/t/release-job-save-people-be-a-hero-paramedic-emergency-coma-ko/19773) -local lockAskingFine = false -RegisterNetEvent('police:payFines') -AddEventHandler('police:payFines', function(amount, sender) - Citizen.CreateThread(function() - - if(lockAskingFine ~= true) then - lockAskingFine = true - local notifReceivedAt = GetGameTimer() - Notification(i18n.translate("info_fine_request_before_amount")..amount..i18n.translate("info_fine_request_after_amount")) - while(true) do - Wait(0) - - if (GetTimeDifference(GetGameTimer(), notifReceivedAt) > 15000) then - TriggerServerEvent('police:finesETA', sender, 2) - Notification(i18n.translate("request_fine_expired")) - lockAskingFine = false - break - end - - if IsControlPressed(1, config.bindings.accept_fine) then - TriggerServerEvent('bank:withdraw', amount) - Notification(i18n.translate("pay_fine_success_before_amount")..amount..i18n.translate("pay_fine_success_after_amount")) - TriggerServerEvent('police:finesETA', sender, 0) - lockAskingFine = false - break - end - - if IsControlPressed(1, config.bindings.refuse_fine) then - TriggerServerEvent('police:finesETA', sender, 3) - lockAskingFine = false - break - end - end - else - TriggerServerEvent('police:finesETA', sender, 1) - end - end) -end) - -RegisterNetEvent('police:receivePaycheck') -AddEventHandler('police:receivePaycheck', function(amount) - if amount then - local _, currentValue = StatGetInt("BANK_BALANCE", -1) - local value = math.floor(amount + currentValue) - - StatSetInt("BANK_BALANCE", value, true) - ShowHudComponentThisFrame(4) - end -end) - --- Copy/paste from fs_freemode (by FiveM-Script: https://github.com/FiveM-Scripts/fs_freemode) - -RegisterNetEvent("police:notify") -AddEventHandler("police:notify", function(icon, type, sender, title, text) - SetNotificationTextEntry("STRING") - AddTextComponentString(text) - SetNotificationMessage(icon, icon, true, type, sender, title, text) - DrawNotification(false, true) -end) - ---Piece of code given by Thefoxeur54 -RegisterNetEvent('police:unseatme') -AddEventHandler('police:unseatme', function(t) - local ped = GetPlayerPed(t) - ClearPedTasksImmediately(ped) - plyPos = GetEntityCoords(PlayerPedId(), true) - local xnew = plyPos.x+2 - local ynew = plyPos.y+2 - - SetEntityCoords(PlayerPedId(), xnew, ynew, plyPos.z) -end) - -RegisterNetEvent('police:toggleDrag') -AddEventHandler('police:toggleDrag', function(t) - if(handCuffed) then - drag = not drag - officerDrag = t - end -end) - -RegisterNetEvent('police:forcedEnteringVeh') -AddEventHandler('police:forcedEnteringVeh', function(veh) - if(handCuffed) then - local pos = GetEntityCoords(PlayerPedId()) - local entityWorld = GetOffsetFromEntityInWorldCoords(PlayerPedId(), 0.0, 20.0, 0.0) - - local rayHandle = CastRayPointToPoint(pos.x, pos.y, pos.z, entityWorld.x, entityWorld.y, entityWorld.z, 10, PlayerPedId(), 0) - local _, _, _, _, vehicleHandle = GetRaycastResult(rayHandle) - - if vehicleHandle ~= nil then - if(IsVehicleSeatFree(vehicleHandle, 1)) then - SetPedIntoVehicle(PlayerPedId(), vehicleHandle, 1) - else - if(IsVehicleSeatFree(vehicleHandle, 2)) then - SetPedIntoVehicle(PlayerPedId(), vehicleHandle, 2) - end - end - end - end -end) - -RegisterNetEvent('police:removeWeapons') -AddEventHandler('police:removeWeapons', function() - RemoveAllPedWeapons(PlayerPedId(), true) -end) - -if(config.enableOtherCopsBlips == true) then - RegisterNetEvent('police:resultAllCopsInService') - AddEventHandler('police:resultAllCopsInService', function(array) - allServiceCops = array - enableCopBlips() - end) -end - --- ---Functions --- - -function Notification(msg) - SetNotificationTextEntry("STRING") - AddTextComponentString(msg) - DrawNotification(0,1) -end - -function drawNotification(text) - SetNotificationTextEntry("STRING") - AddTextComponentString(text) - DrawNotification(false, false) -end - -function DisplayNotificationLabel(label, sublabel) - SetNotificationTextEntry(label) - if sublabel then - AddTextComponentSubstringPlayerName(sublabel) - end - - DrawNotification(true, true) -end - ---From Player Blips and Above Head Display (by Scammer : https://forum.fivem.net/t/release-scammers-script-collection-09-03-17/3313) -function enableCopBlips() - for k, existingBlip in pairs(blipsCops) do - RemoveBlip(existingBlip) - end - blipsCops = {} - - local localIdCops = {} - for _, player in ipairs(GetActivePlayers()) do - if(GetPlayerPed(player) ~= PlayerPedId()) then - for i,c in pairs(allServiceCops) do - if(i == GetPlayerServerId(player)) then - localIdCops[player] = c - break - end - end - end - end - - for id, c in pairs(localIdCops) do - local ped = GetPlayerPed(id) - local blip = GetBlipFromEntity(ped) - - if not DoesBlipExist(blip) then - blip = AddBlipForEntity(ped) - SetBlipSprite(blip, 1) - Citizen.InvokeNative( 0x5FBCA48327B914DF, blip, true) - HideNumberOnBlip( blip) - SetBlipNameToPlayerName(blip, id) - - SetBlipScale(blip, 0.85) - SetBlipAlpha(blip, 255) - - table.insert(blipsCops, blip) - else - blipSprite = GetBlipSprite(blip) - - HideNumberOnBlip(blip) - if blipSprite ~= 1 then - SetBlipSprite(blip, 1) - Citizen.InvokeNative(0x5FBCA48327B914DF, blip, true) - end - - SetBlipNameToPlayerName(blip, id) - SetBlipScale(blip, 0.85) - SetBlipAlpha(blip, 255) - - table.insert(blipsCops, blip) - end - end -end - -function GetPlayers() - local players = {} - - for _, player in ipairs(GetActivePlayers()) do - if NetworkIsPlayerActive(player) then - table.insert(players, player) - end - end - - return players -end - -function GetClosestPlayer() - local players = GetPlayers() - local closestDistance = -1 - local closestPlayer = -1 - local ply = PlayerPedId() - local plyCoords = GetEntityCoords(ply, 0) - - for index,value in ipairs(players) do - local target = GetPlayerPed(value) - if(target ~= ply) then - local targetCoords = GetEntityCoords(GetPlayerPed(value), 0) - local distance = Vdist(targetCoords["x"], targetCoords["y"], targetCoords["z"], plyCoords["x"], plyCoords["y"], plyCoords["z"]) - if(closestDistance == -1 or closestDistance > distance) then - closestPlayer = value - closestDistance = distance - end - end - end - - return closestPlayer, closestDistance -end - -function drawTxt(text,font,centre,x,y,scale,r,g,b,a) - SetTextFont(font) - SetTextProportional(0) - SetTextScale(scale, scale) - SetTextColour(r, g, b, a) - SetTextDropShadow(0, 0, 0, 0,255) - SetTextEdge(1, 0, 0, 0, 255) - SetTextDropShadow() - SetTextOutline() - SetTextCentre(centre) - SetTextEntry("STRING") - AddTextComponentString(text) - DrawText(x, y) -end - -function isNearTakeService() - local distance = 10000 - local pos = {} - for i = 1, #clockInStation do - local coords = GetEntityCoords(PlayerPedId(), 0) - local currentDistance = Vdist(clockInStation[i].x, clockInStation[i].y, clockInStation[i].z, coords.x, coords.y, coords.z) - if(currentDistance < distance) then - distance = currentDistance - pos = clockInStation[i] - end - end - - if anyMenuOpen.menuName == "cloackroom" and anyMenuOpen.isActive and distance > 3 then - CloseMenu() - end - - if(distance < 30) then - if anyMenuOpen.menuName ~= "cloackroom" and not anyMenuOpen.isActive then - DrawMarker(1, pos.x, pos.y, pos.z-1, 0, 0, 0, 0, 0, 0, 1.0, 1.0, 1.0, 0, 155, 255, 200, 0, 0, 2, 0, 0, 0, 0) - end - end - - if(distance < 2) then - return true - end -end - -function isNearStationGarage() - local distance = 10000 - local pos = {} - for i = 1, #garageStation do - local coords = GetEntityCoords(PlayerPedId(), 0) - local currentDistance = Vdist(garageStation[i].x, garageStation[i].y, garageStation[i].z, coords.x, coords.y, coords.z) - if(currentDistance < distance) then - distance = currentDistance - pos = garageStation[i] - end - end - - if anyMenuOpen.menuName == "garage" and anyMenuOpen.isActive and distance > 5 then - CloseMenu() - end - - if(distance < 30) then - if anyMenuOpen.menuName ~= "garage" and not anyMenuOpen.isActive then - DrawMarker(1, pos.x, pos.y, pos.z-1, 0, 0, 0, 0, 0, 0, 2.0, 2.0, 1.0, 0, 155, 255, 200, 0, 0, 2, 0, 0, 0, 0) - end - end - - if(distance < 2) then - return true - end -end - -function isNearHelicopterStation() - local distance = 10000 - local pos = {} - for i = 1, #heliStation do - local coords = GetEntityCoords(PlayerPedId(), 0) - local currentDistance = Vdist(heliStation[i].x, heliStation[i].y, heliStation[i].z, coords.x, coords.y, coords.z) - if(currentDistance < distance) then - distance = currentDistance - pos = heliStation[i] - end - end - - if(distance < 30) then - DrawMarker(1, pos.x, pos.y, pos.z-1, 0, 0, 0, 0, 0, 0, 2.5, 2.5, 1.0, 0, 155, 255, 200, 0, 0, 2, 0, 0, 0, 0) - end - if(distance < 2) then - return true - end -end - -function isNearArmory() - local distance = 10000 - local pos = {} - for i = 1, #armoryStation do - local coords = GetEntityCoords(PlayerPedId(), 0) - local currentDistance = Vdist(armoryStation[i].x, armoryStation[i].y, armoryStation[i].z, coords.x, coords.y, coords.z) - if(currentDistance < distance) then - distance = currentDistance - pos = armoryStation[i] - end - end - - if (anyMenuOpen.menuName == "armory" or anyMenuOpen.menuName == "armory-weapon_list") and anyMenuOpen.isActive and distance > 2 then - CloseMenu() - end - if(distance < 30) then - DrawMarker(1, pos.x, pos.y, pos.z-1, 0, 0, 0, 0, 0, 0, 1.0, 1.0, 1.0, 0, 155, 255, 200, 0, 0, 2, 0, 0, 0, 0) - end - if(distance < 2) then - return true - end -end - -function ServiceOn() - isInService = true - TriggerServerEvent("police:takeService") -end - -function ServiceOff() - isInService = false - TriggerServerEvent("police:breakService") - - if config.enableOtherCopsBlips == true then - allServiceCops = {} - - for k, existingBlip in pairs(blipsCops) do - RemoveBlip(existingBlip) - end - blipsCops = {} - end -end - -function DisplayHelpText(str) - BeginTextCommandDisplayHelp("STRING") - AddTextComponentSubstringPlayerName(str) - EndTextCommandDisplayHelp(0, 0, 1, -1) -end - -function CloseMenu() - SendNUIMessage({ - action = "close" - }) - - anyMenuOpen.menuName = "" - anyMenuOpen.isActive = false -end - -RegisterNUICallback('sendAction', function(data, cb) - _G[data.action](data.params) - cb('ok') -end) - --- ---Threads --- - -local alreadyDead = false -local playerStillDragged = false - -Citizen.CreateThread(function() - DoScreenFadeIn(100) - local gxt = "fmmc" - local CurrentSlot = 0 - - while HasAdditionalTextLoaded(CurrentSlot) and not HasThisAdditionalTextLoaded(gxt, CurrentSlot) do - Wait(1) - CurrentSlot = CurrentSlot + 1 - end - - if not HasThisAdditionalTextLoaded(gxt, CurrentSlot) then - ClearAdditionalText(CurrentSlot, true) - RequestAdditionalText(gxt, CurrentSlot) - while not HasThisAdditionalTextLoaded(gxt, CurrentSlot) do - Wait(0) - end - end - - RequestAnimDict('mp_arresting') - while not HasAnimDictLoaded('mp_arresting') do - Citizen.Wait(50) - end - - if not IsIplActive("FIBlobby") then - RequestIpl("FIBlobbyfake") - end - - TriggerServerEvent("police:checkIsCop") - - if config.enableNeverWanted then - SetMaxWantedLevel(0) - SetWantedLevelMultiplier(0.0) - else - SetMaxWantedLevel(5) - SetWantedLevelMultiplier(1.0) - end - - if config.stationBlipsEnabled then - for _, item in pairs(clockInStation) do - item.blip = AddBlipForCoord(item.x, item.y, item.z) - SetBlipSprite(item.blip, 60) - SetBlipScale(item.blip, 1.0) - SetBlipColour(item.blip, 38) - SetBlipAsShortRange(item.blip, true) - end - end - - while true do - Citizen.Wait(5) - DisablePlayerVehicleRewards(PlayerId()) - - if(anyMenuOpen.isActive) then - DisableControlAction(1, 21) - DisableControlAction(1, 140) - DisableControlAction(1, 141) - DisableControlAction(1, 142) - - SetDisableAmbientMeleeMove(PlayerPedId(), true) - - if (IsControlJustPressed(1,172)) then - SendNUIMessage({ - action = "keyup" - }) - PlaySoundFrontend(-1, "NAV_UP_DOWN", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) - elseif (IsControlJustPressed(1,173)) then - SendNUIMessage({ - action = "keydown" - }) - PlaySoundFrontend(-1, "NAV_UP_DOWN", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) - elseif (anyMenuOpen.menuName == "cloackroom") then - if IsControlJustPressed(1, 176) then - SendNUIMessage({ - action = "keyenter" - }) - - PlaySoundFrontend(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) - Citizen.Wait(500) - CloseMenu() - end - elseif (IsControlJustPressed(1,176)) then - SendNUIMessage({ - action = "keyenter" - }) - PlaySoundFrontend(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) - elseif (IsControlJustPressed(1,177)) then - if(anyMenuOpen.menuName == "policemenu" or anyMenuOpen.menuName == "cloackroom" or anyMenuOpen.menuName == "garage") then - CloseMenu() - elseif(anyMenuOpen.menuName == "armory") then - CloseArmory() - elseif(anyMenuOpen.menuName == "armory-weapon_list") then - BackArmory() - else - BackMenuPolice() - end - end - else - EnableControlAction(1, 21) - EnableControlAction(1, 140) - EnableControlAction(1, 141) - EnableControlAction(1, 142) - end - - --Control death events - if(config.useModifiedEmergency == false) then - if(IsPlayerDead(PlayerId())) then - if(alreadyDead == false) then - if(isInService) then - ServiceOff() - end - - handCuffed = false - drag = false - alreadyDead = true - end - else - alreadyDead = false - end - end - - if (handCuffed == true) then - local myPed = PlayerPedId() - local animation = 'idle' - local flags = 50 - - while IsPedBeingStunned(myPed, 0) do - ClearPedTasksImmediately(myPed) - end - - DisableControlAction(1, 12, true) - DisableControlAction(1, 13, true) - DisableControlAction(1, 14, true) - - DisableControlAction(1, 23, true) - DisableControlAction(1, 24, true) - - DisableControlAction(1, 15, true) - DisableControlAction(1, 16, true) - DisableControlAction(1, 17, true) - - if not cuffing then - SetCurrentPedWeapon(myPed, GetHashKey("WEAPON_UNARMED"), true) - RemoveAllPedWeapons(myPed, true) - cuffing = true - end - - if not IsEntityPlayingAnim(myPed, "mp_arresting", animation, 3) then - TaskPlayAnim(myPed, "mp_arresting", animation, 8.0, -8.0, -1, flags, 0, 0, 0, 0 ) - end - else - EnableControlAction(1, 12, false) - EnableControlAction(1, 13, false) - EnableControlAction(1, 14, false) - - EnableControlAction(1, 23, false) - EnableControlAction(1, 24, false) - - EnableControlAction(1, 15, false) - EnableControlAction(1, 16, false) - EnableControlAction(1, 17, false) - - if IsEntityPlayingAnim(PlayerPedId(), "mp_arresting", "idle", 3) then - StopAnimTask(PlayerPedId(), "mp_arresting", animation, 3) - ClearPedTasksImmediately(PlayerPedId()) - end - - cuffing = false - end - - --Piece of code from Drag command (by Frazzle, Valk, Michael_Sanelli, NYKILLA1127 : https://forum.fivem.net/t/release-drag-command/22174) - if drag then - local ped = GetPlayerPed(GetPlayerFromServerId(officerDrag)) - local myped = PlayerPedId() - AttachEntityToEntity(myped, ped, 4103, 11816, 0.48, 0.00, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true) - playerStillDragged = true - else - if(playerStillDragged) then - DetachEntity(PlayerPedId(), true, false) - playerStillDragged = false - end - end - - if config.enableNeverWanted then - if IsPlayerWantedLevelGreater(PlayerId(), 0) then - ClearPlayerWantedLevel(PlayerId()) - end - end - - if(isCop) then - if(isNearTakeService()) then - if not (anyMenuOpen.isActive) then - DisplayHelpText(i18n.translate("help_text_open_cloackroom") .. GetLabelText("collision_8vlv02g"),0,1,0.5,0.8,0.6,255,255,255,255) - if IsControlJustPressed(1,config.bindings.interact_position) then - load_cloackroom() - OpenCloackroom() - end - end - end - - if(isInService) then - if(isNearStationGarage()) then - if(policevehicle ~= nil) then - if not (anyMenuOpen.isActive) then - DisplayHelpText(i18n.translate("help_text_put_car_into_garage"),0,1,0.5,0.8,0.6,255,255,255,255) - end - else - DisplayHelpText(i18n.translate("help_text_get_car_out_garage"),0,1,0.5,0.8,0.6,255,255,255,255) - end - - if IsControlJustPressed(1,config.bindings.interact_position) then - if(policevehicle ~= nil) then - Citizen.InvokeNative(0xEA386986E786A54F, Citizen.PointerValueIntInitialized(policevehicle)) - policevehicle = nil - else - OpenGarage() - end - end - end - - --Open Armory menu - if(isNearArmory()) then - if not (anyMenuOpen.isActive) then - DisplayHelpText(i18n.translate("help_text_open_armory"),0,1,0.5,0.8,0.6,255,255,255,255) - - if IsControlJustPressed(1,config.bindings.interact_position) then - Lx, Ly, Lz = table.unpack(GetEntityCoords(PlayerPedId(), true)) - DoScreenFadeOut(500) - Wait(600) - - SetEntityCoords(PlayerPedId(), 452.119966796875, -980.061966796875, 30.690966796875) - Wait(800) - armoryPed = createArmoryPed() - - if not DoesCamExist(ArmoryRoomCam) then - ArmoryRoomCam = CreateCam("DEFAULT_SCRIPTED_FLY_CAMERA", true) - AttachCamToEntity(ArmoryRoomCam, PlayerPedId(), 0.0, 0.0, 1.0, true) - PointCamAtEntity(ArmoryRoomCam, armoryPed, 0.0, -30.0, 1.0, true) - - SetCamRot(ArmoryRoomCam, 0.0,0.0, GetEntityHeading(PlayerPedId())) - SetCamFov(ArmoryRoomCam, 70.0) - end - - Wait(100) - DoScreenFadeIn(500) - - if DoesEntityExist(armoryPed) then - TaskTurnPedToFaceEntity(PlayerPedId(), armoryPed, -1) - end - - Wait(300) - OpenArmory() - if not IsAmbientSpeechPlaying(armoryPed) then - PlayAmbientSpeechWithVoice(armoryPed, "WEPSEXPERT_GREETSHOPGEN", "WEPSEXP", "SPEECH_PARAMS_FORCE", 0) - end - end - end - end - - if (anyMenuOpen.menuName == "armory") then - if DoesCamExist(ArmoryRoomCam) then - RenderScriptCams(true, 1, 1800, 1, 0) - end - end - - if (IsControlJustPressed(1,config.bindings.use_police_menu)) then - load_menu() - TogglePoliceMenu() - end - - if isNearHelicopterStation() then - if(policeHeli ~= nil) then - DisplayHelpText(i18n.translate("help_text_put_heli_into_garage"),0,1,0.5,0.8,0.6,255,255,255,255) - else - DisplayHelpText(i18n.translate("help_text_get_heli_out_garage"),0,1,0.5,0.8,0.6,255,255,255,255) - end - - if IsControlJustPressed(1,config.bindings.interact_position) then - if(policeHeli ~= nil) then - Citizen.InvokeNative(0xEA386986E786A54F, Citizen.PointerValueIntInitialized(policeHeli)) - policeHeli = nil - else - local heli = GetHashKey("polmav") - local ply = PlayerPedId() - local plyCoords = GetEntityCoords(ply, 0) - - RequestModel(heli) - while not HasModelLoaded(heli) do - Citizen.Wait(0) - end - - policeHeli = CreateVehicle(heli, plyCoords["x"], plyCoords["y"], plyCoords["z"], 90.0, true, false) - SetVehicleHasBeenOwnedByPlayer(policevehicle,true) - - local netid = NetworkGetNetworkIdFromEntity(policeHeli) - SetNetworkIdCanMigrate(netid, true) - NetworkRegisterEntityAsNetworked(VehToNet(policeHeli)) - - SetVehicleLivery(policeHeli, 0) - TaskWarpPedIntoVehicle(ply, policeHeli, -1) - SetEntityAsMissionEntity(policeHeli, true, true) - end - end - end - end - end - end -end) - -if config.enablePaychecks then - Citizen.CreateThread(function() - while true do - Wait(1600) - if GetClockHours() == 10 and GetClockMinutes() == 00 then - TriggerServerEvent("police:TransferPayCheck") - end - end - end) -end - -Citizen.CreateThread(function() - while true do - if drag then - local ped = GetPlayerPed(GetPlayerFromServerId(playerPedDragged)) - plyPos = GetEntityCoords(ped, true) - SetEntityCoords(ped, plyPos.x, plyPos.y, plyPos.z) - end - Citizen.Wait(1000) - end -end) - -Citizen.CreateThread(function() - while true do - Citizen.Wait(1) - if IsPedInAnyVehicle(PlayerPedId(), false) then - currentVeh = GetVehiclePedIsIn(PlayerPedId(), false) - x,y,z = table.unpack(GetEntityCoords(PlayerPedId(), true)) - - if DoesObjectOfTypeExistAtCoords(x, y, z, 0.9, GetHashKey("P_ld_stinger_s"), true) then - for i= 0, 7 do - SetVehicleTyreBurst(currentVeh, i, true, 1148846080) - end - - Citizen.Wait(100) - DeleteSpike() - end - end - end -end) diff --git a/resources/police/client/cloackroom.lua b/resources/police/client/cloackroom.lua deleted file mode 100644 index da0e4cf92..000000000 --- a/resources/police/client/cloackroom.lua +++ /dev/null @@ -1,180 +0,0 @@ ---[[ - Cops_FiveM - A cops script for FiveM RP servers. - Copyright (C) 2018 FiveM-Scripts - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero 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 Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with Cops_FiveM in the file "LICENSE". If not, see . -]] - -local buttons = {} - -function load_cloackroom() - for k in ipairs (buttons) do - buttons [k] = nil - end - - for k, data in pairs(skins) do - if config.useCopWhitelist then - if dept == k then - for k, v in pairs(data) do - buttons[#buttons+1] = {name = tostring(v.name), func = "clockIn", params = tostring(v.model)} - end - end - else - for k, v in pairs(data) do - buttons[#buttons+1] = {name = tostring(v.name), func = "clockIn", params = tostring(v.model)} - end - end - end - - buttons[#buttons+1] = {name = i18n.translate("cloackroom_break_service_title"), func = "clockOut", params = ""} - - if(config.enableOutfits == true) then - if(rank <= 0) then - buttons[#buttons+1] = {name = i18n.translate("cloackroom_add_yellow_vest_title"), func = "cloackroom_add_yellow_vest", params = ""} - buttons[#buttons+1] = {name = i18n.translate("cloackroom_remove_yellow_vest_title"), func = "cloackroom_rem_yellow_vest", params = ""} - end - end -end - -function clockIn(model) - if model then - if IsModelValid(model) and IsModelInCdimage(model) then - ServiceOn() - SetCopModel(model) - - drawNotification(i18n.translate("now_in_service_notification")) - drawNotification(i18n.translate("help_open_menu_notification")) - else - drawNotification("This model is ~r~invalid~w~.") - end - end -end - -function clockOut() - ServiceOff() - removeUniforme() - drawNotification(i18n.translate("break_service_notification")) -end - -function cloackroom_add_yellow_vest() - Citizen.CreateThread(function() - if(GetEntityModel(PlayerPedId()) == hashSkin) then - SetPedComponentVariation(PlayerPedId(), 8, 59, 0, 2) - else - SetPedComponentVariation(PlayerPedId(), 8, 36, 0, 2) - end - end) -end - -function cloackroom_rem_yellow_vest() - Citizen.CreateThread(function() - if(GetEntityModel(PlayerPedId()) == hashSkin) then - SetPedComponentVariation(PlayerPedId(), 8, 58, 0, 2) - else - SetPedComponentVariation(PlayerPedId(), 8, 35, 0, 2) - end - end) -end - -function SetCopModel(model) - SetMaxWantedLevel(0) - SetWantedLevelMultiplier(0.0) - SetRelationshipBetweenGroups(0, GetHashKey("police"), GetHashKey("PLAYER")) - SetRelationshipBetweenGroups(0, GetHashKey("PLAYER"), GetHashKey("police")) - - modelHash = GetHashKey(model) - - RequestModel(modelHash) - while not HasModelLoaded(modelHash) do - Citizen.Wait(0) - end - - if model == "s_m_y_cop_01" then - if (config.enableOutfits == true) then - if(GetEntityModel(PlayerPedId()) == GetHashKey("mp_m_freemode_01")) then - SetPedPropIndex(PlayerPedId(), 1, 5, 0, 2) --Sunglasses - SetPedPropIndex(PlayerPedId(), 2, 0, 0, 2) --Bluetoothn earphone - SetPedComponentVariation(PlayerPedId(), 11, 55, 0, 2) --Shirt - SetPedComponentVariation(PlayerPedId(), 8, 58, 0, 2) --Nightstick decoration - SetPedComponentVariation(PlayerPedId(), 4, 35, 0, 2) --Pants - SetPedComponentVariation(PlayerPedId(), 6, 24, 0, 2) --Shooes - SetPedComponentVariation(PlayerPedId(), 10, 8, config.rank.outfit_badge[rank], 2) --rank - else - SetPedPropIndex(PlayerPedId(), 1, 11, 3, 2) --Sunglasses - SetPedPropIndex(PlayerPedId(), 2, 0, 0, 2) --Bluetoothn earphone - SetPedComponentVariation(PlayerPedId(), 3, 14, 0, 2) --Non buggy tshirt - SetPedComponentVariation(PlayerPedId(), 11, 48, 0, 2) --Shirt - SetPedComponentVariation(PlayerPedId(), 8, 35, 0, 2) --Nightstick decoration - SetPedComponentVariation(PlayerPedId(), 4, 34, 0, 2) --Pants - SetPedComponentVariation(PlayerPedId(), 6, 29, 0, 2) --Shooes - SetPedComponentVariation(PlayerPedId(), 10, 7, config.rank.outfit_badge[rank], 2) --rank - end - else - SetPlayerModel(PlayerId(), modelHash) - end - elseif model == "s_m_y_hwaycop_01" then - SetPlayerModel(PlayerId(), modelHash) - SetPedComponentVariation(PlayerPedId(), 10, 7, config.rank.outfit_badge[rank], 2) - elseif model == "s_m_y_sheriff_01" then - SetPlayerModel(PlayerId(), modelHash) - SetPedComponentVariation(PlayerPedId(), 10, 7, config.rank.outfit_badge[rank], 2) - elseif model == "s_m_y_ranger_01" then - SetPlayerModel(PlayerId(), modelHash) - SetPedComponentVariation(PlayerPedId(), 10, 7, config.rank.outfit_badge[rank], 2) - elseif model == "a_m_y_genstreet_01" then - - else - SetPlayerModel(PlayerId(), modelHash) - end - - giveBasicKit() - SetModelAsNoLongerNeeded(modelHash) -end - -function removeUniforme() - if(config.enableOutfits == true) then - RemoveAllPedWeapons(PlayerPedId()) - TriggerServerEvent("skin_customization:SpawnPlayer") - else - local model = GetHashKey("a_m_y_mexthug_01") - RequestModel(model) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end - - SetPlayerModel(PlayerId(), model) - SetModelAsNoLongerNeeded(model) - - SetMaxWantedLevel(5) - SetWantedLevelMultiplier(1.0) - - SetRelationshipBetweenGroups(3, GetHashKey("police"), GetHashKey("PLAYER")) - SetRelationshipBetweenGroups(3, GetHashKey("PLAYER"), GetHashKey("police")) - end -end - -function OpenCloackroom() - if anyMenuOpen.menuName ~= "cloackroom" and not anyMenuOpen.isActive then - SendNUIMessage({ - title = GetLabelText("collision_8vlv02g"), - subtitle = GetLabelText("INPUT_CHARACTER_WHEEL"), - buttons = buttons, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "cloackroom" - anyMenuOpen.isActive = true - if config.enableVersionNotifier then - TriggerServerEvent('police:UpdateNotifier') - end - end -end diff --git a/resources/police/client/garage.lua b/resources/police/client/garage.lua deleted file mode 100644 index 536b3cae1..000000000 --- a/resources/police/client/garage.lua +++ /dev/null @@ -1,90 +0,0 @@ ---[[ - Cops_FiveM - A cops script for FiveM RP servers. - Copyright (C) 2018 FiveM-Scripts - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero 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 Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with Cops_FiveM in the file "LICENSE". If not, see . -]] - -local buttons = {} - -function load_garage() - for k in ipairs (buttons) do - buttons [k] = nil - end - - for k, data in pairs(vehicles) do - if config.useCopWhitelist then - if dept == k then - for k, v in pairs(data) do - buttons[#buttons+1] = {name = tostring(v.name), func = "SpawnerVeh", params = tostring(v.model)} - end - end - else - if dept == 1 then - for k, v in pairs(data) do - buttons[#buttons+1] = {name = tostring(v.name), func = "SpawnerVeh", params = tostring(v.model)} - end - end - end - end -end - -function SpawnerVeh(hash) - if IsPedInAnyVehicle(PlayerPedId(), false) then - currentVehicle = GetVehiclePedIsIn(PlayerPedId(), false) - DeleteEntity(currentVehicle) - end - - local car = GetHashKey(hash) - local playerPed = PlayerPedId() - - RequestModel(car) - while not HasModelLoaded(car) do - Citizen.Wait(0) - end - - local playerCoords = GetEntityCoords(playerPed) - local playerHeading = GetEntityHeading(playerPed) - - policevehicle = CreateVehicle(car, playerCoords, 90.0, true, false) - SetVehicleEngineOn(policevehicle, true, true, true) - SetVehicleMod(policevehicle, 11, 2) - SetVehicleMod(policevehicle, 12, 2) - SetVehicleMod(policevehicle, 13, 2) - - SetEntityHeading(policevehicle, (playerHeading+160)%360) - SetVehicleEnginePowerMultiplier(policevehicle, 25.0) - SetVehicleOnGroundProperly(policevehicle) - SetVehicleHasBeenOwnedByPlayer(policevehicle,true) - - SetVehRadioStation(policevehicle, "OFF") - - local netid = NetworkGetNetworkIdFromEntity(policevehicle) - SetNetworkIdCanMigrate(netid, true) - NetworkRegisterEntityAsNetworked(VehToNet(policevehicle)) - - TaskWarpPedIntoVehicle(playerPed, policevehicle, -1) - SetEntityInvincible(policevehicle, false) -end - -function OpenGarage() - CloseMenu() - SendNUIMessage({ - title = i18n.translate("garage_global_title"), - subtitle = GetLabelText("VEX_NMB"), - buttons = buttons, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "garage" - anyMenuOpen.isActive = true -end \ No newline at end of file diff --git a/resources/police/client/html/css/style.css b/resources/police/client/html/css/style.css deleted file mode 100644 index d016a02dd..000000000 --- a/resources/police/client/html/css/style.css +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * Cops_FiveM Menu - * Authors: Streetcorps, Kyominii - * Website: Cops_FiveM - * License: AGPL-3.0 - */ - -@font-face { - font-family: 'SignPainter'; - src: url('../fonts/SignPainter-HouseScript.ttf') format('truetype'); - font-weight: normal; - font-style: normal; -} - -html, body, { - height: 100%; -} - -body { - font-family: Arial, Helvetica Neue, Helvetica, sans-serif; - padding-top: 5px; -} - -.menu { - float: right; - margin-right: 10px; - width: 418px; - background: rgba(0, 0, 0, 0.8); - display: none; -} - -.header { - background: rgb(30,87,153); - background: url("../img/background.png") no-repeat; - color: #fff; - padding-top: 15px; - font-size: 52px; - font-family: 'SignPainter'; - min-height: 66px; - text-align: center; - text-shadow: 0 0 10px rgba(255, 255, 255, 0.3); -} - -.subheader { - height: 35px; - color: #3e8fcc !important; - background: rgb(0, 0, 0); - box-shadow: 0px 5px 25px rgba(0, 0, 0, 0.5); - font-size: 18px; - padding-top: 10px; - padding-left: 10px; - overflow: hidden; -} - -.content { - background: linear-gradient(to bottom, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0.8) 100%); - box-shadow: 0px 5px 25px rgba(0, 0, 0, 0.5); - user-select: none; - color: #fff; - font-size: 20px; - overflow: hidden; -} - -.list { - padding-left: 0; - margin-top: 0; - margin-bottom: 0; -} - -ul li:nth-of-type(1n+10) { - display: none; -} - -li { - position: relative; - padding: 10px; - font-size: 17px; - color: #D4D5D6; - font-family: Arial, Helvetica Neue, Helvetica, sans-serif; - padding-top: 8px; - padding-left: 10px; - padding-bottom: 7px; -} - -.item { - list-style-type: none; -} - -.item.active { - color: #111; - background: rgba(255,255,255,1); - background: linear-gradient(to right, rgba(255,255,255,1) 0%, rgba(255,255,255,0.8) 100%); -} - -.scroll { - background: rgba(0, 0, 0, 0.7) url('../img/arrows_upanddown.jpg') center center no-repeat; - border-top: 1px solid rgba(255, 255, 255, 0.2); - display: none; - height: 38px; - width: 100%; -} \ No newline at end of file diff --git a/resources/police/client/html/fonts/BebasNeue.otf b/resources/police/client/html/fonts/BebasNeue.otf deleted file mode 100644 index 214e00754..000000000 Binary files a/resources/police/client/html/fonts/BebasNeue.otf and /dev/null differ diff --git a/resources/police/client/html/fonts/SignPainter-HouseScript.ttf b/resources/police/client/html/fonts/SignPainter-HouseScript.ttf deleted file mode 100644 index 099807c24..000000000 Binary files a/resources/police/client/html/fonts/SignPainter-HouseScript.ttf and /dev/null differ diff --git a/resources/police/client/html/img/arrows_upanddown.jpg b/resources/police/client/html/img/arrows_upanddown.jpg deleted file mode 100644 index 1efb10a18..000000000 Binary files a/resources/police/client/html/img/arrows_upanddown.jpg and /dev/null differ diff --git a/resources/police/client/html/img/background.png b/resources/police/client/html/img/background.png deleted file mode 100644 index b9b6cd84f..000000000 Binary files a/resources/police/client/html/img/background.png and /dev/null differ diff --git a/resources/police/client/html/index.html b/resources/police/client/html/index.html deleted file mode 100644 index 75e61fcc2..000000000 --- a/resources/police/client/html/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/resources/police/client/html/js/script.js b/resources/police/client/html/js/script.js deleted file mode 100644 index 4a274b482..000000000 --- a/resources/police/client/html/js/script.js +++ /dev/null @@ -1,81 +0,0 @@ -$(document).ready(function(){ - - window.addEventListener('message', (event) => { - if(event.data.action == "setAndOpen"){ - - $(".header").append(event.data.title); - $(".subheader").append(event.data.subtitle); - - for(let i = 0; i < event.data.buttons.length; i++){ - let li = $("
  • ").append(event.data.buttons[i].name).addClass("item").attr("function", event.data.buttons[i].func).attr("params", event.data.buttons[i].params); - if(i == 0) { - li.addClass("active"); - } - $(".list").append(li); - } - - var count = $("ul").children().length; - if (count > 10) { - $(".scroll").show(); - } else { - $(".scroll").hide(); - } - - $(".menu").show(); - } - - if(event.data.action == "close"){ - $(".menu").hide(); - $(".list").empty(); - $(".header").empty(); - $(".subheader").empty(); - } - - if(event.data.action == "keyup"){ - if($(".item").length > 1) { - let active = $(".active").removeClass("active"); - - if(active.prev().length != 0 && active.prev().css("display") == "none"){ - $(".list").find(".item:visible:last").hide(); - active.prev().show(); - } - - if(active.prev().length == 0) { - active.siblings().last().addClass("active"); - $(".item").hide(); - $(".item").slice(-10).show(); - } else { - active.prev().addClass("active"); - } - } - } - - if(event.data.action == "keydown") { - if($(".item").length > 1) { - let active = $(".active").removeClass("active"); - - if(active.next().length != 0 && active.next().css("display") == "none"){ - $(".list").find(".item:visible:first").hide(); - active.next().show(); - } - - if(active.next().length == 0) { - active.siblings().first().addClass("active"); - $(".item").hide(); - $(".item").slice(0, 10).show(); - } else { - active.next().addClass("active"); - } - } - } - - if(event.data.action == "keyenter"){ - let action = $(".active").attr("function"); - let params = $(".active").attr("params"); - $.post('http://police/sendAction', JSON.stringify({ - action: action, - params: params - })); - } - }); -}); \ No newline at end of file diff --git a/resources/police/client/i18n.lua b/resources/police/client/i18n.lua deleted file mode 100644 index fd6cec2f9..000000000 --- a/resources/police/client/i18n.lua +++ /dev/null @@ -1,42 +0,0 @@ -i18n = setmetatable({}, i18n) -i18n.__index = i18n - -local store = {} -local lang = {} -avalLangs = {} - -function i18n.setup(l) - - if(l ~= nil)then - lang = l - end - -end - -function i18n.exportData() - local result = store - return result -end - -function i18n.importData(l,s) - table.insert( avalLangs, l) - store[l] = s -end - -function i18n.setLang(l) - lang = l -end - -function i18n.translate(key) - local result = "" - if(store == nil) then - result = "Error 502 : no translation available !" - else - result = store[lang][key] - if(result == nil) then - result = "Error 404 : key not found !" - end - end - - return result -end \ No newline at end of file diff --git a/resources/police/client/menu.lua b/resources/police/client/menu.lua deleted file mode 100644 index dfc5781b2..000000000 --- a/resources/police/client/menu.lua +++ /dev/null @@ -1,484 +0,0 @@ ---[[ - Cops_FiveM - A cops script for FiveM RP servers. - Copyright (C) 2018 FiveM-Scripts - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero 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 Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with Cops_FiveM in the file "LICENSE". If not, see . -]] - -local buttonsCategories = {} -local buttonsAnimation = {} -local buttonsCitizen = {} -local buttonsFine = {} -local buttonsVehicle = {} -local buttonsProps = {} - -function load_menu() - for k in ipairs (buttonsCategories) do - buttonsCategories [k] = nil - end - - for k in ipairs (buttonsAnimation) do - buttonsAnimation [k] = nil - end - - for k in ipairs (buttonsCitizen) do - buttonsCitizen [k] = nil - end - - for k in ipairs (buttonsFine) do - buttonsFine [k] = nil - end - - for k in ipairs (buttonsVehicle) do - buttonsVehicle [k] = nil - end - - for k in ipairs (buttonsProps) do - buttonsProps [k] = nil - end - - --Categories - buttonsCategories[#buttonsCategories+1] = {name = GetLabelText("CRW_ANIMATION"), func = "OpenAnimMenu", params = ""} - buttonsCategories[#buttonsCategories+1] = {name = GetLabelText("collision_c29ovv"), func = "OpenCitizenMenu", params = ""} - buttonsCategories[#buttonsCategories+1] = {name = GetLabelText("PIM_TVEHI"), func = "OpenVehMenu", params = ""} - buttonsCategories[#buttonsCategories+1] = {name = GetLabelText("collision_9o6rwvf"), func = "OpenPropsMenu", params = ""} - - --Animations - buttonsAnimation[#buttonsAnimation+1] = {name = i18n.translate("menu_anim_do_traffic_title"), func = 'DoTraffic', params = ""} - buttonsAnimation[#buttonsAnimation+1] = {name = i18n.translate("menu_anim_take_notes_title"), func = 'Note', params = ""} - buttonsAnimation[#buttonsAnimation+1] = {name = i18n.translate("menu_anim_standby_title"), func = 'StandBy', params = ""} - buttonsAnimation[#buttonsAnimation+1] = {name = i18n.translate("menu_anim_standby_2_title"), func = 'StandBy2', params = ""} - buttonsAnimation[#buttonsAnimation+1] = {name = i18n.translate("menu_anim_Cancel_emote_title"), func = 'CancelEmote', params = ""} - - --Citizens - buttonsCitizen[#buttonsCitizen+1] = {name = i18n.translate("menu_weapons_title"), func = 'RemoveWeapons', params = ""} - buttonsCitizen[#buttonsCitizen+1] = {name = i18n.translate("menu_toggle_cuff_title"), func = 'ToggleCuff', params = ""} - buttonsCitizen[#buttonsCitizen+1] = {name = i18n.translate("menu_force_player_get_in_car_title"), func = 'PutInVehicle', params = ""} - buttonsCitizen[#buttonsCitizen+1] = {name = i18n.translate("menu_force_player_get_out_car_title"), func = 'UnseatVehicle', params = ""} - buttonsCitizen[#buttonsCitizen+1] = {name = i18n.translate("menu_drag_player_title"), func = 'DragPlayer', params = ""} - buttonsCitizen[#buttonsCitizen+1] = {name = i18n.translate("menu_fines_title"), func = 'OpenMenuFine', params = ""} - - --Fines - buttonsFine[#buttonsFine+1] = {name = "$250", func = 'Fines', params = 250} - buttonsFine[#buttonsFine+1] = {name = "$500", func = 'Fines', params = 500} - buttonsFine[#buttonsFine+1] = {name = "$1000", func = 'Fines', params = 1000} - buttonsFine[#buttonsFine+1] = {name = "$1500", func = 'Fines', params = 1500} - buttonsFine[#buttonsFine+1] = {name = "$2000", func = 'Fines', params = 2000} - buttonsFine[#buttonsFine+1] = {name = "$4000", func = 'Fines', params = 4000} - buttonsFine[#buttonsFine+1] = {name = "$6000", func = 'Fines', params = 6000} - buttonsFine[#buttonsFine+1] = {name = "$8000", func = 'Fines', params = 8000} - buttonsFine[#buttonsFine+1] = {name = "$10000", func = 'Fines', params = 10000} - buttonsFine[#buttonsFine+1] = {name = i18n.translate("menu_custom_amount_fine_title"), func = 'Fines', params = -1} - - -- vehicles - buttonsVehicle[#buttonsVehicle+1] = {name = i18n.translate("menu_crochet_veh_title"), func = 'Crochet', params = ""} - buttonsVehicle[#buttonsVehicle+1] = {name = GetLabelText("FMMC_REMVEH"), func = 'DropVehicle', params = ""} - buttonsVehicle[#buttonsVehicle+1] = {name = "Spike Stripes", func = 'SpawnSpikesStripe', params = ""} - - --Props - for k,v in pairs(SpawnObjects) do - buttonsProps[#buttonsProps+1] = {name = v.name, func = "SpawnProps", params = tostring(v.hash)} - end - - buttonsProps[#buttonsProps+1] = {name=GetLabelText("FMMC_PR_23"), func = "SpawnProps", params="prop_mp_barrier_01b"} - buttonsProps[#buttonsProps+1] = {name=GetLabelText("FMMC_PR_BARQADB"), func = "SpawnProps", params="prop_barrier_work05"} - buttonsProps[#buttonsProps+1] = {name=GetLabelText("FMMC_DPR_LTRFCN"), func = "SpawnProps", params="prop_air_conelight"} - buttonsProps[#buttonsProps+1] = {name=GetLabelText("FMMC_PR_PBARR"), func = "SpawnProps", params="prop_barrier_work06a"} - buttonsProps[#buttonsProps+1] = {name=GetLabelText("FMMC_PR_CABTBTH"), func = "SpawnProps", params="prop_tollbooth_1"} - buttonsProps[#buttonsProps+1] = {name=GetLabelText("FMMC_DPR_TRFCNE"), func = "SpawnProps", params="prop_mp_cone_01"} - buttonsProps[#buttonsProps+1] = {name=GetLabelText("FMMC_DPR_TRFPLE"), func = "SpawnProps", params="prop_mp_cone_04"} - - buttonsProps[#buttonsProps+1] = {name = GetLabelText("collision_7x5xu9w"), func = "RemoveLastProps", params = ""} - buttonsProps[#buttonsProps+1] = {name = GetLabelText("FMMC_REMOBJ"), func = "RemoveAllProps", params = ""} -end - -function DoTraffic() - Citizen.CreateThread(function() - if not IsPedInAnyVehicle(PlayerPedId(), false) then - TaskStartScenarioInPlace(PlayerPedId(), "WORLD_HUMAN_CAR_PARK_ATTENDANT", 0, false) - Citizen.Wait(60000) - ClearPedTasksImmediately(PlayerPedId()) - drawNotification(i18n.translate("menu_doing_traffic_notification")) - else - drawNotification(GetLabelText("PEN_EXITV")) - end - end) -end - -function Note() - Citizen.CreateThread(function() - if not IsPedInAnyVehicle(PlayerPedId(), false) then - TaskStartScenarioInPlace(PlayerPedId(), "WORLD_HUMAN_CLIPBOARD", 0, false) - Citizen.Wait(20000) - ClearPedTasksImmediately(PlayerPedId()) - else - drawNotification(GetLabelText("PEN_EXITV")) - end - end) -end - -function StandBy() - Citizen.CreateThread(function() - if not IsPedInAnyVehicle(PlayerPedId(), false) then - TaskStartScenarioInPlace(PlayerPedId(), "WORLD_HUMAN_COP_IDLES", 0, true) - Citizen.Wait(20000) - ClearPedTasksImmediately(PlayerPedId()) - else - drawNotification(GetLabelText("PEN_EXITV")) - end - end) -end - -function StandBy2() - Citizen.CreateThread(function() - if not IsPedInAnyVehicle(PlayerPedId(), false) then - TaskStartScenarioInPlace(PlayerPedId(), "WORLD_HUMAN_GUARD_STAND", 0, 1) - Citizen.Wait(20000) - ClearPedTasksImmediately(PlayerPedId()) - else - drawNotification(GetLabelText("PEN_EXITV")) - end - end) -end - -function CancelEmote() - Citizen.CreateThread(function() - ClearPedTasksImmediately(PlayerPedId()) - end) -end - -function CheckInventory() - local t, distance = GetClosestPlayer() - if(distance ~= -1 and distance < 3) then - TriggerServerEvent("police:targetCheckInventory", GetPlayerServerId(t)) - else - drawNotification(i18n.translate("no_player_near_ped")) - end -end - -function RemoveWeapons() - local t, distance = GetClosestPlayer() - if(distance ~= -1 and distance < 3) then - TriggerServerEvent("police:removeWeapons", GetPlayerServerId(t)) - else - drawNotification(i18n.translate("no_player_near_ped")) - end -end - -function ToggleCuff() - local t, distance = GetClosestPlayer() - if(distance ~= -1 and distance < 3) then - TriggerServerEvent("police:cuffGranted", GetPlayerServerId(t)) - else - drawNotification(i18n.translate("no_player_near_ped")) - end -end - -function PutInVehicle() - local t, distance = GetClosestPlayer() - if(distance ~= -1 and distance < 3) then - local v = GetVehiclePedIsIn(PlayerPedId(), true) - TriggerServerEvent("police:forceEnterAsk", GetPlayerServerId(t), v) - else - drawNotification(i18n.translate("no_player_near_ped")) - end -end - -function UnseatVehicle() - local t, distance = GetClosestPlayer() - if(distance ~= -1 and distance < 3) then - TriggerServerEvent("police:confirmUnseat", GetPlayerServerId(t)) - else - drawNotification(i18n.translate("no_player_near_ped")) - end -end - -function DragPlayer() - local t, distance = GetClosestPlayer() - if(distance ~= -1 and distance < 3) then - TriggerServerEvent("police:dragRequest", GetPlayerServerId(t)) - TriggerEvent("police:notify", "CHAR_ANDREAS", 1, i18n.translate("title_notification"), false, i18n.translate("drag_sender_notification_part_1") .. GetPlayerName(serverTargetPlayer) .. i18n.translate("drag_sender_notification_part_2")) - else - drawNotification(i18n.translate("no_player_near_ped")) - end -end - -function Fines(amount) - local t, distance = GetClosestPlayer() - if(distance ~= -1 and distance < 3) then - Citizen.Trace("Price : "..tonumber(amount)) - if(tonumber(amount) == -1) then - DisplayOnscreenKeyboard(1, "FMMC_KEY_TIP8S", "", "", "", "", "", 20) - while (UpdateOnscreenKeyboard() == 0) do - DisableAllControlActions(0); - Wait(0); - end - if (GetOnscreenKeyboardResult()) then - local res = tonumber(GetOnscreenKeyboardResult()) - if(res ~= nil and res ~= 0) then - amount = tonumber(res) - end - end - - if(tonumber(amount) ~= -1) then - TriggerServerEvent("police:finesGranted", GetPlayerServerId(t), tonumber(amount)) - end - else - TriggerServerEvent("police:finesGranted", GetPlayerServerId(t), tonumber(amount)) - end - else - drawNotification(i18n.translate("no_player_near_ped")) - end -end - -function Crochet() - Citizen.CreateThread(function() - local pos = GetEntityCoords(PlayerPedId()) - local entityWorld = GetOffsetFromEntityInWorldCoords(PlayerPedId(), 0.0, 20.0, 0.0) - - local rayHandle = CastRayPointToPoint(pos.x, pos.y, pos.z, entityWorld.x, entityWorld.y, entityWorld.z, 10, PlayerPedId(), 0) - local _, _, _, _, vehicleHandle = GetRaycastResult(rayHandle) - if DoesEntityExist(vehicleHandle) and IsEntityAVehicle(vehicleHandle) then - local prevObj = GetClosestObjectOfType(pos.x, pos.y, pos.z, 10.0, GetHashKey("prop_weld_torch"), false, true, true) - if(IsEntityAnObject(prevObj)) then - SetEntityAsMissionEntity(prevObj) - DeleteObject(prevObj) - end - - TaskStartScenarioInPlace(PlayerPedId(), "WORLD_HUMAN_WELDING", 0, true) - Citizen.Wait(20000) - SetVehicleDoorsLocked(vehicleHandle, 1) - ClearPedTasksImmediately(PlayerPedId()) - drawNotification(i18n.translate("menu_veh_opened_notification")) - else - drawNotification(i18n.translate("no_veh_near_ped")) - end - end) -end - -function DropVehicle() - Citizen.CreateThread(function() - local pos = GetEntityCoords(PlayerPedId()) - local entityWorld = GetOffsetFromEntityInWorldCoords(PlayerPedId(), 0.0, 20.0, 0.0) - - local rayHandle = CastRayPointToPoint(pos.x, pos.y, pos.z, entityWorld.x, entityWorld.y, entityWorld.z, 10, PlayerPedId(), 0) - local _, _, _, _, vehicleHandle = GetRaycastResult(rayHandle) - if DoesEntityExist(vehicleHandle) and IsEntityAVehicle(vehicleHandle) then - DeleteEntity(vehicleHandle) - else - drawNotification(i18n.translate("no_veh_near_ped")) - end - end) -end - -function SpawnSpikesStripe() - if IsPedInAnyPoliceVehicle(PlayerPedId()) then - local modelHash = GetHashKey("P_ld_stinger_s") - local currentVeh = GetVehiclePedIsIn(PlayerPedId(), false) - local x,y,z = table.unpack(GetOffsetFromEntityInWorldCoords(currentVeh, 0.0, -5.2, -0.25)) - - RequestScriptAudioBank("BIG_SCORE_HIJACK_01", true) - Citizen.Wait(500) - - RequestModel(modelHash) - while not HasModelLoaded(modelHash) do - Citizen.Wait(0) - end - - if HasModelLoaded(modelHash) then - SpikeObject = CreateObject(modelHash, x, y, z, true, false, true) - SetEntityNoCollisionEntity(SpikeObject, PlayerPedId(), 1) - SetEntityDynamic(SpikeObject, false) - ActivatePhysics(SpikeObject) - - if DoesEntityExist(SpikeObject) then - local height = GetEntityHeightAboveGround(SpikeObject) - - SetEntityCoords(SpikeObject, x, y, z - height + 0.05) - SetEntityHeading(SpikeObject, GetEntityHeading(PlayerPedId())-80.0) - SetEntityCollision(SpikeObject, false, false) - PlaceObjectOnGroundProperly(SpikeObject) - - SetEntityAsMissionEntity(SpikeObject, false, false) - SetModelAsNoLongerNeeded(modelHash) - PlaySoundFromEntity(-1, "DROP_STINGER", PlayerPedId(), "BIG_SCORE_3A_SOUNDS", 0, 0) - end - drawNotification("Spike stripe~g~ deployed~w~.") - end - else - drawNotification("You need to get ~y~inside~w~ a ~y~police vehicle~w~.") - PlaySoundFrontend(-1, "ERROR", "HUD_FRONTEND_DEFAULT_SOUNDSET", true) - end -end - -function DeleteSpike() - local model = GetHashKey("P_ld_stinger_s") - local x,y,z = table.unpack(GetEntityCoords(PlayerPedId(), true)) - - if DoesObjectOfTypeExistAtCoords(x, y, z, 0.9, model, true) then - local spike = GetClosestObjectOfType(x, y, z, 0.9, model, false, false, false) - DeleteObject(spike) - end -end - -local propslist = {} - -function SpawnProps(model) - if(#propslist < config.propsSpawnLimitByCop) then - local prophash = GetHashKey(tostring(model)) - RequestModel(prophash) - while not HasModelLoaded(prophash) do - Citizen.Wait(0) - end - - local offset = GetOffsetFromEntityInWorldCoords(PlayerPedId(), 0.0, 0.75, 0.0) - local _, worldZ = GetGroundZFor_3dCoord(offset.x, offset.y, offset.z) - local propsobj = CreateObjectNoOffset(prophash, offset.x, offset.y, worldZ, true, true, true) - local heading = GetEntityHeading(PlayerPedId()) - - SetEntityHeading(propsobj, heading) - SetEntityAsMissionEntity(propsobj) - SetModelAsNoLongerNeeded(prophash) - - propslist[#propslist+1] = ObjToNet(propsobj) - end -end - -function RemoveLastProps() - DeleteObject(NetToObj(propslist[#propslist])) - propslist[#propslist] = nil -end - -function RemoveAllProps() - for i, props in pairs(propslist) do - DeleteObject(NetToObj(props)) - propslist[i] = nil - end - -end - -function TogglePoliceMenu() - if((anyMenuOpen.menuName ~= "policemenu" and anyMenuOpen.menuName ~= "policemenu-anim" and anyMenuOpen.menuName ~= "policemenu-citizens" and anyMenuOpen.menuName ~= "policemenu-veh" and anyMenuOpen.menuName ~= "policemenu-fines" and anyMenuOpen.menuName ~= "policemenu-props") and not anyMenuOpen.isActive) then - SendNUIMessage({ - title = i18n.translate("menu_global_title"), - subtitle = GetLabelText("PM_MP_OPTIONS"), - buttons = buttonsCategories, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "policemenu" - anyMenuOpen.isActive = true - else - if((anyMenuOpen.menuName ~= "policemenu" and anyMenuOpen.menuName ~= "policemenu-anim" and anyMenuOpen.menuName ~= "policemenu-citizens" and anyMenuOpen.menuName ~= "policemenu-veh" and anyMenuOpen.menuName ~= "policemenu-fines" and anyMenuOpen.menuName ~= "policemenu-props") and anyMenuOpen.isActive) then - CloseMenu() - TogglePoliceMenu() - else - CloseMenu() - end - end -end - -function BackMenuPolice() - if(anyMenuOpen.menuName == "policemenu-anim" or anyMenuOpen.menuName == "policemenu-citizens" or anyMenuOpen.menuName == "policemenu-veh" or anyMenuOpen.menuName == "policemenu-props") then - CloseMenu() - TogglePoliceMenu() - else - CloseMenu() - OpenCitizenMenu() - end -end - -function OpenAnimMenu() - CloseMenu() - SendNUIMessage({ - title = i18n.translate("menu_global_title"), - subtitle = GetLabelText("CRW_ANIMATION"), - buttons = buttonsAnimation, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "policemenu-anim" - anyMenuOpen.isActive = true -end - -function OpenCitizenMenu() - CloseMenu() - SendNUIMessage({ - title = i18n.translate("menu_global_title"), - subtitle = GetLabelText("collision_c29ovv"), - buttons = buttonsCitizen, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "policemenu-citizens" - anyMenuOpen.isActive = true -end - -function OpenVehMenu() - CloseMenu() - SendNUIMessage({ - title = i18n.translate("menu_global_title"), - subtitle = GetLabelText("PIM_TVEHI"), - buttons = buttonsVehicle, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "policemenu-veh" - anyMenuOpen.isActive = true -end - -function OpenMenuFine() - CloseMenu() - SendNUIMessage({ - title = i18n.translate("menu_global_title"), - subtitle = GetLabelText("PM_MP_OPTIONS"), - buttons = buttonsFine, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "policemenu-fines" - anyMenuOpen.isActive = true -end - -function OpenPropsMenu() - CloseMenu() - SendNUIMessage({ - title = i18n.translate("menu_global_title"), - subtitle = GetLabelText("collision_9o6rwvf"), - buttons = buttonsProps, - action = "setAndOpen" - }) - - anyMenuOpen.menuName = "policemenu-props" - anyMenuOpen.isActive = true -end - -Citizen.CreateThread(function() - while true do - Citizen.Wait(5) - for _, props in pairs(propslist) do - local ox, oy, oz = table.unpack(GetEntityCoords(NetToObj(props), true)) - local cVeh = GetClosestVehicle(ox, oy, oz, 20.0, 0, 70) - if(IsEntityAVehicle(cVeh)) then - if IsEntityAtEntity(cVeh, NetToObj(props), 3.0, 5.0, 2.0, 0, 1, 0) then - local cDriver = GetPedInVehicleSeat(cVeh, -1) - TaskVehicleTempAction(cDriver, cVeh, 6, 1000) - - SetVehicleHandbrake(cVeh, true) - SetVehicleIndicatorLights(cVeh, 0, true) - SetVehicleIndicatorLights(cVeh, 1, true) - end - end - - end - end -end) \ No newline at end of file diff --git a/resources/police/config/cloackroom.lua b/resources/police/config/cloackroom.lua deleted file mode 100644 index 99203d3fe..000000000 --- a/resources/police/config/cloackroom.lua +++ /dev/null @@ -1,32 +0,0 @@ -skins = { - [0] = { - {name="LSPD Officer", model="s_m_y_cop_01"}, - {name="SWAT Unit", model="BritishArmed"}, - {name="Biker Unit", model="s_m_y_hwaycop_01"}, - {name="High-Speed Unit", model="CSGOfbib"}, - {name="Prison Guard", model="s_m_m_prisguard_01"}, - {name="Undercover", model="s_m_y_cop_01"} - }, - [1] = { - {name="BCSO Sheriff", model="s_m_y_cop_01"}, - {name="SWAT Unit", model="BritishArmed"}, - {name="Biker Unit", model="s_m_y_hwaycop_01"}, - {name="High-Speed Unit", model="CSGOfbib"}, - {name="Prison Guard", model="s_m_m_prisguard_01"}, - {name="Undercover", model="s_m_y_cop_01"} - }, - [2] = { - {name="SASP Officer", model="s_m_y_cop_01"}, - {name="SWAT Unit", model="BritishArmed"}, - {name="Biker Unit", model="s_m_y_hwaycop_01"}, - {name="High-Speed Unit", model="CSGOfbib"}, - {name="Prison Guard", model="s_m_m_prisguard_01"}, - {name="Undercover", model="s_m_y_cop_01"} - }, - [3] = { - {name="Highway Patrol", model="s_m_y_hwaycop_01"} - }, - [4] = { - {name="Prison Officer", model="s_m_m_prisguard_01"} - } -} \ No newline at end of file diff --git a/resources/police/config/config.lua b/resources/police/config/config.lua deleted file mode 100644 index 10141b287..000000000 --- a/resources/police/config/config.lua +++ /dev/null @@ -1,219 +0,0 @@ -config = { - enableVersionNotifier = true, --notify if a new version is available (server console) - enableOutfits = false, - - stationBlipsEnabled = true, -- switch between true or false to enable/disable blips for police stations - useCopWhitelist = true, - - enableOtherCopsBlips = true, - useNativePoliceGarage = false, - enableNeverWanted = true, - - enablePaychecks = false, - weekly_salary = 931, - - propsSpawnLimitByCop = 25, - - --Available languages : 'en', 'fr', 'de' - lang = 'en', - - bindings = { - interact_position = 51, -- E - use_police_menu = 166, -- F5 - accept_fine = 246, -- Y - refuse_fine = 45 -- R - }, - - --Customizable Departments - departments = { - label = { - [0] = "Los Santos Police Department", - [1] = "Blaine County Sheriff Office", - [2] = "San Andreas State Police", - [3] = "Federal Beauro of Investigation", - [4] = "Prison Department" - }, - - minified_label = { - [0] = "LSPD", - [1] = "BCSO", - [2] = "SASP", - [3] = "FBI", - [4] = "PRISON" - } - }, - - --Customizable ranks - rank = { - - --You can add or remove ranks as you want (just make sure to use numeric index, ascending) - label = { - [0] = "Trainee", -- Ranger Rank - [1] = "Trainee", -- LSPD Rank - [2] = "Trainee", -- Sheriff Rank - [3] = "Trainee", -- State Highway Patrol Rank - - [4] = "Park Ranger", - [5] = "Police Officer", - [6] = "Deputy Sheriff", - [7] = "State Trooper", - - [8] = "Park Ranger II", - [9] = "Master Police Officer", - [10] = "Deputy Sheriff II", - [11] = "State Trooper II", - - [12] = "Sergeant", - [13] = "Sergeant", - [14] = "Sergeant", - [15] = "Sergeant", - - [16] = "Lieutenant", - [17] = "Lieutenant", - [18] = "Lieutenant", - [19] = "Lieutenant", - - [20] = "Captian", - [21] = "Captian", - [22] = "Captian", - [23] = "Captian", - - [24] = "Game Warden ", - [25] = "Chief of Police", - [26] = "Sheriff", - [27] = "Chief of SHP", - - [28] = "Ranger Admin Rank", - [29] = "Police Admin Rank", - [30] = "Sheriff Admin Rank", - [31] = "SHP Admin Rank", - }, - - --Used for chat - minified_label = { - [0] = "TNE", - [1] = "TNE", --1 - [2] = "TNE", - [3] = "TNE", - - [4] = "PR", - [5] = "PO", --2 - [6] = "DS", - [7] = "ST", - - [8] = "PR2", - [9] = "MPO", --3 - [10] = "DS2", - [11] = "ST2", - - [12] = "SGT", - [13] = "SGT", --4 - [14] = "SGT", - [15] = "SGT", - - [16] = "LT", - [17] = "LT", --5 - [18] = "LT", - [19] = "LT", - - [20] = "CPT", - [21] = "CPT", --6 - [22] = "CPT", - [23] = "CPT", - - [24] = "GW", - [25] = "COP", --7 - [26] = "SHF", - [27] = "COS", - - [28] = "RAR", - [29] = "APR", --8 - [30] = "ASR", - [31] = "SSR", - }, - - --You can set here a badge for each rank you have. You have to enable "enableOutfits" to use this - --The index is the rank index, the value is the badge index. - --Here a link where you have the 4 MP Models badges with their index : https://kyominii.com/fivem/index.php/MP_Badges - outfit_badge = { - [0] = 0, - [1] = 0, - [2] = 0, - [3] = 0, - - [4] = 0, - [5] = 0, - [6] = 0, - [7] = 0, - - [8] = 1, - [9] = 1, - [10] = 1, - [11] = 1, - - [12] = 1, - [13] = 1, - [14] = 1, - [15] = 1, - - [16] = 2, - [17] = 2, - [18] = 2, - [19] = 2, - - [20] = 2, - [21] = 2, - [22] = 2, - [23] = 2, - - [24] = 3, - [25] = 3, - [26] = 3, - [27] = 3, - - [28] = 3, - [29] = 3, - [30] = 3, - [31] = 3, - }, - - --Minimum rank require to modify officers rank - min_rank_set_rank = 24 - } -} - -clockInStation = { - {x=850.156677246094, y=-1283.92004394531, z=28.0047378540039}, -- La Mesa - {x=457.956909179688, y=-992.72314453125, z=30.6895866394043}, -- Mission Row - {x=1840.05, y=3690.34, z=34.29}, -- Sandy Shore - {x=-439.6, y=5991.36, z=31.72}, -- Paleto Bay - {x=-1093.0604248046875, y=-808.6140747070312, z=19.28019142150879}, -- Vespucci PD - {x=360.3169860839844, y=-1583.9188232421875, z=29.291934967041016}, -- Davis Sheriff station - {x=117.71, y=-761.21, z=45.75}, -- FIB Building - {x=611.90, y=1.69, z=90.65}, -- Vinewood PD - {x=1539.50, y=810.65, z=77.66} -- SAHP Highway PD -} - -garageStation = { - {x=-470.85266113281, y=6022.9296875, z=31.340530395508}, -- La Mesa - {x=1873.3372802734, y=3687.3508300781, z=33.616954803467}, -- Mission Row - {x=1870.68, y=3692.99, z=33.6}, -- Sandy Shores - {x=855.24249267578, y=-1279.9300537109, z=26.513223648071 }, --Paleto Bay - {x=-1070.1719970703125, y=-854.4666137695312, z=4.8671650886535645 }, -- Vespucci - {x=383.7397766113281, y=-1624.2393798828125, z=29.291946411132812} -- Davis Sheriff station -} - -heliStation = { - {x=449.113966796875, y=-981.084966796875, z=43.691966796875} -- Mission Row -} - -armoryStation = { - {x=452.119966796875, y=-980.061966796875, z=30.690966796875}, -- La Mesa - {x=853.157, y=-1267.74, z= 26.6729}, -- Mission Row - {x=1851.62, y=3696.99, z=34.29}, -- Sandy Shore - {x=-437.65, y= 5989.63, z=31.72}, -- Paleto Bay - -- still need to add vespucci - {x=352.9969177246094, y=-1592.7291259765625, z=29.291934967041016} -- Davis Sheriff station -} - -i18n.setLang(tostring(config.lang)) diff --git a/resources/police/config/objects.lua b/resources/police/config/objects.lua deleted file mode 100644 index 5ea5a5d4c..000000000 --- a/resources/police/config/objects.lua +++ /dev/null @@ -1,4 +0,0 @@ --- Configure the objects that cops can spawn on the map. -SpawnObjects = { - -- {name="Something", hash="prop_mp_barrier_01b"}, -} \ No newline at end of file diff --git a/resources/police/config/vehicles.lua b/resources/police/config/vehicles.lua deleted file mode 100644 index d0265443c..000000000 --- a/resources/police/config/vehicles.lua +++ /dev/null @@ -1,28 +0,0 @@ -vehicles = { - [0] = { - {name="Park Ranger Truck", model="pranger"}, - }, - [1] = { - {name="Police Buffalo", model="police2"}, - {name="Police Stanier", model="police"}, - {name="Police Interceptor", model="police3"}, - {name="Police Motorcycle", model="policeb"}, - {name="Police Transport Van", model="policet"}, - {name="Undercover Police Stanier", model="police4"} - }, - [2] = { - {name="Sheriff Stanier", model="sheriff"}, - {name="Sheriff Granger", model="sheriff2"}, - {name="Police Motorcycle", model="policeb"} - }, - [3] = { - {name="FIB Buffalo", model="fbi"}, - {name="FIB Granger", model="fbi2"}, - {name="Police Buffalo", model="police2"}, - }, - [4] = { - {name="Police Stanier", model="police"}, - {name="Prison Transport Van", model="PBus"}, - {name="Sheriff Stanier", model="sheriff"}, - } -} \ No newline at end of file diff --git a/resources/police/config/weapons.lua b/resources/police/config/weapons.lua deleted file mode 100644 index 322187d85..000000000 --- a/resources/police/config/weapons.lua +++ /dev/null @@ -1,27 +0,0 @@ --- Configure the items that cops receive when they get on duty. -basic_kit = { - "WEAPON_PISTOL", - "WEAPON_COMBATPISTOL", - "WEAPON_STUNGUN", - "WEAPON_NIGHTSTICK", - "WEAPON_FLASHLIGHT", - "WEAPON_CARBINERIFLE", - "WEAPON_SPECIALCARBINE", - "WEAPON_PUMPSHOTGUN", - "WEAPON_SAWNOFFSHOTGUN", - "WEAPON_FIREEXTINGUISHER", - "WEAPON_FLARE" -} - --- Configure the weapons that cops can choose in the armory room. -weapons = { - {name="Assault SMG", hash="WEAPON_ASSAULTSMG"}, - {name="Assault Shotgun", hash="WEAPON_ASSAULTSHOTGUN"}, - {name="Combact Pistol", hash="WEAPON_COMBATPISTOL"}, - {name="Heavy Sniper", hash="WEAPON_HEAVYSNIPER"}, - {name="Micro SMG", hash="WEAPON_MICROSMG"}, - {name="Pistol 50.", hash="WEAPON_PISTOL50"}, - {name="Shotgun", hash="WEAPON_PUMPSHOTGUN"}, - {name="SMG", hash="WEAPON_SMG"}, - {name="Smoke grenade", hash="WEAPON_SMOKEGRENADE"}, -} \ No newline at end of file diff --git a/resources/police/docs/features.md b/resources/police/docs/features.md deleted file mode 100644 index db785ef63..000000000 --- a/resources/police/docs/features.md +++ /dev/null @@ -1,18 +0,0 @@ -# Current Features - -* support ghmattimysql -* configurable (features and language) -* cops whitelist -* take/break service (positions with blips) -* different service mode -* cop garage (vehicle/heli) -* fines (legacy feature) -* cuff/uncuff -* weapons removed (legacy feature) -* force cuffed player to go in the vehicle -* unseat this player (Thanks @Thefoxeur54 ) -* GUI menu with some animations -* cops can see each other blips : (thanks @Scammer -- https://forum.fivem.net/t/release-scammers-script-collection-09-03-17/3313) -* drag players (thanks @Frazzle and others : https://forum.fivem.net/t/release-drag-command/22174) -* ranks (example of use : cloackroom.lua line 12) -* so many other features ... diff --git a/resources/police/docs/scripts.md b/resources/police/docs/scripts.md deleted file mode 100644 index d764687e3..000000000 --- a/resources/police/docs/scripts.md +++ /dev/null @@ -1,3 +0,0 @@ -# Supported scripts -* [ghmattimysql](https://github.com/GHMatti/ghmattimysql) -* [Venomous Freemode](https://github.com/FiveM-Scripts/venomous-freemode) diff --git a/resources/police/fxmanifest.lua b/resources/police/fxmanifest.lua deleted file mode 100644 index 3a040af84..000000000 --- a/resources/police/fxmanifest.lua +++ /dev/null @@ -1,40 +0,0 @@ -fx_version 'bodacious' -game 'gta5' -version '1.5.1' - -ui_page('client/html/index.html') - -files({ - 'client/html/index.html', - 'client/html/js/script.js', - 'client/html/css/style.css', - 'client/html/img/background.png', - 'client/html/img/arrows_upanddown.jpg', - 'client/html/fonts/SignPainter-HouseScript.ttf' -}) - -client_scripts { - 'client/i18n.lua', - 'locales/en.lua', - 'locales/fr.lua', - 'locales/de.lua', - 'config/cloackroom.lua', - 'config/config.lua', - 'config/objects.lua', - 'config/vehicles.lua', - 'config/weapons.lua', - 'client/client.lua', - 'client/cloackroom.lua', - 'client/menu.lua', - 'client/garage.lua', - 'client/armory.lua' - } - -server_scripts { - 'client/i18n.lua', - 'locales/en.lua', - 'locales/fr.lua', - 'locales/de.lua', - 'config/config.lua', - 'server/server.lua' -} diff --git a/resources/police/locales/de.lua b/resources/police/locales/de.lua deleted file mode 100644 index 0bdada070..000000000 --- a/resources/police/locales/de.lua +++ /dev/null @@ -1,139 +0,0 @@ -i18n.importData("de", { - police_station = "Polizeistation", - title_notification = "Regierung", - now_cuffed = "Dir wurden die Handschellen angelegt !", - now_uncuffed = "Freiheit !", - info_fine_request_before_amount = "Drücke ~g~Y~s~ um das Strafgeld zu akzeptieren $", - info_fine_request_after_amount = " , drücke ~r~R~s~ um es zu verweigern !", - request_fine_expired = "Die Strafgeld Anfrage ist ~r~abgelaufen~s~ !", - pay_fine_success_before_amount = "Du hast gerade $", - pay_fine_success_after_amount = " Strafgeld gezahlt.", - help_text_open_cloackroom = "Drücke ~INPUT_CONTEXT~ um die ~b~Polizei Garderobe zu öffnen", - help_text_put_car_into_garage = "Drücke ~INPUT_CONTEXT~ um das Polizei Auto in die ~b~Garage zu parken", - help_text_get_car_out_garage = "Drücke ~INPUT_CONTEXT~ um das Polizei Auto aus der ~b~Garage zu nehmen", - help_text_put_heli_into_garage = "Drücke ~INPUT_CONTEXT~ um den Hubschrauber in die ~b~Garage zu parken", - help_text_get_heli_out_garage = "Drücke ~INPUT_CONTEXT~ um den Hubschrauber aus der ~b~Garage zu nehmen", - no_player_near_ped = "Kein Spieler in der Nähe", - no_veh_near_ped = "Kein Fahrzeug in der Nähe", - cop_whitelist_disabled = "Cop whitelist is disable, please enable the whitelist to use this command !", - - menu_id_card_title = "ID Karte", - menu_check_inventory_title = "Kontrolliere das Inventar", - menu_toggle_cuff_title = "Handschellen anglegen/abnehmen", - menu_weapons_title = "Waffe beschlagnahmen", - menu_force_player_get_in_car_title = "Ins Fahrzeug befördern", - menu_force_player_get_out_car_title = "Aus dem Fahrzeug ziehen", - menu_drag_player_title = "Den Spieler tragen", - menu_fines_title = "Strafgeld", - menu_check_plate_title = "Kennzeichen kontrollieren", - menu_crochet_veh_title = "Fahrzeug aufbrechen", - menu_global_title = "Polizei Menu", - menu_categories_title = "Kategorien", - menu_animations_title = "Animationen", - menu_citizens_title = "Bürger", - menu_vehicles_title = "Fahrzeuge", - menu_close_menu_title = "Schließe das Menu", - menu_anim_do_traffic_title = "Mach einen auf Traffik Polizisten", - menu_anim_take_notes_title = "Nimm Notizen", - menu_anim_standby_title = "Bereit stehen", - menu_anim_standby_2_title = "Bereit stehen 2", - menu_anim_Cancel_emote_title = "Abbrechen emote", - - menu_custom_amount_fine_title = "Benutzerdefinierte anzahl", - menu_doing_traffic_notification = "~g~Du machst einen auf Traffik Polizisten.", - menu_taking_notes_notification = "~g~Du bist am Notizen schreiben.", - menu_being_stand_by_notification = "~g~Du stehst bereit.", - menu_veh_opened_notification = "Das Fahrzeug ist jetzt ~g~offen~w~.", - - menu_put_in_jail_title = "Ins Gefängis bringen", - menu_arrest_title = "Verhaften", - menu_custom_amount_jail_title = "Benutzerdefinierte anzahl an Sekunden", - jail_notification_title = "^4[JAIL]", - jail_arrest_notification_part_1 = "Du wurdest verhaftet für ^1", -- send to the client after he got puted into the jail - jail_arrest_notification_part_2 = " ^0Sekunden!", - jail_weapons_removed = "Deine Waffen wurden entfernt weil du verhaftet wurdest!", - jail_not_cuffed = "Der Spieler muss an Handschellen gefässelt sein!", - jail_remove_weapons_notification_part_1 = "Alle Waffen vom ", - jail_remove_weapons_notification_part_2 = " wurden entfernt.", - menu_delete_vehicle_title = "Fahrzeug Löschen", - - garage_global_title = "Polizei Garage", - garage_loading = "~b~Laden...", - - cloackroom_global_title = "Polizei Garderobe", - cloackroom_take_service_ranger_title = "Clock in as Park Ranger", - cloackroom_take_service_sheriff_title = "Clock in as Sheriff", - cloackroom_take_service_chp_title = "Clock in as State Trooper", - cloackroom_take_service_prison_title = "Clock in as a Prison Guard", - cloackroom_take_service_normal_title = "Dienst beginnen (Uniformed Officer)", - cloackroom_take_service_hidden_title = "Dienst beginnen (Undercover)", - cloackroom_take_service_swat_title = "Dienst beginnen (SWAT)", - cloackroom_break_service_title = "Dienst abbrechen", - cloackroom_add_bulletproof_vest_title = "Schußsichere Weste anlegen", - cloackroom_remove_bulletproof_vest_title = "Schußsichere Weste entfernen", - cloackroom_add_yellow_vest_title = "Gelbe Warnweste anlegen", - cloackroom_remove_yellow_vest_title = "Gelbe Warnweste entfernen", - now_in_service_notification = "Du bist nun im ~g~Dienst", - break_service_notification = "Du hast deinen ~r~Dienst abgebrochen", - help_open_menu_notification = "Drücke ~g~F5~w~ um das ~b~Polizei Menu ~w~zu öffnen", - - menu_props_title = "Objects", - menu_spawn_props_title = "Laichen ein props", - menu_spawn_barrier_title = "Spawn a police barrier", - menu_spawn_work_ahead_barrier_title = "Spawn work ahead barrier", - menu_remove_last_props_title = "Entfernen letzte props", - menu_remove_all_props_title = "Entfernen alle props", - removed_prop = "Object has been ~g~removed~w~.", - removed_props = "Objects have been ~g~removed~w~.", - - vehicle_checking_plate_part_1 = "Das Fahrzeug #", -- before number plate - vehicle_checking_plate_part_2 = " gehört ", -- between number plate and player name when veh registered - vehicle_checking_plate_part_3 = "", -- after player name when veh registered - vehicle_checking_plate_not_registered = " ist nicht Registriert !", -- after player name - unseat_sender_notification_part_1 = "", -- before player name - unseat_sender_notification_part_2 = " ist Raus !", -- after player name - drag_sender_notification_part_1 = "Tragen ", -- before player name - drag_sender_notification_part_2 = "", -- after player name - checking_inventory_part_1 = "", - checking_inventory_part_2 = " sein Inventar : ", - checking_weapons_part_1 = "", - checking_weapons_part_2 = " seine Waffen : ", - send_fine_request_part_1 = "Strafgeld Anfrage von $", - send_fine_request_part_2 = " wurde an folgenden Spieler gesendet ", - already_have_a_pendind_fine_request = " hat bereits eine Strafgeld Anfrage ausstehend", - request_fine_timeout = " hat nicht auf die Strafgeld Anfrage reagiert", - request_fine_refused = " hat die Strafgeld Anfrage verweigert", - request_fine_accepted = " hat das Strafgeld bezahlt", - toggle_cuff_player_part_1 = "Versuche Handschellen anzulegen am Spieler ", - toggle_cuff_player_part_2 = "", - force_player_get_in_vehicle_part_1 = "Versuche ", - force_player_get_in_vehicle_part_2 = " in das Fahrzeug zu befördern", - usage_command_copadd = "Benutze : /copadd [ID]", - usage_command_coprem = "Benutze : /coprem [ID]", - usage_command_coprank = "Benutze : /coprank [ID] [RANK]", - command_received = "Roger that !", - become_cop_success = "Herzlichen Glückwunsch, Sie sind nun ein Polizist !~w~", - remove_from_cops = "Sie sind kein Polizist mehr !~w~.", - no_player_with_this_id = "Kein Spieler mit folgender ID gefunden !", - not_enough_permission = "Du hast nicht die benötigten Rechte um diesen Befehl auszuführen !", - new_dept = "Congrats, you are now part of the", - same_dept = "That's the same department!", - new_rank = "Congrats, you are now : ", - player_not_cop = "This player isn't a cop", - rank_not_exist = "This rank doesn't exist", - dept_not_exist = "This department doesn't exist", - - armory_global_title = "Polizei Waffenkammer", - help_text_open_armory = "Drücke ~INPUT_CONTEXT~ um die Polizei Waffenkammer zu öffnen", - armory_add_bulletproof_vest_title = "Schußsichere Weste anlegen", - armory_remove_bulletproof_vest_title = "Schußsichere Weste entfernen", - armory_weapons_list = "Waffen auswählen", - armory_basic_kit = "Standart Polizei Kit", - - WEAPON_COMBATPISTOL = "Combat Pistol", - WEAPON_PISTOL50 = "Pistol 50.", - WEAPON_PUMPSHOTGUN = "Shotgun", - WEAPON_ASSAULTSHOTGUN = "Assault Shotgun", - WEAPON_ASSAULTSMG = "Assault SMG", - WEAPON_HEAVYSNIPER = "Heavy Sniper" -}) \ No newline at end of file diff --git a/resources/police/locales/en.lua b/resources/police/locales/en.lua deleted file mode 100644 index 47464cbdc..000000000 --- a/resources/police/locales/en.lua +++ /dev/null @@ -1,122 +0,0 @@ -i18n.importData("en", { - police_station = "Police Station", - title_notification = "Government", - now_cuffed = "You've been hand cuffed!", - now_uncuffed = "Freedom!", - info_fine_request_before_amount = "Press ~g~Y~s~ to accept the $", - info_fine_request_after_amount = " fine, press ~r~R~s~ to refuse !", - request_fine_expired = "The fine request has just ~r~expired~s~ !", - pay_fine_success_before_amount = "You have just paid a fine or summons of $", - pay_fine_success_after_amount = " fine.", - help_text_open_cloackroom = "Press ~INPUT_CONTEXT~ to open the ~b~", - help_text_put_car_into_garage = "Press ~INPUT_CONTEXT~ to put the police vehicle into the ~b~garage", - help_text_get_car_out_garage = "Press ~INPUT_CONTEXT~ to get a police vehicle out of the ~b~garage", - help_text_put_heli_into_garage = "Press ~INPUT_CONTEXT~ to put the helicopter into the ~b~garage", - help_text_get_heli_out_garage = "Press ~INPUT_CONTEXT~ to get an helicopter out of the ~b~garage", - no_player_near_ped = "No players near you", - no_veh_near_ped = "No vehicles near you", - cop_whitelist_disabled = "Cop whitelist is disable, please enable the whitelist to use this command !", - menu_id_card_title = "ID Card", - menu_check_inventory_title = "Check Inventory", - menu_toggle_cuff_title = "Toggle Hand-Cuffs", - menu_weapons_title = "Confiscate weapons", - menu_force_player_get_in_car_title = "Put player in vehicle!", - menu_force_player_get_out_car_title = "Get player out of vehicle!", - menu_drag_player_title = "Drag the player forcefully", - menu_fines_title = "Fines and Summons", - menu_check_plate_title = "Run Plates", - menu_crochet_veh_title = "Lockpick car", - menu_global_title = "Police Menu", - menu_categories_title = "Categories", - menu_animations_title = "Animations", - menu_citizens_title = "Citizens", - menu_vehicles_title = "Vehicles", - menu_close_menu_title = "Close the menu", - menu_anim_do_traffic_title = "Do a traffic stop", - menu_anim_take_notes_title = "Take notes", - menu_anim_standby_title = "Stand By", - menu_anim_standby_2_title = "Stand By 2", - menu_anim_Cancel_emote_title = "Cancel emote", - menu_custom_amount_fine_title = "Custom amount", - menu_doing_traffic_notification = "~g~You're now running a traffic stop.", - menu_taking_notes_notification = "~g~You're taking notes.", - menu_being_stand_by_notification = "~g~You're awaiting orders.", - menu_veh_opened_notification = "The vehicle is ~g~open~w~.", - menu_put_in_jail_title = "Put in jail", - menu_arrest_title = "Arrest", - menu_custom_amount_jail_title = "Custom amount in seconds", - menu_delete_vehicle_title = "Delete Vehicle", - jail_notification_title = "^4[JAIL]", - jail_arrest_notification_part_1 = "You got Arrested for ^1", -- send to the client after he got put into the jail - jail_arrest_notification_part_2 = " ^0seconds!", - jail_weapons_removed = "Your Weapons have been removed for being Arrested!", - jail_not_cuffed = "Player need to be cuffed!", - jail_remove_weapons_notification_part_1 = "All the weapons from ", - jail_remove_weapons_notification_part_2 = " got removed.", - garage_global_title = "Police garage", - garage_loading = "~b~Loading...", - cloackroom_global_title = "Police's Cloackroom", - cloackroom_take_service_ranger_title = "Clock in as Park Ranger", - cloackroom_take_service_normal_title = "Clock in as Officer", - cloackroom_take_service_sheriff_title = "Clock in as Sheriff", - cloackroom_take_service_chp_title = "Clock in as State Trooper", - cloackroom_take_service_prison_title = "Clock in as a Prison Guard", - cloackroom_take_service_hidden_title = "Clock in as Detective", - cloackroom_take_service_swat_title = "Clock in as S.W.A.T", - cloackroom_break_service_title = "Clock out", - cloackroom_add_yellow_vest_title = "Put on a yellow vest", - cloackroom_remove_yellow_vest_title = "Remove your yellow vest", - now_in_service_notification = "You've just ~g~clocked in", - break_service_notification = "You've just ~r~clocked out", - help_open_menu_notification = "Press ~g~F5~w~ to open ~b~the police menu", - menu_props_title = "Objects", - menu_spawn_props_title = "Spawn a cone", - menu_spawn_barrier_title = "Spawn a police barrier", - menu_spawn_work_ahead_barrier_title = "Spawn work ahead barrier", - menu_remove_last_props_title = "Remove last props", - menu_remove_all_props_title = "Remove all props", - removed_prop = "Object has been ~g~removed~w~.", - removed_props = "Objects have been ~g~removed~w~.", - vehicle_checking_plate_part_1 = "The vehicle #", -- before number plate - vehicle_checking_plate_part_2 = " belongs to ", -- between number plate and player name when veh registered - vehicle_checking_plate_part_3 = "", -- after player name when veh registered - vehicle_checking_plate_not_registered = " isn't registered!", -- after player name - unseat_sender_notification_part_1 = "", -- before player name - unseat_sender_notification_part_2 = " has escaped!", -- after player name - drag_sender_notification_part_1 = "Dragging ", -- before player name - drag_sender_notification_part_2 = "", -- after player name - checking_inventory_part_1 = "", - checking_inventory_part_2 = "'s inventory : ", - checking_weapons_part_1 = "", - checking_weapons_part_2 = "'s weapons : ", - send_fine_request_part_1 = "Tell the player to pay a $", - send_fine_request_part_2 = " fine request to ", - already_have_a_pendind_fine_request = " already has a pending fine request", - request_fine_timeout = " hasn't answered to the fine request", - request_fine_refused = " has refused to pay thier fine", - request_fine_accepted = " has paid the fine", - toggle_cuff_player_part_1 = "Trying to toggle cuff to ", - toggle_cuff_player_part_2 = "", - force_player_get_in_vehicle_part_1 = "Trying to force ", - force_player_get_in_vehicle_part_2 = " to enter the vehicle", - usage_command_copadd = "Usage: /copadd [ID]", - usage_command_coprem = "Usage: /coprem [ID]", - usage_command_coprank = "Usage: /coprank [ID] [RANK]", - command_received = "Roger that !", - become_cop_success = "Welcome to the Force!~w~", - remove_from_cops = "You've been fired !~w~.", - no_player_with_this_id = "No player with this ID!", - not_enough_permission = "You don't have the permission to execute this task.", - new_dept = "Congrats, you are now part of the", - same_dept = "That's the same department!", - new_rank = "Congrats, you are now: ", - player_not_cop = "This player isn't a cop", - rank_not_exist = "This rank doesn't exist", - dept_not_exist = "This department doesn't exist", - armory_global_title = "Police Armory", - help_text_open_armory = "Press ~INPUT_CONTEXT~ to open police's armory", - armory_add_bulletproof_vest_title = "Put on a bulletproof vest", - armory_remove_bulletproof_vest_title = "Take off your bulletproof vest", - armory_weapons_list = "Choose weapons", - armory_basic_kit = "Basic cop kit", -}) \ No newline at end of file diff --git a/resources/police/locales/fr.lua b/resources/police/locales/fr.lua deleted file mode 100644 index a0a576c83..000000000 --- a/resources/police/locales/fr.lua +++ /dev/null @@ -1,130 +0,0 @@ -i18n.importData("fr", { - police_station = "Station de police", - title_notification = "Gouvernement", - now_cuffed = "Vous êtes menotté !", - now_uncuffed = "Liberté !", - info_fine_request_before_amount = "Appuyez sur ~g~Y~s~ pour accepter l'amende de $", - info_fine_request_after_amount = ", appuyez sur ~r~R~s~ pour la refuser !", - request_fine_expired = "La demande de l'amende à ~r~expirée~s~ !", - pay_fine_success_before_amount = "Vous avez payé l'amende de $", - pay_fine_success_after_amount = ".", - help_text_open_cloackroom = "Appuyez sur ~INPUT_CONTEXT~ pour ouvrir le ~b~vestiaire de Police", - help_text_put_car_into_garage = "Appuyez sur ~INPUT_CONTEXT~ pour rentrer le ~b~véhicule de Police", - help_text_get_car_out_garage = "Appuyez sur ~INPUT_CONTEXT~ pour sortir un ~b~véhicule de Police", - help_text_put_heli_into_garage = "Appuyez sur ~INPUT_CONTEXT~ pour rentrer l'~b~hélicoptère de Police", - help_text_get_heli_out_garage = "Appuyez sur ~INPUT_CONTEXT~ pour sortir un ~b~hélicoptère de Police", - no_player_near_ped = "Aucun joueur à proximité", - no_veh_near_ped = "Aucun véhicule à proximté", - cop_whitelist_disabled = "La whitelist police est désactivée, veuillez l'activer pour utiliser cette commande !", - - menu_id_card_title = "Carte d'identité", - menu_check_inventory_title = "Fouiller", - menu_toggle_cuff_title = "(De)Menotter", - menu_weapons_title = "Confisquer les armes", - menu_force_player_get_in_car_title = "Mettre dans le véhicule", - menu_force_player_get_out_car_title = "Faire sortir du véhicule", - menu_drag_player_title = "Escorter le joueur", - menu_fines_title = "Amendes", - menu_check_plate_title = "Plaque d'immatriculation", - menu_crochet_veh_title = "Crocheter le véhicule", - menu_global_title = "Menu Police", - menu_categories_title = "Categories", - menu_animations_title = "Animations", - menu_citizens_title = "Citoyens", - menu_vehicles_title = "Véhicules", - menu_close_menu_title = "Fermer le menu", - menu_anim_do_traffic_title = "Faire la circulation", - menu_anim_take_notes_title = "Prendre des notes", - menu_anim_standby_title = "Repos", - menu_anim_standby_2_title = "Repos 2", - menu_anim_Cancel_emote_title = "Annuler emote", - menu_custom_amount_fine_title = "Autre montant", - menu_doing_traffic_notification = "~g~Vous faites la circulation.", - menu_taking_notes_notification = "~g~Vous prenez des notes.", - menu_being_stand_by_notification = "~g~Vous êtes en Stand By.", - menu_veh_opened_notification = "Le véhicule est ~g~ouvert~w~.", - - menu_put_in_jail_title = "Put in jail", - menu_arrest_title = "Arrest", - menu_custom_amount_jail_title = "Custom amount in seconds", - jail_notification_title = "^4[JAIL]", - jail_arrest_notification_part_1 = "You got Arrested for ^1", -- send to the client after he got puted into the jail - jail_arrest_notification_part_2 = " ^0seconds!", - jail_weapons_removed = "Your Weapons got removed for being Arrested!", - jail_not_cuffed = "Player need to be cuffed!", - jail_remove_weapons_notification_part_1 = "All the weapons from ", - jail_remove_weapons_notification_part_2 = " got removed.", - menu_delete_vehicle_title = "Delete Vehicle", - - garage_global_title = "Garage de police", - garage_loading = "~b~Chargement...", - - cloackroom_global_title = "Vestiaire Police", - cloackroom_take_service_ranger_title = "Clock in as Park Ranger", - cloackroom_take_service_sheriff_title = "Clock in as Sheriff", - cloackroom_take_service_chp_title = "Clock in as State Trooper", - cloackroom_take_service_prison_title = "Clock in as a Prison Guard", - cloackroom_take_service_normal_title = "Prendre le service (uniforme)", - cloackroom_take_service_hidden_title = "Prendre le service (BAC)", - cloackroom_take_service_swat_title = "Prendre le service (intervention)", - cloackroom_break_service_title = "Fin de service", - cloackroom_add_bulletproof_vest_title = "Gilet par balle", - cloackroom_remove_bulletproof_vest_title = "Enlever le Gilet par balle", - cloackroom_add_yellow_vest_title = "Gilet jaune", - cloackroom_remove_yellow_vest_title = "Enlever le Gilet jaune", - now_in_service_notification = "Vous êtes maintenant ~g~En service", - break_service_notification = "Vous avez ~r~terminé votre service", - help_open_menu_notification = "Appuyer sur ~g~F5~w~ pour ouvrir le ~b~Menu Police", - - menu_props_title = "Objects", - menu_spawn_props_title = "Placer un props", - menu_spawn_barrier_title = "Spawn a police barrier", - menu_spawn_work_ahead_barrier_title = "Spawn work ahead barrier", - menu_remove_last_props_title = "Retirer le dernier props", - menu_remove_all_props_title = "Retirer tous les props", - removed_prop = "Object has been ~g~removed~w~.", - removed_props = "Objects have been ~g~removed~w~.", - - vehicle_checking_plate_part_1 = "Le véhicule #", -- before number plate - vehicle_checking_plate_part_2 = " appartient à ", -- between number plate and player name when veh registered - vehicle_checking_plate_part_3 = "", -- after player name when veh registered - vehicle_checking_plate_not_registered = " n'est pas enregistré !", -- after player name - unseat_sender_notification_part_1 = "", -- before player name - unseat_sender_notification_part_2 = " est sortie !", -- after player name - drag_sender_notification_part_1 = "Escorte de ", -- before player name - drag_sender_notification_part_2 = "", -- after player name - checking_inventory_part_1 = "Items de ", - checking_inventory_part_2 = " : ", - checking_weapons_part_1 = "Armes de ", - checking_weapons_part_2 = " : ", - send_fine_request_part_1 = "Envoi d'une requête d'amende de $", - send_fine_request_part_2 = " à ", - already_have_a_pendind_fine_request = " à déjà une demande d'amende", - request_fine_timeout = " n'a pas répondu à la demande d'amende", - request_fine_refused = " à refusé son amende", - request_fine_accepted = " à payé son amende", - toggle_cuff_player_part_1 = "Tentative de mettre les menottes à ", - toggle_cuff_player_part_2 = "", - force_player_get_in_vehicle_part_1 = "Tentative de faire rentrer ", - force_player_get_in_vehicle_part_2 = " dans le véhicule", - usage_command_copadd = "Utilisation : /copadd [ID]", - usage_command_coprem = "Utilisation : /coprem [ID]", - usage_command_coprank = "Utilisation : /coprank [ID] [RANG]", - command_received = "Compris !", - become_cop_success = "Félicitation, vous êtes désormais policier !~w~.", - remove_from_cops = "Vous n'êtes plus policier !~w~.", - no_player_with_this_id = "Aucun joueur avec cet ID !", - not_enough_permission = "Vous n'avez pas la permission de faire ça !", - new_dept = "Congrats, you are now part of the", - same_dept = "That's the same department!", - new_rank = "Félicitation, vous êtes désormais : ", - player_not_cop = "Ce joueur n'est pas un policier", - rank_not_exist = "Ce grade n'existe pas", - dept_not_exist = "This department doesn't exist", - armory_global_title = "Armurerie de Police", - help_text_open_armory = "Appuyez sur ~INPUT_CONTEXT~ pour ouvrir l'armurerie", - armory_add_bulletproof_vest_title = "Mettre le gilet par-balle", - armory_remove_bulletproof_vest_title = "Retirer le gilet par-balle", - armory_weapons_list = "Choisir les armes", - armory_basic_kit = "Kit police de base", -}) \ No newline at end of file diff --git a/resources/police/server/server.lua b/resources/police/server/server.lua deleted file mode 100644 index d4c29fc36..000000000 --- a/resources/police/server/server.lua +++ /dev/null @@ -1,402 +0,0 @@ ---[[ - Cops_FiveM - A cops script for FiveM RP servers. - Copyright (C) 2018 FiveM-Scripts - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero 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 Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with Cops_FiveM in the file "LICENSE". If not, see . -]] - - -if config.useCopWhitelist then - local setupTable = "CREATE TABLE IF NOT EXISTS `police` (`identifier` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`dept` int(11) NOT NULL DEFAULT '0',`rank` int(11) NOT NULL DEFAULT '0', `amount` int(11) NOT NULL DEFAULT '1000')" - exports.ghmattimysql:execute(setupTable, {}, function() - IsDatabaseVerified = true - end) -end - -if GetResourceMetadata(GetCurrentResourceName(), 'resource_Isdev', 0) == "yes" then - RconPrint("/!\\ You are running a dev version of Cops FiveM !\n") -end - -if config.enableVersionNotifier then - PerformHttpRequest("https://raw.githubusercontent.com/FiveM-Scripts/Cops_FiveM/master/police/fxmanifest.lua", function(errorCode, result, headers) - local version = GetResourceMetadata(GetCurrentResourceName(), 'version', 0) - - if string.find(tostring(result), version) == nil then - print("\n\r[Cops_FiveM] The version on this server is not up to date. Please update now.\n\r") - end - end, "GET", "", "") -end - -local inServiceCops = {} - -function addCop(identifier) - exports.ghmattimysql:scalar("SELECT identifier FROM police WHERE identifier = @identifier", { ['identifier'] = tostring(identifier)}, function (result) - if not result then - exports.ghmattimysql:execute("INSERT INTO police (`identifier`) VALUES ('"..identifier.."')", {['@identifier'] = identifier}) - end - end) -end - -function setDept(source, player,playerDept) - local identifier = getPlayerID(player) - if(config.departments.label[playerDept]) then - exports.ghmattimysql:execute("SELECT * FROM police WHERE identifier = '"..identifier.."'", { ['@identifier'] = identifier}, function (result) - if(result[1]) then - if(result[1].dept ~= playerDept) then - exports.ghmattimysql:execute("UPDATE police SET dept="..playerDept.." WHERE identifier='"..identifier.."'", { ['identifier'] = identifier}) - TriggerClientEvent('chatMessage', source, i18n.translate("title_notification"), {255, 0, 0}, i18n.translate("command_received")) - TriggerClientEvent("police:notify", player, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("new_dept") .. " " .. config.departments.label[playerDept]) - TriggerClientEvent('police:receiveIsCop', source, result[1].rank, playerDept) - else - TriggerClientEvent('chatMessage', source, i18n.translate("title_notification"), {255, 0, 0}, i18n.translate("same_dept")) - end - else - TriggerClientEvent('chatMessage', source, i18n.translate("title_notification"), {255, 0, 0}, i18n.translate("player_not_cop")) - end - end) - else - TriggerClientEvent('chatMessage', source, i18n.translate("title_notification"), {255, 0, 0}, i18n.translate("dept_not_exist")) - end -end - -function remCop(identifier) - exports.ghmattimysql:execute("DELETE FROM police WHERE identifier = '"..identifier.."'", { ['identifier'] = identifier}) -end - -AddEventHandler('playerDropped', function() - if(inServiceCops[source]) then - inServiceCops[source] = nil - - for i, c in pairs(inServiceCops) do - TriggerClientEvent("police:resultAllCopsInService", i, inServiceCops) - end - end -end) - -RegisterServerEvent('police:checkIsCop') -AddEventHandler('police:checkIsCop', function() - local identifier = getPlayerID(source) - local src = source - - if config.useCopWhitelist then - exports.ghmattimysql:scalar("SELECT `identifier` FROM police WHERE identifier = @identifier", { ['identifier'] = identifier}, function(result) - if not result then - TriggerClientEvent('police:receiveIsCop', src, -1) - else - exports.ghmattimysql:execute("SELECT * FROM police WHERE identifier = @identifier", { ['identifier'] = identifier}, function(data) - if data then - TriggerClientEvent('police:receiveIsCop', src, data[1].rank, data[1].dept) - end - end) - end - end) - else - TriggerClientEvent('police:receiveIsCop', src, 0, 1) - end -end) - -RegisterServerEvent('police:takeService') -AddEventHandler('police:takeService', function() - - if(not inServiceCops[source]) then - inServiceCops[source] = getPlayerID(source) - - for i, c in pairs(inServiceCops) do - TriggerClientEvent("police:resultAllCopsInService", i, inServiceCops) - end - end -end) - -RegisterServerEvent('police:breakService') -AddEventHandler('police:breakService', function() - - if(inServiceCops[source]) then - inServiceCops[source] = nil - - for i, c in pairs(inServiceCops) do - TriggerClientEvent("police:resultAllCopsInService", i, inServiceCops) - end - end -end) - -RegisterServerEvent('police:getAllCopsInService') -AddEventHandler('police:getAllCopsInService', function() - TriggerClientEvent("police:resultAllCopsInService", source, inServiceCops) -end) - -RegisterServerEvent('police:removeWeapons') -AddEventHandler('police:removeWeapons', function(target) - local identifier = getPlayerID(target) - TriggerClientEvent("police:removeWeapons", target) -end) - -RegisterServerEvent('police:confirmUnseat') -AddEventHandler('police:confirmUnseat', function(t) - TriggerClientEvent("police:notify", source, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("unseat_sender_notification_part_1") .. GetPlayerName(t) .. i18n.translate("unseat_sender_notification_part_2")) - TriggerClientEvent('police:unseatme', t) -end) - -RegisterServerEvent('police:dragRequest') -AddEventHandler('police:dragRequest', function(t) - TriggerClientEvent("police:notify", source, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("drag_sender_notification_part_1").. GetPlayerName(t) .. i18n.translate("drag_sender_notification_part_2")) - TriggerClientEvent('police:toggleDrag', t, source) -end) - -RegisterServerEvent('police:finesGranted') -AddEventHandler('police:finesGranted', function(target, amount) - TriggerClientEvent('police:payFines', target, amount, source) - TriggerClientEvent("police:notify", source, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("send_fine_request_part_1")..amount..i18n.translate("send_fine_request_part_2")..GetPlayerName(target)) -end) - -RegisterServerEvent('police:finesETA') -AddEventHandler('police:finesETA', function(officer, code) - if(code==1) then - TriggerClientEvent("police:notify", officer, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, GetPlayerName(source)..i18n.translate("already_have_a_pendind_fine_request")) - elseif(code==2) then - TriggerClientEvent("police:notify", officer, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, GetPlayerName(source)..i18n.translate("request_fine_timeout")) - elseif(code==3) then - TriggerClientEvent("police:notify", officer, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, GetPlayerName(source)..i18n.translate("request_fine_refused")) - elseif(code==0) then - TriggerClientEvent("police:notify", officer, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, GetPlayerName(source)..i18n.translate("request_fine_accepted")) - end -end) - -RegisterServerEvent('police:cuffGranted') -AddEventHandler('police:cuffGranted', function(t) - TriggerClientEvent("police:notify", source, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("toggle_cuff_player_part_1")..GetPlayerName(t)..i18n.translate("toggle_cuff_player_part_2")) - TriggerClientEvent('police:getArrested', t) -end) - -RegisterServerEvent('police:forceEnterAsk') -AddEventHandler('police:forceEnterAsk', function(t, v) - TriggerClientEvent("police:notify", source, "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("force_player_get_in_vehicle_part_1")..GetPlayerName(t)..i18n.translate("force_player_get_in_vehicle_part_2")) - TriggerClientEvent('police:forcedEnteringVeh', t, v) -end) - -RegisterServerEvent('CheckPoliceVeh') -AddEventHandler('CheckPoliceVeh', function(vehicle) - TriggerClientEvent('FinishPoliceCheckForVeh',source) - TriggerClientEvent('policeveh:spawnVehicle', source, vehicle) -end) - -RegisterServerEvent('police:GetPayChecks') -AddEventHandler('police:GetPayChecks', function(t) - local identifier = getPlayerID(source) - local src = source - - exports.ghmattimysql:scalar("SELECT `amount` FROM police WHERE identifier = @identifier", { ['identifier'] = identifier}, function(result) - if result then - data = json.encode(result) - print(data) - TriggerClientEvent('police:receivePaycheck', src, data) - end - end) -end) - -RegisterServerEvent('police:TransferPayCheck') -AddEventHandler('police:TransferPayCheck', function(t) - local identifier = getPlayerID(source) - local src = source - - exports.ghmattimysql:scalar("SELECT `amount` FROM police WHERE identifier = @identifier", { ['identifier'] = identifier}, function(result) - if result then - data = json.encode(result) - salary = config.weekly_salary + tonumber(data) - local values = { "police", "amount", salary, { ["identifier"] = identifier } } - exports.ghmattimysql:execute("UPDATE ?? SET ?? = ? WHERE ?", values, function(data) - if data then - TriggerClientEvent('police:receivePaycheck', src, salary) - end - end) - end - end) -end) - ---RegisterServerEvent('police:UpdateNotifier') ---AddEventHandler('police:UpdateNotifier', function() --- local src = source --- PerformHttpRequest("https://raw.githubusercontent.com/FiveM-Scripts/Cops_FiveM/master/police/__resource.lua", function(errorCode, result, headers) --- local version = GetResourceMetadata(GetCurrentResourceName(), 'resource_version', 0) --- if string.find(tostring(result), version) == nil then --- TriggerClientEvent('police:Update', src, true) --- end --- end, "GET", "", "") ---end) - -RegisterCommand("CopAddAdmin", function(source,args,raw) - if #args ~= 1 then - RconPrint("Usage: CopAddAdmin [ingame-id]\n") - CancelEvent() - return - else - local maxi = -1 - for key, value in pairs(config.rank.label) do - if key > maxi then - maxi = key - end - end - - if(GetPlayerName(tonumber(args[1])) == nil)then - RconPrint("Player is not ingame\n") - CancelEvent() - - return - end - - local identifier = getPlayerID(tonumber(args[1])) - exports.ghmattimysql:scalar("SELECT identifier FROM police WHERE identifier = @identifier", {['identifier'] = identifier}, function(result) - if not result then - exports.ghmattimysql:execute("INSERT INTO police (`identifier`, `dept`, `rank`) VALUES (@identifier, @dept, @maxi)", { ['identifier'] = identifier, ['dept'] = 1, ['maxi'] = maxi}) - TriggerClientEvent("police:notify", tonumber(args[1]), "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("become_cop_success")) - - RconPrint(GetPlayerName(tonumber(args[1])) .. " is now added to the police database.\n") - TriggerClientEvent('police:receiveIsCop', tonumber(args[1]), maxi, 1) - else - RconPrint(GetPlayerName(tonumber(args[1])) .. ' already exists.\n') - end - end) - CancelEvent() - end -end, true) - -RegisterCommand("CopAdd", function(source,args,raw) - if #args ~= 1 then - RconPrint("Usage: CopAdd [ingame-id]\n") - CancelEvent() - return - else - if GetPlayerName(tonumber(args[1])) == nil then - RconPrint("Player is not ingame\n") - CancelEvent() - return - end - - local identifier = getPlayerID(tonumber(args[1])) - exports.ghmattimysql:scalar("SELECT identifier FROM police WHERE identifier = @identifier", { ['identifier'] = identifier}, function (result) - if not result then - print('Adding record for player to the database') - addCop(identifier) - - TriggerClientEvent("police:notify", tonumber(args[1]), "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("become_cop_success")) - TriggerClientEvent('police:receiveIsCop', tonumber(args[1]), 0, 1) - - RconPrint(GetPlayerName(tonumber(args[1])) .. " is now added to the police database.\n") - else - RconPrint(GetPlayerName(tonumber(args[1])) .. " is already a police officer.\n") - end - end) - end -end, true) - -RegisterCommand("CopRem", function(source,args,raw) - if #args ~= 1 then - RconPrint("Usage: CopRem [ingame-id]\n") - CancelEvent() - return - else - if(GetPlayerName(tonumber(args[1])) == nil)then - RconPrint("Player is not ingame\n") - CancelEvent() - return - end - - local identifier = getPlayerID(tonumber(args[1])) - - exports.ghmattimysql:scalar("SELECT identifier FROM police WHERE identifier = @identifier", { ['identifier'] = identifier}, function (result) - if not result then - RconPrint(GetPlayerName(tonumber(args[1])) .. " isn't here.\n") - else - exports.ghmattimysql:execute("DELETE FROM police WHERE identifier = @identifier", { ['identifier'] = identifier}) - TriggerClientEvent('police:noLongerCop', tonumber(args[1])) - TriggerClientEvent("police:notify", tonumber(args[1]), "CHAR_AGENT14", 1, i18n.translate("title_notification"), false, i18n.translate("remove_from_cops")) - RconPrint(GetPlayerName(tonumber(args[1])) .. " is now removed from the police database.\n") - end - end) - - CancelEvent() - end -end, true) - -RegisterCommand("CopRank", function(source,args,raw) - if #args ~= 2 then - RconPrint("Usage: CopRank [ingame-id] [rank]\n") - CancelEvent() - return - elseif(not config.rank.label[tonumber(args[2])]) then - RconPrint("You have to enter a valid rank !\n") - CancelEvent() - return - else - if(GetPlayerName(tonumber(args[1])) == nil)then - RconPrint("Player is not ingame\n") - CancelEvent() - return - end - - local identifier = getPlayerID(tonumber(args[1])) - exports.ghmattimysql:scalar("SELECT `identifier` FROM police WHERE identifier = @identifier", { ['identifier'] = identifier}, function (rank) - if(rank == nil) then - RconPrint(GetPlayerName(tonumber(args[1])) .. " isn't here.\n") - else - exports.ghmattimysql:execute("UPDATE police SET `rank` = @rank WHERE identifier = @identifier", { ['identifier'] = identifier, ['rank'] = args[2]}) - TriggerClientEvent('police:receiveIsCop', tonumber(args[1]), tonumber(args[2])) - RconPrint(GetPlayerName(tonumber(args[1])) .. " information has been updated.\n") - end - end) - - CancelEvent() - end -end, true) - -RegisterCommand("CopDept", function(source,args,raw) - if #args ~= 2 then - RconPrint("Usage: CopDept [ingame-id] [department]\n") - CancelEvent() - return - else - if(GetPlayerName(tonumber(args[1])) == nil) then - RconPrint("Player is not ingame\n") - CancelEvent() - return - end - - local identifier = getPlayerID(tonumber(args[1])) - exports.ghmattimysql:scalar("SELECT `identifier` FROM police WHERE identifier = @identifier", { ['identifier'] = identifier}, function (result) - if result then - if GetPlayerName(tonumber(args[1])) ~= nil then - local player = tonumber(args[1]) - local dept = tonumber(args[2]) - - setDept(args[1], player, dept) - else - TriggerClientEvent('chatMessage', args[1], i18n.translate("title_notification"), {255, 0, 0}, i18n.translate("no_player_with_this_id")) - end - else - TriggerClientEvent('chatMessage', args[1], i18n.translate("title_notification"), {255, 0, 0}, i18n.translate("not_enough_permission")) - end - end) - - CancelEvent() - end -end, true) - -function getPlayerID(source) - local identifiers = GetPlayerIdentifiers(source) - local player = getIdentifiant(identifiers) - return player -end - -function getIdentifiant(id) - for _, v in ipairs(id) do - return v - end -end diff --git a/resources/vMenu/vmenu.log b/resources/vMenu/vmenu.log index a47e5717e..792744f41 100644 --- a/resources/vMenu/vmenu.log +++ b/resources/vMenu/vmenu.log @@ -4,3 +4,7 @@ [ 03-09-2024 05:30:49 ] [KICK ACTION] Player: ~r~ ¦ 1A-80 has kicked: 227 | Adam | Senior Officer for: You have been kicked. Reason: VDM x2. [ 03-09-2024 06:44:32 ] [KICK ACTION] Player: ~r~ ¦ 1A-80 has kicked: 227 | Adam | Senior Officer for: You have been kicked. Reason: . [ 03-09-2024 07:06:41 ] [KICK ACTION] Player: ~r~ ¦ 1A-80 has kicked: 227 | Adam | Senior Officer for: You have been kicked. Reason: RDM x2. +[ 08-09-2024 03:11:38 ] [BAN ACTION] A new ban record has been added. Player: 'Brzzy' was banned by '[197]Max Rod' for 'Banned by staff. good job +Your ban id: afd274e2-146e-4407-b68a-34f0edf1c24c' until '09/09/2024 09:11:38'. +[ 08-09-2024 03:27:19 ] [BAN ACTION] The following ban record has been removed (player unbanned). [Player: Brzzy was banned by [197]Max Rod for Banned by staff. good job +Your ban id: afd274e2-146e-4407-b68a-34f0edf1c24c until 09/09/2024 09:11:38.] diff --git a/server.cfg b/server.cfg index da97e9587..3ee0b57c6 100644 --- a/server.cfg +++ b/server.cfg @@ -46,7 +46,6 @@ ensure Head-Tags setr SCREENSHOT_BASIC_TOKEN 9dfc22d9d7a9ff2 -ensure ghmattimysql ensure mysql-async ensure oxmysql @@ -54,7 +53,7 @@ set mysql_connection_string "server=localhost;uid=root;password=Elite_Gaming_13; //set mysql_connection_string "server=localhost;uid=root;password=Elite_Gaming_13;database=elitebot" #[-----Scripts With MySQL-----] -ensure police +ensure Interaction-Menu ensure screenshot-basic ensure pma-voice setr voice_defaultCycle "57" @@ -560,4 +559,9 @@ add_ace group.helper jd.staff allow add_ace group.superadmin hypnonema allow add_ace group.admin hypnonema allow add_ace group.moderator hypnonema allow -add_ace group.helper hypnonema allow \ No newline at end of file +add_ace group.helper hypnonema allow + +add_ace builtin.everyone sem_intmenu.leo allow +add_ace builtin.everyone sem_intmenu.fire allow +add_ace group.helper sem_intmenu.unjail allow +add_ace group.helper sem_intmenu.unhospital allow \ No newline at end of file