001/* 002 * Copyright 2021 Siroshun09 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.github.siroshun09.mccommand.bungee; 018 019 020import com.github.siroshun09.mccommand.bungee.sender.BungeeSender; 021import com.github.siroshun09.mccommand.common.Command; 022import com.github.siroshun09.mccommand.common.context.CommandContext; 023import com.github.siroshun09.mccommand.common.context.SimpleCommandContext; 024import net.kyori.adventure.platform.bungeecord.BungeeAudiences; 025import net.md_5.bungee.api.CommandSender; 026import net.md_5.bungee.api.ProxyServer; 027import net.md_5.bungee.api.plugin.Plugin; 028import net.md_5.bungee.api.plugin.TabExecutor; 029import org.jetbrains.annotations.NotNull; 030 031import java.util.concurrent.Executor; 032import java.util.concurrent.Executors; 033 034/** 035 * The class for registering commands to BungeeCord. 036 */ 037public final class BungeeCommandFactory { 038 039 private BungeeCommandFactory() { 040 throw new UnsupportedOperationException(); 041 } 042 043 /** 044 * Registers the command. 045 * 046 * @param plugin the BungeeCord plugin 047 * @param command the command to register 048 */ 049 public static void register(@NotNull Plugin plugin, @NotNull Command command) { 050 ProxyServer.getInstance() 051 .getPluginManager() 052 .registerCommand( 053 plugin, 054 new BungeeCommandImpl(plugin, command) 055 ); 056 } 057 058 /** 059 * Registers the command. 060 * <p> 061 * If you register a command with this method, it will be executed asynchronously. 062 * <p> 063 * Note: 064 * <p> 065 * The tab completion will execute on main thread. 066 * 067 * @param plugin the BungeeCord plugin 068 * @param command the command to register 069 */ 070 public static void registerAsync(@NotNull Plugin plugin, @NotNull Command command) { 071 registerAsync(plugin, command, Executors.newSingleThreadExecutor()); 072 } 073 074 /** 075 * Registers the command. 076 * <p> 077 * If you register a command with this method, it will be executed asynchronously. 078 * <p> 079 * Note: 080 * <p> 081 * The tab completion will execute on main thread. 082 * 083 * @param plugin the BungeeCord plugin 084 * @param command the command to register 085 * @param executor the executor to run command 086 */ 087 public static void registerAsync(@NotNull Plugin plugin, @NotNull Command command, @NotNull Executor executor) { 088 ProxyServer.getInstance() 089 .getPluginManager() 090 .registerCommand( 091 plugin, 092 new AsyncBungeeCommandImpl(plugin, command, executor) 093 ); 094 } 095 096 private static class BungeeCommandImpl extends net.md_5.bungee.api.plugin.Command implements TabExecutor { 097 098 private final BungeeAudiences audiences; 099 private final Command command; 100 101 private BungeeCommandImpl(@NotNull Plugin plugin, @NotNull Command command) { 102 super(command.getName(), null, command.getAliases().toArray(new String[0])); 103 this.audiences = BungeeAudiences.create(plugin); 104 this.command = command; 105 } 106 107 @Override 108 public void execute(CommandSender sender, String[] args) { 109 command.onExecution( 110 createContext(sender, args) 111 ); 112 } 113 114 @Override 115 public Iterable<String> onTabComplete(CommandSender sender, String[] args) { 116 return command.onTabCompletion( 117 createContext(sender, args) 118 ); 119 } 120 121 private CommandContext createContext(CommandSender sender, String[] args) { 122 return SimpleCommandContext.newBuilder() 123 .setCommand(command) 124 .setSender(new BungeeSender(audiences, sender)) 125 .setArguments(args) 126 .setLabel(command.getName()) 127 .build(); 128 } 129 } 130 131 private static class AsyncBungeeCommandImpl extends net.md_5.bungee.api.plugin.Command implements TabExecutor { 132 133 private final BungeeAudiences audiences; 134 private final Command command; 135 private final Executor executor; 136 137 private AsyncBungeeCommandImpl(@NotNull Plugin plugin, @NotNull Command command, @NotNull Executor executor) { 138 super(command.getName(), null, command.getAliases().toArray(new String[0])); 139 this.audiences = BungeeAudiences.create(plugin); 140 this.command = command; 141 this.executor = executor; 142 } 143 144 @Override 145 public void execute(CommandSender sender, String[] args) { 146 executor.execute(() -> 147 command.onExecution( 148 createContext(sender, args) 149 ) 150 ); 151 } 152 153 @Override 154 public Iterable<String> onTabComplete(CommandSender sender, String[] args) { 155 return command.onTabCompletion( 156 createContext(sender, args) 157 ); 158 } 159 160 private CommandContext createContext(CommandSender sender, String[] args) { 161 return SimpleCommandContext.newBuilder() 162 .setCommand(command) 163 .setSender(new BungeeSender(audiences, sender)) 164 .setArguments(args) 165 .setLabel(command.getName()) 166 .build(); 167 } 168 } 169}