174 lines
6.4 KiB
JavaScript
174 lines
6.4 KiB
JavaScript
//
|
|
// avatarEntityRemover.js
|
|
//
|
|
// Created by Zach Fox on 2019-03-15
|
|
// Copyright 2019 High Fidelity, Inc.
|
|
//
|
|
// See accompanying README.md for usage instructions.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
|
|
|
|
(function () {
|
|
var approvedUsernames = [];
|
|
var removedAvatarEntityProperties = [];
|
|
var enableAvatarEntityRestore = false;
|
|
var kickDomain = "hifi://domain";
|
|
var enableCollisionlessAvatarEntities = false;
|
|
var tryAgainDeleteInterval = false;
|
|
var TRY_DELETE_AGAIN_MS = 1000;
|
|
|
|
|
|
// Saves an entity's properties if the configuration options are set to enable that feature,
|
|
// then deletes the entity
|
|
function maybeSaveThenDelete(entityID, properties) {
|
|
if (enableAvatarEntityRestore) {
|
|
removedAvatarEntityProperties.push(properties);
|
|
}
|
|
|
|
// This will do nothing unless the user has lock/unlock rights
|
|
Entities.editEntity(entityID, {"locked": false});
|
|
|
|
Entities.editEntity(entityID, {"dimensions": {"x": 0.01, "y": 0.01, "z": 0.01}});
|
|
Entities.deleteEntity(entityID);
|
|
}
|
|
|
|
|
|
// Gets called when the script runner adds an entity to their entity tree.
|
|
// 1. Checks if the user is approved to add avatar entities, and stops execution if they are
|
|
// 2. Gets some properties of the added entity
|
|
// 3. If the added avatar entity is locked, kicks the user to a different domain
|
|
// 4. If the added avatar entity is unlocked,
|
|
// depending on certain entity properties, keeps or deletes the entity.
|
|
function onAddingEntity(entityID) {
|
|
if (approvedUsernames.indexOf(AccountServices.username) > -1) {
|
|
return;
|
|
}
|
|
|
|
var props = Entities.getEntityProperties(entityID, ['avatarEntity', 'entityHostType', 'locked', 'owningAvatarID', 'collisionless']);
|
|
|
|
if (props.owningAvatarID === MyAvatar.sessionUUID && (props.avatarEntity || props.entityHostType === "avatar")) {
|
|
if (enableCollisionlessAvatarEntities && props.collisionless) {
|
|
return;
|
|
}
|
|
|
|
if (props.locked) {
|
|
console.log("Boot Code 00000002");
|
|
Window.location = kickDomain;
|
|
return;
|
|
}
|
|
|
|
// This will do nothing unless the user has lock/unlock rights
|
|
Entities.editEntity(entityID, {locked: false});
|
|
|
|
Entities.editEntity(entityID, {"dimensions": {"x": 0.01, "y": 0.01, "z": 0.01}});
|
|
Entities.deleteEntity(entityID);
|
|
}
|
|
}
|
|
|
|
|
|
// Gets called on a short interval. If the user isn't approved to add avatar entities,
|
|
// removes all avatar entities (unless the script is configured to allow collisionless avatar entities
|
|
// and the avatar entity is collisionless).
|
|
function maybeRemoveAllCurrentAvatarEntities() {
|
|
if (approvedUsernames.indexOf(AccountServices.username) > -1) {
|
|
return;
|
|
}
|
|
|
|
MyAvatar.getAvatarEntitiesVariant().forEach(function(avatarEntity) {
|
|
if (enableCollisionlessAvatarEntities && avatarEntity.properties.collisionless) {
|
|
return;
|
|
}
|
|
|
|
Entities.deleteEntity(avatarEntity.id);
|
|
});
|
|
}
|
|
|
|
|
|
// Gets called on script startup. If the user isn't approved to add avatar entities,
|
|
// calls `maybeSaveThenDelete()`. If the user is wearing any locked avatar entities,
|
|
// they'll get kicked to a different domain.
|
|
function maybeSaveThenRemoveAllCurrentAvatarEntities() {
|
|
if (approvedUsernames.indexOf(AccountServices.username) > -1) {
|
|
return;
|
|
}
|
|
|
|
MyAvatar.getAvatarEntitiesVariant().forEach(function(avatarEntity) {
|
|
if (avatarEntity.properties.locked) {
|
|
console.log("Boot Code 00000001");
|
|
Window.location = kickDomain;
|
|
return;
|
|
}
|
|
|
|
if (enableCollisionlessAvatarEntities && avatarEntity.properties.collisionless) {
|
|
return;
|
|
}
|
|
|
|
maybeSaveThenDelete(avatarEntity.id, avatarEntity.properties);
|
|
});
|
|
}
|
|
|
|
|
|
var AvatarEntityRemover = function() {};
|
|
|
|
AvatarEntityRemover.prototype = {
|
|
// On script startup, sets configuration options from `userData` and starts main script logic
|
|
preload: function (id) {
|
|
var properties = Entities.getEntityProperties(id, ["userData"]);
|
|
var userData;
|
|
|
|
try {
|
|
userData = JSON.parse(properties.userData);
|
|
} catch (e) {
|
|
console.error("Error parsing userData: ", e);
|
|
}
|
|
|
|
if (userData) {
|
|
if (userData.enableAvatarEntityRestore) {
|
|
enableAvatarEntityRestore = userData.enableAvatarEntityRestore;
|
|
}
|
|
|
|
if (userData.kickDomain) {
|
|
kickDomain = userData.kickDomain;
|
|
}
|
|
|
|
if (userData.enableCollisionlessAvatarEntities) {
|
|
enableCollisionlessAvatarEntities = userData.enableCollisionlessAvatarEntities;
|
|
}
|
|
|
|
if (userData.configURL) {
|
|
var configURL = userData.configURL;
|
|
// Cachebusting attempt
|
|
if (configURL.indexOf("?") === -1) {
|
|
configURL = configURL + "?" + Date.now();
|
|
}
|
|
approvedUsernames = Script.require(Script.resolvePath(configURL)).approvedUsernames;
|
|
}
|
|
}
|
|
|
|
Entities.addingEntity.connect(onAddingEntity);
|
|
maybeSaveThenRemoveAllCurrentAvatarEntities();
|
|
tryAgainDeleteInterval = Script.setInterval(maybeRemoveAllCurrentAvatarEntities, TRY_DELETE_AGAIN_MS);
|
|
},
|
|
|
|
// Disconnects signals, stops timers, and, if enabled as a configuration option, restores the avatar entities
|
|
// that this script deleted
|
|
unload: function() {
|
|
Entities.addingEntity.disconnect(onAddingEntity);
|
|
|
|
if (enableAvatarEntityRestore) {
|
|
removedAvatarEntityProperties.forEach(function(props) {
|
|
Entities.addEntity(props, "avatar");
|
|
});
|
|
}
|
|
|
|
if (tryAgainDeleteInterval) {
|
|
Script.clearInterval(tryAgainDeleteInterval);
|
|
tryAgainDeleteInterval = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
return new AvatarEntityRemover();
|
|
});
|