Initial commit

This commit is contained in:
2023-03-23 00:48:09 +01:00
commit 4e08ef5747
12 changed files with 4027 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
root = true
[*.{js,json}]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
+4
View File
@@ -0,0 +1,4 @@
node_modules/
dist/**
src/protocol.json
!.gitkeep
+3
View File
@@ -0,0 +1,3 @@
[submodule "src/protocol"]
path = src/protocol
url = https://git.sys36.net/windows-96/ppp2/protocol
+8
View File
@@ -0,0 +1,8 @@
# ppp2 client
## building
```
$ npm i
$ npm run build-proto
$ npm run build
```
View File
+3793
View File
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
{
"type": "module",
"name": "ppp2-client",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build-proto": "NODE_VERSION=19 npm_config_prefix= $HOME/.nvm/nvm-exec ./node_modules/protobufjs-cli/bin/pbjs -t=json src/protocol/protobuf/2.0/*.proto > src/protocol.json",
"dev": "NODE_ENV=development webpack watch",
"build": "NODE_ENV=production webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git@git.sys36.net:windows-96/ppp2/client.git"
},
"author": "",
"license": "UNLICENSED",
"dependencies": {
"long": "^5.2.1",
"ws": "^8.13.0"
},
"devDependencies": {
"protobufjs-cli": "^1.1.1",
"webpack": "^5.76.3",
"webpack-cli": "^5.0.1"
}
}
+105
View File
@@ -0,0 +1,105 @@
import {
Container,
AuthenticationRequest,
AuthenticationResponse,
Message
} from './Protocol.js'
import { EventEmitter } from 'events'
const WebSocket = (typeof window === 'undefined' ? import('ws'): window.WebSocket)
export class Client extends EventEmitter {
#gateway
#ws
#id
#address
constructor(gateway) {
super()
this.#id = 0
this.#gateway = gateway
}
#protoSend({ id, message }) {
const container = Container.create({
id,
[message.constructor.name]: message
})
const buf = Container.encode(container).finish()
console.log('sending:', buf)
this.#ws.send(buf)
}
#protoRequest(message) {
const id = this.#id++
return new Promise(resolve => {
const onReceive = container => {
if(container.id === id) {
resolve(container)
this.removeListener('raw', onReceive)
}
}
this.on('raw', onReceive)
this.#protoSend({
id,
message
})
})
}
login({ seed }) {
const ws = new WebSocket(this.#gateway)
this.#ws = ws
ws.onopen = async () => {
const response = await this.#protoRequest(AuthenticationRequest.create({ seed }))
const auth = AuthenticationResponse.toObject(response.AuthenticationResponse, { longs: String })
this.#address = BigInt(auth.address)
this.emit('ready')
}
ws.onmessage = async ({ data }) => {
const message = Container.decode(new Uint8Array(await data.arrayBuffer()))
const container = Container.toObject(message, {
oneofs: true
})
this.emit('raw', container)
}
ws.onclose = () => {
}
}
send(destination, port, data) {
if(typeof destination === 'bigint') {
destination = destination.toString(10)
}
this.#protoSend({
id: this.#id++,
message: Message.create({
address: destination,
port,
data
})
})
}
get address() {
return this.#address
}
listen(port, callback) {
this.on('raw', container => {
if(container.message === 'Message') {
const message = Message.toObject(container.Message, { longs: String })
callback(BigInt(message.address), message.data)
}
})
}
}
+42
View File
@@ -0,0 +1,42 @@
import encoders from './protocol.json' assert { type: 'json' }
import protobuf from 'protobufjs'
import Long from 'long'
protobuf.util.Long = Long
protobuf.configure()
const import_proto = (descriptor, types) => {
const proto = protobuf.Root.fromJSON(descriptor)
return types.map(type => proto.lookupType(type))
}
export const [
Container,
AuthenticationRequest,
AuthenticationResponse,
Message,
PublishRequest,
PublishResponse,
DiscoverRequest,
DiscoverResponse
] = import_proto(protocol20, [
'Container',
'AuthenticationRequest',
'AuthenticationResponse',
'Message',
'PublishRequest',
'PublishResponse',
'DiscoverRequest',
'DiscoverResponse'
])
export const messages = [
Container,
AuthenticationRequest,
AuthenticationResponse,
Message,
PublishRequest,
PublishResponse,
DiscoverRequest,
DiscoverResponse
]
+13
View File
@@ -0,0 +1,13 @@
import Long from 'long'
import { Client } from './Client.js'
export function formatAddress(address) {
const int = BigInt(address)
return int.toString(16).padStart(16, '0').match(/.{1,4}/g).join(':')
}
export function decodeAddress(address) {
return Long.fromString(BigInt('0x' + address.replace(/:/g, '')).toString(10))
}
export { Client }
Submodule
+1
Submodule src/protocol added at d0747faf68
+21
View File
@@ -0,0 +1,21 @@
import { resolve, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import webpack from 'webpack'
export default {
mode: process.env.NODE_ENV || 'production',
entry: './src/index.js',
output: {
library: {type:'module'},
filename: 'ppp2.js',
path: resolve(fileURLToPath(join(import.meta.url, '..')), 'dist')
},
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
})
],
experiments: {
outputModule: true
}
}