示例#1
0
 private static bool IsFileSizeCorrect(string fn, long expectedSize)
 {
     if (new FileInfo(fn).Length == expectedSize)
         return true;
     UserFeedback.Trace("'{0}' is not the expected size", fn);
     return false;
 }
示例#2
0
 private static void ShowUsage()
 {
     UserFeedback.Warning("Usage: aoe2wide.exe [width height]");
     UserFeedback.Info("If the new width and height are omitted, the current screen resolution(s) will be used.");
     UserFeedback.Trace("Alternatively, use: aoe2wide.exe createpatches");
     UserFeedback.Trace("  to try to create fresh patch files for all your age2_x1 executables, from the RootPatch file");
 }
示例#3
0
 private static bool IsFileHashCorrect(string fn, string expectedHash)
 {
     var actualHash = GetChecksum(fn);
     if (actualHash.Equals(expectedHash, StringComparison.InvariantCultureIgnoreCase))
         return true;
     UserFeedback.Trace(string.Format(@"'{0}' doesn't meet the expected hashcode '{1}' instead of '{2}'",
                                      fn,
                                      actualHash,
                                      expectedHash));
     return false;
 }
示例#4
0
        private static void FindResAndPatchExecutable(int newWidth, int newHeight, string exe)
        {
            try
            {
                UserFeedback.Trace(@"");
                _orgExePath = exe;
                var patch = FindPatchForExe(_orgExePath);
                if (patch == null)
                {
                    UserFeedback.Trace("No patches found for executable '{0}'", _orgExePath);
                    return;
                }

                UserFeedback.Info(string.Format("Patching Exe '{0}' (version {1}) with patch file '{2}'", _orgExePath, patch.Version, patch.PatchFilepath));

                if (patch.InterfaceX1DrsPosition > 0 && !File.Exists(_orgX1DrsPath))
                    throw new FatalError(string.Format(@"Cannot find X1 drs file '{0}' in the game folder", _orgX1DrsPath));

                if (patch.InterfaceX1DrsPosition == 0 && File.Exists(_orgX1DrsPath))
                    UserFeedback.Warning(string.Format(@"Found X1 drs file '{0}' in the game folder, but no x1drspos=??? in patch file. X1 drs won't be patched!", _orgX1DrsPath));

                if (newWidth == 0 && newHeight == 0)
                {
                    UserFeedback.Info(
                        @"Auto patching for all current screen sizes. Note that the game will always use the primary screen!");
                    var doneList = new HashSet<int>();
                    foreach (var screen in System.Windows.Forms.Screen.AllScreens)
                    {
                        try
                        {
                            newWidth = screen.Bounds.Width;
                            newHeight = screen.Bounds.Height;
                            var key = newWidth + (newHeight * 65536);
                            if (doneList.Add(key))
                                PatchExecutable(newWidth, newHeight, patch);
                        }
                        catch (Exception e)
                        {
                            UserFeedback.Error(e);
                        }
                    }
                }
                else
                {
                    PatchExecutable(newWidth, newHeight, patch);
                }
            }
            catch (Exception e)
            {
                UserFeedback.Error(e);
            }
            return;
        }
示例#5
0
 private static string FindGameDirectory()
 {
     UserFeedback.Trace(@"Locating game main folder...");
     var iter = new DirectoryInfo(Directory.GetCurrentDirectory());
     while (iter.GetFiles(@"language_x1.dll").Length == 0)
     {
         iter = iter.Parent;
         if (iter == null)
             throw new FatalError(@"Cannot locate the game directory (where I expect language_x1.dll). Please run AoE2Wide from the game folder or a subfolder of it.");
     }
     UserFeedback.Trace(@"Located @'{0}'", iter.FullName);
     return iter.FullName;
 }
示例#6
0
        static void Main(string[] args)
        {
            try
            {
                Go(args);
            }
            catch (Exception e)
            {
                UserFeedback.Error(e);
            }

            UserFeedback.Close();
        }
示例#7
0
        private static int FindComparablePos(byte[] correctExe, byte[] otherExe, int pos)
        {
            for (var windowSize = 4; windowSize < 25; windowSize += 4)
            {
                var window      = new byte[windowSize];
                var startOffset = 0;
                if (startOffset + pos < 0)
                {
                    startOffset = -pos;
                }
                if ((startOffset + windowSize) >= correctExe.Length)
                {
                    startOffset = correctExe.Length - (pos + windowSize);
                }

                for (var i = 0; i < windowSize; i++)
                {
                    window[i] = correctExe[i + pos + startOffset];
                }

                var positions = FindWindow(otherExe, window).ToArray();

                if (positions.Length == 1)
                {
                    return(positions[0] - startOffset);
                }

                if (positions.Length == 0)
                {
                    if (windowSize == 8 && startOffset == 0)
                    {
                        startOffset = -4;
                        for (var i = 0; i < windowSize; i++)
                        {
                            window[i] = correctExe[i + pos + startOffset];
                        }

                        positions = FindWindow(otherExe, window).ToArray();
                        if (positions.Length == 1)
                        {
                            return(positions[0] - startOffset);
                        }
                    }
                    UserFeedback.Warning(string.Format(@"Found no matches for block {0:X8} {1}", pos, windowSize));
                    return(-pos);
                }
            }

            UserFeedback.Warning("Found too many matches for block {0:X8}", pos);
            return(-pos);
        }
示例#8
0
        private static void ConvertPatchFile(string otherExe)
        {
            UserFeedback.Info(@"Converting RootPatch file to a patch file for '{0}'", otherExe);
            var rootPatchFilePath = FindRootPatchFile();

            UserFeedback.Trace(@"Reading the root patch file");
            var patch = Patcher.ReadPatch(rootPatchFilePath, true);

            UserFeedback.Trace(@"Locating the root executable file");
            var rootExePath = FindExeFile(patch.FileSize, patch.Md5);

            UserFeedback.Trace(@"Reading the target executable");
            var exe2 = File.ReadAllBytes(otherExe);

            UserFeedback.Trace(@"Reading root executable");
            var exe1 = File.ReadAllBytes(rootExePath);

            var md5 = GetChecksum(exe2);

            UserFeedback.Trace(@"Detecting version from filename and/or md5");
            string version = GetVersion(otherExe, md5);
            UserFeedback.Trace(@"Version: '{0}'", version);

            var rootMd5 = GetChecksum(exe1);
            Patch newPatch;
            if (rootMd5.Equals(md5))
            {
                UserFeedback.Trace(@"Executable is equal; leaving patch file as-is");
                newPatch = new Patch
                               {
                                   FileSize = patch.FileSize,
                                   InterfaceDrsPosition = patch.InterfaceDrsPosition,
                                   Items = patch.Items,
                                   Md5 = patch.Md5
                               };
            }
            else
            {
                UserFeedback.Trace(@"Locating comparable locations, this may take a while");
                newPatch = Patcher.ConvertPatch(exe1, exe2, patch);
                newPatch.FileSize = exe2.Length;
                newPatch.Md5 = md5;
            }
            newPatch.Version = version;

            var patchFileName = @"AoE2Wide_" + version + @".patch";

            var patchOutput = Path.Combine(Path.GetDirectoryName(otherExe), patchFileName);
            UserFeedback.Trace("Writing the patch file '{0}'", patchOutput);
            Patcher.WritePatch(newPatch, patchOutput);
        }
示例#9
0
 private static string FindFile(string whatFile, string fileName, Int64? expectedSize, string expectedHash)
 {
     var files = FindFiles(whatFile, fileName, expectedSize, expectedHash);
     if (files.Length > 1)
     {
         UserFeedback.Warning(
             @"Multiple correct {0} instances found in current directory and subdirectories:",
             whatFile);
         foreach (var file in files)
             UserFeedback.Trace(file);
     }
     UserFeedback.Info(@"Using '{0}'", files[0]);
     return files[0];
 }
示例#10
0
        private static string[] FindFiles(string whatFile, string fileName, Int64? expectedSize, string expectedHash)
        {
            UserFeedback.Trace(string.Format(@"Locating {0} file '{1}'", whatFile, fileName));
            var files = Directory.GetFiles(_gameDirectory, fileName, SearchOption.AllDirectories);

            if (expectedSize.HasValue)
                files = files.Where(fn => IsFileSizeCorrect(fn, expectedSize.Value)).ToArray();

            if (expectedHash != null)
                files = files.Where(fn => IsFileHashCorrect(fn, expectedHash)).ToArray();

            if (files.Length == 0)
                throw new FatalError(string.Format(@"No correct {0} found in current directory or subdirectories",
                                                   whatFile));
            return files;
        }
示例#11
0
 public static Patch TryReadPatch(string patchFile, bool activeOnly)
 {
     try
     {
         UserFeedback.Info(@"Reading the patch file '{0}'", patchFile);
         return(ReadPatch(patchFile, activeOnly));
     }
     catch (Exception e)
     {
         UserFeedback.Error(e);
         return(new Patch()
         {
             PatchFilepath = patchFile
         });
     }
 }
示例#12
0
 static void PatchADrs(string _orgDrsPath, string newDrsName, int oldWidth, int oldHeight, int newWidth, int newHeight)
 {
     UserFeedback.Trace(@"Opening original {0}", System.IO.Path.GetFileName(_orgDrsPath));
     using (
         var interfaceDrs = new FileStream(_orgDrsPath, FileMode.Open,
                                           FileSystemRights.ReadData,
                                           FileShare.Read, 1024 * 1024, FileOptions.SequentialScan))
     {
         UserFeedback.Trace(@"Creating patched drs file '{0}'", newDrsName);
         using (
             var newDrs = new FileStream(newDrsName, FileMode.Create, FileSystemRights.Write,
                                         FileShare.None,
                                         1024 * 1024, FileOptions.SequentialScan))
         {
             UserFeedback.Trace(@"Patching DRS '{0}'", System.IO.Path.GetFileName(_orgDrsPath));
             DrsPatcher.Patch(interfaceDrs, newDrs, oldWidth, oldHeight, newWidth, newHeight);
         }
     }
 }
示例#13
0
 static void PatchAllDrs()
 {
     var doneList = new HashSet<int>();
     foreach (var screen in System.Windows.Forms.Screen.AllScreens)
     {
         try
         {
             var newWidth = screen.Bounds.Width;
             var newHeight = screen.Bounds.Height;
             var key = newWidth + (newHeight * 65536);
             if (doneList.Add(key))
                 PatchAllDrs(newWidth, newHeight);
         }
         catch (Exception e)
         {
             UserFeedback.Error(e);
         }
     }
 }
示例#14
0
        private static Patch FindPatchForExe(int exeFileSize, string exeMd5, string exeFilenameForFeedback)
        {
            if (patchFiles == null)
                patchFiles = FindPatchFiles();

            if (allPatches == null)
                allPatches = patchFiles.Select(patchFile => Patcher.TryReadPatch(patchFile, true)).ToArray();

            var matchingPatches = allPatches.Where(patch => patch.FileSize == exeFileSize && patch.Md5.Equals(exeMd5)).ToArray();

            if (matchingPatches.Length == 0)
                return null;

            if (matchingPatches.Length == 1)
                return matchingPatches[0];

            UserFeedback.Warning("Multiple matching patches found for executable '{0}', using first:", exeFilenameForFeedback);
            foreach (var mp in matchingPatches)
                UserFeedback.Trace("* {0}", mp.PatchFilepath);

            return matchingPatches[0];
        }
示例#15
0
        private static void AddAsmToRootPatchFile()
        {
            UserFeedback.Info(@"Locating listing file");
            var lstFile = FindFile("listing file", "age2_x1*.lst", null, null);

            UserFeedback.Info(@"Locating RootPatch file");
            var rootPatchFilePath = FindRootPatchFile();

            UserFeedback.Trace(@"Reading the root patch file");
            var patch = Patcher.ReadPatch(rootPatchFilePath, false);

            UserFeedback.Trace(@"Reading the listing file");
            var asmMap = Patcher.ReadAsmMap(lstFile);

            UserFeedback.Trace(@"Adding Asm to the patch data");
            Patcher.AddAsm(patch, asmMap);

            var outputRootPatchFilePath = rootPatchFilePath + "2";

            UserFeedback.Trace("Writing the patch file '{0}'", outputRootPatchFilePath);
            Patcher.WritePatch(patch, outputRootPatchFilePath);
        }
示例#16
0
        public static byte[] Enlarge(uint id, byte[] data, int oldWidth, int oldHeight, int newWidth, int newHeight)
        {
            var reader = new BinaryReader(new MemoryStream(data, false));

            var version = reader.ReadUInt32();

            if (version != 0x4e302e32)
            {
                return(data);
            }

            var framecount = reader.ReadUInt32();

            if (framecount != 1)
            {
                return(data);
            }

            var comment = reader.ReadBytes(24);

            /*var linesOffset = */ reader.ReadUInt32();
            var maskOffset    = reader.ReadUInt32();
            var paletteOffset = reader.ReadUInt32();
            var properties    = reader.ReadUInt32();

            var width = reader.ReadInt32();

            if (width != oldWidth)
            {
                return(data);
            }

            var height  = reader.ReadInt32();
            var centerX = reader.ReadInt32();
            var centerY = reader.ReadInt32();

            if (height - centerY != oldHeight)
            {
                return(data);
            }

            if (centerY != 0)
            {
                int higher = newHeight - oldHeight;
                centerY  -= higher;
                newHeight = oldHeight = height;
            }

            var newMaskSize      = (uint)(newHeight * 4);
            var newLinesOffset   = maskOffset + newMaskSize;
            var newLinesSize     = (uint)(newHeight * 4);
            var newLineDataStart = newLinesOffset + newLinesSize;

            var outStream = new MemoryStream();
            var writer    = new BinaryWriter(outStream);

            UserFeedback.Info(string.Format("Resizing image #{0} for {1}x{2} to {3}x{4}",
                                            id, oldWidth, oldHeight, newWidth, newHeight));

            writer.Write(version);
            writer.Write(framecount);
            writer.Write(comment);
            writer.Write(newLinesOffset);
            writer.Write(maskOffset);
            writer.Write(paletteOffset);
            writer.Write(properties);
            writer.Write(newWidth);
            writer.Write(newHeight);
            writer.Write(centerX);
            writer.Write(centerY);

            var osp = outStream.Position;

            Trace.Assert(osp == maskOffset);

            var orgLineMasks = new UInt32[oldHeight];

            for (var inLine = 0; inLine < oldHeight; inLine++)
            {
                orgLineMasks[inLine] = reader.ReadUInt32();
            }

            var orgLineStarts = new UInt32[oldHeight + 1];

            for (var inLine = 0; inLine < oldHeight; inLine++)
            {
                orgLineStarts[inLine] = reader.ReadUInt32();
            }
            orgLineStarts[oldHeight] = (uint)data.Length;

            var orgLines = new List <byte[]>(oldHeight);

            for (var inLine = 0; inLine < oldHeight; inLine++)
            {
                var orgLineSize = orgLineStarts[inLine + 1] - orgLineStarts[inLine];
                orgLines.Add(reader.ReadBytes((int)orgLineSize));
            }

            var newLineMasks = new UInt32[newHeight];
            var newLines     = new List <byte[]>(newHeight);

            var extraLines = newHeight - oldHeight;
            var shrinking  = extraLines < 0;
            var expanding  = extraLines > 0;

            var centreLine = oldHeight / 2;

            var shrinkSkipStart = centreLine + extraLines;
            var shrinkSkipEnd   = centreLine;

            // duplication is the amount of times every duplicated line, is duplicated
            var duplication = 1 + (extraLines + 1) / (oldHeight / 2);
            // the duplication block size is the block that is being duplicated
            // the last line of which MIGHT not be duplicated 'duplication' times
            //  eg if duplication is 2, extralines = 501, dbs = 251, the last of which is
            //  duped just once.
            var duplicationBlockSize = (extraLines + duplication - 1) / duplication;

            var dupStart = centreLine - duplicationBlockSize / 2;
            var dupEnd   = dupStart + duplicationBlockSize;

            var dupedLines = 0; //'UNIT'TEST

            for (var inLine = 0; inLine < oldHeight; inLine++)
            {
                // If shrinking skip 'extralines' lines on the centerline and above
                if (shrinking && inLine >= shrinkSkipStart && inLine < shrinkSkipEnd)
                {
                    dupedLines--;
                    continue;
                }

                newLineMasks[newLines.Count] = orgLineMasks[inLine];

                var newLine = StretchLine(orgLines[inLine], oldWidth, newWidth);
                newLines.Add(newLine);

                // If expanding, duplicate the right amount of lines before centreLine
                if (!expanding || inLine < dupStart || inLine >= dupEnd)
                {
                    continue;
                }

                for (var rep = 0; rep < duplication && dupedLines < extraLines; rep++)
                {
                    newLineMasks[newLines.Count] = orgLineMasks[inLine];
                    newLines.Add(newLine);
                    dupedLines++;
                }
            }
            Trace.Assert(newLines.Count == newHeight);
            Trace.Assert(dupedLines == extraLines);

            var nextLineStart = newLineDataStart;

            foreach (var newLineMask in newLineMasks)
            {
                writer.Write(newLineMask);
            }

            osp = outStream.Position;
            Trace.Assert(newLinesOffset == osp);

            foreach (var newLine in newLines)
            {
                writer.Write(nextLineStart);
                nextLineStart += (uint)newLine.Length;
            }

            osp = outStream.Position;
            Trace.Assert(newLineDataStart == osp);

            foreach (var newLine in newLines)
            {
                writer.Write(newLine);
            }

            Trace.Assert(outStream.Position == nextLineStart);

            writer.Close();

            var newSlp = outStream.ToArray();

            // For debugging:
            //File.WriteAllBytes(string.Format(@"slp\{0}org.slp", id), data);
            //File.WriteAllBytes(string.Format(@"slp\{0}new.slp", id), newSlp);

            return(newSlp);
        }
示例#17
0
        static public void PatchResolutions(byte[] exe, int oldWidth, int oldHeight, int newWidth, int newHeight, Patch patch)
        {
            // Create the map so, that originally larger resolutions stay larger even after patching. They _may_ become invalid though.
            // This is necessary to keep the internal (in AoE) if > else if > else if > code working.
            var hmap           = new Dictionary <int, int>();
            var existingWidths = new[] { 800, 1024, 1280, 1600 };
            var wshift         = newWidth;

            foreach (var w in existingWidths)
            {
                if (w == oldWidth)
                {
                    hmap[w] = newWidth;
                }
                else if (w > oldWidth)
                {
                    hmap[w] = ++wshift;
                }
            }

            var vmap            = new Dictionary <int, int>();
            var existingHeights = new[] { 600, 768, 1024, 1200 };
            var hshift          = newHeight;

            foreach (var h in existingHeights)
            {
                if (h == oldHeight)
                {
                    vmap[h] = newHeight;
                }
                else if (h > oldHeight)
                {
                    vmap[h] = ++hshift;
                }
            }

            foreach (var pair in hmap)
            {
                UserFeedback.Trace(string.Format(@"Horizontal {0} => {1}", pair.Key, pair.Value));
            }

            foreach (var pair in vmap)
            {
                UserFeedback.Trace(string.Format(@"Vertical {0} => {1}", pair.Key, pair.Value));
            }

            foreach (var item in patch.Items)
            {
                if (item.Pos >= exe.Length)
                {
                    UserFeedback.Warning(@"Error in input: Invalid location {0:X8}. [NOT PATCHED]", item.Pos);
                    continue;
                }
                var oldValue = item.ReferenceValue;
                int newValue;
                var hor = item.Type.Contains("H");
                var ver = item.Type.Contains("V");

                // If a number is used for both horizontal and vertical
                //  prefer the one that we are patching.
                if (hor && ver)
                {
                    if (oldWidth == oldValue) // so if we have 1024 HV, and are patching 1024x768, we'd ignore the V, and use the H
                    {
                        ver = false;
                    }
                    else
                    {
                        hor = false;
                    }
                }
                Trace.Assert(hor || ver);
                var map = ver ? vmap : hmap;
                if (!map.TryGetValue(oldValue, out newValue))
                {
                    newValue = oldValue;
                }

                if (item.Type.Contains("H") && item.Type.Contains("V"))
                {
                    UserFeedback.Trace(string.Format(@"{0} HV: Mapping to {1}", oldValue, newValue));
                }

                var ob0      = (int)exe[item.Pos];
                var ob1      = (int)exe[item.Pos + 1];
                var ob2      = (int)exe[item.Pos + 2];
                var ob3      = (int)exe[item.Pos + 3];
                var orgValue = ob0 | ob1 << 8 | ob2 << 16 | ob3 << 24;
                if (item.Type.Equals("dV") || item.Type.Equals("dH"))
                {
                    var expectedOrgValue = item.Parameter;
                    if (expectedOrgValue == 0)
                    {
                        UserFeedback.Warning(
                            string.Format(
                                "{0} action is safer if you mention the expected orgValue. Encountered {1} @ {2:X8}",
                                item.Type, orgValue, item.Pos));
                    }
                    else
                    {
                        if (expectedOrgValue != orgValue)
                        {
                            UserFeedback.Warning(string.Format(
                                                     @"{0} action expected value mismatch: {1} expected, {2} encountered @ {3:X8} [NOT PATCHED]",
                                                     item.Type,
                                                     expectedOrgValue, orgValue, item.Pos));
                            continue;
                        }
                    }

                    var offset = newValue - oldValue;
                    newValue = orgValue + offset;
                }
                else
                {
                    if (orgValue != oldValue)
                    {
                        UserFeedback.Warning(string.Format(
                                                 @"{0} action expected value mismatch: {1} expected, {2} encountered @ {3:X8} [NOT PATCHED]",
                                                 item.Type,
                                                 oldValue, orgValue, item.Pos));
                        continue;
                    }
                }
                var b0 = (byte)(newValue & 0xFF);
                var b1 = (byte)((newValue >> 8) & 0xFF);
                var b2 = (byte)((newValue >> 16) & 0xFF);
                var b3 = (byte)((newValue >> 24) & 0xFF);
                exe[item.Pos]     = b0;
                exe[item.Pos + 1] = b1;
                exe[item.Pos + 2] = b2;
                exe[item.Pos + 3] = b3;
            }
        }
示例#18
0
        private static void PatchExecutable(int newWidth, int newHeight, Patch patch)
        {
            try
            {
                int oldWidth, oldHeight;
                GetOldWidthHeight(newWidth, newHeight, out oldWidth, out oldHeight);

                UserFeedback.Info(string.Format(@"Changing {0}x{1} to {2}x{3}", oldWidth, oldHeight, newWidth, newHeight));

                UserFeedback.Trace(@"Reading original executable");
                var exe = File.ReadAllBytes(_orgExePath);

                var versionString = patch.Version.Length == 0 ? "" : patch.Version + "_";

                var newDrsName = Path.Combine(Path.Combine(_gameDirectory, @"Data"), string.Format(@"{0:D4}{1:D4}.drs", newWidth, newHeight));
                var newX1DrsName = Path.Combine(Path.Combine(_gameDirectory, @"Data"), string.Format(@"{0:D4}{1:D4}_x1.drs", newWidth, newHeight));
                var newExeName = Path.Combine(_gameDirectory,
                                              string.Format(@"age2_x1_{2}{0}x{1}.exe", newWidth, newHeight,
                                                            versionString));

                var batchName = Path.Combine(_gameDirectory,
                                              string.Format(@"AoC{2} {0}x{1}.bat", newWidth, newHeight,
                                                            patch.Version));

                var desktopBatchName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
                                              string.Format(@"AoC{2} {0}x{1}.bat", newWidth, newHeight,
                                                            patch.Version));
                //Trace(@"Writing file with all occurrences of resolutions");
                //Patcher.ListEm(bytes);

                UserFeedback.Trace("Patching the executable: DRS reference");
                Patcher.PatchDrsRefInExe(exe, Path.GetFileName(newDrsName), patch);

                if (patch.InterfaceX1DrsPosition > 0)
                {
                    UserFeedback.Trace("Patching the executable: X1 DRS reference");
                    Patcher.PatchX1DrsRefInExe(exe, Path.GetFileName(newX1DrsName), patch);
                }

                UserFeedback.Trace("Patching the executable: resolutions");
                Patcher.PatchResolutions(exe, oldWidth, oldHeight, newWidth, newHeight, patch);

                UserFeedback.Trace(string.Format(@"Writing the patched executable '{0}'", newExeName));
                File.WriteAllBytes(newExeName, exe);

                if (skipExistingFiles && File.Exists(batchName))
                {
                    UserFeedback.Trace(@"Skipping existing convenience batch file '{0}'", batchName);
                }
                else
                {
                    UserFeedback.Trace(@"Writing convenience batch file '{0}'", batchName);
                    var batContent = new List<string> {@"@echo off"};

                    var processExe = IsVistaOrHigher ? FindProcessExe() : null;

                    if (processExe != null)
                    {
                        batContent.Add(
                            @"ECHO Using process.exe to suspend explorer.exe (win7, vista palette fix)");
                        batContent.Add(string.Format("\"{0}\" -s explorer.exe", processExe));
                    }

                    batContent.Add(@"ECHO Starting Age of Empires II - The Conquerers in the correct screen mode");
                    batContent.Add(string.Format("\"{0}\" {1}", Path.GetFileName(newExeName), oldWidth));

                    if (processExe != null)
                    {
                        batContent.Add(@"ECHO Resuming explorer (was suspended before)");
                        batContent.Add(string.Format("\"{0}\" -r explorer.exe", processExe));
                    }

                    File.WriteAllLines(batchName, batContent.ToArray());
                }

                if (skipExistingFiles && File.Exists(desktopBatchName))
                {
                    UserFeedback.Trace(@"Skipping existing convenience desktop batch file '{0}'", desktopBatchName);
                }
                else
                {
                    var driveLetter = Path.GetPathRoot(_gameDirectory);
                    driveLetter = driveLetter.Replace(Path.DirectorySeparatorChar, ' ');
                    UserFeedback.Trace(@"Writing convenience desktop batch file '{0}'", desktopBatchName);
                    var batContent = new List<string>
                                         {
                                             @"@echo off",
                                             driveLetter,
                                             string.Format("cd \"{0}\"", _gameDirectory)
                                         };

                    var processExe = IsVistaOrHigher ? FindProcessExe() : null;

                    if (processExe != null)
                    {
                        batContent.Add(
                            @"ECHO Using process.exe to suspend explorer.exe (win7, vista palette fix)");
                        batContent.Add(string.Format("\"{0}\" -s explorer.exe", processExe));
                    }

                    batContent.Add(@"ECHO Starting Age of Empires II - The Conquerers in the correct screen mode");
                    batContent.Add(string.Format("\"{0}\" {1}", Path.GetFileName(newExeName), oldWidth));

                    if (processExe != null)
                    {
                        batContent.Add(@"ECHO Resuming explorer (was suspended before)");
                        batContent.Add(string.Format("\"{0}\" -r explorer.exe", processExe));
                    }

                    File.WriteAllLines(desktopBatchName, batContent.ToArray());
                }

                if (skipExistingFiles && File.Exists(newDrsName))
                {
                    UserFeedback.Info(@"Patched drs file '{0}' exists already, skipping.", newDrsName);
                }
                else
                {
                    PatchADrs(_orgDrsPath, newDrsName, oldWidth, oldHeight, newWidth, newHeight);
                }

                if (patch.InterfaceX1DrsPosition > 0)
                {
                    if (skipExistingFiles && File.Exists(newX1DrsName))
                    {
                        UserFeedback.Info(@"Patched X1 drs file '{0}' exists already, skipping.", newX1DrsName);
                    }
                    else
                    {
                        PatchADrs(_orgX1DrsPath, newX1DrsName, oldWidth, oldHeight, newWidth, newHeight);
                    }
                }

                try
                {
                    var pubDir = Path.Combine(_gameDirectory, @"donePatches");
                    if (Directory.Exists(pubDir))
                    {
                        var specificPubDir = Path.Combine(pubDir, string.Format(@"{0}x{1}", newWidth, newHeight));
                        if (!Directory.Exists(specificPubDir))
                            Directory.CreateDirectory(specificPubDir);

                        var specificPubDataDir = Path.Combine(specificPubDir, @"Data");
                        if (!Directory.Exists(specificPubDataDir))
                            Directory.CreateDirectory(specificPubDataDir);

                        var pubExePath = Path.Combine(specificPubDir, Path.GetFileName(newExeName));
                        var pubDrsPath = Path.Combine(specificPubDataDir, Path.GetFileName(newDrsName));

                        File.Copy(newExeName, pubExePath, true);
                        File.Copy(newDrsName, pubDrsPath, true);
                    }
                }
                catch (Exception e)
                {
                    UserFeedback.Warning("Couldn't publish: {0}", e.ToString());
                }

                UserFeedback.Trace("Done");
            }
            catch (Exception e)
            {
                UserFeedback.Error(e);
            }
        }
示例#19
0
        static void Go(string[] args)
        {
            _gameDirectory = FindGameDirectory();
            if (args.Length == 1)
            {
                if (args[0].Equals(@"addasm"))
                {
                    AddAsmToRootPatchFile();
                    return;
                }
                /*                if (args[0].Equals(@"test"))
                                {
                                    PatchAllDrs();
                                    return;
                                }*/
                if (args[0].Equals("createpatches"))
                {
                    var allExes = FindFiles(@"AoK-TC executables", @"age2_x1*.exe", null, null);
                    var allPatchedExes = new List<string>();
                    try
                    {
                        allPatchedExes = new List<string>(FindFiles(@"Patched executables", @"age2_x1*_???*x???*.exe", null, null));
                    }
                    catch (FatalError)
                    {
                        // Happens if no patched exes are found. No problem!
                    }

                    foreach (var exe in allExes)
                    {
                        if (allPatchedExes.Contains(exe))
                        {
                            UserFeedback.Trace(@"Skipping patched exe '{0}'", exe);
                            continue;
                        }

                        ConvertPatchFile(exe);
                    }
                }
                else
                {
                    ShowUsage();
                }
                return;
            }

            int newWidth = 0, newHeight = 0;
            switch (args.Length)
            {
                case 0:
                    break;
                case 2:
                    {
                        if (!int.TryParse(args[0], out newWidth) || !int.TryParse(args[1], out newHeight))
                        {
                            ShowUsage();
                            return;
                        }

                    }
                    break;
                default:
                    ShowUsage();
                    break;
            }

            _orgDrsPath = Path.Combine(Path.Combine(_gameDirectory, @"Data"), @"interfac.drs");
            _orgX1DrsPath = Path.Combine(Path.Combine(_gameDirectory, @"Data"), @"interfac_x1.drs");

            if (!File.Exists(_orgDrsPath))
                throw new FatalError(string.Format(@"Cannot find drs file '{0}' in the game folder", _orgDrsPath));

            UserFeedback.Info("Trying to find a patch file for all executables > 2MiB in size");
            var allExecutables = FindFiles("executables", "*.exe", null, null);
            var allLargeExes = allExecutables.Where(exe => new FileInfo(exe).Length > 2000000);

            foreach (var exe in allLargeExes)
                FindResAndPatchExecutable(newWidth, newHeight, exe);
        }
示例#20
0
        public static byte[] UpdateGuiTable(byte[] data, uint id, int oldWidth, int oldHeight, int newWidth, int newHeight)
        {
            int Xcol, Ycol, Wcol, Hcol;

            switch (oldWidth)
            {
            case 800:
                Xcol = (int)Columns.X800;
                Ycol = (int)Columns.Y800;
                Wcol = (int)Columns.W800;
                Hcol = (int)Columns.H800;
                break;

            case 1024:
                Xcol = (int)Columns.X1024;
                Ycol = (int)Columns.Y1024;
                Wcol = (int)Columns.W1024;
                Hcol = (int)Columns.H1024;
                break;

            case 1280:
                Xcol = (int)Columns.X1280;
                Ycol = (int)Columns.Y1280;
                Wcol = (int)Columns.W1280;
                Hcol = (int)Columns.H1280;
                break;

            default:
                return(data);
            }

            int higher = newHeight - oldHeight;
            int wider  = newWidth - oldWidth;

            if (data.Length < 10)
            {
                return(data);
            }

            try
            {
                var test = System.Text.Encoding.ASCII.GetString(data, 0, 10);
                if (test == null || !test.Equals("Item Name\t"))
                {
                    return(data);
                }
            }
            catch
            {
                return(data);
            }

            try
            {
                var file  = System.Text.Encoding.ASCII.GetString(data);
                var lines = file.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                var table = lines.Select(line => line.Split(new char[] { '\t' })).ToArray();
                foreach (var tableRow in table)
                {
                    if (tableRow.Length < 13)
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(tableRow[(int)Columns.Name]))
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(tableRow[(int)Columns.H1280]))
                    {
                        continue;
                    }

                    var x = int.Parse(tableRow[Xcol]);
                    var y = int.Parse(tableRow[Ycol]);
                    var w = int.Parse(tableRow[Wcol]);
                    var h = int.Parse(tableRow[Hcol]);

                    // Stuff that overlaps the centerline, stretches
                    if (y < oldHeight / 2 && (y + h) > oldHeight / 2)
                    {
                        h += higher;
                    }
                    // Stuff that is below the old centerline, moves down
                    else if (y > oldHeight / 2)
                    {
                        y += higher;
                    }

/*
 *                  // Only stuff that sticks to the right side:
 *                  if ((x + w) == oldWidth)
 *                  {
 *                      // Stuff on the right half, moves right
 *                      if (x > oldWidth / 2)
 *                      {
 *                          x += wider;
 *                      }
 *                      else if (x == oldWidth / 2)
 *                      {
 *                          // stuff in the center, stays in the center
 *                          x = newWidth / 2;
 *                          w = newWidth / 2;
 *                      }
 *                      else
 *                      {
 *                          // Stuff that stretches over the center, stretches (including full-width stuff)
 *                          w += wider;
 *                      }
 *                  }
 */
                    if (w == oldWidth)
                    {
                        w = newWidth;
                    }

                    tableRow[Xcol] = x.ToString();
                    tableRow[Ycol] = y.ToString();
                    tableRow[Wcol] = w.ToString();
                    tableRow[Hcol] = h.ToString();
                }
                var newLines = table.Select(tableRow => tableRow.Aggregate((output, col) => output + "\t" + col));
                var newText  = newLines.Aggregate((output, line) => output + "\r\n" + line);
                var newBytes = System.Text.Encoding.ASCII.GetBytes(newText);
                UserFeedback.Info("Patched Gui Table #{0}", id);
                return(newBytes);
            }
            catch (Exception e)
            {
                UserFeedback.Warning("Failed to patch Gui Table #{0}; leaving it unchanged.", id);
                UserFeedback.Error(e);
                return(data);
            }
        }