Beispiel #1
0
        /// <summary>
        ///     Calculate the checksum for a LEGO Universe zone
        /// </summary>
        /// <param name="zone">Path to zone file</param>
        /// <returns>Calculated checksum</returns>
        public static uint Generate(string zone)
        {
            uint value = ushort.MaxValue; // For checksum calculations
            uint total = ushort.MaxValue; // Sum of all changes applied to value

            //
            // Read zone file
            //

            var luz = new LuzFile();

            using (var stream = File.OpenRead(zone))
            {
                using var reader = new BitReader(stream);

                luz.Deserialize(reader);
            }

            //
            // Apply zone layer
            //

            var zoneLayer = new ChecksumLayer
            {
                Id       = uint.MaxValue,
                Layer    = default,
Beispiel #2
0
        public static uint GenerateChecksum(this LuzFile @this, List <LvlFile> scenes)
        {
            if (@this.Scenes.Length != scenes.Count)
            {
                throw new ArgumentOutOfRangeException(nameof(scenes), "The count of scenes has to equal the count of scenes in this luz file.");
            }

            uint value = ushort.MaxValue; // For checksum calculations
            uint total = ushort.MaxValue; // Sum of all changes applied to value

            var zoneLayer = new ChecksumLayer
            {
                Id       = uint.MaxValue,
                Layer    = default,
Beispiel #3
0
        public async Task SaveAsync(string path)
        {
            var file = new LuzFile
            {
                TerrainFile        = Terrain.Name,
                TerrainFileName    = Terrain.FileName,
                TerrainDescription = Terrain.Description,
                Version            = 0x26,
                SpawnPoint         = SpawnPosition,
                SpawnRotation      = SpawnRotation,
                WorldId            = Id,
                Scenes             = Scenes.Select(s => s.LuzScene).ToArray(),
                RevisionNumber     = Revision
            };

            var zoneFile = Path.Combine(path, Name);

            var root = Path.GetDirectoryName(zoneFile);

            if (!Directory.Exists(root))
            {
                Directory.CreateDirectory(root);
            }

            await using var stream = File.Create(zoneFile);

            using var writer = new BitWriter(stream);

            file.Serialize(writer);

            foreach (var scene in Scenes)
            {
                await scene.SaveAsync(Path.Combine(path, Path.GetDirectoryName(Name)));
            }

            await Terrain.SaveAsync(root);
        }
        public static GameObject Import(string workingFile)
        {
            const float scale = 3.125f;

            using var stream = File.OpenRead(workingFile);
            using var reader = new BitReader(stream);

            var zone = new LuzFile();

            zone.Deserialize(reader);

            return(null);

            var zoneInstance = new GameObject($"Zone {Path.GetFileName(workingFile)}");

            var zoneDetails = zoneInstance.AddOrGetComponent <ZoneDetails>();

            zoneDetails.ZoneName = Path.GetFileName(workingFile);

            zoneDetails.ZoneId = zone.WorldId;

            var spawnPoint = new GameObject("Zone Spawnpoint");

            spawnPoint.transform.parent = zoneInstance.transform;

            spawnPoint.transform.position = new Vector3(zone.SpawnPoint.X, zone.SpawnPoint.Y, zone.SpawnPoint.Z);
            spawnPoint.transform.rotation = new Quaternion(zone.SpawnRotation.X, zone.SpawnRotation.Y, zone.SpawnRotation.Z, zone.SpawnRotation.W);

            zoneDetails.SpawnPoint = spawnPoint.transform;

            var sourceDir = Path.GetDirectoryName(workingFile) ?? WorkspaceControl.CurrentWorkspace.AssetPath;

            var terrain = TerrainInterface.Import(Path.Combine(
                                                      sourceDir,
                                                      zone.TerrainFileName)
                                                  );

            terrain.transform.parent = zoneInstance.transform;

            foreach (var sceneInfo in zone.Scenes)
            {
                var scenePath = Path.Combine(sourceDir, sceneInfo.FileName);

                var sceneInstance = new GameObject($"Scene {sceneInfo.SceneName} ({sceneInfo.SceneId}, {sceneInfo.LayerId})");

                var sceneDetails = sceneInstance.AddOrGetComponent <SceneDetails>();

                sceneInstance.transform.parent = zoneInstance.transform;

                using var lvlStream = File.OpenRead(scenePath);
                using var lvlReader = new BitReader(lvlStream);

                var lvl = new LvlFile();

                lvl.Deserialize(lvlReader);

                sceneDetails.SceneName = sceneInfo.SceneName;

                sceneDetails.SceneLayer = sceneInfo.LayerId;

                sceneDetails.SkyBox = lvl.LevelSkyConfig == null ? sceneDetails.SkyBox : lvl.LevelSkyConfig.Skybox;

                if (lvl.LevelObjects == null)
                {
                    continue;
                }

                foreach (var template in lvl.LevelObjects.Templates)
                {
                    GameObject lwoObject;

                    try
                    {
                        lwoObject = ObjectInterface.Import(template.Lot, out var error);

                        if (lwoObject == null)
                        {
                            Debug.LogError(error);

                            continue;
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e);

                        continue;
                    }

                    lwoObject.transform.parent = sceneInstance.transform;

                    lwoObject.transform.position = new Vector3(template.Position.X, template.Position.Y, template.Position.Z);
                    lwoObject.transform.rotation = new Quaternion(template.Rotation.X, template.Rotation.Y, template.Rotation.Z, template.Rotation.W);
                }
            }

            return(zoneInstance);
        }
Beispiel #5
0
        public async Task LoadZoneDataAsync(int seek)
        {
            Zones.Clear();

            Logger.Information("Parsing zone info...");

            var zone = await ClientCache.FindAsync <ZoneTable>(seek);

            if (zone == default)
            {
                Logger.Error($"Cannot find zone {seek}");
                return;
            }
            ;

            var luzFile = Path.Combine("maps", zone.ZoneName.ToLower());

            if (!luzFile.EndsWith(".luz"))
            {
                return;
            }

            Logger.Information($"Parsing: {luzFile}");

            try
            {
                var luz = new LuzFile();

                await using var stream = _resources.GetStream(luzFile);

                var reader = new BitReader(stream);

                luz.Deserialize(reader);

                var path = Path.GetDirectoryName(luzFile);

                var lvlFiles = new List <LvlFile>();

                foreach (var scene in luz.Scenes)
                {
                    await using var sceneStream = _resources.GetStream(Path.Combine(path, scene.FileName));

                    using var sceneReader = new BitReader(sceneStream);

                    Logger.Information($"Parsing: {scene.FileName}");

                    var lvl = new LvlFile();

                    lvl.Deserialize(sceneReader);

                    lvlFiles.Add(lvl);

                    if (lvl.LevelObjects?.Templates == default)
                    {
                        continue;
                    }

                    foreach (var template in lvl.LevelObjects.Templates)
                    {
                        template.ObjectId |= 70368744177664;
                    }
                }

                var terrainStream = _resources.GetStream(Path.Combine(path, luz.TerrainFileName));

                using var terrainReader = new BitReader(terrainStream);

                var terrain = new TerrainFile();

                terrain.Deserialize(terrainReader);

                var triggers = await TriggerDictionary.FromDirectoryAsync(Path.Combine(_resources.RootPath, path));

                Logger.Information($"Parsed: {seek}");

                Zones[seek] = new ZoneInfo
                {
                    LuzFile           = luz,
                    LvlFiles          = lvlFiles,
                    TriggerDictionary = triggers,
                    TerrainFile       = terrain
                };
            }
            catch (Exception e)
            {
                Logger.Error($"Failed to parse {luzFile}: {e.Message}\n{e.StackTrace}");
            }
        }
Beispiel #6
0
        public static async Task ExportToWavefrontAsync(this LuzFile @this, AccessDatabase database, string source, string resources, string result)
        {
            TerrainFile terrain;

            await using (var stream = File.OpenRead(Path.Combine(source, @this.TerrainFileName)))
            {
                using var reader = new BitReader(stream);

                terrain = new TerrainFile();

                terrain.Deserialize(reader);
            }

            var levels = new LvlFile[@this.Scenes.Length];

            for (var i = 0; i < @this.Scenes.Length; i++)
            {
                var scene = @this.Scenes[i];

                await using var stream = File.OpenRead(Path.Combine(source, scene.FileName));

                using var reader = new BitReader(stream);

                var level = new LvlFile();

                level.Deserialize(reader);

                levels[i] = level;
            }

            var objects = new List <LevelObjectTemplate>();

            foreach (var level in levels)
            {
                if (level.LevelObjects?.Templates == default)
                {
                    continue;
                }

                foreach (var template in level.LevelObjects.Templates)
                {
                    if (!template.LegoInfo.TryGetValue("add_to_navmesh", out var add))
                    {
                        continue;
                    }

                    if (!(bool)add)
                    {
                        continue;
                    }

                    objects.Add(template);
                }
            }

            foreach (var template in objects)
            {
                var instance = database.LoadObject(template.Lot);

                var renderer = instance.GetComponent <RenderComponentTable>();

                if (renderer == default)
                {
                    continue;
                }

                Console.WriteLine(renderer.render_asset);
            }
        }
        public static async Task InsertAsync(string path)
        {
            LuzFile luz;

            await using (var stream = File.OpenRead(path))
            {
                using var reader = new BitReader(stream);

                luz = new LuzFile();

                luz.Deserialize(reader);
            }

            var worlds = Interface.Database["ZoneTable"];

            if (luz.WorldId == 0)
            {
                var attributes = File.GetAttributes(path);

                attributes &= ~FileAttributes.ReadOnly;

                File.SetAttributes(path, attributes);

                luz.WorldId = (uint)worlds.ClaimKey(100);

                await using var stream = File.Create(path);

                using var writer = new BitWriter(stream);

                luz.Serialize(writer);
            }

            var entry = worlds.FirstOrDefault(w => w.Key == luz.WorldId);

            if (entry != default)
            {
                if (entry.Value <string>("zoneName").StartsWith("ZoneTable"))
                {
                    worlds.Remove(entry);
                }
                else
                {
                    return;
                }
            }

            var rootPath = Path.GetDirectoryName(path);

            var terrain = await TerrainEditor.OpenAsync(Path.Combine(rootPath, luz.TerrainFileName));

            entry = worlds.Create(luz.WorldId);

            var root = new Uri(Path.Combine(Interface.Configuration.Output, "./maps/"));
            var map  = new Uri(path);

            var relative = root.MakeRelativeUri(map).ToString();

            Console.WriteLine($"Inserting: [{luz.WorldId}] {Path.GetFileName(path)} into {relative}");

            var _ = new ZoneTableTable(entry)
            {
                zoneName          = relative,
                ghostdistance     = 5000,
                zoneID            = (int)luz.WorldId,
                scriptID          = -1,
                ghostdistance_min = 150,
                heightInChunks    = terrain.Source.Height,
                widthInChunks     = terrain.Source.Weight,
                localize          = false,
                petsAllowed       = true,
                mountsAllowed     = true
            };
        }
Beispiel #8
0
        public async Task LoadZoneDataAsync(int seek)
        {
            Zones.Clear();

            var luzFiles = _resources.GetAllFilesWithExtension("luz");

            foreach (var luzFile in luzFiles)
            {
                Logger.Information($"Parsing: {luzFile}");

                try
                {
                    var luz = new LuzFile();

                    await using var stream = _resources.GetStream(luzFile);

                    var reader = new BitReader(stream);

                    luz.Deserialize(reader);

                    if (luz.WorldId != seek)
                    {
                        continue;
                    }

                    var path = Path.GetDirectoryName(luzFile);

                    var triggers = await GetTriggers(path);

                    var lvlFiles = new List <LvlFile>();

                    foreach (var scene in luz.Scenes)
                    {
                        await using var sceneStream = _resources.GetStream(Path.Combine(path, scene.FileName));

                        var sceneReader = new BitReader(sceneStream);

                        var lvl = new LvlFile();

                        lvl.Deserialize(sceneReader);

                        lvlFiles.Add(lvl);

                        if (lvl.LevelObjects?.Templates == default)
                        {
                            continue;
                        }

                        foreach (var template in lvl.LevelObjects.Templates)
                        {
                            template.ObjectId |= 70368744177664;
                        }
                    }

                    Logger.Information($"Parsed: {(ZoneId) luz.WorldId}");

                    Zones[(ZoneId)luz.WorldId] = new ZoneInfo
                    {
                        LuzFile  = luz,
                        LvlFiles = lvlFiles,
                        Triggers = triggers.ToList()
                    };
                }
                catch (Exception e)
                {
                    Logger.Error($"Failed to parse {luzFile}: {e.Message}\n{e.StackTrace}");
                }
            }
        }
Beispiel #9
0
    public override void OnImportAsset(AssetImportContext ctx)
    {
        _luzFile = new LuzFile($"{UniverseImporter.LuzImportDir}/{Path.GetFileName(ctx.assetPath)}");

        var luzAssetPath = $"{Path.GetDirectoryName(ctx.assetPath)}/{Path.GetFileNameWithoutExtension(ctx.assetPath)}";

        Directory.CreateDirectory(luzAssetPath);

        var objects     = UniverseImporter.Database.Tables.First(s => s.Name.ToLower() == "componentsregistry");
        var renderComps = UniverseImporter.Database.Tables.First(s => s.Name.ToLower() == "rendercomponent");

        var spawnPoint = new GameObject("Spawn Point");

        spawnPoint.transform.position = _luzFile.SpawnPoint;
        spawnPoint.transform.rotation = _luzFile.SpawnRotation;

        ctx.AddObjectToAsset("Spawn Point", spawnPoint);

        foreach (var lvlFile in _luzFile.LvlFiles)
        {
            foreach (var template in lvlFile.Chunks2001.SelectMany(c => c.Objects))
            {
                if (template.Ldf.TryGetValue("spawntemplate", out var realId))
                {
                    Debug.Log($"{template.Lot} is spawner");
                    template.Lot = (int)realId;
                    Debug.Log($"{template.Lot} came from spawner.");
                }

                /*
                 * else if (template.Ldf.TryGetValue("loadSrvrOnly", out var serverOnly) && (bool) serverOnly ||
                 *      template.Ldf.TryGetValue("carver_only", out var carverOnly) && (bool) carverOnly ||
                 *      template.Ldf.TryGetValue("renderDisabled", out var disabled) && (bool) disabled)
                 * {
                 *  continue;
                 * }
                 */

                var comps  = objects.Rows?.Where(r => r?.Fields[0]?.Value.ToString() == template.Lot.ToString()).ToArray();
                var render = comps?.FirstOrDefault(r => r.Fields[1].Value.ToString() == "2");
                if (render == null)
                {
                    continue;
                }
                var renderId = render.Fields[2].Value.ToString();

                var row = renderComps.Rows.First(s => s.Fields[0].Value.ToString() == renderId);

                var final = $"{Path.Combine(UniverseImporter.ResDir, row.Fields[1].Value.ToString())}";

                final = final.Replace(@"\\", "/").Replace("\\", "/");
                Debug.Log(final);
                try
                {
                    var nifPath = $"{luzAssetPath}/{Path.GetFileName(final)}";

                    if (!File.Exists(nifPath))
                    {
                        File.Copy(final, nifPath);

                        AssetDatabase.ImportAsset(nifPath);
                    }

                    var obj = (GameObject)PrefabUtility.InstantiatePrefab(
                        AssetDatabase.LoadAssetAtPath(nifPath, typeof(GameObject)));
                    obj.transform.localPosition = template.Position;
                    obj.transform.localRotation = template.Rotation;
                    obj.transform.localScale    = Vector3.one * template.Scale;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }

                Debug.Log(final);
            }
        }
    }
Beispiel #10
0
        public static async Task UpgradeZone(string path)
        {
            var origin = path;

            var id = Interface.Database["ZoneTable"].ClaimKey(100);

            path = Path.Combine(Interface.Configuration.Output, "maps", path);

            LuzFile luz;

            var root = Path.GetDirectoryName(path);

            await using (var stream = File.OpenRead(path))
            {
                using var reader = new BitReader(stream);

                luz = new LuzFile();

                luz.Deserialize(reader);
            }

            foreach (var scene in luz.Scenes)
            {
                LvlFile lvl;

                var scenePath = Path.Combine(root, scene.FileName);

                await using (var stream = File.OpenRead(scenePath))
                {
                    using var reader = new BitReader(stream);

                    lvl = new LvlFile();

                    lvl.Deserialize(reader);
                }

                if (lvl.IsOld)
                {
                    Console.WriteLine($"Converting {scene.SceneName} to new.");

                    lvl.ConvertToNew();

                    await using (var stream = File.Create(scenePath))
                    {
                        using var writer = new BitWriter(stream);

                        lvl.Serialize(writer);
                    }
                }

                var spawnPoint = lvl.LevelObjects?.Templates?.FirstOrDefault(l => l.Lot == 4945);

                if (spawnPoint == null)
                {
                    continue;
                }

                luz.SpawnPoint    = spawnPoint.Position;
                luz.SpawnRotation = spawnPoint.Rotation;
            }

            if (luz.Version < 0x26)
            {
                Console.WriteLine($"Converting {Path.GetFileName(path)} to new.");

                luz.Version = 0x26;

                luz.WorldId = (uint)id;

                await using (var stream = File.Create(path))
                {
                    using var writer = new BitWriter(stream);

                    luz.Serialize(writer);
                }
            }

            Console.WriteLine("Updating terrain.");

            var terrainPath = Path.Combine(root, luz.TerrainFileName);

            var terrain = await TerrainEditor.OpenAsync(terrainPath);

            foreach (var chunk in terrain.Source.Chunks)
            {
                for (var i = 0; i < chunk.ColorRelatedArray.Length; i++)
                {
                    chunk.ColorRelatedArray[i] = 1;
                }
            }

            await terrain.SaveAsync(terrainPath);

            Console.WriteLine($"Adding [{id}] {Path.GetFileName(path)} to database.");

            var zones = Interface.Database["ZoneTable"];

            var row = zones.Create(id);

            var _ = new ZoneTableTable(row)
            {
                zoneName      = origin,
                zoneID        = (int)luz.WorldId,
                ghostdistance = 500,
                scriptID      = -1,
                locStatus     = 0
            };
        }