< Summary

Class:BuilderInWorldController
Assembly:BuilderInWorld
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/BuilderMode/BuilderInWorldController.cs
Covered lines:40
Uncovered lines:366
Coverable lines:406
Total lines:819
Line coverage:9.8% (40 of 406)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
BuilderInWorldController()0%110100%
Awake()0%2100%
Start()0%2100%
OnDestroy()0%30500%
Update()0%72800%
OnNFTUsageChange()0%2100%
OnKernelConfigChanged(...)0%2100%
EnableFeature(...)0%6200%
CatalogReceived(...)0%2100%
CatalogLoaded()0%6200%
Init()0%20400%
InitBuilderProjectPanel()0%6200%
CatalogHeadersReceived(...)0%6200%
GetCatalog()0%12300%
ConfigureLoadingController()0%2100%
InitGameObjects()0%550100%
InitControllers()0%110100%
StartTutorial()0%2100%
CleanItems()0%5.015091.67%
ActivateFeature()0%2100%
ChangeEditModeStatusByShortcut()0%42600%
GetCloserUnselectedVoxelEntityOnPointer()0%56700%
NewSceneAdded(...)0%6200%
NewSceneReady(...)0%6200%
UserHasPermissionOnParcelScene(...)0%30500%
IsParcelSceneDeployedFromSDK(...)0%42600%
CheckEnterEditMode()0%12300%
TryStartEnterEditMode()0%2100%
TryStartEnterEditMode(...)0%2100%
TryStartEnterEditMode(...)0%56700%
StartEditMode()0%6200%
EnterEditMode()0%42600%
OnAllParcelsFloorLoaded()0%6200%
OpenNewProjectDetailsIfNeeded()0%6200%
StartExitMode()0%6200%
ExitEditMode()0%42600%
InmediateExit()0%2100%
EnterBiwControllers()0%2100%
ExitBiwControllers()0%2100%
IsNewScene()0%2100%
SetupNewScene()0%2100%
ExitAfterCharacterTeleport(...)0%2100%
FindSceneToEdit(...)0%20400%
FindSceneToEdit()0%8.125050%
OnPlayerTeleportedToEditScene(...)0%6200%
UpdateCatalogLoadingProgress(...)0%2100%
UpdateSceneLoadingProgress(...)0%2100%
OnUserProfileUpdate(...)0%2100%
CheckLandsAccess()0%12300%
UpdateLandsWithAccess()0%6200%
ShowGenericNotification(...)0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/BuilderMode/BuilderInWorldController.cs

#LineLine coverage
 1using Builder;
 2using DCL;
 3using DCL.Configuration;
 4using DCL.Controllers;
 5using DCL.Tutorial;
 6using Newtonsoft.Json;
 7using System;
 8using System.Collections;
 9using System.Collections.Generic;
 10using System.Linq;
 11using UnityEngine;
 12using Environment = DCL.Environment;
 13
 14public class BuilderInWorldController : MonoBehaviour
 15{
 16    private const float CULLING_ACTIVATION_DELAY = 0.5f;
 17
 18    [Header("Activation of Feature")]
 19    public bool activeFeature = false;
 20
 21    public bool bypassLandOwnershipCheck = false;
 22
 23    [Header("DesignVariables")]
 24    [SerializeField]
 19825    private float distanceToDisableBuilderInWorld = 45f;
 26
 27    [Header("Scene References")]
 28    public GameObject cameraParentGO;
 29
 30    public GameObject cursorGO;
 31    public InputController inputController;
 32    public GameObject[] groundVisualsGO;
 33
 34    [Header("Prefab References")]
 35    public BIWOutlinerController outlinerController;
 36
 37    public BIWInputHandler bIWInputHandler;
 38    public BIWPublishController biwPublishController;
 39    public BIWCreatorController biwCreatorController;
 40    public BIWModeController biwModeController;
 41    public BIWFloorHandler biwFloorHandler;
 42    public BuilderInWorldEntityHandler builderInWorldEntityHandler;
 43    public ActionController actionController;
 44    public BuilderInWorldBridge builderInWorldBridge;
 45    public BIWSaveController biwSaveController;
 46    public BuilderInWorldAudioHandler biwAudioHandler;
 47
 48    [Header("Build Modes")]
 49    public BuilderInWorldGodMode editorMode;
 50
 51    public LayerMask layerToRaycast;
 52
 53    private ParcelScene sceneToEdit;
 54
 55    [Header("Project References")]
 56    public Material skyBoxMaterial;
 57
 58    [Header("Loading")]
 59    public BuilderInWorldLoadingView initialLoadingView;
 60
 61    [HideInInspector]
 62    public bool isBuilderInWorldActivated = false;
 63
 64    private GameObject editionGO;
 65    private GameObject undoGO;
 66    private GameObject snapGO;
 67    private GameObject freeMovementGO;
 68    private int checkerInsideSceneOptimizationCounter = 0;
 69    private string sceneToEditId;
 70    private bool catalogAdded = false;
 71    private bool sceneReady = false;
 72    private bool isInit = false;
 73    private Material previousSkyBoxMaterial;
 74    private Vector3 parcelUnityMiddlePoint;
 75    private bool previousAllUIHidden;
 76    private WebRequestAsyncOperation catalogAsyncOp;
 77    private bool isCatalogLoading = false;
 78    private bool areCatalogHeadersReady = false;
 79    private float beginStartFlowTimeStamp = 0;
 80    private float startEditorTimeStamp = 0;
 81    private bool isCatalogRequested = false;
 82    private bool isEnteringEditMode = false;
 83
 84    public event Action OnEnterEditMode;
 85    public event Action OnExitEditMode;
 86
 87    internal IBuilderInWorldLoadingController initialLoadingController;
 88
 89    private UserProfile userProfile;
 19890    private List<LandWithAccess> landsWithAccess = new List<LandWithAccess>();
 91    private Coroutine updateLandsWithAcessCoroutine;
 92    private Dictionary<string, string> catalogCallHeaders;
 93
 94    private void Awake()
 95    {
 096        BIWCatalogManager.Init();
 097        builderInWorldBridge.OnCatalogHeadersReceived += CatalogHeadersReceived;
 098    }
 99
 100    void Start()
 101    {
 0102        KernelConfig.i.EnsureConfigInitialized().Then(config =>  EnableFeature(config.features.enableBuilderInWorld));
 0103        KernelConfig.i.OnChange += OnKernelConfigChanged;
 0104    }
 105
 106    private void OnDestroy()
 107    {
 0108        if (userProfile != null)
 0109            userProfile.OnUpdate -= OnUserProfileUpdate;
 110
 0111        CoroutineStarter.Stop(updateLandsWithAcessCoroutine);
 112
 0113        if (sceneToEdit != null)
 0114            sceneToEdit.OnLoadingStateUpdated -= UpdateSceneLoadingProgress;
 115
 0116        Environment.i.world.sceneController.OnNewSceneAdded -= NewSceneAdded;
 0117        Environment.i.world.sceneController.OnReadyScene -= NewSceneReady;
 118
 0119        KernelConfig.i.OnChange -= OnKernelConfigChanged;
 120
 0121        if (HUDController.i.builderInWorldMainHud != null)
 122        {
 0123            HUDController.i.builderInWorldMainHud.OnTutorialAction -= StartTutorial;
 0124            HUDController.i.builderInWorldMainHud.OnStartExitAction -= StartExitMode;
 0125            HUDController.i.builderInWorldMainHud.OnLogoutAction -= ExitEditMode;
 126        }
 127
 0128        BuilderInWorldTeleportAndEdit.OnTeleportEnd -= OnPlayerTeleportedToEditScene;
 129
 0130        if (initialLoadingController != null)
 0131            initialLoadingController.Dispose();
 132
 133
 0134        BuilderInWorldNFTController.i.OnNFTUsageChange -= OnNFTUsageChange;
 0135        builderInWorldBridge.OnCatalogHeadersReceived -= CatalogHeadersReceived;
 0136        CleanItems();
 137
 0138        HUDController.i.OnBuilderProjectPanelCreation -= InitBuilderProjectPanel;
 0139    }
 140
 141    private void Update()
 142    {
 0143        if (isCatalogLoading && catalogAsyncOp?.webRequest != null)
 0144            UpdateCatalogLoadingProgress(catalogAsyncOp.webRequest.downloadProgress * 100);
 145
 0146        if (!isBuilderInWorldActivated)
 0147            return;
 148
 0149        if (checkerInsideSceneOptimizationCounter >= 60)
 150        {
 0151            if (Vector3.Distance(DCLCharacterController.i.characterPosition.unityPosition, parcelUnityMiddlePoint) >= di
 0152                ExitEditMode();
 0153            checkerInsideSceneOptimizationCounter = 0;
 0154        }
 155        else
 156        {
 0157            checkerInsideSceneOptimizationCounter++;
 158        }
 0159    }
 160
 161    private void OnNFTUsageChange()
 162    {
 0163        HUDController.i.builderInWorldMainHud.RefreshCatalogAssetPack();
 0164        HUDController.i.builderInWorldMainHud.RefreshCatalogContent();
 0165    }
 166
 0167    private void OnKernelConfigChanged(KernelConfigModel current, KernelConfigModel previous) { EnableFeature(current.fe
 168
 169    private void EnableFeature(bool enable)
 170    {
 0171        activeFeature = enable;
 172
 0173        if (enable)
 0174            Init();
 0175    }
 176
 177    private void CatalogReceived(string catalogJson)
 178    {
 0179        isCatalogLoading = false;
 0180        AssetCatalogBridge.i.AddFullSceneObjectCatalog(catalogJson);
 0181        CatalogLoaded();
 0182    }
 183
 184    public void CatalogLoaded()
 185    {
 0186        catalogAdded = true;
 0187        if (HUDController.i.builderInWorldMainHud != null)
 0188            HUDController.i.builderInWorldMainHud.RefreshCatalogContent();
 0189        StartEditMode();
 0190    }
 191
 192    public void Init()
 193    {
 0194        if (isInit)
 0195            return;
 196
 0197        isInit = true;
 198
 0199        userProfile = UserProfile.GetOwnUserProfile();
 0200        if (!string.IsNullOrEmpty(userProfile.userId))
 0201            updateLandsWithAcessCoroutine = CoroutineStarter.Start(CheckLandsAccess());
 202        else
 0203            userProfile.OnUpdate += OnUserProfileUpdate;
 204
 0205        InitGameObjects();
 206
 0207        HUDConfiguration hudConfig = new HUDConfiguration();
 0208        hudConfig.active = true;
 0209        hudConfig.visible = false;
 0210        HUDController.i.CreateHudElement(hudConfig, HUDElementID.BUILDER_IN_WORLD_MAIN);
 0211        HUDController.i.OnBuilderProjectPanelCreation += InitBuilderProjectPanel;
 212
 0213        HUDController.i.builderInWorldMainHud.Initialize();
 214
 0215        HUDController.i.builderInWorldMainHud.OnTutorialAction += StartTutorial;
 0216        HUDController.i.builderInWorldMainHud.OnStartExitAction += StartExitMode;
 0217        HUDController.i.builderInWorldMainHud.OnLogoutAction += ExitEditMode;
 218
 0219        if (HUDController.i.builderProjectsPanelController != null)
 0220            HUDController.i.builderProjectsPanelController.OnJumpInOrEdit += GetCatalog;
 221
 0222        BuilderInWorldTeleportAndEdit.OnTeleportEnd += OnPlayerTeleportedToEditScene;
 223
 0224        ConfigureLoadingController();
 0225        InitControllers();
 226
 0227        CommonScriptableObjects.builderInWorldNotNecessaryUIVisibilityStatus.Set(true);
 228
 0229        builderInWorldBridge.AskKernelForCatalogHeaders();
 230
 0231        isCatalogLoading = true;
 0232        BuilderInWorldNFTController.i.Initialize();
 0233        BuilderInWorldNFTController.i.OnNFTUsageChange += OnNFTUsageChange;
 0234    }
 235
 236    private void InitBuilderProjectPanel()
 237    {
 0238        if (HUDController.i.builderProjectsPanelController != null)
 0239            HUDController.i.builderProjectsPanelController.OnJumpInOrEdit += GetCatalog;
 0240    }
 241
 242    private void CatalogHeadersReceived(string rawHeaders)
 243    {
 0244        catalogCallHeaders = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawHeaders);
 0245        areCatalogHeadersReady = true;
 0246        if (isCatalogRequested)
 0247            GetCatalog();
 0248    }
 249
 250    private void GetCatalog()
 251    {
 0252        if (catalogAdded)
 0253            return;
 254
 0255        if (areCatalogHeadersReady)
 0256            catalogAsyncOp = BuilderInWorldUtils.MakeGetCall(BIWUrlUtils.GetUrlCatalog(), CatalogReceived, catalogCallHe
 257        else
 0258            builderInWorldBridge.AskKernelForCatalogHeaders();
 259
 0260        isCatalogRequested = true;
 0261    }
 262
 263    private void ConfigureLoadingController()
 264    {
 0265        initialLoadingController = new BuilderInWorldLoadingController();
 0266        initialLoadingController.Initialize(initialLoadingView);
 0267    }
 268
 269    public void InitGameObjects()
 270    {
 9271        if (snapGO == null)
 9272            snapGO = new GameObject("SnapGameObject");
 273
 9274        snapGO.transform.SetParent(transform);
 275
 9276        if (freeMovementGO == null)
 9277            freeMovementGO = new GameObject("FreeMovementGO");
 278
 9279        freeMovementGO.transform.SetParent(cameraParentGO.transform);
 280
 9281        if (editionGO == null)
 9282            editionGO = new GameObject("EditionGO");
 283
 9284        editionGO.transform.SetParent(cameraParentGO.transform);
 285
 9286        if (undoGO == null)
 287        {
 9288            undoGO = new GameObject("UndoGameObject");
 9289            undoGO.transform.SetParent(transform);
 290        }
 9291    }
 292
 293    public void InitControllers()
 294    {
 9295        builderInWorldEntityHandler.Init();
 9296        biwModeController.Init(editionGO, undoGO, snapGO, freeMovementGO);
 9297        biwPublishController.Init();
 9298        biwCreatorController.Init();
 9299        outlinerController.Init();
 9300        biwFloorHandler.Init();
 9301        bIWInputHandler.Init();
 9302        biwSaveController.Init();
 9303        actionController.Init();
 9304        biwAudioHandler.Init();
 9305    }
 306
 0307    private void StartTutorial() { TutorialController.i.SetBuilderInWorldTutorialEnabled(); }
 308
 309    public void CleanItems()
 310    {
 20311        Destroy(undoGO);
 20312        Destroy(snapGO);
 20313        Destroy(editionGO);
 20314        Destroy(freeMovementGO);
 315
 20316        if (HUDController.i.builderInWorldMainHud != null)
 0317            HUDController.i.builderInWorldMainHud.Dispose();
 318
 20319        if (Camera.main != null)
 320        {
 20321            DCLBuilderOutline outliner = Camera.main.GetComponent<DCLBuilderOutline>();
 20322            Destroy(outliner);
 323        }
 324
 20325        biwFloorHandler?.Clean();
 20326        biwCreatorController?.Clean();
 20327    }
 328
 329    [ContextMenu("Activate feature")]
 330    public void ActivateFeature()
 331    {
 0332        activeFeature = true;
 0333        HUDController.i.taskbarHud.SetBuilderInWorldStatus(activeFeature);
 0334    }
 335
 336    public void ChangeEditModeStatusByShortcut()
 337    {
 0338        if (!activeFeature)
 0339            return;
 340
 0341        if (isEnteringEditMode)
 0342            return;
 343
 0344        if (isBuilderInWorldActivated)
 345        {
 0346            HUDController.i.builderInWorldMainHud.ExitStart();
 0347            return;
 348        }
 349
 0350        FindSceneToEdit();
 351
 0352        if (!UserHasPermissionOnParcelScene(sceneToEdit))
 353        {
 0354            ShowGenericNotification(BuilderInWorldSettings.LAND_EDITION_NOT_ALLOWED_BY_PERMISSIONS_MESSAGE);
 0355            return;
 356        }
 0357        if (IsParcelSceneDeployedFromSDK(sceneToEdit))
 358        {
 0359            ShowGenericNotification(BuilderInWorldSettings.LAND_EDITION_NOT_ALLOWED_BY_SDK_LIMITATION_MESSAGE);
 0360            return;
 361        }
 362
 0363        GetCatalog();
 0364        TryStartEnterEditMode(true, null, "Shortcut");
 0365    }
 366
 367    public VoxelEntityHit GetCloserUnselectedVoxelEntityOnPointer()
 368    {
 369        RaycastHit[] hits;
 0370        UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 371
 0372        float currentDistance = 9999;
 0373        VoxelEntityHit voxelEntityHit = null;
 374
 0375        hits = Physics.RaycastAll(ray, BuilderInWorldSettings.RAYCAST_MAX_DISTANCE, layerToRaycast);
 376
 0377        foreach (RaycastHit hit in hits)
 378        {
 0379            string entityID = hit.collider.gameObject.name;
 380
 0381            if (sceneToEdit.entities.ContainsKey(entityID))
 382            {
 0383                DCLBuilderInWorldEntity entityToCheck = builderInWorldEntityHandler.GetConvertedEntity(sceneToEdit.entit
 384
 0385                if (entityToCheck == null)
 386                    continue;
 387
 0388                Camera camera = Camera.main;
 389
 0390                if (!entityToCheck.IsSelected && entityToCheck.tag == BuilderInWorldSettings.VOXEL_TAG)
 391                {
 0392                    if (Vector3.Distance(camera.transform.position, entityToCheck.rootEntity.gameObject.transform.positi
 393                    {
 0394                        voxelEntityHit = new VoxelEntityHit(entityToCheck, hit);
 0395                        currentDistance = Vector3.Distance(camera.transform.position, entityToCheck.rootEntity.gameObjec
 396                    }
 397                }
 398            }
 399        }
 400
 0401        return voxelEntityHit;
 402    }
 403
 404    private void NewSceneAdded(IParcelScene newScene)
 405    {
 0406        if (newScene.sceneData.id != sceneToEditId)
 0407            return;
 408
 0409        Environment.i.world.sceneController.OnNewSceneAdded -= NewSceneAdded;
 410
 0411        sceneToEdit = (ParcelScene)Environment.i.world.state.GetScene(sceneToEditId);
 0412        sceneToEdit.OnLoadingStateUpdated += UpdateSceneLoadingProgress;
 0413    }
 414
 415    private void NewSceneReady(string id)
 416    {
 0417        if (sceneToEditId != id)
 0418            return;
 419
 0420        sceneToEdit.OnLoadingStateUpdated -= UpdateSceneLoadingProgress;
 0421        Environment.i.world.sceneController.OnReadyScene -= NewSceneReady;
 0422        sceneToEditId = null;
 0423        sceneReady = true;
 0424        CheckEnterEditMode();
 0425    }
 426
 427    private bool UserHasPermissionOnParcelScene(ParcelScene sceneToCheck)
 428    {
 0429        if (bypassLandOwnershipCheck)
 0430            return true;
 431
 0432        List<Vector2Int> allParcelsWithAccess = landsWithAccess.SelectMany(land => land.parcels).ToList();
 0433        foreach (Vector2Int parcel in allParcelsWithAccess)
 434        {
 0435            if (sceneToCheck.sceneData.parcels.Any(currentParcel => currentParcel.x == parcel.x && currentParcel.y == pa
 0436                return true;
 437        }
 438
 0439        return false;
 0440    }
 441
 442    private bool IsParcelSceneDeployedFromSDK(ParcelScene sceneToCheck)
 443    {
 0444        List<DeployedScene> allDeployedScenesWithAccess = landsWithAccess.SelectMany(land => land.scenes).ToList();
 0445        foreach (DeployedScene scene in allDeployedScenesWithAccess)
 446        {
 0447            if (scene.source != DeployedScene.Source.SDK)
 448                continue;
 449
 0450            List<Vector2Int> parcelsDeployedFromSDK = scene.parcels.ToList();
 0451            foreach (Vector2Int parcel in parcelsDeployedFromSDK)
 452            {
 0453                if (sceneToCheck.sceneData.parcels.Any(currentParcel => currentParcel.x == parcel.x && currentParcel.y =
 0454                    return true;
 455            }
 456        }
 457
 0458        return false;
 0459    }
 460
 461    private void CheckEnterEditMode()
 462    {
 0463        if (catalogAdded && sceneReady)
 0464            EnterEditMode();
 0465    }
 466
 0467    public void TryStartEnterEditMode() { TryStartEnterEditMode(true, null); }
 0468    public void TryStartEnterEditMode(IParcelScene targetScene) { TryStartEnterEditMode(true, targetScene); }
 469
 470    public void TryStartEnterEditMode(bool activateCamera, IParcelScene targetScene = null , string source = "BuilderPan
 471    {
 0472        if (sceneToEditId != null)
 0473            return;
 474
 0475        FindSceneToEdit(targetScene);
 476
 0477        if (!UserHasPermissionOnParcelScene(sceneToEdit))
 478        {
 0479            ShowGenericNotification(BuilderInWorldSettings.LAND_EDITION_NOT_ALLOWED_BY_PERMISSIONS_MESSAGE);
 0480            return;
 481        }
 0482        else if (IsParcelSceneDeployedFromSDK(sceneToEdit))
 483        {
 0484            ShowGenericNotification(BuilderInWorldSettings.LAND_EDITION_NOT_ALLOWED_BY_SDK_LIMITATION_MESSAGE);
 0485            return;
 486        }
 487
 488        //If the scene is still not loaded, we return as we still can't enter in builder in world
 0489        if (sceneToEditId != null)
 0490            return;
 491
 0492        isEnteringEditMode = true;
 0493        previousAllUIHidden = CommonScriptableObjects.allUIHidden.Get();
 0494        NotificationsController.i.allowNotifications = false;
 0495        CommonScriptableObjects.allUIHidden.Set(true);
 0496        NotificationsController.i.allowNotifications = true;
 0497        inputController.inputTypeMode = InputTypeMode.BUILD_MODE_LOADING;
 0498        initialLoadingController.Show();
 0499        initialLoadingController.SetPercentage(0f);
 0500        DataStore.i.appMode.Set(AppMode.BUILDER_IN_WORLD_EDITION);
 0501        BIWAnalytics.StartEditorFlow(source);
 0502        beginStartFlowTimeStamp = Time.realtimeSinceStartup;
 503        //Note (Adrian) this should handle different when we have the full flow of the feature
 0504        if (activateCamera)
 0505            editorMode.ActivateCamera(sceneToEdit);
 506
 0507        if (catalogAdded)
 0508            StartEditMode();
 0509    }
 510
 511    private void StartEditMode()
 512    {
 0513        if (sceneToEdit == null)
 0514            return;
 515
 0516        isEnteringEditMode = true;
 517
 0518        Environment.i.platform.cullingController.Stop();
 519
 0520        sceneToEditId = sceneToEdit.sceneData.id;
 521
 522        // In this point we're sure that the catalog loading (the first half of our progress bar) has already finished
 0523        initialLoadingController.SetPercentage(50f);
 0524        Environment.i.world.sceneController.OnNewSceneAdded += NewSceneAdded;
 0525        Environment.i.world.sceneController.OnReadyScene += NewSceneReady;
 0526        Environment.i.world.blockersController.SetEnabled(false);
 527
 0528        builderInWorldBridge.StartKernelEditMode(sceneToEdit);
 0529    }
 530
 531    private void EnterEditMode()
 532    {
 0533        if (!initialLoadingController.isActive)
 0534            return;
 535
 0536        isEnteringEditMode = false;
 0537        BuilderInWorldNFTController.i.ClearNFTs();
 538
 0539        ParcelSettings.VISUAL_LOADING_ENABLED = false;
 540
 0541        sceneToEdit.SetEditMode(true);
 0542        cursorGO.SetActive(false);
 0543        parcelUnityMiddlePoint = BuilderInWorldUtils.CalculateUnityMiddlePoint(sceneToEdit);
 544
 0545        if (HUDController.i.builderInWorldMainHud != null)
 546        {
 0547            HUDController.i.builderInWorldMainHud.SetParcelScene(sceneToEdit);
 0548            HUDController.i.builderInWorldMainHud.RefreshCatalogContent();
 0549            HUDController.i.builderInWorldMainHud.RefreshCatalogAssetPack();
 0550            HUDController.i.builderInWorldMainHud.SetVisibilityOfCatalog(true);
 0551            HUDController.i.builderInWorldMainHud.SetVisibilityOfInspector(true);
 552        }
 553
 0554        CommonScriptableObjects.builderInWorldNotNecessaryUIVisibilityStatus.Set(false);
 0555        DataStore.i.builderInWorld.showTaskBar.Set(true);
 556
 0557        DCLCharacterController.OnPositionSet += ExitAfterCharacterTeleport;
 558
 0559        EnterBiwControllers();
 0560        Environment.i.world.sceneController.ActivateBuilderInWorldEditScene();
 561
 0562        initialLoadingController.SetPercentage(100f);
 563
 0564        if (IsNewScene())
 565        {
 0566            biwFloorHandler.OnAllParcelsFloorLoaded -= OnAllParcelsFloorLoaded;
 0567            biwFloorHandler.OnAllParcelsFloorLoaded += OnAllParcelsFloorLoaded;
 0568            SetupNewScene();
 0569        }
 570        else
 571        {
 0572            initialLoadingController.Hide(onHideAction: () =>
 573            {
 0574                inputController.inputTypeMode = InputTypeMode.BUILD_MODE;
 0575                HUDController.i.builderInWorldMainHud?.SetVisibility(true);
 0576                CommonScriptableObjects.allUIHidden.Set(previousAllUIHidden);
 0577                OpenNewProjectDetailsIfNeeded();
 0578            });
 579        }
 580
 0581        isBuilderInWorldActivated = true;
 582
 0583        previousSkyBoxMaterial = RenderSettings.skybox;
 0584        RenderSettings.skybox = skyBoxMaterial;
 585
 0586        foreach (var groundVisual in groundVisualsGO)
 587        {
 0588            groundVisual.SetActive(false);
 589        }
 0590        startEditorTimeStamp = Time.realtimeSinceStartup;
 0591        OnEnterEditMode?.Invoke();
 592
 0593        BIWAnalytics.AddSceneInfo(sceneToEdit.sceneData.basePosition, BuilderInWorldUtils.GetLandOwnershipType(landsWith
 0594        BIWAnalytics.EnterEditor( Time.realtimeSinceStartup - beginStartFlowTimeStamp);
 0595    }
 596
 597    private void OnAllParcelsFloorLoaded()
 598    {
 0599        if (!initialLoadingController.isActive)
 0600            return;
 601
 0602        biwFloorHandler.OnAllParcelsFloorLoaded -= OnAllParcelsFloorLoaded;
 0603        initialLoadingController.Hide(onHideAction: () =>
 604        {
 0605            inputController.inputTypeMode = InputTypeMode.BUILD_MODE;
 0606            HUDController.i.builderInWorldMainHud.SetVisibility(true);
 0607            CommonScriptableObjects.allUIHidden.Set(previousAllUIHidden);
 0608            OpenNewProjectDetailsIfNeeded();
 0609        });
 0610    }
 611
 612    private void OpenNewProjectDetailsIfNeeded()
 613    {
 0614        if (builderInWorldBridge.builderProject.isNewEmptyProject)
 0615            editorMode.OpenNewProjectDetails();
 0616    }
 617
 618    public void StartExitMode()
 619    {
 0620        if (biwSaveController.numberOfSaves > 0)
 621        {
 0622            editorMode.TakeSceneScreenshotForExit();
 623
 0624            HUDController.i.builderInWorldMainHud.ConfigureConfirmationModal(
 625                BuilderInWorldSettings.EXIT_MODAL_TITLE,
 626                BuilderInWorldSettings.EXIT_WITHOUT_PUBLISH_MODAL_SUBTITLE,
 627                BuilderInWorldSettings.EXIT_WITHOUT_PUBLISH_MODAL_CANCEL_BUTTON,
 628                BuilderInWorldSettings.EXIT_WITHOUT_PUBLISH_MODAL_CONFIRM_BUTTON);
 0629        }
 630        else
 631        {
 0632            HUDController.i.builderInWorldMainHud.ConfigureConfirmationModal(
 633                BuilderInWorldSettings.EXIT_MODAL_TITLE,
 634                BuilderInWorldSettings.EXIT_MODAL_SUBTITLE,
 635                BuilderInWorldSettings.EXIT_MODAL_CANCEL_BUTTON,
 636                BuilderInWorldSettings.EXIT_MODAL_CONFIRM_BUTTON);
 637        }
 0638    }
 639
 640    public void ExitEditMode()
 641    {
 0642        Environment.i.platform.cullingController.Start();
 643
 0644        biwFloorHandler.OnAllParcelsFloorLoaded -= OnAllParcelsFloorLoaded;
 0645        initialLoadingController.Hide(true);
 0646        inputController.inputTypeMode = InputTypeMode.GENERAL;
 647
 0648        CommonScriptableObjects.builderInWorldNotNecessaryUIVisibilityStatus.Set(true);
 0649        DataStore.i.builderInWorld.showTaskBar.Set(true);
 0650        snapGO.transform.SetParent(transform);
 651
 0652        ParcelSettings.VISUAL_LOADING_ENABLED = true;
 653
 0654        outlinerController.CancelAllOutlines();
 655
 0656        cursorGO.SetActive(true);
 657
 0658        sceneToEdit.SetEditMode(false);
 659
 0660        DCLCharacterController.OnPositionSet -= ExitAfterCharacterTeleport;
 661
 0662        InmediateExit();
 663
 0664        if (HUDController.i.builderInWorldMainHud != null)
 665        {
 0666            HUDController.i.builderInWorldMainHud.ClearEntityList();
 0667            HUDController.i.builderInWorldMainHud.SetVisibility(false);
 668        }
 669
 0670        Environment.i.world.sceneController.DeactivateBuilderInWorldEditScene();
 0671        Environment.i.world.blockersController.SetEnabled(true);
 672
 0673        ExitBiwControllers();
 674
 0675        if (biwSaveController.numberOfSaves > 0)
 676        {
 0677            HUDController.i.builderInWorldMainHud?.SaveSceneInfo();
 0678            biwSaveController.ResetNumberOfSaves();
 679        }
 680
 0681        foreach (var groundVisual in groundVisualsGO)
 682        {
 0683            groundVisual.SetActive(true);
 684        }
 685
 0686        isBuilderInWorldActivated = false;
 0687        RenderSettings.skybox = previousSkyBoxMaterial;
 688
 0689        OnExitEditMode?.Invoke();
 0690        DataStore.i.appMode.Set(AppMode.DEFAULT);
 0691        BIWAnalytics.ExitEditor(Time.realtimeSinceStartup - startEditorTimeStamp);
 0692    }
 693
 694    public void InmediateExit()
 695    {
 0696        CommonScriptableObjects.allUIHidden.Set(previousAllUIHidden);
 0697        builderInWorldBridge.ExitKernelEditMode(sceneToEdit);
 0698    }
 699
 700    public void EnterBiwControllers()
 701    {
 0702        biwModeController.EnterEditMode(sceneToEdit);
 0703        builderInWorldEntityHandler.EnterEditMode(sceneToEdit);
 0704        biwFloorHandler.EnterEditMode(sceneToEdit);
 0705        biwCreatorController.EnterEditMode(sceneToEdit);
 0706        biwPublishController.EnterEditMode(sceneToEdit);
 0707        bIWInputHandler.EnterEditMode(sceneToEdit);
 0708        outlinerController.EnterEditMode(sceneToEdit);
 0709        biwSaveController.EnterEditMode(sceneToEdit);
 0710        actionController.EnterEditMode(sceneToEdit);
 0711        biwAudioHandler.EnterEditMode(sceneToEdit);
 0712    }
 713
 714    public void ExitBiwControllers()
 715    {
 0716        biwModeController.ExitEditMode();
 0717        builderInWorldEntityHandler.ExitEditMode();
 0718        biwFloorHandler.ExitEditMode();
 0719        biwCreatorController.ExitEditMode();
 0720        biwPublishController.ExitEditMode();
 0721        bIWInputHandler.ExitEditMode();
 0722        outlinerController.ExitEditMode();
 0723        biwSaveController.ExitEditMode();
 0724        actionController.ExitEditMode();
 0725        biwAudioHandler.ExitEditMode();
 0726    }
 727
 0728    public bool IsNewScene() { return sceneToEdit.entities.Count <= 0; }
 729
 0730    public void SetupNewScene() { biwFloorHandler.CreateDefaultFloor(); }
 731
 0732    void ExitAfterCharacterTeleport(DCLCharacterPosition position) { ExitEditMode(); }
 733
 734    public void FindSceneToEdit(IParcelScene targetScene)
 735    {
 0736        if (targetScene != null)
 737        {
 0738            var parcelSceneTarget = (ParcelScene)targetScene;
 0739            if (sceneToEdit != null && sceneToEdit != parcelSceneTarget)
 0740                actionController.Clear();
 741
 0742            sceneToEdit = parcelSceneTarget;
 0743        }
 744        else
 745        {
 0746            FindSceneToEdit();
 747        }
 0748    }
 749
 750    public void FindSceneToEdit()
 751    {
 36752        foreach (IParcelScene scene in Environment.i.world.state.scenesSortedByDistance)
 753        {
 9754            if (WorldStateUtils.IsCharacterInsideScene(scene))
 755            {
 0756                ParcelScene parcelScene = (ParcelScene)scene;
 757
 0758                if (sceneToEdit != null && sceneToEdit != parcelScene)
 0759                    actionController.Clear();
 760
 0761                sceneToEdit = parcelScene;
 0762                break;
 763            }
 764        }
 9765    }
 766
 767    private void OnPlayerTeleportedToEditScene(Vector2Int coords)
 768    {
 0769        if (activeFeature)
 770        {
 0771            var targetScene = Environment.i.world.state.scenesSortedByDistance
 0772                                         .FirstOrDefault(scene => scene.sceneData.parcels.Contains(coords));
 0773            TryStartEnterEditMode(targetScene);
 774        }
 0775    }
 776
 0777    private void UpdateCatalogLoadingProgress(float catalogLoadingProgress) { initialLoadingController.SetPercentage(cat
 778
 0779    private void UpdateSceneLoadingProgress(float sceneLoadingProgress) { initialLoadingController.SetPercentage(50f + (
 780
 781    private void OnUserProfileUpdate(UserProfile user)
 782    {
 0783        userProfile.OnUpdate -= OnUserProfileUpdate;
 0784        updateLandsWithAcessCoroutine = CoroutineStarter.Start(CheckLandsAccess());
 0785    }
 786
 787    private IEnumerator CheckLandsAccess()
 788    {
 0789        while (true)
 790        {
 0791            UpdateLandsWithAccess();
 0792            yield return WaitForSecondsCache.Get(BuilderInWorldSettings.REFRESH_LANDS_WITH_ACCESS_INTERVAL);
 793        }
 794    }
 795
 796    private void UpdateLandsWithAccess()
 797    {
 0798        if (isBuilderInWorldActivated)
 0799            return;
 800
 0801        DeployedScenesFetcher.FetchLandsFromOwner(
 802                                 Environment.i.platform.serviceProviders.catalyst,
 803                                 Environment.i.platform.serviceProviders.theGraph,
 804                                 userProfile.ethAddress,
 805                                 KernelConfig.i.Get().tld,
 806                                 BuilderInWorldSettings.CACHE_TIME_LAND,
 807                                 BuilderInWorldSettings.CACHE_TIME_SCENES)
 0808                             .Then(lands => landsWithAccess = lands.ToList());
 0809    }
 810
 811    private static void ShowGenericNotification(string message)
 812    {
 0813        Notification.Model notificationModel = new Notification.Model();
 0814        notificationModel.message = message;
 0815        notificationModel.type = NotificationFactory.Type.GENERIC;
 0816        notificationModel.timer = BuilderInWorldSettings.LAND_NOTIFICATIONS_TIMER;
 0817        HUDController.i.notificationHud.ShowNotification(notificationModel);
 0818    }
 819}