public void ParseFile(Int3 batchId, string pathPrefix, string suffix, List <EntitySpawnPoint> spawnPoints) { Optional <string> subnauticaPath = SteamFinder.FindSteamGamePath(264710, "Subnautica"); if (subnauticaPath.IsEmpty()) { throw new InvalidOperationException("Could not locate subnautica root"); } string path = Path.Combine(subnauticaPath.Get(), "SNUnmanagedData/Build18"); string fileName = Path.Combine(path, pathPrefix + "batch-cells-" + batchId.x + "-" + batchId.y + "-" + batchId.z + "-" + suffix + ".bin"); if (!File.Exists(fileName)) { return; } using (Stream stream = File.OpenRead(fileName)) { CellManager.CellsFileHeader cellsFileHeader = serializer.Deserialize <CellManager.CellsFileHeader>(stream); for (int cellCounter = 0; cellCounter < cellsFileHeader.numCells; cellCounter++) { CellManager.CellHeader cellHeader = serializer.Deserialize <CellManager.CellHeader>(stream); ProtobufSerializer.LoopHeader gameObjectCount = serializer.Deserialize <ProtobufSerializer.LoopHeader>(stream); for (int goCounter = 0; goCounter < gameObjectCount.Count; goCounter++) { GameObject gameObject = DeserializeGameObject(stream); EntitySpawnPoint esp = EntitySpawnPoint.From(batchId, gameObject, cellHeader); spawnPoints.Add(esp); } } } }
private bool GetDataFiles(out string lootDistributions, out Dictionary <string, WorldEntityInfo> worldEntityData) { lootDistributions = ""; worldEntityData = new Dictionary <string, WorldEntityInfo>(); string resourcesPath = ""; Optional <string> steamPath = SteamFinder.FindSteamGamePath(264710, "Subnautica"); string gameResourcesPath = ""; if (!steamPath.IsEmpty()) { gameResourcesPath = Path.Combine(steamPath.Get(), "Subnautica_Data/resources.assets"); } if (File.Exists(gameResourcesPath)) { resourcesPath = gameResourcesPath; } else if (File.Exists("../resources.assets")) { resourcesPath = Path.GetFullPath("../resources.assets"); } else if (File.Exists("resources.assets")) { resourcesPath = Path.GetFullPath("resources.assets"); } else { throw new FileNotFoundException("Make sure resources.assets is in current or parent directory and readable."); } using (FileStream resStream = new FileStream(resourcesPath, FileMode.Open)) using (AssetsFileReader resReader = new AssetsFileReader(resStream)) { AssetsFile resourcesFile = new AssetsFile(resReader); AssetsFileTable resourcesFileTable = new AssetsFileTable(resourcesFile); foreach (AssetFileInfoEx afi in resourcesFileTable.pAssetFileInfo) { if (afi.curFileType == TEXT_CLASS_ID) { resourcesFile.reader.Position = afi.absoluteFilePos; string assetName = resourcesFile.reader.ReadCountStringInt32(); if (assetName == "EntityDistributions") { resourcesFile.reader.Align(); lootDistributions = resourcesFile.reader.ReadCountStringInt32().Replace("\\n", ""); } } else if (afi.curFileType == MONOBEHAVIOUR_CLASS_ID) { resourcesFile.reader.Position = afi.absoluteFilePos; resourcesFile.reader.Position += 28; string assetName = resourcesFile.reader.ReadCountStringInt32(); if (assetName == "WorldEntityData") { resourcesFile.reader.Align(); uint size = resourcesFile.reader.ReadUInt32(); WorldEntityInfo wei; for (int i = 0; i < size; i++) { wei = new WorldEntityInfo(); wei.classId = resourcesFile.reader.ReadCountStringInt32(); wei.techType = (TechType)resourcesFile.reader.ReadInt32(); wei.slotType = (EntitySlot.Type)resourcesFile.reader.ReadInt32(); wei.prefabZUp = resourcesFile.reader.ReadBoolean(); resourcesFile.reader.Align(); wei.cellLevel = (LargeWorldEntity.CellLevel)resourcesFile.reader.ReadInt32(); wei.localScale = new UnityEngine.Vector3(resourcesFile.reader.ReadSingle(), resourcesFile.reader.ReadSingle(), resourcesFile.reader.ReadSingle()); worldEntityData.Add(wei.classId, wei); } } } } } return(true); }