Пример #1
0
        public P4GPCModLoader(ILogger logger, Config configuration, Reloaded.Hooks.ReloadedII.Interfaces.IReloadedHooks hooks)
        {
            mLogger        = logger;
            mConfiguration = configuration;
            mHooks         = hooks;

#if DEBUG
            Debugger.Launch();
#endif

            // Init
            TrySetConsoleEncoding(EncodingCache.ShiftJIS);
            var version = typeof(P4GPCModLoader).Assembly.GetName().Version.ToString();
            version = version.Substring(0, version.LastIndexOf('.'));
            mLogger.WriteLine($"[modloader] Persona 4 Golden (Steam) Mod loader by TGE (2020) v{version}");
            mNativeFunctions  = NativeFunctions.GetInstance(hooks);
            mFileAccessServer = new FileAccessServer(hooks, mNativeFunctions);

            // Load mods
            var modDb = new ModDb(mConfiguration.ModsDirectory, mConfiguration.EnabledMods);

            // CPK redirector
            mCpkRedirector = new CpkRedirector(mLogger, modDb, configuration);
            mFileAccessServer.AddClient(mCpkRedirector);

            // DW_PACK (PAC) redirector
            mDwPackRedirector = new DwPackRedirector(mLogger, modDb, configuration, mCpkRedirector);
            mFileAccessServer.AddClient(mDwPackRedirector);

            // XACT (XWB, XSB) redirector
            mXactRedirector = new XactRedirector(mLogger, modDb, configuration);
            mFileAccessServer.AddClient(mXactRedirector);
        }
 public void EnsureRedirected(ModDb modDb)
 {
     if (!RedirectAttempted)
     {
         TryRedirect(modDb);
     }
 }
Пример #3
0
        public bool Redirect(ModDb modDb)
        {
            RedirectAttempted = true;

            foreach (var mod in modDb.Mods)
            {
                var pacRedirectFilePath = Path.Combine(mod.LoadDirectory, Pack.FileName, Native->Path);
                if (mod.Files.Contains(pacRedirectFilePath))
                {
                    // Replacement file stored in folder named after pac file
                    Redirect(pacRedirectFilePath);
                    mLogger.Info($"{Pack.FileName} {Native->Path} Redirected to {pacRedirectFilePath}");
                    return(true);
                }

                if (Pack.Cpk != null)
                {
                    var cpkRedirectFilePath = Path.Combine(mod.LoadDirectory, Pack.Cpk.FileName, Native->Path);
                    if (mod.Files.Contains(cpkRedirectFilePath))
                    {
                        // Replacement file stored in folder named after cpk file
                        Redirect(cpkRedirectFilePath);
                        mLogger.Info($"{Pack.FileName} {Native->Path} Redirected to {cpkRedirectFilePath}");
                        return(true);
                    }
                }

                mLogger.Debug($"No redirection for {Native->Path}.");
            }

            return(false);
        }
Пример #4
0
 public CpkRedirector(ILogger logger, ModDb modDb, Config configuration)
 {
     mLogger      = new SemanticLogger(logger, "[modloader:CpkRedirector]", configuration);
     mModDb       = modDb;
     mCpkByHandle = new Dictionary <IntPtr, VirtualCpkHandle>();
     mCpkByName   = new Dictionary <string, VirtualCpk>(StringComparer.OrdinalIgnoreCase);
 }
Пример #5
0
 public DwPackRedirector(ILogger logger, ModDb modDb)
 {
     mLogger        = new SemanticLogger(logger, "[modloader:DwPackRedirector]");
     mModDb         = modDb;
     mPacksByHandle = new Dictionary <IntPtr, VirtualDwPack>();
     mPacksByName   = new Dictionary <string, VirtualDwPack>(StringComparer.OrdinalIgnoreCase);
 }
Пример #6
0
        static void Main(string[] args)
        {
            var keepRunning = args.Length > 0 && args[0] == "--background";
            var asmName     = Assembly.GetExecutingAssembly().GetName();
            var logger      = new LoggerConfiguration()
                              .WriteTo.Console()
                              .WriteTo.File($"{asmName.Name}.log")
                              .CreateLogger();

            PatcherConfig configuration;

            if (!File.Exists(PatcherConfig.FILE_PATH))
            {
                logger.Error($"{PatcherConfig.FILE_PATH} doesn't exist. Creating default configuration...");
                configuration = new PatcherConfig()
                {
                    FilesDir       = "path/to/mkdd/files/directory",
                    ModsDir        = "path/to/mods/directory",
                    BinDir         = "path/to/mods/directory/.bin",
                    OutDir         = "path/to/mkdd/files/directory",
                    CacheDir       = "path/to/mods/directory/.cache",
                    ArcPackPath    = "Tools/LunaboyRarcTools/ArcPack.exe",
                    ArcExtractPath = "Tools/LunaboyRarcTools/ArcExtract.exe",
                };
            }
            else
            {
                configuration = PatcherConfig.Load(PatcherConfig.FILE_PATH);
            }

            logger.Information($"{asmName.Name} {asmName.Version.Major}.{asmName.Version.Minor}.{asmName.Version.Revision} by TGE ({DateTime.Now.Year})\n");

#if !DEBUG
            try
            {
#endif
            var modDb   = new ModDb(logger, configuration, configuration.ModsDir);
            var patcher = new Patcher(logger, configuration, modDb);
            patcher.Patch(MergeOrder.TopToBottom);

            if (keepRunning)
            {
                while (true)
                {
                    patcher.Patch(MergeOrder.TopToBottom);
                    Console.WriteLine("Press any key to patch");
                    Console.ReadKey();
                }
            }
#if !DEBUG
        }

        catch (Exception e)
        {
            logger.Fatal($"An unhandled exception occured: {e.Message}\nThe program will now exit.");
        }
#endif
        }
Пример #7
0
 public XactRedirector(ILogger logger, ModDb modDb)
 {
     mLogger            = new SemanticLogger(logger, "[modloader:XactRedirector]");
     mModDb             = modDb;
     mWaveBankByName    = new Dictionary <string, VirtualWaveBank>();
     mWaveBankByHandle  = new Dictionary <IntPtr, VirtualWaveBank>();
     mSoundBankByName   = new Dictionary <string, VirtualSoundBank>();
     mSoundBankByHandle = new Dictionary <IntPtr, VirtualSoundBank>();
 }
Пример #8
0
 public DwPackRedirector(ILogger logger, ModDb modDb, Config configuration, CpkRedirector cpkRedirector)
 {
     mLogger                   = new SemanticLogger(logger, "[modloader:DwPackRedirector]", configuration);
     mModDb                    = modDb;
     mPacksByHandle            = new Dictionary <IntPtr, VirtualDwPackHandle>();
     mPacksByName              = new Dictionary <string, VirtualDwPack>(StringComparer.OrdinalIgnoreCase);
     mHandleByPack             = new Dictionary <VirtualDwPack, IntPtr>();
     mCpkRedirector            = cpkRedirector;
     mCpkRedirector.CpkLoaded += OnCpkLoaded;
     mLoadedCpks               = new List <VirtualCpk>();
 }
Пример #9
0
        public void Redirect(ModDb modDb)
        {
            var newPacIndex  = Entries.Max(x => x.PacIndex);
            var newFileIndex = Entries.Where(x => x.PacIndex == newPacIndex).Max(x => x.FileIndex) + 1;
            var newFileCount = 0;
            var rebuild      = false;

            foreach (var mod in modDb.Mods)
            {
                foreach (var file in mod.Files)
                {
                    var relPath = file.Substring(file.IndexOf(mod.LoadDirectory) + mod.LoadDirectory.Length + 1);
                    if (relPath.IndexOf('\\') == -1)
                    {
                        continue;
                    }
                    var cpkName = relPath.Substring(0, relPath.IndexOf('\\'));
                    if (!cpkName.Equals(FileName, StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    var cpkRelPath = file.Substring(file.IndexOf(cpkName) + cpkName.Length + 1);
                    var index      = mWrapper.Entries.FindIndex(x => x.Path.Equals(cpkRelPath, StringComparison.OrdinalIgnoreCase));

                    if (index == -1)
                    {
                        // This is a new file
                        mWrapper.Entries.Add(new CpkFileEntry()
                        {
                            Path = cpkRelPath, PacIndex = (short)newPacIndex, FileIndex = (short)newFileIndex++
                        });
                        ++newFileCount;
                        rebuild = true;
                    }
                    //else if ( FileName == "sysdat")
                    //{
                    //    mWrapper.Entries[ index ].PacIndex = (short)newPacIndex;
                    //    mWrapper.Entries[ index ].FileIndex = (short)newFileIndex++;
                    //}
                }
            }

            if (rebuild)
            {
                Rebuild(newFileCount);
            }
        }
Пример #10
0
        public bool TryRedirect(ModDb modDb)
        {
            RedirectAttempted = true;

            foreach (var mod in modDb.Mods)
            {
                var redirectedFilePath = Path.Combine(mod.LoadDirectory, Pack.FileName, Native->Path);
                if (mod.Files.Contains(redirectedFilePath))
                {
                    Redirect(redirectedFilePath);
                    mLogger.Info($"{Pack.FileName} {Native->Path} Redirected to {redirectedFilePath}");
                    return(true);
                }
                else
                {
                    mLogger.Debug($"No redirection for {Native->Path} because {redirectedFilePath} does not exist.");
                }
            }

            return(false);
        }
Пример #11
0
        public P4GPCModLoader(ILogger logger, Config configuration, Reloaded.Hooks.ReloadedII.Interfaces.IReloadedHooks hooks)
        {
            // Enable file logging only if console is enabled
            // performance impact would be too great otherwise
            if (Native.GetConsoleWindow() != IntPtr.Zero)
            {
                mLogger = new FileLoggingLogger(logger, "p4gpc.modloader.log.txt");
            }
            else
            {
                mLogger = logger;
            }

            mConfiguration = configuration;
            mHooks         = hooks;

#if DEBUG
            Debugger.Launch();
#endif

            // Init
            TrySetConsoleEncoding(EncodingCache.ShiftJIS);
            mLogger.WriteLine("[modloader] Persona 4 Golden (Steam) Mod loader by TGE (2020) v1.1.2");
            mNativeFunctions  = NativeFunctions.GetInstance(hooks);
            mFileAccessServer = new FileAccessServer(hooks, mNativeFunctions);

            // Load mods
            var modDb = new ModDb(mConfiguration.ModsDirectory, mConfiguration.EnabledMods);

            // DW_PACK (PAC) redirector
            mDwPackRedirector = new DwPackRedirector(mLogger, modDb);
            mFileAccessServer.AddClient(mDwPackRedirector);

            // XACT (XWB, XSB) redirector
            mXactRedirector = new XactRedirector(mLogger, modDb);
            mFileAccessServer.AddClient(mXactRedirector);
        }
Пример #12
0
 private void Initialize()
 {
     mMergeOrder = MergeOrder.BottomToTop;
     mModDb      = new ModDb(mLogger, mConfiguration.Patcher, mConfiguration.Patcher.ModsDir);
     PopulateGrid();
 }