Different Send/Receive Message Channel Types

and some other minor stuff
This commit is contained in:
Dinhero21 2024-01-08 04:25:38 -03:00
parent 8a58ee0ae5
commit 6cba62e78c
9 changed files with 41 additions and 134 deletions

View file

@ -17,7 +17,7 @@ const MODULE_DIR_PATH = resolve(__dirname, '../module')
const VERSION = '1.19.4'
export const TARGET_OPTIONS = {
host: 'grandma-does.tech',
host: 'kaboom.pw',
port: 25565,
keepAlive: false,
username: 'Player137',
@ -71,14 +71,14 @@ export class Instance {
} satisfies Message)
}
public createChannel<T> (id: string): Channel<T> {
const channel = new Channel<T>(id)
public createChannel<TSend, TReceive = TSend> (id: string): Channel<TSend, TReceive> {
const channel = new Channel<TSend, TReceive>(id)
channel._subscribe(data => {
this.postMessage(id, data)
})
this.worker.on('message', (message: Message<T>) => {
this.worker.on('message', (message: Message<TReceive>) => {
if (message.channel !== id) return
channel._write(message.data)

5
src/module/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
*
!.gitignore
# internal modules
!proxy

View file

@ -1,22 +1,17 @@
import { type Side, type Message } from './shared.js'
import { type AsyncVoid, EventHandler } from '../../util/events.js'
import { PublicEventHandler } from '../../util/events.js'
import { createChannel } from '../../worker/parent.js'
import { Packet, type RawPacket } from '../../util/packet.js'
import { type AsyncVoid } from '../../util/types.js'
export type EventMap = Record<string, (packet: Packet) => AsyncVoid>
export class EventEmitter extends EventHandler<EventMap> {
public async emit (name: string, packet: Packet): Promise<void> {
await this._emit(name, packet)
}
}
export type PacketEventMap = Record<string, (packet: Packet) => AsyncVoid>
// ? Should I export the channel
export const channel = createChannel<Message>('proxy')
export class Proxy {
public readonly client = new EventEmitter()
public readonly server = new EventEmitter()
public readonly client = new PublicEventHandler<PacketEventMap>()
public readonly server = new PublicEventHandler<PacketEventMap>()
constructor () {
channel.subscribe(({ side, packet: raw }: Message) => {
@ -65,4 +60,6 @@ export class Proxy {
}
}
export default new Proxy()
export const proxy = new Proxy()
export default proxy

View file

@ -1,39 +1,41 @@
export type Listener<T> = (data: T) => void
// _x -> x
// x -> _x
export class Channel<T> {
export class Channel<TSend, TReceive = TSend> {
public readonly id
constructor (id: string) {
this.id = id
}
private readonly listeners = new Set<(data: T) => void>()
private readonly listeners = new Set<Listener<TReceive>>()
public subscribe (listener: (data: T) => void): void {
public subscribe (listener: Listener<TReceive>): void {
this.listeners.add(listener)
}
public unsubscribe (listener: (data: T) => void): void {
public unsubscribe (listener: Listener<TReceive>): void {
this.listeners.delete(listener)
}
public write (data: T): void {
public write (data: TSend): void {
for (const listener of this._listeners) {
listener(data)
}
}
private readonly _listeners = new Set<(data: T) => void>()
private readonly _listeners = new Set<Listener<TSend>>()
public _subscribe (listener: (data: T) => void): void {
public _subscribe (listener: Listener<TSend>): void {
this._listeners.add(listener)
}
public _unsubscribe (listener: (data: T) => void): void {
public _unsubscribe (listener: Listener<TSend>): void {
this._listeners.delete(listener)
}
public _write (data: T): void {
public _write (data: TReceive): void {
for (const listener of this.listeners) {
listener(data)
}

View file

@ -1,4 +1,4 @@
export type AsyncVoid = void | Promise<void>
import { type AsyncVoid } from './types.js'
export type EventMap<T> = { [K in keyof T]: (...args: any[]) => AsyncVoid }
@ -40,3 +40,9 @@ export class EventHandler<T extends EventMap<T>> {
map.clear()
}
}
export class PublicEventHandler<T extends EventMap<T>> extends EventHandler<T> {
public async emit<E extends keyof T> (name: E, ...data: Parameters<T[E]>): Promise<void> {
await this._emit(name, ...data)
}
}

View file

@ -3,13 +3,13 @@ export interface RawPacket {
data: unknown
}
export class Packet<T = unknown> {
export class Packet<Data = unknown> {
public name
public data
public canceled: boolean = false
constructor (name: string, data: T) {
constructor (name: string, data: Data) {
this.name = name
this.data = data
}

1
src/util/types.ts Normal file
View file

@ -0,0 +1 @@
export type AsyncVoid = void | Promise<void>

View file

@ -1,104 +0,0 @@
// import { type UUID } from 'crypto'
// import { type AsyncVoid, EventHandler } from '../../util/events.js'
// import { type Packet } from '../util/packet.js'
// import proxy from './proxy.js'
// export type i64 = [number, number]
// export interface ClientChatPacketData {
// timestamp: i64
// salt: i64
// acknowledged: Uint8Array
// }
// export type Signature = Uint8Array
// export interface ClientChatMessagePacketData extends ClientChatPacketData {
// message: string
// signature: Signature | undefined
// offset: number
// }
// export interface ClientChatCommandPacketData extends ClientChatPacketData {
// command: string
// argumentSignatures: Signature[]
// messageCount: number
// }
// export interface ProfileLessChatPacketData {
// message: string
// type: number
// name: string
// // TODO: find out what target is supposed to be
// target: undefined
// }
// export interface PlayerChatPacketData {
// senderUuid: UUID
// index: number
// signature: Signature | undefined
// plainMessage: string
// timestamp: i64
// salt: i64
// // TODO: find out what previousMessages is supposed to be
// previousMessages: never[]
// unsignedChatContent: string
// filterType: number
// // TODO: Find out what filterTypeMask is supposed to be
// filterTypeMask: undefined
// type: number
// networkName: string
// // TODO: find out what networkTargetName is supposed to be
// networkTargetName: undefined
// }
// export interface SystemChatPacketData {
// content: string
// isActionBar: boolean
// }
// export interface ChatEventMap {
// 'client.command': (packet: Packet<ClientChatCommandPacketData>) => AsyncVoid
// 'client.message': (packet: Packet<ClientChatMessagePacketData>) => AsyncVoid
// 'server.profiless': (packet: Packet<ProfileLessChatPacketData>) => AsyncVoid
// 'server.player': (packet: Packet<PlayerChatPacketData>) => AsyncVoid
// 'server.system': (packet: Packet<SystemChatPacketData>) => AsyncVoid
// }
// export class Chat extends EventHandler<ChatEventMap> {
// constructor () {
// super()
// proxy.client.on('chat_command', async packet => {
// await this._emit('client.command', packet as Packet<ClientChatCommandPacketData>)
// })
// proxy.client.on('chat_message', async packet => {
// await this._emit('client.message', packet as Packet<ClientChatMessagePacketData>)
// })
// proxy.server.on('profileless_chat', async packet => {
// await this._emit('server.profiless', packet as Packet<ProfileLessChatPacketData>)
// })
// proxy.server.on('player_chat', async packet => {
// await this._emit('server.player', packet as Packet<PlayerChatPacketData>)
// })
// proxy.server.on('system_chat', async packet => {
// await this._emit('server.system', packet as Packet<SystemChatPacketData>)
// })
// }
// // // TODO: Fix
// // public writeClientCommand (command: string): void {
// // proxy.writeClient('chat_command', { command })
// // }
// // public writeClientMessage (message: string): void {
// // proxy.writeClient('chat_message', { message })
// // }
// }
// export default new Chat()

View file

@ -17,14 +17,14 @@ function postMessage (channel: string, data: any): void {
})
}
export function createChannel<T> (id: string): Channel<T> {
const channel = new Channel<T>(id)
export function createChannel<TSend, TReceive = TSend> (id: string): Channel<TSend, TReceive> {
const channel = new Channel<TSend, TReceive>(id)
channel._subscribe(message => {
postMessage(id, message)
})
port.on('message', (message: Message<T>) => {
port.on('message', (message: Message<TReceive>) => {
if (message.channel !== id) return
channel._write(message.data)