/[LeafOK_CVS]/pvpgn-1.7.4/README.DEV
ViewVC logotype

Contents of /pvpgn-1.7.4/README.DEV

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
no message

1
2 PVPGN (wannabe) DEVELOPERS GUIDE
3
4 Please read this file before asking any questions !
5
6 0. About this document
7 =======================
8
9 This document is intended to be read by all of you out there wanting to do
10 development or testing for/on PvPGN.
11
12 ChangeLog:
13 29-07-2003: dizzy : Initial version
14 28-08-2004: dizzy : Run-time debugging : Appendix A
15 30-08-2004: dizzy : Updated (fdwatch, xalloc, goto, gdb)
16
17 1. Why ?
18 =========
19
20 You want to start coding for PvPGN ? Why ? What do you expect to get from it ?
21 Answer yourself this questions and then go to the next paragraph.
22
23 2. History
24 ===========
25
26 PvPGN has started as a game server emulation project, taking the excelent's
27 bnetd project source and working on it. While initially it has started as
28 a War3 emulation patch over bnetd it become a lot more than that (lots of
29 new features, lots of code changes organizing). Because of the code roots
30 you will notice a lot of things still carrying the "bnetd" word (most notable
31 examples are the main servers program file called "bnetd" or the main server
32 configuration file called bnetd.conf). We considered that as a sign of respect
33 from us to the bnetd coders we keep their names on the code they written (but
34 on the new code of course we may name them different).
35
36 3. Objective
37 =============
38
39 PvPGN's main objective is to support all Battle.Net clients (games) but are
40 considering in the near future to extend it to support other game protocols
41 as well.
42
43 4. Layout of files
44 ===================
45
46 Note: Starting here on you may find lots of terms and wors which may sound
47 "strange" to you and for this reason we have included a glossary of terms
48 in the end of this file.
49
50 The PvPGN project consists of a main server (called "bnetd") and various
51 other programs and (little) servers (ex. bnchat, d2cs, d2dbs etc...).
52
53 PvPGN follows the bnetd's layout of files:
54 ./bin -> used to store binaries (after compilation)
55 ./conf -> configuration files (many of them templates)
56 ./files -> various files needed for clients connecting
57 ./man -> outdated man pages :(
58 ./sbin -> same as ./bin
59 ./scripts -> various scripts for testing/managing pvpgn
60 ./src -> the source main directory
61 ./src/bnetd -> source files used only by the main server
62 ./src/common -> source files used in common by different programs
63 ./src/compat -> source files concerning portability of code
64 ...
65
66 The build process takes place in the "src" dir.
67
68 5. Coding Style
69 ================
70
71 a. General
72
73 PvPGN is mainly developed on and for UNIX/Linux. The reasons are because we
74 as coders work on this systems and because our users (at least the big ones)
75 use UNIX/Linux more than ex. Windows. But, even so we try to code in a portable
76 fashion and any release PvPGN had we made sure it compiles on win32 too (we
77 even release win32 binaries). We will never refuse a good win32 coder but we
78 prefer UNIX ones ;)
79
80 One thing which is overlooked by newbie coders is the "esthetical" side of the
81 code. It may not be so important to many people (which code on the idea "if it
82 works then its good") but for us, coding on PvPGN is VERY important. When you
83 are coding for PvPGN PLEASE try to make your code look similar to already
84 written code (this includes identing, identificator names, etc...). Keeping
85 the code look "the same" makes its reading a lot more easier so, finding
86 bugs easier so coding better.
87
88 One way to make sure your code sticks with the PvPGN coding style is to use
89 "indent" code indenting formating tool (http://www.gnu.org/software/indent/).
90 To use indent to get your code acording to PvPGN coding style use something
91 like this (it will format properly the file clan.c and save the new file to
92 clan.c.new):
93 $ indent -kr -bl -bli0 -l0 -br -ce -cli4 clan.c -o clan.c.new
94
95 Other overlooked aspect for newbie coders is code replication. Please DONT
96 copy and paste code arround !!! If you need to copy common functionality from
97 some place, think about making some API of that functionalilty, put it in
98 some functions and use it from both places. I repeat, DONT replicate code.
99
100 When allocating memory inside a function always free it in the same function
101 before its exit (exceptions: the function returns the allocated memory in
102 which case the calling function should take care of the allocated memory;
103 or the allocated memory is cached/stored somewhere to be used later, in which
104 case you must make sure it will be free()d when not needed anymore).
105
106 In the startup code of any "external" function (function which may be called
107 from other modules then the one containing it) please check ALL the input
108 parameters (you will notice how PvPGN already does that in such functions).
109 Traditionally this has been done with contructs like:
110 if (var==NULL) { eventlog(error); return <error-code>; }
111 We have recently changed our policy because of increasing code size and lots
112 of redundant checks, we now usually prefer using assert() for this type of
113 checks (check the manual page for assert).
114
115 A new addition is the xalloc memory allocation wrappers (for malloc,
116 calloc, realloc, strdup and free). We now do NOT allow memory allocation to
117 take place without this wrappers. They make the code smaller and easier to
118 read because they never fail so they eliminate the need for failure checks
119 and eventlogs in such cases.
120
121 Another thing recently adopted in the team is the usage of "goto" keyword.
122 Many people have argued (and continue to) that goto are inherently _evil_ and
123 they produce "spaghetti code". But that is true for pointers and lots of other
124 powerfull C features. We consider the programmer to be the cause of bad
125 written codes and not some keywords. So we are moving into using "goto"
126 mainly in the "error exit paths" cases. Let's say you have a function which
127 needs to allocate some stuff (in 3 variables), checks for each allocation,
128 exits with error for each specific failure (also free()ing the already
129 allocated space). You can do it the PvPGN traditional way like:
130
131 ------- CODE ----------
132 a = malloc(X);
133 if (!a) {
134 eventlog(bla);
135 return -1;
136 }
137
138 b = malloc(Y);
139 if (!b) {
140 eventlog(bla);
141 free(a);
142 return -1;
143 }
144
145 c = malloc(Z);
146 if (!c) {
147 eventlog(bla);
148 free(b);
149 free(a);
150 return -1;
151 }
152 <do stuff>
153
154 return 0;
155 ------ CODE -----------
156
157 Or you can do it the new, "goto" way:
158 --------- CODE --------------
159 a = malloc(X);
160 if (!a) {
161 eventlog(bla);
162 goto err_a;
163 }
164
165 b = malloc(Y);
166 if (!b) {
167 eventlog(bla);
168 goto err_b;
169 }
170
171 c = malloc(Z);
172 if (!c) {
173 eventlog(bla);
174 goto err_c;
175 }
176 <do stuff>
177 return 0;
178
179 err_c:
180 free(c);
181 err_b:
182 free(b);
183 err_a:
184 return -1;
185 -------- CODE ------------
186
187 The last version is a lot easier to read/debug. Because the reader is usually
188 interested by the main (non-error) code path not about the error code path.
189 Also the traditional way replicates codes (those replicated free()) which is
190 error prone (more badly, its prone to memory leaks, and believe me, I did
191 fixed a lot of this forgotten free() in error exit paths).
192 NOTE: however, with the xalloc wrappers that never fail the above examples
193 are obsolete, still there are many other similar situations where you need
194 a complex error exit path and goto comes in handy.
195
196 When developing code you should compile always with "all warnings" enabled
197 and try to fix them (some warnings uncover real bugs), like for gcc use
198 "-Wall". When running/testing the codes you should use a memory debugger like
199 valgrind and/or bounds checking compiler patches like bounds-checking-gcc.
200 For more details about how to run pvpgn check Appendix B.
201
202 b. Code Organizing
203
204 PvPGN (inhireted from bnetd) trys to group functions based on their data on
205 which they work on. Thus it somewhat resembles the principle of data
206 encapsulation used in OOP. For example connection.h defines structs necesarry
207 to work with connections (the main one beeing t_connection) and functions
208 which work with this structs and which do actions related to this connections.
209 Also notice that all this functions are named like conn_<name>(). In general
210 if you have a set of functions working on a set of structs, you define the
211 structs and the functions in a <module>.h file (thus defining the API) then
212 write the function implementations in <module>.c file. And the function names
213 should be something like <module>_<name>(). Separating and grouping functions
214 in their own modules, working on their own data structures helps isolating
215 functionality in the server and thus hunting bugs a lot easier.
216
217 c. Code Flow
218
219 Note: this chapter is more or less correct. Is intended to give a general
220 ideea about the code flow, it may contain flows and things which are not
221 in sync with the actual code, for a better understanding I recommend reading
222 the actual code
223
224 The server starts in main() found in bnetd/main.c file. There it parses
225 command line arguments then tries to initilize the modules by calling their
226 initilizing function (many of them called like <module>_init()). Some of this
227 modules depend on the initilizing of others so the order there may be important.
228 Also some of the modules if fail on initilizing may represent a general fail
229 thus PvPGN bails out. But should print out a explaining message (or write it
230 to the log configured file).
231
232 From there the server calls the main server loop function found in server.c.
233 Here the loop may be simplified to something like:
234 1. fdwatch() on the set of opened sockets
235 2. call fdwatch_handle() which reads (if any) network data and "handle" them
236 (by calling the handle function coresponding to the class of the connection
237 receiving the data)
238 3. write (if any) to the network from the output queue
239 4. do any periodic or time based events
240 5. go to 1
241
242 As seen on step 2. above we call the handling functions coresponding to the
243 class of the connection. The handle functions usualy are a big switch/case or
244 a for/if (which is equivalent) and they check for the packet type received, then
245 they act acordingly to the data received (many of them responing with packets
246 by adding them to the output packet queue of the connection).
247
248 Appendix A. Glossary of terms
249 ===============================
250
251 * autoupdate: the feature of Battle.Net servers to send a (MPQ, see MPQ) file
252 to the client which after downloading it, it is used to update the client
253
254 * connection class: when a connection is established to a bnet listening
255 address the client sends an initial byte which tells the server of what class
256 of connection the following packets will be; classes of connections determine
257 what packets can go through that connection.
258
259 * MPQ: a format archive which is used by Blizzard clients and Battle.Net
260 servers. This files are used for containing verious files (sound/graphics in
261 clients, AI scripts, update patches etc...)
262
263 * versioncheck: also know as vcheck and sometimes just vc ; a client
264 verification system used by Battle.Net servers to identify client version and
265 "purity". Based on this the server may accept/refuse connection or ask for
266 upgrade (see autoupdate).
267
268 Appendix B. How to run PvPGN for debugging
269 ===========================================
270
271 It is very helpfull in finding out memory coruption bugs as soon as possible
272 so while developing codes or just when running a server it is good that you
273 use some memory coruption run-time debuggers. I dont know about Win32 users
274 but on Unix/Linux there are some good options.
275
276 1. valgrind (http://valgrind.kde.org)
277
278 Valgrind is not very portable (only x86, Linux and very recently FreeBSD),
279 also it slows down the debugged codes (it acts like a CPU emulator so it
280 has to do that) but I have yet to find out a better debugging tool for what
281 he does. Valgrind is so cool that recently many OSS projects use it for
282 finding out bugs in their codes. For more information you can check out their
283 web page. I will focus on valgrind with PvPGN.
284
285 After you have compiled and installed valgrind (it's easy, ./configure, make,
286 make install) you will use it by running PvPGN like this:
287
288 $ valgrind --tool=memcheck --num-callers=10 /path/to/bnetd -f 2> valg.out
289
290 "num-callers" makes valgrind record backtraces with 10 entries and is usually
291 needed with PvPGN which has not very small backtrace path :)
292
293 Another option you might want to use is "--leak-check=yes" and probably
294 "--leak-resolution=high". This options make valgrind even slower but they
295 will give memory leak information when PvPGN exits.
296
297 I encourage EVERYONE to use it if available (that is if you run PvPGN on
298 a supported platform). Only very big servers won't be able to do it because
299 there is no hardware powerfull enough to run a big server with valgrind (but
300 big means over 500 users online). You should test it with your server and if
301 it does not make your bnetd go over 90% CPU then you should be fine. If you
302 cannot run valgrind for any reason or if you are hunting for some bugs
303 valgrind cannot find (yes, valgrind is superb but there is a class of bugs,
304 especially overflows which valgrind can't help you with) you should then try
305 the next debugging tool.
306
307 2. bounds-checking GCC (http://sourceforge.net/projects/boundschecking/)
308
309 This has the drawback of beeing just for GCC (as far as I know of) but has
310 the advantage over valgrind that is : more portable (virtually it should be
311 possible to use it anywhere you can use a recent GCC), a lot faster and can
312 detect bugs that valgrind cannot find. However it has the disadvantage that
313 it's error reports do not contain backtraces so they might be lesser usefull.
314
315 To use it basically it cuts down to:
316 - download a recent compiler (ex GCC 3.4.1)
317 - download the coresponding patch from the project's sf.net page
318 - apply the patch while beeing in the gcc source dir you unpacked with a
319 command like bunzip2 -c /path/to/patch.bz2 | patch -p1
320 - compile gcc and install gcc
321 - to make pvpgn compile with your new gcc do something like:
322 $ CC=/path/to/new/gcc CFLAGS="-O0 -Wall -fbounds-checking -g" ./configure
323 - then the usual make, make install
324 - to run PvPGN you will probably need to redirect stderr like:
325 $ /path/to/bnetd -f 2> debug.out
326
327 You will probably encounter some problems when configuring, building gcc, so
328 you should read the text in the beginning of the bounds-checking patch file.
329 Also the gcc install docs are usefull.
330
331 When starting up your new bounds checking enabled binary you will see some
332 usefull messages. By default the patch makes the debugged program exit on the
333 first error it encounters. For a production server this is not very nice so
334 you will want to set GCC_BOUNDS_OPTS shell variable to "-never-fatal" like:
335 $ GCC_BOUNDS_OPTS="-never-fatal" /path/to/bnetd -f 2> debug.out
336
337 Appendix C. How to generate and use "core" files
338 =================================================
339
340 This appendix is for Unix users. I dont know if other platforms have similar
341 features, that when the program crashes unexpectedly the OS would dump the
342 contents of the memory of the crashing process into a disk file for later
343 inspection.
344
345 First make sure that PvPGN has been compiled with debugging ("-g" parameter
346 to gcc) and with no optimizations ("-O0" parameter to gcc). PvPGN default
347 build process puts "-g -O2" so you need to edit Makefile file before compile
348 and change it to "-g -O0". Then something like "make clean; make".
349
350 On Unix/Linux to be able to get core dumps you first need to make sure your
351 core file size limit is set acordingly. Use "ulimit -c" for querying and
352 setting this limit (I recommend setting it to "unlimited"). After that when
353 you start PvPGN make sure you are in a directory where you have write access
354 (so the OS when it wants to do the core dump it will be allowed to do so).
355 The last thing to do is when starting PvPGN make sure it starts in FOREGROUND,
356 example : /path/to/bnetd -f . If you did all this then when PvPGN will crash
357 you will get a core dump. On linux this is a file called "core", on *BSD it's
358 called <processname>.core (for bnetd that means it's called bnetd.core).
359
360 Now that you got a core file it is time to use it to identify what happened
361 wrong in the crashing process. We use gdb (the GNU debugger, should be
362 available on all Unices) to do this. Run gdb like this:
363 $ gdb /path/to/bnetd /path/to/corefile
364
365 Then gdb should startup, print out a lot of messages and stop after printing
366 a file and line number and quoting some C code where the crash has happened.
367 You can find out a lot more information than this. Run gdb's command "bt full"
368 and it will display a full backtrace of the moment of the crash. The backtrace
369 will contain how the functions were called along the way (their parameters),
370 and also any local variables. If you do not know what to do next from here
371 contact a PvPGN developer and give him exactly that backtrace dump, he should
372 know more.

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1