Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Luvinia Server / Client

Newbie Spellweaver
Joined
May 8, 2023
Messages
7
Reaction score
5
Hi all,
I am pretty interested in working on this game, since me and a group of people are already hosting another game's private server i could see potential on bringing this to the table.

i've downloaded the soure code/server/client from the initial post and i am currently studying the contents.

I got the game working locally with the given instructions (shop works flawlessly and could edit its contents without issues) and i am currently looking into other specifics like tools (none is translated) scripts, packaging, etc.

I happen to have the installer for one of the later versions of the english release client (version A1.01.0038) so looking for ways to instead make this client work with the current server rather than translate the rest of the vietnam client is on my list. That said i believe i will require access to the packaged files (.dp) before i can get farther than the char selection/creation screen.

If anyone has any of the translated tools or know if it is best to keep vietnam vs the english version for any reason let me know.
 
Initiate Mage
Joined
May 10, 2023
Messages
2
Reaction score
2
When restored, the ZYLoginDB comes with the accountdb table containing:
1683730072140 - Luvinia Server / Client - RaGEZONE Forums

I've saw something alike in other tables..
My concern is that I have structure info inside the rows/collumns instead of actual data.
How are you guys making this work?

With all running as the tutorial says, I get to this
 

Attachments

You must be registered for see attachments list
Last edited:
Newbie Spellweaver
Joined
May 8, 2023
Messages
7
Reaction score
5
When restored, the ZYLoginDB comes with the accountdb table containing:
View attachment 197898
I've saw something alike in other tables..
My concern is that I have structure info inside the rows/collumns instead of actual data.
How are you guys making this work?

With all running as the tutorial says, I get to this
I noticed those tables too, but for now you need to know that the one managing the login info is this one
1683763165047 - Luvinia Server / Client - RaGEZONE Forums
.

From the message you are getting it seems like the server app is not finding the sql server(if you check the login server it likely spaming something about failed connection). I'd recommend creating a .mdl file and following these steps to check if you can successfully connect to the sql DB.
When your configuration here is correct, use that info and put it on the .ini files that the steps in the 1st post mention. If i remember correctly you don't need to update them all, just the Billing Server, DB Server and Login server.

I was making space on my HDD and found some files of luvinia I worked on when it was first seen in the wild. I don't know how far anybody got with these files (looking through posts nobody tried running the MapEditor and tools yet?) so I'm sharing what I've got, if anybody still has interested in this game, and tell me what he needs I can upload it before deleting it from my HDD forever.

Since I didn't found anything back then to extract the DP files, I made my own using C# so now I'm releasing it:
Code:
public class DataPack
{
    public class FileListEntry
    {
        public string fileName;
        public int offset;
        public int size;
        public int originalSize;
        public int validSize;
        public int crc32;
        public int compressType;
       
        public byte[] Data;
       
        public void LoadFileData(byte[] bytes)
        {
            using (var ms = new MemoryStream(bytes))
            {
                if (!((compressType & 0x1) == 1))
                {
                    if ((compressType & 0x4) == 1) // Standard compress
                    {
                        Console.WriteLine("Compressed!");
                    }
                    else
                    {
                        Data = new byte[size];
                        ms.Read(Data, 0, size);
                        Data = lzoCompress.Decompress(Data, size*2);
                    }
                }
                else
                {
                    Data = bytes;
                }
            }
        }

        public void Extract(string folderPath)
        {
            var filePath = folderPath + fileName;
            if(File.Exists(filePath)) return;
           
            filePath = filePath.Replace('?', '_');
           
            var fi = new FileInfo(filePath);
            Directory.CreateDirectory(fi.DirectoryName);
            File.WriteAllBytes(filePath, Data);
        }
    };
    /// <summary>
    /// The offset of all file data in the current package
    /// </summary>
    int offset;
   
    /// <summary>
    /// File index header size
    /// </summary>
    int indexHeadSize;
   
    int maxIndexNum;
   
    /// <summary>
    /// The size of the empty file index header
    /// </summary>
    int emptyIndexHeadSize;   
    int maxEmptyIndexNum;
    int emptyIndexCount;
   
    FileListEntry[] FileEntries;
    FileListEntry[] EmptyFileEntries;
   
    private const int HeadSize = 280;
   
    public void ExtractFiles(string filePath, string extractPath)
    {
        using (var fs = File.OpenRead(filePath))
        {
            var br = new BinaryReader(fs);
            offset = br.ReadInt32();
            indexHeadSize = br.ReadInt32();

            maxIndexNum = indexHeadSize / HeadSize;

            var indexCount = br.ReadInt32();
            Debug.Assert(indexCount <= maxIndexNum, "dwIndexCount <= m_dwMaxIndexNum");

            FileEntries = new FileListEntry[indexCount];
            for (int i = 0; i < indexCount; i++)
            {
                var fileEntry = new FileListEntry();
                fileEntry.fileName = ReadAsciiStatic(br, 256);

                // 24
                var bs = br.ReadBytes(24);
                bs = Decrypt(bs);

                fileEntry.offset = BitConverter.ToInt32(bs, 0);
                fileEntry.size = BitConverter.ToInt32(bs, 3);
                fileEntry.originalSize = BitConverter.ToInt32(bs, 7);
                fileEntry.validSize = BitConverter.ToInt32(bs, 11);
                fileEntry.crc32 = BitConverter.ToInt32(bs, 15);
                fileEntry.compressType = BitConverter.ToInt32(bs, 19);
                var oldPos = br.BaseStream.Position;
                br.BaseStream.Seek(fileEntry.offset, SeekOrigin.Begin);
                fileEntry.LoadFileData(br.ReadBytes(fileEntry.size));
                fileEntry.Extract(extractPath);
                br.BaseStream.Seek(oldPos, SeekOrigin.Begin);
            }
        }
    }

    public void Load(string filePath)
    {
        using (var fs = File.OpenRead(filePath))
        {
            var br = new BinaryReader(fs);
            offset = br.ReadInt32();
            indexHeadSize = br.ReadInt32();
           
            maxIndexNum = indexHeadSize / HeadSize;

            var indexCount = br.ReadInt32();
            Debug.Assert(indexCount <= maxIndexNum, "dwIndexCount <= m_dwMaxIndexNum");

            FileEntries = new FileListEntry[indexCount];
            for (int i = 0; i < indexCount; i++)
            {
                FileEntries[i] = new FileListEntry();
                FileEntries[i].fileName = ReadAsciiStatic(br, 256);

                // 24
                var bs = br.ReadBytes(24);
                bs = Decrypt(bs);

                FileEntries[i].offset = BitConverter.ToInt32(bs, 0);
                FileEntries[i].size = BitConverter.ToInt32(bs, 3);
                FileEntries[i].originalSize = BitConverter.ToInt32(bs, 7);
                FileEntries[i].validSize = BitConverter.ToInt32(bs, 11);
                FileEntries[i].crc32 = BitConverter.ToInt32(bs, 15);
                FileEntries[i].compressType = BitConverter.ToInt32(bs, 19);
                var oldPos = br.BaseStream.Position;
                br.BaseStream.Seek(FileEntries[i].offset, SeekOrigin.Begin);
                FileEntries[i].LoadFileData(br.ReadBytes(FileEntries[i].size));
                br.BaseStream.Seek(oldPos, SeekOrigin.Begin);
            }

            br.BaseStream.Seek(4 + 4 + 4 + indexHeadSize, SeekOrigin.Begin);
            emptyIndexHeadSize = br.ReadInt32();
            maxEmptyIndexNum = emptyIndexHeadSize / HeadSize;
            emptyIndexCount = br.ReadInt32();
            Debug.Assert(emptyIndexCount <= maxEmptyIndexNum, "dwIndexCount2 <= m_dwMaxEmptyIndexNum");

            EmptyFileEntries = new FileListEntry[emptyIndexCount];
            for (int i = 0; i < emptyIndexCount; i++)
            {
                EmptyFileEntries[i] = new FileListEntry();
                EmptyFileEntries[i].fileName = ReadAsciiStatic(br, 256);

                // 24
                var bs = br.ReadBytes(24);
                bs = Decrypt(bs);

                EmptyFileEntries[i].offset = BitConverter.ToInt32(bs, 0);
                EmptyFileEntries[i].size = BitConverter.ToInt32(bs, 3);
                EmptyFileEntries[i].originalSize = BitConverter.ToInt32(bs, 7);
                EmptyFileEntries[i].validSize = BitConverter.ToInt32(bs, 11);
                EmptyFileEntries[i].crc32 = BitConverter.ToInt32(bs, 15);
                EmptyFileEntries[i].compressType = BitConverter.ToInt32(bs, 19);
                var oldPos = br.BaseStream.Position;
                br.BaseStream.Seek(EmptyFileEntries[i].offset, SeekOrigin.Begin);
                EmptyFileEntries[i].LoadFileData(br.ReadBytes(EmptyFileEntries[i].size));
                br.BaseStream.Seek(oldPos, SeekOrigin.Begin);
            }
        }
    }
   
    public void Extract(string folderPath)
    {
        if(!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
       
        foreach(var entry in FileEntries)
        {
            entry.Extract(folderPath);
        }
    }
   
    public static byte[] Decrypt(byte[] encrypted)
    {
        var decrypted = encrypted;
        for (var i = 0; i < decrypted.Length; i++)
        {
            decrypted[i] ^= 0xFF;
        }
        return decrypted;
    }
   
    public static string ReadAsciiStatic(BinaryReader br, int maxLength)
    {
        var buf = br.ReadBytes(maxLength);
        buf = Decrypt(buf);
        var str = Encoding.ASCII.GetString(buf);
   
        if (str.Contains("\0"))
            str = str.Substring(0, str.IndexOf('\0'));
   
        return str;
    }
};

MapEditor:
mV8TLLz - Luvinia Server / Client - RaGEZONE Forums


PackageTool (I think I translated this one myself since there are clear differences between mine and the one shared before):
vrao618 - Luvinia Server / Client - RaGEZONE Forums


GameModel Viewer:
aAcBD2e - Luvinia Server / Client - RaGEZONE Forums
Do you happen to still have any of these translated tools? I saw you shared some links last year but none works now.

Also from your C# to extract DP files, i am porting it to python (can't find a lzo.dll to work with my project and thus i fail to execute even when i have a wrapper library) but i got one question. What is the difference between the Load + Extract sequence and the ExtractFiles option? the way i see it one does the extract 1 by 1 while the other loads all the data and then creates all the files... The empty files section of the load function worries me as we load another list of files that we never extract.
 

Attachments

You must be registered for see attachments list
Last edited:
Newbie Spellweaver
Joined
Jun 15, 2021
Messages
13
Reaction score
1
Hi

Now I can open the game, and until this moment it's working very well.

Sometimes it fail to login, because some error about "FLAG 2" (it appears in Login Server LOG), but I just execute the servers until it work. xD

Now the problem is the language

I tried to translate some XML files to see if it change something in the game, but didn't work.

In the "Tools" folder (\Luviniaold\GPHXC\Tools) to do the translation, or, maybe, open the .DP files, in client folder, but I didn't found anything that could help in this part.

Notepad++ couldn't read the file because it is big, but when I open the file "data3.dp", it appears as a broken file.

1684341266598 - Luvinia Server / Client - RaGEZONE Forums


Does anybody know how to make it work? Or get any tool to open the .DP files?
 

Attachments

You must be registered for see attachments list
Newbie Spellweaver
Joined
Jun 15, 2021
Messages
13
Reaction score
1
Thank you, Orion!

I could open the .dp files and have found a lot of things that bring me back memories about the game (I have played this game in 2012, but now somethings look more clear).

Now I think this will work even better :D .

I had a question: what do I need to do after translating the data so that they are applied to the game client?

For example: I translated the warrior skills. Do I just need to transfer the files to some other folder? Does it need to be zipped to match the game server?

How to do this?
 
Last edited:
Newbie Spellweaver
Joined
May 8, 2023
Messages
7
Reaction score
5
I put a new link for the tool that allows editing .DP files :)
thanks for the translated package tool!

there is a tool (QuickBMS) that was recommended a few posts ago and a c++ program. i had just adapted the c++ into a python script to open the DP file but i was thinking how patching, repackaging and upgrading would need to be handled so i was waiting on getting access to that info from a current server i am supporting to see what i could reuse here but this tool looks amazing!

Thank you, Orion!

I could open the .dp files and have found a lot of things that bring me back memories about the game (I have played this game in 2012, but now somethings look more clear).

Now I think this will work even better :D .

I had a question: what do I need to do after translating the data so that they are applied to the game client?

For example: I translated the warrior skills. Do I just need to transfer the files to some other folder? Does it need to be zipped to match the game server?

How to do this?
If things work the way i remember, as long as the IDs of strings match you don't need to do anything else. most of the translations exist in xml files so that is not a big issue...

Now from what i could read on the initial posts for the client to work with the patch you will need to update the PackRes.cfg that basically hosts a checksum for all files so nothing is edited. Idk if the package tool orion shared can also update that (i'd expect it to do it) but if not i was hoping to work on a tool for recreating that file this weekend. All the info on how it is constructed can be seen in the 1st post
 
Newbie Spellweaver
Joined
Jun 15, 2021
Messages
13
Reaction score
1
I'll keep learning and trying until I get it xD

Guys, just for you to keep in mind: if you want, I know of a site to download the client in English. On a Brazilian site that still has a working link.

I'll leave it here in case you're interested.

If you download it, be careful when installing so you don't install random extensions that come with the installer.

Last update of the page: 17/02/2014

 
Newbie Spellweaver
Joined
May 8, 2023
Messages
7
Reaction score
5
I'll keep learning and trying until I get it xD

Guys, just for you to keep in mind: if you want, I know of a site to download the client in English. On a Brazilian site that still has a working link.

I'll leave it here in case you're interested.

If you download it, be careful when installing so you don't install random extensions that come with the installer.

Last update of the page: 17/02/2014

Thanks, i might check it later. I do have my own english client though (from back in the day when i used to play). i have yet to figure out how to repack everything but so far it is looking good.
 

Attachments

You must be registered for see attachments list
Newbie Spellweaver
Joined
Jun 15, 2021
Messages
13
Reaction score
1
Thanks, i might check it later. I do have my own english client though (from back in the day when i used to play). i have yet to figure out how to repack everything but so far it is looking good.
In this print, the client is the one that you own before it start, or is the vietnamese one that you got somethings translated? Looks great your progress.

And how did you get all these itens? (Backpack and cards.)

You create GM character?
 
Newbie Spellweaver
Joined
May 8, 2023
Messages
7
Reaction score
5
In this print, the client is the one that you own before it start, or is the vietnamese one that you got somethings translated? Looks great your progress.

And how did you get all these itens? (Backpack and cards.)

You create GM character?
That is the vietnamese client. English one seems to be a bit behind(there are extra dialogue, skills, maps in the viernamese client) and things like char creation/game login fails (i might know why char creation fails though).

I got the items from the "cash" item shop. As for the cards... i tweaked the shop to be able to buy the card packs (though right now sever seems to be giving only 1 star version of all cards through the packs). I have yet to create a GM character
 
Newbie Spellweaver
Joined
Jun 15, 2021
Messages
13
Reaction score
1
Excellent. Good to know.

I think in the sourcecode folder you can find some txt files that have some information about GM commands.

Earlier today I tried to put some files that I thought were translated into the client, but it didn't work. The files are related to skills, and it stay in the same way as before the changes I tried to do.

Could you give me a reference of which paths and which files you are changing to change the client please?
 
Newbie Spellweaver
Joined
Jun 15, 2021
Messages
13
Reaction score
1
Guys, I figured it out how to translate most of the content of the game quests and texts by copying the informations of a english client textresource folder to World Server texteresource folder.

At the beginning it's fine, because now I can read most of the content of the game. But nothing come without a cost, so there is some quests that fail the function to move character direct to quest coordenate. (I think this is a minor problem, considering that we need, at first, to read and understand the content to move on).

1685285628978 - Luvinia Server / Client - RaGEZONE Forums

1685285640623 - Luvinia Server / Client - RaGEZONE Forums


But, as you can see in these prints, the NPC names and map titles didn't changed.(with "map names" I refer to top right corner info)
Like NPC names, the monster names didn't change too.

I haven't figured out what file I could change to turn it in characters different of the chinese.
Tried even to change the names in the world server textresource folder file called "monsterlist", to monster and NPC names and regionlist to maps names, but it didn't work.

And there is another things that make me think that this server game we got in this thread was a PVP private server:

1 - We start a new character with a lot of itens to lv 70+ and 500k gold.
2 - The first NPC that could get us in the storyline quest just take us from lv 1 to lv 10, without any mission.
3 - After got lv 20+, something happen and you go directly to lv 110.

I really didn't understand what can be done to fix this.

I tried to read the script of the first NPC, but it seems to be in half, with just the part do get lv 10 and choose the class.

Does anybody here know how to make it work properly? Or maybe rewrite this script?
 

Attachments

You must be registered for see attachments list
Newbie Spellweaver
Joined
May 8, 2023
Messages
7
Reaction score
5
Guys, I figured it out how to translate most of the content of the game quests and texts by copying the informations of a english client textresource folder to World Server texteresource folder.

At the beginning it's fine, because now I can read most of the content of the game. But nothing come without a cost, so there is some quests that fail the function to move character direct to quest coordenate. (I think this is a minor problem, considering that we need, at first, to read and understand the content to move on).

View attachment 236258
View attachment 236259

But, as you can see in these prints, the NPC names and map titles didn't changed.(with "map names" I refer to top right corner info)
Like NPC names, the monster names didn't change too.

I haven't figured out what file I could change to turn it in characters different of the chinese.
Tried even to change the names in the world server textresource folder file called "monsterlist", to monster and NPC names and regionlist to maps names, but it didn't work.

And there is another things that make me think that this server game we got in this thread was a PVP private server:

1 - We start a new character with a lot of itens to lv 70+ and 500k gold.
2 - The first NPC that could get us in the storyline quest just take us from lv 1 to lv 10, without any mission.
3 - After got lv 20+, something happen and you go directly to lv 110.

I really didn't understand what can be done to fix this.

I tried to read the script of the first NPC, but it seems to be in half, with just the part do get lv 10 and choose the class.

Does anybody here know how to make it work properly? Or maybe rewrite this script?

Oh nice, i think i can give you extra insight on the missing parts since i have been playing around with many things:

NPC names: All NPCs are generated and linked the same way as monsters, thus if you want to update their names/title you need to modify monsterlist.ini on the world server. Keep in mind because of the decoding of the file it is currently impossible for the names to have spaces so "Bank Administrator" would need to be something like "Bank_Administrator" instead. This is a limitation of the compiled world server, if we could recompile it it might be possible to update that behavior but that seems VERY unlikely.

Map name: Same thing, there are a bunch of xml files with what seems should be the text replacements but are not being called by the server. Instead you will need to change all names from the .ini file in the setup folder
,
1685291242756 - Luvinia Server / Client - RaGEZONE Forums


Broken UI: I stumbled upon this too and i've noticed that it happened after merging the interface folder. Long story short this folder is divided in 2 main parts which is the guixml folder (contains XML that generates all the user interfaces based on the interface assets) and the rest of the folders with assets. From what i experienced some behavior is changed and incompatible between the english game version and the one we are using. So i recommend a manual merge for the guixml files. Doing this fixed a couple of issues for me including: Item shop that stopped working, auto walk from quest window not working properly.

As for the quests, they do not seem to be 100% related to the scripts. Instead steps, quest name, rewards and conditions are all descibed in .xml files in the quest folder of both server/client. Modifying those should allow to have 100% control over each quest, their requirements and their rewards. On the scripts though you should be able to redefine NPC behavior so quests show/stop showing.

I am currently working on a script to auto translate all monsters/NPC names but i am busy this weekend so it won't be ready that soon.

That said i do have a question for you, how do you have the game look... goood? my graphics look like the UI is always doing weird things and adds noise everywhere.

1685291857084 - Luvinia Server / Client - RaGEZONE Forums
1685291869166 - Luvinia Server / Client - RaGEZONE Forums
1685291879881 - Luvinia Server / Client - RaGEZONE Forums
1685291911473 - Luvinia Server / Client - RaGEZONE Forums
 

Attachments

You must be registered for see attachments list
Newbie Spellweaver
Joined
Jun 15, 2021
Messages
13
Reaction score
1
Now I see. I have done the translate of the regionlist.ini file, but I think I made a mess, because the World Server didn't process the file. It just stopped in "DAWN..." (Dawn Town, Star Country) and some trash characters (in log, it seem to be ok, but in the server it do not process no other line).



I will try to make another shot, maybe with another tool. I use NOTEPAD++ to do the changes in files. Sometimes it work very well, sometimes it fails (some crashes in the client, suspending and closing the game before it open).



About the interface: I don't know how to answer that. In some cases, I just take the files of interface that I own, from the SOA Games client (latest files in 2014). I like to edit in one by one, even it take more time than I like xD.



But I have to tell you: in my client, there is some problems in interface too. Specially in the Skills page, because it shows the description of the skills without a specific format.


Now I am out the computer that I make the changes, but when I log in it, I will show some stuff that still need some fixing.

The way I'm working in the server, I think in maybe a month or two it will by online playeable (I wish haha).

But I think the problem with the First storyline NPC quest, in Geneway College is worst than the translation by itself.
 
Banned
Banned
Joined
Apr 20, 2009
Messages
168
Reaction score
21
Now I see. I have done the translate of the regionlist.ini file, but I think I made a mess, because the World Server didn't process the file. It just stopped in "DAWN..." (Dawn Town, Star Country) and some trash characters (in log, it seem to be ok, but in the server it do not process no other line).



I will try to make another shot, maybe with another tool. I use NOTEPAD++ to do the changes in files. Sometimes it work very well, sometimes it fails (some crashes in the client, suspending and closing the game before it open).



About the interface: I don't know how to answer that. In some cases, I just take the files of interface that I own, from the SOA Games client (latest files in 2014). I like to edit in one by one, even it take more time than I like xD.



But I have to tell you: in my client, there is some problems in interface too. Specially in the Skills page, because it shows the description of the skills without a specific format.


Now I am out the computer that I make the changes, but when I log in it, I will show some stuff that still need some fixing.

The way I'm working in the server, I think in maybe a month or two it will by online playeable (I wish haha).

But I think the problem with the First storyline NPC quest, in Geneway College is worst than the translation by itself.
post client link english
 
Junior Spellweaver
Joined
Apr 21, 2023
Messages
141
Reaction score
15
can someone re upload the lunia client and server db ,all source code,pls
 
Newbie Spellweaver
Joined
Jul 2, 2023
Messages
6
Reaction score
1
Guy are you still actively working on the client? Could anyone make a new mega link with the most up to date translation efforts. I am an old player and would love to get a ps running. I am willing to help with translation effort.
 
Newbie Spellweaver
Joined
Jun 15, 2021
Messages
13
Reaction score
1
Hi, guys!

I worked a lot in the files, and have a good result, but it's not done yet.

So let me give you guys some advices:

1 - The server and client files are able to download in the first post of this thread;
2 - In this thread, you will find a lot of information about the files and transaltions (some changes are made in own client, some changes are made in the server files);
3 - The first NPC got the script broken (Antonia), as you can get lv 10 and the class without any work. That is if you want to start a new server to make it PVE;
4 - Even with this problem pointed about script of NPC Antonia, you can take lv 10 and go out of the Geneway College and take some new storyline quests;
5 - I understand that this server was a PVP Server, because when is create a new character, that character starts with some itens lv 70+ and 500k gold.

Some information that can solve the problem of translation of maps and monsters (mobs and npcs):

In World Server folder, there is a sub-folder called "Textresource", there is all text files that bring references to server like skills, hints about npcs, baseui, etc. (there is about 150+ files in this textresource folder).

So there you will find a file called: "globaltextres.xml". In this file, we can see that this file points to some XML Files inside the world server folders.

There is two files called "Monsterlist.xml" and "Regionlist.xml" pointed in "globaltextres.xml"

I have made some tests, but it didn't work at all.
So if anyone can solve this problem about the pointing of monsterlist.xml and regiolist.xml files, the game will get 70% easier to translate (questtexts are easier to translate with ChatGPT xDD).
I hope somebody can make this work and share with us how to make it.

I will attach some prints of xml files.

I suppose that the world server are reading the monsterlist.ini and regionlist.ini when it should read the XML files.
Believe me, translate monsters name and regions name by .INI files is not the best way.

I hope this help you, guys.

1689788291109 - Luvinia Server / Client - RaGEZONE Forums
1689788335646 - Luvinia Server / Client - RaGEZONE Forums
1689788356172 - Luvinia Server / Client - RaGEZONE Forums
 

Attachments

You must be registered for see attachments list
Back
Top