made lua module use db.c for script list instead of scripts file

This commit is contained in:
Aaron Blakely 2024-03-06 02:50:22 -06:00
parent 3ff13e35b1
commit 24e535dbaf
12 changed files with 274 additions and 92 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View File

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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));
}

BIN
testdb

Binary file not shown.

BIN
xbot.db Normal file → Executable file

Binary file not shown.