made lua module use db.c for script list instead of scripts file
This commit is contained in:
parent
3ff13e35b1
commit
24e535dbaf
@ -4,5 +4,6 @@
|
||||
#include "irc.h"
|
||||
|
||||
struct irc_conn read_config(struct irc_conn bot, char *file);
|
||||
void run_autoload(struct irc_conn *bot);
|
||||
|
||||
#endif
|
23
lib/db.h
23
lib/db.h
@ -7,7 +7,8 @@
|
||||
enum db_type
|
||||
{
|
||||
DB_TYPE_CHAR,
|
||||
DB_TYPE_INT
|
||||
DB_TYPE_INT,
|
||||
DB_TYPE_FLOAT
|
||||
};
|
||||
|
||||
struct db_hash
|
||||
@ -29,17 +30,21 @@ struct db_table
|
||||
struct db_hash *hashes;
|
||||
};
|
||||
|
||||
int write_db(struct db_table *db, char *fname);
|
||||
struct db_table *read_db(char *fname);
|
||||
int db_write(struct db_table *db, char *fname);
|
||||
struct db_table *db_read(char *fname);
|
||||
|
||||
int db_add_hash(struct db_table *db, char *key, void *value);
|
||||
int db_add_hash_char(struct db_table *db, char *key, char *value);
|
||||
int db_add_hash_int(struct db_table *db, char *key, int value);
|
||||
int db_set_hash(struct db_table *db, char *key, void *value);
|
||||
int db_set_hash_char(struct db_table *db, char *key, char *value);
|
||||
int db_set_hash_int(struct db_table *db, char *key, int value);
|
||||
int db_set_hash_float(struct db_table *db, char *key, float value);
|
||||
|
||||
int db_del_hash(struct db_table *db, char *key);
|
||||
|
||||
void *get_hash(struct db_table *db, char *key);
|
||||
char *get_hash_char(struct db_table *db, char *key);
|
||||
int get_hash_int(struct db_table *db, char *key);
|
||||
void *db_get_hash(struct db_table *db, char *key);
|
||||
int db_get_hash_type(struct db_table *db, char *key);
|
||||
|
||||
char *db_get_hash_char(struct db_table *db, char *key);
|
||||
int db_get_hash_int(struct db_table *db, char *key);
|
||||
float db_get_hash_float(struct db_table *db, char *key);
|
||||
|
||||
#endif
|
||||
|
@ -39,9 +39,12 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file);
|
||||
void unload_module(struct irc_conn *bot, char *where, char *file);
|
||||
void list_modules(struct irc_conn *bot, char *where);
|
||||
void set_bot(struct irc_conn *b);
|
||||
void set_bot_db(struct db_table *db);
|
||||
MY_API void register_module(char *name, char *author, char *version, char *description);
|
||||
MY_API void unregister_module(char *name);
|
||||
MY_API struct mods *get_mods();
|
||||
MY_API struct irc_conn *get_bot();
|
||||
MY_API struct db_table *get_bot_db();
|
||||
|
||||
|
||||
#endif
|
||||
|
167
mods/lua/lua.c
167
mods/lua/lua.c
@ -17,102 +17,106 @@
|
||||
struct lua_interp lua;
|
||||
struct irc_conn *instance;
|
||||
|
||||
char *scriptsfile = "./mods/lua/scripts";
|
||||
|
||||
int append_script(char *fname)
|
||||
{
|
||||
int i;
|
||||
FILE *fp;
|
||||
char *buf = (char *)malloc(sizeof(char *) * 500);
|
||||
char *scriptlist = db_get_hash_char(get_bot_db(), "lua.scripts");
|
||||
char *newlist = (char *)malloc(sizeof(char) * 500);
|
||||
char *p = scriptlist;
|
||||
|
||||
// check if the file is already in the list
|
||||
struct script_list list = get_scripts();
|
||||
|
||||
for (i = 0; i < list.count; i++)
|
||||
if (scriptlist == NULL)
|
||||
{
|
||||
if (strcmp(list.scripts[i], fname) == 0)
|
||||
{
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
db_set_hash_char(get_bot_db(), "lua.scripts", fname);
|
||||
db_write(get_bot_db(), instance->db_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((fp = fopen(scriptsfile, "a")) == NULL)
|
||||
{
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
sprintf(newlist, "%s,%s", scriptlist, fname);
|
||||
printf("newlist: %s\n", newlist);
|
||||
|
||||
sprintf(buf, "%s\n", fname);
|
||||
fputs(buf, fp);
|
||||
fclose(fp);
|
||||
db_set_hash_char(get_bot_db(), "lua.scripts", newlist);
|
||||
|
||||
db_write(get_bot_db(), instance->db_file);
|
||||
|
||||
free(newlist);
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int remove_script(char *fname)
|
||||
{
|
||||
FILE *fp, *tmp;
|
||||
char *buf = (char *)malloc(sizeof(char *) * 500);
|
||||
char *tmpfile = "./mods/lua/scripts.tmp";
|
||||
char *scriptlist = db_get_hash_char(get_bot_db(), "lua.scripts");
|
||||
char *newlist = (char *)malloc(sizeof(char) * 500);
|
||||
char *p = scriptlist;
|
||||
char *q = newlist;
|
||||
int len = strlen(fname);
|
||||
int found = 0;
|
||||
|
||||
if ((fp = fopen(scriptsfile, "r")) == NULL)
|
||||
if (scriptlist == NULL)
|
||||
{
|
||||
free(buf);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = fopen(tmpfile, "w");
|
||||
|
||||
while (fgets(buf, 500, fp) != NULL)
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (strcmp(buf, fname) != 0)
|
||||
if (strncmp(p, fname, len) == 0)
|
||||
{
|
||||
fputs(buf, tmp);
|
||||
p = skip(p, ',');
|
||||
found = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
*q = *p;
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
fclose(tmp);
|
||||
if (found == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
remove(scriptsfile);
|
||||
rename(tmpfile, scriptsfile);
|
||||
*q = '\0';
|
||||
|
||||
// remove trailing , if it exists
|
||||
|
||||
if (newlist[strlen(newlist) - 1] == ',')
|
||||
{
|
||||
newlist[strlen(newlist) - 1] = '\0';
|
||||
}
|
||||
|
||||
db_set_hash_char(get_bot_db(), "lua.scripts", newlist);
|
||||
db_write(get_bot_db(), instance->db_file);
|
||||
|
||||
free(newlist);
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct script_list get_scripts()
|
||||
{
|
||||
FILE *fp;
|
||||
char *buf = (char *)malloc(sizeof(char *) * 500);
|
||||
struct script_list list;
|
||||
char *scriptlist = db_get_hash_char(get_bot_db(), "lua.scripts");
|
||||
printf("dbug: scriptlist: %s\n", scriptlist);
|
||||
|
||||
// dbug: scriptlist: hello.lua,test.lua,youtube.lua
|
||||
|
||||
struct script_list list = {0};
|
||||
char *p = scriptlist;
|
||||
int i = 0;
|
||||
|
||||
if ((fp = fopen(scriptsfile, "r")) == NULL)
|
||||
if (scriptlist == NULL)
|
||||
{
|
||||
free(buf);
|
||||
|
||||
list.count = 0;
|
||||
return list;
|
||||
}
|
||||
|
||||
while (fgets(buf, 500, fp) != NULL)
|
||||
while (*p != '\0')
|
||||
{
|
||||
list.scripts[i] = (char *)malloc(sizeof(char *) * 150);
|
||||
strlcpy(list.scripts[i], buf, 150);
|
||||
|
||||
// remove newline
|
||||
list.scripts[i][strlen(list.scripts[i]) - 1] = '\0';
|
||||
|
||||
|
||||
list.scripts[i] = p;
|
||||
p = skip(p, ',');
|
||||
i++;
|
||||
}
|
||||
|
||||
list.count = i;
|
||||
|
||||
free(buf);
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -326,8 +330,10 @@ void mod_init()
|
||||
{
|
||||
int i;
|
||||
char *buf = (char *)malloc(sizeof(char *) * 500);
|
||||
struct script_list list = get_scripts();
|
||||
struct script_list list = {0};
|
||||
|
||||
instance = get_bot();
|
||||
list = get_scripts();
|
||||
|
||||
lua.scripts = calloc(512, sizeof(struct lua_script));
|
||||
lua.events = calloc(1024, sizeof(struct lua_event));
|
||||
@ -360,9 +366,54 @@ void mod_init()
|
||||
{
|
||||
printf("Loading %s\n", list.scripts[i]);
|
||||
|
||||
sprintf(buf, "!load %s", list.scripts[i]);
|
||||
sprintf(buf, "./scripts/%s", list.scripts[i]);
|
||||
strlcpy(lua.scripts[lua.script_count].fname, buf, 150);
|
||||
|
||||
lua_load_script(instance, "lua", "localhost", "-stdio-", buf);
|
||||
if (luaL_loadfile(lua.L, buf) != LUA_OK)
|
||||
{
|
||||
printf("Error loading lua script: %s\n", lua_tostring(lua.L, -1));
|
||||
continue;
|
||||
}
|
||||
|
||||
// execute the script
|
||||
if (lua_pcall(lua.L, 0, 0, 0) != LUA_OK)
|
||||
{
|
||||
printf("Error executing lua script: %s\n", lua_tostring(lua.L, -1));
|
||||
continue;
|
||||
}
|
||||
|
||||
// get a ref to unload function if it exists and store it with luaL_ref
|
||||
lua_getglobal(lua.L, "unload");
|
||||
|
||||
if (lua_isfunction(lua.L, -1))
|
||||
{
|
||||
lua.scripts[lua.script_count].unload = luaL_ref(lua.L, LUA_REGISTRYINDEX);
|
||||
printf("dbg: unload ref: %d\n", lua.scripts[lua.script_count].unload);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua.scripts[lua.script_count].unload = -1;
|
||||
printf("No unload() function in %s\n", list.scripts[i]);
|
||||
}
|
||||
|
||||
// call the load function if it exists
|
||||
lua_getglobal(lua.L, "load");
|
||||
|
||||
if (lua_isfunction(lua.L, -1))
|
||||
{
|
||||
if (lua_pcall(lua.L, 0, 0, 0) != LUA_OK)
|
||||
{
|
||||
printf("Error calling load() in %s: %s\n", buf, lua_tostring(lua.L, -1));
|
||||
continue;
|
||||
}
|
||||
|
||||
lua.script_count++;
|
||||
printf("Loaded %s\n", list.scripts[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error: No load() function in %s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Lua module loaded\n");
|
||||
|
0
scripts/t1.lua
Executable file
0
scripts/t1.lua
Executable file
34
src/config.c
34
src/config.c
@ -44,6 +44,34 @@ struct irc_conn read_config(struct irc_conn bot, char *file)
|
||||
if (config_lookup_string(cf, "bot.db", &base))
|
||||
strlcpy(bot.db_file, base, sizeof bot.db_file);
|
||||
|
||||
config_destroy(cf);
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
||||
void run_autoload(struct irc_conn *bot)
|
||||
{
|
||||
int count, n;
|
||||
config_t cfg, *cf;
|
||||
const config_setting_t *autoload;
|
||||
const char *base = (const char*)malloc(sizeof(char) * 1024);
|
||||
const char *mod = NULL;
|
||||
char *modpath = (char *)malloc(sizeof(char) * 500);
|
||||
|
||||
cf = &cfg;
|
||||
config_init(cf);
|
||||
|
||||
if (!config_read_file(cf, "xbot.cfg"))
|
||||
{
|
||||
printf("[xbot.cfg:%d] Configuration error: %s\n",
|
||||
config_error_line(cf),
|
||||
config_error_text(cf)
|
||||
);
|
||||
|
||||
config_destroy(cf);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
autoload = config_lookup(cf, "mods.autoload");
|
||||
count = config_setting_length(autoload);
|
||||
|
||||
@ -51,14 +79,12 @@ struct irc_conn read_config(struct irc_conn bot, char *file)
|
||||
{
|
||||
mod = config_setting_get_string_elem(autoload, n);
|
||||
#ifdef _WIN32
|
||||
sprintf(modpath, "./mods/%s.dll", mod);
|
||||
sprintf(modpath, "./mods/%s.dll", mod);
|
||||
#else
|
||||
sprintf(modpath, "./mods/%s.so", mod);
|
||||
#endif
|
||||
load_module(&bot, "main", "runtime", modpath);
|
||||
load_module(bot, "main", "runtime", modpath);
|
||||
}
|
||||
|
||||
config_destroy(cf);
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
99
src/db.c
99
src/db.c
@ -6,7 +6,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int write_db(struct db_table *db, char *fname)
|
||||
int db_write(struct db_table *db, char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
int i;
|
||||
@ -37,7 +37,7 @@ int write_db(struct db_table *db, char *fname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct db_table *read_db(char *fname)
|
||||
struct db_table *db_read(char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
struct db_table *db;
|
||||
@ -89,15 +89,23 @@ struct db_table *read_db(char *fname)
|
||||
return db;
|
||||
}
|
||||
|
||||
int db_add_hash(struct db_table *db, char *key, void *value)
|
||||
int db_set_hash(struct db_table *db, char *key, void *value)
|
||||
{
|
||||
int i;
|
||||
|
||||
// check if the key already exists and update it
|
||||
for (i = 0; i < db->count; i++)
|
||||
{
|
||||
if (strcmp(db->hashes[i].key, key) == 0)
|
||||
{
|
||||
return -1;
|
||||
if (db->hashes[i].type == DB_TYPE_CHAR)
|
||||
{
|
||||
free(db->hashes[i].value);
|
||||
}
|
||||
|
||||
db->hashes[i].value = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,8 +123,33 @@ int db_add_hash(struct db_table *db, char *key, void *value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int db_add_hash_char(struct db_table *db, char *key, char *value)
|
||||
|
||||
int db_set_hash_char(struct db_table *db, char *key, char *value)
|
||||
{
|
||||
// check if the key already exists and update it
|
||||
int i;
|
||||
|
||||
for (i = 0; i < db->count; i++)
|
||||
{
|
||||
if (strcmp(db->hashes[i].key, key) == 0)
|
||||
{
|
||||
if (db->hashes[i].type == DB_TYPE_CHAR)
|
||||
{
|
||||
free(db->hashes[i].value);
|
||||
}
|
||||
|
||||
db->hashes[i].type = DB_TYPE_CHAR;
|
||||
db->hashes[i].value_len = strlen(value) + 1;
|
||||
db->hashes[i].value = (char *)malloc(sizeof(char) * db->hashes[i].value_len);
|
||||
|
||||
memset(db->hashes[i].value, 0, sizeof(char) * db->hashes[i].value_len);
|
||||
|
||||
strlcpy(db->hashes[i].value, value, sizeof(char) * db->hashes[i].value_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
db->hashes = (struct db_hash *)realloc(db->hashes, sizeof(struct db_hash) * (db->count + 1));
|
||||
|
||||
// zero out reallocated memory
|
||||
@ -130,10 +163,10 @@ int db_add_hash_char(struct db_table *db, char *key, char *value)
|
||||
|
||||
strlcpy(db->hashes[db->count].value, value, sizeof(char) * db->hashes[db->count].value_len);
|
||||
|
||||
return db_add_hash(db, key, db->hashes[db->count].value);
|
||||
return db_set_hash(db, key, db->hashes[db->count].value);
|
||||
}
|
||||
|
||||
int db_add_hash_int(struct db_table *db, char *key, int value)
|
||||
int db_set_hash_int(struct db_table *db, char *key, int value)
|
||||
{
|
||||
db->hashes = (struct db_hash *)realloc(db->hashes, sizeof(struct db_hash) * (db->count + 1));
|
||||
|
||||
@ -146,7 +179,23 @@ int db_add_hash_int(struct db_table *db, char *key, int value)
|
||||
|
||||
memcpy(db->hashes[db->count].value, &value, sizeof(int));
|
||||
|
||||
return db_add_hash(db, key, db->hashes[db->count].value);
|
||||
return db_set_hash(db, key, db->hashes[db->count].value);
|
||||
}
|
||||
|
||||
int db_set_hash_float(struct db_table *db, char *key, float value)
|
||||
{
|
||||
db->hashes = (struct db_hash *)realloc(db->hashes, sizeof(struct db_hash) * (db->count + 1));
|
||||
|
||||
// zero out reallocated memory
|
||||
memset(&db->hashes[db->count], 0, sizeof(struct db_hash));
|
||||
|
||||
db->hashes[db->count].type = DB_TYPE_FLOAT;
|
||||
db->hashes[db->count].value_len = sizeof(float);
|
||||
db->hashes[db->count].value = (float *)malloc(sizeof(float));
|
||||
|
||||
memcpy(db->hashes[db->count].value, &value, sizeof(float));
|
||||
|
||||
return db_set_hash(db, key, db->hashes[db->count].value);
|
||||
}
|
||||
|
||||
int db_del_hash(struct db_table *db, char *key)
|
||||
@ -169,7 +218,7 @@ int db_del_hash(struct db_table *db, char *key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *get_hash(struct db_table *db, char *key)
|
||||
void *db_get_hash(struct db_table *db, char *key)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -184,16 +233,40 @@ void *get_hash(struct db_table *db, char *key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *get_hash_char(struct db_table *db, char *key)
|
||||
int db_get_hash_type(struct db_table *db, char *key)
|
||||
{
|
||||
return (char *)get_hash(db, key);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < db->count; i++)
|
||||
{
|
||||
if (strcmp(db->hashes[i].key, key) == 0)
|
||||
{
|
||||
return db->hashes[i].type;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_hash_int(struct db_table *db, char *key)
|
||||
char *db_get_hash_char(struct db_table *db, char *key)
|
||||
{
|
||||
return (char *)db_get_hash(db, key);
|
||||
}
|
||||
|
||||
int db_get_hash_int(struct db_table *db, char *key)
|
||||
{
|
||||
int value;
|
||||
|
||||
memcpy(&value, get_hash(db, key), sizeof(int));
|
||||
memcpy(&value, db_get_hash(db, key), sizeof(int));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
float db_get_hash_float(struct db_table *db, char *key)
|
||||
{
|
||||
float value;
|
||||
|
||||
memcpy(&value, db_get_hash(db, key), sizeof(float));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
15
src/main.c
15
src/main.c
@ -46,30 +46,37 @@ int main()
|
||||
last_ping.tv_sec = time(NULL);
|
||||
|
||||
set_bot(&bot);
|
||||
|
||||
init_events();
|
||||
init_timers();
|
||||
init_mods();
|
||||
|
||||
// Read the config
|
||||
|
||||
bot = read_config(bot, "xbot.cfg");
|
||||
|
||||
// check if the db exists, if not, create it
|
||||
if (access(bot.db_file, F_OK) == -1)
|
||||
{
|
||||
printf("Creating db\n");
|
||||
printf("Creating database file: %s\n", bot.db_file);
|
||||
bot.db = (struct db_table *)malloc(sizeof(struct db_table));
|
||||
memset(bot.db, 0, sizeof(struct db_table));
|
||||
set_bot_db(bot.db);
|
||||
|
||||
bot.db->count = 0;
|
||||
bot.db->hashes = NULL;
|
||||
|
||||
write_db(bot.db, bot.db_file);
|
||||
db_write(bot.db, bot.db_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
bot.db = read_db(bot.db_file);
|
||||
printf("Reading database file: %s\n", bot.db_file);
|
||||
bot.db = db_read(bot.db_file);
|
||||
set_bot_db(bot.db);
|
||||
}
|
||||
|
||||
// run autoload
|
||||
run_autoload(&bot);
|
||||
|
||||
// Connect to the server
|
||||
printf("Connecting to %s...\n", bot.host);
|
||||
|
||||
|
11
src/module.c
11
src/module.c
@ -14,6 +14,7 @@
|
||||
|
||||
struct mods *mods;
|
||||
struct irc_conn *instance;
|
||||
struct db_table *dbinstance;
|
||||
|
||||
void init_mods()
|
||||
{
|
||||
@ -315,3 +316,13 @@ void set_bot(struct irc_conn *b)
|
||||
{
|
||||
instance = b;
|
||||
}
|
||||
|
||||
void set_bot_db(struct db_table *db)
|
||||
{
|
||||
dbinstance = db;
|
||||
}
|
||||
|
||||
MY_API struct db_table *get_bot_db()
|
||||
{
|
||||
return dbinstance;
|
||||
}
|
||||
|
11
test_db.c
11
test_db.c
@ -27,8 +27,9 @@ int main()
|
||||
// write some data if db is empty
|
||||
if (db->count == 0)
|
||||
{
|
||||
db_add_hash_char(db, "lua.scripts", "hello.lua,test.lua,youtube.lua");
|
||||
db_add_hash_int(db, "lua.scriptcount", 2);
|
||||
db_set_hash_char(db, "lua.scripts", "hello.lua,test.lua,youtube.lua");
|
||||
db_set_hash_int(db, "lua.scriptcount", 2);
|
||||
db_set_hash_float(db, "lua.version", 5.1);
|
||||
write_db(db, FNAME);
|
||||
|
||||
return 0;
|
||||
@ -40,7 +41,11 @@ int main()
|
||||
{
|
||||
printf("Key: %s, Value: %d\n", db->hashes[i].key, get_hash_int(db, db->hashes[i].key));
|
||||
}
|
||||
else
|
||||
else if (db->hashes[i].type == DB_TYPE_FLOAT)
|
||||
{
|
||||
printf("Key: %s, Value: %f\n", db->hashes[i].key, get_hash_float(db, db->hashes[i].key));
|
||||
}
|
||||
else if (db->hashes[i].type == DB_TYPE_CHAR)
|
||||
{
|
||||
printf("Key: %s, Value: %s\n", db->hashes[i].key, get_hash_char(db, db->hashes[i].key));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user