`
RednaxelaFX
  • 浏览: 3016238 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

Fortune Arterial Tools

阅读更多
using System;
using System.IO;
using System.Text;

namespace fx.meta.bgi.util
{
    public sealed class ExtractText
    {
        public static void Main( string[ ] args ) {
            if ( args.Length < 1 ) {
                Console.WriteLine( "Give a valid script file as the first parameter." );
                return;
            }

            string infilename = args[ 0 ];
            string outfilename = args[ 0 ] + ".txt";

            FileInfo infile = new FileInfo( infilename );
            if ( !infile.Exists ) {
                Console.WriteLine( "Give a valid script file as the first parameter." );
                return;
            }

            long filelen = infile.Length;

            // read all the text and write to output
            Encoding utf16le = new UnicodeEncoding( false, true );
            Encoding jis = Encoding.GetEncoding( 932 );
            using ( BinaryReader reader = new BinaryReader( infile.OpenRead( ), jis ) ) {
                using ( BinaryWriter writer = new BinaryWriter( File.Create( outfilename ), utf16le ) ) {

                    reader.BaseStream.Seek( 0x020, SeekOrigin.Begin );
                    uint opcode = reader.ReadUInt32( );
                    uint codeSize = reader.ReadUInt32( );

                    if ( opcode != 0x07F ) {
                        throw new Exception( "Unsupported script. Expecting 0x7F at 0x20, but found " + opcode.ToString( "X" ) );
                    }
                    if ( codeSize > filelen ) {
                        throw new Exception( "Bad script. Code size greater than file size." );
                    }

                    writer.Write( ( ushort ) 0xFEFF );
                    reader.BaseStream.Seek( ( long ) codeSize, SeekOrigin.Begin );
                    StringBuilder builder = null;
                    while ( reader.BaseStream.Position < reader.BaseStream.Length ) {
                        string position = reader.BaseStream.Position.ToString( "X" );
                        builder = new StringBuilder( );
                        char c = '\0';
                        while ( ( c = reader.ReadChar( ) ) != '\0' ) {
                            if ( c == '\n' ) {
                                builder.Append( @"\n" );
                            } else {
                                builder.Append( c );
                            }
                        }
                        string text = builder.ToString( );
                        string strlen = jis.GetByteCount( text ).ToString( );
                        writer.Write( utf16le.GetBytes( string.Format( "{0}, {1}, {2}{3}", position, strlen, text, Environment.NewLine ) ) );
                    }
                }
            }
        }
    }
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;

namespace fx.meta.bgi.util
{
    public sealed class InsertText
    {
        public static void Main( string[ ] args ) {

            if ( args.Length < 1 ) {
                Console.WriteLine( "Give a valid script file as the first parameter." );
                return;
            }

            string scriptName = args[ 0 ];   
            string textName = scriptName + ".txt";
            string newScriptName = scriptName + ".new";

            FileInfo scriptFile = new FileInfo( scriptName );
            if ( !scriptFile.Exists ) {
                Console.WriteLine( "Give a valid script file as the first parameter." );
                return;
            }
            if ( !File.Exists( textName ) ) {
                Console.WriteLine( "Correspoding text file not available." );
                return;
            }

            long filelen = scriptFile.Length;

            // read all the text and write to output   
            Encoding utf16le = new UnicodeEncoding( false, true );
            Encoding jis = Encoding.GetEncoding( 932 );
            Encoding gbk = Encoding.GetEncoding( 936 );
            using ( BinaryReader script = new BinaryReader( scriptFile.OpenRead( ), jis ) ) {
                using ( StreamReader text = new StreamReader( File.OpenRead( textName ), utf16le ) ) {
                    using ( BinaryWriter writer = new BinaryWriter( File.Create( newScriptName ), gbk ) ) {

                        Dictionary<uint, uint> offsetMapping = new Dictionary<uint, uint>( );
                        List<string> newTexts = new List<string>( );
                        int offsetDifference = 0;

                        script.BaseStream.Seek( 0x020, SeekOrigin.Begin );
                        uint opcode = script.ReadUInt32( );
                        uint codeSize = script.ReadUInt32( );

                        if ( opcode != 0x07F ) {
                            throw new Exception( "Unsupported script. Expecting 0x7F at 0x20, but found " + opcode.ToString( "X" ) );
                        }
                        if ( codeSize > filelen ) {
                            throw new Exception( "Bad script. Code size greater than file size." );
                        }

                        uint currentOffset = codeSize;
                        string line = text.ReadLine( );
                        while ( line != null && !line.Equals( string.Empty ) ) {

                            string[ ] elem = line.Split( new string[ ] { ", " }, StringSplitOptions.RemoveEmptyEntries );
                            uint oldOffset = UInt32.Parse( elem[ 0 ], NumberStyles.AllowHexSpecifier );
                            offsetMapping.Add( oldOffset, ( uint ) ( oldOffset + offsetDifference ) );
                            Console.WriteLine( "{0}, {1}, {2}",
                                oldOffset.ToString( "X" ),
                                ( offsetMapping[ oldOffset ] ).ToString( "X" ),
                                offsetDifference.ToString( ) );

                            int oldTextLength = Int32.Parse( elem[ 1 ] );
                            int newTextLength = 0;
                            if ( 2 < elem.Length ) {
                                newTextLength = gbk.GetByteCount( elem[ 2 ] );
                                string s = elem[ 2 ].Replace( @"\n", "\n" );
                                newTexts.Add( s );
                            } else {
                                newTextLength = 0;
                                newTexts.Add( string.Empty );
                            }
                            offsetDifference += ( int ) ( newTextLength - oldTextLength );

                            line = text.ReadLine( );
                        }

                        script.BaseStream.Seek( 0, SeekOrigin.Begin );
                        byte[ ] scriptBuffer = script.ReadBytes( ( int ) codeSize );

                        for ( int dwptr = 0; dwptr < codeSize; dwptr += 4 ) {
                            uint currentDw = scriptBuffer[ dwptr ];
                            if ( currentDw != 0x03 && currentDw != 0x07F )
                                continue;

                            dwptr += 4;
                            currentDw = ToUInt32( scriptBuffer, dwptr );

                            if ( ( currentDw >= codeSize )
                                && ( offsetMapping.ContainsKey( currentDw ) ) ) {
                                uint newOfs = offsetMapping[ currentDw ];
                                WriteUInt32( newOfs, scriptBuffer, dwptr );
                            } else {
                                dwptr -= 4;
                            }
                        }

                        writer.Write( scriptBuffer );

                        foreach ( string s in newTexts ) {
                            writer.Write( gbk.GetBytes( s ) );
                            writer.Write( ( byte ) 0 );
                        }
                    }
                }
            }
        }

        static uint ToUInt32( byte[ ] array, int beginOfs ) {
            return ( uint ) (
                ( array[ beginOfs + 3 ] << 24 ) |
                ( array[ beginOfs + 2 ] << 16 ) |
                ( array[ beginOfs + 1 ] << 8 ) |
                ( array[ beginOfs ] ) );
        }

        static void WriteUInt32( uint data, byte[ ] array, int beginOfs ) {
            array[ beginOfs ] = ( byte ) ( ( data ) & 0x0FF );
            array[ beginOfs + 1 ] = ( byte ) ( ( data >> 8 ) & 0x0FF );
            array[ beginOfs + 2 ] = ( byte ) ( ( data >> 16 ) & 0x0FF );
            array[ beginOfs + 3 ] = ( byte ) ( ( data >> 24 ) & 0x0FF );
        }
    }
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics