// ==UserScript==
// @name Brick Hill Outfit Randomizer And Purge
// @version 1.0
// @description Adds 2 buttons to randomize and purge your avatar
// @author Noah Cool Boy
// @match https://www.brick-hill.com/customize/
// @namespace https://greasyfork.org/users/725966
// ==/UserScript==
let token = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let outfitCard = document.querySelector(".outfit-card .content")
let buttons = document.createElement("div")
buttons.style.display = "flex"
buttons.style.marginTop = "5px"
buttons.innerHTML = `<button class="blue" style="width: 100%; margin-right: 5px" onclick="rand()">Randomize</button><button class="red" style="width: 100%; margin-left: 5px" onclick="purge()">Purge</button>`
// No judging please ^
outfitCard.appendChild(buttons)
document.purge = async function() {
// THIS IS SLOW AND BAD AAAAAAAAAAAAAAAAAA (thanks for the rate limiting, jefemy)
let status = document.createElement("span")
outfitCard.appendChild(status)
status.innerText = "Starting..."
let defaultColors = {Head:"F3B700", "Left Arm": "F3B700", "Right Arm": "F3B700", "Torso":"3292D3", "Left Leg": "85AD00", "Right Leg":"85AD00"}
let keys = Object.keys(defaultColors)
for(let x = 0; x < keys.length; x++) {
let key = keys[x]
let req = new XMLHttpRequest()
req.open("POST", "/api/avatar/process", false)
req.withCredentials = true
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
status.innerText = "Resetting "+key
req.send(`_token=${token}&type=color&part=${key}&color=${defaultColors[key]}`) // Why is this api so slow??
await wait(5)
}
setTimeout(()=>{
status.innerText = "Resetting clothing"
let http = new XMLHttpRequest()
http.open("GET", "/api/avatar/wearing", false) // Only gangstas don't use async :sunglasses:
http.withCredentials = true
http.send()
let wearing = JSON.parse(http.responseText)
wearing.forEach((clothing, i) => {
setTimeout(()=>{
avatarUpdate("remove", clothing.id)
}, i*1500)
})
setTimeout(()=>{document.location.reload()}, wearing.length*1500+1500)
}, 1000)
}
let types = {}
document.querySelectorAll(".item-types a").forEach(v=>{
if(v.innerText == "Outfits") return
types[v.getAttribute("data-url")] = v.innerText
})
document.rand = function() {
let modal = document.createElement("div")
modal.className = "modal"
modal.innerHTML = `<div class="modal-content"><span class="close">x</span>Random Outfit Generator<hr>What would you like to randomize?<br>${Object.values(types).map(v=>`<div class="option"><input type="checkbox" checked>${v}<br></div>`).join("")}<div class="colors"><input type="checkbox">Body Colors<br></div><div class="modal-buttons"><button class="green">Randomize!</button></div></div>`
modal.querySelector(".close").addEventListener("click",()=>{
modal.remove()
})
modal.querySelector("button").addEventListener("click", ()=>{
randomize(modal)
})
outfitCard.appendChild(modal)
}
function wait(ms) {
return new Promise(a => {
setTimeout(a, ms)
})
}
function randomize(modal) {
modal.querySelector(".close").remove()
modal.querySelector("button").remove()
let status = document.createElement("span")
modal.querySelector(".modal-content").appendChild(status)
let ad = document.createElement("img")
ad.src = "https://noah.ovh/bh/randomizer/"
ad.alt = "This used to be an ad"
ad.style.marginTop = "10px"
ad.width = 400
modal.querySelector(".modal-content").appendChild(ad)
let opts = [...modal.querySelectorAll(".option")].map(v => v.innerText.trim())
setTimeout(async ()=>{
let inventory = {}
if(window.localStorage.randomizer_cache && window.localStorage.randomizer_cache_date && Date.now() - window.localStorage.randomizer_cache_date < 1000 * 60 * 60 * 24) {
inventory = JSON.parse(window.localStorage.randomizer_cache)
} else {
for(let x = 0; x < opts.length; x++) {
let type = opts[x]
inventory[type] = []
let apiType = Object.keys(types).find(key => types[key] == type)
let page = 1
while(true) {
let req = new XMLHttpRequest()
req.open("GET","/api/avatar/crate/"+apiType+"/"+page,false)
req.withCredentials = true
req.send()
let data = JSON.parse(req.responseText)
inventory[type] = inventory[type].concat(data.data.map(v=>v.item_id))
if(data.pages.current >= data.pages.pageCount) {
break
}
page++
//console.log(`Getting ${type} ${data.pages.current}/${data.pages.pageCount}`)
await wait(5)
status.innerText = `Getting ${type} ${data.pages.current}/${data.pages.pageCount}`
}
}
//console.log(inventory)
//console.log(JSON.stringify(inventory))
window.localStorage.randomizer_cache = JSON.stringify(inventory)
window.localStorage.randomizer_cache_date = Date.now()
}
opts = [...modal.querySelectorAll(".option")].map(v => [v.innerText.trim(), v.querySelector("input").checked])
opts = opts.filter(v=>v[1]).map(v=>v[0])
Object.keys(inventory).filter(v => !opts.includes(v)).forEach(v=>delete inventory[v])
if(inventory.Hats) {
inventory.Hats2 = inventory.Hats
inventory.Hats3 = inventory.Hats
}
let messages = ["Shuffling the stuff", "Doing things", "Randomizing the avatar", "Making your new outfit", "Tiny computer is thinking", "Generating a combo", "The machine is hard at work"]
status.innerText = messages[Math.floor(Math.random()*messages.length)]
let outfit = Object.values(inventory).filter(v=>v.length).map(v=>v[Math.floor(Math.random()*v.length)])
for(let x = 0; x < outfit.length; x++) {
avatarUpdate("wear", outfit[x])
await wait(1000)
}
let bodyColors = modal.querySelector(".colors > input")
if(bodyColors.checked) {
console.log("Checked!")
let bodyParts = ["Torso", "Left Arm", "Right Arm", "Left Leg", "Right Leg", "Head"]
for(let x = 0; x < bodyParts.length; x++) {
let req = new XMLHttpRequest()
req.open("POST", "/api/avatar/process", false)
req.withCredentials = true
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
let randColor = Array(6).fill(0).map(v=>"0123456789ABCDEF"[Math.floor(Math.random()*16)]).join("")
req.send(`_token=${token}&type=color&part=${bodyParts[x]}&color=${randColor}`)
let parts = [...document.querySelectorAll(".part-btn")] // es-lint is NOT happy so I had to make it 2 lines
parts.find(v=>v.onclick.toString().includes(bodyParts[x])).style.backgroundColor = "#"+randColor
await wait(5)
}
window.location.reload() // I didn't find any way to force reload the avatar preview
} else {
modal.remove()
}
}, 1)
}