public override void Use(Player p, string message) { string[] args = message.Split(' '); string path = args.Length == 1 ? LevelInfo.LevelPath(args[0]) : LevelInfo.BackupPath(args[0], args[1]); Server.s.Log(path); if (!File.Exists(path)) { Player.SendMessage(p, "Level or backup could not be found."); return; } Level lvl = LvlFile.Load(name, path); lvl.setPhysics(0); lvl.backedup = true; lvl.permissionbuild = LevelPermission.Admin; lvl.jailx = (ushort)(lvl.spawnx * 32); lvl.jaily = (ushort)(lvl.spawny * 32); lvl.jailz = (ushort)(lvl.spawnz * 32); lvl.jailrotx = lvl.rotx; lvl.jailroty = lvl.roty; p.Loading = true; CmdReveal.DespawnEntities(p); Level oldLevel = p.level; p.level = lvl; p.SendMotd(); if (!p.SendRawMap(oldLevel, lvl)) { return; } ushort x = (ushort)((0.5 + lvl.spawnx) * 32); ushort y = (ushort)((1 + lvl.spawny) * 32); ushort z = (ushort)((0.5 + lvl.spawnz) * 32); p.aiming = false; Player.GlobalSpawn(p, x, y, z, lvl.rotx, lvl.roty, true); p.ClearBlockchange(); p.Loading = false; if (args.Length == 1) { lvl.name = "&cMuseum " + Server.DefaultColor + "(" + args[0] + ")"; } else { lvl.name = "&cMuseum " + Server.DefaultColor + "(" + args[0] + " " + args[1] + ")"; } if (!p.hidden) { Player.GlobalMessage(p.ColoredName + " %Swent to the " + lvl.name); } }
protected override void SaveUndoData(List <Player.UndoPos> buffer, string path) { UndoCacheNode node = new UndoCacheNode(); string lastLoggedName = ""; using (FileStream fs = File.Create(path)) { BinaryWriter w = new BinaryWriter(fs); long entriesPos = 0; ChunkHeader last = default(ChunkHeader); foreach (Player.UndoPos uP in buffer) { DateTime time = Server.StartTime.AddSeconds(uP.timeDelta); int timeDiff = (int)(time - last.BaseTime).TotalSeconds; if (last.LevelName != uP.mapName || timeDiff > (65535 >> 2) || last.Entries == ushort.MaxValue) { if (!LevelInfo.ExistsOffline(uP.mapName)) { if (uP.mapName != lastLoggedName) { lastLoggedName = uP.mapName; Server.s.Log("Missing map file \"" + lastLoggedName + "\", skipping undo entries"); } continue; } ushort width, height, length; LvlFile.LoadDimensions(LevelInfo.LevelPath(uP.mapName), out width, out height, out length); node.Width = width; node.Height = height; node.Length = length; WriteChunkEntries(w, last.Entries, entriesPos); node.MapName = uP.mapName; last = WriteEmptyChunk(w, node, time, ref entriesPos); } UndoCacheItem item = UndoCacheItem.Make(node, 0, uP); int flags = (item.Flags & 0xC000) | timeDiff; w.Write((ushort)flags); w.Write(item.Index); w.Write(item.Type); w.Write(item.NewType); last.Entries++; } if (last.Entries > 0) { WriteChunkEntries(w, last.Entries, entriesPos); } } }
public void FromOfflineLevel(string name) { this.name = name; LvlFile.LoadDimensions(LevelInfo.LevelPath(name), out Width, out Height, out Length); string path = LevelInfo.GetPropertiesPath(name); Server.s.Log(path); if (path != null) { PropertiesFile.Read(path, ParseProperty, '='); } path = "levels/level properties/" + name + ".env"; Server.s.Log(path); if (File.Exists(path)) { PropertiesFile.Read(path, ParseEnv, '='); } }
void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { RevertAndClearState(p, x, y, z); CatchPos cpos = (CatchPos)p.blockchangeObject; string path = LevelInfo.BackupPath(p.level.name, cpos.backup); try { using (Level other = LvlFile.Load("tempLevel", path)) { if (!CopyBlocks(p, other, x, y, z, cpos)) { return; } } if (p.staticCommands) { p.Blockchange += Blockchange1; } } catch (Exception ex) { Server.ErrorLog(ex); Server.s.Log("Restore selection failed"); } }
public async Task SaveAsync(string path) { var scene = LuzScene; var file = new LvlFile { LvlVersion = 0x26 }; if (Objects?.Count > 0) { file.LevelObjects = new LevelObjects(file.LvlVersion) { Templates = Objects.Select(o => o.Template).ToArray() }; } if (!string.IsNullOrWhiteSpace(SkyBox)) { var skyConfig = new LevelSkyConfig { Skybox = { [0] = SkyBox } }; file.LevelSkyConfig = skyConfig; } file.LevelInfo = new LevelInfo { RevisionNumber = Revision }; await using var stream = File.Create(Path.Combine(path, scene.FileName)); using var writer = new BitWriter(stream); file.Serialize(writer); }
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 LuzFile(string path) { var reader = new BinaryReader(File.OpenRead(path)); Version = reader.ReadUInt32(); if (Version >= 0x24) { reader.ReadUInt32(); } WorldId = reader.ReadUInt32(); if (Version >= 0x26) { SpawnPoint = new NiVector3(reader, null); SpawnRotation = new NiQuaternion(reader, null); } SceneCount = Version < 0x25 ? reader.ReadByte() : reader.ReadUInt32(); Scenes = new LuzScene[SceneCount]; LvlFiles = new LvlFile[SceneCount]; for (var i = 0; i < SceneCount; i++) { Scenes[i] = new LuzScene(reader); Debug.Log(Scenes[i].FileName); LvlFiles[i] = new LvlFile($"{Path.GetDirectoryName(path)}/{Scenes[i].FileName}"); } reader.ReadByte(); TerrainFileName = new NiString(reader, false, true); TerrainFile = new NiString(reader, false, true); TerrainDescription = new NiString(reader, false, true); if (Version >= 0x20) { SceneTransitionCount = reader.ReadUInt32(); Transitions = new LuzSceneTransition[SceneTransitionCount]; for (var i = 0; i < SceneTransitionCount; i++) { Transitions[i] = new LuzSceneTransition(reader, this); } } if (Version < 0x23) { return; } { reader.ReadUInt32(); reader.ReadUInt32(); PathDataCount = reader.ReadUInt32(); PathData = new LuzPathData[PathDataCount]; for (var i = 0; i < PathDataCount; i++) { var version = reader.ReadUInt32(); var name = new NiString(reader, true, true); var type = (PathType)reader.ReadUInt32(); reader.ReadUInt32(); switch (type) { case PathType.Movement: PathData[i] = new LuzPathData(reader, version, name, type); break; case PathType.MovingPlatform: PathData[i] = new LuzMovingPlatformPath(reader, version, name, type); break; case PathType.Property: PathData[i] = new LuzPropertyPath(reader, version, name, type); break; case PathType.Camera: PathData[i] = new LuzCameraPath(reader, version, name, type); break; case PathType.Spawner: PathData[i] = new LuzSpawnerPath(reader, version, name, type); break; case PathType.Showcase: PathData[i] = new LuzPathData(reader, version, name, type); break; case PathType.Race: PathData[i] = new LuzPathData(reader, version, name, type); break; case PathType.Rail: PathData[i] = new LuzPathData(reader, version, name, type); break; default: throw new ArgumentOutOfRangeException(); } var count = reader.ReadUInt32(); PathData[i].Waypoints = new LuzPathWaypoint[count]; for (var j = 0; j < count; j++) { switch (type) { case PathType.Movement: PathData[i].Waypoints[j] = new LuzMovementWaypoint(reader, PathData[i]); break; case PathType.MovingPlatform: PathData[i].Waypoints[j] = new LuzMovingPlatformWaypoint(reader, PathData[i]); break; case PathType.Property: PathData[i].Waypoints[j] = new LuzPathWaypoint(reader, PathData[i]); break; case PathType.Camera: PathData[i].Waypoints[j] = new LuzCameraWaypoint(reader, PathData[i]); break; case PathType.Spawner: PathData[i].Waypoints[j] = new LuzSpawnerWaypoint(reader, PathData[i]); break; case PathType.Showcase: PathData[i].Waypoints[j] = new LuzPathWaypoint(reader, PathData[i]); break; case PathType.Race: PathData[i].Waypoints[j] = new LuzRaceWaypoint(reader, PathData[i]); break; case PathType.Rail: PathData[i].Waypoints[j] = new LuzRailWaypoint(reader, PathData[i]); break; default: throw new ArgumentOutOfRangeException(); } } } } }
//givenName is safe against SQL injections, it gets checked in CmdLoad.cs public static Level Load(string givenName, byte phys) { if (LevelLoad != null) { LevelLoad(givenName); } OnLevelLoadEvent.Call(givenName); if (cancelload) { cancelload = false; return(null); } CreateLeveldb(givenName); string path = LevelInfo.LevelPath(givenName); if (File.Exists(path)) { try { Level level = LvlFile.Load(givenName, path); level.setPhysics(phys); level.backedup = true; using (DataTable ZoneDB = Database.fillData("SELECT * FROM `Zone" + givenName + "`")) { Zone Zn; for (int i = 0; i < ZoneDB.Rows.Count; ++i) { DataRow row = ZoneDB.Rows[i]; Zn.smallX = ushort.Parse(row["SmallX"].ToString()); Zn.smallY = ushort.Parse(row["SmallY"].ToString()); Zn.smallZ = ushort.Parse(row["SmallZ"].ToString()); Zn.bigX = ushort.Parse(row["BigX"].ToString()); Zn.bigY = ushort.Parse(row["BigY"].ToString()); Zn.bigZ = ushort.Parse(row["BigZ"].ToString()); Zn.Owner = row["Owner"].ToString(); level.ZoneList.Add(Zn); } } level.jailx = (ushort)(level.spawnx * 32); level.jaily = (ushort)(level.spawny * 32); level.jailz = (ushort)(level.spawnz * 32); level.jailrotx = level.rotx; level.jailroty = level.roty; level.StartPhysics(); //level.physChecker.Elapsed += delegate //{ // if (!level.physicssate && level.physics > 0) // level.StartPhysics(); //}; //level.physChecker.Start(); try { DataTable foundDB = Database.fillData("SELECT * FROM `Portals" + givenName + "`"); for (int i = 0; i < foundDB.Rows.Count; ++i) { DataRow row = foundDB.Rows[i]; if ( !Block.portal(level.GetTile(ushort.Parse(row["EntryX"].ToString()), ushort.Parse(row["EntryY"].ToString()), ushort.Parse(row["EntryZ"].ToString())))) { Database.executeQuery("DELETE FROM `Portals" + givenName + "` WHERE EntryX=" + row["EntryX"] + " AND EntryY=" + row["EntryY"] + " AND EntryZ=" + row["EntryZ"]); } } foundDB = Database.fillData("SELECT * FROM `Messages" + givenName + "`"); for (int i = 0; i < foundDB.Rows.Count; ++i) { DataRow row = foundDB.Rows[i]; if ( !Block.mb(level.GetTile(ushort.Parse(row["X"].ToString()), ushort.Parse(row["Y"].ToString()), ushort.Parse(row["Z"].ToString())))) { //givenName is safe against SQL injections, it gets checked in CmdLoad.cs Database.executeQuery("DELETE FROM `Messages" + givenName + "` WHERE X=" + row["X"] + " AND Y=" + row["Y"] + " AND Z=" + row["Z"]); } } foundDB.Dispose(); } catch (Exception e) { Server.ErrorLog(e); } try { string propsPath = LevelInfo.GetPropertiesPath(level.name); if (propsPath != null) { LvlProperties.Load(level, propsPath); } else { Server.s.Log(".properties file for level " + level.name + " was not found."); } LvlProperties.LoadEnv(level, level.name); } catch (Exception e) { Server.ErrorLog(e); } BlockDefinition[] defs = BlockDefinition.Load(false, level); for (int i = 0; i < defs.Length; i++) { if (defs[i] == null) { continue; } level.CustomBlockDefs[i] = defs[i]; } Server.s.Log(string.Format("Level \"{0}\" loaded.", level.name)); if (LevelLoaded != null) { LevelLoaded(level); } OnLevelLoadedEvent.Call(level); return(level); } catch (Exception ex) { Server.ErrorLog(ex); return(null); } } Server.s.Log("ERROR loading level."); return(null); }
public void Save(bool Override = false, bool clearPhysics = false) { if (blocks == null) { return; } string path = LevelInfo.LevelPath(name); if (LevelSave != null) { LevelSave(this); } OnLevelSaveEvent.Call(this); if (cancelsave1) { cancelsave1 = false; return; } if (cancelsave) { cancelsave = false; return; } try { if (!Directory.Exists("levels")) { Directory.CreateDirectory("levels"); } if (!Directory.Exists("levels/level properties")) { Directory.CreateDirectory("levels/level properties"); } if (changed || !File.Exists(path) || Override || (physicschanged && clearPhysics)) { if (clearPhysics) { ClearPhysics(); } if (File.Exists(path)) { if (File.Exists(path + ".prev")) { File.Delete(path + ".prev"); } File.Copy(path, path + ".prev"); File.Delete(path); } LvlFile.Save(this, path + ".backup"); File.Copy(path + ".backup", path); SaveSettings(this); Server.s.Log(string.Format("SAVED: Level \"{0}\". ({1}/{2}/{3})", name, players.Count, PlayerInfo.Online.Count, Server.players)); changed = false; } else { Server.s.Log("Skipping level save for " + name + "."); } } catch (OutOfMemoryException e) { Server.ErrorLog(e); if (Server.mono) { Process[] prs = Process.GetProcesses(); foreach (Process pr in prs) { if (pr.ProcessName == "MCGalaxy") { pr.Kill(); } } } else { Command.all.Find("restart").Use(null, ""); } } catch (Exception e) { Server.s.Log("FAILED TO SAVE :" + name); Player.GlobalMessage("FAILED TO SAVE :" + name); Server.ErrorLog(e); } GC.Collect(); GC.WaitForPendingFinalizers(); }
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 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 }; }