Skip to content

Commit

Permalink
Merge pull request #14 from reumarks/User-save-data
Browse files Browse the repository at this point in the history
User save data
  • Loading branch information
expitau authored May 1, 2024
2 parents fbf7837 + bb8217c commit d8916b2
Show file tree
Hide file tree
Showing 8 changed files with 950 additions and 378 deletions.
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,8 @@ Visit the [live site](https://expitau.github.io/InfiniteCraftWiki/) to see it in

## Importing Save Files

This site has support for importing your crafted elements from Infinite Craft. To do this, go to https://neal.fun/infinite-craft/, right click -> Inspect element -> Console, and paste the following code:

```javascript
fetch("https://raw.githubusercontent.com/expitau/InfiniteCraftWiki/main/web/data/index.json").then(res => res.json()).then(data => { index = Object.fromEntries(Object.entries(data).map(x => [x[1][1], x[0]])); window.location.href = `https://expitau.github.io/InfiniteCraftWiki?s=${JSON.parse(localStorage.getItem('infinite-craft-data')).elements.map(a => index[a.text]).filter(x => x).join(",")}` })
```

This will automatically redirect after a few seconds and load your data.
This site has support for importing your crafted elements from Infinite Craft. This diagram provides an overview of the messaging protocol used to sync files.
![sync diagram](docs/syncDiagram.png)

## Developers

Expand Down
Binary file added docs/syncDiagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
91 changes: 91 additions & 0 deletions web/bookmarklet-iframe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html lang="en">

<!-- This document is on neal.fun, providing updates via postmessage back to the host -->

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bookmarklet iframe</title>
</head>

<body>
<script>
let isActive = true;
let wikiTab = window.open(window.location.host == 'expitau.github.io' ? 'https://expitau.github.io/InfiniteCraftWiki' : `http://${window.location.host}/web/index.html`);

let lastSaveData = [];
let saveData = [];

function sendDataToWiki(type, data = {}) {
wikiTab.postMessage(JSON.stringify({ type, data }), `http://${window.location.host}`);
}

function processDataFromWiki(data) {
if (!isActive) return;

if (data.type == 'heartbeat') {
sendDataToWiki('heartbeatAck')
lastHeartbeat = Date.now();
} else if (data.type == 'disconnect') {
sendDataToParent('disconnected')
isActive = false;
}
}

function sendDataToParent(type, data = {}) {
window.parent.postMessage(JSON.stringify({ type, data }), 'https://neal.fun')
}

function processDataFromParent(data) {
if (data.type != 'data') {
return
}

fetch(`https://raw.githubusercontent.com/expitau/InfiniteCraftWiki/main/web/data/index.json`)
.then(res => res.json())
.then(indexData => {
let index = Object.fromEntries(Object.entries(indexData).map(x => [x[1][1], x[0]]));
saveData = JSON.parse(data.data).elements.map(a => index[a.text]).filter(x => x);

if (saveData.join(",") !== lastSaveData.join(",")) {
console.log("Sending update", saveData, lastSaveData)
sendDataToWiki('update', saveData);
lastSaveData = saveData;
} else {
console.log('Save data matches!');
}

});
}

// Heartbeat with wiki
let lastHeartbeat = Date.now();
setInterval(() => {
if (!isActive) return;

if (Date.now() - lastHeartbeat > 5000) {
sendDataToParent('disconnected')
} else {
sendDataToParent('connected')
}
}, 500);

// Add event listener for reciving local storage from Infinite Craft
window.addEventListener('message', function (event) {
if (!isActive) return;

if (event.origin == `http://${window.location.host}`) {
processDataFromWiki(JSON.parse(event.data))
return
}

if (event.origin == 'https://neal.fun') {
processDataFromParent(JSON.parse(event.data))
return
}
}, false);
</script>
</body>

</html>
78 changes: 77 additions & 1 deletion web/bookmarklet.js
Original file line number Diff line number Diff line change
@@ -1 +1,77 @@
fetch("https://raw.githubusercontent.com/expitau/InfiniteCraftWiki/main/web/data/index.json").then(res => res.json()).then(data => { index = Object.fromEntries(Object.entries(data).map(x => [x[1][1], x[0]])); window.location.href = `https://expitau.github.io/InfiniteCraftWiki?s=${JSON.parse(localStorage.getItem('infinite-craft-data')).elements.map(a => index[a.text]).filter(x => x).join(",")}` })
window.BOOKMARKLET_DATA = function () {
/* Fetch metadata.json and alert if version different */
async function checkVersion() {
let VERSION = 1;
let response = await fetch(`https://raw.githubusercontent.com/expitau/InfiniteCraftWiki/main/web/data/metadata.json`);
let data = await response.json();
console.log(data);
if (data.bookmarkletVersion != VERSION) {
alert('Bookmarklet version is outdated! Update the bookmarklet by dragging it into your bookmarks bar again from the wiki page.');
}
}
/* Click here to redirect to infinite craft -> Click again to Save data to the Wiki */
function createIframeWithAccess() {
if (document.getElementById('IframeWithAccess') != null) {
document.getElementById('IframeWithAccess').remove();
}

let iframe = document.createElement('iframe');
iframe.id = 'IframeWithAccess';
iframe.style.display = 'none';
iframe.src = '$$IFRAME_PATH$$';
document.body.appendChild(iframe);

function sendDataToIFrame(type, data) {
let host = new URL(iframe.src).origin;
iframe.contentWindow.postMessage(JSON.stringify({ type: type, data: data }), host);
}

function processDataFromIFrame(data) {
if (data.type == 'connected') {
connectedMessage.style.color = "green";
document.getElementById('connectedMessage').innerHTML = "Syncing with wiki";
} else if (data.type == 'disconnected') {
connectedMessage.style.color = "red";
document.getElementById('connectedMessage').innerHTML = "Wiki connection lost - use bookmarklet to reconnect";
}
}
clearInterval(window.syncInterval);
window.syncInterval = setInterval(() => {
var localStorageData = localStorage.getItem('infinite-craft-data');
sendDataToIFrame('data', localStorageData);
}, 1000);

window.addEventListener('message', function (event) {
if (event.source == iframe.contentWindow) {
processDataFromIFrame(JSON.parse(event.data));
}
}, false);
}

function displayMessage(header, content) {
document.body.innerHTML = `<div style="position: fixed;width: 100vw;text-align: center;height: 100vh;background-color: #191919;color: #c6c7c7;padding-top: 50px;font-size: 18px; font-family: "Roboto", sans-serif;"><h1 style="margin-bottom: 5px;">${header}</h1><br><div style="font-weight: bold; color: gray;">${content}</div></div>`;
}

/* If not currently on infinite craft game, redirect */
if (!window.location.href.includes('neal.fun/infinite-craft')) {
setTimeout(() => {
window.location.href = 'https://neal.fun/infinite-craft/';
}, 1000);
displayMessage('Redirecting to Infinite Craft', 'Click this bookmarklet again once you are there to start syncing your data!<br>Click <a href="https://neal.fun/infinite-craft/">here</a> if you are not redirected');
return;
}

checkVersion().then(() => {
createIframeWithAccess();

/* Reset the connection message */
document.getElementById('connectedMessage')?.remove();
let mainContainer = document.getElementsByClassName('container')[0];
let connectedMessage = document.createElement('div');
connectedMessage.id = 'connectedMessage';
connectedMessage.style = 'margin-left: 150px; font-size: larger; margin-top: 15px;';
connectedMessage.style.color = "green";
connectedMessage.innerHTML = 'Syncing with Wiki';
mainContainer.appendChild(connectedMessage);
})
}.toString();
2 changes: 1 addition & 1 deletion web/data/metadata.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"recipeCount":3469889}
{"recipeCount":3469889,"bookmarkletVersion":1}
Loading

0 comments on commit d8916b2

Please sign in to comment.