Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth changes and readme.md #13

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## BlockLive: Real-Time Collaboration for Scratch

<img src="/img/logowithtext.svg" alt="BlockLive logo" height="100px">

**BlockLive** is a Chrome extension that lets you work together with friends on Scratch projects in real-time! No more tedious remixing and sharing - BlockLive keeps everyone on the same page with instant synchronization.

**Features:**

* **Real-time Collaboration:** See changes made by your collaborators instantly, from block edits to asset uploads and project name changes.
* **Easy Setup:** Install the extension, open a Scratch project, and invite your friends using the BlockLive interface.
* **Collaborative Editing:** Everyone can work on the project simultaneously, fostering creative teamwork.
* **Websocket Powered:** BlockLive uses websockets for efficient and low-latency communication.

**Installation:**

1. Visit [the Chrome Webstore](https://chromewebstore.google.com/detail/blocklive-scratch-realtim/gelkmljpoacdjkjkcfekkmgkpnmeomlk).
2. Click "Add to Chrome" and follow the on-screen instructions.

**Getting Started:**

1. **Create a new project or open an existing project**:
- Start a new project or open a project you want to collaborate on.

2. **Enable BlockLive**:
- Click on the BlockLive Share button in the Scratch interface to enable real-time collaboration.

3. **Invite collaborators**:
- Invite your friends to the project using the menu in the popup.

4. **Collaborate in real-time**:
- Work together with your collaborators, see their changes live, and communicate using the built-in chat feature.

**Important Notes:**

* **Allowlist:** For security reasons, you need to add collaborators to your allowlist before they can join your project.
* **Development:** BlockLive is still under development. You may encounter bugs or limitations.

**Contributing:**

We welcome contributions from the community! If you'd like to help improve BlockLive, you can find the source code on [GitHub](https://github.com/BlockliveScratch/blocklive).

**Support the Project:**

If you find BlockLive useful, consider supporting the development by donating us on [buymeacoffee](https://buymeacoffee.com/ilhp10).

**We hope you enjoy collaborating on Scratch with BlockLive!**
39 changes: 38 additions & 1 deletion backend/scratch-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ export const freePassesPath = 'storage/freePasses.json'
export const failedAuthLog = {}
export const secondTimeSuccessAuthLog = {};


let cachedComments = [];
let lastTimeCheckedComments = 0;
const commentsRateLimit = 1000 * 5;

function logAuth(username, success, word, info) {
if (!username) { return; }
Expand Down Expand Up @@ -43,6 +45,12 @@ function getAuthProjectId() {
return authProjects[idIndex];
}

async function getAuthProjectData() {
const projectId = getAuthProjectId();
const data = await (await fetch(`https://api.scratch.mit.edu/projects/${projectId}`)).json();
return { projectId, projectUsername: data.author.username };
}

let userManager
let sessionManager
export function setPaths(app, userManagerr, sessionManagerr) {
Expand All @@ -62,6 +70,9 @@ export function setPaths(app, userManagerr, sessionManagerr) {

const CLOUD_WAIT = 1000 * 5;
app.get('/verify/userToken', async (req, res) => { // ?code=000000&method=cloud|CLOUDs
if (bypassUserAuth) {
return res.send({ freepass: true })
}
try {
let clientCode = req.query.code
if (!clientCode) { res.send({ err: 'no client code included' }); return }
Expand All @@ -71,6 +82,8 @@ export function setPaths(app, userManagerr, sessionManagerr) {
res.send({ err: 'client code not found', clientCode });
return;
}

await sleep(500) // Makes sure cloud is ready to be called and we don't need to spend extra time on retrying

let cloud = await getVerificationCloud(tempCode)
if (!cloud || cloud?.err) {
Expand Down Expand Up @@ -158,6 +171,30 @@ async function getVerificationCloud(tempCode) {
return cloud;
}

async function checkComments() {
if (lastTimeCheckedComments + commentsRateLimit > Date.now()) {
return cachedComments;
}

let { projectUsername, projectId } = await getAuthProjectData();

const data = await (await fetch(`https://api.scratch.mit.edu/users/${projectUsername}/projects/${projectId}/comments?offset=0&limit=40&rand=${Math.random()}`)).json();
cachedComments = data;
lastTimeCheckedComments = Date.now();
return data;
}

async function verifyCommentCode(code, retried=false) {
if (retried) { await sleep(commentsRateLimit); }
const data = await checkComments();
const comment = data?.comments?.filter(c => c.content == code).reverse()[0];
if (!comment) {
if (!retried) { return await verifyCommentCode(code, true) }
return null;
}
return comment;
}


// export let freePasses = {} // username : passtime

Expand Down
6 changes: 4 additions & 2 deletions extension/scripts/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ async function startBlocklive(creatingNew) {
})
}
if(creatingNew) {
addToCredits('Get BIocklive for Live Collabs #bl')
addToCredits('Get Blocklive for Live Collabs #bl')
}
}

Expand Down Expand Up @@ -214,6 +214,8 @@ async function joinExistingBlocklive(id) {
liveMessage({meta:"joinSession"}) // join sessionManager session
readyToRecieveChanges = true
pauseEventHandling = false;

reloadOnlineUsers();
// hackyRefreshFlyoutVariables()

setTimeout(BL_UTILS.refreshFlyout,100) // todo figure way other than timeout
Expand Down Expand Up @@ -2780,7 +2782,7 @@ let blActivateClick = async ()=>{
await refreshShareModal()

// add blocklive ref in instructions credits
addToCredits('Get BIocklive for Live Collabs #bl')
addToCredits('Get Blocklive for Live Collabs #bl')

// stop spinny
document.querySelector('loader.blockliveloader').style.display = 'none'
Expand Down
13 changes: 10 additions & 3 deletions extension/scripts/mystuff.js
Original file line number Diff line number Diff line change
Expand Up @@ -400,21 +400,28 @@ chrome.runtime.sendMessage(exId, { meta: 'getUsernamePlus' }, async (userData) =
})



let shouldShowBanner = true;
async function updateShouldHideBanner() {
const res = await fetch('https://spore.us.to/api/verify/bypass');
const bypass = (await res.text()) === 'true';
shouldShowBanner = !bypass;
}
updateShouldHideBanner();

chrome.runtime.sendMessage(exId, { meta: 'verifying' }, (verifying) => {
console.log('vf',verifying)
console.log('verifying',verifying)
if (verifying=='nocon'){
if (verifying=='nocon' && shouldShowBanner) {
// defaultAddHideBlockliveButton()
document.querySelector('.box-head').insertAdjacentHTML('afterend', `<div class="blBanner" id="unverified" style="background:red; color:white;">⚠️ Cant connect to blocklive servers at blocklivecollab.com <a href="https://status.uptime-monitor.io/6499c89d4bfb79bb5f20ac4d" target="_blank">Check Uptime</a> or <a onclick="(()=>{chrome.runtime.sendMessage(exId,{meta:'dontShowVerifyError',val:false}); addHideBlockliveButton(false);})()">Dont show this message again</a><div>`)
}
else if (verifying) {
else if (verifying && shouldShowBanner) {
defaultAddHideBlockliveButton()
document.querySelector('#verifying')?.remove()
document.querySelector('.box-head').insertAdjacentHTML('afterend', `<div class="blBanner" id="verifying" style="background:#ea47ff; color:white;"><img height=15 src="https://upload.wikimedia.org/wikipedia/commons/a/ad/YouTube_loading_symbol_3_%28transparent%29.gif"/> Blocklive is verifying your account ...<div>`)
} else {
if (newVerified) { return }
if (!shouldShowBanner) { return }
defaultAddHideBlockliveButton()
document.querySelector('.box-head').insertAdjacentHTML('afterend', `<div class="blBanner" id="unverified" style="background:red; color:white;">⚠️ Blocklive could not verify your account. Reload the tab in a few seconds. If this issue continues, contact @ilhp10 or @rgantzos<div>`)
}
Expand Down
1 change: 1 addition & 0 deletions img/logowithtext.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.