398 lines
12 KiB
JavaScript
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
|
|
// *************************************
|
|
|
|
})();
|
|
|