From abfc7304a53228ba517b6f3042ad126d9646ec93 Mon Sep 17 00:00:00 2001 From: TheDreWen Date: Tue, 12 May 2026 08:18:54 +0200 Subject: [PATCH] Add Lagoon proximity chat plugin with player initialization and utilities --- .gitignore | 2 + manifest.json | 34 +++++++++++++++++ package-lock.json | 72 +++++++++++++++++++++++++++++++++++ package.json | 9 +++++ scripts/entities/player.js | 8 ++++ scripts/main.js | 63 +++++++++++++++++++++++++++++++ scripts/properties.js | 1 + scripts/utils.js | 28 ++++++++++++++ src/entities/player.ts | 10 +++++ src/main.ts | 77 ++++++++++++++++++++++++++++++++++++++ src/properties.ts | 1 + src/type.d.ts | 8 ++++ src/utils.ts | 33 ++++++++++++++++ tsconfig.json | 13 +++++++ 14 files changed, 359 insertions(+) create mode 100644 manifest.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 scripts/entities/player.js create mode 100644 scripts/main.js create mode 100644 scripts/properties.js create mode 100644 scripts/utils.js create mode 100644 src/entities/player.ts create mode 100644 src/main.ts create mode 100644 src/properties.ts create mode 100644 src/type.d.ts create mode 100644 src/utils.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index 2309cc8..cb4ad16 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ + + # ---> Node # Logs logs diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..271f542 --- /dev/null +++ b/manifest.json @@ -0,0 +1,34 @@ +{ + "format_version": 3, + "header": { + "description": "Lagoon plugin for proximity chat.", + "name": "lagoon", + "uuid": "1aa9a1f5-3270-4edc-9b3c-e3a90f8bfdd8", + "min_engine_version": "1.26.20", + "version": "1.0.0" + }, + "modules": [ + { + "type": "data", + "uuid": "4b2d8ccc-7f1d-4751-a043-a94382567134", + "version": "1.0.0" + }, + { + "type": "script", + "language": "javascript", + "uuid": "71bc1103-8e94-4b3b-9d9a-bf92648604d2", + "version": "1.0.0", + "entry": "scripts/main.js" + } + ], + "dependencies": [ + { + "module_name": "@minecraft/server", + "version": "2.8.0-beta" + }, + { + "module_name": "@minecraft/server-net", + "version": "1.0.0-beta" + } + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..61252e7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,72 @@ +{ + "name": "UnderScape", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@minecraft/server": "^2.8.0-beta.1.26.20-stable", + "@minecraft/server-net": "^1.0.0-beta.1.26.20-stable" + }, + "devDependencies": { + "typescript": "^6.0.3" + } + }, + "node_modules/@minecraft/common": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@minecraft/common/-/common-1.3.0.tgz", + "integrity": "sha512-GLT8USFhvEyeTTFHZAgszbrnoT007hmXmK+aO4l+2A1up9/zwZ+4e8R8F0KcKrCWDjLEqkOJtPow0hQCcNJ++Q==", + "license": "MIT", + "peer": true + }, + "node_modules/@minecraft/server": { + "version": "2.8.0-beta.1.26.20-stable", + "resolved": "https://registry.npmjs.org/@minecraft/server/-/server-2.8.0-beta.1.26.20-stable.tgz", + "integrity": "sha512-oxrzclVYyf3WDotWBQ5YauQ47CksnOhDdlm/jX1LPvWvNo6atMYCls6kWLE5CsQrMBwEfwb5pazFxXeUh/4ZMw==", + "license": "MIT", + "peerDependencies": { + "@minecraft/common": "^1.2.0", + "@minecraft/vanilla-data": ">=1.20.70" + } + }, + "node_modules/@minecraft/server-admin": { + "version": "1.0.0-beta.11940b24", + "resolved": "https://registry.npmjs.org/@minecraft/server-admin/-/server-admin-1.0.0-beta.11940b24.tgz", + "integrity": "sha512-UZ8YyB8mvF31f22+uM67gJums9d6NDgz9AQ2l4a++EHUP9uen0m3aaBaqM9RyumJpRBJbv/hslAKOyeDT01qew==", + "license": "MIT", + "peer": true + }, + "node_modules/@minecraft/server-net": { + "version": "1.0.0-beta.1.26.20-stable", + "resolved": "https://registry.npmjs.org/@minecraft/server-net/-/server-net-1.0.0-beta.1.26.20-stable.tgz", + "integrity": "sha512-A4Z5fatdvaR6rGCiMzuZ375Q0ZQa75wlHhFtjeZ5SPBDJwmq7pxVt1ayhLZCQcsyNLsM+l+M1Qta2UgFI3mmtw==", + "license": "MIT", + "peerDependencies": { + "@minecraft/common": "^1.0.0", + "@minecraft/server": "^1.17.0 || ^2.0.0", + "@minecraft/server-admin": "^1.0.0-beta.1.26.20-stable" + } + }, + "node_modules/@minecraft/vanilla-data": { + "version": "1.26.20", + "resolved": "https://registry.npmjs.org/@minecraft/vanilla-data/-/vanilla-data-1.26.20.tgz", + "integrity": "sha512-bscvQ8TTQBWy/4PQj/XUFJuYDfjcEi2I4TTkn8aZpbY13tpFM+plviuprx0DGC2rMPZRWO1pizM51dx76sbpKw==", + "license": "MIT", + "peer": true + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6cb4d60 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "@minecraft/server": "^2.8.0-beta.1.26.20-stable", + "@minecraft/server-net": "^1.0.0-beta.1.26.20-stable" + }, + "devDependencies": { + "typescript": "^6.0.3" + } +} diff --git a/scripts/entities/player.js b/scripts/entities/player.js new file mode 100644 index 0000000..b220581 --- /dev/null +++ b/scripts/entities/player.js @@ -0,0 +1,8 @@ +import utils from "utils"; +export function InitPlayer(p) { + if (!p.initialized) { + p.initialized = true; + p.lagoonCode = utils.generateCode(); + p.sendMessage(utils.prefix + '§aVotre lagoon code : ' + p.lagoonCode + '\n§r§oMerci de ne pas divulguer ce code, il vous est propre !'); + } +} diff --git a/scripts/main.js b/scripts/main.js new file mode 100644 index 0000000..e3a58ae --- /dev/null +++ b/scripts/main.js @@ -0,0 +1,63 @@ +import { system, world } from "@minecraft/server"; +import utils from "utils"; +import { websocket } from "@minecraft/server-net"; +import { InitPlayer } from "entities/player"; +import { roomCode } from "properties"; +class LagoonAddons { + constructor() { + this.timer = 0; + world.afterEvents.worldLoad.subscribe(() => system.run(() => this.initEarlyExecution())); + } + async initEarlyExecution() { + this.ws = await websocket.connect('wss://lagoon.under-scape.com/ws/rooms/' + roomCode + '/plugins/proximity'); + this.ws.afterEvents.message.subscribe((event) => { + try { + const payload = JSON.parse(event.message); + const type = payload.type; + const data = payload.data; + if (type == 'status' && data == 'connected !') { + utils.logStaff('§aLagoon connected !'); + console.log('Lagoon connected !'); + } + } + catch (error) { + utils.logStaff('ERROR With Payload : ' + event.message); + console.log('ERROR With Payload : ' + event.message); + } + }); + this.ws.afterEvents.close.subscribe((event) => { + utils.logStaff(`§cConnexion à lagoon fermé ! (${event})`); + console.log(`Connexion à lagoon fermé ! (${event})`); + }); + world.getAllPlayers().forEach((p) => InitPlayer(p)); + world.afterEvents.playerSpawn.subscribe((e) => { + system.runTimeout(() => { + InitPlayer(e.player); + }, 20 * 3); + }); + system.runInterval(() => this.clock(), 1); + utils.logStaff('§aLagoon loaded !'); + console.log('Lagoon loaded !'); + } + async clock() { + this.timer++; + // 1 seconde + if (this.timer % 20 === 0) { + if (this.ws.isOpen) { + const players = world.getAllPlayers().map((p) => { + return { + ...p.location, + code: p.lagoonCode, + muted: p.hasTag('muted') + }; + }); + this.ws.send(JSON.stringify({ + type: 'positions', + uuid: utils.makeid(100), + data: players + })); + } + } + } +} +new LagoonAddons(); diff --git a/scripts/properties.js b/scripts/properties.js new file mode 100644 index 0000000..038468b --- /dev/null +++ b/scripts/properties.js @@ -0,0 +1 @@ +export const roomCode = 'despia'; diff --git a/scripts/utils.js b/scripts/utils.js new file mode 100644 index 0000000..913fe3f --- /dev/null +++ b/scripts/utils.js @@ -0,0 +1,28 @@ +import { world } from "@minecraft/server"; +class Utils { + constructor() { + this.prefix = '§e[§cLagoon§e]§c '; + } + getRndInteger(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + getStaffPlayers() { + return world.getPlayers({ tags: ['staff'] }); + } + logStaff(message) { + this.getStaffPlayers().forEach((p) => p.sendMessage(this.prefix + message)); + } + makeid(length) { + var result = ''; + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var charactersLength = characters.length; + for (var i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; + } + generateCode() { + return this.makeid(5); + } +} +export default new Utils(); diff --git a/src/entities/player.ts b/src/entities/player.ts new file mode 100644 index 0000000..9df6d31 --- /dev/null +++ b/src/entities/player.ts @@ -0,0 +1,10 @@ +import { Player } from "@minecraft/server"; +import utils from "utils"; + +export function InitPlayer(p: Player) { + if(!p.initialized) { + p.initialized = true; + p.lagoonCode = utils.generateCode(); + p.sendMessage(utils.prefix+'§aVotre lagoon code : '+p.lagoonCode+'\n§r§oMerci de ne pas divulguer ce code, il vous est propre !') + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..1202d2c --- /dev/null +++ b/src/main.ts @@ -0,0 +1,77 @@ +import { system, world } from "@minecraft/server"; +import utils from "utils"; +import { websocket, WebSocketClient } from "@minecraft/server-net"; +import { InitPlayer } from "entities/player"; +import { roomCode } from "properties"; + +class LagoonAddons { + + private ws!: WebSocketClient; + public timer: number = 0; + + constructor () { + world.afterEvents.worldLoad.subscribe(() => system.run(() => this.initEarlyExecution())); + } + + async initEarlyExecution() { + this.ws = await websocket.connect('wss://lagoon.under-scape.com/ws/rooms/'+roomCode+'/plugins/proximity'); + this.ws.afterEvents.message.subscribe((event) => { + try { + const payload = JSON.parse(event.message); + + const type = payload.type; + const data = payload.data; + if(type == 'status' && data == 'connected !') { + utils.logStaff('§aLagoon connected !'); + console.log('Lagoon connected !') + } + } catch (error) { + utils.logStaff('ERROR With Payload : '+event.message); + console.log('ERROR With Payload : '+event.message) + } + }); + this.ws.afterEvents.close.subscribe((event) => { + utils.logStaff(`§cConnexion à lagoon fermé ! (${event})`); + console.log(`Connexion à lagoon fermé ! (${event})`) + }); + + world.getAllPlayers().forEach((p) => InitPlayer(p)); + world.afterEvents.playerSpawn.subscribe((e) => { + system.runTimeout(() => { + InitPlayer(e.player); + }, 20 * 3); + }); + + system.runInterval(() => this.clock(), 1); + + utils.logStaff('§aLagoon loaded !'); + console.log('Lagoon loaded !'); + } + + + async clock() { + this.timer++; + + // 1 seconde + if (this.timer % 20 === 0) { + + if (this.ws.isOpen) { + const players: {x: number, y: number, z: number, code: string, muted: boolean}[] = world.getAllPlayers().map((p) => { + return { + ...p.location, + code: p.lagoonCode, + muted: p.hasTag('muted') + } + }); + + this.ws.send(JSON.stringify({ + type: 'positions', + uuid: utils.makeid(100), + data: players + })); + } + } + } +} + +new LagoonAddons(); \ No newline at end of file diff --git a/src/properties.ts b/src/properties.ts new file mode 100644 index 0000000..9386db5 --- /dev/null +++ b/src/properties.ts @@ -0,0 +1 @@ +export const roomCode = 'despia'; \ No newline at end of file diff --git a/src/type.d.ts b/src/type.d.ts new file mode 100644 index 0000000..7140bd4 --- /dev/null +++ b/src/type.d.ts @@ -0,0 +1,8 @@ +import { Player } from "@minecraft/server"; + +declare module "@minecraft/server" { + export interface Player { + lagoonCode: string; + initialized: boolean; + } +} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..cc7f0b8 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,33 @@ +import { Player, system, world } from "@minecraft/server"; + +class Utils { + public prefix: string = '§e[§cLagoon§e]§c '; + + getRndInteger(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + getStaffPlayers(): Player[] { + return world.getPlayers({ tags: ['staff'] }); + } + + logStaff(message: string) { + this.getStaffPlayers().forEach((p) => p.sendMessage(this.prefix + message)); + } + + makeid(length: number) { + var result = ''; + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var charactersLength = characters.length; + for (var i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; + } + + generateCode() { + return this.makeid(5); + } +} + +export default new Utils(); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ec5fba8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "module": "ES2020", + "target": "ES2021", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true, + "baseUrl": "./src", + "rootDir": "./src", + "outDir": "./scripts" + }, + "exclude": ["node_modules"], + "include": ["src"] +} \ No newline at end of file