mirror of
https://github.com/YouHaveTrouble/PreventStabby.git
synced 2026-05-11 21:06:55 +00:00
Compare commits
132 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fccd413cf8 | |||
| af376437a0 | |||
| 636ccf516c | |||
| bd9ecc09ae | |||
| 9ba3bd1dc8 | |||
| 624cc335f2 | |||
| 23fc50ac46 | |||
| 466091f1ea | |||
| 138170c066 | |||
| c1d0fcf5b3 | |||
| b3d9ae720f | |||
| 667e441460 | |||
| fb913d97ae | |||
| d013eabd02 | |||
| df20c95e38 | |||
| c6f0df5d50 | |||
| 6a5e5f8d44 | |||
| ee3526c55d | |||
| 2189616a9e | |||
| 1484d262c0 | |||
| 4976ff56f0 | |||
| 477f042e91 | |||
| 409d115337 | |||
| 6c022dd88e | |||
| 01b6cd309c | |||
| 7253eab958 | |||
| 645068f66c | |||
| 27a68339ed | |||
| 42f8f92a6a | |||
| d3e8b590cb | |||
| 88917d65c3 | |||
| 4096cfe152 | |||
| 7f74826e2c | |||
| c369c110e5 | |||
| 375ef3de4e | |||
| 292b7b1b77 | |||
| 47ade3e0c0 | |||
| 7d8d27b1ef | |||
| 096599081b | |||
| 7b155d0b3e | |||
| 58a4a9f25d | |||
| 3c7904786e | |||
| 1aeb245666 | |||
| b9e2aefc40 | |||
| 8df1fe54e4 | |||
| b414f96257 | |||
| c11c455c53 | |||
| d859fd0aaa | |||
| 3919b0f44b | |||
| 0290629d27 | |||
| 4590b1d532 | |||
| 8ae6e9212c | |||
| fec1dd2ab6 | |||
| fba2f03aab | |||
| e30437694c | |||
| 8fcf34e310 | |||
| aac1f99374 | |||
| 7f1da79444 | |||
| 244ceb4dcc | |||
| ac1cafe0d9 | |||
| b3ce1913fd | |||
| 9a707b34a3 | |||
| d52648b4ff | |||
| 7d2c41646e | |||
| 61908b8fab | |||
| 5abf99cd6c | |||
| 3c014304ba | |||
| b361681600 | |||
| 7ada9eab29 | |||
| 78504ee097 | |||
| 7da6ff0ac9 | |||
| c83888837b | |||
| 4052afe4d3 | |||
| 93efa37e77 | |||
| 44a5c6d800 | |||
| 2ee577a08c | |||
| f5d38eefc3 | |||
| e5b566db67 | |||
| 9b18c435f6 | |||
| b99c14b631 | |||
| 6fd3e4b671 | |||
| 0ff0177f0b | |||
| 5a36ba7748 | |||
| 388e3c74a5 | |||
| 4088a6dd5b | |||
| a8e606dab5 | |||
| 35f0e6c9d8 | |||
| 51f0f6c93b | |||
| 52fb010270 | |||
| cd26d621e5 | |||
| 4c08041ee6 | |||
| 643511df31 | |||
| 94f97568d5 | |||
| 9a9a44939a | |||
| 1e7adf398a | |||
| c0ca85c44d | |||
| a86485a089 | |||
| bea0d9c7df | |||
| 0eccf1b1af | |||
| 2669c538cd | |||
| 36861084cc | |||
| f182c2c859 | |||
| 60b360f170 | |||
| 6de41b68bd | |||
| ee12750cf1 | |||
| 5f0bd41d8b | |||
| da454823f4 | |||
| 4e598dea2c | |||
| 227a4ca463 | |||
| 44ac3aa0f3 | |||
| 9249fe754b | |||
| 5a7b38e62f | |||
| 9d45a1ea02 | |||
| b78c7ecd90 | |||
| 1fa2a6f6a8 | |||
| 3b56d57faf | |||
| 477eb7f5de | |||
| f31536395a | |||
| acc2cf3117 | |||
| 3be97b57d4 | |||
| 938b10ada4 | |||
| 74835aa283 | |||
| e895cab31d | |||
| 0f535b8141 | |||
| 4c68f7e149 | |||
| c2033f5bcb | |||
| b43a9853e8 | |||
| ef7016d576 | |||
| e5d9ec456e | |||
| 31b87dc608 | |||
| 7655b2804e | |||
| 7495372ced |
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: YouHaveTrouble
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) 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
|
||||
this service 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 make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. 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.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE 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.
|
||||
|
||||
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
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 2 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, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision 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, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This 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.
|
||||
@@ -4,16 +4,16 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>eu.endermite</groupId>
|
||||
<artifactId>TogglePvP</artifactId>
|
||||
<version>1.0</version>
|
||||
<groupId>me.youhavetrouble.preventstabby</groupId>
|
||||
<artifactId>PreventStabby</artifactId>
|
||||
<version>2.1.3</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>TogglePvP</name>
|
||||
<name>PreventStabby</name>
|
||||
|
||||
<description>PvP toggle plugin</description>
|
||||
<description>Stop people from getting stabbed!</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<java.version>21</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
@@ -31,7 +31,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<version>3.6.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
@@ -40,6 +40,19 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>me.youhavetrouble.preventstabby.bstats</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<manifestEntries>
|
||||
<paperweight-mappings-namespace>mojang</paperweight-mappings-namespace>
|
||||
</manifestEntries>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@@ -55,32 +68,44 @@
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigotmc-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
<id>papermc-repo</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||
<id>sk89q-repo</id>
|
||||
<url>https://maven.enginehub.org/repo/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.16.5-R0.1-SNAPSHOT</version>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.21-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldguard</groupId>
|
||||
<artifactId>worldguard-bukkit</artifactId>
|
||||
<version>7.0.9-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.12</version>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.11.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.reflections</groupId>
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.12</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -1,43 +1,34 @@
|
||||
<h2>TogglePvP ⚔</h2>
|
||||
<h1>PreventStabby ⚔</h1>
|
||||
|
||||
Use Issues section to report bugs or submit suggestions.
|
||||
|
||||
<h3>Commands</h3>
|
||||
Permission: <code>togglepvp.command</code> (given by default to everyone) :
|
||||
You can find available commands <a href="https://github.com/YouHaveTrouble/PreventStabby/wiki/Commands">HERE</a>.
|
||||
|
||||
<h3>Configuration</h3>
|
||||
Explanation of all available config options is <a href="https://github.com/YouHaveTrouble/PreventStabby/wiki/Config">HERE</a>.
|
||||
|
||||
<h3>Placeholders</h3>
|
||||
List of all PlaceholderAPI placeholders can be found <a href="https://github.com/YouHaveTrouble/PreventStabby/wiki/Placeholders">HERE</a>.
|
||||
|
||||
<h3>Developer API</h3>
|
||||
Developer API documetation is <a href="https://github.com/YouHaveTrouble/PreventStabby/wiki/Developer-API">HERE</a>!
|
||||
|
||||
<h2>Features</h2>
|
||||
<ul>
|
||||
<li>/pvp help- displays help message</li>
|
||||
<li>Per-player PvP Toggle</li>
|
||||
<li>Global PvP override, allowing to ignore personal toggles temporarily</li>
|
||||
<li>Block all forms of player-induced damage when PvP off</li>
|
||||
<li>Block damage done to pets and mounts when PvP off</li>
|
||||
<li>Block the ability to pour lava and set fire under player's feet</li>
|
||||
<li>Block channeling tridents spawning fire under players with PvP off</li>
|
||||
<li>Block fishing pole pulling for players with PvP off</li>
|
||||
<li>Pets do not attack players with PvP off</li>
|
||||
<li>Configurable PvP protection after login</li>
|
||||
<li>Configurable PvP protection after teleport</li>
|
||||
<li>Kill players that logged out during combat</li>
|
||||
<li>Block specific commands while in combat</li>
|
||||
<li>Block teleports in combat (might cause issues with some plugins)</li>
|
||||
<li>Toggles for eggs and snowballs applying knockback</li>
|
||||
<li>Extensive developer API</li>
|
||||
</ul>
|
||||
|
||||
Permission: <code>togglepvp.command.toggle</code> (given by default to everyone) :
|
||||
<ul>
|
||||
<li>/pvp toggle - toggles PvP</li>
|
||||
<li>/pvp on - enables PvP (aliases: enable)</li>
|
||||
<li>/pvp off - disables PvP (aliases: disable)</li>
|
||||
</ul>
|
||||
|
||||
Permission: <code>togglepvp.command.toggle.others</code> (given by default to ops) :
|
||||
<ul>
|
||||
<li>/pvp toggle [player] - toggles other player's PvP</li>
|
||||
<li>/pvp on [player] - enables other player's PvP (aliases: enable)</li>
|
||||
<li>/pvp off [player] - disables other player's PvP (aliases: disable)</li>
|
||||
</ul>
|
||||
|
||||
<h3>Features</h3>
|
||||
Player who disables PvP cannot get hurt by any player induced damage.
|
||||
They also can't deal any damage to other players.
|
||||
This includes basic attacks, projectiles, splash potions,
|
||||
lingering potions and lightning strikes from channeling trident enchant.
|
||||
Additionally lightning strikes from channeling cannot spawn fire under
|
||||
players, who have pvp disabled and it's impossible to use
|
||||
fishing rod on players who have pvp disabled.
|
||||
|
||||
There is also a feature that disallows pouring lava or using
|
||||
flint and steel nearby players with disabled pvp. You can
|
||||
either disable it in config or set its radius.
|
||||
|
||||
All the protections are extended to tameable entities (pets) that set player's uuid as their owner on tame.
|
||||
|
||||
Pets will not attack players with pvp off or if their owner has pvp off.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
package eu.endermite.togglepvp;
|
||||
|
||||
import eu.endermite.togglepvp.commands.MainCommand;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.PlayerManager;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.Listener;
|
||||
import eu.endermite.togglepvp.util.DatabaseSQLite;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.reflections.Reflections;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public final class TogglePvp extends JavaPlugin {
|
||||
|
||||
@Getter private static TogglePvp plugin;
|
||||
private ConfigCache configCache;
|
||||
private PlayerManager playerManager;
|
||||
private DatabaseSQLite sqLite;
|
||||
private SmartCache smartCache;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
plugin = this;
|
||||
reloadPluginConfig();
|
||||
File dbFile = new File("plugins/TogglePvP");
|
||||
sqLite = new DatabaseSQLite("jdbc:sqlite:plugins/TogglePvP/TogglePvP.db", dbFile);
|
||||
sqLite.createDatabaseFile();
|
||||
if (!sqLite.testConnection()) {
|
||||
getLogger().severe("Error with accessing database. Check if server has write rights.");
|
||||
getLogger().severe("Plugin will now disable.");
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
playerManager = new PlayerManager();
|
||||
smartCache = new SmartCache();
|
||||
smartCache.runSmartCache();
|
||||
|
||||
// Register listeners
|
||||
Reflections reflections = new Reflections(new String[]{"eu.endermite.togglepvp"});
|
||||
Set<Class<?>> listenerClasses = reflections.getTypesAnnotatedWith(Listener.class);
|
||||
listenerClasses.forEach((listener)-> {
|
||||
try {
|
||||
getServer().getPluginManager().registerEvents((org.bukkit.event.Listener) listener.getConstructor().newInstance(), this);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
getLogger().severe("Error with registering listeners.");
|
||||
getLogger().severe("Plugin will now disable.");
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
});
|
||||
|
||||
// Register command
|
||||
Objects.requireNonNull(getCommand("pvp")).setExecutor(new MainCommand());
|
||||
Objects.requireNonNull(getCommand("pvp")).setTabCompleter(new MainCommand());
|
||||
}
|
||||
|
||||
public void reloadPluginConfig() {
|
||||
saveDefaultConfig();
|
||||
reloadConfig();
|
||||
configCache = new ConfigCache();
|
||||
}
|
||||
|
||||
public void reloadPluginConfig(CommandSender commandSender) {
|
||||
getServer().getScheduler().runTaskAsynchronously(this, () -> {
|
||||
reloadPluginConfig();
|
||||
commandSender.sendMessage("TogglePvP configuration reloaded.");
|
||||
});
|
||||
}
|
||||
|
||||
public ConfigCache getConfigCache() {
|
||||
return configCache;
|
||||
}
|
||||
|
||||
public PlayerManager getPlayerManager() {
|
||||
return playerManager;
|
||||
}
|
||||
|
||||
public DatabaseSQLite getSqLite() {return sqLite;}
|
||||
|
||||
public SmartCache getSmartCache() {
|
||||
return smartCache;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package eu.endermite.togglepvp;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class TogglePvpAPI {
|
||||
|
||||
/**
|
||||
* Sets player PvP state. This will always save to database.
|
||||
* @param uuid uuid of player to set
|
||||
* @param newState State to set
|
||||
*/
|
||||
public static void setPvpEnabled(UUID uuid, boolean newState) {
|
||||
TogglePvp.getPlugin().getSmartCache().setPlayerPvpState(uuid, newState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets player's PvP state. If player is not cached this will query the database.
|
||||
* @param uuid uuid of player to get data from.
|
||||
* @return true if enabled, false if disabled
|
||||
*/
|
||||
public static boolean getPvpEnabled(UUID uuid) {
|
||||
return TogglePvp.getPlugin().getSmartCache().getPlayerData(uuid).isPvpEnabled();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package eu.endermite.togglepvp.commands;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HelpCommand {
|
||||
|
||||
public static void help(CommandSender sender, String[] args) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(TogglePvp.getPlugin(), () -> {
|
||||
|
||||
List<String> helpPage = new ArrayList<>();
|
||||
|
||||
helpPage.add(PluginMessages.parseMessage("&b&m &bTogglePvP Help&b&m "));
|
||||
helpPage.add(PluginMessages.parseMessage("&9/pvp &b&lhelp &f- shows this message"));
|
||||
if (sender.hasPermission("togglepvp.command.toggle")) {
|
||||
helpPage.add(PluginMessages.parseMessage("&9/pvp &b&l[on/off] &f- enables or disables PvP"));
|
||||
helpPage.add(PluginMessages.parseMessage("&9/pvp &b<oggle &f- toggles PvP status"));
|
||||
}
|
||||
String[] helpReady = helpPage.toArray(new String[0]);
|
||||
sender.sendMessage(helpReady);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package eu.endermite.togglepvp.commands;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MainCommand implements TabExecutor {
|
||||
|
||||
private final HashMap<String, String> subCommands = new HashMap<>();
|
||||
|
||||
public MainCommand() {
|
||||
subCommands.put("help", "togglepvp.command");
|
||||
subCommands.put("toggle", "togglepvp.command.toggle");
|
||||
subCommands.put("on", "togglepvp.command.toggle");
|
||||
subCommands.put("enable", "togglepvp.command.toggle");
|
||||
subCommands.put("off", "togglepvp.command.toggle");
|
||||
subCommands.put("disable", "togglepvp.command.toggle");
|
||||
subCommands.put("reload", "togglepvp.command.reload");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (sender.hasPermission("togglepvp.command")) {
|
||||
if (args.length >= 1) {
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "help":
|
||||
HelpCommand.help(sender, args);
|
||||
break;
|
||||
case "toggle":
|
||||
PvpToggleCommand.toggle(sender, args);
|
||||
break;
|
||||
case "on":
|
||||
case "enable":
|
||||
PvpToggleCommand.enable(sender, args);
|
||||
break;
|
||||
case "off":
|
||||
case "disable":
|
||||
PvpToggleCommand.disable(sender, args);
|
||||
break;
|
||||
case "reload":
|
||||
ReloadCommand.reload(sender);
|
||||
break;
|
||||
default:
|
||||
sender.sendMessage(PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getNo_such_command()));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
HelpCommand.help(sender, args);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getNo_permission()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
List<String> commands = new ArrayList<>();
|
||||
if (args.length == 1) {
|
||||
String arg1 = args[0].toLowerCase();
|
||||
for (Map.Entry<String, String> entry : subCommands.entrySet()) {
|
||||
if (entry.getKey().toLowerCase().startsWith(arg1) && sender.hasPermission(entry.getValue()))
|
||||
commands.add(entry.getKey());
|
||||
}
|
||||
return commands;
|
||||
} else if (args.length == 2 && sender.hasPermission("togglepvp.command.toggle")) {
|
||||
switch (args[0].toLowerCase()) {
|
||||
default:
|
||||
break;
|
||||
case "toggle":
|
||||
case "on":
|
||||
case "enable":
|
||||
case "off":
|
||||
case "disable":
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
commands.add(player.getName());
|
||||
}
|
||||
break;
|
||||
}
|
||||
return commands;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
package eu.endermite.togglepvp.commands;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PvpToggleCommand {
|
||||
|
||||
public static void toggle(CommandSender sender, String[] args) {
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(TogglePvp.getPlugin(), () -> {
|
||||
|
||||
if (!sender.hasPermission("togglepvp.command.toggle")) {
|
||||
String message = ChatColor.translateAlternateColorCodes('&', TogglePvp.getPlugin().getConfigCache().getNo_permission());
|
||||
sender.sendMessage(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 1) {
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
|
||||
if (CombatTimer.isInCombat(player.getUniqueId())) {
|
||||
sender.sendMessage(PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getCant_do_that_during_combat()));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean currentState = TogglePvp.getPlugin().getPlayerManager().togglePlayerPvpState(player.getUniqueId());
|
||||
|
||||
String message = "";
|
||||
if (currentState) {
|
||||
message = PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getPvp_enabled());
|
||||
} else {
|
||||
message = PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getPvp_disabled());
|
||||
}
|
||||
player.sendMessage(message);
|
||||
} else {
|
||||
sender.sendMessage("Try /pvp toggle <player>");
|
||||
}
|
||||
} else if (args.length == 2) {
|
||||
if (!sender.hasPermission("togglepvp.command.toggle.others")) {
|
||||
String message = ChatColor.translateAlternateColorCodes('&', TogglePvp.getPlugin().getConfigCache().getNo_permission());
|
||||
sender.sendMessage(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
if (CombatTimer.isInCombat(player.getUniqueId())) {
|
||||
sender.sendMessage(PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getCant_do_that_during_combat()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
boolean currentState = TogglePvp.getPlugin().getPlayerManager().togglePlayerPvpState(player.getUniqueId());
|
||||
String message;
|
||||
if (currentState) {
|
||||
message = TogglePvp.getPlugin().getConfigCache().getPvp_enabled_other();
|
||||
} else {
|
||||
message = TogglePvp.getPlugin().getConfigCache().getPvp_disabled_other();
|
||||
}
|
||||
sender.sendMessage(PluginMessages.parsePlayerName(player, message));
|
||||
|
||||
} catch (NullPointerException e) {
|
||||
sender.sendMessage(PluginMessages.parseMessage("&cPlayer offline."));
|
||||
}
|
||||
} else {
|
||||
if (sender.hasPermission("togglepvp.command.toggle.others")) {
|
||||
sender.sendMessage("Try /pvp toggle <player>");
|
||||
} else {
|
||||
sender.sendMessage("Try /pvp toggle");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void enable(CommandSender sender, String[] args) {
|
||||
if (!sender.hasPermission("togglepvp.command.toggle")) {
|
||||
String message = ChatColor.translateAlternateColorCodes('&', TogglePvp.getPlugin().getConfigCache().getNo_permission());
|
||||
sender.sendMessage(message);
|
||||
return;
|
||||
}
|
||||
if (args.length == 1) {
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
if (CombatTimer.isInCombat(player.getUniqueId())) {
|
||||
sender.sendMessage(PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getCant_do_that_during_combat()));
|
||||
return;
|
||||
}
|
||||
TogglePvp.getPlugin().getPlayerManager().setPlayerPvpState(player.getUniqueId(), true);
|
||||
String message = PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getPvp_enabled());
|
||||
player.sendMessage(message);
|
||||
} else {
|
||||
sender.sendMessage("Try /pvp enable <player>");
|
||||
}
|
||||
} else if (args.length == 2) {
|
||||
if (!sender.hasPermission("togglepvp.command.toggle.others")) {
|
||||
String message = ChatColor.translateAlternateColorCodes('&', TogglePvp.getPlugin().getConfigCache().getNo_permission());
|
||||
sender.sendMessage(message);
|
||||
return;
|
||||
}
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
if (CombatTimer.isInCombat(player.getUniqueId())) {
|
||||
sender.sendMessage(PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getCant_do_that_during_combat()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
String message = TogglePvp.getPlugin().getConfigCache().getPvp_enabled_other();
|
||||
sender.sendMessage(PluginMessages.parsePlayerName(player, message));
|
||||
TogglePvp.getPlugin().getPlayerManager().setPlayerPvpState(player.getUniqueId(), true);
|
||||
} catch (NullPointerException e) {
|
||||
sender.sendMessage(PluginMessages.parseMessage("&cPlayer offline."));
|
||||
}
|
||||
} else {
|
||||
if (sender.hasPermission("togglepvp.command.toggle.others")) {
|
||||
sender.sendMessage("Try /pvp enable <player>");
|
||||
} else {
|
||||
sender.sendMessage("Try /pvp enable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void disable(CommandSender sender, String[] args) {
|
||||
if (!sender.hasPermission("togglepvp.command.toggle")) {
|
||||
String message = ChatColor.translateAlternateColorCodes('&', TogglePvp.getPlugin().getConfigCache().getNo_permission());
|
||||
sender.sendMessage(message);
|
||||
return;
|
||||
}
|
||||
if (args.length == 1) {
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
if (CombatTimer.isInCombat(player.getUniqueId())) {
|
||||
sender.sendMessage(PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getCant_do_that_during_combat()));
|
||||
return;
|
||||
}
|
||||
TogglePvp.getPlugin().getPlayerManager().setPlayerPvpState(player.getUniqueId(), false);
|
||||
String message = PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getPvp_disabled());
|
||||
player.sendMessage(message);
|
||||
} else {
|
||||
sender.sendMessage("Try /pvp disable <player>");
|
||||
}
|
||||
} else if (args.length == 2) {
|
||||
if (!sender.hasPermission("togglepvp.command.toggle.others")) {
|
||||
String message = TogglePvp.getPlugin().getConfigCache().getNo_permission();
|
||||
sender.sendMessage(message);
|
||||
return;
|
||||
}
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
if (CombatTimer.isInCombat(player.getUniqueId())) {
|
||||
sender.sendMessage(PluginMessages.parseMessage(TogglePvp.getPlugin().getConfigCache().getCant_do_that_during_combat()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
String message = TogglePvp.getPlugin().getConfigCache().getPvp_disabled_other();
|
||||
sender.sendMessage(PluginMessages.parsePlayerName(player, message));
|
||||
TogglePvp.getPlugin().getPlayerManager().setPlayerPvpState(player.getUniqueId(), true);
|
||||
} catch (NullPointerException e) {
|
||||
sender.sendMessage(PluginMessages.parseMessage("&cPlayer offline."));
|
||||
}
|
||||
} else {
|
||||
if (sender.hasPermission("togglepvp.command.toggle.others")) {
|
||||
sender.sendMessage("Try /pvp disable <player>");
|
||||
} else {
|
||||
sender.sendMessage("Try /pvp disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package eu.endermite.togglepvp.commands;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class ReloadCommand {
|
||||
|
||||
public static void reload(CommandSender sender) {
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(TogglePvp.getPlugin(), () -> {
|
||||
if (!sender.hasPermission("togglepvp.command.reload")) {
|
||||
String message = ChatColor.translateAlternateColorCodes('&', TogglePvp.getPlugin().getConfigCache().getNo_permission());
|
||||
sender.sendMessage(message);
|
||||
return;
|
||||
}
|
||||
TogglePvp.getPlugin().reloadPluginConfig(sender);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package eu.endermite.togglepvp.config;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
|
||||
public class ConfigCache {
|
||||
|
||||
@Getter private final boolean pvp_enabled_by_default;
|
||||
@Getter private final boolean lava_and_fire_stopper_enabled;
|
||||
@Getter private final String pvp_enabled;
|
||||
@Getter private final String pvp_disabled;
|
||||
@Getter private final String cannot_attack_victim;
|
||||
@Getter private final String cannot_attack_attacker;
|
||||
@Getter private final String cannot_attack_pets_victim;
|
||||
@Getter private final String cannot_attack_pets_attacker;
|
||||
@Getter private final String no_permission;
|
||||
@Getter private final String no_such_command;
|
||||
@Getter private final String pvp_enabled_other;
|
||||
@Getter private final String pvp_disabled_other;
|
||||
@Getter private final double lava_and_fire_stopper_radius;
|
||||
@Getter private final boolean channeling_enchant_disabled;
|
||||
@Getter private final long cache_time;
|
||||
@Getter private final long combat_time;
|
||||
@Getter private final boolean punish_for_combat_logout;
|
||||
@Getter private final boolean punish_for_combat_logout_announce;
|
||||
@Getter private final String punish_for_combat_logout_message;
|
||||
@Getter private final String entering_combat;
|
||||
@Getter private final String leaving_combat;
|
||||
@Getter final String cant_do_that_during_combat;
|
||||
@Getter final boolean only_owner_can_interact_with_pet;
|
||||
|
||||
public ConfigCache() {
|
||||
|
||||
Configuration config = TogglePvp.getPlugin().getConfig();
|
||||
|
||||
// Settings
|
||||
this.pvp_enabled_by_default = config.getBoolean("settings.pvp_enabled_by_default", false);
|
||||
|
||||
this.lava_and_fire_stopper_enabled = config.getBoolean("settings.lava_and_fire_stopper.enabled", true);
|
||||
this.lava_and_fire_stopper_radius = config.getDouble("settings.lava_and_fire_stopper.radius", 2.5);
|
||||
|
||||
this.channeling_enchant_disabled = config.getBoolean("settings.channeling_enchant_disabled", true);
|
||||
|
||||
this.combat_time = config.getLong("settings.combat_time", 25L);
|
||||
this.punish_for_combat_logout = config.getBoolean("settings.punish_for_combat_logout.enabled", true);
|
||||
this.punish_for_combat_logout_announce = config.getBoolean("settings.punish_for_combat_logout.announce", true);
|
||||
this.punish_for_combat_logout_message = config.getString("settings.punish_for_combat_logout.message", "&f%player% logged out while in combat. What a loser.");
|
||||
this.only_owner_can_interact_with_pet = config.getBoolean("settings.only_owner_can_interact_with_pet", false);
|
||||
this.cache_time = config.getLong("settings.cache_time", 30L);
|
||||
|
||||
// Messages
|
||||
this.pvp_enabled = config.getString("messages.pvp_enabled", "&cYou enabled PvP!");
|
||||
this.pvp_disabled = config.getString("messages.pvp_disabled", "&cYou disabled PvP!");
|
||||
this.cannot_attack_victim = config.getString("messages.cannot_attack_victim", "&cYou can't attack players that have PvP turned off!");
|
||||
this.cannot_attack_attacker = config.getString("messages.cannot_attack_attacker", "&cYou can't attack players while you have PvP turned off!");
|
||||
this.cannot_attack_pets_victim = config.getString("messages.cannot_attack_pets_victim", "&cYou can't attack pets while you have PvP turned off");
|
||||
this.cannot_attack_pets_attacker = config.getString("messages.cannot_attack_pets_attacker", "&cYou can't attack pets of players that have PvP turned off");
|
||||
this.no_permission = config.getString("messages.no_permission", "&cYou don't have permission to use that.");
|
||||
this.no_such_command = config.getString("messages.no_such_command", "&cNo such command.");
|
||||
this.pvp_enabled_other = config.getString("messages.pvp_enabled_others", "&cYou've enabled %player%'s PvP.");
|
||||
this.pvp_disabled_other = config.getString("messages.pvp_disabled_others", "&cYou've disabled %player%'s PvP.");
|
||||
this.entering_combat = config.getString("messages.entering_combat", "&cEntering combat");
|
||||
this.leaving_combat = config.getString("messages.leaving_combat", "&cLeaving combat");
|
||||
this.cant_do_that_during_combat = config.getString("messages.cant_do_that_during_combat", "&cYou can't do that while in combat!");
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.pets;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import java.util.UUID;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PetHitByExplosionListener implements Listener {
|
||||
|
||||
/**
|
||||
* Cancels explosion damage for pets with pvp off that is caused by players
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerHitByExplosion(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
if (!(event.getEntity() instanceof Tameable))
|
||||
return;
|
||||
|
||||
if (!event.getCause().equals(EntityDamageEvent.DamageCause.ENTITY_EXPLOSION))
|
||||
return;
|
||||
|
||||
Tameable victim = (Tameable) event.getEntity();
|
||||
if (victim.getOwner() == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
UUID damageruuid = UUID.fromString(event.getDamager().getMetadata("PLAYEREXPLODED").get(0).asString());
|
||||
if (victim.getOwner().getUniqueId() == damageruuid) {
|
||||
return;
|
||||
}
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
if (!smartCache.getPlayerData(damageruuid).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damageruuid, config.getCannot_attack_pets_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damageruuid, config.getCannot_attack_pets_victim());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damageruuid, victim.getOwner().getUniqueId());
|
||||
} catch (NullPointerException | IndexOutOfBoundsException ignored) {}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.pets;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PetHitByFireworkListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onFireworkDamage(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
if (event.getDamager() instanceof Firework && event.getEntity() instanceof Tameable) {
|
||||
Tameable victim = (Tameable) event.getEntity();
|
||||
if (victim.getOwner() == null)
|
||||
return;
|
||||
Firework firework = (Firework) event.getDamager();
|
||||
if (!(firework.getShooter() instanceof Player))
|
||||
return;
|
||||
Player damager = (Player) firework.getShooter();
|
||||
if (victim.getOwner() == damager)
|
||||
return;
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager.getUniqueId(), TogglePvp.getPlugin().getConfigCache().getCannot_attack_pets_attacker());
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager.getUniqueId(), TogglePvp.getPlugin().getConfigCache().getCannot_attack_pets_victim());
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getOwner().getUniqueId());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.pets;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PetHitBySplashPotionListener implements Listener {
|
||||
|
||||
/**
|
||||
* If thrown potion applies negative effects and it's thrown by a player
|
||||
* it will have no effect on a pet of a player with pvp off
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onWolfHitBySplashPotion(org.bukkit.event.entity.PotionSplashEvent event) {
|
||||
|
||||
if (!(event.getEntity().getShooter() instanceof Player))
|
||||
return;
|
||||
|
||||
boolean harmful = false;
|
||||
|
||||
for (PotionEffect effect : event.getPotion().getEffects()) {
|
||||
if (effect.getType().equals(PotionEffectType.BLINDNESS) ||
|
||||
effect.getType().equals(PotionEffectType.CONFUSION) ||
|
||||
effect.getType().equals(PotionEffectType.HARM) ||
|
||||
effect.getType().equals(PotionEffectType.HUNGER) ||
|
||||
effect.getType().equals(PotionEffectType.POISON) ||
|
||||
effect.getType().equals(PotionEffectType.SLOW_DIGGING) ||
|
||||
effect.getType().equals(PotionEffectType.WEAKNESS) ||
|
||||
effect.getType().equals(PotionEffectType.SLOW) ||
|
||||
effect.getType().equals(PotionEffectType.WITHER)) {
|
||||
harmful = true;
|
||||
}
|
||||
}
|
||||
if (!harmful)
|
||||
return;
|
||||
for (Entity entity : event.getAffectedEntities()) {
|
||||
if (entity instanceof Tameable) {
|
||||
Player damager = (Player) event.getEntity().getShooter();
|
||||
Tameable victim = (Tameable) entity;
|
||||
if (victim.getOwner() == null || victim.getOwner() == damager)
|
||||
continue;
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
|
||||
if (!TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(damager.getUniqueId())) {
|
||||
event.setIntensity(victim, 0);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker());
|
||||
continue;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
event.setIntensity(victim, 0);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
continue;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getOwner().getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.pets;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PetLeashListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPetLeash(org.bukkit.event.entity.PlayerLeashEntityEvent event) {
|
||||
if (event.getEntity() instanceof Tameable) {
|
||||
Tameable victim = (Tameable) event.getEntity();
|
||||
if (victim.getOwner() == null)
|
||||
return;
|
||||
|
||||
Player damager = event.getPlayer();
|
||||
if (victim.getOwner() == damager)
|
||||
return;
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_victim());
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.pets;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PetTargettingPetListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onWolfAttackWolf(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
if (event.getDamager() instanceof Tameable && event.getEntity() instanceof Tameable) {
|
||||
Tameable damager = (Tameable) event.getDamager();
|
||||
Tameable victim = (Tameable) event.getEntity();
|
||||
if (damager.getOwner() == null || victim.getOwner() == null)
|
||||
return;
|
||||
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
|
||||
boolean damagerPvpEnabled = smartCache.getPlayerData(damager.getOwner().getUniqueId()).isPvpEnabled();
|
||||
boolean victimPvpEnabled = smartCache.getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled();
|
||||
if (!victimPvpEnabled || !damagerPvpEnabled) {
|
||||
if (damager instanceof Wolf) {
|
||||
Wolf wolf = (Wolf) damager;
|
||||
wolf.setAngry(false);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.pets;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PetTargettingPlayerListener implements Listener {
|
||||
/**
|
||||
* Stops pets with owners targetting players with pvp off
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onWolfTarget(org.bukkit.event.entity.EntityTargetEvent event) {
|
||||
if (!(event.getEntity() instanceof Tameable))
|
||||
return;
|
||||
|
||||
Tameable entity = (Tameable) event.getEntity();
|
||||
if (entity.getOwner() == null)
|
||||
return;
|
||||
|
||||
if (event.getTarget() instanceof Player) {
|
||||
boolean attackerPvPEnabled = TogglePvp.getPlugin().getSmartCache().getPlayerData(entity.getOwner().getUniqueId()).isPvpEnabled();
|
||||
Player victim = (Player) event.getTarget();
|
||||
boolean victimPvpEnabled = TogglePvp.getPlugin().getSmartCache().getPlayerData(victim.getUniqueId()).isPvpEnabled();
|
||||
if (!attackerPvPEnabled || !victimPvpEnabled) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.pets;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlayerAttackPetListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerAttacktameable(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
|
||||
if (event.getDamager() instanceof Player && event.getEntity() instanceof Tameable) {
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
Tameable tameable = (Tameable) event.getEntity();
|
||||
if (tameable.getOwner() == null)
|
||||
return;
|
||||
|
||||
Player damager = (Player) event.getDamager();
|
||||
|
||||
if (damager.getUniqueId() == tameable.getOwner().getUniqueId())
|
||||
return;
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
boolean damagerPvpState = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(damager.getUniqueId());
|
||||
|
||||
if (!damagerPvpState) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(tameable.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_victim());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), tameable.getOwner().getUniqueId());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.pets;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlayerHitPetWithProjectile implements Listener {
|
||||
|
||||
/**
|
||||
* Cancels damage done by projectiles to pets of players with pvp off
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerHitWolfWithProjectile(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
if (event.getEntity() instanceof Tameable && event.getDamager() instanceof Projectile) {
|
||||
Projectile projectile = (Projectile) event.getDamager();
|
||||
if (!(projectile.getShooter() instanceof Player))
|
||||
return;
|
||||
|
||||
Tameable victim = (Tameable) event.getEntity();
|
||||
Player damager = (Player) projectile.getShooter();
|
||||
if (victim.getOwner() == null || victim.getOwner() == damager)
|
||||
return;
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker());
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_victim());
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getOwner().getUniqueId());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.pets;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlayerInteractWithPetListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerInteractWithPet(org.bukkit.event.player.PlayerInteractEntityEvent event) {
|
||||
|
||||
if (!TogglePvp.getPlugin().getConfigCache().isOnly_owner_can_interact_with_pet())
|
||||
return;
|
||||
|
||||
if (!(event.getRightClicked() instanceof Tameable))
|
||||
return;
|
||||
|
||||
Tameable tameable = (Tameable) event.getRightClicked();
|
||||
if (tameable.getOwner() == null)
|
||||
return;
|
||||
|
||||
if (tameable.getOwner().getUniqueId().equals(event.getPlayer().getUniqueId()))
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.player;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PetAttackPlayerListener implements Listener {
|
||||
|
||||
/**
|
||||
* Pets stop following player with pvp off after trying to hit them
|
||||
* This is to fix any inconsistancy with pet behavior
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onWolfAttack(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
if (!(event.getDamager() instanceof Tameable))
|
||||
return;
|
||||
|
||||
Tameable entity = (Tameable) event.getDamager();
|
||||
if (entity.getOwner() != null && event.getEntity() instanceof Player) {
|
||||
|
||||
boolean damagerPvpEnabled = TogglePvp.getPlugin().getSmartCache().getPlayerData(entity.getOwner().getUniqueId()).isPvpEnabled();
|
||||
Player victim = (Player) event.getEntity();
|
||||
boolean victimPvpEnabled = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId());
|
||||
if (!victimPvpEnabled || !damagerPvpEnabled) {
|
||||
if (entity instanceof Wolf) {
|
||||
Wolf wolf = (Wolf) entity;
|
||||
wolf.setAngry(false);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(entity.getOwner().getUniqueId(), victim.getUniqueId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.player;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlayerAttackListener implements Listener {
|
||||
|
||||
/**
|
||||
* Cancels basic attacks done to player with pvp off
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerAttack(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
Entity damagerEntity = event.getDamager();
|
||||
Entity victimEntity = event.getEntity();
|
||||
|
||||
if (damagerEntity instanceof Player && victimEntity instanceof Player) {
|
||||
Player damager = (Player) damagerEntity;
|
||||
Player victim = (Player) victimEntity;
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
|
||||
boolean damagerPvpEnabled = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(damager.getUniqueId());
|
||||
boolean victimPvpEnabled = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId());
|
||||
|
||||
if (!damagerPvpEnabled) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker());
|
||||
return;
|
||||
}
|
||||
if (!victimPvpEnabled) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.player;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.EnderCrystal;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.minecart.ExplosiveMinecart;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import java.util.UUID;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlayerHitByExplosionListener implements Listener {
|
||||
|
||||
/**
|
||||
* Cancels explosion damage for players with pvp off that is caused by players
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerHitByExplosion(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
if (event.getEntity() instanceof Player) {
|
||||
if (!event.getCause().equals(EntityDamageEvent.DamageCause.ENTITY_EXPLOSION)) {
|
||||
return;
|
||||
}
|
||||
Player victim = (Player) event.getEntity();
|
||||
try {
|
||||
UUID damageruuid = UUID.fromString(event.getDamager().getMetadata("PLAYEREXPLODED").get(0).asString());
|
||||
if (victim.getUniqueId().equals(damageruuid))
|
||||
return;
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
if (!TogglePvp.getPlugin().getSmartCache().getPlayerData(damageruuid).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damageruuid, config.getCannot_attack_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId())) {
|
||||
PluginMessages.sendActionBar(damageruuid, config.getCannot_attack_victim());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damageruuid, victim.getUniqueId());
|
||||
|
||||
} catch (NullPointerException | IndexOutOfBoundsException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags ender crystal with exploder uuid
|
||||
*/
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerHitEnderCrystal(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
if (event.getEntity() instanceof EnderCrystal) {
|
||||
EnderCrystal enderCrystal = (EnderCrystal) event.getEntity();
|
||||
if (event.getDamager() instanceof Player) {
|
||||
enderCrystal.setMetadata("PLAYEREXPLODED", new FixedMetadataValue(TogglePvp.getPlugin(), event.getDamager().getUniqueId().toString()));
|
||||
} else if (event.getDamager() instanceof Projectile) {
|
||||
Projectile projectile = (Projectile) event.getDamager();
|
||||
if (projectile.getShooter() instanceof Player) {
|
||||
Player damager = (Player) projectile.getShooter();
|
||||
enderCrystal.setMetadata("PLAYEREXPLODED", new FixedMetadataValue(TogglePvp.getPlugin(), damager.getUniqueId().toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag ender crystal with destroying players uuid
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerPrimedTnt(org.bukkit.event.entity.ExplosionPrimeEvent event) {
|
||||
if (event.getEntity() instanceof TNTPrimed) {
|
||||
TNTPrimed tntPrimed = (TNTPrimed) event.getEntity();
|
||||
if (tntPrimed.getSource() instanceof Player) {
|
||||
Player damager = (Player) tntPrimed.getSource();
|
||||
tntPrimed.setMetadata("PLAYEREXPLODED", new FixedMetadataValue(TogglePvp.getPlugin(), damager.getUniqueId().toString()));
|
||||
} else if (tntPrimed.getSource() instanceof TNTPrimed) {
|
||||
try {
|
||||
TNTPrimed sourceTnt = (TNTPrimed) tntPrimed.getSource();
|
||||
String damagerUuid = sourceTnt.getMetadata("PLAYEREXPLODED").get(0).asString();
|
||||
tntPrimed.setMetadata("PLAYEREXPLODED", new FixedMetadataValue(TogglePvp.getPlugin(), damagerUuid));
|
||||
} catch (NullPointerException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag TNT minecart with placing player uuid
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerPlacedTntMinecart(org.bukkit.event.entity.EntityPlaceEvent event) {
|
||||
if (event.getEntityType().equals(EntityType.MINECART_TNT)) {
|
||||
if (event.getPlayer() != null) {
|
||||
event.getEntity().setMetadata("PLAYEREXPLODED", new FixedMetadataValue(TogglePvp.getPlugin(), event.getPlayer().getUniqueId().toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag TNT minecart with uuid of player who last nudged it
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerNudgedTntMinecart(org.bukkit.event.vehicle.VehicleEntityCollisionEvent event) {
|
||||
if (event.getVehicle() instanceof ExplosiveMinecart && event.getEntity() instanceof Player) {
|
||||
Player damager = (Player) event.getEntity();
|
||||
event.getVehicle().setMetadata("PLAYEREXPLODED", new FixedMetadataValue(TogglePvp.getPlugin(), damager.getUniqueId().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.player;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlayerHitByFireworkListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onFireworkDamage(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
if (event.getDamager() instanceof Firework && event.getEntity() instanceof Player) {
|
||||
Player victim = (Player) event.getEntity();
|
||||
Firework firework = (Firework) event.getDamager();
|
||||
if (firework.getShooter() instanceof Player) {
|
||||
Player damager = (Player) firework.getShooter();
|
||||
if (damager == victim) {
|
||||
return;
|
||||
}
|
||||
boolean damagerPvpEnabled = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId());
|
||||
if (!damagerPvpEnabled) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager.getUniqueId(), TogglePvp.getPlugin().getConfigCache().getCannot_attack_attacker());
|
||||
return;
|
||||
}
|
||||
boolean victimPvpEnabled = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId());
|
||||
if (!victimPvpEnabled) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager.getUniqueId(), TogglePvp.getPlugin().getConfigCache().getCannot_attack_victim());
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.player;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlayerHitByProjectileListener implements Listener {
|
||||
|
||||
/**
|
||||
* Cancels damage done by projectiles to player with pvp off
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerHitProjectile(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
|
||||
if (event.getEntity() instanceof Player && event.getDamager() instanceof Projectile) {
|
||||
Projectile projectile = (Projectile) event.getDamager();
|
||||
if (projectile.getShooter() instanceof Player) {
|
||||
Player damager = (Player) projectile.getShooter();
|
||||
Player victim = (Player) event.getEntity();
|
||||
|
||||
// Ender pearls and other self-damage
|
||||
if (damager == victim) {
|
||||
return;
|
||||
}
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
boolean damagerPvpEnabled = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(damager.getUniqueId());
|
||||
boolean victimPvpEnabled = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId());
|
||||
if (!damagerPvpEnabled) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker());
|
||||
return;
|
||||
}
|
||||
if (!victimPvpEnabled) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.player;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlayerHitBySplashPotionListener implements Listener {
|
||||
|
||||
/**
|
||||
* If thrown potion is applies negative effects and it's thrown by a player it will ahve no effect on player with pvp off
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerHitBySplashPotion(org.bukkit.event.entity.PotionSplashEvent event) {
|
||||
|
||||
if (!(event.getEntity().getShooter() instanceof Player))
|
||||
return;
|
||||
|
||||
boolean harmful = false;
|
||||
|
||||
for (PotionEffect effect : event.getPotion().getEffects()) {
|
||||
if (effect.getType().equals(PotionEffectType.BLINDNESS) ||
|
||||
effect.getType().equals(PotionEffectType.CONFUSION) ||
|
||||
effect.getType().equals(PotionEffectType.HARM) ||
|
||||
effect.getType().equals(PotionEffectType.HUNGER) ||
|
||||
effect.getType().equals(PotionEffectType.POISON) ||
|
||||
effect.getType().equals(PotionEffectType.SLOW_DIGGING) ||
|
||||
effect.getType().equals(PotionEffectType.WEAKNESS) ||
|
||||
effect.getType().equals(PotionEffectType.SLOW) ||
|
||||
effect.getType().equals(PotionEffectType.WITHER)) {
|
||||
harmful = true;
|
||||
}
|
||||
}
|
||||
if (!harmful)
|
||||
return;
|
||||
for (Entity entity : event.getAffectedEntities()) {
|
||||
if (entity instanceof Player) {
|
||||
Player damager = (Player) event.getEntity().getShooter();
|
||||
Player victim = (Player) entity;
|
||||
if (damager == victim)
|
||||
continue;
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
boolean damagerPvpEnabled = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(damager.getUniqueId());
|
||||
if (!damagerPvpEnabled) {
|
||||
event.setIntensity(victim, 0);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker());
|
||||
continue;
|
||||
}
|
||||
boolean victimPvpEnabled = TogglePvp.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId());
|
||||
if (!victimPvpEnabled) {
|
||||
event.setIntensity(victim, 0);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
continue;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.player;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.players.PlayerData;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import java.time.Instant;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlayerJoinAndLeaveListener implements Listener {
|
||||
/**
|
||||
* This event is here to get players saved options on join
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
PlayerData playerData = TogglePvp.getPlugin().getSqLite().getPlayerInfo(player.getUniqueId());
|
||||
|
||||
TogglePvp.getPlugin().getPlayerManager().addPlayer(player.getUniqueId(), playerData);
|
||||
}
|
||||
/**
|
||||
* This event is here to dump player's saved options from memory
|
||||
* Also punishes players who log out during combat
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPlayerLeave(org.bukkit.event.player.PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
TogglePvp.getPlugin().getSqLite().updatePlayerInfo(player.getUniqueId(), TogglePvp.getPlugin().getPlayerManager().getPlayer(player.getUniqueId()));
|
||||
if (TogglePvp.getPlugin().getConfigCache().isPunish_for_combat_logout()) {
|
||||
long now = Instant.now().getEpochSecond();
|
||||
long combatTime = TogglePvp.getPlugin().getPlayerManager().getPlayer(player.getUniqueId()).getCombattime();
|
||||
if (combatTime > now) {
|
||||
player.setHealth(0);
|
||||
if (TogglePvp.getPlugin().getConfigCache().isPunish_for_combat_logout_announce()) {
|
||||
PluginMessages.broadcastMessage(player, TogglePvp.getPlugin().getConfigCache().getPunish_for_combat_logout_message());
|
||||
}
|
||||
TogglePvp.getPlugin().getPlayerManager().getPlayer(player.getUniqueId()).setCombattime(now-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.unspecific;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import java.util.Iterator;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class AreaEffectCloudApplyListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onCloudEffects(AreaEffectCloudApplyEvent event) {
|
||||
|
||||
PotionEffectType potionEffectType = event.getEntity().getBasePotionData().getType().getEffectType();
|
||||
|
||||
if (potionEffectType == null)
|
||||
return;
|
||||
|
||||
if(event.getEntity().getSource() instanceof Player) {
|
||||
if (potionEffectType.equals(PotionEffectType.BLINDNESS) ||
|
||||
potionEffectType.equals(PotionEffectType.CONFUSION) ||
|
||||
potionEffectType.equals(PotionEffectType.HARM) ||
|
||||
potionEffectType.equals(PotionEffectType.HUNGER) ||
|
||||
potionEffectType.equals(PotionEffectType.POISON) ||
|
||||
potionEffectType.equals(PotionEffectType.SLOW_DIGGING) ||
|
||||
potionEffectType.equals(PotionEffectType.WEAKNESS) ||
|
||||
potionEffectType.equals(PotionEffectType.SLOW) ||
|
||||
potionEffectType.equals(PotionEffectType.WITHER)) {
|
||||
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
|
||||
Iterator<LivingEntity> it = event.getAffectedEntities().iterator();
|
||||
Player damager = (Player) event.getEntity().getSource();
|
||||
while(it.hasNext()) {
|
||||
LivingEntity entity = it.next();
|
||||
if(entity instanceof Player) {
|
||||
|
||||
Player victim = (Player) entity;
|
||||
if (damager == victim)
|
||||
continue;
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
it.remove();
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker());
|
||||
continue;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getUniqueId()).isPvpEnabled()) {
|
||||
it.remove();
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
continue;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getUniqueId());
|
||||
} else if (entity instanceof Tameable) {
|
||||
Tameable victim = (Tameable) entity;
|
||||
if (victim.getOwner() == null || victim.getOwner() == damager) {
|
||||
return;
|
||||
}
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
it.remove();
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker());
|
||||
continue;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getUniqueId()).isPvpEnabled()) {
|
||||
it.remove();
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_victim());
|
||||
continue;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getOwner().getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.unspecific;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import org.bukkit.entity.LightningStrike;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.weather.LightningStrikeEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
/**
|
||||
* Listen for lightning strikes and tag the trident spawned ones.
|
||||
* Idea from aasmus' PvPToggle plugin
|
||||
*/
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class EntityHitByLightningListener implements Listener {
|
||||
|
||||
/**
|
||||
* Cancels damage from lightning strike caused by channeling for players with pvp off
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerLightningDamage(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
|
||||
if (event.getDamager() instanceof LightningStrike && event.getDamager().getMetadata("TRIDENT").size() >= 1) {
|
||||
if (event.getEntity() instanceof Player) {
|
||||
Player victim = (Player) event.getEntity();
|
||||
if (!TogglePvp.getPlugin().getSmartCache().getPlayerData(victim.getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else if (event.getEntity() instanceof Tameable) {
|
||||
Tameable victim = (Tameable) event.getEntity();
|
||||
if (victim.getOwner() != null && !TogglePvp.getPlugin().getSmartCache().getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags the lightning strike
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onLightningStrike(LightningStrikeEvent event){
|
||||
if(event.getCause() == LightningStrikeEvent.Cause.TRIDENT){
|
||||
if (TogglePvp.getPlugin().getConfigCache().isChanneling_enchant_disabled()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
event.getLightning().setMetadata("TRIDENT", new FixedMetadataValue(TogglePvp.getPlugin(), event.getLightning().getLocation()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.unspecific;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class FishingListener implements Listener {
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
|
||||
/**
|
||||
* Prevents hooking players with disabled pvp with fishing rod
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onFish(org.bukkit.event.player.PlayerFishEvent event) {
|
||||
if (event.getCaught() instanceof Player) {
|
||||
Player damager = event.getPlayer();
|
||||
Player victim = (Player) event.getCaught();
|
||||
if (damager == victim) {
|
||||
return;
|
||||
}
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker());
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getUniqueId());
|
||||
} else if (event.getCaught() instanceof Tameable) {
|
||||
Tameable victim = (Tameable) event.getCaught();
|
||||
Player damager = event.getPlayer();
|
||||
if (victim.getOwner() == null || victim.getOwner() == damager) {
|
||||
return;
|
||||
}
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker());
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getOwner().getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.unspecific;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.BoundingBoxUtil;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class LavaDumpAndIgniteListener implements Listener {
|
||||
|
||||
private ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
|
||||
/**
|
||||
* Prevents dumping lava and pufferfish bucket near players with pvp off
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onLavaDump(org.bukkit.event.player.PlayerBucketEmptyEvent event) {
|
||||
|
||||
if (!TogglePvp.getPlugin().getConfigCache().isLava_and_fire_stopper_enabled())
|
||||
return;
|
||||
|
||||
if (event.getBucket().equals(Material.LAVA_BUCKET) || event.getBucket().equals(Material.PUFFERFISH_BUCKET)) {
|
||||
Location location = event.getBlockClicked().getLocation();
|
||||
Player damager = event.getPlayer();
|
||||
double radius = config.getLava_and_fire_stopper_radius();
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
BoundingBox boundingBox = BoundingBoxUtil.getBoundingBox(location, radius);
|
||||
for (Entity entity : location.getWorld().getNearbyEntities(boundingBox)) {
|
||||
if (entity instanceof Player) {
|
||||
Player victim = (Player) entity;
|
||||
if (victim != damager) {
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getUniqueId());
|
||||
}
|
||||
} else if (entity instanceof Tameable) {
|
||||
Tameable victim = (Tameable) entity;
|
||||
if (victim.getOwner() == null) {
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean victimPvpEnabled = smartCache.getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled();
|
||||
if (!victimPvpEnabled) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_victim());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getOwner().getUniqueId());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents setting blocks on fire near players with pvp off
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onIgnite(org.bukkit.event.block.BlockIgniteEvent event) {
|
||||
|
||||
if (!TogglePvp.getPlugin().getConfigCache().isLava_and_fire_stopper_enabled())
|
||||
return;
|
||||
|
||||
if (event.getPlayer() == null)
|
||||
return;
|
||||
|
||||
Location location = event.getBlock().getLocation();
|
||||
Player damager = event.getPlayer();
|
||||
double radius = config.getLava_and_fire_stopper_radius();
|
||||
BoundingBox boundingBox = BoundingBoxUtil.getBoundingBox(location, radius);
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
for (Entity entity : location.getWorld().getNearbyEntities(boundingBox)) {
|
||||
if (entity instanceof Player) {
|
||||
Player victim = (Player) entity;
|
||||
if (victim != damager) {
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getUniqueId());
|
||||
}
|
||||
} else if (entity instanceof Tameable) {
|
||||
Tameable victim = (Tameable) entity;
|
||||
if (victim.getOwner() == null || victim.getOwner() == damager) {
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_victim());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getOwner().getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.unspecific;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class LightningBlockIgniteListener implements Listener {
|
||||
|
||||
/**
|
||||
* Lightning strikes from channeling enchant won't ignite blocks if player with pvp off is in radius
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBlockIgnite(org.bukkit.event.block.BlockIgniteEvent event) {
|
||||
|
||||
if (event.getIgnitingEntity() instanceof LightningStrike && event.getIgnitingEntity().getMetadata("TRIDENT").size() >= 1) {
|
||||
LightningStrike lightningStrike = (LightningStrike) event.getIgnitingEntity();
|
||||
|
||||
for (Entity entity : lightningStrike.getNearbyEntities(2,2,2)) {
|
||||
if (entity instanceof Player) {
|
||||
Player victim = (Player) entity;
|
||||
if (!TogglePvp.getPlugin().getSmartCache().getPlayerData(victim.getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (entity instanceof Tameable) {
|
||||
Tameable victim = (Tameable) entity;
|
||||
if (victim.getOwner() == null) {
|
||||
return;
|
||||
}
|
||||
if (!TogglePvp.getPlugin().getSmartCache().getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
package eu.endermite.togglepvp.listeners.unspecific;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.config.ConfigCache;
|
||||
import eu.endermite.togglepvp.players.SmartCache;
|
||||
import eu.endermite.togglepvp.util.BoundingBoxUtil;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
|
||||
@eu.endermite.togglepvp.util.Listener
|
||||
public class PlaceWitherRoseListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerWitherRosePlace(org.bukkit.event.block.BlockPlaceEvent event) {
|
||||
|
||||
ConfigCache config = TogglePvp.getPlugin().getConfigCache();
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
|
||||
if (!config.isLava_and_fire_stopper_enabled())
|
||||
return;
|
||||
|
||||
if (event.getBlock().getType().equals(Material.WITHER_ROSE)) {
|
||||
Location location = event.getBlockPlaced().getLocation();
|
||||
double radius = config.getLava_and_fire_stopper_radius();
|
||||
BoundingBox boundingBox = BoundingBoxUtil.getBoundingBox(location, radius);
|
||||
for (Entity entity : location.getWorld().getNearbyEntities(boundingBox)) {
|
||||
if (entity instanceof Player) {
|
||||
Player damager = event.getPlayer();
|
||||
Player victim = (Player) entity;
|
||||
if (victim == damager)
|
||||
return;
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_victim());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getUniqueId());
|
||||
} else if (entity instanceof Tameable) {
|
||||
Tameable victim = (Tameable) entity;
|
||||
Player damager = event.getPlayer();
|
||||
if (victim.getOwner() == null || victim.getOwner() == damager) {
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(damager.getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!smartCache.getPlayerData(victim.getOwner().getUniqueId()).isPvpEnabled()) {
|
||||
PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_victim());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
CombatTimer.refreshPlayersCombatTime(damager.getUniqueId(), victim.getOwner().getUniqueId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package eu.endermite.togglepvp.players;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public class PlayerData {
|
||||
|
||||
private long cachetime, combattime;
|
||||
private boolean pvpEnabled;
|
||||
private boolean lastCombatCheck;
|
||||
|
||||
public PlayerData(boolean pvpEnabled) {
|
||||
this.pvpEnabled = pvpEnabled;
|
||||
this.combattime = Instant.now().getEpochSecond()-1;
|
||||
|
||||
refreshCachetime();
|
||||
}
|
||||
|
||||
public boolean isPvpEnabled() {
|
||||
return pvpEnabled;
|
||||
}
|
||||
|
||||
public void setPvpEnabled(boolean pvpEnabled) {
|
||||
this.pvpEnabled = pvpEnabled;
|
||||
}
|
||||
|
||||
public long getCachetime() {
|
||||
return cachetime;
|
||||
}
|
||||
|
||||
public void refreshCachetime() {
|
||||
this.cachetime = Instant.now().getEpochSecond()+ TogglePvp.getPlugin().getConfigCache().getCache_time();
|
||||
}
|
||||
|
||||
public long getCombattime() {
|
||||
return combattime;
|
||||
}
|
||||
|
||||
public void setCombattime(long combattime) {
|
||||
this.combattime = combattime;
|
||||
}
|
||||
|
||||
public void refreshCombatTime() {
|
||||
this.combattime = Instant.now().getEpochSecond()+ TogglePvp.getPlugin().getConfigCache().getCombat_time();
|
||||
}
|
||||
|
||||
public boolean getLastCombatCheck() {
|
||||
return lastCombatCheck;
|
||||
}
|
||||
|
||||
public void setLastCombatCheck(boolean bool) {
|
||||
lastCombatCheck = bool;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package eu.endermite.togglepvp.players;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.util.CombatTimer;
|
||||
import eu.endermite.togglepvp.util.PluginMessages;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerManager {
|
||||
|
||||
@Getter
|
||||
HashMap<UUID, PlayerData> playerList = new HashMap<>();
|
||||
|
||||
public final BukkitTask combatTrackerTask;
|
||||
|
||||
public PlayerManager() {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
PlayerData playerData = TogglePvp.getPlugin().getSqLite().getPlayerInfo(p.getUniqueId());
|
||||
playerList.put(p.getUniqueId(), playerData);
|
||||
}
|
||||
|
||||
combatTrackerTask = Bukkit.getScheduler().runTaskTimerAsynchronously(TogglePvp.getPlugin(), () -> {
|
||||
for (Map.Entry<UUID, PlayerData> set : playerList.entrySet()) {
|
||||
UUID uuid = set.getKey();
|
||||
if (!CombatTimer.isInCombat(uuid)) {
|
||||
if (set.getValue().getLastCombatCheck()) {
|
||||
set.getValue().setLastCombatCheck(false);
|
||||
PluginMessages.sendActionBar(uuid, TogglePvp.getPlugin().getConfigCache().getLeaving_combat());
|
||||
}
|
||||
} else {
|
||||
set.getValue().setLastCombatCheck(true);
|
||||
}
|
||||
}
|
||||
}, 20, 20);
|
||||
}
|
||||
|
||||
public void refreshPlayersCacheTime(UUID uuid) {
|
||||
playerList.get(uuid).refreshCachetime();
|
||||
}
|
||||
|
||||
public void refreshPlayersCombatTime(UUID uuid) {
|
||||
try {
|
||||
playerList.get(uuid).refreshCombatTime();
|
||||
} catch (Exception ignored) { }
|
||||
}
|
||||
|
||||
public PlayerData getPlayer(UUID uuid) {
|
||||
return playerList.get(uuid);
|
||||
}
|
||||
|
||||
public void addPlayer(UUID uuid, PlayerData data) {
|
||||
playerList.put(uuid, data);
|
||||
}
|
||||
|
||||
public boolean getPlayerPvPState(UUID uuid) {
|
||||
return TogglePvp.getPlugin().getSmartCache().getPlayerData(uuid).isPvpEnabled();
|
||||
}
|
||||
|
||||
public void setPlayerPvpState(UUID uuid, boolean state) {
|
||||
TogglePvp.getPlugin().getSmartCache().getPlayerData(uuid).setPvpEnabled(state);
|
||||
}
|
||||
|
||||
public boolean togglePlayerPvpState(UUID uuid) {
|
||||
SmartCache smartCache = TogglePvp.getPlugin().getSmartCache();
|
||||
if (smartCache.getPlayerData(uuid).isPvpEnabled()) {
|
||||
smartCache.getPlayerData(uuid).setPvpEnabled(false);
|
||||
return false;
|
||||
} else {
|
||||
smartCache.getPlayerData(uuid).setPvpEnabled(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package eu.endermite.togglepvp.players;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SmartCache {
|
||||
|
||||
public void runSmartCache() {
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(TogglePvp.getPlugin(), () -> {
|
||||
// Refresh cache timer if player is online
|
||||
for (Map.Entry<UUID, PlayerData> e : TogglePvp.getPlugin().getPlayerManager().getPlayerList().entrySet()) {
|
||||
try {
|
||||
Player player = Bukkit.getPlayer(e.getKey());
|
||||
if (player != null && player.isOnline()) {
|
||||
TogglePvp.getPlugin().getPlayerManager().refreshPlayersCacheTime(e.getKey());
|
||||
}
|
||||
} catch (NullPointerException ignored) {}
|
||||
}
|
||||
// Check for entries that should be invalidated
|
||||
try {
|
||||
long now = Instant.now().getEpochSecond();
|
||||
TogglePvp.getPlugin().getPlayerManager().getPlayerList().entrySet()
|
||||
.removeIf(cacheEntry -> cacheEntry.getValue().getCachetime() < now);
|
||||
} catch (Exception ignored) {}
|
||||
}, 100, 100);
|
||||
}
|
||||
|
||||
public PlayerData getPlayerData(UUID uuid) {
|
||||
// Try to get data from cache and refresh it
|
||||
try {
|
||||
TogglePvp.getPlugin().getPlayerManager().refreshPlayersCacheTime(uuid);
|
||||
return TogglePvp.getPlugin().getPlayerManager().getPlayer(uuid);
|
||||
} catch (NullPointerException e) {
|
||||
// If player data is not in cache get it from database and put into cache
|
||||
try {
|
||||
PlayerData playerData = TogglePvp.getPlugin().getSqLite().getPlayerInfo(uuid);
|
||||
TogglePvp.getPlugin().getPlayerManager().addPlayer(uuid, playerData);
|
||||
return playerData;
|
||||
} catch (NullPointerException ex) {
|
||||
// Return false if database call fails
|
||||
return new PlayerData(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPlayerPvpState(UUID uuid, boolean state) {
|
||||
// If player is in cache update that
|
||||
if (TogglePvp.getPlugin().getPlayerManager().getPlayer(uuid) != null) {
|
||||
TogglePvp.getPlugin().getPlayerManager().getPlayer(uuid).setPvpEnabled(state);
|
||||
}
|
||||
// Update the database aswell
|
||||
TogglePvp.getPlugin().getSqLite().updatePlayerInfo(uuid, new PlayerData(state));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package eu.endermite.togglepvp.util;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
|
||||
public class BoundingBoxUtil {
|
||||
|
||||
public static BoundingBox getBoundingBox(Location location, double radius) {
|
||||
|
||||
double x1 = location.getX()+radius;
|
||||
double y1 = location.getY()+radius;
|
||||
double z1 = location.getZ()+radius;
|
||||
|
||||
double x2 = location.getX()-radius;
|
||||
double y2 = location.getY()-radius;
|
||||
double z2 = location.getZ()-radius;
|
||||
|
||||
return new BoundingBox(x1, y1, z1, x2, y2, z2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package eu.endermite.togglepvp.util;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CombatTimer {
|
||||
|
||||
public static void refreshPlayersCombatTime(UUID uuid) {
|
||||
try {
|
||||
long now = Instant.now().getEpochSecond();
|
||||
long combattime = TogglePvp.getPlugin().getSmartCache().getPlayerData(uuid).getCombattime();
|
||||
if (combattime < now) {
|
||||
PluginMessages.sendActionBar(uuid, TogglePvp.getPlugin().getConfigCache().getEntering_combat());
|
||||
}
|
||||
TogglePvp.getPlugin().getPlayerManager().refreshPlayersCombatTime(uuid);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public static void refreshPlayersCombatTime(UUID attacker_uuid, UUID victim_uuid) {
|
||||
refreshPlayersCombatTime(attacker_uuid);
|
||||
refreshPlayersCombatTime(victim_uuid);
|
||||
}
|
||||
|
||||
public static boolean isInCombat(UUID uuid) {
|
||||
try {
|
||||
long combattimer = TogglePvp.getPlugin().getSmartCache().getPlayerData(uuid).getCombattime();
|
||||
long now = Instant.now().getEpochSecond();
|
||||
return combattimer > now;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package eu.endermite.togglepvp.util;
|
||||
|
||||
import eu.endermite.togglepvp.TogglePvp;
|
||||
import eu.endermite.togglepvp.players.PlayerData;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DatabaseSQLite {
|
||||
|
||||
private final String url;
|
||||
private final File folder;
|
||||
|
||||
public DatabaseSQLite(String url, File folder) {
|
||||
this.url = url;
|
||||
this.folder = folder;
|
||||
|
||||
}
|
||||
|
||||
public boolean createDatabaseFile() {
|
||||
this.folder.mkdir();
|
||||
try (Connection conn = DriverManager.getConnection(url)) {
|
||||
if (conn != null) {
|
||||
DatabaseMetaData meta = conn.getMetaData();
|
||||
System.out.println("The driver name is " + meta.getDriverName());
|
||||
Statement statement = conn.createStatement();
|
||||
String sql = "CREATE TABLE IF NOT EXISTS `players` (`player_uuid` varchar(36) UNIQUE PRIMARY KEY, `pvpenabled` boolean);";
|
||||
statement.execute(sql);
|
||||
conn.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
System.out.println(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean testConnection() {
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = DriverManager.getConnection(url);
|
||||
System.out.println("Connection to SQLite has been established.");
|
||||
if (conn != null) {
|
||||
conn.close();
|
||||
return true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public PlayerData getPlayerInfo(UUID uuid) {
|
||||
|
||||
try {
|
||||
Connection conn = DriverManager.getConnection(url);
|
||||
Statement insertnewuser = conn.createStatement();
|
||||
try {
|
||||
String newuserdata = "INSERT OR IGNORE INTO `players` (player_uuid, pvpenabled) VALUES ('" + uuid.toString() + "', " + TogglePvp.getPlugin().getConfigCache().isPvp_enabled_by_default() + ")";
|
||||
insertnewuser.execute(newuserdata);
|
||||
} catch (SQLException e) {
|
||||
if (e.getErrorCode() != 19) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Statement statement = conn.createStatement();
|
||||
String sql = "SELECT * FROM `players` WHERE `player_uuid` = '" + uuid.toString() + "';";
|
||||
statement.execute(sql);
|
||||
ResultSet result = statement.getResultSet();
|
||||
boolean state = result.getBoolean("pvpenabled");
|
||||
conn.close();
|
||||
return new PlayerData(state);
|
||||
} catch (SQLException throwables) {
|
||||
throwables.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updatePlayerInfo(UUID uuid, PlayerData data) {
|
||||
try {
|
||||
Connection conn = DriverManager.getConnection(url);
|
||||
Statement insertnewuser = conn.createStatement();
|
||||
try {
|
||||
String newuserdata = "UPDATE `players` SET pvpenabled = "+data.isPvpEnabled()+" WHERE `player_uuid` = '"+uuid.toString()+"';";
|
||||
insertnewuser.execute(newuserdata);
|
||||
} catch (SQLException e) {
|
||||
TogglePvp.getPlugin().getLogger().severe("Error while saving player data!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (SQLException throwables) {
|
||||
throwables.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package eu.endermite.togglepvp.util;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
|
||||
public @interface Listener {}
|
||||
@@ -1,44 +0,0 @@
|
||||
package eu.endermite.togglepvp.util;
|
||||
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public class PluginMessages {
|
||||
|
||||
public static String parseMessage(String message) {
|
||||
//TODO PAPI support
|
||||
return ChatColor.translateAlternateColorCodes('&', message);
|
||||
}
|
||||
|
||||
public static void sendActionBar(Player player, String message) {
|
||||
BaseComponent[] component = TextComponent.fromLegacyText(parseMessage(message));
|
||||
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, component);
|
||||
}
|
||||
|
||||
public static void sendActionBar(UUID uuid, String message) {
|
||||
try {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
sendActionBar(player, message);
|
||||
} catch (NullPointerException ignored) {}
|
||||
}
|
||||
|
||||
public static String parsePlayerName(Player player, String message) {
|
||||
message = message.replaceAll("%player%", player.getDisplayName());
|
||||
return parseMessage(message);
|
||||
}
|
||||
|
||||
public static void broadcastMessage(Player player, String message) {
|
||||
message = parsePlayerName(player, message);
|
||||
message = parseMessage(message);
|
||||
BaseComponent[] component = TextComponent.fromLegacyText(parseMessage(message));
|
||||
Bukkit.spigot().broadcast(component);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package me.youhavetrouble.preventstabby;
|
||||
|
||||
import me.youhavetrouble.preventstabby.commands.MainCommand;
|
||||
import me.youhavetrouble.preventstabby.config.ConfigCache;
|
||||
import me.youhavetrouble.preventstabby.hooks.PlaceholderApiHook;
|
||||
import me.youhavetrouble.preventstabby.hooks.WorldGuardHook;
|
||||
import me.youhavetrouble.preventstabby.data.PlayerListener;
|
||||
import me.youhavetrouble.preventstabby.data.PlayerManager;
|
||||
import me.youhavetrouble.preventstabby.listeners.EnvironmentalListener;
|
||||
import me.youhavetrouble.preventstabby.listeners.PvpListener;
|
||||
import me.youhavetrouble.preventstabby.listeners.UtilListener;
|
||||
import me.youhavetrouble.preventstabby.util.*;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class PreventStabby extends JavaPlugin {
|
||||
|
||||
private static PreventStabby plugin;
|
||||
private ConfigCache configCache;
|
||||
private PlayerManager playerManager;
|
||||
private DatabaseSQLite sqLite;
|
||||
private static boolean worldGuardHook;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
plugin = this;
|
||||
reloadPluginConfig();
|
||||
File dbFile = new File("plugins/PreventStabby");
|
||||
sqLite = new DatabaseSQLite("jdbc:sqlite:plugins/PreventStabby/database.db", dbFile, getLogger());
|
||||
playerManager = new PlayerManager(this);
|
||||
|
||||
// Register listeners
|
||||
getServer().getPluginManager().registerEvents(new UtilListener(), this);
|
||||
getServer().getPluginManager().registerEvents(new PlayerListener(), this);
|
||||
getServer().getPluginManager().registerEvents(new EnvironmentalListener(this), this);
|
||||
|
||||
getServer().getPluginManager().registerEvents(new PvpListener(this), this);
|
||||
|
||||
// Register command
|
||||
PluginCommand pvpCommand = getCommand("pvp");
|
||||
if (pvpCommand == null) {
|
||||
getLogger().severe("Error with registering commands.");
|
||||
getLogger().severe("Plugin will now disable.");
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
MainCommand mainCommand = new MainCommand();
|
||||
pvpCommand.setExecutor(mainCommand);
|
||||
pvpCommand.setTabCompleter(mainCommand);
|
||||
|
||||
if (getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||
new PlaceholderApiHook(this).register();
|
||||
}
|
||||
|
||||
Metrics metrics = new Metrics(this, 14074);
|
||||
|
||||
getServer().getOnlinePlayers().forEach(player -> playerManager.getPlayerData(player.getUniqueId()));
|
||||
getServer().getWorlds().forEach(world -> {
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
if (!chunk.isEntitiesLoaded()) continue;
|
||||
Bukkit.getRegionScheduler().run(plugin, chunk.getWorld(), chunk.getX(), chunk.getZ(), (task) -> {
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
if (!(entity instanceof Tameable tameable)) continue;
|
||||
UUID ownerId = tameable.getOwnerUniqueId();
|
||||
if (ownerId == null) continue;
|
||||
getPlayerManager().getPlayerData(ownerId).thenAccept(playerData -> {
|
||||
if (playerData == null) return;
|
||||
playerData.addRelatedEntity(entity.getUniqueId());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (getServer().getPluginManager().getPlugin("WorldGuard") != null) {
|
||||
try {
|
||||
WorldGuardHook.init(this.getLogger());
|
||||
worldGuardHook = true;
|
||||
} catch (NoClassDefFoundError e) {
|
||||
worldGuardHook = false;
|
||||
}
|
||||
} else {
|
||||
worldGuardHook = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean worldGuardHookEnabled() {
|
||||
return worldGuardHook;
|
||||
}
|
||||
|
||||
public void reloadPluginConfig() {
|
||||
configCache = new ConfigCache(this);
|
||||
}
|
||||
|
||||
public void reloadPluginConfig(CommandSender commandSender) {
|
||||
getServer().getAsyncScheduler().runNow(this, (task) -> {
|
||||
reloadPluginConfig();
|
||||
PluginMessages.sendMessage(commandSender, "PreventStabby configuration reloaded.");
|
||||
});
|
||||
}
|
||||
|
||||
public ConfigCache getConfigCache() {
|
||||
return configCache;
|
||||
}
|
||||
|
||||
public PlayerManager getPlayerManager() {
|
||||
return playerManager;
|
||||
}
|
||||
|
||||
public DatabaseSQLite getSqLite() {return sqLite;}
|
||||
|
||||
public static PreventStabby getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package me.youhavetrouble.preventstabby.api;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.data.DamageCheckResult;
|
||||
import me.youhavetrouble.preventstabby.util.PvpState;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public class PreventStabbyAPI {
|
||||
|
||||
/**
|
||||
* @return Current state of forced PvP
|
||||
*/
|
||||
public static PvpState getForcedPvpState() {
|
||||
return PreventStabby.getPlugin().getPlayerManager().getForcedPvpState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets forced PvP state until server restart or changed with override command or this method.
|
||||
*/
|
||||
public static void setForcedPvpState(PvpState newForcedPvpState) {
|
||||
PreventStabby.getPlugin().getPlayerManager().setForcedPvpState(newForcedPvpState);
|
||||
}
|
||||
|
||||
public static DamageCheckResult canDamage(Entity attacker, Entity victim) {
|
||||
return PreventStabby.getPlugin().getPlayerManager().canDamage(attacker, victim);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package me.youhavetrouble.preventstabby.api.event;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.data.PlayerData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Fired when player enters combat.
|
||||
*/
|
||||
public class PlayerEnterCombatEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
private final Player player;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerEnterCombatEvent(Player player) {
|
||||
this.player = player;
|
||||
this.cancelled = false;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public PlayerData getPlayerData() {
|
||||
return PreventStabby.getPlugin().getPlayerManager().getPlayer(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
cancelled = cancel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package me.youhavetrouble.preventstabby.api.event;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.data.PlayerData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Fired when player leaves combat. If cancelled, it will refresh combat timer to the value set in the config.
|
||||
*/
|
||||
public class PlayerLeaveCombatEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
private final Player player;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerLeaveCombatEvent(Player player) {
|
||||
this.player = player;
|
||||
this.cancelled = false;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public PlayerData getPlayerData() {
|
||||
return PreventStabby.getPlugin().getPlayerManager().getPlayer(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
cancelled = cancel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package me.youhavetrouble.preventstabby.api.event;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.data.PlayerData;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Fired when player gets their personal pvp state toggled.
|
||||
*/
|
||||
public class PlayerTogglePvpEvent extends Event {
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
private final OfflinePlayer player;
|
||||
private final boolean newState;
|
||||
private boolean sendMessage;
|
||||
|
||||
public PlayerTogglePvpEvent(OfflinePlayer player, boolean newState, boolean sendMessage) {
|
||||
this.player = player;
|
||||
this.newState = newState;
|
||||
this.sendMessage = sendMessage;
|
||||
}
|
||||
|
||||
public OfflinePlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public PlayerData getPlayerData() {
|
||||
return PreventStabby.getPlugin().getPlayerManager().getPlayer(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state player's pvp state was toggled to.
|
||||
* @return The state player's pvp state was toggled to.
|
||||
*/
|
||||
public boolean newState() {
|
||||
return newState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the state message will be sent to the player, false otherwise
|
||||
* @return True if the state message will be sent to the player, false otherwise
|
||||
*/
|
||||
public boolean isSendMessage() {
|
||||
return sendMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is true at the end of event pipeline, message with the current state will be sent to player.
|
||||
*/
|
||||
public void setSendMessage(boolean sendMessage) {
|
||||
this.sendMessage = sendMessage;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package me.youhavetrouble.preventstabby.commands;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.config.PreventStabbyPermission;
|
||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||
import me.youhavetrouble.preventstabby.util.PvpState;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class GlobalToggleCommand {
|
||||
public static void globalToggle(CommandSender sender, String[] args) {
|
||||
Bukkit.getAsyncScheduler().runNow(PreventStabby.getPlugin(), (task) -> {
|
||||
if (!PreventStabbyPermission.COMMAND_GLOBAL_TOGGLE.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length != 2) {
|
||||
PluginMessages.sendMessage(sender, "Try /pvp override <enabled/disabled/none>");
|
||||
return;
|
||||
}
|
||||
|
||||
PvpState pvpState = PvpState.valueOf(args[1].toUpperCase(Locale.ROOT));
|
||||
|
||||
switch (pvpState) {
|
||||
case ENABLED:
|
||||
PreventStabby.getPlugin().getPlayerManager().setForcedPvpState(PvpState.ENABLED);
|
||||
PluginMessages.broadcastMessage(PreventStabby.getPlugin().getConfigCache().force_pvp_on);
|
||||
break;
|
||||
case DISABLED:
|
||||
PreventStabby.getPlugin().getPlayerManager().setForcedPvpState(PvpState.DISABLED);
|
||||
PluginMessages.broadcastMessage(PreventStabby.getPlugin().getConfigCache().force_pvp_off);
|
||||
break;
|
||||
case NONE:
|
||||
PreventStabby.getPlugin().getPlayerManager().setForcedPvpState(PvpState.NONE);
|
||||
PluginMessages.broadcastMessage(PreventStabby.getPlugin().getConfigCache().force_pvp_none);
|
||||
break;
|
||||
default:
|
||||
PluginMessages.sendMessage(sender, "Try /pvp override <enabled/disabled/none>");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package me.youhavetrouble.preventstabby.commands;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.config.PreventStabbyPermission;
|
||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class HelpCommand {
|
||||
public static void help(CommandSender sender, String[] args) {
|
||||
Bukkit.getAsyncScheduler().runNow(PreventStabby.getPlugin(), (task) -> {
|
||||
|
||||
if (!PreventStabbyPermission.COMMAND_HELP.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return;
|
||||
}
|
||||
|
||||
Component helpComponent = PluginMessages.MINIMESSAGE
|
||||
.deserialize("<aqua><strikethrough> </strikethrough> PreventStabby Help <strikethrough> </strikethrough>")
|
||||
.append(Component.newline())
|
||||
.append(PluginMessages.MINIMESSAGE.deserialize("<blue>/pvp <aqua><bold>help</bold> <white>- shows this message"));
|
||||
|
||||
if (PreventStabbyPermission.COMMAND_TOGGLE.doesCommandSenderHave(sender)) {
|
||||
helpComponent = helpComponent.append(Component.newline());
|
||||
helpComponent = helpComponent
|
||||
.append(PluginMessages.MINIMESSAGE.deserialize("<blue>/pvp <aqua><bold>[on/off]</bold> <white>- enables or disables PvP"))
|
||||
.append(Component.newline())
|
||||
.append(PluginMessages.MINIMESSAGE.deserialize("<blue>/pvp <aqua><bold>toggle</bold> <white>- toggles PvP status"));
|
||||
}
|
||||
sender.sendMessage(helpComponent);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package me.youhavetrouble.preventstabby.commands;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.config.PreventStabbyPermission;
|
||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MainCommand implements TabExecutor {
|
||||
|
||||
private final HashMap<String, PreventStabbyPermission> subCommands = new HashMap<>();
|
||||
|
||||
public MainCommand() {
|
||||
subCommands.put("help", PreventStabbyPermission.COMMAND_HELP);
|
||||
subCommands.put("toggle", PreventStabbyPermission.COMMAND_TOGGLE);
|
||||
subCommands.put("on", PreventStabbyPermission.COMMAND_TOGGLE);
|
||||
subCommands.put("enable", PreventStabbyPermission.COMMAND_TOGGLE);
|
||||
subCommands.put("off", PreventStabbyPermission.COMMAND_TOGGLE);
|
||||
subCommands.put("disable", PreventStabbyPermission.COMMAND_TOGGLE);
|
||||
subCommands.put("reload", PreventStabbyPermission.COMMAND_RELOAD);
|
||||
subCommands.put("override", PreventStabbyPermission.COMMAND_GLOBAL_TOGGLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!sender.hasPermission("preventstabby.command")) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return true;
|
||||
}
|
||||
if (args.length == 0) {
|
||||
PvpToggleCommand.toggle(sender, args);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "help":
|
||||
HelpCommand.help(sender, args);
|
||||
break;
|
||||
case "toggle":
|
||||
PvpToggleCommand.toggle(sender, args);
|
||||
break;
|
||||
case "on":
|
||||
case "enable":
|
||||
PvpToggleCommand.enable(sender, args);
|
||||
break;
|
||||
case "off":
|
||||
case "disable":
|
||||
PvpToggleCommand.disable(sender, args);
|
||||
break;
|
||||
case "reload":
|
||||
ReloadCommand.reload(sender);
|
||||
break;
|
||||
case "override":
|
||||
GlobalToggleCommand.globalToggle(sender, args);
|
||||
break;
|
||||
default:
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_such_command);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
List<String> commands = new ArrayList<>();
|
||||
if (args.length == 1) {
|
||||
String arg1 = args[0].toLowerCase();
|
||||
for (Map.Entry<String, PreventStabbyPermission> entry : subCommands.entrySet()) {
|
||||
if (entry.getKey().toLowerCase().startsWith(arg1)
|
||||
&& entry.getValue().doesCommandSenderHave(sender))
|
||||
commands.add(entry.getKey());
|
||||
}
|
||||
return commands;
|
||||
} else if (args.length == 2) {
|
||||
switch (args[0].toLowerCase()) {
|
||||
default:
|
||||
break;
|
||||
case "toggle":
|
||||
case "on":
|
||||
case "enable":
|
||||
case "off":
|
||||
case "disable":
|
||||
if (!PreventStabbyPermission.COMMAND_TOGGLE_OTHERS.doesCommandSenderHave(sender)) break;
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
commands.add(player.getName());
|
||||
}
|
||||
break;
|
||||
case "override":
|
||||
if (!PreventStabbyPermission.COMMAND_GLOBAL_TOGGLE.doesCommandSenderHave(sender)) break;
|
||||
commands.add("enabled");
|
||||
commands.add("disabled");
|
||||
commands.add("none");
|
||||
break;
|
||||
}
|
||||
return StringUtil.copyPartialMatches(args[1], commands, new ArrayList<>());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
package me.youhavetrouble.preventstabby.commands;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.api.event.PlayerTogglePvpEvent;
|
||||
import me.youhavetrouble.preventstabby.config.PreventStabbyPermission;
|
||||
import me.youhavetrouble.preventstabby.data.PlayerManager;
|
||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PvpToggleCommand {
|
||||
|
||||
private static final PlayerManager playerManager = PreventStabby.getPlugin().getPlayerManager();
|
||||
|
||||
public static void toggle(CommandSender sender, String[] args) {
|
||||
Bukkit.getAsyncScheduler().runNow(PreventStabby.getPlugin(), (task) -> {
|
||||
if (!PreventStabbyPermission.COMMAND_TOGGLE.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length <= 1) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
PluginMessages.sendMessage(sender, "Try /pvp toggle <player>");
|
||||
return;
|
||||
}
|
||||
if (playerManager.getPlayer(player.getUniqueId()).isInCombat()) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().cant_do_that_during_combat);
|
||||
return;
|
||||
}
|
||||
playerManager.togglePlayerPvpState(player.getUniqueId()).thenAccept(newState -> {
|
||||
PlayerTogglePvpEvent toggleEvent = new PlayerTogglePvpEvent(player, newState, true);
|
||||
Bukkit.getGlobalRegionScheduler().run(PreventStabby.getPlugin(), (task1) -> {
|
||||
if (PlayerTogglePvpEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
Bukkit.getPluginManager().callEvent(toggleEvent);
|
||||
}
|
||||
if (!toggleEvent.isSendMessage()) return;
|
||||
if (newState) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().pvp_enabled);
|
||||
} else {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().pvp_disabled);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
} else if (args.length == 2) {
|
||||
if (!PreventStabbyPermission.COMMAND_TOGGLE_OTHERS.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return;
|
||||
}
|
||||
if (sender instanceof Player player) {
|
||||
if (playerManager.getPlayer(player.getUniqueId()).isInCombat()) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().cant_do_that_during_combat);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
if (player == null) {
|
||||
PluginMessages.sendMessage(sender, "<red>Player offline.");
|
||||
return;
|
||||
}
|
||||
playerManager.togglePlayerPvpState(player.getUniqueId()).thenAccept(newState -> {
|
||||
PlayerTogglePvpEvent toggleEvent = new PlayerTogglePvpEvent(player, newState, false);
|
||||
Bukkit.getGlobalRegionScheduler().run(PreventStabby.getPlugin(), (task1) -> {
|
||||
if (PlayerTogglePvpEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
Bukkit.getPluginManager().callEvent(toggleEvent);
|
||||
}
|
||||
if (toggleEvent.isSendMessage()) {
|
||||
if (newState) {
|
||||
PluginMessages.sendMessage(player, PreventStabby.getPlugin().getConfigCache().pvp_enabled);
|
||||
} else {
|
||||
PluginMessages.sendMessage(player, PreventStabby.getPlugin().getConfigCache().pvp_disabled);
|
||||
}
|
||||
}
|
||||
String message;
|
||||
if (newState) {
|
||||
message = PreventStabby.getPlugin().getConfigCache().pvp_enabled_other;
|
||||
} else {
|
||||
message = PreventStabby.getPlugin().getConfigCache().pvp_disabled_other;
|
||||
}
|
||||
PluginMessages.sendMessage(sender, PluginMessages.parsePlayerName(player, message));
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void enable(CommandSender sender, String[] args) {
|
||||
if (!PreventStabbyPermission.COMMAND_TOGGLE.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return;
|
||||
}
|
||||
if (args.length == 1) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
PluginMessages.sendMessage(sender, "Try /pvp enable <player>");
|
||||
return;
|
||||
}
|
||||
if (playerManager.getPlayer(player.getUniqueId()).isInCombat()) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().cant_do_that_during_combat);
|
||||
return;
|
||||
}
|
||||
playerManager.setPlayerPvpState(player.getUniqueId(), true);
|
||||
PlayerTogglePvpEvent toggleEvent = new PlayerTogglePvpEvent(player, true, true);
|
||||
Bukkit.getGlobalRegionScheduler().run(PreventStabby.getPlugin(), (task) -> {
|
||||
if (PlayerTogglePvpEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
Bukkit.getPluginManager().callEvent(toggleEvent);
|
||||
}
|
||||
if (toggleEvent.isSendMessage()) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().pvp_enabled);
|
||||
}
|
||||
});
|
||||
|
||||
} else if (args.length == 2) {
|
||||
if (!PreventStabbyPermission.COMMAND_TOGGLE_OTHERS.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return;
|
||||
}
|
||||
if (sender instanceof Player player) {
|
||||
if (playerManager.getPlayer(player.getUniqueId()).isInCombat()) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().cant_do_that_during_combat);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
if (player == null) {
|
||||
PluginMessages.sendMessage(sender, "<red>Player offline.");
|
||||
return;
|
||||
}
|
||||
String message = PreventStabby.getPlugin().getConfigCache().pvp_enabled_other;
|
||||
PluginMessages.sendMessage(sender, PluginMessages.parsePlayerName(player, message));
|
||||
playerManager.setPlayerPvpState(player.getUniqueId(), true);
|
||||
PlayerTogglePvpEvent toggleEvent = new PlayerTogglePvpEvent(player, true, false);
|
||||
Bukkit.getGlobalRegionScheduler().run(PreventStabby.getPlugin(), (task) -> {
|
||||
if (PlayerTogglePvpEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
Bukkit.getPluginManager().callEvent(toggleEvent);
|
||||
}
|
||||
if (toggleEvent.isSendMessage()) {
|
||||
PluginMessages.sendMessage(player, PreventStabby.getPlugin().getConfigCache().pvp_enabled);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (PreventStabbyPermission.COMMAND_TOGGLE_OTHERS.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, "Try /pvp enable <player>");
|
||||
} else {
|
||||
PluginMessages.sendMessage(sender, "Try /pvp enable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void disable(CommandSender sender, String[] args) {
|
||||
if (!PreventStabbyPermission.COMMAND_TOGGLE.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return;
|
||||
}
|
||||
if (args.length == 1) {
|
||||
if (sender instanceof Player player) {
|
||||
if (playerManager.getPlayer(player.getUniqueId()).isInCombat()) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().cant_do_that_during_combat);
|
||||
return;
|
||||
}
|
||||
playerManager.setPlayerPvpState(player.getUniqueId(), false);
|
||||
PlayerTogglePvpEvent toggleEvent = new PlayerTogglePvpEvent(player, false, true);
|
||||
Bukkit.getGlobalRegionScheduler().run(PreventStabby.getPlugin(), (task) -> {
|
||||
if (PlayerTogglePvpEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
Bukkit.getPluginManager().callEvent(toggleEvent);
|
||||
}
|
||||
if (toggleEvent.isSendMessage()) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().pvp_disabled);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
PluginMessages.sendMessage(sender, "Try /pvp disable <player>");
|
||||
}
|
||||
} else if (args.length == 2) {
|
||||
if (!PreventStabbyPermission.COMMAND_TOGGLE_OTHERS.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return;
|
||||
}
|
||||
if (sender instanceof Player player) {
|
||||
if (playerManager.getPlayer(player.getUniqueId()).isInCombat()) {
|
||||
PluginMessages.sendMessage(sender, PreventStabby.getPlugin().getConfigCache().cant_do_that_during_combat);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
if (player == null) {
|
||||
PluginMessages.sendMessage(sender, "<red>Player offline.");
|
||||
return;
|
||||
}
|
||||
String message = PreventStabby.getPlugin().getConfigCache().pvp_disabled_other;
|
||||
PluginMessages.sendMessage(sender, PluginMessages.parsePlayerName(player, message));
|
||||
playerManager.setPlayerPvpState(player.getUniqueId(), false);
|
||||
PlayerTogglePvpEvent toggleEvent = new PlayerTogglePvpEvent(player, false, false);
|
||||
Bukkit.getGlobalRegionScheduler().run(PreventStabby.getPlugin(), (task) -> {
|
||||
if (PlayerTogglePvpEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
Bukkit.getPluginManager().callEvent(toggleEvent);
|
||||
}
|
||||
if (toggleEvent.isSendMessage()) {
|
||||
PluginMessages.sendMessage(player, PreventStabby.getPlugin().getConfigCache().pvp_disabled);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
if (PreventStabbyPermission.COMMAND_TOGGLE_OTHERS.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.sendMessage(sender, "Try /pvp disable <player>");
|
||||
} else {
|
||||
PluginMessages.sendMessage(sender, "Try /pvp disable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package me.youhavetrouble.preventstabby.commands;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.config.PreventStabbyPermission;
|
||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class ReloadCommand {
|
||||
|
||||
public static void reload(CommandSender sender) {
|
||||
Bukkit.getAsyncScheduler().runNow(PreventStabby.getPlugin(), (task) -> {
|
||||
if (!PreventStabbyPermission.COMMAND_RELOAD.doesCommandSenderHave(sender)) {
|
||||
PluginMessages.parseMessage(sender, PreventStabby.getPlugin().getConfigCache().no_permission);
|
||||
return;
|
||||
}
|
||||
PreventStabby.getPlugin().reloadPluginConfig(sender);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
package me.youhavetrouble.preventstabby.config;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class ConfigCache {
|
||||
|
||||
public final boolean pvp_enabled_by_default,
|
||||
bucket_stopper_enabled,
|
||||
fire_stopper_enabled,
|
||||
block_stopper_enabled,
|
||||
punish_for_combat_logout_kill,
|
||||
punish_for_combat_logout_announce,
|
||||
block_teleports_in_combat,
|
||||
allow_fishing_rod_pull;
|
||||
public final String pvp_enabled, pvp_disabled, cannot_attack_victim, cannot_attack_attacker,
|
||||
cannot_attack_pets_victim, cannot_attack_pets_attacker, no_permission, no_such_command, pvp_enabled_other,
|
||||
pvp_disabled_other, punish_for_combat_logout_message, entering_combat, leaving_combat,
|
||||
cant_do_that_during_combat, cannot_attack_mounts_attacker, cannot_attack_mounts_victim, force_pvp_on,
|
||||
force_pvp_off, force_pvp_none, placeholder_combat_time, placeholder_not_in_combat, cannot_attack_pvp_force_off,
|
||||
placeholder_pvp_forced_true, placeholder_pvp_forced_false, placeholder_pvp_forced_none;
|
||||
|
||||
public final String cannot_attack_forced_pvp_off, cannot_attack_teleport_or_spawn_protection_attacker,
|
||||
cannot_attack_pets_teleport_or_spawn_protection_attacker, cannot_attack_mounts_teleport_or_spawn_protection_attacker,
|
||||
cannot_attack_teleport_or_spawn_protection_victim;
|
||||
|
||||
public final double combat_time, login_protection_time, teleport_protection_time, bucket_stopper_radius,
|
||||
fire_stopper_radius, block_stopper_radius;
|
||||
private final Set<String> combatBlockedCommands = new HashSet<>();
|
||||
private final Set<Material> dangerousBlocks = new HashSet<>();
|
||||
|
||||
private final FileConfiguration config;
|
||||
|
||||
public ConfigCache(PreventStabby plugin) {
|
||||
plugin.reloadConfig();
|
||||
config = plugin.getConfig();
|
||||
|
||||
migrate("settings.punish_for_combat_logout.enabled",
|
||||
"settings.punish_for_combat_logout.kill",
|
||||
true);
|
||||
|
||||
// Settings
|
||||
this.pvp_enabled_by_default = getBoolean(
|
||||
"settings.pvp_enabled_by_default",
|
||||
false,
|
||||
List.of("Should pvp be enabled by default when the player first joins?")
|
||||
);
|
||||
|
||||
this.combat_time = getDouble(
|
||||
"settings.combat_time",
|
||||
25,
|
||||
List.of("How long in seconds should combat last since the last hit")
|
||||
);
|
||||
|
||||
this.punish_for_combat_logout_kill = getBoolean(
|
||||
"settings.punish_for_combat_logout.kill",
|
||||
true,
|
||||
List.of("Should players be killed if they log out during combat?")
|
||||
);
|
||||
this.punish_for_combat_logout_announce = getBoolean(
|
||||
"settings.punish_for_combat_logout.announce",
|
||||
true,
|
||||
List.of("Should we announce that player logged out of combat?")
|
||||
);
|
||||
|
||||
List<String> commandsBlockedInCombat = getList(
|
||||
"settings.block_in_combat.commands",
|
||||
List.of("spawn", "tpa", "home"),
|
||||
List.of("Commands to block when player is in combat")
|
||||
);
|
||||
for (String command : commandsBlockedInCombat) {
|
||||
this.combatBlockedCommands.add(command.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
this.block_teleports_in_combat = getBoolean(
|
||||
"settings.block_in_combat.teleports",
|
||||
false,
|
||||
List.of("Block teleportation triggered by plugins while in combat")
|
||||
);
|
||||
|
||||
this.login_protection_time = getDouble(
|
||||
"settings.login_protection_time",
|
||||
0,
|
||||
List.of("Protection time after player logs in in seconds")
|
||||
);
|
||||
this.teleport_protection_time = getDouble(
|
||||
"settings.teleport_protection_time",
|
||||
0,
|
||||
List.of("Protection time after player is teleported in seconds")
|
||||
);
|
||||
|
||||
this.allow_fishing_rod_pull = getBoolean(
|
||||
"settings.allow_fishing_rod_pull",
|
||||
false,
|
||||
List.of("Should fishing rod pulling be allowed regardless of players pvp state?")
|
||||
);
|
||||
this.bucket_stopper_enabled = getBoolean(
|
||||
"settings.environmental.bucket_stopper.enabled",
|
||||
true,
|
||||
List.of("Should plugin block dumping buckets with dangers near players with pvp off?")
|
||||
);
|
||||
this.bucket_stopper_radius = getDouble(
|
||||
"settings.environmental.bucket_stopper.radius",
|
||||
2.5,
|
||||
List.of("Distance from the player where dumping buckets will be disallowed")
|
||||
);
|
||||
this.fire_stopper_enabled = getBoolean(
|
||||
"settings.environmental.fire_stopper.enabled",
|
||||
true,
|
||||
List.of("Should plugin block igniting blocks near players with pvp off?")
|
||||
);
|
||||
this.fire_stopper_radius = getDouble(
|
||||
"settings.environmental.fire_stopper.radius",
|
||||
2.5,
|
||||
List.of("Distance from the player where igniting blocks will be disallowed")
|
||||
);
|
||||
this.block_stopper_enabled = getBoolean(
|
||||
"settings.environmental.block_stopper.enabled",
|
||||
true,
|
||||
List.of("Should plugin block placing dangerous blocks near players with pvp off?")
|
||||
);
|
||||
this.block_stopper_radius = getDouble(
|
||||
"settings.environmental.block_stopper.radius",
|
||||
2.5,
|
||||
List.of("Distance from the player where placing dangerous blocks will be disallowed")
|
||||
);
|
||||
List<String> rawDangerousBlocks = getList(
|
||||
"settings.environmental.block_stopper.blocks",
|
||||
List.of("tnt", "magma_block", "cactus", "campfire"),
|
||||
List.of("List of dangerous blocks that will be blocked when placed near players with pvp off")
|
||||
);
|
||||
for (String block : rawDangerousBlocks) {
|
||||
Material material = Material.matchMaterial(block);
|
||||
if (material != null) {
|
||||
dangerousBlocks.add(material);
|
||||
} else {
|
||||
plugin.getLogger().warning("Invalid material: " + block);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Messages
|
||||
this.pvp_enabled = getString("messages.pvp_enabled", "<red>You enabled PvP!");
|
||||
this.pvp_disabled = getString("messages.pvp_disabled", "<red>You disabled PvP!");
|
||||
this.cannot_attack_victim = getString("messages.cannot_attack_victim", "<red>You can't attack players that have PvP turned off!");
|
||||
this.cannot_attack_attacker = getString("messages.cannot_attack_attacker", "<red>You can't attack players while you have PvP turned off!");
|
||||
this.cannot_attack_pets_victim = getString("messages.cannot_attack_pets_victim", "<red>You can't attack pets while you have PvP turned off");
|
||||
this.cannot_attack_pets_attacker = getString("messages.cannot_attack_pets_attacker", "<red>You can't attack pets of players that have PvP turned off");
|
||||
this.cannot_attack_mounts_victim = getString("messages.cannot_attack_mounts_victim", "<red>You can't attack mounts of players that have PvP turned off");
|
||||
this.cannot_attack_mounts_attacker = getString("messages.cannot_attack_mounts_attacker", "<red>You can't attack mounts while you have PvP turned off");
|
||||
this.cannot_attack_pvp_force_off = getString("messages.cannot_attack_pvp_force_off", "<red>PvP is forcibly disabled");
|
||||
|
||||
this.no_permission = getString("messages.no_permission", "<red>You don't have permission to use that.");
|
||||
this.no_such_command = getString("messages.no_such_command", "<red>No such command.");
|
||||
this.pvp_enabled_other = getString("messages.pvp_enabled_others", "<red>You've enabled %player%'s PvP.");
|
||||
this.pvp_disabled_other = getString("messages.pvp_disabled_others", "<red>You've disabled %player%'s PvP.");
|
||||
this.entering_combat = getString("messages.entering_combat", "<red>Entering combat");
|
||||
this.leaving_combat = getString("messages.leaving_combat", "<red>Leaving combat");
|
||||
this.cant_do_that_during_combat = getString("messages.cant_do_that_during_combat", "<red>You can't do that while in combat!");
|
||||
this.force_pvp_on = getString("messages.force_pvp_on", "PvP is now force enabled");
|
||||
this.force_pvp_off = getString("messages.force_pvp_off", "PvP is now force disabled");
|
||||
this.force_pvp_none = getString("messages.force_pvp_none", "PvP state is not forced now");
|
||||
|
||||
this.punish_for_combat_logout_message = getString("messages.punish_for_combat_logout.message", "%player%<reset><white> logged out while in combat. What a loser.");
|
||||
|
||||
this.placeholder_combat_time = getString("placeholder.placeholder_combat_time", "Combat time: %time%");
|
||||
this.placeholder_not_in_combat = getString("placeholder.not_in_combat", "Not in combat");
|
||||
|
||||
this.placeholder_pvp_forced_true = getString("placeholder.pvp_forced_true", "PvP is forced on");
|
||||
this.placeholder_pvp_forced_false = getString("placeholder.pvp_forced_false", "PvP is forced off");
|
||||
this.placeholder_pvp_forced_none = getString("placeholder.pvp_forced_none", "PvP is not forced");
|
||||
|
||||
this.cannot_attack_forced_pvp_off = getString("messages.cannot_attack_pvp_force_off", "<red>PvP is forcibly disabled");
|
||||
this.cannot_attack_teleport_or_spawn_protection_attacker = getString("messages.cannot_attack_teleport_or_spawn_protection_attacker", "<red>You can't attack players while they have teleport or spawn protection");
|
||||
this.cannot_attack_pets_teleport_or_spawn_protection_attacker = getString("messages.cannot_attack_pets_teleport_or_spawn_protection_attacker", "<red>You can't attack pets while you have teleport or spawn protection");
|
||||
this.cannot_attack_mounts_teleport_or_spawn_protection_attacker = getString("messages.cannot_attack_mounts_teleport_or_spawn_protection_attacker", "<red>You can't attack mounts while you have teleport or spawn protection");
|
||||
this.cannot_attack_teleport_or_spawn_protection_victim = getString("messages.cannot_attack_teleport_or_spawn_protection_victim", "<red>You can't attack players while you have teleport or spawn protection");
|
||||
try {
|
||||
config.save(new File(plugin.getDataFolder(), "config.yml"));
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Failed to save configuration file! - " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getCombatBlockedCommands() {
|
||||
return Collections.unmodifiableSet(combatBlockedCommands);
|
||||
}
|
||||
|
||||
public Set<Material> getDangerousBlocks() {
|
||||
return Collections.unmodifiableSet(dangerousBlocks);
|
||||
}
|
||||
|
||||
private String getString(String path, @NotNull String def) {
|
||||
return getString(path, def, null);
|
||||
}
|
||||
|
||||
private String getString(String path, @NotNull String def, @Nullable List<String> comments) {
|
||||
String value;
|
||||
if (config.isSet(path)) {
|
||||
value = config.getString(path, def);
|
||||
} else {
|
||||
config.set(path, def);
|
||||
value = def;
|
||||
}
|
||||
if (comments != null) config.setComments(path, comments);
|
||||
return value;
|
||||
}
|
||||
|
||||
private boolean getBoolean(String path, boolean def, @Nullable List<String> comments) {
|
||||
boolean value;
|
||||
if (config.isSet(path)) {
|
||||
value = config.getBoolean(path, def);
|
||||
} else {
|
||||
config.set(path, def);
|
||||
value = def;
|
||||
}
|
||||
if (comments != null) config.setComments(path, comments);
|
||||
return value;
|
||||
}
|
||||
|
||||
private double getDouble(String path, double def, @Nullable List<String> comments) {
|
||||
double value;
|
||||
if (config.isSet(path)) {
|
||||
value = config.getDouble(path, def);
|
||||
} else {
|
||||
config.set(path, def);
|
||||
value = def;
|
||||
}
|
||||
if (comments != null) config.setComments(path, comments);
|
||||
return value;
|
||||
}
|
||||
|
||||
private long getLong(String path, long def, @Nullable List<String> comments) {
|
||||
long value;
|
||||
if (config.isSet(path)) {
|
||||
value = config.getLong(path, def);
|
||||
} else {
|
||||
config.set(path, def);
|
||||
value = def;
|
||||
}
|
||||
if (comments != null) config.setComments(path, comments);
|
||||
return value;
|
||||
}
|
||||
|
||||
private List<String> getList(String path, List<String> def, @Nullable List<String> comments) {
|
||||
List<String> value;
|
||||
if (config.isSet(path)) {
|
||||
value = config.getStringList(path);
|
||||
} else {
|
||||
config.set(path, def);
|
||||
value = def;
|
||||
}
|
||||
if (comments != null) config.setComments(path, comments);
|
||||
return value;
|
||||
}
|
||||
|
||||
private List<String> getList(String path, List<String> def) {
|
||||
return getList(path, def, null);
|
||||
}
|
||||
|
||||
private void migrate(String oldPath, String newPath, @Nullable Object defaultValue) {
|
||||
if (config.isSet(oldPath) && !config.isSet(newPath)) {
|
||||
Object value = config.get(oldPath);
|
||||
config.set(newPath, value != null ? value : defaultValue);
|
||||
config.set(oldPath, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package me.youhavetrouble.preventstabby.config;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public enum PreventStabbyPermission {
|
||||
|
||||
COMMAND("command"),
|
||||
COMMAND_TOGGLE("command.toggle"),
|
||||
COMMAND_TOGGLE_OTHERS("command.toggle.others"),
|
||||
COMMAND_RELOAD("command.reload"),
|
||||
COMMAND_GLOBAL_TOGGLE("command.toggle.global"),
|
||||
COMMAND_HELP("command.help");
|
||||
|
||||
private final String permission;
|
||||
PreventStabbyPermission(String permission) {
|
||||
this.permission = "preventstabby."+permission;
|
||||
}
|
||||
|
||||
public boolean doesCommandSenderHave(CommandSender sender) {
|
||||
return sender.hasPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package me.youhavetrouble.preventstabby.data;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @param ableToDamage Result of the damage check
|
||||
* @param feedbackForAttacker Feedback to send to the attacker
|
||||
* @param attackerId UUID of attacker player
|
||||
* @param victimId UUID of victim player
|
||||
*/
|
||||
public record DamageCheckResult(
|
||||
boolean ableToDamage,
|
||||
@Nullable UUID attackerId,
|
||||
@Nullable UUID victimId,
|
||||
@Nullable String feedbackForAttacker,
|
||||
boolean shouldVictimBePutInCombat
|
||||
) {
|
||||
|
||||
public static DamageCheckResult positive() {
|
||||
return new DamageCheckResult(
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public static DamageCheckResult positive(UUID attackerId, UUID victimId, boolean shouldVictimBePutInCombat) {
|
||||
return new DamageCheckResult(
|
||||
true,
|
||||
attackerId,
|
||||
victimId,
|
||||
null,
|
||||
shouldVictimBePutInCombat
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package me.youhavetrouble.preventstabby.data;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* PreventStabby player data keeper.
|
||||
*/
|
||||
public class PlayerData {
|
||||
|
||||
private final UUID playerUuid;
|
||||
private long lastAccessTimestamp;
|
||||
private Long combatStartTimestamp, teleportTimestamp, loginTimestamp;
|
||||
private boolean pvpEnabled, lastCombatCheck;
|
||||
private final Set<UUID> relatedEntities = new HashSet<>();
|
||||
|
||||
public PlayerData(UUID playerUuid, boolean pvpEnabled) {
|
||||
this.playerUuid = playerUuid;
|
||||
this.pvpEnabled = pvpEnabled;
|
||||
this.lastCombatCheck = false;
|
||||
this.combatStartTimestamp = null;
|
||||
this.loginTimestamp = null;
|
||||
this.teleportTimestamp = null;
|
||||
refreshCacheTime();
|
||||
}
|
||||
|
||||
public UUID getPlayerUuid() {
|
||||
return playerUuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if player has personal pvp enabled, false otherwise.
|
||||
* @return True if player has personal pvp enabled, false otherwise.
|
||||
*/
|
||||
public boolean isPvpEnabled() {
|
||||
return pvpEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets player's personal pvp state.
|
||||
* @param pvpEnabled Pvp state to set.
|
||||
*/
|
||||
protected void setPvpEnabled(boolean pvpEnabled) {
|
||||
this.pvpEnabled = pvpEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns player's last access timestamp.
|
||||
* @return Player's last access timestamp.
|
||||
*/
|
||||
protected long getLastAccessTimestamp() {
|
||||
return lastAccessTimestamp;
|
||||
}
|
||||
|
||||
protected boolean isCacheExpired() {
|
||||
return System.currentTimeMillis() - lastAccessTimestamp > 60000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the last access to any of the fields
|
||||
*/
|
||||
protected void refreshCacheTime() {
|
||||
this.lastAccessTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the timestamp when combat started.
|
||||
* @return The timestamp when combat started.
|
||||
*/
|
||||
protected long getCombatStartTimestamp() {
|
||||
refreshCacheTime();
|
||||
return combatStartTimestamp;
|
||||
}
|
||||
|
||||
protected boolean getLastCombatCheckState() {
|
||||
return lastCombatCheck;
|
||||
}
|
||||
|
||||
protected void setLastCombatCheckState(boolean state) {
|
||||
this.lastCombatCheck = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the player as in combat.
|
||||
*/
|
||||
public void markInCombat() {
|
||||
refreshCacheTime();
|
||||
if (PreventStabby.getPlugin().getConfigCache().combat_time <= 0) return;
|
||||
this.combatStartTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
protected void markNotInCombat() {
|
||||
refreshCacheTime();
|
||||
this.combatStartTimestamp = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the login timestamp for the player.
|
||||
* @param loginTimestamp The login timestamp to set.
|
||||
*/
|
||||
protected void setLoginTimestamp(long loginTimestamp) {
|
||||
this.loginTimestamp = loginTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the login timestamp for the player.
|
||||
* @return The login timestamp for the player.
|
||||
*/
|
||||
@Nullable
|
||||
public Long getLoginTimestamp() {
|
||||
return loginTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timestamp of the player's teleport.
|
||||
* @param teleportTimestamp The timestamp of the player's teleport.
|
||||
*/
|
||||
public void setTeleportTimestamp(long teleportTimestamp) {
|
||||
this.teleportTimestamp = teleportTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is currently in combat.
|
||||
*
|
||||
* @return true if the player is in combat, false otherwise.
|
||||
*/
|
||||
public boolean isInCombat() {
|
||||
if (combatStartTimestamp == null) return false;
|
||||
return System.currentTimeMillis() - (combatStartTimestamp + (PreventStabby.getPlugin().getConfigCache().combat_time * 1000)) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the number of seconds left until combat ends for the player.
|
||||
* @return The number of seconds left until combat ends. -1 if not in combat
|
||||
*/
|
||||
public long getSecondsLeftUntilCombatEnd() {
|
||||
if (combatStartTimestamp == null) return -1;
|
||||
long timeSinceCombatStart = System.currentTimeMillis() - combatStartTimestamp;
|
||||
long combatTimeConfigured = (long) (PreventStabby.getPlugin().getConfigCache().combat_time * 1000);
|
||||
return (timeSinceCombatStart < combatTimeConfigured) ? (combatTimeConfigured - timeSinceCombatStart) / 1000 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has login protection.
|
||||
*
|
||||
* @return true if the player has login protection, false otherwise.
|
||||
*/
|
||||
public boolean hasLoginProtection() {
|
||||
if (loginTimestamp == null) return false;
|
||||
return System.currentTimeMillis() - (loginTimestamp + (PreventStabby.getPlugin().getConfigCache().login_protection_time * 1000)) < 0;
|
||||
}
|
||||
|
||||
public boolean hasTeleportProtection() {
|
||||
if (teleportTimestamp == null) return false;
|
||||
return System.currentTimeMillis() - (teleportTimestamp + (PreventStabby.getPlugin().getConfigCache().teleport_protection_time * 1000)) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the player has any form of protection enabled, including login and teleport protection.
|
||||
*
|
||||
* @return true if the player has protection enabled, false otherwise.
|
||||
*/
|
||||
public boolean isProtected() {
|
||||
return hasLoginProtection() || hasTeleportProtection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of entities related to the player that should keep player's data loaded
|
||||
* @return The list of entities related to the player that should keep player's data loaded
|
||||
*/
|
||||
public Set<UUID> getRelatedEntities() {
|
||||
return relatedEntities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getRelatedEntities()
|
||||
* @param entity The entity id to add to the list of related entities
|
||||
*/
|
||||
public void addRelatedEntity(UUID entity) {
|
||||
relatedEntities.add(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getRelatedEntities()
|
||||
* @param entity The entity id to remove from the list of related entities
|
||||
*/
|
||||
public void removeRelatedEntity(UUID entity) {
|
||||
relatedEntities.remove(entity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package me.youhavetrouble.preventstabby.data;
|
||||
|
||||
import com.destroystokyo.paper.event.entity.EntityAddToWorldEvent;
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.player.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class PlayerListener implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerLogin(AsyncPlayerPreLoginEvent event) {
|
||||
if (!event.getLoginResult().equals(AsyncPlayerPreLoginEvent.Result.ALLOWED)) return;
|
||||
UUID uuid = event.getUniqueId();
|
||||
try {
|
||||
PreventStabby.getPlugin().getPlayerManager().getPlayerData(uuid).get();
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
PreventStabby.getPlugin().getLogger().severe(e.getMessage());
|
||||
PreventStabby.getPlugin().getLogger().severe("Failed to load data for player %s".formatted(event.getPlayerProfile().getName()));
|
||||
PreventStabby.getPlugin().getPlayerManager().addPlayer(uuid, new PlayerData(uuid, false));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
PlayerData playerData = PreventStabby.getPlugin().getPlayerManager().getPlayer(event.getPlayer().getUniqueId());
|
||||
playerData.setLoginTimestamp(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* This event is here to save player's data to database
|
||||
* Also punishes players who log out during combat
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerLeave(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
PlayerData playerData = PreventStabby.getPlugin().getPlayerManager().getPlayer(player.getUniqueId());
|
||||
if (playerData == null) return;
|
||||
if (!playerData.isInCombat()) return;
|
||||
if (PreventStabby.getPlugin().getConfigCache().punish_for_combat_logout_announce) {
|
||||
PluginMessages.broadcastMessage(player, PreventStabby.getPlugin().getConfigCache().punish_for_combat_logout_message);
|
||||
}
|
||||
if (!PreventStabby.getPlugin().getConfigCache().punish_for_combat_logout_kill) return;
|
||||
player.setHealth(0);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
PlayerData playerData = PreventStabby.getPlugin().getPlayerManager().getPlayer(player.getUniqueId());
|
||||
if (playerData == null) return; // Plugins using players as entities can cause this state
|
||||
playerData.setTeleportTimestamp(Instant.now().getEpochSecond());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onPlayerDeath(EntityDeathEvent event) {
|
||||
if (!(event.getEntity() instanceof Player player)) return;
|
||||
PlayerData playerData = PreventStabby.getPlugin().getPlayerManager().getPlayer(player.getUniqueId());
|
||||
if (playerData == null) return; // Plugins using players as entities can cause this state
|
||||
playerData.markNotInCombat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load data for owners of loaded tameables
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onEntityLoad(EntityAddToWorldEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (!(entity instanceof Tameable tameable)) return;
|
||||
UUID ownerId = tameable.getOwnerUniqueId();
|
||||
if (ownerId == null) return;
|
||||
PreventStabby.getPlugin().getPlayerManager().getPlayerData(ownerId).thenAccept(playerData -> {
|
||||
if (playerData == null) return;
|
||||
playerData.addRelatedEntity(entity.getUniqueId());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
package me.youhavetrouble.preventstabby.data;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.api.event.PlayerEnterCombatEvent;
|
||||
import me.youhavetrouble.preventstabby.api.event.PlayerLeaveCombatEvent;
|
||||
import me.youhavetrouble.preventstabby.hooks.WorldGuardHook;
|
||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||
import me.youhavetrouble.preventstabby.util.PvpState;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class PlayerManager {
|
||||
|
||||
private final PreventStabby plugin;
|
||||
private final ConcurrentHashMap<UUID, PlayerData> playerList = new ConcurrentHashMap<>();
|
||||
private PvpState pvpForcedState = PvpState.NONE;
|
||||
|
||||
public PlayerManager(PreventStabby plugin) {
|
||||
this.plugin = plugin;
|
||||
Bukkit.getAsyncScheduler().runAtFixedRate(plugin, (task) -> {
|
||||
// Check for entries that should be invalidated
|
||||
playerList.values().removeIf(PlayerData::isCacheExpired);
|
||||
}, 250, 250, TimeUnit.MILLISECONDS);
|
||||
|
||||
Bukkit.getAsyncScheduler().runAtFixedRate(plugin, (task) -> {
|
||||
Collection<? extends Player> players = new ArrayList<>(Bukkit.getOnlinePlayers());
|
||||
// Load data for all online players as a failsafe
|
||||
CompletableFuture.allOf(players.stream().map(player -> getPlayerData(player.getUniqueId())).toArray(CompletableFuture[]::new)).join();
|
||||
// Refresh cache time for all players
|
||||
for (PlayerData playerData : playerList.values()) {
|
||||
if (playerData == null) continue;
|
||||
playerData.refreshCacheTime();
|
||||
}
|
||||
}, 1, 1, TimeUnit.SECONDS);
|
||||
|
||||
Bukkit.getGlobalRegionScheduler().runAtFixedRate(plugin, (task) -> {
|
||||
for (PlayerData playerData : playerList.values()) {
|
||||
if (playerData == null) continue;
|
||||
Player player = Bukkit.getPlayer(playerData.getPlayerUuid());
|
||||
playerData.getRelatedEntities().removeIf( uuid -> {
|
||||
Entity entity = Bukkit.getEntity(uuid);
|
||||
return entity == null;
|
||||
});
|
||||
if (player == null || !player.isOnline()) {
|
||||
// player not online, so check for related entities
|
||||
if (playerData.getRelatedEntities().isEmpty()) continue;
|
||||
}
|
||||
playerData.refreshCacheTime();
|
||||
if (player == null || !player.isOnline()) continue; // If player is offline, skip the rest of the logic
|
||||
// leaving combat logic
|
||||
if (playerData.getLastCombatCheckState() && !playerData.isInCombat()) {
|
||||
PlayerLeaveCombatEvent leaveCombatEvent = null;
|
||||
if (PlayerLeaveCombatEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
leaveCombatEvent = new PlayerLeaveCombatEvent(player);
|
||||
Bukkit.getPluginManager().callEvent(leaveCombatEvent);
|
||||
}
|
||||
if (leaveCombatEvent != null && leaveCombatEvent.isCancelled()) {
|
||||
playerData.markInCombat();
|
||||
playerData.setLastCombatCheckState(playerData.isInCombat());
|
||||
continue;
|
||||
}
|
||||
PluginMessages.sendActionBar(player, plugin.getConfigCache().leaving_combat);
|
||||
playerData.setLastCombatCheckState(playerData.isInCombat());
|
||||
continue;
|
||||
}
|
||||
// entering combat logic
|
||||
if (plugin.getConfigCache().combat_time <= 0) return; // disable combat entering when combat time is <0
|
||||
if (!playerData.getLastCombatCheckState() && playerData.isInCombat()) {
|
||||
PlayerEnterCombatEvent enterCombatEvent = null;
|
||||
if (PlayerEnterCombatEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
enterCombatEvent = new PlayerEnterCombatEvent(player);
|
||||
Bukkit.getPluginManager().callEvent(enterCombatEvent);
|
||||
}
|
||||
if (enterCombatEvent != null && enterCombatEvent.isCancelled()) {
|
||||
playerData.markNotInCombat();
|
||||
playerData.setLastCombatCheckState(playerData.isInCombat());
|
||||
continue;
|
||||
}
|
||||
PluginMessages.sendActionBar(player, plugin.getConfigCache().entering_combat);
|
||||
playerData.setLastCombatCheckState(playerData.isInCombat());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets player's PlayerData object. Returns null when player with provided UUID doesn't exist.
|
||||
*
|
||||
* @param uuid Player's UUID.
|
||||
* @return Player's PlayerData object or null if player doesn't exist.
|
||||
*/
|
||||
public PlayerData getPlayer(UUID uuid) {
|
||||
return playerList.get(uuid);
|
||||
}
|
||||
|
||||
protected void addPlayer(UUID uuid, PlayerData data) {
|
||||
playerList.put(uuid, data);
|
||||
}
|
||||
|
||||
public void handleDamageCheck(@NotNull DamageCheckResult damageCheckResult) {
|
||||
if (damageCheckResult.attackerId() == null) return;
|
||||
if (damageCheckResult.victimId() == null) return;
|
||||
PluginMessages.sendOutMessages(damageCheckResult);
|
||||
PlayerData attacker = getPlayer(damageCheckResult.attackerId());
|
||||
PlayerData victim = getPlayer(damageCheckResult.victimId());
|
||||
if (attacker == null || victim == null) return;
|
||||
if (!damageCheckResult.ableToDamage()) return;
|
||||
attacker.markInCombat();
|
||||
if (!damageCheckResult.shouldVictimBePutInCombat()) return;
|
||||
victim.markInCombat();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines whether the given attacker can damage the victim.
|
||||
*
|
||||
* @param attacker The attacking entity.
|
||||
* @param victim The victim entity.
|
||||
* @return A {@link DamageCheckResult} object containing the result of the damage check.
|
||||
*/
|
||||
public DamageCheckResult canDamage(@NotNull Entity attacker, @NotNull Entity victim) {
|
||||
Target attackerData = Target.getTarget(attacker);
|
||||
Target victimData = Target.getTarget(victim);
|
||||
if (attackerData == null || victimData == null) return DamageCheckResult.positive();
|
||||
return canDamage(attackerData.playerUuid, victimData.playerUuid, victimData.classifier);
|
||||
}
|
||||
|
||||
public DamageCheckResult canDamage(UUID attackerId, UUID victimId, Target.EntityClassifier victimClassifier) {
|
||||
|
||||
if (attackerId == null || victimId == null) return DamageCheckResult.positive();
|
||||
|
||||
PlayerData attackerPlayerData = getPlayer(attackerId);
|
||||
PlayerData victimPlayerData = getPlayer(victimId);
|
||||
|
||||
if (attackerPlayerData == null || victimPlayerData == null) {
|
||||
return DamageCheckResult.positive();
|
||||
}
|
||||
|
||||
if (attackerPlayerData.getPlayerUuid().equals(victimPlayerData.getPlayerUuid())) {
|
||||
return DamageCheckResult.positive(attackerId, victimId, false);
|
||||
}
|
||||
|
||||
if (attackerPlayerData.isProtected()) {
|
||||
String message = switch (victimClassifier) {
|
||||
case PLAYER -> plugin.getConfigCache().cannot_attack_teleport_or_spawn_protection_attacker;
|
||||
case PET -> plugin.getConfigCache().cannot_attack_pets_teleport_or_spawn_protection_attacker;
|
||||
case MOUNT -> plugin.getConfigCache().cannot_attack_mounts_teleport_or_spawn_protection_attacker;
|
||||
default -> null;
|
||||
};
|
||||
return new DamageCheckResult(false, attackerId, victimId, message, false);
|
||||
}
|
||||
if (victimPlayerData.isProtected()) {
|
||||
String message = null;
|
||||
if (victimClassifier == Target.EntityClassifier.PLAYER) {
|
||||
message = plugin.getConfigCache().cannot_attack_teleport_or_spawn_protection_victim;
|
||||
}
|
||||
return new DamageCheckResult(false, attackerId, victimId, message, false);
|
||||
}
|
||||
|
||||
switch (getForcedPvpState()) {
|
||||
case DISABLED -> {
|
||||
return new DamageCheckResult(false, attackerId, victimId, plugin.getConfigCache().cannot_attack_forced_pvp_off, false);
|
||||
}
|
||||
case ENABLED -> {
|
||||
return DamageCheckResult.positive(attackerId, victimId, victimClassifier.equals(Target.EntityClassifier.PLAYER));
|
||||
}
|
||||
}
|
||||
|
||||
if (!attackerPlayerData.isPvpEnabled() || (PreventStabby.worldGuardHookEnabled() && !WorldGuardHook.isPlayerForcedToPvp(Bukkit.getPlayer(attackerId)))) {
|
||||
String message = switch (victimClassifier) {
|
||||
case PLAYER -> plugin.getConfigCache().cannot_attack_attacker;
|
||||
case PET -> plugin.getConfigCache().cannot_attack_pets_victim;
|
||||
case MOUNT -> plugin.getConfigCache().cannot_attack_mounts_attacker;
|
||||
default -> null;
|
||||
};
|
||||
return new DamageCheckResult(false, attackerId, victimId, message, victimClassifier.equals(Target.EntityClassifier.PLAYER));
|
||||
}
|
||||
|
||||
if (!victimPlayerData.isPvpEnabled() || (PreventStabby.worldGuardHookEnabled() && !WorldGuardHook.isPlayerForcedToPvp(Bukkit.getPlayer(victimId)))) {
|
||||
String message = switch (victimClassifier) {
|
||||
case PLAYER -> plugin.getConfigCache().cannot_attack_victim;
|
||||
case PET -> plugin.getConfigCache().cannot_attack_pets_attacker;
|
||||
case MOUNT -> plugin.getConfigCache().cannot_attack_mounts_victim;
|
||||
default -> null;
|
||||
};
|
||||
return new DamageCheckResult(false, attackerId, victimId, message, victimClassifier.equals(Target.EntityClassifier.PLAYER));
|
||||
}
|
||||
|
||||
return new DamageCheckResult(
|
||||
true,
|
||||
attackerId,
|
||||
victimId,
|
||||
null,
|
||||
victimClassifier.equals(Target.EntityClassifier.PLAYER)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current forced pvp state.
|
||||
* @return Current forced pvp state.
|
||||
*/
|
||||
public PvpState getForcedPvpState() {
|
||||
return pvpForcedState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets current forced pvp state.
|
||||
* @param forcedPvpState New forced pvp state.
|
||||
*/
|
||||
public void setForcedPvpState(PvpState forcedPvpState) {
|
||||
this.pvpForcedState = forcedPvpState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the PlayerData object for the player with the provided UUID. Returns new default if there isn't data.
|
||||
*
|
||||
* @param uuid The UUID of the player.
|
||||
* @return The PlayerData object associated with the player.
|
||||
*/
|
||||
public CompletableFuture<PlayerData> getPlayerData(UUID uuid) {
|
||||
// Try to get data from cache and refresh it
|
||||
PlayerData data = getPlayer(uuid);
|
||||
if (data != null) {
|
||||
data.refreshCacheTime();
|
||||
return CompletableFuture.completedFuture(data);
|
||||
}
|
||||
// Get data from database or provide default
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
PlayerData playerData = plugin.getSqLite().getPlayerInfo(uuid);
|
||||
if (playerData == null) {
|
||||
playerData = new PlayerData(uuid, false);
|
||||
}
|
||||
plugin.getPlayerManager().addPlayer(uuid, playerData);
|
||||
return playerData;
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> setPlayerPvpState(UUID uuid, boolean state) {
|
||||
// If player is in cache update that
|
||||
if (getPlayer(uuid) != null) {
|
||||
getPlayer(uuid).setPvpEnabled(state);
|
||||
}
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
// Update the database aswell
|
||||
plugin.getSqLite().updatePlayerInfo(uuid, new PlayerData(uuid, state));
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<Boolean> togglePlayerPvpState(UUID uuid) {
|
||||
return getPlayerData(uuid).thenApply(playerData -> {
|
||||
playerData.setPvpEnabled(!playerData.isPvpEnabled());
|
||||
plugin.getSqLite().updatePlayerInfo(uuid, new PlayerData(uuid, playerData.isPvpEnabled()));
|
||||
return playerData.isPvpEnabled();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package me.youhavetrouble.preventstabby.data;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataHolder;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Target {
|
||||
|
||||
public static final NamespacedKey playerSourceIdKey = new NamespacedKey("preventstabby", "playersource");
|
||||
|
||||
/**
|
||||
* The unique identifier for a player.
|
||||
*/
|
||||
public final UUID playerUuid;
|
||||
|
||||
/**
|
||||
* Represents the entity classifier of a target.
|
||||
* This indicates what type of entity player's id was assumed from
|
||||
*/
|
||||
public final EntityClassifier classifier;
|
||||
|
||||
private Target(UUID uuid, EntityClassifier classifier) {
|
||||
this.playerUuid = uuid;
|
||||
this.classifier = classifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UUID of the actual player, being owner of a pet, shooter of a projectile, etc.
|
||||
*
|
||||
* @param entity Base entity to get the player UUID from
|
||||
* @return UUID of the actual player, null if not found
|
||||
*/
|
||||
@Nullable
|
||||
public static Target getTarget(@NotNull Entity entity) {
|
||||
if (entity instanceof Player) return new Target(entity.getUniqueId(), EntityClassifier.PLAYER);
|
||||
|
||||
// Get shooter of projectile
|
||||
if (entity instanceof Projectile projectile) {
|
||||
if (projectile.getShooter() instanceof Player shooter) {
|
||||
return new Target(shooter.getUniqueId(), EntityClassifier.PLAYER);
|
||||
}
|
||||
}
|
||||
|
||||
// Get player riding mount
|
||||
if (!entity.getPassengers().isEmpty()) {
|
||||
Entity passenger = entity.getPassengers().get(0);
|
||||
if (passenger instanceof Player) {
|
||||
return new Target(passenger.getUniqueId(), EntityClassifier.MOUNT);
|
||||
}
|
||||
}
|
||||
|
||||
// Get owner of tamed entity
|
||||
if (entity instanceof Tameable tameable) {
|
||||
if (tameable.getOwner() != null) {
|
||||
return new Target(tameable.getOwner().getUniqueId(), EntityClassifier.PET);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to get player's id from other various entities
|
||||
PersistentDataContainer pdc = entity.getPersistentDataContainer();
|
||||
if (!pdc.has(playerSourceIdKey)) return null;
|
||||
String id = pdc.get(playerSourceIdKey, PersistentDataType.STRING);
|
||||
if (id == null) return null;
|
||||
try {
|
||||
UUID uuid = UUID.fromString(id);
|
||||
return new Target(uuid, EntityClassifier.OTHER);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the player source ID to the given data holder.
|
||||
* @param dataHolder The persistent data holder to assign the player source ID to.
|
||||
* @param id The UUID of the player source ID to assign.
|
||||
*/
|
||||
public static void assignPlayerSourceId(@NotNull PersistentDataHolder dataHolder, @NotNull UUID id) {
|
||||
dataHolder.getPersistentDataContainer().set(playerSourceIdKey, PersistentDataType.STRING, id.toString());
|
||||
}
|
||||
|
||||
public enum EntityClassifier {
|
||||
PLAYER,
|
||||
PET,
|
||||
MOUNT,
|
||||
OTHER
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package me.youhavetrouble.preventstabby.hooks;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlaceholderApiHook extends PlaceholderExpansion {
|
||||
|
||||
private final PreventStabby plugin;
|
||||
private final LegacyComponentSerializer legacyComponentSerializer;
|
||||
|
||||
public PlaceholderApiHook(PreventStabby preventStabby) {
|
||||
plugin = preventStabby;
|
||||
this.legacyComponentSerializer = LegacyComponentSerializer.legacyAmpersand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getIdentifier() {
|
||||
return "preventstabby";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getAuthor() {
|
||||
return plugin.getDescription().getAuthors().get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getVersion() {
|
||||
return plugin.getDescription().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer player, String params) {
|
||||
return switch (params) {
|
||||
case "pvp" -> {
|
||||
if (!player.isOnline()) yield String.valueOf(false);
|
||||
yield String.valueOf(plugin.getPlayerManager().getPlayer(player.getUniqueId()).isPvpEnabled());
|
||||
}
|
||||
case "combat_time" -> getCombatTimePlaceholder(player.getUniqueId(), player);
|
||||
case "in_combat" -> {
|
||||
if (!player.isOnline()) yield String.valueOf(false);
|
||||
yield String.valueOf(plugin.getPlayerManager().getPlayer(player.getUniqueId()).isInCombat());
|
||||
}
|
||||
case "pvp_forced" -> switch (PreventStabby.getPlugin().getPlayerManager().getForcedPvpState()) {
|
||||
case NONE ->
|
||||
legacyComponentSerializer.serialize(PluginMessages.parseMessage(plugin.getConfigCache().placeholder_pvp_forced_none));
|
||||
case ENABLED ->
|
||||
legacyComponentSerializer.serialize(PluginMessages.parseMessage(plugin.getConfigCache().placeholder_pvp_forced_true));
|
||||
case DISABLED ->
|
||||
legacyComponentSerializer.serialize(PluginMessages.parseMessage(plugin.getConfigCache().placeholder_pvp_forced_false));
|
||||
};
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private String getCombatTimePlaceholder(UUID uuid, OfflinePlayer player) {
|
||||
if (!player.isOnline()) {
|
||||
return legacyComponentSerializer.serialize(PluginMessages.parseMessage(plugin.getConfigCache().placeholder_not_in_combat));
|
||||
}
|
||||
long seconds = plugin.getPlayerManager().getPlayer(uuid).getSecondsLeftUntilCombatEnd();
|
||||
if (seconds > 0) {
|
||||
String msg = plugin.getConfigCache().placeholder_combat_time;
|
||||
msg = msg.replaceAll("%time%", String.valueOf(seconds));
|
||||
return legacyComponentSerializer.serialize(PluginMessages.parseMessage(msg));
|
||||
}
|
||||
return legacyComponentSerializer.serialize(PluginMessages.parseMessage(plugin.getConfigCache().placeholder_not_in_combat));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package me.youhavetrouble.preventstabby.hooks;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagConflictException;
|
||||
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class WorldGuardHook {
|
||||
|
||||
private static FlagRegistry flagRegistry;
|
||||
public static StateFlag FORCE_PVP_FLAG;
|
||||
|
||||
public static void init(Logger logger) {
|
||||
try {
|
||||
Class.forName("com.sk89q.worldguard.protection.flags.registry.FlagRegistry");
|
||||
WorldGuardPlugin worldGuardPlugin = WorldGuardPlugin.inst();
|
||||
if (WorldGuard.getInstance() == null || worldGuardPlugin == null) return;
|
||||
logger.info("Hooking into WorldGuard");
|
||||
flagRegistry = WorldGuard.getInstance().getFlagRegistry();
|
||||
createForcePvpFlag();
|
||||
} catch (NoClassDefFoundError | ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static void createForcePvpFlag() {
|
||||
if (flagRegistry == null) return;
|
||||
String flagName = "preventstabby-force-pvp";
|
||||
try {
|
||||
StateFlag flag = new StateFlag(flagName, false);
|
||||
flagRegistry.register(flag);
|
||||
FORCE_PVP_FLAG = flag;
|
||||
} catch (FlagConflictException e) {
|
||||
Flag<?> existing = flagRegistry.get(flagName);
|
||||
if (existing instanceof StateFlag) {
|
||||
FORCE_PVP_FLAG = (StateFlag) existing;
|
||||
} else {
|
||||
PreventStabby.getPlugin().getLogger().severe("[PreventStabby] There is a conflict between flag names!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPlayerForcedToPvp(Player player) {
|
||||
if (player == null) return false;
|
||||
if (!PreventStabby.worldGuardHookEnabled()) return false;
|
||||
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||
RegionQuery query = container.createQuery();
|
||||
org.bukkit.Location loc = player.getLocation();
|
||||
if (loc.getWorld() == null) return false;
|
||||
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
||||
ApplicableRegionSet set = query.getApplicableRegions(new Location(BukkitAdapter.adapt(loc.getWorld()), loc.getX(), loc.getY(), loc.getZ()));
|
||||
return set.testState(localPlayer, FORCE_PVP_FLAG);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package me.youhavetrouble.preventstabby.listeners;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.config.ConfigCache;
|
||||
import me.youhavetrouble.preventstabby.data.DamageCheckResult;
|
||||
import me.youhavetrouble.preventstabby.data.Target;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
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.BlockIgniteEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class EnvironmentalListener implements Listener {
|
||||
|
||||
private final PreventStabby plugin;
|
||||
private final Set<Material> dangerousBuckets = new HashSet<>();
|
||||
|
||||
public EnvironmentalListener(PreventStabby plugin) {
|
||||
this.plugin = plugin;
|
||||
dangerousBuckets.add(Material.LAVA_BUCKET);
|
||||
dangerousBuckets.add(Material.PUFFERFISH_BUCKET);
|
||||
dangerousBuckets.add(Material.POWDER_SNOW_BUCKET);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onDangerousBucketDump(PlayerBucketEmptyEvent event) {
|
||||
ConfigCache config = plugin.getConfigCache();
|
||||
if (!config.bucket_stopper_enabled) return;
|
||||
if (!dangerousBuckets.contains(event.getBucket())) return;
|
||||
Location location = event.getBlockClicked().getLocation();
|
||||
Player placer = event.getPlayer();
|
||||
double radius = config.bucket_stopper_radius;
|
||||
|
||||
BoundingBox boundingBox = BoundingBox.of(location.toVector(), radius, radius, radius);
|
||||
for (Entity victim : location.getWorld().getNearbyEntities(boundingBox)) {
|
||||
if (victim.getUniqueId() == placer.getUniqueId()) continue;
|
||||
Target victimTarget = Target.getTarget(victim);
|
||||
if (victimTarget == null) continue;
|
||||
DamageCheckResult result = plugin.getPlayerManager().canDamage(placer.getUniqueId(), victim.getUniqueId(), victimTarget.classifier);
|
||||
if (!result.ableToDamage()) {
|
||||
event.setCancelled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onBlockIgnite(BlockIgniteEvent event) {
|
||||
ConfigCache config = plugin.getConfigCache();
|
||||
if (!config.fire_stopper_enabled) return;
|
||||
Entity igniter = event.getIgnitingEntity();
|
||||
if (igniter == null) return;
|
||||
Target igniterTarget = Target.getTarget(igniter);
|
||||
if (igniterTarget == null) return;
|
||||
Location location = event.getBlock().getLocation();
|
||||
double radius = config.fire_stopper_radius;
|
||||
|
||||
BoundingBox boundingBox = BoundingBox.of(location.toVector(), radius, radius, radius);
|
||||
for (Entity victim : location.getWorld().getNearbyEntities(boundingBox)) {
|
||||
if (victim.getUniqueId() == igniterTarget.playerUuid) continue;
|
||||
Target victimTarget = Target.getTarget(victim);
|
||||
if (victimTarget == null) continue;
|
||||
DamageCheckResult result = plugin.getPlayerManager().canDamage(igniterTarget.playerUuid, victim.getUniqueId(), victimTarget.classifier);
|
||||
if (!result.ableToDamage()) {
|
||||
event.setCancelled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onDangerousBlockPlace(BlockPlaceEvent event) {
|
||||
ConfigCache config = plugin.getConfigCache();
|
||||
if (!config.block_stopper_enabled) return;
|
||||
Player player = event.getPlayer();
|
||||
Location location = event.getBlock().getLocation().toCenterLocation();
|
||||
Target target = Target.getTarget(player);
|
||||
if (target == null) return;
|
||||
if (!config.getDangerousBlocks().contains(event.getBlock().getType())) return;
|
||||
double radius = config.block_stopper_radius;
|
||||
|
||||
BoundingBox boundingBox = BoundingBox.of(location.toVector(), radius, radius, radius);
|
||||
for (Entity victim : location.getWorld().getNearbyEntities(boundingBox)) {
|
||||
if (victim.getUniqueId() == target.playerUuid) continue;
|
||||
Target victimTarget = Target.getTarget(victim);
|
||||
if (victimTarget == null) continue;
|
||||
DamageCheckResult result = plugin.getPlayerManager().canDamage(target.playerUuid, victim.getUniqueId(), victimTarget.classifier);
|
||||
if (!result.ableToDamage()) {
|
||||
event.setCancelled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package me.youhavetrouble.preventstabby.listeners;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.data.DamageCheckResult;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.PotionSplashEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerFishEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class PvpListener implements Listener {
|
||||
|
||||
private final PreventStabby plugin;
|
||||
|
||||
public PvpListener(PreventStabby plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onEntityDamage(EntityDamageByEntityEvent event) {
|
||||
Entity attacker = event.getDamager();
|
||||
Entity victim = event.getEntity();
|
||||
|
||||
DamageCheckResult result = plugin.getPlayerManager().canDamage(attacker, victim);
|
||||
if (!result.ableToDamage()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
plugin.getPlayerManager().handleDamageCheck(result);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPotionSplash(PotionSplashEvent event) {
|
||||
if (!(event.getEntity().getShooter() instanceof Player thrower)) return;
|
||||
boolean harmful = false;
|
||||
for (PotionEffect effect : event.getPotion().getEffects()) {
|
||||
if (!PotionEffectType.Category.HARMFUL.equals(effect.getType().getEffectCategory())) continue;
|
||||
harmful = true;
|
||||
break;
|
||||
}
|
||||
if (!harmful) return;
|
||||
for (LivingEntity victim : event.getAffectedEntities()) {
|
||||
if (thrower == victim) continue;
|
||||
DamageCheckResult result = plugin.getPlayerManager().canDamage(thrower, victim);
|
||||
if (!result.ableToDamage()) {
|
||||
event.setIntensity(victim, 0);
|
||||
}
|
||||
plugin.getPlayerManager().handleDamageCheck(result);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPotionCloudEffectApply(AreaEffectCloudApplyEvent event) {
|
||||
if (!(event.getEntity().getSource() instanceof Player thrower)) return;
|
||||
boolean harmful = false;
|
||||
AreaEffectCloud cloud = event.getEntity();
|
||||
if (cloud.getBasePotionType() == null) return;
|
||||
PotionType potionType = cloud.getBasePotionType();
|
||||
for (PotionEffect effect : potionType.getPotionEffects()) {
|
||||
if (!PotionEffectType.Category.HARMFUL.equals(effect.getType().getEffectCategory())) continue;
|
||||
harmful = true;
|
||||
break;
|
||||
}
|
||||
if (!harmful) return;
|
||||
event.getAffectedEntities().removeIf(victim -> {
|
||||
if (thrower == victim) return false;
|
||||
boolean shouldRemoveFromAffected = false;
|
||||
DamageCheckResult result = plugin.getPlayerManager().canDamage(thrower, victim);
|
||||
if (!result.ableToDamage()) {
|
||||
shouldRemoveFromAffected = true;
|
||||
}
|
||||
plugin.getPlayerManager().handleDamageCheck(result);
|
||||
return shouldRemoveFromAffected;
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onFish(PlayerFishEvent event) {
|
||||
if (event.getCaught() instanceof Item) return;
|
||||
if (plugin.getConfigCache().allow_fishing_rod_pull) return;
|
||||
Player attacker = event.getPlayer();
|
||||
Entity victim = event.getCaught();
|
||||
if (victim == null) return;
|
||||
if (attacker == victim) return;
|
||||
DamageCheckResult result = plugin.getPlayerManager().canDamage(attacker, victim);
|
||||
if (!result.ableToDamage()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
plugin.getPlayerManager().handleDamageCheck(result);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onCommandInCombat(PlayerCommandPreprocessEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (!plugin.getPlayerManager().getPlayer(player.getUniqueId()).isInCombat()) return;
|
||||
String message = event.getMessage().toLowerCase(Locale.ROOT);
|
||||
if (message.startsWith("/")) {
|
||||
message = message.substring(1);
|
||||
}
|
||||
message = message.split(" ")[0];
|
||||
if (!plugin.getConfigCache().getCombatBlockedCommands().contains(message)) return;
|
||||
|
||||
event.setCancelled(true);
|
||||
player.sendMessage(plugin.getConfigCache().cant_do_that_during_combat);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package me.youhavetrouble.preventstabby.listeners;
|
||||
|
||||
import me.youhavetrouble.preventstabby.data.Target;
|
||||
import org.bukkit.entity.EnderCrystal;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.minecart.ExplosiveMinecart;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityPlaceEvent;
|
||||
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||
import org.bukkit.event.vehicle.VehicleEntityCollisionEvent;
|
||||
|
||||
/**
|
||||
* This class is a listener that performs various operations related to tagging entities with player UUIDs.
|
||||
*/
|
||||
public class UtilListener implements Listener {
|
||||
|
||||
/**
|
||||
* Tag TNT minecart with uuid of player who placed it
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerPlacedTntMinecart(EntityPlaceEvent event) {
|
||||
if (!(event.getEntity() instanceof ExplosiveMinecart minecart)) return;
|
||||
if (event.getPlayer() == null) return;
|
||||
Target.assignPlayerSourceId(minecart, event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag TNT minecart with uuid of player who last nudged it
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerNudgedTntMinecart(VehicleEntityCollisionEvent event) {
|
||||
if (!(event.getVehicle() instanceof ExplosiveMinecart minecart)) return;
|
||||
if (!(event.getEntity() instanceof Player player)) return;
|
||||
Target.assignPlayerSourceId(minecart, player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag primed TNT with players uuid
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerPrimedTnt(ExplosionPrimeEvent event) {
|
||||
if (!(event.getEntity() instanceof TNTPrimed tntPrimed)) return;
|
||||
if (tntPrimed.getSource() instanceof TNTPrimed primingTnt) {
|
||||
Target primingTntTarget = Target.getTarget(primingTnt);
|
||||
if (primingTntTarget == null) return;
|
||||
Target.assignPlayerSourceId(tntPrimed, primingTntTarget.playerUuid);
|
||||
return;
|
||||
}
|
||||
if (tntPrimed.getSource() instanceof Player primingPlayer) {
|
||||
Target.assignPlayerSourceId(tntPrimed, primingPlayer.getUniqueId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags ender crystal with exploding players uuid
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerHitEnderCrystal(EntityDamageByEntityEvent event) {
|
||||
if (!(event.getEntity() instanceof EnderCrystal enderCrystal)) return;
|
||||
if (event.getDamager() instanceof Player player) {
|
||||
Target.assignPlayerSourceId(enderCrystal, player.getUniqueId());
|
||||
return;
|
||||
}
|
||||
if (event.getDamager() instanceof Projectile projectile && projectile.getShooter() instanceof Player player) {
|
||||
Target.assignPlayerSourceId(enderCrystal, player.getUniqueId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package me.youhavetrouble.preventstabby.util;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.data.PlayerData;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class DatabaseSQLite {
|
||||
|
||||
private final String url;
|
||||
private final File folder;
|
||||
private final Logger logger;
|
||||
|
||||
public DatabaseSQLite(String url, File folder, Logger logger) {
|
||||
this.url = url;
|
||||
this.folder = folder;
|
||||
this.logger = logger;
|
||||
createDatabaseFile();
|
||||
}
|
||||
|
||||
private void createDatabaseFile() {
|
||||
this.folder.mkdir();
|
||||
try (Connection conn = DriverManager.getConnection(url)) {
|
||||
if (conn == null) return;
|
||||
DatabaseMetaData meta = conn.getMetaData();
|
||||
logger.info("The driver name is " + meta.getDriverName());
|
||||
Statement statement = conn.createStatement();
|
||||
String sql = "CREATE TABLE IF NOT EXISTS `players` (`player_uuid` varchar(36) UNIQUE PRIMARY KEY, `pvpenabled` boolean);";
|
||||
statement.execute(sql);
|
||||
} catch (SQLException exception) {
|
||||
logger.warning(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerData getPlayerInfo(UUID uuid) {
|
||||
try (Connection conn = DriverManager.getConnection(url)) {
|
||||
PreparedStatement statement = conn.prepareStatement(
|
||||
"INSERT OR IGNORE INTO `players` (player_uuid, pvpenabled) VALUES (?, ?);"
|
||||
);
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setBoolean(2, PreventStabby.getPlugin().getConfigCache().pvp_enabled_by_default);
|
||||
statement.executeUpdate();
|
||||
statement = conn.prepareStatement("SELECT * FROM `players` WHERE `player_uuid` = ?;");
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.executeQuery();
|
||||
ResultSet result = statement.executeQuery();
|
||||
boolean state = result.getBoolean("pvpenabled");
|
||||
return new PlayerData(uuid, state);
|
||||
} catch (SQLException exception) {
|
||||
logger.warning(exception.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updatePlayerInfo(UUID uuid, PlayerData data) {
|
||||
try (Connection conn = DriverManager.getConnection(url)) {
|
||||
try {
|
||||
PreparedStatement statement = conn.prepareStatement("UPDATE `players` SET pvpenabled = ? WHERE `player_uuid` = ?;");
|
||||
statement.setBoolean(1, data.isPvpEnabled());
|
||||
statement.setString(2, uuid.toString());
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException exception) {
|
||||
logger.severe("Error while saving player data!");
|
||||
logger.warning(exception.getMessage());
|
||||
}
|
||||
} catch (SQLException exception) {
|
||||
logger.warning(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package me.youhavetrouble.preventstabby.util;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.data.DamageCheckResult;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PluginMessages {
|
||||
|
||||
public static final MiniMessage MINIMESSAGE = MiniMessage.miniMessage();
|
||||
|
||||
public static Component parseMessage(String message) {
|
||||
message = makeColorsWork('&', message);
|
||||
message = makeColorsWork(LegacyComponentSerializer.SECTION_CHAR, message);
|
||||
return MINIMESSAGE.deserialize(message);
|
||||
}
|
||||
|
||||
public static Component parseMessage(CommandSender sender,String message) {
|
||||
if (sender instanceof Player player && isPlaceholderApiEnabled()) {
|
||||
message = PlaceholderAPI.setPlaceholders(player, message);
|
||||
}
|
||||
return parseMessage(message);
|
||||
}
|
||||
|
||||
private static boolean isPlaceholderApiEnabled() {
|
||||
return PreventStabby.getPlugin().getServer().getPluginManager().getPlugin("PlaceholderAPI") != null;
|
||||
}
|
||||
|
||||
public static void sendMessage(@NotNull CommandSender sender, String message) {
|
||||
if ("".equals(message)) return;
|
||||
sender.sendMessage(parseMessage(sender, message));
|
||||
}
|
||||
|
||||
public static void sendActionBar(@NotNull Player player, String message) {
|
||||
if ("".equals(message)) return;
|
||||
Component parsedMessage = parseMessage(player, message);
|
||||
player.sendActionBar(parsedMessage);
|
||||
}
|
||||
|
||||
public static void sendActionBar(UUID uuid, String message) {
|
||||
if ("".equals(message)) return;
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player == null) return;
|
||||
sendActionBar(player, message);
|
||||
}
|
||||
|
||||
public static String parsePlayerName(Player player, String message) {
|
||||
message = message.replaceAll("%player%", player.getDisplayName());
|
||||
return message;
|
||||
}
|
||||
|
||||
public static void broadcastMessage(Player player, String message) {
|
||||
if ("".equals(message)) return;
|
||||
message = parsePlayerName(player, message);
|
||||
if (PreventStabby.getPlugin().getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||
message = PlaceholderAPI.setPlaceholders(player, message);
|
||||
}
|
||||
Bukkit.broadcast(parseMessage(message));
|
||||
}
|
||||
|
||||
public static void broadcastMessage(String message) {
|
||||
if ("".equals(message)) return;
|
||||
Bukkit.broadcast(parseMessage(message));
|
||||
}
|
||||
|
||||
public static void sendOutMessages(DamageCheckResult damageCheckResult) {
|
||||
if (damageCheckResult.attackerId() != null && damageCheckResult.feedbackForAttacker() != null) {
|
||||
sendActionBar(damageCheckResult.attackerId(), damageCheckResult.feedbackForAttacker());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps most legacy color codes to adventure minimessage tags.
|
||||
* @param symbol Usually '&'.
|
||||
* @param string String to replace symbols in.
|
||||
* @return String with legacy color codes replaced with minimessage tags.
|
||||
*/
|
||||
private static String makeColorsWork(Character symbol, String string) {
|
||||
// Adventure and ChatColor do not like each other, so this is a thing.
|
||||
string = string.replaceAll(symbol + "0", "<black>");
|
||||
string = string.replaceAll(symbol + "1", "<dark_blue>");
|
||||
string = string.replaceAll(symbol + "2", "<dark_green>");
|
||||
string = string.replaceAll(symbol + "3", "<dark_aqua>");
|
||||
string = string.replaceAll(symbol + "4", "<dark_red>");
|
||||
string = string.replaceAll(symbol + "5", "<dark_purple>");
|
||||
string = string.replaceAll(symbol + "6", "<gold>");
|
||||
string = string.replaceAll(symbol + "7", "<gray>");
|
||||
string = string.replaceAll(symbol + "8", "<dark_gray>");
|
||||
string = string.replaceAll(symbol + "9", "<blue>");
|
||||
string = string.replaceAll(symbol + "a", "<green>");
|
||||
string = string.replaceAll(symbol + "b", "<aqua>");
|
||||
string = string.replaceAll(symbol + "c", "<red>");
|
||||
string = string.replaceAll(symbol + "d", "<light_purple>");
|
||||
string = string.replaceAll(symbol + "e", "<yellow>");
|
||||
string = string.replaceAll(symbol + "f", "<white>");
|
||||
string = string.replaceAll(symbol + "k", "<obfuscated>");
|
||||
string = string.replaceAll(symbol + "l", "<bold>");
|
||||
string = string.replaceAll(symbol + "m", "<strikethrough>");
|
||||
string = string.replaceAll(symbol + "n", "<underlined>");
|
||||
string = string.replaceAll(symbol + "o", "<italic>");
|
||||
string = string.replaceAll(symbol + "r", "<reset>");
|
||||
return string;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package me.youhavetrouble.preventstabby.util;
|
||||
|
||||
public enum PvpState {
|
||||
/**
|
||||
* PvP Force enabled
|
||||
*/
|
||||
ENABLED,
|
||||
/**
|
||||
* PvP force disabled
|
||||
*/
|
||||
DISABLED,
|
||||
/**
|
||||
* PvP not forced
|
||||
*/
|
||||
NONE
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
settings:
|
||||
# Decides if pvp should be enabled or disabled by default
|
||||
pvp_enabled_by_default: false
|
||||
|
||||
# Prevents dumping lava and pufferfish bucket, placing wither roses and lighting blocks on fire near players with pvp off
|
||||
lava_and_fire_stopper:
|
||||
enabled: true
|
||||
radius: 2.5
|
||||
|
||||
# Disables channeling (trident enchant) lightning strike
|
||||
# You may want to keep it disabled because players with pvp off can use it to attack players with pvp on
|
||||
channeling_enchant_disabled: false
|
||||
|
||||
# Makes it so only pet owner can interact with it.
|
||||
# Useful if you don't want people renaming other people's pets.
|
||||
only_owner_can_interact_with_pet: false
|
||||
|
||||
# Time (in seconds) to keep player in combat
|
||||
combat_time: 25
|
||||
|
||||
# Kill the player if they log out during combat
|
||||
punish_for_combat_logout:
|
||||
enabled: true
|
||||
announce: true
|
||||
message: "&f%player% logged out while in combat. What a loser."
|
||||
|
||||
# Time (in seconds) to keep player data in memory when players goes offline.
|
||||
# This is used for checking if offline players pvp state.
|
||||
# Adjust only if you know what you're doing. NEVER set to less than 6.
|
||||
cache_time: 30
|
||||
|
||||
messages:
|
||||
pvp_enabled: "&cYou enabled PvP!"
|
||||
pvp_disabled: "&cYou disabled PvP!"
|
||||
cannot_attack_victim: "&cYou can't attack players that have PvP turned off!"
|
||||
cannot_attack_attacker: "&cYou can't attack players while you have PvP turned off!"
|
||||
cannot_attack_pets_victim: "&cYou can't attack pets of players that have PvP turned off"
|
||||
cannot_attack_pets_attacker: "&cYou can't attack pets while you have PvP turned off"
|
||||
no_permission: "&cYou don't have permission to use that."
|
||||
no_such_command: "&cNo such command."
|
||||
pvp_enabled_others: "&cYou've enabled %player%'s PvP."
|
||||
pvp_disabled_others: "&cYou've disabled %player%'s PvP."
|
||||
entering_combat: "&cEntering combat"
|
||||
leaving_combat: "&cLeaving combat"
|
||||
cant_do_that_during_combat: "&cYou can't do that while in combat!"
|
||||
@@ -1,22 +1,50 @@
|
||||
name: TogglePvP
|
||||
name: PreventStabby
|
||||
version: ${project.version}
|
||||
main: eu.endermite.togglepvp.TogglePvp
|
||||
main: me.youhavetrouble.preventstabby.PreventStabby
|
||||
authors: [YouHaveTrouble]
|
||||
api-version: 1.13
|
||||
description: PvP toggle plugin
|
||||
api-version: 1.21
|
||||
folia-supported: true
|
||||
description: Stop people from getting stabbed!
|
||||
soft-depend:
|
||||
- WorldGuard
|
||||
- PlaceholderAPI
|
||||
commands:
|
||||
pvp:
|
||||
usage: /pvp [args]
|
||||
preventstabby:
|
||||
permission: preventstabby.command
|
||||
aliases:
|
||||
- pvp
|
||||
permissions:
|
||||
togglepvp.command:
|
||||
preventstabby.combatcommandblock.bypass:
|
||||
default: op
|
||||
description: Allows to bypass combat command blocker
|
||||
preventstabby.combatteleportblock.bypass:
|
||||
default: op
|
||||
description: Allows to bypass combat teleport blocker
|
||||
preventstabby.command:
|
||||
default: true
|
||||
description: Allows usage of /pvp command
|
||||
togglepvp.command.toggle:
|
||||
preventstabby.command.help:
|
||||
default: true
|
||||
description: Allows usage of /pvp help command
|
||||
children:
|
||||
preventstabby.command: true
|
||||
preventstabby.command.toggle:
|
||||
default: true
|
||||
description: Allows usage of /pvp <toggle/enable/disable> command
|
||||
togglepvp.command.toggle.others:
|
||||
children:
|
||||
preventstabby.command: true
|
||||
preventstabby.command.toggle.others:
|
||||
default: op
|
||||
description: Allows usage of /pvp <toggle/enable/disable> <player> command
|
||||
togglepvp.command.reload:
|
||||
children:
|
||||
preventstabby.command: true
|
||||
preventstabby.command.toggle.global:
|
||||
default: op
|
||||
description: Allows usage of /pvp reload command
|
||||
description: Allows usage of /pvp override <enabled/disabled/none> command
|
||||
children:
|
||||
preventstabby.command: true
|
||||
preventstabby.command.reload:
|
||||
default: op
|
||||
description: Allows usage of /pvp reload command
|
||||
children:
|
||||
preventstabby.command: true
|
||||
Reference in New Issue
Block a user