Skip to content
Open
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 @@ -71,6 +71,12 @@ public interface DiscordSRVPlayer {
*/
boolean isChatVisible();

/**
* If this is the player's first time joining the server.
* @return {@code true} if this is the player's first join
*/
boolean isFirstJoin();

/**
* Sends the provided message to the player.
* @param component the message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ public boolean isVanished() {
return BukkitComponentSerializer.legacy().deserialize(player.getDisplayName());
}

@Override
public boolean isFirstJoin() {
return !player.hasPlayedBefore();
}

@Override
public @NotNull Identity identity() {
return identity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ public void removeChatSuggestions(Collection<String> suggestions) {
return BungeeComponentUtil.fromLegacy(player.getDisplayName());
}

@Override
public boolean isFirstJoin() {
return false;
}

@Override
public String toString() {
return "BungeePlayer{" + username() + "}";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public BanSyncConfig() {
@Order(-10)
public long serverId = 0L;

@Comment("On a player's first join to the server, prefer the Discord side for tie-breaking")
public boolean preferDiscordTieBreakerOnFirstJoin = true;

@Comment("Role id that will be used for role related actions, if they are configured below")
public Long bannedRoleId = 0L;

Expand Down Expand Up @@ -80,8 +83,8 @@ public static class DiscordToMinecraftConfig {
+ "ban: A ban/unban on the Discord Server\n"
+ "role: Addition/removal of the banned role (specified above) to the user on Discord\n"
+ "either: Either of the above\n"
+ "BEWARE: Settings of 'role' or 'either' can be exploited to remove bans from players if %1 is set to 'discord'")
@Constants.Comment("tie-breaker")
+ "BEWARE: Settings of 'role' or 'either' can be exploited to remove bans from players if %1 is set to 'discord', and %2 isn't set to `true`")
@Constants.Comment({"tie-breaker", "prefer-discord-on-first-join"})
public BanSyncDiscordTrigger trigger = BanSyncDiscordTrigger.BAN;

@Comment("The reason used when creating new bans in Minecraft")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,8 @@ public IPlayer player() {
public boolean joinedBeforeInitialization() {
return joinedBeforeInitialization;
}

public boolean firstJoin() {
return player.isFirstJoin();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import com.discordsrv.common.abstraction.sync.enums.SyncSide;
import com.discordsrv.common.abstraction.sync.cause.GenericSyncCauses;
import com.discordsrv.api.events.linking.AccountLinkedEvent;
import com.discordsrv.common.events.player.PlayerConnectedEvent;

public class BanSyncModule extends AbstractSyncModule<DiscordSRV, BanSyncConfig, Game, Long, Punishment> {

Expand Down Expand Up @@ -158,6 +162,14 @@ public void applyPunishment(@Nullable Punishment punishment, ISyncCause cause) {
}
}

// Make sure players can't bypass bans by joining the server while banned on Discord
@Subscribe
@Override
public void onPlayerConnected(PlayerConnectedEvent event) {
resyncAll(GenericSyncCauses.GAME_JOIN, Someone.of(discordSRV, event.player()), config -> config.preferDiscordTieBreakerOnFirstJoin && event.firstJoin() ? SyncSide.DISCORD : config.tieBreakers.join);

}

@Subscribe
public void onGuildBan(GuildBanEvent event) {
handleDiscordBanChange(event.getGuild(), event.getUser(), true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ public void removeChatSuggestions(Collection<String> suggestions) {}
return Component.text("Vankka");
}

@Override
public boolean isFirstJoin() {
return false;
}

@Override
public boolean hasPermission(Permission permission) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ private void onJoin(ServerGamePacketListenerImpl serverPlayNetworkHandler, Packe
if (!enabled) return;

ServerPlayer playerEntity = serverPlayNetworkHandler.player;
boolean firstJoin = playerEntity.getStats().getValue(Stats.CUSTOM.get(Stats.LEAVE_GAME)) == 0;

MinecraftComponent component;
if (discordSRV.getNameFromGameProfile(playerEntity.getGameProfile()).equalsIgnoreCase(playerEntity.getName().getString())) {
Expand All @@ -68,7 +67,7 @@ private void onJoin(ServerGamePacketListenerImpl serverPlayNetworkHandler, Packe
player,
component,
null,
firstJoin,
player.isFirstJoin(),
false,
component == null,
false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stats;
import net.minecraft.world.scores.PlayerTeam;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -162,6 +163,11 @@ public void removeChatSuggestions(Collection<String> suggestions) {
return discordSRV.componentFactory().fromNative(team.getFormattedName(player.getName()));
}

@Override
public boolean isFirstJoin() {
return player.getStats().getValue(Stats.CUSTOM.get(Stats.LEAVE_GAME)) == 0;
}

@Override
public boolean isChatVisible() {
//? if minecraft: >1.20.1 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ public boolean isChatVisible() {
&& chatMode != PlayerSettings.ChatMode.HIDDEN;
}

@Override
public boolean isFirstJoin() {
return false;
}

@Override
public String toString() {
return "VelocityPlayer{" + username() + "}";
Expand Down