@jsprismarine/prismarine
Version:
Dedicated Minecraft Bedrock Edition server written in TypeScript
164 lines (159 loc) • 14.6 kB
JavaScript
;
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
require('node:fs');
require('confbox');
require('@jsprismarine/errors');
require('@jsprismarine/jsbinaryutils');
require('node:assert');
require('node:path');
require('node:process');
require('../../block/BlockToolType.cjs.cjs');
require('@jsprismarine/bedrock-data');
require('@jsprismarine/nbt');
require('zlib');
require('@jsprismarine/math');
require('@jsprismarine/minecraft');
require('../packet/AddActorPacket.cjs.cjs');
require('../packet/MoveActorAbsolutePacket.cjs.cjs');
require('../packet/RemoveActorPacket.cjs.cjs');
require('node:crypto');
require('../packet/ActorFallPacket.cjs.cjs');
require('../packet/AddItemActorPacket.cjs.cjs');
require('../packet/AddPlayerPacket.cjs.cjs');
require('../packet/AnimatePacket.cjs.cjs');
require('../packet/AvailableActorIdentifiersPacket.cjs.cjs');
require('../packet/AvailableCommandsPacket.cjs.cjs');
require('../CompressionProvider.cjs.cjs');
require('../packet/NetworkSettingsPacket.cjs.cjs');
require('../packet/BiomeDefinitionListPacket.cjs.cjs');
require('../packet/ChangeDimensionPacket.cjs.cjs');
require('../packet/ChunkRadiusUpdatedPacket.cjs.cjs');
require('../packet/CommandRequestPacket.cjs.cjs');
require('../packet/ContainerClosePacket.cjs.cjs');
require('../packet/ContainerOpenPacket.cjs.cjs');
require('../packet/CreativeContentPacket.cjs.cjs');
require('../packet/DisconnectPacket.cjs.cjs');
require('../packet/EmoteListPacket.cjs.cjs');
require('../packet/InteractPacket.cjs.cjs');
require('../packet/InventoryContentPacket.cjs.cjs');
require('../packet/InventoryTransactionPacket.cjs.cjs');
require('../packet/ItemComponentPacket.cjs.cjs');
require('../packet/ItemStackRequestPacket.cjs.cjs');
require('../packet/ItemStackResponsePacket.cjs.cjs');
require('../packet/LevelChunkPacket.cjs.cjs');
require('../packet/LevelSoundEventPacket.cjs.cjs');
require('../packet/LoginPacket.cjs.cjs');
require('../packet/MobEquipmentPacket.cjs.cjs');
require('../packet/MovePlayerPacket.cjs.cjs');
require('../packet/NetworkChunkPublisherUpdatePacket.cjs.cjs');
require('../packet/OnScreenTextureAnimationPacket.cjs.cjs');
require('../packet/PacketViolationWarningPacket.cjs.cjs');
require('../packet/PlaySoundPacket.cjs.cjs');
const network_packet_PlayStatusPacket = require('../packet/PlayStatusPacket.cjs.cjs');
require('../packet/PlayerActionPacket.cjs.cjs');
require('../packet/PlayerListPacket.cjs.cjs');
require('../packet/PlayerSkinPacket.cjs.cjs');
require('../packet/RequestChunkRadiusPacket.cjs.cjs');
require('../packet/RequestNetworkSettingsPacket.cjs.cjs');
require('../packet/ResourcePackResponsePacket.cjs.cjs');
require('../packet/ResourcePackStackPacket.cjs.cjs');
const network_packet_ResourcePacksInfoPacket = require('../packet/ResourcePacksInfoPacket.cjs.cjs');
require('../packet/ServerSettingsRequestPacket.cjs.cjs');
require('../packet/SetActorDataPacket.cjs.cjs');
require('../packet/SetDefaultGametypePacket.cjs.cjs');
require('../packet/SetHealthPacket.cjs.cjs');
require('../packet/SetLocalPlayerAsInitializedPacket.cjs.cjs');
require('../packet/SetPlayerGametypePacket.cjs.cjs');
require('../packet/SetTimePacket.cjs.cjs');
require('../packet/ShowProfilePacket.cjs.cjs');
require('../packet/StartGamePacket.cjs.cjs');
require('../packet/TextPacket.cjs.cjs');
require('../packet/TickSyncPacket.cjs.cjs');
require('../packet/TransferPacket.cjs.cjs');
require('../packet/UpdateAdventureSettingsPacket.cjs.cjs');
require('../packet/UpdateAttributesPacket.cjs.cjs');
require('../packet/UpdateBlockPacket.cjs.cjs');
require('../packet/WorldEventPacket.cjs.cjs');
require('@jsprismarine/brigadier');
const network_Identifiers = require('../Identifiers.cjs.cjs');
require('../../config/Config.cjs.cjs');
require('./AnimateHandler.cjs.cjs');
require('./CommandRequestHandler.cjs.cjs');
require('./ContainerCloseHandler.cjs.cjs');
require('./EmoteListHandler.cjs.cjs');
require('./InteractHandler.cjs.cjs');
require('./InventoryTransactionHandler.cjs.cjs');
require('./LevelSoundEventHandler.cjs.cjs');
require('./MobEquipmentHandler.cjs.cjs');
require('./MovePlayerHandler.cjs.cjs');
require('./PacketViolationWarningHandler.cjs.cjs');
require('./PlayerActionHandler.cjs.cjs');
require('./RequestChunkRadiusHandler.cjs.cjs');
require('./RequestNetworkSettingsHandler.cjs.cjs');
require('./ResourcePackResponseHandler.cjs.cjs');
require('./ServerSettingsRequestHandler.cjs.cjs');
require('./SetDefaultGametypeHandler.cjs.cjs');
require('./SetLocalPlayerAsInitializedHandler.cjs.cjs');
require('./SetPlayerGametypeHandler.cjs.cjs');
require('./TextHandler.cjs.cjs');
require('./TickSyncHandler.cjs.cjs');
require('node:readline');
const Player = require('../../Player.cjs.cjs');
require('@jsprismarine/raknet');
require('evt');
require('assert');
require('heap');
require('../packet/UpdateAbilitiesPacket.cjs.cjs');
const network_type_PlayStatusType = require('../type/PlayStatusType.cjs.cjs');
class LoginHandler {
static NetID = network_Identifiers.default.LoginPacket;
/**
* @TODO: Check if player count >= max players
* @TODO: encryption handshake.
*/
async handle(packet, server, connection) {
const playStatus = new network_packet_PlayStatusPacket.default();
if (packet.protocol !== network_Identifiers.default.Protocol) {
playStatus.status = packet.protocol < network_Identifiers.default.Protocol ? network_type_PlayStatusType.default.LoginFailedClient : network_type_PlayStatusType.default.LoginFailedServer;
await connection.sendDataPacket(playStatus, true);
return;
}
if (!packet.displayName) {
connection.disconnect("Invalid username!", false);
return;
}
const player = new Player.default({
connection,
world: server.getWorldManager().getDefaultWorld(),
server,
uuid: packet.identity
});
player.setName(packet.displayName);
player.xuid = packet.XUID;
player.randomId = packet.clientRandomId;
player.locale = packet.languageCode;
player.skin = packet.skin;
player.device = packet.device;
await server.getSessionManager().findPlayer({ name: packet.displayName, xuid: packet.XUID })?.kick("Logged in from another location");
if (!player.xuid && server.getConfig().getOnlineMode()) {
await player.kick("Server is in online-mode!");
return;
}
const reason = server.getBanManager().isBanned(player);
if (reason !== false) {
await player.kick(`You have been banned${reason ? ` for reason: ${reason}` : ""}!`);
return;
}
await player.enable();
const session = connection.initPlayerConnection(server, player);
await session.sendPlayStatus(network_type_PlayStatusType.default.LoginSuccess);
const resourcePacksInfo = new network_packet_ResourcePacksInfoPacket.default();
resourcePacksInfo.resourcePackRequired = false;
resourcePacksInfo.forceServerPacksEnabled = false;
resourcePacksInfo.hasScripts = false;
resourcePacksInfo.hasAddonPacks = false;
await connection.sendDataPacket(resourcePacksInfo, true);
}
}
exports.default = LoginHandler;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTG9naW5IYW5kbGVyLmNqcy5janMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9uZXR3b3JrL2hhbmRsZXIvTG9naW5IYW5kbGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBsYXllciB9IGZyb20gJy4uLy4uLyc7XG5pbXBvcnQgdHlwZSBTZXJ2ZXIgZnJvbSAnLi4vLi4vU2VydmVyJztcbmltcG9ydCB0eXBlIENsaWVudENvbm5lY3Rpb24gZnJvbSAnLi4vQ2xpZW50Q29ubmVjdGlvbic7XG5pbXBvcnQgSWRlbnRpZmllcnMgZnJvbSAnLi4vSWRlbnRpZmllcnMnO1xuaW1wb3J0IHsgUGxheVN0YXR1c1BhY2tldCB9IGZyb20gJy4uL1BhY2tldHMnO1xuaW1wb3J0IHR5cGUgTG9naW5QYWNrZXQgZnJvbSAnLi4vcGFja2V0L0xvZ2luUGFja2V0JztcbmltcG9ydCBSZXNvdXJjZVBhY2tzSW5mb1BhY2tldCBmcm9tICcuLi9wYWNrZXQvUmVzb3VyY2VQYWNrc0luZm9QYWNrZXQnO1xuaW1wb3J0IFBsYXlTdGF0dXNUeXBlIGZyb20gJy4uL3R5cGUvUGxheVN0YXR1c1R5cGUnO1xuaW1wb3J0IHR5cGUgUHJlTG9naW5QYWNrZXRIYW5kbGVyIGZyb20gJy4vUHJlTG9naW5QYWNrZXRIYW5kbGVyJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTG9naW5IYW5kbGVyIGltcGxlbWVudHMgUHJlTG9naW5QYWNrZXRIYW5kbGVyPExvZ2luUGFja2V0PiB7XG4gICAgcHVibGljIHN0YXRpYyBOZXRJRCA9IElkZW50aWZpZXJzLkxvZ2luUGFja2V0O1xuXG4gICAgLyoqXG4gICAgICogQFRPRE86IENoZWNrIGlmIHBsYXllciBjb3VudCA+PSBtYXggcGxheWVyc1xuICAgICAqIEBUT0RPOiBlbmNyeXB0aW9uIGhhbmRzaGFrZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgaGFuZGxlKHBhY2tldDogTG9naW5QYWNrZXQsIHNlcnZlcjogU2VydmVyLCBjb25uZWN0aW9uOiBDbGllbnRDb25uZWN0aW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHBsYXlTdGF0dXMgPSBuZXcgUGxheVN0YXR1c1BhY2tldCgpO1xuXG4gICAgICAgIC8vIEtpY2sgY2xpZW50IGlmIGhhcyBuZXdlciAvIG9sZGVyIGNsaWVudCB2ZXJzaW9uXG4gICAgICAgIGlmIChwYWNrZXQucHJvdG9jb2wgIT09IElkZW50aWZpZXJzLlByb3RvY29sKSB7XG4gICAgICAgICAgICBwbGF5U3RhdHVzLnN0YXR1cyA9XG4gICAgICAgICAgICAgICAgcGFja2V0LnByb3RvY29sIDwgSWRlbnRpZmllcnMuUHJvdG9jb2xcbiAgICAgICAgICAgICAgICAgICAgPyBQbGF5U3RhdHVzVHlwZS5Mb2dpbkZhaWxlZENsaWVudFxuICAgICAgICAgICAgICAgICAgICA6IFBsYXlTdGF0dXNUeXBlLkxvZ2luRmFpbGVkU2VydmVyO1xuICAgICAgICAgICAgYXdhaXQgY29ubmVjdGlvbi5zZW5kRGF0YVBhY2tldChwbGF5U3RhdHVzLCB0cnVlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEtpY2sgdGhlIHBsYXllciBpZiB0aGVpciB1c2VybmFtZSBpcyBpbnZhbGlkXG4gICAgICAgIGlmICghcGFja2V0LmRpc3BsYXlOYW1lKSB7XG4gICAgICAgICAgICBjb25uZWN0aW9uLmRpc2Nvbm5lY3QoJ0ludmFsaWQgdXNlcm5hbWUhJywgZmFsc2UpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGxheWVyID0gbmV3IFBsYXllcih7XG4gICAgICAgICAgICBjb25uZWN0aW9uLFxuICAgICAgICAgICAgd29ybGQ6IHNlcnZlci5nZXRXb3JsZE1hbmFnZXIoKS5nZXREZWZhdWx0V29ybGQoKSEsXG4gICAgICAgICAgICBzZXJ2ZXIsXG4gICAgICAgICAgICB1dWlkOiBwYWNrZXQuaWRlbnRpdHlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcGxheWVyLnNldE5hbWUocGFja2V0LmRpc3BsYXlOYW1lKTtcbiAgICAgICAgcGxheWVyLnh1aWQgPSBwYWNrZXQuWFVJRDtcbiAgICAgICAgcGxheWVyLnJhbmRvbUlkID0gcGFja2V0LmNsaWVudFJhbmRvbUlkO1xuICAgICAgICBwbGF5ZXIubG9jYWxlID0gcGFja2V0Lmxhbmd1YWdlQ29kZTtcbiAgICAgICAgcGxheWVyLnNraW4gPSBwYWNrZXQuc2tpbjtcbiAgICAgICAgcGxheWVyLmRldmljZSA9IHBhY2tldC5kZXZpY2U7XG5cbiAgICAgICAgLy8gUGxheWVyIHdpdGggc2FtZSBuYW1lIG9yIHh1aWQgaXMgYWxyZWFkeSBjb25uZWN0ZWQsXG4gICAgICAgIC8vIHNvIGtpY2sgdGhlIG9sZCBwbGF5ZXIgYW5kIGxldCB0aGUgbmV3IHBsYXllciBjb25uZWN0LlxuICAgICAgICBhd2FpdCBzZXJ2ZXJcbiAgICAgICAgICAgIC5nZXRTZXNzaW9uTWFuYWdlcigpXG4gICAgICAgICAgICAuZmluZFBsYXllcih7IG5hbWU6IHBhY2tldC5kaXNwbGF5TmFtZSwgeHVpZDogcGFja2V0LlhVSUQgfSlcbiAgICAgICAgICAgID8ua2ljaygnTG9nZ2VkIGluIGZyb20gYW5vdGhlciBsb2NhdGlvbicpO1xuXG4gICAgICAgIGlmICghcGxheWVyLnh1aWQgJiYgc2VydmVyLmdldENvbmZpZygpLmdldE9ubGluZU1vZGUoKSkge1xuICAgICAgICAgICAgYXdhaXQgcGxheWVyLmtpY2soJ1NlcnZlciBpcyBpbiBvbmxpbmUtbW9kZSEnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlYXNvbiA9IHNlcnZlci5nZXRCYW5NYW5hZ2VyKCkuaXNCYW5uZWQocGxheWVyKTtcbiAgICAgICAgaWYgKHJlYXNvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGF3YWl0IHBsYXllci5raWNrKGBZb3UgaGF2ZSBiZWVuIGJhbm5lZCR7cmVhc29uID8gYCBmb3IgcmVhc29uOiAke3JlYXNvbn1gIDogJyd9IWApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgcGxheWVyLmVuYWJsZSgpO1xuXG4gICAgICAgIC8vIFVwZGF0ZSB0aGUgcGxheWVyIGNvbm5lY3Rpb24gdG8gYmUgcmVjb2duaXplZCBhcyBhIGNvbm5lY3RlZCBwbGF5ZXJcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IGNvbm5lY3Rpb24uaW5pdFBsYXllckNvbm5lY3Rpb24oc2VydmVyLCBwbGF5ZXIpO1xuICAgICAgICBhd2FpdCBzZXNzaW9uLnNlbmRQbGF5U3RhdHVzKFBsYXlTdGF0dXNUeXBlLkxvZ2luU3VjY2Vzcyk7XG5cbiAgICAgICAgLy8gRmluYWxpemUgY29ubmVjdGlvbiBoYW5kc2hha2VcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQYWNrc0luZm8gPSBuZXcgUmVzb3VyY2VQYWNrc0luZm9QYWNrZXQoKTtcbiAgICAgICAgcmVzb3VyY2VQYWNrc0luZm8ucmVzb3VyY2VQYWNrUmVxdWlyZWQgPSBmYWxzZTtcbiAgICAgICAgcmVzb3VyY2VQYWNrc0luZm8uZm9yY2VTZXJ2ZXJQYWNrc0VuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgcmVzb3VyY2VQYWNrc0luZm8uaGFzU2NyaXB0cyA9IGZhbHNlO1xuICAgICAgICByZXNvdXJjZVBhY2tzSW5mby5oYXNBZGRvblBhY2tzID0gZmFsc2U7XG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24uc2VuZERhdGFQYWNrZXQocmVzb3VyY2VQYWNrc0luZm8sIHRydWUpO1xuICAgIH1cbn1cbiJdLCJuYW1lcyI6WyJJZGVudGlmaWVycyIsIlBsYXlTdGF0dXNQYWNrZXQiLCJQbGF5U3RhdHVzVHlwZSIsIlBsYXllciIsIlJlc291cmNlUGFja3NJbmZvUGFja2V0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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