content/hifi-content/Experiences/Releases/usefulUtilities/botinator/2019-03-30_22-37-48/assignmentClientManager.js
2022-02-13 23:16:46 +01:00

398 lines
12 KiB
JavaScript

//
//
// Botinator
// assignmentClientManager.js
// Created by Milad Nazeri on 2019-03-28
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
// Manages the differnt ac scripts needed
//
//
(function() {
// *************************************
// START UTILITY FUNCTIONS
// *************************************
// #region UTILITY FUNCTIONS
// Use a ring to cycle through the list for as many unique recordings as are available
function findValue(index, array, offset) {
offset = offset || 0;
return array[(index + offset) % array.length];
}
// Random Float helper for the location
function randFloat(low, high) {
return low + Math.random() * (high - low);
}
// Get a random location based on the user's desired min and max range.
function getRandomLocation(contentBoundaryCorners) {
contentBoundaryCorners = fixupContentBoundaryCorners(contentBoundaryCorners);
return {
x: randFloat(contentBoundaryCorners[0].x, contentBoundaryCorners[1].x),
y: randFloat(contentBoundaryCorners[0].y, contentBoundaryCorners[1].y),
z: randFloat(contentBoundaryCorners[0].z, contentBoundaryCorners[1].z)
};
}
// Stop all the bots currently playing
function stopAllBots() {
availableAssignmentClientPlayers.forEach(function(ac) {
ac.stop();
});
botCount = 0;
isPlaying = false;
}
// Update all the current positions for the bots
function updateAllBotsPosition() {
availableAssignmentClientPlayers.forEach(function(ac) {
var position = getRandomLocation(contentBoundaryCorners);
ac.setPosition(position);
});
}
// Update all the current volumes for the bots
function updateAllBotsVolume() {
availableAssignmentClientPlayers.forEach(function(ac) {
ac.setVolume(volume);
});
}
// Start playing sequence to fill players with bots
var AC_AVAILABILITY_CHECK_MS = 1000;
function startSequence() {
// Check to see how many bots are needed
if (botCount >= totalNumberOfBotsNeeded) {
return;
}
if (botCount < availableAssignmentClientPlayers.length) {
var player = availableAssignmentClientPlayers[botCount];
player.play();
botCount++;
if (botCount >= totalNumberOfBotsNeeded) {
return;
}
}
Script.setTimeout(function() {
startSequence();
}, AC_AVAILABILITY_CHECK_MS);
}
// The following borrowed from Zach's push preventer script
// A utility function used to ensure that all of the values in "box corner 1" are less than
// those in "box corner 2"
function maybeSwapCorners(contentBoundaryCorners, dimension) {
var temp;
if (contentBoundaryCorners[0][dimension] > contentBoundaryCorners[1][dimension]) {
temp = contentBoundaryCorners[0][dimension];
contentBoundaryCorners[0][dimension] = contentBoundaryCorners[1][dimension];
contentBoundaryCorners[1][dimension] = temp;
}
return [contentBoundaryCorners[0][dimension], contentBoundaryCorners[1][dimension]];
}
// Ensures that all of the values in "box corner 1" are less than those in "box corner 2".
function fixupContentBoundaryCorners(contentBoundaryCorners) {
var x = maybeSwapCorners(contentBoundaryCorners, "x");
var y = maybeSwapCorners(contentBoundaryCorners, "y");
var z = maybeSwapCorners(contentBoundaryCorners, "z");
return [
{x: x[0], y: y[0], z: z[0]},
{x: x[1], y: y[1], z: z[1]}
];
}
// #endregion
// *************************************
// END UTILITY FUNCTIONS
// *************************************
// *************************************
// START CONSTS_AND_VARS
// *************************************
// #region CONSTS_AND_VARS
var X = 0;
var Y = 1;
var Z = 2;
// List of possible bots to use
var BOTS = Script.require("./botsToLoad.js");
// The Assignment Client channel
var ASSIGNMENT_MANAGER_CHANNEL = "ASSIGNMENT_MANAGER_CHANNEL";
var ASSIGNMENT_CLIENT_MESSANGER_CHANNEL = "ASSIGNMENT_CLIENT_MESSANGER_CHANNEL";
// Array of the assignment client players and their assignment client player object
var availableAssignmentClientPlayers = [];
// Total number of bots needed
var totalNumberOfBotsNeeded = 0;
// Current playing bot count we are at
var botCount = 0;
// Current registered bount count
var botRegisterdCount = 0;
// Range to pull the random location from
var contentBoundaryCorners = [{x: 0, y: 0, z: 0}, {x: 0, y: 0, z: 0}];
// Check for if currently running
var isPlaying = false;
// Volume the bots should play at
var volume = 1.0;
// #endregion
// *************************************
// END CONSTS_AND_VARS
// *************************************
// *************************************
// START ASSIGNMENT_CLIENT_PLAYER
// *************************************
// #region ASSIGNMENT_CLIENT_PLAYER
// Individual AssignmentClientPlayerObject
function AssignmentClientPlayerObject(uuid, fileToPlay, position, volume) {
this.uuid = uuid;
this.fileToPlay = fileToPlay;
this.position = position;
this.volume = volume;
}
// Sets the position to play this bot at
function setPosition(position) {
this.position = position;
}
// Sets the volume to play this bot at
function setVolume(volume) {
this.volume = volume;
}
// Play the current clip
function play() {
Messages.sendMessage(ASSIGNMENT_MANAGER_CHANNEL, JSON.stringify({
action: "PLAY",
fileToPlay: this.fileToPlay,
position: this.position,
uuid: this.uuid,
volume: this.volume
}));
}
// Stop the current clip
function stop() {
Messages.sendMessage(ASSIGNMENT_MANAGER_CHANNEL, JSON.stringify({
action: "STOP",
uuid: this.uuid
}));
}
AssignmentClientPlayerObject.prototype = {
setPosition: setPosition,
play: play,
setVolume: setVolume,
stop: stop
};
// #endregion
// *************************************
// END ASSIGNMENT_CLIENT_PLAYER
// *************************************
// *************************************
// START MESSAGES
// *************************************
// #region MESSAGES
// Handle Messages received
function onMangerChannelMessageReceived(channel, message, sender) {
if (channel !== ASSIGNMENT_MANAGER_CHANNEL || sender === Agent.sessionUUID) {
return;
}
try {
message = JSON.parse(message);
} catch (error) {
console.log("invalid object");
console.log("MESSAGE:", message);
return;
}
switch (message.action) {
case "REGISTER_ME":
var fileName = findValue(botRegisterdCount, BOTS);
var position = getRandomLocation(contentBoundaryCorners);
availableAssignmentClientPlayers.push(
new AssignmentClientPlayerObject(message.uuid, fileName, position, volume));
botRegisterdCount++;
var messageToSend = JSON.stringify({
action: "AC_AVAILABLE_UPDATE",
newAvailableACs: availableAssignmentClientPlayers.length
});
Messages.sendMessage(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL, messageToSend);
break;
case "ARE_YOU_THERE_MANAGER_ITS_ME_BOT":
Messages.sendMessage(ASSIGNMENT_MANAGER_CHANNEL, JSON.stringify({
action: "REGISTER_MANAGER",
uuid: sender
}));
break;
default:
console.log("unrecongized action in assignmentClientManger.js");
break;
}
}
function onTabletChannelMessageReceived(channel, message, sender) {
try {
message = JSON.parse(message);
} catch (error) {
console.log("invalid object");
console.log(error);
return;
}
if (channel !== ASSIGNMENT_CLIENT_MESSANGER_CHANNEL || sender === Agent.sessionUUID) {
return;
}
switch (message.action) {
case "SEND_DATA":
if (isPlaying) {
stopAllBots();
isPlaying = false;
}
if (JSON.stringify(contentBoundaryCorners) !==
JSON.stringify(message.contentBoundaryCorners)) {
contentBoundaryCorners = message.contentBoundaryCorners;
updateAllBotsPosition();
}
if (volume !== message.volume) {
volume = message.volume;
updateAllBotsVolume();
}
totalNumberOfBotsNeeded = message.totalNumberOfBotsNeeded;
break;
case "PLAY":
if (isPlaying) {
return;
}
isPlaying = true;
startSequence();
break;
case "STOP":
if (isPlaying) {
stopAllBots();
}
break;
case "GET_MANAGER_STATUS":
var messageToSend = JSON.stringify({
action: "GET_MANAGER_STATUS",
newAvailableACs: availableAssignmentClientPlayers.length,
isPlaying: isPlaying
});
Messages.sendMessage(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL, messageToSend);
break;
default:
console.log("unrecongized action in assignmentClientManger.js");
break;
}
}
// #endregion
// *************************************
// END MESSAGES
// *************************************
// *************************************
// START MAIN
// *************************************
// #region MAIN
// Startup for the manager when it comes online
function startUp() {
Messages.subscribe(ASSIGNMENT_MANAGER_CHANNEL);
Messages.subscribe(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL);
Messages.messageReceived.connect(onMangerChannelMessageReceived);
Messages.messageReceived.connect(onTabletChannelMessageReceived);
Script.scriptEnding.connect(onEnding);
}
startUp();
// #endregion
// *************************************
// END MAIN
// *************************************
// *************************************
// START CLEANUP
// *************************************
// #region CLEANUP
// Cleanup the manager and it's messages
function onEnding() {
Messages.messageReceived.disconnect(onMangerChannelMessageReceived);
Messages.messageReceived.disconnect(onTabletChannelMessageReceived);
var messageToSend = JSON.stringify({
action: "GET_MANAGER_STATUS",
newAvailableACs: 0,
isPlaying: false,
closeTablet: true
});
Messages.sendMessage(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL, messageToSend);
Messages.unsubscribe(ASSIGNMENT_MANAGER_CHANNEL);
Messages.unsubscribe(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL);
}
// #endregion
// *************************************
// END CLEANUP
// *************************************
})();