diff --git a/classes/Player.ts b/classes/Player.ts index 4393018..2f6f6fc 100644 --- a/classes/Player.ts +++ b/classes/Player.ts @@ -39,7 +39,10 @@ export class Player { async writeToSocket(ar: Uint8Array) { await this.socket.write(ar).catch(async (e) => { log.critical(e); - await this.server.removeUser(this.socket); + await this.server.removeUser( + this.socket, + "Write failed" + e.message.split("\n")[0], + ); }); } diff --git a/classes/Server.ts b/classes/Server.ts index e58b645..8ee992c 100644 --- a/classes/Server.ts +++ b/classes/Server.ts @@ -28,7 +28,7 @@ export class Server { [13, 65], ]); - maxUsers = 69; + maxUsers = config.maxUsers; worlds: World[] = [new World({ x: 64, y: 64, z: 64 }, config.main)]; @@ -67,9 +67,9 @@ export class Server { "https://www.classicube.net/heartbeat.jsp" + `?port=${config.port}` + `&max=${this.maxUsers}` + - "&name=Cla66ic" + + `&name=${config.name}` + "&public=True" + - "&software=Cla66ic" + + `&software=${config.software}` + `&version=7&salt=${config.hash}` + `&users=${[...new Set(this.players.map((obj) => obj.ip))].length}`, ); @@ -136,7 +136,7 @@ export class Server { } } } - async removeUser(conn: Deno.Conn) { + async removeUser(conn: Deno.Conn, text: string) { const player = this.players.find((e) => e.socket == conn); if (!player) return; @@ -149,7 +149,7 @@ export class Server { // whatever } - this.broadcast(`${player.username} has &cleft`); + this.broadcast(`${player.username} has &cleft&f, "${text}"`); await this.worlds.find((e) => e.name == player.world)!.save(); @@ -319,7 +319,7 @@ export class Server { try { packetIDReadAttempt = await connection.read(packetID); } catch { - await this.removeUser(connection); // TODO: add a reason to this + await this.removeUser(connection, "Packet ID read failed"); break; } @@ -328,7 +328,7 @@ export class Server { if (!packetLength) { log.critical("Unknown Packet: " + packetID[0]); - await this.removeUser(connection); // TODO: add a reason to this + await this.removeUser(connection, "Unknown packet ID " + packetID[0]); // TODO: add a reason to this break; } @@ -338,7 +338,7 @@ export class Server { try { packetReadAttempt = await connection.read(rawPacket); } catch { - await this.removeUser(connection); // TODO: add a reason to this + await this.removeUser(connection, "Packet read attempt failed."); // TODO: add a reason to this break; } @@ -351,14 +351,20 @@ export class Server { try { fullRead += (await connection.read(halfPacket))!; } catch { - await this.removeUser(connection); // TODO: add a reason to this + await this.removeUser( + connection, + "Couldn't read all of packet " + packetID[0], + ); break; } } this.handlePacket(rawPacket, packetID[0], connection); } else { - await this.removeUser(connection); + await this.removeUser( + connection, + "Packet ID read returned null. Packet " + packetID[0], + ); break; } } diff --git a/deps.ts b/deps.ts index f151797..cd87316 100644 --- a/deps.ts +++ b/deps.ts @@ -25,4 +25,7 @@ export const config = { hash: Deno.env.get("HASH"), onlineMode: Deno.env.get("ONLINEMODE") == "true", main: Deno.env.get("MAIN") || "main", + maxUsers: +(Deno.env.get("USERS") || 24) > 255 ? 255 : +(Deno.env.get("USERS") || 24), + software: Deno.env.get("SOFTWARE") || "Custom Cla66ic", + name: Deno.env.get("NAME") || "Cla66ic Server" }; diff --git a/plugins/commands.ts b/plugins/commands.ts index 6acd659..b277e8a 100644 --- a/plugins/commands.ts +++ b/plugins/commands.ts @@ -1,4 +1,4 @@ -import { Plugin } from "../classes/classes.ts"; +import { PacketWriter, Player, Plugin } from "../classes/classes.ts"; import { Server } from "../classes/Server.ts"; import { config } from "../deps.ts"; @@ -7,14 +7,36 @@ export default class CommandPlugin extends Plugin { "help", "reloadplugins", "clients", + "tp", + "eval" ]; + async tp(from: Player, to: Player) { + if(to.world != from.world) { + from.toWorld(this.server.worlds.find((e) => + e.name == to.world + )!); + } + + await from.writeToSocket( + new PacketWriter() + .writeByte(0x08) + .writeSByte(255) + .writeShort(to.position.x) + .writeShort(to.position.y) + .writeShort(to.position.z) + .writeByte(to.rotation.yaw) + .writeByte(to.rotation.pitch) + .toPacket(), + ); + } + constructor(server: Server) { super(); this.server = server; - this.on("command", async (command, player) => { + this.on("command", async (command, player, args) => { if (command == "help") { let allComamnds = ""; for (const [_k, v] of server.plugins) { @@ -38,7 +60,42 @@ export default class CommandPlugin extends Plugin { ); } }); - } - }); + } else if(command == "eval") { + if(config.ops.includes(player.username)) { + + server.broadcast(eval(args.join(" "))); + } + } else if (command == "tp") { + if(args.length == 1) { + const teleportTo = this.server.players.find((e) => args[0] === e.username) + + if(teleportTo) { + await this.tp(player, teleportTo); + } else { + player.message("Player is missing") + } + } else if(args.length == 3) { + const x = +args[0] + const y = +args[1] + const z = +args[2] + + if(isNaN(x) || isNaN(y) || isNaN(z)) { + player.message("invalid coords") + return; + } + await player.writeToSocket( + new PacketWriter() + .writeByte(0x08) + .writeSByte(255) + .writeShort(x * 32) + .writeShort(y * 32) + .writeShort(z * 32) + .writeByte(player.rotation.yaw) + .writeByte(player.rotation.pitch) + .toPacket(), + ); + } + } + }); } }