1
EGGDROP MODULE INFORMATION 18 Dec 2001
8
III. HOW TO INSTALL A MODULE
9
IV. MODULES INCLUDED WITH EGGDROP
10
V. PROGRAMMING MODULES
11
VI. WHAT TO DO WITH A MODULE?
19
Modules are portions of code which are loaded separately to the
20
bot itself and provide extra services. For example, the filesys
21
module provides the entire file system.
26
Modules allow C coders to add their own enhancements to the
27
bot without recompiling the whole thing, and without increasing
28
the size of the Eggdrop core.
31
III. HOW TO INSTALL A MODULE
33
Please note that these are only basic instructions for compiling and
34
installing a module. Please read any and all directions included with
35
the module you wish to install.
37
1. Download and un-tar the Eggdrop source code.
39
2. Place the new module in its own directory (in the format of
40
(modulename).mod) in src/mod.
42
3. Run ./configure (from eggdrop1.6.x/).
44
4. Type 'make config' or 'make iconfig'.
48
6. Copy the compiled module file (modulename.so) into your bot's
51
7. Add 'loadmodule modulename' to your eggdrop.conf file (do not
54
8. Rehash or restart your bot.
56
To see your currently running modules type '.module'.
59
IV. MODULES INCLUDED WITH EGGDROP
61
assoc This module provides assoc support, i.e. naming channels on
64
blowfish Eggdrop can encrypt your userfile, so users can have secure
65
passwords. Please note that when you change your encryption
66
method later (i.e. using other modules like a md5 module),
67
you can't use your current userfile anymore. Eggdrop will not
1
$Id: MODULES,v 1.29 2004/05/27 05:23:39 wcc Exp $
3
Eggdrop Module Information
4
Last revised: March 04, 2003
5
_________________________________________________________________
7
Eggdrop Module Information
10
The purpose of this document is to show you how to download, install, create,
16
3. How to install a module
17
4. Modules included with Eggdrop
18
5. Programming modules
19
6. What to do with a finished module
24
Modules are portions of code which are loaded separately to the bot itself
25
and provide extra services. For example, the filesys module provides the
31
Modules allow C coders to add their own enhancements to the bot while
32
keeping them optional and without increasing the size of the Eggdrop core.
35
3. How to install a module
37
Please note that these are only basic instructions for compiling and
38
installing a module. Please read any and all directions included with
39
the module you wish to install.
41
1. Download and un-tar the Eggdrop source code.
43
2. Place the new module in its own directory (in the format of
44
(modulename).mod) in src/mod.
46
3. Run ./configure (from eggdrop1.6.x/).
48
4. Type 'make config' or 'make iconfig'.
52
6. Copy the compiled module file (modulename.so) into your bot's
55
7. Add 'loadmodule modulename' to your eggdrop.conf file (do not
58
8. Rehash or restart your bot.
60
To view your currently loaded modules, type '.module'.
63
4. Modules included with Eggdrop
65
assoc This module provides assoc support, i.e. naming channels on the
68
blowfish Eggdrop can encrypt your userfile, so users can have secure
69
passwords. Please note that when you change your encryption
70
method later (i.e. using other modules like a md5 module),
71
you can't use your current userfile anymore. Eggdrop will not
68
72
start without an encryption module.
70
channels This module provides channel related support for the bot.
71
Without it, you wont be able to make the bot join a channel
74
channels This module provides channel related support for the bot.
75
Without it, you won't be able to make the bot join a channel
72
76
or save channel specific userfile information.
74
compress This module provides provides support for file compression.
75
This allows the bot to transfer compressed user files and,
76
therefore, save a significant amount of bandwidth.
78
compress This module provides provides support for file compression. This
79
allows the bot to transfer compressed user files and, therefore,
80
save a significant amount of bandwidth.
78
console This module provides storage of console settings when you exit
82
console This module provides storage of console settings when you exit
79
83
the bot or type .store on the partyline.
81
ctcp This module provides the normal ctcp replies that you'd expect.
85
ctcp This module provides the normal ctcp replies that you'd expect.
82
86
Without it loaded, CTCP CHAT will not work.
84
dns This module provides asynchronous dns support. This will avoid
85
long periods where the bot just hangs there, waiting for a
86
hostname to resolve, which will often let it timeout on all
88
dns This module provides asynchronous dns support. This will avoid
89
long periods where the bot just hangs there, waiting for a
90
hostname to resolve, which will often let it timeout on all
89
filesys This module provides an area within the bot where users can
90
store files. With this module, the bot is usable as a file
93
filesys This module provides an area within the bot where users can store
94
and manage files. With this module, the bot is usable as a file
93
irc This module provides basic IRC support for your bot. You have
94
to load this if you want your bot to come on IRC.
96
notes This module provides support for storing of notes for users
97
from each other. Note sending between currently online users
98
is supported in the core, this is only for storing the notes
101
seen This module provides very basic seen commands via msg, on
102
channel or via dcc. This module works only for users in the
103
bot's userlist. If you are looking for a better and more
104
advanced seen module, try the gseen module by G'Quann. You
105
can find it at http://www.visions-of-fantasy.de/gseen.mod/.
107
server This module provides the core server support. You have to load
108
this if you want your bot to come on IRC. Not loading this is
97
irc This module provides basic IRC support for your bot. You have to
98
load this if you want your bot to come on IRC.
100
notes This module provides support for storing of notes for users from
101
each other. Note sending between currently online users is
102
supported in the core, this is only for storing the notes for
105
seen This module provides very basic seen commands via msg, on channel
106
or via dcc. This module works only for users in the bot's
107
userlist. If you are looking for a better and more advanced seen
108
module, try the gseen module by G'Quann. You can find it at
109
http://www.visions-of-fantasy.de/gseen.mod/.
111
server This module provides the core server support. You have to load
112
this if you want your bot to come on IRC. Not loading this is
109
113
equivalent to the old NO_IRC define.
111
share This module provides userfile sharing support between two
115
share This module provides userfile sharing support between two
112
116
directly linked bots.
114
transfer The transfer module provides dcc send/get support and userfile
118
transfer The transfer module provides DCC SEND/GET support and userfile
115
119
transfer support for userfile sharing.
117
uptime This module reports uptime statistics to http://uptime.eggheads.org.
118
Go look and see what your uptime is! It takes about 9 hours to
119
show up, so if your bot isn't listed, try again later. See
120
doc/settings/mod.uptime for more information, including details
121
on what information is sent to the uptime server.
123
wire This module provides all the standard .wire commands via dcc.
124
It is an encrypted partyline communication tool, compatible
127
woobie This is for demonstrative purposes only. If you are looking for starting
128
point in writing modules, woobie is the right thing.
131
V. PROGRAMMING MODULES
134
This section is very likely to be out of date. It was not updated
135
for quite some time. The most reliable way to learn about module
136
programming is to take a deep look at the other available modules.
138
Note: This is for a simple module of 1 source file. If you're doing a
139
multiple source file module, you shouldn't need to read this
142
(a) Create a src/mod/MODULE.mod directory in your Eggdrop distro
143
(where MODULE is the module name) and cd to it.
145
(b) Copy the file `Makefile' from src/mod/woobie.mod and replace all
146
occurrences of `woobie' with your module name. This should ensure
147
that your module gets compiled.
149
(c) Next, you want to create a file called MODULE.c (again MODULE is the
150
module name), and here's where the work starts. :)
152
(1) Things you need to include in your source code:
154
(i) #define MODULE_NAME "module-name"
156
You MUST use this. It's required by several short cuts in the
157
code, and it's got to be the name you will be using in .loadmod
159
(ii) #define MAKING_MODULENAME
160
You MUST also include this, or else the module won't work.
161
MODULENAME is the name of your module(MODULE_NAME), but in
164
(iii) #include "../module.h"
166
This provides all the accessible functions in Eggdrop.
167
Examine src/mod/module.h closely to find a list of functions
170
(iv) #include any other standard c include files you might need (Note
171
stdio.h string.h stdlib.h & sys/types.h are already included).
173
(v) Function *global;
175
This variable provides access to all the Eggdrop functions; without
176
it, you can't call any Eggdrop functions (heck, the module wont even
179
(2) CORE functions every module needs.
181
*SIDENOTE* I suggest that in a single source file module, you define all
182
functions/variables (except global & module_start) as static. This will
183
drastically reduce the size of modules on decent systems.
185
In each of these cases, MODULE refers to the name of your module.
187
(i) char *MODULE_start(Function *func_table)
188
- This function is called when the module is first loaded.
189
You MUST do several things in this function:
190
(a) global = func_table; (so you can make Eggdrop calls)
192
(b) module_register(MODULE_NAME, MODULE_table, major, minor);
193
This records details about the module for other modules
194
and Eggdrop itself to access. Major is a major version
195
number, minor is a minor version number, and MODULE_table
196
is a function table (see below).
198
(c) module_depend(MODULE_NAME, "another-module", major, minor);
199
This lets Eggdrop know that your module NEEDS "another-module"
200
of major version 'major' and at least minor version 'minor'
201
to run, and hence should try to load it if it's not already
202
here. This will return 1 on success, or 0 if it can't be done
203
(at which stage you should return an error).
205
(d) Any other initialization stuff you desire should be included
206
in this function. See below for various things you can do.
208
(e) a return value of some sort
209
Returning NULL implies the module loaded successfully,
210
therefor the bot can continue. Returning a non-NULL STRING
211
is an error message. The module (and any other dependant
212
modules) will stop loading and an error will be returned.
214
(ii) static Function *MODULE_table = {
222
Ok, it's not a function. It's a list of functions which any
223
other module can call up, so you can provide services for other
224
modules (e.g. transfer has raw_dcc_send in it's table to allow
225
the filesys to send files to others). The first 4 functions are
226
FIXED. You MUST have them; they provide important system info.
228
(iii) static char *MODULE_close ()
229
- This is called when the module is unloaded.
230
Apart from tidying any relevant data (I suggest you be thorough,
231
we don't want any trailing garbage from modules), you MUST do
234
(a) module_undepend(MODULE_NAME);
235
This lets Eggdrop know your module no longer depends on
238
(b) Return a value. NULL implies success; any non-NULL STRING
239
implies that the module cannot be unloaded for some reason,
240
and hence the bot should not unload it (see blowfish for
243
(iv) static int MODULE_expmem ()
244
This should tally all memory you allocate/deallocate within
245
the module (using modmalloc & modfree). It's used by memory
246
debugging to track memory faults, and it is used by .status
247
to total up memory usage.
249
(v) static void MODULE_report (int idx)
250
This should provide a relatively short report of the module's
251
status (for .module/.status).
253
(3) AVAILABLE FUNCTIONS
256
You can RELY on these functions being available. This is just a
257
short list of the ones you need to make a mildly useful module.
258
A good portion of the remaining Eggdrop functions are available,
259
check src/mod/module.h for more information.
261
void *nmalloc (int a);
265
void nfree (void *a);
267
- frees a modmalloc'd block
271
- actually a #define; records the current position in
272
execution (for debugging)
274
void dprintf (int idx,char *format, ... )
276
- just like normal printf; outputs to a dcc/socket/server
278
idx is a normal dcc idx OR if < 0 is a sock #
281
DP_LOG (send to log file)
282
DP_STDOUT (send to stdout)
283
DP_MODE (send via mode queue to server) *fast*
284
DP_SERVER (send via normal queue to server) *normal*
285
DP_HELP (send via help queue to server) - use this
286
for mass outputs to users
288
int module_register ( char *module_name,
289
Function *function_table,
290
int major, int minor )
294
const module_entry *module_find ( char *module_name, int major, int minor);
296
- look for a module (matching major, >= minor), and return
299
Members of module_entry:
301
char *name; - module name (duh)
302
int major; - real major version
303
int minor; - real minor version
304
Function *funcs; - function table (see above)
306
int module_depend ( char *module_name, char *needed_module,
307
int major, int minor )
309
- marks your module (module_name) as dependent upon
310
needed_module (matching major, >= minor) and tries to
311
load the required module if it's not already loaded.
314
int module_undepend ( char *module_name)
316
- marks your module (module_name) as no longer needing any
319
void module_rename (char *old_module_name, char *new_module_name)
323
void add_hook (int hook_num, Function *funcs)
324
void del_hook (int hook_num, Function *funcs)
326
- used for adding removing hooks into Eggdrop code on
327
various events, these functions are called depending
332
HOOK_SECONDLY - called every second
333
HOOK_MINUTELY - called every minute
334
HOOK_5MINUTELY - called every 5 minutes
335
HOOK_HOURLY - called every hour (hourly-updates
337
HOOK_DAILY - called when the logfiles are switched
338
HOOK_READ_USERFILE - called when the userfile is read
339
HOOK_USERFILE - called when the userfile is written
340
HOOK_PRE_REHASH - called just *before* rehash
341
HOOK_REHASH - called just after rehash
342
HOOK_IDLE - called whenever the dcc connections
343
have been idle for a whole second
344
HOOK_BACKUP - called when a user/channel file
346
HOOK_LOADED - called when Eggdrop is first loaded
347
HOOK_DIE - called when Eggdrop is about to die
350
char *module_load ( char *module_name );
352
- tries to load the given module; returns 0 on success, or
355
char *module_unload ( char *module_name );
357
- tries to unload the given module; returns 0 on success, or
361
void add_tcl_commands(tcl_cmds *tab);
362
void rem_tcl_commands(tcl_cmds *tab);
364
- provides a quick way to create and remove a list of Tcl
365
commands. the table is in the form:
367
{ char *func_name, Function *function_to_call }
369
These are normal Tcl commands (as done in tcl*.c).
370
Use { 0, 0 } to indicate the end of the list.
372
void add_tcl_ints(tcl_ints *);
373
void rem_tcl_ints(tcl_ints *);
375
- provides a way to add/remove links from c variables to Tcl
376
variables (add checks to see if the Tcl variable already
377
exists and copies it over the C one). the format of table is:
379
{ char *variable_name, int *variable, int readonly }
381
Use {0,0,0}; to indicate the end of the list.
383
void add_tcl_strings(tcl_strings *);
384
void rem_tcl_strings(tcl_strings *);
386
- provides a way to add/remove links from c strings to Tcl
387
strings (also copies existing Tcl values). the format is:
389
{ char * variable_name, char *string, int length, int flags }
391
Use { 0, 0, 0, 0 } to indicate the end of the list.
393
length: set to 0 if you want a const string.
395
flags: use STR_DIR if you want a / constantly appended;
396
use STR_PROTECT if you want the variable set
397
in the config file, not during normal usage.
399
void putlog (int logmode, char *channel, char *format, ... )
401
- logs a comment. see src/eggdrop.h for logmodes.
403
void add_builtins (p_tcl_hash_list table, cmd_t *cc);
404
void rem_builtins (p_tcl_hash_list table, cmd_t *cc);
406
- the method of adding/remove bindings for Tcl hash tables
408
Table is a hash table you find with find_hash_table.
412
{ char *command, char *flags, Function *function }
414
terminate with { 0, 0, 0, 0 }
416
this is EXACTLY like a bind command in Tcl (heck, tcl_bind
417
calls the same function this does).
419
function is called with exactly the same args as a Tcl
420
binding is (except for dcc, which does include the handle
421
in C) with type conversion taken into account (e.g. idx's
422
are ints). return is much the same as Tcl bindings, use int
423
0/1 for those which require 0/1, or char * for those which
424
require a string (e.g. filt). return nothing if no return
425
is required. return is also in src/tclhash.c
428
VI. WHAT TO DO WITH A MODULE?
430
If you have written a module and feel that you wish to share it with the
431
rest of the Eggdrop community, upload it to the incoming directory on
432
incoming.eggheads.org(/incoming/modules/1.6). Place a nice descriptive
433
text with it, and it'll make its way to the modules directory on
434
ftp.eggheads.org. Don't forget to mention in your text file which
435
version Eggdrop the module is written for.
121
uptime This module reports uptime statistics to the uptime contest
122
web site at http://uptime.eggheads.org. Go look and see what
123
your uptime is! It takes about 9 hours to show up, so if your
124
bot isn't listed, try again later. See doc/settings/mod.uptime
125
for more information, including details on what information is
126
sent to the uptime server.
128
wire This module provides all the standard .wire commands via dcc.
129
It is an encrypted partyline communication tool, compatible with
132
woobie This is for demonstrative purposes only. If you are looking for
133
starting point in writing modules, woobie is the right thing.
136
5. Programming modules
138
WARNING: This section is very likely to be out of date.
140
Note: This is for a simple module of 1 source file. If you're doing a
141
multiple source file module, you shouldn't need to read this anyway.
143
1. Create a src/mod/MODULE.mod directory in your Eggdrop directory (where
144
MODULE is the module name) and cd to it.
146
2. Copy the file `Makefile' from src/mod/woobie.mod and replace all
147
occurrences of `woobie' with your module name. This should ensure
148
that your module gets compiled.
150
3. Next, you want to create a file called MODULE.c (MODULE is the module
153
4. You MUST include the following in your source code:
155
a. #define MODULE_NAME "module-name"
157
This should be defined to the same name you will be using when you load
160
b. #define MAKING_MODULENAME
162
MODULENAME is the name of your module (MODULE_NAME), but in all caps.
164
c. #include "../module.h"
166
This provides access to Eggdrop's global function table. Examine
167
src/mod/module.h closely to find a list of functions available.
169
d. #include any other standard c header files you might need. Note that
170
stdio.h, string.h, stdlib.h, and sys/types.h are already included.
174
This variable provides access to all the Eggdrop functions; without it,
175
you can't call any Eggdrop functions (the module won't even load).
177
5. Every module must also have the following functions:
179
In most modules, all functions/variables (except global and MODULE_start)
180
should be static. This will drastically reduce the size of modules on
183
Throughout step 5, MODULE refers to the module name. Note that
184
"MODULE_NAME" should literally be "MODULE_NAME".
186
a. char *MODULE_start(Function *func_table)
187
This function is called when the module is first loaded. There are
188
several things that need to be done in this function:
192
This allows you to make calls to the global function table.
194
module_register(MODULE_NAME, MODULE_table, MAJOR, MINOR);
196
This records details about the module for other modules and Eggdrop
197
itself to access. MAJOR and MINOR are ints, where MAJOR is the
198
module's major version number and MINOR is a minor version number.
199
MODULE_table is a function table (see below).
201
module_depend(MODULE_NAME, "another-module", MAJOR, MINOR);
202
This lets Eggdrop know that your module NEEDS "another-module" of
203
major version 'MAJOR' and at least minor version 'MINOR' to run,
204
and hence should try to load it if it's not already loaded. This
205
will return 1 on success, or 0 if it can't be done (at which stage
206
you should return an error).
208
Any other initialization stuff you desire should also be included in
209
this function. See below for various things you can do.
211
You also will need to return a value. Returning NULL implies the
212
module loaded successfully. Returning a non-NULL STRING is an error
213
message. The module (and any other dependant modules) will stop
214
loading and an error will be returned.
216
b. static Function *MODULE_table = {
225
This is a table of functions which any other module can access. The
226
first 4 functions are FIXED. You MUST have them; they provide important
229
c. static char *MODULE_close ()
230
This is called when the module is unloaded. Apart from tidying any
231
relevant data (I suggest you be thorough, we don't want any trailing
232
garbage from modules), you MUST do the following:
234
module_undepend(MODULE_NAME);
235
This lets Eggdrop know your module no longer depends on any other
238
Return a value. NULL implies success; any non-NULL STRING implies
239
that the module cannot be unloaded for some reason, and hence the
240
bot should not unload it (see the blowfish module for an example).
242
d. static int MODULE_expmem ()
243
This should tally all memory you allocate/deallocate within the module
244
(using nmalloc, nfree, etc) in bytes. It's used by memory debugging to
245
track memory faults, and it is used by .status to total up memory usage.
247
e. static void MODULE_report (int idx)
248
This should provide a relatively short report of the module's status
249
(for the module and status commands).
251
These functions are available to modules. MANY more available functions
252
can be found in src/mod/module.h.
254
void *nmalloc(int j);
256
This allocates j bytes of memory.
260
This frees an nmalloc'd block of memory.
264
Actually a macro -- records the current position in execution (for
265
debugging). Using Context is no longer recommended, because it uses
266
too many resources and a core file provides much more information.
268
void dprintf(int idx, char *format, ...)
270
This acts like a normal printf() function, but it outputs to
273
idx is a normal dcc idx, or if < 0 is a sock number.
276
DP_LOG - send to log file
277
DP_STDOUT - send to stdout
278
DP_MODE - send via mode queue to the server
279
DP_SERVER - send via normal queue to the server
280
DP_HELP - send via help queue to server
282
const module_entry *module_find(char *module_name, int major, int minor);
284
Searches for a loaded module (matching major, >= minor), and returns
287
Members of module_entry:
288
char *name; - module name
289
int major; - real major version
290
int minor; - real minor version
291
Function *funcs; - function table (see above)
293
void module_rename(char *old_module_name, char *new_module_name)
295
This renames a module frim old_module_name to new_module_name.
297
void add_hook(int hook_num, Function *funcs)
298
void del_hook(int hook_num, Function *funcs)
300
These are used for adding or removing hooks to/from Eggdrop code that
301
are triggered on various events. Valid hooks are:
302
HOOK_SECONDLY - called every second
303
HOOK_MINUTELY - called every minute
304
HOOK_5MINUTELY - called every 5 minutes
305
HOOK_HOURLY - called every hour (hourly-updates minutes past)
306
HOOK_DAILY - called when the logfiles are switched
308
HOOK_READ_USERFILE - called when the userfile is read
309
HOOK_USERFILE - called when the userfile is written
310
HOOK_PRE_REHASH - called just before a rehash
311
HOOK_REHASH - called just after a rehash
312
HOOK_IDLE - called whenever the dcc connections have been
313
idle for a whole second
314
HOOK_BACKUP - called when a user/channel file backup is done
315
HOOK_LOADED - called when Eggdrop is first loaded
316
HOOK_DIE - called when Eggdrop is about to die
318
char *module_unload (char *module_name);
319
char *module_load (char *module_name);
321
Tries to load or unload the specified module; returns 0 on success, or
324
void add_tcl_commands(tcl_cmds *tab);
325
void rem_tcl_commands(tcl_cmds *tab);
327
Provides a quick way to create and remove a table of Tcl commands. The
328
table is in the form of:
330
{char *func_name, Function *function_to_call}
332
Use { NULL, NULL } to indicate the end of the list.
334
void add_tcl_ints(tcl_ints *);
335
void rem_tcl_ints(tcl_ints *);
337
Provides a quick way to create and remove a table of links from C
338
int variables to Tcl variables (add_tcl_ints checks to see if the Tcl
339
variable exists and copies it over the C one). The format of table is:
341
{char *variable_name, int *variable, int readonly}
343
Use {NULL, NULL, 0} to indicate the end of the list.
345
void add_tcl_strings(tcl_strings *);
346
void rem_tcl_strings(tcl_strings *);
348
Provides a quick way to create and remove a table of links from C
349
string variables to Tcl variables (add_tcl_ints checks to see if the
350
Tcl variable exists and copies it over the C one). The format of table
353
{char *variable_name, char *string, int length, int flags}
355
Use {NULL, NULL, 0, 0} to indicate the end of the list. Use 0 for
356
length if you want a const string. Use STR_DIR for flags if you want a
357
'/' constantly appended; use STR_PROTECT if you want the variable set
358
in the config file, but not during normal usage.
360
void add_builtins(p_tcl_hash_list table, cmd_t *cc);
361
void rem_builtins(p_tcl_hash_list table, cmd_t *cc);
363
This adds binds to one of Eggdrop's bind tables. The format of the
366
{char *command, char *flags, Function *function, char *displayname}
368
Use {NULL, NULL, NULL, NULL} to indicate the end of the list.
370
This works EXACTLY like the Tcl 'bind' command. displayname is what Tcl
371
sees this function's proc name as (in .binds all).
373
function is called with exactly the same args as a Tcl binding is with
374
type conversion taken into account (e.g. idx's are ints). Return values
375
are much the same as Tcl bindings. Use int 0/1 for those which require
376
0/1, or char * for those which require a string (auch as filt). Return
377
nothing if no return value is required.
379
void putlog (int logmode, char *channel, char *format, ...)
381
Adds text to a logfile (determined by logmode and channel). This text
382
will also output to any users' consoles if they have the specified
383
console mode enabled.
386
6. What to do with a module?
388
If you have written a module and feel that you wish to share it with the
389
rest of the Eggdrop community, upload it to the incoming directory on
390
incoming.eggheads.org (/incoming/modules/1.6). Place a nice descriptive
391
text (modulename.desc) with it, and it'll make its way to the modules
392
directory on ftp.eggheads.org. Don't forget to mention in your text file
393
which version Eggdrop the module is written for.
436
394
_________________________________________________________________
438
Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
396
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Eggheads Development Team