Tuesday, July 3, 2012

Hey?

Good news everyone! not really Passed some exams and finally got back to webgl and fuse again. I should work, right?

Sunday, June 17, 2012

Oh my, oh my.

Oh my, oh my. It has been literally ages since I have written anything in here. And it has been quite long since I have stopped playing with (emphasis on the with) the Silkroad.

Perhaps it is time to come back, with some nice project. The only issue is that I am quite sunken in my university stuff - did I ever tell you how cool algebraic structures are? Nope. And I will not. Ever.

Obviously, I am somewhere in the middle of my university exams, which are not as easy as I would like them to be, although I am in no position to complain since I have chosen this path to enlightenment.

Brace yourselves, the winter updates are coming. For now, you can play with my little (but cool, prolly webkit only) html5 thingy; it is great if you like to fold paper into cyclic shapes.

Monday, August 30, 2010

Friday, August 27, 2010

Fooling around

Not so sinister today. I have been playing with python and C and also finished some qt stuff. Lost hard drive in process (rest in peace). Seen Prince of Persia: Sands of time movie...and I am currently working on Czech subtitles. Screw that...

Anyway, been playing with Silkroad 3DObjects and blender during night. I am working on simple import (and possibly export) toolkit for new 2.53 blender beta...unfortunately API documentation is not complete yet, so its damn hard to get by.

chinawoman_bogy

Thursday, August 19, 2010

Doing it right the way...hopefully?

As always I am updating my blog because of something rather sinister.

This time it because of some certain Germans I am really not satisfied with. I was writing about possible exploits in poorly written code (ie. if the coder was my employee he would already be sacked) in previous article.

It has been few days since I used this exploit on certain server...which has done exactly nothing to prevent it from happening again. I am confused about this because these people claim to be working on their own software, thus they should be experienced enough to prevent such failure...and in case they fail at it, they should be able to patch it. Quickly.

Consider following code (it is written in python again) which works as a 'smart' packet buffer reader, allowing us to read 16-bit integers (words) and string of length indicated by a word. It is only excerpt, original code does much more.

class reader:
 def sword(self):
  return struct.unpack('H', self.bytes(2))[0]

 def ascii(self):
  count = self.sword()
  return self.bytes(count) 

 def bytes(self, count):
  return self.buffer[self.offset:self.move(count)]

 def move(self, by):
  self.offset += by
  return self.offset

Notice the red section. There is a mistake, target of our exploitation. The move function merely adds value (arg: by) to current offset without checking validity of position.

Consider this simple solution...which works, remarkably.
def move(self, by):
  self.offset += by
  if self.offset >= self.length
   raise IndexError

  return self.offset

That much to securing your own code, dummies...

 


Update (as of 20-08-2010): As it became obvious, the emulator that was public (and crashed many times) was actually sremu (which explains the resemblance). Hopefully creators of the sunrise are not that much dummy after all. We shall see in near future.

Tuesday, August 17, 2010

Exploitable? No way!

Are you running some kind of csremu/vbsremu/dsremu/iamsogaysremu? Are you sure that your favourite piece of emulation software is working properly? Is it parsing data properly, checking for possible reading over buffer bounds? Most emulators fail at this. And they fail pretty hard, resulting in crashes and/or possible exploitation and injected code execution.

If you are using interpreted language such as vb6 or c#.net the latter possibility is quite unlikely to happen, however be ready to face out-of-bounds exceptions. Look at this extremely short script, written in python, which is able to crash certain badly written server with a single packet.

import socket
import struct

sockie = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockie.connect(('server.ip', 15779))
sockie.send(struct.pack('HHHBHHH', 9, 0x6102, 0, 0, 0xffff, 0xffff, 1337));
sockie.close()

How does it work? Script assumes that server is that bad written that it does not keep any state of connection and only responds to packets based on their op-codes. This slightly speeds the process up because it can avoid sending 'unnecessary' packets (such as handshake confirmation or patch information). This, however, rapidly reduces number of exploitable packets (in the gateway communication, there are at least 3 of them).

This exploit lays in login packet, which is supposed to look somehow like this:
short length
short opcode
short security

byte  method
short length
byte+ username
short length
byte+ password
short serverid

Now what does it mean? There is length, opcode, security - that makes for a cute packet header. Nothing really exploitable in there (well not directly).

Then, there is the data part - login method, username, password and server id. Look carefully at the username and password fields. In packets, they are stored as a short (16 bit) integer. Their value specifies how long the username is.

Now, what if the value indicated is longer than remaining buffer? There we get our exploit. This causes the long sought out-of-bounds exception. And that is what that little python script does.

Same exploit is possible with client identification (0x2001) and patch information (0x6100) where SR_Client string is sent in exactly same manner.

Happy bugfixing!


Update (as of 19-08-2010): same code should look like this in php:
<?php
 fwrite(fsockopen("server.ip", 15779, null, null, 1.0), "\x07\x00\x02\x61\x00\x00\x00\xff\xff\xff\xff\xff\xff");
?>

Friday, July 9, 2010

Little update

It has been quite long since I have posted here. It has also taken a lot of courage and a lot of beer to actually encourage me to write something. Blessed be the brewery. Whatever.

For those who care, the esro project is still up and running. In short - we have switched to different board software, removed that fugly front page - update: it is up again, god damn it! - and had npcdoom working round a clock to provide you bastards with your drug of choice (silkroad). He has worked really hard, so you can expect another stage of in-house beta test soon. By now, he has nearly everything from to-do (and to-fix) working. Previous few sentences are maybe a little exaggerated. A little. Lets not give up our hopes, he is the god of abyss.

Project status updates

Yeah, all my previous projects are in the nearly same state as they were in by the start of year 2010. I have learnt some new and rather interesting stuff but nothing much. I have also switched from windows to linux platform - this leading to termination of my 'silkroad' requiring projects (good bye dungeons...) - at least until I find myself in mood to work on them.

Also, some week ago, my vacation started. Not that it actually matters. Only that I have to find some work for myself. Paid one, preferably. Although I have most probably found one, the project involved leads to some web-service stuff...meaning some php or java. I am not very fond of java and the too-much-mvc approach people like nowdays. I quit working with php few years ago, only to write in C/C++ (which I have done for past years quite successfully)...

We would like to have crest server before public beta test. After few nights of thinking, I have abandoned the original idea of 'super optimized' server written in C. I have done that because I would have to implement the 'http' or 'ftp' (even worse) layer. I have also abandoned the idea of lighttpd or apache2.x module simply because of the security and development trouble. All of this brought me to an idea 'why not simply use the lighttpd or apache, memory mapping and simple tar archive' with kinda same and rather results?

Whatever...

Friday, December 4, 2009

Map editor progress, new project (sicssi)

Although I should not - because it always ends up like this - I am writing about my yet another new project (actually I never got to write about it). I am always starting new projects, leaving theme unfinished; in state that resembles concept more than working application. Same happened to my older Silkroad project, the SMViewer, which failed and now is part of history. Yes, there have been some talk about its successors - especially about simv and sime (Silkroad map viewer and Silkroad map editor) which are in state of concept as well. I have mentioned that thay are going to be written in C#.Net language, using DirectX for 3D visualisation. I had some problems with DirectX because of Windows 7 and rather stupid Visual Studio (2008). It was caused by some 64b & 32b incompatibilities, simply put: Managed DirectX for C#.Net does not have 64b version.

After I accidentally solved that problem and was able to reproduce fix for it, I wrote another testing application - for those who had that privilege to see it: yes the SimpleTest - this time I had working 3D concept, simple square with editable corners. Application was able to track mouse cursor, project ray through space and search for possible vertex intersections, applied when found first one in vertex array. Once found, this vertex was highlighted and it was possible to change its Y-coordinate (height) by simple pressing left or right mouse button. Simple and nice concept.





It would be extremely easy to create sime, using simple VertexBuffer and IndexBuffer to define map-grid vertices (and some 3D-points representing grid nodes). Yes, I was lazy and had no time (school) to do that. So no progress was done.

Rays in space
I think it will cause no harm if I provide some help to those who do not know 3D-space analytic geometry. I am going to talk about projecting rays and searching for intersections with points in space. It is rather simple, although I will start with some theory.

Having 3D world is one thing; having it rendered into 2D is another thing. Obviously, if we put our cursor on this transformed 2D output, we will never be able to reproduce where exactly our cursor points. However we can reproduce ray between 2 points; one in near plane and one in far plane (near and far planes define distances from camera where we can see - things beyond these are not rendered). So we have this ray that defines where our cursor points. Nice.

We could do some math with Matrices to get these points, but DirectX provides some functionality to do this. Following code example should describe how to have it done.
// Z-coordinate specifies plane in this case
// 0 is near plane, 1 is far plane
Vector3 pointA = new Vector3(mouse.X, mouse.Y, 0.0f);
Vector3 pointB = new Vector3(mouse.X, mouse.Y, 1.0f);

// Method Vector3.Unproject gives us points space, on near and far plane, as we wanted
pointA.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, device.Transform.World);
pointB.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, device.Transform.World);
Once we know points, beginning and end of ray, we only have to search for points laying on it. To do this, we have to know little of analytic geometry - ray equation. Ray equation has many forms, but we are interested in vector-expressed form, which basicly looks like this:



If cx, cy and cz are equal - point is part of the ray, thus point we are searching for. This is nice, however there is little problem - in real situation, these number will never be equal. They will always differ a little - it is up to you, how big difference you wish to tolerate.
Yes, one more thing - ray direction vector is ray origin subtracted from ray end. Easy, is not it?

Saturday, November 21, 2009

Running down a little

So yes, so it seems. Really. Or does not? Whoever knows, tell me. With disjointed (right word for it...I hope) ankle, it is hard to walk; fortunately there is no snow/ice yet. Good global warming, and these bastards want to stop it. Gosh, I hope they are going to melt down in acid some day. Or in their lies. Whatever.

I had some hard school, some hard times - every lesson we have is in different classroom which is always on different level of our school building → total, legendary awesomeness. No I am not lying, I mean it. Honestly.

It also means that I worked only a little on actual esro-related projects, I have also had little affair with Dragon Age: Origins (which caused some school-related hardships, you see).



However I have found some time to work on something more or less related to esro project, I started to learn Managed DirectX basics, means DirectX implementation in .NET, respectively in C#.NET which I prefer to other .NET languages, although Visual Basic is barely a language (at least I do not consider it being language at all).

So, I made some advances in no time - advances from knowing nothing - and I have to admit that I really like DirectX API, it is not like OpenGL, it is OOP and it works well. Lets fry platform compatibility.

Some may also wonder, why C#.NET? Was not I C/C++ maniac? I still am, however I am going to use DirectX in my school project - and unfortunately C is not something we are taught, so I can hardly use it (and no one will understand C; it is gonna be like: "where are classes? I cant see any classes - you have failed"). Also, this C# thing is fast, I mean developement is fast and easy. One point for Microsoft.

I only miss pointers and pointer operations; I also can not fill-in structures directly, as I used to in C. Code like fread(structure_ptr, 1, sizeof(*structure_ptr), file_ptr); will not simply work. Creepy.

But I got over it, resigned, I will just have to reimplement some BinaryReader and BinaryWriter classes, create some own Silkroad.Map class. Should be easy.

And for these of you, who are eager to some progress, there goes one screenshot of my DirectX Testing project.

Saturday, October 31, 2009

Project continues

I have not written a thing since school started - I had too much to do. I attended to Driving classes, to University classes and my little bloggie became the last important thing in my life.

However with less effort I still continue on working on Silkroad (ESRO) things. I have done some additional research of Topography maps, discovered few interesting things. Looked into surfaces, did another discovery. Good for me.

Topography
This time I am not going to describe format or anything. It is already described in previous post (however it is little wrong down there). And it should be easy to understand and correct from following mapan output.
Screenshots
Some screenies from research (done on CSRO since ESRO server is not online yet).




Analysis (partial)
(Doubt anyone is interested though)

<HEADs data>
00 00 00 00 00 00

<CELLs list>
< 95.254616> [  9] 0|0|0|0|0|0 151
< 95.150909> [  9] 0|0|0|0|0|0   0
< 94.895622> [  9] 0|0|0|0|0|0  48
< 39.814507> [  9] 0|0|0|0|0|0 173
< 34.398918> [  9] 0|0|0|0|0|0 255
< 31.741215> [  9] 0|0|0|0|0|0 253
< 30.212603> [  9] 0|0|0|0|0|0 147
< 29.142269> [  9] 0|0|0|0|0|0 147
< 27.314711> [  9] 0|0|0|0|0|0   0
< 28.980433> [ 10] 0|0|0|0|1|0 102 F4
< 57.589970> [ 10] 0|0|0|0|1|0 119 F4
< 99.747597> [ 10] 0|0|0|0|1|0 135 F4
<111.529999> [ 10] 0|0|0|0|1|0 126 F4
<112.705101> [ 10] 0|0|0|0|1|0 148 F4
<110.057098> [ 10] 0|0|0|0|1|0 149 F4
<107.895660> [ 10] 0|0|0|0|1|0 151 F4
<102.116287> [177] 0|0|0|1|0|0 153 F3

... too long → omitted data ...

< 84.616913> [  7] 0|0|0|0|0|0  71
< 86.001633> [  7] 0|0|0|0|0|0  72
< 87.746216> [  7] 0|0|0|0|0|0   0
< 87.350670> [ 10] 0|0|0|0|1|0   0 F4
< 87.209175> [ 10] 0|0|0|0|1|0 174 F4
< 15.944324> [ 10] 0|0|0|0|1|0 173 F4
< 12.501476> [ 10] 0|0|0|0|1|0 146 F4
< 10.208254> [ 10] 0|0|0|0|1|0 149 F4
<  8.148597> [ 10] 0|0|0|0|1|0 146 F4
<  7.875810> [  9] 0|0|0|0|0|0 145
< 10.152893> [  9] 0|0|0|0|0|0 145
< 11.087356> [  9] 0|0|0|0|0|0 145
< 12.417652> [  9] 0|0|0|0|0|0 145
< 10.967405> [  9] 0|0|0|0|0|0 149
<  8.922949> [  9] 0|0|0|0|0|0  41
<  9.426557> [  9] 0|0|0|0|0|0 124
< 24.530247> [  2] 0|0|0|0|0|0  36


<DATAs head>
00 03 00 00 48 42

<DATAs body>
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 04 01 04 01 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 04 01 04 01 04 01 04 01 04 01 04
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 04 01 04 01 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 01 04 00 04 00 04 00 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 01 04 01 04 01 04 00 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 01 04 01 04 01 04 01 04 01 04 01 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 01 04 01 04 00 04 01 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 01 04 00 04 01 04 00 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 01 04 00 04 01 04 00 04
00 00 00 00 00 00 00 00 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04
00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04 00 04

<DATAs more>
a3 4c 10 43 c1 79 ad c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Wednesday, August 19, 2009

Silkroad svtmod project


This project is little toolkit designed for easy modification of Silkroad version file - our familiar SV.T in Media.pk2 pack.

Theory

SV.T file contains encrypted string with version number. This number is converted into integer, divided by 1000 and then added to 1.

Silkroad loads this file, decrypts string inside and converts it into 32-bit integer. This integer has two purposes:
  1. It is displayed (with modification described before) in Silkroad launcher and Silkroad client.
  2. It is sent in 0x6100 packet to server to be checked (and in case it is outdated and still update-able version, Silkroad downloads updates).

Below is described the 0x6100 packet.
Size    Type            Name            Description
---------------------------------------------------
1 char loginMethod Specifies login method (probably)
varies sstr identification Identifies client
4 long version Version of client

SV.T file format
Size    Type            Name            Description
---------------------------------------------------
varies lstr versionString Encrypted string with version

Implementation
I have written simple application in C#.NET for SV.T file modification and reading, the svtmod. As always, it is console based application, with unix-like command line arguments.

Command line arguments
svtmod [-f "path/to/SV.T"] [-v "version"]
  • If path to SV.T is not specified, svtmod uses ./SV.T.
  • If version is not specified, svtmod tries to read value from SV.T path.
Usage example
  • Read version of existing SV.T file
    svtmod -f "media/SV.T"
  • Write version to SV.T file (Silkroad displays this value as 6.666)
    svtmod -f "update/SV.T" -v "5666"
Screenshots
As you can see, there is nothing to see on console application.

Much more interesting stuff - the Silkroad Launcher.

And most interesting one - Silkroad Client.

Tuesday, July 28, 2009

Silkroad news, CREST project and NEKO archive extension

It has been while since I wrote something. So, some new information. We, people from ESRO project are hard working to provide you best gaming experience, although Joymax (also known as b0tmax or gaymax) is doing everything to screw with us. For example, in last update, they have changes OpCodes (identifiers) of packets. Thats is very nice of them, especially because they fucked up their own game as following screenshot illustrates, taken at Xian-65 server in this morning.



It is funny, is not it? No, not that pathetic char of mine, but that horse running around. It probably got startled by some Turk buffing his ass before starting Sroking, which was first bot to run with new OpCodes. At least some people say so. Hilarious!

Also, I have been working on garden today. This event is so rare, that my neighbours were worried about world's damnation. Poor things. I have to admit that I really enjoyed last few days (since Friday) which I spent working outside, without looking into my screen 15+ hours a day. Nice change :)

NEKO archive
So, what is it? Another troll? No, not at all. When I was younger and utter newbie to C/C++ (I was VB6 & PHP kid - hard to believe, is not it?) , I was playing with Burrows-Wheeler transformation and wanted to create super duper compression application. What a folly, I was stupid kid. But at last, I was not dreaming about creating super duper game like others did.

So, why am I writing about NEKO archive? It is not like I have travelled back into past and revived my old compression project I left to die back there.

There is only one reason - my Silkroad project requires it. Crests are little pieces of data, their length is only 256B. Even after converting them back into BMP, their size is about 1334 bytes (1338 bytes when processed by Silkroad client, which adds 4 empty bytes to the end of file) .

Having +- 1kB file is nice, it is not much. But main problem is, that there are thousands of these. Having this much of files on your drive is troublesome. Browsing takes ages, drive is fragmented, and work with these files is rather inconvenient.

Because of this, I have been searching for some archive to store crests in. I wanted to use TAR, however I have found out, that using it would be reTARded, since header for each file is 512 bytes big, filled with useless information or nulls (useless for me). Problem is not uselessness of data in it, but is size. It is twice as big as crest data size. Because this would be nasty waste, I have created much simpler archive format, which does not waste drive's space so much.

So, NEKO format is designated for CREST storing. I might extend it some time, to provide TAR-like functionality without wasting space. But I am not planning it now. I just don't feel like.

Because CRESTS are usually added and never removed (at least, ISRO does not remove them at all), my format is designed particularly for data incrementation.

Archive is structured into 3 parts, listed below:
  1. archive header
  2. colour palette
  3. crest entries
More sophisticated description follows.
Size    Type            Name            Description
---------------------------------------------------
4 char fileType Specifies file identification, value NEKO is used.
4 long fileVersion Specifies file format version, value 0x01 is used.

1024 char colorPalette Specifies colour pallete used by Joymax. It is static member.

4 long crestCount Specifies crest count
varies cstr crestName Specifies crest name, ASCII-string ends with 0x00.
256 char crestData Specifies crest data, its mapping to colour palette.

Well, that is all for today.

Thursday, July 23, 2009

Silkroad maps (SMViewer) project - updated

Few days ago I wrote about my new project, about the SMViewer thing. I spent some time deciding whether I should use DirectX or OpenGL but then I decided that I will prefer OS portability over simple C# implementation for C++ ignorants.

I decided to use SFML window framework - it is simple, fast and nice made OOP, platform independent (*nix, Mac, Windows; what else do I need?) framework which has many other-language bindings (such as C#.Net and D).

My SMViewer engine does not support texturing yet, so I render only wire-network of map. Though it looks nice.

Screnshots







Video

Saturday, July 18, 2009

Int. Silkroad CREST system revealed

Well we have revealed in it night - I have to express my thanks to Callum for borrowing me iSRO account and Rafa for packet and listening to me on MSN: "Thanks you very much!"

Basics

  • ISRO does not use FTP, they use plain HTTP server for crest storing
  • ISRO crest server does not have +Indexes (enabled directory listing), so you will always get, to following lovley message when trying to list crests. Wicked, is not it?
    디렉터리 나열이 거부되었습니다.
    이 가상 디렉터리에서는 콘텐트를 나열할 수 없습니다.
    In English (translated by great Google Translator) it says:
    Directory listing denied.
    This virtual directory can list the content.
  • ISRO crest naming convention is same as in Chinese/Korean version
Packets
We (they, since I am not working directly on server emulator) had some unknown data in one of their packets. Here comes described data part of packet.
Size    Type            Name            Description
---------------------------------------------------
1 char flag ?
4 long guildId ID of guild
varies scstr guildName Name of guild
4 long crestIndex Index of crest
Example with some actual data (packet was caught on Uranus server).
Name                    Value
---------------------------------------------------
flag 01
guildId 71 0B 00 00
guildName 0B 00 44 69 76 69 6E 65 45 6C 69 74 65
crestIndex 03 00 00 00
Getting crest
Now, that we know structure of packet, we can assume how client gets crest from its (crest) server - no matter, whether it uses FTP or HTTP based storage.

However I have described structure of crest name in my Silkroad CREST project post, I will write it here again.
Name                    Description
---------------------------------------------------
type Type of crest (Aliance, Guild)
serverId ID of server
guildId ID of guild
crestIndex Index of crest
Knowing this, we will rebuild name of this actual guild's crest (using data from packet example and knowledge of Uranus server I).
Name                    Value
---------------------------------------------------
type G
serverId 187
guildId 2929
crestIndex 3

Which takes us to name G187_2929_3.crb - easy, is not it?
Now, if we want (of course we want) to download this crest from ISRO, we have to use following url.
http://gdmark.joymax.com:15080/SRO_CREST/G187_2929_3.crb
Extra
As bonus, I give you list of servers with their IDs.
ServerId                ServerName
---------------------------------------------------
65  Xian
74  Aege
76  Troy
94  Athens
96  Oasis
102 Venice
107 Greece
113 Alps
114 Olympus
132 Tibet
134 Babel
150 RedSea
151 Rome
152 Sparta
156 Eldorado
159 Pacific
162 Alexander
165 Persia
166 Zeus
174 Poseidon
178 Hercules
179 Odin
180 Mercury
181 Mars
182 Saturn
183 Venus
187 Uranus
188 Pluto
190 Neptune
191 Hera (New)
194 Gaia (New)
204 Eos (New)
205 Phoenix (New)
206 Ares (New)
207 Iris (New)
208 Titan (New)
209 Apollo (New)
Cheers!

Friday, July 17, 2009

Silkroad maps (SMViewer) project


Hereby, I am announcing it as my new project. I am going to use VC++ and DirectX (9.x), so project wont be Mac/Linux portable.

I have many reasons why I am doing this; one of them is that I would like to make IntroScript editor.

Surface map file (.m)
Brief description of m-map file, which contains surface height and surface texture mapping (with rendering options and brightness).

Header
Size    Type            Name            Description
---------------------------------------------------
8 char type File format type
4 char version Version of file format type
Content
Map block
  • Each map block contains header with unknown meaning.
  • Each map block contains data block with unknown meaning.
  • Each map block contains 17x17 grid of cells.
Size    Type            Name            Description
---------------------------------------------------
6 char header Header, unknown meaning
2023 - - Cells
546 char unknown Unknown data block
Map cell
  • Water begins on level 0.
Size    Type            Name            Description
---------------------------------------------------
4 float height Height of map cell
10b surfaceId Surface texture ID
1b flag_6
1b flag_5
1b flag_4
1b flag_3
1b flag_2
1b flag_1
1 char light Lightness of texture
VC++ notation
struct MBlock
{
        unsigned char header[6];
        MCell grid[17][17];
        unsigned char unknown[546];
};


struct MCell
{
        float height;
        unsigned short surfaceId : 10;
        unsigned short flag_6 : 1;
        unsigned short flag_5 : 1;
        unsigned short flag_4 : 1;
        unsigned short flag_3 : 1;
        unsigned short flag_2 : 1;
        unsigned short flag_1 : 1;
        unsigned char light;
};


Object map file (.o)
Brief description of o-map file, which maps objects into world.

Content
Group
Size    Type            Name            Description
---------------------------------------------------
2 short objectCount Amount of objects in group
Block
Size    Type            Name            Description
---------------------------------------------------
4 long objectId Object model ID
4 float positionX X coord (from left bottom corner of region)
4 float positionY Y coord
4 float positionZ Z coord
2 short unknown 0xffff or 0x0000
4 float theta Angle on Axis Y
4 long unique Unique id of object, if same, object is not shown
2 short unknown 0x0000 or 0x0001
1 char regionX X of region to be used as offset
1 char regionY Y of region to be used as offset
VC++ notation
struct OGroup
{
unsigned short objectCount;
};

struct OBlock
{
unsigned int objectId;
float positionX;
float positionY;
float positionZ;
unsigned short unknown_1;
float theta;
unsigned int unique;
unsigned short unknown_2;
unsigned char regionX;
unsigned char regionY;
};

Silkroad textdata/itemdata project

Silkroad saves information about game objects in text form - "CSV" (though it is separated by TABs, not by commas).

Textdata/Itemdata


Itemdata database cosists of 160 columns, which hold different values. (Why else would there be 160 columns, if they had same values, eh?)
Some columns are not described; that is because I am working on this in my spare time.

Columns description
A  # ?
B # identificator
C # resource identificator
D # chinese name
E # resource identificator (pair)
F # resource identificator (name)
G # resource identificator (desc)
H # ? mall flag (sellable)
I #
J #
K # ? {1 = equip; 2 = pets; 3 = etc}
L # item type
M # item subtype
N # ?
O # race {0 = china; 1 = euro; 3 = universal}
P # item bonus {0 = none; 2 = sox}
Q #
R #
S #
T # flags { 0 = not storable; 1 = not storable; 128; 196; 255 }
U # 0 = trade items; 1 = mall, 3 = rest
V #
W #
X #
Y # 0, 1, 129
Z #
AA # price buy
AB # ? price repair
AC # ? price repair broken
AD # ?
AE # ?
AF # price sell
AG # requirements (1 = level requirement, 513 etc. are skill mastery reqs)
AH # requirements (pair; value)
AI #
AJ #
AK #
AL #
AM #
AN #
AO #
AP #
AQ #
AR #
AS #
AT #
AU #
AV #
AW #
AX #
AY #
AZ #
BA # urn of BSR - equipped
BB # urn of BSR - world
BC # urn of DDJ - icon
BD #
BE #
BF # stacking amount
BG # gender {0 = woman; 1 = man; 2 = unisex}
BH #
BI #
BJ # grade - ceil(grade/3)
BK #
BL # min. durability
BM # max. durability
BN # min. phy def
BO # max. phy def
BP # +val phy def
BQ # min. parry
BR # max. parry
BS # ?
BT # min. phy absorption
BU # max. phy absorption
BV # ? +val phy absorption
BW # min. block
BX # max. block
BY # min. mag def
BZ # max. mag def
CA # +val mag def
CB # min. mag absorption
CC # max. mag absorption
CD # ? +val mag absorption
CE # min. phy reinforce
CF # max. phy reinforce
CG # min. mag reinforce
CH # max. mag reinforce
CI # ?
CJ # ?
CK # ?
CL # ?
CM # ?
CN # ?
CO # ?
CP # ?
CQ # range x10
CR # min. phy attack (min. range)
CS # min. phy attack (max. range)
CT # max. phy attack (min. range)
CU # max. phy attack (max. range)
CV # +val phy attack
CW # min. mag attack (min. range)
CX # min. mag attack (max. range)
CY # max. mag attack (min. range)
CZ # max. mag attack (max. range)
DA # +val mag attack
DB # min. phy reinforce (min. range)
DC # min. phy reinforce (max. range)
DD # max. phy reinforce (min. range)
DE # max. phy reinforce (max. range)
DF # min. mag reinforce (min. range)
DG # min. mag reinforce (max. range)
DH # max. mag reinforce (min. range)
DI # max. mag reinforce (max. range)
DJ # min. attack rating
DK # max. attack rating
DL # ?
DM # min. critical
DN # max. critical
DO # hp recover amount
DP # - chinese
DQ # hp recover percent
DR # - chinese
DS # mp recover amount
DT # - chinese
DU # mp recover percent
DV # - chinese
DW #
DX #
DY #
DZ #
EA #
EB #
EC #
ED #
EE #
EF #
EG #
EH #
EI #
EJ #
EK #
EL #
EM #
EN #
EO #
EP #
EQ #
ER #
ES #
ET #
EU #
EV #
EW #
EX #
EY #
EZ #
FA #
FB #
FC # magical options unit count
FD #
Note: Columns AG-AW contain requirements (such as certain skill level, etc.). These columns are paired. Example and description shall be supplemented.

Silkroad CREST project

One night, I was thinking: "How does the emblem system work?". I could not sleep so I started to fiddle with Silkroad client and started off this this project.

Basics

Silkroad stores guild/union crests on stand-alone FTP server. There is no obvious reason for this implementation and I do not understand why they have done it in this way.

Another weird fact is that files are kept in single directory which makes it really difficult to load (takes long).
Following example shows list of some files from crest storage.
A10_1363_2.crb
A10_1363_3.crb
G90_350_5.crb
G90_350_6.crb
File naming
A10_1363_2.crb
File name written above can be split into these parts:
Name                    Description
---------------------------------------------------
type                    Type of crest (Aliance, Guild)
serverId                ID of server
guildId                 ID of guild
crestIndex              Index of crest
File data
Silkroad uses 16x16 pixel big 8bpp bitmaps with static color palette and no compression. Thus, stored crests on FTP server are 256B big.

Once you know this, it is simple to rebuild "original" bitmap from crest file.
You only need basic knowledge of BMP structure. BMP is composed of 4 logical parts, as is shown below:
header
meta
palette
bitmap (crest file content)
Crest file contains bitmap part of BMP. Since header, meta and palette are static, it is easy to rebuild bitmap:
static part (header, meta, palette)
dynamic part (bitmap)
Issues
  1. FTP server is damn slow
  2. Requests timeout on some occasions
Results
  1. Crest downloader & converter (running)
  2. Some crests from Korean Silkroad.