You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
4.7 KiB

2 years ago
import * as des from './deserializer';
import * as send from './send';
import * as math from './math';
import * as storage from './storage';
import * as config from './config';
2 years ago
import { SESSION, MESSAGE, EVENT } from './enums';
import { sessions, desks, queries } from './storage';
2 years ago
// Session ACKed events up to SN
function recv_ack(d, session) {
const sn = des.u32(d);
session.state = SESSION.READY;
session.sn = sn;
session.sync_attempts = 0;
2 years ago
if (config.DEBUG_PRINT) console.log(`ack ${sn} in`);
2 years ago
}
async function recv_syn(d, session) {
const lsn = des.u32(d);
const count = des.u32(d);
if (config.DEBUG_PRINT) console.log(`syn ${lsn} in, total size = ${d.size}`);
2 years ago
const we_expect = lsn - session.lsn;
const first = count - we_expect;
const events = [];
if (config.DEBUG_PRINT) console.log(`we expect ${we_expect}, count ${count}`);
2 years ago
for (let i = 0; i < count; ++i) {
const event = des.event(d);
if (i >= first) {
event.desk_id = session.desk_id;
event.user_id = session.id;
2 years ago
handle_event(session, event);
events.push(event);
}
}
2 years ago
desks[session.desk_id].sn += we_expect;
desks[session.desk_id].events.push(...events);
session.lsn = lsn;
storage.queries.update_desk_sn.run({
'$id': session.desk_id,
'$sn': desks[session.desk_id].sn
});
storage.queries.update_session_lsn.run({
'$id': session.id,
'$lsn': lsn
});
12 months ago
2 years ago
send.send_ack(session.ws, lsn);
send.sync_desk(session.desk_id);
}
function recv_fire(d, session) {
const event = des.event(d);
event.user_id = session.id;
switch (event.type) {
case EVENT.SET_COLOR: {
session.color = event.color;
storage.queries.update_session_color.run({
'$id': session.id,
'$color': event.color
});
break;
}
case EVENT.SET_WIDTH: {
session.width = event.width;
storage.queries.update_session_width.run({
'$id': session.id,
'$width': event.width
});
break;
}
}
send.fire_event(session, event);
2 years ago
}
function recv_follow(d, session) {
const user_id = des.u32(d);
if (config.DEBUG_PRINT) console.log(`follow ${user_id} in`);
if (user_id === 4294967295) {
// unfollow
session.follow = null;
} else {
// follow
session.follow = user_id;
}
}
function handle_event(session, event) {
switch (event.type) {
case EVENT.STROKE: {
const stroke_result = storage.queries.insert_stroke.get({
'$width': event.width,
'$color': event.color,
'$points': event.points,
'$pressures': event.pressures,
});
event.stroke_id = stroke_result.id;
storage.queries.insert_event.run({
'$type': event.type,
'$desk_id': session.desk_id,
'$session_id': session.id,
'$stroke_id': event.stroke_id,
'$image_id': 0,
'$x': 0,
'$y': 0,
});
desks[session.desk_id].total_points += event.points.length;
break;
}
case EVENT.ERASER:
case EVENT.IMAGE:
case EVENT.IMAGE_MOVE:
case EVENT.UNDO: {
storage.queries.insert_event.run({
'$type': event.type,
'$desk_id': session.desk_id,
'$session_id': session.id,
'$stroke_id': event.stroke_id || 0,
'$image_id': event.image_id || 0,
'$x': event.x || 0,
'$y': event.y || 0,
});
break;
}
default: {
console.error('fuck');
console.trace();
process.exit(1);
}
}
}
2 years ago
export async function handle_message(ws, d) {
if (!(ws.data.session_id in sessions)) {
return;
}
const session = sessions[ws.data.session_id];
const desk_id = session.desk_id;
const message_type = des.u32(d);
2 years ago
switch (message_type) {
case MESSAGE.FIRE: {
recv_fire(d, session);
break;
}
case MESSAGE.SYN: {
recv_syn(d, session);
break;
}
case MESSAGE.ACK: {
recv_ack(d, session);
break;
}
case MESSAGE.FOLLOW: {
recv_follow(d, session);
break;
}
2 years ago
default: {
console.error('fuck');
console.trace();
process.exit(1);
}
}
}