11 hours ago

update on the previus extention

a few things have been upgraded


class LocalStoragePseudoCloud {

constructor() {

this.peer = null;

this.conn = null;

this.isHost = false;

this.VAR_PREFIX = 'pm_var_';

this.LIST_PREFIX = 'pm_list_';

this.LOG_KEY = 'pm_local_log';

this.BANNED_USERS_KEY = 'pm_banned_users';

this.ALLOWED_USER = 'ralsei-';

this.messageCooldown = 2000; // 2 seconds per message per user

this.lastMessageTime = {};

// Auto-load PeerJS

if (typeof Peer === 'undefined') {

const s = document.createElement('script');

s.src = 'https://unpkg.com/[email protected]/dist/peerjs.min.js';

s.onload = () => console.log('PeerJS loaded.');

document.head.appendChild(s);

}

}

getInfo() {

return {

id: 'LocalStoragePseudoCloud',

name: 'Local Storage Cloud (WebRTC) Advanced',

color1: '#5ba58c',

color2: '#4b8d78',

blocks: [

// VARIABLES

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

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

// LISTS

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

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

{ opcode: 'setItem', blockType: Scratch.BlockType.COMMAND, text: 'set item [INDEX] of list [LIST] to [ITEM]', arguments: { INDEX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1 }, LIST: { type: Scratch.ArgumentType.STRING }, ITEM: { type: Scratch.ArgumentType.STRING } } },

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

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

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

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

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

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

// CHAT-FRIENDLY BLOCKS

{ opcode: 'sendMessage', blockType: Scratch.BlockType.COMMAND, text: 'send message [TEXT] as [USERNAME]', arguments: { TEXT: { type: Scratch.ArgumentType.STRING }, USERNAME: { type: Scratch.ArgumentType.STRING } } },

{ opcode: 'lastMessage', blockType: Scratch.BlockType.REPORTER, text: 'last message' },

{ opcode: 'allMessages', blockType: Scratch.BlockType.REPORTER, text: 'all messages' },

{ opcode: 'clearChat', blockType: Scratch.BlockType.COMMAND, text: 'clear chat' },

{ opcode: 'messageCount', blockType: Scratch.BlockType.REPORTER, text: 'messages count' },

// BAN USERS

{ opcode: 'banUser', blockType: Scratch.BlockType.COMMAND, text: 'ban user [USERNAME]', arguments: { USERNAME: { type: Scratch.ArgumentType.STRING } } },

// LOGGING

{ opcode: 'clearLogs', blockType: Scratch.BlockType.COMMAND, text: 'clear logs' },

{ opcode: 'logsAsArray', blockType: Scratch.BlockType.REPORTER, text: 'logs as array' },

// CLOUD

{ opcode: 'startHost', blockType: Scratch.BlockType.COMMAND, text: 'start cloud host' },

{ opcode: 'connectCloud', blockType: Scratch.BlockType.COMMAND, text: 'connect to cloud with code [CODE]', arguments: { CODE: { type: Scratch.ArgumentType.STRING } } },

{ opcode: 'cloudStatus', blockType: Scratch.BlockType.REPORTER, text: 'cloud status' }

]

};

}

// ---------- helpers ----------

_log(action, user = '') {

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

log.push({ time: new Date().toISOString(), user, action });

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

}

_send(type, payload) {

if (this.conn && this.conn.open) this.conn.send({ type, payload });

}

_syncAll() {

const vars = {};

const lists = {};

for (let k in localStorage) {

if (k.startsWith(this.VAR_PREFIX)) vars[k] = localStorage.getItem(k);

if (k.startsWith(this.LIST_PREFIX)) lists[k] = localStorage.getItem(k);

}

this._send('sync', { vars, lists });

}

// ---------- VARIABLES ----------

setVar(a) {

localStorage.setItem(this.VAR_PREFIX + a.KEY, a.VALUE);

this._log(`set variable ${a.KEY}=${a.VALUE}`);

this._send('var', a);

}

getVar(a) {

return localStorage.getItem(this.VAR_PREFIX + a.KEY) || '';

}

// ---------- LISTS ----------

createList(a) {

localStorage.setItem(this.LIST_PREFIX + a.LIST, '[]');

this._log(`created list ${a.LIST}`);

this._send('list', { name: a.LIST, value: [] });

}

_getList(name) {

return JSON.parse(localStorage.getItem(this.LIST_PREFIX + name) || '[]');

}

_setList(name, arr) {

localStorage.setItem(this.LIST_PREFIX + name, JSON.stringify(arr));

this._log(`set list ${name}=${JSON.stringify(arr)}`);

this._send('list', { name, value: arr });

}

addToList(a) {

const l = this._getList(a.LIST);

l.push(a.ITEM);

this._setList(a.LIST, l);

}

setItem(a) {

const l = this._getList(a.LIST);

if (a.INDEX > 0 && a.INDEX <= l.length) {

l[a.INDEX - 1] = a.ITEM;

this._setList(a.LIST, l);

}

}

deleteItem(a) {

const l = this._getList(a.LIST);

if (a.INDEX > 0 && a.INDEX <= l.length) {

l.splice(a.INDEX - 1, 1);

this._setList(a.LIST, l);

}

}

getItem(a) { return this._getList(a.LIST)[a.INDEX-1] || ''; }

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

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

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

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

// ---------- CHAT ----------

_chatListName() { return 'chat'; }

sendMessage(a) {

const user = a.USERNAME || 'guest';

const now = Date.now();

if (this.lastMessageTime[user] && now - this.lastMessageTime[user] < this.messageCooldown) return;

this.lastMessageTime[user] = now;

const banned = JSON.parse(localStorage.getItem(this.BANNED_USERS_KEY) || '[]');

if (banned.includes(user)) return;

const chat = this._getList(this._chatListName());

chat.push(`${user}: ${a.TEXT}`);

this._setList(this._chatListName(), chat);

this._log(`send message as ${user}: ${a.TEXT}`, user);

}

lastMessage() {

const chat = this._getList(this._chatListName());

return chat[chat.length-1] || '';

}

allMessages() { return this._getList(this._chatListName()); }

clearChat() { this._setList(this._chatListName(), []); this._log('cleared chat'); }

messageCount() { return this._getList(this._chatListName()).length; }

// ---------- BAN ----------

banUser(a) {

if (this.getVar({KEY:'username'}) !== this.ALLOWED_USER) return;

const banned = JSON.parse(localStorage.getItem(this.BANNED_USERS_KEY) || '[]');

if (!banned.includes(a.USERNAME)) banned.push(a.USERNAME);

localStorage.setItem(this.BANNED_USERS_KEY, JSON.stringify(banned));

this._log(`banned user ${a.USERNAME}`, this.ALLOWED_USER);

}

// ---------- LOGS ----------

clearLogs() { localStorage.setItem(this.LOG_KEY, '[]'); }

logsAsArray() { return JSON.stringify(JSON.parse(localStorage.getItem(this.LOG_KEY)||'[]')); }

// ---------- CLOUD ----------

startHost() {

if (typeof Peer === 'undefined') { alert('PeerJS not loaded yet. Wait a second.'); return; }

this.isHost = true;

this.peer = new Peer();

this.peer.on('open', id => { alert('Cloud code: '+id); console.log('Hosting cloud with code:', id); });

this.peer.on('connection', conn => { this.conn = conn; conn.on('open', () => this._syncAll()); conn.on('data', d => this._handleData(d)); });

}

connectCloud(a) {

if (typeof Peer === 'undefined') { alert('PeerJS not loaded yet. Wait a second.'); return; }

this.peer = new Peer();

this.peer.on('open', () => { this.conn = this.peer.connect(a.CODE); this.conn.on('data', d => this._handleData(d)); });

}

_handleData(d) {

if(d.type==='sync'){ Object.entries(d.payload.vars).forEach(([k,v])=>localStorage.setItem(k,v)); Object.entries(d.payload.lists).forEach(([k,v])=>localStorage.setItem(k,v)); }

if(d.type==='var') localStorage.setItem(this.VAR_PREFIX+d.payload.KEY,d.payload.VALUE);

if(d.type==='list') localStorage.setItem(this.LIST_PREFIX+d.payload.name,JSON.stringify(d.payload.value));

}

cloudStatus() { if(!this.peer)return'offline'; if(this.isHost)return'hosting'; if(this.conn&&this.conn.open)return'connected'; return'connecting'; }

}

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



0 comments

Loading...

Next up

where does road to hell go? thanks

ah yes

the cyber dogs

from the year 2999

pov someone from china trieng to be in my servers:

{source https://youtu.be/dSIBD40inpU?si=zZFUjeb5RwyKVkwU&t=529}

pov:

ultra broke

LOLOLOLOLOLOL

how was ur time at the sans fight?

beRDLY IS A POKEMON NOW LOL

id 255 hehehe