281 lines
12 KiB
JavaScript
281 lines
12 KiB
JavaScript
/* globals WELCOME_WAGON_OPTIONS */
|
|
|
|
/**
|
|
* @type WELCOME_WAGON_OPTIONS
|
|
* @property {string|undefined} DOMAIN_ID
|
|
* @property {string|undefined} SEARCH_ID
|
|
* @property {string|undefined} DISPLAY_NAME
|
|
* @property {Vec3Type|undefined} SEARCH_AREA
|
|
* @property {string|undefined} ACTIVE_WELCOME_WAGON_JSON
|
|
* @property {string|undefined} DISABLED_WELCOME_WAGON_JSON
|
|
* @property {string|undefined} PLATFORM_NAME
|
|
* @property {string|undefined} WELCOME_WAGON_CHANNEL
|
|
* @property {string|undefined} MODULES_PATH
|
|
*/
|
|
|
|
/** @const {number} */
|
|
var VERSION = 1.04;
|
|
|
|
// TODO: replace with http://content.highfidelity.com once stable.
|
|
/** @const {string} */
|
|
var WELCOME_WAGON_FOLDER = 'http://hifi-content.s3.amazonaws.com/DomainContent/production/welcomeWagon/';
|
|
|
|
/** @const {string} */
|
|
var DOMAIN_ID = WELCOME_WAGON_OPTIONS.DOMAIN_ID !== undefined ? WELCOME_WAGON_OPTIONS.DOMAIN_ID : location.domainId;
|
|
|
|
/** @const {string} */
|
|
var ROTATING_DOMAIN = WELCOME_WAGON_OPTIONS.ROTATING_DOMAIN !== undefined ? WELCOME_WAGON_OPTIONS.ROTATING_DOMAIN :
|
|
'WelcomeWagon';
|
|
|
|
/** @const {Vec3Type} */
|
|
var SEARCH_CENTER = WELCOME_WAGON_OPTIONS.SEARCH_CENTER !== undefined ? WELCOME_WAGON_OPTIONS.SEARCH_CENTER : {x: 19.2, y: 0.1, z: -135.6};
|
|
var SEARCH_AREA = WELCOME_WAGON_OPTIONS.SEARCH_AREA !== undefined ? WELCOME_WAGON_OPTIONS.SEARCH_AREA : 60000; // search area (sphere) in meters radius
|
|
|
|
var DISPLAY_NAME = WELCOME_WAGON_OPTIONS.DISPLAY_NAME !== undefined ? WELCOME_WAGON_OPTIONS.DISPLAY_NAME : 'WelcomeWagon [BOT]';
|
|
|
|
var ACTIVE_WELCOME_WAGON_JSON = WELCOME_WAGON_OPTIONS.ACTIVE_WELCOME_WAGON_JSON !== undefined ?
|
|
WELCOME_WAGON_OPTIONS.ACTIVE_WELCOME_WAGON_JSON :
|
|
WELCOME_WAGON_FOLDER + 'ww-wagonPad-complete.json';
|
|
|
|
var DISABLED_WELCOME_WAGON_JSON = WELCOME_WAGON_OPTIONS.DISABLED_WELCOME_WAGON_JSON !== undefined ? WELCOME_WAGON_OPTIONS.DISABLED_WELCOME_WAGON_JSON :
|
|
WELCOME_WAGON_FOLDER + 'ww-wagonPad-ghost.json';
|
|
|
|
var PLATFORM_NAME = WELCOME_WAGON_OPTIONS.PLATFORM_NAME !== undefined ? WELCOME_WAGON_OPTIONS.PLATFORM_NAME : 'ww-landingPad';
|
|
|
|
var WELCOME_WAGON_CHANNEL = WELCOME_WAGON_OPTIONS.WELCOME_WAGON_CHANNEL !== undefined ? WELCOME_WAGON_OPTIONS.WELCOME_WAGON_CHANNEL : 'com.highfidelity.welcomeWagon';
|
|
|
|
var MODULES_PATH = WELCOME_WAGON_OPTIONS.MODULES_PATH !== undefined ? WELCOME_WAGON_OPTIONS.MODULES_PATH : WELCOME_WAGON_FOLDER + 'modules/';
|
|
|
|
var request = Script.require(MODULES_PATH + 'request.js').request;
|
|
var _entityImport = Script.require(MODULES_PATH + 'entityImport.js');
|
|
|
|
var welcomeWagonEntities = [];
|
|
var welcomeWagonEnabled = false;
|
|
|
|
var welcomeWagonCheckInterval = null;
|
|
|
|
var STOP_CHECKING_WHEN = {
|
|
NEVER: 0,
|
|
WELCOME_WAGON_ARRIVES: 1,
|
|
WELCOME_WAGON_LEAVES: 2
|
|
};
|
|
|
|
var stopCheckingWhen = STOP_CHECKING_WHEN.NEVER;
|
|
var maxIntervalRuns = 1;
|
|
var intervalRuns = 0;
|
|
|
|
function clearExistingInterval() {
|
|
print('Trying to clear Existing Interval');
|
|
if (welcomeWagonCheckInterval === null) {
|
|
print('Clear Existing Interval is not needed, as there is no interval.');
|
|
return;
|
|
}
|
|
print('About to clear Existing Interval');
|
|
Script.clearInterval(welcomeWagonCheckInterval);
|
|
welcomeWagonCheckInterval = null;
|
|
print('Cleared Existing Interval');
|
|
}
|
|
|
|
// var NOT_FOUND_INDEX = -1;
|
|
|
|
function removeLockedEntity(entityID) {
|
|
Entities.editEntity(entityID, {locked: false});
|
|
Entities.deleteEntity(entityID);
|
|
}
|
|
|
|
function checkDomainASync() {
|
|
/**
|
|
* @typedef {{domain: {id: {string}}}} PlaceDetails
|
|
* @param {{data: {place: ({root: PlaceDetails}|PlaceDetails)}}} data
|
|
*/
|
|
request('https://metaverse.highfidelity.com/api/v1/places/' + ROTATING_DOMAIN, function (error, data) {
|
|
if (error === false) {
|
|
var rotatingDomainID = data.data.place.root !== undefined ? data.data.place.root.domain.id :
|
|
data.data.place.domain.id;
|
|
var hasMatchingDomainID = Uuid.isEqual(DOMAIN_ID, rotatingDomainID);
|
|
if (welcomeWagonEntities.length === 0 || welcomeWagonEnabled !== hasMatchingDomainID) {
|
|
welcomeWagonEnabled = hasMatchingDomainID;
|
|
|
|
var platformEntityID = null;
|
|
Entities.findEntities(SEARCH_CENTER, SEARCH_AREA).forEach(function(entityID) {
|
|
if (Entities.getEntityProperties(entityID, 'name').name === PLATFORM_NAME) {
|
|
platformEntityID = entityID;
|
|
}
|
|
});
|
|
if (platformEntityID === null) {
|
|
print('couldn\'t find platform');
|
|
return;
|
|
}
|
|
|
|
var platformProperties = Entities.getEntityProperties(platformEntityID, ['position', 'rotation']);
|
|
|
|
var importJSON = welcomeWagonEnabled ? ACTIVE_WELCOME_WAGON_JSON : DISABLED_WELCOME_WAGON_JSON;
|
|
|
|
var entityTree = _entityImport.importEntitiesJSON(importJSON, {
|
|
position: platformProperties.position,
|
|
rotation: platformProperties.rotation
|
|
}, {
|
|
locked: true
|
|
}, {
|
|
parentID: platformEntityID
|
|
});
|
|
/* var platformIndex = NOT_FOUND_INDEX;
|
|
entityTree.childEntities.forEach(function(childEntity, index) {
|
|
if (childEntity.name === PLATFORM_NAME) {
|
|
platformIndex = index;
|
|
}
|
|
}); */
|
|
|
|
// if (platformIndex === NOT_FOUND_INDEX) {
|
|
// print('Platform not found in JSON.');
|
|
// return;
|
|
// }
|
|
|
|
// TODO: first delete welcomeWagonEntities
|
|
|
|
Entities.findEntities(SEARCH_CENTER, SEARCH_AREA).forEach(function(entityID) {
|
|
var properties = Entities.getEntityProperties(entityID, 'parentID');
|
|
if (properties.parentID === platformEntityID) {
|
|
removeLockedEntity(entityID);
|
|
}
|
|
});
|
|
|
|
/* var platFormEntity = entityTree.childEntities[platformIndex];
|
|
if (platFormEntity.childEntities.length > 0) {
|
|
print('Found child entities on the platform, these will not be imported.');
|
|
}*/
|
|
|
|
// entityTree.childEntities.splice(platformIndex, 1);
|
|
|
|
/* entityTree.childEntities.forEach(function(childEntity, index) {
|
|
childEntity.rotation = Quat.multiply(childEntity.rotation, Quat.inverse(platFormEntity.rotation));
|
|
childEntity.position = Vec3.multiplyQbyV(Quat.inverse(platFormEntity.rotation), Vec3.subtract(childEntity.position, platFormEntity.position));
|
|
}); */
|
|
|
|
welcomeWagonEntities = _entityImport.createEntitiesFromTree([
|
|
entityTree
|
|
])[0].childEntities;
|
|
|
|
if (welcomeWagonCheckInterval !== null) {
|
|
if ((stopCheckingWhen === STOP_CHECKING_WHEN.WELCOME_WAGON_ARRIVES && welcomeWagonEnabled) ||
|
|
(stopCheckingWhen === STOP_CHECKING_WHEN.WELCOME_WAGON_LEAVES && !welcomeWagonEnabled)
|
|
) {
|
|
print('[INFO] stopped checking when ' + (stopCheckingWhen === STOP_CHECKING_WHEN.WELCOME_WAGON_ARRIVES ? 'arrived' : 'departed'));
|
|
clearExistingInterval();
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// TODO: Do nothing here for now, could be a metaverse bug (make require display the exact error, which is available in the data)
|
|
print("[ERROR] Something went wrong with the request: " + error + " / data: " + JSON.stringify(data));
|
|
}
|
|
});
|
|
}
|
|
|
|
Messages.messageReceived.connect(function(channel, message /* , senderUUID, localOnly */) {
|
|
if (channel !== WELCOME_WAGON_CHANNEL) {
|
|
return;
|
|
}
|
|
try {
|
|
/**
|
|
* @param{{
|
|
* interval: number|undefined,
|
|
* maxIntervalRuns: number|undefined,
|
|
* stopCheckingWhen: number|undefined,
|
|
* forceReset: boolean|undefined,
|
|
* directCheck: boolean|undefined
|
|
* }} messageData
|
|
*/
|
|
var messageData = JSON.parse(message);
|
|
switch (messageData.action) {
|
|
case 'check':
|
|
var interval = messageData.interval !== undefined ? messageData.interval : 3000;
|
|
maxIntervalRuns = messageData.maxIntervalRuns !== undefined ? messageData.maxIntervalRuns : 1;
|
|
stopCheckingWhen = messageData.stopCheckingWhen !== undefined ? messageData.stopCheckingWhen :
|
|
STOP_CHECKING_WHEN.NEVER;
|
|
intervalRuns = 0;
|
|
if (messageData.forceReset) {
|
|
welcomeWagonEntities = [];
|
|
}
|
|
clearExistingInterval();
|
|
var intervalCallback = function() {
|
|
if (intervalRuns >= maxIntervalRuns) {
|
|
print('[INFO] stopped checking when maxIntervalRuns was reached.');
|
|
clearExistingInterval();
|
|
return;
|
|
}
|
|
print('-Interval runs ' + intervalRuns);
|
|
checkDomainASync();
|
|
intervalRuns++;
|
|
print('+Interval runs ' + intervalRuns);
|
|
};
|
|
welcomeWagonCheckInterval = Script.setInterval(intervalCallback, interval);
|
|
// Important to run the directCheck after defining the interval, in case we clear it right away.
|
|
if (messageData.directCheck) {
|
|
intervalCallback();
|
|
}
|
|
break;
|
|
default:
|
|
print('Unknown action: ' + messageData.action + ' from message: ' + message);
|
|
}
|
|
} catch (exception) {
|
|
// exception
|
|
print('Unable to print JSON data: ' + message);
|
|
}
|
|
});
|
|
|
|
Messages.subscribe(WELCOME_WAGON_CHANNEL);
|
|
|
|
print('WelcomeWagonAC.js version: ' + VERSION);
|
|
|
|
// Assignment Client related code:
|
|
if (Script.isAgentScript()) {
|
|
Agent.isAvatar = true;
|
|
Avatar.skeletonModelURL = 'http://hifi-content.s3.amazonaws.com/ozan/dev/avatars/invisible_avatar/invisible_avatar.fst';
|
|
Avatar.displayName = DISPLAY_NAME;
|
|
|
|
var initialized = false;
|
|
|
|
var update = function(/* deltaTime */) {
|
|
if (!initialized) {
|
|
if (Entities.serversExist() && Entities.canRez()) {
|
|
Entities.setPacketsPerSecond(60000);
|
|
EntityViewer.setPosition(SEARCH_CENTER);
|
|
EntityViewer.setCenterRadius(SEARCH_AREA);
|
|
// This should allow us to see nano-scale entities from great distances
|
|
EntityViewer.setVoxelSizeScale(Number.MAX_VALUE);
|
|
Script.setInterval(function() {
|
|
EntityViewer.queryOctree();
|
|
}, 1000);
|
|
|
|
initialized = true;
|
|
Script.update.disconnect(update);
|
|
}
|
|
}
|
|
};
|
|
|
|
AvatarList.avatarAddedEvent.connect(function(avatarID) {
|
|
if (avatarID === Agent.sessionUUID) {
|
|
print('Skipping own session UUID ' + avatarID);
|
|
return;
|
|
}
|
|
print('Requesting ' + avatarID);
|
|
// Test
|
|
var IDENTITY_PACKETS_TIMEOUT = 1000;
|
|
Script.setTimeout(function() {
|
|
Users.requestUsernameFromID(avatarID);
|
|
}, IDENTITY_PACKETS_TIMEOUT);
|
|
});
|
|
|
|
Users.usernameFromIDReply.connect(function(id, username, machineFingerprint, isAdmin) {
|
|
print('machineFingerprint ' + machineFingerprint);
|
|
if (!isAdmin) {
|
|
// Users.ignore(id, true);
|
|
print(username + " {" + id + "} is NOT supposed to see me.");
|
|
} else {
|
|
print(username + " {" + id + "} is supposed to see me.");
|
|
}
|
|
});
|
|
|
|
Script.update.connect(update);
|
|
}
|