Add Lagoon proximity chat plugin with player initialization and utilities

This commit is contained in:
2026-05-12 08:18:54 +02:00
parent 7b683fb7dc
commit abfc7304a5
14 changed files with 359 additions and 0 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
# ---> Node
# Logs
logs

34
manifest.json Normal file
View File

@@ -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"
}
]
}

72
package-lock.json generated Normal file
View File

@@ -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"
}
}
}
}

9
package.json Normal file
View File

@@ -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"
}
}

View File

@@ -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 !');
}
}

63
scripts/main.js Normal file
View File

@@ -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();

1
scripts/properties.js Normal file
View File

@@ -0,0 +1 @@
export const roomCode = 'despia';

28
scripts/utils.js Normal file
View File

@@ -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();

10
src/entities/player.ts Normal file
View File

@@ -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 !')
}
}

77
src/main.ts Normal file
View File

@@ -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();

1
src/properties.ts Normal file
View File

@@ -0,0 +1 @@
export const roomCode = 'despia';

8
src/type.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
import { Player } from "@minecraft/server";
declare module "@minecraft/server" {
export interface Player {
lagoonCode: string;
initialized: boolean;
}
}

33
src/utils.ts Normal file
View File

@@ -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();

13
tsconfig.json Normal file
View File

@@ -0,0 +1,13 @@
{
"compilerOptions": {
"module": "ES2020",
"target": "ES2021",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true,
"baseUrl": "./src",
"rootDir": "./src",
"outDir": "./scripts"
},
"exclude": ["node_modules"],
"include": ["src"]
}