/// <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,
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); }
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}"); } }
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 }; }
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}"); } } }
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 }; }