Merge pull request #56 from TBMCPlugins/dev
Components, components everywhere
This commit is contained in:
commit
4ee76a97bf
39 changed files with 1332 additions and 941 deletions
15
.editorconfig
Normal file
15
.editorconfig
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[*]
|
||||||
|
charset=utf-8
|
||||||
|
end_of_line=lf
|
||||||
|
insert_final_newline=false
|
||||||
|
indent_style=space
|
||||||
|
indent_size=4
|
||||||
|
|
||||||
|
[*.java]
|
||||||
|
indent_style=tab
|
||||||
|
tab_width=4
|
||||||
|
|
||||||
|
[{*.yml,*.yaml}]
|
||||||
|
indent_style=space
|
||||||
|
indent_size=2
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="WeakerAccess" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="false" />
|
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="false" />
|
||||||
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
|
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
|
||||||
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
|
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="EntryPointsManager">
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
|
||||||
|
</list>
|
||||||
|
</component>
|
||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
<option name="originalFiles">
|
<option name="originalFiles">
|
||||||
<list>
|
<list>
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" filepath="$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" />
|
<module fileurl="file://$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" filepath="$PROJECT_DIR$/BuildConfigUpdater/BuildConfigUpdater.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" filepath="$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" />
|
<module fileurl="file://$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" filepath="$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" filepath="$PROJECT_DIR$/ButtonCore/ButtonCore (1) (com.github.TBMCPlugins.ButtonCore).iml" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" filepath="$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" />
|
<module fileurl="file://$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" filepath="$PROJECT_DIR$/ButtonProcessor/ButtonProcessor.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -1,175 +1,231 @@
|
||||||
package buttondevteam.lib.chat;
|
package buttondevteam.component.channel;
|
||||||
|
|
||||||
import buttondevteam.core.MainPlugin;
|
import buttondevteam.core.ComponentManager;
|
||||||
import org.bukkit.Bukkit;
|
import buttondevteam.core.MainPlugin;
|
||||||
import org.bukkit.command.CommandSender;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import org.bukkit.entity.Player;
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
|
import buttondevteam.lib.chat.Color;
|
||||||
import javax.annotation.Nullable;
|
import com.google.common.collect.Lists;
|
||||||
import java.util.ArrayList;
|
import org.bukkit.Bukkit;
|
||||||
import java.util.List;
|
import org.bukkit.command.CommandSender;
|
||||||
import java.util.function.BiFunction;
|
import org.bukkit.entity.Player;
|
||||||
import java.util.function.BiPredicate;
|
|
||||||
import java.util.function.Function;
|
import javax.annotation.Nullable;
|
||||||
import java.util.function.Predicate;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
public class Channel {
|
import java.util.List;
|
||||||
/**
|
import java.util.function.BiFunction;
|
||||||
* Specifies a score that means it's OK to send - but it does not define any groups, only send or not send. See {@link #GROUP_EVERYONE}
|
import java.util.function.BiPredicate;
|
||||||
*/
|
import java.util.function.Function;
|
||||||
public static final int SCORE_SEND_OK = 0;
|
import java.util.function.Predicate;
|
||||||
/**
|
import java.util.stream.Stream;
|
||||||
* Specifies a score that means the user doesn't have permission to see or send the message. Any negative value has the same effect.
|
|
||||||
*/
|
public class Channel {
|
||||||
public static final int SCORE_SEND_NOPE = -1;
|
/**
|
||||||
/**
|
* Specifies a score that means it's OK to send - but it does not define any groups, only send or not send. See {@link #GROUP_EVERYONE}
|
||||||
* Send the message to everyone <i>who has access to the channel</i> - this does not necessarily mean all players
|
*/
|
||||||
*/
|
public static final int SCORE_SEND_OK = 0;
|
||||||
public static final String GROUP_EVERYONE = "everyone";
|
/**
|
||||||
public final String DisplayName;
|
* Specifies a score that means the user doesn't have permission to see or send the message. Any negative value has the same effect.
|
||||||
public final Color color;
|
*/
|
||||||
public final String ID;
|
public static final int SCORE_SEND_NOPE = -1;
|
||||||
@Nullable
|
/**
|
||||||
public String[] IDs;
|
* Send the message to everyone <i>who has access to the channel</i> - this does not necessarily mean all players
|
||||||
/**
|
*/
|
||||||
* Filters both the sender and the targets
|
public static final String GROUP_EVERYONE = "everyone";
|
||||||
*/
|
|
||||||
private final Function<CommandSender, RecipientTestResult> filteranderrormsg;
|
private static ChannelComponent component;
|
||||||
|
|
||||||
private static final List<Channel> channels = new ArrayList<>();
|
private String defDisplayName;
|
||||||
|
private Color defColor;
|
||||||
/**
|
|
||||||
* Creates a channel.
|
private void throwGame() {
|
||||||
*
|
if (component == null) throw new RuntimeException("Cannot access channel properties until registered!");
|
||||||
* @param displayname The name that should appear at the start of the message. <b>A chat color is expected at the beginning (§9).</b>
|
}
|
||||||
* @param color The default color of the messages sent in the channel
|
|
||||||
* @param command The command to be used for the channel <i>without /</i>. For example "mod". It's also used for scoreboard objective names.
|
public final ConfigData<Boolean> Enabled() {
|
||||||
* @param filteranderrormsg Checks all senders against the criteria provided here and sends the message if the index matches the sender's - if no score at all, displays the error.<br>
|
throwGame();
|
||||||
* May be null to send to everyone.
|
return component.getConfig().getData(ID + ".enabled", true);
|
||||||
*/
|
}
|
||||||
public Channel(String displayname, Color color, String command,
|
|
||||||
Function<CommandSender, RecipientTestResult> filteranderrormsg) {
|
/**
|
||||||
DisplayName = displayname;
|
* Must start with a color code
|
||||||
this.color = color;
|
*/
|
||||||
ID = command;
|
public final ConfigData<String> DisplayName() {
|
||||||
this.filteranderrormsg = filteranderrormsg;
|
throwGame();
|
||||||
}
|
return component.getConfig().getData(ID + ".displayName", defDisplayName);
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Must be only called from a subclass - otherwise it'll throw an exception.
|
public final ConfigData<Color> Color() {
|
||||||
*
|
throwGame();
|
||||||
* @see Channel#Channel(String, Color, String, Function)
|
return component.getConfig().getData(ID + ".color", defColor, c -> Color.valueOf((String) c), Enum::toString);
|
||||||
*/
|
}
|
||||||
@SuppressWarnings("unchecked")
|
public final String ID;
|
||||||
protected <T extends Channel> Channel(String displayname, Color color, String command,
|
|
||||||
BiFunction<T, CommandSender, RecipientTestResult> filteranderrormsg) {
|
@SuppressWarnings("unchecked")
|
||||||
DisplayName = displayname;
|
public ConfigData<String[]> IDs() {
|
||||||
this.color = color;
|
throwGame();
|
||||||
ID = command;
|
return component.getConfig().getData(ID + ".IDs", new String[0], l -> ((List<String>) l).toArray(new String[0]), Lists::newArrayList);
|
||||||
this.filteranderrormsg = s -> filteranderrormsg.apply((T) this, s);
|
}
|
||||||
}
|
/**
|
||||||
|
* Filters both the sender and the targets
|
||||||
public boolean isGlobal() {
|
*/
|
||||||
return filteranderrormsg == null;
|
private final Function<CommandSender, RecipientTestResult> filteranderrormsg;
|
||||||
}
|
|
||||||
|
private static final List<Channel> channels = new ArrayList<>();
|
||||||
/**
|
|
||||||
* Note: Errors are sent to the sender automatically
|
/**
|
||||||
*
|
* Creates a channel.
|
||||||
* @param sender The user we're sending to
|
*
|
||||||
* @param score The (source) score to compare with the user's
|
* @param displayname The name that should appear at the start of the message. <b>A chat color is expected at the beginning (§9).</b>
|
||||||
*/
|
* @param color The default color of the messages sent in the channel
|
||||||
public boolean shouldSendTo(CommandSender sender, int score) {
|
* @param command The command to be used for the channel <i>without /</i>. For example "mod". It's also used for scoreboard objective names.
|
||||||
return score == getMCScore(sender); //If there's any error, the score won't be equal
|
* @param filteranderrormsg Checks all senders against the criteria provided here and sends the message if the index matches the sender's - if no score at all, displays the error.<br>
|
||||||
}
|
* May be null to send to everyone.
|
||||||
|
*/
|
||||||
/**
|
public Channel(String displayname, Color color, String command,
|
||||||
* Note: Errors are sent to the sender automatically
|
Function<CommandSender, RecipientTestResult> filteranderrormsg) {
|
||||||
*/
|
defDisplayName = displayname;
|
||||||
public int getMCScore(CommandSender sender) {
|
defColor = color;
|
||||||
return getRTR(sender).score; //No need to check if there was an error
|
ID = command;
|
||||||
}
|
this.filteranderrormsg = filteranderrormsg;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Note: Errors are sent to the sender automatically<br>
|
/**
|
||||||
* <p>
|
* Must be only called from a subclass - otherwise it'll throw an exception.
|
||||||
* Null means don't send
|
*
|
||||||
*/
|
* @see Channel#Channel(String, Color, String, Function)
|
||||||
@Nullable
|
*/
|
||||||
public String getGroupID(CommandSender sender) {
|
@SuppressWarnings("unchecked")
|
||||||
return getRTR(sender).groupID; //No need to check if there was an error
|
protected <T extends Channel> Channel(String displayname, Color color, String command,
|
||||||
}
|
BiFunction<T, CommandSender, RecipientTestResult> filteranderrormsg) {
|
||||||
|
defDisplayName = displayname;
|
||||||
public RecipientTestResult getRTR(CommandSender sender) {
|
defColor = color;
|
||||||
if (filteranderrormsg == null)
|
ID = command;
|
||||||
return new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE);
|
this.filteranderrormsg = s -> filteranderrormsg.apply((T) this, s);
|
||||||
return filteranderrormsg.apply(sender);
|
}
|
||||||
}
|
|
||||||
|
public boolean isGlobal() {
|
||||||
public static List<Channel> getChannels() {
|
return filteranderrormsg == null;
|
||||||
return channels;
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* Note: Errors are sent to the sender automatically
|
||||||
* Convenience method for the function parameter of {@link #Channel(String, Color, String, Function)}. It checks if the sender is OP or optionally has the specified group. The error message is
|
*
|
||||||
* generated automatically.
|
* @param sender The user we're sending to
|
||||||
*
|
* @param score The (source) score to compare with the user's
|
||||||
* @param permgroup The group that can access the channel or <b>null</b> to only allow OPs.
|
*/
|
||||||
* @return If has access
|
public boolean shouldSendTo(CommandSender sender, int score) {
|
||||||
*/
|
return score == getMCScore(sender); //If there's any error, the score won't be equal
|
||||||
public static Function<CommandSender, RecipientTestResult> inGroupFilter(String permgroup) {
|
}
|
||||||
return noScoreResult(
|
|
||||||
s -> s.isOp() || (permgroup != null && (s instanceof Player && MainPlugin.permission != null && MainPlugin.permission.playerInGroup((Player) s, permgroup))),
|
/**
|
||||||
"You need to be a(n) " + (permgroup != null ? permgroup : "OP") + " to use this channel.");
|
* Note: Errors are sent to the sender automatically
|
||||||
}
|
*/
|
||||||
|
public int getMCScore(CommandSender sender) {
|
||||||
public static Function<CommandSender, RecipientTestResult> noScoreResult(Predicate<CommandSender> filter,
|
return getRTR(sender).score; //No need to check if there was an error
|
||||||
String errormsg) {
|
}
|
||||||
return s -> filter.test(s) ? new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE) : new RecipientTestResult(errormsg);
|
|
||||||
}
|
/**
|
||||||
|
* Note: Errors are sent to the sender automatically<br>
|
||||||
public static <T extends Channel> BiFunction<T, CommandSender, RecipientTestResult> noScoreResult(
|
* <p>
|
||||||
BiPredicate<T, CommandSender> filter, String errormsg) {
|
* Null means don't send
|
||||||
return (this_, s) -> filter.test(this_, s) ? new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE) : new RecipientTestResult(errormsg);
|
*/
|
||||||
}
|
@Nullable
|
||||||
|
public String getGroupID(CommandSender sender) {
|
||||||
public static Channel GlobalChat;
|
return getRTR(sender).groupID; //No need to check if there was an error
|
||||||
public static Channel AdminChat;
|
}
|
||||||
public static Channel ModChat;
|
|
||||||
|
public RecipientTestResult getRTR(CommandSender sender) {
|
||||||
static void RegisterChannel(Channel channel) {
|
if (filteranderrormsg == null)
|
||||||
channels.add(channel);
|
return new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE);
|
||||||
Bukkit.getScheduler().runTask(MainPlugin.Instance, () -> Bukkit.getPluginManager().callEvent(new ChatChannelRegisterEvent(channel))); // Wait for server start
|
return filteranderrormsg.apply(sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RecipientTestResult {
|
/**
|
||||||
public final String errormessage;
|
* Get a stream of the enabled channels
|
||||||
public final int score; // Anything below 0 is "never send"
|
*
|
||||||
public final String groupID;
|
* @return Only the enabled channels
|
||||||
public static final RecipientTestResult ALL = new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE);
|
*/
|
||||||
|
public static Stream<Channel> getChannels() {
|
||||||
/**
|
return channels.stream().filter(ch -> ch.Enabled().get());
|
||||||
* Creates a result that indicates an <b>error</b>
|
}
|
||||||
*
|
|
||||||
* @param errormessage The error message to show the sender if they don't meet the criteria.
|
/**
|
||||||
*/
|
* Return all channels whether they're enabled or not
|
||||||
public RecipientTestResult(String errormessage) {
|
*
|
||||||
this.errormessage = errormessage;
|
* @return A list of all channels
|
||||||
this.score = SCORE_SEND_NOPE;
|
*/
|
||||||
this.groupID = null;
|
public static List<Channel> getChannelList() {
|
||||||
}
|
return Collections.unmodifiableList(channels);
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Creates a result that indicates a <b>success</b>
|
/**
|
||||||
*
|
* Convenience method for the function parameter of {@link #Channel(String, Color, String, Function)}. It checks if the sender is OP or optionally has the specified group. The error message is
|
||||||
* @param score The score that identifies the target group. <b>Must be non-negative.</b> For example, the index of the town or nation to send to.
|
* generated automatically.
|
||||||
* @param groupID The ID of the target group.
|
*
|
||||||
*/
|
* @param permgroup The group that can access the channel or <b>null</b> to only allow OPs.
|
||||||
public RecipientTestResult(int score, String groupID) {
|
* @return If has access
|
||||||
if (score < 0) throw new IllegalArgumentException("Score must be non-negative!");
|
*/
|
||||||
this.score = score;
|
public static Function<CommandSender, RecipientTestResult> inGroupFilter(String permgroup) {
|
||||||
this.groupID = groupID;
|
return noScoreResult(
|
||||||
this.errormessage = null;
|
s -> s.isOp() || (permgroup != null && (s instanceof Player && MainPlugin.permission != null && MainPlugin.permission.playerInGroup((Player) s, permgroup))),
|
||||||
}
|
"You need to be a(n) " + (permgroup != null ? permgroup : "OP") + " to use this channel.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static Function<CommandSender, RecipientTestResult> noScoreResult(Predicate<CommandSender> filter,
|
||||||
|
String errormsg) {
|
||||||
|
return s -> filter.test(s) ? new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE) : new RecipientTestResult(errormsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Channel> BiFunction<T, CommandSender, RecipientTestResult> noScoreResult(
|
||||||
|
BiPredicate<T, CommandSender> filter, String errormsg) {
|
||||||
|
return (this_, s) -> filter.test(this_, s) ? new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE) : new RecipientTestResult(errormsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Channel GlobalChat;
|
||||||
|
public static Channel AdminChat;
|
||||||
|
public static Channel ModChat;
|
||||||
|
|
||||||
|
public static void RegisterChannel(Channel channel) {
|
||||||
|
if (!channel.isGlobal() && !ComponentManager.isEnabled(ChannelComponent.class))
|
||||||
|
return; //Allow registering the global chat (and I guess other chats like the RP chat)
|
||||||
|
if (component == null)
|
||||||
|
component = (ChannelComponent) Component.getComponents().get(ChannelComponent.class);
|
||||||
|
if (component == null)
|
||||||
|
throw new RuntimeException("Attempting to register a channel before the component is registered!");
|
||||||
|
channels.add(channel);
|
||||||
|
Bukkit.getScheduler().runTask(MainPlugin.Instance, () -> Bukkit.getPluginManager().callEvent(new ChatChannelRegisterEvent(channel))); // Wait for server start
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RecipientTestResult {
|
||||||
|
public final String errormessage;
|
||||||
|
public final int score; // Anything below 0 is "never send"
|
||||||
|
public final String groupID;
|
||||||
|
public static final RecipientTestResult ALL = new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a result that indicates an <b>error</b>
|
||||||
|
*
|
||||||
|
* @param errormessage The error message to show the sender if they don't meet the criteria.
|
||||||
|
*/
|
||||||
|
public RecipientTestResult(String errormessage) {
|
||||||
|
this.errormessage = errormessage;
|
||||||
|
this.score = SCORE_SEND_NOPE;
|
||||||
|
this.groupID = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a result that indicates a <b>success</b>
|
||||||
|
*
|
||||||
|
* @param score The score that identifies the target group. <b>Must be non-negative.</b> For example, the index of the town or nation to send to.
|
||||||
|
* @param groupID The ID of the target group.
|
||||||
|
*/
|
||||||
|
public RecipientTestResult(int score, String groupID) {
|
||||||
|
if (score < 0) throw new IllegalArgumentException("Score must be non-negative!");
|
||||||
|
this.score = score;
|
||||||
|
this.groupID = groupID;
|
||||||
|
this.errormessage = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package buttondevteam.component.channel;
|
||||||
|
|
||||||
|
import buttondevteam.lib.architecture.Component;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
public class ChannelComponent extends Component {
|
||||||
|
@Override
|
||||||
|
protected void register(JavaPlugin plugin) {
|
||||||
|
super.register(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void unregister(JavaPlugin plugin) {
|
||||||
|
super.unregister(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void enable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void disable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package buttondevteam.lib.chat;
|
package buttondevteam.component.channel;
|
||||||
|
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
|
@ -1,5 +1,7 @@
|
||||||
package buttondevteam.lib.chat;
|
package buttondevteam.component.channel;
|
||||||
|
|
||||||
|
import buttondevteam.lib.chat.Color;
|
||||||
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
|
@ -1,15 +0,0 @@
|
||||||
package buttondevteam.component.commands;
|
|
||||||
|
|
||||||
import buttondevteam.lib.architecture.Component;
|
|
||||||
|
|
||||||
public class CommandComponent extends Component { //TODO: Do we just move everything here?
|
|
||||||
@Override
|
|
||||||
public void enable() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disable() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
package buttondevteam.core;
|
package buttondevteam.component.members;
|
||||||
|
|
||||||
|
import buttondevteam.core.MainPlugin;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||||
import lombok.val;
|
import lombok.val;
|
|
@ -0,0 +1,42 @@
|
||||||
|
package buttondevteam.component.members;
|
||||||
|
|
||||||
|
import buttondevteam.core.MainPlugin;
|
||||||
|
import buttondevteam.lib.architecture.Component;
|
||||||
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
|
import org.bukkit.Statistic;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static buttondevteam.core.MainPlugin.permission;
|
||||||
|
|
||||||
|
public class MemberComponent extends Component implements Listener {
|
||||||
|
private ConfigData<String> memberGroup() {
|
||||||
|
return getConfig().getData("memberGroup", "member");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void enable() {
|
||||||
|
registerListener(this);
|
||||||
|
registerCommand(new MemberCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void disable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
if (permission != null && !permission.playerInGroup(event.getPlayer(), memberGroup().get())
|
||||||
|
&& (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(7, ChronoUnit.DAYS).isBefore(Instant.now())
|
||||||
|
|| event.getPlayer().getStatistic(Statistic.PLAY_ONE_TICK) > 20 * 3600 * 12)) {
|
||||||
|
permission.playerAddGroup(null, event.getPlayer(), memberGroup().get());
|
||||||
|
event.getPlayer().sendMessage("§bYou are a member now. YEEHAW");
|
||||||
|
MainPlugin.Instance.getLogger().info("Added " + event.getPlayer().getName() + " as a member.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,15 @@
|
||||||
package buttondevteam.core;
|
package buttondevteam.component.randomtp;
|
||||||
|
|
||||||
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@CommandClass
|
@SuppressWarnings("FieldCanBeLocal")@CommandClass
|
||||||
public class RandomTP extends TBMCCommandBase
|
public class RandomTP extends TBMCCommandBase
|
||||||
{
|
{
|
||||||
private final int radius = 70; //set how far apart the five teleport positions are
|
private final int radius = 70; //set how far apart the five teleport positions are
|
||||||
|
@ -51,9 +51,9 @@ public class RandomTP extends TBMCCommandBase
|
||||||
|
|
||||||
/*================================================================================================*/
|
/*================================================================================================*/
|
||||||
|
|
||||||
public void onEnable(JavaPlugin plugin)
|
public void onEnable(Component component)
|
||||||
{
|
{
|
||||||
TBMCChatAPI.AddCommand(plugin, this);
|
TBMCChatAPI.AddCommand(component, this);
|
||||||
|
|
||||||
world = Bukkit.getWorld("World");
|
world = Bukkit.getWorld("World");
|
||||||
border = world.getWorldBorder();
|
border = world.getWorldBorder();
|
|
@ -0,0 +1,15 @@
|
||||||
|
package buttondevteam.component.randomtp;
|
||||||
|
|
||||||
|
import buttondevteam.lib.architecture.Component;
|
||||||
|
|
||||||
|
public class RandomTPComponent extends Component {
|
||||||
|
@Override
|
||||||
|
protected void enable() {
|
||||||
|
new RandomTP().onEnable(this); //It registers it's command
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void disable() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package buttondevteam.core;
|
package buttondevteam.component.restart;
|
||||||
|
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
import buttondevteam.lib.chat.TBMCCommandBase;
|
|
@ -1,20 +1,44 @@
|
||||||
package buttondevteam.component.restart;
|
package buttondevteam.component.restart;
|
||||||
|
|
||||||
import buttondevteam.core.PrimeRestartCommand;
|
|
||||||
import buttondevteam.core.ScheduledRestartCommand;
|
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
|
import buttondevteam.lib.chat.IFakePlayer;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
public class RestartComponent extends Component {
|
public class RestartComponent extends Component implements Listener {
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
//TODO: Permissions for the commands
|
//TODO: Permissions for the commands
|
||||||
TBMCChatAPI.AddCommand(getPlugin(), ScheduledRestartCommand.class);
|
TBMCChatAPI.AddCommand(this, new ScheduledRestartCommand());
|
||||||
TBMCChatAPI.AddCommand(getPlugin(), PrimeRestartCommand.class);
|
TBMCChatAPI.AddCommand(this, new PrimeRestartCommand());
|
||||||
|
registerListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable() {
|
public void disable() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long lasttime = 0;
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerLeave(PlayerQuitEvent event) {
|
||||||
|
if (PrimeRestartCommand.isPlsrestart()
|
||||||
|
&& !event.getQuitMessage().equalsIgnoreCase("Server closed")
|
||||||
|
&& !event.getQuitMessage().equalsIgnoreCase("Server is restarting")) {
|
||||||
|
if (Bukkit.getOnlinePlayers().size() <= 1) {
|
||||||
|
if (PrimeRestartCommand.isLoud())
|
||||||
|
Bukkit.broadcastMessage("§cNobody is online anymore. Restarting.");
|
||||||
|
Bukkit.spigot().restart();
|
||||||
|
} else if (!(event.getPlayer() instanceof IFakePlayer) && System.nanoTime() - 10 * 1000000000L - lasttime > 0) { //Ten seconds passed since last reminder
|
||||||
|
lasttime = System.nanoTime();
|
||||||
|
if (PrimeRestartCommand.isLoud())
|
||||||
|
Bukkit.broadcastMessage(ChatColor.DARK_RED + "The server will restart as soon as nobody is online.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package buttondevteam.core;
|
package buttondevteam.component.restart;
|
||||||
|
|
||||||
|
import buttondevteam.core.MainPlugin;
|
||||||
import buttondevteam.lib.ScheduledServerRestartEvent;
|
import buttondevteam.lib.ScheduledServerRestartEvent;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
import buttondevteam.lib.chat.TBMCCommandBase;
|
|
@ -0,0 +1,47 @@
|
||||||
|
package buttondevteam.component.towny;
|
||||||
|
|
||||||
|
import buttondevteam.core.ComponentManager;
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.architecture.Component;
|
||||||
|
import com.palmergames.bukkit.towny.Towny;
|
||||||
|
import com.palmergames.bukkit.towny.exceptions.AlreadyRegisteredException;
|
||||||
|
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
|
||||||
|
import com.palmergames.bukkit.towny.object.Resident;
|
||||||
|
import com.palmergames.bukkit.towny.object.TownyUniverse;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
public class TownyComponent extends Component {
|
||||||
|
@Override
|
||||||
|
protected void enable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void disable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only renames the resident if this component is enabled. Used to handle name changes.
|
||||||
|
*
|
||||||
|
* @param oldName The player's old name as known by us
|
||||||
|
* @param newName The player's new name
|
||||||
|
*/
|
||||||
|
public static void renameInTowny(String oldName, String newName) {
|
||||||
|
if (!ComponentManager.isEnabled(TownyComponent.class))
|
||||||
|
return; TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse();
|
||||||
|
Resident resident = tu.getResidentMap().get(oldName.toLowerCase()); //The map keys are lowercase
|
||||||
|
if (resident == null) {
|
||||||
|
Bukkit.getLogger().warning("Resident not found - couldn't rename in Towny.");
|
||||||
|
TBMCCoreAPI.sendDebugMessage("Resident not found - couldn't rename in Towny.");
|
||||||
|
} else if (tu.getResidentMap().contains(newName.toLowerCase())) {
|
||||||
|
Bukkit.getLogger().warning("Target resident name is already in use."); // TODO: Handle
|
||||||
|
TBMCCoreAPI.sendDebugMessage("Target resident name is already in use.");
|
||||||
|
} else
|
||||||
|
try {
|
||||||
|
TownyUniverse.getDataSource().renamePlayer(resident, newName); //Fixed in Towny 0.91.1.2
|
||||||
|
} catch (AlreadyRegisteredException e) {
|
||||||
|
TBMCCoreAPI.SendException("Failed to rename resident, there's already one with this name.", e);
|
||||||
|
} catch (NotRegisteredException e) {
|
||||||
|
TBMCCoreAPI.SendException("Failed to rename resident, the resident isn't registered.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,11 +6,11 @@ import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
public class PluginUpdaterComponent extends Component {
|
public class PluginUpdaterComponent extends Component {
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
TBMCChatAPI.AddCommand(getPlugin(), UpdatePluginCommand.class);
|
TBMCChatAPI.AddCommand(this, new UpdatePluginCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable() { //TODO: Unregister commands and such
|
public void disable() { //Commands are automatically unregistered
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,41 +21,27 @@ public class CommandCaller implements CommandExecutor {
|
||||||
public static void RegisterCommand(TBMCCommandBase cmd) throws Exception {
|
public static void RegisterCommand(TBMCCommandBase cmd) throws Exception {
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
instance = new CommandCaller();
|
instance = new CommandCaller();
|
||||||
String topcmd = cmd.GetCommandPath();
|
String[] topcmd = new String[1]; //Holds out param
|
||||||
if (topcmd == null)
|
PluginCommand pc = getPluginCommand(cmd, topcmd);
|
||||||
throw new Exception("Command " + cmd.getClass().getSimpleName() + " has no command path!");
|
pc.setExecutor(instance);
|
||||||
if (cmd.getPlugin() == null)
|
String[] helptext = cmd.GetHelpText(topcmd[0]);
|
||||||
throw new Exception("Command " + cmd.GetCommandPath() + " has no plugin!");
|
if (helptext == null || helptext.length == 0)
|
||||||
int i;
|
throw new Exception("Command " + cmd.GetCommandPath() + " has no help text!");
|
||||||
if ((i = topcmd.indexOf(' ')) != -1) // Get top-level command
|
pc.setUsage(helptext.length > 1 ? helptext[1] : helptext[0]);
|
||||||
topcmd = topcmd.substring(0, i);
|
|
||||||
{
|
|
||||||
PluginCommand pc = ((JavaPlugin) cmd.getPlugin()).getCommand(topcmd);
|
|
||||||
if (pc == null)
|
|
||||||
throw new Exception("Top level command " + topcmd + " not registered in plugin.yml for plugin: "
|
|
||||||
+ cmd.getPlugin().getName());
|
|
||||||
else {
|
|
||||||
pc.setExecutor(instance);
|
|
||||||
String[] helptext = cmd.GetHelpText(topcmd);
|
|
||||||
if (helptext == null || helptext.length == 0)
|
|
||||||
throw new Exception("Command " + cmd.GetCommandPath() + " has no help text!");
|
|
||||||
pc.setUsage(helptext.length > 1 ? helptext[1] : helptext[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
|
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
String path = command.getName().toLowerCase();
|
StringBuilder path = new StringBuilder(command.getName().toLowerCase());
|
||||||
for (String arg : args)
|
for (String arg : args)
|
||||||
path += " " + arg;
|
path.append(" ").append(arg);
|
||||||
TBMCCommandBase cmd = TBMCChatAPI.GetCommands().get(path);
|
TBMCCommandBase cmd = TBMCChatAPI.GetCommands().get(path.toString());
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
String[] subcmds = null;
|
String[] subcmds = null;
|
||||||
while (cmd == null && (subcmds = TBMCChatAPI.GetSubCommands(path, sender)).length == 0 && path.contains(" ")) {
|
while (cmd == null && (subcmds = TBMCChatAPI.GetSubCommands(path.toString(), sender)).length == 0 && path.toString().contains(" ")) {
|
||||||
path = path.substring(0, path.lastIndexOf(' '));
|
path = new StringBuilder(path.substring(0, path.toString().lastIndexOf(' ')));
|
||||||
argc++;
|
argc++;
|
||||||
cmd = TBMCChatAPI.GetCommands().get(path);
|
cmd = TBMCChatAPI.GetCommands().get(path.toString());
|
||||||
}
|
}
|
||||||
if (cmd == null) {
|
if (cmd == null) {
|
||||||
if (subcmds.length > 0) //Subcmds will always have value here (see assignment above)
|
if (subcmds.length > 0) //Subcmds will always have value here (see assignment above)
|
||||||
|
@ -85,4 +71,37 @@ public class CommandCaller implements CommandExecutor {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void UnregisterCommand(TBMCCommandBase cmd) throws Exception {
|
||||||
|
PluginCommand pc = getPluginCommand(cmd, null);
|
||||||
|
pc.setExecutor(null); //Sets the executor to this plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the plugin command from the TBMC command.
|
||||||
|
*
|
||||||
|
* @param cmd The TBMC command
|
||||||
|
* @param out_topcmd An array with at least 1 elements or null
|
||||||
|
* @return The Bukkit plugin command - an exception is generated if null
|
||||||
|
* @throws Exception If the command isn't set up properly (or a different error)
|
||||||
|
*/
|
||||||
|
public static PluginCommand getPluginCommand(TBMCCommandBase cmd, String[] out_topcmd) throws Exception {
|
||||||
|
String topcmd = cmd.GetCommandPath();
|
||||||
|
if (topcmd == null)
|
||||||
|
throw new Exception("Command " + cmd.getClass().getSimpleName() + " has no command path!");
|
||||||
|
if (cmd.getPlugin() == null)
|
||||||
|
throw new Exception("Command " + cmd.GetCommandPath() + " has no plugin!");
|
||||||
|
int i;
|
||||||
|
if ((i = topcmd.indexOf(' ')) != -1) // Get top-level command
|
||||||
|
topcmd = topcmd.substring(0, i);
|
||||||
|
if (out_topcmd != null && out_topcmd.length > 0)
|
||||||
|
out_topcmd[0] = topcmd;
|
||||||
|
{
|
||||||
|
PluginCommand pc = ((JavaPlugin) cmd.getPlugin()).getCommand(topcmd);
|
||||||
|
if (pc == null)
|
||||||
|
throw new Exception("Top level command " + topcmd + " not registered in plugin.yml for plugin: "
|
||||||
|
+ cmd.getPlugin().getName());
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,63 @@
|
||||||
package buttondevteam.core;
|
package buttondevteam.core;
|
||||||
|
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||||
|
import lombok.val;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@CommandClass(modOnly = true)
|
@CommandClass(modOnly = true)
|
||||||
public class ComponentCommand extends TBMCCommandBase {
|
public class ComponentCommand extends TBMCCommandBase {
|
||||||
@Override
|
@Override
|
||||||
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
||||||
if (args.length < 2)
|
if (args.length < 1)
|
||||||
return false;
|
return false;
|
||||||
switch (args[0]) {
|
boolean enable = true;
|
||||||
case "enable":
|
try {
|
||||||
break;
|
switch (args[0]) {
|
||||||
case "disable":
|
case "enable":
|
||||||
break;
|
enable = true;
|
||||||
case "list":
|
break;
|
||||||
break;
|
case "disable":
|
||||||
default:
|
enable = false;
|
||||||
|
break;
|
||||||
|
case "list":
|
||||||
|
sender.sendMessage("§6List of components:");
|
||||||
|
Component.getComponents().values().stream().map(c -> c.getPlugin().getName() + " - " + c.getClass().getSimpleName() + " - " + (c.isEnabled() ? "en" : "dis") + "abled").forEach(sender::sendMessage);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (args.length < 2)
|
||||||
return false;
|
return false;
|
||||||
|
val oc = getComponentOrError(args[1], sender);
|
||||||
|
if (!oc.isPresent())
|
||||||
|
return true;
|
||||||
|
if (enable) //Reload config so the new config values are read
|
||||||
|
getPlugin().reloadConfig(); //All changes are saved to disk on disable
|
||||||
|
Component.setComponentEnabled(oc.get(), enable);
|
||||||
|
sender.sendMessage(oc.get().getClass().getSimpleName() + " " + (enable ? "en" : "dis") + "abled.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("Couldn't " + (enable ? "en" : "dis") + "able component " + args[0] + "!", e);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<Component> getComponentOrError(String arg, CommandSender sender) {
|
||||||
|
val oc = Component.getComponents().values().stream().filter(c -> c.getClass().getSimpleName().equalsIgnoreCase(arg)).findAny();
|
||||||
|
if (!oc.isPresent())
|
||||||
|
sender.sendMessage("§cComponent not found!");
|
||||||
|
return oc;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] GetHelpText(String alias) {
|
public String[] GetHelpText(String alias) {
|
||||||
return new String[0];
|
return new String[]{
|
||||||
|
"§6---- Component command ----",
|
||||||
|
"Enable or disable or list components"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,117 +1,138 @@
|
||||||
package buttondevteam.core;
|
package buttondevteam.core;
|
||||||
|
|
||||||
import buttondevteam.component.restart.RestartComponent;
|
import buttondevteam.component.channel.Channel;
|
||||||
import buttondevteam.component.updater.PluginUpdater;
|
import buttondevteam.component.channel.ChannelComponent;
|
||||||
import buttondevteam.component.updater.PluginUpdaterComponent;
|
import buttondevteam.component.channel.ChatRoom;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.component.members.MemberComponent;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.component.randomtp.RandomTPComponent;
|
||||||
import buttondevteam.lib.chat.Channel;
|
import buttondevteam.component.restart.RestartComponent;
|
||||||
import buttondevteam.lib.chat.ChatRoom;
|
import buttondevteam.component.towny.TownyComponent;
|
||||||
import buttondevteam.lib.chat.Color;
|
import buttondevteam.component.updater.PluginUpdater;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.component.updater.PluginUpdaterComponent;
|
||||||
import buttondevteam.lib.player.ChromaGamerBase;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
import buttondevteam.lib.architecture.ButtonPlugin;
|
||||||
import buttondevteam.lib.player.TBMCPlayerBase;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import com.earth2me.essentials.Essentials;
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
import net.milkbowl.vault.permission.Permission;
|
import buttondevteam.lib.chat.Color;
|
||||||
import org.bukkit.Bukkit;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import org.bukkit.command.BlockCommandSender;
|
import buttondevteam.lib.player.ChromaGamerBase;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
import org.bukkit.entity.Player;
|
import buttondevteam.lib.player.TBMCPlayerBase;
|
||||||
import org.bukkit.plugin.PluginDescriptionFile;
|
import com.earth2me.essentials.Essentials;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import net.milkbowl.vault.permission.Permission;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.BlockCommandSender;
|
||||||
import javax.annotation.Nullable;
|
import org.bukkit.command.Command;
|
||||||
import java.io.File;
|
import org.bukkit.command.CommandSender;
|
||||||
import java.io.IOException;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import java.nio.file.Files;
|
import org.bukkit.entity.Player;
|
||||||
import java.nio.file.StandardCopyOption;
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
import java.util.Arrays;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
import javax.annotation.Nullable;
|
||||||
import java.util.logging.Logger;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
public class MainPlugin extends JavaPlugin {
|
import java.nio.file.Files;
|
||||||
public static MainPlugin Instance;
|
import java.nio.file.StandardCopyOption;
|
||||||
@Nullable
|
import java.util.Arrays;
|
||||||
public static Permission permission;
|
import java.util.Optional;
|
||||||
public static boolean Test;
|
import java.util.UUID;
|
||||||
public static Essentials ess;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
private Logger logger;
|
public class MainPlugin extends ButtonPlugin {
|
||||||
|
public static MainPlugin Instance;
|
||||||
@Override
|
@Nullable
|
||||||
public void onEnable() {
|
public static Permission permission;
|
||||||
// Logs "Plugin Enabled", registers commands
|
public static boolean Test;
|
||||||
Instance = this;
|
public static Essentials ess;
|
||||||
PluginDescriptionFile pdf = getDescription();
|
|
||||||
logger = getLogger();
|
private Logger logger;
|
||||||
setupPermissions();
|
|
||||||
Test = getConfig().getBoolean("test", true);
|
private ConfigData<Boolean> writePluginList() {
|
||||||
saveConfig();
|
return getIConfig().getData("writePluginList", false);
|
||||||
Component.registerComponent(this, new PluginUpdaterComponent());
|
}
|
||||||
Component.registerComponent(this, new RestartComponent());
|
|
||||||
ComponentManager.enableComponents();
|
@Override
|
||||||
TBMCChatAPI.AddCommand(this, MemberCommand.class);
|
public void pluginEnable() {
|
||||||
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
// Logs "Plugin Enabled", registers commands
|
||||||
ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender
|
Instance = this;
|
||||||
? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks
|
PluginDescriptionFile pdf = getDescription();
|
||||||
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof Player
|
logger = getLogger();
|
||||||
? TBMCPlayer.getPlayer(((Player) sender).getUniqueId(), TBMCPlayer.class) : null)); //Players, has higher priority
|
setupPermissions();
|
||||||
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class);
|
Test = getConfig().getBoolean("test", true);
|
||||||
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fOOC§f", Color.White, "ooc", null));
|
saveConfig();
|
||||||
Channel.GlobalChat.IDs = new String[]{"g"}; //Support /g as well
|
Component.registerComponent(this, new PluginUpdaterComponent());
|
||||||
TBMCChatAPI.RegisterChatChannel(
|
Component.registerComponent(this, new RestartComponent());
|
||||||
Channel.AdminChat = new Channel("§cADMIN§f", Color.Red, "a", Channel.inGroupFilter(null)));
|
Component.registerComponent(this, new ChannelComponent());
|
||||||
TBMCChatAPI.RegisterChatChannel(
|
Component.registerComponent(this, new RandomTPComponent());
|
||||||
Channel.ModChat = new Channel("§9MOD§f", Color.Blue, "mod", Channel.inGroupFilter("mod")));
|
Component.registerComponent(this, new MemberComponent());
|
||||||
TBMCChatAPI.RegisterChatChannel(new Channel("§6DEV§f", Color.Gold, "dev", Channel.inGroupFilter("developer")));
|
Component.registerComponent(this, new TownyComponent());
|
||||||
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§cRED§f", Color.DarkRed, "red"));
|
ComponentManager.enableComponents();
|
||||||
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§6ORANGE§f", Color.Gold, "orange"));
|
TBMCChatAPI.AddCommand(this, ComponentCommand.class);
|
||||||
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§eYELLOW§f", Color.Yellow, "yellow"));
|
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
||||||
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§aGREEN§f", Color.Green, "green"));
|
ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender
|
||||||
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§bBLUE§f", Color.Blue, "blue"));
|
? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks
|
||||||
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§5PURPLE§f", Color.DarkPurple, "purple"));
|
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof Player
|
||||||
try {
|
? TBMCPlayer.getPlayer(((Player) sender).getUniqueId(), TBMCPlayer.class) : null)); //Players, has higher priority
|
||||||
Files.write(new File("plugins", "plugins.txt").toPath(), Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(p -> (CharSequence) p.getDataFolder().getName())::iterator);
|
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class);
|
||||||
} catch (IOException e) {
|
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fOOC§f", Color.White, "g", null)); //The /ooc ID has moved to the config
|
||||||
TBMCCoreAPI.SendException("Failed to write plugin list!", e);
|
TBMCChatAPI.RegisterChatChannel(
|
||||||
}
|
Channel.AdminChat = new Channel("§cADMIN§f", Color.Red, "a", Channel.inGroupFilter(null)));
|
||||||
ess = Essentials.getPlugin(Essentials.class);
|
TBMCChatAPI.RegisterChatChannel(
|
||||||
new RandomTP().onEnable(this); //It registers it's command
|
Channel.ModChat = new Channel("§9MOD§f", Color.Blue, "mod", Channel.inGroupFilter("mod")));
|
||||||
logger.info(pdf.getName() + " has been Enabled (V." + pdf.getVersion() + ") Test: " + Test + ".");
|
TBMCChatAPI.RegisterChatChannel(new Channel("§6DEV§f", Color.Gold, "dev", Channel.inGroupFilter("developer")));
|
||||||
}
|
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§cRED§f", Color.DarkRed, "red"));
|
||||||
|
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§6ORANGE§f", Color.Gold, "orange"));
|
||||||
@Override
|
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§eYELLOW§f", Color.Yellow, "yellow"));
|
||||||
public void onDisable() {
|
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§aGREEN§f", Color.Green, "green"));
|
||||||
ComponentManager.disableComponents();
|
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§bBLUE§f", Color.Blue, "blue"));
|
||||||
logger.info("Saving player data...");
|
TBMCChatAPI.RegisterChatChannel(new ChatRoom("§5PURPLE§f", Color.DarkPurple, "purple"));
|
||||||
TBMCPlayerBase.savePlayers();
|
if (writePluginList().get()) {
|
||||||
logger.info("Player data saved.");
|
try {
|
||||||
new Thread(() -> {
|
Files.write(new File("plugins", "plugins.txt").toPath(), Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(p -> (CharSequence) p.getDataFolder().getName())::iterator);
|
||||||
File[] files = PluginUpdater.updatedir.listFiles();
|
} catch (IOException e) {
|
||||||
if (files == null)
|
TBMCCoreAPI.SendException("Failed to write plugin list!", e);
|
||||||
return;
|
}
|
||||||
System.out.println("Updating " + files.length + " plugins...");
|
}
|
||||||
for (File file : files) {
|
ess = Essentials.getPlugin(Essentials.class);
|
||||||
try {
|
logger.info(pdf.getName() + " has been Enabled (V." + pdf.getVersion() + ") Test: " + Test + ".");
|
||||||
Files.move(file.toPath(), new File("plugins", file.getName()).toPath(), StandardCopyOption.REPLACE_EXISTING);
|
}
|
||||||
System.out.println("Updated " + file.getName());
|
|
||||||
} catch (IOException e) {
|
@Override
|
||||||
e.printStackTrace();
|
public void pluginDisable() {
|
||||||
}
|
ComponentManager.disableComponents();
|
||||||
}
|
logger.info("Saving player data...");
|
||||||
System.out.println("Update complete!");
|
TBMCPlayerBase.savePlayers();
|
||||||
}).start();
|
logger.info("Player data saved.");
|
||||||
}
|
new Thread(() -> {
|
||||||
|
File[] files = PluginUpdater.updatedir.listFiles();
|
||||||
private boolean setupPermissions() {
|
if (files == null)
|
||||||
RegisteredServiceProvider<Permission> permissionProvider = getServer().getServicesManager()
|
return;
|
||||||
.getRegistration(Permission.class);
|
logger.info("Updating " + files.length + " plugins...");
|
||||||
if (permissionProvider != null) {
|
for (File file : files) {
|
||||||
permission = permissionProvider.getProvider();
|
try {
|
||||||
}
|
Files.move(file.toPath(), new File("plugins", file.getName()).toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
return (permission != null);
|
logger.info("Updated " + file.getName());
|
||||||
}
|
} catch (IOException e) {
|
||||||
}
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("Update complete!");
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean setupPermissions() {
|
||||||
|
RegisteredServiceProvider<Permission> permissionProvider = getServer().getServicesManager()
|
||||||
|
.getRegistration(Permission.class);
|
||||||
|
if (permissionProvider != null) {
|
||||||
|
permission = permissionProvider.getProvider();
|
||||||
|
}
|
||||||
|
return (permission != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
sender.sendMessage("§cThis command isn't available."); //In theory, unregistered commands use this method
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,61 +1,35 @@
|
||||||
package buttondevteam.core;
|
package buttondevteam.core;
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import buttondevteam.lib.chat.IFakePlayer;
|
import buttondevteam.lib.player.TBMCPlayerBase;
|
||||||
import buttondevteam.lib.player.TBMCPlayerBase;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.Statistic;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import java.util.Arrays;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
|
public class PlayerListener implements Listener {
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
@EventHandler(priority = EventPriority.NORMAL)
|
||||||
import java.util.Date;
|
public void OnPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
TBMCPlayerBase.joinPlayer(event.getPlayer());
|
||||||
import static buttondevteam.core.MainPlugin.permission;
|
}
|
||||||
|
|
||||||
public class PlayerListener implements Listener {
|
@EventHandler(priority = EventPriority.NORMAL)
|
||||||
|
public void OnPlayerLeave(PlayerQuitEvent event) {
|
||||||
@EventHandler(priority = EventPriority.NORMAL)
|
TBMCPlayerBase.quitPlayer(event.getPlayer());
|
||||||
public void OnPlayerJoin(PlayerJoinEvent event) {
|
}
|
||||||
TBMCPlayerBase.joinPlayer(event.getPlayer());
|
|
||||||
if (permission != null && !permission.playerInGroup(event.getPlayer(), "member")
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
&& (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(7, ChronoUnit.DAYS).isBefore(Instant.now())
|
public void onSystemChat(TBMCSystemChatEvent event) {
|
||||||
|| event.getPlayer().getStatistic(Statistic.PLAY_ONE_TICK) > 20 * 3600 * 12)) {
|
if (event.isHandled())
|
||||||
permission.playerAddGroup(null, event.getPlayer(), "member");
|
return; // Only handle here if ButtonChat couldn't - ButtonChat doesn't even handle this
|
||||||
event.getPlayer().sendMessage("§bYou are a member now. YEEHAW");
|
if (Arrays.stream(event.getExceptions()).anyMatch("Minecraft"::equalsIgnoreCase))
|
||||||
MainPlugin.Instance.getLogger().info("Added " + event.getPlayer().getName() + " as a member.");
|
return;
|
||||||
}
|
Bukkit.getOnlinePlayers().stream().filter(event::shouldSendTo)
|
||||||
}
|
.forEach(p -> p.sendMessage(event.getChannel().DisplayName().get().substring(0, 2) + event.getMessage()));
|
||||||
|
}
|
||||||
private long lasttime = 0;
|
|
||||||
@EventHandler(priority = EventPriority.NORMAL)
|
|
||||||
public void OnPlayerLeave(PlayerQuitEvent event) {
|
|
||||||
TBMCPlayerBase.quitPlayer(event.getPlayer());
|
|
||||||
if (PrimeRestartCommand.isPlsrestart()
|
|
||||||
&& !event.getQuitMessage().equalsIgnoreCase("Server closed")
|
|
||||||
&& !event.getQuitMessage().equalsIgnoreCase("Server is restarting")) {
|
|
||||||
if (Bukkit.getOnlinePlayers().size() <= 1) {
|
|
||||||
if (PrimeRestartCommand.isLoud())
|
|
||||||
Bukkit.broadcastMessage("§cNobody is online anymore. Restarting.");
|
|
||||||
Bukkit.spigot().restart();
|
|
||||||
} else if (!(event.getPlayer() instanceof IFakePlayer) && System.nanoTime() - 10 * 1000000000L - lasttime > 0) { //Ten seconds passed since last reminder
|
|
||||||
lasttime = System.nanoTime();
|
|
||||||
if (PrimeRestartCommand.isLoud())
|
|
||||||
Bukkit.broadcastMessage(ChatColor.DARK_RED + "The server will restart as soon as nobody is online.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
|
||||||
public void onSystemChat(TBMCSystemChatEvent event) {
|
|
||||||
if (event.isHandled())
|
|
||||||
return; // Only handle here if ButtonChat couldn't
|
|
||||||
Bukkit.getOnlinePlayers().stream().filter(event::shouldSendTo)
|
|
||||||
.forEach(p -> p.sendMessage(event.getChannel().DisplayName.substring(0, 2) + event.getMessage()));
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package buttondevteam.core;
|
package buttondevteam.core;
|
||||||
|
|
||||||
import buttondevteam.lib.chat.Channel;
|
import buttondevteam.component.channel.Channel;
|
||||||
|
import buttondevteam.component.channel.ChannelComponent;
|
||||||
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.chat.Color;
|
import buttondevteam.lib.chat.Color;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -38,6 +40,7 @@ public class TestPrepare {
|
||||||
return cl.isAssignableFrom(invocation.getMethod().getReturnType());
|
return cl.isAssignableFrom(invocation.getMethod().getReturnType());
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
Component.registerComponent(Mockito.mock(MainPlugin.class), new ChannelComponent());
|
||||||
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null));
|
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package buttondevteam.lib;
|
package buttondevteam.lib;
|
||||||
|
|
||||||
import buttondevteam.lib.chat.Channel;
|
import buttondevteam.component.channel.Channel;
|
||||||
import buttondevteam.lib.chat.ChatMessage;
|
import buttondevteam.lib.chat.ChatMessage;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.experimental.Delegate;
|
import lombok.experimental.Delegate;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package buttondevteam.lib;
|
package buttondevteam.lib;
|
||||||
|
|
||||||
import buttondevteam.lib.chat.Channel;
|
import buttondevteam.component.channel.Channel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package buttondevteam.lib;
|
package buttondevteam.lib;
|
||||||
|
|
||||||
import buttondevteam.lib.chat.Channel;
|
import buttondevteam.component.channel.Channel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package buttondevteam.lib;
|
package buttondevteam.lib;
|
||||||
|
|
||||||
import buttondevteam.lib.chat.Channel;
|
import buttondevteam.component.channel.Channel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
@ -13,14 +13,16 @@ import org.bukkit.event.HandlerList;
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public class TBMCSystemChatEvent extends TBMCChatEventBase {
|
public class TBMCSystemChatEvent extends TBMCChatEventBase {
|
||||||
|
private final String[] exceptions;
|
||||||
private boolean handled;
|
private boolean handled;
|
||||||
|
|
||||||
public void setHandled() {
|
public void setHandled() {
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TBMCSystemChatEvent(Channel channel, String message, int score, String groupid) { // TODO: Rich message
|
public TBMCSystemChatEvent(Channel channel, String message, int score, String groupid, String[] exceptions) { // TODO: Rich message
|
||||||
super(channel, message, score, groupid);
|
super(channel, message, score, groupid);
|
||||||
|
this.exceptions = exceptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
package buttondevteam.lib.architecture;
|
package buttondevteam.lib.architecture;
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.var;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public abstract class ButtonPlugin extends JavaPlugin {
|
public abstract class ButtonPlugin extends JavaPlugin {
|
||||||
private final HashMap<String, ConfigData<?>> datamap = new HashMap<>();
|
@Getter(AccessLevel.PROTECTED)
|
||||||
private ConfigurationSection section;
|
private IHaveConfig iConfig;
|
||||||
|
|
||||||
protected abstract void pluginEnable();
|
protected abstract void pluginEnable();
|
||||||
|
|
||||||
protected abstract void pluginDisable();
|
protected abstract void pluginDisable();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public final void onEnable() {
|
||||||
section = getConfig().getConfigurationSection("global");
|
var section = super.getConfig().getConfigurationSection("global");
|
||||||
if (section == null) section = getConfig().createSection("global");
|
if (section == null) section = super.getConfig().createSection("global");
|
||||||
|
iConfig = new IHaveConfig(section);
|
||||||
try {
|
try {
|
||||||
pluginEnable();
|
pluginEnable();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -28,25 +28,14 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public final void onDisable() {
|
||||||
try {
|
try {
|
||||||
pluginDisable();
|
pluginDisable();
|
||||||
|
saveConfig();
|
||||||
|
iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well
|
||||||
|
TBMCChatAPI.RemoveCommands(this);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e);
|
TBMCCoreAPI.SendException("Error while disabling plugin " + getName() + "!", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IHaveConfig#getData(Map, ConfigurationSection, String, Object)
|
|
||||||
*/
|
|
||||||
protected <T> ConfigData<T> getData(String path, T def) {
|
|
||||||
return IHaveConfig.getData(datamap, section, path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IHaveConfig#getData(Map, ConfigurationSection, String, Object, Function, Function)
|
|
||||||
*/
|
|
||||||
protected <T> ConfigData<T> getData(String path, T def, Function<Object, T> getter, Function<T, Object> setter) {
|
|
||||||
return IHaveConfig.getData(datamap, section, path, def, getter, setter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,19 +5,16 @@ import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
|
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.experimental.var;
|
import lombok.experimental.var;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration is based on class name
|
* Configuration is based on class name
|
||||||
|
@ -27,30 +24,15 @@ public abstract class Component {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
@Getter(value = AccessLevel.PROTECTED)
|
@Getter
|
||||||
@NonNull
|
@NonNull
|
||||||
private JavaPlugin plugin;
|
private JavaPlugin plugin;
|
||||||
@NonNull
|
@NonNull
|
||||||
private ConfigurationSection config;
|
private @Getter
|
||||||
|
IHaveConfig config;
|
||||||
|
|
||||||
public ConfigData<Boolean> shouldBeEnabled() {
|
public final ConfigData<Boolean> shouldBeEnabled() {
|
||||||
return getData("enabled", true);
|
return config.getData("enabled", true);
|
||||||
}
|
|
||||||
|
|
||||||
private HashMap<String, ConfigData<?>> datamap = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IHaveConfig#getData(Map, ConfigurationSection, String, Object)
|
|
||||||
*/
|
|
||||||
protected <T> ConfigData<T> getData(String path, T def) {
|
|
||||||
return IHaveConfig.getData(datamap, config, path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IHaveConfig#getData(Map, ConfigurationSection, String, Object, Function, Function)
|
|
||||||
*/
|
|
||||||
protected <T> ConfigData<T> getData(String path, T def, Function<Object, T> getter, Function<T, Object> setter) {
|
|
||||||
return IHaveConfig.getData(datamap, config, path, def, getter, setter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,7 +66,7 @@ public abstract class Component {
|
||||||
val metaAnn = component.getClass().getAnnotation(ComponentMetadata.class);
|
val metaAnn = component.getClass().getAnnotation(ComponentMetadata.class);
|
||||||
if (metaAnn != null) {
|
if (metaAnn != null) {
|
||||||
Class<? extends Component>[] dependencies = metaAnn.depends();
|
Class<? extends Component>[] dependencies = metaAnn.depends();
|
||||||
for (val dep : dependencies) {
|
for (val dep : dependencies) { //TODO: Support dependencies at enable/disable as well
|
||||||
if (!components.containsKey(dep)) {
|
if (!components.containsKey(dep)) {
|
||||||
plugin.getLogger().warning("Failed to " + (register ? "" : "un") + "register component " + component.getClassName() + " as a required dependency is missing/disabled: " + dep.getSimpleName());
|
plugin.getLogger().warning("Failed to " + (register ? "" : "un") + "register component " + component.getClassName() + " as a required dependency is missing/disabled: " + dep.getSimpleName());
|
||||||
return false;
|
return false;
|
||||||
|
@ -93,10 +75,7 @@ public abstract class Component {
|
||||||
}
|
}
|
||||||
if (register) {
|
if (register) {
|
||||||
component.plugin = plugin;
|
component.plugin = plugin;
|
||||||
var compconf = plugin.getConfig().getConfigurationSection("components");
|
updateConfig(plugin, component);
|
||||||
if (compconf == null) compconf = plugin.getConfig().createSection("components");
|
|
||||||
component.config = compconf.getConfigurationSection(component.getClassName());
|
|
||||||
if (component.config == null) component.config = compconf.createSection(component.getClassName());
|
|
||||||
component.register(plugin);
|
component.register(plugin);
|
||||||
components.put(component.getClass(), component);
|
components.put(component.getClass(), component);
|
||||||
if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled().get()) {
|
if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled().get()) {
|
||||||
|
@ -108,12 +87,11 @@ public abstract class Component {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true; //Component shouldn't be enabled
|
||||||
} else {
|
} else {
|
||||||
if (component.enabled) {
|
if (component.enabled) {
|
||||||
try {
|
try {
|
||||||
component.disable();
|
setComponentEnabled(component, false);
|
||||||
component.enabled = false;
|
|
||||||
} catch (Exception | NoClassDefFoundError e) {
|
} catch (Exception | NoClassDefFoundError e) {
|
||||||
TBMCCoreAPI.SendException("Failed to disable component " + component.getClassName() + "!", e);
|
TBMCCoreAPI.SendException("Failed to disable component " + component.getClassName() + "!", e);
|
||||||
return false; //If failed to disable, won't unregister either
|
return false; //If failed to disable, won't unregister either
|
||||||
|
@ -138,10 +116,27 @@ public abstract class Component {
|
||||||
public static void setComponentEnabled(Component component, boolean enabled) throws UnregisteredComponentException {
|
public static void setComponentEnabled(Component component, boolean enabled) throws UnregisteredComponentException {
|
||||||
if (!components.containsKey(component.getClass()))
|
if (!components.containsKey(component.getClass()))
|
||||||
throw new UnregisteredComponentException(component);
|
throw new UnregisteredComponentException(component);
|
||||||
if (component.enabled = enabled)
|
if (component.enabled == enabled) return; //Don't do anything
|
||||||
|
if (component.enabled = enabled) {
|
||||||
|
updateConfig(component.getPlugin(), component);
|
||||||
component.enable();
|
component.enable();
|
||||||
else
|
} else {
|
||||||
component.disable();
|
component.disable();
|
||||||
|
component.plugin.saveConfig();
|
||||||
|
TBMCChatAPI.RemoveCommands(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateConfig(JavaPlugin plugin, Component component) {
|
||||||
|
if (plugin.getConfig() != null) { //Production
|
||||||
|
var compconf = plugin.getConfig().getConfigurationSection("components");
|
||||||
|
if (compconf == null) compconf = plugin.getConfig().createSection("components");
|
||||||
|
var configSect = compconf.getConfigurationSection(component.getClassName());
|
||||||
|
if (configSect == null)
|
||||||
|
configSect = compconf.createSection(component.getClassName());
|
||||||
|
component.config = new IHaveConfig(configSect);
|
||||||
|
} else //Testing
|
||||||
|
component.config = new IHaveConfig(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,6 +154,7 @@ public abstract class Component {
|
||||||
*
|
*
|
||||||
* @param plugin Plugin object
|
* @param plugin Plugin object
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||||
protected void register(JavaPlugin plugin) {
|
protected void register(JavaPlugin plugin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +165,7 @@ public abstract class Component {
|
||||||
*
|
*
|
||||||
* @param plugin Plugin object
|
* @param plugin Plugin object
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||||
protected void unregister(JavaPlugin plugin) {
|
protected void unregister(JavaPlugin plugin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,35 +184,26 @@ public abstract class Component {
|
||||||
protected abstract void disable();
|
protected abstract void disable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a TBMCCommand to the plugin. Make sure to add it to plugin.yml and use {@link buttondevteam.lib.chat.CommandClass}.
|
* Registers a TBMCCommand to the component. Make sure to add it to plugin.yml and use {@link buttondevteam.lib.chat.CommandClass}.
|
||||||
*
|
*
|
||||||
* @param plugin Main plugin responsible for stuff
|
|
||||||
* @param commandBase Custom coded command class
|
* @param commandBase Custom coded command class
|
||||||
*/
|
*/
|
||||||
protected void registerCommand(JavaPlugin plugin, TBMCCommandBase commandBase) {
|
protected final void registerCommand(TBMCCommandBase commandBase) {
|
||||||
TBMCChatAPI.AddCommand(plugin, commandBase);
|
TBMCChatAPI.AddCommand(this, commandBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a Listener to this plugin
|
* Registers a Listener to this component
|
||||||
*
|
*
|
||||||
* @param plugin Main plugin responsible for stuff
|
|
||||||
* @param listener The event listener to register
|
* @param listener The event listener to register
|
||||||
* @return The provided listener
|
* @return The provided listener
|
||||||
*/
|
*/
|
||||||
protected Listener registerListener(JavaPlugin plugin, Listener listener) {
|
protected final Listener registerListener(Listener listener) {
|
||||||
TBMCCoreAPI.RegisterEventsForExceptions(listener, plugin);
|
TBMCCoreAPI.RegisterEventsForExceptions(listener, plugin);
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getClassName() {
|
private String getClassName() {
|
||||||
Class<?> enclosingClass = getClass().getEnclosingClass();
|
return getClass().getSimpleName();
|
||||||
String className;
|
|
||||||
if (enclosingClass != null) {
|
|
||||||
className = (enclosingClass.getName());
|
|
||||||
} else {
|
|
||||||
className = (getClass().getName());
|
|
||||||
}
|
|
||||||
return className;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,27 @@
|
||||||
package buttondevteam.lib.architecture;
|
package buttondevteam.lib.architecture;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the getter/setter constructor if {@link T} isn't a primitive type or String.<br>
|
* Use the getter/setter constructor if {@link T} isn't a primitive type or String.<br>
|
||||||
* Use {@link Component#getData(String, Object)} or {@link ButtonPlugin#getData(String, Object)} to get an instance.
|
* Use {@link Component#getConfig()} or {@link ButtonPlugin#getIConfig()} then {@link IHaveConfig#getData(String, Object)} to get an instance.
|
||||||
*/
|
*/
|
||||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||||
@AllArgsConstructor(access = AccessLevel.PACKAGE)
|
//@AllArgsConstructor(access = AccessLevel.PACKAGE)
|
||||||
public class ConfigData<T> { //TODO: Save after a while
|
public class ConfigData<T> { //TODO: Save after a while
|
||||||
|
/**
|
||||||
|
* May be null for testing
|
||||||
|
*/
|
||||||
private final ConfigurationSection config;
|
private final ConfigurationSection config;
|
||||||
private final String path;
|
private final String path;
|
||||||
private final T def;
|
private final T def;
|
||||||
|
private final Object primitiveDef;
|
||||||
/**
|
/**
|
||||||
* The parameter is of a primitive type as returned by {@link YamlConfiguration#get(String)}
|
* The parameter is of a primitive type as returned by {@link YamlConfiguration#get(String)}
|
||||||
*/
|
*/
|
||||||
|
@ -27,9 +31,32 @@ public class ConfigData<T> { //TODO: Save after a while
|
||||||
*/
|
*/
|
||||||
private Function<T, Object> setter;
|
private Function<T, Object> setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The config value should not change outside this instance
|
||||||
|
*/
|
||||||
|
private T value;
|
||||||
|
private boolean saved = false;
|
||||||
|
|
||||||
|
public ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Function<Object, T> getter, Function<T, Object> setter) {
|
||||||
|
this.config = config;
|
||||||
|
this.path = path;
|
||||||
|
this.def = def;
|
||||||
|
this.primitiveDef = primitiveDef;
|
||||||
|
this.getter = getter;
|
||||||
|
this.setter = setter;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public T get() {
|
public T get() {
|
||||||
Object val = config.get(path, def);
|
if (value != null) return value; //Speed things up
|
||||||
|
Object val = config == null ? null : config.get(path); //config==null: testing
|
||||||
|
if (val == null) {
|
||||||
|
val = primitiveDef;
|
||||||
|
}
|
||||||
|
if (!saved && Objects.equals(val, primitiveDef)) { //String needs .equals()
|
||||||
|
set(def); //Save default value - def is always set
|
||||||
|
saved = true;
|
||||||
|
}
|
||||||
if (getter != null) {
|
if (getter != null) {
|
||||||
T hmm = getter.apply(val);
|
T hmm = getter.apply(val);
|
||||||
if (hmm == null) hmm = def; //Set if the getter returned null
|
if (hmm == null) hmm = def; //Set if the getter returned null
|
||||||
|
@ -43,6 +70,8 @@ public class ConfigData<T> { //TODO: Save after a while
|
||||||
if (setter != null)
|
if (setter != null)
|
||||||
val = setter.apply(value);
|
val = setter.apply(value);
|
||||||
else val = value;
|
else val = value;
|
||||||
config.set(path, val);
|
if (config != null)
|
||||||
|
config.set(path, val);
|
||||||
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,27 @@
|
||||||
package buttondevteam.lib.architecture;
|
package buttondevteam.lib.architecture;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.HashMap;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Members of this interface should be protected (access level)
|
* Members of this interface should be protected (access level)
|
||||||
*/
|
*/
|
||||||
final class IHaveConfig {
|
public final class IHaveConfig {
|
||||||
private IHaveConfig() {}
|
private final HashMap<String, ConfigData<?>> datamap = new HashMap<>();
|
||||||
|
@Getter
|
||||||
|
private ConfigurationSection config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* May be used in testing
|
||||||
|
*
|
||||||
|
* @param section May be null for testing
|
||||||
|
*/
|
||||||
|
IHaveConfig(ConfigurationSection section) {
|
||||||
|
config = section;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method overload should only be used with primitves or String.
|
* This method overload should only be used with primitves or String.
|
||||||
|
@ -20,9 +32,9 @@ final class IHaveConfig {
|
||||||
* @return The data object that can be used to get or set the value
|
* @return The data object that can be used to get or set the value
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected static <T> ConfigData<T> getData(Map<String, ConfigData<?>> datamap, ConfigurationSection config, String path, T def) {
|
public <T> ConfigData<T> getData(String path, T def) {
|
||||||
ConfigData<?> data = datamap.get(path);
|
ConfigData<?> data = datamap.get(path);
|
||||||
if (data == null) datamap.put(path, data = new ConfigData<>(config, path, def));
|
if (data == null) datamap.put(path, data = new ConfigData<>(config, path, def, def));
|
||||||
return (ConfigData<T>) data;
|
return (ConfigData<T>) data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,9 +49,28 @@ final class IHaveConfig {
|
||||||
* @return The data object that can be used to get or set the value
|
* @return The data object that can be used to get or set the value
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected static <T> ConfigData<T> getData(Map<String, ConfigData<?>> datamap, ConfigurationSection config, String path, T def, Function<Object, T> getter, Function<T, Object> setter) {
|
public <T> ConfigData<T> getData(String path, T def, Function<Object, T> getter, Function<T, Object> setter) {
|
||||||
ConfigData<?> data = datamap.get(path);
|
ConfigData<?> data = datamap.get(path);
|
||||||
if (data == null) datamap.put(path, data = new ConfigData<>(config, path, def, getter, setter));
|
if (data == null)
|
||||||
|
datamap.put(path, data = new ConfigData<>(config, path, def, setter.apply(def), getter, setter));
|
||||||
|
return (ConfigData<T>) data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method overload may be used with any class. The given default value will be run through the getter.
|
||||||
|
*
|
||||||
|
* @param path The path in config to use
|
||||||
|
* @param primitiveDef The <b>primitive</b> value to use by default
|
||||||
|
* @param getter A function that converts a primitive representation to the correct value
|
||||||
|
* @param setter A function that converts a value to a primitive representation
|
||||||
|
* @param <T> The type of this variable (can be any class)
|
||||||
|
* @return The data object that can be used to get or set the value
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> ConfigData<T> getDataPrimDef(String path, Object primitiveDef, Function<Object, T> getter, Function<T, Object> setter) {
|
||||||
|
ConfigData<?> data = datamap.get(path);
|
||||||
|
if (data == null)
|
||||||
|
datamap.put(path, data = new ConfigData<>(config, path, getter.apply(primitiveDef), primitiveDef, getter, setter));
|
||||||
return (ConfigData<T>) data;
|
return (ConfigData<T>) data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package buttondevteam.lib.chat;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
public abstract class Command2 {
|
||||||
|
/**
|
||||||
|
* Default handler for commands, can be used to copy the args too.
|
||||||
|
*
|
||||||
|
* @param sender The sender which ran the command
|
||||||
|
* @param command The (sub)command ran by the user
|
||||||
|
* @param args All of the arguments passed as is
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean def(CommandSender sender, String command, @TextArg String args) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: @CommandClass(helpText=...)
|
||||||
|
* Parameters annotated with this receive all of the remaining arguments
|
||||||
|
*/
|
||||||
|
@Target(ElementType.PARAMETER)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface TextArg {
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,4 +36,11 @@ public @interface CommandClass {
|
||||||
* Exclude this class from the path. Useful if more commands share some property but aren't subcommands of a common command. See {@link CommandClass} for more details.
|
* Exclude this class from the path. Useful if more commands share some property but aren't subcommands of a common command. See {@link CommandClass} for more details.
|
||||||
*/
|
*/
|
||||||
boolean excludeFromPath() default false;
|
boolean excludeFromPath() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The help text to show for the players.
|
||||||
|
*
|
||||||
|
* @return The help text
|
||||||
|
*/
|
||||||
|
String[] helpText() default {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,282 +1,340 @@
|
||||||
package buttondevteam.lib.chat;
|
package buttondevteam.lib.chat;
|
||||||
|
|
||||||
import buttondevteam.core.CommandCaller;
|
import buttondevteam.component.channel.Channel;
|
||||||
import buttondevteam.core.MainPlugin;
|
import buttondevteam.component.channel.Channel.RecipientTestResult;
|
||||||
import buttondevteam.lib.TBMCChatEvent;
|
import buttondevteam.core.CommandCaller;
|
||||||
import buttondevteam.lib.TBMCChatPreprocessEvent;
|
import buttondevteam.core.MainPlugin;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCChatEvent;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCChatPreprocessEvent;
|
||||||
import buttondevteam.lib.chat.Channel.RecipientTestResult;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import lombok.val;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import org.bukkit.Bukkit;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import org.bukkit.command.CommandSender;
|
import lombok.val;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.reflections.Reflections;
|
import org.bukkit.entity.Player;
|
||||||
import org.reflections.scanners.SubTypesScanner;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.reflections.util.ClasspathHelper;
|
import org.reflections.Reflections;
|
||||||
import org.reflections.util.ConfigurationBuilder;
|
import org.reflections.scanners.SubTypesScanner;
|
||||||
|
import org.reflections.util.ClasspathHelper;
|
||||||
import java.lang.reflect.Modifier;
|
import org.reflections.util.ConfigurationBuilder;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
import java.util.Map.Entry;
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
import java.util.HashMap;
|
||||||
import java.util.function.Consumer;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
public class TBMCChatAPI {
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
private static final HashMap<String, TBMCCommandBase> commands = new HashMap<>();
|
public class TBMCChatAPI {
|
||||||
|
|
||||||
public static HashMap<String, TBMCCommandBase> GetCommands() {
|
private static final HashMap<String, TBMCCommandBase> commands = new HashMap<>();
|
||||||
return commands;
|
|
||||||
}
|
public static HashMap<String, TBMCCommandBase> GetCommands() {
|
||||||
|
return commands;
|
||||||
/**
|
}
|
||||||
* Returns messages formatted for Minecraft chat listing the subcommands of the command.
|
|
||||||
*
|
/**
|
||||||
* @param command
|
* Returns messages formatted for Minecraft chat listing the subcommands of the command.
|
||||||
* The command which we want the subcommands of
|
*
|
||||||
* @param sender
|
* @param command
|
||||||
* The sender for permissions
|
* The command which we want the subcommands of
|
||||||
* @return The subcommands
|
* @param sender
|
||||||
*/
|
* The sender for permissions
|
||||||
public static String[] GetSubCommands(TBMCCommandBase command, CommandSender sender) {
|
* @return The subcommands
|
||||||
return GetSubCommands(command.GetCommandPath(), sender);
|
*/
|
||||||
}
|
public static String[] GetSubCommands(TBMCCommandBase command, CommandSender sender) {
|
||||||
|
return GetSubCommands(command.GetCommandPath(), sender);
|
||||||
/**
|
}
|
||||||
* Returns messages formatted for Minecraft chat listing the subcommands of the command.<br>
|
|
||||||
* Returns a header if subcommands were found, otherwise returns an empty array.
|
/**
|
||||||
*
|
* Returns messages formatted for Minecraft chat listing the subcommands of the command.<br>
|
||||||
* @param command
|
* Returns a header if subcommands were found, otherwise returns an empty array.
|
||||||
* The command which we want the subcommands of
|
*
|
||||||
* @param sender
|
* @param command
|
||||||
* The sender for permissions
|
* The command which we want the subcommands of
|
||||||
* @return The subcommands
|
* @param sender
|
||||||
*/
|
* The sender for permissions
|
||||||
public static String[] GetSubCommands(String command, CommandSender sender) {
|
* @return The subcommands
|
||||||
ArrayList<String> cmds = new ArrayList<String>();
|
*/
|
||||||
Consumer<String> addToCmds = cmd -> {
|
public static String[] GetSubCommands(String command, CommandSender sender) {
|
||||||
if (cmds.size() == 0)
|
ArrayList<String> cmds = new ArrayList<String>();
|
||||||
cmds.add("§6---- Subcommands ----");
|
Consumer<String> addToCmds = cmd -> {
|
||||||
cmds.add(cmd);
|
if (cmds.size() == 0)
|
||||||
};
|
cmds.add("§6---- Subcommands ----");
|
||||||
for (Entry<String, TBMCCommandBase> cmd : TBMCChatAPI.GetCommands().entrySet()) {
|
cmds.add(cmd);
|
||||||
if (cmd.getKey().startsWith(command + " ")) {
|
};
|
||||||
if (cmd.getValue().isPlayerOnly() && !(sender instanceof Player))
|
for (Entry<String, TBMCCommandBase> cmd : TBMCChatAPI.GetCommands().entrySet()) {
|
||||||
continue;
|
if (cmd.getKey().startsWith(command + " ")) {
|
||||||
if (cmd.getValue().isModOnly() && (MainPlugin.permission != null ? !MainPlugin.permission.has(sender, "tbmc.admin") : !sender.isOp()))
|
if (cmd.getValue().isPlayerOnly() && !(sender instanceof Player))
|
||||||
continue;
|
continue;
|
||||||
int ind = cmd.getKey().indexOf(' ', command.length() + 2);
|
if (cmd.getValue().isModOnly() && (MainPlugin.permission != null ? !MainPlugin.permission.has(sender, "tbmc.admin") : !sender.isOp()))
|
||||||
if (ind >= 0) {
|
continue;
|
||||||
String newcmd = cmd.getKey().substring(0, ind);
|
int ind = cmd.getKey().indexOf(' ', command.length() + 2);
|
||||||
if (!cmds.contains("/" + newcmd))
|
if (ind >= 0) {
|
||||||
addToCmds.accept("/" + newcmd);
|
String newcmd = cmd.getKey().substring(0, ind);
|
||||||
} else
|
if (!cmds.contains("/" + newcmd))
|
||||||
addToCmds.accept("/" + cmd.getKey());
|
addToCmds.accept("/" + newcmd);
|
||||||
}
|
} else
|
||||||
}
|
addToCmds.accept("/" + cmd.getKey());
|
||||||
return cmds.toArray(new String[0]); //Apparently it's faster to use an empty array in modern Java
|
}
|
||||||
}
|
}
|
||||||
|
return cmds.toArray(new String[0]); //Apparently it's faster to use an empty array in modern Java
|
||||||
/**
|
}
|
||||||
* <p>
|
|
||||||
* This method adds a plugin's commands to help and sets their executor.
|
/**
|
||||||
* </p>
|
* <p>
|
||||||
* <p>
|
* This method adds a plugin's commands to help and sets their executor.
|
||||||
* </p>
|
* </p>
|
||||||
* <b>The command classes have to have a constructor each with no parameters</b>
|
* <p>
|
||||||
* <p>
|
* </p>
|
||||||
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console.
|
* <b>The command classes have to have a constructor each with no parameters</b>
|
||||||
* </p>
|
* <p>
|
||||||
* <p>
|
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console.
|
||||||
* <i>Using this method after the server is done loading will have no effect.</i>
|
* </p>
|
||||||
* </p>
|
* <p>
|
||||||
*
|
* <i>Using this method after the server is done loading will have no effect.</i>
|
||||||
* @param plugin
|
* </p>
|
||||||
* The caller plugin
|
*
|
||||||
* @param acmdclass
|
* @param plugin
|
||||||
* A command's class to get the package name for commands. The provided class's package and subpackages are scanned for commands.
|
* The caller plugin
|
||||||
*/
|
* @param acmdclass
|
||||||
public static synchronized void AddCommands(JavaPlugin plugin, Class<? extends TBMCCommandBase> acmdclass) {
|
* A command's class to get the package name for commands. The provided class's package and subpackages are scanned for commands.
|
||||||
plugin.getLogger().info("Registering commands from " + acmdclass.getPackage().getName());
|
*/
|
||||||
Reflections rf = new Reflections(new ConfigurationBuilder()
|
public static synchronized void AddCommands(JavaPlugin plugin, Class<? extends TBMCCommandBase> acmdclass) {
|
||||||
.setUrls(ClasspathHelper.forPackage(acmdclass.getPackage().getName(),
|
plugin.getLogger().info("Registering commands from " + acmdclass.getPackage().getName());
|
||||||
plugin.getClass().getClassLoader()))
|
Reflections rf = new Reflections(new ConfigurationBuilder()
|
||||||
.addUrls(
|
.setUrls(ClasspathHelper.forPackage(acmdclass.getPackage().getName(),
|
||||||
ClasspathHelper.forClass(OptionallyPlayerCommandBase.class,
|
plugin.getClass().getClassLoader()))
|
||||||
OptionallyPlayerCommandBase.class.getClassLoader()),
|
.addUrls(
|
||||||
ClasspathHelper.forClass(PlayerCommandBase.class, PlayerCommandBase.class.getClassLoader())) // http://stackoverflow.com/questions/12917417/using-reflections-for-finding-the-transitive-subtypes-of-a-class-when-not-all
|
ClasspathHelper.forClass(OptionallyPlayerCommandBase.class,
|
||||||
.addClassLoader(plugin.getClass().getClassLoader()).addScanners(new SubTypesScanner()));
|
OptionallyPlayerCommandBase.class.getClassLoader()),
|
||||||
Set<Class<? extends TBMCCommandBase>> cmds = rf.getSubTypesOf(TBMCCommandBase.class);
|
ClasspathHelper.forClass(PlayerCommandBase.class, PlayerCommandBase.class.getClassLoader())) // http://stackoverflow.com/questions/12917417/using-reflections-for-finding-the-transitive-subtypes-of-a-class-when-not-all
|
||||||
for (Class<? extends TBMCCommandBase> cmd : cmds) {
|
.addClassLoader(plugin.getClass().getClassLoader()).addScanners(new SubTypesScanner()));
|
||||||
try {
|
Set<Class<? extends TBMCCommandBase>> cmds = rf.getSubTypesOf(TBMCCommandBase.class);
|
||||||
if (!cmd.getPackage().getName().startsWith(acmdclass.getPackage().getName()))
|
for (Class<? extends TBMCCommandBase> cmd : cmds) {
|
||||||
continue; // It keeps including the commands from here
|
try {
|
||||||
if (Modifier.isAbstract(cmd.getModifiers()))
|
if (!cmd.getPackage().getName().startsWith(acmdclass.getPackage().getName()))
|
||||||
continue;
|
continue; // It keeps including the commands from here
|
||||||
TBMCCommandBase c = cmd.newInstance();
|
if (Modifier.isAbstract(cmd.getModifiers()))
|
||||||
c.plugin = plugin;
|
continue;
|
||||||
if (HasNulls(plugin, c))
|
TBMCCommandBase c = cmd.newInstance();
|
||||||
continue;
|
c.plugin = plugin;
|
||||||
commands.put(c.GetCommandPath(), c);
|
CommandCaller.RegisterCommand(c); //Will check for nulls
|
||||||
CommandCaller.RegisterCommand(c);
|
commands.put(c.GetCommandPath(), c);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getName(), e);
|
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* This method adds a plugin's command to help and sets it's executor.
|
* This method adds a plugin's command to help and sets it's executor. They will be automatically unregistered on plugin disable.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console.
|
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* <i>Using this method after the server is done loading will have no effect.</i>
|
* <i>Using this method after the server is done loading will have no effect.</i>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param plugin
|
* @param plugin
|
||||||
* The caller plugin
|
* The caller plugin
|
||||||
* @param thecmdclass
|
* @param thecmdclass
|
||||||
* The command's class to create it (because why let you create the command class)
|
* The command's class to create it (because why let you create the command class)
|
||||||
*/
|
*/
|
||||||
public static void AddCommand(JavaPlugin plugin, Class<? extends TBMCCommandBase> thecmdclass, Object... params) {
|
public static void AddCommand(JavaPlugin plugin, Class<? extends TBMCCommandBase> thecmdclass, Object... params) {
|
||||||
// plugin.getLogger().info("Registering command " + thecmdclass.getSimpleName() + " for " + plugin.getName());
|
// plugin.getLogger().info("Registering command " + thecmdclass.getSimpleName() + " for " + plugin.getName());
|
||||||
try {
|
try {
|
||||||
TBMCCommandBase c;
|
TBMCCommandBase c;
|
||||||
if (params.length > 0)
|
if (params.length > 0)
|
||||||
c = thecmdclass.getConstructor(Arrays.stream(params).map(Object::getClass).toArray(Class[]::new))
|
c = thecmdclass.getConstructor(Arrays.stream(params).map(Object::getClass).toArray(Class[]::new))
|
||||||
.newInstance(params);
|
.newInstance(params);
|
||||||
else
|
else
|
||||||
c = thecmdclass.newInstance();
|
c = thecmdclass.newInstance();
|
||||||
c.plugin = plugin;
|
c.plugin = plugin;
|
||||||
if (HasNulls(plugin, c))
|
CommandCaller.RegisterCommand(c); //Will check for nulls
|
||||||
return;
|
commands.put(c.GetCommandPath(), c);
|
||||||
commands.put(c.GetCommandPath(), c);
|
} catch (Exception e) {
|
||||||
CommandCaller.RegisterCommand(c);
|
TBMCCoreAPI.SendException("An error occured while registering command " + thecmdclass.getSimpleName(), e);
|
||||||
} catch (Exception e) {
|
}
|
||||||
TBMCCoreAPI.SendException("An error occured while registering command " + thecmdclass.getSimpleName(), e);
|
} //TODO: onCommand(CommandSender sender, String alias, int arg1, String arg2) (planned for a while)
|
||||||
}
|
|
||||||
}
|
/**
|
||||||
|
* <p>
|
||||||
/**
|
* This method adds a plugin's command to help and sets its executor. They will be automatically unregistered on plugin disable.
|
||||||
* <p>
|
* </p>
|
||||||
* This method adds a plugin's command to help and sets it's executor.
|
* <p>
|
||||||
* </p>
|
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a message to console.
|
||||||
* <p>
|
* </p>
|
||||||
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console.
|
* <p>
|
||||||
* </p>
|
* <i>Using this method after the server is done loading will have no effect.</i>
|
||||||
* <p>
|
* </p>
|
||||||
* <i>Using this method after the server is done loading will have no effect.</i>
|
*
|
||||||
* </p>
|
* @param plugin
|
||||||
*
|
* The caller plugin
|
||||||
* @param plugin
|
* @param cmd
|
||||||
* The caller plugin
|
* The command to add
|
||||||
* @param cmd
|
*/
|
||||||
* The command to add
|
public static void AddCommand(JavaPlugin plugin, TBMCCommandBase cmd) {
|
||||||
*/
|
try {
|
||||||
public static void AddCommand(JavaPlugin plugin, TBMCCommandBase cmd) {
|
if (plugin == null) throw new IllegalArgumentException("The plugin is null!");
|
||||||
if (HasNulls(plugin, cmd))
|
if (cmd == null) throw new IllegalArgumentException("The command is null!");
|
||||||
return;
|
cmd.plugin = plugin;
|
||||||
// plugin.getLogger().info("Registering command /" + cmd.GetCommandPath() + " for " + plugin.getName());
|
CommandCaller.RegisterCommand(cmd); //Checks for other nulls
|
||||||
try {
|
commands.put(cmd.GetCommandPath(), cmd);
|
||||||
cmd.plugin = plugin;
|
} catch (Exception e) {
|
||||||
commands.put(cmd.GetCommandPath(), cmd);
|
TBMCCoreAPI.SendException("An error occured while registering command " + (cmd == null ? "n u l l" : cmd.GetCommandPath()), e);
|
||||||
CommandCaller.RegisterCommand(cmd);
|
}
|
||||||
} catch (Exception e) {
|
}
|
||||||
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.GetCommandPath(), e);
|
|
||||||
}
|
/**
|
||||||
}
|
* <p>
|
||||||
|
* This method adds a plugin's command to help and sets its executor. They will be automatically unregistered on component disable.
|
||||||
private static boolean HasNulls(JavaPlugin plugin, TBMCCommandBase cmd) {
|
* </p>
|
||||||
if (cmd == null) {
|
* <p>
|
||||||
TBMCCoreAPI.SendException("An error occured while registering a command for plugin " + plugin.getName(),
|
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a message to console.
|
||||||
new Exception("The command is null!"));
|
* </p>
|
||||||
return true;
|
* <p>
|
||||||
} else if (cmd.GetCommandPath() == null) {
|
* <i>Using this method after the server is done loading will have no effect.</i>
|
||||||
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getClass().getSimpleName()
|
* </p>
|
||||||
+ " for plugin " + plugin.getName(), new Exception("The command path is null!"));
|
*
|
||||||
return true;
|
* @param component The caller component
|
||||||
}
|
* @param cmd The command to add
|
||||||
return false;
|
*/
|
||||||
}
|
public static void AddCommand(Component component, TBMCCommandBase cmd) {
|
||||||
|
try {
|
||||||
/**
|
if (component == null) throw new IllegalArgumentException("The component is null!");
|
||||||
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.<br>
|
if (cmd == null) throw new IllegalArgumentException("The command is null!");
|
||||||
* This will also send the error message to the sender, if they can't send the message.
|
cmd.plugin = component.getPlugin();
|
||||||
*
|
cmd.component = component;
|
||||||
* @param cm The message to send
|
CommandCaller.RegisterCommand(cmd); //Checks for other nulls
|
||||||
* @return The event cancelled state
|
commands.put(cmd.GetCommandPath(), cmd);
|
||||||
*/
|
} catch (Exception e) {
|
||||||
public static boolean SendChatMessage(ChatMessage cm) {
|
TBMCCoreAPI.SendException("An error occured while registering command " + (cmd == null ? "n u l l" : cmd.GetCommandPath()), e);
|
||||||
return SendChatMessage(cm, cm.getUser().channel().get());
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.<br>
|
* Removes all commands from the plugin
|
||||||
* This will also send the error message to the sender, if they can't send the message.
|
*
|
||||||
*
|
* @param plugin The plugin to remove commands from
|
||||||
* @param cm The message to send
|
*/
|
||||||
* @param channel The MC channel to send in
|
public static void RemoveCommands(JavaPlugin plugin) {
|
||||||
* @return The event cancelled state
|
commands.values().removeIf(c -> {
|
||||||
*/
|
try {
|
||||||
public static boolean SendChatMessage(ChatMessage cm, Channel channel) {
|
if (c.plugin == plugin) {
|
||||||
if (!Channel.getChannels().contains(channel))
|
CommandCaller.UnregisterCommand(c);
|
||||||
throw new RuntimeException("Channel " + channel.DisplayName + " not registered!");
|
return true; //Remove
|
||||||
val permcheck = cm.getPermCheck();
|
}
|
||||||
RecipientTestResult rtr = getScoreOrSendError(channel, permcheck);
|
return false;
|
||||||
int score = rtr.score;
|
} catch (Exception e) {
|
||||||
if (score == Channel.SCORE_SEND_NOPE || rtr.groupID == null)
|
TBMCCoreAPI.SendException("An error occured while unregistering commands for " + plugin.getName(), e);
|
||||||
return true;
|
return true; //Remove if it couldn't get the plugin command
|
||||||
TBMCChatPreprocessEvent eventPre = new TBMCChatPreprocessEvent(cm.getSender(), channel, cm.getMessage());
|
}
|
||||||
Bukkit.getPluginManager().callEvent(eventPre);
|
});
|
||||||
if (eventPre.isCancelled())
|
}
|
||||||
return true;
|
|
||||||
cm.setMessage(eventPre.getMessage());
|
/**
|
||||||
TBMCChatEvent event;
|
* Removes all commands from the component
|
||||||
event = new TBMCChatEvent(channel, cm, rtr);
|
*
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
* @param component The component to remove commands from
|
||||||
return event.isCancelled();
|
*/
|
||||||
}
|
public static void RemoveCommands(Component component) {
|
||||||
|
commands.values().removeIf(c -> {
|
||||||
/**
|
try {
|
||||||
* Sends a regular message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.
|
if (c.component == component) {
|
||||||
*
|
CommandCaller.UnregisterCommand(c);
|
||||||
* @param channel
|
return true; //Remove
|
||||||
* The channel to send to
|
}
|
||||||
* @param rtr
|
return false;
|
||||||
* The score&group to use to find the group - use {@link RecipientTestResult#ALL} if the channel doesn't have scores
|
} catch (Exception e) {
|
||||||
* @param message
|
TBMCCoreAPI.SendException("An error occured while unregistering commands for " + component.getClass().getSimpleName(), e);
|
||||||
* The message to send
|
return true; //Remove if it couldn't get the plugin command
|
||||||
* @return The event cancelled state
|
}
|
||||||
*/
|
});
|
||||||
public static boolean SendSystemMessage(Channel channel, RecipientTestResult rtr, String message) {
|
}
|
||||||
if (!Channel.getChannels().contains(channel))
|
|
||||||
throw new RuntimeException("Channel " + channel.DisplayName + " not registered!");
|
/**
|
||||||
TBMCSystemChatEvent event = new TBMCSystemChatEvent(channel, message, rtr.score, rtr.groupID);
|
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.<br>
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
* This will also send the error message to the sender, if they can't send the message.
|
||||||
return event.isCancelled();
|
*
|
||||||
}
|
* @param cm The message to send
|
||||||
|
* @return The event cancelled state
|
||||||
private static RecipientTestResult getScoreOrSendError(Channel channel, CommandSender sender) {
|
*/
|
||||||
RecipientTestResult result = channel.getRTR(sender);
|
public static boolean SendChatMessage(ChatMessage cm) {
|
||||||
if (result.errormessage != null)
|
return SendChatMessage(cm, cm.getUser().channel().get());
|
||||||
sender.sendMessage("§c" + result.errormessage);
|
}
|
||||||
return result;
|
|
||||||
}
|
/**
|
||||||
|
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.<br>
|
||||||
/**
|
* This will also send the error message to the sender, if they can't send the message.
|
||||||
* Register a chat channel. See {@link Channel#Channel(String, Color, String, java.util.function.Function)} for details.
|
*
|
||||||
*
|
* @param cm The message to send
|
||||||
* @param channel
|
* @param channel The MC channel to send in
|
||||||
* A new {@link Channel} to register
|
* @return The event cancelled state
|
||||||
*/
|
*/
|
||||||
public static void RegisterChatChannel(Channel channel) {
|
public static boolean SendChatMessage(ChatMessage cm, Channel channel) {
|
||||||
Channel.RegisterChannel(channel);
|
if (!Channel.getChannelList().contains(channel))
|
||||||
}
|
throw new RuntimeException("Channel " + channel.DisplayName().get() + " not registered!");
|
||||||
}
|
if (!channel.Enabled().get()) {
|
||||||
|
cm.getSender().sendMessage("§cThe channel '" + channel.DisplayName().get() + "' is disabled!");
|
||||||
|
return true; //Cancel sending if channel is disabled
|
||||||
|
}
|
||||||
|
val permcheck = cm.getPermCheck();
|
||||||
|
RecipientTestResult rtr = getScoreOrSendError(channel, permcheck);
|
||||||
|
int score = rtr.score;
|
||||||
|
if (score == Channel.SCORE_SEND_NOPE || rtr.groupID == null)
|
||||||
|
return true;
|
||||||
|
TBMCChatPreprocessEvent eventPre = new TBMCChatPreprocessEvent(cm.getSender(), channel, cm.getMessage());
|
||||||
|
Bukkit.getPluginManager().callEvent(eventPre);
|
||||||
|
if (eventPre.isCancelled())
|
||||||
|
return true;
|
||||||
|
cm.setMessage(eventPre.getMessage());
|
||||||
|
TBMCChatEvent event;
|
||||||
|
event = new TBMCChatEvent(channel, cm, rtr);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
return event.isCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a regular message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.
|
||||||
|
*
|
||||||
|
* @param channel
|
||||||
|
* The channel to send to
|
||||||
|
* @param rtr
|
||||||
|
* The score&group to use to find the group - use {@link RecipientTestResult#ALL} if the channel doesn't have scores
|
||||||
|
* @param message
|
||||||
|
* The message to send
|
||||||
|
* @param exceptions Platforms where this message shouldn't be sent (same as {@link ChatMessage#getOrigin()}
|
||||||
|
* @return The event cancelled state
|
||||||
|
*/
|
||||||
|
public static boolean SendSystemMessage(Channel channel, RecipientTestResult rtr, String message, String... exceptions) {
|
||||||
|
if (!Channel.getChannelList().contains(channel))
|
||||||
|
throw new RuntimeException("Channel " + channel.DisplayName().get() + " not registered!");
|
||||||
|
if (!channel.Enabled().get())
|
||||||
|
return true; //Cancel sending
|
||||||
|
TBMCSystemChatEvent event = new TBMCSystemChatEvent(channel, message, rtr.score, rtr.groupID, exceptions);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
return event.isCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RecipientTestResult getScoreOrSendError(Channel channel, CommandSender sender) {
|
||||||
|
RecipientTestResult result = channel.getRTR(sender);
|
||||||
|
if (result.errormessage != null)
|
||||||
|
sender.sendMessage("§c" + result.errormessage);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a chat channel. See {@link Channel#Channel(String, Color, String, java.util.function.Function)} for details.
|
||||||
|
*
|
||||||
|
* @param channel
|
||||||
|
* A new {@link Channel} to register
|
||||||
|
*/
|
||||||
|
public static void RegisterChatChannel(Channel channel) {
|
||||||
|
Channel.RegisterChannel(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,106 +1,111 @@
|
||||||
package buttondevteam.lib.chat;
|
package buttondevteam.lib.chat;
|
||||||
|
|
||||||
import javassist.Modifier;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import org.bukkit.command.CommandSender;
|
import javassist.Modifier;
|
||||||
import org.bukkit.plugin.Plugin;
|
import lombok.Getter;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import java.util.function.Function;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
/**
|
import java.util.function.Function;
|
||||||
* Extend this class to create new TBMCCommand and use {@link TBMCChatAPI#AddCommand(org.bukkit.plugin.java.JavaPlugin, TBMCCommandBase)} to add it. <u><b>Note:</b></u> The command path (command name
|
|
||||||
* and subcommand arguments) will be the class name by default, removing any "command" from it. To change it (especially for subcommands), use the path field in the {@link CommandClass} annotation.
|
/**
|
||||||
*
|
* Extend this class to create new TBMCCommand and use {@link TBMCChatAPI#AddCommand(org.bukkit.plugin.java.JavaPlugin, TBMCCommandBase)} to add it. <u><b>Note:</b></u> The command path (command name
|
||||||
* @author Norbi
|
* and subcommand arguments) will be the class name by default, removing any "command" from it. To change it (especially for subcommands), use the path field in the {@link CommandClass} annotation.
|
||||||
*
|
*
|
||||||
*/
|
* @author Norbi
|
||||||
@TBMCCommandEnforcer
|
*
|
||||||
public abstract class TBMCCommandBase {
|
*/
|
||||||
|
@TBMCCommandEnforcer
|
||||||
public TBMCCommandBase() {
|
public abstract class TBMCCommandBase {
|
||||||
path = getcmdpath();
|
|
||||||
modonly = ismodonly();
|
public TBMCCommandBase() {
|
||||||
}
|
path = getcmdpath();
|
||||||
|
modonly = ismodonly();
|
||||||
public abstract boolean OnCommand(CommandSender sender, String alias, String[] args);
|
}
|
||||||
|
|
||||||
public abstract String[] GetHelpText(String alias);
|
public abstract boolean OnCommand(CommandSender sender, String alias, String[] args);
|
||||||
|
|
||||||
private final String path;
|
public abstract String[] GetHelpText(String alias);
|
||||||
|
|
||||||
/**
|
private final String path;
|
||||||
* The command's path, or name if top-level command.<br>
|
|
||||||
* For example:<br>
|
/**
|
||||||
* "u admin updateplugin" or "u" for the top level one<br>
|
* The command's path, or name if top-level command.<br>
|
||||||
* <u>The path must be lowercase!</u><br>
|
* For example:<br>
|
||||||
* <b>Abstract classes with no {@link CommandClass} annotations will be ignored.</b>
|
* "u admin updateplugin" or "u" for the top level one<br>
|
||||||
*
|
* <u>The path must be lowercase!</u><br>
|
||||||
* @return The command path, <i>which is the command class name by default</i> (removing any "command" from it) - Change via the {@link CommandClass} annotation
|
* <b>Abstract classes with no {@link CommandClass} annotations will be ignored.</b>
|
||||||
*/
|
*
|
||||||
public final String GetCommandPath() {
|
* @return The command path, <i>which is the command class name by default</i> (removing any "command" from it) - Change via the {@link CommandClass} annotation
|
||||||
return path;
|
*/
|
||||||
}
|
public final String GetCommandPath() {
|
||||||
|
return path;
|
||||||
private String getcmdpath() {
|
}
|
||||||
if (!getClass().isAnnotationPresent(CommandClass.class))
|
|
||||||
throw new RuntimeException(
|
private String getcmdpath() {
|
||||||
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
|
if (!getClass().isAnnotationPresent(CommandClass.class))
|
||||||
Function<Class<?>, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ...
|
throw new RuntimeException(
|
||||||
.replace("command", "");
|
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
|
||||||
String path = getClass().getAnnotation(CommandClass.class).path(),
|
Function<Class<?>, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ...
|
||||||
prevpath = path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
|
.replace("command", "");
|
||||||
for (Class<?> cl = getClass().getSuperclass(); cl != null
|
String path = getClass().getAnnotation(CommandClass.class).path(),
|
||||||
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
|
prevpath = path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
|
||||||
.getSuperclass()) { //
|
for (Class<?> cl = getClass().getSuperclass(); cl != null
|
||||||
String newpath;
|
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
|
||||||
if (!cl.isAnnotationPresent(CommandClass.class)
|
.getSuperclass()) { //
|
||||||
|| (newpath = cl.getAnnotation(CommandClass.class).path()).length() == 0
|
String newpath;
|
||||||
|| newpath.equals(prevpath)) {
|
if (!cl.isAnnotationPresent(CommandClass.class)
|
||||||
if ((Modifier.isAbstract(cl.getModifiers()) && !cl.isAnnotationPresent(CommandClass.class))
|
|| (newpath = cl.getAnnotation(CommandClass.class).path()).length() == 0
|
||||||
|| cl.getAnnotation(CommandClass.class).excludeFromPath()) // <--
|
|| newpath.equals(prevpath)) {
|
||||||
continue;
|
if ((Modifier.isAbstract(cl.getModifiers()) && !cl.isAnnotationPresent(CommandClass.class))
|
||||||
newpath = getFromClass.apply(cl);
|
|| cl.getAnnotation(CommandClass.class).excludeFromPath()) // <--
|
||||||
}
|
continue;
|
||||||
path = (prevpath = newpath) + " " + path;
|
newpath = getFromClass.apply(cl);
|
||||||
}
|
}
|
||||||
return path;
|
path = (prevpath = newpath) + " " + path;
|
||||||
}
|
}
|
||||||
|
return path;
|
||||||
Plugin plugin; // Used By TBMCChatAPI
|
}
|
||||||
|
|
||||||
public final Plugin getPlugin() { // Used by CommandCaller (ButtonChat)
|
Plugin plugin; // Used By TBMCChatAPI
|
||||||
return plugin;
|
|
||||||
}
|
public final Plugin getPlugin() { // Used by CommandCaller (ButtonChat)
|
||||||
|
return plugin;
|
||||||
public final boolean isPlayerOnly() {
|
}
|
||||||
return this instanceof PlayerCommandBase ||
|
|
||||||
(this instanceof OptionallyPlayerCommandBase &&
|
public final boolean isPlayerOnly() {
|
||||||
(!getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class)
|
return this instanceof PlayerCommandBase ||
|
||||||
|| getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly()));
|
(this instanceof OptionallyPlayerCommandBase &&
|
||||||
}
|
(!getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class)
|
||||||
|
|| getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly()));
|
||||||
private final boolean modonly;
|
}
|
||||||
|
|
||||||
/**
|
private final boolean modonly;
|
||||||
* Returns true if this class' or any superclass' modOnly property is set to true.
|
|
||||||
*/
|
/**
|
||||||
public final boolean isModOnly() {
|
* Returns true if this class' or any superclass' modOnly property is set to true.
|
||||||
return modonly;
|
*/
|
||||||
}
|
public final boolean isModOnly() {
|
||||||
|
return modonly;
|
||||||
private boolean ismodonly() {
|
}
|
||||||
if (!getClass().isAnnotationPresent(CommandClass.class))
|
|
||||||
throw new RuntimeException(
|
private boolean ismodonly() {
|
||||||
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
|
if (!getClass().isAnnotationPresent(CommandClass.class))
|
||||||
boolean modOnly = getClass().getAnnotation(CommandClass.class).modOnly();
|
throw new RuntimeException(
|
||||||
for (Class<?> cl = getClass().getSuperclass(); cl != null
|
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
|
||||||
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
|
boolean modOnly = getClass().getAnnotation(CommandClass.class).modOnly();
|
||||||
.getSuperclass()) { //
|
for (Class<?> cl = getClass().getSuperclass(); cl != null
|
||||||
if (cl.isAnnotationPresent(CommandClass.class) && !modOnly
|
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
|
||||||
&& cl.getAnnotation(CommandClass.class).modOnly()) {
|
.getSuperclass()) { //
|
||||||
modOnly = true;
|
if (cl.isAnnotationPresent(CommandClass.class) && !modOnly
|
||||||
break;
|
&& cl.getAnnotation(CommandClass.class).modOnly()) {
|
||||||
}
|
modOnly = true;
|
||||||
}
|
break;
|
||||||
return modOnly;
|
}
|
||||||
}
|
}
|
||||||
}
|
return modOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
Component component; //May be null
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package buttondevteam.lib.player;
|
package buttondevteam.lib.player;
|
||||||
|
|
||||||
import buttondevteam.lib.chat.Channel;
|
import buttondevteam.component.channel.Channel;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
public class ChannelPlayerData { //I just want this to work
|
public class ChannelPlayerData { //I just want this to work
|
||||||
|
@ -16,7 +16,7 @@ public class ChannelPlayerData { //I just want this to work
|
||||||
String str = data.get();
|
String str = data.get();
|
||||||
if (str.isEmpty())
|
if (str.isEmpty())
|
||||||
return def;
|
return def;
|
||||||
return Channel.getChannels().stream().filter(c -> str.equals(c.ID)).findAny().orElse(def);
|
return Channel.getChannels().filter(c -> str.equals(c.ID)).findAny().orElse(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(Channel value) {
|
public void set(Channel value) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package buttondevteam.lib.player;
|
package buttondevteam.lib.player;
|
||||||
|
|
||||||
|
import buttondevteam.component.channel.Channel;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.chat.Channel;
|
|
||||||
import com.google.common.collect.HashBiMap;
|
import com.google.common.collect.HashBiMap;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
package buttondevteam.lib.player;
|
package buttondevteam.lib.player;
|
||||||
|
|
||||||
|
import buttondevteam.component.towny.TownyComponent;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import com.palmergames.bukkit.towny.Towny;
|
|
||||||
import com.palmergames.bukkit.towny.exceptions.AlreadyRegisteredException;
|
|
||||||
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
|
|
||||||
import com.palmergames.bukkit.towny.object.Resident;
|
|
||||||
import com.palmergames.bukkit.towny.object.TownyUniverse;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
@ -127,22 +123,7 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
||||||
Bukkit.getLogger().info("Player name saved: " + player.PlayerName().get());
|
Bukkit.getLogger().info("Player name saved: " + player.PlayerName().get());
|
||||||
} else if (!p.getName().equals(player.PlayerName().get())) {
|
} else if (!p.getName().equals(player.PlayerName().get())) {
|
||||||
Bukkit.getLogger().info("Renaming " + player.PlayerName().get() + " to " + p.getName());
|
Bukkit.getLogger().info("Renaming " + player.PlayerName().get() + " to " + p.getName());
|
||||||
TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse();
|
TownyComponent.renameInTowny(player.PlayerName().get(), p.getName());
|
||||||
Resident resident = tu.getResidentMap().get(player.PlayerName().get().toLowerCase()); //The map keys are lowercase
|
|
||||||
if (resident == null) {
|
|
||||||
Bukkit.getLogger().warning("Resident not found - couldn't rename in Towny.");
|
|
||||||
TBMCCoreAPI.sendDebugMessage("Resident not found - couldn't rename in Towny.");
|
|
||||||
} else if (tu.getResidentMap().contains(p.getName().toLowerCase())) {
|
|
||||||
Bukkit.getLogger().warning("Target resident name is already in use."); // TODO: Handle
|
|
||||||
TBMCCoreAPI.sendDebugMessage("Target resident name is already in use.");
|
|
||||||
} else
|
|
||||||
try {
|
|
||||||
TownyUniverse.getDataSource().renamePlayer(resident, p.getName()); //Fixed in Towny 0.91.1.2
|
|
||||||
} catch (AlreadyRegisteredException e) {
|
|
||||||
TBMCCoreAPI.SendException("Failed to rename resident, there's already one with this name.", e);
|
|
||||||
} catch (NotRegisteredException e) {
|
|
||||||
TBMCCoreAPI.SendException("Failed to rename resident, the resident isn't registered.", e);
|
|
||||||
}
|
|
||||||
player.PlayerName().set(p.getName());
|
player.PlayerName().set(p.getName());
|
||||||
Bukkit.getLogger().info("Renaming done.");
|
Bukkit.getLogger().info("Renaming done.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
name: ButtonCore
|
name: ButtonCore
|
||||||
main: buttondevteam.core.MainPlugin
|
main: buttondevteam.core.MainPlugin
|
||||||
version: 1.0
|
version: 1.0
|
||||||
author: TBMCPlugins
|
author: TBMCPlugins
|
||||||
commands:
|
commands:
|
||||||
updateplugin:
|
updateplugin:
|
||||||
description: Update a TBMC plugin
|
description: Update a TBMC plugin
|
||||||
schrestart:
|
schrestart:
|
||||||
description: Schedules a restart for a given time.
|
description: Schedules a restart for a given time.
|
||||||
primerestart:
|
primerestart:
|
||||||
description: Restarts the server as soon as nobody is online.
|
description: Restarts the server as soon as nobody is online.
|
||||||
randomtp:
|
randomtp:
|
||||||
description: teleport player to random location within world border. Every five players teleport to the same general area, and then a new general area is randomly selected for the next five players.
|
description: teleport player to random location within world border. Every five players teleport to the same general area, and then a new general area is randomly selected for the next five players.
|
||||||
member:
|
member:
|
||||||
description: Add or remove a member
|
description: Add or remove a member
|
||||||
|
component:
|
||||||
|
description: Enable or disable or list components
|
||||||
|
|
Loading…
Reference in a new issue