Skip to content

Commit c426146

Browse files
Improve networking entity client
1 parent 9127926 commit c426146

File tree

8 files changed

+201
-51
lines changed

8 files changed

+201
-51
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import playerPosition from "./player-position.mjs"
2+
3+
class EntityRepository {
4+
constructor() {
5+
// entity-id, entity
6+
this.entities = new Map();
7+
this.streamedInEntities = new Map();
8+
this.streamingWorker = new Worker('streaming-worker.mjs');
9+
playerPosition.update = (position) => {
10+
this.updateWorker();
11+
};
12+
this.streamingWorker.onmessage = event => {
13+
if (event.streamIn) {
14+
this.addStreamedInEntity(event.streamIn);
15+
//TODO: send event to server
16+
} else if (event.streamOut) {
17+
this.removeStreamedInEntity(event.streamOut);
18+
//TODO: send event to server
19+
}
20+
};
21+
}
22+
23+
getEntities() {
24+
return this.entities.values();
25+
}
26+
27+
getStreamedInEntities() {
28+
return this.streamedInEntities;
29+
}
30+
31+
setEntities(entities) {
32+
let newEntities = new Map();
33+
for (const entity of entities) {
34+
newEntities.set(entity.id, entity);
35+
}
36+
this.entities = newEntities;
37+
this.updateWorker();
38+
}
39+
40+
addStreamedInEntity(entity) {
41+
this.streamedInEntities.set(entity.id, entity);
42+
this.updateWorker();
43+
}
44+
45+
removeStreamedInEntity(entity) {
46+
this.streamedInEntities.delete(entity.id);
47+
this.updateWorker();
48+
}
49+
50+
updateWorker() {
51+
this.streamingWorker.postMessage({
52+
position: playerPosition.getPosition(),
53+
entities: this.entities,
54+
streamedIn: this.streamedInEntities
55+
})
56+
}
57+
}
58+
59+
export default new EntityRepository();

api/AltV.Net.NetworkingEntity/Client/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<script src='deps/reconnecting-websocket.min.js'></script>
55
<script src='deps/protobuf.min.js'></script>
6-
<script src='networking-entity.js'></script>
6+
<script type="module" src="networking-entity.mjs"></script>
77
<meta charset="UTF-8">
88
<title>networking-entity</title>
99
</head>

api/AltV.Net.NetworkingEntity/Client/networking-entity.js

Lines changed: 0 additions & 50 deletions
This file was deleted.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import "./websocket.mjs";
2+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class PlayerPosition {
2+
constructor() {
3+
this.position = {x: 0, y: 0, z: 0};
4+
this.update = null;
5+
try {
6+
alt.on("playerPosition", (x, y, z) => {
7+
this.position.x = x;
8+
this.position.y = y;
9+
this.position.z = z;
10+
if (this.update) {
11+
this.update(this.position);
12+
}
13+
})
14+
} catch (e) {
15+
console.log(e);
16+
}
17+
}
18+
19+
getPosition() {
20+
return this.position;
21+
}
22+
}
23+
24+
export default new PlayerPosition();
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
class Proto {
2+
3+
constructor() {
4+
// List of promises waiting for protoBuf to finish indexing
5+
this.protoBufGets = [];
6+
this.proto = null;
7+
8+
protobuf.load("entity.proto", (err, root) => {
9+
if (err)
10+
throw err;
11+
this.proto = {
12+
Position: root.lookupType("Entity.Position"),
13+
ClientEvent: root.lookupType("Entity.ClientEvent"),
14+
ServerEvent: root.lookupType("Entity.ServerEvent"),
15+
AuthEvent: root.lookupType("Entity.AuthEvent"),
16+
EntityStreamInEvent: root.lookupType("Entity.EntityStreamInEvent"),
17+
EntityStreamOutEvent: root.lookupType("Entity.EntityStreamOutEvent")
18+
};
19+
for (const get of this.protoBufGets) {
20+
get(this.proto);
21+
}
22+
});
23+
24+
this.executor = this.executor.bind(this);
25+
this.getProto = this.getProto.bind(this);
26+
this.getValue = this.getValue.bind(this);
27+
}
28+
29+
getProto() {
30+
return new Promise(this.executor);
31+
}
32+
33+
getValue() {
34+
return this.proto;
35+
}
36+
37+
executor(resolve, reject) {
38+
if (this.proto != null) {
39+
resolve(this.proto);
40+
} else {
41+
this.protoBufGets.push(resolve);
42+
}
43+
}
44+
}
45+
46+
export default new Proto();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
onmessage = function (e) {
2+
let data = e.data;
3+
if (data.position) {
4+
this.position = data.position;
5+
}
6+
if (data.entities) {
7+
this.entities = data.entities;
8+
}
9+
if (data.streamedIn) {
10+
this.streamedIn = data.streamedIn;
11+
}
12+
console.log("execute worker", this.position, this.entities, this.streamedIn);
13+
start(this.position, this.entities, this.streamedIn);
14+
};
15+
16+
function distance(v1, v2) {
17+
const dx = v1.x - v2.x;
18+
const dy = v1.y - v2.y;
19+
const dz = v1.z - v2.z;
20+
21+
return Math.sqrt(dx * dx + dy * dy + dz * dz);
22+
}
23+
24+
function start(position, entities, streamedIn) {
25+
for (const [id, entity] of entities) {
26+
if (!streamedIn.has(id)) {
27+
if (distance(entity.position, position) <= entity.range) {
28+
postMessage({streamIn: entity});
29+
}
30+
}
31+
}
32+
for (const [_, entity] of streamedIn) {
33+
if (distance(entity.position, position) > entity.range) {
34+
postMessage({streamOut: entity});
35+
}
36+
}
37+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import entitiesRepository from "./entity-repository.mjs";
2+
import proto from "./proto.mjs";
3+
4+
class WebSocket {
5+
constructor() {
6+
this.connection = new ReconnectingWebSocket('ws://localhost:46429');
7+
this.connection.binaryType = 'arraybuffer';
8+
this.connection.onopen = () => {
9+
proto.getProto().then((proto) => {
10+
const authEvent = proto.AuthEvent.create({token: "123"});
11+
const clientEvent = proto.ClientEvent.create({auth: authEvent});
12+
const buffer = proto.ClientEvent.encode(clientEvent).finish();
13+
this.connection.send(buffer);
14+
});
15+
};
16+
17+
this.connection.onerror = (error) => {
18+
console.log("err", error);
19+
};
20+
21+
this.connection.onmessage = async (e) => {
22+
const serverEvent = proto.getValue().ServerEvent.decode(new Uint8Array(await new Response(e.data).arrayBuffer()));
23+
if (serverEvent.send != null) {
24+
const entities = serverEvent.send.entities;
25+
entitiesRepository.setEntities(entities);
26+
}
27+
console.log('event', serverEvent);
28+
};
29+
}
30+
}
31+
32+
export default new WebSocket();

0 commit comments

Comments
 (0)