/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Region.Framework.Scenes
{
#region Delegates
public delegate uint GenerateClientFlagsHandler(UUID userID, UUID objectIDID);
public delegate void SetBypassPermissionsHandler(bool value);
public delegate bool BypassPermissionsHandler();
public delegate bool PropagatePermissionsHandler();
public delegate bool RezObjectHandler(int objectCount, UUID owner, Vector3 objectPosition, Scene scene);
public delegate bool DeleteObjectHandler(UUID objectID, UUID deleter, Scene scene);
public delegate bool TakeObjectHandler(UUID objectID, UUID stealer, Scene scene);
public delegate bool TakeCopyObjectHandler(UUID objectID, UUID userID, Scene inScene);
public delegate bool DuplicateObjectHandler(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition);
public delegate bool EditObjectHandler(UUID objectID, UUID editorID, Scene scene);
public delegate bool EditObjectInventoryHandler(UUID objectID, UUID editorID, Scene scene);
public delegate bool MoveObjectHandler(UUID objectID, UUID moverID, Scene scene);
public delegate bool ObjectEntryHandler(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene);
public delegate bool ReturnObjectHandler(UUID objectID, UUID returnerID, Scene scene);
public delegate bool InstantMessageHandler(UUID user, UUID target, Scene startScene);
public delegate bool InventoryTransferHandler(UUID user, UUID target, Scene startScene);
public delegate bool ViewScriptHandler(UUID script, UUID objectID, UUID user, Scene scene);
public delegate bool ViewNotecardHandler(UUID script, UUID objectID, UUID user, Scene scene);
public delegate bool EditScriptHandler(UUID script, UUID objectID, UUID user, Scene scene);
public delegate bool EditNotecardHandler(UUID notecard, UUID objectID, UUID user, Scene scene);
public delegate bool RunScriptHandler(UUID script, UUID objectID, UUID user, Scene scene);
public delegate bool StartScriptHandler(UUID script, UUID user, Scene scene);
public delegate bool StopScriptHandler(UUID script, UUID user, Scene scene);
public delegate bool ResetScriptHandler(UUID prim, UUID script, UUID user, Scene scene);
public delegate bool TerraformLandHandler(UUID user, Vector3 position, Scene requestFromScene);
public delegate bool RunConsoleCommandHandler(UUID user, Scene requestFromScene);
public delegate bool IssueEstateCommandHandler(UUID user, Scene requestFromScene, bool ownerCommand);
public delegate bool IsGodHandler(UUID user, Scene requestFromScene);
public delegate bool EditParcelHandler(UUID user, ILandObject parcel, Scene scene);
public delegate bool SellParcelHandler(UUID user, ILandObject parcel, Scene scene);
public delegate bool AbandonParcelHandler(UUID user, ILandObject parcel, Scene scene);
public delegate bool ReclaimParcelHandler(UUID user, ILandObject parcel, Scene scene);
public delegate bool BuyLandHandler(UUID user, ILandObject parcel, Scene scene);
public delegate bool LinkObjectHandler(UUID user, UUID objectID);
public delegate bool DelinkObjectHandler(UUID user, UUID objectID);
public delegate bool CreateObjectInventoryHandler(int invType, UUID objectID, UUID userID);
public delegate bool CopyObjectInventoryHandler(UUID itemID, UUID objectID, UUID userID);
public delegate bool DeleteObjectInventoryHandler(UUID itemID, UUID objectID, UUID userID);
public delegate bool CreateUserInventoryHandler(int invType, UUID userID);
public delegate bool EditUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID);
public delegate bool TeleportHandler(UUID userID, Scene scene);
#endregion
public class ScenePermissions
{
private Scene m_scene;
public ScenePermissions(Scene scene)
{
m_scene = scene;
}
#region Events
public event GenerateClientFlagsHandler OnGenerateClientFlags;
public event SetBypassPermissionsHandler OnSetBypassPermissions;
public event BypassPermissionsHandler OnBypassPermissions;
public event PropagatePermissionsHandler OnPropagatePermissions;
public event RezObjectHandler OnRezObject;
public event DeleteObjectHandler OnDeleteObject;
public event TakeObjectHandler OnTakeObject;
public event TakeCopyObjectHandler OnTakeCopyObject;
public event DuplicateObjectHandler OnDuplicateObject;
public event EditObjectHandler OnEditObject;
public event EditObjectInventoryHandler OnEditObjectInventory;
public event MoveObjectHandler OnMoveObject;
public event ObjectEntryHandler OnObjectEntry;
public event ReturnObjectHandler OnReturnObject;
public event InstantMessageHandler OnInstantMessage;
public event InventoryTransferHandler OnInventoryTransfer;
public event ViewScriptHandler OnViewScript;
public event ViewNotecardHandler OnViewNotecard;
public event EditScriptHandler OnEditScript;
public event EditNotecardHandler OnEditNotecard;
public event RunScriptHandler OnRunScript;
public event StartScriptHandler OnStartScript;
public event StopScriptHandler OnStopScript;
public event ResetScriptHandler OnResetScript;
public event TerraformLandHandler OnTerraformLand;
public event RunConsoleCommandHandler OnRunConsoleCommand;
public event IssueEstateCommandHandler OnIssueEstateCommand;
public event IsGodHandler OnIsGod;
public event EditParcelHandler OnEditParcel;
public event SellParcelHandler OnSellParcel;
public event AbandonParcelHandler OnAbandonParcel;
public event ReclaimParcelHandler OnReclaimParcel;
public event BuyLandHandler OnBuyLand;
public event LinkObjectHandler OnLinkObject;
public event DelinkObjectHandler OnDelinkObject;
public event CreateObjectInventoryHandler OnCreateObjectInventory;
public event CopyObjectInventoryHandler OnCopyObjectInventory;
public event DeleteObjectInventoryHandler OnDeleteObjectInventory;
public event CreateUserInventoryHandler OnCreateUserInventory;
public event EditUserInventoryHandler OnEditUserInventory;
public event CopyUserInventoryHandler OnCopyUserInventory;
public event DeleteUserInventoryHandler OnDeleteUserInventory;
public event TeleportHandler OnTeleport;
#endregion
#region Object Permission Checks
public uint GenerateClientFlags(UUID userID, UUID objectID)
{
SceneObjectPart part=m_scene.GetSceneObjectPart(objectID);
if (part == null)
return 0;
// libomv will moan about PrimFlags.ObjectYouOfficer being
// obsolete...
#pragma warning disable 0612
uint perms=part.GetEffectiveObjectFlags() |
(uint)PrimFlags.ObjectModify |
(uint)PrimFlags.ObjectCopy |
(uint)PrimFlags.ObjectMove |
(uint)PrimFlags.ObjectTransfer |
(uint)PrimFlags.ObjectYouOwner |
(uint)PrimFlags.ObjectAnyOwner |
(uint)PrimFlags.ObjectOwnerModify |
(uint)PrimFlags.ObjectYouOfficer;
#pragma warning restore 0612
GenerateClientFlagsHandler handlerGenerateClientFlags =
OnGenerateClientFlags;
if (handlerGenerateClientFlags != null)
{
Delegate[] list = handlerGenerateClientFlags.GetInvocationList();
foreach (GenerateClientFlagsHandler check in list)
{
perms &= check(userID, objectID);
}
}
return perms;
}
public void SetBypassPermissions(bool value)
{
SetBypassPermissionsHandler handler = OnSetBypassPermissions;
if (handler != null)
handler(value);
}
public bool BypassPermissions()
{
BypassPermissionsHandler handler = OnBypassPermissions;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (BypassPermissionsHandler h in list)
{
if (h() == false)
return false;
}
}
return true;
}
public bool PropagatePermissions()
{
PropagatePermissionsHandler handler = OnPropagatePermissions;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (PropagatePermissionsHandler h in list)
{
if (h() == false)
return false;
}
}
return true;
}
#region REZ OBJECT
public bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition)
{
RezObjectHandler handler = OnRezObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (RezObjectHandler h in list)
{
if (h(objectCount, owner,objectPosition, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region DELETE OBJECT
public bool CanDeleteObject(UUID objectID, UUID deleter)
{
DeleteObjectHandler handler = OnDeleteObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (DeleteObjectHandler h in list)
{
if (h(objectID, deleter, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region TAKE OBJECT
public bool CanTakeObject(UUID objectID, UUID AvatarTakingUUID)
{
TakeObjectHandler handler = OnTakeObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (TakeObjectHandler h in list)
{
if (h(objectID, AvatarTakingUUID, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region TAKE COPY OBJECT
public bool CanTakeCopyObject(UUID objectID, UUID userID)
{
TakeCopyObjectHandler handler = OnTakeCopyObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (TakeCopyObjectHandler h in list)
{
if (h(objectID, userID, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region DUPLICATE OBJECT
public bool CanDuplicateObject(int objectCount, UUID objectID, UUID owner, Vector3 objectPosition)
{
DuplicateObjectHandler handler = OnDuplicateObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (DuplicateObjectHandler h in list)
{
if (h(objectCount, objectID, owner, m_scene, objectPosition) == false)
return false;
}
}
return true;
}
#endregion
#region EDIT OBJECT
public bool CanEditObject(UUID objectID, UUID editorID)
{
EditObjectHandler handler = OnEditObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (EditObjectHandler h in list)
{
if (h(objectID, editorID, m_scene) == false)
return false;
}
}
return true;
}
public bool CanEditObjectInventory(UUID objectID, UUID editorID)
{
EditObjectInventoryHandler handler = OnEditObjectInventory;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (EditObjectInventoryHandler h in list)
{
if (h(objectID, editorID, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region MOVE OBJECT
public bool CanMoveObject(UUID objectID, UUID moverID)
{
MoveObjectHandler handler = OnMoveObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (MoveObjectHandler h in list)
{
if (h(objectID, moverID, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region OBJECT ENTRY
public bool CanObjectEntry(UUID objectID, bool enteringRegion, Vector3 newPoint)
{
ObjectEntryHandler handler = OnObjectEntry;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (ObjectEntryHandler h in list)
{
if (h(objectID, enteringRegion, newPoint, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region RETURN OBJECT
public bool CanReturnObject(UUID objectID, UUID returnerID)
{
ReturnObjectHandler handler = OnReturnObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (ReturnObjectHandler h in list)
{
if (h(objectID, returnerID, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region INSTANT MESSAGE
public bool CanInstantMessage(UUID user, UUID target)
{
InstantMessageHandler handler = OnInstantMessage;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (InstantMessageHandler h in list)
{
if (h(user, target, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region INVENTORY TRANSFER
public bool CanInventoryTransfer(UUID user, UUID target)
{
InventoryTransferHandler handler = OnInventoryTransfer;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (InventoryTransferHandler h in list)
{
if (h(user, target, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region VIEW SCRIPT
public bool CanViewScript(UUID script, UUID objectID, UUID user)
{
ViewScriptHandler handler = OnViewScript;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (ViewScriptHandler h in list)
{
if (h(script, objectID, user, m_scene) == false)
return false;
}
}
return true;
}
public bool CanViewNotecard(UUID script, UUID objectID, UUID user)
{
ViewNotecardHandler handler = OnViewNotecard;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (ViewNotecardHandler h in list)
{
if (h(script, objectID, user, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region EDIT SCRIPT
public bool CanEditScript(UUID script, UUID objectID, UUID user)
{
EditScriptHandler handler = OnEditScript;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (EditScriptHandler h in list)
{
if (h(script, objectID, user, m_scene) == false)
return false;
}
}
return true;
}
public bool CanEditNotecard(UUID script, UUID objectID, UUID user)
{
EditNotecardHandler handler = OnEditNotecard;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (EditNotecardHandler h in list)
{
if (h(script, objectID, user, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region RUN SCRIPT (When Script Placed in Object)
public bool CanRunScript(UUID script, UUID objectID, UUID user)
{
RunScriptHandler handler = OnRunScript;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (RunScriptHandler h in list)
{
if (h(script, objectID, user, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region START SCRIPT (When Script run box is Checked after placed in object)
public bool CanStartScript(UUID script, UUID user)
{
StartScriptHandler handler = OnStartScript;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (StartScriptHandler h in list)
{
if (h(script, user, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region STOP SCRIPT (When Script run box is unchecked after placed in object)
public bool CanStopScript(UUID script, UUID user)
{
StopScriptHandler handler = OnStopScript;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (StopScriptHandler h in list)
{
if (h(script, user, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region RESET SCRIPT
public bool CanResetScript(UUID prim, UUID script, UUID user)
{
ResetScriptHandler handler = OnResetScript;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (ResetScriptHandler h in list)
{
if (h(prim, script, user, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region TERRAFORM LAND
public bool CanTerraformLand(UUID user, Vector3 pos)
{
TerraformLandHandler handler = OnTerraformLand;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (TerraformLandHandler h in list)
{
if (h(user, pos, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region RUN CONSOLE COMMAND
public bool CanRunConsoleCommand(UUID user)
{
RunConsoleCommandHandler handler = OnRunConsoleCommand;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (RunConsoleCommandHandler h in list)
{
if (h(user, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region CAN ISSUE ESTATE COMMAND
public bool CanIssueEstateCommand(UUID user, bool ownerCommand)
{
IssueEstateCommandHandler handler = OnIssueEstateCommand;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (IssueEstateCommandHandler h in list)
{
if (h(user, m_scene, ownerCommand) == false)
return false;
}
}
return true;
}
#endregion
#region CAN BE GODLIKE
public bool IsGod(UUID user)
{
IsGodHandler handler = OnIsGod;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (IsGodHandler h in list)
{
if (h(user, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region EDIT PARCEL
public bool CanEditParcel(UUID user, ILandObject parcel)
{
EditParcelHandler handler = OnEditParcel;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (EditParcelHandler h in list)
{
if (h(user, parcel, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region SELL PARCEL
public bool CanSellParcel(UUID user, ILandObject parcel)
{
SellParcelHandler handler = OnSellParcel;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (SellParcelHandler h in list)
{
if (h(user, parcel, m_scene) == false)
return false;
}
}
return true;
}
#endregion
#region ABANDON PARCEL
public bool CanAbandonParcel(UUID user, ILandObject parcel)
{
AbandonParcelHandler handler = OnAbandonParcel;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (AbandonParcelHandler h in list)
{
if (h(user, parcel, m_scene) == false)
return false;
}
}
return true;
}
#endregion
public bool CanReclaimParcel(UUID user, ILandObject parcel)
{
ReclaimParcelHandler handler = OnReclaimParcel;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (ReclaimParcelHandler h in list)
{
if (h(user, parcel, m_scene) == false)
return false;
}
}
return true;
}
public bool CanBuyLand(UUID user, ILandObject parcel)
{
BuyLandHandler handler = OnBuyLand;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (BuyLandHandler h in list)
{
if (h(user, parcel, m_scene) == false)
return false;
}
}
return true;
}
public bool CanLinkObject(UUID user, UUID objectID)
{
LinkObjectHandler handler = OnLinkObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (LinkObjectHandler h in list)
{
if (h(user, objectID) == false)
return false;
}
}
return true;
}
public bool CanDelinkObject(UUID user, UUID objectID)
{
DelinkObjectHandler handler = OnDelinkObject;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (DelinkObjectHandler h in list)
{
if (h(user, objectID) == false)
return false;
}
}
return true;
}
#endregion
/// Check whether the specified user is allowed to directly create the given inventory type in a prim's
/// inventory (e.g. the New Script button in the 1.21 Linden Lab client).
///
///
///
///
///
public bool CanCreateObjectInventory(int invType, UUID objectID, UUID userID)
{
CreateObjectInventoryHandler handler = OnCreateObjectInventory;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (CreateObjectInventoryHandler h in list)
{
if (h(invType, objectID, userID) == false)
return false;
}
}
return true;
}
public bool CanCopyObjectInventory(UUID itemID, UUID objectID, UUID userID)
{
CopyObjectInventoryHandler handler = OnCopyObjectInventory;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (CopyObjectInventoryHandler h in list)
{
if (h(itemID, objectID, userID) == false)
return false;
}
}
return true;
}
public bool CanDeleteObjectInventory(UUID itemID, UUID objectID, UUID userID)
{
DeleteObjectInventoryHandler handler = OnDeleteObjectInventory;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (DeleteObjectInventoryHandler h in list)
{
if (h(itemID, objectID, userID) == false)
return false;
}
}
return true;
}
///
/// Check whether the specified user is allowed to create the given inventory type in their inventory.
///
///
///
///
public bool CanCreateUserInventory(int invType, UUID userID)
{
CreateUserInventoryHandler handler = OnCreateUserInventory;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (CreateUserInventoryHandler h in list)
{
if (h(invType, userID) == false)
return false;
}
}
return true;
}
///
/// Check whether the specified user is allowed to edit the given inventory item within their own inventory.
///
///
///
///
public bool CanEditUserInventory(UUID itemID, UUID userID)
{
EditUserInventoryHandler handler = OnEditUserInventory;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (EditUserInventoryHandler h in list)
{
if (h(itemID, userID) == false)
return false;
}
}
return true;
}
///
/// Check whether the specified user is allowed to copy the given inventory item from their own inventory.
///
///
///
///
public bool CanCopyUserInventory(UUID itemID, UUID userID)
{
CopyUserInventoryHandler handler = OnCopyUserInventory;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (CopyUserInventoryHandler h in list)
{
if (h(itemID, userID) == false)
return false;
}
}
return true;
}
///
/// Check whether the specified user is allowed to edit the given inventory item within their own inventory.
///
///
///
///
public bool CanDeleteUserInventory(UUID itemID, UUID userID)
{
DeleteUserInventoryHandler handler = OnDeleteUserInventory;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (DeleteUserInventoryHandler h in list)
{
if (h(itemID, userID) == false)
return false;
}
}
return true;
}
public bool CanTeleport(UUID userID)
{
TeleportHandler handler = OnTeleport;
if (handler != null)
{
Delegate[] list = handler.GetInvocationList();
foreach (TeleportHandler h in list)
{
if (h(userID, m_scene) == false)
return false;
}
}
return true;
}
}
}