Example #1
0
        public static void CreateImageList()
        {
            string path = EditorUtility.OpenFolderPanel("Select Image Folder", "", "");

            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            // read existing mod file if existent
            ModdingData md      = new ModdingData();
            string      modFile = path + "/" + SDKUtil.MODFILE_NAME;

            if (File.Exists(modFile))
            {
                md = SDKUtil.ReadJSONFileDirect <ModdingData>(modFile);
            }
            if (md.imageData == null)
            {
                md.imageData = new List <ImageData>();
            }

            // gather images
            IEnumerable <string> files = DirectoryUtil.GetFiles(path, new[] { "*.png", "*.jpg" });

            foreach (string file in files)
            {
                string fileName = Path.GetFileName(file);
                if (md.imageData.Any(id => id.imageLink == fileName))
                {
                    continue;
                }

                string name = Path.GetFileNameWithoutExtension(fileName);
                if (DateTime.TryParseExact(SDKUtil.MaxLength(name, 19), "yyyy-MM-dd HH.mm.ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime))
                {
                    name = dateTime.ToLongDateString() + " " + dateTime.ToShortTimeString();
                }
                md.imageData.Add(new ImageData(fileName, name));
            }

            File.WriteAllText(modFile, SDKUtil.SerializeObject(md));

            EditorUtility.DisplayDialog("Done", $"Found {md.imageData.Count} images. Check modding.json in target folder.", "OK");
        }
Example #2
0
        public Zone(Zone copyFrom) : this()
        {
            name                  = copyFrom.name;
            minSize               = copyFrom.minSize;
            curSize               = copyFrom.curSize;
            offset                = copyFrom.offset;
            offsetRaw             = copyFrom.offsetRaw;
            scenePath             = copyFrom.scenePath;
            availableTime         = copyFrom.availableTime;
            hasAmbientColor       = copyFrom.hasAmbientColor;
            hasBackgroundColor    = copyFrom.hasBackgroundColor;
            hasLightColor         = copyFrom.hasLightColor;
            hasLightIntensity     = copyFrom.hasLightIntensity;
            ambientColor          = copyFrom.ambientColor;
            lightColor            = copyFrom.lightColor;
            lightIntensity        = copyFrom.lightIntensity;
            backgroundColor       = copyFrom.backgroundColor;
            chapter               = copyFrom.chapter;
            createCheckpoint      = copyFrom.createCheckpoint;
            isExit                = copyFrom.isExit;
            isIntro               = copyFrom.isIntro;
            reactivateTransitions = copyFrom.reactivateTransitions;
            invisibleGround       = copyFrom.invisibleGround;
            music                 = copyFrom.music;
            randomMusic           = copyFrom.randomMusic;
            skybox                = copyFrom.skybox;
            blockAgents           = copyFrom.blockAgents;
            variationOf           = copyFrom.variationOf;
            originalName          = copyFrom.originalName;
            properties            = SDKUtil.CopyProperties(copyFrom.properties);

            foreach (Floor floor in copyFrom.floors)
            {
                Floor copy = new Floor(floor);
                copy.positionInfoMarker = floor.positionInfoMarker; // FIXME: quick-fix for retaining challenge mode correctly until copy-constructor for position info exists

                floors.Add(copy);
            }
        }
Example #3
0
        public override void OnGUI()
        {
            // independent of actual window
            if (uploadInProgress)
            {
                int timeRemaining = Mathf.Max(1, Mathf.RoundToInt((DateTime.Now.Subtract(uploadStartTime).Seconds / uploadProgress) * (1 - uploadProgress)));
                Progress.SetRemainingTime(uploadProgressId, timeRemaining);
                Progress.Report(uploadProgressId, uploadProgress, "Uploading worlds to server...");
            }
            base.OnGUI();

            GUILayout.Label("Packaging ensures that the editor shows the most up to date version of your world.", EditorStyles.wordWrappedLabel);

            // TODO: cache
            string[] worlds = GetWorldPaths();
            if (worlds.Length == 0)
            {
                EditorGUILayout.Space();
                EditorGUILayout.HelpBox("There are no worlds created yet. Use the Setup tool to create one.", MessageType.Info);
            }
            else
            {
                if (worlds.Length > 1)
                {
                    EditorGUILayout.Space();
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Packaging Mode:", EditorStyles.wordWrappedLabel);
                    packageMode = EditorGUILayout.Popup(packageMode, PACKAGE_OPTIONS);
                    GUILayout.EndHorizontal();
                }
                else
                {
                    packageMode = 0;
                }

                EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress);
                string buttonText = "Package";
                if (packageMode == 1)
                {
                    string[] worldsToBuild = GetWorldsToBuild(packageMode).Select(Path.GetFileName).ToArray();
                    buttonText += " (" + ((dirWatcher.affectedFiles.Count > 0) ? string.Join(", ", worldsToBuild) : "everything") + ")";
                }

                if (GUILayout.Button(buttonText))
                {
                    EditorCoroutineUtility.StartCoroutine(PackageWorlds(packageMode, releaseChannel, packageMode == 2, packageMode == 2), this);
                }
                EditorGUI.EndDisabledGroup();

                EditorGUILayout.Space();
                GUILayout.Label("To test inside the Quest or to make the world accessible to others, upload it to the traVRsal server.", EditorStyles.wordWrappedLabel);

                GUILayout.BeginHorizontal();
                GUILayout.Label("Release Channel:", EditorStyles.wordWrappedLabel);
                releaseChannel = EditorGUILayout.Popup(releaseChannel, RELEASE_CHANNELS);

                EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || verifyInProgress || documentationInProgress);
                if (GUILayout.Button("Prepare Upload"))
                {
                    EditorCoroutineUtility.StartCoroutine(PrepareUpload(), this);
                }
                EditorGUI.EndDisabledGroup();
                GUILayout.EndHorizontal();

                CheckTokenGUI();
                if (worldListMismatch && !SDKUtil.networkIssue)
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.HelpBox("The worlds inside your Worlds folder do not match your registered worlds on www.traVRsal.com. You probably need to rename these locally to match exactly.", MessageType.Error);
                    if (GUILayout.Button("Refresh"))
                    {
                        EditorCoroutineUtility.StartCoroutine(RefreshVerify(), this);
                    }
                }

                if (uncompressedTextures > 0)
                {
                    EditorGUILayout.Space();
                    GUILayout.BeginHorizontal();
                    EditorGUILayout.HelpBox("Uncompressed Textures in Project: " + uncompressedTextures, MessageType.Warning);
                    if (GUILayout.Button("Fix"))
                    {
                        EditorCoroutineUtility.StartCoroutine(CompressTextures(), this);
                    }
                    GUILayout.EndHorizontal();
                }

                if (verifications.Count > 0)
                {
                    EditorGUILayout.Space();
                    GUILayout.Label("Verification Results", EditorStyles.boldLabel);

                    foreach (string dir in GetWorldPaths())
                    {
                        string worldName = Path.GetFileName(dir);
                        if (!verifications.ContainsKey(worldName))
                        {
                            continue;
                        }

                        VerificationResult v = verifications[worldName];

                        v.showDetails = EditorGUILayout.Foldout(v.showDetails, worldName);

                        if (v.showDetails)
                        {
                            PrintTableRow("Size (Quest)", v.distroExistsAndroid ? SDKUtil.BytesToString(v.distroSizeAndroid) : "not packaged yet");
                            PrintTableRow("Size (Windows)", v.distroExistsStandaloneWin ? SDKUtil.BytesToString(v.distroSizeStandaloneWin) : "not packaged yet");
                            if (linuxSupport)
                            {
                                PrintTableRow("Size (Linux)", v.distroExistsStandaloneLinux ? SDKUtil.BytesToString(v.distroSizeStandaloneLinux) : "not packaged yet");
                            }
                            if (v.documentationExists)
                            {
                                BeginPartialTableRow("Documentation");
                                if (GUILayout.Button("Open"))
                                {
                                    Help.BrowseURL(GetDocuPath(worldName) + "index.html");
                                }
                                EndPartialTableRow();
                            }
                            else
                            {
                                PrintTableRow("Documentation", "not created yet");
                            }
                            BeginPartialTableRow("Actions");
                            EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || !uploadPossible);
                            if (GUILayout.Button("Upload"))
                            {
                                EditorCoroutineUtility.StartCoroutine(UploadWorld(worldName), this);
                            }
                            if (debugMode && GUILayout.Button("Register"))
                            {
                                EditorCoroutineUtility.StartCoroutine(PublishWorldUpdates(worldName), this);
                            }
                            EditorGUI.EndDisabledGroup();
                            EndPartialTableRow();
                        }
                    }
                }

                if (debugMode)
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.HelpBox("Debug mode is enabled.", MessageType.Warning);

                    EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || verifyInProgress || documentationInProgress);
                    if (GUILayout.Button("Create Documentation"))
                    {
                        EditorCoroutineUtility.StartCoroutine(CreateDocumentation(), this);
                    }
                    EditorGUI.EndDisabledGroup();
                }
            }

            OnGUIDone();
        }
Example #4
0
        private static bool UpdateWorldData(string worldName)
        {
            string root  = GetWorldsRoot() + "/" + worldName + "/";
            World  world = SDKUtil.ReadJSONFileDirect <World>(root + "World.json");

            if (world == null)
            {
                EditorUtility.DisplayDialog("Error", $"World.json file for {worldName} seems corrupted and needs to be fixed first.", "OK");
                return(false);
            }

            string worldBasePath = Path.GetDirectoryName(AssetDatabase.GUIDToAssetPath(AssetDatabase.AssetPathToGUID(root + "World.json"))) + "/Pieces";

            world.objectSpecs = new List <ObjectSpec>();
            string[] assets = AssetDatabase.FindAssets("*", new[] { root + "Pieces" });
            foreach (string asset in assets)
            {
                string assetPath = AssetDatabase.GUIDToAssetPath(asset);
                if (!assetPath.ToLower().EndsWith(".prefab"))
                {
                    continue;
                }

                GameObject prefab = PrefabUtility.LoadPrefabContents(assetPath);
                if (prefab.TryGetComponent(out ExtendedAttributes ea))
                {
                    if (!ea.spec.IsDefault())
                    {
                        string prefix = Path.GetDirectoryName(assetPath);
                        if (prefix != null && prefix.Length > worldBasePath.Length)
                        {
                            prefix = prefix.Substring(worldBasePath.Length + 1) + "/";
                            prefix = prefix.Replace('\\', '/');
                        }
                        else
                        {
                            prefix = "";
                        }

                        string fileName = Path.GetFileNameWithoutExtension(assetPath);
                        ea.spec.objectKey = prefix + fileName;
                        world.objectSpecs.Add(ea.spec);
                    }
                }
                if (prefab != null)
                {
                    PrefabUtility.UnloadPrefabContents(prefab);
                }
            }

            // increase version
            if (string.IsNullOrEmpty(world.version))
            {
                world.version = "0.0.1";
            }
            else
            {
                if (Version.TryParse(world.version, out Version version))
                {
                    world.version = $"{version.Major}.{version.Minor}.{version.Build + 1}";
                }
                else
                {
                    world.version = "0.0.1";
                    Debug.LogError($"World.json of {worldName} contained an unreadable version. Resetting to {world.version}.");
                }
            }
            world.versionCode++;

            // write back
            world.NullifyEmpties();
            File.WriteAllText(root + "World.json", SDKUtil.SerializeObject(world));

            return(true);
        }
Example #5
0
        private void ManipulateWorld(string command)
        {
            World world = LoadWorld();

            if (world == null)
            {
                return;
            }

            switch (command)
            {
            case "SetToCurrentVersion":
                PackageInfo pi = PackageInfo.FindForAssetPath("Packages/com.wetzold.travrsal.sdk/package.json");
                if (pi != null)
                {
                    world.minVersion = pi.version;
                    EditorUtility.DisplayDialog("Success", $"Set minimum app version required to play the world to {pi.version}.", "OK");
                }
                break;

            case "AddZone":
                if (string.IsNullOrEmpty(zoneName))
                {
                    return;
                }
                string root = GetWorldPaths()[0];
                string path = $"{root}/Data/{zoneName}.tmx";
                if (File.Exists(path))
                {
                    EditorUtility.DisplayDialog("Error", "A zone with that name already exists.", "OK");
                    return;
                }
                AssetDatabase.CopyAsset($"Packages/{SDKUtil.PACKAGE_NAME}/Editor/CopyTemplates/EmptyZone.copy", $"Assets/Worlds/{world.key}/Data/{zoneName}.tmx");

                // two cases: either world explicitly lists files already or default is used with config.world mechanism
                if (world.worldData != null && world.worldData.Count > 0)
                {
                    world.worldData.Add(new WorldDataReference(path, WorldDataReference.ImportType.TileMap));
                }
                else
                {
                    string  mapFile  = root + "/Data/Config.world";
                    TMWorld worldMap = SDKUtil.ReadJSONFileDirect <TMWorld>(mapFile);
                    if (worldMap != null)
                    {
                        worldMap.maps = worldMap.maps.Append(new WorldMap(Path.GetFileName(path)));

                        File.WriteAllText(mapFile, SDKUtil.SerializeObject(worldMap));
                    }
                    else
                    {
                        EditorUtility.DisplayDialog("Error", $"Data/Config.world file for {world.key} does not exist. New zone was created but needs to be manually linked.", "OK");
                    }
                }
                zoneName = "";
                AssetDatabase.Refresh();
                break;

            case "AddVariable":
                if (string.IsNullOrEmpty(varName))
                {
                    return;
                }
                if (world.initialVariables == null)
                {
                    world.initialVariables = new List <Variable>();
                }
                world.initialVariables.Add(new Variable(varName));
                varName = "";
                break;

            case "AddSetting":
                if (string.IsNullOrEmpty(worldSetting))
                {
                    return;
                }
                if (world.settings == null)
                {
                    world.settings = new List <WorldSetting>();
                }
                world.settings.Add(new WorldSetting(worldSetting));
                worldSetting = "";
                break;

            case "AddCustomShader":
                if (string.IsNullOrEmpty(customShader))
                {
                    return;
                }
                if (world.customShaders == null)
                {
                    world.customShaders = new List <string>();
                }
                world.customShaders.Add(customShader);
                customShader = "";
                break;
            }

            SaveWorld(world);
        }
Example #6
0
 public string GetPersistedState()
 {
     return(SDKUtil.SerializeObject(this));
 }
Example #7
0
        public void LoadPersistedState(string state)
        {
            Variable v = SDKUtil.DeserializeObject <Variable>(state);

            Merge(v);
        }
Example #8
0
        public override void OnGUI()
        {
            // independent of actual window
            if (uploadInProgress)
            {
                int timeRemaining = Mathf.Max(1, Mathf.RoundToInt((DateTime.Now.Subtract(uploadStartTime).Seconds / uploadProgress) * (1 - uploadProgress)));
                EditorUtility.DisplayProgressBar("Progress", "Uploading levels to server... " + timeRemaining + "s", uploadProgress);
            }
            base.OnGUI();

            GUILayout.Label("Packaging ensures that the editor shows the most up to date version of your level.", EditorStyles.wordWrappedLabel);

            GUILayout.Space(10);
            GUILayout.BeginHorizontal();
            GUILayout.Label("Packaging Mode:", EditorStyles.wordWrappedLabel);
            packageMode = GUILayout.SelectionGrid(packageMode, PACKAGE_OPTIONS, 2, EditorStyles.radioButton);
            GUILayout.EndHorizontal();

            EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress);
            string buttonText = "Package";

            if (packageMode == 1)
            {
                string[] levelsToBuild = GetLevelsToBuild().Select(path => Path.GetFileName(path)).ToArray();
                buttonText += " (" + ((dirWatcher.affectedFiles.Count > 0) ? string.Join(", ", levelsToBuild) : "everything") + ")";
            }
            if (GUILayout.Button(buttonText))
            {
                EditorCoroutineUtility.StartCoroutine(PackageLevels(packageMode == 2 ? true : false, packageMode == 2 ? true : false), this);
            }
            EditorGUI.EndDisabledGroup();

            GUILayout.BeginHorizontal();
            EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || verifyInProgress);
            if (GUILayout.Button("Prepare Upload"))
            {
                EditorCoroutineUtility.StartCoroutine(PrepareUpload(), this);
            }
            EditorGUI.EndDisabledGroup();

            EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || !uploadPossible);
            if (GUILayout.Button("Upload"))
            {
                EditorCoroutineUtility.StartCoroutine(UploadLevels(), this);
            }
            EditorGUI.EndDisabledGroup();

            GUILayout.EndHorizontal();

            if (verifications.Count() > 0)
            {
                GUILayout.Space(10);
                GUILayout.Label("Verification Results", EditorStyles.boldLabel);

                foreach (string dir in GetLevelPaths())
                {
                    string levelName = Path.GetFileName(dir);
                    if (!verifications.ContainsKey(levelName))
                    {
                        continue;
                    }

                    VerificationResult v = verifications[levelName];

                    v.showDetails = EditorGUILayout.Foldout(v.showDetails, levelName);

                    if (v.showDetails)
                    {
                        // PrintTableRow("Size (Original)", SDKUtil.BytesToString(v.sourceSize));
                        PrintTableRow("Size (Quest)", v.distroExistsAndroid ? SDKUtil.BytesToString(v.distroSizeAndroid) : "not packaged yet");
                        PrintTableRow("Size (PC)", v.distroExistsStandalone ? SDKUtil.BytesToString(v.distroSizeStandalone) : "not packaged yet");
                        if (v.documentationExists)
                        {
                            BeginPartialTableRow("Documentation");
                            if (GUILayout.Button("Open"))
                            {
                                Help.BrowseURL(GetDocuPath(levelName) + "index.html");
                            }
                            EndPartialTableRow();
                        }
                        else
                        {
                            PrintTableRow("Documentation", "not created yet");
                        }
                    }
                }
            }

            if (debugMode)
            {
                EditorGUI.BeginDisabledGroup(documentationInProgress);
                if (GUILayout.Button("Create Documentation"))
                {
                    EditorCoroutineUtility.StartCoroutine(CreateDocumentation(), this);
                }
                EditorGUI.EndDisabledGroup();
            }

            OnGUIDone();
        }