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)
            }
        }
 public PhysicsConstraint(
     TypeDesc desc,
     int oldObj,
     ConstraintType physicsConstraintType,
     ParsedDataMap header,
     ParsedDataMap?constraint)
     : base(desc, oldObj)
 {
     PhysicsConstraintType = physicsConstraintType;
     Header     = header;
     Constraint = constraint;
 }
Exemplo n.º 3
0
        public ParsedDataMap ReadDataMapRecursive(DataMap map, SaveInfo info)
        {
            if (map.BaseMap == null)
            {
                return(ReadDataMap(map, info));
            }
            ParsedDataMap baseMap = ReadDataMapRecursive(map.BaseMap, info);
            ParsedDataMap thisMap = ReadDataMap(map, info);

            thisMap.AddBaseParsedMap(baseMap, info);
            return(thisMap);
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
        protected override void Parse(ref ByteStreamReader bsr)
        {
            SourceFileHeader = new SourceFileHeader(this);
            SourceFileHeader.ParseStream(ref bsr);
            SaveInfo.ParseContext.CurrentSymbolTable = bsr.ReadSymbolTable(SourceFileHeader.TokenCount, SourceFileHeader.TokenTableSize) !;
            GameHeader = bsr.ReadDataMap("GameHeader", SaveInfo);
            Globals    = bsr.ReadDataMap("GLOBAL", SaveInfo);
            StateFiles = new EmbeddedStateFile[bsr.ReadSInt()];

            for (int i = 0; i < StateFiles.Length; i++)
            {
                StateFiles[i] = EmbeddedStateFile.CreateFromName(this, bsr.ReadCharArray(260));
                int fileLength = bsr.ReadSInt();
                StateFiles[i].ParseStream(bsr.SplitAndSkip(fileLength));
            }

            SaveInfo.Cleanup();
            Debug.Assert(bsr.BytesRemaining == 0);
            SaveInfo.PrintDeterminedDatamaps();
        }
Exemplo n.º 6
0
 public static ParsedEntData CreateFromName(SourceSave saveRef, ParsedDataMap headerInfo, DataMap entMap)
 {
     // order of these checks matters
     if (entMap.InheritsFrom("CBasePlayer"))
     {
         return(new CBasePlayerEntData(saveRef, headerInfo, entMap));
     }
     else if (entMap.InheritsFrom("CAI_BaseNPC"))
     {
         return(new CAI_BaseNpcEntData(saveRef, headerInfo, entMap));
     }
     else if (entMap.InheritsFrom("CBaseEntity"))
     {
         return(new CBaseEntityParsedEntData(saveRef, headerInfo, entMap));
     }
     else
     {
         return(new ParsedEntData(saveRef, headerInfo, entMap));
     }
 }
Exemplo n.º 7
0
        /* This pretty much exactly what the game does. A datamap is created dynamically which contains a description
         * for each key/value of the map.
         * Custom params:
         * [0] - the field type of each key
         * [1] - the custom read function of each key (if applicable)
         * [2] - the embedded map of each key (if applicable)
         * [3] - the field type of each value
         * [4] - the custom read function of each value (if applicable)
         * [5] - the embedded map of each value (if applicable)
         * */
        public static UtilMap <TK, TV> Restore(TypeDesc mapDesc, SaveInfo info, ref ByteStreamReader bsr)
        {
            object[] @params   = mapDesc.CustomParams !;
            DataMap? embKeyMap = @params[2] is string sk ? info.SDataMapLookup[sk] : null;
            DataMap? embValMap = @params[5] is string sv ? info.SDataMapLookup[sv] : null;

            TypeDesc keyDesc = new TypeDesc(
                name: "K",
                flags: DescFlags.FTYPEDESC_SAVE,
                fieldType: (FieldType)@params[0],
                customReadFunc: (CustomReadFunc?)@params[1],
                numElements: 1)
            {
                EmbeddedMap = embKeyMap
            };
            TypeDesc valDesc = new TypeDesc(
                name: "T",                 // std::map<Key, T>
                flags: DescFlags.FTYPEDESC_SAVE,
                fieldType: (FieldType)@params[3],
                customReadFunc: (CustomReadFunc?)@params[4],
                numElements: 1)
            {
                EmbeddedMap = embValMap
            };
            DataMap vecMap = new DataMap("um", new[] { keyDesc, valDesc });

            bsr.StartBlock(info);
            int count = bsr.ReadSInt();
            var res   = new KeyValuePair <ParsedSaveField <TK>, ParsedSaveField <TV> > [count];

            for (int i = 0; i < count; i++)
            {
                ParsedDataMap readResult = bsr.ReadDataMap(vecMap, info);
                var           k          = (ParsedSaveField <TK>)readResult.ParsedFields["K"];
                var           v          = (ParsedSaveField <TV>)readResult.ParsedFields["T"];
                res[i] = new KeyValuePair <ParsedSaveField <TK>, ParsedSaveField <TV> >(k, v);
            }
            bsr.EndBlock(info);
            return(new UtilMap <TK, TV>(mapDesc, res, keyDesc, valDesc));
        }
Exemplo n.º 8
0
        /* This pretty much exactly what the game does. A datamap is created dynamically which contains only a single
         * description for each element of this vector. This solution means I only have to do a single cast.
         * Custom params:
         * [0] - the field type of each element
         * [1] - the custom read function of each element (if applicable)
         * [2] - the embedded map of each element (if applicable)
         * */
        public static UtilVector <T> Restore(TypeDesc vecDesc, SaveInfo info, ref ByteStreamReader bsr)
        {
            object[] @params = vecDesc.CustomParams !;

            DataMap?embMap = @params[2] is string s ? info.SDataMapLookup[s] : null;

            int count = bsr.ReadSInt();

            TypeDesc elemDesc = new TypeDesc(
                name: "elems",
                flags: DescFlags.FTYPEDESC_SAVE,
                fieldType: (FieldType)@params[0],
                customReadFunc: (CustomReadFunc?)@params[1],
                numElements: (ushort)(embMap == null ? count : 1))
            {
                EmbeddedMap = embMap
            };

            // Sometimes the count is one but the read result does not have an element. I'm not sure if this is
            // intended or not but by default that will cause an exception.

            DataMap vecMap = new DataMap(embMap == null ? "elems" : "uv", new[] { elemDesc });

            T[] res;
            if (embMap == null && count > 1)
            {
                ParsedDataMap mapReadResult = bsr.ReadDataMap(vecMap, info);
                res = (ParsedSaveField <T[]>)mapReadResult.ParsedFields.Single().Value;
            }
            else                 // if the field type is embedded then the elements are read one by one
            {
                res = new T[count];
                for (int i = 0; i < count; i++)
                {
                    ParsedDataMap mapReadResult = bsr.ReadDataMap(vecMap, info);
                    res[i] = (ParsedSaveField <T>)mapReadResult.ParsedFields.Single().Value;
                }
            }
            return(new UtilVector <T>(res, elemDesc, vecDesc));
        }
        protected override void Parse(ref ByteStreamReader bsr)
        {
            ExtendedHeader = bsr.ReadDataMap("AIExtendedSaveHeader_t", SaveInfo);

            if (ExtendedHeader.GetFieldOrDefault <short>("version")
                >= AI_EXTENDED_SAVE_HEADER_FIRST_VERSION_WITH_CONDITIONS)
            {
                bsr.StartBlock(SaveInfo);
                Conditions = new ConditionStrings(SaveRef);
                Conditions.ParseStream(ref bsr);
                bsr.EndBlock(SaveInfo);
            }

            if (ExtendedHeader.GetFieldOrDefault <short>("version")
                >= AI_EXTENDED_SAVE_HEADER_FIRST_VERSION_WITH_NAVIGATOR_SAVE)
            {
                bsr.StartBlock(SaveInfo);
                Navigator = new CAI_NavigatorEntData(SaveRef !);
                Navigator.ParseStream(ref bsr);
                bsr.EndBlock(SaveInfo);
            }

            base.Parse(ref bsr);
        }
        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;
        }
 public CAI_BaseNpcEntData(SourceSave saveRef, ParsedDataMap headerInfo, DataMap classMap)
     : base(saveRef, headerInfo, classMap)
 {
 }
 public VersionableSaveGameHeader(SourceSave?saveRef, ParsedDataMap dataHeader) : base(saveRef, dataHeader)
 {
 }
Exemplo n.º 13
0
 public PhysicsVehicleController(TypeDesc desc, int oldObj, ParsedDataMap controller) : base(desc, oldObj)
 {
     Controller = controller;
 }
 public class CBasePlayerEntData : CBaseEntityParsedEntData {     // todo any other classes along the way that do stuff?
     public CBasePlayerEntData(SourceSave saveRef, ParsedDataMap headerInfo, DataMap classMap)
         : base(saveRef, headerInfo, classMap)
     {
     }
 protected override void Parse(ref ByteStreamReader bsr)
 {
     base.Parse(ref bsr);
     PhysHeader = bsr.ReadDataMap("PhysBlockHeader_t", SaveInfo);
 }
Exemplo n.º 16
0
        // all of these generic types must* stay consistent with TypeDesc.GetNetTypeFromFieldType
        private ParsedSaveField?ReadSaveField(TypeDesc desc, SaveInfo info, int bytesAvail)
        {
            switch (desc.FieldType)
            {
            case EMBEDDED:
                if (desc.NumElements == 1)
                {
                    return(new ParsedSaveField <ParsedDataMap>(ReadDataMapRecursive(desc.EmbeddedMap !, info), desc));
                }
                else
                {
                    ParsedDataMap[] parsedMaps = new ParsedDataMap[desc.NumElements];
                    for (int i = 0; i < desc.NumElements; i++)
                    {
                        parsedMaps[i] = ReadDataMapRecursive(desc.EmbeddedMap !, info);
                    }
                    return(new ParsedSaveField <ParsedDataMap[]>(parsedMaps, desc, parsedMaps.Length));
                }

            case CUSTOM:
                return(desc.InvokeCustomReadFunc(ref this, info));                        // this can return null

            case MODELNAME:
                return(ReadSimpleString(desc, bytesAvail, s => (ModelName)s));

            case SOUNDNAME:
                return(ReadSimpleString(desc, bytesAvail, s => (SoundName)s));

            case FUNCTION:
                return(ReadSimpleString(desc, bytesAvail, s => (Func)s));

            case STRING:
                return(ReadSimpleString(desc, bytesAvail));

            case MODELINDEX:
                return(ReadSimpleString(desc, bytesAvail, s => (ModelIndex)s));

            case MATERIALINDEX:
                return(ReadSimple <int, MaterialIndex>(desc, bytesAvail, i => (MaterialIndex)i));

            case FLOAT:
                return(ReadSimple <float>(desc, bytesAvail));

            case VECTOR2D:
                return(ReadSimple <Vector2>(desc, bytesAvail));

            case VECTOR:
                return(ReadSimple <Vector3>(desc, bytesAvail));

            case POSITION_VECTOR:
                return(ReadSimple <Vector3>(desc, bytesAvail, vec => vec + info.LandmarkPos));

            case QUATERNION:
                return(ReadSimple <Vector4>(desc, bytesAvail));

            case EHANDLE:
                return(ReadSimple <int, Ehandle>(desc, bytesAvail, i => (Ehandle)i));

            case CLASSPTR:
                return(ReadSimple <int, ClassPtr>(desc, bytesAvail, i => (ClassPtr)i));

            case EDICT:
                return(ReadSimple <int, Edict>(desc, bytesAvail, i => (Edict)i));

            case INTEGER:
                return(ReadSimple <int>(desc, bytesAvail));

            case BOOLEAN:
                return(ReadSimple <byte, bool>(desc, bytesAvail, b => b != 0));

            case SHORT:
                return(ReadSimple <short>(desc, bytesAvail));

            case BYTE:
                return(ReadSimple <byte>(desc, bytesAvail));

            case INTERVAL:
                return(ReadSimple <Interval>(desc, bytesAvail));

            case CHARACTER:
                return(desc.NumElements == 1 ? ReadSimple <byte, char>(desc, bytesAvail, b => (char)b)
                                                : new ParsedSaveField <CharArray>(ReadCharArray(bytesAvail), desc, bytesAvail));

            case COLOR32:
                return(ReadSimple <int, Color32>(desc, bytesAvail, i => (Color32)i));

            case TIME:
                return(ReadSimple <float, Time>(desc, bytesAvail, f => {
                    if (f == ZERO_TIME)
                    {
                        return (Time)0;
                    }
                    if (f != INVALID_TIME && f != FLT_MAX)
                    {
                        return (Time)(f + info.BaseTime);
                    }
                    return (Time)f;
                }));

            case TICK:
                int baseTick = info.TimeToTicks(info.BaseTime + 0.1f);
                return(ReadSimple <int, Tick>(desc, bytesAvail,
                                              i => (Tick)(i == TICK_NEVER_THINK_ENCODE ? TICK_NEVER_THINK : i + baseTick)));

            case VMATRIX:
                return(ReadSimple <VMatrix>(desc, bytesAvail));

            case VMATRIX_WORLDSPACE:
                return(ReadSimple <VMatrix>(desc, bytesAvail, mat => {
                    mat.ApplyTranslation(in info.LandmarkPos);
                    return mat;
                }));
 protected SaveGameHeader(SourceSave?saveRef, ParsedDataMap dataHeader) : base(saveRef)
 {
     DataHeader = dataHeader;
 }
Exemplo n.º 18
0
 public PhysicsConstraintGroup(TypeDesc desc, int oldObj, ParsedDataMap groupTemplate) : base(desc, oldObj)
 {
     GroupTemplate = groupTemplate;
 }
Exemplo n.º 19
0
 public PhysicsObject(TypeDesc desc, int oldObj, ParsedDataMap objTemplate, ParsedDataMap?controllerTemplate)
     : base(desc, oldObj)
 {
     ObjectTemplate     = objTemplate;
     ControllerTemplate = controllerTemplate;
 }
Exemplo n.º 20
0
 // same name as in game code - CPhysicsEnvironment::Restore
 public static ParsedSaveField?Restore(
     SaveInfo saveInfo,
     ParsedDataMap physHeader,
     (ParsedEntData ent, TypeDesc typeDesc) physRestoreInfo,
Exemplo n.º 21
0
 public ParsedEntData(SourceSave saveRef, ParsedDataMap headerInfo, DataMap classMap) : base(saveRef)
 {
     HeaderInfo = headerInfo;
     ClassMap   = classMap;
 }
Exemplo n.º 22
0
 public PhysicsMotionController(TypeDesc desc, int oldObj, ParsedDataMap motionController) : base(desc, oldObj)
 {
     MotionController = motionController;
 }
 public ETableHeader(SourceSave?saveRef, ParsedDataMap dataHeader) : base(saveRef, dataHeader)
 {
 }
 public PhysicsInfoHeader(SourceSave?saveRef, ParsedDataMap dataHeader) : base(saveRef, dataHeader)
 {
 }
Exemplo n.º 25
0
 public PhysicsSpring(TypeDesc desc, int oldObj, ParsedDataMap spring) : base(desc, oldObj)
 {
     Spring = spring;
 }