Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ public interface ISettings extends IConf {

boolean showZeroBaltop();

String getNickRegex();

BigDecimal getMultiplier(final User user);

int getMaxItemLore();
Expand Down
11 changes: 11 additions & 0 deletions Essentials/src/main/java/com/earth2me/essentials/IUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ default boolean hasOutstandingTeleportRequest() {

String getFormattedJailTime();

/**
* Returns last activity time.
* <p>
* It is used internally to determine if user's afk status should be set to
* true because of ACTIVITY {@link AfkStatusChangeEvent.Cause}, or the player
* should be kicked for being afk too long.
*
* @return Last activity time (Epoch Milliseconds)
*/
long getLastActivityTime();

@Deprecated
List<String> getMails();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2120,6 +2120,11 @@ public boolean showZeroBaltop() {
return config.getBoolean("show-zero-baltop", true);
}

@Override
public String getNickRegex() {
return config.getString("allowed-nicks-regex", "^[a-zA-Z_0-9§]+$");
}

@Override
public BigDecimal getMultiplier(final User user) {
BigDecimal multiplier = defaultMultiplier;
Expand Down
5 changes: 5 additions & 0 deletions Essentials/src/main/java/com/earth2me/essentials/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,11 @@ public boolean checkMuteTimeout(final long currentTime) {
return false;
}

@Override
public long getLastActivityTime() {
return this.lastActivity;
}

@Deprecated
public void updateActivity(final boolean broadcast) {
updateActivity(broadcast, AfkStatusChangeEvent.Cause.UNKNOWN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ protected void updatePlayer(final Server server, final CommandSource sender, fin

private String formatNickname(final User user, final String nick) throws Exception {
final String newNick = user == null ? FormatUtil.replaceFormat(nick) : FormatUtil.formatString(user, "essentials.nick", nick);
if (!newNick.matches("^[a-zA-Z_0-9" + ChatColor.COLOR_CHAR + "]+$") && user != null && !user.isAuthorized("essentials.nick.allowunsafe")) {
if (!newNick.matches(ess.getSettings().getNickRegex()) && user != null && !user.isAuthorized("essentials.nick.allowunsafe")) {
throw new TranslatableException("nickNamesAlpha");
} else if (getNickLength(newNick) > ess.getSettings().getMaxNickLength()) {
throw new TranslatableException("nickTooLong");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import net.ess3.api.events.SignTransactionEvent;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
import org.bukkit.inventory.ItemStack;
Expand Down Expand Up @@ -45,6 +46,12 @@ protected boolean onSignInteract(final ISign sign, final User player, final Stri
}

charge.isAffordableFor(player);
final SignTransactionEvent signTransactionEvent = new SignTransactionEvent(sign, this, player, items.getItemStack(), SignTransactionEvent.TransactionType.BUY, charge.getMoney());

ess.getServer().getPluginManager().callEvent(signTransactionEvent);
if (signTransactionEvent.isCancelled()) {
return true;
}
if (!items.pay(player)) {
throw new ChargeException("inventoryFull");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.Trade.OverflowType;
import com.earth2me.essentials.User;
import net.ess3.api.events.SignTransactionEvent;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
import org.bukkit.inventory.ItemStack;
Expand Down Expand Up @@ -47,6 +48,13 @@ protected boolean onSignInteract(final ISign sign, final User player, final Stri
}

charge.isAffordableFor(player);

final SignTransactionEvent signTransactionEvent = new SignTransactionEvent(sign, this, player, charge.getItemStack(), SignTransactionEvent.TransactionType.SELL, money.getMoney());
ess.getServer().getPluginManager().callEvent(signTransactionEvent);
if (signTransactionEvent.isCancelled()) {
return false;
}

money.pay(player, OverflowType.DROP);
charge.charge(player);
Trade.log("Sign", "Sell", "Interact", username, charge, username, money, sign.getBlock().getLocation(), player.getMoney(), ess);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package net.ess3.api.events;

import com.earth2me.essentials.signs.EssentialsSign;
import net.ess3.api.IUser;
import org.bukkit.event.Cancellable;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.bukkit.event.HandlerList;

import java.math.BigDecimal;

/**
* Fired when a player either buys or sells from an Essentials sign
*/
public final class SignTransactionEvent extends SignInteractEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private final ItemStack itemStack;
private final TransactionType transactionType;
private final BigDecimal transactionValue;
private boolean isCancelled = false;

public SignTransactionEvent(EssentialsSign.ISign sign, EssentialsSign essSign, IUser user, ItemStack itemStack, TransactionType transactionType, BigDecimal transactionValue) {
super(sign, essSign, user);
this.itemStack = itemStack;
this.transactionType = transactionType;
this.transactionValue = transactionValue;
}

@Override
public boolean isCancelled() {
return this.isCancelled;
}

@Override
public void setCancelled(boolean cancelled) {
this.isCancelled = cancelled;
}

/**
* Gets the ItemStack that is about to be bought or sold in this transition.
* @return The ItemStack being bought or sold.
*/
public @NotNull ItemStack getItemStack() {
return itemStack.clone();
}

/**
* Gets the type of transaction, either buy or sell.
* @return The transaction type.
*/
public @NotNull TransactionType getTransactionType() {
return transactionType;
}

/**
* Gets the value of the item being bought or sold.
* @return The item's value.
*/
public BigDecimal getTransactionValue() {
return transactionValue;
}

/**
* The type of transaction for this sign transaction.
*/
public enum TransactionType {
BUY,
SELL
}

@Override
public HandlerList getHandlers() {
return handlers;
}

public static HandlerList getHandlerList() {
return handlers;
}
}
5 changes: 5 additions & 0 deletions Essentials/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ nickname-prefix: '~'
# The maximum length allowed in nicknames. The nickname prefix is not included in this.
max-nick-length: 15

# The regex pattern used to determine if a requested nickname should be allowed for use.
# If the a requested nickname does not matched this pattern, the nickname will be rejected.
# Users with essentials.nick.allowunsafe will be able to bypass this check.
allowed-nicks-regex: '^[a-zA-Z_0-9§]+$'

# A list of phrases that cannot be used in nicknames. You can include regular expressions here.
# Users with essentials.nick.blacklist.bypass will be able to bypass this filter.
nick-blacklist:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static final class DefaultTypes {
public final static MessageType FIRST_JOIN = new MessageType("first-join", true);
public final static MessageType LEAVE = new MessageType("leave", true);
public final static MessageType CHAT = new MessageType("chat", true);
public final static MessageType PRIVATE_CHAT = new MessageType("private-chat", true);
public final static MessageType DEATH = new MessageType("death", true);
public final static MessageType AFK = new MessageType("afk", true);
public final static MessageType ADVANCEMENT = new MessageType("advancement", true);
Expand All @@ -68,7 +69,7 @@ public static final class DefaultTypes {
public final static MessageType LOCAL = new MessageType("local", true);
public final static MessageType QUESTION = new MessageType("question", true);
public final static MessageType SHOUT = new MessageType("shout", true);
private final static MessageType[] VALUES = new MessageType[]{JOIN, FIRST_JOIN, LEAVE, CHAT, DEATH, AFK, ADVANCEMENT, ACTION, SERVER_START, SERVER_STOP, KICK, MUTE, LOCAL, QUESTION, SHOUT};
private final static MessageType[] VALUES = new MessageType[]{JOIN, FIRST_JOIN, LEAVE, CHAT, PRIVATE_CHAT, DEATH, AFK, ADVANCEMENT, ACTION, SERVER_START, SERVER_STOP, KICK, MUTE, LOCAL, QUESTION, SHOUT};

/**
* Gets an array of all the default {@link MessageType MessageTypes}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class DiscordSettings implements IConf {
private MessageFormat permMuteReasonFormat;
private MessageFormat unmuteFormat;
private MessageFormat kickFormat;
private MessageFormat pmToDiscordFormat;

public DiscordSettings(EssentialsDiscord plugin) {
this.plugin = plugin;
Expand Down Expand Up @@ -445,6 +446,10 @@ public MessageFormat getKickFormat() {
return kickFormat;
}

public MessageFormat getPmToDiscordFormat() {
return pmToDiscordFormat;
}

private String getFormatString(String node) {
final String pathPrefix = node.startsWith(".") ? "" : "messages.";
return config.getString(pathPrefix + (pathPrefix.isEmpty() ? node.substring(1) : node), null);
Expand Down Expand Up @@ -581,6 +586,8 @@ public void reloadConfig() {
"username", "displayname", "controllername", "controllerdisplayname", "reason");
kickFormat = generateMessageFormat(getFormatString("kick"), "{displayname} was kicked with reason: {reason}", false,
"username", "displayname", "reason");
pmToDiscordFormat = generateMessageFormat(getFormatString("private-chat"), "[SocialSpy] {sender-username} -> {receiver-username}: {message}", false,
"sender-username", "sender-displayname", "receiver-username", "receiver-displayname", "message");

plugin.onReload();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.api.events.PrivateMessageSentEvent;
import net.ess3.api.IUser;
import net.ess3.api.events.AfkStatusChangeEvent;
import net.ess3.api.events.MuteStatusChangeEvent;
Expand Down Expand Up @@ -47,6 +48,23 @@ public void onDiscordMessage(DiscordMessageEvent event) {

// Bukkit Events

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPrivateMessage(PrivateMessageSentEvent event) {

if (event.getSender() instanceof IUser && ((IUser) event.getSender()).isAuthorized("essentials.chat.spy.exempt")) {
return;
}

sendDiscordMessage(MessageType.DefaultTypes.PRIVATE_CHAT,
MessageUtil.formatMessage(jda.getSettings().getPmToDiscordFormat(),
MessageUtil.sanitizeDiscordMarkdown(event.getSender().getName()),
MessageUtil.sanitizeDiscordMarkdown(event.getSender().getDisplayName()),
MessageUtil.sanitizeDiscordMarkdown(event.getRecipient().getName()),
MessageUtil.sanitizeDiscordMarkdown(event.getRecipient().getDisplayName()),
MessageUtil.sanitizeDiscordMarkdown(event.getMessage())),
event.getSender() instanceof IUser ? ((IUser) event.getSender()).getBase() : null);
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onMute(MuteStatusChangeEvent event) {
if (!event.getValue()) {
Expand Down
10 changes: 10 additions & 0 deletions EssentialsDiscord/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ message-types:
kick: staff
# Message sent when a player's mute state is changed on the Minecraft server.
mute: staff
# Message sent when a private message (/msg, /whisper, etc.) is sent on the Minecraft Server.
private-chat: none
# Message sent when a player talks in local chat.
# use-essentials-events must be set to "true" for this to work.
local: none
Expand Down Expand Up @@ -433,3 +435,11 @@ messages:
# - {displayname}: The display name of the user who got kicked
# - {reason}: The reason the player was kicked
kick: "{displayname} was kicked with reason: {reason}"
# This is the message that is used to relay minecraft private messages in Discord.
# The following placeholders can be used here:
# - {sender-username}: The username of the player sending the message
# - {sender-displayname}: The display name of the player sending the message (This would be their nickname)
# - {receiver-username}: The username of the player receiving the message
# - {receiver-displayname}: The display name of the player receiving the message (This would be their nickname)
# - {message}: The content of the message being sent
pms-to-discord: "[SocialSpy] {sender-username} -> {receiver-username}: {message}"
Loading