///
///
import Feature from "../../featureClass/class";
import DragonWings from "./cosmetic/dragon/dragonWings"
import Toggle from "../settings/settingThings/toggle"
import { f } from "../../../mappings/mappings";
import FakeRequireToggle from "../settings/settingThings/FakeRequireToggle";
class Cosmetics extends Feature {
constructor() {
super()
}
onEnable() {
this.initVariables()
this.loadedCosmetics = []
this.uuidToCosmetic = {}
this.uuidToCosmeticDirect = {}
this.cosmeticsData = {}
this.hiddenEssentialCosmetics = []
this.cosmeticsList = {
"dragon_wings": DragonWings
}
this.playerHasACosmeticA = false
this.firstPersonVisable = new Toggle("Cosmetics visable in first person", "", false, "cosmetics_first_person_visable", this)
this.lessFirstPersonVisable = new Toggle("Make cosmetics less visable in first person mode", "", true, "cosmetics_first_person_less_visable", this).requires(this.firstPersonVisable)
this.ownCosmeticAudio = new Toggle("Audio for own cosmetics", "", false, "cosmetics_own_audio", this)
this.dragon_wings_enabled = new Toggle("Dragon Wings Toggle", "", true, "cosmetic_dragon_wings_toggle", this).requires(new FakeRequireToggle(false)).onchange(this, () => {
global.soopyV2Server.updateCosmeticsData({
cosmetic: "dragon_wings",
type: this.dragon_wings_enabled.getValue() ? "enable" : "disable"
})
})
this.postRenderEntityTrigger = undefined
this.loadCosmeticsData()
this.worldLoad()
this.registerEvent("tick", this.tick)
this.registerEvent("renderWorld", this.renderWorld)
this.registerEvent("playerJoined", this.playerJoined)
this.registerEvent("playerLeft", this.playerLeft)
this.registerEvent("worldLoad", this.worldLoad)
this.registerStep(false, 2, this.step)
this.registerEvent('gameUnload', () => {
if (this.postRenderEntityTrigger) {
this.postRenderEntityTrigger.unregister()
this.postRenderEntityTrigger = undefined
}
})
// this.registerStep(false, 60*10, ()=>{
// new Thread(()=>{this.loadCosmeticsData.call(this)}).start()
// })
// this.registerEvent("renderEntity", this.renderEntity)
if (global.soopyV2Server && global.soopyV2Server.userCosmeticPermissions) {
this.updateUserCosmeticPermissionSettings()
}
}
updateUserCosmeticPermissionSettings() {
if (!this.enabled) return
if (global.soopyV2Server.userCosmeticPermissions === "*" || global.soopyV2Server.userCosmeticPermissions.dragon_wings) {
this.dragon_wings_enabled.requiresO.set(true)
} else {
this.dragon_wings_enabled.requiresO.set(false)
}
}
renderWorld(ticks) {
for (let i = 0; i < this.loadedCosmetics.length; i++) {
this.loadedCosmetics[i].onRenderEntity(ticks, false)
}
}
async loadCosmeticsData() {
let data = await fetch("https://soopy.dev/api/soopyv2/cosmetics.json").json()
this.cosmeticsData = data
this.playerHasACosmeticA = !!data[Player.getUUID().toString().replace(/-/g, "")]
if (this.playerHasACosmeticA && !this.postRenderEntityTrigger) {
// this.registerEvent("postRenderEntity", this.renderEntity)
this.postRenderEntityTrigger = register("postRenderEntity", (entity, pos, ticks, event) => {
if (ticks !== 1) return
if (this.uuidToCosmeticDirect[entity.getUUID().toString().replace(/-/g, "")]) {
let cosmetics = Object.values(this.uuidToCosmeticDirect[entity.getUUID().toString().replace(/-/g, "")])
for (let cosmetic of cosmetics) {
cosmetic.onRenderEntity(ticks, true)
}
}
})
}
this.scanForNewCosmetics()
}
setUserCosmeticsInformation(uuid, cosmetics) {
if (!this.enabled) return
uuid = uuid.replace(/-/g, "")
this.loadedCosmetics = this.loadedCosmetics.filter(cosmetic => {
if (cosmetic.player.getUUID().toString().replace(/-/g, "") === uuid) {
return false
}
return true
})
Object.keys(this.uuidToCosmetic).forEach(cosmeticName => {
delete this.uuidToCosmetic[cosmeticName][uuid]
})
delete this.uuidToCosmeticDirect[uuid]
if (!cosmetics) {
delete this.cosmeticsData[uuid]
return
}
this.cosmeticsData[uuid] = cosmetics
this.scanForNewCosmetics()
}
step() {
this.scanForNewCosmetics()
this.filterUnloadedCosmetics(false)
this.restoreEssentialCosmetics()
this.loadedCosmetics.forEach(c => {
c.removeEssentialCosmetics()
})
}
scanForNewCosmetics() {
this.loadCosmeticsForPlayer(Player)
World.getAllPlayers().forEach(p => {
if (p.getUUID().toString().replace(/-/g, "") === Player.getUUID().toString().replace(/-/g, "")) return
this.loadCosmeticsForPlayer(p)
})
}
loadCosmeticsForPlayer(player) {
Object.keys(this.cosmeticsList).forEach(cosmeticName => {
if (!this.uuidToCosmetic[cosmeticName]) this.uuidToCosmetic[cosmeticName] = {}
if (this.uuidToCosmetic[cosmeticName][player.getUUID().toString().replace(/-/g, "")]) return
if (this.shouldPlayerHaveCosmetic(player, cosmeticName)) {
let cosmetic = new (this.cosmeticsList[cosmeticName])(player, this)
this.loadedCosmetics.push(cosmetic)
this.uuidToCosmetic[cosmeticName][player.getUUID().toString().replace(/-/g, "")] = cosmetic
if (!this.uuidToCosmeticDirect[player.getUUID.toString()]) this.uuidToCosmeticDirect[player.getUUID().toString().replace(/-/g, "")] = {}
this.uuidToCosmeticDirect[player.getUUID().toString().replace(/-/g, "")][cosmeticName] = cosmetic
}
})
}
worldLoad() {
this.loadedCosmetics = []
this.uuidToCosmetic = {}
this.uuidToCosmeticDirect = {}
this.loadCosmeticsForPlayer(Player)
this.scanForNewCosmetics()
}
playerJoined(player) {
if (player.getUUID().toString().replace(/-/g, "") === Player.getUUID().toString().replace(/-/g, "")) return
this.loadCosmeticsForPlayer(player)
}
playerLeft(playerName) {
this.loadedCosmetics = this.loadedCosmetics.filter(cosmetic => {
if (cosmetic.player.getUUID().toString().replace(/-/g, "") === Player.getUUID().toString().replace(/-/g, "")) return true
if (cosmetic.player.getName() === playerName) {
this.uuidToCosmetic[cosmetic.id][cosmetic.player.getUUID().toString().replace(/-/g, "")] = undefined
this.uuidToCosmeticDirect[cosmetic.player.getUUID().toString().replace(/-/g, "")] = undefined
return false
}
return true
})
}
shouldPlayerHaveCosmetic(player, cosmetic) {
if (this.getPlayerCosmeticSettings(player, cosmetic)) {
if (!this.getPlayerCosmeticSettings(player, cosmetic).enabled) return false
return true
}
return false
}
getPlayerCosmeticSettings(player, cosmetic) {
return this.cosmeticsData[player.getUUID().toString().replace(/-/g, "")]?.[cosmetic]
}
filterUnloadedCosmetics(tick = false) {
this.loadedCosmetics = this.loadedCosmetics.filter(cosmetic => {
if (tick) cosmetic.onTick()
if (cosmetic.player.getUUID().toString().replace(/-/g, "") === Player.getUUID().toString().replace(/-/g, "")) return true
if (cosmetic.player.getPlayer()[f.isDead]) { //filter out players that are no longer loaded
this.uuidToCosmetic[cosmetic.id][cosmetic.player.getUUID().toString().replace(/-/g, "")] = undefined
this.uuidToCosmeticDirect[cosmetic.player.getUUID().toString().replace(/-/g, "")] = undefined
return false
}
return true
})
}
tick() {
for (let cosmetic of this.loadedCosmetics) {
cosmetic.onTick()
}
}
restoreEssentialCosmetics() {
this.hiddenEssentialCosmetics.forEach(cosmetic => {
setField(cosmetic, "showModel", true)
})
this.hiddenEssentialCosmetics = []
}
initVariables() {
this.loadedCosmetics = undefined
this.uuidToCosmetic = undefined
this.uuidToCosmeticDirect = {}
this.playerHasACosmeticA = undefined
this.cosmeticsData = undefined
this.hiddenEssentialCosmetics = undefined
this.hiddenEssentialCosmetics = undefined
this.cosmeticsList = undefined
}
onDisable() {
if (this.postRenderEntityTrigger) {
this.postRenderEntityTrigger.unregister()
this.postRenderEntityTrigger = undefined
}
this.restoreEssentialCosmetics()
this.initVariables()
}
}
let instance = new Cosmetics()
module.exports = {
class: instance
}
function setField(e, field, value) {
let field2 = e.class.getDeclaredField(field);
field2.setAccessible(true)
return field2.set(e, value)
}