commit 7e0c6a58d74802dd3e21ed8cf10e4f128a0bd655 Author: j502647092 Date: Wed May 27 18:06:22 2015 +0800 init project... Signed-off-by: j502647092 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6d80b42 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Eclipse stuff +/.classpath +/.project +/.settings + +# netbeans +/nbproject + +# we use maven! +/build.xml + +# maven +/target +/repo + +# vim +.*.sw[a-p] + +# various other potential build files +/build +/bin +/dist +/manifest.mf + +/world + +# Mac filesystem dust +*.DS_Store + +# intellij +*.iml +*.ipr +*.iws +.idea/ + +# Project Stuff +/src/main/resources/Soulbound + +# Atlassian Stuff +/atlassian-ide-plugin.xml \ No newline at end of file diff --git a/LICENCE.txt b/LICENCE.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/LICENCE.txt @@ -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/README b/README new file mode 100644 index 0000000..18cab81 --- /dev/null +++ b/README @@ -0,0 +1,34 @@ +Residence - Self serve area protection system +============================================= + +Official links: +Wiki: http://residencebukkitmod.wikispaces.com/ +IRC: irc://irc.esper.net/Residence +Spigot Resource page: http://www.spigotmc.org/resources/residence-reloaded-1-8.2697/ + +Downloads: +Latest Development Snapshot: https://github.com/bekvon/Residence/raw/dist/dist/Residence.jar +Latest Config.yml: https://github.com/bekvon/Residence/raw/master/src/config.yml + +To build the source yourself, simply download the source: +https://github.com/bekvon/Residence/zipball/master + +Unzip and run ant. + +Need Help?: + +Before asking for help, please check the FAQ(wiki). It has some solutions to frequent problems. + +To help us better assist you, please follow these simple guidelines when asking for help. + +1)Use a service such as http://pastebin.com when sharing errors or configurations. + +2)Include the following version information: Craftbukkit, Residence, Vault. If you are unsure, type in the Minecraft console: "/version [plugin]" left blank will default to Craftbukkit. + +3)Include a paste of your current config.yml from Residence and your permissions.yml from your respective permissions plugin. + +4)Be as detailed as possible when describing your problem. How can we reproduce your problem? + + +If no one is available on the IRC channel, please make a post on the Residence BukkitDev page with the above information. + diff --git a/lib/Essentials.jar b/lib/Essentials.jar new file mode 100644 index 0000000..f056eec Binary files /dev/null and b/lib/Essentials.jar differ diff --git a/lib/Vault.jar b/lib/Vault.jar new file mode 100644 index 0000000..f9aa324 Binary files /dev/null and b/lib/Vault.jar differ diff --git a/lib/WorldEdit.jar b/lib/WorldEdit.jar new file mode 100644 index 0000000..600dcca Binary files /dev/null and b/lib/WorldEdit.jar differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8bf6997 --- /dev/null +++ b/pom.xml @@ -0,0 +1,67 @@ + + 4.0.0 + cn.CityCraft + Residence + 2.7.0.0-SNAPSHOT + Residence + + src + + + src + + **/*.java + + + + + + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/groups/public/ + + + + + org.spigotmc + spigot-api + jar + 1.8.3-R0.1-SNAPSHOT + + + com.earth2me + essentials + 2.9.6 + system + ${project.basedir}/lib/Essentials.jar + + + net.milkbowl.vault + VaultAPI + 1.5 + system + ${project.basedir}/lib/Vault.jar + + + com.sk89q + WorldEdit + 5.4.5 + system + ${project.basedir}/lib/WorldEdit.jar + + + + UTF-8 + + \ No newline at end of file diff --git a/src/com/bekvon/bukkit/residence/ConfigManager.java b/src/com/bekvon/bukkit/residence/ConfigManager.java new file mode 100644 index 0000000..68d4ef0 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/ConfigManager.java @@ -0,0 +1,289 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.bekvon.bukkit.residence; +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.protection.FlagPermissions; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; + +/** + * + * @author Administrator + */ +public class ConfigManager { + protected String defaultGroup; + protected boolean useLeases; + protected boolean enableEconomy; + protected String economySystem; + protected boolean adminsOnly; + protected boolean allowEmptyResidences; + protected int infoToolId; + protected int selectionToolId; + protected boolean adminOps; + protected String multiworldPlugin; + protected boolean enableRentSystem; + protected boolean leaseAutoRenew; + protected int rentCheckInterval; + protected int leaseCheckInterval; + protected int autoSaveInt; + protected boolean flagsInherit; + protected ChatColor chatColor; + protected boolean chatEnable; + protected boolean actionBar; + protected int minMoveUpdate; + protected FlagPermissions globalCreatorDefaults; + protected FlagPermissions globalResidenceDefaults; + protected Map globalGroupDefaults; + protected String language; + protected boolean preventBuildInRent; + protected boolean stopOnSaveError; + protected boolean legacyperms; + protected String namefix; + protected boolean showIntervalMessages; + protected boolean spoutEnable; + protected boolean enableLeaseMoneyAccount; + protected boolean enableDebug; + protected List customContainers; + protected List customBothClick; + protected List customRightClick; + private boolean enforceAreaInsideArea; + + public ConfigManager(FileConfiguration config) + { + globalCreatorDefaults = new FlagPermissions(); + globalResidenceDefaults = new FlagPermissions(); + globalGroupDefaults = new HashMap(); + this.load(config); + } + + @SuppressWarnings("deprecation") + private void load(FileConfiguration config) { + defaultGroup = config.getString("Global.DefaultGroup", "default").toLowerCase(); + adminsOnly = config.getBoolean("Global.AdminOnlyCommands", false); + useLeases = config.getBoolean("Global.UseLeaseSystem", false); + leaseAutoRenew = config.getBoolean("Global.LeaseAutoRenew", true); + enableEconomy = config.getBoolean("Global.EnableEconomy", false); + economySystem = config.getString("Global.EconomySystem", "iConomy"); + infoToolId = config.getInt("Global.InfoToolId", Material.STRING.getId()); + selectionToolId = config.getInt("Global.SelectionToolId", Material.WOOD_AXE.getId()); + adminOps = config.getBoolean("Global.AdminOPs", true); + multiworldPlugin = config.getString("Global.MultiWorldPlugin"); + enableRentSystem = config.getBoolean("Global.EnableRentSystem", false); + rentCheckInterval = config.getInt("Global.RentCheckInterval", 10); + leaseCheckInterval = config.getInt("Global.LeaseCheckInterval", 10); + autoSaveInt = config.getInt("Global.SaveInterval", 10); + flagsInherit = config.getBoolean("Global.ResidenceFlagsInherit", false); + minMoveUpdate = config.getInt("Global.MoveCheckInterval", 500); + chatEnable = config.getBoolean("Global.ResidenceChatEnable", true); + actionBar = config.getBoolean("Global.UseActionBar", true); + enforceAreaInsideArea = config.getBoolean("Global.EnforceAreaInsideArea", false); + language = config.getString("Global.Language","English"); + globalCreatorDefaults = FlagPermissions.parseFromConfigNode("CreatorDefault", config.getConfigurationSection("Global")); + globalResidenceDefaults = FlagPermissions.parseFromConfigNode("ResidenceDefault", config.getConfigurationSection("Global")); + preventBuildInRent = config.getBoolean("Global.PreventRentModify", true); + stopOnSaveError = config.getBoolean("Global.StopOnSaveFault",true); + legacyperms = config.getBoolean("Global.LegacyPermissions",false); + namefix = config.getString("Global.ResidenceNameRegex",null);//"[^a-zA-Z0-9\\-\\_]" + showIntervalMessages = config.getBoolean("Global.ShowIntervalMessages", false); + spoutEnable = config.getBoolean("Global.EnableSpout", false); + enableLeaseMoneyAccount = config.getBoolean("Global.EnableLeaseMoneyAccount", true); + enableDebug = config.getBoolean("Global.EnableDebug", false); + customContainers = config.getIntegerList("Global.CustomContainers"); + customBothClick = config.getIntegerList("Global.CustomBothClick"); + customRightClick = config.getIntegerList("Global.CustomRightClick"); + ConfigurationSection node = config.getConfigurationSection("Global.GroupDefault"); + if(node!=null) + { + Set keys = node.getConfigurationSection(defaultGroup).getKeys(false); + if(keys!=null) + { + for(String key: keys) + { + globalGroupDefaults.put(key, FlagPermissions.parseFromConfigNode(key, config.getConfigurationSection("Global.GroupDefault"))); + } + } + } + try { + chatColor = ChatColor.valueOf(config.getString("Global.ResidenceChatColor", "DARK_PURPLE")); + } catch (Exception ex) { + chatColor = ChatColor.DARK_PURPLE; + } + } + + public boolean useLegacyPermissions() + { + return legacyperms; + } + + public String getDefaultGroup() { + return defaultGroup; + } + + public String getResidenceNameRegex() + { + return namefix; + } + + public boolean enableEconomy() { + return enableEconomy && Residence.getEconomyManager()!=null; + } + + public boolean enabledRentSystem() + { + return enableRentSystem && enableEconomy(); + } + + public boolean useLeases() { + return useLeases; + } + + public boolean allowAdminsOnly() { + return adminsOnly; + } + public boolean allowEmptyResidences() + { + return allowEmptyResidences; + } + public int getInfoToolID() + { + return infoToolId; + } + public int getSelectionTooldID() + { + return selectionToolId; + } + + public boolean getOpsAreAdmins() + { + return adminOps; + } + + public String getMultiworldPlugin() + { + return multiworldPlugin; + } + + public boolean autoRenewLeases() + { + return leaseAutoRenew; + } + + public String getEconomySystem() + { + return economySystem; + } + + public int getRentCheckInterval() + { + return rentCheckInterval; + } + + public int getLeaseCheckInterval() + { + return leaseCheckInterval; + } + + public int getAutoSaveInterval() + { + return autoSaveInt; + } + + public boolean flagsInherit() + { + return flagsInherit; + } + + public boolean chatEnabled() + { + return chatEnable; + } + + public boolean useActionBar() + { + return actionBar; + } + + public ChatColor getChatColor() + { + return chatColor; + } + + public int getMinMoveUpdateInterval() + { + return minMoveUpdate; + } + + public FlagPermissions getGlobalCreatorDefaultFlags() + { + return globalCreatorDefaults; + } + + public FlagPermissions getGlobalResidenceDefaultFlags() + { + return globalResidenceDefaults; + } + + public Map getGlobalGroupDefaultFlags() + { + return globalGroupDefaults; + } + + public String getLanguage() + { + return language; + } + + public boolean preventRentModify() + { + return preventBuildInRent; + } + public boolean stopOnSaveError() + { + return stopOnSaveError; + } + public boolean showIntervalMessages() + { + return showIntervalMessages; + } + public boolean enableSpout() + { + return spoutEnable; + } + public boolean enableLeaseMoneyAccount() + { + return enableLeaseMoneyAccount; + } + public boolean debugEnabled() + { + return enableDebug; + } + + public List getCustomContainers() + { + return customContainers; + } + + public List getCustomBothClick() + { + return customBothClick; + } + + public List getCustomRightClick() + { + return customRightClick; + } + + public boolean getEnforceAreaInsideArea() { + return enforceAreaInsideArea; + } +} diff --git a/src/com/bekvon/bukkit/residence/Residence.java b/src/com/bekvon/bukkit/residence/Residence.java new file mode 100644 index 0000000..4e72d94 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/Residence.java @@ -0,0 +1,816 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.bekvon.bukkit.residence; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import com.bekvon.bukkit.residence.chat.ChatManager; +import com.bekvon.bukkit.residence.config.Config; +import com.bekvon.bukkit.residence.economy.EconomyInterface; +import com.bekvon.bukkit.residence.economy.EssentialsEcoAdapter; +import com.bekvon.bukkit.residence.economy.TransactionManager; +import com.bekvon.bukkit.residence.economy.rent.RentManager; +import com.bekvon.bukkit.residence.itemlist.WorldItemManager; +import com.bekvon.bukkit.residence.listeners.ResidenceBlockListener; +import com.bekvon.bukkit.residence.listeners.ResidenceEntityListener; +import com.bekvon.bukkit.residence.listeners.ResidencePlayerListener; +import com.bekvon.bukkit.residence.permissions.PermissionManager; +import com.bekvon.bukkit.residence.persistance.YMLSaveHelper; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import com.bekvon.bukkit.residence.protection.FlagPermissions; +import com.bekvon.bukkit.residence.protection.LeaseManager; +import com.bekvon.bukkit.residence.protection.PermissionListManager; +import com.bekvon.bukkit.residence.protection.ResidenceManager; +import com.bekvon.bukkit.residence.protection.WorldFlagManager; +import com.bekvon.bukkit.residence.selection.SelectionManager; +import com.bekvon.bukkit.residence.selection.WorldEditSelectionManager; +import com.bekvon.bukkit.residence.text.Language; +import com.bekvon.bukkit.residence.text.help.HelpEntry; +import com.bekvon.bukkit.residence.text.help.InformationPager; +import com.bekvon.bukkit.residence.vaultinterface.ResidenceVaultAdapter; +import com.earth2me.essentials.Essentials; +import com.residence.mcstats.Metrics; +import com.residence.zip.ZipLibrary; + +/** + * + * @author Gary Smoak - bekvon + * + */ +public class Residence extends JavaPlugin { + + protected static ResidenceManager rmanager; + protected static SelectionManager smanager; + protected static PermissionManager gmanager; + protected static ConfigManager cmanager; + protected static ResidenceBlockListener blistener; + protected static ResidencePlayerListener plistener; + protected static ResidenceEntityListener elistener; + protected static TransactionManager tmanager; + protected static PermissionListManager pmanager; + protected static LeaseManager leasemanager; + protected static WorldItemManager imanager; + protected static WorldFlagManager wmanager; + protected static RentManager rentmanager; + protected static ChatManager chatmanager; + protected static Server server; + protected static HelpEntry helppages; + protected static Language language; + protected boolean firstenable = true; + protected static EconomyInterface economy; + public final static int saveVersion = 1; + protected static File dataFolder; + protected static int leaseBukkitId = -1; + protected static int rentBukkitId = -1; + protected static int healBukkitId = -1; + protected static int autosaveBukkitId = -1; + protected static boolean initsuccess = false; + protected Map deleteConfirm; + protected static List resadminToggle; + private final static String[] validLanguages = { "English", "German", + "French", "Hungarian", "Spanish", "Chinese", "Czech", "Brazilian", + "Polish" }; + private Runnable doHeals = new Runnable() { + public void run() { + plistener.doHeals(); + } + }; + private Runnable rentExpire = new Runnable() { + public void run() { + rentmanager.checkCurrentRents(); + if (cmanager.showIntervalMessages()) { + System.out.println("[Residence] - Rent Expirations checked!"); + } + } + }; + private Runnable leaseExpire = new Runnable() { + public void run() { + leasemanager.doExpirations(); + if (cmanager.showIntervalMessages()) { + System.out.println("[Residence] - Lease Expirations checked!"); + } + } + }; + private Runnable autoSave = new Runnable() { + public void run() { + try { + if (initsuccess) { + saveYml(); + } + } catch (Exception ex) { + Logger.getLogger("Minecraft").log(Level.SEVERE, + "[Residence] SEVERE SAVE ERROR", ex); + } + } + }; + + public Residence() { + } + + public void reloadPlugin() { + this.onDisable(); + this.reloadConfig(); + this.onEnable(); + + } + + @Override + public FileConfiguration getConfig() { + if(Config.getInstance()==null){ + Config.load(this); + } + return Config.getInstance(); + } + + @Override + public void saveConfig() { + Config.save(); + } + + @Override + public void reloadConfig() { + Config.load(this); + } + + @Override + public void onDisable() { + server.getScheduler().cancelTask(autosaveBukkitId); + server.getScheduler().cancelTask(healBukkitId); + if (cmanager.useLeases()) { + server.getScheduler().cancelTask(leaseBukkitId); + } + if (cmanager.enabledRentSystem()) { + server.getScheduler().cancelTask(rentBukkitId); + } + if (initsuccess) { + try { + saveYml(); + ZipLibrary.backup(); + } catch (Exception ex) { + Logger.getLogger("Minecraft").log(Level.SEVERE, + "[Residence] 插件数据保存失败", ex); + } + Logger.getLogger("Minecraft").log(Level.INFO, + "[Residence] Disabled!"); + } + } + + @Override + public void onEnable() { + try { + initsuccess = false; + deleteConfirm = new HashMap(); + resadminToggle = new ArrayList(); + server = this.getServer(); + dataFolder = this.getDataFolder(); + if (!dataFolder.isDirectory()) { + dataFolder.mkdirs(); + } + + if (!new File(dataFolder, "config.yml").isFile()) { + this.writeDefaultConfigFromJar(); + } + if (this.getConfig().getInt("ResidenceVersion", 0) == 0) { + this.writeDefaultConfigFromJar(); + this.getConfig().load("config.yml"); + System.out + .println("[Residence] Config Invalid, wrote default..."); + } + cmanager = new ConfigManager(this.getConfig()); + String multiworld = cmanager.getMultiworldPlugin(); + if (multiworld != null) { + Plugin plugin = server.getPluginManager().getPlugin(multiworld); + if (plugin != null) { + if (!plugin.isEnabled()) { + System.out + .println("[Residence] - Enabling multiworld plugin: " + + multiworld); + server.getPluginManager().enablePlugin(plugin); + } + } + } + gmanager = new PermissionManager(this.getConfig()); + imanager = new WorldItemManager(this.getConfig()); + wmanager = new WorldFlagManager(this.getConfig()); + chatmanager = new ChatManager(); + rentmanager = new RentManager(); + for (String lang : validLanguages) { + try { + if (this.checkNewLanguageVersion(lang)) { + this.writeDefaultLanguageFile(lang); + } + } catch (Exception ex) { + System.out + .println("[Residence] 语言文件升级失败: " + + lang + ".yml"); + helppages = new HelpEntry(""); + language = new Language(); + } + } + try { + File langFile = new File(new File(dataFolder, "Language"), + cmanager.getLanguage() + ".yml"); + if (langFile.isFile()) { + FileConfiguration langconfig = new YamlConfiguration(); + langconfig.load(langFile); + helppages = HelpEntry.parseHelp(langconfig, "CommandHelp"); + HelpEntry.setLinesPerPage(langconfig.getInt( + "HelpLinesPerPage", 7)); + InformationPager.setLinesPerPage(langconfig.getInt( + "HelpLinesPerPage", 7)); + language = Language.parseText(langconfig, "Language"); + } else { + System.out + .println("[Residence] 语言文件不存在..."); + } + } catch (Exception ex) { + System.out.println("[Residence] 语言文件载入失败: " + + cmanager.getLanguage() + ".yml, 错误: " + + ex.getMessage()); + Logger.getLogger(Residence.class.getName()).log(Level.SEVERE, + null, ex); + helppages = new HelpEntry(""); + language = new Language(); + } + economy = null; + if (this.getConfig().getBoolean("Global.EnableEconomy", false)) { + System.out + .println("[Residence] 扫描经济系统..."); + if (gmanager.getPermissionsPlugin() instanceof ResidenceVaultAdapter) { + ResidenceVaultAdapter vault = (ResidenceVaultAdapter) gmanager + .getPermissionsPlugin(); + if (vault.economyOK()) { + economy = vault; + System.out + .println("[Residence] 发现 Vault 使用经济系统: " + + vault.getEconomyName()); + } + } + if (economy == null) { + this.loadVaultEconomy(); + } + if (economy == null) { + this.loadEssentialsEconomy(); + } + if (economy == null) { + System.out + .println("[Residence] 未找到经济系统..."); + } + } + try { + this.loadYml(); + } catch (Exception e) { + this.getLogger().log(Level.SEVERE, "不能载入保存的文件", + e); + throw e; + } + if (rmanager == null) { + rmanager = new ResidenceManager(); + } + if (leasemanager == null) { + leasemanager = new LeaseManager(rmanager); + } + if (tmanager == null) { + tmanager = new TransactionManager(rmanager, gmanager); + } + if (pmanager == null) { + pmanager = new PermissionListManager(); + } + if (firstenable) { + if (!this.isEnabled()) { + return; + } + FlagPermissions.initValidFlags(); + Plugin p = server.getPluginManager().getPlugin("WorldEdit"); + if (p != null) { + smanager = new WorldEditSelectionManager(server); + Logger.getLogger("Minecraft").log(Level.INFO, + "[Residence] 发现 WorldEdit"); + } else { + smanager = new SelectionManager(server); + Logger.getLogger("Minecraft").log(Level.INFO, + "[Residence] WorldEdit 未找到!"); + } + + blistener = new ResidenceBlockListener(); + plistener = new ResidencePlayerListener(); + elistener = new ResidenceEntityListener(); + PluginManager pm = getServer().getPluginManager(); + pm.registerEvents(blistener, this); + pm.registerEvents(plistener, this); + pm.registerEvents(elistener, this); + + firstenable = false; + } else { + plistener.reload(); + } + int autosaveInt = cmanager.getAutoSaveInterval(); + if (autosaveInt < 1) { + autosaveInt = 1; + } + autosaveInt = autosaveInt * 60 * 20; + autosaveBukkitId = server.getScheduler().scheduleSyncRepeatingTask( + this, autoSave, autosaveInt, autosaveInt); + healBukkitId = server.getScheduler().scheduleSyncRepeatingTask( + this, doHeals, 20, 20); + if (cmanager.useLeases()) { + int leaseInterval = cmanager.getLeaseCheckInterval(); + if (leaseInterval < 1) { + leaseInterval = 1; + } + leaseInterval = leaseInterval * 60 * 20; + leaseBukkitId = server.getScheduler() + .scheduleSyncRepeatingTask(this, leaseExpire, + leaseInterval, leaseInterval); + } + if (cmanager.enabledRentSystem()) { + int rentint = cmanager.getRentCheckInterval(); + if (rentint < 1) { + rentint = 1; + } + rentint = rentint * 60 * 20; + rentBukkitId = server.getScheduler().scheduleSyncRepeatingTask( + this, rentExpire, rentint, rentint); + } + for (Player player : Bukkit.getServer().getOnlinePlayers()) { + if (Residence.getPermissionManager().isResidenceAdmin(player)) { + turnResAdminOn(player); + } + } + try { + Metrics metrics = new Metrics(this); + metrics.start(); + } catch (IOException e) { + // Failed to submit the stats :-( + } + Logger.getLogger("Minecraft") + .log(Level.INFO, + "[Residence] 载入完成! 版本: " + + this.getDescription().getVersion() + + " 重制 by 喵♂呜"); + initsuccess = true; + } catch (Exception ex) { + initsuccess = false; + getServer().getPluginManager().disablePlugin(this); + System.out + .println("[Residence] - 初始化失败! 卸载插件! 错误:"); + Logger.getLogger(Residence.class.getName()).log(Level.SEVERE, null, + ex); + } + } + + public void consoleMessage(String message) { + ConsoleCommandSender console = Bukkit.getConsoleSender(); + console.sendMessage("[Residence] " + message); + } + + public static boolean validName(String name) { + if (name.contains(":") || name.contains(".")) { + return false; + } + if (cmanager.getResidenceNameRegex() == null) { + return true; + } else { + String namecheck = name.replaceAll( + cmanager.getResidenceNameRegex(), ""); + if (!name.equals(namecheck)) { + return false; + } + return true; + } + } + + public static File getDataLocation() { + return dataFolder; + } + + public static ResidenceManager getResidenceManager() { + return rmanager; + } + + public static SelectionManager getSelectionManager() { + return smanager; + } + + public static PermissionManager getPermissionManager() { + return gmanager; + } + + public static EconomyInterface getEconomyManager() { + return economy; + } + + public static Server getServ() { + return server; + } + + public static LeaseManager getLeaseManager() { + return leasemanager; + } + + public static ConfigManager getConfigManager() { + return cmanager; + } + + public static TransactionManager getTransactionManager() { + return tmanager; + } + + public static WorldItemManager getItemManager() { + return imanager; + } + + public static WorldFlagManager getWorldFlags() { + return wmanager; + } + + public static RentManager getRentManager() { + return rentmanager; + } + + public static ResidencePlayerListener getPlayerListener() { + return plistener; + } + + public static ResidenceBlockListener getBlockListener() { + return blistener; + } + + public static ResidenceEntityListener getEntityListener() { + return elistener; + } + + public static ChatManager getChatManager() { + return chatmanager; + } + + public static Language getLanguage() { + if (language == null) { + language = new Language(); + } + return language; + } + + public static FlagPermissions getPermsByLoc(Location loc) { + ClaimedResidence res = rmanager.getByLoc(loc); + if (res != null) { + return res.getPermissions(); + } else { + return wmanager.getPerms(loc.getWorld().getName()); + } + } + + public static FlagPermissions getPermsByLocForPlayer(Location loc, + Player player) { + ClaimedResidence res = rmanager.getByLoc(loc); + if (res != null) { + return res.getPermissions(); + } else { + if (player != null) + return wmanager.getPerms(player); + else + return wmanager.getPerms(loc.getWorld().getName()); + } + } + + private void loadEssentialsEconomy() { + Plugin p = getServer().getPluginManager().getPlugin("Essentials"); + if (p != null) { + economy = new EssentialsEcoAdapter((Essentials) p); + Logger.getLogger("Minecraft").log(Level.INFO, + "[Residence] 成功关联Essentials Economy!"); + } else { + Logger.getLogger("Minecraft").log(Level.INFO, + "[Residence] Essentials Economy 未找到!"); + } + } + + private void loadVaultEconomy() { + Plugin p = getServer().getPluginManager().getPlugin("Vault"); + if (p != null) { + ResidenceVaultAdapter vault = new ResidenceVaultAdapter(getServer()); + if (vault.economyOK()) { + Logger.getLogger("Minecraft").log( + Level.INFO, + "[Residence] 发现 Vault 使用经济系统: " + + vault.getEconomyName()); + economy = vault; + } else { + Logger.getLogger("Minecraft") + .log(Level.INFO, + "[Residence] 发现 Vault, 但是 Vault 无法使用经济系统..."); + } + } else { + Logger.getLogger("Minecraft").log(Level.INFO, + "[Residence] Vault 未找到!"); + } + } + + public static boolean isResAdminOn(Player player) { + if (resadminToggle.contains(player.getName())) { + return true; + } + return false; + } + + public static void turnResAdminOn(Player player) { + resadminToggle.add(player.getName()); + } + + public static boolean isResAdminOn(String player) { + if (resadminToggle.contains(player.toLowerCase())) { + return true; + } + return false; + } + + private void saveYml() throws IOException { + File saveFolder = new File(dataFolder, "Save"); + File worldFolder = new File(saveFolder, "Worlds"); + worldFolder.mkdirs(); + YMLSaveHelper yml; + Map save = rmanager.save(); + for (Entry entry : save.entrySet()) { + File ymlSaveLoc = new File(worldFolder, "res_" + entry.getKey() + + ".yml"); + File tmpFile = new File(worldFolder, "tmp_res_" + entry.getKey() + + ".yml"); + yml = new YMLSaveHelper(tmpFile); + yml.getRoot().put("Version", saveVersion); + World world = server.getWorld(entry.getKey()); + if (world != null) + yml.getRoot().put("Seed", world.getSeed()); + yml.getRoot().put("Residences", (Map) entry.getValue()); + yml.save(); + if (ymlSaveLoc.isFile()) { + File backupFolder = new File(worldFolder, "Backup"); + backupFolder.mkdirs(); + File backupFile = new File(backupFolder, "res_" + + entry.getKey() + ".yml"); + if (backupFile.isFile()) { + backupFile.delete(); + } + ymlSaveLoc.renameTo(backupFile); + } + tmpFile.renameTo(ymlSaveLoc); + } + + // For Sale save + File ymlSaveLoc = new File(saveFolder, "forsale.yml"); + File tmpFile = new File(saveFolder, "tmp_forsale.yml"); + yml = new YMLSaveHelper(tmpFile); + yml.save(); + yml.getRoot().put("Version", saveVersion); + yml.getRoot().put("Economy", tmanager.save()); + yml.save(); + if (ymlSaveLoc.isFile()) { + File backupFolder = new File(saveFolder, "Backup"); + backupFolder.mkdirs(); + File backupFile = new File(backupFolder, "forsale.yml"); + if (backupFile.isFile()) { + backupFile.delete(); + } + ymlSaveLoc.renameTo(backupFile); + } + tmpFile.renameTo(ymlSaveLoc); + + // Leases save + ymlSaveLoc = new File(saveFolder, "leases.yml"); + tmpFile = new File(saveFolder, "tmp_leases.yml"); + yml = new YMLSaveHelper(tmpFile); + yml.getRoot().put("Version", saveVersion); + yml.getRoot().put("Leases", leasemanager.save()); + yml.save(); + if (ymlSaveLoc.isFile()) { + File backupFolder = new File(saveFolder, "Backup"); + backupFolder.mkdirs(); + File backupFile = new File(backupFolder, "leases.yml"); + if (backupFile.isFile()) { + backupFile.delete(); + } + ymlSaveLoc.renameTo(backupFile); + } + tmpFile.renameTo(ymlSaveLoc); + + // permlist save + ymlSaveLoc = new File(saveFolder, "permlists.yml"); + tmpFile = new File(saveFolder, "tmp_permlists.yml"); + yml = new YMLSaveHelper(tmpFile); + yml.getRoot().put("Version", saveVersion); + yml.getRoot().put("PermissionLists", pmanager.save()); + yml.save(); + if (ymlSaveLoc.isFile()) { + File backupFolder = new File(saveFolder, "Backup"); + backupFolder.mkdirs(); + File backupFile = new File(backupFolder, "permlists.yml"); + if (backupFile.isFile()) { + backupFile.delete(); + } + ymlSaveLoc.renameTo(backupFile); + } + tmpFile.renameTo(ymlSaveLoc); + + // rent save + ymlSaveLoc = new File(saveFolder, "rent.yml"); + tmpFile = new File(saveFolder, "tmp_rent.yml"); + yml = new YMLSaveHelper(tmpFile); + yml.getRoot().put("Version", saveVersion); + yml.getRoot().put("RentSystem", rentmanager.save()); + yml.save(); + if (ymlSaveLoc.isFile()) { + File backupFolder = new File(saveFolder, "Backup"); + backupFolder.mkdirs(); + File backupFile = new File(backupFolder, "rent.yml"); + if (backupFile.isFile()) { + backupFile.delete(); + } + ymlSaveLoc.renameTo(backupFile); + } + tmpFile.renameTo(ymlSaveLoc); + + if (cmanager.showIntervalMessages()) { + System.out.println("[Residence] - 保存插件数据..."); + } + } + + @SuppressWarnings("unchecked") + protected boolean loadYml() throws Exception { + File saveFolder = new File(dataFolder, "Save"); + try { + File worldFolder = new File(saveFolder, "Worlds"); + if (!saveFolder.isDirectory()) { + this.getLogger().warning("保存目录不存在..."); + this.getLogger().warning("请重新启动服务器"); + return true; + } + YMLSaveHelper yml; + File loadFile; + HashMap worlds = new HashMap(); + for (World world : server.getWorlds()) { + loadFile = new File(worldFolder, "res_" + world.getName() + + ".yml"); + if (loadFile.isFile()) { + yml = new YMLSaveHelper(loadFile); + yml.load(); + worlds.put(world.getName(), yml.getRoot().get("Residences")); + } + } + rmanager = ResidenceManager.load(worlds); + loadFile = new File(saveFolder, "forsale.yml"); + if (loadFile.isFile()) { + yml = new YMLSaveHelper(loadFile); + yml.load(); + tmanager = TransactionManager.load((Map) yml.getRoot() + .get("Economy"), gmanager, rmanager); + } + loadFile = new File(saveFolder, "leases.yml"); + if (loadFile.isFile()) { + yml = new YMLSaveHelper(loadFile); + yml.load(); + leasemanager = LeaseManager.load((Map) yml + .getRoot().get("Leases"), rmanager); + } + loadFile = new File(saveFolder, "permlists.yml"); + if (loadFile.isFile()) { + yml = new YMLSaveHelper(loadFile); + yml.load(); + pmanager = PermissionListManager.load((Map) yml + .getRoot().get("PermissionLists")); + } + loadFile = new File(saveFolder, "rent.yml"); + if (loadFile.isFile()) { + yml = new YMLSaveHelper(loadFile); + yml.load(); + rentmanager = RentManager.load((Map) yml + .getRoot().get("RentSystem")); + } + // System.out.print("[Residence] Loaded..."); + return true; + } catch (Exception ex) { + Logger.getLogger(Residence.class.getName()).log(Level.SEVERE, null, + ex); + throw ex; + } + } + + private void writeDefaultConfigFromJar() { + if (this.writeDefaultFileFromJar(new File(this.getDataFolder(), + "config.yml"), "config.yml", true)) { + System.out.println("[Residence] 保存默认配置文件..."); + } + } + + private void writeDefaultLanguageFile(String lang) { + File outFile = new File(new File(this.getDataFolder(), "Language"), + lang + ".yml"); + outFile.getParentFile().mkdirs(); + if (this.writeDefaultFileFromJar(outFile, "languagefiles/" + lang + + ".yml", true)) { + System.out.println("[Residence] 保存默认 " + lang + + " 语言文件..."); + } + } + + private boolean checkNewLanguageVersion(String lang) throws IOException, + FileNotFoundException, InvalidConfigurationException { + File outFile = new File(new File(this.getDataFolder(), "Language"), + lang + ".yml"); + File checkFile = new File(new File(this.getDataFolder(), "Language"), + "temp-" + lang + ".yml"); + if (outFile.isFile()) { + FileConfiguration testconfig = new YamlConfiguration(); + testconfig.load(outFile); + int oldversion = testconfig.getInt("FieldsVersion", 0); + if (!this.writeDefaultFileFromJar(checkFile, "languagefiles/" + + lang + ".yml", false)) { + return false; + } + FileConfiguration testconfig2 = new YamlConfiguration(); + testconfig2.load(checkFile); + int newversion = testconfig2.getInt("FieldsVersion", oldversion); + if (checkFile.isFile()) { + checkFile.delete(); + } + if (newversion > oldversion) { + return true; + } + return false; + } + return true; + } + + @SuppressWarnings("resource") + private boolean writeDefaultFileFromJar(File writeName, String jarPath, + boolean backupOld) { + try { + File fileBackup = new File(this.getDataFolder(), "backup-" + + writeName); + File jarloc = new File(getClass().getProtectionDomain() + .getCodeSource().getLocation().toURI()).getCanonicalFile(); + if (jarloc.isFile()) { + JarFile jar = new JarFile(jarloc); + JarEntry entry = jar.getJarEntry(jarPath); + if (entry != null && !entry.isDirectory()) { + InputStream in = jar.getInputStream(entry); + InputStreamReader isr = new InputStreamReader(in, "UTF8"); + if (writeName.isFile()) { + if (backupOld) { + if (fileBackup.isFile()) { + fileBackup.delete(); + } + writeName.renameTo(fileBackup); + } else { + writeName.delete(); + } + } + FileOutputStream out = new FileOutputStream(writeName); + OutputStreamWriter osw = new OutputStreamWriter(out, "UTF8"); + char[] tempbytes = new char[512]; + int readbytes = isr.read(tempbytes, 0, 512); + while (readbytes > -1) { + osw.write(tempbytes, 0, readbytes); + readbytes = isr.read(tempbytes, 0, 512); + } + osw.close(); + isr.close(); + return true; + } + } + return false; + } catch (Exception ex) { + System.out + .println("[Residence] 文件写入失败: " + writeName); + return false; + } + } +} diff --git a/src/com/bekvon/bukkit/residence/ResidenceCommandListener.java b/src/com/bekvon/bukkit/residence/ResidenceCommandListener.java new file mode 100644 index 0000000..5ec614b --- /dev/null +++ b/src/com/bekvon/bukkit/residence/ResidenceCommandListener.java @@ -0,0 +1,1800 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.bekvon.bukkit.residence; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; + +import com.bekvon.bukkit.residence.chat.ChatChannel; +import com.bekvon.bukkit.residence.event.ResidenceCommandEvent; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import com.bekvon.bukkit.residence.protection.CuboidArea; +import com.bekvon.bukkit.residence.protection.FlagPermissions; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; + +public class ResidenceCommandListener extends Residence { + + public boolean onCommand(CommandSender sender, Command command, + String label, String[] args) { + ResidenceCommandEvent cevent = new ResidenceCommandEvent( + command.getName(), args, sender); + server.getPluginManager().callEvent(cevent); + if (cevent.isCancelled()) { + return true; + } + if (command.getName().equals("resreload") && args.length == 0) { + if (sender instanceof Player) { + Player player = (Player) sender; + if (Residence.getPermissionManager().isResidenceAdmin(player)) { + this.reloadPlugin(); + sender.sendMessage(ChatColor.GREEN + + "[Residence] 重载配置文件."); + System.out.println("[Residence] 重载 by " + + player.getName() + "."); + } + } else { + this.reloadPlugin(); + System.out.println("[Residence] 重载 by 控制台."); + } + return true; + } + if (command.getName().equals("resload")) { + if (!(sender instanceof Player) || sender instanceof Player + && gmanager.isResidenceAdmin((Player) sender)) { + try { + this.loadYml(); + sender.sendMessage(ChatColor.GREEN + + "[Residence] Reloaded save file..."); + } catch (Exception ex) { + sender.sendMessage(ChatColor.RED + + "[Residence] Unable to reload the save file, exception occured!"); + sender.sendMessage(ChatColor.RED + ex.getMessage()); + Logger.getLogger(Residence.class.getName()).log( + Level.SEVERE, null, ex); + } + } + return true; + } else if (command.getName().equals("resworld")) { + if (args.length == 2 && args[0].equalsIgnoreCase("remove")) { + if (sender instanceof ConsoleCommandSender) { + rmanager.removeAllFromWorld(sender, args[1]); + return true; + } else { + sender.sendMessage(ChatColor.RED + + "MUST be run from console."); + } + } + return false; + } else if (command.getName().equals("rc")) { + if (sender instanceof Player) { + Player player = (Player) sender; + String pname = player.getName(); + if (cmanager.chatEnabled()) { + if (args.length == 0) { + plistener.tooglePlayerResidenceChat(player); + } else { + String area = plistener.getCurrentResidenceName(pname); + if (area != null) { + ChatChannel channel = chatmanager.getChannel(area); + if (channel != null) { + String message = ""; + for (String arg : args) { + message = message + " " + arg; + } + channel.chat(pname, message); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidChannel")); + } + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("NotInResidence")); + } + } + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("ChatDisabled")); + } + } + return true; + } else if (command.getName().equals("res") + || command.getName().equals("residence") + || command.getName().equals("resadmin")) { + boolean resadmin = false; + if (sender instanceof Player) { + if (command.getName().equals("resadmin") + && gmanager.isResidenceAdmin((Player) sender)) { + resadmin = true; + } + if (command.getName().equals("resadmin") + && !gmanager.isResidenceAdmin((Player) sender)) { + ((Player) sender).sendMessage(ChatColor.RED + + language.getPhrase("NonAdmin")); + return true; + } + } else { + resadmin = true; + } + return commandRes(args, resadmin, command, sender); + } + return super.onCommand(sender, command, label, args); + } + + @SuppressWarnings("deprecation") + private boolean commandRes(String[] args, boolean resadmin, + Command command, CommandSender sender) { + if (args.length > 0 && args[args.length - 1].equalsIgnoreCase("?") + || args.length > 1 && args[args.length - 2].equals("?")) { + return commandHelp(args, resadmin, sender); + } + int page = 1; + try { + if (args.length > 0) { + page = Integer.parseInt(args[args.length - 1]); + } + } catch (Exception ex) { + } + Player player = null; + PermissionGroup group = null; + String pname = null; + if (sender instanceof Player) { + player = (Player) sender; + group = Residence.getPermissionManager().getGroup(player); + pname = player.getName(); + } else { + resadmin = true; + } + if (cmanager.allowAdminsOnly()) { + if (!resadmin) { + player.sendMessage(ChatColor.RED + + language.getPhrase("AdminOnly")); + return true; + } + } + if (args.length == 0) { + return false; + } + if (args.length == 0) { + args = new String[1]; + args[0] = "?"; + } + String cmd = args[0].toLowerCase(); + if (cmd.equals("remove") || cmd.equals("delete")) { + return commandResRemove(args, resadmin, sender, page); + } + if (cmd.equals("confirm")) { + return commandResConfirm(args, resadmin, sender, page); + } + if (cmd.equals("version")) { + sender.sendMessage(ChatColor.GRAY + + "------------------------------------"); + sender.sendMessage(ChatColor.RED + "This server running " + + ChatColor.GOLD + "Residence" + ChatColor.RED + + " version: " + ChatColor.BLUE + + this.getDescription().getVersion()); + sender.sendMessage(ChatColor.GREEN + "Created by: " + + ChatColor.YELLOW + "bekvon"); + sender.sendMessage(ChatColor.GREEN + "Updated to 1.8 by: " + + ChatColor.YELLOW + "DartCZ"); + sender.sendMessage(ChatColor.RED + "Updated to 2.7.0.0 by: " + + ChatColor.YELLOW + "喵♂呜"); + String names = null; + List authlist = this.getDescription().getAuthors(); + for (String auth : authlist) { + if (names == null) + names = auth; + else + names = names + ", " + auth; + } + sender.sendMessage(ChatColor.GREEN + "Authors: " + ChatColor.YELLOW + + names); + sender.sendMessage(ChatColor.DARK_AQUA + + "For a command list, and help, see the wiki:"); + sender.sendMessage(ChatColor.GREEN + + "http://residencebukkitmod.wikispaces.com/"); + sender.sendMessage(ChatColor.AQUA + + "Visit the Spigot Resource page at:"); + sender.sendMessage(ChatColor.BLUE + + "http://www.spigotmc.org/resources/residence-reloaded-1-8.2697/"); + sender.sendMessage(ChatColor.GRAY + + "------------------------------------"); + return true; + } + if (cmd.equals("setowner") && args.length == 3) { + if (!resadmin) { + sender.sendMessage(ChatColor.RED + + language.getPhrase("NoPermission")); + return true; + } + ClaimedResidence area = rmanager.getByName(args[1]); + if (area != null) { + area.getPermissions().setOwner(args[2], true); + if (area.getParent() == null) { + sender.sendMessage(ChatColor.GREEN + + language.getPhrase("ResidenceOwnerChange", + ChatColor.YELLOW + " " + args[1] + " " + + ChatColor.GREEN + "." + + ChatColor.YELLOW + args[2] + + ChatColor.GREEN)); + } else { + sender.sendMessage(ChatColor.GREEN + + language.getPhrase( + "SubzoneOwnerChange", + ChatColor.YELLOW + + " " + + args[1].split("\\.")[args[1] + .split("\\.").length - 1] + + " " + ChatColor.GREEN + "." + + ChatColor.YELLOW + args[2] + + ChatColor.GREEN)); + } + } else { + sender.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + if (player == null) { + return true; + } + if (command.getName().equals("resadmin")) { + if (args.length == 1 && args[0].equals("on")) { + resadminToggle.add(player.getName()); + player.sendMessage(ChatColor.YELLOW + + language.getPhrase("AdminToggle", + language.getPhrase("TurnOn"))); + return true; + } else if (args.length == 1 && args[0].equals("off")) { + resadminToggle.remove(player.getName()); + player.sendMessage(ChatColor.YELLOW + + language.getPhrase("AdminToggle", + language.getPhrase("TurnOff"))); + return true; + } + } + if (!resadmin && resadminToggle.contains(player.getName())) { + if (!gmanager.isResidenceAdmin(player)) { + resadminToggle.remove(player.getName()); + } + } + if (cmd.equals("select")) { + return commandResSelect(args, resadmin, player, page); + } + if (cmd.equals("create")) { + return commandResCreate(args, resadmin, player, page); + } + if (cmd.equals("subzone") || cmd.equals("sz")) { + return commandResSubzone(args, resadmin, player, page); + } + if (cmd.equals("sublist")) { + return commandResSublist(args, resadmin, player, page); + } + if (cmd.equals("removeall")) { + if (args.length != 2) { + return false; + } + if (resadmin || args[1].endsWith(pname)) { + rmanager.removeAllByOwner(player, args[1]); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("RemovePlayersResidences", + ChatColor.YELLOW + args[1] + ChatColor.GREEN)); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("NoPermission")); + } + return true; + } + if (cmd.equals("compass")) { + return commandResCompass(args, resadmin, player, page); + } + if (cmd.equals("area")) { + return commandResArea(args, resadmin, player, page); + } + if (cmd.equals("lists")) { + return commandResList(args, resadmin, player, page); + } + if (cmd.equals("default")) { + if (args.length == 2) { + ClaimedResidence res = rmanager.getByName(args[1]); + res.getPermissions().applyDefaultFlags(player, resadmin); + return true; + } + return false; + } + if (cmd.equals("limits")) { + if (args.length == 1) { + gmanager.getGroup(player).printLimits(player); + return true; + } + return false; + } + if (cmd.equals("info")) { + if (args.length == 1) { + String area = rmanager.getNameByLoc(player.getLocation()); + if (area != null) { + rmanager.printAreaInfo(area, player); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } else if (args.length == 2) { + rmanager.printAreaInfo(args[1], player); + return true; + } + return false; + } + if (cmd.equals("check")) { + if (args.length == 3 || args.length == 4) { + if (args.length == 4) { + pname = args[3]; + } + ClaimedResidence res = rmanager.getByName(args[1]); + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + return true; + } + if (!res.getPermissions().hasApplicableFlag(pname, args[2])) { + player.sendMessage(language.getPhrase("FlagCheckFalse", + ChatColor.YELLOW + args[2] + ChatColor.RED + "." + + ChatColor.YELLOW + pname + ChatColor.RED + + "." + ChatColor.YELLOW + args[1] + + ChatColor.RED)); + } else { + player.sendMessage(language + .getPhrase( + "FlagCheckTrue", + ChatColor.GREEN + + args[2] + + ChatColor.YELLOW + + "." + + ChatColor.GREEN + + pname + + ChatColor.YELLOW + + "." + + ChatColor.YELLOW + + args[1] + + ChatColor.RED + + "." + + (res.getPermissions().playerHas( + pname, + res.getPermissions() + .getWorld(), + args[2], false) ? ChatColor.GREEN + + "TRUE" + : ChatColor.RED + "FALSE"))); + } + return true; + } + return false; + } + if (cmd.equals("current")) { + if (args.length != 1) { + return false; + } + String res = rmanager.getNameByLoc(player.getLocation()); + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NotInResidence")); + } else { + player.sendMessage(ChatColor.GREEN + + language.getPhrase("InResidence", ChatColor.YELLOW + + res + ChatColor.GREEN)); + } + return true; + } + if (cmd.equals("set")) { + return commandResSet(args, resadmin, player, page); + } + if (cmd.equals("pset")) { + return commandResPset(args, resadmin, player, page); + } + if (cmd.equals("gset")) { + return commandResGset(args, resadmin, player, page); + } + if (cmd.equals("lset")) { + return commandResLset(args, resadmin, player, page); + } + if (cmd.equals("list")) { + if (args.length == 1) { + rmanager.listResidences(player); + return true; + } else if (args.length == 2) { + try { + Integer.parseInt(args[1]); + rmanager.listResidences(player, page); + } catch (Exception ex) { + rmanager.listResidences(player, args[1]); + } + return true; + } else if (args.length == 3) { + rmanager.listResidences(player, args[1], page); + return true; + } + return false; + } + if (cmd.equals("listhidden")) { + if (!resadmin) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NoPermission")); + return true; + } + if (args.length == 1) { + rmanager.listResidences(player, 1, true); + return true; + } else if (args.length == 2) { + try { + Integer.parseInt(args[1]); + rmanager.listResidences(player, page, true); + } catch (Exception ex) { + rmanager.listResidences(player, args[1], 1, true); + } + return true; + } else if (args.length == 3) { + rmanager.listResidences(player, args[1], page, true); + return true; + } + return false; + } + if (cmd.equals("rename")) { + if (args.length == 3) { + rmanager.renameResidence(player, args[1], args[2], resadmin); + return true; + } + return false; + } + if (cmd.equals("renamearea")) { + if (args.length == 4) { + ClaimedResidence res = rmanager.getByName(args[1]); + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + return true; + } + res.renameArea(player, args[2], args[3], resadmin); + return true; + } + return false; + } + if (cmd.equals("unstuck")) { + if (args.length != 1) { + return false; + } + group = gmanager.getGroup(player); + if (!group.hasUnstuckAccess()) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NoPermission")); + return true; + } + ClaimedResidence res = rmanager.getByLoc(player.getLocation()); + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NotInResidence")); + } else { + player.sendMessage(ChatColor.YELLOW + + language.getPhrase("Moved") + "..."); + player.teleport(res.getOutsideFreeLoc(player.getLocation())); + } + return true; + } + if (cmd.equals("kick")) { + if (args.length != 2) { + return false; + } + Player targetplayer = Bukkit.getPlayer(args[1]); + if (targetplayer == null) { + + } + group = gmanager.getGroup(player); + if (!group.hasKickAccess()) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NoPermission")); + return true; + } + ClaimedResidence res = rmanager + .getByLoc(targetplayer.getLocation()); + if (res.getOwner().equals(player.getName())) { + if (res.getPlayersInResidence().contains(targetplayer)) { + targetplayer.teleport(res.getOutsideFreeLoc(player + .getLocation())); + targetplayer.sendMessage(ChatColor.RED + + language.getPhrase("Kicked") + "!"); + } + } + + } + if (cmd.equals("mirror")) { + if (args.length != 3) { + return false; + } + rmanager.mirrorPerms(player, args[2], args[1], resadmin); + return true; + } + if (cmd.equals("listall")) { + if (args.length == 1) { + rmanager.listAllResidences(player, 1); + } else if (args.length == 2) { + try { + rmanager.listAllResidences(player, page); + } catch (Exception ex) { + } + } else { + return false; + } + return true; + } + if (cmd.equals("listallhidden")) { + if (!resadmin) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NoPermission")); + return true; + } + if (args.length == 1) { + rmanager.listAllResidences(player, 1, true); + } else if (args.length == 2) { + try { + rmanager.listAllResidences(player, page, true); + } catch (Exception ex) { + } + } else { + return false; + } + return true; + } + if (cmd.equals("material")) { + if (args.length != 2) { + return false; + } + try { + player.sendMessage(ChatColor.GREEN + + language.getPhrase( + "MaterialGet", + ChatColor.GOLD + + args[1] + + ChatColor.GREEN + + "." + + ChatColor.RED + + Material.getMaterial( + Integer.parseInt(args[1])) + .name() + ChatColor.GREEN)); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidMaterial")); + } + return true; + } + if (cmd.equals("tpset")) { + ClaimedResidence res = rmanager.getByLoc(player.getLocation()); + if (res != null) { + res.setTpLoc(player, resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + if (cmd.equals("tp")) { + if (args.length != 2) { + return false; + } + ClaimedResidence res = rmanager.getByName(args[1]); + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + return true; + } + res.tpToResidence(player, player, resadmin); + return true; + } + if (cmd.equals("lease")) { + return commandResLease(args, resadmin, player, page); + } + if (cmd.equals("bank")) { + return commandResBank(args, resadmin, player, page); + } + if (cmd.equals("market")) { + return commandResMarket(args, resadmin, player, page); + } + if (cmd.equals("message")) { + return commandResMessage(args, resadmin, player, page); + } + if (cmd.equals("give") && args.length == 3) { + rmanager.giveResidence(player, args[2], args[1], resadmin); + return true; + } + if (cmd.equals("server")) { + if (!resadmin) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NoPermission")); + return true; + } + if (args.length == 2) { + ClaimedResidence res = rmanager.getByName(args[1]); + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + return true; + } + res.getPermissions().setOwner("Server Land", false); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("ResidenceOwnerChange", + ChatColor.YELLOW + args[1] + ChatColor.GREEN + + "." + ChatColor.YELLOW + + "Server Land" + ChatColor.GREEN)); + return true; + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + return true; + } + } + if (cmd.equals("clearflags")) { + if (!resadmin) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NoPermission")); + return true; + } + ClaimedResidence area = rmanager.getByName(args[1]); + if (area != null) { + area.getPermissions().clearFlags(); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("FlagsCleared")); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + if (cmd.equals("tool")) { + player.sendMessage(ChatColor.YELLOW + + language.getPhrase("SelectionTool") + ":" + + ChatColor.GREEN + + Material.getMaterial(cmanager.getSelectionTooldID())); + player.sendMessage(ChatColor.YELLOW + + language.getPhrase("InfoTool") + ": " + ChatColor.GREEN + + Material.getMaterial(cmanager.getInfoToolID())); + return true; + } + return false; + } + + private boolean commandHelp(String[] args, boolean resadmin, + CommandSender sender) { + if (helppages != null) { + String helppath = "res"; + for (int i = 0; i < args.length; i++) { + if (args[i].equalsIgnoreCase("?")) { + break; + } + helppath = helppath + "." + args[i]; + } + int page = 1; + if (!args[args.length - 1].equalsIgnoreCase("?")) { + try { + page = Integer.parseInt(args[args.length - 1]); + } catch (Exception ex) { + sender.sendMessage(ChatColor.RED + + language.getPhrase("InvalidHelp")); + } + } + if (helppages.containesEntry(helppath)) { + helppages.printHelp(sender, page, helppath); + return true; + } + } + return false; + } + + private boolean commandResSelect(String[] args, boolean resadmin, + Player player, int page) { + PermissionGroup group = Residence.getPermissionManager().getGroup( + player); + if (!group.selectCommandAccess() && !resadmin) { + player.sendMessage(ChatColor.RED + + language.getPhrase("SelectDiabled")); + return true; + } + if (!group.canCreateResidences() && group.getMaxSubzoneDepth() <= 0 + && !resadmin) { + player.sendMessage(ChatColor.RED + + language.getPhrase("SelectDiabled")); + return true; + } + if ((!player.hasPermission("residence.create") + && player.isPermissionSet("residence.create") + && !player.hasPermission("residence.select") && player + .isPermissionSet("residence.select")) && !resadmin) { + player.sendMessage(ChatColor.RED + + language.getPhrase("SelectDiabled")); + return true; + } + if (args.length == 2) { + if (args[1].equals("size") || args[1].equals("cost")) { + if (smanager.hasPlacedBoth(player.getName())) { + try { + smanager.showSelectionInfo(player); + return true; + } catch (Exception ex) { + Logger.getLogger(Residence.class.getName()).log( + Level.SEVERE, null, ex); + return true; + } + } else if (smanager.worldEdit(player)) { + try { + smanager.showSelectionInfo(player); + return true; + } catch (Exception ex) { + Logger.getLogger(Residence.class.getName()).log( + Level.SEVERE, null, ex); + return true; + } + } + } else if (args[1].equals("vert")) { + smanager.vert(player, resadmin); + return true; + } else if (args[1].equals("sky")) { + smanager.sky(player, resadmin); + return true; + } else if (args[1].equals("bedrock")) { + smanager.bedrock(player, resadmin); + return true; + } else if (args[1].equals("coords")) { + Location playerLoc1 = smanager.getPlayerLoc1(player.getName()); + if (playerLoc1 != null) { + player.sendMessage(ChatColor.GREEN + + language.getPhrase("Primary.Selection") + ":" + + ChatColor.AQUA + " (" + playerLoc1.getBlockX() + + ", " + playerLoc1.getBlockY() + ", " + + playerLoc1.getBlockZ() + ")"); + } + Location playerLoc2 = smanager.getPlayerLoc2(player.getName()); + if (playerLoc2 != null) { + player.sendMessage(ChatColor.GREEN + + language.getPhrase("Secondary.Selection") + ":" + + ChatColor.AQUA + " (" + playerLoc2.getBlockX() + + ", " + playerLoc2.getBlockY() + ", " + + playerLoc2.getBlockZ() + ")"); + } + return true; + } else if (args[1].equals("chunk")) { + smanager.selectChunk(player); + return true; + } else if (args[1].equals("worldedit")) { + if (smanager.worldEdit(player)) { + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase( + "SelectionSuccess")); + } + return true; + } + } else if (args.length == 3) { + if (args[1].equals("expand")) { + int amount; + try { + amount = Integer.parseInt(args[2]); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidAmount")); + return true; + } + smanager.modify(player, false, amount); + return true; + } else if (args[1].equals("shift")) { + int amount; + try { + amount = Integer.parseInt(args[2]); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidAmount")); + return true; + } + smanager.modify(player, true, amount); + return true; + } + } + if (args.length > 1 && args[1].equals("residence")) { + String resName; + String areaName; + ClaimedResidence res = null; + if (args.length > 2) { + res = rmanager.getByName(args[2]); + } else { + res = rmanager.getByLoc(player.getLocation()); + } + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + return true; + } + resName = res.getName(); + CuboidArea area = null; + if (args.length > 3) { + area = res.getArea(args[3]); + areaName = args[3]; + } else { + areaName = res.getAreaIDbyLoc(player.getLocation()); + area = res.getArea(areaName); + } + if (area != null) { + smanager.placeLoc1(player, area.getHighLoc()); + smanager.placeLoc2(player, area.getLowLoc()); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("SelectionArea", ChatColor.GOLD + + areaName + ChatColor.GREEN + "." + + ChatColor.GOLD + resName + ChatColor.GREEN)); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("AreaNonExist")); + } + return true; + } else { + try { + smanager.selectBySize(player, Integer.parseInt(args[1]), + Integer.parseInt(args[2]), Integer.parseInt(args[3])); + return true; + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("SelectionFail")); + return true; + } + } + } + + private boolean commandResCreate(String[] args, boolean resadmin, + Player player, int page) { + if (args.length != 2) { + return false; + } + WorldEditPlugin wep = (WorldEditPlugin) server.getPluginManager() + .getPlugin("WorldEdit"); + if (wep != null) { + if (wep.getConfig().getInt("wand-item") == Residence + .getConfigManager().selectionToolId) { + smanager.worldEdit(player); + } + } + if (smanager.hasPlacedBoth(player.getName())) { + rmanager.addResidence(player, args[1], + smanager.getPlayerLoc1(player.getName()), + smanager.getPlayerLoc2(player.getName()), resadmin); + return true; + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("SelectPoints")); + return true; + } + } + + private boolean commandResSubzone(String[] args, boolean resadmin, + Player player, int page) { + if (args.length != 2 && args.length != 3) { + return false; + } + String zname; + String parent; + if (args.length == 2) { + parent = rmanager.getNameByLoc(player.getLocation()); + zname = args[1]; + } else { + parent = args[1]; + zname = args[2]; + } + WorldEditPlugin wep = (WorldEditPlugin) server.getPluginManager() + .getPlugin("WorldEdit"); + if (wep != null) { + if (wep.getConfig().getInt("wand-item") == Residence + .getConfigManager().selectionToolId) { + smanager.worldEdit(player); + } + } + if (smanager.hasPlacedBoth(player.getName())) { + ClaimedResidence res = rmanager.getByName(parent); + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + return true; + } + res.addSubzone(player, smanager.getPlayerLoc1(player.getName()), + smanager.getPlayerLoc2(player.getName()), zname, resadmin); + return true; + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("SelectPoints")); + return true; + } + } + + private boolean commandResArea(String[] args, boolean resadmin, + Player player, int page) { + if (args.length == 4) { + if (args[1].equals("remove")) { + ClaimedResidence res = rmanager.getByName(args[2]); + if (res != null) { + res.removeArea(player, args[3], resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } else if (args[1].equals("add")) { + WorldEditPlugin wep = (WorldEditPlugin) server + .getPluginManager().getPlugin("WorldEdit"); + if (wep != null) { + if (wep.getConfig().getInt("wand-item") == Residence + .getConfigManager().selectionToolId) { + smanager.worldEdit(player); + } + } + if (smanager.hasPlacedBoth(player.getName())) { + ClaimedResidence res = rmanager.getByName(args[2]); + if (res != null) { + res.addArea( + player, + new CuboidArea(smanager.getPlayerLoc1(player + .getName()), smanager + .getPlayerLoc2(player.getName())), + args[3], resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("SelectPoints")); + } + return true; + } else if (args[1].equals("replace")) { + WorldEditPlugin wep = (WorldEditPlugin) server + .getPluginManager().getPlugin("WorldEdit"); + if (wep != null) { + if (wep.getConfig().getInt("wand-item") == Residence + .getConfigManager().selectionToolId) { + smanager.worldEdit(player); + } + } + if (smanager.hasPlacedBoth(player.getName())) { + ClaimedResidence res = rmanager.getByName(args[2]); + if (res != null) { + res.replaceArea( + player, + new CuboidArea(smanager.getPlayerLoc1(player + .getName()), smanager + .getPlayerLoc2(player.getName())), + args[3], resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("SelectPoints")); + } + return true; + } + } + if ((args.length == 3 || args.length == 4) && args[1].equals("list")) { + ClaimedResidence res = rmanager.getByName(args[2]); + if (res != null) { + res.printAreaList(player, page); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } else if ((args.length == 3 || args.length == 4) + && args[1].equals("listall")) { + ClaimedResidence res = rmanager.getByName(args[2]); + if (res != null) { + res.printAdvancedAreaList(player, page); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + return false; + } + + private boolean commandResRemove(String[] args, boolean resadmin, + CommandSender sender, int page) { + Player player = null; + if (sender instanceof Player) { + player = (Player) sender; + if (args.length == 1) { + String area = rmanager.getNameByLoc(player.getLocation()); + if (area != null) { + ClaimedResidence res = rmanager.getByName(area); + if (res.getParent() != null) { + String[] split = area.split("\\."); + String words = split[split.length - 1]; + if (!deleteConfirm.containsKey(player.getName()) + || !area.equalsIgnoreCase(deleteConfirm + .get(player.getName()))) { + player.sendMessage(ChatColor.RED + + language.getPhrase( + "DeleteSubzoneConfirm", + ChatColor.YELLOW + words + + ChatColor.RED)); + deleteConfirm.put(player.getName(), area); + } else { + rmanager.removeResidence(player, area, resadmin); + } + return true; + } else { + if (!deleteConfirm.containsKey(player.getName()) + || !area.equalsIgnoreCase(deleteConfirm + .get(player.getName()))) { + player.sendMessage(ChatColor.RED + + language.getPhrase("DeleteConfirm", + ChatColor.YELLOW + area + + ChatColor.RED)); + deleteConfirm.put(player.getName(), area); + } else { + rmanager.removeResidence(player, area, resadmin); + } + return true; + } + } + return false; + } + } + if (args.length != 2) { + return false; + } + if (player != null) { + if (!deleteConfirm.containsKey(player.getName()) + || !args[1].equalsIgnoreCase(deleteConfirm.get(player + .getName()))) { + String words = ""; + if (rmanager.getByName(args[1]) != null) { + ClaimedResidence res = rmanager.getByName(args[1]); + if (res.getParent() != null) { + String[] split = args[1].split("\\."); + words = split[split.length - 1]; + } + } + if (words == "") { + player.sendMessage(ChatColor.RED + + language.getPhrase("DeleteConfirm", + ChatColor.YELLOW + args[1] + ChatColor.RED)); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("DeleteSubzoneConfirm", + ChatColor.YELLOW + words + ChatColor.RED)); + } + deleteConfirm.put(player.getName(), args[1]); + } else { + rmanager.removeResidence(player, args[1], resadmin); + } + } else { + if (!deleteConfirm.containsKey("Console") + || !args[1].equalsIgnoreCase(deleteConfirm.get("Console"))) { + String words = ""; + if (rmanager.getByName(args[1]) != null) { + ClaimedResidence res = rmanager.getByName(args[1]); + if (res.getParent() != null) { + String[] split = args[1].split("\\."); + words = split[split.length - 1]; + } + } + if (words == "") { + server.getConsoleSender().sendMessage( + ChatColor.RED + + language.getPhrase("DeleteConfirm", + ChatColor.YELLOW + args[1] + + ChatColor.RED)); + } else { + server.getConsoleSender().sendMessage( + ChatColor.RED + + language.getPhrase( + "DeleteSubzoneConfirm", + ChatColor.YELLOW + words + + ChatColor.RED)); + } + deleteConfirm.put("Console", args[1]); + } else { + rmanager.removeResidence(args[1]); + } + } + return true; + } + + private boolean commandResConfirm(String[] args, boolean resadmin, + CommandSender sender, int page) { + Player player = null; + String name = "Console"; + if (sender instanceof Player) { + player = (Player) sender; + name = player.getName(); + } + if (args.length == 1) { + String area = deleteConfirm.get(name); + if (area == null) { + sender.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } else { + rmanager.removeResidence(player, area, resadmin); + deleteConfirm.remove(name); + if (player == null) { + sender.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase( + "ResidenceRemove", + ChatColor.YELLOW + name + ChatColor.GREEN)); + } + } + } + return true; + } + + private boolean commandResSet(String[] args, boolean resadmin, + Player player, int page) { + if (args.length == 3) { + String area = rmanager.getNameByLoc(player.getLocation()); + if (area != null) { + rmanager.getByName(area).getPermissions() + .setFlag(player, args[1], args[2], resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } else if (args.length == 4) { + ClaimedResidence area = rmanager.getByName(args[1]); + if (area != null) { + area.getPermissions().setFlag(player, args[2], args[3], + resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + return false; + } + + private boolean commandResPset(String[] args, boolean resadmin, + Player player, int page) { + if (args.length == 3 && args[2].equalsIgnoreCase("removeall")) { + ClaimedResidence area = rmanager.getByLoc(player.getLocation()); + if (area != null) { + area.getPermissions().removeAllPlayerFlags(player, args[1], + resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } else if (args.length == 4 && args[3].equalsIgnoreCase("removeall")) { + ClaimedResidence area = rmanager.getByName(args[1]); + if (area != null) { + area.getPermissions().removeAllPlayerFlags(player, args[2], + resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } else if (args.length == 4) { + ClaimedResidence area = rmanager.getByLoc(player.getLocation()); + if (area != null) { + area.getPermissions().setPlayerFlag(player, args[1], args[2], + args[3], resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } else if (args.length == 5) { + ClaimedResidence area = rmanager.getByName(args[1]); + if (area != null) { + area.getPermissions().setPlayerFlag(player, args[2], args[3], + args[4], resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + return false; + } + + private boolean commandResGset(String[] args, boolean resadmin, + Player player, int page) { + if (args.length == 4) { + ClaimedResidence area = rmanager.getByLoc(player.getLocation()); + if (area != null) { + area.getPermissions().setGroupFlag(player, args[1], args[2], + args[3], resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidArea")); + } + return true; + } else if (args.length == 5) { + ClaimedResidence area = rmanager.getByName(args[1]); + if (area != null) { + area.getPermissions().setGroupFlag(player, args[2], args[3], + args[4], resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + return false; + } + + private boolean commandResLset(String[] args, boolean resadmin, + Player player, int page) { + ClaimedResidence res = null; + Material mat = null; + String listtype = null; + boolean showinfo = false; + if (args.length == 2 && args[1].equals("info")) { + res = rmanager.getByLoc(player.getLocation()); + showinfo = true; + } else if (args.length == 3 && args[2].equals("info")) { + res = rmanager.getByName(args[1]); + showinfo = true; + } + if (showinfo) { + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + return true; + } + player.sendMessage(ChatColor.RED + "Blacklist:"); + res.getItemBlacklist().printList(player); + player.sendMessage(ChatColor.GREEN + "Ignorelist:"); + res.getItemIgnoreList().printList(player); + return true; + } else if (args.length == 4) { + res = rmanager.getByName(args[1]); + listtype = args[2]; + try { + mat = Material.valueOf(args[3].toUpperCase()); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidMaterial")); + return true; + } + } else if (args.length == 3) { + res = rmanager.getByLoc(player.getLocation()); + listtype = args[1]; + try { + mat = Material.valueOf(args[2].toUpperCase()); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidMaterial")); + return true; + } + } + if (res != null) { + if (listtype.equalsIgnoreCase("blacklist")) { + res.getItemBlacklist().playerListChange(player, mat, resadmin); + } else if (listtype.equalsIgnoreCase("ignorelist")) { + res.getItemIgnoreList().playerListChange(player, mat, resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidList")); + } + return true; + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + return true; + } + } + + private boolean commandResBank(String[] args, boolean resadmin, + Player player, int page) { + if (args.length != 3) { + return false; + } + ClaimedResidence res = rmanager.getByName(plistener + .getCurrentResidenceName(player.getName())); + if (res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NotInResidence")); + return true; + } + int amount = 0; + try { + amount = Integer.parseInt(args[2]); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidAmount")); + return true; + } + if (args[1].equals("deposit")) { + res.getBank().deposit(player, amount, resadmin); + } else if (args[1].equals("withdraw")) { + res.getBank().withdraw(player, amount, resadmin); + } else { + return false; + } + return true; + } + + private boolean commandResLease(String[] args, boolean resadmin, + Player player, int page) { + if (args.length == 2 || args.length == 3) { + if (args[1].equals("renew")) { + if (args.length == 3) { + leasemanager.renewArea(args[2], player); + } else { + leasemanager + .renewArea( + rmanager.getNameByLoc(player.getLocation()), + player); + } + return true; + } else if (args[1].equals("cost")) { + if (args.length == 3) { + ClaimedResidence res = Residence.getResidenceManager() + .getByName(args[2]); + if (res == null || leasemanager.leaseExpires(args[2])) { + int cost = leasemanager.getRenewCost(res); + player.sendMessage(ChatColor.YELLOW + + language.getPhrase("LeaseRenewalCost", + ChatColor.RED + args[2] + + ChatColor.YELLOW + "." + + ChatColor.RED + cost + + ChatColor.YELLOW)); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("LeaseNotExpire")); + } + return true; + } else { + String area = rmanager.getNameByLoc(player.getLocation()); + ClaimedResidence res = rmanager.getByName(area); + if (area == null || res == null) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidArea")); + return true; + } + if (leasemanager.leaseExpires(area)) { + int cost = leasemanager.getRenewCost(res); + player.sendMessage(ChatColor.YELLOW + + language.getPhrase("LeaseRenewalCost", + ChatColor.RED + area + ChatColor.YELLOW + + "." + ChatColor.RED + cost + + ChatColor.YELLOW)); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("LeaseNotExpire")); + } + return true; + } + } + } else if (args.length == 4) { + if (args[1].equals("set")) { + if (!resadmin) { + player.sendMessage(ChatColor.RED + + language.getPhrase("NoPermission")); + return true; + } + if (args[3].equals("infinite")) { + if (leasemanager.leaseExpires(args[2])) { + leasemanager.removeExpireTime(args[2]); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("LeaseInfinite")); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("LeaseNotExpire")); + } + return true; + } else { + int days; + try { + days = Integer.parseInt(args[3]); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidDays")); + return true; + } + leasemanager.setExpireTime(player, args[2], days); + return true; + } + } + } + return false; + } + + private boolean commandResMarket(String[] args, boolean resadmin, + Player player, int page) { + if (args.length == 1) { + return false; + } + String command = args[1].toLowerCase(); + if (command.equals("list")) { + return commandResMarketList(args, resadmin, player, page); + } + if (command.equals("autorenew")) { + return commandResMarketAutorenew(args, resadmin, player, page); + } + if (command.equals("rentable")) { + return commandResMarketRentable(args, resadmin, player, page); + } + if (command.equals("rent")) { + return commandResMarketRent(args, resadmin, player, page); + } + if (command.equals("release")) { + if (args.length != 3) { + return false; + } + if (rentmanager.isRented(args[2])) { + rentmanager.removeFromForRent(player, args[2], resadmin); + } else { + rentmanager.unrent(player, args[2], resadmin); + } + return true; + } + if (command.equals("info")) { + if (args.length == 2) { + String areaname = rmanager.getNameByLoc(player.getLocation()); + tmanager.viewSaleInfo(areaname, player); + if (cmanager.enabledRentSystem() + && rentmanager.isForRent(areaname)) { + rentmanager.printRentInfo(player, areaname); + } + } else if (args.length == 3) { + tmanager.viewSaleInfo(args[2], player); + if (cmanager.enabledRentSystem() + && rentmanager.isForRent(args[2])) { + rentmanager.printRentInfo(player, args[2]); + } + } else { + return false; + } + return true; + } + if (command.equals("buy")) { + if (args.length != 3) { + return false; + } + tmanager.buyPlot(args[2], player, resadmin); + return true; + } + if (command.equals("unsell")) { + if (args.length != 3) { + return false; + } + tmanager.removeFromSale(player, args[2], resadmin); + return true; + } + if (command.equals("sell")) { + if (args.length != 4) { + return false; + } + int amount; + try { + amount = Integer.parseInt(args[3]); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidAmount")); + return true; + } + tmanager.putForSale(args[2], player, amount, resadmin); + return true; + } + return false; + } + + private boolean commandResMarketRent(String[] args, boolean resadmin, + Player player, int page) { + if (args.length < 3 || args.length > 4) { + return false; + } + boolean repeat = false; + if (args.length == 4) { + if (args[3].equalsIgnoreCase("t") + || args[3].equalsIgnoreCase("true")) { + repeat = true; + } else if (!args[3].equalsIgnoreCase("f") + && !args[3].equalsIgnoreCase("false")) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidBoolean")); + return true; + } + } + rentmanager.rent(player, args[2], repeat, resadmin); + return true; + } + + private boolean commandResMarketRentable(String[] args, boolean resadmin, + Player player, int page) { + if (args.length < 5 || args.length > 6) { + return false; + } + if (!cmanager.enabledRentSystem()) { + player.sendMessage(ChatColor.RED + + language.getPhrase("RentDisabled")); + return true; + } + int days; + int cost; + try { + cost = Integer.parseInt(args[3]); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidCost")); + return true; + } + try { + days = Integer.parseInt(args[4]); + } catch (Exception ex) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidDays")); + return true; + } + boolean repeat = false; + if (args.length == 6) { + if (args[5].equalsIgnoreCase("t") + || args[5].equalsIgnoreCase("true")) { + repeat = true; + } else if (!args[5].equalsIgnoreCase("f") + && !args[5].equalsIgnoreCase("false")) { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidBoolean")); + return true; + } + } + rentmanager.setForRent(player, args[2], cost, days, repeat, resadmin); + return true; + } + + private boolean commandResMarketAutorenew(String[] args, boolean resadmin, + Player player, int page) { + if (!cmanager.enableEconomy()) { + player.sendMessage(ChatColor.RED + + language.getPhrase("MarketDisabled")); + return true; + } + if (args.length != 4) { + return false; + } + boolean value; + if (args[3].equalsIgnoreCase("true") || args[3].equalsIgnoreCase("t")) { + value = true; + } else if (args[3].equalsIgnoreCase("false") + || args[3].equalsIgnoreCase("f")) { + value = false; + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidBoolean")); + return true; + } + if (rentmanager.isRented(args[2]) + && rentmanager.getRentingPlayer(args[2]).equalsIgnoreCase( + player.getName())) { + rentmanager.setRentedRepeatable(player, args[2], value, resadmin); + } else if (rentmanager.isForRent(args[2])) { + rentmanager.setRentRepeatable(player, args[2], value, resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("RentReleaseInvalid", ChatColor.YELLOW + + args[2] + ChatColor.RED)); + } + return true; + } + + private boolean commandResMarketList(String[] args, boolean resadmin, + Player player, int page) { + if (!cmanager.enableEconomy()) { + player.sendMessage(ChatColor.RED + + language.getPhrase("MarketDisabled")); + return true; + } + player.sendMessage(ChatColor.BLUE + "---" + + language.getPhrase("MarketList") + "---"); + tmanager.printForSaleResidences(player); + if (cmanager.enabledRentSystem()) { + rentmanager.printRentableResidences(player); + } + return true; + } + + private boolean commandResMessage(String[] args, boolean resadmin, + Player player, int page) { + ClaimedResidence res = null; + int start = 0; + boolean enter = false; + if (args.length < 2) { + return false; + } + if (args[1].equals("enter")) { + enter = true; + res = rmanager.getByLoc(player.getLocation()); + start = 2; + } else if (args[1].equals("leave")) { + res = rmanager.getByLoc(player.getLocation()); + start = 2; + } else if (args[1].equals("remove")) { + if (args.length > 2 && args[2].equals("enter")) { + res = rmanager.getByLoc(player.getLocation()); + if (res != null) { + res.setEnterLeaveMessage(player, null, true, resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } else if (args.length > 2 && args[2].equals("leave")) { + res = rmanager.getByLoc(player.getLocation()); + if (res != null) { + res.setEnterLeaveMessage(player, null, false, resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidMessageType")); + return true; + } else if (args.length > 2 && args[2].equals("enter")) { + enter = true; + res = rmanager.getByName(args[1]); + start = 3; + } else if (args.length > 2 && args[2].equals("leave")) { + res = rmanager.getByName(args[1]); + start = 3; + } else if (args.length > 2 && args[2].equals("remove")) { + res = rmanager.getByName(args[1]); + if (args.length != 4) { + return false; + } + if (args[3].equals("enter")) { + if (res != null) { + res.setEnterLeaveMessage(player, null, true, resadmin); + } + return true; + } else if (args[3].equals("leave")) { + if (res != null) { + res.setEnterLeaveMessage(player, null, false, resadmin); + } + return true; + } + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidMessageType")); + return true; + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidMessageType")); + return true; + } + if (start == 0) { + return false; + } + String message = ""; + for (int i = start; i < args.length; i++) { + message = message + args[i] + " "; + } + if (res != null) { + res.setEnterLeaveMessage(player, message, enter, resadmin); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + + private boolean commandResSublist(String[] args, boolean resadmin, + Player player, int page) { + if (args.length == 1 || args.length == 2 || args.length == 3) { + ClaimedResidence res; + if (args.length == 1) { + res = rmanager.getByLoc(player.getLocation()); + } else { + res = rmanager.getByName(args[1]); + } + if (res != null) { + res.printSubzoneList(player, page); + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + return false; + } + + private boolean commandResCompass(String[] args, boolean resadmin, + Player player, int page) { + if (args.length != 2) { + player.setCompassTarget(player.getWorld().getSpawnLocation()); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("CompassTargetReset")); + return true; + } + if (rmanager.getByName(args[1]) != null) { + if (rmanager.getByName(args[1]).getWorld() + .equalsIgnoreCase(player.getWorld().getName())) { + Location low = rmanager.getByName(args[1]).getArea("main") + .getLowLoc(); + Location high = rmanager.getByName(args[1]).getArea("main") + .getHighLoc(); + Location mid = new Location(low.getWorld(), + (low.getBlockX() + high.getBlockX()) / 2, + (low.getBlockY() + high.getBlockY()) / 2, + (low.getBlockZ() + high.getBlockZ()) / 2); + player.setCompassTarget(mid); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("CompassTargetSet", + ChatColor.YELLOW + args[1] + ChatColor.GREEN)); + } + } else { + player.sendMessage(ChatColor.RED + + language.getPhrase("InvalidResidence")); + } + return true; + } + + private boolean commandResList(String[] args, boolean resadmin, + Player player, int page) { + if (args.length == 2) { + if (args[1].equals("list")) { + pmanager.printLists(player); + return true; + } + } else if (args.length == 3) { + if (args[1].equals("view")) { + pmanager.printList(player, args[2]); + return true; + } else if (args[1].equals("remove")) { + pmanager.removeList(player, args[2]); + return true; + } else if (args[1].equals("add")) { + pmanager.makeList(player, args[2]); + return true; + } + } else if (args.length == 4) { + if (args[1].equals("apply")) { + pmanager.applyListToResidence(player, args[2], args[3], + resadmin); + return true; + } + } else if (args.length == 5) { + if (args[1].equals("set")) { + pmanager.getList(player.getName(), args[2]).setFlag(args[3], + FlagPermissions.stringToFlagState(args[4])); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("FlagSet")); + return true; + } + } else if (args.length == 6) { + if (args[1].equals("gset")) { + pmanager.getList(player.getName(), args[2]).setGroupFlag( + args[3], args[4], + FlagPermissions.stringToFlagState(args[5])); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("FlagSet")); + return true; + } else if (args[1].equals("pset")) { + pmanager.getList(player.getName(), args[2]).setPlayerFlag( + args[3], args[4], + FlagPermissions.stringToFlagState(args[5])); + player.sendMessage(ChatColor.GREEN + + language.getPhrase("FlagSet")); + return true; + } + } + return false; + } +} diff --git a/src/com/bekvon/bukkit/residence/chat/ChatChannel.java b/src/com/bekvon/bukkit/residence/chat/ChatChannel.java new file mode 100644 index 0000000..55e0353 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/chat/ChatChannel.java @@ -0,0 +1,68 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.chat; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.event.ResidenceChatEvent; +import java.util.ArrayList; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.Server; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class ChatChannel { + + protected String name; + protected List members; + + public ChatChannel(String channelName) + { + name = channelName; + members = new ArrayList(); + } + + public void chat(String sourcePlayer, String message) + { + Server serv = Residence.getServ(); + ChatColor color = Residence.getConfigManager().getChatColor(); + ResidenceChatEvent cevent = new ResidenceChatEvent(Residence.getResidenceManager().getByName(name),serv.getPlayer(sourcePlayer),message,color); + Residence.getServ().getPluginManager().callEvent(cevent); + if(cevent.isCancelled()) + return; + for(String member : members) + { + Player player = serv.getPlayer(member); + if(player!=null) + player.sendMessage(cevent.getColor() + sourcePlayer + ": " + cevent.getChatMessage()); + } + System.out.println("ResidentialChat[" + name + "] - " + sourcePlayer + ": " + cevent.getChatMessage()); + } + + public void join(String player) + { + if(!members.contains(player)) + members.add(player); + } + + public void leave(String player) + { + members.remove(player); + } + + public boolean hasMember(String player) + { + return members.contains(player); + } + + public int memberCount() + { + return members.size(); + } +} diff --git a/src/com/bekvon/bukkit/residence/chat/ChatManager.java b/src/com/bekvon/bukkit/residence/chat/ChatManager.java new file mode 100644 index 0000000..2814247 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/chat/ChatManager.java @@ -0,0 +1,60 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.chat; + +import com.bekvon.bukkit.residence.Residence; +import java.util.HashMap; +import java.util.Map; +import org.bukkit.Server; + +/** + * + * @author Administrator + */ +public class ChatManager { + + protected Map channelmap; + protected Server server; + + public ChatManager() + { + server = Residence.getServ(); + channelmap = new HashMap(); + } + + public void setChannel(String player, String channel) + { + this.removeFromChannel(player); + if(!channelmap.containsKey(channel)) + channelmap.put(channel, new ChatChannel(channel)); + channelmap.get(channel).join(player); + } + + public void removeFromChannel(String player) + { + for(ChatChannel chan : channelmap.values()) + { + if(chan.hasMember(player)) + chan.leave(player); + } + } + + public ChatChannel getChannel(String channel) + { + return channelmap.get(channel); + } + + public ChatChannel getPlayerChannel(String player) + { + for(ChatChannel chan : channelmap.values()) + { + if(chan.hasMember(player)) + return chan; + } + return null; + } + +} diff --git a/src/com/bekvon/bukkit/residence/config/Config.java b/src/com/bekvon/bukkit/residence/config/Config.java new file mode 100644 index 0000000..8694f7c --- /dev/null +++ b/src/com/bekvon/bukkit/residence/config/Config.java @@ -0,0 +1,55 @@ +package com.bekvon.bukkit.residence.config; + +import java.io.File; +import java.io.IOException; + +import org.bukkit.plugin.Plugin; + +public class Config extends ConfigLoader { + private static String CONFIG_NAME = "config.yml"; + private static FileConfig instance; + private static File file; + + public Config(Plugin p) { + super(p, CONFIG_NAME); + file = new File(p.getDataFolder(), CONFIG_NAME); + instance = super.getInstance(); + } + + public Config(Plugin p, String ver) { + super(p, CONFIG_NAME, ver); + instance = super.getInstance(); + } + + public static void load(Plugin p) { + new Config(p); + } + + public static void load(Plugin p, String ver) { + new Config(p, ver); + } + + public static FileConfig getInstance() { + return instance; + } + + public static String getMessage(String path) { + String message = instance.getString(path); + if (message != null) + message = message.replaceAll("&", "§"); + return message; + } + + public static String[] getStringArray(String path) { + return instance.getStringList(path).toArray(new String[0]); + } + + public static void save(){ + try { + instance.save(file); + } catch (IOException e) { + saveError(file); + e.printStackTrace(); + } + } +} diff --git a/src/com/bekvon/bukkit/residence/config/ConfigLoader.java b/src/com/bekvon/bukkit/residence/config/ConfigLoader.java new file mode 100644 index 0000000..34c8ff9 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/config/ConfigLoader.java @@ -0,0 +1,102 @@ +package com.bekvon.bukkit.residence.config; + +import java.io.File; +import java.io.IOException; + +import org.bukkit.plugin.Plugin; + +public class ConfigLoader extends FileConfig { + protected static FileConfig config; + protected static boolean tip = true; + protected static Plugin plugin; + + public ConfigLoader(Plugin p, File file) { + ConfigLoader.plugin = p; + config = loadConfig(p, file, null, true); + } + + public ConfigLoader(Plugin p, File file, boolean res) { + ConfigLoader.plugin = p; + config = loadConfig(p, file, null, res); + } + + public ConfigLoader(Plugin p, File file, String ver) { + ConfigLoader.plugin = p; + config = loadConfig(p, file, ver, true); + } + + public ConfigLoader(Plugin p, File file, String ver, boolean res) { + ConfigLoader.plugin = p; + config = loadConfig(p, file, ver, res); + } + + public ConfigLoader(Plugin p, String filename) { + ConfigLoader.plugin = p; + config = loadConfig(p, new File(p.getDataFolder(), filename), null, + true); + } + + public ConfigLoader(Plugin p, String filename, boolean res) { + ConfigLoader.plugin = p; + config = loadConfig(p, new File(p.getDataFolder(), filename), null, res); + } + + public ConfigLoader(Plugin p, String filename, String ver) { + ConfigLoader.plugin = p; + config = loadConfig(p, new File(p.getDataFolder(), filename), ver, true); + } + + public ConfigLoader(Plugin p, String filename, String ver, boolean res) { + ConfigLoader.plugin = p; + config = loadConfig(p, new File(p.getDataFolder(), filename), ver, true); + } + + public static FileConfig getInstance() { + return config; + } + + public FileConfig loadConfig(Plugin p, File file, String ver, boolean res) { + tip = res ; + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + p.getLogger().info("创建新的文件夹" + file.getParentFile().getAbsolutePath() + "..."); + } + if (!file.exists()) { + fileCreate(p, file, res); + } else { + if (ver != null) { + FileConfig configcheck = init(file); + String version = configcheck.getString("version"); + if (version == null || !version.equals(ver)) { + p.saveResource(file.getName(), true); + p.getLogger().warning( + "配置文件: " + file.getName() + " 版本过低 正在升级..."); + } + } + } + if (tip) + p.getLogger().info( + "载入配置文件: " + file.getName() + + (ver != null ? " 版本: " + ver : "")); + return init(file); + } + + private void fileCreate(Plugin p, File file, boolean res) { + if (res) { + p.saveResource(file.getName(), false); + } else { + try { + p.getLogger().info("创建新的配置文件" + file.getAbsolutePath() + "..."); + file.createNewFile(); + } catch (IOException e) { + p.getLogger().info("配置文件" + file.getName() + "创建失败..."); + e.printStackTrace(); + } + } + } + + public static void saveError(File file) { + plugin.getLogger().info("配置文件" + file.getName() + "保存错误..."); + } + +} diff --git a/src/com/bekvon/bukkit/residence/config/FileConfig.java b/src/com/bekvon/bukkit/residence/config/FileConfig.java new file mode 100644 index 0000000..ada5623 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/config/FileConfig.java @@ -0,0 +1,88 @@ +package com.bekvon.bukkit.residence.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.logging.Level; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.file.YamlConstructor; +import org.bukkit.configuration.file.YamlRepresenter; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.representer.Representer; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +/** + * An implementation of {@link Configuration} which saves all files in Yaml. + * Note that this implementation is not synchronized. + */ +public class FileConfig extends YamlConfiguration { + + protected final DumperOptions yamlOptions = new DumperOptions(); + protected final Representer yamlRepresenter = new YamlRepresenter(); + protected final Yaml yaml = new Yaml(new YamlConstructor(), + yamlRepresenter, yamlOptions); + + public static FileConfig init(File file) { + return FileConfig.loadConfiguration(file); + } + + public static FileConfig loadConfiguration(File file) { + Validate.notNull(file, "File cannot be null"); + FileConfig config = new FileConfig(); + try { + config.load(file); + } catch (FileNotFoundException ex) { + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex); + } catch (InvalidConfigurationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex); + } + return config; + } + + @Override + public String saveToString() { + yamlOptions.setIndent(options().indent()); + yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + String header = buildHeader(); + String dump = yaml.dump(getValues(false)); + if (dump.equals(BLANK_CONFIG)) { + dump = ""; + } + return header + dump; + } + + public void load(File file) throws FileNotFoundException, IOException, + InvalidConfigurationException { + Validate.notNull(file, "File cannot be null"); + final FileInputStream stream = new FileInputStream(file); + load(new InputStreamReader(stream, Charsets.UTF_8)); + } + + public void save(File file) throws IOException { + Validate.notNull(file, "File cannot be null"); + Files.createParentDirs(file); + String data = saveToString(); + Writer writer = new OutputStreamWriter(new FileOutputStream(file), + Charsets.UTF_8); + try { + writer.write(data); + } finally { + writer.close(); + } + } +} diff --git a/src/com/bekvon/bukkit/residence/economy/EconomyInterface.java b/src/com/bekvon/bukkit/residence/economy/EconomyInterface.java new file mode 100644 index 0000000..9f4a61b --- /dev/null +++ b/src/com/bekvon/bukkit/residence/economy/EconomyInterface.java @@ -0,0 +1,10 @@ +package com.bekvon.bukkit.residence.economy; + +public interface EconomyInterface { + public double getBalance(String playerName); + public boolean canAfford(String playerName, double amount); + public boolean add(String playerName, double amount); + public boolean subtract(String playerName, double amount); + public boolean transfer(String playerFrom, String playerTo, double amount); + public String getName(); +} diff --git a/src/com/bekvon/bukkit/residence/economy/EssentialsEcoAdapter.java b/src/com/bekvon/bukkit/residence/economy/EssentialsEcoAdapter.java new file mode 100644 index 0000000..c8798a6 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/economy/EssentialsEcoAdapter.java @@ -0,0 +1,109 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.economy; + +import com.earth2me.essentials.Essentials; +import com.earth2me.essentials.api.Economy; +import com.earth2me.essentials.api.NoLoanPermittedException; +import com.earth2me.essentials.api.UserDoesNotExistException; + +/** + * + * @author Administrator + */ +public class EssentialsEcoAdapter implements EconomyInterface { + + Essentials plugin; + + public EssentialsEcoAdapter(Essentials p) { + plugin = p; + String serverland = "Server Land"; + if (!Economy.playerExists(serverland)) { + Economy.createNPC(serverland); + } + } + + @Override + public double getBalance(String playerName) { + try { + if (Economy.playerExists(playerName)) { + return Economy.getMoney(playerName); + } else { + return 0; + } + } catch (UserDoesNotExistException ex) { + return 0; + } + } + + @Override + public boolean canAfford(String playerName, double amount) { + try { + if (Economy.playerExists(playerName)) { + return Economy.hasEnough(playerName, amount); + } + return false; + } catch (UserDoesNotExistException ex) { + return false; + } + } + + @Override + public boolean add(String playerName, double amount) { + if (Economy.playerExists(playerName)) { + try { + Economy.add(playerName, amount); + return true; + } catch (UserDoesNotExistException ex) { + return false; + } catch (NoLoanPermittedException ex) { + return false; + } + } else { + return false; + } + } + + @Override + public boolean subtract(String playerName, double amount) { + if (Economy.playerExists(playerName)) { + try { + Economy.subtract(playerName, amount); + return true; + } catch (UserDoesNotExistException ex) { + return false; + } catch (NoLoanPermittedException ex) { + return false; + } + } else { + return false; + } + } + + @Override + public boolean transfer(String playerFrom, String playerTo, double amount) { + try { + if (Economy.playerExists(playerFrom) && Economy.playerExists(playerTo) && Economy.hasEnough(playerFrom, amount)) { + if (!subtract(playerFrom, amount)) + return false; + if (!add(playerTo, amount)) { + add(playerFrom, amount); + return false; + } + return true; + } + } catch (UserDoesNotExistException ex) { + return false; + } + return false; + } + + @Override + public String getName() { + return "EssentialsEconomy"; + } + +} diff --git a/src/com/bekvon/bukkit/residence/economy/ResidenceBank.java b/src/com/bekvon/bukkit/residence/economy/ResidenceBank.java new file mode 100644 index 0000000..8640833 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/economy/ResidenceBank.java @@ -0,0 +1,101 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.economy; +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class ResidenceBank { + int storedMoney; + ClaimedResidence res; + + public ResidenceBank(ClaimedResidence parent) + { + storedMoney = 0; + res = parent; + } + + public int getStoredMoney() + { + return storedMoney; + } + + public void setStoredMoney(int amount) + { + storedMoney = amount; + } + + public void add(int amount) + { + storedMoney = storedMoney + amount; + } + + public boolean hasEnough(int amount) + { + if(storedMoney >= amount) + return true; + return false; + } + + public void subtract(int amount) + { + storedMoney = storedMoney - amount; + if(storedMoney<0) + storedMoney = 0; + } + + public void withdraw(Player player, int amount, boolean resadmin) + { + if(!Residence.getConfigManager().enableEconomy()) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("MarketDisabled")); + } + if(!resadmin && !res.getPermissions().playerHas(player.getName(), "bank", false)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoBankAccess")); + return; + } + if(!hasEnough(amount)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("BankNoMoney")); + return; + } + if(Residence.getEconomyManager().add(player.getName(), amount)) + { + this.subtract(amount); + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("BankWithdraw",ChatColor.YELLOW + String.format("%d",amount) + ChatColor.GREEN)); + } + } + + public void deposit(Player player, int amount, boolean resadmin) + { + if(!Residence.getConfigManager().enableEconomy()) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("MarketDisabled")); + } + if(!resadmin && !res.getPermissions().playerHas(player.getName(), "bank", false)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoBankAccess")); + return; + } + if(!Residence.getEconomyManager().canAfford(player.getName(), amount)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NotEnoughMoney")); + return; + } + if(Residence.getEconomyManager().subtract(player.getName(), amount)) + { + this.add(amount); + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("BankDeposit",ChatColor.YELLOW + String.format("%d",amount) + ChatColor.GREEN)); + } + } +} diff --git a/src/com/bekvon/bukkit/residence/economy/TransactionManager.java b/src/com/bekvon/bukkit/residence/economy/TransactionManager.java new file mode 100644 index 0000000..b6c3a4b --- /dev/null +++ b/src/com/bekvon/bukkit/residence/economy/TransactionManager.java @@ -0,0 +1,266 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.economy; + +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.protection.CuboidArea; +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.protection.ResidenceManager; +import com.bekvon.bukkit.residence.permissions.PermissionManager; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import org.bukkit.Server; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class TransactionManager { + ResidenceManager manager; + private Map sellAmount; + PermissionManager gm; + + public static boolean chargeEconomyMoney(Player player, int amount) { + EconomyInterface econ = Residence.getEconomyManager(); + if (econ == null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("MarketDisabled")); + return false; + } + if (!econ.canAfford(player.getName(), amount)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NotEnoughMoney")); + return false; + } + econ.subtract(player.getName(), amount); + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("MoneyCharged", ChatColor.YELLOW + String.format("%d", amount) + ChatColor.GREEN + "." + ChatColor.YELLOW + econ.getName() + ChatColor.GREEN)); + return true; + } + + public TransactionManager(ResidenceManager m, PermissionManager g) { + gm = g; + manager = m; + sellAmount = Collections.synchronizedMap(new HashMap()); + } + + public void putForSale(String areaname, Player player, int amount, boolean resadmin) { + if (Residence.getConfigManager().enabledRentSystem()) { + if (Residence.getRentManager().isForRent(areaname)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("RentSellFail")); + return; + } + } + if (!resadmin) { + if (!Residence.getConfigManager().enableEconomy() || Residence.getEconomyManager() == null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("MarketDisabled")); + return; + } + boolean cansell = Residence.getPermissionManager().getGroup(player).canSellLand() || player.hasPermission("residence.sell"); + if (!cansell && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + if (amount <= 0) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidAmount")); + return; + } + } + String pname = player.getName(); + ClaimedResidence area = manager.getByName(areaname); + if (area == null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidResidence")); + return; + } + if (!area.getPermissions().getOwner().equals(pname) && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + if (sellAmount.containsKey(areaname)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AlreadySellFail")); + return; + } + sellAmount.put(areaname, amount); + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("ResidenceForSale", ChatColor.YELLOW + areaname + ChatColor.GREEN + "." + ChatColor.YELLOW + amount + ChatColor.GREEN)); + } + + public boolean putForSale(String areaname, int amount) { + if (Residence.getConfigManager().enabledRentSystem()) { + if (Residence.getRentManager().isForRent(areaname)) { + return false; + } + } + ClaimedResidence area = manager.getByName(areaname); + if (area == null) { + return false; + } + if (sellAmount.containsKey(areaname)) { + return false; + } + sellAmount.put(areaname, amount); + return true; + } + + public void buyPlot(String areaname, Player player, boolean resadmin) { + PermissionGroup group = gm.getGroup(player); + if (!resadmin) { + if (!Residence.getConfigManager().enableEconomy() || Residence.getEconomyManager() == null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("MarketDisabled")); + return; + } + boolean canbuy = group.canBuyLand() || player.hasPermission("residence.buy"); + if (!canbuy && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + } + if (isForSale(areaname)) { + ClaimedResidence res = manager.getByName(areaname); + if (res == null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidArea")); + sellAmount.remove(areaname); + return; + } + if (res.getPermissions().getOwner().equals(player.getName())) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("OwnerBuyFail")); + return; + } + if (Residence.getResidenceManager().getOwnedZoneCount(player.getName()) >= group.getMaxZones() && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ResidenceTooMany")); + return; + } + Server serv = Residence.getServ(); + int amount = sellAmount.get(areaname); + if (!resadmin) { + if (!group.buyLandIgnoreLimits()) { + CuboidArea[] areas = res.getAreaArray(); + for (CuboidArea thisarea : areas) { + if (!group.inLimits(thisarea)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ResidenceBuyTooBig")); + return; + } + } + } + } + EconomyInterface econ = Residence.getEconomyManager(); + if (econ == null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("MarketDisabled")); + return; + } + String buyerName = player.getName(); + String sellerName = res.getPermissions().getOwner(); + Player sellerNameFix = Residence.getServ().getPlayer(sellerName); + if (sellerNameFix != null) { + sellerName = sellerNameFix.getName(); + } + if (econ.canAfford(buyerName, amount)) { + if (!econ.transfer(buyerName, sellerName, amount)) { + player.sendMessage(ChatColor.RED + "Error, could not transfer " + amount + " from " + buyerName + " to " + sellerName); + return; + } + res.getPermissions().setOwner(player.getName(), true); + res.getPermissions().applyDefaultFlags(); + this.removeFromSale(areaname); + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("MoneyCharged", ChatColor.YELLOW + String.format("%d", amount) + ChatColor.GREEN + "." + ChatColor.YELLOW + econ.getName() + ChatColor.GREEN)); + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("ResidenceBought", ChatColor.GREEN + areaname + ChatColor.YELLOW)); + Player seller = serv.getPlayer(sellerName); + if (seller != null && seller.isOnline()) { + seller.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("ResidenceBuy", ChatColor.YELLOW + player.getName() + ChatColor.GREEN + "." + ChatColor.YELLOW + areaname + ChatColor.GREEN)); + seller.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("MoneyCredit", ChatColor.YELLOW + String.format("%d", amount) + ChatColor.GREEN + "." + ChatColor.YELLOW + econ.getName() + ChatColor.GREEN)); + } + } else { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NotEnoughMoney")); + } + } else { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidResidence")); + } + } + + public void removeFromSale(Player player, String areaname, boolean resadmin) { + ClaimedResidence area = manager.getByName(areaname); + if (area != null) { + if (!isForSale(areaname)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ResidenceNotForSale")); + return; + } + if (area.getPermissions().getOwner().equals(player.getName()) || resadmin) { + removeFromSale(areaname); + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("ResidenceStopSelling")); + } else { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + } + } else { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidArea")); + } + } + + public void removeFromSale(String areaname) { + sellAmount.remove(areaname); + } + + public boolean isForSale(String areaname) { + return sellAmount.containsKey(areaname); + } + + public void viewSaleInfo(String areaname, Player player) { + if (sellAmount.containsKey(areaname)) { + player.sendMessage("------------------------"); + player.sendMessage(ChatColor.YELLOW + "Name:" + ChatColor.DARK_GREEN + " " + areaname); + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("SellAmount") + ":" + ChatColor.RED + " " + sellAmount.get(areaname)); + if (Residence.getConfigManager().useLeases()) { + Date etime = Residence.getLeaseManager().getExpireTime(areaname); + if (etime != null) { + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("LeaseExpire") + ":" + ChatColor.GREEN + " " + etime.toString()); + } + } + player.sendMessage("------------------------"); + } + } + + public void printForSaleResidences(Player player) { + Set> set = sellAmount.entrySet(); + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("LandForSale") + ":"); + StringBuilder sbuild = new StringBuilder(); + sbuild.append(ChatColor.GREEN); + boolean firstadd = true; + for (Entry land : set) { + if (!firstadd) { + sbuild.append(", "); + } else { + firstadd = false; + } + sbuild.append(land.getKey()); + } + player.sendMessage(sbuild.toString()); + } + + public void clearSales() { + sellAmount.clear(); + System.out.println("[Residence] - ReInit land selling."); + } + + public int getSaleAmount(String name) { + return sellAmount.get(name); + } + + public Map save() { + return sellAmount; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static TransactionManager load(Map root, PermissionManager p, ResidenceManager r) { + TransactionManager tman = new TransactionManager(r, p); + if (root != null) { + tman.sellAmount = root; + } + return tman; + } +} diff --git a/src/com/bekvon/bukkit/residence/economy/rent/RentManager.java b/src/com/bekvon/bukkit/residence/economy/rent/RentManager.java new file mode 100644 index 0000000..472a8df --- /dev/null +++ b/src/com/bekvon/bukkit/residence/economy/rent/RentManager.java @@ -0,0 +1,499 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.economy.rent; +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.event.ResidenceRentEvent; +import com.bekvon.bukkit.residence.event.ResidenceRentEvent.RentEventType; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import com.bekvon.bukkit.residence.protection.FlagPermissions.FlagState; + +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class RentManager { + protected Map rentedLand; + protected Map rentableLand; + + public RentManager() + { + rentedLand = new HashMap(); + rentableLand = new HashMap(); + } + + public void setForRent(Player player, String landName, int amount, int days, boolean repeatable, boolean resadmin) + { + if(!Residence.getConfigManager().enabledRentSystem()) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("MarketDisabled")); + return; + } + if(Residence.getTransactionManager().isForSale(landName)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("SellRentFail")); + return; + } + ClaimedResidence res = Residence.getResidenceManager().getByName(landName); + if(res == null) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("InvalidResidence")); + return; + } + if(!resadmin) + { + if(!res.getPermissions().hasResidencePermission(player, true)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoPermission")); + return; + } + PermissionGroup group = Residence.getPermissionManager().getGroup(player); + if(this.getRentableCount(player.getName()) >= group.getMaxRentables()) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("ResidenceMaxRent")); + return; + } + } + if(!rentableLand.containsKey(landName)) + { + ResidenceRentEvent revent = new ResidenceRentEvent(res,player,RentEventType.RENTABLE); + Residence.getServ().getPluginManager().callEvent(revent); + if(revent.isCancelled()) + return; + RentableLand newrent = new RentableLand(); + newrent.days = days; + newrent.cost = amount; + newrent.repeatable = repeatable; + rentableLand.put(landName,newrent); + String[] split = landName.split("\\."); + if(split.length!=0) + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("ResidenceForRentSuccess",ChatColor.YELLOW+split[split.length-1] + ChatColor.GREEN+"."+ChatColor.YELLOW+amount+ChatColor.GREEN+"."+ChatColor.YELLOW+days+ChatColor.GREEN)); + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("ResidenceAlreadyRent")); + } + } + + public void rent(Player player, String landName, boolean repeat, boolean resadmin) + { + if(!Residence.getConfigManager().enabledRentSystem()) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("RentDisabled")); + return; + } + ClaimedResidence res = Residence.getResidenceManager().getByName(landName); + if(res!=null) + { + if(res.getPermissions().getOwner().equalsIgnoreCase(player.getName())) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("OwnerRentFail")); + return; + } + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("InvalidResidence")); + return; + } + PermissionGroup group = Residence.getPermissionManager().getGroup(player); + if(!resadmin && this.getRentCount(player.getName()) >= group.getMaxRents()) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("ResidenceMaxRent")); + return; + } + if(!this.isForRent(landName)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("ResidenceNotForRent")); + return; + } + if(this.isRented(landName)) + { + String[] split = landName.split("\\."); + if(split.length!=0) + player.sendMessage(Residence.getLanguage().getPhrase("ResidenceAlreadyRented",ChatColor.YELLOW+split[split.length-1] + ChatColor.RED+"."+ChatColor.YELLOW + this.getRentingPlayer(landName))); + return; + } + RentableLand land = rentableLand.get(landName); + if(Residence.getEconomyManager().canAfford(player.getName(), land.cost)) + { + ResidenceRentEvent revent = new ResidenceRentEvent(res,player,RentEventType.RENT); + Residence.getServ().getPluginManager().callEvent(revent); + if(revent.isCancelled()) + return; + if(Residence.getEconomyManager().transfer(player.getName(), res.getPermissions().getOwner(), land.cost)) + { + RentedLand newrent = new RentedLand(); + newrent.player = player.getName(); + newrent.startTime = System.currentTimeMillis(); + newrent.endTime = System.currentTimeMillis() + daysToMs(land.days); + newrent.autoRefresh = repeat; + rentedLand.put(landName, newrent); + res.getPermissions().copyUserPermissions(res.getPermissions().getOwner(), player.getName()); + res.getPermissions().clearPlayersFlags(res.getPermissions().getOwner()); + res.getPermissions().setPlayerFlag(player.getName(), "admin", FlagState.TRUE); + String[] split = landName.split("\\."); + if(split.length!=0) + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("ResidenceRentSuccess",ChatColor.YELLOW + split[split.length-1] + ChatColor.GREEN+"."+ChatColor.YELLOW + land.days + ChatColor.GREEN)); + } + else + { + player.sendMessage(ChatColor.RED+"Error, unable to transfer money..."); + } + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NotEnoughMoney")); + } + } + + public void removeFromForRent(Player player, String landName, boolean resadmin) + { + RentedLand rent = rentedLand.get(landName); + if(rent == null) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("ResidenceNotRented")); + return; + } + if(resadmin || rent.player.equalsIgnoreCase(player.getName())) + { + ResidenceRentEvent revent = new ResidenceRentEvent(Residence.getResidenceManager().getByName(landName),player,RentEventType.UNRENTABLE); + Residence.getServ().getPluginManager().callEvent(revent); + if(revent.isCancelled()) + return; + rentedLand.remove(landName); + if(!rentableLand.get(landName).repeatable) + { + rentableLand.remove(landName); + } + ClaimedResidence res = Residence.getResidenceManager().getByName(landName); + if(res!=null) + res.getPermissions().applyDefaultFlags(); + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("ResidenceUnrent",ChatColor.YELLOW+landName + ChatColor.GREEN)); + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoPermission")); + } + } + + private long daysToMs(int days) + { + return (((long)days) * 24L * 60L * 60L * 1000L); + } + + @SuppressWarnings("unused") + private int msToDays(long ms) + { + return (int) Math.ceil(((((double)ms/1000D)/60D)/60D)/24D); + } + + public void unrent(Player player, String landName, boolean resadmin) + { + String[] split = landName.split("\\."); + ClaimedResidence res = Residence.getResidenceManager().getByName(landName); + if(res == null) + { + player.sendMessage(ChatColor.YELLOW+Residence.getLanguage().getPhrase("InvalidResidence")); + return; + } + if(!res.getPermissions().hasResidencePermission(player, true) && !resadmin) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoPermission")); + return; + } + if(rentedLand.containsKey(landName) && !resadmin) + { + if(split.length!=0) + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("ResidenceAlreadyRented",ChatColor.YELLOW+split[split.length-1] + ChatColor.RED+"."+ChatColor.YELLOW + rentedLand.get(landName).player)+ChatColor.YELLOW); + return; + } + if(rentableLand.containsKey(landName)) + { + ResidenceRentEvent revent = new ResidenceRentEvent(res,player,RentEventType.UNRENT); + Residence.getServ().getPluginManager().callEvent(revent); + if(revent.isCancelled()) + return; + rentableLand.remove(landName); + if(rentedLand.containsKey(landName)) + { + rentedLand.remove(landName); + if(res!=null) + res.getPermissions().applyDefaultFlags(); + } + if(split.length!=0) + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("ResidenceRemoveRentable",ChatColor.YELLOW+split[split.length-1] + ChatColor.RED)); + + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("ResidenceNotForRent")); + } + } + + public void removeFromRent(String landName) + { + rentedLand.remove(landName); + } + + public void removeRentable(String landName) + { + removeFromRent(landName); + rentableLand.remove(landName); + } + + public boolean isForRent(String landName) + { + return rentableLand.containsKey(landName); + } + + public boolean isRented(String landName) + { + return rentedLand.containsKey(landName); + } + + public String getRentingPlayer(String landName) + { + return rentedLand.containsKey(landName) ? rentedLand.get(landName).player : null; + } + + public int getCostOfRent(String landName) + { + return rentableLand.containsKey(landName) ? rentableLand.get(landName).cost : 0; + } + + public boolean getRentableRepeatable(String landName) + { + return rentableLand.containsKey(landName) ? rentableLand.get(landName).repeatable : false; + } + + public boolean getRentedAutoRepeats(String landName) + { + return getRentableRepeatable(landName) ? (rentedLand.containsKey(landName) ? rentedLand.get(landName).autoRefresh : false) : false; + } + + public int getRentDays(String landName) + { + return rentableLand.containsKey(landName) ? rentableLand.get(landName).days : 0; + } + + public void checkCurrentRents() + { + Iterator> it = rentedLand.entrySet().iterator(); + while(it.hasNext()) + { + Entry next = it.next(); + RentedLand land = next.getValue(); + if(land.endTime<=System.currentTimeMillis()) + { + ClaimedResidence res = Residence.getResidenceManager().getByName(next.getKey()); + if(Residence.getConfigManager().debugEnabled()) + System.out.println("Rent Check: "+next.getKey()); + if (res != null) { + ResidenceRentEvent revent = new ResidenceRentEvent(res, null, RentEventType.RENT_EXPIRE); + Residence.getServ().getPluginManager().callEvent(revent); + if (!revent.isCancelled()) { + RentableLand rentable = rentableLand.get(next.getKey()); + if (!rentable.repeatable) { + rentableLand.remove(next.getKey()); + it.remove(); + res.getPermissions().applyDefaultFlags(); + } else if (land.autoRefresh) { + if (!Residence.getEconomyManager().canAfford(land.player, rentable.cost)) { + it.remove(); + res.getPermissions().applyDefaultFlags(); + } else { + if (!Residence.getEconomyManager().transfer(land.player, res.getPermissions().getOwner(), rentable.cost)) { + it.remove(); + res.getPermissions().applyDefaultFlags(); + } + else + { + land.endTime = System.currentTimeMillis() + this.daysToMs(rentable.days); + } + } + } else { + res.getPermissions().applyDefaultFlags(); + it.remove(); + } + } + } + else + { + rentableLand.remove(next.getKey()); + it.remove(); + } + } + } + } + + public void setRentRepeatable(Player player, String landName, boolean value, boolean resadmin) + { + String[] split = landName.split("\\."); + RentableLand land = rentableLand.get(landName); + ClaimedResidence res = Residence.getResidenceManager().getByName(landName); + if(land!=null && res!=null && (res.getPermissions().getOwner().equalsIgnoreCase(player.getName()) || resadmin)) + { + land.repeatable = value; + if(!value && this.isRented(landName)) + rentedLand.get(landName).autoRefresh = false; + if(value && split.length!=0) + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("RentableEnableRenew",ChatColor.YELLOW+split[split.length-1] + ChatColor.RED)); + else if(split.length!=0) + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("RentableDisableRenew",ChatColor.YELLOW+split[split.length-1] + ChatColor.RED)); + } + } + + public void setRentedRepeatable(Player player, String landName, boolean value, boolean resadmin) + { + String[] split = landName.split("\\."); + RentedLand land = rentedLand.get(landName); + if(land!=null && (land.player.equals(player.getName()) || resadmin)) + { + land.autoRefresh = value; + if(value && split.length!=0) + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("RentEnableRenew",ChatColor.YELLOW+split[split.length-1] + ChatColor.RED)); + else if(split.length!=0) + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("RentDisableRenew",ChatColor.YELLOW+split[split.length-1] + ChatColor.RED)); + } + } + + public void printRentInfo(Player player, String landName) + { + RentableLand rentable = rentableLand.get(landName); + RentedLand rented = rentedLand.get(landName); + if(rentable!=null) + { + player.sendMessage(ChatColor.GOLD+Residence.getLanguage().getPhrase("Land")+":"+ChatColor.DARK_GREEN + landName); + player.sendMessage(ChatColor.YELLOW+Residence.getLanguage().getPhrase("Cost")+": "+ChatColor.DARK_AQUA + rentable.cost + " per " + rentable.days + " days"); + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("RentableAutoRenew")+":"+ChatColor.DARK_AQUA + rentable.repeatable); + if(rented!=null) + { + player.sendMessage(ChatColor.GOLD+Residence.getLanguage().getPhrase("Status")+":"+ChatColor.YELLOW+" "+Residence.getLanguage().getPhrase("ResidenceRentedBy",ChatColor.RED + rented.player+ChatColor.YELLOW)); + player.sendMessage(ChatColor.YELLOW+Residence.getLanguage().getPhrase("RentExpire")+":"+ChatColor.GREEN + new Date(rented.endTime)); + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("RentAutoRenew")+":"+ChatColor.DARK_AQUA + rented.autoRefresh); + } + else + { + player.sendMessage(ChatColor.GOLD+Residence.getLanguage().getPhrase("Status")+":"+ChatColor.GREEN+" "+Residence.getLanguage().getPhrase("Available")); + } + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("ResidenceNotForRent")); + } + } + + @SuppressWarnings("unchecked") + public static RentManager load(Map root) + { + RentManager rentManager = new RentManager(); + if(root!=null) + { + Map rentables = (Map) root.get("Rentables"); + for(Entry rent : rentables.entrySet()) + { + rentManager.rentableLand.put(rent.getKey(), RentableLand.load((Map) rent.getValue())); + } + Map rented = (Map) root.get("Rented"); + for(Entry rent : rented.entrySet()) + { + rentManager.rentedLand.put(rent.getKey(), RentedLand.load((Map) rent.getValue())); + } + } + return rentManager; + } + + public Map save() + { + Map root = new HashMap(); + Map rentables = new HashMap(); + for(Entry rent : rentableLand.entrySet()) + { + rentables.put(rent.getKey(), rent.getValue().save()); + } + Map rented = new HashMap(); + for(Entry rent : rentedLand.entrySet()) + { + rented.put(rent.getKey(), rent.getValue().save()); + } + root.put("Rentables", rentables); + root.put("Rented", rented); + return root; + } + + public void updateRentableName(String oldName, String newName) + { + if(rentableLand.containsKey(oldName)) + { + rentableLand.put(newName, rentableLand.get(oldName)); + rentableLand.remove(oldName); + } + if(rentedLand.containsKey(oldName)) + { + rentedLand.put(newName, rentedLand.get(oldName)); + rentedLand.remove(oldName); + } + } + + public void printRentableResidences(Player player) + { + Set> set = rentableLand.entrySet(); + player.sendMessage(ChatColor.YELLOW+Residence.getLanguage().getPhrase("RentableLand")+":"); + StringBuilder sbuild = new StringBuilder(); + sbuild.append(ChatColor.GREEN); + boolean firstadd = true; + for(Entry land : set) + { + if(!this.isRented(land.getKey())) + { + if(!firstadd) + sbuild.append(", "); + else + firstadd = false; + sbuild.append(land.getKey()); + } + } + player.sendMessage(sbuild.toString()); + } + + public int getRentCount(String player) + { + Set> set = rentedLand.entrySet(); + int count = 0; + for(Entry land : set) + { + if(land.getValue().player.equalsIgnoreCase(player)) + count++; + } + return count; + } + + public int getRentableCount(String player) + { + Set set = rentableLand.keySet(); + int count = 0; + for(String land : set) + { + ClaimedResidence res = Residence.getResidenceManager().getByName(land); + if(res!=null) + if(res.getPermissions().getOwner().equalsIgnoreCase(player)) + count++; + } + return count; + } +} diff --git a/src/com/bekvon/bukkit/residence/economy/rent/RentableLand.java b/src/com/bekvon/bukkit/residence/economy/rent/RentableLand.java new file mode 100644 index 0000000..374d347 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/economy/rent/RentableLand.java @@ -0,0 +1,36 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.economy.rent; + +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author Administrator + */ +public class RentableLand { + + public int days; + public int cost; + public boolean repeatable; + + public Map save() { + Map rented = new HashMap(); + rented.put("Days", days); + rented.put("Cost", cost); + rented.put("Repeatable", repeatable); + return rented; + } + + public static RentableLand load(Map map) { + RentableLand newland = new RentableLand(); + newland.cost = (Integer)map.get("Cost"); + newland.days = (Integer)map.get("Days"); + newland.repeatable = (Boolean)map.get("Repeatable"); + return newland; + } +} diff --git a/src/com/bekvon/bukkit/residence/economy/rent/RentedLand.java b/src/com/bekvon/bukkit/residence/economy/rent/RentedLand.java new file mode 100644 index 0000000..021391c --- /dev/null +++ b/src/com/bekvon/bukkit/residence/economy/rent/RentedLand.java @@ -0,0 +1,39 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.economy.rent; + +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author Administrator + */ +public class RentedLand { + + public String player; + public long startTime; + public long endTime; + public boolean autoRefresh; + + public Map save() { + Map rentables = new HashMap(); + rentables.put("Player", player); + rentables.put("StartTime", startTime); + rentables.put("EndTime", endTime); + rentables.put("AutoRefresh", autoRefresh); + return rentables; + } + public static RentedLand load(Map map) + { + RentedLand newland = new RentedLand(); + newland.player = (String) map.get("Player"); + newland.startTime = (Long)map.get("StartTime"); + newland.endTime = (Long)map.get("EndTime"); + newland.autoRefresh = (Boolean)map.get("AutoRefresh"); + return newland; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/CancellableResidenceEvent.java b/src/com/bekvon/bukkit/residence/event/CancellableResidenceEvent.java new file mode 100644 index 0000000..07da3b1 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/CancellableResidenceEvent.java @@ -0,0 +1,32 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.event.Cancellable; + +/** + * + * @author Administrator + */ +public class CancellableResidenceEvent extends ResidenceEvent implements Cancellable { + + protected boolean cancelled; + + public CancellableResidenceEvent(String eventName, ClaimedResidence resref) + { + super(eventName,resref); + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean bln) { + cancelled = bln; + } + +} diff --git a/src/com/bekvon/bukkit/residence/event/CancellableResidencePlayerEvent.java b/src/com/bekvon/bukkit/residence/event/CancellableResidencePlayerEvent.java new file mode 100644 index 0000000..0c3cd9d --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/CancellableResidencePlayerEvent.java @@ -0,0 +1,34 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +/** + * + * @author Administrator + */ +public class CancellableResidencePlayerEvent extends ResidencePlayerEvent implements Cancellable { + + protected boolean cancelled; + + public CancellableResidencePlayerEvent(String eventName, ClaimedResidence resref, Player player) + { + super(eventName, resref, player); + cancelled = false; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean bln) { + cancelled = bln; + } + +} diff --git a/src/com/bekvon/bukkit/residence/event/CancellableResidencePlayerFlagEvent.java b/src/com/bekvon/bukkit/residence/event/CancellableResidencePlayerFlagEvent.java new file mode 100644 index 0000000..df0cf8f --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/CancellableResidencePlayerFlagEvent.java @@ -0,0 +1,33 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; + +/** + * + * @author Administrator + */ +public class CancellableResidencePlayerFlagEvent extends ResidencePlayerFlagEvent implements Cancellable { + + protected boolean cancelled; + + public CancellableResidencePlayerFlagEvent(String eventName, ClaimedResidence resref, Player player, String flag, FlagType type, String target) + { + super(eventName, resref, player, flag, type, target); + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean bln) { + cancelled = bln; + } + +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceChangedEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceChangedEvent.java new file mode 100644 index 0000000..3834ab7 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceChangedEvent.java @@ -0,0 +1,80 @@ +package com.bekvon.bukkit.residence.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; + +/** + * The {@link ResidenceChangedEvent} is fired when a player transitions between residences and/or + * residence subzones. Possible transitions include: + *
    + *
  • Moving from no residence into a residence/subzone;
  • + *
  • Moving from a residence/subzone to no residence; or
  • + *
  • Moving between residences/subzones
  • + *
+ *

+ * {@link ResidenceChangedEvent} is a replacement for {@link ResidenceEnterEvent} and + * {@link ResidenceLeaveEvent}, which have been marked as deprecated and will be removed in future + * releases. Using this event benefits developers as it encapsulates enter/leave conditions in a + * single event and doesn't require additional correlation to detect and residence-to-residence + * transition. + *

+ *

+ * This event is fired whenever conditions are met when a player moves or teleports to a new + * location. The event is also triggered when players appear in a residence upon logging in. + * + * @author frelling + * + */ +public class ResidenceChangedEvent extends ResidencePlayerEvent { + private static final HandlerList handlers = new HandlerList(); + + private ClaimedResidence from = null; + private ClaimedResidence to = null; + + /** + * Constructs a {@link ResidenceChangedEvent} to identify a residence transition for the + * given player + * + * @param from the residence that the player left or {@code null} if coming from an + * unprotected area. + * @param to the residence that the player entered or {@code null} if entering an + * unprotected area. + * @param player player involved in the transition + */ + public ResidenceChangedEvent(ClaimedResidence from, ClaimedResidence to, Player player) { + super("RESIDENCE_CHANGE", null, player); + this.from = from; + this.to = to; + } + + /** + * Returns the residence from which player came. + * + * @return the residence from which player came or {@code null} if player came from an + * unprotected area + */ + public ClaimedResidence getFrom() { + return from; + } + + /** + * Returns the residence that player has entered. + * + * @return the residence that player has entered or {@code null} if player enters an + * unprotected area + */ + public ClaimedResidence getTo() { + return to; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceChatEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceChatEvent.java new file mode 100644 index 0000000..c741125 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceChatEvent.java @@ -0,0 +1,56 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceChatEvent extends CancellableResidencePlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + protected String message; + ChatColor color; + + public ResidenceChatEvent(ClaimedResidence resref, Player player, String message, ChatColor color) { + super("RESIDENCE_CHAT_EVENT", resref, player); + this.message = message; + this.color = color; + } + + public String getChatMessage() + { + return message; + } + + public void setChatMessage(String newmessage) + { + message = newmessage; + } + + public ChatColor getColor() + { + return color; + } + + public void setColor(ChatColor c) + { + color = c; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceCommandEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceCommandEvent.java new file mode 100644 index 0000000..31dd5d4 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceCommandEvent.java @@ -0,0 +1,66 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import org.bukkit.command.CommandSender; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceCommandEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + protected boolean cancelled; + protected String cmd; + protected String arglist[]; + CommandSender commandsender; + + public ResidenceCommandEvent(String command, String args[], CommandSender sender) + { + super(); + cancelled = false; + arglist = args; + cmd = command; + commandsender = sender; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean bln) { + cancelled = bln; + } + + public String getCommand() + { + return cmd; + } + + public String[] getArgs() + { + return arglist; + } + + public CommandSender getSender() + { + return commandsender; + } + +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceCreationEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceCreationEvent.java new file mode 100644 index 0000000..2b2246c --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceCreationEvent.java @@ -0,0 +1,58 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import com.bekvon.bukkit.residence.protection.CuboidArea; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceCreationEvent extends CancellableResidencePlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + protected String resname; + CuboidArea area; + + public ResidenceCreationEvent(Player player, String newname, ClaimedResidence resref, CuboidArea resarea) + { + super("RESIDENCE_CREATE",resref,player); + resname = newname; + area = resarea; + } + + public String getResidenceName() + { + return resname; + } + + public void setResidenceName(String name) + { + resname = name; + } + + public CuboidArea getPhysicalArea() + { + return area; + } + + public void setPhysicalArea(CuboidArea newarea) + { + area = newarea; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceDeleteEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceDeleteEvent.java new file mode 100644 index 0000000..d208bac --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceDeleteEvent.java @@ -0,0 +1,46 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceDeleteEvent extends CancellableResidencePlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public enum DeleteCause { + LEASE_EXPIRE,PLAYER_DELETE,OTHER + } + + DeleteCause cause; + + public ResidenceDeleteEvent(Player player, ClaimedResidence resref, DeleteCause delcause) + { + super("RESIDENCE_DELETE", resref, player); + cause = delcause; + } + + public DeleteCause getCause() + { + return cause; + } + +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceEnterEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceEnterEvent.java new file mode 100644 index 0000000..eaf1765 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceEnterEvent.java @@ -0,0 +1,38 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Note: This event has been replaced with {@link ResidenceChangedEvent} and is marked as + * deprecated as of 21-MAY-2013. It will be removed in future releases. Please see + * {@link ResidenceChangedEvent} comments for further information. + * + * TODO - Remove this class at a suitable time in the future. + * + * @author Administrator + */ +@Deprecated +public class ResidenceEnterEvent extends ResidencePlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public ResidenceEnterEvent(ClaimedResidence resref, Player player) + { + super("RESIDENCE_ENTER", resref, player); + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceEvent.java new file mode 100644 index 0000000..a2bc64a --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceEvent.java @@ -0,0 +1,45 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + private String message; + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + ClaimedResidence res; + + public ResidenceEvent(String eventName, ClaimedResidence resref) + { + message = eventName; + res = resref; + } + + public String getMessage() { + return message; + } + + public ClaimedResidence getResidence() + { + return res; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceFlagChangeEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceFlagChangeEvent.java new file mode 100644 index 0000000..aec72a0 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceFlagChangeEvent.java @@ -0,0 +1,42 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import com.bekvon.bukkit.residence.protection.FlagPermissions.FlagState; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceFlagChangeEvent extends CancellableResidencePlayerFlagEvent { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + FlagState newstate; + + public ResidenceFlagChangeEvent(ClaimedResidence resref, Player player, String flag, FlagType type,FlagState newState, String target) + { + super("RESIDENCE_FLAG_CHANGE", resref, player, flag, type, target); + newstate = newState; + } + + public FlagState getNewState() + { + return newstate; + } + +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceFlagCheckEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceFlagCheckEvent.java new file mode 100644 index 0000000..a0b00fd --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceFlagCheckEvent.java @@ -0,0 +1,57 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceFlagCheckEvent extends ResidenceFlagEvent { +private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + private boolean override; + private boolean overridevalue; + boolean defaultvalue; + + public ResidenceFlagCheckEvent(ClaimedResidence resref, String flag, FlagType type, String target, boolean defaultValue) + { + super("RESIDENCE_FLAG_CHECK", resref, flag, type, target); + defaultvalue = defaultValue; + override = false; + } + + public boolean isOverriden() + { + return override; + } + + public void overrideCheck(boolean flagval) + { + overridevalue = flagval; + override=true; + } + + public boolean getOverrideValue() + { + return overridevalue; + } + + public boolean getDefaultValue() + { + return defaultvalue; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceFlagEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceFlagEvent.java new file mode 100644 index 0000000..c483f21 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceFlagEvent.java @@ -0,0 +1,60 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import com.bekvon.bukkit.residence.protection.FlagPermissions.FlagState; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceFlagEvent extends ResidenceEvent { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public enum FlagType + { + RESIDENCE,GROUP,PLAYER + } + + String flagname; + FlagType flagtype; + FlagState flagstate; + String flagtarget; + + public ResidenceFlagEvent(String eventName, ClaimedResidence resref, String flag, FlagType type, String target) + { + super(eventName, resref); + flagname = flag; + flagtype = type; + flagtarget = target; + } + + public String getFlag() + { + return flagname; + } + + public FlagType getFlagType() + { + return flagtype; + } + + public String getFlagTargetPlayerOrGroup() + { + return flagtarget; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceLeaveEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceLeaveEvent.java new file mode 100644 index 0000000..7edca7e --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceLeaveEvent.java @@ -0,0 +1,38 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Note: This event has been replaced with {@link ResidenceChangedEvent} and is marked as + * deprecated as of 21-MAY-2013. It will be removed in future releases. Please see + * {@link ResidenceChangedEvent} comments for further information. + * + * TODO - Remove this class at a suitable time in the future. + * + * @author Administrator + */ +@Deprecated +public class ResidenceLeaveEvent extends ResidencePlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public ResidenceLeaveEvent(ClaimedResidence resref, Player player) + { + super("RESIDENCE_LEAVE", resref, player); + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceOwnerChangeEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceOwnerChangeEvent.java new file mode 100644 index 0000000..2ace8cb --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceOwnerChangeEvent.java @@ -0,0 +1,38 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceOwnerChangeEvent extends ResidenceEvent { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + protected String newowner; + + public ResidenceOwnerChangeEvent(ClaimedResidence resref, String newOwner) + { + super("RESIDENCE_OWNER_CHANGE",resref); + newowner = newOwner; + } + + public String getNewOwner() + { + return newowner; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidencePlayerEvent.java b/src/com/bekvon/bukkit/residence/event/ResidencePlayerEvent.java new file mode 100644 index 0000000..ac38e44 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidencePlayerEvent.java @@ -0,0 +1,44 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class ResidencePlayerEvent extends ResidenceEvent implements ResidencePlayerEventInterface { + + Player p; + + public ResidencePlayerEvent(String eventName, ClaimedResidence resref, Player player) + { + super(eventName, resref); + res = resref; + p = player; + } + + public boolean isPlayer() + { + return p!=null; + } + + public boolean isAdmin() + { + if(isPlayer()) + { + return Residence.getPermissionManager().isResidenceAdmin(p); + } + return true; + } + public Player getPlayer() + { + return p; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidencePlayerEventInterface.java b/src/com/bekvon/bukkit/residence/event/ResidencePlayerEventInterface.java new file mode 100644 index 0000000..9400215 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidencePlayerEventInterface.java @@ -0,0 +1,18 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public interface ResidencePlayerEventInterface { + public boolean isAdmin(); + public boolean isPlayer(); + public Player getPlayer(); +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidencePlayerFlagEvent.java b/src/com/bekvon/bukkit/residence/event/ResidencePlayerFlagEvent.java new file mode 100644 index 0000000..6cf9d6d --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidencePlayerFlagEvent.java @@ -0,0 +1,42 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class ResidencePlayerFlagEvent extends ResidenceFlagEvent implements ResidencePlayerEventInterface { + Player p; + + public ResidencePlayerFlagEvent(String eventName,ClaimedResidence resref, Player player, String flag, FlagType type, String target) + { + super(eventName, resref, flag, type, target); + p = player; + } + + public boolean isPlayer() + { + return p!=null; + } + + public boolean isAdmin() + { + if(isPlayer()) + { + return Residence.getPermissionManager().isResidenceAdmin(p); + } + return true; + } + + public Player getPlayer() { + return p; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceRenameEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceRenameEvent.java new file mode 100644 index 0000000..74df940 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceRenameEvent.java @@ -0,0 +1,24 @@ +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; + +public class ResidenceRenameEvent extends ResidenceEvent { + protected String NewResName; + protected String OldResName; + protected ClaimedResidence res; + public ResidenceRenameEvent(ClaimedResidence resref, String NewName, String OldName) { + super("RESIDENCE_RENAME", resref); + NewResName = NewName; + OldResName = OldName; + res = resref; + } + public String getNewResidenceName() { + return NewResName; + } + public String getOldResidenceName() { + return OldResName; + } + public ClaimedResidence getResidence() { + return res; + } +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceRentEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceRentEvent.java new file mode 100644 index 0000000..75ab3b9 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceRentEvent.java @@ -0,0 +1,46 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceRentEvent extends CancellableResidencePlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + RentEventType eventtype; + + public enum RentEventType + { + RENT, UNRENT, RENTABLE, UNRENTABLE, RENT_EXPIRE + } + + public ResidenceRentEvent(ClaimedResidence resref, Player player, RentEventType type) + { + super("RESIDENCE_RENT_EVENT", resref, player); + eventtype = type; + } + + public RentEventType getCause() + { + return eventtype; + } + +} diff --git a/src/com/bekvon/bukkit/residence/event/ResidenceTPEvent.java b/src/com/bekvon/bukkit/residence/event/ResidenceTPEvent.java new file mode 100644 index 0000000..70550a5 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/event/ResidenceTPEvent.java @@ -0,0 +1,47 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.event; + +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * + * @author Administrator + */ +public class ResidenceTPEvent extends CancellableResidencePlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + Player reqPlayer; + Location loc; + public ResidenceTPEvent(ClaimedResidence resref, Location teleloc, Player player, Player reqplayer) + { + super("RESIDENCE_TP",resref,player); + reqPlayer = reqplayer; + loc = teleloc; + } + + public Player getRequestingPlayer() + { + return reqPlayer; + } + + public Location getTeleportLocation() + { + return loc; + } +} diff --git a/src/com/bekvon/bukkit/residence/itemlist/ItemList.java b/src/com/bekvon/bukkit/residence/itemlist/ItemList.java new file mode 100644 index 0000000..3aa1577 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/itemlist/ItemList.java @@ -0,0 +1,218 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.itemlist; +import org.bukkit.ChatColor; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class ItemList { + + protected List list; + protected ListType type; + + public ItemList(ListType listType) + { + this(); + type = listType; + } + + protected ItemList() + { + list = new ArrayList(); + } + + public static enum ListType + { + BLACKLIST,WHITELIST,IGNORELIST,OTHER + } + + public ListType getType() + { + return type; + } + + public boolean contains(Material mat) + { + return list.contains(mat); + } + + public void add(Material mat) + { + if(!list.contains(mat)) + list.add(mat); + } + + public boolean toggle(Material mat) + { + if(list.contains(mat)) + { + list.remove(mat); + return false; + } + else + { + list.add(mat); + return true; + } + } + + public void remove(Material mat) + { + list.remove(mat); + } + + public boolean isAllowed(Material mat) + { + if(type == ListType.BLACKLIST) + { + if(list.contains(mat)) + { + return false; + } + return true; + } + else if(type == ListType.WHITELIST) + { + if(list.contains(mat)) + { + return true; + } + return false; + } + return true; + } + + public boolean isIgnored(Material mat) + { + if(type == ListType.IGNORELIST) + { + if(list.contains(mat)) + { + return true; + } + } + return false; + } + + public boolean isListed(Material mat) + { + return this.contains(mat); + } + + public int getListSize() + { + return list.size(); + } + + public static ItemList readList(ConfigurationSection node) + { + return ItemList.readList(node, new ItemList()); + } + + @SuppressWarnings("deprecation") + protected static ItemList readList(ConfigurationSection node, ItemList list) + { + ListType type = ListType.valueOf(node.getString("Type","").toUpperCase()); + list.type = type; + List items = node.getStringList("Items"); + if (items != null) { + for (String item : items) { + int parse = -1; + try { + parse = Integer.parseInt(item); + } catch (Exception ex) { + } + if (parse == -1) { + try { + list.add(Material.valueOf(item.toUpperCase())); + } catch (Exception ex) { + } + } else { + try { + list.add(Material.getMaterial(parse)); + } catch (Exception ex) { + } + } + } + } + return list; + } + + public void printList(Player player) + { + StringBuilder builder = new StringBuilder(); + boolean first = true; + for(Material mat : list) + { + if(!first) + builder.append(", "); + else + builder.append(ChatColor.YELLOW); + builder.append(mat); + first = false; + } + player.sendMessage(builder.toString()); + } + + public Material[] toArray() + { + Material mats[] = new Material[list.size()]; + int i = 0; + for(Material mat : list) + { + mats[i] = mat; + i++; + } + return mats; + } + + public Map save() + { + Map saveMap = new LinkedHashMap(); + saveMap.put("Type", type.toString()); + List saveList = new ArrayList(); + for(Material mat : list) + { + saveList.add(mat.toString()); + } + saveMap.put("ItemList", saveList); + return saveMap; + } + + public static ItemList load(Map map) + { + ItemList newlist = new ItemList(); + return load(map,newlist); + } + + @SuppressWarnings("unchecked") + protected static ItemList load(Map map, ItemList newlist) + { + try + { + newlist.type = ListType.valueOf((String) map.get("Type")); + List list = (List) map.get("ItemList"); + for(String item : list) + { + newlist.add(Material.valueOf(item)); + } + } + catch (Exception ex) + {} + return newlist; + } +} diff --git a/src/com/bekvon/bukkit/residence/itemlist/ResidenceItemList.java b/src/com/bekvon/bukkit/residence/itemlist/ResidenceItemList.java new file mode 100644 index 0000000..eae10e8 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/itemlist/ResidenceItemList.java @@ -0,0 +1,55 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.itemlist; +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import java.util.Map; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class ResidenceItemList extends ItemList { + ClaimedResidence res; + + public ResidenceItemList(ClaimedResidence parent, ListType type) + { + super(type); + res = parent; + } + + private ResidenceItemList() + { + + } + + public void playerListChange(Player player, Material mat, boolean resadmin) { + PermissionGroup group = Residence.getPermissionManager().getGroup(player); + if(resadmin || (res.getPermissions().hasResidencePermission(player, true) && group.itemListAccess())) + { + if(super.toggle(mat)) + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("ListMaterialAdd",ChatColor.GREEN + mat.toString() + ChatColor.YELLOW+"."+ChatColor.GREEN + type.toString().toLowerCase() + ChatColor.YELLOW)); + else + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("ListMaterialRemove",ChatColor.GREEN + mat.toString() + ChatColor.YELLOW+"."+ChatColor.GREEN + type.toString().toLowerCase() + ChatColor.YELLOW)); + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoPermission")); + } + } + + public static ResidenceItemList load(ClaimedResidence parent, Map map) + { + ResidenceItemList newlist = new ResidenceItemList(); + newlist.res = parent; + return (ResidenceItemList) ItemList.load(map, newlist); + } +} diff --git a/src/com/bekvon/bukkit/residence/itemlist/WorldItemList.java b/src/com/bekvon/bukkit/residence/itemlist/WorldItemList.java new file mode 100644 index 0000000..ce6d1a2 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/itemlist/WorldItemList.java @@ -0,0 +1,83 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.itemlist; + +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; + +/** + * + * @author Administrator + */ +public class WorldItemList extends ItemList { + + protected String world; + protected String group; + + public WorldItemList(ListType listType) + { + super(listType); + } + + protected WorldItemList() + { + + } + + public String getWorld() + { + return world; + } + + public String getGroup() + { + return group; + } + + public boolean isAllowed(Material mat, String inworld, String ingroup) { + if(!listApplicable(inworld,ingroup)) + return true; + return super.isAllowed(mat); + } + + public boolean isIgnored(Material mat, String inworld, String ingroup) + { + if(!listApplicable(inworld,ingroup)) + return false; + return super.isIgnored(mat); + } + + public boolean isListed(Material mat, String inworld, String ingroup) + { + if(!listApplicable(inworld,ingroup)) + return false; + return super.isListed(mat); + } + + public boolean listApplicable(String inworld, String ingroup) + { + if (world != null) { + if (!world.equalsIgnoreCase(inworld)) { + return false; + } + } + if (group != null) { + if (!group.equals(ingroup)) { + return false; + } + } + return true; + } + + public static WorldItemList readList(ConfigurationSection node) + { + WorldItemList list = new WorldItemList(); + ItemList.readList(node, list); + list.world = node.getString("World",null); + list.group = node.getString("Group",null); + return list; + } +} diff --git a/src/com/bekvon/bukkit/residence/itemlist/WorldItemManager.java b/src/com/bekvon/bukkit/residence/itemlist/WorldItemManager.java new file mode 100644 index 0000000..e3865ca --- /dev/null +++ b/src/com/bekvon/bukkit/residence/itemlist/WorldItemManager.java @@ -0,0 +1,60 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.itemlist; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import org.bukkit.Material; +import org.bukkit.configuration.file.FileConfiguration; + +/** + * + * @author Administrator + */ +public class WorldItemManager { + protected List lists; + + public WorldItemManager(FileConfiguration config) + { + lists = new ArrayList(); + this.readLists(config); + } + + public boolean isAllowed(Material mat, String group, String world) { + for (WorldItemList list : lists) { + if (!list.isAllowed(mat, world, group)) { + return false; + } + } + return true; + } + + public boolean isIgnored(Material mat, String group, String world) + { + for (WorldItemList list : lists) { + if (list.isIgnored(mat, world, group)) { + return true; + } + } + return false; + } + + private void readLists(FileConfiguration config) { + Set keys = config.getConfigurationSection("ItemList").getKeys(false); + if (keys != null) { + for (String key : keys) { + try { + WorldItemList list = WorldItemList.readList(config.getConfigurationSection("ItemList." + key)); + lists.add(list); + //System.out.println("Debug: read list " + key + " world: " + list.getWorld() + " group: " + list.getGroup() + " itemcount:" + list.getListSize()); + } catch (Exception ex) { + System.out.println("Failed to load item list:" + key); + } + } + } + } +} diff --git a/src/com/bekvon/bukkit/residence/listeners/ResidenceBlockListener.java b/src/com/bekvon/bukkit/residence/listeners/ResidenceBlockListener.java new file mode 100644 index 0000000..c6709e3 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/listeners/ResidenceBlockListener.java @@ -0,0 +1,215 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.listeners; + +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.protection.FlagPermissions; + +import org.bukkit.entity.Player; +import org.bukkit.block.Block; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.BlockPlaceEvent; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockSpreadEvent; + +/** + * + * @author Administrator + */ +public class ResidenceBlockListener implements Listener { + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + if (Residence.isResAdminOn(player)) { + return; + } + Material mat = event.getBlock().getType(); + String world = event.getBlock().getWorld().getName(); + String group = Residence.getPermissionManager().getGroupNameByPlayer(player); + if (Residence.getItemManager().isIgnored(mat, group, world)) { + return; + } + ClaimedResidence res = Residence.getResidenceManager().getByLoc(event.getBlock().getLocation()); + if (Residence.getConfigManager().enabledRentSystem()) { + if (res != null) { + String resname = res.getName(); + if (Residence.getConfigManager().preventRentModify() && Residence.getRentManager().isRented(resname)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("RentedModifyDeny")); + event.setCancelled(true); + return; + } + } + } + FlagPermissions perms = Residence.getPermsByLocForPlayer(event.getBlock().getLocation(), player); + String pname = player.getName(); + if (res != null) { + if (res.getItemIgnoreList().isListed(mat)) { + return; + } + } + boolean hasdestroy = perms.playerHas(pname, player.getWorld().getName(), "destroy", perms.playerHas(pname, player.getWorld().getName(), "build", true)); + boolean hasContainer = perms.playerHas(pname, player.getWorld().getName(), "container", true); + if (!hasdestroy || (!hasContainer && mat == Material.CHEST)) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + Player player = event.getPlayer(); + if (Residence.isResAdminOn(player)) { + return; + } + Material mat = event.getBlock().getType(); + String world = event.getBlock().getWorld().getName(); + String group = Residence.getPermissionManager().getGroupNameByPlayer(player); + if (Residence.getItemManager().isIgnored(mat, group, world)) { + return; + } + ClaimedResidence res = Residence.getResidenceManager().getByLoc(event.getBlock().getLocation()); + if (Residence.getConfigManager().enabledRentSystem()) { + if (res != null) { + String resname = res.getName(); + if (Residence.getConfigManager().preventRentModify() && Residence.getRentManager().isRented(resname)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("RentedModifyDeny")); + event.setCancelled(true); + return; + } + } + } + String pname = player.getName(); + if (res != null) { + if (!res.getItemBlacklist().isAllowed(mat)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ItemBlacklisted")); + event.setCancelled(true); + return; + } + } + FlagPermissions perms = Residence.getPermsByLocForPlayer(event.getBlock().getLocation(), player); + boolean hasplace = perms.playerHas(pname, player.getWorld().getName(), "place", perms.playerHas(pname, player.getWorld().getName(), "build", true)); + if (!hasplace) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockSpread(BlockSpreadEvent event) { + Location loc = event.getBlock().getLocation(); + FlagPermissions perms = Residence.getPermsByLoc(loc); + if (!perms.has("spread", true)) { + event.setCancelled(true); + } + } + + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockPistonRetract(BlockPistonRetractEvent event) { + FlagPermissions perms = Residence.getPermsByLoc(event.getBlock().getLocation()); + if (!perms.has("piston", true)){ + event.setCancelled(true); + return; + } + if (event.isSticky()){ + Location location = event.getRetractLocation(); + FlagPermissions blockperms = Residence.getPermsByLoc(location); + if (!blockperms.has("piston", true)) { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockPistonExtend(BlockPistonExtendEvent event) { + FlagPermissions perms = Residence.getPermsByLoc(event.getBlock().getLocation()); + if (!perms.has("piston", true)) { + event.setCancelled(true); + } + for (Block block : event.getBlocks()) { + FlagPermissions blockpermsfrom = Residence.getPermsByLoc(block.getLocation()); + Location blockto = block.getLocation(); + blockto.setX(blockto.getX()+event.getDirection().getModX()); + blockto.setY(blockto.getY()+event.getDirection().getModY()); + blockto.setZ(blockto.getZ()+event.getDirection().getModZ()); + FlagPermissions blockpermsto = Residence.getPermsByLoc(blockto); + if (!blockpermsfrom.has("piston", true) || !blockpermsto.has("piston", true)) { + event.setCancelled(true); + return; + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockFromTo(BlockFromToEvent event) { + FlagPermissions perms = Residence.getPermsByLoc(event.getToBlock().getLocation()); + boolean hasflow = perms.has("flow", true); + Material mat = event.getBlock().getType(); + if (!hasflow) { + event.setCancelled(true); + return; + } + if (mat == Material.LAVA || mat == Material.STATIONARY_LAVA) { + if (!perms.has("lavaflow", hasflow)) { + event.setCancelled(true); + } + return; + } + if (mat == Material.WATER || mat == Material.STATIONARY_WATER) { + if (!perms.has("waterflow", hasflow)) { + event.setCancelled(true); + } + return; + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockBurn(BlockBurnEvent event) { + FlagPermissions perms = Residence.getPermsByLoc(event.getBlock().getLocation()); + if (!perms.has("firespread", true)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockIgnite(BlockIgniteEvent event) { + FlagPermissions perms = Residence.getPermsByLocForPlayer(event.getBlock().getLocation(), event.getPlayer()); + IgniteCause cause = event.getCause(); + if (cause == IgniteCause.SPREAD) { + if (!perms.has("firespread", true)) { + event.setCancelled(true); + } + } else if (cause == IgniteCause.FLINT_AND_STEEL) { + Player player = event.getPlayer(); + if (player != null && !perms.playerHas(player.getName(), player.getWorld().getName(), "ignite", true) && !Residence.isResAdminOn(player)) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoPermission")); + } + } else { + if(!perms.has("ignite", true)){ + event.setCancelled(true); + } + } + } +} diff --git a/src/com/bekvon/bukkit/residence/listeners/ResidenceEntityListener.java b/src/com/bekvon/bukkit/residence/listeners/ResidenceEntityListener.java new file mode 100644 index 0000000..0c6737c --- /dev/null +++ b/src/com/bekvon/bukkit/residence/listeners/ResidenceEntityListener.java @@ -0,0 +1,405 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.listeners; +import org.bukkit.ChatColor; +import org.bukkit.Location; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.bekvon.bukkit.residence.protection.FlagPermissions; + +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityInteractEvent; +import org.bukkit.event.entity.PotionSplashEvent; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; + +import org.bukkit.Material; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Bat; +import org.bukkit.entity.Chicken; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Horse; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Ocelot; +import org.bukkit.entity.Pig; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Rabbit; +import org.bukkit.entity.Sheep; +import org.bukkit.entity.Snowman; +import org.bukkit.entity.Squid; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Wolf; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Ghast; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.ExplosionPrimeEvent; +import org.bukkit.event.hanging.HangingBreakByEntityEvent; +import org.bukkit.event.hanging.HangingBreakEvent; +import org.bukkit.event.hanging.HangingPlaceEvent; + +/** + * + * @author Administrator + */ +public class ResidenceEntityListener implements Listener { + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onEndermanChangeBlock(EntityChangeBlockEvent event) { + if (event.getEntityType() != EntityType.ENDERMAN && event.getEntityType() != EntityType.WITHER) { + return; + } + FlagPermissions perms = Residence.getPermsByLoc(event.getBlock().getLocation()); + FlagPermissions world = Residence.getWorldFlags().getPerms(event.getBlock().getWorld().getName()); + if (event.getEntityType() == EntityType.WITHER) { + if (!perms.has("wither", perms.has("explode", world.has("wither", world.has("explode", true))))) { + event.setCancelled(true); + } + } else if (!perms.has("build", true)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onEntityInteract(EntityInteractEvent event){ + Block block = event.getBlock(); + Material mat = block.getType(); + Entity entity = event.getEntity(); + FlagPermissions perms = Residence.getPermsByLoc(block.getLocation()); + boolean hastrample = perms.has("trample", perms.has("hasbuild", true)); + if(!hastrample && !(entity.getType() == EntityType.FALLING_BLOCK) && (mat == Material.SOIL || mat == Material.SOUL_SAND)){ + event.setCancelled(true); + } + } + + private boolean isMonster(Entity ent) { + return (ent instanceof Monster || ent instanceof Slime || ent instanceof Ghast); + } + + private boolean isAnimal(Entity ent) { + return (ent instanceof Horse || ent instanceof Bat || ent instanceof Snowman || ent instanceof IronGolem || ent instanceof Ocelot || ent instanceof Pig || ent instanceof Sheep || ent instanceof Chicken || ent instanceof Wolf || ent instanceof Cow || ent instanceof Squid || ent instanceof Villager || ent instanceof Rabbit); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void AnimalKilling (EntityDamageByEntityEvent event){ + Entity damager = event.getDamager(); + + if ((!(damager instanceof Arrow)) && (!(damager instanceof Player))) { + return; + } + + Player cause; + if ((damager instanceof Arrow) && (!(((Arrow) damager).getShooter() instanceof Player))) { + return; + + } else if (damager instanceof Player) { + cause = (Player) damager; + } else { + cause = (Player) ((Arrow) damager).getShooter(); + } + + if (Residence.isResAdminOn(cause)) { + return; + } + + Entity entity = event.getEntity(); + ClaimedResidence res = Residence.getResidenceManager().getByLoc(entity.getLocation()); + + if (res != null && !res.getPermissions().playerHas(cause.getName(), "animalkilling", true)) { + if (isAnimal(entity)) { + cause.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onCreatureSpawn(CreatureSpawnEvent event) { + FlagPermissions perms = Residence.getPermsByLoc(event.getLocation()); + Entity ent = event.getEntity(); + if(isAnimal(ent)){ + if(!perms.has("animals", true)){ + event.setCancelled(true); + } + } else { + if (!perms.has("monsters", true) && isMonster(ent)) { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onHangingPlace(HangingPlaceEvent event) { + Player player = event.getPlayer(); + if (Residence.isResAdminOn(player)) { + return; + } + FlagPermissions perms = Residence.getPermsByLocForPlayer(event.getEntity().getLocation(), player); + String pname = player.getName(); + String world = player.getWorld().getName(); + if (!perms.playerHas(pname, world, "place", perms.playerHas(pname, world, "build", true))) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onHangingBreak(HangingBreakEvent event) { + if (event instanceof HangingBreakByEntityEvent) { + HangingBreakByEntityEvent evt = (HangingBreakByEntityEvent) event; + if (evt.getRemover() instanceof Player) { + Player player = (Player) evt.getRemover(); + if (Residence.isResAdminOn(player)) { + return; + } + String pname = player.getName(); + FlagPermissions perms = Residence.getPermsByLocForPlayer(event.getEntity().getLocation(), player); + String world = event.getEntity().getWorld().getName(); + if (!perms.playerHas(pname, world, "destroy", perms.playerHas(pname, world, "build", true))) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + } + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onEntityCombust(EntityCombustEvent event) { + FlagPermissions perms = Residence.getPermsByLoc(event.getEntity().getLocation()); + if (!perms.has("burn", true)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onExplosionPrime(ExplosionPrimeEvent event) { + EntityType entity = event.getEntityType(); + FlagPermissions perms = Residence.getPermsByLoc(event.getEntity().getLocation()); + if (entity == EntityType.CREEPER) { + if (!perms.has("creeper", perms.has("explode", true))) { + event.setCancelled(true); + event.getEntity().remove(); + } + } + if (entity == EntityType.PRIMED_TNT || entity == EntityType.MINECART_TNT) { + if (!perms.has("tnt", perms.has("explode", true))) { + event.setCancelled(true); + event.getEntity().remove(); + } + } + if (entity == EntityType.FIREBALL) { + if (!perms.has("fireball", perms.has("explode", true))) { + event.setCancelled(true); + event.getEntity().remove(); + } + } + if (entity == EntityType.SMALL_FIREBALL) { + if (!perms.has("fireball", perms.has("explode", true))) { + event.setCancelled(true); + event.getEntity().remove(); + } + } + if (entity == EntityType.WITHER_SKULL) { + if (!perms.has("witherdamage", perms.has("damage", true))) { + event.setCancelled(true); + event.getEntity().remove(); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onEntityExplode(EntityExplodeEvent event) { + if (event.isCancelled() || event.getEntity() == null) + return; + Boolean cancel = false; + EntityType entity = event.getEntityType(); + FlagPermissions perms = Residence.getPermsByLoc(event.getEntity().getLocation()); + FlagPermissions world = Residence.getWorldFlags().getPerms(event.getEntity().getWorld().getName()); + if (entity == EntityType.CREEPER) { + if (!perms.has("creeper", perms.has("explode", true))) { + cancel = true; + } + } + if (entity == EntityType.PRIMED_TNT || entity == EntityType.MINECART_TNT) { + if (!perms.has("tnt", perms.has("explode", true))) { + cancel = true; + } + } + if (entity == EntityType.FIREBALL) { + if (!perms.has("fireball", perms.has("explode", true))) { + cancel = true; + } + } + if (entity == EntityType.SMALL_FIREBALL) { + if (!perms.has("fireball", perms.has("explode", true))) { + cancel = true; + } + } + if (entity == EntityType.WITHER_SKULL || entity == EntityType.WITHER) { + if (!perms.has("wither", perms.has("explode", world.has("wither", world.has("explode", true))))) { + cancel = true; + } + } + if (cancel) { + event.setCancelled(true); + event.getEntity().remove(); + } else { + List preserve = new ArrayList(); + for (Block block : event.blockList()) { + FlagPermissions blockperms = Residence.getPermsByLoc(block.getLocation()); + if ((!blockperms.has("wither", blockperms.has("explode", world.has("wither", world.has("explode", true)))) && (entity == EntityType.WITHER || entity == EntityType.WITHER_SKULL) || (!blockperms.has("fireball", blockperms.has("explode", true)) && (entity == EntityType.FIREBALL || entity == EntityType.SMALL_FIREBALL)) || (!blockperms.has("tnt", blockperms.has("explode", true)) && (entity == EntityType.PRIMED_TNT || entity == EntityType.MINECART_TNT)) || (!blockperms.has("creeper", blockperms.has("explode", true)) && entity == EntityType.CREEPER))) { + if (block != null) { + preserve.add(block); + } + } + } + for (Block block : preserve) { + event.blockList().remove(block); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onSplashPotion(PotionSplashEvent event) { + if(event.isCancelled()) + return; + Entity ent = event.getEntity(); + boolean srcpvp = Residence.getPermsByLoc(ent.getLocation()).has("pvp", true); + Iterator it = event.getAffectedEntities().iterator(); + while(it.hasNext()){ + LivingEntity target = it.next(); + if(target.getType()==EntityType.PLAYER){ + Boolean tgtpvp = Residence.getPermsByLoc(target.getLocation()).has("pvp", true); + if(!srcpvp || !tgtpvp){ + event.setIntensity(target, 0); + } + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) { + if (event.getEntityType() == EntityType.ITEM_FRAME || event.getEntityType() == EntityType.ARMOR_STAND) { + Entity dmgr = event.getDamager(); + Player player; + if (event.getDamager() instanceof Player) { + player = (Player) event.getDamager(); + } else { + if (dmgr instanceof Projectile && ((Projectile) dmgr).getShooter() instanceof Player) { + player = (Player) ((Projectile) dmgr).getShooter(); + } else + return; + } + + if (Residence.isResAdminOn(player)) + return; + + // Note: Location of entity, not player; otherwise player could stand outside of res and still damage + Location loc = event.getEntity().getLocation(); + ClaimedResidence res = Residence.getResidenceManager().getByLoc(loc); + if (res != null && !res.getPermissions().playerHas(player.getName(), "container", false)) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("FlagDeny", "container")); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onEntityDamage(EntityDamageEvent event) { + Entity ent = event.getEntity(); + if(ent.hasMetadata("NPC")) { + return; + } + boolean tamedWolf = ent instanceof Wolf ? ((Wolf)ent).isTamed() : false; + ClaimedResidence area = Residence.getResidenceManager().getByLoc(ent.getLocation()); + /* Living Entities */ + if (event instanceof EntityDamageByEntityEvent) { + EntityDamageByEntityEvent attackevent = (EntityDamageByEntityEvent) event; + Entity damager = attackevent.getDamager(); + ClaimedResidence srcarea = null; + if (damager != null) { + srcarea = Residence.getResidenceManager().getByLoc(damager.getLocation()); + } + boolean srcpvp = true; + if (srcarea != null) { + srcpvp = srcarea.getPermissions().has("pvp", true); + } + ent = attackevent.getEntity(); + if ((ent instanceof Player || tamedWolf) && (damager instanceof Player || (damager instanceof Arrow && (((Arrow)damager).getShooter() instanceof Player)))) { + Player attacker = null; + if (damager instanceof Player) { + attacker = (Player) damager; + } else if (damager instanceof Arrow) { + attacker = (Player)((Arrow)damager).getShooter(); + } + if(!srcpvp) { + attacker.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoPVPZone")); + event.setCancelled(true); + return; + } + /* Check for Player vs Player */ + if (area == null) { + /* World PvP */ + if (!Residence.getWorldFlags().getPerms(damager.getWorld().getName()).has("pvp", true)) { + attacker.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("WorldPVPDisabled")); + event.setCancelled(true); + } + } else { + /* Normal PvP */ + if (!area.getPermissions().has("pvp", true)) { + attacker.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoPVPZone")); + event.setCancelled(true); + } + } + return; + } else if ((ent instanceof Player || tamedWolf) && (damager instanceof Creeper)) { + if (area == null) { + if (!Residence.getWorldFlags().getPerms(damager.getWorld().getName()).has("creeper", true)) { + event.setCancelled(true); + } + } else { + if (!area.getPermissions().has("creeper", true)) { + event.setCancelled(true); + } + } + } + } + if (area == null) { + if (!Residence.getWorldFlags().getPerms(ent.getWorld().getName()).has("damage", true) && (ent instanceof Player || tamedWolf)) { + event.setCancelled(true); + } + } else { + if (!area.getPermissions().has("damage", true) && (ent instanceof Player || tamedWolf)) { + event.setCancelled(true); + } + } + if (event.isCancelled()) { + /* Put out a fire on a player */ + if ((ent instanceof Player || tamedWolf) + && (event.getCause() == EntityDamageEvent.DamageCause.FIRE + || event.getCause() == EntityDamageEvent.DamageCause.FIRE_TICK)) { + ent.setFireTicks(0); + } + } + } +} diff --git a/src/com/bekvon/bukkit/residence/listeners/ResidencePlayerListener.java b/src/com/bekvon/bukkit/residence/listeners/ResidencePlayerListener.java new file mode 100644 index 0000000..1d0d780 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/listeners/ResidencePlayerListener.java @@ -0,0 +1,847 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.listeners; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Damageable; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Hanging; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerBucketFillEvent; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.plugin.Plugin; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.chat.ChatChannel; +import com.bekvon.bukkit.residence.event.ResidenceChangedEvent; +import com.bekvon.bukkit.residence.event.ResidenceEnterEvent; +import com.bekvon.bukkit.residence.event.ResidenceLeaveEvent; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import com.bekvon.bukkit.residence.protection.FlagPermissions; +import com.bekvon.bukkit.residence.utils.ActionBar; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; + +/** + * + * @author Administrator + */ +@SuppressWarnings("deprecation") +public class ResidencePlayerListener implements Listener { + + protected Map currentRes; + protected Map lastUpdate; + protected Map lastOutsideLoc; + protected int minUpdateTime; + protected boolean chatenabled; + protected List playerToggleChat; + + public ResidencePlayerListener() { + currentRes = new HashMap(); + lastUpdate = new HashMap(); + lastOutsideLoc = new HashMap(); + playerToggleChat = new ArrayList(); + minUpdateTime = Residence.getConfigManager().getMinMoveUpdateInterval(); + chatenabled = Residence.getConfigManager().chatEnabled(); + for (Player player : Bukkit.getServer().getOnlinePlayers()) { + lastUpdate.put(player.getName(), System.currentTimeMillis()); + } + } + + public void reload() { + currentRes = new HashMap(); + lastUpdate = new HashMap(); + lastOutsideLoc = new HashMap(); + playerToggleChat = new ArrayList(); + minUpdateTime = Residence.getConfigManager().getMinMoveUpdateInterval(); + chatenabled = Residence.getConfigManager().chatEnabled(); + for (Player player : Bukkit.getServer().getOnlinePlayers()) { + lastUpdate.put(player.getName(), System.currentTimeMillis()); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + String pname = event.getPlayer().getName(); + currentRes.remove(pname); + lastUpdate.remove(pname); + lastOutsideLoc.remove(pname); + Residence.getChatManager().removeFromChannel(pname); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + lastUpdate.put(player.getName(), 0L); + if (Residence.getPermissionManager().isResidenceAdmin(player)) { + Residence.turnResAdminOn(player); + } + handleNewLocation(player, player.getLocation(), false); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerSpawn(PlayerRespawnEvent event) { + Location loc = event.getRespawnLocation(); + Boolean bed = event.isBedSpawn(); + Player player = event.getPlayer(); + ClaimedResidence res = Residence.getResidenceManager().getByLoc(loc); + if (res == null) { + return; + } + if (res.getPermissions().playerHas(player.getName(), "move", true)) { + return; + } + if (bed) { + loc = player.getWorld().getSpawnLocation(); + } + res = Residence.getResidenceManager().getByLoc(loc); + if (res != null) { + if (!res.getPermissions().playerHas(player.getName(), "move", true)) { + loc = res.getOutsideFreeLoc(loc); + } + } + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("NoSpawn")); + event.setRespawnLocation(loc); + } + + private boolean isContainer(Material mat, Block block) { + return FlagPermissions.getMaterialUseFlagList().containsKey(mat) + && FlagPermissions.getMaterialUseFlagList().get(mat) + .equals("container") + || Residence.getConfigManager().getCustomContainers() + .contains(Integer.valueOf(block.getTypeId())); + } + + private boolean isCanUseEntity_BothClick(Material mat, Block block) { + return mat == Material.LEVER + || mat == Material.STONE_BUTTON + || mat == Material.WOOD_BUTTON + || mat == Material.WOODEN_DOOR + || mat == Material.SPRUCE_DOOR + || mat == Material.BIRCH_DOOR + || mat == Material.JUNGLE_DOOR + || mat == Material.ACACIA_DOOR + || mat == Material.DARK_OAK_DOOR + || mat == Material.SPRUCE_FENCE_GATE + || mat == Material.BIRCH_FENCE_GATE + || mat == Material.JUNGLE_FENCE_GATE + || mat == Material.ACACIA_FENCE_GATE + || mat == Material.DARK_OAK_FENCE_GATE + || mat == Material.TRAP_DOOR + || mat == Material.FENCE_GATE + || mat == Material.PISTON_BASE + || mat == Material.PISTON_STICKY_BASE + || mat == Material.DRAGON_EGG + || Residence.getConfigManager().getCustomBothClick() + .contains(Integer.valueOf(block.getTypeId())); + } + + private boolean isCanUseEntity_RClickOnly(Material mat, Block block) { + return mat == Material.ITEM_FRAME + || mat == Material.BEACON + || mat == Material.FLOWER_POT + || mat == Material.COMMAND + || mat == Material.ANVIL + || mat == Material.CAKE_BLOCK + || mat == Material.NOTE_BLOCK + || mat == Material.DIODE + || mat == Material.DIODE_BLOCK_OFF + || mat == Material.DIODE_BLOCK_ON + || mat == Material.BED_BLOCK + || mat == Material.WORKBENCH + || mat == Material.BREWING_STAND + || mat == Material.ENCHANTMENT_TABLE + || Residence.getConfigManager().getCustomRightClick() + .contains(Integer.valueOf(block.getTypeId())); + } + + private boolean isCanUseEntity(Material mat, Block block) { + return isCanUseEntity_BothClick(mat, block) + || isCanUseEntity_RClickOnly(mat, block); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + Material heldItem = player.getItemInHand().getType(); + Block block = event.getClickedBlock(); + if (block == null) { + return; + } + Material mat = block.getType(); + if (!((isContainer(mat, block) || isCanUseEntity_RClickOnly(mat, block)) + && event.getAction() == Action.RIGHT_CLICK_BLOCK + || isCanUseEntity_BothClick(mat, block) || event.getAction() == Action.PHYSICAL)) { + int typeId = player.getItemInHand().getTypeId(); + if (typeId != Residence.getConfigManager().getSelectionTooldID() + && typeId != Residence.getConfigManager().getInfoToolID() + && typeId != 351 && typeId != 416) { + return; + } + } + FlagPermissions perms = Residence.getPermsByLocForPlayer( + block.getLocation(), player); + String world = player.getWorld().getName(); + String permgroup = Residence.getPermissionManager() + .getGroupNameByPlayer(player); + boolean resadmin = Residence.isResAdminOn(player); + if (event.getAction() == Action.PHYSICAL) { + if (!resadmin) { + boolean hasuse = perms.playerHas(player.getName(), world, + "use", true); + boolean haspressure = perms.playerHas(player.getName(), world, + "pressure", hasuse); + if ((!hasuse && !haspressure || !haspressure) + && (mat == Material.STONE_PLATE || mat == Material.WOOD_PLATE)) { + event.setCancelled(true); + return; + } + } + if (!perms.playerHas(player.getName(), world, "trample", + perms.playerHas(player.getName(), world, "build", true)) + && (mat == Material.SOIL || mat == Material.SOUL_SAND)) { + event.setCancelled(true); + return; + } + return; + } + if (!resadmin + && !Residence.getItemManager().isAllowed(heldItem, permgroup, + world)) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("ItemBlacklisted")); + event.setCancelled(true); + return; + } + if (event.getAction() == Action.LEFT_CLICK_BLOCK + || event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (player.getItemInHand().getTypeId() == Residence + .getConfigManager().getSelectionTooldID()) { + Plugin wep = Bukkit.getPluginManager().getPlugin("WorldEdit"); + if (wep != null) { + if (((WorldEditPlugin) wep).getConfig().getInt("wand-item") == Residence + .getConfigManager().getSelectionTooldID()) { + return; + } + } + PermissionGroup group = Residence.getPermissionManager() + .getGroup(player); + if (player.hasPermission("residence.select") + || player.hasPermission("residence.create") + && !player.isPermissionSet("residence.select") + || group.canCreateResidences() + && !player.isPermissionSet("residence.create") + && !player.isPermissionSet("residence.select") + || resadmin) { + if (event.getAction() == Action.LEFT_CLICK_BLOCK) { + Location loc = block.getLocation(); + Residence.getSelectionManager().placeLoc1(player, loc); + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase( + "SelectPoint", + Residence.getLanguage().getPhrase( + "Primary")) + ChatColor.RED + + "(" + loc.getBlockX() + "," + loc.getBlockY() + + "," + loc.getBlockZ() + ")" + ChatColor.GREEN + + "!"); + } else if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + Location loc = block.getLocation(); + Residence.getSelectionManager().placeLoc2(player, loc); + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase( + "SelectPoint", + Residence.getLanguage().getPhrase( + "Secondary")) + ChatColor.RED + + "(" + loc.getBlockX() + "," + loc.getBlockY() + + "," + loc.getBlockZ() + ")" + ChatColor.GREEN + + "!"); + } + } + } + if (player.getItemInHand().getTypeId() == Residence + .getConfigManager().getInfoToolID()) { + if (event.getAction() == Action.LEFT_CLICK_BLOCK) { + Location loc = block.getLocation(); + String res = Residence.getResidenceManager().getNameByLoc( + loc); + if (res != null) { + Residence.getResidenceManager().printAreaInfo(res, + player); + event.setCancelled(true); + } + if (res == null) { + event.setCancelled(true); + player.sendMessage(Residence.getLanguage().getPhrase( + "NoResHere")); + } + } + } + if (!resadmin) { + if (heldItem != null) { + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (player.getItemInHand().getTypeId() == 351) { + if (player.getItemInHand().getData().getData() == 15 + && block.getType() == Material.GRASS + || player.getItemInHand().getData() + .getData() == 3 + && block.getTypeId() == 17 + && (block.getData() == 3 + || block.getData() == 7 + || block.getData() == 11 || block + .getData() == 15)) { + perms = Residence.getPermsByLocForPlayer(block + .getRelative(event.getBlockFace()) + .getLocation(), player); + if (!perms.playerHas(player.getName(), world, + "build", true)) { + event.setCancelled(true); + return; + } + } + } + if (heldItem == Material.ARMOR_STAND) { + perms = Residence.getPermsByLocForPlayer(block + .getRelative(event.getBlockFace()) + .getLocation(), player); + if (!perms.playerHas(player.getName(), world, + "build", true)) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase( + "NoPermission")); + event.setCancelled(true); + return; + } + } + } + } + if (isContainer(mat, block) || isCanUseEntity(mat, block)) { + boolean hasuse = perms.playerHas(player.getName(), world, + "use", true); + for (Entry checkMat : FlagPermissions + .getMaterialUseFlagList().entrySet()) { + if (mat == checkMat.getKey()) { + if (!perms.playerHas(player.getName(), world, + checkMat.getValue(), hasuse)) { + if (hasuse + || checkMat.getValue().equals( + "container")) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + + Residence + .getLanguage() + .getPhrase("FlagDeny", + checkMat.getValue())); + return; + } else { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + + Residence.getLanguage() + .getPhrase("FlagDeny", + "use")); + return; + } + } + } + } + if (Residence.getConfigManager().getCustomContainers() + .contains(Integer.valueOf(block.getTypeId()))) { + if (!perms.playerHas(player.getName(), world, + "container", hasuse)) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase( + "FlagDeny", "container")); + return; + } + } + if (Residence.getConfigManager().getCustomBothClick() + .contains(Integer.valueOf(block.getTypeId()))) { + if (!hasuse) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase( + "FlagDeny", "use")); + return; + } + } + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (Residence.getConfigManager().getCustomRightClick() + .contains(Integer.valueOf(block.getTypeId()))) { + if (!hasuse) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase( + "FlagDeny", "use")); + return; + } + } + } + } + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { + Player player = event.getPlayer(); + if (Residence.isResAdminOn(player)) { + return; + } + Entity ent = event.getRightClicked(); + /* Trade */ + if (ent.getType() == EntityType.VILLAGER) { + ClaimedResidence res = Residence.getResidenceManager().getByLoc( + event.getPlayer().getLocation()); + + if (res != null + && !res.getPermissions().playerHas(player.getName(), + "trade", true)) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("NoPermission")); + event.setCancelled(true); + } + } + + /* Container - ItemFrame protection */ + Material heldItem = player.getItemInHand().getType(); + if (!(ent instanceof Hanging)) { + return; + } + Hanging hanging = (Hanging) ent; + if (hanging.getType() != EntityType.ITEM_FRAME) { + return; + } + FlagPermissions perms = Residence.getPermsByLocForPlayer( + ent.getLocation(), player); + String world = player.getWorld().getName(); + String permgroup = Residence.getPermissionManager() + .getGroupNameByPlayer(player); + if (!Residence.getItemManager().isAllowed(heldItem, permgroup, world)) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("ItemBlacklisted")); + event.setCancelled(true); + return; + } + if (!perms.playerHas(player.getName(), world, "container", + perms.playerHas(player.getName(), world, "use", true))) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + + Residence.getLanguage() + .getPhrase("FlagDeny", "container")); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) { + Player player = event.getPlayer(); + if (Residence.isResAdminOn(player)) { + return; + } + + Entity ent = event.getRightClicked(); + if (ent.getType() != EntityType.ARMOR_STAND) { + return; + } + + FlagPermissions perms = Residence.getPermsByLocForPlayer( + ent.getLocation(), player); + String world = player.getWorld().getName(); + + if (!perms.playerHas(player.getName(), world, "container", + perms.playerHas(player.getName(), world, "use", true))) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + + Residence.getLanguage() + .getPhrase("FlagDeny", "container")); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) { + Player player = event.getPlayer(); + if (Residence.isResAdminOn(player)) { + return; + } + String pname = player.getName(); + ClaimedResidence res = Residence.getResidenceManager().getByLoc( + event.getBlockClicked().getLocation()); + if (res != null) { + if (Residence.getConfigManager().preventRentModify() + && Residence.getConfigManager().enabledRentSystem()) { + if (Residence.getRentManager().isRented(res.getName())) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase( + "RentedModifyDeny")); + event.setCancelled(true); + return; + } + } + } + FlagPermissions perms = Residence.getPermsByLocForPlayer(event + .getBlockClicked().getLocation(), player); + if (!perms.playerHas(pname, player.getWorld().getName(), "bucket", + perms.playerHas(pname, player.getWorld().getName(), "build", + true))) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("FlagDeny", "bucket")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerBucketFill(PlayerBucketFillEvent event) { + Player player = event.getPlayer(); + String pname = player.getName(); + if (Residence.isResAdminOn(player)) { + return; + } + ClaimedResidence res = Residence.getResidenceManager().getByLoc( + event.getBlockClicked().getLocation()); + if (res != null) { + if (Residence.getConfigManager().preventRentModify() + && Residence.getConfigManager().enabledRentSystem()) { + if (Residence.getRentManager().isRented(res.getName())) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase( + "RentedModifyDeny")); + event.setCancelled(true); + return; + } + } + } + FlagPermissions perms = Residence.getPermsByLocForPlayer(event + .getBlockClicked().getLocation(), player); + boolean hasbucket = perms.playerHas(pname, player.getWorld().getName(), + "bucket", perms.playerHas(pname, player.getWorld().getName(), + "build", true)); + if (!hasbucket) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("FlagDeny", "bucket")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerTeleport(PlayerTeleportEvent event) { + Location loc = event.getTo(); + Player player = event.getPlayer(); + + if (Residence.isResAdminOn(player)) { + handleNewLocation(player, loc, false); + return; + } + + ClaimedResidence res = Residence.getResidenceManager().getByLoc(loc); + if (event.getCause() == TeleportCause.ENDER_PEARL + || event.getCause() == TeleportCause.COMMAND + || event.getCause() == TeleportCause.NETHER_PORTAL) { + if (res != null) { + String areaname = Residence.getResidenceManager().getNameByLoc( + loc); + if (!res.getPermissions().playerHas(player.getName(), "move", + true)) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase( + "ResidenceMoveDeny", areaname)); + return; + } + } + } + if (event.getCause() == TeleportCause.PLUGIN) { + if (res != null) { + String areaname = Residence.getResidenceManager().getNameByLoc( + loc); + if (!res.getPermissions().playerHas(player.getName(), "tp", + true) + && !player.hasPermission("residence.admin.tp")) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("TeleportDeny", + areaname)); + return; + } + } + } + handleNewLocation(player, loc, false); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerMove(PlayerMoveEvent event) { + Player player = event.getPlayer(); + if (player == null) { + return; + } + long last = lastUpdate.get(player.getName()); + long now = System.currentTimeMillis(); + if (now - last < Residence.getConfigManager() + .getMinMoveUpdateInterval()) { + return; + } + lastUpdate.put(player.getName(), now); + if (event.getFrom().getWorld() == event.getTo().getWorld()) { + if (event.getFrom().distance(event.getTo()) == 0) { + return; + } + } + handleNewLocation(player, event.getTo(), true); + } + + public void handleNewLocation(Player player, Location loc, boolean move) { + String pname = player.getName(); + + ClaimedResidence res = Residence.getResidenceManager().getByLoc(loc); + String areaname = null; + boolean chatchange = false; + String subzone = null; + if (res != null) { + areaname = Residence.getResidenceManager().getNameByLoc(loc); + while (res.getSubzoneByLoc(player.getLocation()) != null) { + subzone = res.getSubzoneNameByLoc(player.getLocation()); + res = res.getSubzoneByLoc(player.getLocation()); + areaname = areaname + "." + subzone; + } + } + ClaimedResidence ResOld = null; + if (currentRes.containsKey(pname)) { + ResOld = Residence.getResidenceManager().getByName( + currentRes.get(pname)); + if (ResOld == null) { + currentRes.remove(pname); + } + } + if (res == null) { + lastOutsideLoc.put(pname, loc); + if (ResOld != null) { + String leave = ResOld.getLeaveMessage(); + /* + * TODO - ResidenceLeaveEvent is deprecated as of 21-MAY-2013. + * Its functionality is replaced by ResidenceChangedEvent. For + * now, this event is still supported until it is removed at a + * suitable time in the future. + */ + ResidenceLeaveEvent leaveevent = new ResidenceLeaveEvent( + ResOld, player); + Residence.getServ().getPluginManager().callEvent(leaveevent); + + // New ResidenceChangeEvent + ResidenceChangedEvent chgEvent = new ResidenceChangedEvent( + ResOld, null, player); + Residence.getServ().getPluginManager().callEvent(chgEvent); + + if (leave != null && !leave.equals("")) { + if (Residence.getConfigManager().useActionBar()) { + ActionBar + .send(player, + (new StringBuilder()) + .append(ChatColor.YELLOW) + .append(insertMessages(player, + ResOld.getName(), + ResOld, leave)) + .toString()); + } else { + player.sendMessage(ChatColor.YELLOW + + this.insertMessages(player, ResOld.getName(), + ResOld, leave)); + } + } + currentRes.remove(pname); + Residence.getChatManager().removeFromChannel(pname); + } + return; + } + if (move) { + if (!res.getPermissions().playerHas(pname, "move", true) + && !Residence.isResAdminOn(player) + && !player.hasPermission("residence.admin.move")) { + Location lastLoc = lastOutsideLoc.get(pname); + if (lastLoc != null) { + player.teleport(lastLoc); + } else { + player.teleport(res.getOutsideFreeLoc(loc)); + } + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase( + "ResidenceMoveDeny", + res.getName().split("\\.")[res.getName().split( + "\\.").length - 1])); + return; + } + } + lastOutsideLoc.put(pname, loc); + if (!currentRes.containsKey(pname) || ResOld != res) { + currentRes.put(pname, areaname); + if (subzone == null) { + chatchange = true; + } + + // "from" residence for ResidenceChangedEvent + ClaimedResidence chgFrom = null; + if (ResOld != res && ResOld != null) { + String leave = ResOld.getLeaveMessage(); + chgFrom = ResOld; + + /* + * TODO - ResidenceLeaveEvent is deprecated as of 21-MAY-2013. + * Its functionality is replaced by ResidenceChangedEvent. For + * now, this event is still supported until it is removed at a + * suitable time in the future. + */ + ResidenceLeaveEvent leaveevent = new ResidenceLeaveEvent( + ResOld, player); + Residence.getServ().getPluginManager().callEvent(leaveevent); + + if (leave != null && !leave.equals("") + && ResOld != res.getParent()) { + if (Residence.getConfigManager().useActionBar()) { + ActionBar + .send(player, + (new StringBuilder()) + .append(ChatColor.YELLOW) + .append(insertMessages(player, + ResOld.getName(), + ResOld, leave)) + .toString()); + } else { + player.sendMessage(ChatColor.YELLOW + + this.insertMessages(player, ResOld.getName(), + ResOld, leave)); + } + } + } + String enterMessage = res.getEnterMessage(); + + /* + * TODO - ResidenceEnterEvent is deprecated as of 21-MAY-2013. Its + * functionality is replaced by ResidenceChangedEvent. For now, this + * event is still supported until it is removed at a suitable time + * in the future. + */ + ResidenceEnterEvent enterevent = new ResidenceEnterEvent(res, + player); + Residence.getServ().getPluginManager().callEvent(enterevent); + + // New ResidenceChangedEvent + ResidenceChangedEvent chgEvent = new ResidenceChangedEvent(chgFrom, + res, player); + Residence.getServ().getPluginManager().callEvent(chgEvent); + + if (enterMessage != null && !enterMessage.equals("") + && !(ResOld != null && res == ResOld.getParent())) { + if (Residence.getConfigManager().useActionBar()) { + ActionBar.send( + player, + (new StringBuilder()) + .append(ChatColor.YELLOW) + .append(insertMessages(player, areaname, + res, enterMessage)).toString()); + } else { + player.sendMessage(ChatColor.YELLOW + + this.insertMessages(player, areaname, res, + enterMessage)); + } + } + } + if (chatchange && chatenabled) { + Residence.getChatManager().setChannel(pname, areaname); + } + } + + public String insertMessages(Player player, String areaname, + ClaimedResidence res, String message) { + try { + message = message.replaceAll("%player", player.getName()); + message = message.replaceAll("%owner", res.getPermissions() + .getOwner()); + message = message.replaceAll("%residence", areaname); + } catch (Exception ex) { + return ""; + } + return message; + } + + public void doHeals() { + try { + for (Player player : Bukkit.getServer().getOnlinePlayers()) { + String resname = Residence.getPlayerListener() + .getCurrentResidenceName(player.getName()); + ClaimedResidence res = null; + if (resname != null) { + res = Residence.getResidenceManager().getByName(resname); + } + if (res != null && res.getPermissions().has("healing", false)) { + Damageable damage = player; + double health = damage.getHealth(); + if (health < 20 && !player.isDead()) { + player.setHealth(health + 1); + } + } + } + } catch (Exception ex) { + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerChat(AsyncPlayerChatEvent event) { + String pname = event.getPlayer().getName(); + if (chatenabled && playerToggleChat.contains(pname)) { + String area = currentRes.get(pname); + if (area != null) { + ChatChannel channel = Residence.getChatManager().getChannel( + area); + if (channel != null) { + channel.chat(pname, event.getMessage()); + } + event.setCancelled(true); + } + } + } + + public void tooglePlayerResidenceChat(Player player) { + String pname = player.getName(); + if (playerToggleChat.contains(pname)) { + playerToggleChat.remove(pname); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("ResidenceChat", + ChatColor.RED + "OFF" + ChatColor.YELLOW + "!")); + } else { + playerToggleChat.add(pname); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("ResidenceChat", + ChatColor.RED + "ON" + ChatColor.YELLOW + "!")); + } + } + + public String getCurrentResidenceName(String player) { + return currentRes.get(player); + } +} diff --git a/src/com/bekvon/bukkit/residence/permissions/PermissionGroup.java b/src/com/bekvon/bukkit/residence/permissions/PermissionGroup.java new file mode 100644 index 0000000..59c550f --- /dev/null +++ b/src/com/bekvon/bukkit/residence/permissions/PermissionGroup.java @@ -0,0 +1,320 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.permissions; + +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.protection.CuboidArea; +import com.bekvon.bukkit.residence.protection.FlagPermissions; +import com.bekvon.bukkit.residence.protection.FlagPermissions.FlagState; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + * + * changed by inori 03/17/2012 line 91:limits MaxHeight changed to 255 + */ +public class PermissionGroup { + protected int xmax; + protected int ymax; + protected int zmax; + protected int resmax; + protected double costperarea; + protected boolean tpaccess; + protected int subzonedepth; + protected FlagPermissions flagPerms; + protected Map creatorDefaultFlags; + protected Map> groupDefaultFlags; + protected Map residenceDefaultFlags; + protected boolean messageperms; + protected String defaultEnterMessage; + protected String defaultLeaveMessage; + protected int maxLeaseTime; + protected int leaseGiveTime; + protected double renewcostperarea; + protected boolean canBuy; + protected boolean canSell; + protected boolean buyIgnoreLimits; + protected boolean cancreate; + protected String groupname; + protected int maxPhysical; + protected boolean unstuck; + protected boolean kick; + protected int minHeight; + protected int maxHeight; + protected int maxRents; + protected int maxRentables; + protected boolean selectCommandAccess; + protected boolean itemListAccess; + + public PermissionGroup(String name) { + flagPerms = new FlagPermissions(); + creatorDefaultFlags = new HashMap(); + residenceDefaultFlags = new HashMap(); + groupDefaultFlags = new HashMap>(); + groupname = name; + } + + public PermissionGroup(String name, ConfigurationSection node) { + this(name); + this.parseGroup(node); + } + + public PermissionGroup(String name, ConfigurationSection node, FlagPermissions parentFlagPerms) { + this(name, node); + flagPerms.setParent(parentFlagPerms); + } + + private void parseGroup(ConfigurationSection limits) { + if (limits == null) { + return; + } + cancreate = limits.getBoolean("Residence.CanCreate", false); + resmax = limits.getInt("Residence.MaxResidences", 0); + maxPhysical = limits.getInt("Residence.MaxAreasPerResidence", 2); + xmax = limits.getInt("Residence.MaxEastWest", 0); + ymax = limits.getInt("Residence.MaxUpDown", 0); + zmax = limits.getInt("Residence.MaxNorthSouth", 0); + minHeight = limits.getInt("Residence.MinHeight", 0); + maxHeight = limits.getInt("Residence.MaxHeight", 255); + tpaccess = limits.getBoolean("Residence.CanTeleport", false); + subzonedepth = limits.getInt("Residence.SubzoneDepth", 0); + messageperms = limits.getBoolean("Messaging.CanChange", false); + defaultEnterMessage = limits.getString("Messaging.DefaultEnter", null); + defaultLeaveMessage = limits.getString("Messaging.DefaultLeave", null); + maxLeaseTime = limits.getInt("Lease.MaxDays", 16); + leaseGiveTime = limits.getInt("Lease.RenewIncrement", 14); + maxRents = limits.getInt("Rent.MaxRents", 0); + maxRentables = limits.getInt("Rent.MaxRentables", 0); + renewcostperarea = limits.getDouble("Economy.RenewCost", 0.02D); + canBuy = limits.getBoolean("Economy.CanBuy", false); + canSell = limits.getBoolean("Economy.CanSell", false); + buyIgnoreLimits = limits.getBoolean("Economy.IgnoreLimits", false); + costperarea = limits.getDouble("Economy.BuyCost", 0); + unstuck = limits.getBoolean("Residence.Unstuck", false); + kick = limits.getBoolean("Residence.Kick", false); + selectCommandAccess = limits.getBoolean("Residence.SelectCommandAccess", true); + itemListAccess = limits.getBoolean("Residence.ItemListAccess", true); + ConfigurationSection node = limits.getConfigurationSection("Flags.Permission"); + Set flags = null; + if (node != null) { + flags = node.getKeys(false); + } + if (flags != null) { + Iterator flagit = flags.iterator(); + while (flagit.hasNext()) { + String flagname = flagit.next(); + boolean access = limits.getBoolean("Flags.Permission." + flagname, false); + flagPerms.setFlag(flagname, access ? FlagState.TRUE : FlagState.FALSE); + } + } + node = limits.getConfigurationSection("Flags.CreatorDefault"); + if (node != null) { + flags = node.getKeys(false); + } + if (flags != null) { + Iterator flagit = flags.iterator(); + while (flagit.hasNext()) { + String flagname = flagit.next(); + boolean access = limits.getBoolean("Flags.CreatorDefault." + flagname, false); + creatorDefaultFlags.put(flagname, access); + } + + } + node = limits.getConfigurationSection("Flags.Default"); + if (node != null) { + flags = node.getKeys(false); + } + if (flags != null) { + Iterator flagit = flags.iterator(); + while (flagit.hasNext()) { + String flagname = flagit.next(); + boolean access = limits.getBoolean("Flags.Default." + flagname, false); + residenceDefaultFlags.put(flagname, access); + } + } + node = limits.getConfigurationSection("Flags.GroupDefault"); + Set groupDef = null; + if (node != null) { + groupDef = node.getKeys(false); + } + if (groupDef != null) { + Iterator groupit = groupDef.iterator(); + while (groupit.hasNext()) { + String name = groupit.next(); + Map gflags = new HashMap(); + flags = limits.getConfigurationSection("Flags.GroupDefault." + name).getKeys(false); + Iterator flagit = flags.iterator(); + while (flagit.hasNext()) { + String flagname = flagit.next(); + boolean access = limits.getBoolean("Flags.GroupDefault." + name + "." + flagname, false); + gflags.put(flagname, access); + } + groupDefaultFlags.put(name, gflags); + } + } + } + + public int getMaxX() { + return xmax; + } + + public int getMaxY() { + return ymax; + } + + public int getMaxZ() { + return zmax; + } + + public int getMinHeight() { + return minHeight; + } + + public int getMaxHeight() { + return maxHeight; + } + + public int getMaxZones() { + return resmax; + } + + public double getCostPerBlock() { + return costperarea; + } + + public boolean hasTpAccess() { + return tpaccess; + } + + public int getMaxSubzoneDepth() { + return subzonedepth; + } + + public boolean canSetEnterLeaveMessages() { + return messageperms; + } + + public String getDefaultEnterMessage() { + return defaultEnterMessage; + } + + public String getDefaultLeaveMessage() { + return defaultLeaveMessage; + } + + public int getMaxLeaseTime() { + return maxLeaseTime; + } + + public int getLeaseGiveTime() { + return leaseGiveTime; + } + + public double getLeaseRenewCost() { + return renewcostperarea; + } + + public boolean canBuyLand() { + return canBuy; + } + + public boolean canSellLand() { + return canSell; + } + + public int getMaxRents() { + return maxRents; + } + + public int getMaxRentables() { + return maxRentables; + } + + public boolean buyLandIgnoreLimits() { + return buyIgnoreLimits; + } + + public boolean hasUnstuckAccess() { + return unstuck; + } + public boolean hasKickAccess() { + return kick; + } + public int getMaxPhysicalPerResidence() { + return maxPhysical; + } + + public Set> getDefaultResidenceFlags() { + return residenceDefaultFlags.entrySet(); + } + + public Set> getDefaultCreatorFlags() { + return creatorDefaultFlags.entrySet(); + } + + public Set>> getDefaultGroupFlags() { + return groupDefaultFlags.entrySet(); + } + + public boolean canCreateResidences() { + return cancreate; + } + + public boolean hasFlagAccess(String flag) { + return flagPerms.has(flag, false); + } + + public boolean inLimits(CuboidArea area) { + if (area.getXSize() > xmax || area.getYSize() > ymax || area.getZSize() > zmax) { + return false; + } + return true; + } + + public boolean selectCommandAccess() { + return selectCommandAccess; + } + + public boolean itemListAccess() { + return itemListAccess; + } + + public void printLimits(Player player) { + player.sendMessage(ChatColor.GRAY + "---------------------------"); + player.sendMessage(ChatColor.YELLOW + "Permissions Group:" + ChatColor.DARK_AQUA + " " + Residence.getPermissionManager().getPermissionsGroup(player)); + player.sendMessage(ChatColor.YELLOW + "Residence Group:" + ChatColor.DARK_AQUA + " " + groupname); + player.sendMessage(ChatColor.YELLOW + "Residence Admin:" + ChatColor.DARK_AQUA + " " + Residence.getPermissionManager().isResidenceAdmin(player)); + player.sendMessage(ChatColor.YELLOW + "Can Create Residences:" + ChatColor.DARK_AQUA + " " + cancreate); + player.sendMessage(ChatColor.YELLOW + "Max Residences:" + ChatColor.DARK_AQUA + " " + resmax); + player.sendMessage(ChatColor.YELLOW + "Max East/West Size:" + ChatColor.DARK_AQUA + " " + xmax); + player.sendMessage(ChatColor.YELLOW + "Max North/South Size:" + ChatColor.DARK_AQUA + " " + zmax); + player.sendMessage(ChatColor.YELLOW + "Max Up/Down Size:" + ChatColor.DARK_AQUA + " " + ymax); + player.sendMessage(ChatColor.YELLOW + "Min/Max Protection Height:" + ChatColor.DARK_AQUA + " " + minHeight + " to " + maxHeight); + player.sendMessage(ChatColor.YELLOW + "Max Subzone Depth:" + ChatColor.DARK_AQUA + " " + subzonedepth); + player.sendMessage(ChatColor.YELLOW + "Can Set Enter/Leave Messages:" + ChatColor.DARK_AQUA + " " + messageperms); + player.sendMessage(ChatColor.YELLOW + "Number of Residences you own:" + ChatColor.DARK_AQUA + " " + Residence.getResidenceManager().getOwnedZoneCount(player.getName())); + if (Residence.getEconomyManager() != null) { + player.sendMessage(ChatColor.YELLOW + "Residence Cost Per Block:" + ChatColor.DARK_AQUA + " " + costperarea); + } + player.sendMessage(ChatColor.YELLOW + "Flag Permissions:" + ChatColor.DARK_AQUA + " " + flagPerms.listFlags()); + if (Residence.getConfigManager().useLeases()) { + player.sendMessage(ChatColor.YELLOW + "Max Lease Days:" + ChatColor.DARK_AQUA + " " + maxLeaseTime); + player.sendMessage(ChatColor.YELLOW + "Lease Time Given on Renew:" + ChatColor.DARK_AQUA + " " + leaseGiveTime); + player.sendMessage(ChatColor.YELLOW + "Renew Cost Per Block:" + ChatColor.DARK_AQUA + " " + renewcostperarea); + } + player.sendMessage(ChatColor.GRAY + "---------------------------"); + } + +} diff --git a/src/com/bekvon/bukkit/residence/permissions/PermissionManager.java b/src/com/bekvon/bukkit/residence/permissions/PermissionManager.java new file mode 100644 index 0000000..2a73da0 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/permissions/PermissionManager.java @@ -0,0 +1,180 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.permissions; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.protection.FlagPermissions; +import com.bekvon.bukkit.residence.vaultinterface.ResidenceVaultAdapter; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.Server; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +/** + * + * @author Administrator + */ +public class PermissionManager { + protected static PermissionsInterface perms; + protected Map groups; + protected Map playersGroup; + protected FlagPermissions globalFlagPerms; + + public PermissionManager(FileConfiguration config) { + try { + groups = Collections + .synchronizedMap(new HashMap()); + playersGroup = Collections + .synchronizedMap(new HashMap()); + globalFlagPerms = new FlagPermissions(); + this.readConfig(config); + boolean enable = config + .getBoolean("Global.EnablePermissions", true); + if (enable) { + this.checkPermissions(); + } + } catch (Exception ex) { + Logger.getLogger(PermissionManager.class.getName()).log( + Level.SEVERE, null, ex); + } + } + + public PermissionGroup getGroup(Player player) { + return groups.get(this.getGroupNameByPlayer(player)); + } + + public PermissionGroup getGroup(String player, String world) { + return groups.get(this.getGroupNameByPlayer(player, world)); + } + + public PermissionGroup getGroupByName(String group) { + group = group.toLowerCase(); + if (!groups.containsKey(group)) { + return groups.get(Residence.getConfigManager().getDefaultGroup()); + } + return groups.get(group); + } + + public String getGroupNameByPlayer(Player player) { + return this.getGroupNameByPlayer(player.getName(), player.getWorld() + .getName()); + } + + public String getGroupNameByPlayer(String player, String world) { + player = player.toLowerCase(); + if (playersGroup.containsKey(player)) { + String group = playersGroup.get(player); + if (group != null) { + group = group.toLowerCase(); + if (group != null && groups.containsKey(group)) { + return group; + } + } + } + String group = this.getPermissionsGroup(player, world); + if (group == null || !groups.containsKey(group)) { + return Residence.getConfigManager().getDefaultGroup().toLowerCase(); + } else { + return group; + } + } + + public String getPermissionsGroup(Player player) { + return this.getPermissionsGroup(player.getName(), player.getWorld() + .getName()); + } + + public String getPermissionsGroup(String player, String world) { + if (perms == null) + return Residence.getConfigManager().getDefaultGroup(); + return perms.getPlayerGroup(player, world); + } + + public boolean isResidenceAdmin(Player player) { + return (player.hasPermission("residence.admin") || (player.isOp() && Residence + .getConfigManager().getOpsAreAdmins())); + } + + private void checkPermissions() { + Server server = Residence.getServ(); + Plugin p = server.getPluginManager().getPlugin("Vault"); + if (p != null) { + ResidenceVaultAdapter vault = new ResidenceVaultAdapter(server); + if (vault.permissionsOK()) { + perms = vault; + Logger.getLogger("Minecraft").log( + Level.INFO, + "[Residence] Found Vault using permissions plugin:" + + vault.getPermissionsName()); + return; + } else { + Logger.getLogger("Minecraft") + .log(Level.INFO, + "[Residence] Found Vault, but Vault reported no usable permissions system..."); + } + } + Logger.getLogger("Minecraft").log(Level.INFO, + "[Residence] Permissions plugin NOT FOUND!"); + } + + private void readConfig(FileConfiguration config) { + String defaultGroup = Residence.getConfigManager().getDefaultGroup(); + globalFlagPerms = FlagPermissions.parseFromConfigNode("FlagPermission", + config.getConfigurationSection("Global")); + ConfigurationSection nodes = config.getConfigurationSection("Groups"); + if (nodes != null) { + Set entrys = nodes.getKeys(false); + for (String key : entrys) { + try { + groups.put( + key.toLowerCase(), + new PermissionGroup(key.toLowerCase(), nodes + .getConfigurationSection(key), + globalFlagPerms)); + List mirrors = nodes.getConfigurationSection(key) + .getStringList("Mirror"); + for (String group : mirrors) { + groups.put( + group.toLowerCase(), + new PermissionGroup(key.toLowerCase(), nodes + .getConfigurationSection(key), + globalFlagPerms)); + } + } catch (Exception ex) { + System.out + .println("[Residence] Error parsing group from config:" + + key + " Exception:" + ex); + } + } + } + if (!groups.containsKey(defaultGroup)) { + groups.put(defaultGroup, new PermissionGroup(defaultGroup)); + } + Set keys = config.getConfigurationSection("GroupAssignments") + .getKeys(false); + if (keys != null) { + for (String key : keys) { + playersGroup.put( + key.toLowerCase(), + config.getString("GroupAssignments." + key, + defaultGroup).toLowerCase()); + } + } + } + + public boolean hasGroup(String group) { + group = group.toLowerCase(); + return groups.containsKey(group); + } + + public PermissionsInterface getPermissionsPlugin() { + return perms; + } +} diff --git a/src/com/bekvon/bukkit/residence/permissions/PermissionsInterface.java b/src/com/bekvon/bukkit/residence/permissions/PermissionsInterface.java new file mode 100644 index 0000000..72e5f71 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/permissions/PermissionsInterface.java @@ -0,0 +1,17 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.permissions; + +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public interface PermissionsInterface { + public String getPlayerGroup(Player player); + public String getPlayerGroup(String player, String world); +} diff --git a/src/com/bekvon/bukkit/residence/persistance/YMLSaveHelper.java b/src/com/bekvon/bukkit/residence/persistance/YMLSaveHelper.java new file mode 100644 index 0000000..ec5819b --- /dev/null +++ b/src/com/bekvon/bukkit/residence/persistance/YMLSaveHelper.java @@ -0,0 +1,67 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.persistance; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.DumperOptions.FlowStyle; +import org.yaml.snakeyaml.Yaml; + +/** + * + * @author Administrator + */ +public class YMLSaveHelper { + + File f; + Yaml yml; + Map root; + + public YMLSaveHelper(File ymlfile) throws IOException + { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(FlowStyle.BLOCK); + yml = new Yaml(options); + + root = new LinkedHashMap(); + if(ymlfile == null) + throw new IOException("YMLSaveHelper: null file..."); + f = ymlfile; + } + + public void save() throws IOException + { + if(f.isFile()) + f.delete(); + FileOutputStream fout = new FileOutputStream(f); + OutputStreamWriter osw = new OutputStreamWriter(fout, "UTF8"); + yml.dump(root, osw); + osw.close(); + } + + @SuppressWarnings("unchecked") + public void load() throws IOException + { + FileInputStream fis = new FileInputStream(f); + InputStreamReader isr = new InputStreamReader(fis, "UTF8"); + root = (Map) yml.load(isr); + isr.close(); + } + + public Map getRoot() + { + return root; + } + +} diff --git a/src/com/bekvon/bukkit/residence/protection/ClaimedResidence.java b/src/com/bekvon/bukkit/residence/protection/ClaimedResidence.java new file mode 100644 index 0000000..1df7f1c --- /dev/null +++ b/src/com/bekvon/bukkit/residence/protection/ClaimedResidence.java @@ -0,0 +1,966 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.bekvon.bukkit.residence.protection; + +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.economy.ResidenceBank; +import com.bekvon.bukkit.residence.economy.TransactionManager; +import com.bekvon.bukkit.residence.event.ResidenceTPEvent; +import com.bekvon.bukkit.residence.itemlist.ItemList.ListType; +import com.bekvon.bukkit.residence.itemlist.ResidenceItemList; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; +import com.bekvon.bukkit.residence.text.help.InformationPager; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + * + */ +public class ClaimedResidence { + + protected ClaimedResidence parent; + protected Map areas; + protected Map subzones; + protected ResidencePermissions perms; + protected ResidenceBank bank; + protected Location tpLoc; + protected String enterMessage; + protected String leaveMessage; + protected ResidenceItemList ignorelist; + protected ResidenceItemList blacklist; + + private ClaimedResidence() { + subzones = new HashMap(); + areas = new HashMap(); + bank = new ResidenceBank(this); + blacklist = new ResidenceItemList(this, ListType.BLACKLIST); + ignorelist = new ResidenceItemList(this, ListType.IGNORELIST); + } + + public ClaimedResidence(String creationWorld) { + this("Server Land", creationWorld); + } + + public ClaimedResidence(String creator, String creationWorld) { + this(); + perms = new ResidencePermissions(this, creator, creationWorld); + } + + public ClaimedResidence(String creator, String creationWorld, ClaimedResidence parentResidence) { + this(creator, creationWorld); + parent = parentResidence; + } + + public boolean addArea(CuboidArea area, String name) { + return addArea(null, area, name, true); + } + + public boolean addArea(Player player, CuboidArea area, String name, boolean resadmin) { + if (!Residence.validName(name)) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidNameCharacters")); + } + return false; + } + if (areas.containsKey(name)) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaExists")); + } + return false; + } + if (!resadmin && Residence.getConfigManager().getEnforceAreaInsideArea() && this.getParent() == null) { + boolean inside = false; + for (CuboidArea are: areas.values()) { + if (are.isAreaWithinArea(area)) { + inside = true; + } + } + if (!inside) { + return false; + } + } + if (!area.getWorld().getName().equalsIgnoreCase(perms.getWorld())) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaDiffWorld")); + } + return false; + } + if (parent == null) { + String collideResidence = Residence.getResidenceManager().checkAreaCollision(area, this); + if (collideResidence != null) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaCollision", ChatColor.YELLOW + collideResidence)); + } + return false; + } + } else { + String[] szs = parent.listSubzones(); + for (String sz : szs) { + ClaimedResidence res = parent.getSubzone(sz); + if (res != null && res != this) { + if (res.checkCollision(area)) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaSubzoneCollision", ChatColor.YELLOW + sz)); + } + return false; + } + } + } + } + if (!resadmin && player != null) { + if (!this.perms.hasResidencePermission(player, true)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return false; + } + if (parent != null) { + if (!parent.containsLoc(area.getHighLoc()) || !parent.containsLoc(area.getLowLoc())) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaNotWithinParent")); + return false; + } + if (!parent.getPermissions().hasResidencePermission(player, true) && !parent.getPermissions().playerHas(player.getName(), "subzone", true)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ParentNoPermission")); + return false; + } + } + PermissionGroup group = Residence.getPermissionManager().getGroup(player); + if (!group.canCreateResidences() && !player.hasPermission("residence.create")) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return false; + } + if (areas.size() >= group.getMaxPhysicalPerResidence()) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaMaxPhysical")); + return false; + } + if (!group.inLimits(area)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaSizeLimit")); + return false; + } + if (group.getMinHeight() > area.getLowLoc().getBlockY()) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaLowLimit", ChatColor.YELLOW + String.format("%d", group.getMinHeight()))); + return false; + } + if (group.getMaxHeight() < area.getHighLoc().getBlockY()) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaHighLimit", ChatColor.YELLOW + String.format("%d", group.getMaxHeight()))); + return false; + } + if (parent == null && Residence.getConfigManager().enableEconomy()) { + int chargeamount = (int) Math.ceil((double) area.getSize() * group.getCostPerBlock()); + if (!TransactionManager.chargeEconomyMoney(player, chargeamount)) { + return false; + } + } + } + Residence.getResidenceManager().removeChunkList(getName()); + areas.put(name, area); + Residence.getResidenceManager().calculateChunks(getName()); + if (player != null) { + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("AreaCreate", ChatColor.YELLOW + name)); + } + return true; + } + + public boolean replaceArea(CuboidArea neware, String name) { + return this.replaceArea(null, neware, name, true); + } + + public boolean replaceArea(Player player, CuboidArea newarea, String name, boolean resadmin) { + if (!areas.containsKey(name)) { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaNonExist")); + return false; + } + CuboidArea oldarea = areas.get(name); + if (!newarea.getWorld().getName().equalsIgnoreCase(perms.getWorld())) { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaDiffWorld")); + return false; + } + if (parent == null) { + String collideResidence = Residence.getResidenceManager().checkAreaCollision(newarea, this); + if (collideResidence != null) { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaCollision", ChatColor.YELLOW + collideResidence)); + return false; + } + } else { + String[] szs = parent.listSubzones(); + for (String sz : szs) { + ClaimedResidence res = parent.getSubzone(sz); + if (res != null && res != this) { + if (res.checkCollision(newarea)) { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaSubzoneCollision", ChatColor.YELLOW + sz)); + return false; + } + } + } + } + //Remove subzones that are not in the area anymore + String[] szs = listSubzones(); + for (String sz : szs) { + ClaimedResidence res = getSubzone(sz); + if (res != null && res != this) { + String[] areas = res.getAreaList(); + for (String area: areas) { + if (!newarea.isAreaWithinArea(res.getArea(area))) { + boolean good = false; + for (CuboidArea arae: getAreaArray()) { + if (arae != oldarea && arae.isAreaWithinArea(res.getArea(area))) { + good = true; + } + } + if (!good) { + res.removeArea(area); + } + } + } + if (res.getAreaArray().length == 0) { + removeSubzone(sz); + } + } + } + if (!resadmin && player != null) { + if (!this.perms.hasResidencePermission(player, true)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return false; + } + if (parent != null) { + if (!parent.containsLoc(newarea.getHighLoc()) || !parent.containsLoc(newarea.getLowLoc())) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaNotWithinParent")); + return false; + } + if (!parent.getPermissions().hasResidencePermission(player, true) && !parent.getPermissions().playerHas(player.getName(), "subzone", true)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ParentNoPermission")); + return false; + } + } + PermissionGroup group = Residence.getPermissionManager().getGroup(player); + if (!group.canCreateResidences() && !player.hasPermission("residence.create")) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return false; + } + if (!group.inLimits(newarea)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaSizeLimit")); + return false; + } + if (group.getMinHeight() > newarea.getLowLoc().getBlockY()) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaLowLimit", ChatColor.YELLOW + String.format("%d", group.getMinHeight()))); + return false; + } + if (group.getMaxHeight() < newarea.getHighLoc().getBlockY()) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaHighLimit", ChatColor.YELLOW + String.format("%d", group.getMaxHeight()))); + return false; + } + if (parent == null && Residence.getConfigManager().enableEconomy()) { + int chargeamount = (int) Math.ceil((double) (newarea.getSize() - oldarea.getSize()) * group.getCostPerBlock()); + if (chargeamount > 0) { + if (!TransactionManager.chargeEconomyMoney(player, chargeamount)) { + return false; + } + } + } + + } + Residence.getResidenceManager().removeChunkList(getName()); + areas.remove(name); + areas.put(name, newarea); + Residence.getResidenceManager().calculateChunks(getName()); + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("AreaUpdate")); + return true; + } + + public boolean addSubzone(String name, Location loc1, Location loc2) { + return this.addSubzone(null, loc1, loc2, name, true); + } + + public boolean addSubzone(Player player, Location loc1, Location loc2, String name, boolean resadmin) { + if (player == null) { + return this.addSubzone(null, "Server Land", loc1, loc2, name, resadmin); + } else { + return this.addSubzone(player, player.getName(), loc1, loc2, name, resadmin); + } + } + + public boolean addSubzone(Player player, String owner, Location loc1, Location loc2, String name, boolean resadmin) { + if (!Residence.validName(name)) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidNameCharacters")); + } + return false; + } + if (!(this.containsLoc(loc1) && this.containsLoc(loc2))) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("SubzoneSelectInside")); + } + return false; + } + if (subzones.containsKey(name)) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("SubzoneExists", ChatColor.YELLOW + name)); + } + return false; + } + if (!resadmin && player != null) { + if (!this.perms.hasResidencePermission(player, true)) { + if (!this.perms.playerHas(player.getName(), "subzone", this.perms.playerHas(player.getName(), "admin", false))) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return false; + } + } + PermissionGroup group = Residence.getPermissionManager().getGroup(player); + if (this.getZoneDepth() >= group.getMaxSubzoneDepth()) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("SubzoneMaxDepth")); + return false; + } + } + CuboidArea newArea = new CuboidArea(loc1, loc2); + Set> set = subzones.entrySet(); + for (Entry resEntry : set) { + ClaimedResidence res = resEntry.getValue(); + if (res.checkCollision(newArea)) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("SubzoneCollide", ChatColor.YELLOW + resEntry.getKey())); + } + return false; + } + } + ClaimedResidence newres; + if (player != null) { + newres = new ClaimedResidence(owner, perms.getWorld(), this); + newres.addArea(player, newArea, name, resadmin); + } else { + newres = new ClaimedResidence(owner, perms.getWorld(), this); + newres.addArea(newArea, name); + } + if (newres.getAreaCount() != 0) { + newres.getPermissions().applyDefaultFlags(); + if (player != null) { + PermissionGroup group = Residence.getPermissionManager().getGroup(player); + newres.setEnterMessage(group.getDefaultEnterMessage()); + newres.setLeaveMessage(group.getDefaultLeaveMessage()); + } + if (Residence.getConfigManager().flagsInherit()) { + newres.getPermissions().setParent(perms); + } + subzones.put(name, newres); + if (player != null) + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("SubzoneCreate", ChatColor.YELLOW + name)); + return true; + } else { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("SubzoneCreateFail", ChatColor.YELLOW + name)); + } + return false; + } + } + + public String getSubzoneNameByLoc(Location loc) { + Set> set = subzones.entrySet(); + ClaimedResidence res = null; + String key = null; + for (Entry entry : set) { + res = entry.getValue(); + if (res.containsLoc(loc)) { + key = entry.getKey(); + break; + } + } + if (key == null) { + return null; + } + String subname = res.getSubzoneNameByLoc(loc); + if (subname != null) { + return key + "." + subname; + } + return key; + } + + public ClaimedResidence getSubzoneByLoc(Location loc) { + Set> set = subzones.entrySet(); + boolean found = false; + ClaimedResidence res = null; + for (Entry entry : set) { + res = entry.getValue(); + if (res.containsLoc(loc)) { + found = true; + break; + } + } + if (!found) { + return null; + } + ClaimedResidence subrez = res.getSubzoneByLoc(loc); + if (subrez == null) { + return res; + } + return subrez; + } + + public ClaimedResidence getSubzone(String subzonename) { + if (!subzonename.contains(".")) { + return subzones.get(subzonename); + } + String split[] = subzonename.split("\\."); + ClaimedResidence get = subzones.get(split[0]); + for (int i = 1; i < split.length; i++) { + if (get == null) { + return null; + } + get = get.getSubzone(split[i]); + } + return get; + } + + public String getSubzoneNameByRes(ClaimedResidence res) { + Set> set = subzones.entrySet(); + for (Entry entry : set) { + if (entry.getValue() == res) { + return entry.getKey(); + } + String n = entry.getValue().getSubzoneNameByRes(res); + if (n != null) { + return entry.getKey() + "." + n; + } + } + return null; + } + + public String[] getSubzoneList() { + ArrayList zones = new ArrayList(); + Set set = subzones.keySet(); + for (String key : set) { + if (key != null) { + zones.add(key); + } + } + return zones.toArray(new String[zones.size()]); + } + + public boolean checkCollision(CuboidArea area) { + Set set = areas.keySet(); + for (String key : set) { + CuboidArea checkarea = areas.get(key); + if (checkarea != null) { + if (checkarea.checkCollision(area)) { + return true; + } + } + } + return false; + } + + public boolean containsLoc(Location loc) { + Collection keys = areas.values(); + for (CuboidArea key : keys) { + if (key.containsLoc(loc)) { + if (parent != null) + return parent.containsLoc(loc); + return true; + } + } + return false; + } + + public ClaimedResidence getParent() { + return parent; + } + + public ClaimedResidence getTopParent() { + if (parent == null) + return this; + return parent.getTopParent(); + } + + public boolean removeSubzone(String name) { + return this.removeSubzone(null, name, true); + } + + public boolean removeSubzone(Player player, String name, boolean resadmin) { + ClaimedResidence res = subzones.get(name); + if (player != null && !res.perms.hasResidencePermission(player, true) && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return false; + } + subzones.remove(name); + if (player != null) { + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("SubzoneRemove", ChatColor.YELLOW + name + ChatColor.GREEN)); + } + return true; + } + + public long getTotalSize() { + Collection set = areas.values(); + long size = 0; + for (CuboidArea entry : set) { + size = size + entry.getSize(); + } + return size; + } + + public CuboidArea[] getAreaArray() { + CuboidArea[] temp = new CuboidArea[areas.size()]; + int i = 0; + for (CuboidArea area : areas.values()) { + temp[i] = area; + i++; + } + return temp; + } + + public ResidencePermissions getPermissions() { + return perms; + } + + public String getEnterMessage() { + return enterMessage; + } + + public String getLeaveMessage() { + return leaveMessage; + } + + public void setEnterMessage(String message) { + enterMessage = message; + } + + public void setLeaveMessage(String message) { + leaveMessage = message; + } + + public void setEnterLeaveMessage(Player player, String message, boolean enter, boolean resadmin) { + // if(message!=null && + // Residence.getConfigManager().getResidenceNameRegex() != null) { + // Removed pending further action + // player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("InvalidCharacters")); + // return; + // } + if (message != null) { + if (message.equals("")) { + message = null; + } + } + PermissionGroup group = Residence.getPermissionManager().getGroup(perms.getOwner(), perms.getWorld()); + if (!group.canSetEnterLeaveMessages() && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("OwnerNoPermission")); + return; + } + if (!perms.hasResidencePermission(player, false) && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + if (enter) { + this.setEnterMessage(message); + } else { + this.setLeaveMessage(message); + } + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("MessageChange")); + } + + @SuppressWarnings("deprecation") + public Location getOutsideFreeLoc(Location insideLoc) { + int maxIt = 100; + CuboidArea area = this.getAreaByLoc(insideLoc); + if (area == null) { + return insideLoc; + } + Location highLoc = area.getHighLoc(); + Location newLoc = new Location(highLoc.getWorld(), highLoc.getBlockX(), highLoc.getBlockY(), highLoc.getBlockZ()); + boolean found = false; + int it = 0; + while (!found && it < maxIt) { + it++; + Location lowLoc; + newLoc.setX(newLoc.getBlockX() + 1); + newLoc.setZ(newLoc.getBlockZ() + 1); + lowLoc = new Location(newLoc.getWorld(), newLoc.getBlockX(), 254, newLoc.getBlockZ()); + newLoc.setY(255); + while ((newLoc.getBlock().getTypeId() != 0 || lowLoc.getBlock().getTypeId() == 0) && lowLoc.getBlockY() > -126) { + newLoc.setY(newLoc.getY() - 1); + lowLoc.setY(lowLoc.getY() - 1); + } + if (newLoc.getBlock().getTypeId() == 0 + && lowLoc.getBlock().getTypeId() != 0) { + found = true; + } + } + if (found) { + return newLoc; + } else { + World world = Residence.getServ().getWorld(perms.getWorld()); + if (world != null) { + return world.getSpawnLocation(); + } + return insideLoc; + } + } + + protected CuboidArea getAreaByLoc(Location loc) { + for (CuboidArea thisarea : areas.values()) { + if (thisarea.containsLoc(loc)) { + return thisarea; + } + } + return null; + } + + public String[] listSubzones() { + String list[] = new String[subzones.size()]; + int i = 0; + for (String res : subzones.keySet()) { + list[i] = res; + i++; + } + return list; + } + + public void printSubzoneList(Player player, int page) { + ArrayList temp = new ArrayList(); + for (Entry sz : subzones.entrySet()) { + temp.add(ChatColor.GREEN + sz.getKey() + ChatColor.YELLOW + " - " + Residence.getLanguage().getPhrase("Owner") + ": " + sz.getValue().getOwner()); + } + InformationPager.printInfo(player, Residence.getLanguage().getPhrase("Subzones"), temp, page); + } + + public void printAreaList(Player player, int page) { + ArrayList temp = new ArrayList(); + for (String area : areas.keySet()) { + temp.add(area); + } + InformationPager.printInfo(player, Residence.getLanguage().getPhrase("PhysicalAreas"), temp, page); + } + + public void printAdvancedAreaList(Player player, int page) { + ArrayList temp = new ArrayList(); + for (Entry entry : areas.entrySet()) { + CuboidArea a = entry.getValue(); + Location h = a.getHighLoc(); + Location l = a.getLowLoc(); + temp.add(ChatColor.GREEN + "{" + ChatColor.YELLOW + "ID:" + ChatColor.RED + entry.getKey() + " " + ChatColor.YELLOW + "P1:" + ChatColor.RED + "(" + h.getBlockX() + "," + h.getBlockY() + "," + h.getBlockZ() + ") " + ChatColor.YELLOW + "P2:" + ChatColor.RED + "(" + l.getBlockX() + "," + l.getBlockY() + "," + l.getBlockZ() + ") " + ChatColor.YELLOW + "(Size:" + ChatColor.RED + a.getSize() + ChatColor.YELLOW + ")" + ChatColor.GREEN + "} "); + } + InformationPager.printInfo(player, Residence.getLanguage().getPhrase("PhysicalAreas"), temp, page); + } + + public String[] getAreaList() { + String arealist[] = new String[areas.size()]; + int i = 0; + for (Entry entry : areas.entrySet()) { + arealist[i] = entry.getKey(); + i++; + } + return arealist; + } + + public int getZoneDepth() { + int count = 0; + ClaimedResidence res = parent; + while (res != null) { + count++; + res = res.getParent(); + } + return count; + } + + public void setTpLoc(Player player, boolean resadmin) { + if (!this.perms.hasResidencePermission(player, false) && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + if (!this.containsLoc(player.getLocation())) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NotInResidence")); + return; + } + tpLoc = player.getLocation(); + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("SetTeleportLocation")); + } + + public void tpToResidence(Player reqPlayer, Player targetPlayer, boolean resadmin) { + if (!resadmin) { + PermissionGroup group = Residence.getPermissionManager().getGroup(reqPlayer); + if (!group.hasTpAccess()) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("TeleportDeny")); + return; + } + if (!reqPlayer.equals(targetPlayer)) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + if (!this.perms.playerHas(reqPlayer.getName(), "tp", true)) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("TeleportNoFlag")); + return; + } + } + if (tpLoc != null) { + ResidenceTPEvent tpevent = new ResidenceTPEvent(this, tpLoc, targetPlayer, reqPlayer); + Residence.getServ().getPluginManager().callEvent(tpevent); + if (!tpevent.isCancelled()) { + targetPlayer.teleport(tpLoc); + targetPlayer.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("TeleportSuccess")); + } + } else { + CuboidArea area = areas.values().iterator().next(); + if (area == null) { + reqPlayer.sendMessage(ChatColor.RED + "Could not find area to teleport to..."); + return; + } + Location targloc = this.getOutsideFreeLoc(area.getHighLoc()); + ResidenceTPEvent tpevent = new ResidenceTPEvent(this, targloc, targetPlayer, reqPlayer); + Residence.getServ().getPluginManager().callEvent(tpevent); + if (!tpevent.isCancelled()) { + targetPlayer.teleport(targloc); + targetPlayer.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("TeleportNear")); + } + } + } + + public String getAreaIDbyLoc(Location loc) { + for (Entry area : areas.entrySet()) { + if (area.getValue().containsLoc(loc)) + return area.getKey(); + } + return null; + } + + public void removeArea(String id) { + Residence.getResidenceManager().removeChunkList(getName()); + areas.remove(id); + Residence.getResidenceManager().calculateChunks(getName()); + } + + public void removeArea(Player player, String id, boolean resadmin) { + + if (this.getPermissions().hasResidencePermission(player, true) || resadmin) { + if (!areas.containsKey(id)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaNonExist")); + return; + } + if (areas.size() == 1 && !Residence.getConfigManager().allowEmptyResidences()) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaRemoveLast")); + return; + } + removeArea(id); + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("AreaRemove")); + } else { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + } + } + + public Map save() { + Map root = new HashMap(); + Map areamap = new HashMap(); + root.put("EnterMessage", enterMessage); + root.put("LeaveMessage", leaveMessage); + root.put("StoredMoney", bank.getStoredMoney()); + root.put("BlackList", blacklist.save()); + root.put("IgnoreList", ignorelist.save()); + for (Entry entry : areas.entrySet()) + { + areamap.put(entry.getKey(), entry.getValue().save()); + } + root.put("Areas", areamap); + Map subzonemap = new HashMap(); + for (Entry sz : subzones.entrySet()) + { + subzonemap.put(sz.getKey(), sz.getValue().save()); + } + root.put("Subzones", subzonemap); + root.put("Permissions", perms.save()); + if (tpLoc != null) + { + Map tpmap = new HashMap(); + tpmap.put("X", tpLoc.getBlockX()); + tpmap.put("Y", tpLoc.getBlockY()); + tpmap.put("Z", tpLoc.getBlockZ()); + root.put("TPLoc", tpmap); + } + return root; + } + + @SuppressWarnings("unchecked") + public static ClaimedResidence load(Map root, ClaimedResidence parent) throws Exception { + ClaimedResidence res = new ClaimedResidence(); + if (root == null) + throw new Exception("Null residence!"); + res.enterMessage = (String) root.get("EnterMessage"); + res.leaveMessage = (String) root.get("LeaveMessage"); + if (root.containsKey("StoredMoney")) + res.bank.setStoredMoney((Integer) root.get("StoredMoney")); + if (root.containsKey("BlackList")) + res.blacklist = ResidenceItemList.load(res, (Map) root.get("BlackList")); + if (root.containsKey("IgnoreList")) + res.ignorelist = ResidenceItemList.load(res, (Map) root.get("IgnoreList")); + Map areamap = (Map) root.get("Areas"); + res.perms = ResidencePermissions.load(res, + (Map) root.get("Permissions")); + World world = Residence.getServ().getWorld(res.perms.getWorld()); + if (world == null) + throw new Exception("Cant Find World: " + res.perms.getWorld()); + for (Entry map : areamap.entrySet()) { + res.areas.put(map.getKey(), CuboidArea.load((Map) map.getValue(), world)); + } + Map subzonemap = (Map) root.get("Subzones"); + for (Entry map : subzonemap.entrySet()) { + ClaimedResidence subres = ClaimedResidence.load((Map) map.getValue(), res); + if (Residence.getConfigManager().flagsInherit()) + subres.getPermissions().setParent(res.getPermissions()); + res.subzones.put(map.getKey(), subres); + } + res.parent = parent; + Map tploc = (Map) root.get("TPLoc"); + if (tploc != null) { + res.tpLoc = new Location(world, (Integer) tploc.get("X"), (Integer) tploc.get("Y"), (Integer) tploc.get("Z")); + } + return res; + } + + public int getAreaCount() + { + return areas.size(); + } + + public boolean renameSubzone(String oldName, String newName) + { + return this.renameSubzone(null, oldName, newName, true); + } + + public boolean renameSubzone(Player player, String oldName, String newName, boolean resadmin) + { + if (!Residence.validName(newName)) + { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidNameCharacters")); + return false; + } + ClaimedResidence res = subzones.get(oldName); + if (res == null) + { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidSubzone")); + return false; + } + if (player != null && !res.getPermissions().hasResidencePermission(player, true) && !resadmin) + { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return false; + } + if (subzones.containsKey(newName)) + { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("SubzoneExists", ChatColor.YELLOW + newName)); + return false; + } + subzones.put(newName, res); + subzones.remove(oldName); + if (player != null) + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("SubzoneRename", oldName + "." + newName)); + return true; + } + + public boolean renameArea(String oldName, String newName) + { + return this.renameArea(null, oldName, newName, true); + } + + public boolean renameArea(Player player, String oldName, String newName, boolean resadmin) + { + if (!Residence.validName(newName)) + { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidNameCharacters")); + return false; + } + if (player == null || perms.hasResidencePermission(player, true) || resadmin) + { + if (areas.containsKey(newName)) + { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaExists")); + return false; + } + CuboidArea area = areas.get(oldName); + if (area == null) + { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("AreaInvalidName")); + return false; + } + areas.put(newName, area); + areas.remove(oldName); + if (player != null) + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("AreaRename", oldName + "." + newName)); + return true; + } + else + { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return false; + } + } + + public CuboidArea getArea(String name) + { + return areas.get(name); + } + + public String getName() { + return Residence.getResidenceManager().getNameByRes(this); + } + + public void remove() { + String name = getName(); + if (name != null) { + Residence.getResidenceManager().removeResidence(name); + Residence.getResidenceManager().removeChunkList(name); + } + } + + public ResidenceBank getBank() + { + return bank; + } + + public String getWorld() + { + return perms.getWorld(); + } + + public String getOwner() + { + return perms.getOwner(); + } + + public ResidenceItemList getItemBlacklist() + { + return blacklist; + } + + public ResidenceItemList getItemIgnoreList() + { + return ignorelist; + } + + public ArrayList getPlayersInResidence() { + ArrayList within = new ArrayList(); + for (Player player : Bukkit.getServer().getOnlinePlayers()) { + if (this.containsLoc(player.getLocation())) { + within.add(player); + } + } + return within; + } +} diff --git a/src/com/bekvon/bukkit/residence/protection/CuboidArea.java b/src/com/bekvon/bukkit/residence/protection/CuboidArea.java new file mode 100644 index 0000000..06e7585 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/protection/CuboidArea.java @@ -0,0 +1,214 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.protection; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.protection.ResidenceManager.ChunkRef; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; + +/** + * + * @author Administrator + */ +public class CuboidArea { + protected Location highPoints; + protected Location lowPoints; + + protected CuboidArea() { + } + + public CuboidArea(Location startLoc, Location endLoc) { + int highx, highy, highz, lowx, lowy, lowz; + if (startLoc.getBlockX() > endLoc.getBlockX()) { + highx = startLoc.getBlockX(); + lowx = endLoc.getBlockX(); + } else { + highx = endLoc.getBlockX(); + lowx = startLoc.getBlockX(); + } + if (startLoc.getBlockY() > endLoc.getBlockY()) { + highy = startLoc.getBlockY(); + lowy = endLoc.getBlockY(); + } else { + highy = endLoc.getBlockY(); + lowy = startLoc.getBlockY(); + } + if (startLoc.getBlockZ() > endLoc.getBlockZ()) { + highz = startLoc.getBlockZ(); + lowz = endLoc.getBlockZ(); + } else { + highz = endLoc.getBlockZ(); + lowz = startLoc.getBlockZ(); + } + highPoints = new Location(startLoc.getWorld(), highx, highy, highz); + lowPoints = new Location(startLoc.getWorld(), lowx, lowy, lowz); + } + + public boolean isAreaWithinArea(CuboidArea area) { + return (this.containsLoc(area.highPoints) && this.containsLoc(area.lowPoints)); + } + + public boolean containsLoc(Location loc) { + if (loc == null) { + return false; + } + if (!loc.getWorld().equals(highPoints.getWorld())) { + return false; + } + if (lowPoints.getBlockX() <= loc.getBlockX() && highPoints.getBlockX() >= loc.getBlockX()) { + if (lowPoints.getBlockZ() <= loc.getBlockZ() && highPoints.getBlockZ() >= loc.getBlockZ()) { + if (lowPoints.getBlockY() <= loc.getBlockY() && highPoints.getBlockY() >= loc.getBlockY()) { + return true; + } + } + } + return false; + } + + public boolean checkCollision(CuboidArea area) { + if (!area.getWorld().equals(this.getWorld())) { + return false; + } + if (area.containsLoc(lowPoints) || area.containsLoc(highPoints) || this.containsLoc(area.highPoints) || this.containsLoc(area.lowPoints)) { + return true; + } + return advCuboidCheckCollision(highPoints, lowPoints, area.highPoints, area.lowPoints); + } + + private boolean advCuboidCheckCollision(Location A1High, Location A1Low, Location A2High, Location A2Low) { + int A1HX = A1High.getBlockX(); + int A1LX = A1Low.getBlockX(); + int A1HY = A1High.getBlockY(); + int A1LY = A1Low.getBlockY(); + int A1HZ = A1High.getBlockZ(); + int A1LZ = A1Low.getBlockZ(); + int A2HX = A2High.getBlockX(); + int A2LX = A2Low.getBlockX(); + int A2HY = A2High.getBlockY(); + int A2LY = A2Low.getBlockY(); + int A2HZ = A2High.getBlockZ(); + int A2LZ = A2Low.getBlockZ(); + if ((A1HX >= A2LX && A1HX <= A2HX) || (A1LX >= A2LX && A1LX <= A2HX) || (A2HX >= A1LX && A2HX <= A1HX) || (A2LX >= A1LX && A2LX <= A1HX)) { + if ((A1HY >= A2LY && A1HY <= A2HY) || (A1LY >= A2LY && A1LY <= A2HY) || (A2HY >= A1LY && A2HY <= A1HY) || (A2LY >= A1LY && A2LY <= A1HY)) { + if ((A1HZ >= A2LZ && A1HZ <= A2HZ) || (A1LZ >= A2LZ && A1LZ <= A2HZ) || (A2HZ >= A1LZ && A2HZ <= A1HZ) || (A2LZ >= A1LZ && A2LZ <= A1HZ)) { + return true; + } + } + } + return false; + } + + public long getSize() { + int xsize = (highPoints.getBlockX() - lowPoints.getBlockX()) + 1; + int ysize = (highPoints.getBlockY() - lowPoints.getBlockY()) + 1; + int zsize = (highPoints.getBlockZ() - lowPoints.getBlockZ()) + 1; + return xsize * ysize * zsize; + } + + public int getXSize() { + return (highPoints.getBlockX() - lowPoints.getBlockX()) + 1; + } + + public int getYSize() { + return (highPoints.getBlockY() - lowPoints.getBlockY()) + 1; + } + + public int getZSize() { + return (highPoints.getBlockZ() - lowPoints.getBlockZ()) + 1; + } + + public Location getHighLoc() { + return highPoints; + } + + public Location getLowLoc() { + return lowPoints; + } + + public World getWorld() { + return highPoints.getWorld(); + } + + public void save(DataOutputStream out, int version) throws IOException { + out.writeUTF(highPoints.getWorld().getName()); + out.writeInt(highPoints.getBlockX()); + out.writeInt(highPoints.getBlockY()); + out.writeInt(highPoints.getBlockZ()); + out.writeInt(lowPoints.getBlockX()); + out.writeInt(lowPoints.getBlockY()); + out.writeInt(lowPoints.getBlockZ()); + } + + public static CuboidArea load(DataInputStream in, int version) throws IOException { + CuboidArea newArea = new CuboidArea(); + Server server = Residence.getServ(); + World world = server.getWorld(in.readUTF()); + int highx = in.readInt(); + int highy = in.readInt(); + int highz = in.readInt(); + int lowx = in.readInt(); + int lowy = in.readInt(); + int lowz = in.readInt(); + newArea.highPoints = new Location(world, highx, highy, highz); + newArea.lowPoints = new Location(world, lowx, lowy, lowz); + return newArea; + } + + public Map save() { + Map root = new LinkedHashMap(); + root.put("X1", this.highPoints.getBlockX()); + root.put("Y1", this.highPoints.getBlockY()); + root.put("Z1", this.highPoints.getBlockZ()); + root.put("X2", this.lowPoints.getBlockX()); + root.put("Y2", this.lowPoints.getBlockY()); + root.put("Z2", this.lowPoints.getBlockZ()); + return root; + } + + public static CuboidArea load(Map root, World world) throws Exception { + if (root == null) { + throw new Exception("Invalid residence physical location..."); + } + CuboidArea newArea = new CuboidArea(); + int x1 = (Integer) root.get("X1"); + int y1 = (Integer) root.get("Y1"); + int z1 = (Integer) root.get("Z1"); + int x2 = (Integer) root.get("X2"); + int y2 = (Integer) root.get("Y2"); + int z2 = (Integer) root.get("Z2"); + newArea.highPoints = new Location(world, x1, y1, z1); + newArea.lowPoints = new Location(world, x2, y2, z2); + return newArea; + } + + public List getChunks() { + List chunks = new ArrayList(); + Location high = this.highPoints; + Location low = this.lowPoints; + int lowX = ChunkRef.getChunkCoord(low.getBlockX()); + int lowZ = ChunkRef.getChunkCoord(low.getBlockZ()); + int highX = ChunkRef.getChunkCoord(high.getBlockX()); + int highZ = ChunkRef.getChunkCoord(high.getBlockZ()); + + for (int x = lowX; x <= highX; x++) { + for (int z = lowZ; z <= highZ; z++) { + chunks.add(new ChunkRef(x, z)); + } + } + return chunks; + } +} diff --git a/src/com/bekvon/bukkit/residence/protection/FlagPermissions.java b/src/com/bekvon/bukkit/residence/protection/FlagPermissions.java new file mode 100644 index 0000000..62b44c7 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/protection/FlagPermissions.java @@ -0,0 +1,663 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.bekvon.bukkit.residence.protection; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +import com.bekvon.bukkit.residence.Residence; + +/** + * + * @author Administrator + */ +public class FlagPermissions { + + protected static ArrayList validFlags = new ArrayList(); + protected static ArrayList validPlayerFlags = new ArrayList(); + protected static ArrayList validAreaFlags = new ArrayList(); + final static Map matUseFlagList = new EnumMap( + Material.class); + protected Map> playerFlags; + protected Map> groupFlags; + protected Map cuboidFlags; + protected FlagPermissions parent; + + public static void addMaterialToUseFlag(Material mat, String flag) { + matUseFlagList.put(mat, flag); + } + + public static void removeMaterialFromUseFlag(Material mat) { + matUseFlagList.remove(mat); + } + + public static EnumMap getMaterialUseFlagList() { + return (EnumMap) matUseFlagList; + } + + public static void addFlag(String flag) { + flag = flag.toLowerCase(); + if (!validFlags.contains(flag)) { + validFlags.add(flag); + } + if (validFlagGroups.containsKey(flag)) { + validFlagGroups.remove(flag); + } + } + + public static void addPlayerOrGroupOnlyFlag(String flag) { + flag = flag.toLowerCase(); + if (!validPlayerFlags.contains(flag)) { + validPlayerFlags.add(flag); + } + if (validFlagGroups.containsKey(flag)) { + validFlagGroups.remove(flag); + } + } + + public static void addResidenceOnlyFlag(String flag) { + flag = flag.toLowerCase(); + if (!validAreaFlags.contains(flag)) { + validAreaFlags.add(flag); + } + if (validFlagGroups.containsKey(flag)) { + validFlagGroups.remove(flag); + } + } + + protected static HashMap> validFlagGroups = new HashMap>(); + + public static void addFlagToFlagGroup(String group, String flag) { + if (!FlagPermissions.validFlags.contains(group) + && !FlagPermissions.validAreaFlags.contains(group) + && !FlagPermissions.validPlayerFlags.contains(group)) { + if (!validFlagGroups.containsKey(group)) { + validFlagGroups.put(group, new ArrayList()); + } + ArrayList flags = validFlagGroups.get(group); + flags.add(flag); + } + } + + public static void removeFlagFromFlagGroup(String group, String flag) { + if (validFlagGroups.containsKey(group)) { + ArrayList flags = validFlagGroups.get(group); + flags.remove(flag); + if (flags.isEmpty()) { + validFlagGroups.remove(group); + } + } + } + + public static boolean flagGroupExists(String group) { + return validFlagGroups.containsKey(group); + } + + public static void initValidFlags() { + validAreaFlags.clear(); + validPlayerFlags.clear(); + validFlags.clear(); + validFlagGroups.clear(); + addFlag("egg"); + addFlag("note"); + addFlag("pressure"); + addFlag("cake"); + addFlag("lever"); + addFlag("door"); + addFlag("button"); + addFlag("table"); + addFlag("brew"); + addFlag("bed"); + addFlag("commandblock"); + addFlag("anvil"); + addFlag("flowerpot"); + addFlag("enchant"); + addFlag("diode"); + addFlag("use"); + addFlag("move"); + addFlag("build"); + addFlag("tp"); + addFlag("ignite"); + addFlag("container"); + addFlag("subzone"); + addFlag("destroy"); + addFlag("place"); + addFlag("bucket"); + addFlag("bank"); + addFlag("beacon"); + + /* New flags */ + addFlag("animalkilling"); + addFlag("trade"); + + addResidenceOnlyFlag("trample"); + addResidenceOnlyFlag("pvp"); + addResidenceOnlyFlag("fireball"); + addResidenceOnlyFlag("explode"); + addResidenceOnlyFlag("damage"); + addResidenceOnlyFlag("monsters"); + addResidenceOnlyFlag("firespread"); + addResidenceOnlyFlag("burn"); + addResidenceOnlyFlag("tnt"); + addResidenceOnlyFlag("creeper"); + addResidenceOnlyFlag("wither"); + addResidenceOnlyFlag("flow"); + addResidenceOnlyFlag("healing"); + addResidenceOnlyFlag("animals"); + addResidenceOnlyFlag("lavaflow"); + addResidenceOnlyFlag("waterflow"); + addResidenceOnlyFlag("physics"); + addResidenceOnlyFlag("piston"); + addResidenceOnlyFlag("spread"); + addResidenceOnlyFlag("hidden"); + addResidenceOnlyFlag("witherdamage"); + addPlayerOrGroupOnlyFlag("admin"); + addFlagToFlagGroup("redstone", "note"); + addFlagToFlagGroup("redstone", "pressure"); + addFlagToFlagGroup("redstone", "lever"); + addFlagToFlagGroup("redstone", "button"); + addFlagToFlagGroup("redstone", "diode"); + addFlagToFlagGroup("craft", "brew"); + addFlagToFlagGroup("craft", "table"); + addFlagToFlagGroup("craft", "enchant"); + addFlagToFlagGroup("trusted", "use"); + addFlagToFlagGroup("trusted", "tp"); + addFlagToFlagGroup("trusted", "build"); + addFlagToFlagGroup("trusted", "container"); + addFlagToFlagGroup("trusted", "bucket"); + addFlagToFlagGroup("trusted", "move"); + addFlagToFlagGroup("fire", "ignite"); + addFlagToFlagGroup("fire", "firespread"); + addMaterialToUseFlag(Material.DIODE, "diode"); + addMaterialToUseFlag(Material.DIODE_BLOCK_OFF, "diode"); + addMaterialToUseFlag(Material.DIODE_BLOCK_ON, "diode"); + addMaterialToUseFlag(Material.WORKBENCH, "table"); + addMaterialToUseFlag(Material.WOODEN_DOOR, "door"); + /* 1.8 Doors */ + addMaterialToUseFlag(Material.SPRUCE_DOOR, "door"); + addMaterialToUseFlag(Material.BIRCH_DOOR, "door"); + addMaterialToUseFlag(Material.JUNGLE_DOOR, "door"); + addMaterialToUseFlag(Material.ACACIA_DOOR, "door"); + addMaterialToUseFlag(Material.DARK_OAK_DOOR, "door"); + + /* 1.8 Fence Gates */ + addMaterialToUseFlag(Material.SPRUCE_FENCE_GATE, "door"); + addMaterialToUseFlag(Material.BIRCH_FENCE_GATE, "door"); + addMaterialToUseFlag(Material.JUNGLE_FENCE_GATE, "door"); + addMaterialToUseFlag(Material.ACACIA_FENCE_GATE, "door"); + addMaterialToUseFlag(Material.DARK_OAK_FENCE_GATE, "door"); + + addMaterialToUseFlag(Material.FENCE_GATE, "door"); + addMaterialToUseFlag(Material.NETHER_FENCE, "door"); + addMaterialToUseFlag(Material.TRAP_DOOR, "door"); + addMaterialToUseFlag(Material.ENCHANTMENT_TABLE, "enchant"); + addMaterialToUseFlag(Material.STONE_BUTTON, "button"); + addMaterialToUseFlag(Material.LEVER, "lever"); + addMaterialToUseFlag(Material.BED_BLOCK, "bed"); + addMaterialToUseFlag(Material.BREWING_STAND, "brew"); + addMaterialToUseFlag(Material.CAKE, "cake"); + addMaterialToUseFlag(Material.NOTE_BLOCK, "note"); + addMaterialToUseFlag(Material.DRAGON_EGG, "egg"); + addMaterialToUseFlag(Material.COMMAND, "commandblock"); + addMaterialToUseFlag(Material.WOOD_BUTTON, "button"); + addMaterialToUseFlag(Material.ANVIL, "anvil"); + addMaterialToUseFlag(Material.FLOWER_POT, "flowerpot"); + addMaterialToUseFlag(Material.BEACON, "beacon"); + addMaterialToUseFlag(Material.JUKEBOX, "container"); + addMaterialToUseFlag(Material.CHEST, "container"); + addMaterialToUseFlag(Material.TRAPPED_CHEST, "container"); + addMaterialToUseFlag(Material.HOPPER, "container"); + addMaterialToUseFlag(Material.DROPPER, "container"); + addMaterialToUseFlag(Material.FURNACE, "container"); + addMaterialToUseFlag(Material.BURNING_FURNACE, "container"); + addMaterialToUseFlag(Material.DISPENSER, "container"); + addMaterialToUseFlag(Material.CAKE_BLOCK, "cake"); + } + + public static FlagPermissions parseFromConfigNode(String name, + ConfigurationSection node) { + FlagPermissions list = new FlagPermissions(); + Set keys = node.getConfigurationSection(name).getKeys(false); + if (keys != null) { + for (String key : keys) { + boolean state = node.getBoolean(name + "." + key, false); + key = key.toLowerCase(); + if (state) { + list.setFlag(key, FlagState.TRUE); + } else { + list.setFlag(key, FlagState.FALSE); + } + } + } + return list; + } + + public FlagPermissions() { + cuboidFlags = Collections + .synchronizedMap(new HashMap()); + playerFlags = Collections + .synchronizedMap(new HashMap>()); + groupFlags = Collections + .synchronizedMap(new HashMap>()); + } + + public boolean setPlayerFlag(String player, String flag, FlagState state) { + player = player.toLowerCase(); + if (!playerFlags.containsKey(player)) { + playerFlags + .put(player, Collections + .synchronizedMap(new HashMap())); + } + Map map = playerFlags.get(player); + if (state == FlagState.FALSE) { + map.put(flag, false); + } else if (state == FlagState.TRUE) { + map.put(flag, true); + } else if (state == FlagState.NEITHER) { + if (map.containsKey(flag)) { + map.remove(flag); + } + } + if (map.isEmpty()) { + playerFlags.remove(player); + } + return true; + } + + public void removeAllPlayerFlags(String player) { + playerFlags.remove(player); + } + + public void removeAllGroupFlags(String group) { + groupFlags.remove(group); + } + + public boolean setGroupFlag(String group, String flag, FlagState state) { + group = group.toLowerCase(); + if (!groupFlags.containsKey(group)) { + groupFlags + .put(group, Collections + .synchronizedMap(new HashMap())); + } + Map map = groupFlags.get(group); + if (state == FlagState.FALSE) { + map.put(flag, false); + } else if (state == FlagState.TRUE) { + map.put(flag, true); + } else if (state == FlagState.NEITHER) { + if (map.containsKey(flag)) { + map.remove(flag); + } + } + if (map.isEmpty()) { + groupFlags.remove(group); + } + return true; + } + + public boolean setFlag(String flag, FlagState state) { + if (state == FlagState.FALSE) { + cuboidFlags.put(flag, false); + } else if (state == FlagState.TRUE) { + cuboidFlags.put(flag, true); + } else if (state == FlagState.NEITHER) { + if (cuboidFlags.containsKey(flag)) { + cuboidFlags.remove(flag); + } + } + return true; + } + + public static enum FlagState { + + TRUE, FALSE, NEITHER, INVALID + } + + public static FlagState stringToFlagState(String flagstate) { + if (flagstate.equalsIgnoreCase("true") + || flagstate.equalsIgnoreCase("t")) { + return FlagState.TRUE; + } else if (flagstate.equalsIgnoreCase("false") + || flagstate.equalsIgnoreCase("f")) { + return FlagState.FALSE; + } else if (flagstate.equalsIgnoreCase("remove") + || flagstate.equalsIgnoreCase("r")) { + return FlagState.NEITHER; + } else { + return FlagState.INVALID; + } + } + + public boolean playerHas(String player, String world, String flag, + boolean def) { + String group = Residence.getPermissionManager().getGroupNameByPlayer( + player, world); + return this.playerCheck(player, flag, + this.groupCheck(group, flag, this.has(flag, def))); + } + + public boolean groupHas(String group, String flag, boolean def) { + return this.groupCheck(group, flag, this.has(flag, def)); + } + + private boolean playerCheck(String player, String flag, boolean def) { + player = player.toLowerCase(); + if (playerFlags.containsKey(player)) { + Map pmap = playerFlags.get(player); + if (pmap.containsKey(flag)) { + return pmap.get(flag); + } + } + if (parent != null) { + return parent.playerCheck(player, flag, def); + } + return def; + } + + private boolean groupCheck(String group, String flag, boolean def) { + if (groupFlags.containsKey(group)) { + Map gmap = groupFlags.get(group); + if (gmap.containsKey(flag)) { + return gmap.get(flag); + } + } + if (parent != null) { + return parent.groupCheck(group, flag, def); + } + return def; + } + + public boolean has(String flag, boolean def) { + if (cuboidFlags.containsKey(flag)) { + return cuboidFlags.get(flag); + } + if (parent != null) { + return parent.has(flag, def); + } + return def; + } + + public boolean isPlayerSet(String player, String flag) { + player = player.toLowerCase(); + Map flags = playerFlags.get(player); + if (flags == null) { + return false; + } + return flags.containsKey(flag); + } + + public boolean inheritanceIsPlayerSet(String player, String flag) { + player = player.toLowerCase(); + Map flags = playerFlags.get(player); + if (flags == null) { + return parent == null ? false : parent.inheritanceIsPlayerSet( + player, flag); + } + return flags.containsKey(flag) ? true : parent == null ? false : parent + .inheritanceIsPlayerSet(player, flag); + } + + public boolean isGroupSet(String group, String flag) { + group = group.toLowerCase(); + Map flags = groupFlags.get(group); + if (flags == null) { + return false; + } + return flags.containsKey(flag); + } + + public boolean inheritanceIsGroupSet(String group, String flag) { + group = group.toLowerCase(); + Map flags = groupFlags.get(group); + if (flags == null) { + return parent == null ? false : parent.inheritanceIsGroupSet(group, + flag); + } + return flags.containsKey(flag) ? true : parent == null ? false : parent + .inheritanceIsGroupSet(group, flag); + } + + public boolean isSet(String flag) { + return cuboidFlags.containsKey(flag); + } + + public boolean inheritanceIsSet(String flag) { + return cuboidFlags.containsKey(flag) ? true : parent == null ? false + : parent.inheritanceIsSet(flag); + } + + public boolean checkValidFlag(String flag, boolean globalflag) { + if (validFlags.contains(flag)) { + return true; + } + if (globalflag) { + if (validAreaFlags.contains(flag)) { + return true; + } + } else { + if (validPlayerFlags.contains(flag)) { + return true; + } + } + return false; + } + + public Map save() { + Map root = new LinkedHashMap(); + root.put("PlayerFlags", playerFlags); + root.put("GroupFlags", groupFlags); + root.put("AreaFlags", cuboidFlags); + return root; + } + + public static FlagPermissions load(Map root) + throws Exception { + FlagPermissions newperms = new FlagPermissions(); + return FlagPermissions.load(root, newperms); + } + + @SuppressWarnings("unchecked") + protected static FlagPermissions load(Map root, + FlagPermissions newperms) throws Exception { + newperms.playerFlags = (Map>) root + .get("PlayerFlags"); + newperms.groupFlags = (Map>) root + .get("GroupFlags"); + newperms.cuboidFlags = (Map) root.get("AreaFlags"); + return newperms; + } + + public String listFlags() { + StringBuilder sbuild = new StringBuilder(); + Set> set = cuboidFlags.entrySet(); + synchronized (cuboidFlags) { + Iterator> it = set.iterator(); + while (it.hasNext()) { + Entry next = it.next(); + if (next.getValue()) { + sbuild.append("+").append(next.getKey()); + if (it.hasNext()) { + sbuild.append(" "); + } + } else { + sbuild.append("-").append(next.getKey()); + if (it.hasNext()) { + sbuild.append(" "); + } + } + } + } + if (sbuild.length() == 0) { + sbuild.append("none"); + } + return sbuild.toString(); + } + + public String listPlayerFlags(String player) { + player = player.toLowerCase(); + if (playerFlags.containsKey(player)) { + StringBuilder sbuild = new StringBuilder(); + Map get = playerFlags.get(player); + Set> set = get.entrySet(); + synchronized (get) { + Iterator> it = set.iterator(); + while (it.hasNext()) { + Entry next = it.next(); + if (next.getValue()) { + sbuild.append("+").append(next.getKey()); + if (it.hasNext()) { + sbuild.append(" "); + } + } else { + sbuild.append("-").append(next.getKey()); + if (it.hasNext()) { + sbuild.append(" "); + } + } + } + } + if (sbuild.length() == 0) { + playerFlags.remove(player); + sbuild.append("none"); + } + return sbuild.toString(); + } else { + return "none"; + } + } + + public String listOtherPlayersFlags(String player) { + player = player.toLowerCase(); + StringBuilder sbuild = new StringBuilder(); + Set set = playerFlags.keySet(); + synchronized (playerFlags) { + Iterator it = set.iterator(); + while (it.hasNext()) { + String next = it.next(); + if (!next.equals(player)) { + String perms = listPlayerFlags(next); + if (!perms.equals("none")) { + sbuild.append(next).append("[" + ChatColor.DARK_AQUA) + .append(perms).append(ChatColor.RED + "] "); + } + } + } + } + return sbuild.toString(); + } + + public String listGroupFlags() { + StringBuilder sbuild = new StringBuilder(); + Set set = groupFlags.keySet(); + synchronized (groupFlags) { + Iterator it = set.iterator(); + while (it.hasNext()) { + String next = it.next(); + String perms = listGroupFlags(next); + if (!perms.equals("none")) { + sbuild.append(next).append("[" + ChatColor.DARK_AQUA) + .append(perms).append(ChatColor.RED + "] "); + } + } + } + return sbuild.toString(); + } + + public String listGroupFlags(String group) { + group = group.toLowerCase(); + if (groupFlags.containsKey(group)) { + StringBuilder sbuild = new StringBuilder(); + Map get = groupFlags.get(group); + Set> set = get.entrySet(); + synchronized (get) { + Iterator> it = set.iterator(); + while (it.hasNext()) { + Entry next = it.next(); + if (next.getValue()) { + sbuild.append("+").append(next.getKey()); + if (it.hasNext()) { + sbuild.append(" "); + } + } else { + sbuild.append("-").append(next.getKey()); + if (it.hasNext()) { + sbuild.append(" "); + } + } + } + } + if (sbuild.length() == 0) { + groupFlags.remove(group); + sbuild.append("none"); + } + return sbuild.toString(); + } else { + return "none"; + } + } + + public void clearFlags() { + groupFlags.clear(); + playerFlags.clear(); + cuboidFlags.clear(); + } + + public void printFlags(Player player) { + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Flags") + ":" + + ChatColor.BLUE + " " + listFlags()); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Your.Flags") + ":" + + ChatColor.GREEN + " " + listPlayerFlags(player.getName())); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Group.Flags") + ":" + + ChatColor.RED + " " + listGroupFlags()); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Others.Flags") + ":" + + ChatColor.RED + " " + listOtherPlayersFlags(player.getName())); + } + + public void copyUserPermissions(String fromUser, String toUser) { + fromUser = fromUser.toLowerCase(); + toUser = toUser.toLowerCase(); + Map get = playerFlags.get(fromUser); + if (get != null) { + Map targ = playerFlags.get(toUser); + if (targ == null) { + targ = new HashMap(); + playerFlags.put(toUser, targ); + } + for (Entry entry : get.entrySet()) { + targ.put(entry.getKey(), entry.getValue()); + } + } + } + + public void clearPlayersFlags(String user) { + if (playerFlags.containsKey(user)) { + playerFlags.remove(user); + } + } + + public void setParent(FlagPermissions p) { + parent = p; + } + + public FlagPermissions getParent() { + return parent; + } +} diff --git a/src/com/bekvon/bukkit/residence/protection/LeaseManager.java b/src/com/bekvon/bukkit/residence/protection/LeaseManager.java new file mode 100644 index 0000000..84b539b --- /dev/null +++ b/src/com/bekvon/bukkit/residence/protection/LeaseManager.java @@ -0,0 +1,280 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.protection; + +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.economy.EconomyInterface; +import com.bekvon.bukkit.residence.event.ResidenceDeleteEvent; +import com.bekvon.bukkit.residence.event.ResidenceDeleteEvent.DeleteCause; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; + +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class LeaseManager { + + private Map leaseExpireTime; + + ResidenceManager manager; + + public LeaseManager(ResidenceManager m) { + manager = m; + leaseExpireTime = Collections + .synchronizedMap(new HashMap()); + } + + public boolean leaseExpires(String area) { + return leaseExpireTime.containsKey(area); + } + + public Date getExpireTime(String area) { + if (leaseExpireTime.containsKey(area)) { + return new Date(leaseExpireTime.get(area)); + } + return null; + } + + public void removeExpireTime(String area) { + leaseExpireTime.remove(area); + } + + public void setExpireTime(String area, int days) { + this.setExpireTime(null, area, days); + } + + public void setExpireTime(Player player, String area, int days) { + area = area.replace(".", "_"); + if (manager.getByName(area) != null) { + leaseExpireTime.put(area, + daysToMs(days) + System.currentTimeMillis()); + if (player != null) + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase("LeaseRenew", + getExpireTime(area).toString())); + } else { + if (player != null) + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("InvalidArea")); + } + } + + public void renewArea(String area, Player player) { + if (!leaseExpires(area)) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("LeaseNotExpire")); + return; + } + PermissionGroup limits = Residence.getPermissionManager().getGroup( + player); + int max = limits.getMaxLeaseTime(); + int add = limits.getLeaseGiveTime(); + int rem = daysRemaining(area); + EconomyInterface econ = Residence.getEconomyManager(); + if (econ != null) { + double cost = limits.getLeaseRenewCost(); + ClaimedResidence res = manager.getByName(area); + int amount = (int) Math.ceil((double) res.getTotalSize() * cost); + if (cost != 0D) { + // Account account = + // iConomy.getBank().getAccount(player.getName()); + if (econ.canAfford(player.getName(), amount)/* + * account.hasEnough( + * amount) + */) { + econ.subtract(player.getName(), amount); + econ.add("Lease Money", amount); + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase( + "MoneyCharged", + ChatColor.YELLOW + + String.format("%d", amount) + + ChatColor.GREEN + "." + + ChatColor.YELLOW + econ.getName() + + ChatColor.GREEN)); + } else { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase( + "NotEnoughMoney")); + return; + } + } + } + if (rem + add > max) { + setExpireTime(player, area, max); + player.sendMessage(ChatColor.GOLD + + Residence.getLanguage().getPhrase("LeaseRenewMax")); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("LeaseRenew", + ChatColor.GREEN + "" + getExpireTime(area)) + + ChatColor.YELLOW); + return; + } + Long get = leaseExpireTime.get(area); + if (get != null) { + get = get + daysToMs(add); + leaseExpireTime.put(area, get); + } else + leaseExpireTime.put(area, daysToMs(add)); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("LeaseRenew", + ChatColor.GREEN + "" + getExpireTime(area))); + } + + public int getRenewCost(ClaimedResidence res) { + PermissionGroup limits = Residence.getPermissionManager().getGroup( + res.getPermissions().getOwner(), + res.getPermissions().getWorld()); + double cost = limits.getLeaseRenewCost(); + int amount = (int) Math.ceil((double) res.getTotalSize() * cost); + return amount; + } + + private long daysToMs(int days) { + return (((long) days) * 24L * 60L * 60L * 1000L); + } + + private int msToDays(long ms) { + return (int) Math.ceil(((((double) ms / 1000D) / 60D) / 60D) / 24D); + } + + private int daysRemaining(String area) { + Long get = leaseExpireTime.get(area); + if (get <= System.currentTimeMillis()) + return 0; + return msToDays((int) (get - System.currentTimeMillis())); + } + + public void doExpirations() { + Set> set = leaseExpireTime.entrySet(); + Iterator> it = set.iterator(); + while (it.hasNext()) { + Entry next = it.next(); + if (next.getValue() <= System.currentTimeMillis()) { + String resname = next.getKey(); + ClaimedResidence res = Residence.getResidenceManager() + .getByName(resname); + if (res == null) { + it.remove(); + } else { + boolean renewed = false; + String owner = res.getPermissions().getOwner(); + PermissionGroup limits = Residence.getPermissionManager() + .getGroup(owner, res.getPermissions().getWorld()); + int cost = this.getRenewCost(res); + if (Residence.getConfigManager().enableEconomy() + && Residence.getConfigManager().autoRenewLeases()) { + if (cost == 0) { + renewed = true; + } else if (res.getBank().hasEnough(cost)) { + res.getBank().subtract(cost); + renewed = true; + if (Residence.getConfigManager().debugEnabled()) + System.out + .println("Lease Renewed From Residence Bank: " + + resname); + } else if (Residence.getEconomyManager().canAfford( + owner, cost)) { + if (Residence.getEconomyManager().subtract(owner, + cost)) { + renewed = true; + if (Residence.getConfigManager().debugEnabled()) + System.out + .println("Lease Renewed From Economy: " + + resname); + } + } + } + if (!renewed) { + if (!Residence.getConfigManager().enabledRentSystem() + || !Residence.getRentManager() + .isRented(resname)) { + ResidenceDeleteEvent resevent = new ResidenceDeleteEvent( + null, res, DeleteCause.LEASE_EXPIRE); + Residence.getServ().getPluginManager() + .callEvent(resevent); + if (!resevent.isCancelled()) { + manager.removeResidence(next.getKey()); + it.remove(); + if (Residence.getConfigManager().debugEnabled()) + System.out + .println("Lease NOT removed, Removing: " + + resname); + } + } + } else { + if (Residence.getConfigManager().enableEconomy() + && Residence.getConfigManager() + .enableLeaseMoneyAccount()) { + Residence.getEconomyManager().add("Lease Money", + cost); + } + if (Residence.getConfigManager().debugEnabled()) + System.out.println("Lease Renew Old: " + + next.getValue()); + next.setValue(System.currentTimeMillis() + + daysToMs(limits.getLeaseGiveTime())); + if (Residence.getConfigManager().debugEnabled()) + System.out.println("Lease Renew New: " + + next.getValue()); + } + } + } + } + } + + public void resetLeases() { + leaseExpireTime.clear(); + String[] list = manager.getResidenceList(); + for (int i = 0; i < list.length; i++) { + if (list[i] != null) { + ClaimedResidence res = Residence.getResidenceManager() + .getByName(list[i]); + PermissionGroup group = Residence.getPermissionManager() + .getGroup(res.getPermissions().getOwner(), + res.getPermissions().getWorld()); + this.setExpireTime(null, list[i], group.getLeaseGiveTime()); + } + } + System.out.println("[Residence] - Set default leases."); + } + + public Map save() { + return leaseExpireTime; + } + + public void updateLeaseName(String oldName, String newName) { + if (leaseExpireTime.containsKey(oldName)) { + leaseExpireTime.put(newName, leaseExpireTime.get(oldName)); + leaseExpireTime.remove(oldName); + } + } + + public static LeaseManager load(Map root, ResidenceManager m) { + LeaseManager l = new LeaseManager(m); + if (root != null) { + for (Object val : root.values()) { + if (!(val instanceof Long)) { + root.remove(val); + } + } + l.leaseExpireTime = Collections.synchronizedMap(root); + } + return l; + } +} diff --git a/src/com/bekvon/bukkit/residence/protection/PermissionListManager.java b/src/com/bekvon/bukkit/residence/protection/PermissionListManager.java new file mode 100644 index 0000000..0fd5bdd --- /dev/null +++ b/src/com/bekvon/bukkit/residence/protection/PermissionListManager.java @@ -0,0 +1,162 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.protection; + +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class PermissionListManager { + + private Map> lists; + + public PermissionListManager() { + lists = Collections + .synchronizedMap(new HashMap>()); + } + + public FlagPermissions getList(String player, String listname) { + Map get = lists.get(player); + if (get == null) { + return null; + } + return get.get(listname); + } + + public void makeList(Player player, String listname) { + Map get = lists.get(player.getName()); + if (get == null) { + get = new HashMap(); + lists.put(player.getName(), get); + } + FlagPermissions perms = get.get(listname); + if (perms == null) { + perms = new FlagPermissions(); + get.put(listname, perms); + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase("ListCreate", listname)); + } else { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("ListExists")); + } + } + + public void removeList(Player player, String listname) { + Map get = lists.get(player.getName()); + if (get == null) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("InvalidList")); + return; + } + FlagPermissions list = get.get(listname); + if (list == null) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("InvalidList")); + return; + } + get.remove(listname); + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("ListRemoved")); + } + + public void applyListToResidence(Player player, String listname, + String areaname, boolean resadmin) { + FlagPermissions list = this.getList(player.getName(), listname); + if (list == null) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("InvalidList")); + return; + } + ClaimedResidence res = Residence.getResidenceManager().getByName( + areaname); + if (res == null) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("InvalidResidence")); + return; + } + res.getPermissions().applyTemplate(player, list, resadmin); + } + + public void printList(Player player, String listname) { + FlagPermissions list = this.getList(player.getName(), listname); + if (list == null) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("InvalidList")); + return; + } + player.sendMessage(ChatColor.LIGHT_PURPLE + + "------Permission Template------"); + player.sendMessage(Residence.getLanguage().getPhrase("Name") + ": " + + ChatColor.GREEN + listname); + list.printFlags(player); + } + + public Map save() { + Map root = new LinkedHashMap(); + for (Entry> players : lists + .entrySet()) { + Map saveMap = new LinkedHashMap(); + Map map = players.getValue(); + for (Entry list : map.entrySet()) { + saveMap.put(list.getKey(), list.getValue().save()); + } + root.put(players.getKey(), saveMap); + } + return root; + } + + @SuppressWarnings("unchecked") + public static PermissionListManager load(Map root) { + + PermissionListManager p = new PermissionListManager(); + if (root != null) { + for (Entry players : root.entrySet()) { + try { + Map value = (Map) players + .getValue(); + Map loadedMap = Collections + .synchronizedMap(new HashMap()); + for (Entry list : value.entrySet()) { + loadedMap.put(list.getKey(), FlagPermissions + .load((Map) list.getValue())); + } + p.lists.put(players.getKey(), loadedMap); + } catch (Exception ex) { + System.out + .println("[Residence] - Failed to load permission lists for player: " + + players.getKey()); + } + } + } + return p; + } + + public void printLists(Player player) { + StringBuilder sbuild = new StringBuilder(); + Map get = lists.get(player.getName()); + sbuild.append(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Lists") + ":" + + ChatColor.DARK_AQUA + " "); + if (get != null) { + for (Entry thislist : get.entrySet()) { + sbuild.append(thislist.getKey()).append(" "); + } + } + player.sendMessage(sbuild.toString()); + } +} diff --git a/src/com/bekvon/bukkit/residence/protection/ResidenceManager.java b/src/com/bekvon/bukkit/residence/protection/ResidenceManager.java new file mode 100644 index 0000000..a41e497 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/protection/ResidenceManager.java @@ -0,0 +1,726 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.protection; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.event.ResidenceCreationEvent; +import com.bekvon.bukkit.residence.event.ResidenceDeleteEvent; +import com.bekvon.bukkit.residence.event.ResidenceDeleteEvent.DeleteCause; +import com.bekvon.bukkit.residence.event.ResidenceRenameEvent; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; +import com.bekvon.bukkit.residence.text.help.InformationPager; + +/** + * + * @author Administrator + */ +public class ResidenceManager { + protected Map residences; + protected Map>> chunkResidences; + + public ResidenceManager() { + residences = new HashMap(); + chunkResidences = new HashMap>>(); + } + + public ClaimedResidence getByLoc(Location loc) { + if (loc == null) { + return null; + } + ClaimedResidence res = null; + boolean found = false; + String world = loc.getWorld().getName(); + ChunkRef chunk = new ChunkRef( loc ); + if (chunkResidences.get(world) != null) { + if (chunkResidences.get(world).get(chunk) != null) { + for (String key : chunkResidences.get(world).get(chunk)) { + ClaimedResidence entry = residences.get(key); + if (entry.containsLoc(loc)) { + res = entry; + found = true; + break; + } + } + } + } + if (!found) { + return null; + } + ClaimedResidence subres = res.getSubzoneByLoc(loc); + if (subres == null) { + return res; + } + return subres; + } + + public ClaimedResidence getByName(String name) { + if (name == null) { + return null; + } + String[] split = name.split("\\."); + if (split.length == 1) { + return residences.get(name); + } + ClaimedResidence res = residences.get(split[0]); + for (int i = 1; i < split.length; i++) { + if (res != null) { + res = res.getSubzone(split[i]); + } else { + return null; + } + } + return res; + } + + public String getNameByLoc(Location loc) { + if (loc == null) { + return null; + } + ClaimedResidence res = null; + String name = null; + boolean found = false; + String world = loc.getWorld().getName(); + ChunkRef chunk = new ChunkRef( loc ); + if (chunkResidences.get(world) != null) { + if (chunkResidences.get(world).get(chunk) != null) { + for (String key : chunkResidences.get(world).get(chunk)) { + ClaimedResidence entry = residences.get(key); + if (entry.containsLoc(loc)) { + res = entry; + found = true; + break; + } + } + } + } + if (!found) { + return null; + } + name = res.getName(); + if (name == null) + return null; + String szname = res.getSubzoneNameByLoc(loc); + if (szname != null) { + return name + "." + szname; + } + return name; + } + + public String getNameByRes(ClaimedResidence res) { + Set> set = residences.entrySet(); + for (Entry check : set) { + if (check.getValue() == res) { + return check.getKey(); + } + String n = check.getValue().getSubzoneNameByRes(res); + if (n != null) { + return check.getKey() + "." + n; + } + } + return null; + } + + public boolean addResidence(String name, Location loc1, Location loc2) { + return this.addResidence(name, "Server Land", loc1, loc2); + } + + public boolean addResidence(String name, String owner, Location loc1, Location loc2) { + return this.addResidence(null, owner, name, loc1, loc2, true); + } + + public boolean addResidence(Player player, String name, Location loc1, Location loc2, boolean resadmin) { + return this.addResidence(player, player.getName(), name, loc1, loc2, resadmin); + } + + public boolean addResidence(Player player, String owner, String name, Location loc1, Location loc2, boolean resadmin) { + if (!Residence.validName(name)) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidNameCharacters")); + } + return false; + } + if (loc1 == null || loc2 == null || !loc1.getWorld().getName().equals(loc2.getWorld().getName())) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("SelectPoints")); + } + return false; + } + PermissionGroup group = Residence.getPermissionManager().getGroup(owner, loc1.getWorld().getName()); + boolean createpermission = group.canCreateResidences() || (player == null ? true : player.hasPermission("residence.create")); + if (!createpermission && !resadmin) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + } + return false; + } + if (player != null) { + if (getOwnedZoneCount(player.getName()) >= group.getMaxZones() && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ResidenceTooMany")); + return false; + } + } + CuboidArea newArea = new CuboidArea(loc1, loc2); + ClaimedResidence newRes = new ClaimedResidence(owner, loc1.getWorld().getName()); + newRes.getPermissions().applyDefaultFlags(); + newRes.setEnterMessage(group.getDefaultEnterMessage()); + newRes.setLeaveMessage(group.getDefaultLeaveMessage()); + + ResidenceCreationEvent resevent = new ResidenceCreationEvent(player, name, newRes, newArea); + Residence.getServ().getPluginManager().callEvent(resevent); + if (resevent.isCancelled()) { + return false; + } + newArea = resevent.getPhysicalArea(); + name = resevent.getResidenceName(); + if (residences.containsKey(name)) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ResidenceAlreadyExists", ChatColor.YELLOW + name + ChatColor.RED)); + } + return false; + } + if (player != null) { + newRes.addArea(player, newArea, "main", resadmin); + } else { + newRes.addArea(newArea, "main"); + } + if (newRes.getAreaCount() != 0) { + residences.put(name, newRes); + calculateChunks(name); + Residence.getLeaseManager().removeExpireTime(name); + if (player != null) { + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("ResidenceCreate", ChatColor.YELLOW + name + ChatColor.GREEN)); + } + if (Residence.getConfigManager().useLeases()) { + if (player != null) { + Residence.getLeaseManager().setExpireTime(player, name, group.getLeaseGiveTime()); + } else { + Residence.getLeaseManager().setExpireTime(name, group.getLeaseGiveTime()); + } + } + return true; + } + return false; + } + + public void listResidences(Player player) { + this.listResidences(player, player.getName(), 1); + } + + public void listResidences(Player player, int page) { + this.listResidences(player, player.getName(), page); + } + + public void listResidences(Player player, String targetplayer) { + this.listResidences(player, targetplayer, 1); + } + + public void listResidences(Player player, String targetplayer, int page) { + this.listResidences(player, targetplayer, page, false); + } + + public void listResidences(Player player, int page, boolean showhidden) { + this.listResidences(player, player.getName(), page, showhidden); + } + + public void listResidences(Player player, String targetplayer, int page, boolean showhidden) { + this.listResidences(player, targetplayer, page, showhidden, false); + } + + public void listResidences(Player player, String targetplayer, int page, boolean showhidden, boolean showsubzones) { + if (showhidden && !Residence.isResAdminOn(player) && !player.getName().equals(targetplayer)) { + showhidden = false; + } + InformationPager.printInfo(player, Residence.getLanguage().getPhrase("Residences") + " - " + targetplayer, this.getResidenceList(targetplayer, showhidden, showsubzones, true), page); + } + + public void listAllResidences(Player player, int page) { + this.listAllResidences(player, page, false); + } + + public void listAllResidences(Player player, int page, boolean showhidden) { + this.listAllResidences(player, page, showhidden, false); + } + + public void listAllResidences(Player player, int page, boolean showhidden, boolean showsubzones) { + if (showhidden && !Residence.isResAdminOn(player)) { + showhidden = false; + } + InformationPager.printInfo(player, Residence.getLanguage().getPhrase("Residences"), this.getResidenceList(null, showhidden, showsubzones, true), page); + } + + public String[] getResidenceList() { + return this.getResidenceList(true, true).toArray(new String[0]); + } + + public ArrayList getResidenceList(boolean showhidden, boolean showsubzones) { + return this.getResidenceList(null, showhidden, showsubzones, false); + } + + public ArrayList getResidenceList(String targetplayer, boolean showhidden, boolean showsubzones) { + return this.getResidenceList(targetplayer, showhidden, showsubzones, false); + } + + public ArrayList getResidenceList(String targetplayer, boolean showhidden, boolean showsubzones, boolean formattedOutput) { + ArrayList list = new ArrayList(); + for (Entry res : residences.entrySet()) { + this.getResidenceList(targetplayer, showhidden, showsubzones, "", res.getKey(), res.getValue(), list, formattedOutput); + } + return list; + } + + private void getResidenceList(String targetplayer, boolean showhidden, boolean showsubzones, String parentzone, String resname, ClaimedResidence res, ArrayList list, boolean formattedOutput) { + boolean hidden = res.getPermissions().has("hidden", false); + if ((showhidden) || (!showhidden && !hidden)) { + if (targetplayer == null || res.getPermissions().getOwner().equalsIgnoreCase(targetplayer)) { + if (formattedOutput) { + list.add(ChatColor.GREEN + parentzone + resname + ChatColor.YELLOW + " - " + Residence.getLanguage().getPhrase("World") + ": " + res.getWorld()); + } else { + list.add(parentzone + resname); + } + } + if (showsubzones) { + for (Entry sz : res.subzones.entrySet()) { + this.getResidenceList(targetplayer, showhidden, showsubzones, parentzone + resname + ".", sz.getKey(), sz.getValue(), list, formattedOutput); + } + } + } + } + + public String checkAreaCollision(CuboidArea newarea, ClaimedResidence parentResidence) { + Set> set = residences.entrySet(); + for (Entry entry : set) { + ClaimedResidence check = entry.getValue(); + if (check != parentResidence && check.checkCollision(newarea)) { + return entry.getKey(); + } + } + return null; + } + + public void removeResidence(String name) { + this.removeResidence(null, name, true); + } + + public void removeResidence(Player player, String name, boolean resadmin) { + ClaimedResidence res = this.getByName(name); + if (res != null) { + if (player != null && !resadmin) { + if (!res.getPermissions().hasResidencePermission(player, true) && !resadmin) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + } + ResidenceDeleteEvent resevent = new ResidenceDeleteEvent(player, res, player == null ? DeleteCause.OTHER : DeleteCause.PLAYER_DELETE); + Residence.getServ().getPluginManager().callEvent(resevent); + if (resevent.isCancelled()) { + return; + } + ClaimedResidence parent = res.getParent(); + if (parent == null) { + removeChunkList(name); + residences.remove(name); + if (player != null) { + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("ResidenceRemove", ChatColor.YELLOW + name + ChatColor.GREEN)); + } + } else { + String[] split = name.split("\\."); + if (player != null) { + parent.removeSubzone(player, split[split.length - 1], true); + } else { + parent.removeSubzone(split[split.length - 1]); + } + } + // Residence.getLeaseManager().removeExpireTime(name); - causing + // concurrent modification exception in lease manager... worked + // around for now + Residence.getRentManager().removeRentable(name); + + } else { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidResidence")); + } + } + } + + public void removeAllByOwner(String owner) { + this.removeAllByOwner(null, owner, residences); + } + + public void removeAllByOwner(Player player, String owner) { + this.removeAllByOwner(player, owner, residences); + } + + private void removeAllByOwner(Player player, String owner, Map resholder) { + Iterator it = resholder.values().iterator(); + while (it.hasNext()) { + ClaimedResidence res = it.next(); + if (res.getOwner().equalsIgnoreCase(owner)) { + ResidenceDeleteEvent resevent = new ResidenceDeleteEvent(player, res, player == null ? DeleteCause.OTHER : DeleteCause.PLAYER_DELETE); + Residence.getServ().getPluginManager().callEvent(resevent); + if (resevent.isCancelled()) + return; + removeChunkList(res.getName()); + it.remove(); + } else { + this.removeAllByOwner(player, owner, res.subzones); + } + } + } + + public int getOwnedZoneCount(String player) { + Collection set = residences.values(); + int count = 0; + for (ClaimedResidence res : set) { + if (res.getPermissions().getOwner().equalsIgnoreCase(player)) { + count++; + } + } + return count; + } + + public void printAreaInfo(String areaname, Player player) { + ClaimedResidence res = this.getByName(areaname); + if (res == null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidResidence")); + return; + } + ResidencePermissions perms = res.getPermissions(); + if (Residence.getConfigManager().enableEconomy()) { + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("Residence") + ":" + ChatColor.DARK_GREEN + " " + areaname + " " + ChatColor.YELLOW + "Bank: " + ChatColor.GOLD + res.getBank().getStoredMoney()); + } else { + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("Residence") + ":" + ChatColor.DARK_GREEN + " " + areaname); + } + if (Residence.getConfigManager().enabledRentSystem() && Residence.getRentManager().isRented(areaname)) { + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("Owner") + ":" + ChatColor.RED + " " + perms.getOwner() + ChatColor.YELLOW + " Rented by: " + ChatColor.RED + Residence.getRentManager().getRentingPlayer(areaname)); + } else { + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("Owner") + ":" + ChatColor.RED + " " + perms.getOwner() + ChatColor.YELLOW + " - " + Residence.getLanguage().getPhrase("World") + ": " + ChatColor.RED + perms.getWorld()); + } + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("Flags") + ":" + ChatColor.BLUE + " " + perms.listFlags()); + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("Your.Flags") + ": " + ChatColor.GREEN + perms.listPlayerFlags(player.getName())); + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("Group.Flags") + ":" + ChatColor.RED + " " + perms.listGroupFlags()); + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("Others.Flags") + ":" + ChatColor.RED + " " + perms.listOtherPlayersFlags(player.getName())); + String aid = res.getAreaIDbyLoc(player.getLocation()); + if (aid != null) { + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("CurrentArea") + ": " + ChatColor.GOLD + aid); + } + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("Total.Size") + ":" + ChatColor.LIGHT_PURPLE + " " + res.getTotalSize()); + if (aid != null) { + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("CoordsT") + ": " + ChatColor.LIGHT_PURPLE + Residence.getLanguage().getPhrase("CoordsTop", res.getAreaByLoc(player.getLocation()).getHighLoc().getBlockX() + "." + res.getAreaByLoc(player.getLocation()).getHighLoc().getBlockY() + "." + res.getAreaByLoc(player.getLocation()).getHighLoc().getBlockZ())); + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("CoordsB") + ": " + ChatColor.LIGHT_PURPLE + Residence.getLanguage().getPhrase("CoordsBottom", res.getAreaByLoc(player.getLocation()).getLowLoc().getBlockX() + "." + res.getAreaByLoc(player.getLocation()).getLowLoc().getBlockY() + "." + res.getAreaByLoc(player.getLocation()).getLowLoc().getBlockZ())); + } + if (Residence.getConfigManager().useLeases() && Residence.getLeaseManager().leaseExpires(areaname)) { + player.sendMessage(ChatColor.YELLOW + Residence.getLanguage().getPhrase("LeaseExpire") + ":" + ChatColor.GREEN + " " + Residence.getLeaseManager().getExpireTime(areaname)); + } + } + + public void mirrorPerms(Player reqPlayer, String targetArea, String sourceArea, boolean resadmin) { + ClaimedResidence reciever = this.getByName(targetArea); + ClaimedResidence source = this.getByName(sourceArea); + if (source == null || reciever == null) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidResidence")); + return; + } + if (!resadmin) { + if (!reciever.getPermissions().hasResidencePermission(reqPlayer, true) || !source.getPermissions().hasResidencePermission(reqPlayer, true)) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + } + reciever.getPermissions().applyTemplate(reqPlayer, source.getPermissions(), resadmin); + } + + public Map save() { + Map worldmap = new LinkedHashMap(); + for (World world : Residence.getServ().getWorlds()) { + Map resmap = new LinkedHashMap(); + for (Entry res : residences.entrySet()) { + if (res.getValue().getWorld().equals(world.getName())) { + try { + resmap.put(res.getKey(), res.getValue().save()); + } catch (Exception ex) { + System.out.println("[Residence] Failed to save residence (" + res.getKey() + ")!"); + Logger.getLogger(ResidenceManager.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + worldmap.put(world.getName(), resmap); + } + return worldmap; + } + + @SuppressWarnings("unchecked") + public static ResidenceManager load(Map root) throws Exception { + ResidenceManager resm = new ResidenceManager(); + if (root == null) { + return resm; + } + for (World world : Residence.getServ().getWorlds()) { + Map reslist = (Map) root.get(world + .getName()); + if (reslist != null) { + try { + resm.chunkResidences.put(world.getName(), loadMap(reslist, resm)); + } catch (Exception ex) { + System.out.println("Error in loading save file for world: " + world.getName()); + if (Residence.getConfigManager().stopOnSaveError()) + throw (ex); + } + } + } + return resm; + } + + @SuppressWarnings("unchecked") + public static Map> loadMap(Map root, ResidenceManager resm) throws Exception { + Map> retRes = new HashMap>(); + if (root != null) { + for (Entry res : root.entrySet()) { + try { + ClaimedResidence residence = ClaimedResidence.load( + (Map) res.getValue(), null); + for (ChunkRef chunk : getChunks(residence)) { + List ress = new ArrayList(); + if (retRes.containsKey(chunk)) { + ress.addAll(retRes.get(chunk)); + } + ress.add(res.getKey()); + retRes.put(chunk, ress); + } + resm.residences.put(res.getKey(), residence); + } catch (Exception ex) { + System.out.print("[Residence] Failed to load residence (" + res.getKey() + ")! Reason:" + ex.getMessage() + " Error Log:"); + Logger.getLogger(ResidenceManager.class.getName()).log(Level.SEVERE, null, ex); + if (Residence.getConfigManager().stopOnSaveError()) { + throw (ex); + } + } + } + } + return retRes; + } + + private static List getChunks(ClaimedResidence res) { + List chunks = new ArrayList(); + for (CuboidArea area : res.getAreaArray()) { + chunks.addAll(area.getChunks()); + } + return chunks; + } + + public boolean renameResidence(String oldName, String newName) { + return this.renameResidence(null, oldName, newName, true); + } + + public boolean renameResidence(Player player, String oldName, String newName, boolean resadmin) { + if (!Residence.validName(newName)) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidNameCharacters")); + return false; + } + ClaimedResidence res = this.getByName(oldName); + if (res == null) { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidResidence")); + } + return false; + } + if (res.getPermissions().hasResidencePermission(player, true) || resadmin) { + if (res.getParent() == null) { + if (residences.containsKey(newName)) { + if (player != null) + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ResidenceAlreadyExists", ChatColor.YELLOW + newName + ChatColor.RED)); + return false; + } + ResidenceRenameEvent resevent = new ResidenceRenameEvent(res, newName, oldName); + Residence.getServ().getPluginManager().callEvent(resevent); + removeChunkList(oldName); + residences.put(newName, res); + residences.remove(oldName); + calculateChunks(newName); + if (Residence.getConfigManager().useLeases()) { + Residence.getLeaseManager().updateLeaseName(oldName, newName); + } + if (Residence.getConfigManager().enabledRentSystem()) { + Residence.getRentManager().updateRentableName(oldName, newName); + } + if (player != null) { + player.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("ResidenceRename", ChatColor.YELLOW + oldName + ChatColor.GREEN + "." + ChatColor.YELLOW + newName + ChatColor.GREEN)); + } + return true; + } else { + String[] oldname = oldName.split("\\."); + ClaimedResidence parent = res.getParent(); + return parent.renameSubzone(player, oldname[oldname.length - 1], newName, resadmin); + } + } else { + if (player != null) { + player.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + } + return false; + } + } + + public void giveResidence(Player reqPlayer, String targPlayer, String residence, boolean resadmin) { + ClaimedResidence res = getByName(residence); + if (res == null) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("InvalidResidence")); + return; + } + if (!res.getPermissions().hasResidencePermission(reqPlayer, true) && !resadmin) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NoPermission")); + return; + } + Player giveplayer = Residence.getServ().getPlayer(targPlayer); + if (giveplayer == null || !giveplayer.isOnline()) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("NotOnline")); + return; + } + CuboidArea[] areas = res.getAreaArray(); + PermissionGroup g = Residence.getPermissionManager().getGroup(giveplayer); + if (areas.length > g.getMaxPhysicalPerResidence() && !resadmin) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ResidenceGiveLimits")); + return; + } + if (getOwnedZoneCount(giveplayer.getName()) >= g.getMaxZones() && !resadmin) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ResidenceGiveLimits")); + return; + } + if (!resadmin) { + for (CuboidArea area : areas) { + if (!g.inLimits(area)) { + reqPlayer.sendMessage(ChatColor.RED + Residence.getLanguage().getPhrase("ResidenceGiveLimits")); + return; + } + } + } + res.getPermissions().setOwner(giveplayer.getName(), true); + // Fix phrases here + reqPlayer.sendMessage(ChatColor.GREEN + Residence.getLanguage().getPhrase("ResidenceGive", ChatColor.YELLOW + residence + ChatColor.GREEN + "." + ChatColor.YELLOW + giveplayer.getName() + ChatColor.GREEN)); + giveplayer.sendMessage(Residence.getLanguage().getPhrase("ResidenceRecieve", ChatColor.GREEN + residence + ChatColor.YELLOW + "." + ChatColor.GREEN + reqPlayer.getName() + ChatColor.YELLOW)); + } + + public void removeAllFromWorld(CommandSender sender, String world) { + int count = 0; + Iterator it = residences.values().iterator(); + while (it.hasNext()) { + ClaimedResidence next = it.next(); + if (next.getWorld().equals(world)) { + it.remove(); + count++; + } + } + chunkResidences.remove(world); + chunkResidences.put(world, new HashMap>()); + if (count == 0) { + sender.sendMessage(ChatColor.RED + "No residences found in world: " + ChatColor.YELLOW + world); + } else { + sender.sendMessage(ChatColor.RED + "Removed " + ChatColor.YELLOW + count + ChatColor.RED + " residences in world: " + ChatColor.YELLOW + world); + } + } + + public int getResidenceCount() { + return residences.size(); + } + + public void removeChunkList(String name) { + ClaimedResidence res = residences.get(name); + if (res != null) { + String world = res.getWorld(); + if (chunkResidences.get(world) != null) { + for (ChunkRef chunk : getChunks(res)) { + List ress = new ArrayList(); + if (chunkResidences.get(world).containsKey(chunk)) { + ress.addAll(chunkResidences.get(world).get(chunk)); + } + ress.remove(name); + chunkResidences.get(world).put(chunk, ress); + } + } + } + } + + public void calculateChunks(String name) { + ClaimedResidence res = residences.get(name); + if (res != null) { + String world = res.getWorld(); + if (chunkResidences.get(world) == null) { + chunkResidences.put(world, new HashMap>()); + } + for (ChunkRef chunk : getChunks(res)) { + List ress = new ArrayList(); + if (chunkResidences.get(world).containsKey(chunk)) { + ress.addAll(chunkResidences.get(world).get(chunk)); + } + ress.add(name); + chunkResidences.get(world).put(chunk, ress); + } + } + } + + public static final class ChunkRef { + + public static int getChunkCoord(final int val) { + // For more info, see CraftBukkit.CraftWorld.getChunkAt( Location ) + return val >> 4; + } + private final int z; + private final int x; + + public ChunkRef(Location loc) { + this.x = getChunkCoord(loc.getBlockX()); + this.z = getChunkCoord(loc.getBlockZ()); + } + public ChunkRef(int x, int z) { + this.x = x; + this.z = z; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ChunkRef other = (ChunkRef) obj; + return this.x == other.x && this.z == other.z; + } + + public int hashCode() { + return x ^ z; + } + + /** + * Useful for debug + */ + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append( "{ x: " ).append(x).append( ", z: " ).append( z ).append( " }" ); + return sb.toString(); + } + } +} diff --git a/src/com/bekvon/bukkit/residence/protection/ResidencePermissions.java b/src/com/bekvon/bukkit/residence/protection/ResidencePermissions.java new file mode 100644 index 0000000..b386ef8 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/protection/ResidencePermissions.java @@ -0,0 +1,503 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.protection; +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.event.ResidenceFlagChangeEvent; +import com.bekvon.bukkit.residence.event.ResidenceFlagCheckEvent; +import com.bekvon.bukkit.residence.event.ResidenceFlagEvent.FlagType; +import com.bekvon.bukkit.residence.event.ResidenceOwnerChangeEvent; +import com.bekvon.bukkit.residence.permissions.PermissionManager; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class ResidencePermissions extends FlagPermissions { + + protected String owner; + protected String world; + protected ClaimedResidence residence; + + private ResidencePermissions(ClaimedResidence res) + { + residence = res; + } + + public ResidencePermissions(ClaimedResidence res, String creator, String inworld) + { + this(res); + owner = creator; + world = inworld; + } + + public boolean playerHas(String player, String flag, boolean def) + { + return this.playerHas(player, world, flag, def); + } + + @Override + public boolean playerHas(String player, String world, String flag, boolean def) { + ResidenceFlagCheckEvent fc = new ResidenceFlagCheckEvent(residence,flag,FlagType.PLAYER,player,def); + Residence.getServ().getPluginManager().callEvent(fc); + if(fc.isOverriden()) + return fc.getOverrideValue(); + return super.playerHas(player, world, flag, def); + } + + @Override + public boolean groupHas(String group, String flag, boolean def) { + ResidenceFlagCheckEvent fc = new ResidenceFlagCheckEvent(residence,flag,FlagType.GROUP,group,def); + Residence.getServ().getPluginManager().callEvent(fc); + if(fc.isOverriden()) + return fc.getOverrideValue(); + return super.groupHas(group, flag, def); + } + + @Override + public boolean has(String flag, boolean def) { + ResidenceFlagCheckEvent fc = new ResidenceFlagCheckEvent(residence,flag,FlagType.RESIDENCE,null,def); + Residence.getServ().getPluginManager().callEvent(fc); + if(fc.isOverriden()) + return fc.getOverrideValue(); + return super.has(flag, def); + } + + + public boolean hasApplicableFlag(String player, String flag) + { + return super.inheritanceIsPlayerSet(player,flag) || super.inheritanceIsGroupSet(Residence.getPermissionManager().getGroupNameByPlayer(player,world),flag) || super.inheritanceIsSet(flag); + } + + public void applyTemplate(Player player, FlagPermissions list, boolean resadmin) + { + if(player!=null) + { + if(!player.getName().equals(owner) && !resadmin) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoPermission")); + return; + } + } + else + { + resadmin = true; + } + PermissionGroup group = Residence.getPermissionManager().getGroup(owner,world); + for(Entry flag : list.cuboidFlags.entrySet()) + { + if(group.hasFlagAccess(flag.getKey()) || resadmin) + { + this.cuboidFlags.put(flag.getKey(), flag.getValue()); + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("FlagSetDeny", ChatColor.YELLOW+flag.getKey() + ChatColor.RED)); + } + } + for(Entry> plists : list.playerFlags.entrySet()) + { + for(Entry flag : plists.getValue().entrySet()) + { + if(group.hasFlagAccess(flag.getKey()) || resadmin) + { + if(!this.playerFlags.containsKey(plists.getKey())) + this.playerFlags.put(plists.getKey(), Collections.synchronizedMap(new HashMap())); + this.playerFlags.get(plists.getKey()).put(flag.getKey(), flag.getValue()); + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("FlagSetDeny", ChatColor.YELLOW+flag.getKey() + ChatColor.RED)); + } + } + } + for(Entry> glists : list.groupFlags.entrySet()) + { + for(Entry flag : glists.getValue().entrySet()) + { + if(group.hasFlagAccess(flag.getKey()) || resadmin) + { + if(!this.groupFlags.containsKey(glists.getKey())) + this.groupFlags.put(glists.getKey(), Collections.synchronizedMap(new HashMap())); + this.groupFlags.get(glists.getKey()).put(flag.getKey(), flag.getValue()); + } + else + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("FlagSetDeny", ChatColor.YELLOW+flag.getKey() + ChatColor.RED)); + } + } + } + if(player!=null) + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("PermissionsApply")); + } + + public boolean hasResidencePermission(Player player, boolean requireOwner) { + if (Residence.getConfigManager().enabledRentSystem()) { + String resname = residence.getName(); + if (Residence.getRentManager().isRented(resname)) { + if (requireOwner) { + return false; + } + String renter = Residence.getRentManager().getRentingPlayer(resname); + if (player.getName().equalsIgnoreCase(renter)) { + return true; + } else { + return (playerHas(player.getName(), "admin", false)); + } + } + } + if (requireOwner) { + return (owner.equalsIgnoreCase(player.getName())); + } + return (playerHas(player.getName(), "admin", false) || owner.equalsIgnoreCase(player.getName())); + } + + private boolean checkCanSetFlag(Player player, String flag, FlagState state, boolean globalflag, boolean resadmin) + { + if(!checkValidFlag(flag,globalflag)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("InvalidFlag")); + return false; + } + if(state == FlagState.INVALID) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("InvalidFlagState")); + return false; + } + if(!resadmin) + { + if(!this.hasResidencePermission(player,false)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("NoPermission")); + return false; + } + if(!hasFlagAccess(owner, flag)) + { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("OwnerNoPermission")); + return false; + } + } + return true; + } + + private boolean hasFlagAccess(String player, String flag) + { + PermissionGroup group = Residence.getPermissionManager().getGroup(player,world); + return group.hasFlagAccess(flag); + } + + public boolean setPlayerFlag(Player player, String targetPlayer, String flag, String flagstate, boolean resadmin) { + if(validFlagGroups.containsKey(flag)) + return this.setFlagGroupOnPlayer(player, targetPlayer, flag, flagstate, resadmin); + FlagState state = FlagPermissions.stringToFlagState(flagstate); + if (checkCanSetFlag(player, flag, state, false, resadmin)) { + ResidenceFlagChangeEvent fc = new ResidenceFlagChangeEvent(residence, player, flag, ResidenceFlagChangeEvent.FlagType.PLAYER, state, targetPlayer); + Residence.getServ().getPluginManager().callEvent(fc); + if (fc.isCancelled()) + return false; + if(super.setPlayerFlag(targetPlayer, flag, state)) + { + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("FlagSet")); + return true; + } + } + return false; + } + + public boolean setGroupFlag(Player player, String group, String flag, String flagstate, boolean resadmin) { + group = group.toLowerCase(); + if(validFlagGroups.containsKey(flag)) + return this.setFlagGroupOnGroup(player, flag, group, flagstate, resadmin); + FlagState state = FlagPermissions.stringToFlagState(flagstate); + if (checkCanSetFlag(player, flag, state, false, resadmin)) { + if (Residence.getPermissionManager().hasGroup(group)) { + ResidenceFlagChangeEvent fc = new ResidenceFlagChangeEvent(residence, player, flag, ResidenceFlagChangeEvent.FlagType.GROUP, state, group); + Residence.getServ().getPluginManager().callEvent(fc); + if (fc.isCancelled()) + return false; + if(super.setGroupFlag(group, flag, state)) + { + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("FlagSet")); + return true; + } + } else { + player.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("InvalidGroup")); + return false; + } + } + return false; + } + + public boolean setFlag(Player player, String flag, String flagstate, boolean resadmin) { + if(validFlagGroups.containsKey(flag)) + return this.setFlagGroup(player, flag, flagstate, resadmin); + FlagState state = FlagPermissions.stringToFlagState(flagstate); + if (checkCanSetFlag(player, flag, state, true, resadmin)) { + ResidenceFlagChangeEvent fc = new ResidenceFlagChangeEvent(residence,player,flag,ResidenceFlagChangeEvent.FlagType.RESIDENCE,state,null); + Residence.getServ().getPluginManager().callEvent(fc); + if(fc.isCancelled()) + return false; + if(super.setFlag(flag, state)) + { + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("FlagSet")); + return true; + } + } + return false; + } + + public boolean removeAllPlayerFlags(Player player, String targetPlayer, boolean resadmin) { + if (this.hasResidencePermission(player, false) || resadmin) { + ResidenceFlagChangeEvent fc = new ResidenceFlagChangeEvent(residence, player, "ALL", ResidenceFlagChangeEvent.FlagType.RESIDENCE, FlagState.NEITHER, null); + Residence.getServ().getPluginManager().callEvent(fc); + if (fc.isCancelled()) { + return false; + } + super.removeAllPlayerFlags(targetPlayer); + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("FlagSet")); + return true; + } + return false; + } + + public boolean removeAllGroupFlags(Player player, String group, boolean resadmin) { + if (this.hasResidencePermission(player, false) || resadmin) { + ResidenceFlagChangeEvent fc = new ResidenceFlagChangeEvent(residence, player, "ALL", ResidenceFlagChangeEvent.FlagType.GROUP, FlagState.NEITHER, null); + Residence.getServ().getPluginManager().callEvent(fc); + if (fc.isCancelled()) { + return false; + } + super.removeAllGroupFlags(group); + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("FlagSet")); + return true; + } + return false; + } + + + @Override + public boolean setFlag(String flag, FlagState state) { + ResidenceFlagChangeEvent fc = new ResidenceFlagChangeEvent(residence, null,flag,ResidenceFlagChangeEvent.FlagType.RESIDENCE,state,null); + Residence.getServ().getPluginManager().callEvent(fc); + if(fc.isCancelled()) + return false; + return super.setFlag(flag, state); + } + + @Override + public boolean setGroupFlag(String group, String flag, FlagState state) { + ResidenceFlagChangeEvent fc = new ResidenceFlagChangeEvent(residence, null,flag,ResidenceFlagChangeEvent.FlagType.GROUP,state,group); + Residence.getServ().getPluginManager().callEvent(fc); + if(fc.isCancelled()) + return false; + return super.setGroupFlag(group, flag, state); + } + + @Override + public boolean setPlayerFlag(String player, String flag, FlagState state) { + ResidenceFlagChangeEvent fc = new ResidenceFlagChangeEvent(residence, null,flag,ResidenceFlagChangeEvent.FlagType.PLAYER,state, player); + Residence.getServ().getPluginManager().callEvent(fc); + if(fc.isCancelled()) + return false; + return super.setPlayerFlag(player,flag,state); + } + + public void applyDefaultFlags(Player player, boolean resadmin) + { + if(this.hasResidencePermission(player, true) || resadmin) + { + this.applyDefaultFlags(); + player.sendMessage(ChatColor.YELLOW+Residence.getLanguage().getPhrase("FlagsDefault")); + } + else + player.sendMessage(ChatColor.GREEN+Residence.getLanguage().getPhrase("NoPermission")); + } + + public void applyDefaultFlags() + { + PermissionManager gm = Residence.getPermissionManager(); + PermissionGroup group = gm.getGroup(owner, world); + Set> dflags = group.getDefaultResidenceFlags(); + Set> dcflags = group.getDefaultCreatorFlags(); + Set>> dgflags = group.getDefaultGroupFlags(); + this.applyGlobalDefaults(); + for (Entry next : dflags) { + if (this.checkValidFlag(next.getKey(), true)) { + if (next.getValue()) { + this.setFlag(next.getKey(), FlagState.TRUE); + } else { + this.setFlag(next.getKey(), FlagState.FALSE); + } + } + } + for (Entry next : dcflags) { + if (this.checkValidFlag(next.getKey(), false)) { + if (next.getValue()) { + this.setPlayerFlag(owner, next.getKey(), FlagState.TRUE); + } else { + this.setPlayerFlag(owner, next.getKey(), FlagState.FALSE); + } + } + } + for (Entry> entry : dgflags) + { + Map value = entry.getValue(); + for(Entry flag : value.entrySet()) + { + if(flag.getValue()) + { + this.setGroupFlag(entry.getKey(), flag.getKey(), FlagState.TRUE); + } + else + { + this.setGroupFlag(entry.getKey(), flag.getKey(), FlagState.FALSE); + } + } + } + } + + public void setOwner(String newOwner, boolean resetFlags) + { + ResidenceOwnerChangeEvent ownerchange = new ResidenceOwnerChangeEvent(residence,newOwner); + Residence.getServ().getPluginManager().callEvent(ownerchange); + owner = newOwner; + if(resetFlags) + this.applyDefaultFlags(); + } + + public String getOwner() + { + return owner; + } + + public String getWorld() + { + return world; + } + + @Override + public Map save() { + Map root = super.save(); + root.put("Owner", owner); + root.put("World", world); + return root; + } + + public static ResidencePermissions load(ClaimedResidence res, Map root) throws Exception { + ResidencePermissions newperms = new ResidencePermissions(res); + newperms.owner = (String) root.get("Owner"); + newperms.world = (String) root.get("World"); + FlagPermissions.load(root, newperms); + if(newperms.owner==null||newperms.world==null||newperms.playerFlags==null||newperms.groupFlags==null||newperms.cuboidFlags==null) + throw new Exception("Invalid Residence Permissions..."); + newperms.fixNames(); + return newperms; + } + + public void fixNames() + { + ArrayList fixNames = new ArrayList(); + Iterator>> it = playerFlags.entrySet().iterator(); + while(it.hasNext()) + { + String name = it.next().getKey(); + if(!name.equals(name.toLowerCase())) + { + fixNames.add(name); + } + } + for(String name : fixNames) + { + Map get = playerFlags.get(name); + playerFlags.remove(name); + playerFlags.put(name.toLowerCase(), get); + } + } + + public void applyGlobalDefaults() + { + this.clearFlags(); + FlagPermissions gRD = Residence.getConfigManager().getGlobalResidenceDefaultFlags(); + FlagPermissions gCD = Residence.getConfigManager().getGlobalCreatorDefaultFlags(); + Map gGD = Residence.getConfigManager().getGlobalGroupDefaultFlags(); + for(Entry entry : gRD.cuboidFlags.entrySet()) + { + if(entry.getValue()) + this.setFlag(entry.getKey(), FlagState.TRUE); + else + this.setFlag(entry.getKey(), FlagState.FALSE); + } + for(Entry entry : gCD.cuboidFlags.entrySet()) + { + if(entry.getValue()) + this.setPlayerFlag(owner, entry.getKey(), FlagState.TRUE); + else + this.setPlayerFlag(owner, entry.getKey(), FlagState.FALSE); + } + for(Entry entry : gGD.entrySet()) + { + for(Entry flag : entry.getValue().cuboidFlags.entrySet()) + { + if(flag.getValue()) + this.setGroupFlag(entry.getKey(), flag.getKey(), FlagState.TRUE); + else + this.setGroupFlag(entry.getKey(), flag.getKey(), FlagState.FALSE); + } + } + } + + public boolean setFlagGroup(Player player, String flaggroup, String state, boolean resadmin) { + if (ResidencePermissions.validFlagGroups.containsKey(flaggroup)) { + ArrayList flags = ResidencePermissions.validFlagGroups.get(flaggroup); + boolean changed = false; + for (String flag : flags) { + if (this.setFlag(player, flag, state, resadmin)) { + changed = true; + } + } + return changed; + } + return false; + } + + public boolean setFlagGroupOnGroup(Player player, String flaggroup, String group, String state, boolean resadmin) { + if (ResidencePermissions.validFlagGroups.containsKey(flaggroup)) { + ArrayList flags = ResidencePermissions.validFlagGroups.get(flaggroup); + boolean changed = false; + for (String flag : flags) { + if (this.setGroupFlag(player, group, flag, state, resadmin)) { + changed = true; + } + } + return changed; + } + return false; + } + + public boolean setFlagGroupOnPlayer(Player player, String target, String flaggroup, String state, boolean resadmin) { + if (ResidencePermissions.validFlagGroups.containsKey(flaggroup)) { + ArrayList flags = ResidencePermissions.validFlagGroups.get(flaggroup); + boolean changed = false; + for (String flag : flags) { + if (this.setPlayerFlag(player, target, flag, state, resadmin)) { + changed = true; + } + } + return changed; + } + return false; + } +} diff --git a/src/com/bekvon/bukkit/residence/protection/WorldFlagManager.java b/src/com/bekvon/bukkit/residence/protection/WorldFlagManager.java new file mode 100644 index 0000000..1478b03 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/protection/WorldFlagManager.java @@ -0,0 +1,141 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.protection; + +import com.bekvon.bukkit.residence.Residence; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class WorldFlagManager { + protected Map> groupperms; + protected Map worldperms; + protected FlagPermissions globaldefaults; + + public WorldFlagManager() + { + globaldefaults = new FlagPermissions(); + worldperms = new HashMap(); + groupperms = new HashMap>(); + } + + public WorldFlagManager(FileConfiguration config) + { + this(); + this.parsePerms(config); + } + + public FlagPermissions getPerms(Player player) + { + return this.getPerms(player.getWorld().getName(), Residence.getPermissionManager().getGroupNameByPlayer(player)); + } + + public FlagPermissions getPerms(String world, String group) + { + world = world.toLowerCase(); + group = group.toLowerCase(); + Map groupworldperms = groupperms.get(group); + if (groupworldperms == null) { + return this.getPerms(world); + } + FlagPermissions list = groupworldperms.get(world); + if (list == null) { + list = groupworldperms.get("global." + world); + if (list == null) { + list = groupworldperms.get("global"); + } + if (list == null) { + return this.getPerms(world); + } + } + return list; + } + + public FlagPermissions getPerms(String world) + { + world = world.toLowerCase(); + FlagPermissions list = worldperms.get(world); + if (list == null) { + if (globaldefaults == null) + return new FlagPermissions(); + else + return globaldefaults; + } + return list; + } + + public void parsePerms(FileConfiguration config) { + try { + + Set keys = config.getConfigurationSection("Global.Flags").getKeys(false); + if (keys != null) { + for (String key : keys) { + if (key.equalsIgnoreCase("Global")) { + globaldefaults = FlagPermissions.parseFromConfigNode(key, config.getConfigurationSection("Global.Flags")); + } else { + worldperms.put(key.toLowerCase(), FlagPermissions.parseFromConfigNode(key, config.getConfigurationSection("Global.Flags"))); + } + } + } + for (Entry entry : worldperms.entrySet()) { + entry.getValue().setParent(globaldefaults); + } + keys = config.getConfigurationSection("Groups").getKeys(false); + if (keys != null) { + for (String key : keys) { + Set worldkeys = config.getConfigurationSection("Groups." + key + ".Flags.World").getKeys(false); + if (worldkeys != null) { + Map perms = new HashMap(); + for (String wkey : worldkeys) { + FlagPermissions list = FlagPermissions.parseFromConfigNode(wkey, config.getConfigurationSection("Groups." + key + ".Flags.World")); + if(wkey.equalsIgnoreCase("global")) + { + list.setParent(globaldefaults); + perms.put(wkey.toLowerCase(), list); + for(Entry worldperm : worldperms.entrySet()) + { + list = FlagPermissions.parseFromConfigNode(wkey, config.getConfigurationSection("Groups." + key + ".Flags.World")); + list.setParent(worldperm.getValue()); + perms.put("global."+worldperm.getKey().toLowerCase(), list); + } + } + else + { + perms.put(wkey.toLowerCase(), list); + } + } + for (Entry entry : perms.entrySet()) { + String wkey = entry.getKey(); + FlagPermissions list = entry.getValue(); + if (!wkey.startsWith("global.")) { + list.setParent(perms.get("global."+wkey)); + if (list.getParent() == null) { + list.setParent(worldperms.get(wkey)); + } + if(list.getParent()==null) + { + list.setParent(globaldefaults); + } + } + } + groupperms.put(key.toLowerCase(), perms); + } + } + } + } catch (Exception ex) { + Logger.getLogger(WorldFlagManager.class.getName()).log(Level.SEVERE, null, ex); + } + } +} diff --git a/src/com/bekvon/bukkit/residence/selection/SelectionManager.java b/src/com/bekvon/bukkit/residence/selection/SelectionManager.java new file mode 100644 index 0000000..6438180 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/selection/SelectionManager.java @@ -0,0 +1,357 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.selection; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.permissions.PermissionGroup; +import com.bekvon.bukkit.residence.protection.CuboidArea; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.bukkit.ChatColor; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class SelectionManager { + protected Map playerLoc1; + protected Map playerLoc2; + protected Server server; + + public static final int MAX_HEIGHT = 255, MIN_HEIGHT = 0; + + public enum Direction { + UP, DOWN, PLUSX, PLUSZ, MINUSX, MINUSZ + } + + public SelectionManager(Server server) { + this.server = server; + playerLoc1 = Collections + .synchronizedMap(new HashMap()); + playerLoc2 = Collections + .synchronizedMap(new HashMap()); + } + + public void placeLoc1(Player player, Location loc) { + if (loc != null) { + playerLoc1.put(player.getName(), loc); + } + } + + public void placeLoc2(Player player, Location loc) { + if (loc != null) { + playerLoc2.put(player.getName(), loc); + } + } + + public Location getPlayerLoc1(String player) { + return playerLoc1.get(player); + } + + public Location getPlayerLoc2(String player) { + return playerLoc2.get(player); + } + + public boolean hasPlacedBoth(String player) { + return (playerLoc1.containsKey(player) && playerLoc2 + .containsKey(player)); + } + + public void showSelectionInfo(Player player) { + String pname = player.getName(); + if (this.hasPlacedBoth(pname)) { + CuboidArea cuboidArea = new CuboidArea(getPlayerLoc1(pname), + getPlayerLoc2(pname)); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Selection.Total.Size") + + ":" + ChatColor.DARK_AQUA + " " + cuboidArea.getSize()); + PermissionGroup group = Residence.getPermissionManager().getGroup( + player); + if (Residence.getConfigManager().enableEconomy()) + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Land.Cost") + + ":" + + ChatColor.DARK_AQUA + + " " + + ((int) Math.ceil((double) cuboidArea.getSize() + * group.getCostPerBlock()))); + player.sendMessage(ChatColor.YELLOW + "X" + + Residence.getLanguage().getPhrase("Size") + ":" + + ChatColor.DARK_AQUA + " " + cuboidArea.getXSize()); + player.sendMessage(ChatColor.YELLOW + "Y" + + Residence.getLanguage().getPhrase("Size") + ":" + + ChatColor.DARK_AQUA + " " + cuboidArea.getYSize()); + player.sendMessage(ChatColor.YELLOW + "Z" + + Residence.getLanguage().getPhrase("Size") + ":" + + ChatColor.DARK_AQUA + " " + cuboidArea.getZSize()); + } else + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("SelectPoints")); + } + + public void vert(Player player, boolean resadmin) { + if (hasPlacedBoth(player.getName())) { + this.sky(player, resadmin); + this.bedrock(player, resadmin); + } else { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("SelectPoints")); + } + } + + public void sky(Player player, boolean resadmin) { + if (hasPlacedBoth(player.getName())) { + PermissionGroup group = Residence.getPermissionManager().getGroup( + player); + int y1 = playerLoc1.get(player.getName()).getBlockY(); + int y2 = playerLoc2.get(player.getName()).getBlockY(); + if (y1 > y2) { + int newy = MAX_HEIGHT; + if (!resadmin) { + if (group.getMaxHeight() < newy) + newy = group.getMaxHeight(); + if (newy - y2 > (group.getMaxY() - 1)) + newy = y2 + (group.getMaxY() - 1); + } + playerLoc1.get(player.getName()).setY(newy); + } else { + int newy = MAX_HEIGHT; + if (!resadmin) { + if (group.getMaxHeight() < newy) + newy = group.getMaxHeight(); + if (newy - y1 > (group.getMaxY() - 1)) + newy = y1 + (group.getMaxY() - 1); + } + playerLoc2.get(player.getName()).setY(newy); + } + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase("SelectionSky")); + } else { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("SelectPoints")); + } + } + + public void bedrock(Player player, boolean resadmin) { + if (hasPlacedBoth(player.getName())) { + PermissionGroup group = Residence.getPermissionManager().getGroup( + player); + int y1 = playerLoc1.get(player.getName()).getBlockY(); + int y2 = playerLoc2.get(player.getName()).getBlockY(); + if (y1 < y2) { + int newy = MIN_HEIGHT; + if (!resadmin) { + if (newy < group.getMinHeight()) + newy = group.getMinHeight(); + if (y2 - newy > (group.getMaxY() - 1)) + newy = y2 - (group.getMaxY() - 1); + } + playerLoc1.get(player.getName()).setY(newy); + } else { + int newy = MIN_HEIGHT; + if (!resadmin) { + if (newy < group.getMinHeight()) + newy = group.getMinHeight(); + if (y1 - newy > (group.getMaxY() - 1)) + newy = y1 - (group.getMaxY() - 1); + } + playerLoc2.get(player.getName()).setY(newy); + } + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase("SelectionBedrock")); + } else { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("SelectPoints")); + } + } + + public void clearSelection(Player player) { + playerLoc1.remove(player.getName()); + playerLoc2.remove(player.getName()); + } + + public void selectChunk(Player player) { + Chunk chunk = player.getWorld().getChunkAt(player.getLocation()); + int xcoord = chunk.getX() * 16; + int zcoord = chunk.getZ() * 16; + int ycoord = MIN_HEIGHT; + int xmax = xcoord + 15; + int zmax = zcoord + 15; + int ymax = MAX_HEIGHT; + this.playerLoc1.put(player.getName(), new Location(player.getWorld(), + xcoord, ycoord, zcoord)); + this.playerLoc2.put(player.getName(), new Location(player.getWorld(), + xmax, ymax, zmax)); + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase("SelectionSuccess")); + } + + public boolean worldEdit(Player player) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("WorldEditNotFound")); + return false; + } + + public void selectBySize(Player player, int xsize, int ysize, int zsize) { + Location myloc = player.getLocation(); + Location loc1 = new Location(myloc.getWorld(), myloc.getBlockX() + + xsize, myloc.getBlockY() + ysize, myloc.getBlockZ() + zsize); + Location loc2 = new Location(myloc.getWorld(), myloc.getBlockX() + - xsize, myloc.getBlockY() - ysize, myloc.getBlockZ() - zsize); + placeLoc1(player, loc1); + placeLoc2(player, loc2); + player.sendMessage(ChatColor.GREEN + + Residence.getLanguage().getPhrase("SelectionSuccess")); + showSelectionInfo(player); + } + + public void modify(Player player, boolean shift, int amount) { + if (!this.hasPlacedBoth(player.getName())) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("SelectPoints")); + return; + } + Direction d = this.getDirection(player); + if (d == null) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("InvalidDirection")); + } + CuboidArea area = new CuboidArea(playerLoc1.get(player.getName()), + playerLoc2.get(player.getName())); + if (d == Direction.UP) { + int oldy = area.getHighLoc().getBlockY(); + oldy = oldy + amount; + if (oldy > MAX_HEIGHT) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("SelectTooHigh")); + oldy = MAX_HEIGHT; + } + area.getHighLoc().setY(oldy); + if (shift) { + int oldy2 = area.getLowLoc().getBlockY(); + oldy2 = oldy2 + amount; + area.getLowLoc().setY(oldy2); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Shifting.Up") + + "..."); + } else + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Expanding.Up") + + "..."); + } + if (d == Direction.DOWN) { + int oldy = area.getLowLoc().getBlockY(); + oldy = oldy - amount; + if (oldy < MIN_HEIGHT) { + player.sendMessage(ChatColor.RED + + Residence.getLanguage().getPhrase("SelectTooLow")); + oldy = MIN_HEIGHT; + } + area.getLowLoc().setY(oldy); + if (shift) { + int oldy2 = area.getHighLoc().getBlockY(); + oldy2 = oldy2 - amount; + area.getHighLoc().setY(oldy2); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Shifting.Down") + + "..."); + } else + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Expanding.Down") + + "..."); + } + if (d == Direction.MINUSX) { + int oldx = area.getLowLoc().getBlockX(); + oldx = oldx - amount; + area.getLowLoc().setX(oldx); + if (shift) { + int oldx2 = area.getHighLoc().getBlockX(); + oldx2 = oldx2 - amount; + area.getHighLoc().setX(oldx2); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Shifting") + + " -X..."); + } else + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Expanding") + + " -X..."); + } + if (d == Direction.PLUSX) { + int oldx = area.getHighLoc().getBlockX(); + oldx = oldx + amount; + area.getHighLoc().setX(oldx); + if (shift) { + int oldx2 = area.getLowLoc().getBlockX(); + oldx2 = oldx2 + amount; + area.getLowLoc().setX(oldx2); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Shifting") + + " +X..."); + } else + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Expanding") + + " +X..."); + } + if (d == Direction.MINUSZ) { + int oldz = area.getLowLoc().getBlockZ(); + oldz = oldz - amount; + area.getLowLoc().setZ(oldz); + if (shift) { + int oldz2 = area.getHighLoc().getBlockZ(); + oldz2 = oldz2 - amount; + area.getHighLoc().setZ(oldz2); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Shifting") + + " -Z..."); + } else + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Expanding") + + " -Z..."); + } + if (d == Direction.PLUSZ) { + int oldz = area.getHighLoc().getBlockZ(); + oldz = oldz + amount; + area.getHighLoc().setZ(oldz); + if (shift) { + int oldz2 = area.getLowLoc().getBlockZ(); + oldz2 = oldz2 + amount; + area.getLowLoc().setZ(oldz2); + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Shifting") + + " +Z..."); + } else + player.sendMessage(ChatColor.YELLOW + + Residence.getLanguage().getPhrase("Expanding") + + " +Z..."); + } + playerLoc1.put(player.getName(), area.getHighLoc()); + playerLoc2.put(player.getName(), area.getLowLoc()); + } + + private Direction getDirection(Player player) { + float pitch = player.getLocation().getPitch(); + float yaw = player.getLocation().getYaw(); + if (pitch < -50) + return Direction.UP; + if (pitch > 50) + return Direction.DOWN; + if ((yaw > 45 && yaw < 135) || (yaw < -45 && yaw > -135)) + return Direction.MINUSX; + if ((yaw > 225 && yaw < 315) || (yaw < -225 && yaw > -315)) + return Direction.PLUSX; + if ((yaw > 135 && yaw < 225) || (yaw < -135 && yaw > -225)) + return Direction.MINUSZ; + if ((yaw < 45 || yaw > 315) || (yaw > -45 || yaw < -315)) + return Direction.PLUSZ; + return null; + } + +} diff --git a/src/com/bekvon/bukkit/residence/selection/WorldEditSelectionManager.java b/src/com/bekvon/bukkit/residence/selection/WorldEditSelectionManager.java new file mode 100644 index 0000000..62622a0 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/selection/WorldEditSelectionManager.java @@ -0,0 +1,107 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.bekvon.bukkit.residence.selection; + +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.bukkit.selections.CuboidSelection; +import com.sk89q.worldedit.bukkit.selections.Selection; +import com.sk89q.worldedit.regions.CuboidRegion; + +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.entity.Player; + +/** + * + * @author Administrator + */ +public class WorldEditSelectionManager extends SelectionManager { + + public WorldEditSelectionManager(Server serv) + { + super(serv); + } + + @Override + public boolean worldEdit(Player player) { + WorldEditPlugin wep = (WorldEditPlugin) server.getPluginManager().getPlugin("WorldEdit"); + Selection sel = wep.getSelection(player); + if(sel!=null) + { + Location pos1 = sel.getMinimumPoint(); + Location pos2 = sel.getMaximumPoint(); + try{ + CuboidRegion region = (CuboidRegion) sel.getRegionSelector().getRegion(); + pos1 = new Location(player.getWorld(), region.getPos1().getX(), region.getPos1().getY(), region.getPos1().getZ()); + pos2 = new Location(player.getWorld(), region.getPos2().getX(), region.getPos2().getY(), region.getPos2().getZ()); + }catch(Exception e){ + } + this.playerLoc1.put(player.getName(), pos1); + this.playerLoc2.put(player.getName(), pos2); + return true; + } + return false; + } + + private void afterSelectionUpdate(Player player) + { + if (hasPlacedBoth(player.getName())) + { + WorldEditPlugin wep = (WorldEditPlugin) server.getPluginManager().getPlugin("WorldEdit"); + World world = playerLoc1.get(player.getName()).getWorld(); + Selection selection = new CuboidSelection(world, playerLoc1.get(player.getName()), playerLoc2.get(player.getName())); + wep.setSelection(player, selection); + } + } + + @Override + public void placeLoc1(Player player, Location loc) { + this.worldEdit(player); + super.placeLoc1(player, loc); + this.afterSelectionUpdate(player); + } + + @Override + public void placeLoc2(Player player, Location loc) { + this.worldEdit(player); + super.placeLoc2(player, loc); + this.afterSelectionUpdate(player); + } + + @Override + public void sky(Player player, boolean resadmin) { + this.worldEdit(player); + super.sky(player, resadmin); + afterSelectionUpdate(player); + } + + @Override + public void bedrock(Player player, boolean resadmin) { + this.worldEdit(player); + super.bedrock(player, resadmin); + afterSelectionUpdate(player); + } + + @Override + public void modify(Player player, boolean shift, int amount) { + this.worldEdit(player); + super.modify(player, shift, amount); + afterSelectionUpdate(player); + } + + @Override + public void selectChunk(Player player) { + this.worldEdit(player); + super.selectChunk(player); + afterSelectionUpdate(player); + } + + @Override + public void showSelectionInfo(Player player) { + this.worldEdit(player); + super.showSelectionInfo(player); + } +} diff --git a/src/com/bekvon/bukkit/residence/text/Language.java b/src/com/bekvon/bukkit/residence/text/Language.java new file mode 100644 index 0000000..f603dc2 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/text/Language.java @@ -0,0 +1,82 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.text; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import org.bukkit.configuration.file.FileConfiguration; + +/** + * + * @author Administrator + */ +public class Language { + public Map text; + + public Language() { + text = new HashMap(); + } + + public void setText(String key, String intext) { + text.put(key, intext); + } + + private String getText(String key) { + String t = text.get(key); + if (t == null) { + t = ""; + } + return t; + } + + public String getPhrase(String key) { + String[] split = key.split("\\."); + return getPhrase(split); + } + + public String getPhrase(String[] keys) { + return this.getPhrase(keys, (String[]) null); + } + + public String getPhrase(String key, String words) { + return this.getPhrase(key.split("\\."), words); + } + + public String getPhrase(String[] keys, String words) { + if (words == null) { + return this.getPhrase(keys, (String[]) null); + } else { + return this.getPhrase(keys, words.split("\\.")); + } + } + + public String getPhrase(String[] keys, String[] words) { + String sentence = ""; + for (String key : keys) { + if (sentence.length() == 0) { + sentence = this.getText(key); + } else { + sentence = sentence + " " + this.getText(key).toLowerCase(); + } + } + if (words != null) { + for (int i = 0; i < words.length; i++) { + sentence = sentence.replaceAll("%" + (i + 1), words[i]); + } + } + return sentence; + } + + public static Language parseText(FileConfiguration node, String topkey) { + Language newholder = new Language(); + Set keys = node.getConfigurationSection(topkey).getKeys(false); + for (String key : keys) { + newholder.text.put(key, node.getString(topkey + "." + key)); + } + return newholder; + } +} diff --git a/src/com/bekvon/bukkit/residence/text/help/HelpEntry.java b/src/com/bekvon/bukkit/residence/text/help/HelpEntry.java new file mode 100644 index 0000000..33504c4 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/text/help/HelpEntry.java @@ -0,0 +1,214 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.text.help; +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; + +/** + * + * @author Administrator + */ +public class HelpEntry { + protected String name; + protected String desc; + protected String[] lines; + protected List subentrys; + protected static int linesPerPage = 7; + + public HelpEntry(String entryname) + { + name = entryname; + subentrys = new ArrayList(); + lines = new String[0]; + } + + public String getName() { + if(name==null) + return ""; + return name; + } + + public void setName(String inname) + { + name = inname; + } + + public void setDescription(String description) + { + desc = description; + } + public String getDescription() + { + if(desc==null) + return ""; + return desc; + } + + public static int getLinesPerPage() + { + return linesPerPage; + } + + public static void setLinesPerPage(int lines) + { + linesPerPage = lines; + } + + public void printHelp(CommandSender sender, int page) { + List helplines = this.getHelpData(); + int pagecount = (int) Math.ceil((double)helplines.size() / (double)linesPerPage); + if (page > pagecount || page < 1) { + sender.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("InvalidHelp")); + return; + } + sender.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("HelpPageHeader",ChatColor.YELLOW + name + ChatColor.RED+"."+ChatColor.YELLOW + page + ChatColor.RED+"."+ChatColor.YELLOW + pagecount + ChatColor.RED)); + sender.sendMessage(ChatColor.DARK_AQUA+Residence.getLanguage().getPhrase("Description")+": "+ChatColor.GREEN + desc); + int start = linesPerPage * (page - 1); + int end = start + linesPerPage; + boolean alternatecolor = false; + for (int i = start; i < end; i++) { + if (helplines.size() > i) { + if(alternatecolor) + { + sender.sendMessage(ChatColor.YELLOW+helplines.get(i)); + alternatecolor = false; + } + else + { + sender.sendMessage(ChatColor.GOLD+helplines.get(i)); + alternatecolor = true; + } + } + } + if(page---"); + else + sender.sendMessage(ChatColor.GRAY+"-----------------------"); + } + + public void printHelp(CommandSender sender, int page, String path) + { + HelpEntry subEntry = this.getSubEntry(path); + if(subEntry!=null) + { + subEntry.printHelp(sender, page); + } + else + { + sender.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("InvalidHelp")); + } + } + + private List getHelpData() + { + List helplines = new ArrayList(); + helplines.addAll(Arrays.asList(lines)); + if(subentrys.size()>0) + helplines.add(ChatColor.LIGHT_PURPLE+"---"+Residence.getLanguage().getPhrase("SubCommands")+"---"); + for(HelpEntry entry : subentrys) + { + helplines.add(ChatColor.GREEN+entry.getName() + ChatColor.YELLOW+" - " + entry.getDescription()); + } + return helplines; + } + + public boolean containesEntry(String name) + { + return this.getSubEntry(name)!=null; + } + + public HelpEntry getSubEntry(String name) + { + String[] split = name.split("\\."); + HelpEntry entry = this; + for(String entryname : split) + { + entry = entry.findSubEntry(entryname); + if(entry == null) + return null; + } + return entry; + } + + private HelpEntry findSubEntry(String name) + { + for(HelpEntry entry : subentrys) + { + if(entry.getName().equalsIgnoreCase(name)) + return entry; + } + return null; + } + + public void addSubEntry(HelpEntry entry) + { + if(!subentrys.contains(entry)) + { + subentrys.add(entry); + } + } + + public void removeSubEntry(HelpEntry entry) + { + if(subentrys.contains(entry)) + { + subentrys.remove(entry); + } + } + + public int getSubEntryCount() + { + return subentrys.size(); + } + + public static HelpEntry parseHelp(FileConfiguration node, String key) + { + String split[] = key.split("\\."); + String thisname = split[split.length-1]; + HelpEntry entry = new HelpEntry(thisname); + ConfigurationSection keysnode = node.getConfigurationSection(key); + Set keys = null; + if(keysnode!=null) + keys = keysnode.getKeys(false); + if(keys!=null) + { + if(keys.contains("Info")) + { + List stringList = node.getStringList(key + ".Info"); + if(stringList != null) + { + entry.lines = new String[stringList.size()]; + for(int i = 0; i < stringList.size(); i++) + { + entry.lines[i] = "- " + stringList.get(i); + } + } + } + if(keys.contains("Description")) + { + entry.desc = node.getString(key + ".Description"); + } + if(keys.contains("SubCommands")) + { + Set subcommandkeys = node.getConfigurationSection(key + ".SubCommands").getKeys(false); + for(String subkey : subcommandkeys) + { + entry.subentrys.add(HelpEntry.parseHelp(node, key+".SubCommands."+subkey)); + } + } + } + return entry; + } + +} diff --git a/src/com/bekvon/bukkit/residence/text/help/InformationPager.java b/src/com/bekvon/bukkit/residence/text/help/InformationPager.java new file mode 100644 index 0000000..4086a01 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/text/help/InformationPager.java @@ -0,0 +1,61 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.text.help; +import org.bukkit.ChatColor; + +import com.bekvon.bukkit.residence.Residence; +import java.util.Arrays; +import java.util.List; +import org.bukkit.command.CommandSender; + +/** + * + * @author Administrator + */ +public class InformationPager { + + public static int linesPerPage=7; + + public static int getLinesPerPage() + { + return linesPerPage; + } + + public static void setLinesPerPage(int lines) + { + linesPerPage = lines; + } + + public static void printInfo(CommandSender sender, String title, String[] lines, int page) + { + InformationPager.printInfo(sender, title, Arrays.asList(lines), page); + } + + public static void printInfo(CommandSender sender, String title, List lines, int page) { + int perPage = 6; + int start = (page-1) * perPage; + int end = start + perPage; + int pagecount = (int) Math.ceil((double)lines.size()/(double)perPage); + if(pagecount == 0) + pagecount = 1; + if(page>pagecount) + { + sender.sendMessage(ChatColor.RED+Residence.getLanguage().getPhrase("InvalidPage")); + return; + } + sender.sendMessage(ChatColor.YELLOW+"---<"+ChatColor.GREEN+title+ChatColor.YELLOW+">---"); + sender.sendMessage(ChatColor.YELLOW+"---<"+Residence.getLanguage().getPhrase("GenericPage",ChatColor.GREEN+String.format("%d",page)+ChatColor.YELLOW+"."+ChatColor.GREEN+pagecount+ChatColor.YELLOW)+">---"); + for(int i = start; i < end; i ++) + { + if(lines.size()>i) + sender.sendMessage(ChatColor.GREEN+lines.get(i)); + } + if(pagecount>page) + sender.sendMessage(ChatColor.GRAY+"---<"+Residence.getLanguage().getPhrase("NextPage")+">---"); + else + sender.sendMessage(ChatColor.GRAY+"-----------------------"); + } +} diff --git a/src/com/bekvon/bukkit/residence/utils/ActionBar.java b/src/com/bekvon/bukkit/residence/utils/ActionBar.java new file mode 100644 index 0000000..53d42a4 --- /dev/null +++ b/src/com/bekvon/bukkit/residence/utils/ActionBar.java @@ -0,0 +1,100 @@ +package com.bekvon.bukkit.residence.utils; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.logging.Level; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.json.simple.JSONObject; + + +/** +* +* @author hamzaxx +*/ +public class ActionBar { + private static String version = ""; + private static Object packet; + private static Method getHandle; + private static Method sendPacket; + private static Field playerConnection; + private static Class nmsChatSerializer; + private static Class nmsIChatBaseComponent; + private static Class packetType; + + static { + try { + version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + packetType = Class.forName(getPacketPlayOutChat()); + Class typeCraftPlayer = Class.forName(getCraftPlayerClasspath()); + Class typeNMSPlayer = Class.forName(getNMSPlayerClasspath()); + Class typePlayerConnection = Class.forName(getPlayerConnectionClasspath()); + nmsChatSerializer = Class.forName(getChatSerializerClasspath()); + nmsIChatBaseComponent = Class.forName(getIChatBaseComponentClasspath()); + getHandle = typeCraftPlayer.getMethod("getHandle"); + playerConnection = typeNMSPlayer.getField("playerConnection"); + sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName(getPacketClasspath())); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | NoSuchFieldException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Error {0}", ex); + } + } + + public static void send(Player receivingPacket, String msg) { + try { + Object serialized = nmsChatSerializer.getMethod("a", String.class).invoke(null, "{\"text\": \"" + ChatColor.translateAlternateColorCodes('&', JSONObject.escape(msg)) + "\"}"); + if (!version.contains("1_7")) { + packet = packetType.getConstructor(nmsIChatBaseComponent, byte.class).newInstance(serialized, (byte) 2); + } else { + packet = packetType.getConstructor(nmsIChatBaseComponent, int.class).newInstance(serialized, 2); + } + Object player = getHandle.invoke(receivingPacket); + Object connection = playerConnection.get(player); + sendPacket.invoke(connection, packet); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Error {0} " + version, ex); + } + + try { + Object player = getHandle.invoke(receivingPacket); + Object connection = playerConnection.get(player); + sendPacket.invoke(connection, packet); + } catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Error {0}", ex); + } + } + + private static String getCraftPlayerClasspath() { + return "org.bukkit.craftbukkit." + version + ".entity.CraftPlayer"; + } + + private static String getPlayerConnectionClasspath() { + return "net.minecraft.server." + version + ".PlayerConnection"; + } + + private static String getNMSPlayerClasspath() { + return "net.minecraft.server." + version + ".EntityPlayer"; + } + + private static String getPacketClasspath() { + return "net.minecraft.server." + version + ".Packet"; + } + + private static String getIChatBaseComponentClasspath() { + return "net.minecraft.server." + version + ".IChatBaseComponent"; + } + + private static String getChatSerializerClasspath() { + if(version.equals("v1_8_R1") || version.contains("1_7")){ + return "net.minecraft.server." + version + ".ChatSerializer"; + } else { + return "net.minecraft.server." + version + ".IChatBaseComponent$ChatSerializer"; // 1_8_R2 moved to IChatBaseComponent + } + } + + private static String getPacketPlayOutChat() { + return "net.minecraft.server." + version + ".PacketPlayOutChat"; + } +} diff --git a/src/com/bekvon/bukkit/residence/vaultinterface/ResidenceVaultAdapter.java b/src/com/bekvon/bukkit/residence/vaultinterface/ResidenceVaultAdapter.java new file mode 100644 index 0000000..7e058ac --- /dev/null +++ b/src/com/bekvon/bukkit/residence/vaultinterface/ResidenceVaultAdapter.java @@ -0,0 +1,164 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.bekvon.bukkit.residence.vaultinterface; + +import com.bekvon.bukkit.residence.economy.EconomyInterface; +import com.bekvon.bukkit.residence.permissions.PermissionsInterface; + +import net.milkbowl.vault.chat.Chat; +import net.milkbowl.vault.economy.Economy; +import net.milkbowl.vault.permission.Permission; + +import org.bukkit.Server; +import org.bukkit.entity.Player; +import org.bukkit.plugin.RegisteredServiceProvider; + +/** + * + * @author Administrator + */ +public class ResidenceVaultAdapter implements EconomyInterface, + PermissionsInterface { + + public static Permission permissions = null; + public static Economy economy = null; + public static Chat chat = null; + + public boolean permissionsOK() { + if (permissions != null + && !permissions.getName().equalsIgnoreCase("SuperPerms")) { + return true; + } + return false; + } + + public boolean economyOK() { + return economy != null; + } + + public boolean chatOK() { + return chat != null; + } + + public ResidenceVaultAdapter(Server s) { + this.setupPermissions(s); + this.setupEconomy(s); + this.setupChat(s); + } + + private boolean setupPermissions(Server s) { + RegisteredServiceProvider permissionProvider = s + .getServicesManager().getRegistration( + net.milkbowl.vault.permission.Permission.class); + if (permissionProvider != null) { + permissions = permissionProvider.getProvider(); + } + return (permissions != null); + } + + private boolean setupChat(Server s) { + RegisteredServiceProvider chatProvider = s.getServicesManager() + .getRegistration(net.milkbowl.vault.chat.Chat.class); + if (chatProvider != null) { + chat = chatProvider.getProvider(); + } + return (chat != null); + } + + private boolean setupEconomy(Server s) { + RegisteredServiceProvider economyProvider = s + .getServicesManager().getRegistration( + net.milkbowl.vault.economy.Economy.class); + if (economyProvider != null) { + economy = economyProvider.getProvider(); + } + return (economy != null); + } + + public String getPlayerGroup(Player player) { + String group = permissions.getPrimaryGroup(player).toLowerCase(); + if (group == null) { + return group; + } else { + return group.toLowerCase(); + } + } + + @SuppressWarnings("deprecation") + public String getPlayerGroup(String player, String world) { + String group = permissions.getPrimaryGroup(world, player); + if (group == null) { + return group; + } else { + return group.toLowerCase(); + } + } + + @SuppressWarnings("deprecation") + @Override + public double getBalance(String playerName) { + return economy.getBalance(playerName); + } + + @SuppressWarnings("deprecation") + @Override + public boolean canAfford(String playerName, double amount) { + return economy.has(playerName, amount); + } + + @SuppressWarnings("deprecation") + @Override + public boolean add(String playerName, double amount) { + return economy.depositPlayer(playerName, amount).transactionSuccess(); + } + + @SuppressWarnings("deprecation") + @Override + public boolean subtract(String playerName, double amount) { + return economy.withdrawPlayer(playerName, amount).transactionSuccess(); + } + + @SuppressWarnings("deprecation") + @Override + public boolean transfer(String playerFrom, String playerTo, double amount) { + if (economy.withdrawPlayer(playerFrom, amount).transactionSuccess()) { + if (economy.depositPlayer(playerTo, amount).transactionSuccess()) { + return true; + } else { + economy.depositPlayer(playerFrom, amount); + return false; + } + } else { + return false; + } + } + + public String getEconomyName() { + if (economy != null) { + return economy.getName(); + } + return ""; + } + + public String getPermissionsName() { + if (permissions != null) { + return permissions.getName(); + } + return ""; + } + + public String getChatName() { + if (chat != null) { + return chat.getName(); + } + return ""; + } + + public String getName() { + return "Vault"; + } + +} \ No newline at end of file diff --git a/src/com/residence/mcstats/Metrics.java b/src/com/residence/mcstats/Metrics.java new file mode 100644 index 0000000..e5a3a52 --- /dev/null +++ b/src/com/residence/mcstats/Metrics.java @@ -0,0 +1,651 @@ +/* +* Copyright 2011-2013 Tyler Blair. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and contributors and should not be interpreted as representing official policies, +* either expressed or implied, of anybody else. +*/ +package com.residence.mcstats; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.scheduler.BukkitTask; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.net.Proxy; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; +import java.util.logging.Level; + +/** +*

The metrics class obtains data about a plugin and submits statistics about it to the metrics backend.

+* Public methods provided by this class:

+* +* Graph createGraph(String name);
+* void addCustomData(BukkitMetrics.Plotter plotter);
+* void start();
+*
+*/ +public class Metrics { + + /** +* The current revision number +*/ + private final static int REVISION = 6; + /** +* The base url of the metrics domain +*/ + private static final String BASE_URL = "http://mcstats.org"; + /** +* The url used to report a server's status +*/ + private static final String REPORT_URL = "/report/%s"; + /** +* The separator to use for custom data. This MUST NOT change unless you are hosting your own version of metrics and +* want to change it. +*/ + private static final String CUSTOM_DATA_SEPARATOR = "~~"; + /** +* Interval of time to ping (in minutes) +*/ + private static final int PING_INTERVAL = 10; + /** +* The plugin this metrics submits for +*/ + private final Plugin plugin; + /** +* All of the custom graphs to submit to metrics +*/ + private final Set graphs = Collections.synchronizedSet(new HashSet()); + /** +* The default graph, used for addCustomData when you don't want a specific graph +*/ + private final Graph defaultGraph = new Graph("Default"); + /** +* The plugin configuration file +*/ + private final YamlConfiguration configuration; + /** +* The plugin configuration file +*/ + private final File configurationFile; + /** +* Unique server id +*/ + private final String guid; + /** +* Debug mode +*/ + private final boolean debug; + /** +* Lock for synchronization +*/ + private final Object optOutLock = new Object(); + /** +* The scheduled task +*/ + private volatile BukkitTask task = null; + + public Metrics(final Plugin plugin) throws IOException { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + + this.plugin = plugin; + + // load the config + configurationFile = getConfigFile(); + configuration = YamlConfiguration.loadConfiguration(configurationFile); + + // add some defaults + configuration.addDefault("opt-out", false); + configuration.addDefault("guid", UUID.randomUUID().toString()); + configuration.addDefault("debug", false); + + // Do we need to create the file? + if (configuration.get("guid", null) == null) { + configuration.options().header("http://mcstats.org").copyDefaults(true); + configuration.save(configurationFile); + } + + // Load the guid then + guid = configuration.getString("guid"); + debug = configuration.getBoolean("debug", false); + } + + /** +* Construct and create a Graph that can be used to separate specific plotters to their own graphs on the metrics +* website. Plotters can be added to the graph object returned. +* +* @param name The name of the graph +* @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given +*/ + public Graph createGraph(final String name) { + if (name == null) { + throw new IllegalArgumentException("Graph name cannot be null"); + } + + // Construct the graph object + final Graph graph = new Graph(name); + + // Now we can add our graph + graphs.add(graph); + + // and return back + return graph; + } + + /** +* Add a Graph object to BukkitMetrics that represents data for the plugin that should be sent to the backend +* +* @param graph The name of the graph +*/ + public void addGraph(final Graph graph) { + if (graph == null) { + throw new IllegalArgumentException("Graph cannot be null"); + } + + graphs.add(graph); + } + + /** +* Adds a custom data plotter to the default graph +* +* @param plotter The plotter to use to plot custom data +*/ + public void addCustomData(final Plotter plotter) { + if (plotter == null) { + throw new IllegalArgumentException("Plotter cannot be null"); + } + + // Add the plotter to the graph o/ + defaultGraph.addPlotter(plotter); + + // Ensure the default graph is included in the submitted graphs + graphs.add(defaultGraph); + } + + /** +* Start measuring statistics. This will immediately create an async repeating task as the plugin and send the +* initial data to the metrics backend, and then after that it will post in increments of PING_INTERVAL * 1200 +* ticks. +* +* @return True if statistics measuring is running, otherwise false. +*/ + public boolean start() { + synchronized (optOutLock) { + // Did we opt out? + if (isOptOut()) { + return false; + } + + // Is metrics already running? + if (task != null) { + return true; + } + + // Begin hitting the server with glorious data + task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() { + + private boolean firstPost = true; + + public void run() { + try { + // This has to be synchronized or it can collide with the disable method. + synchronized (optOutLock) { + // Disable Task, if it is running and the server owner decided to opt-out + if (isOptOut() && task != null) { + task.cancel(); + task = null; + // Tell all plotters to stop gathering information. + for (Graph graph : graphs) { + graph.onOptOut(); + } + } + } + + // We use the inverse of firstPost because if it is the first time we are posting, + // it is not a interval ping, so it evaluates to FALSE + // Each time thereafter it will evaluate to TRUE, i.e PING! + postPlugin(!firstPost); + + // After the first post we set firstPost to false + // Each post thereafter will be a ping + firstPost = false; + } catch (IOException e) { + if (debug) { + Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage()); + } + } + } + }, 0, PING_INTERVAL * 1200); + + return true; + } + } + + /** +* Has the server owner denied plugin metrics? +* +* @return true if metrics should be opted out of it +*/ + public boolean isOptOut() { + synchronized (optOutLock) { + try { + // Reload the metrics file + configuration.load(getConfigFile()); + } catch (IOException ex) { + if (debug) { + Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); + } + return true; + } catch (InvalidConfigurationException ex) { + if (debug) { + Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); + } + return true; + } + return configuration.getBoolean("opt-out", false); + } + } + + /** +* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task. +* +* @throws java.io.IOException +*/ + public void enable() throws IOException { + // This has to be synchronized or it can collide with the check in the task. + synchronized (optOutLock) { + // Check if the server owner has already set opt-out, if not, set it. + if (isOptOut()) { + configuration.set("opt-out", false); + configuration.save(configurationFile); + } + + // Enable Task, if it is not running + if (task == null) { + start(); + } + } + } + + /** +* Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task. +* +* @throws java.io.IOException +*/ + public void disable() throws IOException { + // This has to be synchronized or it can collide with the check in the task. + synchronized (optOutLock) { + // Check if the server owner has already set opt-out, if not, set it. + if (!isOptOut()) { + configuration.set("opt-out", true); + configuration.save(configurationFile); + } + + // Disable Task, if it is running + if (task != null) { + task.cancel(); + task = null; + } + } + } + + /** +* Gets the File object of the config file that should be used to store data such as the GUID and opt-out status +* +* @return the File object for the config file +*/ + public File getConfigFile() { + // I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use + // is to abuse the plugin object we already have + // plugin.getDataFolder() => base/plugins/PluginA/ + // pluginsFolder => base/plugins/ + // The base is not necessarily relative to the startup directory. + File pluginsFolder = plugin.getDataFolder().getParentFile(); + + // return => base/plugins/PluginMetrics/config.yml + return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml"); + } + + /** +* Generic method that posts a plugin to the metrics website +*/ + private void postPlugin(final boolean isPing) throws IOException { + // Server software specific section + PluginDescriptionFile description = plugin.getDescription(); + String pluginName = description.getName(); + boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled + String pluginVersion = description.getVersion(); + String serverVersion = Bukkit.getVersion(); + int playersOnline = Bukkit.getServer().getOnlinePlayers().size(); + + // END server software specific section -- all code below does not use any code outside of this class / Java + + // Construct the post data + final StringBuilder data = new StringBuilder(); + + // The plugin's description file containg all of the plugin data such as name, version, author, etc + data.append(encode("guid")).append('=').append(encode(guid)); + encodeDataPair(data, "version", pluginVersion); + encodeDataPair(data, "server", serverVersion); + encodeDataPair(data, "players", Integer.toString(playersOnline)); + encodeDataPair(data, "revision", String.valueOf(REVISION)); + + // New data as of R6 + String osname = System.getProperty("os.name"); + String osarch = System.getProperty("os.arch"); + String osversion = System.getProperty("os.version"); + String java_version = System.getProperty("java.version"); + int coreCount = Runtime.getRuntime().availableProcessors(); + + // normalize os arch .. amd64 -> x86_64 + if (osarch.equals("amd64")) { + osarch = "x86_64"; + } + + encodeDataPair(data, "osname", osname); + encodeDataPair(data, "osarch", osarch); + encodeDataPair(data, "osversion", osversion); + encodeDataPair(data, "cores", Integer.toString(coreCount)); + encodeDataPair(data, "online-mode", Boolean.toString(onlineMode)); + encodeDataPair(data, "java_version", java_version); + + // If we're pinging, append it + if (isPing) { + encodeDataPair(data, "ping", "true"); + } + + // Acquire a lock on the graphs, which lets us make the assumption we also lock everything + // inside of the graph (e.g plotters) + synchronized (graphs) { + final Iterator iter = graphs.iterator(); + + while (iter.hasNext()) { + final Graph graph = iter.next(); + + for (Plotter plotter : graph.getPlotters()) { + // The key name to send to the metrics server + // The format is C-GRAPHNAME-PLOTTERNAME where separator - is defined at the top + // Legacy (R4) submitters use the format Custom%s, or CustomPLOTTERNAME + final String key = String.format("C%s%s%s%s", CUSTOM_DATA_SEPARATOR, graph.getName(), CUSTOM_DATA_SEPARATOR, plotter.getColumnName()); + + // The value to send, which for the foreseeable future is just the string + // value of plotter.getValue() + final String value = Integer.toString(plotter.getValue()); + + // Add it to the http post data :) + encodeDataPair(data, key, value); + } + } + } + + // Create the url + URL url = new URL(BASE_URL + String.format(REPORT_URL, encode(pluginName))); + + // Connect to the website + URLConnection connection; + + // Mineshafter creates a socks proxy, so we can safely bypass it + // It does not reroute POST requests so we need to go around it + if (isMineshafterPresent()) { + connection = url.openConnection(Proxy.NO_PROXY); + } else { + connection = url.openConnection(); + } + + connection.setDoOutput(true); + + // Write the data + final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); + writer.write(data.toString()); + writer.flush(); + + // Now read the response + final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + final String response = reader.readLine(); + + // close resources + writer.close(); + reader.close(); + + if (response == null || response.startsWith("ERR")) { + throw new IOException(response); //Throw the exception + } else { + // Is this the first update this hour? + if (response.contains("OK This is your first update this hour")) { + synchronized (graphs) { + final Iterator iter = graphs.iterator(); + + while (iter.hasNext()) { + final Graph graph = iter.next(); + + for (Plotter plotter : graph.getPlotters()) { + plotter.reset(); + } + } + } + } + } + } + + /** +* Check if mineshafter is present. If it is, we need to bypass it to send POST requests +* +* @return true if mineshafter is installed on the server +*/ + private boolean isMineshafterPresent() { + try { + Class.forName("mineshafter.MineServer"); + return true; + } catch (Exception e) { + return false; + } + } + + /** +*

Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first key/value pair +* MUST be included manually, e.g:

+* +* StringBuffer data = new StringBuffer(); +* data.append(encode("guid")).append('=').append(encode(guid)); +* encodeDataPair(data, "version", description.getVersion()); +* +* +* @param buffer the stringbuilder to append the data pair onto +* @param key the key value +* @param value the value +*/ + private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException { + buffer.append('&').append(encode(key)).append('=').append(encode(value)); + } + + /** +* Encode text as UTF-8 +* +* @param text the text to encode +* @return the encoded text, as UTF-8 +*/ + private static String encode(final String text) throws UnsupportedEncodingException { + return URLEncoder.encode(text, "UTF-8"); + } + + /** +* Represents a custom graph on the website +*/ + public static class Graph { + + /** +* The graph's name, alphanumeric and spaces only :) If it does not comply to the above when submitted, it is +* rejected +*/ + private final String name; + /** +* The set of plotters that are contained within this graph +*/ + private final Set plotters = new LinkedHashSet(); + + private Graph(final String name) { + this.name = name; + } + + /** +* Gets the graph's name +* +* @return the Graph's name +*/ + public String getName() { + return name; + } + + /** +* Add a plotter to the graph, which will be used to plot entries +* +* @param plotter the plotter to add to the graph +*/ + public void addPlotter(final Plotter plotter) { + plotters.add(plotter); + } + + /** +* Remove a plotter from the graph +* +* @param plotter the plotter to remove from the graph +*/ + public void removePlotter(final Plotter plotter) { + plotters.remove(plotter); + } + + /** +* Gets an unmodifiable set of the plotter objects in the graph +* +* @return an unmodifiable {@link java.util.Set} of the plotter objects +*/ + public Set getPlotters() { + return Collections.unmodifiableSet(plotters); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(final Object object) { + if (!(object instanceof Graph)) { + return false; + } + + final Graph graph = (Graph) object; + return graph.name.equals(name); + } + + /** +* Called when the server owner decides to opt-out of BukkitMetrics while the server is running. +*/ + protected void onOptOut() { + } + } + + /** +* Interface used to collect custom data for a plugin +*/ + public static abstract class Plotter { + + /** +* The plot's name +*/ + private final String name; + + /** +* Construct a plotter with the default plot name +*/ + public Plotter() { + this("Default"); + } + + /** +* Construct a plotter with a specific plot name +* +* @param name the name of the plotter to use, which will show up on the website +*/ + public Plotter(final String name) { + this.name = name; + } + + /** +* Get the current value for the plotted point. Since this function defers to an external function it may or may +* not return immediately thus cannot be guaranteed to be thread friendly or safe. This function can be called +* from any thread so care should be taken when accessing resources that need to be synchronized. +* +* @return the current value for the point to be plotted. +*/ + public abstract int getValue(); + + /** +* Get the column name for the plotted point +* +* @return the plotted point's column name +*/ + public String getColumnName() { + return name; + } + + /** +* Called after the website graphs have been updated +*/ + public void reset() { + } + + @Override + public int hashCode() { + return getColumnName().hashCode(); + } + + @Override + public boolean equals(final Object object) { + if (!(object instanceof Plotter)) { + return false; + } + + final Plotter plotter = (Plotter) object; + return plotter.name.equals(name) && plotter.getValue() == getValue(); + } + } +} \ No newline at end of file diff --git a/src/com/residence/zip/ZipLibrary.java b/src/com/residence/zip/ZipLibrary.java new file mode 100644 index 0000000..c677feb --- /dev/null +++ b/src/com/residence/zip/ZipLibrary.java @@ -0,0 +1,118 @@ +package com.residence.zip; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.bukkit.World; + +import com.bekvon.bukkit.residence.Residence; + +public class ZipLibrary { + private static File BackupDir = new File(Residence.getDataLocation(), "Backup"); + + public static void backup() throws IOException { + try { + BackupDir.mkdir(); + + } + catch (Exception e) { + e.printStackTrace(); + return; + } + + // Generate the proper date for the backup filename + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + File fileZip = new File(BackupDir, dateFormat.format(date) + ".zip"); + + // Create the Source List, and add directories/etc to the file. + List sources = new ArrayList(); + + File saveFolder = new File(Residence.getDataLocation(), "Save"); + File worldFolder = new File(saveFolder, "Worlds"); + if (!saveFolder.isDirectory()) { + return; + } + File saveFile; + for (World world : Residence.getServ().getWorlds()) { + saveFile = new File(worldFolder, "res_" + world.getName() + ".yml"); + if (saveFile.isFile()) { + sources.add(saveFile); + } + } + + + packZip(fileZip, sources); + } + + private static void packZip(File output, List sources) throws IOException { + ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(output)); + zipOut.setLevel(Deflater.DEFAULT_COMPRESSION); + + for (File source : sources) { + if (source.isDirectory()) { + zipDir(zipOut, "", source); + } + else { + zipFile(zipOut, "", source); + } + } + + zipOut.flush(); + zipOut.close(); + } + + private static String buildPath(String path, String file) { + if (path == null || path.isEmpty()) { + return file; + } + + return path + File.separator + file; + } + + private static void zipDir(ZipOutputStream zos, String path, File dir) throws IOException { + if (!dir.canRead()) { + return; + } + + File[] files = dir.listFiles(); + path = buildPath(path, dir.getName()); + + for (File source : files) { + if (source.isDirectory()) { + zipDir(zos, path, source); + } + else { + zipFile(zos, path, source); + } + } + } + + private static void zipFile(ZipOutputStream zos, String path, File file) throws IOException { + if (!file.canRead()) { + return; + } + + zos.putNextEntry(new ZipEntry(buildPath(path, file.getName()))); + + FileInputStream fis = new FileInputStream(file); + byte[] buffer = new byte[4092]; + int byteCount = 0; + + while ((byteCount = fis.read(buffer)) != -1) { + zos.write(buffer, 0, byteCount); + } + + fis.close(); + zos.closeEntry(); + } +} diff --git a/src/config.yml b/src/config.yml new file mode 100644 index 0000000..f8b5ef9 --- /dev/null +++ b/src/config.yml @@ -0,0 +1,327 @@ +#领地插件配置文件2.7.0.0 重制 By: 喵♂呜(部分汉化来自宝石汉化组 大刘,Zesty). +Global: + # 载入的语言文件 + Language: Chinese + # 圈地工具ID(默认是|木锄-290|)(木斧是271) + SelectionToolId: 290 + # 查看工具ID(默认是线) + InfoToolId: 287 + # 运动检查间隔,以毫秒为单位. + # 数值越小,对服务器负担越大. + # 增加数值会导致玩家在被强制传送前进入禁止移动区域. + MoveCheckInterval: 500 + # 数据保存间隔(单位: 分) + SaveInterval: 10 + # 默认权限组 + DefaultGroup: default + # 是否启用'出租'系统 + UseLeaseSystem: false + # 出租系统检查间隔(单位: 分) + LeaseCheckInterval: 10 + # 允许出租系统自动续租,只要玩家有足够的资金.如果经济系统被禁用,这个设置将无效. + LeaseAutoRenew: true + # 使用权限系统. + EnablePermissions: true + # 设置为'true'如果不使用 Permissions 或 PermissionsBukkit, 或使用旧版 Permissions. + LegacyPermissions: false + # 使用/禁用领地的经济系统 (支持 Vault 所支持的所有经济插件). + EnableEconomy: true + # 使用/禁用领地'租用'系统 + EnableRentSystem: false + # 以分钟为单位,领地租用到期检测间隔 (如果开启了领地租用系统). + RentCheckInterval: 10 + # 使用/禁用领地内聊天频道. + ResidenceChatEnable: true + # 设置为true启动ActionBar 仅限 1.8 以上. + # 设置为false将显示消息在聊天窗口. + UseActionBar: true + # 领地频道聊天颜色. + ResidenceChatColor: DARK_PURPLE + # 是否只有OP或者拥有 'residence.admin' 权限的玩家创建/修改/删除领地(启用后普通玩家将无法使用领地命令). + AdminOnlyCommands: false + # 设置为'true'让OP具有领地管理员权限. + AdminOPs: true + # 多世界插件的名称设置, 如果你没有多世界插件,你可忽略这个. + # 这样做是确保多世界插件在领地插件前开启,以确保其他世界的领地正确读取. + # 可选项: Multiverse-Core MultiWorld 或者别的插件(区分大小写) + MultiWorldPlugin: Multiverse-Core + # 设置为'true'可以使'领地子区域'继承 领地 当前的flag设置. + ResidenceFlagsInherit: true + # 设置为'false'则允许出租的领地可被租用的玩家修改. + PreventRentModify: true + # 设置为'false'将造成即使在保存文件时检测到错误,领地插件也会继续加载. + StopOnSaveFault: true + # 领地名称字符过滤,Google搜索 "Java正则表达式" 可以了解它是如何工作. + ResidenceNameRegex: '[^a-zA-Z0-9\\-\\_]' + # 设置为'true'将会 当每次租用到期或出租期满,都会发送给控制台一个信息. + ShowIntervalMessages: false + # 实验 - 以下设置块的ID列表将作为检查的“箱子”和“使用”标志的使用,当使用MOD自定义箱子和物品时. + CustomContainers: [] + CustomBothClick: [] + CustomRightClick: [] + # 这个是世界flag,不在领地中时. + Flags: + Global: #下面这些为世界总体默认flag设置, 这会覆盖各个组的设置. + use: true + build: true + ignite: true + firespread: true + damage: true + creeper: true + tnt: true + pvp: true + WorldNameHere: #这里你可以设定个人的世界,这些覆盖总体的flag + #build: true + # 这个是所有人可以设置的权限true为允许设置false为不允许. + FlagPermission: + move: true + build: true + place: true + destroy: true + use: true + container: true + pvp: true + tp: true + ignite: true + firespread: true + bucket: true + flow: true + lavaflow: true + waterflow: true + creeper: true + tnt: true + monsters: true + animals: true + subzone: true + healing: true + piston: true + diode: true + lever: true + button: true + door: true + table: true + enchant: true + brew: true + bed: true + cake: true + note: true + trample: false + burn: true + explode: false + fireball: true + # 以下为领地飞行的Flag + fly: true + # 以下为领地扩展的Flag + zombie: true + skeleton: true + creeperspawn: true + spider: true + cavespider: true + slime: true + ghast: true + blaze: true + magmacube: true + silverfish: true + snowgolem: true + irongolem: true + enderman: true + chicken: true + cow: true + wolf: true + mooshroom: true + ocelot: true + zombiepigmen: true + pig: true + sheep: true + squid: true + villager: true + bat: true + witch: true + witherspawn: true + melt: true + form: true + animalkilling: true + mobkilling: true + drops: true + pickup: true + commands: true + enderpearl: true + falldamage: true + portal: true + villagerkilling: true + vehicleprotect: true + lightning: true + grow: true + hunger: true + sprint: true + fishing: true + eggs: true + sneak: true + pigzap: true + slimesplit: true + shear: true + pigsaddle: true + trade: true + god: true + day: true + night: true + weather: true + blockdamage: true + # 这是领地创建后默认设置. + ResidenceDefault: + build: false + use: false + container: false + pvp: false + tnt: false + creeper: false + flow: false + piston: false + ignite: false + firespread: false + # 以下为领地飞行的Flag + fly: false + # 以下为领地扩展的Flag + animalkilling: false + villagerkilling: false + # 这是领地创建后 拥有者 的flag. + CreatorDefault: + build: true + move: true + use: true + ignite: true + container: true + # 以下为领地飞行的Flag + fly: true + # 以下为领地扩展的Flag + animalkilling: true + villagerkilling: true + # 这是默认组,适用于任何组的用户领地flag. + GroupDefault: + #default: #group name + #build: true + +# 这些用户组相当于 '.yml的Permissions groups. +Groups: + Default: #用户组名称 + # 有关玩家可以定义的信息. + # 去除下面的'#'可以镜像复制此配置到其他组. + #Mirror: + #- 'group1' + #- 'group2' + Residence: + # 玩家是否可以创建领地.这个设置可被 'residence.create' 权限覆盖. + CanCreate: true + # 玩家允许拥有最大领地数. + MaxResidences: 3 + # 一个领地的最大物理区域数目. + MaxAreasPerResidence: 2 + # 一个领地在东西方向最大距离 (X坐标). + MaxEastWest: 16 + # 一个领地在南北方向最大距离 (Z坐标). + MaxNorthSouth: 16 + # 一个领地在上下方向最大高度 (Y坐标). + MaxUpDown: 256 + # 允许创建领地的最低高度. + MinHeight: 0 + # 允许创建领地的最高高度. + MaxHeight: 255 + # 子区域领地最大深度. + # 当一个领地子区域包含另一个子区域时,最大深度为2. + # 设置为0将禁用领地子区域. + SubzoneDepth: 3 + # 是否允许传送 + CanTeleport: true + # 是否允许使用'/res unstuck'命令, 当你卡在领地内时可以传送出去 + Unstuck: true + # 是否允许使用'/res select '命令, 如果禁用,那么只能使用工具选取领地. + SelectCommandAccess: true + # 领地主人是否允许使用 黑名单/屏蔽列表 . + ItemListAccess: true + # 进入和离开领地时的消息设置. + Messaging: + #玩家是否可以改变领地进出提示. + CanChange: true + # 这个文本是当前用户组新建领地后的默认进入信息. + # 消息留空将禁用. + DefaultEnter: '欢迎 %player 来到 %owner 的领地 %residence.' + # 这个文本是当前用户组新建领地后的默认离开信息. + # 消息留空将禁用信息. + DefaultLeave: '你离开了 %owner 的领地 %residence.' + # 有关出租系统的设置. + Lease: + # 可出租最大天数. + MaxDays: 16 + # 当使用 '/res lease renew' 命令时可续租多少天. + RenewIncrement: 14 + # 有关租用系统的设置 + Rent: + # 决定一次可以租用多少个领地 + MaxRents: 3 + # 决定玩家一次可以设置为出租的领地个数 + MaxRentables: 3 + # 有关领地经济系统的设置. + Economy: + # 是否可以购买出售中的领地. + CanBuy: true + # 是否可以出售领地. + CanSell: false + # 在购买领地时,是否忽略领地限制. + IgnoreLimits: false + # 创建一个新领地或添加物理区域时的每个方块大小花费. + BuyCost: 0.05 + # 出租领地时每个方块大小花费 (如果出租系统开启). + RenewCost: 0.02 + # Flag检查顺序: + # 1: Player 玩家 + # 2: Group 用户组 + # 3: Owner 拥有者 + # 4: 如果其他都未定义将使用默认(一般是true). + # Flag 的权限默认是 false. + # 这些 flag 设置覆盖总体设置. + Flags: + # 特别允许或拒绝这个组的?ザ赖腇lag. + Permission: + #build: true + # 特指为这个组的成员在领地内是否可以进行建造的Flag. + Default: + #build: true + # 特指领地的创建者在领地内是否可以进行建造的Flag. + CreatorDefault: + #build: true + # 特指其他组的成员在领地内是否可以进行建造的Flag. + GroupDefault: + #default: #组名 + #build: false + # 这些Flag将应用于这个组, 当他们在领地之外时将会被使用. + # 这些Flag将会覆盖上面的Flag, 均为全局选?钕? + World: + Global: # 这些Flag将会应用于所有世界. + #build: false + WorldNameHere: # 或者你也可以单独设置每个世界的情况. + #build: false +# 你可以手动设定组里一个玩家的情况, 这将覆盖他所在组的权限. +GroupAssignments: + bekvon: default + player: default + +ItemList: #在这里你可以建立黑名单/白名单. + DefaultList: #列表的名称并不重要,只要它是唯一的.最好使用一个描述性的名称. + # 列表类型, 可以是黑名单, 白名单, 或屏蔽列表. + Type: blacklist + # 如果你想的话, 你可以将此列表只应用到一个世界上, 否则将会应用到所有世界中. + #World: world + # 你也可以将此列表只应用到一个组里, 否者将会应用到所有组中. + #Group: default + # 此列表是允许或禁止的材料名称的列表 + # 你可以通过在游戏里输入命令'/res material ' 查询材料名称的物品ID + #另外, 你也可以在列表中输入物品ID, 但是这将使其难以辨别并且难以直接查询列表中的物品的启用或禁止情况 + Items: + - 'BEDROCK' + - 'LAVA' + - 'WATER' + - 'STATIONARY_LAVA' + - 'STATIONARY_WATER' + - 'MOB_SPAWNER' +# 这个是用来判断领地插件config.yml修订版本的,不要修改. +ResidenceVersion: 2 diff --git a/src/languagefiles/Chinese.yml b/src/languagefiles/Chinese.yml new file mode 100644 index 0000000..1bdc3e7 --- /dev/null +++ b/src/languagefiles/Chinese.yml @@ -0,0 +1,611 @@ +# NOTE: 'If you want to modify this file, it is HIGHLY recommended that you make a copy +# of this file and modify that instead. This file will be updated automatically by Residence +# when a newer version is detected, and your changes will be overwritten. Once you +# have a copy of this file, change the Language: 'option under the Residence config.yml +# to whatever you named your copy. +Version: 21 +FieldsVersion: 22 +Language: + # The below lines represent various messages residence sends to the players. + # Note that some messages have variables such as %1 that are inserted at runtime. + #Version 1 Fields + InvalidResidence: '无效的领地...' + InvalidSubzone: '无效的附属领地...' + InvalidDirection: '无效的方向...' + InvalidChannel: '无效频道...' + InvalidAmount: '无效数量...' + InvalidCost: '无效的花费金额...' + InvalidDays: '无效的天数...' + InvalidMaterial: '无效的材料...' + InvalidBoolean: '无效值,必须是布尔值,true(t)或者false(f)。' + InvalidArea: '无效的区域...' + InvalidGroup: '无效的权限组...' + InvalidMessageType: '消息类型必须enter(进入)或remove(离开)。' + InvalidList: '无效的清单...' + InvalidFlag: '权限不存在...' + InvalidFlagState: '无效的权限状态,必须是true(t)开启,false(f)关闭,或者 remove(r)移除。' + AreaExists: '区域名字已经存在。' + AreaCreate: '领地ID %1 创建成功' + AreaDiffWorld: '区域与领地是在一个不同的世界。' + AreaCollision: '区域与领地 %1 冲突。' + AreaSubzoneCollision: '区域和附属领地 %1 冲突。' + AreaNonExist: '区域不存在。' + AreaInvalidName: '区域名无效...' + AreaRename: '区域名从 %1 更改到 %2' + AreaRemove: '移除区域 %1 ...' + AreaRemoveLast: '不能把最后一个区域从领地中移除。' + AreaNotWithinParent: '这个区域不在父区域之内。' + AreaUpdate: '区域已更新...' + AreaMaxPhysical: '你已经达到你的领地所允许的最大区域。' + AreaSizeLimit: '区域的大小超出你允许的范围上限。' + AreaHighLimit: '你不能保护这样高的领地,你的上限是 %1 。' + AreaLowLimit: '你不能保护这样深的领地,你的上限是 %1 。' + NotInResidence: '你不在一个领地里。' + InResidence: '你正站在领地 %1 里。' + ResidenceOwnerChange: '领地的拥有者从玩家 %1 改为玩家 %2 。' + NonAdmin: '你不是领地的管理员。' + AdminOnly: '只有管理员才能使用这个命令。' + ChatDisabled: '领地聊天已关闭...' + SubzoneRename: '附属领地 %1 已重命名为 %2 。' + SubzoneRemove: '附属领地 %1 已移除.' + SubzoneCreate: '创建附属领地 %1 。' + SubzoneCreateFail: '不能创建附属领地 %1 。' + SubzoneExists: '附属领地 %1 已经存在。' + SubzoneCollide: '附属领地与另一个附属领地 %1 冲突。' + SubzoneMaxDepth: '您已达到了系统允许的最大分区深度。' + SubzoneSelectInside: '两个选择点必须在领地内。' + SelectPoints: '在用这个命令之前,请先用选择工具选取两个点!' + SelectionSuccess: '选择成功!' + SelectionFail: '无效的选择命令...' + SelectionBedrock: '扩大到允许的最低高度。' + SelectionSky: '扩大到允许的最高高度。' + SelectionArea: '在领地 %2 中选择区域 %1 。' + SelectDiabled: '你没有圈地权限。' + NoPermission: '你没有使用此命令的权限。' + OwnerNoPermission: '所有者无此命令的权限。' + ParentNoPermission: '你没有改变父区域的权限。' + MessageChange: '消息已设置...' + FlagSet: '权限已设置...' + FlagCheckTrue: '权限 %1 为玩家 %2 在领地 %3 设置,值为=%4 。' + FlagCheckFalse: '权限 %1 未为玩家 %2 在领地中设置。' + FlagsCleared: '权限已清除。' + FlagsDefault: '权限已设置为默认。' + Usage: '命令用法' + InvalidHelp: '无效的帮助页...' + SubCommands: '子命令' + InvalidList: '未知列表的类型,必须是黑名单中的类型.' + MaterialGet: '材料名称为ID %1 是 %2 。' + MarketDisabled: '市场功能已禁用!' + MarketList: '市场列表' + SelectionTool: '选择工具' + InfoTool: '信息工具' + NoBankAccess: '你没有银行权限...' + NotEnoughMoney: '你没有足够的钱。' + BankNoMoney: '在银行里没有足够的钱。' + BankDeposit: '你存 %1 元到领地银行。' + BankWithdraw: '你取出 %1 元从领地银行。' + MoneyCharged: '支出 %1 元从 %2 帐户。' + MoneyCredit: '收入 %1 元从 %2 帐户。' + RentDisabled: '租凭系统已关闭。' + RentReleaseInvalid: '领地 %1 没有被租用或者被出租。' + RentSellFail: '不能出售一个被租出去的领地。' + SellRentFail: '当前领地在出售不能出租领地。' + OwnerBuyFail: '无法购买自己的土地!' + OwnerRentFail: '不能租你自己的土地!' + AlreadySellFail: '领地已经出售!' + ResidenceBought: '你已经买下了领地 %1 !' + ResidenceBuy: '玩家 %1 从你那买下了领地 %2 。' + ResidenceBuyTooBig: '此领地已超过系统允许的最大领域。' + ResidenceNotForSale: '领地没有用于出售。' + ResidenceForSale: '现在以 %2 销售领地 %1 。' + ResidenceStopSelling: '领地不再销售。' + ResidenceTooMany: '已达到系统允许领地的最大上限。' + ResidenceMaxRent: '已达到系统允许你租用领地的最大上限。' + ResidenceAlreadyRent: '领地已经被租用...' + ResidenceNotForRent: '领地不用于出租...' + ResidenceNotRented: '领地没有被租用。' + ResidenceUnrent: '领地 %1 已不再出租。' + ResidenceRemoveRentable: '领地 %1 不再出租。' + ResidenceForRentSuccess: '领地 %1 现在租金为 %2 ,每次 %3 天。' + ResidenceRentSuccess: '你已经租用领地 %1 %2 天...' + ResidenceAlreadyRented: '领地 %1 ,目前已出租给 %2 。' + ResidenceAlreadyExists: '领地 %1 已存在。' + ResidenceCreate: '你创建了领地 %1 !' + ResidenceRename: '领地 %1 已改名为 %2 。' + ResidenceRemove: '领地 %1 已经被移除...' + RentDisabled: '出租被禁用...' + RentDisableRenew: '%1 自动到期续约已关闭' + RentEnableRenew: '%1 自动到期续约已开启.' + RentableDisableRenew: '%1 更新可租用状态关闭.' + RentableEnableRenew: '%1 更新可租用状态开启.' + LandForSale: '出售土地' + SellAmount: '销售金额' + LeaseExpire: '租赁到期时间' + RentExpire: '租金到期时间' + RentableAutoRenew: '自动更新可出租的土地' + RentAutoRenew: '租借自动更新' + RentableLand: '可供出租土地' + ListMaterialAdd: '%1 添加到领地 %2' + ListMaterialRemove: '%1 已从领地 %2 移除' + ItemBlacklisted: '你不能在这使用被禁止的物品.' + RentedModifyDeny: '不能修改一个租来的领地.' + WorldPVPDisabled: '当前世界的PvP被禁止.' + NoPVPZone: '没有PVP的区域.' + FlagDeny: '你没有拥有领地 %1 的权限.' + FlagSetDeny: '所有者不能使用这个权限 %1' + SelectPoint: '选择了 %1 的选择点' + ResidenceChat: '领地聊天切换到 %1 ' + ResidenceMoveDeny: '你没有领地 %1 的移动权限' + TeleportDeny: '你没有传送权限。' + TeleportSuccess: '已传送!' + TeleportNear: '已传送到领地的附近。' + TeleportNoFlag: '对不起,你没有传送权限去目标领地。' + SetTeleportLocation: '传送点已设置...' + HelpPageHeader: '帮助页 - %1 - 第 %2页 共 %3页' + ListExists: '列表已经存在...' + ListRemoved: '列表被移除...' + ListCreate: '已创建列表 %1' + LeaseRenew: '租赁有效期至 %1到期' + LeaseRenewMax: '租赁最大的允许值' + LeaseNotExpire: '没有这样的租赁或者租赁未到期.' + LeaseRenewalCost: '更新区域 %1 的花费是 %2' + LeaseInfinite: '租赁时间已设置为无限...' + PermissionsApply: '权限已应用到领地.' + PhysicalAreas: '物理区域' + CurrentArea: '当前区域' + LeaseExpire: '租约期满' + NotOnline: '目标玩家必须在线.' + ResidenceGiveLimits: '无法给予目标玩家,因为这超过了目标玩家的上线' + ResidenceGive: '你把领地 %1 给了玩家 %2' + ResidenceRecieve: '你从玩家 %2 那里接收到了 %1 领地' + #Version 4 New Fields + #ResidenceListAll: 'Residences - - removed, use GenericPage now + ResidenceListAllEmpty: '在这个服务器上没有任何的领地...' + InvalidPage: '无效页数...' + NextPage: '下一页' + #Version 10 New Fields + RemovePlayersResidences: '删除了所有这个玩家的领地 %1' + GenericPage: '页数 %1 / %2' + #Version 11 New Fields + ResidenceRentedBy: '被 %1 租用' + #Version 14 New Fields + InvalidCharacters: '侦测到无效名字...' + InvalidNameCharacters: '名字里包含非法字符...' + #Version 15 New Fields + DeleteConfirm: '你确定要删除领地 %1 吗?输入"/res confirm"来确定。' + #Version 18 New Fields + SelectTooHigh: '警告!你所划分的领地大小已超过服务器限制!' + SelectTooLow: '警告!你所划分的领地大小已超过服务器限制!' + WorldEditNotFound: '未发现WorldEdit插件。' + #Version 19 New Fields + NoResHere: '没有人在这里设置了领地。' + DeleteSubzoneConfirm: '你确定要删除分区 %1 吗?输入“/res confirm”来确定。' + #Version 20 New Fields + SubzoneOwnerChange: '分区 %1 所有者改为 %2' + CoordsTop: 'X:%1 Y:%2 Z:%3' + CoordsBottom: 'X:%1 Y:%2 Z:%3' + #Version 21 New Fields + AdminToggle: 'Automatic resadmin toggle turned %1' + #Version 22 New Fields + NoSpawn: 'You do not have move permissions at your spawn point. Relocating' + CompassTargetReset: '你的指南针指向已重置' + CompassTargetSet: '你的指南针现在指向领地 %1' + + + #The below lines are mostly a word bank for various uses. + #Version 1 Fields + Description: '描述' + Land: '土地' + Cost: '花费' + Selection: '选择' + Total: '总计' + Size: '尺寸' + Expanding: '扩张' + Shifting: '移' + Up: '上' + Down: '下' + Error: '错误' + Flags: '权限' + Your: '你的' + Group: '组' + Others: '其他人' + Primary: '第一个' + Secondary: '第二个' + Selection: '选择' + Moved: '移动' + Status: '状态' + Available: '可用' + On: '开启' + Off: '关闭' + Name: '名字' + Lists: '列表' + Residences: '领地' + Residence: '领地' + Count: '统计' + Owner: '所有者' + #Version 4 Fields + World: '世界' + #Version 12 Fields + Subzones: '附属领地' + #Version 20 Fields + CoordsT: '顶坐标' + CoordsB: '底部的坐标' + #Version 22 Fields + TurnOn: '开' + TurnOff: '关' + +# This is the help / usage messages for each command. +# It follows this format: +# +# Description: ' +# Info: ' +# SubCommands: +# - these follow the same format, and each sub command can have its own subcommands +# When a user gets help for a command (adds a ? mark on the end), first its Info lines are printed, then its sub commands are printed below that +# Pages are automatically generated if the total lines of text exceeds 6 (will be configurable later). +# Add a page number after the ? mark to see that page. + +HelpLinesPerPage: 7 +CommandHelp: #this is just a holder node, that holds the entire help + Description: 领地插件相关帮助 + SubCommands: #this is the actual beginning of all commands + res: #main residence command + Description: 领地插件相关帮助 + Info: + - '如果有疑问在这里找不到,欢迎访问Wiki' + - '地址:residencebukkitmod.wikispaces.com (英文)' + - '输入/[命令] ? <页面>获得更多信息' + SubCommands: + select: #selection commands + Description: Selection Commands + Info: + - '选择此命令的使用范围领地.' + - '/res select [x] [y] [z] - 选择一个区块在中间, 你的半径.' + SubCommands: + coords: + Description: 显示选定的坐标 + Info: + - 'Usage: /res select coords' + size: + Description: 显示选定的领地大小 + Info: + - 'Usage: /res select size' + cost: + Description: 显示选定的领地需缴纳金 + Info: + - 'Usage: /res select cost' + vert: + Description: Expand Selection Vertically + Info: + - 'Usage: /res select vert' + - 'Will expand selection as high and as low as allowed.' + sky: + Description: Expand Selection to Sky + Info: + - 'Usage: /res select sky' + - 'Expands as high as your allowed to go.' + bedrock: + Description: Expand Selection to Bedrock + Info: + - 'Usage: /res select bedrock' + - 'Expands as low as your allowed to go.' + expand: + Description: Expand selection in a direction. + Info: + - 'Usage: /res select expand ' + - 'Expands in the direction your looking.' + shift: + Description: Shift selection in a direction + Info: + - 'Usage: /res select shift ' + - 'Pushes your selection by in the direction your looking.' + chunk: + Description: Select the chunk your currently in. + Info: + - 'Usage: /res select chunk' + - 'Selects the chunk your currently standing in.' + 领地: + Description: Select a existing area in a 领地. + Info: + - 'Usage /res select <领地> ' + - 'Selects a existing area in a 领地.' + create: #creation command + Description: 创建领地 + Info: + - Usage: '/res create <领地名字>' + remove: #remove command + Description: 删除领地 + Info: + - 'Usage: /res remove <领地名字>' + removeall: + Description: 删除某位玩家所属的全部领地 + Info: + - 'Usage: /res removeall [owner]' + - 'Removes all residences owned by a specific player.' + - 'Requires /resadmin if you use it on anyone besides yourself.' + confirm: + - 'Usage: /res confirm' + - '确认你要删除某个领地' + subzone: + Description: 在某个领地里创建附属领地 + Info: + - 'Usage: /res subzone <领地名> [附属领地名]' + - '如果领地名为空,那么将以你所在的领地为主' + area: + Description: 'Manage physical areas for a residence.' + SubCommands: + list: + Description: List physical areas in a residence + Info: + - Usage: /res area list [residence] + listall: + Description: List coordinates and other info for areas + Info: + - Usage: /res area listall [residence] + add: + Description: Add physical areas to a residence + Info: + - Usage: /res area add [residence] [areaID] + - You must first select two points first. + remove: + Description: Remove physical areas from a residence + Info: + - Usage: /res area remove [residence] [areaID] + replace: + Description: Replace physical areas in a residence + Info: + - Usage: /res area replace [residence] [areaID] + - You must first select two points first. + - Replacing a area will charge the difference in size if the new area is bigger. + info: + Description: 显示某个领地的信息 + Info: + - Usage: /res info <领地名> + - 如果领地名为空,将以你所处的领地为主 + limits: + Description: 显示领地功能限制 + Info: + - Usage: /res limits + - 显示你在创建或管理领地时对部分功能的限制 + message: + Description: 设置领地进入/离开信息 + Info: + - Usage: /res message <领地名> [enter/leave] [信息] + - 设置某个领地的进入/离开信息 + - Usage: /res message <领地名> remove [enter/leave] + - 删除某个领地的进入/离开信息 + lease: + Description: Manage residence leases + Info: + - Usage: /res lease [renew/cost] [residence] + - /res lease cost will show the cost of renewing a residence lease. + - /res lease renew will renew the residence provided you have enough money. + SubCommands: + set: + Description: Set the lease time (admin only) + Info: + - Usage: /resadmin lease set [residence] [#days/infinite] + - Sets the lease time to a specified number of days, or infinite. + bank: + Description: Manage money in a Residence + Info: + - Usage: /res bank [deposit/withdraw] [amount] + - You must be standing in a Residence + - You must have the +bank flag. + tp: + Description: 传送到某个领地 + Info: + - Usage: /res tp [领地名] + - 将你传送到某个领地,前提对应领地允许传送或你是对应领地的主人 + - Your permission group must also be allowed to teleport by the server admin. + tpset: + Description: 设置某个领地的传送目标 + Info: + - Usage: /res tpset + - This will set the teleport location for a residence to where your standing. + - You must be standing in the residence to use this command. + - You must also be the owner or have the +admin flag for the residence. + set: + Description: Set general flags on a Residence + Info: + - Usage: /res set [flag] [true/false/remove] + - To see a list of flags, use /res flags ? + - These flags apply to any players who do not have the flag applied specifically to them. (see /res pset ?) + pset: + Description: Set flags on a specific player for a Residence. + Info: + - Usage: /res pset [player] [flag] [true/false/remove] + - Usage: /res pset [player] removeall + - To see a list of flags, use /res flags ? + gset: + Description: Set flags on a specific group for a Residence. + Info: + - Usage: /res gset [group] [flag] [true/false/remove] + - To see a list of flags, use /res flags ? + lset: + Description: Change blacklist and ignorelist options + Info: + - Usage: /res lset [blacklist/ignorelist] [material] + - Usage: /res lset info + - Blacklisting a material prevents it from being placed in the residence. + - Ignorelist causes a specific material to not be protected by Residence. + flags: + Description: List of flags + Info: + - 'For flag values, usually true allows the action, and false denys the action.' + - 'build - 允许或禁止玩家放置破坏方块' + - 'use - 允许或禁止玩家使用门、按钮、拉杆等' + - 'move - 允许或禁止玩家进入此领地或在此领地活动' + - 'container - 允许或禁止玩家使用熔炉、箱子、发射器等' + - 'trusted - Gives build, use, move, container and tp flags' + - 'place - allows or denys only placement of blocks, overrides the build flag.' + - 'destroy - allows or denys only destruction of blocks, overrides the build flag.' + - 'pvp - allow or deny pvp in the residence' + - 'tp - allow or disallow teleporting to the residence.' + - 'admin - gives a player permission to change flags on a residence.' + - 'subzone - allow a player to make subzones in the residence.' + - 'monsters - allows or denys monster spawns' + - 'animals - allows or denys animal spawns.' + - 'healing - setting to true makes the residence heal its occupants' + - 'tnt - allow or deny tnt explosions' + - 'creeper - allow or deny creeper explosions' + - 'ignite - allows or denys fire ignition.' + - 'firespread - allows or denys fire spread.' + - 'bucket - allow or deny bucket use.' + - 'flow - allows or denys liquid flow.' + - 'lavaflow - allows or denys lava flow, overrides flow' + - 'waterflow - allows or denys water flow, overrides flow' + - 'damage - allows or denys all entity damage within the residence.' + - 'piston - allow or deny pistons from pushing or pulling blocks in the residence.' + - 'hidden - hides residence from list or listall commands.' + - 'cake - allows or denys players to eat cake' + - 'lever - allows or denys players to use levers' + - 'button - allows or denys players to use buttons' + - 'diode - allows or denys players to use redstone repeaters' + - 'door - allows or denys players to use doors and trapdoors' + - 'table - allows or denys players to use workbenches' + - 'enchant - allows or denys players to use enchanting tables' + - 'brew - allows or denys players to use brewing stands' + - 'bed - allows or denys players to use beds' + - 'button - allows or denys players to use buttons' + - 'pressure - allows or denys players to use pressure plates' + - 'note - allows or denys players to use note blocks' + - 'redstone - Gives lever, diode, button, pressure, note flags' + - 'craft - Gives table, enchant, brew flags' + list: + Description: List Residences + Info: + - Usage: /res list + - Lists all the residences you own. + - To list everyones residences, use /res listall. + listall: + Description: List All Residence + Info: + - Usage: /res listall + - Lists all residences on the server. + sublist: + Description: List Residence Subzones + Info: + - Usage: /res sublist + - List subzones within a residence. + default: + Description: Reset residence to default flags. + Info: + - Usage: /res default + - Resets the flags on a residence to their default. You must be the owner or an admin to do this. + rename: + Description: Renames a residence. + Info: + - Usage: /res rename [OldName] [NewName] + - You must be the owner or an admin to do this. + - The name must not already be taken by another residence. + mirror: + Description: Mirrors Flags + Info: + - Usage: /res mirror [Source Residence] [Target Residence] + - Mirrors flags from one residence to another. You must be owner of both or a admin to do this. + market: + Description: Buy, Sell, or Rent Residences + Info: + - Usage: /res market ? for more info + SubCommands: + info: + Description: Get economy info on residence + Info: + - Usage: /res market info [residence] + - Shows if the Residence is for sale or for rent, and the cost. + list: + Description: Lists rentable and for sale residences. + Info: + - Usage: /res market list + sell: + Description: Sell a residence + Info: + - Usage: /res market sell [residence] [amount] + - Puts a residence for sale for [amount] of money. + - Another player can buy the residence with /res market buy + buy: + Description: Buy a residence + Info: + - Usage: /res market buy [residence] + - Buys a Residence if its for sale. + unsell: + Description: Stops selling a residence + Info: + - Usage: /res market unsell [residence] + rent: + Description: Rent a residence + Info: + - Usage: /res market rent [residence] + - Rents a residence. Autorenew can be either true or false. If true, the residence will be automatically re-rented upon expire if the residence owner has allowed it. + rentable: + Description: Make a residence rentable. + Info: + - Usage: /res market rentable [residence] [cost] [days] + - Makes a residence rentable for [cost] money for every [days] number of days. If is true, the residence will automatically be able to be rented again after the current rent expires. + release: + Description: Remove a residence from rent or rentable. + Info: + - Usage: /res market release [residence] + - If you are the renter, this command releases the rent on the house for you. + - If you are the owner, this command makes the residence not for rent anymore. + current: + Description: Show residence your currently in. + Info: + - Usage: /res current + lists: + Description: Predefined permission lists + Info: + - Predefined permissions that can be applied to a residence. + SubCommands: + add: + Description: Add a list + Info: + - Usage: /res lists add + remove: + Description: Remove a list + Info: + - Usage: /res lists remove + apply: + Description: Apply a list to a residence + Info: + - Usage: /res lists apply + set: + Description: Set a flag + Info: + - Usage: /res lists set + pset: + Description: Set a player flag + Info: + - Usage: /res lists pset + gset: + Description: Set a group flag + Info: + - Usage: /res lists gset + view: + Description: View a list. + Info: + - Usage: /res lists view + server: + Description: 设置某个领地为服务器所属(仅限管理员使用) + Info: + - Usage: /resadmin server [residence] + - 可以让某个领地变为服务器所属 + setowner: + Description: 设置某个领地的所有者(仅限管理员使用) + Info: + - Usage: /resadmin setowner [领地名] [玩家] + resreload: + Description: 重新加载插件配置(仅限管理员使用) + Info: + - Usage: /resreload + resload: + Description: Load residence save file (UNSAFE, admin only). + Info: + - Usage: /resload + - UNSAFE command, does not save residences first. + - Loads the residence save file after you have made changes. + version: + Description: 显示领地插件的版本信息 + Info: + - Usage: /res version diff --git a/src/languagefiles/English.yml b/src/languagefiles/English.yml new file mode 100644 index 0000000..c5a987d --- /dev/null +++ b/src/languagefiles/English.yml @@ -0,0 +1,628 @@ +# NOTE: If you want to modify this file, it is HIGHLY recommended that you make a copy +# of this file and modify that instead. This file will be updated automatically by Residence +# when a newer version is detected, and your changes will be overwritten. Once you +# have a copy of this file, change the Language: option under the Residence config.yml +# to whatever you named your copy. +Version: 21 +FieldsVersion: 22 +Language: + # The below lines represent various messages residence sends to the players. + # Note that some messages have variables such as %1 that are inserted at runtime. + #Version 1 Fields + InvalidResidence: Invalid Residence... + InvalidSubzone: Invalid Subzone... + InvalidDirection: Invalid Direction... + InvalidChannel: Invalid Channel... + InvalidAmount: Invalid Amount... + InvalidCost: Invalid Cost... + InvalidDays: Invalid number of days... + InvalidMaterial: Invalid Material... + InvalidBoolean: Invalid value, must be true(t) or false(f) + InvalidArea: Invalid Area... + InvalidGroup: Invalid Group... + InvalidMessageType: Message type must be enter or remove. + InvalidList: Invalid List... + InvalidFlag: Invalid Flag... + InvalidFlagState: Invalid flag state, must be true(t), false(f), or remove(r) + AreaExists: Area name already exists. + AreaCreate: 'Residence Area created, ID %1' + AreaDiffWorld: Area is in a different world from residence. + AreaCollision: 'Area collides with residence %1' + AreaSubzoneCollision: 'Area collides with subzone %1' + AreaNonExist: No such area exists. + AreaInvalidName: Invalid Area Name... + AreaRename: 'Renamed area %1 to %2' + AreaRemove: 'Removed area %1...' + AreaRemoveLast: Cannot remove the last area in a residence. + AreaNotWithinParent: Area is not within parent area. + AreaUpdate: Area Updated... + AreaMaxPhysical: You've reached the max physical areas allowed for your residence. + AreaSizeLimit: Area size is not within your allowed limits. + AreaHighLimit: 'You cannot protect this high up, your limit is %1' + AreaLowLimit: 'You cannot protect this deep, your limit is %1' + NotInResidence: You are not in a Residence. + Kicked: 'You were kicked from residence' + InResidence: 'You are standing in Residence %1' + ResidenceOwnerChange: 'Residence %1 owner changed to %2' + NonAdmin: You are not a Residence admin. + AdminOnly: Only admins have access to this command. + ChatDisabled: Residence Chat Disabled... + SubzoneRename: 'Renamed subzone %1 to %2' + SubzoneRemove: 'Subzone %1 removed.' + SubzoneCreate: 'Created Subzone %1' + SubzoneCreateFail: 'Unable to create subzone %1' + SubzoneExists: 'Subzone %1 already exists.' + SubzoneCollide: 'Subzone collides with subzone %1' + SubzoneMaxDepth: You have reached the maximum allowed subzone depth. + SubzoneSelectInside: Both selection points must be inside the residence. + SelectPoints: Select two points first before using this command! + SelectionSuccess: Selection Successful! + SelectionFail: Invalid select command... + SelectionBedrock: Selection expanded to your lowest allowed limit. + SelectionSky: Selection expanded to your highest allowed limit. + SelectionArea: 'Selected area %1 of residence %2' + SelectDiabled: You don't have access to selections commands. + NoPermission: You dont have permission for this. + OwnerNoPermission: The owner does not have permission for this. + ParentNoPermission: You don't have permission to make changes to the parent zone. + MessageChange: Message Set... + FlagSet: Flag Set... + FlagCheckTrue: 'Flag %1 applys to player %2 for residence %3, value = %4' + FlagCheckFalse: 'Flag %1 does not apply to player %2 for residence.' + FlagsCleared: Flags Cleared. + FlagsDefault: Flags set to default. + Usage: Command Usage + InvalidHelp: Invalid Help Page... + SubCommands: Sub Commands + InvalidList: Unknown list type, must be blacklist or ignorelist. + MaterialGet: 'The material name for ID %1 is %2' + MarketDisabled: Economy Disabled! + MarketList: Market List + SelectionTool: Selection Tool + InfoTool: Info Tool + NoBankAccess: You dont have bank access. + NotEnoughMoney: You dont have enough money. + BankNoMoney: Not enough money in the bank. + BankDeposit: 'You deposit %1 into the residence bank.' + BankWithdraw: 'You withdraw %1 from the residence bank.' + MoneyCharged: 'Charged %1 to your %2 account.' + MoneyCredit: 'Credited %1 to your %2 account.' + RentDisabled: Rent system is disabled. + RentReleaseInvalid: 'Residence %1 is not rented or for rent.' + RentSellFail: Cannot sell a Residence if it is for rent. + SellRentFail: Cannot rent a Residence if it is for sale. + OwnerBuyFail: Cannot buy your own land! + OwnerRentFail: Cannot rent your own land! + AlreadySellFail: Residence already for sale! + ResidenceBought: 'You bought residence %1' + ResidenceBuy: 'Residence %1 has bought residence %2 from you.' + ResidenceBuyTooBig: This residence has areas bigger then your allowed max. + ResidenceNotForSale: Residence is not for sale. + ResidenceForSale: 'Residence %1 is now for sale for %2' + ResidenceStopSelling: Residence is no longer for sale. + ResidenceTooMany: You already own the max number of residences your allowed to. + ResidenceMaxRent: You already are renting the maximum number of residences your allowed to. + ResidenceAlreadyRent: Residence is already for rent... + ResidenceNotForRent: Residence not for rent... + ResidenceNotRented: Residence not rented. + ResidenceUnrent: 'Residence %1 has been unrented.' + ResidenceRemoveRentable: 'Residence %1 is no longer rentable.' + ResidenceForRentSuccess: 'Residence %1 is now for rent for %2 every %3 days.' + ResidenceRentSuccess: 'You have rented Residence %1 for %2 days.' + ResidenceAlreadyRented: 'Residence %1 has currently been rented to %2' + ResidenceAlreadyExists: 'A residence named %1 already exists.' + ResidenceCreate: 'You have created residence %1!' + ResidenceRename: 'Renamed Residence %1 to %2' + ResidenceRemove: 'Residence %1 has been removed...' + RentDisabled: Rent is disabled... + RentDisableRenew: 'Residence %1 will now no longer re-rent upon expire.' + RentEnableRenew: 'Residence %1 will now automatically re-rent upon expire.' + RentableDisableRenew: '%1 will no longer renew rentable status upon expire.' + RentableEnableRenew: '%1 will now automatically renew rentable status upon expire.' + LandForSale: Land For Sale + SellAmount: Sell Amount + LeaseExpire: Lease Expire Time + RentExpire: Rent Expire Time + RentableAutoRenew: Rentable Auto Renew + RentAutoRenew: Rent Auto Renew + RentableLand: Rentable Land + ListMaterialAdd: '%1 added to the residence %2' + ListMaterialRemove: '%1 removed from the residence %2' + ItemBlacklisted: You are blacklisted from using this item here. + RentedModifyDeny: Cannot modify a rented residence. + WorldPVPDisabled: World PVP is disabled. + NoPVPZone: No PVP zone. + FlagDeny: 'You dont have %1 permission here.' + FlagSetDeny: 'Owner does not have access to flag %1' + SelectPoint: 'Placed %1 Selection Point' + ResidenceChat: 'Residence chat toggled %1' + ResidenceMoveDeny: 'You dont have movement permission for Residence %1' + TeleportDeny: You dont have teleport access. + TeleportSuccess: 'Teleported!' + TeleportNear: Teleported to near residence. + TeleportNoFlag: You dont have teleport access for that residence. + SetTeleportLocation: Teleport Location Set... + HelpPageHeader: 'Help Pages - %1 - Page <%2 of %3>' + ListExists: List already exists... + ListRemoved: List removed... + ListCreate: 'Created list %1' + LeaseRenew: 'Lease valid until %1' + LeaseRenewMax: Lease renewed to maximum allowed + LeaseNotExpire: No such lease, or lease does not expire. + LeaseRenewalCost: 'Renewal cost for area %1 is %2' + LeaseInfinite: Lease time set to infinite... + PermissionsApply: Permissions applied to residence. + PhysicalAreas: Physical Areas + CurrentArea: Current Area + LeaseExpire: Lease Expiration + NotOnline: Target player must be online. + ResidenceGiveLimits: Cannot give residence to target player, because it is outside the target players limits. + ResidenceGive: 'You give residence %1 to player %2' + ResidenceRecieve: 'You have recieved residence %1 from player %2' + #Version 4 New Fields + #ResidenceListAll: 'Residences - ' - removed, use GenericPage now + ResidenceListAllEmpty: No Residences exists on the server... + InvalidPage: Invalid Page... + NextPage: Next Page + #Version 10 New Fields + RemovePlayersResidences: 'Removed all residences belonging to player %1' + GenericPage: 'Page %1 of %2' + #Version 11 New Fields + ResidenceRentedBy: 'Rented by %1' + #Version 14 New Fields + InvalidCharacters: Invalid characters detected... + InvalidNameCharacters: Name contained unallowed characters... + #Version 15 New Fields + DeleteConfirm: 'Are you sure you want to delete residence %1, use "/res confirm" to confirm.' + #Version 18 New Fields + SelectTooHigh: Warning, selection went above top of map, limiting. + SelectTooLow: Warning, selection went below bottom of map, limiting. + WorldEditNotFound: WorldEdit was not detected. + #Version 19 New Fields + NoResHere: There is no residence in there. + DeleteSubzoneConfirm: 'Are you sure you want to delete subzone %1, use "/res confirm" to confirm.' + #Version 20 New Fields + SubzoneOwnerChange: 'Subzone %1 owner changed to %2' + CoordsTop: 'X:%1 Y:%2 Z:%3' + CoordsBottom: 'X:%1 Y:%2 Z:%3' + #Version 21 New Fields + AdminToggle: 'Automatic resadmin toggle turned %1' + #Version 22 New Fields + NoSpawn: 'You do not have move permissions at your spawn point. Relocating' + CompassTargetReset: 'Your compass has been reset' + CompassTargetSet: 'Your compass now points to %1' + + #The below lines are mostly a word bank for various uses. + #Version 1 Fields + Description: Description + Land: Land + Cost: Cost + Selection: Selection + Total: Total + Size: Size + Expanding: Expanding + Shifting: Shifting + Up: Up + Down: Down + Error: Error + Flags: Flags + Your: Your + Group: Group + Others: Others + Primary: Primary + Secondary: Secondary + Selection: Selection + Moved: Moved + Status: Status + Available: Available + On: On + Off: Off + Name: Name + Lists: Lists + Residences: Residences + Residence: Residence + Count: Count + Owner: Owner + #Version 4 Fields + World: World + #Version 12 Fields + Subzones: Subzones + #Version 20 Fields + CoordsT: Top Coords + CoordsB: Bottom Coords + #Version 22 Fields + TurnOn: 'on' + TurnOff: 'off' + +# This is the help / usage messages for each command. +# It follows this format: +# +# Description: +# Info: +# SubCommands: +# - these follow the same format, and each sub command can have its own subcommands +# When a user gets help for a command (adds a ? mark on the end), first its Info lines are printed, then its sub commands are printed below that +# Pages are automatically generated if the total lines of text exceeds 6 (will be configurable later). +# Add a page number after the ? mark to see that page. + +HelpLinesPerPage: 7 +CommandHelp: #this is just a holder node, that holds the entire help + Description: Contains Help for Residence + SubCommands: #this is the actual beginning of all commands + res: #main residence command + Description: Main Residence Command + Info: + - 'See the residence wiki for more help.' + - 'Wiki: residencebukkitmod.wikispaces.com' + - 'Use /[command] ? to view more help information.' + SubCommands: + select: #selection commands + Description: Selection Commands + Info: + - 'This command selects areas for usage with residence.' + - '/res select [x] [y] [z] - selects a radius of blocks, with you in the middle.' + SubCommands: + coords: + Description: Display selected coordinates + Info: + - 'Usage: /res select coords' + size: + Description: Display selected size + Info: + - 'Usage: /res select size' + cost: + Description: Display selection cost + Info: + - 'Usage: /res select cost' + vert: + Description: Expand Selection Vertically + Info: + - 'Usage: /res select vert' + - 'Will expand selection as high and as low as allowed.' + sky: + Description: Expand Selection to Sky + Info: + - 'Usage: /res select sky' + - 'Expands as high as your allowed to go.' + bedrock: + Description: Expand Selection to Bedrock + Info: + - 'Usage: /res select bedrock' + - 'Expands as low as your allowed to go.' + expand: + Description: Expand selection in a direction. + Info: + - 'Usage: /res select expand ' + - 'Expands in the direction your looking.' + shift: + Description: Shift selection in a direction + Info: + - 'Usage: /res select shift ' + - 'Pushes your selection by in the direction your looking.' + chunk: + Description: Select the chunk your currently in. + Info: + - 'Usage: /res select chunk' + - 'Selects the chunk your currently standing in.' + residence: + Description: Select a existing area in a residence. + Info: + - 'Usage /res select ' + - 'Selects a existing area in a residence.' + worldedit: + Description: Set selection using the current WorldEdit selection. + Info: + - 'Usage /res select worldedit' + - 'Sets selection area using the current WorldEdit selection.' + create: #creation command + Description: Create Residences + Info: + - 'Usage: /res create ' + remove: #remove command + Description: Remove residences. + Info: + - 'Usage: /res remove ' + removeall: + Description: Remove all residences owned by a player. + Info: + - 'Usage: /res removeall [owner]' + - 'Removes all residences owned by a specific player.' + - 'Requires /resadmin if you use it on anyone besides yourself.' + confirm: + - 'Usage: /res confirm' + - 'Confirms removal of a residence.' + subzone: + Description: Create subzones in residences. + Info: + - 'Usage: /res subzone [subzone name]' + - 'If residence name is left off, will attempt to use residence your standing in.' + area: + Description: Manage physical areas for a residence. + SubCommands: + list: + Description: List physical areas in a residence + Info: + - 'Usage: /res area list [residence] ' + listall: + Description: List coordinates and other info for areas + Info: + - 'Usage: /res area listall [residence] ' + add: + Description: Add physical areas to a residence + Info: + - 'Usage: /res area add [residence] [areaID]' + - 'You must first select two points first.' + remove: + Description: Remove physical areas from a residence + Info: + - 'Usage: /res area remove [residence] [areaID]' + replace: + Description: Replace physical areas in a residence + Info: + - 'Usage: /res area replace [residence] [areaID]' + - 'You must first select two points first.' + - 'Replacing a area will charge the difference in size if the new area is bigger.' + info: + Description: Show info on a residence. + Info: + - 'Usage: /res info ' + - 'Leave off to display info for the residence your currently in.' + limits: + Description: Show your limits. + Info: + - 'Usage: /res limits' + - 'Shows the limitations you have on creating and managing residences.' + message: + Description: Manage residence enter / leave messages + Info: + - 'Usage: /res message [enter/leave] [message]' + - 'Set the enter or leave message of a residence.' + - 'Usage: /res message remove [enter/leave]' + - 'Removes a enter or leave message.' + lease: + Description: Manage residence leases + Info: + - 'Usage: /res lease [renew/cost] [residence]' + - '/res lease cost will show the cost of renewing a residence lease.' + - '/res lease renew will renew the residence provided you have enough money.' + SubCommands: + set: + Description: Set the lease time (admin only) + Info: + - 'Usage: /resadmin lease set [residence] [#days/infinite]' + - 'Sets the lease time to a specified number of days, or infinite.' + bank: + Description: Manage money in a Residence + Info: + - 'Usage: /res bank [deposit/withdraw] [amount]' + - 'You must be standing in a Residence' + - 'You must have the +bank flag.' + tp: + Description: Teleport to a residence + Info: + - 'Usage: /res tp [residence]' + - 'Teleports you to a residence, you must have +tp flag access or be the owner.' + - 'Your permission group must also be allowed to teleport by the server admin.' + tpset: + Description: Set the teleport location of a Residence + Info: + - 'Usage: /res tpset' + - 'This will set the teleport location for a residence to where your standing.' + - 'You must be standing in the residence to use this command.' + - 'You must also be the owner or have the +admin flag for the residence.' + set: + Description: Set general flags on a Residence + Info: + - 'Usage: /res set [flag] [true/false/remove]' + - 'To see a list of flags, use /res flags ?' + - 'These flags apply to any players who do not have the flag applied specifically to them. (see /res pset ?)' + pset: + Description: Set flags on a specific player for a Residence. + Info: + - 'Usage: /res pset [player] [flag] [true/false/remove]' + - 'Usage: /res pset [player] removeall' + - 'To see a list of flags, use /res flags ?' + gset: + Description: Set flags on a specific group for a Residence. + Info: + - 'Usage: /res gset [group] [flag] [true/false/remove]' + - 'To see a list of flags, use /res flags ?' + lset: + Description: Change blacklist and ignorelist options + Info: + - 'Usage: /res lset [blacklist/ignorelist] [material]' + - 'Usage: /res lset info' + - 'Blacklisting a material prevents it from being placed in the residence.' + - 'Ignorelist causes a specific material to not be protected by Residence.' + flags: + Description: List of flags + Info: + - 'For flag values, usually true allows the action, and false denys the action.' + - 'build - allows or denys building' + - 'use - allows or denys use of doors, lever, buttons, etc...' + - 'move - allows or denys movement in the residence.' + - 'container - allows or denys use of furnaces, chests, dispensers, etc...' + - 'trusted - Gives build, use, move, container and tp flags' + - 'place - allows or denys only placement of blocks, overrides the build flag.' + - 'destroy - allows or denys only destruction of blocks, overrides the build flag.' + - 'pvp - allow or deny pvp in the residence' + - 'tp - allow or disallow teleporting to the residence.' + - 'admin - gives a player permission to change flags on a residence.' + - 'subzone - allow a player to make subzones in the residence.' + - 'monsters - allows or denys monster spawns' + - 'animals - allows or denys animal spawns.' + - 'healing - setting to true makes the residence heal its occupants' + - 'tnt - allow or deny tnt explosions' + - 'creeper - allow or deny creeper explosions' + - 'ignite - allows or denys fire ignition.' + - 'firespread - allows or denys fire spread.' + - 'bucket - allow or deny bucket use.' + - 'flow - allows or denys liquid flow.' + - 'lavaflow - allows or denys lava flow, overrides flow' + - 'waterflow - allows or denys water flow, overrides flow' + - 'damage - allows or denys all entity damage within the residence.' + - 'piston - allow or deny pistons from pushing or pulling blocks in the residence.' + - 'hidden - hides residence from list or listall commands.' + - 'cake - allows or denys players to eat cake' + - 'lever - allows or denys players to use levers' + - 'button - allows or denys players to use buttons' + - 'diode - allows or denys players to use redstone repeaters' + - 'door - allows or denys players to use doors and trapdoors' + - 'table - allows or denys players to use workbenches' + - 'enchant - allows or denys players to use enchanting tables' + - 'brew - allows or denys players to use brewing stands' + - 'bed - allows or denys players to use beds' + - 'button - allows or denys players to use buttons' + - 'pressure - allows or denys players to use pressure plates' + - 'note - allows or denys players to use note blocks' + - 'redstone - Gives lever, diode, button, pressure, note flags' + - 'craft - Gives table, enchant, brew flags' + - 'burn - allows or denys Mob combustion in residences' + list: + Description: List Residences + Info: + - 'Usage: /res list ' + - 'Lists all the residences a player owns (except hidden ones).' + - 'If listing your own residences, shows hidden ones as well.' + - 'To list everyones residences, use /res listall.' + listhidden: + Description: List Hidden Residences (ADMIN ONLY) + Info: + - 'Usage: /res listhidden ' + - 'Lists hidden residences for a player.' + listall: + Description: List All Residences + Info: + - 'Usage: /res listall ' + - 'Lists all residences on the server. (except hidden ones that you dont own)' + listallhidden: + Description: List All Hidden Residences (ADMIN ONLY) + Info: + - 'Usage: /res listhidden ' + - 'Lists all hidden residences on the server.' + sublist: + Description: List Residence Subzones + Info: + - 'Usage: /res sublist ' + - 'List subzones within a residence.' + default: + Description: Reset residence to default flags. + Info: + - 'Usage: /res default ' + - 'Resets the flags on a residence to their default. You must be the owner or an admin to do this.' + rename: + Description: Renames a residence. + Info: + - 'Usage: /res rename [OldName] [NewName]' + - 'You must be the owner or an admin to do this.' + - 'The name must not already be taken by another residence.' + mirror: + Description: Mirrors Flags + Info: + - 'Usage: /res mirror [Source Residence] [Target Residence]' + - 'Mirrors flags from one residence to another. You must be owner of both or a admin to do this.' + market: + Description: Buy, Sell, or Rent Residences + Info: + - 'Usage: /res market ? for more info' + SubCommands: + info: + Description: Get economy info on residence + Info: + - 'Usage: /res market info [residence]' + - 'Shows if the Residence is for sale or for rent, and the cost.' + list: + Description: Lists rentable and for sale residences. + Info: + - 'Usage: /res market list' + sell: + Description: Sell a residence + Info: + - 'Usage: /res market sell [residence] [amount]' + - 'Puts a residence for sale for [amount] of money.' + - 'Another player can buy the residence with /res market buy' + buy: + Description: Buy a residence + Info: + - 'Usage: /res market buy [residence]' + - 'Buys a Residence if its for sale.' + unsell: + Description: Stops selling a residence + Info: + - 'Usage: /res market unsell [residence]' + rent: + Description: Rent a residence + Info: + - 'Usage: /res market rent [residence] ' + - 'Rents a residence. Autorenew can be either true or false. If true, the residence will be automatically re-rented upon expire if the residence owner has allowed it.' + rentable: + Description: Make a residence rentable. + Info: + - 'Usage: /res market rentable [residence] [cost] [days] ' + - 'Makes a residence rentable for [cost] money for every [days] number of days. If is true, the residence will automatically be able to be rented again after the current rent expires.' + release: + Description: Remove a residence from rent or rentable. + Info: + - 'Usage: /res market release [residence]' + - 'If you are the renter, this command releases the rent on the house for you.' + - 'If you are the owner, this command makes the residence not for rent anymore.' + current: + Description: Show residence your currently in. + Info: + - 'Usage: /res current' + lists: + Description: Predefined permission lists + Info: + - 'Predefined permissions that can be applied to a residence.' + SubCommands: + add: + Description: Add a list + Info: + - 'Usage: /res lists add ' + remove: + Description: Remove a list + Info: + - 'Usage: /res lists remove ' + apply: + Description: Apply a list to a residence + Info: + - 'Usage: /res lists apply ' + set: + Description: Set a flag + Info: + - 'Usage: /res lists set ' + pset: + Description: Set a player flag + Info: + - 'Usage: /res lists pset ' + gset: + Description: Set a group flag + Info: + - 'Usage: /res lists gset ' + view: + Description: View a list. + Info: + - 'Usage: /res lists view ' + server: + Description: Make land server owned (admin only). + Info: + - 'Usage: /resadmin server [residence]' + - 'Make a residence server owned.' + setowner: + Description: Change owner of a residence (admin only). + Info: + - 'Usage: /resadmin setowner [residence] [player]' + resreload: + Description: Reload residence (admin only). + Info: + - 'Usage: /resreload' + resload: + Description: Load residence save file (UNSAFE, admin only). + Info: + - 'Usage: /resload' + - 'UNSAFE command, does not save residences first.' + - 'Loads the residence save file after you have made changes.' + version: + Description: Show residence version + Info: + - 'Usage: /res version' diff --git a/src/plugin.yml b/src/plugin.yml new file mode 100644 index 0000000..9e00d77 --- /dev/null +++ b/src/plugin.yml @@ -0,0 +1,49 @@ +name: Residence +main: com.bekvon.bukkit.residence.ResidenceCommandListener +version: 2.7.0.0 +website: http://www.spigotmc.org/resources/residence-reloaded-1-8.2697/ +description: Cuboid Residence Plugin +authors: [bekvon,nate302,t00thpick1,喵♂呜] +contributors: [lemon42,smbarbour,inorixu,Shayana_fr] +softdepend: [Vault,Essentials,RealPlugin,BOSEconomy,iConomy,bPermissions,PermissionsBukkit,Permissions,WorldEdit,My Worlds] +commands: + res: + description: Manage Residences + usage: §c使用/res ? 获取更多帮助. + residence: + description: Manage Residences + usage: §c使用/residence ? 获取更多帮助. + resadmin: + description: Residence admin functions. + usage: §c使用/res ? or /resadmin ? 获取更多帮助. + resreload: + description: 重载领地插件. + usage: §c使用/resreload + resload: + description: 载入保存在配置文件的数据. + usage: §c使用/resload + rc: + description: §c在领地频道聊天. + usage: §c使用/rc 切换频道, 或者 /rc 发送消息. + resworld: + description: §c移除某个世界所有的领地. + usage: §c使用/resworld remove [world] 移除世界所有领地. +permissions: + residence.admin: + description: Gives you access to /resadmin + default: op + residence.admin.tp: + description: Allows to override tp flag + default: op + residence.admin.move: + description: Allows to override move flag + default: op + residence.create: + description: Allows you to create residences + default: op + residence.select: + description: Allows you to select an area to make residences + default: op + residence.versioncheck: + description: Notice to new version after connect + default: op