Important information: this site is currently scheduled to go offline indefinitely by end of the year.

Continent of the 9 (C9)

The Original Forum. Game archives, full of resources. How to open them? Get help here.
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Continent of the 9 (C9)

Post by chrrox »

Post your translated file here and Ill get it back in game.
Brouznouf
n00b
Posts: 12
Joined: Wed Aug 19, 2009 9:39 pm
Been thanked: 1 time

Re: Continent of the 9 (C9)

Post by Brouznouf »

I've looked the difference between the original and the repair version of file. In fact it's just the end of file, the tree structure of files, which differ because i think they used a korean software to zip.

So to make a correct archive copy the end of the orginal (where the tree structure begins) into the new one.

But I'm wondering if gameguard is able to detect the modification of a file and believe it's cheat ?
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Continent of the 9 (C9)

Post by chrrox »

Gameguard can not detect this kind of mod.
Brouznouf
n00b
Posts: 12
Joined: Wed Aug 19, 2009 9:39 pm
Been thanked: 1 time

Re: Continent of the 9 (C9)

Post by Brouznouf »

chrrox wrote:Post your translated file here and Ill get it back in game.
How do you get the file back in the game ?

I've looked into the binary data of csf file and it appears that for some files this info are deleted from the header :

crc32
compressed size
uncompressed size

And at the end of the file (Central directory structure) the external attributes of each file are 0x81B40002.

I think it will be easy to do this mod with a small software, but how do you set the "End of central directory record".

Ps : It's the first time i tried to look into the res of a software so i have any knowledge and i suppose there is a better way to convert the zip file into a csf one.

EDIT : So i have done the software you can find the src below (in c#), now i have one probleme with characteername.filter i dont know why the data is the same the offset where the header is in the zip is correct. But when the game launch i get this error :

Image

I got this error when i have changed some data, if i change any data but i use my software c9 run fine.

So if you have any idea it will be great.

Thanks

Code: Select all

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

namespace ZipToCSF
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] headerByte;

            bool readEnd = false;
            int i = 0;
            Int16 fileNameLength;
            Int16 extraFileNameLength;
            Int16 commentLength;
            Int32 fileLength;

            FileStream zipFile = File.Open("GameData.zip", FileMode.Open);
            FileStream csfFile = File.Open("GameData.cfs", FileMode.Create);

            BinaryReader zipReader = new BinaryReader(zipFile);
            BinaryWriter csfWriter = new BinaryWriter(csfFile);

            while (zipReader.BaseStream.Position < zipReader.BaseStream.Length)
            {

                headerByte = zipReader.ReadBytes(4);
                csfWriter.Write(headerByte);

                if (headerByte[0] == 0x50 && headerByte[1] == 0x4B && headerByte[2] == 0x03 && headerByte[3] == 0x04)
                {
                    //Les infos
                    csfWriter.Write(zipReader.ReadBytes(10));
                    //CRC32
                    zipReader.ReadBytes(4);
                    //data length (compressed)
                    fileLength = zipReader.ReadInt32();
                    //data length (uncompressed)
                    zipReader.ReadBytes(4);
                    //Set crc and the data length to null
                    csfWriter.Write(0x00000000);
                    csfWriter.Write(0x00000000);
                    csfWriter.Write(0x00000000);
                    //Get the file name length
                    fileNameLength = zipReader.ReadInt16();
                    extraFileNameLength = zipReader.ReadInt16();
                    //Write them
                    csfWriter.Write(fileNameLength);
                    csfWriter.Write(extraFileNameLength);
                    
                    String fileName = new String(zipReader.ReadChars(fileNameLength));
                    String extraFileName = new String(zipReader.ReadChars(extraFileNameLength));

                    csfWriter.Write(fileName.ToCharArray());
                    csfWriter.Write(extraFileName.ToCharArray());

                    csfWriter.Write(zipReader.ReadBytes(fileLength));
                    csfWriter.Write(zipReader.ReadBytes(12));

                    Console.WriteLine(fileName + " done...");

                }

                if (headerByte[0] == 0x50 && headerByte[1] == 0x4B && headerByte[2] == 0x06 && headerByte[3] == 0x08)
                {
                    fileLength = fileLength = zipReader.ReadInt32();
                    csfWriter.Write(fileLength);
                    csfWriter.Write(zipReader.ReadBytes(fileLength));
                }

                if (headerByte[0] == 0x50 && headerByte[1] == 0x4B && headerByte[2] == 0x01 && headerByte[3] == 0x02)
                {
                    csfWriter.Write(zipReader.ReadBytes(24));
                    fileNameLength = zipReader.ReadInt16();
                    extraFileNameLength = zipReader.ReadInt16();
                    commentLength = zipReader.ReadInt16();

                    csfWriter.Write(fileNameLength);
                    csfWriter.Write(extraFileNameLength);
                    csfWriter.Write(commentLength);

                    csfWriter.Write(zipReader.ReadBytes(4));
                    //On remplace les attributs
                    zipReader.ReadBytes(4);
                    csfWriter.Write((byte)0x20);
                    csfWriter.Write((byte)0x00);
                    csfWriter.Write((byte)0xB4);
                    csfWriter.Write((byte)0x81);

                    csfWriter.Write(zipReader.ReadBytes(4));
                    csfWriter.Write(zipReader.ReadBytes(fileNameLength));
                    csfWriter.Write(zipReader.ReadBytes(extraFileNameLength));
                    csfWriter.Write(zipReader.ReadBytes(commentLength));

                }

                if (headerByte[0] == 0x50 && headerByte[1] == 0x4B && headerByte[2] == 0x05 && headerByte[3] == 0x05)
                {
                    fileNameLength = zipReader.ReadInt16();
                    csfWriter.Write(fileNameLength);
                    csfWriter.Write(zipReader.ReadBytes(fileNameLength));
                }

                if (headerByte[0] == 0x50 && headerByte[1] == 0x4B && headerByte[2] == 0x05 && headerByte[3] == 0x06)
                {
                    readEnd = true;
                    break;
                }
                

            }

            if (!readEnd)
            {
                csfWriter.Write((byte)0x50);
                csfWriter.Write((byte)0x4B);
                csfWriter.Write((byte)0x05);
                csfWriter.Write((byte)0x06);
                
            }
            csfWriter.Write((Int16)0x5423);
            csfWriter.Write((Int16)0x5423);
            csfWriter.Write((Int16)0x5DA8);
            csfWriter.Write((Int16)0x5DA8);
            csfWriter.Write((Int16)0x7ED0);
            csfWriter.Write((Int16)0x0003);
            zipReader.ReadBytes(4);
            csfWriter.Write(zipReader.ReadBytes(4));
            csfWriter.Write((Int16)0x5423);

            System.Console.WriteLine("Enter to finish...");
            System.Console.ReadLine();
        }
    }
}

Brouznouf
n00b
Posts: 12
Joined: Wed Aug 19, 2009 9:39 pm
Been thanked: 1 time

Re: Continent of the 9 (C9)

Post by Brouznouf »

Ok it's worked i've figured out what changed between the zip and the cfs.

At the end of the file (header 0x06054B50), the cfs one have a particulary description :

4 bytes : 0X54235423 , the same for all cfs files
8 bytes : 0x5DA85DA800037ED0 , each cfs file have his one value (this is the value of GameData.cfs)
4 bytes : this value is the most important it's a "crypted" value of start offset of the tree structure definition
2 bytes : 0x5423 , the same for all cfs files

To set the correct start offset you can use the original file and add (or remove) the diff of length.

What i have said before is now obsolete, you just have to change the end of the zip file to make it working.

You can find here the C# source code to convert a zip to csf (you will need the originial csf file)

Code: Select all

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

namespace ZipToCSF
{
    class Program
    {
        static void Main(string[] args)
        {

            Int32 offsetStart;


            FileStream zipFile = File.Open("GameData.zip", FileMode.Open);
            FileStream csfFile = File.Open("GameData.new.cfs", FileMode.Create);
            FileStream csfOrig = File.Open("GameData.cfs", FileMode.Open);

            

            BinaryReader zipReader = new BinaryReader(zipFile);
            BinaryWriter csfWriter = new BinaryWriter(csfFile);
            BinaryReader csfReader = new BinaryReader(csfOrig);

            while (zipReader.BaseStream.Position < (zipReader.BaseStream.Length - 18))
            {
                csfWriter.Write(zipReader.ReadBytes(1));
            }

            csfReader.BaseStream.Seek(-14, SeekOrigin.End);

            csfWriter.Write(0x54235423);

            csfWriter.Write(csfReader.ReadBytes(8));

            offsetStart = csfReader.ReadInt32();

            offsetStart += (int)(zipReader.BaseStream.Length - csfReader.BaseStream.Length);

            csfWriter.Write(offsetStart);


            csfWriter.Write((byte)0x23);
            csfWriter.Write((byte)0x54);

            csfWriter.Close();
            csfReader.Close();
            zipReader.Close();

            System.Console.WriteLine("Enter to finish...");
            System.Console.ReadLine();
        }
    }
}

chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Continent of the 9 (C9)

Post by chrrox »

Great job now we can get en eglish version of this game going :)
Brouznouf
n00b
Posts: 12
Joined: Wed Aug 19, 2009 9:39 pm
Been thanked: 1 time

Re: Continent of the 9 (C9)

Post by Brouznouf »

Yep i'm working on a french version (that's why my english is so bad :) ), but we are only 2 so if you have a more active community and you need some help dont be afraid to contact me i will be pleased to help you (of course not on the traduction but on the archive file)
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Continent of the 9 (C9)

Post by chrrox »

It works great here is an example.
Image
Brouznouf
n00b
Posts: 12
Joined: Wed Aug 19, 2009 9:39 pm
Been thanked: 1 time

Re: Continent of the 9 (C9)

Post by Brouznouf »

Nice however i have question for the charset, we are french and we use some special char like é è à etc ... Is the korean charset gonna be a problem for this char ? I have seen in a file the language definition and i'm wondering if the charset is define somewhere in the ressource ?

EDIT : And i have seen in the root directory of the game, file C9Patch.cfg is also a zip and you can set the url for the patch. So if you want to be very pro it will be funny to make our own patch server and distribute the translation by mod this file.
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Continent of the 9 (C9)

Post by chrrox »

Yes it should be very interesting if we make our own patch server they are using apatche web server so it should be very possible.
What happens when you try to display the characters in game?
I think if you have the font installed that you put in the xml files you should be ok.
Deveruchi
ultra-n00b
Posts: 2
Joined: Sun Aug 16, 2009 9:58 am

Re: Continent of the 9 (C9)

Post by Deveruchi »

How to decode files .c9u and .c9d? In .c9u stored text of interface. In first half of .c9d stored sounds and effects of skills, and the second part of file stored game text: messages, tooltip.
Brouznouf
n00b
Posts: 12
Joined: Wed Aug 19, 2009 9:39 pm
Been thanked: 1 time

Re: Continent of the 9 (C9)

Post by Brouznouf »

Now working of the C9U file:

I'm sure this file are definition of panel, here is the description of what i've believe in order to use this file

First 4 bytes the header type of file : 0x3CF5C28F
4 bytes : ???? (usually equal to 0x00000000)
4 bytes : Length of the panel Name
panelNameLength bytes : Panel Name
24 bytes : Attributes of the panel
[Composants of Panel]
4 bytes : Header for the composant (type ?)
24 bytes : Attributes of the Composant
4 bytes : Size of the texture file name us
textureSizeName bytes : Name of the texture file

Other attributes of the composant

If some people are more advanced it will be nice to extract this info to translate the text of some composant.
Brouznouf
n00b
Posts: 12
Joined: Wed Aug 19, 2009 9:39 pm
Been thanked: 1 time

Re: Continent of the 9 (C9)

Post by Brouznouf »

There is a way to get the text from the c9u files :

Search the BaseFont String
After this you have a 4 bytes wich egal the size of the text you want to get
After you get the text

Be careful the text is encode with UTF-16 charset so the real length of text in the file is the size * 2
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Continent of the 9 (C9)

Post by chrrox »

The program UltraEdit Can edit the text without much trouble after you set the font to Hangul.
There are some very small files of the same type we could study .c9d files in the ui folder.
I noticed a lot of English text already in the files.
Chessman
n00b
Posts: 16
Joined: Sat Aug 22, 2009 5:47 pm
Has thanked: 2 times

Re: Continent of the 9 (C9)

Post by Chessman »

The .c9u and .c9d are encrypted xml files. 8D
Post Reply