package com.forgeessentials.remote.command;
import java.util.List;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.event.ClickEvent;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraftforge.permission.PermissionLevel;
import com.forgeessentials.api.UserIdent;
import com.forgeessentials.api.permissions.FEPermissions;
import com.forgeessentials.api.remote.RemoteSession;
import com.forgeessentials.commons.network.NetworkUtils;
import com.forgeessentials.commons.network.Packet7Remote;
import com.forgeessentials.core.commands.ForgeEssentialsCommandBase;
import com.forgeessentials.core.misc.TranslatedCommandException;
import com.forgeessentials.core.misc.Translator;
import com.forgeessentials.remote.ModuleRemote;
import com.forgeessentials.util.CommandParserArgs;
import com.forgeessentials.util.PlayerInfo;
import com.forgeessentials.util.output.ChatOutputHandler;
public class CommandRemote extends ForgeEssentialsCommandBase
{
@Override
public String getCommandName()
{
return "remote";
}
private static final String[] parseMainArgs = { "regen", "setkey", "kick", "start", "stop", "block", "qr" };
@Override
public void processCommand(ICommandSender sender, String[] vargs)
{
CommandParserArgs args = new CommandParserArgs(this, vargs, sender);
parse(args);
}
/**
* @param args
*/
public void parse(CommandParserArgs args)
{
if (args.isTabCompletion && args.size() == 1)
{
args.tabCompletion = ForgeEssentialsCommandBase.getListOfStringsMatchingLastWord(args.peek(), parseMainArgs);
return;
}
if (args.isEmpty())
{
if (!args.hasPlayer())
throw new TranslatedCommandException(FEPermissions.MSG_NO_CONSOLE_COMMAND);
showPasskey(args, args.ident);
}
else
{
String arg = args.remove();
switch (arg)
{
case "help":
{
args.confirm("/remote start: Start remote server (= enable)");
args.confirm("/remote stop: Stop remote server (= disable)");
args.confirm("/remote regen [player]: Generate new passkey");
args.confirm("/remote setkey <player> <key>: Set your own passkey");
args.confirm("/remote block <player>: Block player from remote, until he generates a new passkey");
args.confirm("/remote kick <player>: Kick player accessing remote right now");
return;
}
case "regen":
{
UserIdent ident = args.parsePlayer(false);
if (!ident.equals(args.ident))
args.checkPermission(ModuleRemote.PERM_CONTROL);
if (args.isTabCompletion)
return;
ModuleRemote.getInstance().setPasskey(ident, ModuleRemote.getInstance().generatePasskey());
args.confirm("Generated new passkey");
showPasskey(args, ident);
return;
}
case "setkey":
{
UserIdent ident = args.parsePlayer(false);
if (!ident.equals(args.ident))
args.checkPermission(ModuleRemote.PERM_CONTROL);
if (args.isEmpty())
throw new TranslatedCommandException(FEPermissions.MSG_NOT_ENOUGH_ARGUMENTS);
String key = args.remove();
if (args.isTabCompletion)
return;
ModuleRemote.getInstance().setPasskey(ident, key);
args.confirm(Translator.format("Passkey of %s changed to %s", ident.getUsernameOrUuid(), key));
showPasskey(args, ident);
return;
}
case "block":
{
UserIdent ident = args.parsePlayer(true);
if (!ident.hasUuid())
throw new TranslatedCommandException("Player %s not found", ident.getUsernameOrUuid());
args.checkPermission(ModuleRemote.PERM_CONTROL);
if (args.isTabCompletion)
return;
ModuleRemote.getInstance().setPasskey(ident, null);
args.confirm(Translator.format("User %s has been blocked from remote until he generates a new passkey", ident.getUsernameOrUuid()));
return;
}
case "kick":
{
UserIdent ident = args.parsePlayer(true);
if (!ident.hasUuid())
throw new TranslatedCommandException("Player %s not found", ident.getUsernameOrUuid());
args.checkPermission(ModuleRemote.PERM_CONTROL);
if (args.isTabCompletion)
return;
RemoteSession session = ModuleRemote.getInstance().getServer().getSession(ident);
if (session == null)
{
args.confirm(Translator.format("User %s is not logged in on remote", ident.getUsernameOrUuid()));
return;
}
session.close("kick", 0);
args.confirm(Translator.format("User %s has been kicked from remote", ident.getUsernameOrUuid()));
return;
}
case "start":
{
args.checkPermission(ModuleRemote.PERM_CONTROL);
if (args.isTabCompletion)
return;
if (ModuleRemote.getInstance().getServer() != null)
throw new TranslatedCommandException("Server already running on port " + ModuleRemote.getInstance().getPort());
ModuleRemote.getInstance().startServer();
if (ModuleRemote.getInstance().getServer() == null)
args.confirm("Error starting remote server");
else
args.confirm("Server started");
return;
}
case "stop":
{
args.checkPermission(ModuleRemote.PERM_CONTROL);
if (args.isTabCompletion)
return;
if (ModuleRemote.getInstance().getServer() == null)
throw new TranslatedCommandException("Server not running");
ModuleRemote.getInstance().stopServer();
args.confirm("Server stopped");
return;
}
case "qr":
{
UserIdent ident = args.parsePlayer(true);
if (!PlayerInfo.get(ident.getPlayerMP()).getHasFEClient())
{
showPasskey(args, args.ident);
}
else
{
String connectString = ModuleRemote.getInstance().getConnectString(ident);
String url = ("https://chart.googleapis.com/chart?cht=qr&chld=M|4&chs=547x547&chl=" + connectString).replaceAll("\\|", "%7C");
NetworkUtils.netHandler.sendTo(new Packet7Remote(url), ident.getPlayerMP());
}
return;
}
default:
throw new TranslatedCommandException("Unknown subcommand " + arg);
}
}
}
/**
* @param sender
* @param args
* @param ident
*/
public void showPasskey(CommandParserArgs args, UserIdent ident)
{
String connectString = ModuleRemote.getInstance().getConnectString(ident);
String url = ("https://chart.googleapis.com/chart?cht=qr&chld=M|4&chs=547x547&chl=" + connectString).replaceAll("\\|", "%7C");
ChatComponentTranslation msg = new ChatComponentTranslation("Remote passkey = " + ModuleRemote.getInstance().getPasskey(ident) + " ");
IChatComponent qrLink = new ChatComponentText("[QR code]");
if (ident.hasUuid() && PlayerInfo.get(ident.getUuid()).getHasFEClient())
qrLink.getChatStyle().setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/remote qr"));
else
qrLink.getChatStyle().setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url));
qrLink.getChatStyle().setColor(EnumChatFormatting.RED);
qrLink.getChatStyle().setUnderlined(true);
msg.appendSibling(qrLink);
ChatOutputHandler.sendMessage(args.sender, msg);
ChatOutputHandler.sendMessage(args.sender, new ChatComponentText("Port = " + ModuleRemote.getInstance().getPort()));
}
@Override
public List<String> addTabCompletionOptions(ICommandSender sender, String[] vargs)
{
try
{
CommandParserArgs args = new CommandParserArgs(this, vargs, sender, true);
parse(args);
return args.tabCompletion;
}
catch (CommandException e)
{
return null;
}
}
@Override
public String getPermissionNode()
{
return ModuleRemote.PERM;
}
@Override
public boolean canConsoleUseCommand()
{
return true;
}
@Override
public String getCommandUsage(ICommandSender sender)
{
return "/remoteqr: Prints a link remote access QR code";
}
@Override
public PermissionLevel getPermissionLevel()
{
return PermissionLevel.TRUE;
}
}