parent
6c6d046891
commit
4c1e566a6c
86 changed files with 12193 additions and 1004 deletions
@ -1,148 +0,0 @@ |
||||
// Constants
|
||||
let MIN_DISTANCE = 12; |
||||
let MAX_PER_GROUP = 3; |
||||
let NB_USERS = 10; |
||||
|
||||
// Utils
|
||||
let rand = function(min, max) { |
||||
min = Math.ceil(min); |
||||
max = Math.floor(max); |
||||
return Math.floor(Math.random() * (max - min + 1)) + min; |
||||
}; |
||||
|
||||
let compareDistances = function(distA, distB) { |
||||
if (distA.distance < distB.distance) { |
||||
return -1; |
||||
} |
||||
if (distA.distance > distB.distance) { |
||||
return 1; |
||||
} |
||||
return 0; |
||||
}; |
||||
|
||||
let computeDistance = function (user1, user2) { |
||||
return Math.sqrt(Math.pow(user2.X - user1.X, 2) + Math.pow(user2.Y - user1.Y, 2)); |
||||
}; |
||||
|
||||
// Test Data
|
||||
let users = []; |
||||
for(let i = 1; i <= NB_USERS; i++) { |
||||
let user = {}; |
||||
user.id = rand(0,99999); |
||||
user.X = rand(0, 40); |
||||
user.Y = rand(0, 40); |
||||
users.push(user); |
||||
} |
||||
|
||||
// Compute distance between each user
|
||||
let getDistanceOfEachUser = function(users) { |
||||
let i = 0; |
||||
let distances = []; |
||||
|
||||
users.forEach(function(user1, key1) { |
||||
users.forEach(function(user2, key2) { |
||||
if(key1 < key2) { |
||||
let distanceObj = {}; |
||||
distanceObj.distance = computeDistance(user1, user2); |
||||
distanceObj.first = user1; |
||||
distanceObj.second = user2; |
||||
|
||||
distances[i] = distanceObj; |
||||
i++; |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
return distances; |
||||
}; |
||||
|
||||
// Organise groups
|
||||
let createGroups = function(distances) { |
||||
let i = 0; |
||||
let groups = []; |
||||
let alreadyInAGroup = []; |
||||
|
||||
for(let j = 0; j < distances.length; j++) { |
||||
let dist = distances[j]; |
||||
|
||||
if(dist.distance <= MIN_DISTANCE) { |
||||
if(typeof groups[i] === 'undefined') { |
||||
groups[i] = []; |
||||
} |
||||
|
||||
if(groups[i].indexOf(dist.first) === -1 && typeof alreadyInAGroup[dist.first.id] === 'undefined') { |
||||
if(groups[i].length > 1) { |
||||
// if group is not empty we check current user can be added in the group according to its distance to the others already in it
|
||||
for(let l = 0; l < groups[i].length; l++) { |
||||
let userTotest = groups[i][l]; |
||||
if(computeDistance(dist.first, userTotest) <= MIN_DISTANCE) { |
||||
groups[i].push(dist.first); |
||||
alreadyInAGroup[dist.first.id] = true; |
||||
break; |
||||
} |
||||
} |
||||
} else { |
||||
groups[i].push(dist.first); |
||||
alreadyInAGroup[dist.first.id] = true; |
||||
} |
||||
} |
||||
|
||||
if(groups[i].length === MAX_PER_GROUP) { |
||||
i++; // on créé un nouveau groupe
|
||||
if(i > (NB_USERS / MAX_PER_GROUP)) { |
||||
console.log('There is no room left for user ID : ' + dist.second.id + ' !'); |
||||
break; |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
if(groups[i].indexOf(dist.second) === -1 && typeof alreadyInAGroup[dist.second.id] === 'undefined') { |
||||
if(groups[i].length > 1) { |
||||
// if group is not empty we check current user can be added in the group according to its distance to the others already in it
|
||||
for(let l = 0; l < groups[i].length; l++) { |
||||
let userTotest = groups[i][l]; |
||||
if(computeDistance(dist.second, userTotest) <= MIN_DISTANCE) { |
||||
groups[i].push(dist.second); |
||||
alreadyInAGroup[dist.second.id] = true; |
||||
break; |
||||
} |
||||
} |
||||
} else { |
||||
groups[i].push(dist.second); |
||||
alreadyInAGroup[dist.second.id] = true; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return groups; |
||||
}; |
||||
|
||||
let distances = getDistanceOfEachUser(users); |
||||
|
||||
// ordonner par distance pour prioriser l'association en groupe des utilisateurs les plus proches
|
||||
distances.sort(compareDistances); |
||||
|
||||
let groups = createGroups(distances); |
||||
|
||||
// Compute distance between each user of a already existing group
|
||||
let checkGroupDistance = function(groups) { |
||||
for(let i = 0; i < groups.length; i++) { |
||||
let group = groups[i]; |
||||
group.forEach(function(user1, key1) { |
||||
group.forEach(function(user2, key2) { |
||||
if(key1 < key2) { |
||||
let distance = computeDistance(user1, user2); |
||||
if(distance > MIN_DISTANCE) { |
||||
// TODO : message a user1 et user2
|
||||
} |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
}; |
||||
|
||||
console.log(users); |
||||
console.log(distances); |
||||
console.log(groups); |
||||
|
@ -1,3 +1,13 @@ |
||||
// lib/server.ts
|
||||
import App from "./src/App"; |
||||
App.listen(8080, () => console.log(`WorkAdventure starting on port 8080!`)) |
||||
import grpc from "grpc"; |
||||
import {roomManager} from "./src/RoomManager"; |
||||
import {IRoomManagerServer, RoomManagerService} from "./src/Messages/generated/messages_grpc_pb"; |
||||
|
||||
//App.listen(8080, () => console.log(`WorkAdventure starting on port 8080!`))
|
||||
|
||||
const server = new grpc.Server(); |
||||
server.addService<IRoomManagerServer>(RoomManagerService, roomManager); |
||||
|
||||
server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure()); |
||||
server.start(); |
||||
|
@ -0,0 +1,114 @@ |
||||
import {IRoomManagerServer} from "./Messages/generated/messages_grpc_pb"; |
||||
import { |
||||
ClientToServerMessage, ItemEventMessage, |
||||
JoinRoomMessage, PlayGlobalMessage, PusherToBackMessage, QueryJitsiJwtMessage, ReportPlayerMessage, |
||||
RoomJoinedMessage, |
||||
ServerToClientMessage, SilentMessage, UserMovesMessage, ViewportMessage, WebRtcSignalToServerMessage, ZoneMessage |
||||
} from "./Messages/generated/messages_pb"; |
||||
import grpc, {ServerWritableStream} from "grpc"; |
||||
import {Empty} from "google-protobuf/google/protobuf/empty_pb"; |
||||
import {socketManager} from "./Services/SocketManager"; |
||||
import {emitError} from "./Services/IoSocketHelpers"; |
||||
import {User, UserSocket} from "./Model/User"; |
||||
import {GameRoom} from "./Model/GameRoom"; |
||||
import Debug from "debug"; |
||||
|
||||
const debug = Debug('roommanager'); |
||||
|
||||
export type ZoneSocket = ServerWritableStream<ZoneMessage, ServerToClientMessage>; |
||||
|
||||
const roomManager: IRoomManagerServer = { |
||||
joinRoom: (call: UserSocket): void => { |
||||
console.log('joinRoom called'); |
||||
|
||||
let room: GameRoom|null = null; |
||||
let user: User|null = null; |
||||
|
||||
call.on('data', (message: PusherToBackMessage) => { |
||||
try { |
||||
if (room === null || user === null) { |
||||
if (message.hasJoinroommessage()) { |
||||
socketManager.handleJoinRoom(call, message.getJoinroommessage() as JoinRoomMessage).then(({room: gameRoom, user: myUser}) => { |
||||
room = gameRoom; |
||||
user = myUser; |
||||
}); |
||||
} else { |
||||
throw new Error('The first message sent MUST be of type JoinRoomMessage'); |
||||
} |
||||
} else { |
||||
if (message.hasJoinroommessage()) { |
||||
throw new Error('Cannot call JoinRoomMessage twice!'); |
||||
/*} else if (message.hasViewportmessage()) { |
||||
socketManager.handleViewport(client, message.getViewportmessage() as ViewportMessage);*/ |
||||
} else if (message.hasUsermovesmessage()) { |
||||
socketManager.handleUserMovesMessage(room, user, message.getUsermovesmessage() as UserMovesMessage); |
||||
/*} else if (message.hasSetplayerdetailsmessage()) { |
||||
socketManager.handleSetPlayerDetails(client, message.getSetplayerdetailsmessage() as SetPlayerDetailsMessage);*/ |
||||
} else if (message.hasSilentmessage()) { |
||||
socketManager.handleSilentMessage(room, user, message.getSilentmessage() as SilentMessage); |
||||
} else if (message.hasItemeventmessage()) { |
||||
socketManager.handleItemEvent(room, user, message.getItemeventmessage() as ItemEventMessage); |
||||
} else if (message.hasWebrtcsignaltoservermessage()) { |
||||
socketManager.emitVideo(room, user, message.getWebrtcsignaltoservermessage() as WebRtcSignalToServerMessage); |
||||
} else if (message.hasWebrtcscreensharingsignaltoservermessage()) { |
||||
socketManager.emitScreenSharing(room, user, message.getWebrtcscreensharingsignaltoservermessage() as WebRtcSignalToServerMessage); |
||||
} else if (message.hasPlayglobalmessage()) { |
||||
socketManager.emitPlayGlobalMessage(room, message.getPlayglobalmessage() as PlayGlobalMessage); |
||||
/*} else if (message.hasReportplayermessage()){ |
||||
socketManager.handleReportMessage(client, message.getReportplayermessage() as ReportPlayerMessage);*/ |
||||
} else if (message.hasQueryjitsijwtmessage()){ |
||||
socketManager.handleQueryJitsiJwtMessage(user, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage); |
||||
} else { |
||||
throw new Error('Unhandled message type'); |
||||
} |
||||
} |
||||
} catch (e) { |
||||
emitError(call, e); |
||||
call.end(); |
||||
} |
||||
|
||||
}); |
||||
|
||||
call.on('end', () => { |
||||
debug('joinRoom ended'); |
||||
if (user !== null && room !== null) { |
||||
socketManager.leaveRoom(room, user); |
||||
} |
||||
call.end(); |
||||
room = null; |
||||
user = null; |
||||
}); |
||||
|
||||
call.on('error', (err: Error) => { |
||||
console.error('An error occurred in joinRoom stream:', err); |
||||
}); |
||||
|
||||
}, |
||||
|
||||
listenZone(call: ZoneSocket): void { |
||||
debug('listenZone called'); |
||||
const zoneMessage = call.request; |
||||
|
||||
socketManager.addZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY()); |
||||
|
||||
call.on('cancelled', () => { |
||||
debug('listenZone cancelled'); |
||||
socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY()); |
||||
call.end(); |
||||
}) |
||||
|
||||
/*call.on('finish', () => { |
||||
debug('listenZone finish'); |
||||
})*/ |
||||
call.on('close', () => { |
||||
debug('listenZone connection closed'); |
||||
socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY()); |
||||
}).on('error', (e) => { |
||||
console.error('An error occurred in listenZone stream:', e); |
||||
socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY()); |
||||
call.end(); |
||||
}); |
||||
}, |
||||
}; |
||||
|
||||
export {roomManager}; |