@lanmower/entrypoint 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +250 -0
- package/apps/environment/index.js +17 -0
- package/apps/interactive-door/index.js +33 -0
- package/apps/patrol-npc/index.js +37 -0
- package/apps/physics-crate/index.js +23 -0
- package/apps/power-crate/index.js +169 -0
- package/apps/tps-game/index.js +168 -0
- package/apps/tps-game/schwust.glb +0 -0
- package/apps/world/index.js +22 -0
- package/client/app.js +181 -0
- package/client/camera.js +116 -0
- package/client/index.html +24 -0
- package/client/style.css +11 -0
- package/package.json +52 -0
- package/server.js +3 -0
- package/src/apps/AppContext.js +172 -0
- package/src/apps/AppLoader.js +160 -0
- package/src/apps/AppRuntime.js +192 -0
- package/src/apps/EventBus.js +62 -0
- package/src/apps/HotReloadQueue.js +63 -0
- package/src/client/InputHandler.js +85 -0
- package/src/client/PhysicsNetworkClient.js +171 -0
- package/src/client/PredictionEngine.js +123 -0
- package/src/client/ReconciliationEngine.js +54 -0
- package/src/connection/ConnectionManager.js +133 -0
- package/src/connection/QualityMonitor.js +46 -0
- package/src/connection/SessionStore.js +67 -0
- package/src/debug/CliDebugger.js +93 -0
- package/src/debug/Inspector.js +52 -0
- package/src/debug/StateInspector.js +42 -0
- package/src/index.client.js +8 -0
- package/src/index.js +1 -0
- package/src/index.server.js +27 -0
- package/src/math.js +21 -0
- package/src/netcode/EventLog.js +74 -0
- package/src/netcode/LagCompensator.js +78 -0
- package/src/netcode/NetworkState.js +66 -0
- package/src/netcode/PhysicsIntegration.js +132 -0
- package/src/netcode/PlayerManager.js +109 -0
- package/src/netcode/SnapshotEncoder.js +49 -0
- package/src/netcode/TickSystem.js +66 -0
- package/src/physics/GLBLoader.js +29 -0
- package/src/physics/World.js +195 -0
- package/src/protocol/Codec.js +60 -0
- package/src/protocol/EventEmitter.js +60 -0
- package/src/protocol/MessageTypes.js +73 -0
- package/src/protocol/SequenceTracker.js +71 -0
- package/src/protocol/msgpack.js +119 -0
- package/src/sdk/ClientMessageHandler.js +80 -0
- package/src/sdk/ReloadHandlers.js +68 -0
- package/src/sdk/ReloadManager.js +126 -0
- package/src/sdk/ServerAPI.js +133 -0
- package/src/sdk/ServerHandlers.js +76 -0
- package/src/sdk/StaticHandler.js +32 -0
- package/src/sdk/TickHandler.js +84 -0
- package/src/sdk/client.js +122 -0
- package/src/sdk/server.js +184 -0
- package/src/shared/movement.js +69 -0
- package/src/spatial/Octree.js +91 -0
- package/src/stage/Stage.js +90 -0
- package/src/stage/StageLoader.js +95 -0
- package/src/storage/FSAdapter.js +56 -0
- package/src/storage/StorageAdapter.js +7 -0
- package/src/transport/TransportWrapper.js +25 -0
- package/src/transport/WebSocketTransport.js +55 -0
- package/src/transport/WebTransportServer.js +83 -0
- package/src/transport/WebTransportTransport.js +94 -0
- package/world/kaira.glb +0 -0
- package/world/schwust.glb +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export class StorageAdapter {
|
|
2
|
+
async get(key) { throw new Error('not implemented') }
|
|
3
|
+
async set(key, value) { throw new Error('not implemented') }
|
|
4
|
+
async delete(key) { throw new Error('not implemented') }
|
|
5
|
+
async list(prefix) { throw new Error('not implemented') }
|
|
6
|
+
async has(key) { throw new Error('not implemented') }
|
|
7
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EventEmitter } from '../protocol/EventEmitter.js'
|
|
2
|
+
|
|
3
|
+
export class TransportWrapper extends EventEmitter {
|
|
4
|
+
constructor() {
|
|
5
|
+
super()
|
|
6
|
+
this.type = 'base'
|
|
7
|
+
this.ready = false
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
get isOpen() {
|
|
11
|
+
return this.ready
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
send(data) {
|
|
15
|
+
throw new Error('send() not implemented')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
sendUnreliable(data) {
|
|
19
|
+
return this.send(data)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
close() {
|
|
23
|
+
this.ready = false
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { TransportWrapper } from './TransportWrapper.js'
|
|
2
|
+
|
|
3
|
+
export class WebSocketTransport extends TransportWrapper {
|
|
4
|
+
constructor(socket) {
|
|
5
|
+
super()
|
|
6
|
+
this.type = 'websocket'
|
|
7
|
+
this.socket = socket
|
|
8
|
+
this.ready = socket.readyState === 1
|
|
9
|
+
|
|
10
|
+
socket.on('message', (data) => {
|
|
11
|
+
this.emit('message', data)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
socket.on('close', () => {
|
|
15
|
+
this.ready = false
|
|
16
|
+
this.emit('close')
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
socket.on('error', (err) => {
|
|
20
|
+
this.ready = false
|
|
21
|
+
this.emit('error', err)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
if (!this.ready) {
|
|
25
|
+
socket.on('open', () => {
|
|
26
|
+
this.ready = true
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get isOpen() {
|
|
32
|
+
return this.socket.readyState === 1
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
send(data) {
|
|
36
|
+
if (this.socket.readyState !== 1) return false
|
|
37
|
+
try {
|
|
38
|
+
this.socket.send(data)
|
|
39
|
+
return true
|
|
40
|
+
} catch (e) {
|
|
41
|
+
return false
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
sendUnreliable(data) {
|
|
46
|
+
return this.send(data)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
close() {
|
|
50
|
+
super.close()
|
|
51
|
+
if (this.socket.readyState === 1) {
|
|
52
|
+
this.socket.close()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
2
|
+
import { createRequire } from 'node:module'
|
|
3
|
+
import { EventEmitter } from '../protocol/EventEmitter.js'
|
|
4
|
+
import { WebTransportTransport } from './WebTransportTransport.js'
|
|
5
|
+
|
|
6
|
+
let Http3Server = null
|
|
7
|
+
let nativeAvailable = false
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
const require = createRequire(import.meta.url)
|
|
11
|
+
const quichePath = require.resolve('@fails-components/webtransport-transport-http3-quiche')
|
|
12
|
+
const nativePath = quichePath.replace(/lib[/\\]index\.js$/, 'build/Release/webtransport.node')
|
|
13
|
+
if (existsSync(nativePath)) {
|
|
14
|
+
const mod = await import('@fails-components/webtransport')
|
|
15
|
+
Http3Server = mod.Http3Server
|
|
16
|
+
nativeAvailable = true
|
|
17
|
+
}
|
|
18
|
+
} catch (e) {}
|
|
19
|
+
|
|
20
|
+
export const WEBTRANSPORT_AVAILABLE = nativeAvailable
|
|
21
|
+
|
|
22
|
+
export class WebTransportServer extends EventEmitter {
|
|
23
|
+
constructor(options = {}) {
|
|
24
|
+
super()
|
|
25
|
+
this.port = options.port || 4433
|
|
26
|
+
this.cert = options.cert || null
|
|
27
|
+
this.key = options.key || null
|
|
28
|
+
this.server = null
|
|
29
|
+
this.running = false
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async start() {
|
|
33
|
+
if (!nativeAvailable || !Http3Server) {
|
|
34
|
+
console.log('[webtransport] Native binary not available, skipping')
|
|
35
|
+
return false
|
|
36
|
+
}
|
|
37
|
+
if (!this.cert || !this.key) {
|
|
38
|
+
console.log('[webtransport] TLS cert/key not provided, skipping')
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
this.server = new Http3Server({
|
|
43
|
+
port: this.port,
|
|
44
|
+
host: '0.0.0.0',
|
|
45
|
+
secret: 'changeit',
|
|
46
|
+
cert: this.cert,
|
|
47
|
+
privKey: this.key
|
|
48
|
+
})
|
|
49
|
+
this.server.startServer()
|
|
50
|
+
this.running = true
|
|
51
|
+
this._acceptSessions()
|
|
52
|
+
return true
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.error('[webtransport] Failed to start:', e.message)
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async _acceptSessions() {
|
|
60
|
+
const sessionStream = await this.server.sessionStream('/')
|
|
61
|
+
const reader = sessionStream.getReader()
|
|
62
|
+
while (this.running) {
|
|
63
|
+
try {
|
|
64
|
+
const { value, done } = await reader.read()
|
|
65
|
+
if (done) break
|
|
66
|
+
if (value) {
|
|
67
|
+
const transport = new WebTransportTransport(value)
|
|
68
|
+
this.emit('session', transport)
|
|
69
|
+
}
|
|
70
|
+
} catch (e) {
|
|
71
|
+
if (this.running) console.error('[webtransport] Session error:', e.message)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
stop() {
|
|
77
|
+
this.running = false
|
|
78
|
+
if (this.server) {
|
|
79
|
+
try { this.server.destroy() } catch (e) {}
|
|
80
|
+
this.server = null
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { TransportWrapper } from './TransportWrapper.js'
|
|
2
|
+
|
|
3
|
+
export class WebTransportTransport extends TransportWrapper {
|
|
4
|
+
constructor(session) {
|
|
5
|
+
super()
|
|
6
|
+
this.type = 'webtransport'
|
|
7
|
+
this.session = session
|
|
8
|
+
this.ready = true
|
|
9
|
+
this.reliableWriter = null
|
|
10
|
+
this.reliableReader = null
|
|
11
|
+
this._closed = false
|
|
12
|
+
this._init()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async _init() {
|
|
16
|
+
try {
|
|
17
|
+
await this._setupReliableStream()
|
|
18
|
+
this._readDatagrams()
|
|
19
|
+
} catch (e) {
|
|
20
|
+
this._handleClose()
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async _setupReliableStream() {
|
|
25
|
+
const stream = await this.session.createBidirectionalStream()
|
|
26
|
+
this.reliableWriter = stream.writable.getWriter()
|
|
27
|
+
this.reliableReader = stream.readable.getReader()
|
|
28
|
+
this._readReliableStream()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async _readReliableStream() {
|
|
32
|
+
try {
|
|
33
|
+
while (!this._closed) {
|
|
34
|
+
const { value, done } = await this.reliableReader.read()
|
|
35
|
+
if (done) break
|
|
36
|
+
if (value) this.emit('message', value)
|
|
37
|
+
}
|
|
38
|
+
} catch (e) {
|
|
39
|
+
if (!this._closed) this._handleClose()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async _readDatagrams() {
|
|
44
|
+
try {
|
|
45
|
+
const reader = this.session.datagrams.readable.getReader()
|
|
46
|
+
while (!this._closed) {
|
|
47
|
+
const { value, done } = await reader.read()
|
|
48
|
+
if (done) break
|
|
49
|
+
if (value) this.emit('message', value)
|
|
50
|
+
}
|
|
51
|
+
} catch (e) {
|
|
52
|
+
if (!this._closed) this._handleClose()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
_handleClose() {
|
|
57
|
+
if (this._closed) return
|
|
58
|
+
this._closed = true
|
|
59
|
+
this.ready = false
|
|
60
|
+
this.emit('close')
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get isOpen() {
|
|
64
|
+
return this.ready && !this._closed
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
send(data) {
|
|
68
|
+
if (!this.isOpen || !this.reliableWriter) return false
|
|
69
|
+
try {
|
|
70
|
+
this.reliableWriter.write(data)
|
|
71
|
+
return true
|
|
72
|
+
} catch (e) {
|
|
73
|
+
return false
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
sendUnreliable(data) {
|
|
78
|
+
if (!this.isOpen) return false
|
|
79
|
+
try {
|
|
80
|
+
const writer = this.session.datagrams.writable.getWriter()
|
|
81
|
+
writer.write(data)
|
|
82
|
+
writer.releaseLock()
|
|
83
|
+
return true
|
|
84
|
+
} catch (e) {
|
|
85
|
+
return this.send(data)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
close() {
|
|
90
|
+
super.close()
|
|
91
|
+
this._closed = true
|
|
92
|
+
try { this.session.close() } catch (e) {}
|
|
93
|
+
}
|
|
94
|
+
}
|
package/world/kaira.glb
ADDED
|
Binary file
|
|
Binary file
|