Added some things, needs testing

Supporting two block creations: using block looked at
Only allowing for OPs
Using a method to get all vanilla commands (with the prefix of "minecraft")
Updated readme
Running command from command block, not the player
This commit is contained in:
Norbi Peti 2018-02-19 00:46:09 +01:00
parent 448d8a8ce0
commit a009dd3730
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
7 changed files with 170 additions and 68 deletions

View file

@ -1,13 +1,26 @@
English / [Magyar](https://github.com/NorbiPeti/OneCommandHelper/blob/master/README_hu.md)
# OneCommandHelper
A plugin that allows one command creations to work on Spigot/Bukkit.
A plugin that allows one (or multiple) command creations to work on Spigot/Bukkit.
This is needed because the plugins installed on the server may have a command which replaces a vanilla command, and the plugin's version may not work the same way.
Let's take /kill as an example.
Essentials has a /kill command, so if you use that plugin, it takes over, so every time you run /kill, it runs that one.
However, that command doesn't know about selectors, so something like `/kill @a[r=1]` wouldn't work with it.
But, there is a syntax in Bukkit, `/plugin:command`, which allows running a specific plugin's command - or Minecraft's.
So simply running `/minecraft:kill` deals with the issue.
But this isn't typically done in one command creations, it'd greatly limit the command length anyways.
So, this plugin does it.
## Installation
Put the downloaded ([see Releases at top or click here](https://github.com/NorbiPeti/OneCommandHelper/releases)) JAR file into the server's plugin directory. No configuration needed.
## Usage
Paste the command into a command block, but *do not power it*. Instead, stand on it, and run /occ in the chat.
Paste the command into a command block, but *do not power it*. Instead, look at it, and run /occ in the chat.
In case of multiple commands, look at the one the command's creator said to activate.
## Video
[![Video](http://img.youtube.com/vi/rfPeuj0NWVg/0.jpg)](http://www.youtube.com/watch?v=rfPeuj0NWVg)

View file

@ -1,13 +1,26 @@
[English](https://github.com/NorbiPeti/OneCommandHelper/blob/master/README.md) / Magyar
# OneCommandHelper
Egy plugin, ami működőképessé teszi az egy parancsos alkotásokat Spigot/Bukkit szervereken.
Egy plugin, ami működőképessé teszi az egy (vagy több) parancsos alkotásokat Spigot/Bukkit szervereken.
Erre azért van szükség, mert a szerverekre telepített pluginoknak lehet olyan parancsuk, ami lecserél egy beépített parancsot.
Vegyül például a /kill parancsot.
Az Essentialsnak van /kill parancsa, ezért ha használod azt a plugint, minden alkalommal, amikor lefuttatod a /kill prancsot, azt futtatja le.
Ugyanakkor az a parancs nem ismeri a szelektorokat, ezért pl. a `/kill @a[r=1]` parancs nem működne vele.
De van egy szintaxis a Bukkitban, `/plugin:parancs`, ami lehetővé teszi egy bizonyos plugin - vagy a Minecraft - parancsának a futtatását.
Így egyszerűen a `/minecraft:kill` futtatása megoldja a problémát.
De ezt általában nem teszik meg az egy parancsos alkotásookban, nagy mértékben korlátozná a parancs hosszúságát egyébként is.
Úgyhogy ez a plugin megcsinálja.
## Telepítés
Rakd a letöltött ([lásd Releases felül vagy kattints ide](https://github.com/NorbiPeti/OneCommandHelper/releases)) JAR fájlt a szerver plugins mappába. Konfiguráció nem szükséges.
## Használat
Illeszd be a parancsot egy parancsblokkba, de *ne aktiváld*, helyette állj a parancsblokkra és írd be a /occ parancsot.
Illeszd be a parancsot egy parancsblokkba, de *ne aktiváld*, helyette nézz rá a parancsblokkra és írd be a /occ parancsot.
Több parancs esetében arra nézz, amelyiket aktiválni kell a parancs készítője szerint.
## Videó
[![Video](http://img.youtube.com/vi/rfPeuj0NWVg/0.jpg)](http://www.youtube.com/watch?v=rfPeuj0NWVg)

View file

@ -12,6 +12,7 @@
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
@ -22,7 +23,7 @@
<repositories>
<repository>
<id>spigot</id>
<id>spigot</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
@ -33,5 +34,10 @@
<artifactId>spigot-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>2.0.2-beta</version>
</dependency>
</dependencies>
</project>

View file

@ -1,5 +1,6 @@
package io.github.norbipeti.onecommandhelper;
import com.google.common.collect.Sets;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -9,59 +10,62 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.help.HelpTopic;
import org.bukkit.help.IndexHelpTopic;
public class Commands implements CommandExecutor
{
private final String[] replacecmds = { "achievement", "ban", "ban-ip",
"banlist", "blockdata", "clear", "clone", "debug",
"defaultgamemode", "deop", "difficulty", "effect", "enchant",
"entitydata", "execute", "fill", "gamemode", "gamerule", "give",
"help", "kick", "kill", "list", "me", "op", "pardon", "particle",
"playsound", "publish", "replaceitem", "save", "save-all",
"save-off", "save-on", "say", "scoreboard", "seed", "setblock",
"setidletimeout", "setworldspawn", "spawnpoint", "spreadplayers",
"stats", "stop", "stopsound", "summon", "teleport", "tell",
"tellraw", "testfor", "testforblock", "testforblocks", "time",
"title", "toggledownfall", "tp", "trigger", "weather", "whitelist",
"worldborder", "xp", "commands", "banip", "broadcast", "home",
"setspawn", "unban" };
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
@Override
public boolean onCommand(CommandSender sender, Command cmd, String alias,
String[] args)
{
StringBuilder acmdb = new StringBuilder("minecraft:execute "
+ sender.getName() + " ~ ~ ~ ");
if (sender != Bukkit.getConsoleSender()
&& !(sender instanceof BlockCommandSender))
{
Block block = ((Player) sender).getLocation().subtract(0, 1, 0)
.getBlock();
if (block.getType() != Material.COMMAND)
{
sender.sendMessage("§cError! Block underneath must be command block! Found "
+ block.getType());
return true;
}
CommandBlock cmdblock = (CommandBlock) block.getState();
acmdb.append(cmdblock.getCommand());
} else
{
if (args.length == 0)
{
sender.sendMessage("§cUsage: /" + alias + " <onecommand>");
return true; //Why use the builtin usage shoing thing
}
}
String acmd = acmdb.toString();
StringBuilder replace = new StringBuilder("(" + replacecmds[0]);
for (int i = 1; i < replacecmds.length; i++)
replace.append("|").append(replacecmds[i]);
replace.append(")");
acmd = acmd.replaceAll("([^t]|^)( |:| /|:/)" + replace + " ",
"$1$2minecraft:$3 ").replaceAll("\" (/*)minecraft:",
"\"$1minecraft:"); //Tellraw
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), acmd);
return true;
}
public class Commands implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String alias,
String[] args) {
if (!sender.isOp()) {
sender.sendMessage("§cYou need to be an OP to use this command.");
return true;
}
StringBuilder acmdb = new StringBuilder("minecraft:execute ");
acmdb.append(sender.getName()).append(" ");
if (sender instanceof Player) {
Block block = ((Player) sender).getTargetBlock(null, 10);
if (block == null) {
sender.sendMessage("§cYou need to look at the command block you want to activate. Make sure you're within 10 blocks of it.");
return true;
}
if (block.getType() != Material.COMMAND) {
sender.sendMessage("§cError! You need to look at a command block. Found "
+ block.getType());
return true;
}
CommandBlock cmdblock = (CommandBlock) block.getState();
acmdb.append(block.getX()).append(" ").append(block.getY()).append(" ").append(block.getZ()).append(" ");
acmdb.append(cmdblock.getCommand());
} else {
sender.sendMessage("§cYou need to be a player and look at the command block where you have the command you need to run.");
return true;
}
String acmd = acmdb.toString();
IndexHelpTopic iht = (IndexHelpTopic) Bukkit.getHelpMap().getHelpTopic("Minecraft");
String[] replacecmds;
try { //Get Minecraft (vanilla) commands
Field f = iht.getClass().getDeclaredField("allTopics");
f.setAccessible(true);
replacecmds = ((Collection<HelpTopic>) f.get(iht)).stream().map(ht -> ht.getName().substring(1)).toArray(String[]::new);
System.out.println(Arrays.toString(replacecmds)); //TODO: Fallback method
} catch (Exception e) {
sender.sendMessage("§cAn error occured while getting commands!");
e.printStackTrace();
return true;
}
StringBuilder replace = new StringBuilder("(").append(replacecmds[0]);
for (int i = 1; i < replacecmds.length; i++)
replace.append("|").append(replacecmds[i]);
replace.append(")");
acmd = acmd.replaceAll("([^t]|^)( |:| /|:/)" + replace + " ",
"$1$2minecraft:$3 ").replaceAll("\" (/*)minecraft:",
"\"$1minecraft:"); //Tellraw
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), acmd);
return true;
}
}

View file

@ -2,10 +2,9 @@ package io.github.norbipeti.onecommandhelper;
import org.bukkit.plugin.java.JavaPlugin;
public class PluginMain extends JavaPlugin
{
@Override
public void onEnable() {
getCommand("occ").setExecutor(new Commands());
}
public class PluginMain extends JavaPlugin {
@Override
public void onEnable() {
getCommand("occ").setExecutor(new Commands());
}
}

View file

@ -1,5 +1,5 @@
name: OneCommandHelper
main: io.github.norbipeti.onecommandhelper.PluginMain
version: 1.0
commands:
name: OneCommandHelper
main: io.github.norbipeti.onecommandhelper.PluginMain
version: 1.0
commands:
occ:

View file

@ -0,0 +1,67 @@
import io.github.norbipeti.onecommandhelper.Commands;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Player;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.logging.Logger;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
public class CommandTestTest { //Nope. See below.
@Test
public void test() {
Bukkit.setServer(Mockito.mock(Server.class, new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
if (is(invocationOnMock, String.class))
return "test";
if (is(invocationOnMock, Logger.class))
return Logger.getLogger("Test");
if (invocationOnMock.getMethod().getName().equals("sendMessage")) {
System.out.println(Arrays.toString(invocationOnMock.getArguments()));
return null;
}
if (!Modifier.isAbstract(invocationOnMock.getMethod().getModifiers()))
return invocationOnMock.callRealMethod();
return null;
}
}));
Commands cmds = new Commands();
cmds.onCommand(Mockito.mock(Player.class, new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
if (is(invocationOnMock, boolean.class))
return true;
if (is(invocationOnMock, Block.class))
return Mockito.mock(Block.class, new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
if (is(invocationOnMock, Material.class))
return Material.COMMAND;
if (is(invocationOnMock, BlockState.class))
return Mockito.mock(CommandBlock.class);
return null; //Nope. The help topics would need to be added too.
}
});
System.out.println(invocationOnMock.getMethod().getName());
System.out.println(Arrays.toString(invocationOnMock.getArguments()));
return null;
}
}), null, "occ", new String[]{});
}
private <T> boolean is(InvocationOnMock invocationOnMock, Class<T> cl) {
return invocationOnMock.getMethod().getReturnType().isAssignableFrom(cl);
}
}