Welcome to RaGEZONE - MMORPG Development Forums (sponsored by tfn.gr) Mark forums read | View Forum Leaders
RaGEZONE - MMORPG Development Forums (sponsored by tfn.gr)

FlyFF Releases Discuss, Guide on how to Build an Emulator. [ Added FlyFF Emulator Forums ] at Flyff forum; Full C++ video guide I will try to Define the Steps to making an emulator to the best of my ...




Your banner here Image
Have your server description here including a banner, all for $100 a month! click for more details.

Reply
Thread Tools
Guide Guide on how to Build an Emulator. [ Added FlyFF Emulator Forums ]
 
 
FrostElite FrostElite is offline
cout << "Hello World \n";

Rank: Member


Reply With Quote
 
Join Date: Sep 2008
Location: Cin>>Location;
Posts: 614
10-05-2008, 04:04 PM
 
Full C++ video guide
I will try to Define the Steps to making an emulator to the best of my ability
If you have any questions feel free to add my msn elitefrost@live.com

This is not a discussion For Caali's unfixible files

chat room for developers http://xat.com/flyffdevs

Kiki's source files
http://rapidshare.com/files/15249115...files.rar.html


100% Credits to kiki and not me!



Forums for Emulator Devlopment: http://z10.invisionfree.com/FlyFF_De...ex.php?act=idx
Any sort of discussion about Caali's files will be banned.


I once was stuck on how to start an emulator and this is a post that helped me alot

Quote: Originally Posted by adidishen View Post
First, you choose a coding language you want to use to create the emulator.
Then, you learn it, if you haven't done so until now.
Now that you know the basics of the language, you start learning how to use sockets with it.

First, you create a socket, bind it to port 23000, tell it to listen for connections, set it to read and parse data, then send some other data back to the client.

You should use a packet sniffer to know what data to send.
Your emulator should have classes (in my opinion) to work well. Mine has a class for almost everything: MySQL, sockets, packets, inter-server packets, server-related variables, packet parsing, packet handling, logging, client class, configuration files parser, error handling.. that's about all of them.

Good luck.


As far as I know, most of the developers don't use C++ to develop the emulator. Some use Java, but most use C#.
Quote: Originally Posted by gunnerone View Post
you will to know alot of basics to make a flyff server this includes sockets, and packet structure and of course the language it self. You should learn the language and use the flyff server you are trying to build as a lesson for yourself it won't be the best but it will help you build it. You could also use a source from like ms or rose to get you going in the right direction. Just edit the source to fit around the flyff stuff ( like you wouldn't use maple encryption for flyff ).
Credits: gunnerone
addishen



Part I WireShark

First off.

Pick your packet Sniffer. I would suggest using Wireshark since it's free and easy to use. The download can be found here. http://www.wireshark.org/download.html


Got wireshark ? Good we'll start collecting packets from the official Flyff.

First off you open The wireshark program



Go Captures> Interfaces and select your Ethernet card.


Now you need to filter out all other Ip's except the official flyff one



Put First Capture Filter into the Filter Name box. I want you to enter host followed by your ip address into the Filter String box. If you ip address is 192.168.1.2, the Filter String box would contain the following.
host 192.168.1.2


We are telling Wireshark to capture everything coming from and going to your ip address. So we will get a log of all the traffic that is coming from or going to your computer. When you have finished those two changes click the Ok button at the bottom of this page.




You should now be back at the Capture Options window. Then click the Start button at the bottom of the screen.



You are now see packets as they are being sent to and from your computer. You might see a lot of traffic or just a little traffic depending upon how much is going on on your network. If you do not see any packets, try opening up a web page. If you still do not see captured data, then you probably have the wrong Interface selected on the Capture options window. When you have a couple packets, click the Capture option at the top of the screen and then Stop option in the menu that drops down.

Wireshark has captured some data as you can see on your screen. There are three frames here. I have labeled them as Frame 1, Frame 2, and Frame 3 in the picture above. Frame 1 shows you an overview of what packets came in and when out of your network. Frame 2 shows more detailed information about a selected packet. Frame 3 shows the hex data of the packet. We only really care about frame 1. The source column tells us where the data was coming from and the destination column tells us where the data was going to. Both of these columns will always have ip addresses in them. The protocol column tells us what protocol that packet was sent with. Which is useful when trying to figure out what ports/procotols a program uses. The info box contains the information that we really need. The info box lists specific requests made over the network. It also lists what ports the data traveled on. Notice that every time a port is listed it is listed as a pair of ports. Data always travels on ports. It is send out of the source ip address on a port, and then received on the destination ip address on a port. These ports are rarely the same. Keeping that in mind, it is easy to see why there are two ports listed in the info box. The first port is the source port. Notice the > which you can think of as the word to. From the first port > to the second port. I hope that I have explained enough to give you a general feel for the program. Check out the help section of the program for more capture filter options. Notice that there is also a filter box above the data you have captured. This is the dISPlay filter. It works like the capture filter, but allows you to filter data that has already been captured. Click the help button in the dISPlay filter window for examples of how to use it.


Wire Shark Tutorial Credit:
http://portforward.com/networking/ethereal.htm


Part II Capturing Packets and Understanding the structure


Now that you have Wireshark set on the Flyff Ip it's now time to start capturing packets.
Start up Flyff and camp the Server screen or ingame



You should start to be recieving packets sent from the server

Quote: Originally Posted by GlaphanKing View Post
After careful hours of looking through various packets, I was able to determine what I think is the correct structure of the shop window for npcs.

Keep in mind that this is a work in progress but I believe this will help in the construction of new and possibly remixed npc shops.

So here we go. This is a rough breakdown for Boboku's Weapon Shop. For those of you who do not know what I am going to show. Please consult packet structures in the release section.

Code:
[5e]

[INT-Length]

[00 FF FF FF]

[01 00]

[03 00 00 00] --> NPC Spawn ID (I think it tells what shop to open)

[14 00] ---> Call Shop window Command

[00 00 00 00]

[01 -> 63 00 00 00]      ------> 01 00 00 00 to 63 00 00 00 changing the first byte consecutively in hex

[NUMBER OF SLOTS SHORT-INT] -----> Determins how many slots for items on the page

[00 00 00 00] --> Unknown possibly slot number?

[INT-ITEM ID] --> ID of the item (1D = Petal Sword)

[00] x 8

[INT-Quantity] --> I believe this is how many items are in the slot

[NOTE #1] --> This two byte int is an ID for the item type. in this case DD 6D represents Mercenary Sword (I think)

[00] x 40

[01] ---> Next slot
Then it repeats with the next slot. When all of the slots are filled it repeats the 01 to 63 int hex twice and goes to the next page.

When all the pages are done, it repeats that long 01 - 63 int loop again but 3 times.

There you have it. This was captured on Caalis server. It is possible to assume that some of the information is current, but my server might be slightly different than this. I will keep you posted.
Code:
Flyff Packet Structure

short:    2byte
int:    4byte
float:    4byte
pstr:    [(int)length][string]

Client's packet structure
These are packets sent by the client to the server
[(byte)0x5e][(int)unknown][(int)length][data][(int)s]

0x5e:        starts every packet
unknown:    the next 4 bytes should be skipped
length:        length of the data field in bytes
data:        commands/requests to the server
s:        this field has to be saved in the charserver

For recieving the clients packets, you need to read the first 9 bytes(3 fields) of the packet, than determine the remaining bytes by the length field, and read them (its length+4 because length doesnt include the s field).

The data field's structure:
[(int)unknown][(int)0xffffffff][(int)command_id][command_data]

unknown:    yet again. 4 bytes to be skipped
0xffffffff:        this value is constant. allways -1
command_id:    this integer determines what to do with the upcomeing data (if any)
command_data:    this field's size is determined by the command_id (but it doesnt exceed the packet's length+4!).
        Its usually uses the s field for data storage as well.

The client allways sends only 1 command per packet.

Server's packet structure
These are packets sent by the server to the client
[(byte)0x5e][(int)length][data]

0x5e:        starts every packet
length:        length of the data field in bytes
data:        commands/answers to the client

This is basically the same as the clients structure above, without the unknown fields, and without the s field. 

The data field's structure:
Loginserver and characterserver:
These servers only send 1 command per packet.
[(int)command_id][command_data]

command_id:    determines what to do with the upcomeing data
command_data:    size is determined by the command_id, same as above just note there is no s field.

Worldserver:
This server may send multiple commands per packet.
[(int)a][(int)character_id][(short)ncommands][commandfield]

a:        this is usually 0xffffff00, except at the first packet sent by the worldserver, where its 0x0000ff00
character_id:    the character's id wich is logged in on the client wich this packet is sent to.
ncommands:    number of commands in the comand field

The command field's structure:
The command field is consist of ncommands number of commands with the following structure:
[(int)character_id][(short)command_id][command_data]
character_id:    the character's id wich is the subject to the command (ex.: if the command_id is death, the character with id 
        character_id will die in each client wich are recieved the packet)
command_id:    this determines what will happen to the character with character_id, also it determines the command_data field's
        size (migth be 0) (ex.: the command death doesnt require any additional info)
command_data:    any info needed by the client to complete the command command_id

A good way to determine where a command starts is checking your character_id at the beginning of the packet (since that id is your char's id if you recorded your gameplay). Than just search for other appearances of this id.


Packets sent by the loginserver to the client:
command_id    desc            command_data
0        greet            [(int)magic]
0xfd        server list        
0xfe        login refuse        [(int)error_type]    some error types: 0x79: wrong id, 0x78: wrong password, 0x6d: service                     unavaliable
Packets sent by the client to the loginserver:
command_id    desc            command_data
0x18        unknown        none
0xfc        server list request    [(pstr)client compile date][(pstr)unknown][(pstr)username][(pstr)password]

packets sent by the characterserver to the client:
command_id    desc                command_data
0        greet                [(int)magic]
0x0b                        [(int)s][(int)magic][(int)magic]
0x11        first packet after login        [(int)magic][(int)magic][(int)magic][(int)magic]
0x14        this should only be sent after    [(int)s]    (sends back the last saved s field)
        the client authenticated itself
        the client will keep calling this while it runs, and the characterserver should allways repply, else the player gets dc.
0xf2        only sent after authentication    [(pstr)serverip]
0xf3        character informations        [(int)s][(int)n_chars][character_data][(int)n_chars][additional_data]
                        nchars=number of characters
                        character data sent n_chars times, with the data of the nth char.
                        additional_data sent n_chars times, structure:
                        [(byte)0][(int)0][(int)0][(int)0]


packets sent by the client to the character server:
0x0b        unknown            none
0x11        should answer with 0x14 if    none
        the client isnt authenticated
        itself yet, nothing otherwise
0x14        answers with 0x0b without the character list shown, 0x14 after

0xf4        character create            [(pstr)username][(pstr)password][(byte)slotid][(pstr)character_name]
                        slotid: 0=left, 1=middle, 2=rigth
0xf5        character delete            [(pstr)username][(pstr)password][(pstr)unknown][(int)character_id]
0xf6        character list            [(pstr)unknown_date][(pstr)username][(pstr)password]
0xff05        last packet before worldserver    [(pstr)user][(int)unknown][(pstr)character_name]

The characterserver has a pretty nice "dance" here, if you make one step wrong, the client migth freeze.
The authentication is complete when the client send your username and password the first time (the characterserver will repply to this packet with the character list)
The dance is like this:
    if Client sends 0x0b, server repplies with 0x11
    if the client sends 0x11, the server repplies 0x14 ONLY if the client hasnt autheticated yet
    if the client sends 0x14, the server repplies 0x0b if not authenticated, 0x14 if authenticated
    if the client sends 0xf6, itll get authenticated, and the server should send 0xf2 (ip), than 0xf6(charlist) rigth after

from hereon the charserver shouldnt do anything, (itll just keep repplying to the clients 0x14's with 0x14's, (else the client will get dc))
after you choosen your character, the client will send a 0xff05, and connect to the worldserver after it recieved the answer from 0xff05


Worldserver:
I begin with some text here.
For the first packet, you recieve a damn long and big and important and whatnot packet.
Its a spawning packet, basically spawns your character into the world. And its contains nearly every damn information to do it.

command_id    desc            structure
0xf0        spawn, damn lot of variations of this packet
0xf1        desapwn(remove)    none
0xf2        mapchange        [(int)mapid][(float)x][(float)y][(float)z]
0x98        special motions        [(int)motion id]    (ex.: 4=sitdown/standup)
0xc1        movetoxyz        [(float)x][(float)y][(float)z][(byte)1]
0xc2        movetochar        [(int)character_id][(int)0]
0xc7        death            [(int)killer_character_id][(int)0x29]
0xc8        teleport            [(float)x][(float)y][(float)z][(int)0][(int)0][(int)0][(int)0][(int)1][(int)0][(int)0][(int)-1][(int)4][(int)0][(int)0][(int)0]
0xcb        motionok        [(float)x][(float)y][(float)z]...etc...
0xcc        flying            [(float)x][(float)y][(float)z]...etc...
0xe0        attackmotion        [(int)motion_id][(int)target_character_id][(int)0][(int)0x10000]
0x13        damage (numbers)    [(int)attacker_id][(int)damage][(int)flags]
0x0f        effect(like success/failure)  [(int)effect id][(float)x=0][(float)y=0][(float)z=0][(int)0]    (if x,y,z=0 here, the client will 
                    use the characters x,y,z who got the command)
0x19        skilleffect        [(int)skill_id][(int)skill level][(int)target_character_id][(int)0][(int)3]
0xa0        green text        [(byte)1][(pstr)text]
0xd0        shout            [(int)shouter_character's id (migth not visible in client)][(pstr)shouter_char_name][(pstr)text]
0x01        chat            [(pstr)text]
Quote: Originally Posted by ανєяηιкαѕ View Post
Well, Although I dont want a source to be released, I also dont want to limit other developers - who like me may have trouble figuring out the packets... Took me a while to understand them too.

So I'll list here packet information as I figure it out, that way someone with enough coding knowledge can create a private server, and we still keep the private server numbers rather low.

I'm starting to day with the Login server, I'll post the Character server, and known packets of the world server tomorrow as I'm lazy... LOL

Key
4 Bytes - Integer, Hash
2 Bytes - Short
8 Bytes - Long

* - When I have a * before INT, it means the integer is little edianed. (http://en.wikipedia.org/wiki/Endianness#Little-endian), this is on server packets and client packets, if I use the * on a server packet, it means you need to make it little edian, if I use it on a client packet, it means its already little edian, so you gotta change it back to normal. Not sure if ALL intergers are like this, I dont think I've come across one that isnt yet, but I'll let you know in the future.

When I use "INT-Length" it means the length of the data following those 4 bytes (As an Integer).

When I use "##-Command" it means the as 4 bytes, ## being the command.

Comments made by me for extra info (like the one about capacitys on eFlyff) are bold, followed by italics.

Common Packets
First thing the server does after receiving a connection is it sends a session key.

Length: 13
Structure
Code:
[5E] [INT-Length] [00] [00] [00] [00] [00] [00] [00] [00]
The last for bytes can be changed to whatever you want, the session key is then used for creating hashes in future packets, thought I might also mention that this is the case for all the servers, (Login, Characters & World).

Login Server
Remember, after receiving a connection, the server sends the session key.

Login packet (Client -> Server)

Structure
Code:
[5E] [HASH-Length] [INT-Length] [HASH-Data] [INT-Data] [FC-Command] [INT-Length] [Date-Reversed] [*INT-Length] [Data-Note#1] [*INT-Length] [Username] [*INT-Length] [Password]
Note #1: I think its a hash of the flyff.a file, might be wrong though.

Incorrect Login (Server -> Client)

Length: 13
Structure
Code:
[5E] [INT-Length] [FE] [00] [00] [00] [Data-Note#2] [00] [00] [00]
Note #2: Its the type of incorrect login (Wrong password, wrong ID, Banned etc...)

Types
Code:
[27] - Opps try again.
[77] - This ID has been blocked
[78] - Wrong password
[79] - Wrong ID
[80] - Your time is up
[81] - Other DB Error
[83] - You cannot connect after 22:00
[84] - You cannot connect from outside the service for Flyff.
[85] - Your character is being checked at the moment. Please login after a while.
[86] - Wrong password, cannot log into account for 15 seconds.
[87] - Wrong password three times, cannot log into account for 15 minutes.
[88] - Server verification error.
[89] - Session is over. please try again.
[6D] - Service is currently unavailable, please check Flyff site for details.
[FF] - Connecting please wait...
[67] - This account is already connected. (Yes/No)
Correct Login (Server -> Client)
Ok so they logged in correctly, YAY lets send the server list.

Structure
Code:
[5E] [INT-Length] [FD-Command] [Note#3] [INT-Length] [Username] [0B] [00] [00] [00] [FF] [FF] [FF] [FF] [*INT-Server ID] [*INT-Length] [Server Name] [*INT-Length] [Server IP] [00] [00] [00] [00] [00] [00] [00] [00] [01] [00] [00] [00] [00] [00] [00] [00] [*INT-Cluster ID] [*INT-Channel ID] [*INT-Length] [Channel Name] [00] [00] [00] [00] [00] [00] [00] [00] [*INT-Online Players] [01] [00] [00] [00] [*INT- Channel Capacity]
Ok, after the first channel is finished, you can continue more channels, just repeat from INT-Cluster ID, once you've added all the channels to that cluster, you can repeat the next cluster & its channels by repeating the bytes, starting from [FF] [FF] [FF] [FF]

Note #3: I dont know what these 5 bytes are, never really looked into it, chances are its a hash of some sort of the following data, anyway eFlyff uses [FE] [CE] [84] [B0] [01] (and so do I, and it works :P)

Handy Info
Flyff channels can store 1100 players each (Maybe they're done that to optimize lag? Presuming they have the money for the best servers... they've limited it to that for a reason, where FlyForFame (havent checked exactly) have gone waaaay over 1100 (GM Notices boasting about 2k+) and its VERY laggy...

Also thought I'd mention, if you sit on the server selection screen doing nothing, client sends (roughly every minute) this packet:

Code:
[5E] [94] [A7] [D8] [58] [04] [00] [00] [00] [0B] [F0] [C1] [08] [14] [00] [00] [00]
I dont reply to it, and the client doesnt D/C, im unsure on what it does... eFlyff doesnt seem to reply to it either... Currently I'm using it to update the logged in timestamp, and if I dont receive activity from a client without 2 minutes, I close the connection (Presuming they closed, lagging/etc you know that annoying "Disconnected message" on eFlyff... it could also be used to send updated Players online data (for the (Normal) (Busy) (Full))...

Its totally up to you xD

Database
At this point, I (think) my database was structured like this (may be wrong cause I cant exactly go back in time :(.

Accounts
- ID
- Username
- Password
- Banned
- Last_IP

Clusters
- ID
- Name
- IP

Channels
- ID
- Cluster
- Name
- Capacity

----------------------------------------------------------------------------------------------------------------------------

Righteo, and to start the Character server, I'll see how far I get before I get bored of typing, also I'm not sure on the order of these packets, but then you shouldn't be coding your server to run in order anyway.

First things first, dont forget on connection to send the session key.

Authentication
I'm not going to explain Authentication, its alot of information and I'm to lazy to post it, check the other thread here about the Flyff Packet structure, it explains Authentication.

Server Select (Client -> Server)
After selecting a server, it then connects to the Character server, and authenticates. Character server packets are identified by the 17th byte.

Packet command: [F6]
This packet contains date, verification hash, username & password.

Your server should check this information is correct, and then send back the characters that belong to this person.

Character Display (Server -> Client)

Structure
Code:
[5E] [INT-Size] [F3] [00] [00] [00] [Data - Note #4] [00] [00] [00] [00] [*INT-Slot] [INT-Length] [INT-Map ID] [0B] [00] [00] [00] [*INT-Length] [Char-Name] [Float-X] [Float-Y] [Float-Z] [*Char-ID] [00] <- x 16 [*INT-HairStyle] [INT-HairColor] [*INT-Face] [INT-Gender (0/1)] [*INT-Job] [*INT-Level] [00] [00] [00] [00] [*INT-STR] [*INT-STA] [*INT-DEX] [*INT-INT] [00] [00] [00] [00] [INT-Note#5] [INT-Note#6] .....
From there you can repeat it again for the next char, if they have another char (Start again from the INT-Slot).

Once you've added all your chars...
Code:
[*INT-LastCharSlot] [*INT-Note#7]
Note #4: 4 Byte verification that you get from the authentication hash.

Note #5: This is an INT, of how many items the person has equiped (Only counting... helmet, suit, gaunlets, boots, cs helmet, cs boots, cs gaunlets, cs suit, cloak, weapon & shield/weapon 2.

Note #6: This is the ID's of each item, 1 after the other.

Note #7: Depending on how many chars there were you add this times char amount.

Code:
[*INT-Char #] [00] [00] [00] [00] [00]
Of course the first INT in that lot would either be the amount of chars loaded, so if you loaded slots 0 & 2, it would have 2 of that set of bytes, first being 0 second being 1.


... Hope thats helpful to someone, and that it makes some sense x_X I dont think I'll be posting anymore as its rather hard to change my code back into packets xD... but if I do I'll take you guys right up to the World spawn, cause that packet is insanely large and I dont want to explain it...

Good Luck ^_^


------------------------------------------------------------

Note

If you want to learn how to code a server, heres some stuff packages to look up in java: (These are the imports im currently using).

java.net.ServerSocket
java.net.Socket
java.util.Vector
java.util.Enumeration
java.io.*
- ByteArrayOutputStream
- OutputStream
- IOException
java.sql.*
java.util.zip.CRC32

Enjoy, and have fun coding ;)

P.S Sorry about my spelling & grammer, I know its not the greatest, but hopefully its readable :|

Edit: Attached is the document I used to figure out the structure of the Clusters list, got to the second cluster before I saw the pattern, someone might find it handy... maybe? Also - someone needs to add ".docx" to the valid uploads list x_X

*** UPDATED ***

Credits for packet breakdowns
DeadlyData
GlaphanKing
GZP
ανєяηιкαѕ




Part III Learning a Coding language and Starting your source!


The two most famous Flyff emulator coding language is c++ and c#
You can either 1. Learn it in college 2. Use Online tutorials.
Some great tutorial sites for learning c++ is
www.cplusplus.com/doc/tutorial/
www.cprogramming.com/tutorial.html

And some great sites for learning c# is
www.functionx.com/csharp/index.htm
http://www.softsteel.co.uk/tutorials.../contents.html
www.java2s.com/Tutorial/CSharp/CatalogCSharp.htm


Once you've started to capture packets you now Hide them, then seek them and add them to the source.
a source could be a .cpp or .h File. It would be Ideal to .have . cpp or c# files that have actually coding in it [Both of these will be explained don't worry]


.cpp also known as C++ Source Code Files
Cpp is a Program source code written in the C++ programming language; may be a standalone program or one of many files referenced within a programming project; can be viewed with a text editor, but most software development programs will display the text with helpful syntax highlighting.
More Stuff will be added!

Break Down of a Cpp file

Code:
 Breakdown of a source code (.cpp) file
A file comment description codeblock.
It is formatted the same as the header file.

   //----------------------------------------------------------------------------------------
	 /*!
	 \file       bookmark_dialog.cpp       
	 \modified                            
	 \copyright  (c) Robert O'Connor ( rob@medicalmnemonics.com )    
	 \licence    GPL
	 \brief      Describes bookmark_dialog class    
	 \author     Robert O'Connor
	 \date       2002/01/03    
   */  
   // RCS-ID:      $Id: included_breakdown_cpp.html,v 1.1 2002/09/02 02:27:13 robertoconnor Exp $
   //----------------------------------------------------------------------------------------

GCC implementation codeblock.
This is the second part of the GCC #pragma interface/implementation combo. It goes as the first line. This #pragma tells the compiler that is the one and only .cpp file that should hold the debug info for the class. It should be the header of this class. Turned off for APPLE, since OSX Jaguar doesn't like it (or need it).

   //----------------------------------------------------------------------------------------
	 // GCC implementation
	 //----------------------------------------------------------------------------------------
   
   #if  defined(__GNUG__) && ! defined(__APPLE__)
   #pragma implementation "bookmark_dialog.h"
   #endif

Application setup.h codeblock:
Include the application's setup.h file, so that we can remove everything in the next part, if the feature is one that we want to compile out.

   //----------------------------------------------------------------------------------------
	 // Setup information
	 //----------------------------------------------------------------------------------------
   
   #include "setup.h"

Start feature removal codeblock:
Same idea as header had.

   //----------------------------------------------------------------------------------------
	 // Begin feature removal condition
	 //----------------------------------------------------------------------------------------
   
   #if ( setupUSE_INTEGRATED_HTML_EDITOR )

Standard wxWindows headers codeblock:
A block that will be the same unchanged in every single .cpp file of the project. (You can skip reading through the details of it if you what if you don't care about what is going on).

   //----------------------------------------------------------------------------------------
	 // Standard wxWindows headers
   //----------------------------------------------------------------------------------------

This includes the headers for the compilers that support precompiled headers to increase compile speed of the application.

   // For compilers that support precompilation, includes "wx/wx.h".
   #include "wx/wxprec.h"

The #pragma hdrstop for BCC tells the compiler that all the headers above that pragma are the same same (which they are, since BCC compiler won't see the #pragma interface of GCC). BCC has precompiled headers which will greatly speed up compile time, but for it to work, everything above #pragma hdrstop has to be the same for all the .cpp files. Therefore put the headers that are unique to this file after this #pragma hdrstop.

   #ifdef __BORLANDC__
   #pragma hdrstop
   #endif

If it isn't a compiler that can support precompiled headers, then just include a long list of the most commonly used headers in the wxWindows library, like windows, strings, etc.

   // For all others, include the necessary headers (this file is usually all you
	 // need because it includes almost all "standard" wxWindows headers)
   #ifndef WX_PRECOMP
   #include "wx/wx.h"
   #endif

Header of this .cpp file codeblock

   //----------------------------------------------------------------------------------------
	 // Header of this .cpp file
	 //----------------------------------------------------------------------------------------
   
   #include "bookmark_dialog.h"

Remaining headers codeblock:
These are the unique headers needed by this class. For better sourcecode organization, they are always arranged in the order of first the wxWindows library headers required by the class, then any wxWindows/contrib headers required (often just the XRC resources header), then finally any headers of the application.

   //----------------------------------------------------------------------------------------
	 // Remaining headers: Needed wx headers, then wx/contrib headers, then application headers
	 //----------------------------------------------------------------------------------------
   
   #include "wx/xrc/xmlres.h"          // XRC XML resouces
   
   //----------------------------------------------------------------------------------------
   
   #include "utils_controls.h"
   #include "help_controller.h"

Internal constants codeblock (some classes)
Some classes may use some internal constants, such as id numbers for a popup menu, list columns, etc. If so, these internal constants should go into this block.

   //----------------------------------------------------------------------------------------
	 // Internal constants
	 //----------------------------------------------------------------------------------------
	 
	 // Popup menu (PU) item IDs                           
      enum {
      PU_ADD_CHANNEL                              = wxID_HIGHEST + 2, 
      PU_ADD_CHANNEL_WIZARD,
      PU_CONFIGURE_CHANNEL
   };

DECLARE_DYNAMIC/ABSTRACT_CLASS codeblock:
If the header had a DECLARE_DYNAMIC_CLASS(), then a IMPLEMENT_DYNAMIC_CLASS()  now needs to go here. If it was DECLARE_ABSTRACT_CLASS() in the header it wold be a IMPLEMENT_ABSTRACT_CLASS() here instead.

   //----------------------------------------------------------------------------------------
	 // wxWindows macro: implement dynamic class
	 //----------------------------------------------------------------------------------------
      
      IMPLEMENT_DYNAMIC_CLASS( bookmark_dialog, wxDialog )
   

Event table codeblock (classes that want to handle events):
This is the event table for the class. This is used for you to connect a certain event to a certain custom function.

   //----------------------------------------------------------------------------------------
	 // Event table: connect the events to the handler functions to process them
	 //----------------------------------------------------------------------------------------
   
   BEGIN_EVENT_TABLE( bookmark_dialog, wxDialog )

Entries for children of the class have 3 parts:
-EVT_BUTTON: What type of event it is that should be connected to the custom function (a button click event)
-wxID_HELP_CONTEXT: Only events raised by buttons by that ID will be sent to the custom function. wxID_HELP_CONTEXT is a special ID nubmer define for the help button. The ID number of -1 would specify events raised by all buttons.
-bookmark_dialog::on_help_button: This is the custom function that should be fired by button events raised by the buttons with an ID of wxID_HELP_CONTEXT.

   EVT_BUTTON( wxID_HELP_CONTEXT, bookmark_dialog::on_help_button )
   EVT_BUTTON( wxID_OK, bookmark_dialog::OnOK )

If the event is raised by a some child control in the XML resources, then just specify the control with a XRCID() macro. In this hypothetical example, only button click events named "bookmark_dialog_preferences_button" in the XRC file will trigger the on_preferences_button() function.

       EVT_BUTTON( XRCID( "bookmark_dialog_preferences_button" ), bookmark_dialog::on_preferences_button ) 

An event raised by the class itself for example the event of this dialog closing obviously doen't need an identifier, so just 2 parts here:
-EVT_CLOSE: Only close events will be sent to the custom function.
-on_close(): The custom function that should be fired.

       EVT_CLOSE( main_frame::on_close )    
   
   END_EVENT_TABLE()

Public members codeblock:
A block of what the public members of the class should do. The first member is the constructor, then the destructor, then the rest.

   //----------------------------------------------------------------------------------------
	 // Public members
	 //----------------------------------------------------------------------------------------
   
   bookmark_dialog::bookmark_dialog( wxWindow* parent )
   {
   wxXmlResource::Get()->LoadDialog( this, parent, "bookmark_dialog" );
   }
   
   
   bookmark_dialog::~bookmark_dialog()
   {
   }
   
   
   void bookmark_dialog::transfer_to( wxString& starting_text, wxString& ending_text )
   {
   starting_text = m_starting_text;
   ending_text = m_ending_text;
   }

Protected members codeblock:
A block of what the protected members of the class should do, if there is any.

   //----------------------------------------------------------------------------------------
	 // Protected members
   //----------------------------------------------------------------------------------------

Private members codeblock:
A block of what the private members of the class should do.

   //----------------------------------------------------------------------------------------
	 // Private members
	 //----------------------------------------------------------------------------------------
   
   void bookmark_dialog::OnOK( wxCommandEvent& event )
   {
   wxString output_string;
   wxString buf;
   
   output_string = "<a";    
   
   wxString name_string = XRCCTRL( *this, "bookmark_dialog_name_textctrl", wxTextCtrl )->GetValue();
   output_string += " name=\"" + name_string + "\">";
   
   wxString description_string = XRCCTRL( *this, "bookmark_dialog_description_textctrl", wxTextCtrl )->GetValue();
   output_string += description_string;
   
   output_string += "</a>";
   
   // Store the starting and ending strings as class members, ready to be transferred
	     // by transfer_to(...) method.
       m_starting_text = output_string;
   m_ending_text = "";
   
   // Get rid of the modal dialog. Not transferring any info from this modal's control
	     // to a parent dialog, so don't have to bother with wxWindow::Validate or 
	     // wxWindow::TransferDataFromWindow.    
       EndModal( wxID_OK );
   }
   
   
   void bookmark_dialog::on_help_button( wxCommandEvent &event )
   {
   #if ( setupUSE_ONLINE_HELP )
   help_controller::get()->show_help_topic( plkrHELP_ID_BOOKMARK_DIALOG );
   #endif 
   }

Module definition block (only a few global classes):
Not in bookmark_dialog, but in a few classes such as plucker_controller, help_controller, and commandline_parser, you will see they are set up with wxModules. These wxModules remove the requirement and headaches of creating and cleaning up globals. To use a wxModule instead of  a global, there is a derived class wxModule definition down at the bottom of the class's .cpp file (the module doesn't need to be mentioned in any header anywhere). 

Before the program 'starts' any execution, it gets a list of all the modules in the application and runs all of their OnInit() functions (which will do nothing in this application; they just return TRUE). After the program 'ends', then all of the wxModule's OnExit() functions are called, which will clean up the classes managed by the wxModule.

Each of the classes managed by wxModule have a get() and set() method which gets or sets the single instance. By calling some_class::get() you can create an instance on demand if there isn't one yet, but retrieve the existing instance if there is one already made. For example, see the call to help_controller::get()->show_help_topic(plkrHELP_ID_BOOKMARK_DIALOG) in the bookmark_dialog::on_help_button() above: it will get the single help_controller and call its show_help_topic() method if it exists already, or else create one on demand and then do its show_help_topic() method.

   //----------------------------------------------------------------------------------------
	 // Module definition
	 //----------------------------------------------------------------------------------------
	 
      class module_body_dialog : public wxModule
      {
      
      DECLARE_DYNAMIC_CLASS( module_body_dialog )
      
      public:
      
      module_body_dialog() {}
      
      bool OnInit()
      {
      return TRUE;
      }
      
      void OnExit()
      {
      wxLogDebug( "Entered module_body_dialog::OnExit()" );
              // We set it to null, and a pointer returns to the previous one, which we delete.
              delete body_dialog::set( NULL );
      wxLogDebug( "Completed module_body_dialog::OnExit()" );
      }
      
      };
      
   IMPLEMENT_DYNAMIC_CLASS( module_body_dialog, wxModule )

Break Down of a c# Source File

Code:
 any programming languages have well defined standards for documenting source code. These standards are useful in that they allow developers to add comments to code in a uniform format. Furthermore, it is possible to use tools to extract the documentation from an entire application's source code and use it to automatically produce project technical documentation in a fraction of the time it would take to manually produce the documentation.

Programming languages such as Java have had code documentation standards for many years. The Java system is called JavaDoc, and allows developers to easily create HTML format documentation from project source code.

Since classic Active Server Pages (ASP) has no defined standards of source code documentation, ASP web application documentation of source code can vary enormously from project to project. While applications such as our ASP Documentation Tool can create technical documentation from ASP source code, lack of a defined documentation standard is a major limitation of ASP. Visual Basic 6.0 is similarly affected by a lack of documentation standards (although our VB Documentation Tool resolves this).

Thankfully with the introduction of the .NET Framework and the new C# programming language, Microsoft included some form of code documentation standards - XML Comments. These were further enhanced with the 2.0 release of the .NET Framework (which also allowed XML comments to be used with VB.NET.
Commenting C# source code

XML comments are added to source code by prefixing the XML comment lines with three forward slashes. Visual Studio will automatically insert a documentation template whenever three forward slashes are typed within a C# source code file. Visual Studio's intellisense system also works within XML comments, using the comments to enhance the information presented about a class, constructor or other member.

Although these comments can potentially be added to the source code at any point, it is usual to ensure that documentation is inserted immediately before the definition of classes, functions, subroutines and properties, thereby allowing these members to be documented. An example of a function documented with XML comments is shown below:

/// <summary>  
///<para>Non-HTML files like Adobe Acrobat PDF files and Word  
///documents are stored with their original URLs partially  
///encoded in their filenames. This function will return the  
///original URL of the file.</para>  
///<para>The encoding done by the Index Server Companion removes  
///characters that cannot be present in Windows filenames  
///(these are: \/:*?"<>|). The decoding performed is:</para>  
/// <list type="table">  
/// <listheader><term>Find</term><description>Replace</description></listheader>  
/// <item><term>^f</term><description>\</description></item>  
/// <item><term>^b</term><description>/</description></item>  
/// <item><term>^c</term><description>:</description></item>  
/// <item><term>^s</term><description>*</description></item>  
/// <item><term>^q</term><description>?</description></item>  
/// <item><term>^d</term><description>\</description></item>  
/// <item><term>^l</term><description><</description></item>  
/// <item><term>^g</term><description>></description></item>  
/// <item><term>^p</term><description>|</description></item>  
/// </list>  
/// </summary>  
/// <param name="FileName">The document's original filename.</param>  
/// <returns>Decoded filename</returns>  
/// <exception cref="System.Exception">Throws an exception when something goes wrong.</exception>  
private string CreateURLFromFileName(string FileName)  
{

    try  
    {
        //Remove o_ prefix from URL  
        FileName = FileName.Substring(2, FileName.Length - 2);

        //Remove other encoded characters  
        FileName = FileName.Replace("^f", "\\");
        FileName = FileName.Replace("^b", "/");
        FileName = FileName.Replace("^c", ":");
        FileName = FileName.Replace("^s", "*");
        FileName = FileName.Replace("^q", "?");
        FileName = FileName.Replace("^d", "\"");
        FileName = FileName.Replace("^l", "<");
        FileName = FileName.Replace("^g", ">");
        FileName = FileName.Replace("^p", "|");
        FileName = FileName.Replace("^f", "\\");
        FileName = FileName.Replace("^f", "\\");
        FileName = FileName.Replace("^f", "\\");
        FileName = FileName.Replace("^f", "\\");
    }  
    catch  
    {

    }

    return FileName;

}

This example shows that as well as a general description of the function's purpose, the function's arguments and return values can also be documented using standard syntax. There are also clearly defined standards for cross-referencing the documentation, adding hyperlinks, lists, tables and code samples. The MSDN documentation for the .NET Framework describes all of the XML comment standard markup supported by the .NET Framework. It is also possible to use your own XML tags within the comments.
The "official" XML comment tags

The following XML comment tags are officially supported in C#: c,code, example, exception, include, list, para, param, paramref, permission, remarks, returns, see, seealso, summary and typeparam.

c: This tag is used to denote code, so it can be used to identify sample code associated with a particular entity within the source code. Note that the tag can only be used to represent a single line of code or to denote that some of the text on a line should be marked up as code. Example: <c>double SalesTotal = 12</c>

code: This tag is used to denote more than one line of code, so it can be used to identify longer areas of sample code.

example: This tag may be used to describe an example of using a particular method or class. It is possible to include code samples within the example tag by making use of either the c or code tags.

exception: The exception tag allows a method's exception handling to be documented. The cref attribute allows the namespace of the exception handler to be included. Example: <exception cref="System.Exception" >Throws an exception if the customer is not found.</exception>

include: This tag allows documentation to be imported from an external XML file rather than being stored within the source code itself. As such it may be useful if the documentation is written by people other than the software developers (e.g. technical writers).

list: This tag allows bulleted or numbered lists or tables to be added to XML comments.

para: This tag indicates that the text within the tags should be formatted within a paragraph. As such it can be used to format text within other tags such as summary or returns. Example: <para>This is a paragraph</para>

param: The param tag is used to document a method's arguments. The tag's name attribute specifies the name of the argument to which the tag refers. The tag is also used by Visual Studio's Intellisense system to show a description of a method's arguments. It is also used by the Visual Studio Object Browser. Example: <param name="FileName" >The filename of the file to be loaded.</param>

paramref: This tag can be used to refer to a method's argument elsewhere within the method's XML comments. The tag's name attribute specifies the name of the argument to which the tag refers. Note that the param tag is actually used to describe the parameter. Example: Use the <paramref name="FileName"/> argument to specify which filename is loaded.

permission: The permission tag can be used to describe any special permissions a specific object needs. The object to which the permission refers is included as the cref attribute. Example: Class needs to write to the file system, ensure user has appropriate access.

summary: The summary tag describes a method or class, so it is the most important tag. As well as being used in a project's documentation, the tag is also used by Visual Studio's Intellisense system to show a description of the method or class being referenced. It is also used by the Visual Studio Object Browser.

remarks: The remarks tag can be used to supply additional information about a method or class, supplementing the details given in the summary tag. As with the summary tag, this tag is also used by Visual Studio's Intellisense system and the Visual Studio Object Browser.

returns: Describes the return value of a method. Example: <returns>True if user has permission to access the resource, otherwise False.</returns>

see: The see tag is used to reference other entities (such as classes) in the project. The see tag is intended for use within other tags such as the summary tag. Example: <seealso cref="System.Configuration"/>

seealso: The seealso tag resembles the see tag and has identical syntax, except that the text is intended to be used to create a separate seealso section for the entity's documentation.

typeparam: Typeparam is used in an identical way to param, except that it is used to document a type associated with a generic class or function.

value: Value is only used when documenting a property, and is used to describe the value assigned to that. The comment is not required for properties that are marked as read only. Example: <value>Sets the employee's salary</value>
What to do with the documented code

Once the XML comments have been added to the code, it is useful to be able to do something with them. Although code documented in a standard format is an obvious benefit, XML comments allow much more to be done with the source code.

Visual Studio allows the comments to be compiled to an XML file. Although this is a useful feature, the XML file should be considered an intermediate documentation format rather than finished project documentation. Simple documentation can be created by applying an XSL stylesheet to the XML file in order to produce a more easily readable HTML version of the documentation. Here is a simple example of how to implement a suitable XSL stylesheet: Simple XSLT stylesheet for Visual Studio .NET XML documentation.

If you want more comprehensive documentation, our .NET Documentation Tool product creates documentation from C# source code (VB.NET is also supported).
Summary & Conclusions

Hopefully this article will encourage you to add XML comments to your C# source code. Whether you are working for a company or for yourself, well commented code always looks professional, and can help give you the competitive edge over other developers and businesses.
Credits for breakdowns:http://www.winnershtriangle.com/w/Ar...tsInCSharp.asp
http://desktop.plkr.org/docs/develop...kdown_cpp.html


More will be added

Last edited by FrostElite; 10-13-2008 at 02:22 AM.
 
 
permalink
 

RaGEZONE is proudly sponsored by
 
gunnerone gunnerone is offline
FlyForFame

Rank: Subscriber


Reply With Quote
 
Join Date: Jan 2008
Location: Monon,Indiana
Posts: 493
10-05-2008, 04:10 PM
 
Mmmmm sexy add more!
__________________
FlyForFame FaceBookGroup
working on Project #22
I HATE LEECHERS
 
 
permalink
 

 
x2Fast4YouX x2Fast4YouX is offline
Alpha

Rank: New Blood


Reply With Quote
 
Join Date: Jul 2007
Location: Australia
Posts: 149
10-05-2008, 04:11 PM
 
Maaan, thats sexy... Cheers.. I am into learning languages now.. RageZone pushed me...
Thanks alot man...

By the way.. do you know what should i start from... on some other forums i asked, people said first learn QBasic, then VisualBasic, and then C# and C++ .

What you think Elite ?
 
 
permalink
 


 
FrostElite FrostElite is offline
cout << "Hello World \n";

Rank: Member


Reply With Quote
 
Join Date: Sep 2008
Location: Cin>>Location;
Posts: 614
10-05-2008, 04:12 PM
 
Quote: Originally Posted by x2Fast4YouX View Post
Maaan, thats sexy... Cheers.. I am into learning languages now.. RageZone pushed me...
Thanks alot man...

By the way.. do you know what should i start from... on some other forums i asked, people said first learn QBasic, then VisualBasic, and then C# and C++ .

What you think Elite ?
people say C# is faster and c++ is eaiser
 
 
permalink
 

 
lastiko lastiko is online now
为您服务

Rank: Member


Reply With Quote
 
Join Date: Nov 2004
Posts: 310
10-05-2008, 04:19 PM
 
w0w... this is cool dude, ill start to dev my own also...xD
 
 
permalink
 

 
Matrixo Matrixo is offline
The Omega

Rank: New Blood


Reply With Quote
 
Join Date: Aug 2008
Posts: 108
10-05-2008, 04:21 PM
 
WoW nice guide, it work? :D
 
 
permalink
 

 
FrostElite FrostElite is offline
cout << "Hello World \n";

Rank: Member


Reply With Quote
 
Join Date: Sep 2008
Location: Cin>>Location;
Posts: 614
10-05-2008, 04:21 PM
 
Quote: Originally Posted by lastiko View Post
w0w... this is cool dude, ill start to dev my own also...xD
Alright good luck with that ;] if you have any questions just ask
 
 
permalink
 

 
Blackclown Blackclown is offline
Alpha

Rank: New Blood


Reply With Quote
 
Join Date: Sep 2008
Posts: 142
10-05-2008, 04:49 PM
 
Wow Thanks a lot i'll try it but its much work...
 
 
permalink
 

 
FrostElite FrostElite is offline
cout << "Hello World \n";

Rank: Member


Reply With Quote
 
Join Date: Sep 2008
Location: Cin>>Location;
Posts: 614
10-05-2008, 04:59 PM
 
Quote: Originally Posted by Blackclown View Post
Wow Thanks a lot i'll try it but its much work...
Yea, it' alot we're still at the beginning ;P
 
 
permalink
 

 
FrostElite FrostElite is offline
cout << "Hello World \n";

Rank: Member


Reply With Quote
 
Join Date: Sep 2008
Location: Cin>>Location;
Posts: 614
10-05-2008, 05:55 PM
 
Quote: Originally Posted by Matrixo View Post
WoW nice guide, it work? :D
what you mean? :P
 
 
permalink
 

 
ayboangelus ayboangelus is offline
Crazy flyff doctor

Rank: Member


Reply With Quote
 
Join Date: Sep 2008
Location: france
Posts: 695
10-05-2008, 06:18 PM
 
Nice thanks for us, but more job for understand and do the tuto.
 
 
permalink