Skip to content

Commit

Permalink
Implement custom skin textures, and fix it not showing up
Browse files Browse the repository at this point in the history
  • Loading branch information
Mindgamesnl committed Dec 11, 2024
1 parent f17350a commit 10292cc
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
java adoptopenjdk-8.0.332+9
java openjdk-21
2 changes: 1 addition & 1 deletion plugin/src/main/bash/data.bin
Original file line number Diff line number Diff line change
@@ -1 +1 @@
BUILD_NUM="1491"
BUILD_NUM="1497"
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public void handleMigrations() {
new AddConfigKeyMigration(SETTINGS_AUTO_RECONNECT, "Add a migration setting for auto reconnect"),
new AddConfigKeyMigration(SETTINGS_SPEAKER_MAX_RANGE, "Add max range config value"),
new AddConfigKeyMigration(SETTINGS_STATIC_CHANNELS_SHOW_IN_WEB_UI, "Add a setting to show the channels web UI"),
new AddConfigKeyMigration(SETTINGS_SPEAKER_SKIN_UUID, "Add a setting for the speaker skin textures"),
};

for (SimpleMigration migration : migrations) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public enum StorageKey {
SETTINGS_PAPI_VC_CONNECTED(false, "papi.voicechat-connected", StorageLocation.CONFIG_FILE),
SETTINGS_PAPI_VC_DISCONNECTED(false, "papi.voicechat-disconnected", StorageLocation.CONFIG_FILE),

SETTINGS_SPEAKER_SKIN_NAME(false, "speaker-skin.profile-name", StorageLocation.CONFIG_FILE),
SETTINGS_SPEAKER_SKIN_UUID(false, "speaker-skin.profile-uuid", StorageLocation.CONFIG_FILE),
SETTINGS_SPEAKER_SKIN_TEXTURE(false, "speaker-skin.texture-url", StorageLocation.CONFIG_FILE),


DEBUG_LOG_STATE_CHANGES(false, "debug.log-state-changes", StorageLocation.DATA_FILE),

AUTH_HOST(true, "keyset.server-ip", StorageLocation.DATA_FILE),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,41 @@
import com.craftmend.openaudiomc.spigot.OpenAudioMcSpigot;
import com.craftmend.openaudiomc.spigot.modules.speakers.SpeakerService;
import com.craftmend.openaudiomc.spigot.services.server.enums.ServerVersion;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTItem;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.block.Skull;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;

import java.util.Arrays;
import java.util.Base64;
import java.util.UUID;

public class SpeakerUtils {
import static com.craftmend.openaudiomc.generic.storage.enums.StorageKey.*;

public static final String speakerSkin = "OpenAudioMc";
public static final UUID speakerUUID = UUID.fromString("c0db149e-d498-4a16-8e35-93d57577589f");
private static final SpeakerService SPEAKER_SERVICE = OpenAudioMc.getService(SpeakerService.class);
public class SpeakerUtils {

private static OfflinePlayer proxiedPlayer;
public static final String speakerSkin = SETTINGS_SPEAKER_SKIN_NAME.getString();
public static final UUID speakerUUID = UUID.fromString(SETTINGS_SPEAKER_SKIN_UUID.getString());
public static final String textureValue;

static {
// attempt to create a offline player instance
try {
proxiedPlayer = new ClassMocker<OfflinePlayer>(OfflinePlayer.class)
.addReturnValue("getUniqueId", speakerUUID)
.addReturnValue("getName", speakerSkin)
.createProxy();
} catch (Exception e) {
OpenAudioLogger.warn("Failed to create a OfflinePlayer proxy class. This will cause issues with speakers on servers running post 1.20.2");
}
String rawUrl = SETTINGS_SPEAKER_SKIN_TEXTURE.getString();
// convert to http instead of https, don't know if its important, but lets stick with what our
// mojang gods decided
rawUrl = rawUrl.replace("https://", "http://");

// turn it into the json format, our gods have also decided this is the way to go
String json = "{textures:{SKIN:{url:\"" + rawUrl + "\"}}}";
textureValue = Base64.getEncoder().encodeToString(json.getBytes());
}

private static final SpeakerService SPEAKER_SERVICE = OpenAudioMc.getService(SpeakerService.class);

public static boolean isSpeakerSkull(Block block) {
if (block.getState() instanceof Skull) {
Skull skull = (Skull) block.getState();
Expand Down Expand Up @@ -65,18 +68,31 @@ public static boolean isSpeakerSkull(Block block) {
public static ItemStack getSkull(String source, int radius) {
ItemStack skull = new ItemStack(SPEAKER_SERVICE.getPlayerSkullItem());
skull.setDurability((short) 3);

// For Minecraft 1.20.4 and below
NBT.modify(skull, nbt -> {
ReadWriteNBT skullOwnerCompound = nbt.getOrCreateCompound("SkullOwner");

// The owner UUID. Note that skulls with the same UUID but different textures will misbehave and only one texture will load.
// They will share the texture. To avoid this limitation, it is recommended to use a random UUID.
skullOwnerCompound.setUUID("Id", UUID.randomUUID());

skullOwnerCompound.getOrCreateCompound("Properties")
.getCompoundList("textures")
.addCompound()
.setString("Value", textureValue);
});

NBT.modifyComponents(skull, nbt -> {
ReadWriteNBT profileNbt = nbt.getOrCreateCompound("minecraft:profile");
profileNbt.setUUID("id", speakerUUID);
ReadWriteNBT propertiesNbt = profileNbt.getCompoundList("properties").addCompound();
propertiesNbt.setString("name", "textures");
propertiesNbt.setString("value", textureValue);
});

SkullMeta sm = (SkullMeta) skull.getItemMeta();
if (sm != null) {
if (SPEAKER_SERVICE.getVersion() == ServerVersion.MODERN) {
if (proxiedPlayer != null) {
sm.setOwningPlayer(proxiedPlayer);
} else {
// fallback for servers that don't support the proxy class
sm.setOwningPlayer(Bukkit.getOfflinePlayer(speakerUUID));
}
}

sm.setOwner(speakerSkin);
sm.setDisplayName(ChatColor.AQUA + "OpenAudioMc Speaker");
sm.setLore(Arrays.asList(
ChatColor.AQUA + "I'm a super cool speaker!",
Expand Down
14 changes: 14 additions & 0 deletions plugin/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,20 @@ cdn:
enabled: false
skip-validation: false

# The speaker skin defines the look and feel of your speakers.
speaker-skin:
# The texture of the speaker's skull. This can't be any online value, it has to be from the mojang texture service.
# You can find a texture url from a name, using a site like https://mcprofile.io/
texture-url: https://textures.minecraft.net/texture/6a5fed371c2231879a5b4c413c94d81e139dc3c21449128333469a439d7b9561

# The default is a Minecraft account called "OpenAudioMc"
# This has to match the profile-uuid, and is case sensitive.
#
# IMPORTANT: Changing the profile n ame or UUID will break all existing speakers in your world.
# IMPORTANT: Only 'new' speakers with the configured profile name and UUID be detected
profile-name: OpenAudioMc
# The game profile UUID of the spaeker's skull owner. Has to be a valid/premium minecraft account.
profile-uuid: c0db149e-d498-4a16-8e35-93d57577589f

# REDIS
# This is only used for syncing shows with other servers and the vistas modules.
Expand Down
2 changes: 1 addition & 1 deletion plugin/src/main/resources/data.bin
Original file line number Diff line number Diff line change
@@ -1 +1 @@
BUILD_NUM="1491"
BUILD_NUM="1497"
4 changes: 2 additions & 2 deletions plugin/src/main/resources/openaudiomc-build.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
BUILD_VERSION="1491"
BUILD_COMMIT="3c3773db2653a2e98dce48cd5d479d01c7ad7134"
BUILD_VERSION="1497"
BUILD_COMMIT="f17350ae1d8dd428fe6ce03024e30a18ca83b508"
BUILD_AUTHOR="Mats"

0 comments on commit 10292cc

Please sign in to comment.