Add broadcasting when players reach certain level milestones (defaults to every 100 levels)

This commit is contained in:
nossr50 2021-01-07 13:33:12 -08:00
parent 801c2c83e2
commit f38d92497a
10 changed files with 233 additions and 4 deletions

View File

@ -1,5 +1,9 @@
Version 2.1.171
Axes can now replant cocoa plants (thanks Lyther)
Players who level up at certain milestones have their level ups broadcast to the server (very configurable and optional, see notes)
Added Level_Up_Chat_Broadcasts settings to config.yml under General
New locale string 'Broadcasts.LevelUpMilestone'
Version 2.1.170
Reverted a change that broke compatibility with the mcMMO papi ecloud thingy

View File

@ -1,11 +1,13 @@
package com.gmail.nossr50.commands.experience;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -30,7 +32,14 @@ public class AddlevelsCommand extends ExperienceCommand {
return;
}
EventUtils.tryLevelChangeEvent(player, skill, value, xpRemoved, true, XPGainReason.COMMAND);
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if(mmoPlayer == null) {
EventUtils.tryLevelChangeEvent(player, skill, value, xpRemoved, true, XPGainReason.COMMAND);
} else {
EventUtils.tryLevelChangeEvent(mmoPlayer, skill, value, xpRemoved, true, XPGainReason.COMMAND);
}
}
@Override

View File

@ -1,11 +1,13 @@
package com.gmail.nossr50.commands.experience;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -36,7 +38,14 @@ public class MmoeditCommand extends ExperienceCommand {
return;
}
EventUtils.tryLevelEditEvent(player, skill, value, xpRemoved, value > skillLevel, XPGainReason.COMMAND, skillLevel);
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if(mmoPlayer != null) {
EventUtils.tryLevelEditEvent(mmoPlayer, skill, value, xpRemoved, value > skillLevel, XPGainReason.COMMAND, skillLevel);
} else {
EventUtils.tryLevelEditEvent(player, skill, value, xpRemoved, value > skillLevel, XPGainReason.COMMAND, skillLevel);
}
}
@Override

View File

@ -581,4 +581,12 @@ public class Config extends AutoUpdateConfigLoader {
public boolean playerJoinEventInfo() { return config.getBoolean("General.EventInfoOnPlayerJoin", true);}
public boolean adminNotifications() { return config.getBoolean("General.AdminNotifications", true);}
public boolean shouldLevelUpBroadcasts() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Enabled", true); }
public boolean shouldLevelUpBroadcastToConsole() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Broadcast_Targets.Send_To_Console", true); }
public boolean isLevelUpBroadcastsPartyMembersOnly() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Broadcast_Targets.Only_Party_Members", false); }
public boolean isLevelUpBroadcastsSameWorldOnly() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Broadcast_Targets.Only_Same_World", false); }
public boolean shouldLevelUpBroadcastsRestrictDistance() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Broadcast_Targets.Distance_Restrictions.Restrict_Distance", false); }
public int getLevelUpBroadcastRadius() { return config.getInt("General.Level_Up_Chat_Broadcasts.Broadcast_Targets.Distance_Restrictions.Restricted_Radius", 100); }
public int getLevelUpBroadcastInterval() { return config.getInt("General.Level_Up_Chat_Broadcasts.Milestone_Interval", 100); }
}

View File

@ -0,0 +1,100 @@
package com.gmail.nossr50.datatypes;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.function.Predicate;
//TODO: Allow for offline players to broadcast
public class LevelUpBroadcastPredicate<T extends CommandSender> implements Predicate<T> {
private final @NotNull T broadcaster;
public LevelUpBroadcastPredicate(@NotNull T broadcaster) {
this.broadcaster = broadcaster;
}
@Override
public boolean test(@NotNull T t) {
Player broadcastingPlayer = (Player) broadcaster; //Always a player no need to check cast
//Broadcaster should be online
if(!broadcastingPlayer.isOnline()) {
return false;
}
McMMOPlayer mmoBroadcastingPlayer = UserManager.getPlayer(broadcastingPlayer);
if(mmoBroadcastingPlayer == null) {
//This should never be null, but just in case...
mcMMO.p.getLogger().severe("McMMOPlayer was null for broadcaster in LevelUpBroadcastPredicate when it should never be null!");
return false;
}
if(t instanceof Player) {
Player listeningPlayer = (Player) t;
//Party Member Check
if(Config.getInstance().isLevelUpBroadcastsPartyMembersOnly()) {
McMMOPlayer mmoListeningPlayer = UserManager.getPlayer(listeningPlayer);
if(mmoListeningPlayer == null) {
return false; //No profile so therefor no party
}
Party playerWhoLeveledParty = mmoBroadcastingPlayer.getParty();
Party broadcastRecipientParty = mmoListeningPlayer.getParty();
if(playerWhoLeveledParty == null || broadcastRecipientParty == null) {
return false; //No party on either player when being in the same party is required
}
if(!playerWhoLeveledParty.equals(broadcastRecipientParty)) {
return false; //Not in the same party when it is required
}
}
//Same world check
if(isLevelUpBroadcastsSameWorldOnly()) {
if(!mmoBroadcastingPlayer.getPlayer().getWorld().equals(listeningPlayer.getWorld())) {
return false; //Not in the same world when its required
}
//Distance checks
if(Config.getInstance().shouldLevelUpBroadcastsRestrictDistance()) {
if(!Misc.isNear(mmoBroadcastingPlayer.getPlayer().getLocation(), listeningPlayer.getLocation(), Config.getInstance().getLevelUpBroadcastRadius())) {
return false;
}
}
}
//Visibility checks
if(!listeningPlayer.canSee(mmoBroadcastingPlayer.getPlayer())) {
return false; //Player who leveled should be invisible to this player so don't send the message
}
return true;
} else {
//Send out to console
return Config.getInstance().shouldLevelUpBroadcastToConsole();
}
}
private static boolean isLevelUpBroadcastsSameWorldOnly() {
return Config.getInstance().isLevelUpBroadcastsSameWorldOnly();
}
@Override
public String toString() {
return "LevelUpBroadcastPredicate{" +
"broadcaster=" + broadcaster +
'}';
}
}

View File

@ -652,7 +652,7 @@ public class McMMOPlayer implements Identified {
levelsGained++;
}
if (EventUtils.tryLevelChangeEvent(player, primarySkillType, levelsGained, xpRemoved, true, xpGainReason)) {
if (EventUtils.tryLevelChangeEvent(this, primarySkillType, levelsGained, xpRemoved, true, xpGainReason)) {
return;
}

View File

@ -32,6 +32,7 @@ import com.gmail.nossr50.events.skills.secondaryabilities.SubSkillEvent;
import com.gmail.nossr50.events.skills.unarmed.McMMOPlayerDisarmEvent;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.CombatUtils;
import org.bukkit.block.Block;
@ -232,6 +233,24 @@ public final class EventUtils {
return isCancelled;
}
public static boolean tryLevelChangeEvent(@NotNull McMMOPlayer mmoPlayer, PrimarySkillType skill, int levelsChanged, float xpRemoved, boolean isLevelUp, XPGainReason xpGainReason) {
McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(mmoPlayer.getPlayer(), skill, levelsChanged, xpGainReason) : new McMMOPlayerLevelDownEvent(mmoPlayer.getPlayer(), skill, levelsChanged, xpGainReason);
mcMMO.p.getServer().getPluginManager().callEvent(event);
boolean isCancelled = event.isCancelled();
if (isCancelled) {
mmoPlayer.modifySkill(skill, mmoPlayer.getSkillLevel(skill) - (isLevelUp ? levelsChanged : -levelsChanged));
mmoPlayer.addXp(skill, xpRemoved);
} else {
if (isLevelUp) {
NotificationManager.processLevelUpBroadcasting(mmoPlayer, skill, mmoPlayer.getSkillLevel(skill));
}
}
return isCancelled;
}
public static boolean tryLevelEditEvent(Player player, PrimarySkillType skill, int levelsChanged, float xpRemoved, boolean isLevelUp, XPGainReason xpGainReason, int oldLevel) {
McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(player, skill, levelsChanged - oldLevel, xpGainReason) : new McMMOPlayerLevelDownEvent(player, skill, levelsChanged, xpGainReason);
mcMMO.p.getServer().getPluginManager().callEvent(event);
@ -248,6 +267,24 @@ public final class EventUtils {
return isCancelled;
}
public static boolean tryLevelEditEvent(@NotNull McMMOPlayer mmoPlayer, PrimarySkillType skill, int levelsChanged, float xpRemoved, boolean isLevelUp, XPGainReason xpGainReason, int oldLevel) {
McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(mmoPlayer.getPlayer(), skill, levelsChanged - oldLevel, xpGainReason) : new McMMOPlayerLevelDownEvent(mmoPlayer.getPlayer(), skill, levelsChanged, xpGainReason);
mcMMO.p.getServer().getPluginManager().callEvent(event);
boolean isCancelled = event.isCancelled();
if (isCancelled) {
mmoPlayer.modifySkill(skill, mmoPlayer.getSkillLevel(skill) - (isLevelUp ? levelsChanged : -levelsChanged));
mmoPlayer.addXp(skill, xpRemoved);
} else {
if (isLevelUp) {
NotificationManager.processLevelUpBroadcasting(mmoPlayer, skill, mmoPlayer.getSkillLevel(skill));
}
}
return isCancelled;
}
/**
* Simulate a block break event.
*

View File

@ -2,6 +2,7 @@ package com.gmail.nossr50.util.player;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.LevelUpBroadcastPredicate;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.notifications.SensitiveCommandType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@ -19,14 +20,23 @@ import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.MessageType;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.SoundCategory;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.time.LocalDate;
public class NotificationManager {
public static final String HEX_BEIGE_COLOR = "#c2a66e";
public static final String HEX_LIME_GREEN_COLOR = "#8ec26e";
/**
* Sends players notifications from mcMMO
* Does so by sending out an event so other plugins can cancel it
@ -256,4 +266,37 @@ public class NotificationManager {
return newArray;
}
public static void processLevelUpBroadcasting(@NotNull McMMOPlayer mmoPlayer, @NotNull PrimarySkillType primarySkillType, int level) {
if(level <= 0)
return;
//Check if broadcasting is enabled
if(Config.getInstance().shouldLevelUpBroadcasts()) {
int levelInterval = Config.getInstance().getLevelUpBroadcastInterval();
int remainder = level % levelInterval;
if(remainder == 0) {
//Grab appropriate audience
Audience audience = mcMMO.getAudiences().filter(getLevelUpBroadcastPredicate(mmoPlayer.getPlayer()));
//TODO: Make prettier+
HoverEvent<Component> levelMilestoneHover = Component.text(mmoPlayer.getPlayer().getName())
.append(Component.newline())
.append(Component.text(LocalDate.now().toString()))
.append(Component.newline())
.append(Component.text(primarySkillType.getName()+" reached level "+level)).color(TextColor.fromHexString(HEX_BEIGE_COLOR))
.asHoverEvent();
String localeMessage = LocaleLoader.getString("Broadcasts.LevelUpMilestone", mmoPlayer.getPlayer().getDisplayName(), level, primarySkillType.toString());
Component message = Component.text(localeMessage).hoverEvent(levelMilestoneHover);
audience.sendMessage(Identity.nil(), message);
}
}
}
//TODO: Could cache
public static @NotNull LevelUpBroadcastPredicate<CommandSender> getLevelUpBroadcastPredicate(@NotNull CommandSender levelUpPlayer) {
return new LevelUpBroadcastPredicate<>(levelUpPlayer);
}
}

View File

@ -8,6 +8,24 @@
# Settings for mcMMO in general
###
General:
# When players reach certain level milestones messages will be broadcast
Level_Up_Chat_Broadcasts:
# Whether or not level up broadcasts are enabled
Enabled: true
# How often to broadcast, you can change this to 1 to always broadcast a level up event, a setting of 100 will limit it to every 100 levels (for example level 100, level 200, etc)
Milestone_Interval: 100
Broadcast_Targets:
# Send the message to the console as well
Send_To_Console: true
# Whether or not to only send chat messages to party members
Only_Party_Members: false
# Whether or not players who recieve a level up broadcast have to be on the same world as the one who leveled up
Only_Same_World: false
# Distance restrictions
Distance_Restrictions:
Restrict_Distance: false
# When using Restrict_Distance the blow setting configures the range of the broadcast
Restricted_Radius: 100
# Turning this on will scale mcMMO around 1-1000 with default scaling factor
# Everything in your config related to skill level requirements, skill level bonuses, etc will be multiplied by 10 when this mode is on
# This change is purely cosmetic, it retains the old feel of mcMMO where you could level up thousands of times

View File

@ -1136,3 +1136,4 @@ Chat.Identity.Console=&6* Console *
Chat.Channel.On=&6(&amcMMO-Chat&6) &eYour chat messages will now be automatically delivered to the &a{0}&e chat channel.
Chat.Channel.Off=&6(&amcMMO-Chat&6) &7Your chat messages will no longer be automatically delivered to specific chat channels.
Chat.Spy.Party=&6[&eSPY&6-&a{2}&6] &r{0} &b\u2192 &r{1}
Broadcasts.LevelUpMilestone=&6(&amcMMO&6) {0}&7 has reached level &a{1}&7 in [[DARK_AQUA]]{2}&7!