Пример #1
0
        public ParsedDataMap ReadDataMap(DataMap map, SaveInfo info)
        {
            if (ReadSShort() != 4)
            {
                throw new ConstraintException($"bad first value while parsing datamap \"{map.ClassName}\", expected 4");
            }
            string sym = ReadSymbol(info) !;

            if (sym != map.DataMapName)
            {
                info.SDataMapLookup.TryGetValue(sym, out DataMap? cmpMap);
                if (!ReferenceEquals(cmpMap, map))
                {
                    DetermineDataMapHierarchy(info, $"\"{sym}\" does not match \"{map.DataMapName}\"", AbsoluteByteIndex - 4);
                    throw new ArgumentException($"bad symbol, expected \"{map.DataMapName}\" but read \"{sym}\"");
                }
            }
            int           fieldsSaved = ReadSInt();
            ParsedDataMap ret         = new ParsedDataMap(map, fieldsSaved);

            for (int i = 0; i < fieldsSaved; i++)
            {
                StartBlock(info, out short byteSize, out string?s);
                map.FieldDict.TryGetValue(s !, out TypeDesc? curFieldDesc);
                if (curFieldDesc != null)
                {
                    if (!curFieldDesc.Placeholder)
                    {
                        try {
                            int             index = AbsoluteByteIndex;
                            ParsedSaveField?f     = ReadSaveField(curFieldDesc !, info, byteSize);
                            f?.SetIndex(index);                             // I allow returning null here for the vphys read
                            EndBlock(info);                                 // try ending the block to see if we read this correctly
                            ret.AddSaveField(f);
                        } catch (Exception e) {
                            info.AddError($"exception while reading field {s} from datamap \"{map.ClassName}\": {e.Message}");
                            SkipCurrentBlock(info);
                        }
                    }
                    else
                    {
                        DetermineDataMapHierarchy(info, $"placeholder field \"{curFieldDesc.Name}\"", AbsoluteByteIndex);
                        SkipCurrentBlock(info);
                    }
                }
                else
                {
                    info.AddError($"skipping field \"{s}\" from datamap \"{map.ClassName}\" ({byteSize} bytes), no appropriate field found");
                    SkipCurrentBlock(info);
                }
            }
            return(ret);
        }
		private static readonly HashSet<string> Searched = new HashSet<string>(); // for debugging
		
		
		protected override void Parse(ref ByteStreamReader bsr) {
			EntData = new ParsedEntData[DataHeader.EntHeaders.Length];
			for (int i = 0; i < DataHeader.EntHeaders.Length; i++) {
				ParsedDataMap entHeader = DataHeader.EntHeaders[i];
				var edictIndex = entHeader.GetFieldOrDefault<int>("edictindex");
				bsr.CurrentByteIndex = entHeader.GetFieldOrDefault<int>("location");
				string? className = entHeader.GetFieldOrDefault<string>("classname");
				if (className == null) // todo
					continue;
				if (!SaveInfo.SDataMapLookup.TryGetValue(className, out DataMap? entMap)) {
					string s = $"{nameof(EntitySaveStateBlock)}.{nameof(Parse)} - datamap for \"{className}\" not found";
					if (bsr.ReadSShort() == 4 && Searched.Add(s)) {
						bsr.DetermineDataMapHierarchy(SaveInfo,
							$"{nameof(EntitySaveStateBlock)}.{nameof(Parse)} - datamap for \"{className}\" not found",
							bsr.AbsoluteByteIndex - 2);
					}
					SaveInfo.AddError(s
#if DEBUG
						,false
#endif
						);
					continue;
				}
				EntData[i] = EntDataFactory.CreateFromName(SaveRef!, entHeader, entMap);
				SaveInfo.ParseContext.CurrentEntity = EntData[i];
				EntData[i]!.ParseStream(ref bsr);
			}
		}
        public static SaveGameHeader?CreateFromHeaderInfo(SourceSave?saveRef, ParsedDataMap dataHeader)
        {
            CharArray name = dataHeader.GetField <CharArray>("szName");

            switch (name)
            {
            case "Entities":
                return(new ETableHeader(saveRef, dataHeader));

            case "Physics":
                return(new PhysicsInfoHeader(saveRef, dataHeader));

            case "AI":
            case "Templates":
            case "ResponseSystem":
            case "Commentary":
            case "EventQueue":
            case "Achievement":
                return(new VersionableSaveGameHeader(saveRef, dataHeader));

            default:
                saveRef !.SaveInfo.AddError($"unknown header name: {name}");
                return(null);
                // todo VScriptServer and maybe PaintDatabase (will have to ree)
            }
        }
Пример #4
0
 protected override void Parse(ref ByteStreamReader bsr)
 {
     try {
         ParsedFields = bsr.ReadDataMapRecursive(ClassMap, SaveInfo);
     } catch (Exception e) {
         SaveInfo.AddError($"exception while parsing map \"{ClassMap.ClassName}\": {e.Message}");
     }
 }
Пример #5
0
 public bool TryReadDataMapRecursive(string dataMapName, SaveInfo info, out ParsedDataMap?result)
 {
     if (TryGetMapFromString(dataMapName, info, out DataMap? map))
     {
         try {
             result = ReadDataMapRecursive(map !, info);
             return(true);
         } catch (Exception e) {
             info.AddError($"exception while reading datamap \"{dataMapName}\" recursively: {e.Message}");
         }
     }
     result = null;
     return(false);
 }
        protected override void Parse(ref ByteStreamReader bsr)
        {
            base.Parse(ref bsr);
            Version = bsr.ReadSInt();
            int nBytesSymbols     = bsr.ReadSInt();
            int nSymbols          = bsr.ReadSInt();
            int nBytesDataHeaders = bsr.ReadSInt();
            int nBytesData        = bsr.ReadSInt();

            SaveInfo.ParseContext.CurrentSymbolTable = bsr.ReadSymbolTable(nSymbols, nBytesSymbols) !;

            int @base = bsr.CurrentByteIndex;

            int sizeHeaders = bsr.ReadSInt();
            int sizeBodies  = bsr.ReadSInt();

            // info about the header block
            BlockHeadersInfo = UtilVector <ParsedDataMap> .RestoreEmbedded("BlockHeadersInfo", "SaveRestoreBlockHeader_t", SaveInfo, ref bsr);

            SaveGameHeaders = new List <SaveGameHeader>(BlockHeadersInfo.Count);
            // read the headers one by one
            foreach (ParsedDataMap headerInfo in BlockHeadersInfo)
            {
                int loc = headerInfo.GetField <int>("locHeader");
                if (loc == -1)
                {
                    continue;
                }
                bsr.CurrentByteIndex = @base + loc;
                SaveGameHeader?sgh = SaveGameHeader.CreateFromHeaderInfo(SaveRef, headerInfo);
                if (sgh == null)
                {
                    continue;
                }
                sgh.ParseStream(ref bsr);
                SaveGameHeaders.Add(sgh);
            }

            //@base = bsr.CurrentByteIndex = @base + sizeHeaders;
            ByteStreamReader bodyBase = bsr.Split();             // block data is offset from this location

            SaveHeader = bsr.ReadDataMap("Save Header", SaveInfo);

            SaveInfo.BaseTime = SaveHeader.GetFieldOrDefault <Time>("time__USE_VCR_MODE");
            //SaveInfo.LandmarkPos // todo gotten from adjacency list?

            @base = bsr.CurrentByteIndex;

            int connections = SaveHeader.GetFieldOrDefault <int>("connectionCount");            // to other maps?
            int lightStyles = SaveHeader.GetFieldOrDefault <int>("lightStyleCount");

            if (connections > 0)
            {
                AdjacencyList = new ParsedDataMap[connections];
                for (int i = 0; i < connections; i++)
                {
                    AdjacencyList[i] = bsr.ReadDataMap("ADJACENCY", SaveInfo);
                }
            }
            if (lightStyles > 0)
            {
                LightStyleList = new ParsedDataMap[lightStyles];
                for (int i = 0; i < lightStyles; i++)
                {
                    LightStyleList[i] = bsr.ReadDataMap("LIGHTSTYLE", SaveInfo);
                }
            }

            @base = bsr.CurrentByteIndex;

            Blocks = new List <SaveStateBlock>(SaveGameHeaders.Count);

            // now read the actual blocks of data based off of information from the headers
            foreach (SaveGameHeader header in SaveGameHeaders)
            {
                int loc = header.DataHeader.GetFieldOrDefault <int>("locBody");
                if (loc == -1)
                {
                    continue;
                }
                //bodyBase.CurrentByteIndex = loc;
                //bsr.CurrentByteIndex = @base;
                if (!SaveStateBlock.CreateFromHeader(SaveRef !, header, out SaveStateBlock blockHandler))
                {
                    SaveInfo.AddError($"{nameof(SaveStateBlock)} not created from header: \"{header.Name}\"");
                    continue;
                }
                blockHandler.ParseStream(ref bodyBase);
                Blocks.Add(blockHandler);
            }

            //bsr.CurrentByteIndex = @base + sizeBodies;
        }