/* 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); }