/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import { ByteBuffer } from '@xmcl/bytebuffer';
import { EventEmitter } from 'events';
import { NetConnectOpts } from 'net';
import { Transform, TransformCallback, Writable } from 'stream';
import { Coder } from './coders';
import { PacketRegistryEntry, Side } from './packet';
export type State = keyof States;
interface States {
    handshake: PacketCoders;
    login: PacketCoders;
    status: PacketCoders;
    play: PacketCoders;
}
/**
 * The channel for send and listen the Minecraft packet.
 */
export declare class Channel extends EventEmitter {
    state: State;
    private readonly states;
    private connection;
    private outbound;
    private inbound;
    private enableCompression;
    private compressionThreshold;
    constructor();
    /**
       * Is the connection ready to read and write
       */
    get ready(): boolean;
    findCoderById(packetId: number, side: Side): Coder<any>;
    getPacketId(packetInst: any, side: Side): number;
    registerPacketType(clazz: new (...args: any) => any): void;
    registerPacket(entry: PacketRegistryEntry): void;
    /**
       * Open the connection and start to listen the port.
       */
    listen(option: NetConnectOpts & {
        keepalive?: boolean | number;
    }): Promise<void>;
    disconnect(): Promise<void>;
    /**
       * Sent a packet to server.
       */
    send<T>(message: T, skeleton?: Partial<T>): void;
    /**
       * Listen for sepcific packet by its class name.
       */
    onPacket<T>(packet: new (...args: any[]) => T, listener: (event: T) => void): this;
    oncePacket<T>(packet: new (...args: any[]) => T, listener: (event: T) => void): this;
}
export interface Channel extends EventEmitter {
    on<T>(channel: string, listener: (event: T) => void): this;
    once<T>(channel: string, listener: (event: T) => void): this;
}
export declare abstract class PacketInBound extends Transform {
    private buffer;
    protected abstract readPacketLength(bb: ByteBuffer): number;
    _transform(chunk: Buffer, encoding: string, callback: TransformCallback): void;
}
export interface PacketRegistry {
    findCoderById(packetId: number, side: 'client' | 'server'): Coder<any>;
    getPacketId(message: any, side: 'client' | 'server'): number;
}
export declare abstract class PacketDecoder extends Transform {
    private client;
    constructor(client: PacketRegistry);
    abstract readPacketId(message: ByteBuffer): number;
    _transform(chunk: Buffer, encoding: string, callback: TransformCallback): void;
}
export declare class PacketEmitter extends Writable {
    private eventBus;
    constructor(eventBus: EventEmitter);
    _write(inst: any, encoding: string, callback: (error?: Error | null) => void): void;
}
export declare abstract class PacketEncoder extends Transform {
    private client;
    constructor(client: PacketRegistry);
    protected abstract writePacketId(bb: ByteBuffer, id: number): void;
    _transform(message: any, encoding: string, callback: TransformCallback): void;
}
export declare abstract class PacketOutbound extends Transform {
    protected abstract writePacketLength(bb: ByteBuffer, len: number): void;
    _transform(packet: Buffer, encoding: string, callback: TransformCallback): void;
}
declare class PacketCoders {
    packetIdCoders: {
        [packetId: number]: Coder<any>;
    };
    packetNameToId: {
        [name: string]: number;
    };
}
export {};
//# sourceMappingURL=channel.d.ts.map