diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d61488..0ef6b89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.10.4 (Sep 24, 2022) + +* add versioning to herovau.lt calls +* change the way portrait/token images are added to herovau.lt -- should now work 100% of the time in basically any environment. + ## 0.10.3 (Sep 23, 2022) * fix issue when changing user token diff --git a/README.md b/README.md index 67edff8..af3ebcf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![ko-fi](https://img.shields.io/badge/-buy%20me%20a%20coffee-%23FF5E5B?style=plastic)](https://ko-fi.com/slate) [![patreon](https://img.shields.io/badge/-support%20me%20on%20patreon-%235C5C5C?style=plastic)](https://patreon.com/slatesfoundrystuff) ![GitHub release (by tag)](https://img.shields.io/github/downloads/zarmstrong/herovau.lt-foundry/herovau.lt-foundry-0.10.3/total?style=plastic) ![GitHub all releases](https://img.shields.io/github/downloads/zarmstrong/herovau.lt-foundry/total?style=plastic) ![GitHub](https://img.shields.io/github/license/zarmstrong/herovau.lt-foundry?style=plastic) +[![ko-fi](https://img.shields.io/badge/-buy%20me%20a%20coffee-%23FF5E5B?style=plastic)](https://ko-fi.com/slate) [![patreon](https://img.shields.io/badge/-support%20me%20on%20patreon-%235C5C5C?style=plastic)](https://patreon.com/slatesfoundrystuff) ![GitHub release (by tag)](https://img.shields.io/github/downloads/zarmstrong/herovau.lt-foundry/herovau.lt-foundry-0.10.4/total?style=plastic) ![GitHub all releases](https://img.shields.io/github/downloads/zarmstrong/herovau.lt-foundry/total?style=plastic) ![GitHub](https://img.shields.io/github/license/zarmstrong/herovau.lt-foundry?style=plastic) # HeroVau.lt Foundry Integration (herovau.lt-foundry) ## Summary: diff --git a/herovault-min.js b/herovault-min.js index cd37e35..876b146 100644 --- a/herovault-min.js +++ b/herovault-min.js @@ -1,4 +1,4 @@ -const hvDebug={enabled:!1},hvVer="0.10.3";let heroVaultURL="https://herovau.lt";const hvColor1="color: #7bf542",hvColor2="color: #d8eb34",hvColor3="color: #ffffff",hvColor4="color: #cccccc",hvColor5="color: #ff0000";let HLOuserToken,hvUserToken,skipTokenPrompt,enableHLO=!0,enablePB=!0,pfsEnabled=!0,proto="https";function setHLOToken(){HLOuserToken=game.settings.get("herovaultfoundry","hlouserToken")}async function checkUserToken(token){var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){if(4==this.readyState&&200==this.status){var responseJSON=JSON.parse(this.responseText);return hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %ccheckUserToken: "+JSON.stringify(responseJSON),hvColor1,hvColor4),skipTokenPrompt=1==responseJSON.status?(hvUserToken=token,game.settings.set("herovaultfoundry","userToken",token),game.settings.set("herovaultfoundry","skipTokenPrompt",!0),!0):(hvUserToken="",game.settings.set("herovaultfoundry","userToken",null),game.settings.set("herovaultfoundry","skipTokenPrompt",!1),!1)}};var hashedToken=await getSHA(token);hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c/foundrymodule.php?action=iv&userToken="+hashedToken,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=iv&userToken="+hvUserToken)}function checkNextAction(obj){game.modules.get("herovaultfoundry")?.active?pickAFunction(obj):skipTokenPrompt?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cCalling herovaultmenu",hvColor1,hvColor4),herovaultMenu(obj)):(null==hvUserToken&&(hvUserToken=""),getVaultToken(herovaultMenu,targetActor))}async function loadPB(obj){game.modules.get("pathbuilder2e-import")?.api?.beginPathbuilderImport(obj,!0)}async function loadHLO(obj){game.modules.get("hlo-importer")?.api?.hloShim(obj)}async function pickAFunction(obj){let hloImport=!1,hvImport=!1,pbImport=!1,PFSPC=!1,dopt={width:400,height:"auto"},menuButtons={heroVaultImport:{icon:"",label:"HeroVau.lt Import/Export",callback:()=>hvImport=!0}};"pf2e"==game.system.id&&game.modules.get("hlo-importer")?.active&&enableHLO&&(menuButtons={...menuButtons,hloimport:{icon:"",label:"Import from Herolab Online",callback:()=>hloImport=!0}},dopt.width+=100),"pf2e"==game.system.id&&game.modules.get("pathbuilder2e-import")?.active&&enablePB&&(menuButtons={...menuButtons,pbimport:{icon:"",label:"Import from Pathbuilder 2e",callback:()=>pbImport=!0}},dopt.width+=100),"pf2e"==game.system.id&&pfsEnabled&&(menuButtons={...menuButtons,pfsimport:{icon:"",label:"Find & Import a PFS PC",callback:()=>PFSPC=!0}},dopt.width+=100),menuButtons={...menuButtons,no:{icon:"",label:"Cancel"}},new Dialog({title:"HeroVau.lt Import",content:` +const hvDebug={enabled:!1},hvVer="0.10.4";let heroVaultURL="https://herovau.lt";const hvColor1="color: #7bf542",hvColor2="color: #d8eb34",hvColor3="color: #ffffff",hvColor4="color: #cccccc",hvColor5="color: #ff0000";let HLOuserToken,hvUserToken,skipTokenPrompt,enableHLO=!0,enablePB=!0,pfsEnabled=!0,proto="https";function setHLOToken(){HLOuserToken=game.settings.get("herovaultfoundry","hlouserToken")}async function checkUserToken(token){var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){if(4==this.readyState&&200==this.status){var responseJSON=JSON.parse(this.responseText);return hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %ccheckUserToken: "+JSON.stringify(responseJSON),hvColor1,hvColor4),skipTokenPrompt=1==responseJSON.status?(hvUserToken=token,game.settings.set("herovaultfoundry","userToken",token),game.settings.set("herovaultfoundry","skipTokenPrompt",!0),!0):(hvUserToken="",game.settings.set("herovaultfoundry","userToken",null),game.settings.set("herovaultfoundry","skipTokenPrompt",!1),!1)}};var hashedToken=await getSHA(token);hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c/foundrymodule.php?action=iv&userToken="+hashedToken,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=iv&userToken="+hvUserToken+"&hvVer="+encodeURIComponent(hvVer))}function checkNextAction(obj){game.modules.get("herovaultfoundry")?.active?pickAFunction(obj):skipTokenPrompt?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cCalling herovaultmenu",hvColor1,hvColor4),herovaultMenu(obj)):(null==hvUserToken&&(hvUserToken=""),getVaultToken(herovaultMenu,targetActor))}async function loadPB(obj){game.modules.get("pathbuilder2e-import")?.api?.beginPathbuilderImport(obj,!0)}async function loadHLO(obj){game.modules.get("hlo-importer")?.api?.hloShim(obj)}async function pickAFunction(obj){let hloImport=!1,hvImport=!1,pbImport=!1,PFSPC=!1,dopt={width:400,height:"auto"},menuButtons={heroVaultImport:{icon:"",label:"HeroVau.lt Import/Export",callback:()=>hvImport=!0}};"pf2e"==game.system.id&&game.modules.get("hlo-importer")?.active&&enableHLO&&(menuButtons={...menuButtons,hloimport:{icon:"",label:"Import from Herolab Online",callback:()=>hloImport=!0}},dopt.width+=100),"pf2e"==game.system.id&&game.modules.get("pathbuilder2e-import")?.active&&enablePB&&(menuButtons={...menuButtons,pbimport:{icon:"",label:"Import from Pathbuilder 2e",callback:()=>pbImport=!0}},dopt.width+=100),"pf2e"==game.system.id&&pfsEnabled&&(menuButtons={...menuButtons,pfsimport:{icon:"",label:"Find & Import a PFS PC",callback:()=>PFSPC=!0}},dopt.width+=100),menuButtons={...menuButtons,no:{icon:"",label:"Cancel"}},new Dialog({title:"HeroVau.lt Import",content:`

Please select the importer you'd like to use from the options below.

@@ -59,7 +59,7 @@ const hvDebug={enabled:!1},hvVer="0.10.3";let heroVaultURL="https://herovau.lt"; } - `,buttons:{yes:{icon:"",label:"Import",callback:()=>searchPFS=!0},no:{icon:"",label:"Cancel"}},default:"yes",close:html=>{searchPFS&&(pfsnumber=html.find('[id="pfsnumber"]')[0].value,pfscharnumber=html.find('[id="pfscharnumber"]')[0].value,hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cSearching for "+pfsnumber+"-"+pfscharnumber,hvColor1,hvColor4),findPFS(obj,pfsnumber,pfscharnumber))}}).render(!0)}async function findPFS(obj,pfsnumber,pfscharnumber){game.settings.get("herovaultfoundry","userToken");var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),1<=Object.keys(responseJSON).length?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cCalling createPCTable",hvColor1,hvColor4),createPCTable(obj,responseJSON)):ui.notifications.error("Unable to find any results."))},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c/foundrymodule.php?action=findPFS&pfsnumber="+pfsnumber+"&pfscharnumber="+pfscharnumber,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=findPFS"+action+"&pfsnumber="+pfsnumber+"&pfscharnumber="+pfscharnumber)}function getVaultToken(callback,callbackArg1,callbackArg2,callbackArg3,callbackArg4){let applyChanges=!1;null==hvUserToken&&(hvUserToken=""),new Dialog({title:"Connect to HeroVau.lt",content:` + `,buttons:{yes:{icon:"",label:"Import",callback:()=>searchPFS=!0},no:{icon:"",label:"Cancel"}},default:"yes",close:html=>{searchPFS&&(pfsnumber=html.find('[id="pfsnumber"]')[0].value,pfscharnumber=html.find('[id="pfscharnumber"]')[0].value,hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cSearching for "+pfsnumber+"-"+pfscharnumber,hvColor1,hvColor4),findPFS(obj,pfsnumber,pfscharnumber))}}).render(!0)}async function findPFS(obj,pfsnumber,pfscharnumber){game.settings.get("herovaultfoundry","userToken");var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),1<=Object.keys(responseJSON).length?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cCalling createPCTable",hvColor1,hvColor4),createPCTable(obj,responseJSON)):ui.notifications.error("Unable to find any results."))},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c/foundrymodule.php?action=findPFS&pfsnumber="+pfsnumber+"&pfscharnumber="+pfscharnumber,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=findPFS"+action+"&pfsnumber="+pfsnumber+"&pfscharnumber="+pfscharnumber+"&hvVer="+encodeURIComponent(hvVer))}function getVaultToken(callback,callbackArg1,callbackArg2,callbackArg3,callbackArg4){let applyChanges=!1;null==hvUserToken&&(hvUserToken=""),new Dialog({title:"Connect to HeroVau.lt",content:`

Enter your User Token from HeroVau.lt. You can find it on the My Account page on http://herovau.lt

@@ -101,15 +101,15 @@ const hvDebug={enabled:!1},hvVer="0.10.3";let heroVaultURL="https://herovau.lt"; margin: 0 auto; padding: 5px; } - `,buttons:{yes:{icon:"",label:"Connect to HeroVau.lt",callback:()=>applyChanges=!0},no:{icon:"",label:"Cancel"}},default:"yes",close:skipToken=>{var userToken;applyChanges&&(userToken=skipToken.find('[id="textBoxUserToken"]')[0].value,skipToken=skipToken.find('[id="skipToken"]')[0].checked,checkUserToken(userToken),hvUserToken=userToken,skipToken&&game.settings.set("herovaultfoundry","skipTokenPrompt",!0),callback(callbackArg1,callbackArg2,callbackArg3,callbackArg4))}}).render(!0)}async function exportToHV(targetActor){try{var hvUserToken=game.settings.get("herovaultfoundry","userToken"),xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),1==responseJSON.status?performExportToHV(targetActor):(hvUserToken="",game.settings.set("herovaultfoundry","userToken",null),ui.notifications.warn("Unable to load vault. Please double-check your User Token."),game.settings.set("herovaultfoundry","skipTokenPrompt",!1),getVaultToken(exportToHV,targetActor,hvUserToken)))},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c/foundrymodule.php?action=iv&userToken="+hvUserToken,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=iv&userToken="+hvUserToken)}catch(e){console.log(e)}}async function performExportToHV(targetActor){try{let menuButtons={},exportNewPC=!1,exportOverwritePC=!1;var vaultInfo;let canOverwrite=!1,portrait,hvUID,portraitAddress,tokenAddress;hvUserToken=game.settings.get("herovaultfoundry","userToken");var hvUserTokenHashed=await getSHA(hvUserToken);if(portrait="icons/svg/mystery-man.svg",null!=targetActor.img&&null!=targetActor.prototypeToken.texture.src&&(portrait=-1!=targetActor.img.includes("mystery-man")&&-1==targetActor.prototypeToken.texture.src.includes("mystery-man")?targetActor.prototypeToken.texture.src:targetActor.img,hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cportrait includes: "+targetActor.img.includes("http"),hvColor1,hvColor4),0==targetActor.img.includes("http")&&0==targetActor.img.includes("cdn.herovau.lt")&&(portraitAddress=game.data.addresses.remote+targetActor.img.trim(),hvDebug.enabled&&(console.log("%cHeroVau.lt/Foundry Bridge | %c target: "+targetActor,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %cportrait: "+portraitAddress,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %csheet portrait: "+targetActor.img,hvColor1,hvColor4))),0==targetActor.prototypeToken.texture.src.includes("http")&&0==targetActor.prototypeToken.texture.src.includes("cdn.herovau.lt")&&(tokenAddress=game.data.addresses.remote+targetActor.prototypeToken.texture.src.trim(),await targetActor.update({"prototypeToken.texture.src":tokenAddress}),hvDebug.enabled&&(console.log("%cHeroVau.lt/Foundry Bridge | %ctoken: "+tokenAddress,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %csheet token: "+targetActor.prototypeToken.texture.src,hvColor1,hvColor4)))),targetActor?.flags?.herovault?.uid){console.log(targetActor.flags),hvUID=targetActor.flags.herovault.uid;var accChk=await checkForAccess(hvUserToken,hvUID);canOverwrite=accChk.canAccess}else if(targetActor?.data?.flags?.herovault?.uid){hvUID=targetActor.data.flags.herovault.uid;let accChk=await checkForAccess(hvUserToken,hvUID);canOverwrite=accChk.canAccess}vaultInfo=await getVaultSlots(hvUserToken),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cvaultInfo: "+JSON.stringify(vaultInfo),hvColor1,hvColor4);var totalSlots=vaultInfo.totalSlots,freeSlots=totalSlots-vaultInfo.usedSlots;let bdy=`

You have ${freeSlots}/${totalSlots} character slots free.


`;hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %ccan access/overwrite?: "+canOverwrite,hvColor1,hvColor4),freeSlots<1&&0==canOverwrite?(bdy='

Unfortunately you do not have enough open slots in your HeroVau.lt to export this PC.
Please upgrade your account or delete a PC from your account to free up some space.


',new Dialog({title:"Export to your HeroVau.lt",content:bdy,buttons:{yes:{icon:"",label:"Ok"}},default:"yes"}).render(!0)):(0",label:"Export to HeroVau.lt as New PC",callback:()=>exportNewPC=!0}},bdy+="

You can export this character as a new PC, taking up a slot on your account.
(Note: if the same exact copy of this character exists on your account, it will be overwritten)

"):bdy+="

You do not have enough free slots to export this character as a new PC.

",canOverwrite&&(bdy+="

Since this character already exists in your vault, you can overwrite that character with this character.


",menuButtons={...menuButtons,exportOverwrite:{icon:"",label:"Export to HeroVau.lt overwriting existing PC",callback:()=>exportOverwritePC=!0}}),menuButtons={...menuButtons,no:{icon:"",label:"Cancel"}},bdy+=`


Please choose an action to perform:


`,new Dialog({title:"Export to your HeroVau.lt",content:bdy,buttons:menuButtons,default:"exportNew",close:async html=>{if(exportNewPC){hvUID="";var exportStatus=await exportPCtoHV(targetActor,hvUserToken,hvUID,!0,portraitAddress,tokenAddress);1==exportStatus.error?ui.notifications.error("Error exporting: "+exportStatus.message):(targetActor.update({"flags.herovault.uid":exportStatus.charhash}),ui.notifications.info(exportStatus.message))}else if(exportOverwritePC){hvDebug.enabled&&console.log("export overwrite PC");let exportStatus=await exportPCtoHV(targetActor,hvUserTokenHashed,hvUID,!1,portraitAddress,tokenAddress);1==exportStatus.error?ui.notifications.error("Error exporting: "+exportStatus.message):(targetActor.update({"flags.herovault.uid":exportStatus.charhash}),ui.notifications.info(exportStatus.message))}}}).render(!0))}catch(e){console.log(e)}}"https:"!==location.protocol&&(heroVaultURL="http://herovau.lt"),Hooks.on("ready",async function(){console.log("%cHeroVau.lt/Foundry Bridge | %cinitializing",hvColor1,hvColor4),"https:"!==location.protocol&&(game.user.isGM&&ui.notifications.info("GM: Please set your server to use HTTPS. For instructions see (coming soon)."),ui.notifications.info("HeroVau.lt using insecure HTTP mode.")),Cookie.get("hvut")&&(game.settings.set("herovaultfoundry","userToken",Cookie.get("hvut")),hvUserToken=game.settings.get("herovaultfoundry","userToken"),Cookie.set("hvut","",-1)),Cookie.get("herovault_skiptoken")&&(skipTokenPrompt=Cookie.get("herovault_skiptoken"),game.settings.set("herovaultfoundry","userToken",skipTokenPrompt),Cookie.set("herovault_skiptoken","",-1)),game.settings.register("herovaultfoundry","userToken",{name:"HeroVau.lt User Token",hint:"Please enter your personal user token from "+heroVaultURL+". Your HeroVau.lt token allows you to import and export PCs directly into your HeroVau.lt account. This is not required to use the Pathbuilder or HeroLab Online features.",scope:"client",config:!0,type:String,default:hvUserToken,onChange:value=>hvUserToken=game.settings.get("herovaultfoundry","userToken")}),game.settings.register("herovaultfoundry","hlouserToken",{name:"HeroLab Online User Token (optional)",hint:"Please enter your personal user token. A user token allows external tools (like HeroVau.lt) to access the HLO server and perform export operations.",scope:"client",config:!0,type:String,default:"",onChange:value=>setHLOToken()}),game.settings.register("herovaultfoundry","debugEnabled",{name:"Enable debug mode",hint:"Debug output will be written to the js console.",scope:"client",config:!0,type:Boolean,default:!1,onChange:value=>hvDebug.enabled=game.settings.get("herovaultfoundry","debugEnabled")}),game.settings.register("herovaultfoundry","skipTokenPrompt",{name:"Skip Token Prompt",hint:"Once your HeroVau.lt user token is set, you will no longer be prompted to set it. Unchecking this makes HeroVau.lt prompt you for the User Token again.",scope:"client",config:!0,type:Boolean,default:!1,onChange:value=>skipTokenPrompt=game.settings.get("herovaultfoundry","skipTokenPrompt")}),hvDebug.enabled=game.settings.get("herovaultfoundry","debugEnabled"),HLOuserToken=game.settings.get("herovaultfoundry","hlouserToken"),hvUserToken=game.settings.get("herovaultfoundry","userToken"),skipTokenPrompt=game.settings.get("herovaultfoundry","skipTokenPrompt")}),Hooks.on("renderActorSheet",function(obj,html){const actor=obj.actor;if(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cActor type: "+actor.type+"can update?: "+actor.testUserPermission(game.user,"update"),hvColor1,hvColor4),"character"===actor.type&&actor.testUserPermission(game.user,"update")){let element=html.find(".window-header .window-title");if(1==element.length){let head=html.find(".window-header");if(0==head.find("#herovault").length){let vaultButton=$('Vault');vaultButton.on("click",()=>checkNextAction(actor)),element.after(vaultButton)}game.modules.get("pathbuilder2e-import")?.active&&enablePB&&$("a:contains('Import from Pathbuilder')").remove()}}});const checkForAccess=async(hvUserToken,hvUID)=>new Promise(resolve=>{var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),resolve(responseJSON))},hvDebug.enabled&&(console.log("%cHeroVau.lt/Foundry Bridge | %cChecking if this account can access: "+hvUID,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %chttps://herovau.lt/foundrymodule.php?action=checkCharacter&userToken="+hvUserToken+"&charUID="+hvUID,hvColor1,hvColor4)),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=checkCharacter&userToken="+hvUserToken+"&charUID="+hvUID)}),getVaultSlots=async hvUserToken=>new Promise(resolve=>{var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),resolve(responseJSON))},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %chttps://herovau.lt/foundrymodule.php?action=getVaultSlots&userToken="+hvUserToken,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=getVaultSlots&userToken="+hvUserToken)}),exportPCtoHV=(targetActor,userToken,charUID,importAsNew,portraitAddress,tokenAddress)=>new Promise(resolve=>{let action="";action=importAsNew?"importNewPC":"importExistingPC";var gameSystem=game.system.id,gameSystemVersion=game.system.version,foundryVersion=game.version,pcEncodedJSON=encodeURIComponent(JSON.stringify(targetActor.toObject())),xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),console.log(responseJSON),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),resolve(responseJSON))},xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action="+action+"&userToken="+userToken+"&encodedChar="+pcEncodedJSON+"&gamesystem="+gameSystem+"&charUID="+charUID+"&portraitAddress="+encodeURIComponent(portraitAddress)+"&tokenAddress="+encodeURIComponent(tokenAddress)+"&foundryVersion="+encodeURIComponent(foundryVersion)+"&gameSystemVersion="+encodeURIComponent(gameSystemVersion))});function herovaultMenu(targetActor){let importPC=!1,exportPC=!1;var menuButtons={...menuButtons={import:{icon:"",label:"Import from HeroVau.lt",callback:()=>importPC=!0},export:{icon:"",label:"Export to HeroVau.lt",callback:()=>exportPC=!0}},no:{icon:"",label:"Cancel"}};new Dialog({title:"HeroVau.lt Import",content:"

Please choose an action to perform:


",buttons:menuButtons,default:"yes",close:html=>{importPC?(hvDebug.enabled&&console.log("import PC menu"),loadPersonalVault(targetActor,hvUserToken)):exportPC&&(hvDebug.enabled&&console.log("export PC"),exportToHV(targetActor,hvUserToken))}},{width:650,height:"auto"}).render(!0)}function exportPC(targetActor){null==hvUserToken&&(hvUserToken="")}function beginVaultConnection(targetActor){skipTokenPrompt?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cCalling herovaultMenu in beginVaultConnection",hvColor1,hvColor4),herovaultMenu(targetActor,hvUserToken)):(null==hvUserToken&&(hvUserToken=""),getVaultToken(herovaultMenu,targetActor,hvUserToken))}function loadPersonalVault(targetActor){var gameSystem=game.system.id;let error=!1;var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){if(4==this.readyState&&200==this.status){let responseJSON=JSON.parse(this.responseText);hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+responseJSON,hvColor1,hvColor4),responseJSON.hasOwnProperty("error")?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cerror found in response",hvColor1,hvColor4),error=!0):hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+Object.keys(responseJSON).length,hvColor1,hvColor4),error?new Dialog({title:"HeroVau.lt",content:` + `,buttons:{yes:{icon:"",label:"Connect to HeroVau.lt",callback:()=>applyChanges=!0},no:{icon:"",label:"Cancel"}},default:"yes",close:skipToken=>{var userToken;applyChanges&&(userToken=skipToken.find('[id="textBoxUserToken"]')[0].value,skipToken=skipToken.find('[id="skipToken"]')[0].checked,checkUserToken(userToken),hvUserToken=userToken,skipToken&&game.settings.set("herovaultfoundry","skipTokenPrompt",!0),callback(callbackArg1,callbackArg2,callbackArg3,callbackArg4))}}).render(!0)}async function exportToHV(targetActor){try{var hvUserToken=game.settings.get("herovaultfoundry","userToken"),xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),1==responseJSON.status?performExportToHV(targetActor):(hvUserToken="",game.settings.set("herovaultfoundry","userToken",null),ui.notifications.warn("Unable to load vault. Please double-check your User Token."),game.settings.set("herovaultfoundry","skipTokenPrompt",!1),getVaultToken(exportToHV,targetActor,hvUserToken)))},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c/foundrymodule.php?action=iv&userToken="+hvUserToken,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=iv&userToken="+hvUserToken+"&hvVer="+encodeURIComponent(hvVer))}catch(e){console.log(e)}}async function toDataURL(src,callback,outputFormat){var img=new Image;img.crossOrigin="Anonymous",img.onload=function(){var dataURL=document.createElement("CANVAS"),ctx=dataURL.getContext("2d");dataURL.height=this.naturalHeight,dataURL.width=this.naturalWidth,ctx.drawImage(this,0,0),dataURL=dataURL.toDataURL(outputFormat),callback(dataURL)},img.src=src,!img.complete&&void 0!==img.complete||(img.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",img.src=src)}function returnImage(img){return console.log("I got img: "+img),img}async function performExportToHV(targetActor){try{let menuButtons={},exportNewPC=!1,exportOverwritePC=!1;var vaultInfo;let canOverwrite=!1,portrait,hvUID,portraitAddress,tokenAddress;hvUserToken=game.settings.get("herovaultfoundry","userToken");var hvUserTokenHashed=await getSHA(hvUserToken);if(portrait="icons/svg/mystery-man.svg",null!=targetActor.img&&null!=targetActor.prototypeToken.texture.src&&(portrait=-1!=targetActor.img.includes("mystery-man")&&-1==targetActor.prototypeToken.texture.src.includes("mystery-man")?targetActor.prototypeToken.texture.src:targetActor.img,hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cportrait includes: "+targetActor.img.includes("http"),hvColor1,hvColor4),portraitAddress=targetActor.img.trim(),hvDebug.enabled&&(console.log("%cHeroVau.lt/Foundry Bridge | %c target: "+targetActor,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %cportrait: "+portraitAddress,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %csheet portrait: "+targetActor.img,hvColor1,hvColor4)),tokenAddress=targetActor.prototypeToken.texture.src.trim(),hvDebug.enabled&&(console.log("%cHeroVau.lt/Foundry Bridge | %ctoken: "+tokenAddress,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %csheet token: "+targetActor.prototypeToken.texture.src,hvColor1,hvColor4))),targetActor?.flags?.herovault?.uid){console.log(targetActor.flags),hvUID=targetActor.flags.herovault.uid;var accChk=await checkForAccess(hvUserToken,hvUID);canOverwrite=accChk.canAccess}else if(targetActor?.data?.flags?.herovault?.uid){hvUID=targetActor.data.flags.herovault.uid;let accChk=await checkForAccess(hvUserToken,hvUID);canOverwrite=accChk.canAccess}vaultInfo=await getVaultSlots(hvUserToken),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cvaultInfo: "+JSON.stringify(vaultInfo),hvColor1,hvColor4);var totalSlots=vaultInfo.totalSlots,freeSlots=totalSlots-vaultInfo.usedSlots;let bdy=`

You have ${freeSlots}/${totalSlots} character slots free.


`;hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %ccan access/overwrite?: "+canOverwrite,hvColor1,hvColor4),freeSlots<1&&0==canOverwrite?(bdy='

Unfortunately you do not have enough open slots in your HeroVau.lt to export this PC.
Please upgrade your account or delete a PC from your account to free up some space.


',new Dialog({title:"Export to your HeroVau.lt",content:bdy,buttons:{yes:{icon:"",label:"Ok"}},default:"yes"}).render(!0)):(0",label:"Export to HeroVau.lt as New PC",callback:()=>exportNewPC=!0}},bdy+="

You can export this character as a new PC, taking up a slot on your account.
(Note: if the same exact copy of this character exists on your account, it will be overwritten)

"):bdy+="

You do not have enough free slots to export this character as a new PC.

",canOverwrite&&(bdy+="

Since this character already exists in your vault, you can overwrite that character with this character.


",menuButtons={...menuButtons,exportOverwrite:{icon:"",label:"Export to HeroVau.lt overwriting existing PC",callback:()=>exportOverwritePC=!0}}),menuButtons={...menuButtons,no:{icon:"",label:"Cancel"}},bdy+=`


Please choose an action to perform:


`,new Dialog({title:"Export to your HeroVau.lt",content:bdy,buttons:menuButtons,default:"exportNew",close:async html=>{if(exportNewPC){hvUID="";var exportStatus=await exportPCtoHV(targetActor,hvUserToken,hvUID,!0,portraitAddress,tokenAddress);1==exportStatus.error?ui.notifications.error("Error exporting: "+exportStatus.message):(targetActor.update({"flags.herovault.uid":exportStatus.charhash}),ui.notifications.info(exportStatus.message))}else if(exportOverwritePC){hvDebug.enabled&&console.log("export overwrite PC");let exportStatus=await exportPCtoHV(targetActor,hvUserTokenHashed,hvUID,!1,portraitAddress,tokenAddress);1==exportStatus.error?ui.notifications.error("Error exporting: "+exportStatus.message):(targetActor.update({"flags.herovault.uid":exportStatus.charhash}),ui.notifications.info(exportStatus.message))}}}).render(!0))}catch(e){console.log(e)}}"https:"!==location.protocol&&(heroVaultURL="http://herovau.lt"),Hooks.on("ready",async function(){console.log("%cHeroVau.lt/Foundry Bridge | %cinitializing",hvColor1,hvColor4),"https:"!==location.protocol&&(game.user.isGM&&ui.notifications.info("GM: Please set your server to use HTTPS. For instructions see (coming soon)."),ui.notifications.info("HeroVau.lt using insecure HTTP mode.")),Cookie.get("hvut")&&(game.settings.set("herovaultfoundry","userToken",Cookie.get("hvut")),hvUserToken=game.settings.get("herovaultfoundry","userToken"),Cookie.set("hvut","",-1)),Cookie.get("herovault_skiptoken")&&(skipTokenPrompt=Cookie.get("herovault_skiptoken"),game.settings.set("herovaultfoundry","userToken",skipTokenPrompt),Cookie.set("herovault_skiptoken","",-1)),game.settings.register("herovaultfoundry","userToken",{name:"HeroVau.lt User Token",hint:"Please enter your personal user token from "+heroVaultURL+". Your HeroVau.lt token allows you to import and export PCs directly into your HeroVau.lt account. This is not required to use the Pathbuilder or HeroLab Online features.",scope:"client",config:!0,type:String,default:hvUserToken,onChange:value=>hvUserToken=game.settings.get("herovaultfoundry","userToken")}),game.settings.register("herovaultfoundry","hlouserToken",{name:"HeroLab Online User Token (optional)",hint:"Please enter your personal user token. A user token allows external tools (like HeroVau.lt) to access the HLO server and perform export operations.",scope:"client",config:!0,type:String,default:"",onChange:value=>setHLOToken()}),game.settings.register("herovaultfoundry","debugEnabled",{name:"Enable debug mode",hint:"Debug output will be written to the js console.",scope:"client",config:!0,type:Boolean,default:!1,onChange:value=>hvDebug.enabled=game.settings.get("herovaultfoundry","debugEnabled")}),game.settings.register("herovaultfoundry","skipTokenPrompt",{name:"Skip Token Prompt",hint:"Once your HeroVau.lt user token is set, you will no longer be prompted to set it. Unchecking this makes HeroVau.lt prompt you for the User Token again.",scope:"client",config:!0,type:Boolean,default:!1,onChange:value=>skipTokenPrompt=game.settings.get("herovaultfoundry","skipTokenPrompt")}),hvDebug.enabled=game.settings.get("herovaultfoundry","debugEnabled"),HLOuserToken=game.settings.get("herovaultfoundry","hlouserToken"),hvUserToken=game.settings.get("herovaultfoundry","userToken"),skipTokenPrompt=game.settings.get("herovaultfoundry","skipTokenPrompt")}),Hooks.on("renderActorSheet",function(obj,html){const actor=obj.actor;if(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cActor type: "+actor.type+"can update?: "+actor.testUserPermission(game.user,"update"),hvColor1,hvColor4),"character"===actor.type&&actor.testUserPermission(game.user,"update")){let element=html.find(".window-header .window-title");if(1==element.length){let head=html.find(".window-header");if(0==head.find("#herovault").length){let vaultButton=$('Vault');vaultButton.on("click",()=>checkNextAction(actor)),element.after(vaultButton)}game.modules.get("pathbuilder2e-import")?.active&&enablePB&&$("a:contains('Import from Pathbuilder')").remove()}}});const checkForAccess=async(hvUserToken,hvUID)=>new Promise(resolve=>{var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),resolve(responseJSON))},hvDebug.enabled&&(console.log("%cHeroVau.lt/Foundry Bridge | %cChecking if this account can access: "+hvUID,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %chttps://herovau.lt/foundrymodule.php?action=checkCharacter&userToken="+hvUserToken+"&charUID="+hvUID,hvColor1,hvColor4)),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=checkCharacter&userToken="+hvUserToken+"&charUID="+hvUID+"&hvVer="+encodeURIComponent(hvVer))}),getVaultSlots=async hvUserToken=>new Promise(resolve=>{var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),resolve(responseJSON))},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %chttps://herovau.lt/foundrymodule.php?action=getVaultSlots&userToken="+hvUserToken,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=getVaultSlots&userToken="+hvUserToken+"&hvVer="+encodeURIComponent(hvVer))}),exportPCtoHV=(targetActor,userToken,charUID,importAsNew,portraitAddress,tokenAddress)=>new Promise(resolve=>{let action="";action=importAsNew?"importNewPC":"importExistingPC";var gameSystem=game.system.id,gameSystemVersion=game.system.version,foundryVersion=game.version,pcEncodedJSON=encodeURIComponent(JSON.stringify(targetActor.toObject())),xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),console.log(responseJSON),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(responseJSON),hvColor1,hvColor4),charUID=responseJSON.charhash,toDataURL(targetActor.img,function(dataUrl){var xmlhttpPortrait=new XMLHttpRequest;xmlhttpPortrait.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),console.log(responseJSON),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cPortrait Upload:"+JSON.stringify(responseJSON),hvColor1,hvColor4),ui.notifications.info("Successfully exported portrait image HeroVau.lt."),resolve(responseJSON))},xmlhttpPortrait.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttpPortrait.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttpPortrait.send("action=portraitSend&userToken="+userToken+"&charUID="+charUID+"&portraitBase64="+encodeURIComponent(dataUrl)+"&hvVer="+encodeURIComponent(hvVer))},"image/png"),toDataURL(targetActor.prototypeToken.texture.src,function(dataUrl){var xmlhttpToken=new XMLHttpRequest;xmlhttpToken.onreadystatechange=function(){var responseJSON;4==this.readyState&&200==this.status&&(responseJSON=JSON.parse(this.responseText),console.log(responseJSON),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cToken Upload:"+JSON.stringify(responseJSON),hvColor1,hvColor4),ui.notifications.info("Successfully exported token image HeroVau.lt."),resolve(responseJSON))},xmlhttpToken.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttpToken.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttpToken.send("action=tokenSend&userToken="+userToken+"&charUID="+charUID+"&tokenBase64="+encodeURIComponent(dataUrl)+"&hvVer="+encodeURIComponent(hvVer))}),resolve(responseJSON))},xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action="+action+"&userToken="+userToken+"&encodedChar="+pcEncodedJSON+"&gamesystem="+gameSystem+"&charUID="+charUID+"&foundryVersion="+encodeURIComponent(foundryVersion)+"&gameSystemVersion="+encodeURIComponent(gameSystemVersion)+"&hvVer="+encodeURIComponent(hvVer))});function herovaultMenu(targetActor){let importPC=!1,exportPC=!1;var menuButtons={...menuButtons={import:{icon:"",label:"Import from HeroVau.lt",callback:()=>importPC=!0},export:{icon:"",label:"Export to HeroVau.lt",callback:()=>exportPC=!0}},no:{icon:"",label:"Cancel"}};new Dialog({title:"HeroVau.lt Import",content:"

Please choose an action to perform:


",buttons:menuButtons,default:"yes",close:html=>{importPC?(hvDebug.enabled&&console.log("import PC menu"),loadPersonalVault(targetActor,hvUserToken)):exportPC&&(hvDebug.enabled&&console.log("export PC"),exportToHV(targetActor,hvUserToken))}},{width:650,height:"auto"}).render(!0)}function exportPC(targetActor){null==hvUserToken&&(hvUserToken="")}function beginVaultConnection(targetActor){skipTokenPrompt?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cCalling herovaultMenu in beginVaultConnection",hvColor1,hvColor4),herovaultMenu(targetActor,hvUserToken)):(null==hvUserToken&&(hvUserToken=""),getVaultToken(herovaultMenu,targetActor,hvUserToken))}function loadPersonalVault(targetActor){var gameSystem=game.system.id;let error=!1;var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){if(4==this.readyState&&200==this.status){let responseJSON=JSON.parse(this.responseText);hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+responseJSON,hvColor1,hvColor4),responseJSON.hasOwnProperty("error")?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cerror found in response",hvColor1,hvColor4),error=!0):hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+Object.keys(responseJSON).length,hvColor1,hvColor4),error?new Dialog({title:"HeroVau.lt",content:`

Error

${responseJSON.error}

-


`,buttons:{yes:{icon:"",label:"Ok"}},default:"yes"}).render(!0):1<=Object.keys(responseJSON).length?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cCalling checkHLOCharacterIsCorrect",hvColor1,hvColor4),createPCTable(targetActor,responseJSON)):(ui.notifications.warn("Unable to load vault. Please double-check your User Token."),game.settings.set("herovaultfoundry","skipTokenPrompt",!1),getVaultToken(loadPersonalVault,targetActor,hvUserToken))}},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cusertoken: "+hvUserToken,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=getvault&gamesystem="+encodeURIComponent(gameSystem)+"&hvVer="+hvVer+"&userToken="+hvUserToken)}function createPCTable(targetActor,responseJSON){var charName,charRace,charClass,charLevel,pickedCharacter,selectedCharUID;hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cin createPCTable",hvColor1,hvColor4);for(var htmlOut="Select a PC from the list:


",new Dialog({title:"Importable Character List",content:` +

`,buttons:{yes:{icon:"",label:"Ok"}},default:"yes"}).render(!0):1<=Object.keys(responseJSON).length?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cCalling checkHLOCharacterIsCorrect",hvColor1,hvColor4),createPCTable(targetActor,responseJSON)):(ui.notifications.warn("Unable to load vault. Please double-check your User Token."),game.settings.set("herovaultfoundry","skipTokenPrompt",!1),getVaultToken(loadPersonalVault,targetActor,hvUserToken))}},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cusertoken: "+hvUserToken,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=getvault&gamesystem="+encodeURIComponent(gameSystem)+"&hvVer="+hvVer+"&userToken="+hvUserToken+"&hvVer="+encodeURIComponent(hvVer))}function createPCTable(targetActor,responseJSON){var charName,charRace,charClass,charLevel,pickedCharacter,selectedCharUID;hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cin createPCTable",hvColor1,hvColor4);for(var htmlOut="Select a PC from the list:


",new Dialog({title:"Importable Character List",content:`
`+htmlOut+`


`,buttons:{yes:{icon:"",label:"Proceed",callback:()=>pickedCharacter=!0},no:{icon:"",label:"Cancel",callback:()=>pickedCharacter=!1}},default:"yes",close:html=>{pickedCharacter?(hvDebug.enabled&&console.log("yes clicked"),selectedCharUID=html.find('[id="pcid"]')[0].value,hvDebug.enabled&&console.log("Selected PC id: "+selectedCharUID),requestCharacter(targetActor,selectedCharUID)):hvDebug.enabled&&console.log("cancel clicked")}},{width:650,height:"auto"}).render(!0)}function requestCharacter(targetActor,charUID){let error=!1;var xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=function(){if(4==this.readyState&&200==this.status){let responseJSON=JSON.parse(this.responseText);hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+responseJSON,hvColor1,hvColor4),responseJSON.hasOwnProperty("error")?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cerror found in response",hvColor1,hvColor4),error=!0):hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+Object.keys(responseJSON).length,hvColor1,hvColor4),error?new Dialog({title:"HeroVau.lt",content:`

Error

${responseJSON.error}

Please contact us with this information above by going to https://herovau.lt/?action=contact.

-


`,buttons:{yes:{icon:"",label:"Ok"}},default:"yes"}).render(!0):responseJSON.downloadURL?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cGot the URL: "+responseJSON.downloadURL,hvColor1,hvColor4),importCharacter(targetActor,responseJSON.downloadURL)):ui.notifications.warn("Unable find character. Please contact HeroVau.lt support.")}},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %ccharUID: "+charUID,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=getCharacter&charUID="+encodeURIComponent(charUID))}async function importCharacter(targetActor,charURL){var importPCID,charDataStr,charImport,errMsg="",xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=async function(){if(4==this.readyState&&200==this.status){var request2=JSON.parse(this.responseText);hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(request2),hvColor1,hvColor4);{var newSaves=targetActor._id;let coreVersionMismatch=!1,systemVersionMismatch=!1,abort=!1;var chatData=game.system.version,coreVersion=game.version;let pcGameSystemVersion,pcCoreVersion;if(request2?.flags?.herovault?.gameSystemVersion&&request2?.flags?.herovault?.foundryVersion?(pcCoreVersion=request2.flags.herovault.foundryVersion,pcGameSystemVersion=request2.flags.herovault.gameSystemVersion):request2.flags?.exportSource?.systemVersion&&request2.flags?.exportSource?.coreVersion&&(pcCoreVersion=request2.flags.exportSource.coreVersion,pcGameSystemVersion=request2.flags.exportSource.systemVersion),pcCoreVersion!=coreVersion&&(coreVersionMismatch=!0,errMsg=errMsg+"This PC was exported from Foundry v"+pcCoreVersion+" and this game server is running Foundry v"+coreVersion+".

"),pcGameSystemVersion!=chatData&&(systemVersionMismatch=!0,errMsg=1==HVversionCompare(pcGameSystemVersion,chatData)?(abort=!0,errMsg+"This PC was exported from "+game.system.title+": "+pcGameSystemVersion+" and this game server is running "+game.system.title+": "+chatData+".

Unfortunately, game systems usually are not backwards compatible, so we areaborting this import. To manually override, please download the hero export from herovau.lt.
This may break this PC -- you have been warned!

If the actor won't open, it is corrupted and should be deleted. If this PC fails to import or corrupts the actor it was imported to, you should attempt to import your PC into Foundry v9 and re-export to HeroVau.lt here: https://slate-pf2-dev.forge-vtt.com/game
Once that procedure is complete, come back to this game and retry importing from HeroVau.lt again."):errMsg+"This PC was exported from "+game.system.title+": "+pcGameSystemVersion+" and this game server is running "+game.system.title+": "+chatData+".

"),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | Mismatch?:%c"+systemVersionMismatch+" | "+coreVersionMismatch,hvColor1,hvColor4),systemVersionMismatch||coreVersionMismatch){errMsg+="There may be compatibility issues.

If the actor won't open, it is corrupted and should be deleted. If this PC fails to import or corrupts the actor it was imported to, you should attempt to import your PC into Foundry v9 and re-export to HeroVau.lt here: https://slate-pf2-dev.forge-vtt.com/game
Once that procedure is complete, come back to this game and retry importing from HeroVau.lt again.

";chatData={user:game.user._id,speaker:ChatMessage.getSpeaker(),content:errMsg,whisper:[game.user._id]};if(ChatMessage.create(chatData,{}),abort)return}request2._id?(importPCID=new RegExp(request2._id,"g"),charDataStr=JSON.stringify(request2),hvDebug.enabled&&(console.log("%cHeroVau.lt/Foundry Bridge | Target ID:%c"+newSaves,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %c"+charDataStr,hvColor1,hvColor4)),charDataStr=charDataStr.replace(importPCID,newSaves),charImport=JSON.parse(charDataStr)):(charImport=request2)._id=newSaves,charImport?.data?.saves&&Array.isArray(charImport.data.saves)&&(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cConverting a bad saves array to object.",hvColor1,hvColor4),newSaves=charImport.data.saves,newSaves=Object.assign({},newSaves),charImport.data.saves=newSaves),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cChecking for crafting:"+request2?.data?.crafting,hvColor1,hvColor4),charImport?.data&&!charImport?.data?.crafting&&(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c Adding crafting block to PC",hvColor1,hvColor4),charImport.data.crafting={formulas:[]});request2=targetActor.permission;charImport.permission=request2,hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cHLO Importer | %c Importing "+charImport.name,hvColor1,hvColor5,hvColor4);request2=targetActor._id;targetActor=Actor.get(request2),charImport=await fixOldSlugs(charImport=await removeDarkvision(charImport));request2=JSON.stringify(charImport);hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cFinal json for import: "+request2,hvColor1,hvColor4);await doImport(targetActor,request2);request2=new XMLHttpRequest;void 0!==charImport?.prototypeToken?.texture?.src&&(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cFetching token image "+charImport.prototypeToken.texture.src,hvColor1,hvColor4),request2.open("GET",charImport.prototypeToken.texture.src,!0),request2.onreadystatechange=function(){404===this.status&&(targetActor.update({"prototypeToken.texture.src":"icons/svg/mystery-man.svg"}),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c404 fetching image "+charImport.prototypeToken.texture.src,hvColor1,hvColor4))},request2.send());request2=new XMLHttpRequest;hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cFetching image "+charImport.src,hvColor1,hvColor4),request2.open("GET",charImport.img,!0),request2.onreadystatechange=function(){404===this.status&&(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c404 fetching image "+charImport.img,hvColor1,hvColor4),targetActor.update({img:"icons/svg/mystery-man.svg"}))},request2.send()}}},xmlhttp.open("GET",charURL,!0),xmlhttp.send()}async function doImport(obj,json){return obj.importFromJSON(json)}async function removeDarkvision(charJSON){if("pf2e"==charJSON?.flags?.exportSource?.system)for(const property in charJSON.items)"darkvision"==charJSON.items[property]?.data?.slug&&charJSON.items.splice(property,1);return charJSON}async function fixOldSlugs(charJSON){if("pf2e"==(charJSON=Object.assign({},charJSON))?.flags?.exportSource?.system)for(const property in charJSON.items)if(charJSON.items[property]?.flags?.core?.sourceId){var itemData=charJSON.items[property].flags.core.sourceId.split(".");if("equipment-srd"==itemData[2]){let pack=game.packs.get(itemData[1]+"."+itemData[2]);itemData=Object.assign({},await pack.getDocument(itemData[3]));if(itemData){let oldItemData=Object.assign({},charJSON.items[property]);oldItemData?.data?.slug&&itemData?.system?.slug&&(oldItemData.data.slug=itemData.system.slug,charJSON.items.push(itemData),charJSON.items.splice(property,1))}}}return charJSON}async function checkForStaleData(charJSON){if("pf2e"==(charJSON=Object.assign({},charJSON))?.flags?.exportSource?.system){var itemSource;for(const property in charJSON.items)charJSON.items[property]?.flags?.core?.sourceId?(itemSource=charJSON.items[property].flags.core.sourceId.split("."),console.log(itemSource[0]+"."+itemSource[1]+"."+itemSource[2]),"equipment-srd"!=itemSource[2]&&"pathfinder-society-boons"!=itemSource[2]&&charJSON.items[property]?._stats&&(charJSON.items[property]._stats.systemId="pf2e",charJSON.items[property]._stats.systemVersion=game.system.version,charJSON.items[property]._stats.coreVersion=game.version,charJSON.items[property]._stats.createdTime=Math.floor(Date.now()/1e3),charJSON.items[property]._stats.modifiedTime=Math.floor(Date.now()/1e3),charJSON.items[property]._stats.lastModifiedBy=game.userId)):console.log("No sourceId, skipping")}return console.log("modified charJSON"),console.log(charJSON),charJSON}var Cookie={set:function(name,value,host){var domain,expires=host?((domain=new Date).setTime(domain.getTime()+864e5*host),"; expires="+domain.toGMTString()):"",host=location.host;1===host.split(".").length?document.cookie=name+"="+value+expires+"; path=/; SameSite=Strict":((domain=host.split(".")).shift(),domain="."+domain.join("."),host.includes("forge-vtt.com")?document.cookie=name+"="+value+expires+"; path=/; domain=.forge-vtt.com; SameSite=Strict":(document.cookie=name+"="+value+expires+"; path=/; domain="+domain+"; SameSite=Strict",document.cookie=name+"="+value+expires+"; path=/; domain="+host+"; SameSite=Strict"),null!=Cookie.get(name)&&Cookie.get(name)==value||(domain="."+host,document.cookie=name+"="+value+expires+"; path=/; domain="+domain+"; SameSite=Strict"))},get:function(name){for(var nameEQ=name+"=",ca=document.cookie.split(";"),i=0;iparseInt(b[i]))return 1;if(b[i]&&!a[i]&&0b.toString(16).padStart(2,"0")).join("")}Hooks.on("init",()=>{game.modules.get("herovaultfoundry").api={exportToHVFromPBHLO:exportToHVFromPBHLO,supportCheck:supportCheck},Hooks.callAll("herovaultfoundryReady",game.modules.get("herovaultfoundry").api)});export{exportToHVFromPBHLO,supportCheck}; \ No newline at end of file +

`,buttons:{yes:{icon:"",label:"Ok"}},default:"yes"}).render(!0):responseJSON.downloadURL?(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cGot the URL: "+responseJSON.downloadURL,hvColor1,hvColor4),importCharacter(targetActor,responseJSON.downloadURL)):ui.notifications.warn("Unable find character. Please contact HeroVau.lt support.")}},hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %ccharUID: "+charUID,hvColor1,hvColor4),xmlhttp.open("POST",heroVaultURL+"/foundrymodule.php",!0),xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"),xmlhttp.send("action=getCharacter&charUID="+encodeURIComponent(charUID)+"&hvVer="+encodeURIComponent(hvVer))}async function importCharacter(targetActor,charURL){var importPCID,charDataStr,charImport,errMsg="",xmlhttp=new XMLHttpRequest;xmlhttp.onreadystatechange=async function(){if(4==this.readyState&&200==this.status){var request2=JSON.parse(this.responseText);hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c"+JSON.stringify(request2),hvColor1,hvColor4);{var newSaves=targetActor._id;let coreVersionMismatch=!1,systemVersionMismatch=!1,abort=!1;var chatData=game.system.version,coreVersion=game.version;let pcGameSystemVersion,pcCoreVersion;if(request2?.flags?.herovault?.gameSystemVersion&&request2?.flags?.herovault?.foundryVersion?(pcCoreVersion=request2.flags.herovault.foundryVersion,pcGameSystemVersion=request2.flags.herovault.gameSystemVersion):request2.flags?.exportSource?.systemVersion&&request2.flags?.exportSource?.coreVersion&&(pcCoreVersion=request2.flags.exportSource.coreVersion,pcGameSystemVersion=request2.flags.exportSource.systemVersion),pcCoreVersion!=coreVersion&&(coreVersionMismatch=!0,errMsg=errMsg+"This PC was exported from Foundry v"+pcCoreVersion+" and this game server is running Foundry v"+coreVersion+".

"),pcGameSystemVersion!=chatData&&(systemVersionMismatch=!0,errMsg=1==HVversionCompare(pcGameSystemVersion,chatData)?(abort=!0,errMsg+"This PC was exported from "+game.system.title+": "+pcGameSystemVersion+" and this game server is running "+game.system.title+": "+chatData+".

Unfortunately, game systems usually are not backwards compatible, so we areaborting this import. To manually override, please download the hero export from herovau.lt.
This may break this PC -- you have been warned!

If the actor won't open, it is corrupted and should be deleted. If this PC fails to import or corrupts the actor it was imported to, you should attempt to import your PC into Foundry v9 and re-export to HeroVau.lt here: https://slate-pf2-dev.forge-vtt.com/game
Once that procedure is complete, come back to this game and retry importing from HeroVau.lt again."):errMsg+"This PC was exported from "+game.system.title+": "+pcGameSystemVersion+" and this game server is running "+game.system.title+": "+chatData+".

"),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | Mismatch?:%c"+systemVersionMismatch+" | "+coreVersionMismatch,hvColor1,hvColor4),systemVersionMismatch||coreVersionMismatch){errMsg+="There may be compatibility issues.

If the actor won't open, it is corrupted and should be deleted. If this PC fails to import or corrupts the actor it was imported to, you should attempt to import your PC into Foundry v9 and re-export to HeroVau.lt here: https://slate-pf2-dev.forge-vtt.com/game
Once that procedure is complete, come back to this game and retry importing from HeroVau.lt again.

";chatData={user:game.user._id,speaker:ChatMessage.getSpeaker(),content:errMsg,whisper:[game.user._id]};if(ChatMessage.create(chatData,{}),abort)return}request2._id?(importPCID=new RegExp(request2._id,"g"),charDataStr=JSON.stringify(request2),hvDebug.enabled&&(console.log("%cHeroVau.lt/Foundry Bridge | Target ID:%c"+newSaves,hvColor1,hvColor4),console.log("%cHeroVau.lt/Foundry Bridge | %c"+charDataStr,hvColor1,hvColor4)),charDataStr=charDataStr.replace(importPCID,newSaves),charImport=JSON.parse(charDataStr)):(charImport=request2)._id=newSaves,charImport?.data?.saves&&Array.isArray(charImport.data.saves)&&(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cConverting a bad saves array to object.",hvColor1,hvColor4),newSaves=charImport.data.saves,newSaves=Object.assign({},newSaves),charImport.data.saves=newSaves),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cChecking for crafting:"+request2?.data?.crafting,hvColor1,hvColor4),charImport?.data&&!charImport?.data?.crafting&&(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c Adding crafting block to PC",hvColor1,hvColor4),charImport.data.crafting={formulas:[]});request2=targetActor.permission;charImport.permission=request2,hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cHLO Importer | %c Importing "+charImport.name,hvColor1,hvColor5,hvColor4);request2=targetActor._id;targetActor=Actor.get(request2),charImport=await fixOldSlugs(charImport=await removeDarkvision(charImport));request2=JSON.stringify(charImport);hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cFinal json for import: "+request2,hvColor1,hvColor4);await doImport(targetActor,request2);request2=new XMLHttpRequest;void 0!==charImport?.prototypeToken?.texture?.src&&(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cFetching token image "+charImport.prototypeToken.texture.src,hvColor1,hvColor4),request2.open("GET",charImport.prototypeToken.texture.src,!0),request2.onreadystatechange=function(){404===this.status&&(targetActor.update({"prototypeToken.texture.src":"icons/svg/mystery-man.svg"}),hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c404 fetching image "+charImport.prototypeToken.texture.src,hvColor1,hvColor4))},request2.send());request2=new XMLHttpRequest;hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %cFetching image "+charImport.src,hvColor1,hvColor4),request2.open("GET",charImport.img,!0),request2.onreadystatechange=function(){404===this.status&&(hvDebug.enabled&&console.log("%cHeroVau.lt/Foundry Bridge | %c404 fetching image "+charImport.img,hvColor1,hvColor4),targetActor.update({img:"icons/svg/mystery-man.svg"}))},request2.send()}}},xmlhttp.open("GET",charURL,!0),xmlhttp.send()}async function doImport(obj,json){return obj.importFromJSON(json)}async function removeDarkvision(charJSON){if("pf2e"==charJSON?.flags?.exportSource?.system)for(const property in charJSON.items)"darkvision"==charJSON.items[property]?.data?.slug&&charJSON.items.splice(property,1);return charJSON}async function fixOldSlugs(charJSON){if("pf2e"==(charJSON=Object.assign({},charJSON))?.flags?.exportSource?.system)for(const property in charJSON.items)if(charJSON.items[property]?.flags?.core?.sourceId){var itemData=charJSON.items[property].flags.core.sourceId.split(".");if("equipment-srd"==itemData[2]){let pack=game.packs.get(itemData[1]+"."+itemData[2]);itemData=Object.assign({},await pack.getDocument(itemData[3]));if(itemData){let oldItemData=Object.assign({},charJSON.items[property]);oldItemData?.data?.slug&&itemData?.system?.slug&&(oldItemData.data.slug=itemData.system.slug,charJSON.items.push(itemData),charJSON.items.splice(property,1))}}}return charJSON}async function checkForStaleData(charJSON){if("pf2e"==(charJSON=Object.assign({},charJSON))?.flags?.exportSource?.system){var itemSource;for(const property in charJSON.items)charJSON.items[property]?.flags?.core?.sourceId?(itemSource=charJSON.items[property].flags.core.sourceId.split("."),console.log(itemSource[0]+"."+itemSource[1]+"."+itemSource[2]),"equipment-srd"!=itemSource[2]&&"pathfinder-society-boons"!=itemSource[2]&&charJSON.items[property]?._stats&&(charJSON.items[property]._stats.systemId="pf2e",charJSON.items[property]._stats.systemVersion=game.system.version,charJSON.items[property]._stats.coreVersion=game.version,charJSON.items[property]._stats.createdTime=Math.floor(Date.now()/1e3),charJSON.items[property]._stats.modifiedTime=Math.floor(Date.now()/1e3),charJSON.items[property]._stats.lastModifiedBy=game.userId)):console.log("No sourceId, skipping")}return console.log("modified charJSON"),console.log(charJSON),charJSON}var Cookie={set:function(name,value,host){var domain,expires=host?((domain=new Date).setTime(domain.getTime()+864e5*host),"; expires="+domain.toGMTString()):"",host=location.host;1===host.split(".").length?document.cookie=name+"="+value+expires+"; path=/; SameSite=Strict":((domain=host.split(".")).shift(),domain="."+domain.join("."),host.includes("forge-vtt.com")?document.cookie=name+"="+value+expires+"; path=/; domain=.forge-vtt.com; SameSite=Strict":(document.cookie=name+"="+value+expires+"; path=/; domain="+domain+"; SameSite=Strict",document.cookie=name+"="+value+expires+"; path=/; domain="+host+"; SameSite=Strict"),null!=Cookie.get(name)&&Cookie.get(name)==value||(domain="."+host,document.cookie=name+"="+value+expires+"; path=/; domain="+domain+"; SameSite=Strict"))},get:function(name){for(var nameEQ=name+"=",ca=document.cookie.split(";"),i=0;iparseInt(b[i]))return 1;if(b[i]&&!a[i]&&0b.toString(16).padStart(2,"0")).join("")}Hooks.on("init",()=>{game.modules.get("herovaultfoundry").api={exportToHVFromPBHLO:exportToHVFromPBHLO,supportCheck:supportCheck},Hooks.callAll("herovaultfoundryReady",game.modules.get("herovaultfoundry").api)});export{exportToHVFromPBHLO,supportCheck}; \ No newline at end of file diff --git a/herovault.js b/herovault.js index 08d3c16..9b20ca0 100644 --- a/herovault.js +++ b/herovault.js @@ -1,5 +1,5 @@ const hvDebug = { enabled: false }; -const hvVer = "0.10.3"; +const hvVer = "0.10.4"; let heroVaultURL = "https://herovau.lt"; const hvColor1 = "color: #7bf542"; //bright green @@ -178,7 +178,9 @@ async function checkUserToken(token) { xmlhttp.send( "action=iv" + "&userToken=" + - hvUserToken + hvUserToken + + "&hvVer=" + + encodeURIComponent(hvVer) ); } @@ -486,7 +488,9 @@ async function findPFS(obj, pfsnumber, pfscharnumber) { "&pfsnumber=" + pfsnumber + "&pfscharnumber=" + - pfscharnumber + pfscharnumber + + "&hvVer=" + + encodeURIComponent(hvVer) ); } @@ -617,13 +621,40 @@ async function exportToHV(targetActor) { xmlhttp.send( "action=iv" + "&userToken=" + - hvUserToken + hvUserToken + + "&hvVer=" + + encodeURIComponent(hvVer) ); } catch (e) { console.log(e); } } +async function toDataURL(src, callback, outputFormat) { + var img = new Image(); + img.crossOrigin = 'Anonymous'; + img.onload = function() { + var canvas = document.createElement('CANVAS'); + var ctx = canvas.getContext('2d'); + var dataURL; + canvas.height = this.naturalHeight; + canvas.width = this.naturalWidth; + ctx.drawImage(this, 0, 0); + dataURL = canvas.toDataURL(outputFormat); + callback(dataURL); + }; + img.src = src; + if (img.complete || img.complete === undefined) { + img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; + img.src = src; + } +} + +function returnImage(img) { + console.log("I got img: "+img) + return img; +} + async function performExportToHV(targetActor) { try { let menuButtons = {}; @@ -632,9 +663,11 @@ async function performExportToHV(targetActor) { let vaultInfo = false; let canOverwrite = false; let portrait, hvUID, portraitAddress, tokenAddress; + //let portrait, token; hvUserToken = game.settings.get("herovaultfoundry", "userToken"); var hvUserTokenHashed=await getSHA(hvUserToken); + portrait = "icons/svg/mystery-man.svg"; if ( targetActor.img != undefined && @@ -656,11 +689,12 @@ async function performExportToHV(targetActor) { hvColor1, hvColor4 ); - if ( - targetActor.img.includes("http") == false && - targetActor.img.includes("cdn.herovau.lt") == false - ) { - portraitAddress = game.data.addresses.remote + targetActor.img.trim(); + // if ( + // targetActor.img.includes("http") == false && + // targetActor.img.includes("cdn.herovau.lt") == false + // ) { + // portraitAddress = game.data.addresses.remote + targetActor.img.trim(); + portraitAddress = targetActor.img.trim(); // await targetActor.update({'data.img': portraitAddress}); // targetActor.img=portraitAddress; if (hvDebug.enabled) { @@ -681,18 +715,19 @@ async function performExportToHV(targetActor) { hvColor4 ); } - } - if ( - targetActor.prototypeToken.texture.src.includes("http") == false && - targetActor.prototypeToken.texture.src.includes("cdn.herovau.lt") == - false - ) { - tokenAddress = - game.data.addresses.remote + - targetActor.prototypeToken.texture.src.trim(); - await targetActor.update({ - "prototypeToken.texture.src": tokenAddress, - }); + //} + // if ( + // targetActor.prototypeToken.texture.src.includes("http") == false && + // targetActor.prototypeToken.texture.src.includes("cdn.herovau.lt") == + // false + // ) { + // tokenAddress = + // game.data.addresses.remote + + // targetActor.prototypeToken.texture.src.trim(); + tokenAddress =targetActor.prototypeToken.texture.src.trim(); + // await targetActor.update({ + // "prototypeToken.texture.src": tokenAddress, + // }); // targetActor.prototypeToken.texture.src=tokenAddress; if (hvDebug.enabled) { console.log( @@ -707,7 +742,27 @@ async function performExportToHV(targetActor) { hvColor4 ); } - } + // } else if (targetActor.prototypeToken.texture.src.includes("http")) + // { + // tokenAddress = targetActor.prototypeToken.texture.src.trim(); + // await targetActor.update({ + // "prototypeToken.texture.src": tokenAddress, + // }); + // // targetActor.prototypeToken.texture.src=tokenAddress; + // if (hvDebug.enabled) { + // console.log( + // "%cHeroVau.lt/Foundry Bridge | %ctoken: " + tokenAddress, + // hvColor1, + // hvColor4 + // ); + // console.log( + // "%cHeroVau.lt/Foundry Bridge | %csheet token: " + + // targetActor.prototypeToken.texture.src, + // hvColor1, + // hvColor4 + // ); + // } + // } } if (targetActor?.flags?.herovault?.uid ) { @@ -903,7 +958,10 @@ const checkForAccess = async (hvUserToken, hvUID) => { "&userToken=" + hvUserToken + "&charUID=" + - hvUID + hvUID + + "&hvVer=" + + encodeURIComponent(hvVer) + ); }); }; @@ -948,7 +1006,9 @@ const getVaultSlots = async (hvUserToken) => { xmlhttp.send( "action=getVaultSlots" + "&userToken=" + - hvUserToken + hvUserToken + + "&hvVer=" + + encodeURIComponent(hvVer) ); }); }; @@ -984,6 +1044,75 @@ const exportPCtoHV = ( hvColor1, hvColor4 ); + charUID = responseJSON.charhash; + toDataURL(targetActor.img, function(dataUrl) { + var xmlhttpPortrait = new XMLHttpRequest(); + xmlhttpPortrait.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + let responseJSON = JSON.parse(this.responseText); + console.log(responseJSON); + if (hvDebug.enabled) + console.log( + "%cHeroVau.lt/Foundry Bridge | %cPortrait Upload:" + JSON.stringify(responseJSON), + hvColor1, + hvColor4 + ); + ui.notifications.info("Successfully exported portrait image HeroVau.lt."); + resolve(responseJSON); + } + }; + xmlhttpPortrait.open("POST", heroVaultURL + "/foundrymodule.php", true); + xmlhttpPortrait.setRequestHeader( + "Content-type", + "application/x-www-form-urlencoded" + ); + xmlhttpPortrait.send( + "action=portraitSend" + + "&userToken=" + + userToken + + "&charUID=" + + charUID + + "&portraitBase64=" + + encodeURIComponent(dataUrl) + + "&hvVer=" + + encodeURIComponent(hvVer) + ); + },'image/png'); + + toDataURL(targetActor.prototypeToken.texture.src, function(dataUrl) { + var xmlhttpToken = new XMLHttpRequest(); + xmlhttpToken.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + let responseJSON = JSON.parse(this.responseText); + console.log(responseJSON); + if (hvDebug.enabled) + console.log( + "%cHeroVau.lt/Foundry Bridge | %cToken Upload:" + JSON.stringify(responseJSON), + hvColor1, + hvColor4 + ); + ui.notifications.info("Successfully exported token image HeroVau.lt."); + resolve(responseJSON); + } + }; + xmlhttpToken.open("POST", heroVaultURL + "/foundrymodule.php", true); + xmlhttpToken.setRequestHeader( + "Content-type", + "application/x-www-form-urlencoded" + ); + xmlhttpToken.send( + "action=tokenSend" + + "&userToken=" + + userToken + + "&charUID=" + + charUID + + "&tokenBase64=" + + encodeURIComponent(dataUrl) + + "&hvVer=" + + encodeURIComponent(hvVer) + ); + }); + resolve(responseJSON); } }; @@ -1004,14 +1133,12 @@ const exportPCtoHV = ( gameSystem + "&charUID=" + charUID + - "&portraitAddress=" + - encodeURIComponent(portraitAddress) + - "&tokenAddress=" + - encodeURIComponent(tokenAddress) + "&foundryVersion=" + encodeURIComponent(foundryVersion) + "&gameSystemVersion=" + - encodeURIComponent(gameSystemVersion) + encodeURIComponent(gameSystemVersion) + + "&hvVer=" + + encodeURIComponent(hvVer) ); }); }; @@ -1177,7 +1304,9 @@ function loadPersonalVault(targetActor) { "&hvVer=" + hvVer + "&userToken=" + - hvUserToken + hvUserToken + + "&hvVer=" + + encodeURIComponent(hvVer) ); } @@ -1348,7 +1477,10 @@ function requestCharacter(targetActor, charUID) { xmlhttp.send( "action=getCharacter" + "&charUID=" + - encodeURIComponent(charUID) + encodeURIComponent(charUID) + + "&hvVer=" + + encodeURIComponent(hvVer) + ); } @@ -1911,7 +2043,9 @@ function getHash(encodedHeroJSON) { }; xmlhttp.open("POST", heroVaultURL + "/foundrymodule.php", true); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - xmlhttp.send("action=genHash&encodedChar=" + encodedHeroJSON); + xmlhttp.send("action=genHash&encodedChar=" + encodedHeroJSON + + "&hvVer=" + + encodeURIComponent(hvVer)); } export function exportToHVFromPBHLO(heroJSON, tAct) { @@ -1955,7 +2089,9 @@ export function exportToHVFromPBHLO(heroJSON, tAct) { "&gamesystem=" + gameSystem + "&charUID=" + - newHash + newHash + + "&hvVer=" + + encodeURIComponent(hvVer) ); } diff --git a/module.json b/module.json index 79de0b8..efbc908 100644 --- a/module.json +++ b/module.json @@ -12,7 +12,7 @@ "ko-fi": "SLATE" } ], - "version": "0.10.3", + "version": "0.10.4", "compatibility": { "minimum": "10.286", "verified": "10.286" @@ -37,7 +37,7 @@ "packs": [], "url": "https://github.com/zarmstrong/herovau.lt-foundry", "manifest": "https://raw.githubusercontent.com/zarmstrong/herovau.lt-foundry/main/module.json", - "download": "https://github.com/zarmstrong/herovau.lt-foundry/releases/download/herovau.lt-foundry-0.10.3/herovau.lt-foundry-0.10.3.zip", + "download": "https://github.com/zarmstrong/herovau.lt-foundry/releases/download/herovau.lt-foundry-0.10.4/herovau.lt-foundry-0.10.4.zip", "license": "MIT", "readme": "https://github.com/zarmstrong/herovau.lt-foundry", "bugs": "https://github.com/zarmstrong/herovau.lt-foundry/issues",