diff --git a/js/account/avatar-sandbox-rewrite.js b/js/account/avatar-sandbox-rewrite.js deleted file mode 100644 index 8846f4f..0000000 --- a/js/account/avatar-sandbox-rewrite.js +++ /dev/null @@ -1,618 +0,0 @@ -let Utilities; - -const Container = document.querySelector('.container.p-0.p-lg-5') -const ItemCache = { - 24122: { - type: "hat", - accessoryType: "hat", - name: "Polytoria Cap", - price: 0, - creator: { - name: "Polytoria", - id: 1 - }, - thumbnail: "https://c0.ptacdn.com/thumbnails/assets/RR0VPd5hX30Fx5APwRBGObotf1xD1DRT.png", - asset: "https://c0.ptacdn.com/assets/InBsL5bpJdp84ZPZGQMeHuyCBlo-uOv7.glb" - }, - 24118: { - type: "shirt", - name: "Green Polytoria Flannel", - price: 0, - creator: { - name: "Polytoria", - id: 1 - }, - thumbnail: "https://c0.ptacdn.com/thumbnails/assets/s7l57JugjbZfWTKAQ0cqTohOBraRbX5E.png", - asset: "https://c0.ptacdn.com/assets/uWrrnFGwgNN5W171vqYTWY7E639rKiXK.png" - }, - 24123: { - type: "pants", - name: "Jeans", - price: 0, - creator: { - name: "Polytoria", - id: 1 - }, - thumbnail: "https://c0.ptacdn.com/thumbnails/assets/anebTuFMLg8NKhRL3ab7hbzCfmcsFqGO.png", - asset: "https://c0.ptacdn.com/assets/HD6TFdXD8CaflRNmd84VCNyNsmTB0SH3.png" - }, - 37582: { - type: "torso", - name: "Slim Body", - price: 0, - creator: { - name: "Polytoria", - id: 1 - }, - thumbnail: "https://c0.ptacdn.com/thumbnails/assets/f_k-ZN_xmA_ALZiJQanOKT-Y4qq5kI1b.png", - asset: "https://c0.ptacdn.com/assets/qoqZ2qPyaGvB3MLGgJZ6oLWTz-xxGo-8.glb" - } -} -let Avatar = { - useCharacter: true, - items: [24122], - shirt: 24118, - pants: 24123, - headColor: '#e0e0e0', - torsoColor: '#e0e0e0', - leftArmColor: '#e0e0e0', - rightArmColor: '#e0e0e0', - leftLegColor: '#e0e0e0', - rightLegColor: '#e0e0e0' -}; - -/* Discovery */ -let Page = 1 -let PageCount = 1 -let Search = "" -let Sort = "createdAt" -let Order = "desc" -let ShowOffsale = true -let TabSelected = "hat" - -!(async () => { - Utilities = await import(chrome.runtime.getURL('resources/utils.js')); - Utilities = Utilities.default; - - chrome.storage.sync.get(['PolyPlus_Settings'], function(result){ - Settings = result.PolyPlus_Settings || Utilities.DefaultSettings; - - if (Settings.AvatarSandboxOn || 1 === 1) { - if (new URLSearchParams(window.location.search).has('sandbox')) { - document.title = 'Poly+ Avatar Sandbox' - PageLoad() - } else { - const SandboxButton = document.createElement('a'); - SandboxButton.classList = 'btn btn-outline-success w-100 mt-3'; - SandboxButton.href = '?sandbox=true'; - SandboxButton.innerHTML = ' Avatar Sandbox'; - document.getElementById('cont-move').parentElement.appendChild(SandboxButton); - } - } - }) -})(); - -async function PageLoad() { - const PageContents = (await ((await fetch(chrome.runtime.getURL('resources/avatar-sandbox.html'))).text())) - Container.innerHTML = PageContents - Utilities.InjectResource("registerTooltips") - - IFrame = document.getElementById('viewFrame') - - UpdateAvatar() - LoadItems() - - const Tabs = document.getElementById('tabs') - Array.from(Tabs.children).forEach((element) => { - element.addEventListener('click', function () { - let Link = element.getElementsByTagName('a')[0]; - if (!Link.classList.contains('active')) { - Link.classList.add('active'); - Tabs.querySelector(`[data-tab="${TabSelected}"]`).classList.remove('active'); - TabSelected = Link.getAttribute('data-tab'); - ItemSearch.previousElementSibling.value = '' - Page = 1; - Search = "" - LoadItems(); - } - }); - }); - - const ItemSearch = document.getElementById('search-btn') - ItemSearch.addEventListener('click', function(){ - Search = ItemSearch.previousElementSibling.value - Page = 1 - LoadItems() - }) - - const ItemSort = document.getElementById('item-sort') - ItemSort.addEventListener('change', function(){ - Sort = ItemSort.options[ItemSort.selectedIndex].value - Page = 1 - LoadItems() - }) - - const ItemOrder = document.getElementById('item-order') - ItemOrder.addEventListener('change', function(){ - Order = ItemOrder.options[ItemOrder.selectedIndex].value - Page = 1 - LoadItems() - }) - - /* - Public API does not have an offsale parameter - - document.getElementById('show-offsale').addEventListener('change', function(){ - ShowOffsale = !ShowOffsale - console.log(ShowOffsale) - Page = 1 - LoadItems() - }) - */ - - // Pagination is annoying - const First = document.getElementById('pagination-first'); - const Prev = document.getElementById('pagination-prev'); - const Next = document.getElementById('pagination-next'); - const Last = document.getElementById('pagination-last'); - - if (Page > 0) { - Prev.parentElement.classList.remove('disabled'); - First.parentElement.classList.remove('disabled'); - } else { - Prev.parentElement.classList.add('disabled'); - First.parentElement.classList.add('disabled'); - } - - First.addEventListener('click', function () { - if (Page > 1) { - Page = 1; - LoadItems(); - } - }); - - Prev.addEventListener('click', function () { - if (Page > 1) { - Page--; - LoadItems(); - } - }); - - Next.addEventListener('click', function () { - if (Page < PageCount) { - Page++; - LoadItems(); - } - }); - - Last.addEventListener('click', function () { - if (Page < PageCount) { - Page = PageCount; - LoadItems(); - } - }); - - const ClearButton = document.getElementById('clear'); - ClearButton.addEventListener('click', function () { - Avatar = { - useCharacter: true, - items: [24122], - shirt: 24118, - pants: 24123, - headColor: '#e0e0e0', - torsoColor: '#e0e0e0', - leftArmColor: '#e0e0e0', - rightArmColor: '#e0e0e0', - leftLegColor: '#e0e0e0', - rightLegColor: '#e0e0e0' - }; - UpdateAvatar(); - }); - - const LoadMyselfButton = document.getElementById('myself'); - LoadMyselfButton.addEventListener('click', function () { - LoadUser(JSON.parse(window.localStorage.getItem('p+account_info')).ID); - }); - - const JSONUploadButton = document.getElementById('jsonUpload'); - JSONUploadButton.addEventListener('change', function () { - const Reader = new FileReader(); - Reader.addEventListener('loadend', function () { - Avatar = JSON.parse(Reader.result); - UpdateAvatar(); - - JSONUploadButton.value = ''; - }); - - Reader.readAsText(JSONUploadButton.files[0]); - }); - - const JSONSaveButton = document.getElementById('jsonSave'); - JSONSaveButton.addEventListener('click', function () { - const Download = document.createElement('a'); - Download.href = URL.createObjectURL( - new Blob([JSON.stringify(Avatar)], { - type: 'application/json' - }) - ); - Download.setAttribute('download', 'AvatarSandbox.json'); - document.body.appendChild(Download); - Download.click(); - document.body.removeChild(Download); - }); - - const OpenInNewTabButton = document.getElementById('openNewTab'); - OpenInNewTabButton.addEventListener('click', function () { - window.open(IFrame, "_blank") - }); - - const LoadAsset = document.getElementById('load-asset') - const LoadAssetType = document.getElementById('load-asset-type') - LoadAsset.addEventListener('click', function(){ - const SelectedType = LoadAssetType.options[LoadAssetType.selectedIndex].value - - if (SelectedType !== 'user') { - if (SelectedType === 'hat') { - Avatar.items.push(LoadAsset.previousElementSibling.value); - } else { - Avatar[SelectedType] = parseInt(LoadAsset.previousElementSibling.value) - } - UpdateAvatar(); - } else { - LoadUser(LoadAsset.previousElementSibling.value) - } - }) - - document.getElementById('view-cache').addEventListener('click', function(){ - console.log('Cache: ', ItemCache) - }) -} - -async function UpdateAvatar() { - // Hats, Tools: https://api.polytoria.com/v1/assets/serve-mesh/ID - // or: https://api.polytoria.com/v1/assets/serve/ID/Asset - - const FormattedAvatar = structuredClone(Avatar) - - const AccessoryPromise = [...Avatar.items, Avatar.tool, Avatar.torso].filter((x) => x !== undefined && !x.toString().startsWith('http') && !x.toString().startsWith('data:')).map(async (x, index) => { - if (ItemCache[x] === undefined) { - const ItemDetails = (await (await fetch('https://api.polytoria.com/v1/store/' + x)).json()) - ItemCache[x] = { - type: ItemDetails.type, - name: ItemDetails.name, - price: ItemDetails.price, - creator: { - name: ItemDetails.creator.name, - id: ItemDetails.creator.id - }, - thumbnail: ItemDetails.thumbnail, - asset: undefined - } - - if (ItemDetails.type === 'hat') { - ItemCache[x].accessoryType = ItemDetails.accessoryType - } - } - - if (ItemCache[x].asset === undefined) { - const MeshURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + x)).json()) - if (MeshURL.success) { - ItemCache[x].asset = MeshURL.url - - if (["mesh", "decal", "audio"].indexOf(ItemCache[x].type) !== -1) { - ItemCache[x].type = document.getElementById('load-asset-type').options[document.getElementById('load-asset-type').selectedIndex].value - } - - if (ItemCache[x].type === 'hat') { - FormattedAvatar.items[index] = MeshURL.url - } else { - FormattedAvatar[ItemCache[x].type] = MeshURL.url - } - } - } else { - if (ItemCache[x].type === 'hat') { - FormattedAvatar.items[index] = ItemCache[x].asset - } else { - FormattedAvatar[ItemCache[x].type] = ItemCache[x].asset - } - } - }) - - const TexturePromise = [Avatar.shirt, Avatar.pants, Avatar.face].filter((x) => x !== undefined && !x.toString().startsWith('http') && !x.toString().startsWith('data:') && x !== undefined).map(async (x, index) => { - if (ItemCache[x] === undefined) { - const ItemDetails = (await (await fetch('https://api.polytoria.com/v1/store/' + x)).json()) - ItemCache[x] = { - type: ItemDetails.type, - name: ItemDetails.name, - price: ItemDetails.price, - creator: { - name: ItemDetails.creator.name, - id: ItemDetails.creator.id - }, - thumbnail: ItemDetails.thumbnail, - asset: undefined - } - - if (ItemDetails.price === 0) { - if (ItemDetails.sales === 0) { - ItemCache[x].price = null - } else { - ItemCache[x].price = 0 - } - } - } - - if (ItemCache[x].asset === undefined) { - const TextureURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve/' + x + '/Asset')).json()) - if (TextureURL.success) { - ItemCache[x].asset = TextureURL.url - if (x === Avatar.shirt) { - FormattedAvatar.shirt = TextureURL.url - } else if (x === Avatar.pants) { - FormattedAvatar.pants = TextureURL.url - } else if (x === Avatar.face) { - FormattedAvatar.face = TextureURL.url - } - } - } else { - if (x === Avatar.shirt) { - FormattedAvatar.shirt = ItemCache[x].asset - } else if (x === Avatar.pants) { - FormattedAvatar.pants = ItemCache[x].asset - } else if (x === Avatar.face) { - FormattedAvatar.face = ItemCache[x].asset - } - } - }) - - if (Avatar.face === undefined) { - FormattedAvatar.face = "https://c0.ptacdn.com/static/3dview/DefaultFace.png" - } - - await Promise.all(AccessoryPromise) - await Promise.all(TexturePromise) - - console.log('Real Avatar: ', Avatar) - console.log('Formatted: ', FormattedAvatar) - IFrame.addEventListener('load', function(){ - IFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(FormattedAvatar))) - }) - IFrame.src = 'about:blank' - - UpdateBodyColors() - LoadWearing() -} - -async function LoadUser(id) { - fetch('https://api.polytoria.com/v1/users/' + id + '/avatar') - .then((response) => { - if (!response.ok) { - throw new Error('Network not ok'); - } - return response.json(); - }) - .then((data) => { - Avatar.items = []; - - data.assets.forEach((item) => { - if (ItemCache[item.id] === undefined) { - ItemCache[item.id] = { - type: item.type, - name: item.name, - price: null, - creator: null, - thumbnail: item.thumbnail, - asset: item.path - } - - if (item.type === 'hat' || item.type === 'tool' || item.type === 'torso') { - ItemCache[item.id].creator = { - id: 1, - name: "Polytoria" - } - } - } - - if (item.type === 'hat') { - ItemCache[item.id].accessoryType = item.accessoryType - Avatar.items.push(item.id) - } else { - Avatar[item.type] = item.id - } - }); - - Avatar.headColor = '#' + data.colors.head || '#cdcdcd'; - Avatar.torsoColor = '#' + data.colors.torso || '#cdcdcd'; - Avatar.leftArmColor = '#' + data.colors.leftArm || '#cdcdcd'; - Avatar.rightArmColor = '#' + data.colors.rightArm || '#cdcdcd'; - Avatar.leftLegColor = '#' + data.colors.leftLeg || '#cdcdcd'; - Avatar.rightLegColor = '#' + data.colors.rightLeg || '#cdcdcd'; - - UpdateAvatar(); - }) - .catch((error) => { - console.log(error); - }); -} - -async function LoadItems() { - document.getElementById('inventory').innerHTML = '' - - const Items = (await (await fetch('https://api.polytoria.com/v1/store?limit=12&order=' + Order + '&sort=' + Sort + '&showOffsale=' + ShowOffsale + '&types[]='+ TabSelected +'&search=' + Search + '&page=' + Page)).json()) - PageCount = Items.pages - if (Page < PageCount) { - document.getElementById('pagination-next').classList.remove('disabled'); - document.getElementById('pagination-last').classList.remove('disabled'); - } else { - document.getElementById('pagination-next').classList.add('disabled'); - document.getElementById('pagination-last').classList.add('disabled'); - } - if (Page > 1 && PageCount > 1) { - console.log('aaa') - console.log(Page > 1, PageCount > 1) - document.getElementById('pagination-prev').classList.remove('disabled'); - document.getElementById('pagination-first').classList.remove('disabled'); - } else { - document.getElementById('pagination-prev').classList.add('disabled'); - document.getElementById('pagination-first').classList.add('disabled'); - } - document.getElementById('pagination-current').innerText = Page - Items.assets.forEach(item => { - const ItemColumn = document.createElement('div') - ItemColumn.classList = 'col-auto' - ItemColumn.innerHTML = ` -
-
-
- - ${ (item.type === 'hat') ? ` - - ${CleanAccessoryType(item.accessoryType)} - - ` : ''} - -
-
- -
${item.name}
-
- - by ${ (["hat", "tool", "face", "torso"].indexOf(item.type) !== -1) ? 'Polytoria' : item.creator.name } - - Free' : (item.price !== "???") ? 'text-success">$ ' + item.price : 'text-muted">???' } - -
- ` - document.getElementById('inventory').appendChild(ItemColumn) - - ItemCache[item.id] = { - type: item.type, - name: item.name, - price: item.price, - creator: { - name: item.creator.name, - id: item.creator.id - }, - thumbnail: item.thumbnail, - asset: undefined - } - - if (item.price === 0) { - if (item.sales === 0) { - console.log("ITEM IS AWARD-ONLY!!! ", item) - ItemCache[item.id].price = null - } else { - ItemCache[item.id].price = 0 - } - } - - if (item.type === 'hat') { - ItemCache[item.id].accessoryType = item.accessoryType - } - - ItemColumn.getElementsByClassName('p-2')[0].addEventListener('click', function(){ - WearAsset(item) - }) - }) -} - -function LoadWearing() { - document.getElementById('wearing').innerHTML = ''; - [...Avatar.items, Avatar.shirt, Avatar.pants, Avatar.torso].filter((x) => x !== undefined).forEach(id => { - const Cached = Object.values(ItemCache)[Object.keys(ItemCache).indexOf(id.toString())] - if (Cached !== undefined) { - if (Cached.creator === undefined || Cached.creator === null) { - Cached.creator = { - id: 1, - name: "-" - } - } - - if (Cached.price === undefined || Cached.price === null) { Cached.price = "???" } - - const ItemColumn = document.createElement('div') - ItemColumn.classList = 'col-auto' - ItemColumn.innerHTML = ` -
-
-
- - ${ (Cached.type === 'hat') ? ` - - ${CleanAccessoryType(Cached.accessoryType)} - - ` : ''} - -
-
- -
${Cached.name}
-
- - by ${Cached.creator.name || "-"} - - Free' : (Cached.price !== "???") ? 'text-success">$ ' + Cached.price : 'text-muted">???' } - -
- ` - document.getElementById('wearing').appendChild(ItemColumn) - - ItemColumn.getElementsByClassName('p-2')[0].addEventListener('click', function(){ - WearAsset(Cached) - }) - } - }) -} - -function WearAsset(details) { - const ItemID = Object.keys(ItemCache)[Object.values(ItemCache).indexOf(details)] - if (Avatar[details.type] !== details.id && Avatar.items.indexOf(details.id) === -1) { - // Equip - if (details.type === 'hat') { - Avatar.items.push(details.id) - } else { - Avatar[details.type] = details.id - } - } else { - // Unequip - if (details.type === 'hat') { - Avatar.items.splice(Avatar.items.indexOf(ItemID), 1); - } else { - Avatar[details.type] = undefined - } - } - - UpdateAvatar() - LoadWearing() -} - -function UpdateBodyColors() { - const BodyColors = { - head: Avatar.headColor, - torso: Avatar.torsoColor, - leftArm: Avatar.leftArmColor, - rightArm: Avatar.rightArmColor, - leftLeg: Avatar.leftLegColor, - rightLeg: Avatar.rightLegColor - } - - Object.keys(BodyColors).forEach((elementID, i) => { - document.getElementById(elementID).style.backgroundColor = Object.values(BodyColors)[i] - }) -} - -function CleanAccessoryType(type) { - const CleanAccessoryTypes = { - hat: "Hat", - backAccessory: "Back Accessory", - faceAccessory: "Face Accessory", - headAttachment: "Head Attachment", - hair: "Hair", - neckAccessory: "Neck Accessory", - headCover: "Head Cover", - headAccessory: "Head Accessory" - } - return Object.values(CleanAccessoryTypes)[Object.keys(CleanAccessoryTypes).indexOf(type)] || "!!!"+type -} \ No newline at end of file diff --git a/js/account/avatar-sandbox.js b/js/account/avatar-sandbox.js old mode 100755 new mode 100644 index 7b19c15..8846f4f --- a/js/account/avatar-sandbox.js +++ b/js/account/avatar-sandbox.js @@ -1,17 +1,58 @@ -let PageContainer = document.querySelector('.container.p-0.p-lg-5'); -let ItemGrid; -let Wearing; -let Tabs; -let IFrame; -let TabSelected = 'hat'; -let Search; -let Page = 1; +let Utilities; + +const Container = document.querySelector('.container.p-0.p-lg-5') +const ItemCache = { + 24122: { + type: "hat", + accessoryType: "hat", + name: "Polytoria Cap", + price: 0, + creator: { + name: "Polytoria", + id: 1 + }, + thumbnail: "https://c0.ptacdn.com/thumbnails/assets/RR0VPd5hX30Fx5APwRBGObotf1xD1DRT.png", + asset: "https://c0.ptacdn.com/assets/InBsL5bpJdp84ZPZGQMeHuyCBlo-uOv7.glb" + }, + 24118: { + type: "shirt", + name: "Green Polytoria Flannel", + price: 0, + creator: { + name: "Polytoria", + id: 1 + }, + thumbnail: "https://c0.ptacdn.com/thumbnails/assets/s7l57JugjbZfWTKAQ0cqTohOBraRbX5E.png", + asset: "https://c0.ptacdn.com/assets/uWrrnFGwgNN5W171vqYTWY7E639rKiXK.png" + }, + 24123: { + type: "pants", + name: "Jeans", + price: 0, + creator: { + name: "Polytoria", + id: 1 + }, + thumbnail: "https://c0.ptacdn.com/thumbnails/assets/anebTuFMLg8NKhRL3ab7hbzCfmcsFqGO.png", + asset: "https://c0.ptacdn.com/assets/HD6TFdXD8CaflRNmd84VCNyNsmTB0SH3.png" + }, + 37582: { + type: "torso", + name: "Slim Body", + price: 0, + creator: { + name: "Polytoria", + id: 1 + }, + thumbnail: "https://c0.ptacdn.com/thumbnails/assets/f_k-ZN_xmA_ALZiJQanOKT-Y4qq5kI1b.png", + asset: "https://c0.ptacdn.com/assets/qoqZ2qPyaGvB3MLGgJZ6oLWTz-xxGo-8.glb" + } +} let Avatar = { useCharacter: true, - items: [], - shirt: null, - pants: null, - tool: {ID: -1, URL: null}, + items: [24122], + shirt: 24118, + pants: 24123, headColor: '#e0e0e0', torsoColor: '#e0e0e0', leftArmColor: '#e0e0e0', @@ -19,371 +60,559 @@ let Avatar = { leftLegColor: '#e0e0e0', rightLegColor: '#e0e0e0' }; -let ItemCardContents = ` -
-
-
- - - :ItemType - - -
-
- -
:ItemName
-
- - by :CreatorName - -
-`; -if (new URLSearchParams(new URL(window.location).search).get('sandbox') === 'true') { - console.log('Avatar Sandbox!'); +/* Discovery */ +let Page = 1 +let PageCount = 1 +let Search = "" +let Sort = "createdAt" +let Order = "desc" +let ShowOffsale = true +let TabSelected = "hat" - LoadFile(chrome.runtime.getURL('resources/avatar-sandbox.html'), function (html) { - PageContainer.innerHTML = html; - ItemGrid = document.getElementById('inventory'); - Wearing = document.getElementById('wearing'); - Tabs = document.getElementById('tabs'); - IFrame = document.getElementById('viewFrame'); +!(async () => { + Utilities = await import(chrome.runtime.getURL('resources/utils.js')); + Utilities = Utilities.default; - Search = document.getElementById('item-search'); - Search.addEventListener('change', function () { - RefreshItems(); - }); + chrome.storage.sync.get(['PolyPlus_Settings'], function(result){ + Settings = result.PolyPlus_Settings || Utilities.DefaultSettings; - UpdateAvatar(); - RefreshItems(); + if (Settings.AvatarSandboxOn || 1 === 1) { + if (new URLSearchParams(window.location.search).has('sandbox')) { + document.title = 'Poly+ Avatar Sandbox' + PageLoad() + } else { + const SandboxButton = document.createElement('a'); + SandboxButton.classList = 'btn btn-outline-success w-100 mt-3'; + SandboxButton.href = '?sandbox=true'; + SandboxButton.innerHTML = ' Avatar Sandbox'; + document.getElementById('cont-move').parentElement.appendChild(SandboxButton); + } + } + }) +})(); - Array.from(Tabs.children).forEach((element) => { - element.addEventListener('click', function () { - let Link = element.getElementsByTagName('a')[0]; - if (!Link.classList.contains('active')) { - Link.classList.add('active'); - Tabs.querySelector(`[data-tab="${TabSelected}"]`).classList.remove('active'); - TabSelected = Link.getAttribute('data-tab'); - Page = 1; - RefreshItems(); - } - }); - }); +async function PageLoad() { + const PageContents = (await ((await fetch(chrome.runtime.getURL('resources/avatar-sandbox.html'))).text())) + Container.innerHTML = PageContents + Utilities.InjectResource("registerTooltips") - let Clear = document.getElementById('clear'); - Clear.addEventListener('click', function () { - Avatar = { - useCharacter: true, - items: [], - shirt: {ID: -1, URL: null}, - pants: {ID: -1, URL: null}, - tool: {ID: -1, URL: null}, - headColor: '#e0e0e0', - torsoColor: '#e0e0e0', - leftArmColor: '#e0e0e0', - rightArmColor: '#e0e0e0', - leftLegColor: '#e0e0e0', - rightLegColor: '#e0e0e0' - }; - UpdateAvatar(); - }); + IFrame = document.getElementById('viewFrame') - let JSONUpload = document.getElementById('jsonUpload'); - JSONUpload.addEventListener('change', function () { - let Reader = new FileReader(); - Reader.addEventListener('loadend', function () { - Avatar = JSON.parse(Reader.result); - UpdateAvatar(); + UpdateAvatar() + LoadItems() - JSONUpload.value = ''; - }); + const Tabs = document.getElementById('tabs') + Array.from(Tabs.children).forEach((element) => { + element.addEventListener('click', function () { + let Link = element.getElementsByTagName('a')[0]; + if (!Link.classList.contains('active')) { + Link.classList.add('active'); + Tabs.querySelector(`[data-tab="${TabSelected}"]`).classList.remove('active'); + TabSelected = Link.getAttribute('data-tab'); + ItemSearch.previousElementSibling.value = '' + Page = 1; + Search = "" + LoadItems(); + } + }); + }); - Reader.readAsText(JSONUpload.files[0]); - }); + const ItemSearch = document.getElementById('search-btn') + ItemSearch.addEventListener('click', function(){ + Search = ItemSearch.previousElementSibling.value + Page = 1 + LoadItems() + }) - let JSONSave = document.getElementById('jsonSave'); - JSONSave.addEventListener('click', function () { - FormatAvatar().then((FormattedAvatar) => { - let Download = document.createElement('a'); - Download.href = URL.createObjectURL( - new Blob([JSON.stringify(FormattedAvatar)], { - type: 'application/json' - }) - ); - Download.setAttribute('download', 'AvatarSandbox.json'); - document.body.appendChild(Download); - Download.click(); - document.body.removeChild(Download); - }); - }); + const ItemSort = document.getElementById('item-sort') + ItemSort.addEventListener('change', function(){ + Sort = ItemSort.options[ItemSort.selectedIndex].value + Page = 1 + LoadItems() + }) - let OpenInNewTab = document.getElementById('openNewTab'); - OpenInNewTab.addEventListener('click', function () { - UpdateAvatar(); - }); - }); + const ItemOrder = document.getElementById('item-order') + ItemOrder.addEventListener('change', function(){ + Order = ItemOrder.options[ItemOrder.selectedIndex].value + Page = 1 + LoadItems() + }) + + /* + Public API does not have an offsale parameter + + document.getElementById('show-offsale').addEventListener('change', function(){ + ShowOffsale = !ShowOffsale + console.log(ShowOffsale) + Page = 1 + LoadItems() + }) + */ + + // Pagination is annoying + const First = document.getElementById('pagination-first'); + const Prev = document.getElementById('pagination-prev'); + const Next = document.getElementById('pagination-next'); + const Last = document.getElementById('pagination-last'); + + if (Page > 0) { + Prev.parentElement.classList.remove('disabled'); + First.parentElement.classList.remove('disabled'); + } else { + Prev.parentElement.classList.add('disabled'); + First.parentElement.classList.add('disabled'); + } + + First.addEventListener('click', function () { + if (Page > 1) { + Page = 1; + LoadItems(); + } + }); + + Prev.addEventListener('click', function () { + if (Page > 1) { + Page--; + LoadItems(); + } + }); + + Next.addEventListener('click', function () { + if (Page < PageCount) { + Page++; + LoadItems(); + } + }); + + Last.addEventListener('click', function () { + if (Page < PageCount) { + Page = PageCount; + LoadItems(); + } + }); + + const ClearButton = document.getElementById('clear'); + ClearButton.addEventListener('click', function () { + Avatar = { + useCharacter: true, + items: [24122], + shirt: 24118, + pants: 24123, + headColor: '#e0e0e0', + torsoColor: '#e0e0e0', + leftArmColor: '#e0e0e0', + rightArmColor: '#e0e0e0', + leftLegColor: '#e0e0e0', + rightLegColor: '#e0e0e0' + }; + UpdateAvatar(); + }); + + const LoadMyselfButton = document.getElementById('myself'); + LoadMyselfButton.addEventListener('click', function () { + LoadUser(JSON.parse(window.localStorage.getItem('p+account_info')).ID); + }); + + const JSONUploadButton = document.getElementById('jsonUpload'); + JSONUploadButton.addEventListener('change', function () { + const Reader = new FileReader(); + Reader.addEventListener('loadend', function () { + Avatar = JSON.parse(Reader.result); + UpdateAvatar(); + + JSONUploadButton.value = ''; + }); + + Reader.readAsText(JSONUploadButton.files[0]); + }); + + const JSONSaveButton = document.getElementById('jsonSave'); + JSONSaveButton.addEventListener('click', function () { + const Download = document.createElement('a'); + Download.href = URL.createObjectURL( + new Blob([JSON.stringify(Avatar)], { + type: 'application/json' + }) + ); + Download.setAttribute('download', 'AvatarSandbox.json'); + document.body.appendChild(Download); + Download.click(); + document.body.removeChild(Download); + }); + + const OpenInNewTabButton = document.getElementById('openNewTab'); + OpenInNewTabButton.addEventListener('click', function () { + window.open(IFrame, "_blank") + }); + + const LoadAsset = document.getElementById('load-asset') + const LoadAssetType = document.getElementById('load-asset-type') + LoadAsset.addEventListener('click', function(){ + const SelectedType = LoadAssetType.options[LoadAssetType.selectedIndex].value + + if (SelectedType !== 'user') { + if (SelectedType === 'hat') { + Avatar.items.push(LoadAsset.previousElementSibling.value); + } else { + Avatar[SelectedType] = parseInt(LoadAsset.previousElementSibling.value) + } + UpdateAvatar(); + } else { + LoadUser(LoadAsset.previousElementSibling.value) + } + }) + + document.getElementById('view-cache').addEventListener('click', function(){ + console.log('Cache: ', ItemCache) + }) } -function UpdateAvatar() { - GenerateHash().then((hash) => { - IFrame.addEventListener('load', function () { - IFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + hash; - }); - IFrame.src = 'about:blank'; - }); +async function UpdateAvatar() { + // Hats, Tools: https://api.polytoria.com/v1/assets/serve-mesh/ID + // or: https://api.polytoria.com/v1/assets/serve/ID/Asset + + const FormattedAvatar = structuredClone(Avatar) + + const AccessoryPromise = [...Avatar.items, Avatar.tool, Avatar.torso].filter((x) => x !== undefined && !x.toString().startsWith('http') && !x.toString().startsWith('data:')).map(async (x, index) => { + if (ItemCache[x] === undefined) { + const ItemDetails = (await (await fetch('https://api.polytoria.com/v1/store/' + x)).json()) + ItemCache[x] = { + type: ItemDetails.type, + name: ItemDetails.name, + price: ItemDetails.price, + creator: { + name: ItemDetails.creator.name, + id: ItemDetails.creator.id + }, + thumbnail: ItemDetails.thumbnail, + asset: undefined + } + + if (ItemDetails.type === 'hat') { + ItemCache[x].accessoryType = ItemDetails.accessoryType + } + } + + if (ItemCache[x].asset === undefined) { + const MeshURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + x)).json()) + if (MeshURL.success) { + ItemCache[x].asset = MeshURL.url + + if (["mesh", "decal", "audio"].indexOf(ItemCache[x].type) !== -1) { + ItemCache[x].type = document.getElementById('load-asset-type').options[document.getElementById('load-asset-type').selectedIndex].value + } + + if (ItemCache[x].type === 'hat') { + FormattedAvatar.items[index] = MeshURL.url + } else { + FormattedAvatar[ItemCache[x].type] = MeshURL.url + } + } + } else { + if (ItemCache[x].type === 'hat') { + FormattedAvatar.items[index] = ItemCache[x].asset + } else { + FormattedAvatar[ItemCache[x].type] = ItemCache[x].asset + } + } + }) + + const TexturePromise = [Avatar.shirt, Avatar.pants, Avatar.face].filter((x) => x !== undefined && !x.toString().startsWith('http') && !x.toString().startsWith('data:') && x !== undefined).map(async (x, index) => { + if (ItemCache[x] === undefined) { + const ItemDetails = (await (await fetch('https://api.polytoria.com/v1/store/' + x)).json()) + ItemCache[x] = { + type: ItemDetails.type, + name: ItemDetails.name, + price: ItemDetails.price, + creator: { + name: ItemDetails.creator.name, + id: ItemDetails.creator.id + }, + thumbnail: ItemDetails.thumbnail, + asset: undefined + } + + if (ItemDetails.price === 0) { + if (ItemDetails.sales === 0) { + ItemCache[x].price = null + } else { + ItemCache[x].price = 0 + } + } + } + + if (ItemCache[x].asset === undefined) { + const TextureURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve/' + x + '/Asset')).json()) + if (TextureURL.success) { + ItemCache[x].asset = TextureURL.url + if (x === Avatar.shirt) { + FormattedAvatar.shirt = TextureURL.url + } else if (x === Avatar.pants) { + FormattedAvatar.pants = TextureURL.url + } else if (x === Avatar.face) { + FormattedAvatar.face = TextureURL.url + } + } + } else { + if (x === Avatar.shirt) { + FormattedAvatar.shirt = ItemCache[x].asset + } else if (x === Avatar.pants) { + FormattedAvatar.pants = ItemCache[x].asset + } else if (x === Avatar.face) { + FormattedAvatar.face = ItemCache[x].asset + } + } + }) + + if (Avatar.face === undefined) { + FormattedAvatar.face = "https://c0.ptacdn.com/static/3dview/DefaultFace.png" + } + + await Promise.all(AccessoryPromise) + await Promise.all(TexturePromise) + + console.log('Real Avatar: ', Avatar) + console.log('Formatted: ', FormattedAvatar) + IFrame.addEventListener('load', function(){ + IFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(FormattedAvatar))) + }) + IFrame.src = 'about:blank' + + UpdateBodyColors() + LoadWearing() } -function LoadFile(path, callback) { - var xhr = new XMLHttpRequest(); - xhr.onload = function () { - return callback(this.responseText); - }; - xhr.open('GET', path, true); - xhr.send(); -} - -async function GenerateHash() { - let FormattedAvatar = await FormatAvatar(); - for (let i = 0; i < FormattedAvatar.items.length; i++) { - FormattedAvatar.items[i] = FormattedAvatar.items[i].URL; - } - if (FormattedAvatar.shirt) { - FormattedAvatar.shirt = FormattedAvatar.shirt.URL; - } - if (FormattedAvatar.pants) { - FormattedAvatar.pants = FormattedAvatar.pants.URL; - } - FormattedAvatar.face = FormattedAvatar.face.URL; - if (FormattedAvatar.tool) { - FormattedAvatar.tool = FormattedAvatar.tool.URL; - } - console.log('Formatted Avatar: ', FormattedAvatar); - console.log('Real Avatar: ', Avatar); - return btoa(encodeURIComponent(JSON.stringify(FormattedAvatar))); -} - -async function FormatAvatar() { - let LocalAvatar = structuredClone(Avatar); - - if (!LocalAvatar.face) { - LocalAvatar.face = {ID: -1, URL: 'https://c0.ptacdn.com/static/3dview/DefaultFace.png'}; - } - - for (let i = 0; i < LocalAvatar.items.length; i++) { - if (LocalAvatar.items[i].URL === null) { - await fetch('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', LocalAvatar.items[i].ID)) - .then((response) => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - .then((data) => { - Avatar.items[i].URL = data.url; - LocalAvatar.items[i].URL = data.url; - }) - .catch((error) => { - console.error('Fetch error:', error); - }); - } - } - - if (LocalAvatar.tool && LocalAvatar.tool.ID !== -1 && LocalAvatar.tool.URL === null) { - await fetch('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', LocalAvatar.tool.ID)) - .then((response) => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - .then((data) => { - Avatar.tool.URL = data.url; - LocalAvatar.tool.URL = data.url; - }) - .catch((error) => { - console.error('Fetch error:', error); - }); - } - - if (LocalAvatar.face.ID !== -1 && LocalAvatar.face.URL === null) { - await fetch('https://api.polytoria.com/v1/assets/serve/:id/Asset'.replace(':id', LocalAvatar.face.ID)) - .then((response) => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - .then((data) => { - Avatar.face.URL = data.url; - LocalAvatar.face.URL = data.url; - }) - .catch((error) => { - console.error('Fetch error:', error); - }); - } - - if (LocalAvatar.shirt && LocalAvatar.shirt.ID !== -1 && LocalAvatar.shirt.URL === null) { - await fetch('https://api.polytoria.com/v1/assets/serve/:id/Asset'.replace(':id', LocalAvatar.shirt.ID)) - .then((response) => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - .then((data) => { - Avatar.shirt.URL = data.url; - LocalAvatar.shirt.URL = data.url; - }) - .catch((error) => { - console.error('Fetch error:', error); - }); - } - - if (LocalAvatar.pants && LocalAvatar.pants.ID !== -1 && LocalAvatar.pants.URL === null) { - await fetch('https://api.polytoria.com/v1/assets/serve/:id/Asset'.replace(':id', LocalAvatar.pants.ID)) - .then((response) => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - .then((data) => { - Avatar.pants.URL = data.url; - LocalAvatar.pants.URL = data.url; - }) - .catch((error) => { - console.error('Fetch error:', error); - }); - } - - return LocalAvatar; -} - -function RefreshItems() { - fetch(`https://api.polytoria.com/v1/store?search=${Search.value}&types%5B%5D=${TabSelected}&sort=createdAt&order=desc&page=${Page}&limit=12`) +async function LoadUser(id) { + fetch('https://api.polytoria.com/v1/users/' + id + '/avatar') .then((response) => { if (!response.ok) { - throw new Error('Network response was not ok'); + throw new Error('Network not ok'); } return response.json(); }) .then((data) => { - Array.from(ItemGrid.children).forEach((element) => { - element.remove(); - }); - data = data.assets; - data.forEach((item) => { - let NewItemCard = document.createElement('div'); - NewItemCard.classList = 'col-auto'; - NewItemCard.innerHTML = ItemCardContents.replace(':ItemName', item.name) - .replace() - .replace(':ItemID', item.id) - .replace(':ItemType', item.type.replace(item.type.charAt(0), item.type.charAt(0).toUpperCase())) - .replace(':CreatorName', item.creator.name) - .replace(':CreatorID', item.creator.id) - .replace(':ItemThumbnail', item.thumbnail); - NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function () { - WearAsset(NewItemCard, item.name, {Name: item.creator.name, ID: item.creator.id}, item.id, item.type, item.thumbnail); - }); + Avatar.items = []; - ItemGrid.appendChild(NewItemCard); + data.assets.forEach((item) => { + if (ItemCache[item.id] === undefined) { + ItemCache[item.id] = { + type: item.type, + name: item.name, + price: null, + creator: null, + thumbnail: item.thumbnail, + asset: item.path + } + + if (item.type === 'hat' || item.type === 'tool' || item.type === 'torso') { + ItemCache[item.id].creator = { + id: 1, + name: "Polytoria" + } + } + } + + if (item.type === 'hat') { + ItemCache[item.id].accessoryType = item.accessoryType + Avatar.items.push(item.id) + } else { + Avatar[item.type] = item.id + } }); + + Avatar.headColor = '#' + data.colors.head || '#cdcdcd'; + Avatar.torsoColor = '#' + data.colors.torso || '#cdcdcd'; + Avatar.leftArmColor = '#' + data.colors.leftArm || '#cdcdcd'; + Avatar.rightArmColor = '#' + data.colors.rightArm || '#cdcdcd'; + Avatar.leftLegColor = '#' + data.colors.leftLeg || '#cdcdcd'; + Avatar.rightLegColor = '#' + data.colors.rightLeg || '#cdcdcd'; + + UpdateAvatar(); }) .catch((error) => { - console.error('Fetch error:', error); + console.log(error); }); } -function WearAsset(element, name, creator, id, type, thumbnail) { - switch (type) { - case 'hat': - let Index = CheckItemID(Avatar.items, id); - if (Index === -1) { - if (Avatar.items.length !== 3) { - Avatar.items.push({Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}); - Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } else { - Avatar.items.splice(0, 1); - Avatar.items.push({Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}); - if (TabSelected === type) { - console.log('tab is', TabSelected, type); - ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } - } - } else { - console.log('remove'); - Avatar.items.splice(Index, 1); - if (TabSelected === type) { - console.log('tab is', TabSelected, type); - ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } - } - break; - case 'face': - if (Avatar.face && Avatar.face.ID !== id) { - Avatar.face = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}; - Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } else { - Avatar.face = { - Name: 'Default Face', - Creator: {Name: 'Polytoria', ID: 1}, - ID: -1, - URL: 'https://c0.ptacdn.com/static/3dview/DefaultFace.png', - Thumbnail: 'https://c0.ptacdn.com/static/3dview/DefaultFace.png' - }; - if (TabSelected === type) { - console.log('tab is', TabSelected, type); - ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } - } - break; - case 'tool': - if (Avatar.tool && Avatar.tool.ID !== id) { - Avatar.tool = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}; - Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } else { - Avatar.tool = null; - if (TabSelected === type) { - console.log('tab is', TabSelected, type); - ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } - } - break; - case 'shirt': - if (Avatar.shirt.ID !== id) { - Avatar.shirt = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}; - Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } else { - Avatar.shirt = null; - if (TabSelected === type) { - console.log('tab is', TabSelected, type); - ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } - } - break; - case 'pants': - if (Avatar.pants.ID !== id) { - Avatar.pants = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}; - Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } else { - Avatar.pants = null; - if (TabSelected === type) { - console.log('tab is', TabSelected, type); - ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`)); - } - } - break; - } +async function LoadItems() { + document.getElementById('inventory').innerHTML = '' - UpdateAvatar(); + const Items = (await (await fetch('https://api.polytoria.com/v1/store?limit=12&order=' + Order + '&sort=' + Sort + '&showOffsale=' + ShowOffsale + '&types[]='+ TabSelected +'&search=' + Search + '&page=' + Page)).json()) + PageCount = Items.pages + if (Page < PageCount) { + document.getElementById('pagination-next').classList.remove('disabled'); + document.getElementById('pagination-last').classList.remove('disabled'); + } else { + document.getElementById('pagination-next').classList.add('disabled'); + document.getElementById('pagination-last').classList.add('disabled'); + } + if (Page > 1 && PageCount > 1) { + console.log('aaa') + console.log(Page > 1, PageCount > 1) + document.getElementById('pagination-prev').classList.remove('disabled'); + document.getElementById('pagination-first').classList.remove('disabled'); + } else { + document.getElementById('pagination-prev').classList.add('disabled'); + document.getElementById('pagination-first').classList.add('disabled'); + } + document.getElementById('pagination-current').innerText = Page + Items.assets.forEach(item => { + const ItemColumn = document.createElement('div') + ItemColumn.classList = 'col-auto' + ItemColumn.innerHTML = ` +
+
+
+ + ${ (item.type === 'hat') ? ` + + ${CleanAccessoryType(item.accessoryType)} + + ` : ''} + +
+
+ +
${item.name}
+
+ + by ${ (["hat", "tool", "face", "torso"].indexOf(item.type) !== -1) ? 'Polytoria' : item.creator.name } + + Free' : (item.price !== "???") ? 'text-success">$ ' + item.price : 'text-muted">???' } + +
+ ` + document.getElementById('inventory').appendChild(ItemColumn) + + ItemCache[item.id] = { + type: item.type, + name: item.name, + price: item.price, + creator: { + name: item.creator.name, + id: item.creator.id + }, + thumbnail: item.thumbnail, + asset: undefined + } + + if (item.price === 0) { + if (item.sales === 0) { + console.log("ITEM IS AWARD-ONLY!!! ", item) + ItemCache[item.id].price = null + } else { + ItemCache[item.id].price = 0 + } + } + + if (item.type === 'hat') { + ItemCache[item.id].accessoryType = item.accessoryType + } + + ItemColumn.getElementsByClassName('p-2')[0].addEventListener('click', function(){ + WearAsset(item) + }) + }) } -function CheckItemID(object, id) { - for (let i = 0; i < object.length; i++) { - if (object[i] === id || object[i].ID === id) { - console.log('Index: ' + i); - return i; - } - } - return -1; +function LoadWearing() { + document.getElementById('wearing').innerHTML = ''; + [...Avatar.items, Avatar.shirt, Avatar.pants, Avatar.torso].filter((x) => x !== undefined).forEach(id => { + const Cached = Object.values(ItemCache)[Object.keys(ItemCache).indexOf(id.toString())] + if (Cached !== undefined) { + if (Cached.creator === undefined || Cached.creator === null) { + Cached.creator = { + id: 1, + name: "-" + } + } + + if (Cached.price === undefined || Cached.price === null) { Cached.price = "???" } + + const ItemColumn = document.createElement('div') + ItemColumn.classList = 'col-auto' + ItemColumn.innerHTML = ` +
+
+
+ + ${ (Cached.type === 'hat') ? ` + + ${CleanAccessoryType(Cached.accessoryType)} + + ` : ''} + +
+
+ +
${Cached.name}
+
+ + by ${Cached.creator.name || "-"} + + Free' : (Cached.price !== "???") ? 'text-success">$ ' + Cached.price : 'text-muted">???' } + +
+ ` + document.getElementById('wearing').appendChild(ItemColumn) + + ItemColumn.getElementsByClassName('p-2')[0].addEventListener('click', function(){ + WearAsset(Cached) + }) + } + }) } + +function WearAsset(details) { + const ItemID = Object.keys(ItemCache)[Object.values(ItemCache).indexOf(details)] + if (Avatar[details.type] !== details.id && Avatar.items.indexOf(details.id) === -1) { + // Equip + if (details.type === 'hat') { + Avatar.items.push(details.id) + } else { + Avatar[details.type] = details.id + } + } else { + // Unequip + if (details.type === 'hat') { + Avatar.items.splice(Avatar.items.indexOf(ItemID), 1); + } else { + Avatar[details.type] = undefined + } + } + + UpdateAvatar() + LoadWearing() +} + +function UpdateBodyColors() { + const BodyColors = { + head: Avatar.headColor, + torso: Avatar.torsoColor, + leftArm: Avatar.leftArmColor, + rightArm: Avatar.rightArmColor, + leftLeg: Avatar.leftLegColor, + rightLeg: Avatar.rightLegColor + } + + Object.keys(BodyColors).forEach((elementID, i) => { + document.getElementById(elementID).style.backgroundColor = Object.values(BodyColors)[i] + }) +} + +function CleanAccessoryType(type) { + const CleanAccessoryTypes = { + hat: "Hat", + backAccessory: "Back Accessory", + faceAccessory: "Face Accessory", + headAttachment: "Head Attachment", + hair: "Hair", + neckAccessory: "Neck Accessory", + headCover: "Head Cover", + headAccessory: "Head Accessory" + } + return Object.values(CleanAccessoryTypes)[Object.keys(CleanAccessoryTypes).indexOf(type)] || "!!!"+type +} \ No newline at end of file diff --git a/js/account/avatar-sandbox2.js b/js/account/avatar-sandbox2.js deleted file mode 100755 index e71155a..0000000 --- a/js/account/avatar-sandbox2.js +++ /dev/null @@ -1,538 +0,0 @@ -const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID; -const BodyColors = [ - '#f8f8f8', - '#cdcdcd', - '#111111', - '#ff0000', - '#a34b4b', - '#ffc9c9', - '#957977', - '#c4281c', - '#da867a', - '#694028', - '#cc8e69', - '#a05f35', - '#7c5c46', - '#eab892', - '#da8541', - '#aa5500', - '#ffcc99', - '#e29b40', - '#ffaf00', - '#ffb000', - '#d7c59a', - '#f5cd30', - '#fdea8d', - '#e5e4df', - '#c1be42', - '#ffff00', - '#ffffcc', - '#a4bd47', - '#7f8e64', - '#a1c48c', - '#3a7d15', - '#4b974b', - '#00ff00', - '#ccffcc', - '#27462d', - '#287f47', - '#789082', - '#9ff3e9', - '#12eed4', - '#f2f3f3', - '#00ffff', - '#008f9c', - '#04afec', - '#80bbdb', - '#b4d2e4', - '#0d69ac', - '#1b2a35', - '#afddff', - '#6e99ca', - '#74869d', - '#2154b9', - '#002060', - '#0000ff', - '#b1a7ff', - '#a3a2a5', - '#6225d1', - '#b480ff', - '#8c5b9f', - '#6b327c', - '#aa00aa', - '#635f62', - '#ff00bf', - '#ff66cc', - '#e8bac8' -]; - -let PageContainer = document.querySelector('.container.p-0.p-lg-5'); -let ItemGrid; -let Wearing; -let Tabs; -let IFrame; -let TabSelected = 'hat'; -let Search; -let Page = 1; -let Avatar = { - useCharacter: true, - items: [24122], - shirt: 24118, - pants: 24123, - headColor: '#e0e0e0', - torsoColor: '#e0e0e0', - leftArmColor: '#e0e0e0', - rightArmColor: '#e0e0e0', - leftLegColor: '#e0e0e0', - rightLegColor: '#e0e0e0' -}; - -if (new URLSearchParams(window.location.search).has('sandbox')) { - console.log('Avatar Sandbox!'); - - LoadFile(chrome.runtime.getURL('resources/avatar-sandbox.html'), function (html) { - PageContainer.innerHTML = html; - ItemGrid = document.getElementById('inventory'); - Wearing = document.getElementById('wearing'); - Tabs = document.getElementById('tabs'); - IFrame = document.getElementById('viewFrame'); - - Search = document.getElementById('item-search'); - Search.addEventListener('onchange', function () { - RefreshItems(); - }); - - UpdateAvatar(); - RefreshItems(); - LoadWearing(); - - Array.from(Tabs.children).forEach((element) => { - element.addEventListener('click', function () { - let Link = element.getElementsByTagName('a')[0]; - if (!Link.classList.contains('active')) { - Link.classList.add('active'); - Tabs.querySelector(`[data-tab="${TabSelected}"]`).classList.remove('active'); - TabSelected = Link.getAttribute('data-tab'); - Page = 1; - RefreshItems(); - } - }); - }); - - let Clear = document.getElementById('clear'); - Clear.addEventListener('click', function () { - Avatar = { - useCharacter: true, - items: [24122], - shirt: 24118, - pants: 24123, - headColor: '#e0e0e0', - torsoColor: '#e0e0e0', - leftArmColor: '#e0e0e0', - rightArmColor: '#e0e0e0', - leftLegColor: '#e0e0e0', - rightLegColor: '#e0e0e0' - }; - UpdateAvatar(); - }); - - let Myself = document.getElementById('myself'); - Myself.addEventListener('click', function () { - LoadMyself(); - }); - - let JSONUpload = document.getElementById('jsonUpload'); - JSONUpload.addEventListener('change', function () { - let Reader = new FileReader(); - Reader.addEventListener('loadend', function () { - Avatar = JSON.parse(Reader.result); - UpdateAvatar(); - - JSONUpload.value = ''; - }); - - Reader.readAsText(JSONUpload.files[0]); - }); - - let JSONSave = document.getElementById('jsonSave'); - JSONSave.addEventListener('click', function () { - let Download = document.createElement('a'); - Download.href = URL.createObjectURL( - new Blob([JSON.stringify(Avatar)], { - type: 'application/json' - }) - ); - Download.setAttribute('download', 'AvatarSandbox.json'); - document.body.appendChild(Download); - Download.click(); - document.body.removeChild(Download); - }); - - let OpenInNewTab = document.getElementById('openNewTab'); - OpenInNewTab.addEventListener('click', function () { - UpdateAvatar(); - }); - - let LoadAsset = document.getElementById('load-asset'); - const LoadAssetType = document.getElementById('load-asset-type') - LoadAsset.addEventListener('click', async function () { - if (!LoadAsset.previousElementSibling.value.startsWith('http') && !LoadAsset.previousElementSibling.value.startsWith('data:')) { - if (LoadAssetType.options[LoadAssetType.selectedIndex].value === 'hat') { - Avatar.items.push((await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + LoadAsset.previousElementSibling.value)).json()).url); - } else { - Avatar[LoadAssetType.options[LoadAssetType.selectedIndex].value] = (await (await fetch('https://api.polytoria.com/v1/assets/serve/' + LoadAsset.previousElementSibling.value + '/Asset')).json()).url; - } - } else { - if (LoadAssetType.options[LoadAssetType.selectedIndex].value === 'hat') { - Avatar.items.push(LoadAsset.previousElementSibling.value); - } else { - Avatar[LoadAssetType.options[LoadAssetType.selectedIndex].value] = LoadAsset.previousElementSibling.value - } - } - UpdateAvatar(); - }); - }); -} else { - const SandboxButton = document.createElement('a'); - SandboxButton.classList = 'btn btn-outline-success w-100 mt-3'; - SandboxButton.href = '?sandbox=true'; - SandboxButton.innerHTML = ' Avatar Sandbox'; - document.getElementById('cont-move').parentElement.appendChild(SandboxButton); -} - -function UpdateAvatar() { - FormatAvatar().then((hash) => { - IFrame.addEventListener('load', function () { - IFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + hash; - }); - IFrame.src = 'about:blank'; - }); -} - -function LoadFile(path, callback) { - var xhr = new XMLHttpRequest(); - xhr.onload = function () { - return callback(this.responseText); - }; - xhr.open('GET', path, true); - xhr.send(); -} - -async function GenerateHash(data) { - if (!data) { - console.log('Data not provided'); - let FormattedAvatar = await FormatAvatar(); - return btoa(encodeURIComponent(JSON.stringify(FormattedAvatar))); - } else { - console.log('Data provided'); - return btoa(encodeURIComponent(JSON.stringify(data))); - } -} - -function RefreshItems() { - fetch(`https://api.polytoria.com/v1/store?search=${Search.value}&types%5B%5D=${TabSelected}&sort=createdAt&order=desc&page=${Page}&limit=12`) - .then((response) => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - .then((data) => { - Array.from(ItemGrid.children).forEach((element) => { - element.remove(); - }); - data = data.assets; - data.forEach((item) => { - let NewItemCard = document.createElement('div'); - NewItemCard.setAttribute('data-id', item.id); - NewItemCard.classList = 'col-auto'; - NewItemCard.innerHTML = ` -
-
-
- - - ${item.type.charAt(0).toUpperCase() + item.type.substring(1)} - - -
-
- -
${item.name}
-
- - by ${item.creator.name} - -
- `; - NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function () { - WearAsset(NewItemCard, item); - }); - - ItemGrid.appendChild(NewItemCard); - }); - }) - .catch((error) => { - console.error('Fetch error:', error); - }); -} - -async function FormatAvatar() { - const FormattedAvatar = structuredClone(Avatar); - - // Hats, Tools: https://api.polytoria.com/v1/assets/serve-mesh/:id - // or: https://api.polytoria.com/v1/assets/serve/:id/Asset - - const meshPromises = Avatar.items.map(async (item, index) => { - if (typeof item === 'number') { - console.log(item); - FormattedAvatar.items[index] = await FetchMesh(item) - console.log('after url'); - //Avatar.items[index] = URL - } - }); - - Avatar.items.forEach(async (item, index) => { - if (typeof item === 'number') { - console.log(item); - FetchMesh(item) - .then((URL) => { - console.log('URL: ' + URL); - FormattedAvatar.items[index] = URL; - }) - .catch((error) => { - throw new Error(error); - }); - console.log('after url'); - //Avatar.items[index] = URL - } - }); - - if (typeof FormattedAvatar.tool === 'number') { - console.log(FormattedAvatar.tool); - FormattedAvatar.tool = await FetchMesh(FormattedAvatar.tool); - } - - if (FormattedAvatar.face === undefined) { FormattedAvatar.face = 'https://c0.ptacdn.com/static/3dview/DefaultFace.png'; } - if (FormattedAvatar.face && typeof FormattedAvatar.face === 'number') { - FormattedAvatar.face = await FetchAsset(FormattedAvatar.face); - } else if (FormattedAvatar.face === undefined) { - FormattedAvatar.face = 'https://c0.ptacdn.com/static/3dview/DefaultFace.png'; - } - - if (typeof FormattedAvatar.shirt === 'number') { - FormattedAvatar.shirt = await FetchAsset(FormattedAvatar.shirt); - } - if (typeof FormattedAvatar.pants === 'number') { - FormattedAvatar.pants = await FetchAsset(FormattedAvatar.pants); - } - - await Promise.all(meshPromises) - - console.log('Real Avatar: ', Avatar) - console.log('Formatted: ', FormattedAvatar) - console.log('URI: ', btoa(encodeURIComponent(JSON.stringify(FormattedAvatar)))) - console.log('Fix: ', JSON.stringify(decodeURIComponent(atob(btoa(encodeURIComponent(JSON.stringify(FormattedAvatar))))))); - return btoa(encodeURIComponent(JSON.stringify(FormattedAvatar))); -} - -function LoadMyself() { - fetch('https://api.polytoria.com/v1/users/:id/avatar'.replace(':id', UserID)) - .then((response) => { - if (!response.ok) { - throw new Error('Network not ok'); - } - return response.json(); - }) - .then((data) => { - Avatar.items = []; - - data.assets.forEach((item) => { - switch (item.type) { - case 'hat': - Avatar.items.push(item.id); - break; - default: - Avatar[item.type] = item.id; - break; - } - }); - - Avatar.headColor = '#' + data.colors.head || '#cdcdcd'; - Avatar.torsoColor = '#' + data.colors.torso || '#cdcdcd'; - Avatar.leftArmColor = '#' + data.colors.leftArm || '#cdcdcd'; - Avatar.rightArmColor = '#' + data.colors.rightArm || '#cdcdcd'; - Avatar.leftLegColor = '#' + data.colors.leftLeg || '#cdcdcd'; - Avatar.rightLegColor = '#' + data.colors.rightLeg || '#cdcdcd'; - - UpdateAvatar(); - }) - .catch((error) => { - console.log(error); - }); -} - -function WearAsset(element, info) { - if (Avatar.items.indexOf(info.id) === -1 && Avatar[info.type] !== info.id) { - console.log('Equip', info); - switch (info.type) { - case 'hat': - Avatar.items.push(info.id); - break; - default: - Avatar[info.type] = info.id; - break; - } - } else { - console.log('unequip', info); - switch (info.type) { - case 'hat': - Avatar.items.splice(Avatar.items.indexOf(info.id), 1); - break; - case 'face': - Avatar.face = 'https://c0.ptacdn.com/static/3dview/DefaultFace.png'; - break; - default: - Avatar[info.type] = undefined; - break; - } - } - - const ToggleButton = element.getElementsByClassName('avatarAction')[0]; - ToggleButton.classList.toggle('btn-success'); - ToggleButton.classList.toggle('btn-danger'); - ToggleButton.children[0].classList.toggle('fa-plus'); - ToggleButton.children[0].classList.toggle('fa-minus'); - - const Duplicate = ItemGrid.querySelector(`[data-id="${info.id}"]`); - if (Duplicate !== null && Duplicate !== element) { - const DuplicateToggleButton = Duplicate.getElementsByClassName('avatarAction')[0]; - DuplicateToggleButton.classList.toggle('btn-success'); - DuplicateToggleButton.classList.toggle('btn-danger'); - DuplicateToggleButton.children[0].classList.toggle('fa-plus'); - DuplicateToggleButton.children[0].classList.toggle('fa-minus'); - } - - LoadWearing(); - UpdateAvatar(); -} - -async function FetchMesh(id) { - if (id === null) { - return null; - } - console.log('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', id)); - - return new Promise((resolve, reject) => { - fetch('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', id)) - .then((response) => { - if (!response.ok) { - throw new Error('Network not ok'); - } - return response.json(); - }) - .then((data) => { - console.log(data, 'finished', data.url); - resolve(data.url); - }) - .catch((error) => { - console.log('Fetch error: ' + error); - }); - }) - return fetch('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', id)) - .then((response) => { - if (!response.ok) { - throw new Error('Network not ok'); - } - return response.json(); - }) - .then((data) => { - console.log(data, 'finished', data.url); - return data.url; - }) - .catch((error) => { - console.log('Fetch error: ' + error); - }); -} - -async function FetchAsset(id) { - if (id === null) { - return null; - } - return fetch('https://api.polytoria.com/v1/assets/serve/:id/Asset'.replace(':id', id)) - .then((response) => { - if (!response.ok) { - throw new Error('Network not ok'); - } - return response.json(); - }) - .then((data) => { - return data.url; - }) - .catch((error) => { - console.log('Fetch error: ' + error); - }); -} - -function LoadWearing() { - const WearingItems = [...Avatar.items, Avatar.shirt, Avatar.pants, Avatar.face].filter((item) => item !== null && item !== undefined); - - Array.from(Wearing.children).forEach((element) => { - const ItemID = element.getElementsByTagName('a')[0].href.split('/')[2]; - if (!WearingItems.includes(ItemID)) { - element.remove(); - } - }); - - WearingItems.forEach((item) => { - const ExistingElement = Wearing.querySelector(`[data-itemid="${item}"]`); - - if (!ExistingElement) { - fetch(`https://api.polytoria.com/v1/store/${item}`) - .then((response) => { - if (!response.ok) { - throw new Error('Network not ok'); - } - return response.json(); - }) - .then((item) => { - if (Wearing.innerHTML === 'No items to show.') { - Wearing.innerHTML = ''; - } - let NewItemCard = document.createElement('div'); - NewItemCard.setAttribute('data-id', item.id); - NewItemCard.classList = 'col-auto'; - NewItemCard.innerHTML = ` -
-
-
- - - ${item.type.charAt(0).toUpperCase() + item.type.substring(1)} - - -
-
- -
${item.name}
-
- - by ${item.creator.name} - -
- `; - Wearing.appendChild(NewItemCard); - NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function () { - WearAsset(NewItemCard, item); - }); - }) - .catch((error) => { - console.log('Fetch error: ' + error); - }); - } - }); - - if (Array.from(Wearing.children).length === 0) { - Wearing.innerHTML = 'No items to show.'; - } -} diff --git a/manifest.json b/manifest.json index 8d643ac..eeed5bc 100644 --- a/manifest.json +++ b/manifest.json @@ -100,7 +100,7 @@ { "matches": ["https://polytoria.com/my/avatar*"], - "js": ["/js/account/avatar-sandbox-rewrite.js"] + "js": ["/js/account/avatar-sandbox.js"] }, {