This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Rcon Gameserver VIA Eggdrop

Discussion of Eggdrop's code and module programming in C.
Post Reply
c
cfpresla
Voice
Posts: 4
Joined: Tue Jul 08, 2008 9:42 am

Rcon Gameserver VIA Eggdrop

Post by cfpresla »

Okay, I've written a program in C which allows me to use RCON on Source Engine servers. I've attempted a plethora of different methods to get this bad boy into my TCL script but nothing seems to be working.

I've compiled the .c files using SWIG into a .so file, and attempted to load the module (tclsh load <module>.so works) - this, however, I've determined to be the wrong way of doing it. I've looked at the mod.woobie example but I'm not sure what I'm supposed to gain by looking at this.

Can anyone help me out? Sorry if I'm posting a question thats been answered 100x :/.

Thanks!
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

The first thing to keep in mind, is that with eggdrops, there are two different kind of modules: Tcl native modules, and eggdrop modules.

Tcl modules are not loaded by eggdrop, but by the tcl interpreter embedded in eggdrop, and is loaded using the load command. These modules will generally not have any access to eggdrop's internal commands and data structures, other than what is provided in the tcl-environment. A good example of a tcl module is the "mysqltcl" module used to give tcl environments easy access to mysql databases.

Eggdrop modules are loaded into eggdrop itself, and can be setup to easily access many of eggdrop's own functions and data structures. Since they are very tightly bound to eggdrop (can't be loaded into any arbitrary tcl interpreter), you usually need the build-tree of your eggdrop available when compiling these kinds of modules. The woobie-module is an example of these kinds of modules, and is loaded using the loadmodule command.


Secondly, writing a module in generic is a lot more complex than writing a simple standalone program. It's rather in the lines of writing a library. You'll have to create several functions to handle events upon loading and unloading modules (such as registering functions, variable spaces and other data structures, and various initialization).

With eggdrop modules, there are 4 mandatory functions that has to be created; <name>_start, <name>_stop, <name>_expmem, <name>_report, aswell as a function table named <name>_table[]. As a bare minimum, these provide mechanisms to do various initialization and cleanup. In order for your module to actually do something useful, you'll also have to register ("export") functions to tcl-commands, variable mapping, event bindings, etc. The woobie and the ctcp modules are good examples on how this is done.


All in all, converting a trivial C-program into a loadable module is not so trivial, but a very good programming exercise given you're up for the challenge. Unfortunately, the documentation for eggdrop modules is but non-existent, and the best source for information are the currently available modules.
NML_375
c
cfpresla
Voice
Posts: 4
Joined: Tue Jul 08, 2008 9:42 am

Post by cfpresla »

Well, after doing more snooping, I realized I was making a big mistake :/

I was looking in the src/mod dir of the compiled bot, not the uncompiled one! I placed in the needed functions and variables, into the C program and placed my functions into the function array. Any tips on how to now access these functions? Sorry, I'm learning about Eggdrops and TCL as I go along.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

It's alittle bit more tricky than that, I'm afraid. The <name>_table functiontable simply makes these functions known (thus available) as C functions to the eggdrop core and modules requesting them. It is thus used to make functions directly available to other module writers.

To link a C function to a tcl proc, and thus make it accessible for scripting; you'll have to create a static tcl_cmds table containing the requested tcl proc name, and the function you wish to link to it. Next, upon registering your module, you'll need to also register these procs using add_tcl_commands(tcl_cmds *table).

Variables are linked in a similar manner, but using add_tcl_strings(tcl_strings *table) and add_tcl_ints(tcl_ints *table) with respective tables.

Bindings are slightly more complex, using the add_builtins(tcl_bind_list_t *tl, cmd_t *cc), where tl specifies what kind of bind-table is used, and cc is the actual list of corresponding lists. This will also create the necessary tcl procs needed on the fly.

There are a few other ways of interacting with the eggdrop and tcl environments as well, but these should get you started.

Edit:
The above is for creating an eggdrop module. Creating a tcl module requires different methods of linking functions with procs.
NML_375
c
cfpresla
Voice
Posts: 4
Joined: Tue Jul 08, 2008 9:42 am

Post by cfpresla »

Okay, so lemme make sure I understand this before I go plowing through code.

From what I've found, these functions are defined in module.h, and tcl_cmds is a type_def'ed struct containing the name of the command and function which the command links to.

If this is correct, I'm assuming I need to created a tabled of the tcl_cmds and pass this table as an arg into add_tcl_commands().

This is the only function which I NEED to access because it calls the others.
int rcon(char *address_arg, char *password_arg, short port_arg, char *cmd, char *val)

So, something like the following would work.

tcl_cmds table[] = { "rcon"; (Function) rcon;}
add_tcl_commands(table);

Thanks for all your help btw!
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Pretty much yes, expect that you'll need to null-terminate the table.

Also, you should use STDVAR argument list with your function. Your function should return TCL_OK upon success, and TCL_ERROR upon error. Any results returned to the tcl environment need to first be exported using the Tcl_AppendResult(...) function call (documented in the tcl library docs).

Finally, the function table should be declared static, as it is also used to unregister functions when the module is unloaded (done in a similar fashion to registering the functions, but using rem_tcl_commands(...) ).


Below is a partial example, the _report and _expmen functions are not implemented, and the module has not been given a name (MODULE_NAME and MAKING_<name> macros have not been defined, and init-function is named mod_start). It should however provide a rough framework to start with, although I cannot guarantee this is free of any errors.

Code: Select all

static int myfunc STDVAR
{
  BADARGS(2, 3, " string [key]"
  Tcl_AppendResult(irp, argv[1], null);
  if (argc == 3)
    Tcl_AppendResult(irp, argv[2], null);
  return TCL_OK;
}

static tcl_cmds mycmd[] = {
  {"myproc", myfunc},
  {NULL, NULL}
};

char *mod_close()
{
  rem_tcl_commands(mycmd);
  module_undepend(MODULE_NAME);
  return NULL;
}

EXPORT_SCOPE char *mod_start();

static Function f_table[] = {
  (Function) mod_start,
  (Function) mod_close,
  (Function) NULL,
  (Function) NULL,
};

char *mod_start(Function *f_global)
{
  if (f_global)
  {
    module_register(MODULE_NAME, f_table, 2, 1);
    if (!module_depend(MODULE_NAME, "eggdrop", 106, 3)) {
      module_undepend(MODULE_NAME);
      return "This module requires Eggdrop 1.6.3 or later.";
    }
  }
  add_tcl_commands(mycmd);
  return NULL;
}

NML_375
c
cfpresla
Voice
Posts: 4
Joined: Tue Jul 08, 2008 9:42 am

Post by cfpresla »

Thats done, now as for calling the function from a TCL script, I assume something like (since I used "rcon" as the cmd name):

[rcon arg1 arg2 ... ]
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Yup, just load the module and use the command just like you would use any other tcl command.
NML_375
z
zorgman
Voice
Posts: 1
Joined: Mon Jan 11, 2010 4:54 pm
Location: Lithuania
Contact:

Post by zorgman »

care to share the module with me?
Post Reply