Refactor everything to a modular format - WIP

This does not compile

Almost done with core !!!
This commit is contained in:
Aikar
2017-05-20 01:45:56 -04:00
parent 798a1d57c9
commit c2a58a471f
46 changed files with 3651 additions and 657 deletions
+5
View File
@@ -8,15 +8,20 @@
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" /> <outputRelativeToContentRoot value="true" />
<module name="acf" /> <module name="acf" />
<module name="acf-bukkit" />
<module name="acf-core" /> <module name="acf-core" />
<module name="acf-example" /> <module name="acf-example" />
<module name="acf-paper" />
<module name="commands" /> <module name="commands" />
</profile> </profile>
</annotationProcessing> </annotationProcessing>
<bytecodeTargetLevel> <bytecodeTargetLevel>
<module name="acf" target="1.8" /> <module name="acf" target="1.8" />
<module name="acf-bukkit" target="1.8" />
<module name="acf-core" target="1.8" /> <module name="acf-core" target="1.8" />
<module name="acf-example" target="1.8" /> <module name="acf-example" target="1.8" />
<module name="acf-paper" target="1.8" />
<module name="acf-parent" target="1.8" />
<module name="commands" target="1.8" /> <module name="commands" target="1.8" />
</bytecodeTargetLevel> </bytecodeTargetLevel>
</component> </component>
+5 -1
View File
@@ -1,3 +1,7 @@
<component name="CopyrightManager"> <component name="CopyrightManager">
<settings default="MIT" /> <settings>
<module2copyright>
<element module="All But Apache Commons" copyright="MIT" />
</module2copyright>
</settings>
</component> </component>
+2
View File
@@ -2,8 +2,10 @@
<project version="4"> <project version="4">
<component name="Encoding"> <component name="Encoding">
<file url="file://$PROJECT_DIR$" charset="UTF-8" /> <file url="file://$PROJECT_DIR$" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/bukkit" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/core" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/core" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/example" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/example" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/paper" charset="UTF-8" />
<file url="PROJECT" charset="UTF-8" /> <file url="PROJECT" charset="UTF-8" />
</component> </component>
</project> </project>
+3
View File
@@ -2,8 +2,11 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/bukkit/acf-bukkit.iml" filepath="$PROJECT_DIR$/bukkit/acf-bukkit.iml" />
<module fileurl="file://$PROJECT_DIR$/core/acf-core.iml" filepath="$PROJECT_DIR$/core/acf-core.iml" /> <module fileurl="file://$PROJECT_DIR$/core/acf-core.iml" filepath="$PROJECT_DIR$/core/acf-core.iml" />
<module fileurl="file://$PROJECT_DIR$/example/acf-example.iml" filepath="$PROJECT_DIR$/example/acf-example.iml" /> <module fileurl="file://$PROJECT_DIR$/example/acf-example.iml" filepath="$PROJECT_DIR$/example/acf-example.iml" />
<module fileurl="file://$PROJECT_DIR$/paper/acf-paper.iml" filepath="$PROJECT_DIR$/paper/acf-paper.iml" />
<module fileurl="file://$PROJECT_DIR$/acf-parent.iml" filepath="$PROJECT_DIR$/acf-parent.iml" />
</modules> </modules>
</component> </component>
</project> </project>
+3
View File
@@ -0,0 +1,3 @@
<component name="DependencyValidationManager">
<scope name="All But Apache Commons" pattern="(file[acf-bukkit]:*/||file[acf-parent]:*/||file[acf-core]:*/||file[acf-example]:*/||file[acf-paper]:*/)&amp;&amp;!file[acf-core]:src/main/java/co/aikar/commands/apachecommonslang//*" />
</component>
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
</component>
</module>
+33
View File
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>BUKKIT</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="acf-core" />
<orderEntry type="library" name="Maven: co.aikar:minecraft-timings:1.0.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.bukkit:bukkit:1.12-pre2-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:21.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.18" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
</component>
</module>
+55
View File
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
~
~ Permission is hereby granted, free of charge, to any person obtaining
~ a copy of this software and associated documentation files (the
~ "Software"), to deal in the Software without restriction, including
~ without limitation the rights to use, copy, modify, merge, publish,
~ distribute, sublicense, and/or sell copies of the Software, and to
~ permit persons to whom the Software is furnished to do so, subject to
~ the following conditions:
~
~ The above copyright notice and this permission notice shall be
~ included in all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
~ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
~ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
~ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
~ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
~ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
~ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<parent>
<groupId>co.aikar</groupId>
<artifactId>acf-parent</artifactId>
<version><!--VERSION-->0.5.0<!--VERSION--></version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>acf-bukkit</artifactId>
<version><!--VERSION-->0.5.0<!--VERSION--></version>
<name>ACF (Bukkit)</name>
<dependencies>
<dependency>
<groupId>co.aikar</groupId>
<artifactId>acf-core</artifactId>
<version><!--VERSION-->0.5.0<!--VERSION--></version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.12-pre2-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,302 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import com.google.common.collect.Iterables;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
public class ACFBukkitUtil {
public static String formatLocation(Location loc) {
if (loc == null) {
return null;
}
return loc.getWorld().getName() +
":" +
loc.getBlockX() +
"," +
loc.getBlockY() +
"," +
loc.getBlockZ();
}
public static String color(String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
public static void sendMsg(CommandIssuer player, String message) {
message = color(message);
if (player == null) {
for (String msg : ACFPatterns.NEWLINE.split(message)) {
ACFLog.info(msg);
}
} else {
for (String msg : ACFPatterns.NEWLINE.split(message)) {
player.sendMessage(msg);
}
}
}
public static Location stringToLocation(String storedLoc) {
return stringToLocation(storedLoc, null);
}
public static Location stringToLocation(String storedLoc, World forcedWorld) {
if (storedLoc == null) {
return null;
}
String[] args = ACFPatterns.COLON.split(storedLoc);
if (args.length >= 4 || (args.length == 3 && forcedWorld != null)) {
String world = forcedWorld != null ? forcedWorld.getName() : args[0];
int i = args.length == 3 ? 0 : 1;
double x = Double.parseDouble(args[i]);
double y = Double.parseDouble(args[i + 1]);
double z = Double.parseDouble(args[i + 2]);
Location loc = new Location(Bukkit.getWorld(world), x, y, z);
if (args.length >= 6) {
loc.setPitch(Float.parseFloat(args[4]));
loc.setYaw(Float.parseFloat(args[5]));
}
return loc;
} else if (args.length == 2) {
String[] args2 = ACFPatterns.COMMA.split(args[1]);
if (args2.length == 3) {
String world = forcedWorld != null ? forcedWorld.getName() : args[0];
double x = Double.parseDouble(args2[0]);
double y = Double.parseDouble(args2[1]);
double z = Double.parseDouble(args2[2]);
return new Location(Bukkit.getWorld(world), x, y, z);
}
}
return null;
}
public static String fullLocationToString(Location loc) {
if (loc == null) {
return null;
}
return (new StringBuilder(64))
.append(loc.getWorld().getName())
.append(':')
.append(ACFUtil.precision(loc.getX(), 4))
.append(':')
.append(ACFUtil.precision(loc.getY(), 4))
.append(':')
.append(ACFUtil.precision(loc.getZ(), 4))
.append(':')
.append(ACFUtil.precision(loc.getPitch(), 4))
.append(':')
.append(ACFUtil.precision(loc.getYaw(), 4))
.toString();
}
public static String fullBlockLocationToString(Location loc) {
if (loc == null) {
return null;
}
return (new StringBuilder(64))
.append(loc.getWorld().getName())
.append(':')
.append(loc.getBlockX())
.append(':')
.append(loc.getBlockY())
.append(':')
.append(loc.getBlockZ())
.append(':')
.append(ACFUtil.precision(loc.getPitch(), 4))
.append(':')
.append(ACFUtil.precision(loc.getYaw(), 4))
.toString();
}
public static String blockLocationToString(Location loc) {
if (loc == null) {
return null;
}
return (new StringBuilder(32))
.append(loc.getWorld().getName())
.append(':')
.append(loc.getBlockX())
.append(':')
.append(loc.getBlockY())
.append(':')
.append(loc.getBlockZ())
.toString();
}
public static double distance(@NotNull Entity e1, @NotNull Entity e2) {
return distance(e1.getLocation(), e2.getLocation());
}
public static double distance2d(@NotNull Entity e1, @NotNull Entity e2) {
return distance2d(e1.getLocation(), e2.getLocation());
}
public static double distance2d(@NotNull Location loc1, @NotNull Location loc2) {
loc1 = loc1.clone();
loc1.setY(loc2.getY());
return distance(loc1, loc2);
}
public static double distance(@NotNull Location loc1, @NotNull Location loc2) {
if (loc1.getWorld() != loc2.getWorld()) {
return 0;
}
return loc1.distance(loc2);
}
public static Location getTargetLoc(Player player) {
return getTargetLoc(player, 128);
}
public static Location getTargetLoc(Player player, int maxDist) {
return getTargetLoc(player, maxDist, 1.5);
}
public static Location getTargetLoc(Player player, int maxDist, double addY) {
try {
Location target = player.getTargetBlock((Set<Material>) null, maxDist).getLocation();
target.setY(target.getY() + addY);
return target;
} catch (Exception ignored) {
return null;
}
}
public static Location getRandLoc(Location loc, int radius) {
return getRandLoc(loc, radius, radius, radius);
}
public static Location getRandLoc(Location loc, int xzRadius, int yRadius) {
return getRandLoc(loc, xzRadius, yRadius, xzRadius);
}
@NotNull public static Location getRandLoc(Location loc, int xRadius, int yRadius, int zRadius) {
Location newLoc = loc.clone();
newLoc.setX(ACFUtil.rand(loc.getX()-xRadius, loc.getX()+xRadius));
newLoc.setY(ACFUtil.rand(loc.getY()-yRadius, loc.getY()+yRadius));
newLoc.setZ(ACFUtil.rand(loc.getZ()-zRadius, loc.getZ()+zRadius));
return newLoc;
}
public static String removeColors(String msg) {
return ChatColor.stripColor(color(msg));
}
public static String replaceChatString(String message, String replace, String with) {
return replaceChatString(message, Pattern.compile(Pattern.quote(replace), Pattern.CASE_INSENSITIVE), with);
}
public static String replaceChatString(String message, Pattern replace, String with) {
final String[] split = replace.split(message + "1");
if (split.length < 2) {
return replace.matcher(message).replaceAll(with);
}
message = split[0];
for (int i = 1; i < split.length; i++) {
final String prev = ChatColor.getLastColors(message);
message += with + prev + split[i];
}
return message.substring(0, message.length() - 1);
}
public static boolean isWithinDistance(@NotNull Player p1, @NotNull Player p2, int dist) {
return isWithinDistance(p1.getLocation(), p2.getLocation(), dist);
}
public static boolean isWithinDistance(@NotNull Location loc1, @NotNull Location loc2, int dist) {
return loc1.getWorld() == loc2.getWorld() && loc1.distance(loc2) <= dist;
}
public static Player findPlayerSmart(CommandIssuer requester, String origName) {
String name = ACFUtil.replace(origName, ":confirm", "");
if (name.length() < 3) {
requester.sendMessage("§cUsername too short, must be at least three characters");
return null;
}
if (!isValidName(name)) {
requester.sendMessage("§c'" + name + "' is not a valid username");
return null;
}
List<Player> matches = Bukkit.getServer().matchPlayer(name);
List<Player> confirmList = new ArrayList<>();
// Remove confirmList players from smart matching.
Iterator<Player> iter = matches.iterator();
while (iter.hasNext()) {
Player player = iter.next();
if (requester instanceof Player && !((Player) requester).canSee(player)) {
if (requester.hasPermission("acf.seevanish")) {
if (!origName.endsWith(":confirm")) {
confirmList.add(player);
iter.remove();
}
} else {
iter.remove();
}
}
}
if (matches.size() > 1 || confirmList.size() > 1) {
requester.sendMessage("§cMultiple players matched '" + name + "', please be more specific");
return null;
}
if (matches.isEmpty()) {
if (confirmList.isEmpty()) {
requester.sendMessage("§cNo player matching '" + name + "' is connected to this server");
return null;
} else {
Player player = Iterables.getOnlyElement(confirmList);
sendMsg(requester,
"&cWarning: " + player.getDisplayName() + "&c is vanished. Do not blow their cover!\n" +
"&cTo confirm your action, add &f:confirm&c to the end of their name. \n" +
"&bEx: &e/g " + player.getName() + ":confirm");
return null;
}
}
return matches.get(0);
}
public static boolean isValidName(String name) {
return name != null && !name.isEmpty() && ACFPatterns.VALID_NAME_PATTERN.matcher(name).matches();
}
static boolean isValidItem(ItemStack item) {
return item != null && item.getType() != Material.AIR && item.getAmount() > 0;
}
}
@@ -33,26 +33,25 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public class BukkitCommandContexts extends CommandContexts { public class BukkitCommandContexts extends CommandContexts<BukkitCommandExecutionContext> {
public BukkitCommandContexts(BukkitCommandManager manager) { public BukkitCommandContexts(BukkitCommandManager manager) {
super(manager); super(manager);
registerContext(OnlinePlayer.class, (c) -> { registerContext(OnlinePlayer.class, (c) -> {
final String playercheck = c.popFirstArg(); final String playercheck = c.popFirstArg();
Player player = ACFUtil.findPlayerSmart(c.getSender(), playercheck); Player player = ACFBukkitUtil.findPlayerSmart(c.getIssuer(), playercheck);
if (player == null) { if (player == null) {
if (c.hasAnnotation(Optional.class)) { if (c.hasAnnotation(Optional.class)) {
return null; return null;
} }
ACFUtil.sendMsg(c.getSender(), "&cCould not find a player by the name " + playercheck); ACFBukkitUtil.sendMsg(c.getIssuer(), "&cCould not find a player by the name " + playercheck);
throw new InvalidCommandArgument(false); throw new InvalidCommandArgument(false);
} }
return new OnlinePlayer(player); return new OnlinePlayer(player);
@@ -63,22 +62,22 @@ public class BukkitCommandContexts extends CommandContexts {
if (world != null) { if (world != null) {
c.popFirstArg(); c.popFirstArg();
} }
if (world == null && c.getSender() instanceof Player) { if (world == null && c.getIssuer() instanceof Player) {
world = ((Entity) c.getSender()).getWorld(); world = ((Entity) c.getIssuer()).getWorld();
} }
if (world == null) { if (world == null) {
throw new InvalidCommandArgument("Invalid World"); throw new InvalidCommandArgument("Invalid World");
} }
return world; return world;
}); });
registerSenderAwareContext(CommandSender.class, CommandExecutionContext::getSender); registerSenderAwareContext(CommandSender.class, bukkitCommandExecutionContext -> bukkitCommandExecutionContext.getSender());
registerSenderAwareContext(Player.class, (c) -> { registerSenderAwareContext(Player.class, (c) -> {
Player player = c.getSender() instanceof Player ? (Player) c.getSender() : null; Player player = c.getIssuer() instanceof Player ? (Player) c.getIssuer() : null;
if (player == null && !c.hasAnnotation(Optional.class)) { if (player == null && !c.hasAnnotation(Optional.class)) {
throw new InvalidCommandArgument("Requires a player to run this command", false); throw new InvalidCommandArgument("Requires a player to run this command", false);
} }
PlayerInventory inventory = player != null ? player.getInventory() : null; PlayerInventory inventory = player != null ? player.getInventory() : null;
if (inventory != null && c.hasFlag("itemheld") && !ACFUtil.isValidItem(inventory.getItem(inventory.getHeldItemSlot()))) { if (inventory != null && c.hasFlag("itemheld") && !ACFBukkitUtil.isValidItem(inventory.getItem(inventory.getHeldItemSlot()))) {
throw new InvalidCommandArgument("You must be holding an item in your main hand.", false); throw new InvalidCommandArgument("You must be holding an item in your main hand.", false);
} }
return player; return player;
@@ -116,6 +115,5 @@ public class BukkitCommandContexts extends CommandContexts {
BukkitCommandContexts_1_12.register(this); BukkitCommandContexts_1_12.register(this);
} }
} }
} }
} }
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import org.bukkit.command.CommandSender;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Map;
public class BukkitCommandExecutionContext extends CommandExecutionContext<BukkitCommandExecutionContext> {
BukkitCommandExecutionContext(RegisteredCommand cmd, Parameter param, CommandIssuer sender, List<String> args,
int index, Map<String, Object> passedArgs) {
super(cmd, param, sender, args, index, passedArgs);
}
public CommandSender getSender() {
return this.issuer.getIssuer();
}
}
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class BukkitCommandIssuer implements CommandIssuer {
private final CommandSender sender;
BukkitCommandIssuer(CommandSender sender) {
this.sender = sender;
}
@Override
public boolean isPlayer() {
return sender instanceof Player;
}
@Override
public <T> T getIssuer() {
//noinspection unchecked
return (T) sender;
}
@Override
public void sendMessage(String message) {
sender.sendMessage(message);
}
@Override
public boolean hasPermission(String name) {
return sender.hasPermission(name);
}
}
@@ -38,6 +38,7 @@ import org.bukkit.plugin.Plugin;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*; import java.util.*;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
@@ -48,7 +49,7 @@ public class BukkitCommandManager extends CommandManager {
private final CommandMap commandMap; private final CommandMap commandMap;
private final TimingManager timingManager; private final TimingManager timingManager;
protected Map<String, Command> knownCommands = new HashMap<>(); protected Map<String, Command> knownCommands = new HashMap<>();
protected Map<String, BaseCommand> registeredCommands = new HashMap<>(); protected Map<String, BukkitRootCommand> registeredCommands = new HashMap<>();
protected CommandContexts contexts; protected CommandContexts contexts;
protected CommandCompletions completions; protected CommandCompletions completions;
@@ -107,32 +108,28 @@ public class BukkitCommandManager extends CommandManager {
command.onRegister(this); command.onRegister(this);
for (Map.Entry<String, RootCommand> entry : command.registeredCommands.entrySet()) { for (Map.Entry<String, RootCommand> entry : command.registeredCommands.entrySet()) {
String key = entry.getKey().toLowerCase(); String key = entry.getKey().toLowerCase();
RootCommand value = entry.getValue(); BukkitRootCommand value = (BukkitRootCommand) entry.getValue();
if (!value.isRegistered) { if (!value.isRegistered) {
commandMap.register(key, plugin, value); commandMap.register(key, plugin, value);
} }
value.isRegistered = true; value.isRegistered = true;
registeredCommands.put(key, command); registeredCommands.put(key, value);
} }
} }
public void unregisterCommand(BaseCommand command) { public void unregisterCommand(BukkitRootCommand command) {
final String plugin = this.plugin.getName().toLowerCase(); final String plugin = this.plugin.getName().toLowerCase();
command.registeredCommands.entrySet().removeIf(entry -> { command.unregister(commandMap);
Command cmd = entry.getValue(); String key = command.getName();
cmd.unregister(commandMap); Command registered = knownCommands.get(key);
String key = entry.getKey(); if (command.equals(registered)) {
Command registered = knownCommands.get(key); knownCommands.remove(key);
if (registered == command) { }
knownCommands.remove(key); knownCommands.remove(plugin + ":" + key);
}
knownCommands.remove(plugin + ":" + key);
return true;
});
} }
public void unregisterCommands() { public void unregisterCommands() {
for (Map.Entry<String, BaseCommand> entry : registeredCommands.entrySet()) { for (Map.Entry<String, BukkitRootCommand> entry : registeredCommands.entrySet()) {
unregisterCommand(entry.getValue()); unregisterCommand(entry.getValue());
} }
} }
@@ -158,6 +155,16 @@ public class BukkitCommandManager extends CommandManager {
return timingManager; return timingManager;
} }
@Override
public RootCommand createRootCommand(String cmd) {
return new BukkitRootCommand(this, cmd);
}
@Override
public CommandExecutionContext<? extends CommandExecutionContext> createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
return new BukkitCommandExecutionContext(command, parameter, sender, args, i, passedArgs);
}
class ProxyCommandMap extends SimpleCommandMap { class ProxyCommandMap extends SimpleCommandMap {
CommandMap proxied; CommandMap proxied;
@@ -187,7 +194,7 @@ public class BukkitCommandManager extends CommandManager {
} }
boolean isOurCommand(Command command) { boolean isOurCommand(Command command) {
return command instanceof BaseCommand && ((BaseCommand) command).manager == BukkitCommandManager.this; return command instanceof RootCommand && ((RootCommand) command).getManager() == BukkitCommandManager.this;
} }
@Override @Override
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class BukkitRootCommand extends Command implements RootCommand {
private final BukkitCommandManager manager;
private final String name;
private BaseCommand defCommand;
private Map<String, BaseCommand> subCommands = new HashMap<>();
private List<BaseCommand> children = new ArrayList<>();
boolean isRegistered = false;
BukkitRootCommand(BukkitCommandManager manager, String name) {
super(name);
this.manager = manager;
this.name = name;
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
return tabComplete(new BukkitCommandIssuer(sender), alias, args);
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
return execute(new BukkitCommandIssuer(sender), commandLabel, args);
}
private List<String> tabComplete(CommandIssuer sender, String alias, String[] args) throws IllegalArgumentException {
Set<String> completions = new HashSet<>();
this.children.forEach(child -> completions.addAll(child.tabComplete(sender, alias, args)));
return new ArrayList<>(completions);
}
private boolean execute(CommandIssuer sender, String commandLabel, String[] args) {
for (int i = args.length; i >= 0; i--) {
String checkSub = StringUtils.join(args, " ", 0, i).toLowerCase();
BaseCommand subHandler = this.subCommands.get(checkSub);
if (subHandler != null) {
if (!subHandler.testPermission(sender)) {
return true;
}
subHandler.execute(sender, commandLabel, args);
return false;
}
}
if (!this.defCommand.testPermission(sender)) {
return true;
}
this.defCommand.execute(sender, commandLabel, args);
return false;
}
public void addChild(BaseCommand command) {
if (this.defCommand == null || !command.subCommands.get("__default").isEmpty()) {
this.defCommand = command;
//this.setDescription(command.getDescription());
//this.setUsage(command.getUsage());
//this.setAliases(command.getAliases());
}
command.subCommands.keySet().forEach(key -> {
if (key.equals(BaseCommand.DEFAULT) || key.equals(BaseCommand.UNKNOWN)) {
return;
}
BaseCommand regged = this.subCommands.get(key);
if (regged != null) {
ACFLog.severe("ACF Error: " + command.getName() + " registered subcommand " + key + " for root command " + getName() + " - but it is already defined in " + regged.getName());
ACFLog.severe("2 subcommands of the same prefix may not be spread over 2 different classes. Ignoring this.");
return;
}
this.subCommands.put(key, command);
});
this.children.add(command);
}
@Override
public CommandManager getManager() {
return manager;
}
}
+3 -14
View File
@@ -2,11 +2,7 @@
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="minecraft" name="Minecraft"> <facet type="minecraft" name="Minecraft">
<configuration> <configuration />
<autoDetectTypes>
<platformType>BUKKIT</platformType>
</autoDetectTypes>
</configuration>
</facet> </facet>
</component> </component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
@@ -20,15 +16,8 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
<orderEntry type="library" name="Maven: co.aikar:minecraft-timings:1.0.3" level="project" /> <orderEntry type="library" name="Maven: co.aikar:minecraft-timings:1.0.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.bukkit:bukkit:1.12-pre2-SNAPSHOT" level="project" /> <orderEntry type="library" name="Maven: com.google.guava:guava:17.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-lang:commons-lang:2.6" level="project" /> <orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:21.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.18" level="project" />
</component> </component>
</module> </module>
+14 -74
View File
@@ -27,90 +27,30 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 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> <modelVersion>4.0.0</modelVersion>
<groupId>co.aikar</groupId> <parent>
<groupId>co.aikar</groupId>
<artifactId>acf-parent</artifactId>
<version><!--VERSION-->0.5.0<!--VERSION--></version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>acf-core</artifactId> <artifactId>acf-core</artifactId>
<version>0.4.0-SNAPSHOT</version> <version><!--VERSION-->0.5.0<!--VERSION--></version>
<name>ACF</name> <name>ACF (Core)</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<distributionManagement>
<repository>
<id>aikar</id>
<url>http://ci.emc.gs/nexus/content/repositories/aikar-release/</url>
</repository>
<snapshotRepository>
<id>aikar</id>
<url>http://ci.emc.gs/nexus/content/repositories/aikar-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>aikar</id>
<url>http://ci.emc.gs/nexus/content/groups/aikar/</url>
</repository>
<repository>
<id>paper</id>
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
</repositories>
<build>
<defaultGoal>clean install</defaultGoal>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<showDeprecation>false</showDeprecation>
<showWarnings>false</showWarnings>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies> <dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
</dependency>
<dependency> <dependency>
<groupId>co.aikar</groupId> <groupId>co.aikar</groupId>
<artifactId>minecraft-timings</artifactId> <artifactId>minecraft-timings</artifactId>
<version>1.0.3</version> <version>1.0.3</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>com.google.guava</groupId>
<artifactId>bukkit</artifactId> <artifactId>guava</artifactId>
<version>1.12-pre2-SNAPSHOT</version> <version>17.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@@ -23,14 +23,14 @@
package co.aikar.commands; package co.aikar.commands;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.Bukkit; import co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil;
import java.util.logging.Logger; import java.util.logging.Logger;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
final class ACFLog { final class ACFLog {
private static final Logger LOGGER = Bukkit.getLogger(); private static final Logger LOGGER = Logger.getLogger("ACF");
public static final String PREFIX = "[ACF] "; public static final String PREFIX = "[ACF] ";
private ACFLog() {} private ACFLog() {}
@@ -76,7 +76,7 @@ final class ACFLog {
if (msg != null) { if (msg != null) {
severe(msg); severe(msg);
} }
severe(ExceptionUtils.getFullStackTrace(e)); severe(ApacheCommonsExceptionUtil.getFullStackTrace(e));
} }
public static void exception(Throwable dbg, int lines) { public static void exception(Throwable dbg, int lines) {
+10 -312
View File
@@ -23,18 +23,8 @@
package co.aikar.commands; package co.aikar.commands;
import com.google.common.collect.Iterables;
import org.apache.commons.lang.StringUtils; import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -44,10 +34,8 @@ import java.text.Normalizer.Form;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -72,123 +60,6 @@ public final class ACFUtil {
return NumberFormat.getInstance().format(balance); return NumberFormat.getInstance().format(balance);
} }
public static String formatLocation(Location loc) {
if (loc == null) {
return null;
}
return loc.getWorld().getName() +
":" +
loc.getBlockX() +
"," +
loc.getBlockY() +
"," +
loc.getBlockZ();
}
public static String color(String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
public static void sendMsg(CommandSender player, String message) {
message = color(message);
if (player == null) {
for (String msg : ACFPatterns.NEWLINE.split(message)) {
ACFLog.info(msg);
}
} else {
for (String msg : ACFPatterns.NEWLINE.split(message)) {
player.sendMessage(msg);
}
}
}
public static Location stringToLocation(String storedLoc) {
return stringToLocation(storedLoc, null);
}
public static Location stringToLocation(String storedLoc, World forcedWorld) {
if (storedLoc == null) {
return null;
}
String[] args = ACFPatterns.COLON.split(storedLoc);
if (args.length >= 4 || (args.length == 3 && forcedWorld != null)) {
String world = forcedWorld != null ? forcedWorld.getName() : args[0];
int i = args.length == 3 ? 0 : 1;
double x = Double.parseDouble(args[i]);
double y = Double.parseDouble(args[i + 1]);
double z = Double.parseDouble(args[i + 2]);
Location loc = new Location(Bukkit.getWorld(world), x, y, z);
if (args.length >= 6) {
loc.setPitch(Float.parseFloat(args[4]));
loc.setYaw(Float.parseFloat(args[5]));
}
return loc;
} else if (args.length == 2) {
String[] args2 = ACFPatterns.COMMA.split(args[1]);
if (args2.length == 3) {
String world = forcedWorld != null ? forcedWorld.getName() : args[0];
double x = Double.parseDouble(args2[0]);
double y = Double.parseDouble(args2[1]);
double z = Double.parseDouble(args2[2]);
return new Location(Bukkit.getWorld(world), x, y, z);
}
}
return null;
}
public static String fullLocationToString(Location loc) {
if (loc == null) {
return null;
}
return (new StringBuilder(64))
.append(loc.getWorld().getName())
.append(':')
.append(precision(loc.getX(), 4))
.append(':')
.append(precision(loc.getY(), 4))
.append(':')
.append(precision(loc.getZ(), 4))
.append(':')
.append(precision(loc.getPitch(), 4))
.append(':')
.append(precision(loc.getYaw(), 4))
.toString();
}
public static String fullBlockLocationToString(Location loc) {
if (loc == null) {
return null;
}
return (new StringBuilder(64))
.append(loc.getWorld().getName())
.append(':')
.append(loc.getBlockX())
.append(':')
.append(loc.getBlockY())
.append(':')
.append(loc.getBlockZ())
.append(':')
.append(precision(loc.getPitch(), 4))
.append(':')
.append(precision(loc.getYaw(), 4))
.toString();
}
public static String blockLocationToString(Location loc) {
if (loc == null) {
return null;
}
return (new StringBuilder(32))
.append(loc.getWorld().getName())
.append(':')
.append(loc.getBlockX())
.append(':')
.append(loc.getBlockY())
.append(':')
.append(loc.getBlockZ())
.toString();
}
public static <T extends Enum> T getEnumFromName(T[] types, String name) { public static <T extends Enum> T getEnumFromName(T[] types, String name) {
return getEnumFromName(types, name, null); return getEnumFromName(types, name, null);
} }
@@ -210,7 +81,7 @@ public final class ACFUtil {
} }
public static String ucfirst(String str) { public static String ucfirst(String str) {
return WordUtils.capitalizeFully(str); return ApacheCommonsLangUtil.capitalizeFully(str);
} }
public static Double parseDouble(String var) { public static Double parseDouble(String var) {
@@ -275,17 +146,17 @@ public final class ACFUtil {
} }
public static String join(Collection<String> args) { public static String join(Collection<String> args) {
return StringUtils.join(args, " "); return ApacheCommonsLangUtil.join(args, " ");
} }
public static String join(Collection<String> args, String sep) { public static String join(Collection<String> args, String sep) {
return StringUtils.join(args, sep); return ApacheCommonsLangUtil.join(args, sep);
} }
public static String join(String[] args) { public static String join(String[] args) {
return join(args, 0, ' '); return join(args, 0, ' ');
} }
public static String join(String[] args, String sep) { public static String join(String[] args, String sep) {
return StringUtils.join(args, sep); return ApacheCommonsLangUtil.join(args, sep);
} }
public static String join(String[] args, char sep) { public static String join(String[] args, char sep) {
return join(args, 0, sep); return join(args, 0, sep);
@@ -296,7 +167,7 @@ public final class ACFUtil {
} }
public static String join(String[] args, int index, char sep) { public static String join(String[] args, int index, char sep) {
return StringUtils.join(args, sep, index, args.length); return ApacheCommonsLangUtil.join(args, sep, index, args.length);
} }
public static String simplifyString(String str) { public static String simplifyString(String str) {
@@ -333,36 +204,6 @@ public final class ACFUtil {
} }
public static String removeColors(String msg) {
return ChatColor.stripColor(ACFUtil.color(msg));
}
public static String replaceChatString(String message, String replace, String with) {
return replaceChatString(message, Pattern.compile(Pattern.quote(replace), Pattern.CASE_INSENSITIVE), with);
}
public static String replaceChatString(String message, Pattern replace, String with) {
final String[] split = replace.split(message + "1");
if (split.length < 2) {
return replace.matcher(message).replaceAll(with);
}
message = split[0];
for (int i = 1; i < split.length; i++) {
final String prev = ChatColor.getLastColors(message);
message += with + prev + split[i];
}
return message.substring(0, message.length() - 1);
}
public static boolean isWithinDistance(@NotNull Player p1, @NotNull Player p2, int dist) {
return isWithinDistance(p1.getLocation(), p2.getLocation(), dist);
}
public static boolean isWithinDistance(@NotNull Location loc1, @NotNull Location loc2, int dist) {
return loc1.getWorld() == loc2.getWorld() && loc1.distance(loc2) <= dist;
}
public static String limit(String str, int limit) { public static String limit(String str, int limit) {
return str.length() > limit ? str.substring(0, limit) : str; return str.length() > limit ? str.substring(0, limit) : str;
} }
@@ -457,48 +298,11 @@ public final class ACFUtil {
return string; return string;
} }
/**
* Copied from Apache Commons WordUtils, with an exception to skip spaces after delimiters.
*
* @see org.apache.commons.lang.WordUtils#capitalize(String, char[])
* @param str
* @param delimiters
* @return
*/
public static String capitalize(String str, char[] delimiters) { public static String capitalize(String str, char[] delimiters) {
int delimLen = (delimiters == null ? -1 : delimiters.length); return ApacheCommonsLangUtil.capitalize(str, delimiters);
if (str == null || str.isEmpty() || delimLen == 0) {
return str;
}
int strLen = str.length();
StringBuilder builder = new StringBuilder(strLen);
boolean capitalizeNext = true;
for (int i = 0; i < strLen; i++) {
char ch = str.charAt(i);
if (isDelimiter(ch, delimiters)) {
builder.append(ch);
capitalizeNext = true;
} else if (ch != ' ' && capitalizeNext) {
builder.append(Character.toTitleCase(ch));
capitalizeNext = false;
} else {
builder.append(ch);
}
}
return builder.toString();
} }
private static boolean isDelimiter(char ch, char[] delimiters) { private static boolean isDelimiter(char ch, char[] delimiters) {
if (delimiters == null) { return ApacheCommonsLangUtil.isDelimiter(ch, delimiters);
return Character.isWhitespace(ch);
}
for (char delimiter : delimiters) {
if (ch == delimiter) {
return true;
}
}
return false;
} }
public static <T> T random(List<T> arr) { public static <T> T random(List<T> arr) {
@@ -584,53 +388,6 @@ public final class ACFUtil {
return sb.toString(); return sb.toString();
} }
public static double distance(@NotNull Entity e1, @NotNull Entity e2) {
return distance(e1.getLocation(), e2.getLocation());
}
public static double distance2d(@NotNull Entity e1, @NotNull Entity e2) {
return distance2d(e1.getLocation(), e2.getLocation());
}
public static double distance2d(@NotNull Location loc1, @NotNull Location loc2) {
loc1 = loc1.clone();
loc1.setY(loc2.getY());
return distance(loc1, loc2);
}
public static double distance(@NotNull Location loc1, @NotNull Location loc2) {
if (loc1.getWorld() != loc2.getWorld()) {
return 0;
}
return loc1.distance(loc2);
}
public static Location getTargetLoc(Player player) {
return getTargetLoc(player, 128);
}
public static Location getTargetLoc(Player player, int maxDist) {
return getTargetLoc(player, maxDist, 1.5);
}
public static Location getTargetLoc(Player player, int maxDist, double addY) {
try {
Location target = player.getTargetBlock((Set<Material>) null, maxDist).getLocation();
target.setY(target.getY() + addY);
return target;
} catch (Exception ignored) {
return null;
}
}
public static Location getRandLoc(Location loc, int radius) {
return getRandLoc(loc, radius, radius, radius);
}
public static Location getRandLoc(Location loc, int xzRadius, int yRadius) {
return getRandLoc(loc, xzRadius, yRadius, xzRadius);
}
@NotNull public static Location getRandLoc(Location loc, int xRadius, int yRadius, int zRadius) {
Location newLoc = loc.clone();
newLoc.setX(rand(loc.getX()-xRadius, loc.getX()+xRadius));
newLoc.setY(rand(loc.getY()-yRadius, loc.getY()+yRadius));
newLoc.setZ(rand(loc.getZ()-zRadius, loc.getZ()+zRadius));
return newLoc;
}
@Nullable public static <E extends Enum<E>> E simpleMatch(Class<? extends Enum<?>> list, String item) { @Nullable public static <E extends Enum<E>> E simpleMatch(Class<? extends Enum<?>> list, String item) {
if (item == null) { if (item == null) {
@@ -725,7 +482,7 @@ public final class ACFUtil {
} }
public static boolean isNumber(String str) { public static boolean isNumber(String str) {
return StringUtils.isNumeric(str); return ApacheCommonsLangUtil.isNumeric(str);
} }
public static String intToRoman(int integer) { public static String intToRoman(int integer) {
@@ -796,62 +553,6 @@ public final class ACFUtil {
return Math.round(x * pow) / pow; return Math.round(x * pow) / pow;
} }
public static Player findPlayerSmart(CommandSender requester, String origName) {
String name = replace(origName, ":confirm", "");
if (name.length() < 3) {
requester.sendMessage("§cUsername too short, must be at least three characters");
return null;
}
if (!isValidName(name)) {
requester.sendMessage("§c'" + name + "' is not a valid username");
return null;
}
List<Player> matches = Bukkit.getServer().matchPlayer(name);
List<Player> confirmList = new ArrayList<>();
// Remove confirmList players from smart matching.
Iterator<Player> iter = matches.iterator();
while (iter.hasNext()) {
Player player = iter.next();
if (requester instanceof Player && !((Player) requester).canSee(player)) {
if (requester.hasPermission("acf.seevanish")) {
if (!origName.endsWith(":confirm")) {
confirmList.add(player);
iter.remove();
}
} else {
iter.remove();
}
}
}
if (matches.size() > 1 || confirmList.size() > 1) {
requester.sendMessage("§cMultiple players matched '" + name + "', please be more specific");
return null;
}
if (matches.isEmpty()) {
if (confirmList.isEmpty()) {
requester.sendMessage("§cNo player matching '" + name + "' is connected to this server");
return null;
} else {
Player player = Iterables.getOnlyElement(confirmList);
sendMsg(requester,
"&cWarning: " + player.getDisplayName() + "&c is vanished. Do not blow their cover!\n" +
"&cTo confirm your action, add &f:confirm&c to the end of their name. \n" +
"&bEx: &e/g " + player.getName() + ":confirm");
return null;
}
}
return matches.get(0);
}
public static boolean isValidName(String name) {
return name != null && !name.isEmpty() && ACFPatterns.VALID_NAME_PATTERN.matcher(name).matches();
}
public static void sneaky(Throwable t) { public static void sneaky(Throwable t) {
//noinspection RedundantTypeArguments //noinspection RedundantTypeArguments
throw ACFUtil.<RuntimeException>superSneaky( t ); throw ACFUtil.<RuntimeException>superSneaky( t );
@@ -862,7 +563,4 @@ public final class ACFUtil {
throw (T) t; throw (T) t;
} }
static boolean isValidItem(ItemStack item) {
return item != null && item.getType() != Material.AIR && item.getAmount() > 0;
}
} }
@@ -28,20 +28,15 @@ import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default; import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.UnknownHandler; import co.aikar.commands.annotation.UnknownHandler;
import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil;
import co.aikar.timings.lib.MCTiming; import co.aikar.timings.lib.MCTiming;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.SetMultimap; import com.google.common.collect.SetMultimap;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.util.StringUtil;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter; import java.lang.reflect.Parameter;
@@ -59,7 +54,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class BaseCommand extends Command { public abstract class BaseCommand {
public static final String UNKNOWN = "__unknown"; public static final String UNKNOWN = "__unknown";
public static final String DEFAULT = "__default"; public static final String DEFAULT = "__default";
@@ -73,14 +68,10 @@ public class BaseCommand extends Command {
private String[] origArgs; private String[] origArgs;
CommandManager manager = null; CommandManager manager = null;
Map<String, RootCommand> registeredCommands = new HashMap<>(); Map<String, RootCommand> registeredCommands = new HashMap<>();
String description;
public BaseCommand() { String commandName;
this(null); String usageMessage;
} String permission;
public BaseCommand(String cmd) {
super(cmd);
}
/** /**
* Gets the root command name that the user actually typed * Gets the root command name that the user actually typed
@@ -107,7 +98,7 @@ public class BaseCommand extends Command {
} }
void onRegister(CommandManager manager) { void onRegister(CommandManager manager) {
onRegister(manager, getName()); onRegister(manager, null);
} }
void onRegister(CommandManager manager, String cmd) { void onRegister(CommandManager manager, String cmd) {
this.manager = manager; this.manager = manager;
@@ -120,27 +111,15 @@ public class BaseCommand extends Command {
cmd = ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(rootCmdAlias.value()))[0]; cmd = ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(rootCmdAlias.value()))[0];
} }
cmd = cmd.toLowerCase(); cmd = cmd.toLowerCase();
try {
setName(cmd);
} catch (NoSuchMethodError ignored) {
try {
// To support pre 1.8 where setName was not added.
Field field = Command.class.getDeclaredField("name");
field.setAccessible(true);
field.set(this, cmd);
} catch (NoSuchFieldException | IllegalAccessException e) {
ACFLog.exception("Error setting name for command", e);
}
}
setLabel(cmd);
} }
this.commandName = cmd;
this.description = cmd + " commands"; this.description = cmd + " commands";
this.usageMessage = "/" + cmd; this.usageMessage = "/" + cmd;
final CommandPermission perm = self.getAnnotation(CommandPermission.class); final CommandPermission perm = self.getAnnotation(CommandPermission.class);
if (perm != null) { if (perm != null) {
this.setPermission(manager.getCommandReplacements().replace(perm.value())); this.permission = manager.getCommandReplacements().replace(perm.value());
} }
boolean foundDefault = false; boolean foundDefault = false;
@@ -158,7 +137,7 @@ public class BaseCommand extends Command {
registerSubcommand(method, DEFAULT); registerSubcommand(method, DEFAULT);
foundDefault = true; foundDefault = true;
} else { } else {
ACFUtil.sneaky(new InvalidConfigurationException("Multiple @Default commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); ACFUtil.sneaky(new IllegalStateException("Multiple @Default commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName()));
} }
} }
if (sub != null) { if (sub != null) {
@@ -171,14 +150,14 @@ public class BaseCommand extends Command {
} }
//CommandSender.class, String.class, String[].class //CommandIssuer.class, String.class, String[].class
UnknownHandler unknown = method.getAnnotation(UnknownHandler.class); UnknownHandler unknown = method.getAnnotation(UnknownHandler.class);
if (unknown != null) { if (unknown != null) {
if (!foundUnknown) { if (!foundUnknown) {
registerSubcommand(method, UNKNOWN); registerSubcommand(method, UNKNOWN);
foundUnknown = true; foundUnknown = true;
} else { } else {
ACFUtil.sneaky(new InvalidConfigurationException("Multiple @UnknownHandler commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName())); ACFUtil.sneaky(new IllegalStateException("Multiple @UnknownHandler commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName()));
} }
} }
} }
@@ -247,6 +226,7 @@ public class BaseCommand extends Command {
String nameLower = name.toLowerCase(); String nameLower = name.toLowerCase();
RootCommand rootCommand = manager.obtainRootCommand(nameLower); RootCommand rootCommand = manager.obtainRootCommand(nameLower);
rootCommand.addChild(cmd); rootCommand.addChild(cmd);
this.registeredCommands.put(nameLower, rootCommand); this.registeredCommands.put(nameLower, rootCommand);
} }
@@ -260,11 +240,11 @@ public class BaseCommand extends Command {
for (int i = 0; i < subCommandParts.length; i++) { for (int i = 0; i < subCommandParts.length; i++) {
subCommandParts[i] = ACFPatterns.PIPE.split(subCommandParts[i])[0]; subCommandParts[i] = ACFPatterns.PIPE.split(subCommandParts[i])[0];
} }
String prefSubCommand = StringUtils.join(subCommandParts, " "); String prefSubCommand = ApacheCommonsLangUtil.join(subCommandParts, " ");
final CommandAlias cmdAlias = method.getAnnotation(CommandAlias.class); final CommandAlias cmdAlias = method.getAnnotation(CommandAlias.class);
final String[] aliasNames = cmdAlias != null ? ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(cmdAlias.value().toLowerCase())) : null; final String[] aliasNames = cmdAlias != null ? ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(cmdAlias.value().toLowerCase())) : null;
String cmdName = aliasNames != null ? aliasNames[0] : getLabel() + " "; String cmdName = aliasNames != null ? aliasNames[0] : this.commandName + " ";
RegisteredCommand cmd = new RegisteredCommand(this, cmdName, method, prefSubCommand); RegisteredCommand cmd = new RegisteredCommand(this, cmdName, method, prefSubCommand);
for (String subcmd : cmdList) { for (String subcmd : cmdList) {
@@ -316,8 +296,7 @@ public class BaseCommand extends Command {
} }
} }
@Override public boolean execute(CommandIssuer sender, String commandLabel, String[] args) {
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
commandLabel = commandLabel.toLowerCase(); commandLabel = commandLabel.toLowerCase();
execSubcommand = null; execSubcommand = null;
@@ -354,7 +333,7 @@ public class BaseCommand extends Command {
} }
private CommandSearch findSubCommand(String[] args, boolean completion) { private CommandSearch findSubCommand(String[] args, boolean completion) {
for (int i = args.length; i >= 0; i--) { for (int i = args.length; i >= 0; i--) {
String checkSub = StringUtils.join(args, " ", 0, i).toLowerCase(); String checkSub = ApacheCommonsLangUtil.join(args, " ", 0, i).toLowerCase();
Set<RegisteredCommand> cmds = subCommands.get(checkSub); Set<RegisteredCommand> cmds = subCommands.get(checkSub);
final int extraArgs = args.length - i; final int extraArgs = args.length - i;
@@ -388,30 +367,29 @@ public class BaseCommand extends Command {
return null; return null;
} }
private static void executeCommand(CommandSender sender, String[] args, RegisteredCommand cmd) { private static void executeCommand(CommandIssuer sender, String[] args, RegisteredCommand cmd) {
if (cmd.hasPermission(sender)) { if (cmd.hasPermission(sender)) {
List<String> sargs = Lists.newArrayList(args); List<String> sargs = Lists.newArrayList(args);
try (MCTiming timing = cmd.getTiming().startTiming()) { try (MCTiming timing = cmd.getTiming().startTiming()) {
cmd.invoke(sender, sargs); cmd.invoke(sender, sargs);
} }
} else { } else {
ACFUtil.sendMsg(sender, "&cI'm sorry, but you do not have permission to perform this command."); sender.sendMessage("&cI'm sorry, but you do not have permission to perform this command.");
} }
} }
public boolean canExecute(CommandSender sender, RegisteredCommand cmd) { public boolean canExecute(CommandIssuer sender, RegisteredCommand cmd) {
return true; return true;
} }
@Override public List<String> tabComplete(CommandIssuer sender, String commandLabel, String[] args)
public List<String> tabComplete(CommandSender sender, String commandLabel, String[] args)
throws IllegalArgumentException { throws IllegalArgumentException {
commandLabel = commandLabel.toLowerCase(); commandLabel = commandLabel.toLowerCase();
final CommandSearch search = findSubCommand(args, true); final CommandSearch search = findSubCommand(args, true);
String argString = StringUtils.join(args, " ").toLowerCase(); String argString = ApacheCommonsLangUtil.join(args, " ").toLowerCase();
final List<String> cmds = new ArrayList<>(); final List<String> cmds = new ArrayList<>();
@@ -436,12 +414,12 @@ public class BaseCommand extends Command {
return filterTabComplete(args[args.length-1], cmds); return filterTabComplete(args[args.length-1], cmds);
} }
private List<String> completeCommand(CommandSender sender, RegisteredCommand cmd, String[] args, String commandLabel) { private List<String> completeCommand(CommandIssuer sender, RegisteredCommand cmd, String[] args, String commandLabel) {
if (args.length > cmd.requiredResolvers + cmd.optionalResolvers) { if (args.length > cmd.requiredResolvers + cmd.optionalResolvers) {
return ImmutableList.of(); return ImmutableList.of();
} }
if (args.length == 0 || cmd.complete == null) { if (args.length == 0 || cmd.complete == null) {
return args.length < 2 ? super.tabComplete(sender, commandLabel, args) : ImmutableList.of(); return args.length < 2 ? null : ImmutableList.of();
} }
String[] completions = ACFPatterns.SPACE.split(cmd.complete); String[] completions = ACFPatterns.SPACE.split(cmd.complete);
@@ -453,20 +431,20 @@ public class BaseCommand extends Command {
private static List<String> filterTabComplete(String arg, List<String> cmds) { private static List<String> filterTabComplete(String arg, List<String> cmds) {
return cmds.stream() return cmds.stream()
.distinct() .distinct()
.filter(cmd -> cmd != null && (arg.isEmpty() || StringUtil.startsWithIgnoreCase(cmd, arg))) .filter(cmd -> cmd != null && (arg.isEmpty() || ApacheCommonsLangUtil.startsWithIgnoreCase(cmd, arg)))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public void help(CommandSender sender, String[] args) { public void help(CommandIssuer sender, String[] args) {
ACFUtil.sendMsg(sender, "&cUnknown Command, please type &f/help"); sender.sendMessage("&cUnknown Command, please type &f/help");
} }
private boolean executeSubcommand(String subcommand, CommandSender sender, String... args) { private boolean executeSubcommand(String subcommand, CommandIssuer sender, String... args) {
final Set<RegisteredCommand> defs = subCommands.get(subcommand); final Set<RegisteredCommand> defs = subCommands.get(subcommand);
RegisteredCommand def = null; RegisteredCommand def = null;
if (!defs.isEmpty()) { if (!defs.isEmpty()) {
if (defs.size() == 1) { if (defs.size() == 1) {
def = Iterables.getOnlyElement(defs); def = defs.iterator().next();
} }
if (def != null) { if (def != null) {
executeCommand(sender, args, def); executeCommand(sender, args, def);
@@ -476,16 +454,28 @@ public class BaseCommand extends Command {
return false; return false;
} }
public boolean preCommand(CommandSender sender, String commandLabel, String[] args) { public boolean preCommand(CommandIssuer sender, String commandLabel, String[] args) {
return false; return false;
} }
public void doHelp(CommandSender sender, String... args) { public void doHelp(CommandIssuer sender, String... args) {
help(sender, args); help(sender, args);
} }
public void showSyntax(CommandSender sender, RegisteredCommand cmd) { public void showSyntax(CommandIssuer sender, RegisteredCommand cmd) {
ACFUtil.sendMsg(sender, "&cUsage: /" + cmd.command + " " + cmd.syntaxText); sender.sendMessage("&cUsage: /" + cmd.command + " " + cmd.syntaxText);
}
public boolean testPermission(CommandIssuer sender) {
if (permission != null && !permission.isEmpty() && !sender.hasPermission(permission)) {
// TODO: Msg
return false;
}
return true;
}
public String getName() {
return commandName;
} }
private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub; private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub;
@@ -35,19 +35,4 @@ public class BaseSubCommand extends BaseCommand {
public String getName() { public String getName() {
return parentCommand.getName(); return parentCommand.getName();
} }
@Override
public String getLabel() {
return parentCommand.getLabel();
}
@Override
public String getDescription() {
return parentCommand.getDescription();
}
@Override
public String getUsage() {
return parentCommand.getUsage();
}
} }
@@ -27,7 +27,6 @@ import co.aikar.commands.annotation.Split;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Parameter; import java.lang.reflect.Parameter;
@@ -70,7 +69,7 @@ public class CommandCompletions {
} }
@NotNull @NotNull
List<String> of(RegisteredCommand command, CommandSender sender, String[] completionInfo, String[] args) { List<String> of(RegisteredCommand command, CommandIssuer sender, String[] completionInfo, String[] args) {
final int argIndex = args.length - 1; final int argIndex = args.length - 1;
String input = args[argIndex]; String input = args[argIndex];
@@ -83,7 +82,7 @@ public class CommandCompletions {
} }
@NotNull @NotNull
List<String> getCompletionValues(RegisteredCommand command, CommandSender sender, String completion, String[] args) { List<String> getCompletionValues(RegisteredCommand command, CommandIssuer sender, String completion, String[] args) {
completion = manager.getCommandReplacements().replace(completion); completion = manager.getCommandReplacements().replace(completion);
final int argIndex = args.length - 1; final int argIndex = args.length - 1;
@@ -123,18 +122,18 @@ public class CommandCompletions {
} }
public interface CommandCompletionHandler { public interface CommandCompletionHandler {
Collection<String> getCompletions(CommandSender sender, String config, String input, CommandCompletionContext context) throws InvalidCommandArgument; Collection<String> getCompletions(CommandIssuer sender, String config, String input, CommandCompletionContext context) throws InvalidCommandArgument;
} }
public class CommandCompletionContext { public class CommandCompletionContext {
private final RegisteredCommand command; private final RegisteredCommand command;
private final CommandSender sender; private final CommandIssuer sender;
private final String input; private final String input;
private final String config; private final String config;
private final Map<String, String> configs = Maps.newHashMap(); private final Map<String, String> configs = Maps.newHashMap();
private final List<String> args; private final List<String> args;
CommandCompletionContext(RegisteredCommand command, CommandSender sender, String input, String config, String[] args) { CommandCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) {
this.command = command; this.command = command;
this.sender = sender; this.sender = sender;
this.input = input; this.input = input;
@@ -208,7 +207,7 @@ public class CommandCompletions {
return (T) resolved.get(name); return (T) resolved.get(name);
} }
public CommandSender getSender() { public CommandIssuer getSender() {
return sender; return sender;
} }
@@ -29,14 +29,13 @@ import co.aikar.commands.annotation.Values;
import co.aikar.commands.contexts.ContextResolver; import co.aikar.commands.contexts.ContextResolver;
import co.aikar.commands.contexts.SenderAwareContextResolver; import co.aikar.commands.contexts.SenderAwareContextResolver;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.bukkit.configuration.InvalidConfigurationException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public class CommandContexts { public class CommandContexts <R extends CommandExecutionContext> {
private final Map<Class<?>, ContextResolver<?>> contextMap = Maps.newHashMap(); protected final Map<Class<?>, ContextResolver<?, R>> contextMap = Maps.newHashMap();
private final CommandManager manager; private final CommandManager manager;
CommandContexts(CommandManager manager) { CommandContexts(CommandManager manager) {
@@ -105,8 +104,11 @@ public class CommandContexts {
}); });
registerContext(String[].class, (c) -> { registerContext(String[].class, (c) -> {
String val; String val;
// Go home IDEA, you're drunk
//noinspection unchecked
List<String> args = c.getArgs();
if (c.isLastArg() && c.getParam().getAnnotation(Single.class) == null) { if (c.isLastArg() && c.getParam().getAnnotation(Single.class) == null) {
val = ACFUtil.join(c.getArgs()); val = ACFUtil.join(args);
} else { } else {
val = c.popFirstArg(); val = c.popFirstArg();
} }
@@ -117,16 +119,17 @@ public class CommandContexts {
} }
return ACFPatterns.getPattern(split.value()).split(val); return ACFPatterns.getPattern(split.value()).split(val);
} else if (!c.isLastArg()) { } else if (!c.isLastArg()) {
ACFUtil.sneaky(new InvalidConfigurationException("Weird Command signature... String[] should be last or @Split")); ACFUtil.sneaky(new IllegalStateException("Weird Command signature... String[] should be last or @Split"));
} }
String[] result = c.getArgs().toArray(new String[c.getArgs().size()]); String[] result = args.toArray(new String[args.size()]);
c.getArgs().clear(); args.clear();
return result; return result;
}); });
registerContext(Enum.class, (c) -> { registerContext(Enum.class, (c) -> {
final String first = c.popFirstArg(); final String first = c.popFirstArg();
//noinspection unchecked
Class<? extends Enum<?>> enumCls = (Class<? extends Enum<?>>) c.getParam().getType(); Class<? extends Enum<?>> enumCls = (Class<? extends Enum<?>>) c.getParam().getType();
Enum<?> match = ACFUtil.simpleMatch(enumCls, first); Enum<?> match = ACFUtil.simpleMatch(enumCls, first);
if (match == null) { if (match == null) {
@@ -137,27 +140,27 @@ public class CommandContexts {
}); });
} }
public <T> void registerSenderAwareContext(Class<T> context, SenderAwareContextResolver<T> supplier) { <T> void registerSenderAwareContext(Class<T> context, SenderAwareContextResolver<T, R> supplier) {
contextMap.put(context, supplier); contextMap.put(context, supplier);
} }
public <T> void registerContext(Class<T> context, ContextResolver<T> supplier) { <T> void registerContext(Class<T> context, ContextResolver<T, R> supplier) {
contextMap.put(context, supplier); contextMap.put(context, supplier);
} }
public ContextResolver<?> getResolver(Class<?> type) { public ContextResolver<?, R> getResolver(Class<?> type) {
Class<?> rootType = type; Class<?> rootType = type;
do { do {
if (type == Object.class) { if (type == Object.class) {
break; break;
} }
final ContextResolver<?> resolver = contextMap.get(type); final ContextResolver<?, R> resolver = contextMap.get(type);
if (resolver != null) { if (resolver != null) {
return resolver; return resolver;
} }
} while ((type = type.getSuperclass()) != null); } while ((type = type.getSuperclass()) != null);
ACFLog.exception(new InvalidConfigurationException("No context resolver defined for " + rootType.getName())); ACFLog.exception(new IllegalStateException("No context resolver defined for " + rootType.getName()));
return null; return null;
} }
} }
@@ -30,28 +30,26 @@ import co.aikar.commands.contexts.ContextResolver;
import co.aikar.commands.contexts.SenderAwareContextResolver; import co.aikar.commands.contexts.SenderAwareContextResolver;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.bukkit.command.CommandSender;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Parameter; import java.lang.reflect.Parameter;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@SuppressWarnings({"WeakerAccess", "unused"}) @SuppressWarnings({"WeakerAccess", "unused"})
public class CommandExecutionContext { public class CommandExecutionContext <T extends CommandExecutionContext> {
private final RegisteredCommand cmd; private final RegisteredCommand cmd;
private final Parameter param; private final Parameter param;
private final CommandSender sender; protected final CommandIssuer issuer;
private final List<String> args; private final List<String> args;
private final int index; private final int index;
private final Map<String, Object> passedArgs; private final Map<String, Object> passedArgs;
private final Map<String, String> flags; private final Map<String, String> flags;
public CommandExecutionContext(RegisteredCommand cmd, Parameter param, CommandSender sender, List<String> args, CommandExecutionContext(RegisteredCommand cmd, Parameter param, CommandIssuer sender, List<String> args,
int index, Map<String, Object> passedArgs) { int index, Map<String, Object> passedArgs) {
this.cmd = cmd; this.cmd = cmd;
this.param = param; this.param = param;
this.sender = sender; this.issuer = sender;
this.args = args; this.args = args;
this.index = index; this.index = index;
this.passedArgs = passedArgs; this.passedArgs = passedArgs;
@@ -87,7 +85,8 @@ public class CommandExecutionContext {
int numRequired = getNumParams(); int numRequired = getNumParams();
for (int i = 0; i < cmd.resolvers.length; i++) { for (int i = 0; i < cmd.resolvers.length; i++) {
Parameter parameter = cmd.parameters[i]; Parameter parameter = cmd.parameters[i];
ContextResolver<?> resolver = cmd.resolvers[i]; //noinspection unchecked
ContextResolver<?, ?> resolver = cmd.resolvers[i];
if (parameter.getAnnotation(Optional.class) != null || parameter.getAnnotation(Default.class) != null) { if (parameter.getAnnotation(Optional.class) != null || parameter.getAnnotation(Default.class) != null) {
numRequired--; numRequired--;
} else if (resolver instanceof SenderAwareContextResolver) { } else if (resolver instanceof SenderAwareContextResolver) {
@@ -157,8 +156,8 @@ public class CommandExecutionContext {
return this.param; return this.param;
} }
public CommandSender getSender() { public CommandIssuer getIssuer() {
return this.sender; return this.issuer;
} }
public List<String> getArgs() { public List<String> getArgs() {
@@ -23,24 +23,30 @@
package co.aikar.commands; package co.aikar.commands;
import org.bukkit.plugin.Plugin; public interface CommandIssuer {
/**
/** * Gets the issuer in the platforms native object
* Aikar Command Framework * @param <T>
*/ * @return
public final class ACF { */
private ACF() {} <T> T getIssuer();
/** /**
* Creates a manager for your current supported platform. * Is this issue a player, or server/console sender
* @param plugin Bukkit Plugin * @return
* @return Command Manager
*/ */
public static CommandManager createManager(Plugin plugin) { boolean isPlayer();
try {
Class.forName("com.destroystokyo.paper.PaperConfig"); /**
return new PaperCommandManager(plugin); * Send the Command Issuer a message
} catch (ClassNotFoundException ignored) {} * @param message
return new BukkitCommandManager(plugin); */
} void sendMessage(String message);
/**
* Has permission node
* @param permission
* @return
*/
boolean hasPermission(String permission);
} }
@@ -25,7 +25,9 @@ package co.aikar.commands;
import co.aikar.timings.lib.TimingManager; import co.aikar.timings.lib.TimingManager;
import java.lang.reflect.Parameter;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
@@ -69,7 +71,10 @@ public abstract class CommandManager {
public abstract TimingManager getTimings(); public abstract TimingManager getTimings();
public abstract RootCommand createRootCommand(String cmd);
public synchronized RootCommand obtainRootCommand(String cmd) { public synchronized RootCommand obtainRootCommand(String cmd) {
return rootCommands.computeIfAbsent(cmd.toLowerCase(), k -> new RootCommand(cmd)); return rootCommands.computeIfAbsent(cmd.toLowerCase(), this::createRootCommand);
} }
public abstract CommandExecutionContext<? extends CommandExecutionContext> createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs);
} }
@@ -23,30 +23,27 @@
package co.aikar.commands; package co.aikar.commands;
import org.apache.commons.lang.ArrayUtils; import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.List; import java.util.List;
public class ForwardingCommand extends BaseCommand { public class ForwardingCommand extends BaseCommand {
private final BaseCommand command; private final BaseCommand command;
private final String[] baseArgs; private final String[] baseArgs;
private static final String[] NO_ARGS = new String[0];
ForwardingCommand(BaseCommand command, String[] baseArgs) { ForwardingCommand(BaseCommand command, String[] baseArgs) {
super(command.getName()); this.commandName = command.commandName;
this.command = command; this.command = command;
this.baseArgs = baseArgs; this.baseArgs = baseArgs;
} }
@Override @Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { public List<String> tabComplete(CommandIssuer sender, String alias, String[] args) throws IllegalArgumentException {
return command.tabComplete(sender, alias, (String[]) ArrayUtils.addAll(baseArgs, args)); return command.tabComplete(sender, alias, ApacheCommonsLangUtil.addAll(baseArgs, args));
} }
@Override @Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) { public boolean execute(CommandIssuer sender, String commandLabel, String[] args) {
return command.execute(sender, commandLabel, (String[]) ArrayUtils.addAll(baseArgs, args)); return command.execute(sender, commandLabel, ApacheCommonsLangUtil.addAll(baseArgs, args));
} }
} }
@@ -36,8 +36,6 @@ import co.aikar.timings.lib.MCTiming;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@@ -55,7 +53,7 @@ public class RegisteredCommand {
private final Method method; private final Method method;
final String prefSubCommand; final String prefSubCommand;
final Parameter[] parameters; final Parameter[] parameters;
final ContextResolver<?>[] resolvers; final ContextResolver<?, ?>[] resolvers;
final String syntaxText; final String syntaxText;
private final String permission; private final String permission;
@@ -90,11 +88,11 @@ public class RegisteredCommand {
final Parameter parameter = parameters[i]; final Parameter parameter = parameters[i];
final Class<?> type = parameter.getType(); final Class<?> type = parameter.getType();
final ContextResolver<?> resolver = commandContexts.getResolver(type); final ContextResolver<?, ?> resolver = commandContexts.getResolver(type);
if (resolver != null) { if (resolver != null) {
resolvers[i] = resolver; resolvers[i] = resolver;
if (!CommandSender.class.isAssignableFrom(parameter.getType())) { if (!CommandIssuer.class.isAssignableFrom(parameter.getType())) {
if (isOptionalResolver(resolver, parameter)) { if (isOptionalResolver(resolver, parameter)) {
optionalResolvers++; optionalResolvers++;
syntaxB.append('[').append(parameter.getName()).append("] "); syntaxB.append('[').append(parameter.getName()).append("] ");
@@ -118,13 +116,13 @@ public class RegisteredCommand {
this.optionalResolvers = optionalResolvers; this.optionalResolvers = optionalResolvers;
} }
static boolean isOptionalResolver(ContextResolver<?> resolver, Parameter parameter) { static boolean isOptionalResolver(ContextResolver<?, ?> resolver, Parameter parameter) {
return resolver instanceof SenderAwareContextResolver return resolver instanceof SenderAwareContextResolver
|| parameter.getAnnotation(Optional.class) != null || parameter.getAnnotation(Optional.class) != null
|| parameter.getAnnotation(Default.class) != null; || parameter.getAnnotation(Default.class) != null;
} }
void invoke(CommandSender sender, List<String> args) { void invoke(CommandIssuer sender, List<String> args) {
if (!scope.canExecute(sender, this)) { if (!scope.canExecute(sender, this)) {
return; return;
} }
@@ -138,29 +136,29 @@ public class RegisteredCommand {
} }
} }
void handleException(CommandSender sender, List<String> args, Exception e) { void handleException(CommandIssuer sender, List<String> args, Exception e) {
if (e instanceof InvocationTargetException && e.getCause() instanceof InvalidCommandArgument) { if (e instanceof InvocationTargetException && e.getCause() instanceof InvalidCommandArgument) {
e = (Exception) e.getCause(); e = (Exception) e.getCause();
} }
if (e instanceof InvalidCommandArgument) { if (e instanceof InvalidCommandArgument) {
if (e.getMessage() != null && !e.getMessage().isEmpty()) { if (e.getMessage() != null && !e.getMessage().isEmpty()) {
ACFUtil.sendMsg(sender, "&cError: " + e.getMessage()); sender.sendMessage("&cError: " + e.getMessage());
} }
if (((InvalidCommandArgument) e).showSyntax) { if (((InvalidCommandArgument) e).showSyntax) {
scope.showSyntax(sender, this); scope.showSyntax(sender, this);
} }
} else { } else {
ACFUtil.sendMsg(sender, "&cI'm sorry, but there was an error performing this command."); sender.sendMessage("&cI'm sorry, but there was an error performing this command.");
ACFLog.exception("Exception in command: " + command + " " + ACFUtil.join(args), e); ACFLog.exception("Exception in command: " + command + " " + ACFUtil.join(args), e);
} }
} }
@Nullable @Nullable
Map<String, Object> resolveContexts(CommandSender sender, List<String> args) throws InvalidCommandArgument { Map<String, Object> resolveContexts(CommandIssuer sender, List<String> args) throws InvalidCommandArgument {
return resolveContexts(sender, args, parameters.length); return resolveContexts(sender, args, parameters.length);
} }
@Nullable @Nullable
Map<String, Object> resolveContexts(CommandSender sender, List<String> args, int argLimit) throws InvalidCommandArgument { Map<String, Object> resolveContexts(CommandIssuer sender, List<String> args, int argLimit) throws InvalidCommandArgument {
args = Lists.newArrayList(args); args = Lists.newArrayList(args);
String[] origArgs = args.toArray(new String[args.size()]); String[] origArgs = args.toArray(new String[args.size()]);
Map<String, Object> passedArgs = Maps.newLinkedHashMap(); Map<String, Object> passedArgs = Maps.newLinkedHashMap();
@@ -171,8 +169,8 @@ public class RegisteredCommand {
final Parameter parameter = parameters[i]; final Parameter parameter = parameters[i];
final String parameterName = parameter.getName(); final String parameterName = parameter.getName();
final Class<?> type = parameter.getType(); final Class<?> type = parameter.getType();
final ContextResolver<?> resolver = resolvers[i]; final ContextResolver<?, ?> resolver = resolvers[i];
CommandExecutionContext context = new CommandExecutionContext(this, parameter, sender, args, i, passedArgs); CommandExecutionContext context = this.scope.manager.createCommandContext(this, parameter, sender, args, i, passedArgs);
if (!isOptionalResolver(resolver, parameter)) { if (!isOptionalResolver(resolver, parameter)) {
remainingRequired--; remainingRequired--;
} }
@@ -221,8 +219,8 @@ public class RegisteredCommand {
return this.timing; return this.timing;
} }
boolean hasPermission(CommandSender check) { boolean hasPermission(CommandIssuer check) {
return permission == null || !(check instanceof Player) || check.hasPermission(permission); return permission == null || !check.isPlayer() || check.hasPermission(permission);
} }
public String getPermission() { public String getPermission() {
@@ -23,77 +23,7 @@
package co.aikar.commands; package co.aikar.commands;
import org.apache.commons.lang.StringUtils; interface RootCommand {
import org.bukkit.command.Command; void addChild(BaseCommand command);
import org.bukkit.command.CommandSender; CommandManager getManager();
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class RootCommand extends Command {
private BaseCommand defCommand;
private Map<String, BaseCommand> subCommands = new HashMap<>();
private List<BaseCommand> children = new ArrayList<>();
boolean isRegistered = false;
RootCommand(String name) {
super(name);
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Set<String> completions = new HashSet<>();
this.children.forEach(child -> completions.addAll(child.tabComplete(sender, alias, args)));
return new ArrayList<>(completions);
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
for (int i = args.length; i >= 0; i--) {
String checkSub = StringUtils.join(args, " ", 0, i).toLowerCase();
BaseCommand subHandler = this.subCommands.get(checkSub);
if (subHandler != null) {
if (!subHandler.testPermission(sender)) {
return true;
}
subHandler.execute(sender, commandLabel, args);
return false;
}
}
if (!this.defCommand.testPermission(sender)) {
return true;
}
this.defCommand.execute(sender, commandLabel, args);
return false;
}
void addChild(BaseCommand command) {
if (this.defCommand == null || !command.subCommands.get("__default").isEmpty()) {
this.defCommand = command;
this.setDescription(command.getDescription());
this.setUsage(command.getUsage());
this.setAliases(command.getAliases());
this.setPermission(command.getPermission());
this.setPermissionMessage(command.getPermissionMessage());
}
command.subCommands.keySet().forEach(key -> {
if (key.equals(BaseCommand.DEFAULT) || key.equals(BaseCommand.UNKNOWN)) {
return;
}
BaseCommand regged = this.subCommands.get(key);
if (regged != null) {
ACFLog.severe("ACF Error: " + command.getLabel() + " registered subcommand " + key + " for root command " + getName() + " - but it is already defined in " + regged.getLabel());
ACFLog.severe("2 subcommands of the same prefix may not be spread over 2 different classes. Ignoring this.");
return;
}
this.subCommands.put(key, command);
});
this.children.add(command);
}
} }
@@ -27,6 +27,6 @@ import co.aikar.commands.CommandExecutionContext;
import co.aikar.commands.InvalidCommandArgument; import co.aikar.commands.InvalidCommandArgument;
@FunctionalInterface @FunctionalInterface
public interface ContextResolver <C> { public interface ContextResolver <C, T extends CommandExecutionContext> {
C getContext(CommandExecutionContext c) throws InvalidCommandArgument; C getContext(CommandExecutionContext<T> c) throws InvalidCommandArgument;
} }
@@ -23,4 +23,6 @@
package co.aikar.commands.contexts; package co.aikar.commands.contexts;
public interface SenderAwareContextResolver<C> extends ContextResolver <C> {} import co.aikar.commands.CommandExecutionContext;
public interface SenderAwareContextResolver<C, T extends CommandExecutionContext> extends ContextResolver <C, T> {}
+2 -1
View File
@@ -34,8 +34,9 @@
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.17" level="project" /> <orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.17" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.10-SNAPSHOT" level="project" /> <orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.10-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm-all:5.0.4" level="project" /> <orderEntry type="library" scope="PROVIDED" name="Maven: org.ow2.asm:asm-all:5.0.4" level="project" />
<orderEntry type="module" module-name="acf-bukkit" />
<orderEntry type="module" module-name="acf-core" /> <orderEntry type="module" module-name="acf-core" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
<orderEntry type="library" name="Maven: co.aikar:minecraft-timings:1.0.3" level="project" /> <orderEntry type="library" name="Maven: co.aikar:minecraft-timings:1.0.3" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
</component> </component>
</module> </module>
+4 -3
View File
@@ -32,12 +32,13 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>ACFExample</name> <name>ACF (Example)</name>
<description>Example / Test for ACF</description> <description>Example / Test for ACF</description>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<url>https://github.com/aikar/commands</url> <url>https://github.com/aikar/commands</url>
<build> <build>
@@ -110,8 +111,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>co.aikar</groupId> <groupId>co.aikar</groupId>
<artifactId>acf-core</artifactId> <artifactId>acf-bukkit</artifactId>
<version>0.4.0-SNAPSHOT</version> <version><!--VERSION-->0.5.0<!--VERSION--></version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>
@@ -23,7 +23,7 @@
package co.aikar.acfexample; package co.aikar.acfexample;
import co.aikar.commands.ACF; import co.aikar.commands.BukkitCommandManager;
import co.aikar.commands.CommandManager; import co.aikar.commands.CommandManager;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@@ -39,7 +39,7 @@ public final class ACFExample extends JavaPlugin {
} }
private void registerCommands() { private void registerCommands() {
commandManager = ACF.createManager(this); commandManager = new BukkitCommandManager(this);
commandManager.getCommandReplacements().addReplacements("test", "foobar", "%foo", "barbaz"); commandManager.getCommandReplacements().addReplacements("test", "foobar", "%foo", "barbaz");
commandManager.getCommandContexts().registerContext(SomeObject.class, SomeObject.getContextResolver()); commandManager.getCommandContexts().registerContext(SomeObject.class, SomeObject.getContextResolver());
commandManager.getCommandCompletions().registerCompletion("test", (sender, config, input, c) -> ( commandManager.getCommandCompletions().registerCompletion("test", (sender, config, input, c) -> (
@@ -27,14 +27,14 @@ import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias; import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion; import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Subcommand;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandIssuer;
@CommandAlias("acf") @CommandAlias("acf")
public class SomeCommand_ExtraSubs extends BaseCommand { public class SomeCommand_ExtraSubs extends BaseCommand {
@Subcommand("testsub test2") @Subcommand("testsub test2")
@CommandCompletion("Foo2") @CommandCompletion("Foo2")
public void onTestSub2(CommandSender sender, String hi) { public void onTestSub2(CommandIssuer sender, String hi) {
sender.sendMessage(hi); sender.sendMessage(hi);
} }
} }
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>BUKKIT</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="acf-core" />
<orderEntry type="library" name="Maven: co.aikar:minecraft-timings:1.0.3" level="project" />
<orderEntry type="module" module-name="acf-bukkit" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.bukkit:bukkit:1.12-pre2-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:21.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.18" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
</component>
</module>
+60
View File
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
~
~ Permission is hereby granted, free of charge, to any person obtaining
~ a copy of this software and associated documentation files (the
~ "Software"), to deal in the Software without restriction, including
~ without limitation the rights to use, copy, modify, merge, publish,
~ distribute, sublicense, and/or sell copies of the Software, and to
~ permit persons to whom the Software is furnished to do so, subject to
~ the following conditions:
~
~ The above copyright notice and this permission notice shall be
~ included in all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
~ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
~ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
~ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
~ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
~ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
~ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<parent>
<groupId>co.aikar</groupId>
<artifactId>acf-parent</artifactId>
<version><!--VERSION-->0.5.0<!--VERSION--></version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>acf-paper</artifactId>
<version><!--VERSION-->0.5.0<!--VERSION--></version>
<name>ACF (Paper)</name>
<dependencies>
<dependency>
<groupId>co.aikar</groupId>
<artifactId>acf-core</artifactId>
<version><!--VERSION-->0.5.0<!--VERSION--></version>
</dependency>
<dependency>
<groupId>co.aikar</groupId>
<artifactId>acf-bukkit</artifactId>
<version><!--VERSION-->0.5.0<!--VERSION--></version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.12-pre2-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
+106
View File
@@ -0,0 +1,106 @@
<!--
~ Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
~
~ Permission is hereby granted, free of charge, to any person obtaining
~ a copy of this software and associated documentation files (the
~ "Software"), to deal in the Software without restriction, including
~ without limitation the rights to use, copy, modify, merge, publish,
~ distribute, sublicense, and/or sell copies of the Software, and to
~ permit persons to whom the Software is furnished to do so, subject to
~ the following conditions:
~
~ The above copyright notice and this permission notice shall be
~ included in all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
~ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
~ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
~ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
~ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
~ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
~ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>co.aikar</groupId>
<artifactId>acf-parent</artifactId>
<version><!--VERSION-->0.5.0<!--VERSION--></version>
<packaging>pom</packaging>
<name>ACF (All)</name>
<url>https://acf.emc.gs</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<distributionManagement>
<repository>
<id>aikar</id>
<url>http://ci.emc.gs/nexus/content/repositories/aikar-release/</url>
</repository>
<snapshotRepository>
<id>aikar</id>
<url>http://ci.emc.gs/nexus/content/repositories/aikar-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>aikar</id>
<url>http://ci.emc.gs/nexus/content/groups/aikar/</url>
</repository>
</repositories>
<build>
<defaultGoal>clean install</defaultGoal>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<showDeprecation>false</showDeprecation>
<showWarnings>false</showWarnings>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
</dependency>
</dependencies>
<modules>
<module>core</module>
<module>bukkit</module>
<module>paper</module>
<!--module>bungee</module-->
<!--module>sponge</module-->
<module>example</module>
</modules>
</project>