用于从 quixel 添加所有项目的脚本
由于 quixel 正在被移除,因此所有项目都可以免费获取。此脚本用于自动执行将项目添加到帐户的过程(截至撰写本文时,项目总数)18874
注意:此脚本仅在最新版本的 Chrome 中进行了测试。
如何使用
- 从下面复制脚本 (
run.js
) - 登录 https://quixel.com
- 前往 https://quixel.com/megascans/collections
- 打开 devtools (F12) -> 转到“控制台”选项卡
- 粘贴脚本并按 。Enter
- 应弹出一个确认执行的对话框,单击“确定”
- 坐下来等待
常见问题
- 收到 “Forbidden” 错误。(即使刷新后,整个页面也只显示 “禁止”)
- API 添加速度过快,您有可能达到 API 的速率限制。(我的测试大约在 10 页之后,所以 ~10k 项)。
- 等待 ~10-20 分钟后,然后继续。请参阅在加载 https://quixel.com 后继续执行。
Common Fixes -> Restart script
- 脚本似乎已暂停/挂起
- 这可能是太多的伐木。尝试监控脚本,如果它显示 “END PAGE X”,记下页码(以防需要重新启动),然后单击 devtools 中的 “🚫” 图标清除控制台。
- 请参见修复。
Common Fixes -> Restart script
- 收到错误
**UNABLE TO ADD ITEM**
- 应该有 所示的错误消息。如果是 ,则它已在您的账户中。
( )
user already owns specified asset at a higher or equal resolution
- 应该有 所示的错误消息。如果是 ,则它已在您的账户中。
- 收到错误
cannot find authentication token. Please login again
- 清除浏览器 Cookie 并重新登录 quixel。尝试简单地手动添加 1 项。如果成功,请参阅 继续执行。
Common Fixes -> Restart script
- 清除浏览器 Cookie 并重新登录 quixel。尝试简单地手动添加 1 项。如果成功,请参阅 继续执行。
常见修复
重启脚本
- 记下它正在运行的页面
- 复制脚本
run.js
- 将第一行的 更新为 (假设第 10 页已挂起)
startPage = 0
startPage = 10
更改日志
- 初始脚本启动
- 更新以清除日志以减少挂起的可能性
- [当前]跳过添加已获取的项目。减少日志。在脚本完成后添加了更多信息以显示购买的物品数量。由于现在跳过了购买的项目,因此从技术上讲,您不再需要指定 。
startPage
((async (startPage = 0, autoClearConsole = true) => {
const getCookie = (name) => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
const callCacheApi = async (params = {}) => {
const defaultParams = {
page: 0,
maxValuesPerFacet: 1000,
hitsPerPage: 1000,
attributesToRetrieve: ["id", "name"].join(",")
}
const response = await fetch("https://proxy-algolia-prod.quixel.com/algolia/cache", {
"headers": {
"x-api-key": "2Zg8!d2WAHIUW?pCO28cVjfOt9seOWPx@2j"
},
"body": JSON.stringify({
url: "https://6UJ1I5A072-2.algolianet.com/1/indexes/assets/query?x-algolia-application-id=6UJ1I5A072&x-algolia-api-key=e93907f4f65fb1d9f813957bdc344892",
params: new URLSearchParams({ ...defaultParams, ...params }).toString()
}),
"method": "POST",
})
return await response.json()
}
const callAcl = async ({ id, name }) => {
const response = await fetch("https://quixel.com/v1/acl", {
"headers": {
"authorization": "Bearer " + authToken,
"content-type": "application/json;charset=UTF-8",
},
"body": JSON.stringify({ assetID: id }),
"method": "POST",
});
const json = await response.json()
if (json?.isError) {
console.error(` --> **UNABLE TO ADD ITEM** Item ${id} | ${name} (${json?.msg})`)
} else {
console.log(` --> ADDED ITEM Item ${id} | ${name}`)
}
}
const callAcquired = async () => {
const response = await fetch("https://quixel.com/v1/assets/acquired", {
"headers": {
"authorization": "Bearer " + authToken,
"content-type": "application/json;charset=UTF-8",
},
"method": "GET",
});
return await response.json()
}
// 1. Check token exist, quixel API needs it
console.log("-> Checking Auth API Token...")
let authToken = ""
try {
const authCookie = getCookie("auth") ?? "{}"
authToken = JSON.parse(decodeURIComponent(authCookie))?.token
if (!authToken) {
return console.error("-> Error: cannot find authentication token. Please login again.")
}
} catch (_) {
return console.error("-> Error: cannot find authentication token. Please login again.")
}
// 2. Get all currently acquired items
console.log("-> Get Acquired Items...")
const acquiredItems = (await callAcquired()).map(a => a.assetID)
// 3. Get total count of items
console.log("-> Getting Total Number of Pages....")
const { nbPages: totalPages, hitsPerPage: itemsPerPage, nbHits: totalItems } = await callCacheApi()
console.log("-> ==============================================")
console.log(`-> Total # of items: ${totalItems}`)
console.log(`-> ${totalPages} total pages with ${itemsPerPage} per page`)
console.log(`-> Total Items to add: ${(totalItems - acquiredItems.length)}.`)
console.log("-> ==============================================")
if (!confirm(`Click OK to start adding ${(totalItems - acquiredItems.length)} items in your account.`)) return
// Loop
for (let pageIdx = startPage || 0; pageIdx < totalPages; pageIdx++) {
console.log(`-> ======================= PAGE ${pageIdx + 1}/${totalPages} START =======================`)
console.log("-> Getting Items from page " + (pageIdx + 1) + " ...")
const { hits: items } = await callCacheApi({ page: pageIdx })
console.log("-> Adding non-acquired items...")
// Filter out owned items
const unownedItems = items.filter(i => !acquiredItems.includes(i.id))
const aclPromises = unownedItems.map(callAcl)
await Promise.all(aclPromises)
console.log(`-> ======================= PAGE ${pageIdx + 1}/${totalPages} COMPLETED =======================`)
if (autoClearConsole) console.clear() // Fix the issue that too much log hangs the console. Set autoClearConsole = false to keep the logs
}
console.log("-> Getting new acquired info...")
// Get acquired items again
const newItemsAcquired = (await callAcquired()).length
const newTotalCount = (await callCacheApi()).nbHits
console.log(`-> Completed. Your account now have a total of ${newItemsAcquired} out of ${newTotalCount} items.`)
alert(`-> Your account now have a total of ${newItemsAcquired} out of ${newTotalCount} items.\n\nIf you find some items missing, try refresh the page and run the script again.`)
})())
请先
!