예제 #1
0
            static bool VerifyFile(Stream ms, string infilepath = "")
            {
                var c             = new CR2WFile();// { FileName = fileEntry.NameOrHash };
                var originalbytes = StreamExtensions.ToByteArray(ms);

                ms.Seek(0, SeekOrigin.Begin);
                var readResult = c.Read(ms);


                switch (readResult)
                {
                case EFileReadErrorCodes.NoCr2w:
                case EFileReadErrorCodes.UnsupportedVersion:
                    break;

                case EFileReadErrorCodes.NoError:
                    var hasAdditionalBytes =
                        c.AdditionalCr2WFileBytes != null && c.AdditionalCr2WFileBytes.Any();


                    var oldst              = c.StringDictionary.Values.ToList();
                    var newst              = c.GenerateStringtable().Item1.Values.ToList();
                    var compstr            = "OLD,NEW";
                    var correctStringTable = oldst.Count == newst.Count;

                    // Stringtable test
                    for (int i = 0; i < Math.Max(oldst.Count, newst.Count); i++)
                    {
                        string str1 = "";
                        string str2 = "";
                        if (i < oldst.Count)
                        {
                            compstr += oldst[i];
                        }
                        compstr += ",";
                        if (i < newst.Count)
                        {
                            compstr += newst[i];
                        }
                        compstr += "\n";

                        if (str1 != str2)
                        {
                            correctStringTable = false;
                        }
                    }

                    // Binary Equal Test
                    var isBinaryEqual = true;

                    using (var wms = new MemoryStream())
                        using (var bw = new BinaryWriter(wms))
                        {
                            c.Write(bw);

                            var newbytes = StreamExtensions.ToByteArray(wms);
                            isBinaryEqual = originalbytes.SequenceEqual(newbytes);

                            if (!isBinaryEqual && !string.IsNullOrEmpty(infilepath))
                            {
                                File.WriteAllBytes($"{infilepath}.n.bin", newbytes);
                                return(false);
                            }
                        }

                    if (!correctStringTable)
                    {
                        return(false);
                    }



                    return(true);

                default:
                    throw new ArgumentOutOfRangeException();
                }

                return(false);
            }
예제 #2
0
        private static int StressTestFile(BundleItem f, ref ConcurrentDictionary <string, string> unknownclasses, ref long totalbytes, ref long unknownbytes, ref Dictionary <string, Tuple <long, long> > chunkstate)
        {
            var crw = new CR2WFile();

            using (var ms = new MemoryStream())
                using (var br = new BinaryReader(ms))
                {
                    f.ExtractExistingMMF(ms);
                    ms.Seek(0, SeekOrigin.Begin);

                    #region Reading Test A
                    // reading test
                    crw.Read(br);
                    #endregion

                    #region StringTableTest A.1
                    // additional tests
                    (var dict, var strings, var nameslist, var importslist) = crw.GenerateStringtable();
                    var newdictvalues = dict.Values.ToList();
                    var dictvalues    = crw.StringDictionary.Values.ToList();
                    var diffDictList  = dictvalues.Except(newdictvalues).ToList();

                    bool isclassicalinconsistentw2anims = false;
                    bool isclassicalinconsistentw2phase = false;

                    if (diffDictList.Count != 0)
                    {
                        //w2anims inconsistencies
                        foreach (string str in diffDictList)
                        {
                            if (str == "extAnimEvents" ||
                                str == "array:2,0,handle:CExtAnimEventsFile" ||
                                str == "CExtAnimEventsFile" ||
                                str.Contains("sounds\\") ||
                                str.Contains("sound\\"))
                            {
                                isclassicalinconsistentw2anims = true;
                                break;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        //w2phase inconsistencies
                        foreach (string str in diffDictList)
                        {
                            if (str == "@SItem" ||
                                str == "SItem" ||
                                str == "#CEnvironmentDefinition" ||
                                str == "CEnvironmentDefinition")
                            {
                                isclassicalinconsistentw2phase = true;
                                break;
                            }
                            else
                            {
                                continue;
                            }
                        }

                        if (isclassicalinconsistentw2anims)
                        {
                            //throw new InvalidBundleException("Classical inconsistent .w2anims - " +
                            //    ".w2animev sound handles left behind in string lists, but actual data is empty");
                        }
                        else if (isclassicalinconsistentw2phase)
                        {
                            //throw new InvalidBundleException("Inconsistent .w2phase - " +
                            //    "secret e3 files");
                            // skip test B
                        }
                        else
                        {
                            throw new InvalidBundleException(" Generated dictionary not equal actual dictionary.");
                        }
                    }
                    #endregion

                    #region Writing Test B
                    if (isclassicalinconsistentw2phase || isclassicalinconsistentw2anims)
                    {
                        // skip test
                        // add additional fail-safe test?
                    }
                    else
                    {
                        byte[] buffer_testB;
                        byte[] buffer_testB_original;

                        using (var ms_testB = new MemoryStream())
                            using (var bw_testB = new BinaryWriter(ms_testB))
                            {
                                crw.Write(bw_testB);
                                buffer_testB = ms_testB.ToArray();
                            }

                        // compare
                        ms.Seek(0, SeekOrigin.Begin);
                        buffer_testB_original = ms.ToArray();

                        if (!Enumerable.SequenceEqual(buffer_testB_original, buffer_testB))
                        {
                            throw new InvalidBundleException(" Generated cr2w file not equal to original file.");
                        }
                    }
                    #endregion
                }
            foreach (var ut in crw.UnknownTypes)
            {
                unknownclasses.TryAdd(ut, ut);
            }
            foreach (var c in crw.Chunks)
            {
                var ubsl = c.unknownBytes?.Bytes != null ? c.unknownBytes.Bytes.Length : 0;

                lock (chunkstate)
                {
                    if (!chunkstate.ContainsKey(c.REDType))
                    {
                        chunkstate.Add(c.REDType, new Tuple <long, long>(0, 0));
                    }
                    var already = chunkstate[c.REDType];
                    chunkstate[c.REDType] = new Tuple <long, long>(
                        already.Item1 + c.Export.dataSize,
                        already.Item2 + ubsl
                        );
                }

                Interlocked.Add(ref totalbytes, c.Export.dataSize);
                Interlocked.Add(ref unknownbytes, ubsl);
            }
            return(0);
        }
예제 #3
0
        public static int VerifyTask(string[] path, ulong[] hashes)
        {
            var hashService    = ServiceLocator.Default.ResolveType <IHashService>();
            var CP77_DIR       = System.Environment.GetEnvironmentVariable("CP77_DIR", EnvironmentVariableTarget.User);
            var gameDirectory  = new DirectoryInfo(CP77_DIR);
            var gameArchiveDir = new DirectoryInfo(Path.Combine(gameDirectory.FullName, "archive", "pc", "content"));
            var bm             = new ArchiveManager(gameArchiveDir);

            if (path != null)
            {
                foreach (var s in path)
                {
                    var hash = FNV1A64HashAlgorithm.HashString(s);

                    if (!hashService.Hashdict.ContainsKey(hash))
                    {
                        continue;
                    }

                    var file = bm.Files[hash];

                    foreach (var fileEntry in file)
                    {
                        VerifyFile(fileEntry);
                    }
                }
            }

            if (hashes != null)
            {
                foreach (var hash in hashes)
                {
                    if (!hashService.Hashdict.ContainsKey(hash))
                    {
                        continue;
                    }

                    var file = bm.Files[hash];

                    foreach (var fileEntry in file)
                    {
                        VerifyFile(fileEntry);
                    }
                }
            }


            void VerifyFile(FileEntry fileEntry)
            {
                if (fileEntry.Archive is not Archive ar)
                {
                    return;
                }
                using var ms = new MemoryStream();
                ar.CopyFileToStream(ms, fileEntry.NameHash64, false);

                var c = new CR2WFile {
                    FileName = fileEntry.NameOrHash
                };

                ms.Seek(0, SeekOrigin.Begin);
                var readResult = c.Read(ms);

                switch (readResult)
                {
                case EFileReadErrorCodes.NoCr2w:
                case EFileReadErrorCodes.UnsupportedVersion:
                    break;

                case EFileReadErrorCodes.NoError:
                    var hasAdditionalBytes =
                        c.AdditionalCr2WFileBytes != null && c.AdditionalCr2WFileBytes.Any();


                    var oldst              = c.StringDictionary.Values.ToList();
                    var newst              = c.GenerateStringtable().Item1.Values.ToList();
                    var compstr            = "OLD,NEW";
                    var correctStringTable = oldst.Count == newst.Count;

                    // Stringtable test
                    for (int i = 0; i < Math.Max(oldst.Count, newst.Count); i++)
                    {
                        string str1 = "";
                        string str2 = "";
                        if (i < oldst.Count)
                        {
                            compstr += oldst[i];
                        }
                        compstr += ",";
                        if (i < newst.Count)
                        {
                            compstr += newst[i];
                        }
                        compstr += "\n";

                        if (str1 != str2)
                        {
                            correctStringTable = false;
                        }
                    }

                    if (!correctStringTable)
                    {
                        Debugger.Break();
                    }

                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(1);
        }