Add random skin to nicked players
This commit is contained in:
parent
64b19191db
commit
1d0adf7283
|
@ -1,6 +1,7 @@
|
|||
package tc.oc.commons.bukkit.chat;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -29,7 +30,15 @@ public class FlairRenderer implements PartialNameRenderer {
|
|||
@Override
|
||||
public String getLegacyName(Identity identity, NameType type) {
|
||||
if(!(type.style.contains(NameFlag.FLAIR) && type.reveal)) return "";
|
||||
return getFlairs(identity).reduce("", String::concat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseComponent getComponentName(Identity identity, NameType type) {
|
||||
return Components.fromLegacyText(getLegacyName(identity, type));
|
||||
}
|
||||
|
||||
public Stream<String> getFlairs(Identity identity) {
|
||||
final UserDoc.Identity user;
|
||||
if(identity.getPlayerId() instanceof UserDoc.Identity) {
|
||||
// Flair may already be stashed inside the Identity
|
||||
|
@ -37,19 +46,18 @@ public class FlairRenderer implements PartialNameRenderer {
|
|||
} else {
|
||||
user = userStore.tryUser(identity.getPlayerId());
|
||||
}
|
||||
if(user == null) return "";
|
||||
if(user == null) return Stream.empty();
|
||||
|
||||
final Set<String> realms = ImmutableSet.copyOf(minecraftService.getLocalServer().realms());
|
||||
|
||||
return user.minecraft_flair()
|
||||
.stream()
|
||||
.filter(flair -> realms.contains(flair.realm))
|
||||
.map(flair -> flair.text)
|
||||
.reduce("", String::concat);
|
||||
.stream()
|
||||
.filter(flair -> realms.contains(flair.realm))
|
||||
.map(flair -> flair.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseComponent getComponentName(Identity identity, NameType type) {
|
||||
return Components.fromLegacyText(getLegacyName(identity, type));
|
||||
public int getNumberOfFlairs(Identity identity) {
|
||||
return (int) getFlairs(identity).count();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import javax.annotation.Nullable;
|
|||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import org.bukkit.Skin;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
|
@ -14,6 +16,10 @@ import tc.oc.commons.bukkit.chat.NameStyle;
|
|||
import tc.oc.commons.bukkit.chat.NameType;
|
||||
import tc.oc.commons.core.scheduler.Scheduler;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Manages the Bukkit aspects of a player's name and appearance
|
||||
*/
|
||||
|
@ -29,6 +35,8 @@ public class PlayerAppearanceChanger {
|
|||
private final FullNameRenderer nameRenderer;
|
||||
private final UsernameRenderer usernameRenderer;
|
||||
private final FlairRenderer flairRenderer;
|
||||
private final Map<String, Skin> skinAssigned;
|
||||
private final Cache<Skin, Integer> skinPool;
|
||||
|
||||
@Inject
|
||||
PlayerAppearanceChanger(IdentityProvider identityProvider, NicknameConfiguration config, Scheduler scheduler, FullNameRenderer nameRenderer, UsernameRenderer usernameRenderer, FlairRenderer flairRenderer) {
|
||||
|
@ -38,6 +46,11 @@ public class PlayerAppearanceChanger {
|
|||
this.nameRenderer = nameRenderer;
|
||||
this.usernameRenderer = usernameRenderer;
|
||||
this.flairRenderer = flairRenderer;
|
||||
this.skinAssigned = new HashMap<>();
|
||||
this.skinPool = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(1, TimeUnit.HOURS)
|
||||
.maximumSize(30)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,6 +96,7 @@ public class PlayerAppearanceChanger {
|
|||
* Release any resources being used to maintain the given player's appearance
|
||||
*/
|
||||
public void cleanupAfterPlayer(Player player) {
|
||||
skinPool.put(player.getRealSkin(), flairRenderer.getNumberOfFlairs(identityProvider.createIdentity(player)));
|
||||
if(config.overheadFlair()) {
|
||||
// Remove players from their "overhead flair team" on quit
|
||||
final Team team = player.getServer().getScoreboardManager().getMainScoreboard().getPlayerTeam(player);
|
||||
|
@ -100,7 +114,7 @@ public class PlayerAppearanceChanger {
|
|||
player.setFakeNameAndSkin(viewer, null, null);
|
||||
player.setFakeDisplayName(viewer, null);
|
||||
} else {
|
||||
player.setFakeNameAndSkin(viewer, identity.getNickname(), Skin.EMPTY);
|
||||
player.setFakeNameAndSkin(viewer, identity.getNickname(), getRandomSkin(fakeDisplayName));
|
||||
player.setFakeDisplayName(viewer, fakeDisplayName);
|
||||
}
|
||||
}
|
||||
|
@ -125,4 +139,34 @@ public class PlayerAppearanceChanger {
|
|||
private @Nullable String renderLegacyNickname(Identity identity) {
|
||||
return identity.getNickname() == null ? null : nameRenderer.getLegacyName(identity, NICKNAME_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random skin from users that have recently disconnected.
|
||||
* Prioritize skins that come from players with fewer flairs.
|
||||
*/
|
||||
private Skin getRandomSkin(@Nullable String nickname) {
|
||||
Skin skin;
|
||||
if(skinAssigned.containsKey(nickname)) {
|
||||
skin = skinAssigned.get(nickname);
|
||||
} else {
|
||||
skin = skinPool.asMap()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.<Skin, Integer>comparingByValue()
|
||||
.reversed()
|
||||
.thenComparing(entry -> entry.getKey().hashCode()))
|
||||
.map(Map.Entry::getKey)
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
if(skin != null) {
|
||||
skinPool.invalidate(skin);
|
||||
} else {
|
||||
skin = Skin.EMPTY;
|
||||
}
|
||||
if(nickname != null) {
|
||||
skinAssigned.put(nickname, skin);
|
||||
}
|
||||
}
|
||||
return skin;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ public class PlayerTabEntry extends DynamicTabEntry {
|
|||
@Override
|
||||
public @Nullable Skin getSkin(TabView view) {
|
||||
final Identity identity = identityProvider.currentIdentity(player);
|
||||
return identity.isDisguised(view.getViewer()) ? null : player.getSkin();
|
||||
return identity.isDisguised(view.getViewer()) ? player.getFakeSkin(view.getViewer()) : player.getSkin();
|
||||
}
|
||||
|
||||
// Dispatched by TabManager
|
||||
|
|
Loading…
Reference in New Issue