egghelp.org community Forum Index
[ egghelp.org home | forum home ]
egghelp.org community
Discussion of eggdrop bots, shell accounts and tcl scripts.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Rcon Gameserver VIA Eggdrop

 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Modules & Programming
View previous topic :: View next topic  
Author Message
cfpresla
Voice


Joined: 08 Jul 2008
Posts: 4

PostPosted: Tue Jul 08, 2008 9:49 am    Post subject: Rcon Gameserver VIA Eggdrop Reply with quote

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!
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2846

PostPosted: Tue Jul 08, 2008 10:43 am    Post subject: Reply with quote

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, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
cfpresla
Voice


Joined: 08 Jul 2008
Posts: 4

PostPosted: Tue Jul 08, 2008 11:04 am    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2846

PostPosted: Tue Jul 08, 2008 11:22 am    Post subject: Reply with quote

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, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
cfpresla
Voice


Joined: 08 Jul 2008
Posts: 4

PostPosted: Tue Jul 08, 2008 11:54 am    Post subject: Reply with quote

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!
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2846

PostPosted: Tue Jul 08, 2008 12:24 pm    Post subject: Reply with quote

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:
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, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
cfpresla
Voice


Joined: 08 Jul 2008
Posts: 4

PostPosted: Tue Jul 08, 2008 2:29 pm    Post subject: Reply with quote

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 ... ]
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2846

PostPosted: Tue Jul 08, 2008 2:32 pm    Post subject: Reply with quote

Yup, just load the module and use the command just like you would use any other tcl command.
_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
zorgman
Voice


Joined: 11 Jan 2010
Posts: 1
Location: Lithuania

PostPosted: Mon Jan 11, 2010 4:59 pm    Post subject: Reply with quote

care to share the module with me?
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Modules & Programming All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Forum hosting provided by Reverse.net

Powered by phpBB © 2001, 2005 phpBB Group
subGreen style by ktauber