4 hours ago

this is neat

i made this extention btw

its bassically cloud varibles and lists


class LocalStoragePlusCloudFinal {

constructor() {

this.USER_KEY = 'pm_local_user';

this.LOG_KEY = 'pm_local_log';

this.ALLOWED_USER = 'ralsei';

}

getInfo() {

return {

id: 'LocalStoragePlusCloudFinal', // ✅ valid ID

name: 'Local Storage+ PseudoCloud Final',

color1: '#5ba58c',

color2: '#4b8d78',

blocks: [

// User

{ opcode: 'setUser', blockType: Scratch.BlockType.COMMAND, text: 'set username to [USER]', arguments: { USER: { type: Scratch.ArgumentType.STRING, defaultValue: 'guest' } } },

// Variables

{ opcode: 'setValue', blockType: Scratch.BlockType.COMMAND, text: 'set variable [KEY] to [VALUE]', arguments: { KEY: { type: Scratch.ArgumentType.STRING, defaultValue: 'score' }, VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: '0' } } },

{ opcode: 'getValue', blockType: Scratch.BlockType.REPORTER, text: 'get variable [KEY]', arguments: { KEY: { type: Scratch.ArgumentType.STRING, defaultValue: 'score' } } },

// Lists

{ opcode: 'createList', blockType: Scratch.BlockType.COMMAND, text: 'create list [LIST]', arguments: { LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' } } },

{ opcode: 'addToList', blockType: Scratch.BlockType.COMMAND, text: 'add [ITEM] to list [LIST]', arguments: { ITEM: { type: Scratch.ArgumentType.STRING, defaultValue: 'thing' }, LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' } } },

{ opcode: 'getFromList', blockType: Scratch.BlockType.REPORTER, text: 'item [INDEX] of list [LIST]', arguments: { INDEX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1 }, LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' } } },

{ opcode: 'listLength', blockType: Scratch.BlockType.REPORTER, text: 'length of list [LIST]', arguments: { LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' } } },

{ opcode: 'clearList', blockType: Scratch.BlockType.COMMAND, text: 'clear list [LIST]', arguments: { LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' } } },

{ opcode: 'listAsArray', blockType: Scratch.BlockType.REPORTER, text: 'list [LIST] as array', arguments: { LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' } } },

{ opcode: 'listContains', blockType: Scratch.BlockType.BOOLEAN, text: 'does list [LIST] contain [ITEM]', arguments: { LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' }, ITEM: { type: Scratch.ArgumentType.STRING, defaultValue: 'thing' } } },

// Logs

{ opcode: 'logEvent', blockType: Scratch.BlockType.COMMAND, text: 'log [TEXT]', arguments: { TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: 'did something' } } },

{ opcode: 'readLog', blockType: Scratch.BlockType.REPORTER, text: 'read log (ralsei only)' },

// Pseudo-Cloud Export/Import

{ opcode: 'exportList', blockType: Scratch.BlockType.REPORTER, text: 'export list [LIST] as string', arguments: { LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' } } },

{ opcode: 'importList', blockType: Scratch.BlockType.COMMAND, text: 'import list [LIST] from string [STRING]', arguments: { LIST: { type: Scratch.ArgumentType.STRING, defaultValue: 'my list' }, STRING: { type: Scratch.ArgumentType.STRING, defaultValue: '[]' } } },

{ opcode: 'exportLog', blockType: Scratch.BlockType.REPORTER, text: 'export log as string' },

{ opcode: 'importLog', blockType: Scratch.BlockType.COMMAND, text: 'import log from string [STRING]', arguments: { STRING: { type: Scratch.ArgumentType.STRING, defaultValue: '[]' } } },

// Clipboard copy for pseudo-cloud

{ opcode: 'copyToClipboard', blockType: Scratch.BlockType.COMMAND, text: 'copy [TEXT] to clipboard', arguments: { TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: '' } } },

]

};

}

_key(k) { return 'pm_local_' + k; }

_listKey(name) { return 'pm_list_' + name; }

_getUser() { return localStorage.getItem(this.USER_KEY) || ''; }

_isAllowed() { return this._getUser() === this.ALLOWED_USER; }

// ------------------ User ------------------

setUser(args) { localStorage.setItem(this.USER_KEY, args.USER); }

// ------------------ Variables ------------------

setValue(args) { localStorage.setItem(this._key(args.KEY), args.VALUE); }

getValue(args) { return localStorage.getItem(this._key(args.KEY)) || ''; }

// ------------------ Lists ------------------

createList(args) { localStorage.setItem(this._listKey(args.LIST), '[]'); }

_getList(name) { return JSON.parse(localStorage.getItem(this._listKey(name)) || '[]'); }

_setList(name, arr) { localStorage.setItem(this._listKey(name), JSON.stringify(arr)); }

addToList(args) { const list = this._getList(args.LIST); list.push(args.ITEM); this._setList(args.LIST, list); }

getFromList(args) { const list = this._getList(args.LIST); return list[args.INDEX-1] || ''; }

listLength(args) { return this._getList(args.LIST).length; }

clearList(args) { this._setList(args.LIST, []); }

listAsArray(args) { return JSON.stringify(this._getList(args.LIST)); }

listContains(args) { return this._getList(args.LIST).includes(args.ITEM); }

// ------------------ Logs ------------------

logEvent(args) {

const log = JSON.parse(localStorage.getItem(this.LOG_KEY) || '[]');

log.push({ time: new Date().toLocaleString(), user: this._getUser(), text: args.TEXT });

localStorage.setItem(this.LOG_KEY, JSON.stringify(log));

}

readLog() {

if (!this._isAllowed()) return '[access denied]';

const log = JSON.parse(localStorage.getItem(this.LOG_KEY) || '[]');

return log.map(e => `[${e.time}] ${e.user}: ${e.text}`).join('\n');

}

// ------------------ Pseudo-Cloud ------------------

exportList(args) { return JSON.stringify(this._getList(args.LIST)); }

importList(args) { this._setList(args.LIST, JSON.parse(args.STRING)); }

exportLog() { return localStorage.getItem(this.LOG_KEY) || '[]'; }

importLog(args) { localStorage.setItem(this.LOG_KEY, args.STRING); }

// ------------------ Clipboard ------------------

copyToClipboard(args) {

try {

navigator.clipboard.writeText(args.TEXT);

} catch(e) {

console.error("Clipboard copy failed:", e);

}

}

}

// ------------------ Safe registration ------------------

if (typeof Scratch !== "undefined" && Scratch.extensions && Scratch.extensions.register) {

Scratch.extensions.register(new LocalStoragePlusCloudFinal());

} else {

console.error("Scratch extensions API not found. Load inside PenguinMod/Scratch.");

}



28 comments

Loading...

Next up

extention bellow

lez see

fucking hell

WHY DIDNT I KNOW THIS EXISTED UNTILL NOW

I WAS SOO DAMN CLOSE

i found a exe version

since i have a windows loader on my linux thing

it will finnally be able to work

HOW DO I APEAR THIS HIGH IN THE SEARCH FOR "RALSEI"

thats crazy

curius if it still passes

oh this one understood negative language

also jeez thats realistic

id 255 hehehe