Compare commits
10 Commits
f91fac4d1e
...
13bcd3d20e
Author | SHA1 | Date | |
---|---|---|---|
![]() |
13bcd3d20e | ||
![]() |
8ebf060f48 | ||
![]() |
c3281dc946 | ||
![]() |
24e535dbaf | ||
![]() |
3ff13e35b1 | ||
![]() |
b61a71e6ae | ||
![]() |
1ef5bdf07b | ||
![]() |
f275caf11f | ||
![]() |
387ce7338f | ||
![]() |
d7b82df673 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@ mods/test
|
|||||||
.cache
|
.cache
|
||||||
UpgradeLog*.XML
|
UpgradeLog*.XML
|
||||||
|
|
||||||
|
xbot.db
|
||||||
*.so
|
*.so
|
||||||
*.dll
|
*.dll
|
||||||
*.lib
|
*.lib
|
||||||
|
2
Makefile
2
Makefile
@ -22,6 +22,8 @@ main:
|
|||||||
$(CC) $(CFLAGS) $(SRC)/module.c -o $(OBJ)/module.o
|
$(CC) $(CFLAGS) $(SRC)/module.c -o $(OBJ)/module.o
|
||||||
$(CC) $(CFLAGS) $(SRC)/channel.c -o $(OBJ)/channel.o
|
$(CC) $(CFLAGS) $(SRC)/channel.c -o $(OBJ)/channel.o
|
||||||
$(CC) $(CFLAGS) $(SRC)/timers.c -o $(OBJ)/timers.o
|
$(CC) $(CFLAGS) $(SRC)/timers.c -o $(OBJ)/timers.o
|
||||||
|
$(CC) $(CFLAGS) $(SRC)/db.c -o $(OBJ)/db.o
|
||||||
|
|
||||||
$(CC) -o $(EXEC) $(OBJECTS) $(BINFLAGS)
|
$(CC) -o $(EXEC) $(OBJECTS) $(BINFLAGS)
|
||||||
@echo "All Done!"
|
@echo "All Done!"
|
||||||
|
|
||||||
|
@ -4,5 +4,6 @@
|
|||||||
#include "irc.h"
|
#include "irc.h"
|
||||||
|
|
||||||
struct irc_conn read_config(struct irc_conn bot, char *file);
|
struct irc_conn read_config(struct irc_conn bot, char *file);
|
||||||
|
void run_autoload(struct irc_conn *bot);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
52
lib/db.h
Executable file
52
lib/db.h
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef DB_H
|
||||||
|
#define DB_H
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#define DB_MAGIC 0xdeadbeef
|
||||||
|
#define DB_VER 0x10
|
||||||
|
|
||||||
|
enum db_type
|
||||||
|
{
|
||||||
|
DB_TYPE_CHAR,
|
||||||
|
DB_TYPE_INT,
|
||||||
|
DB_TYPE_FLOAT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct db_hash
|
||||||
|
{
|
||||||
|
int key_len;
|
||||||
|
int value_len;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
char *key;
|
||||||
|
void *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct db_table
|
||||||
|
{
|
||||||
|
int db_magic;
|
||||||
|
int db_ver;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
struct db_hash *hashes;
|
||||||
|
};
|
||||||
|
|
||||||
|
MY_API int db_write(struct db_table *db, char *fname);
|
||||||
|
MY_API struct db_table *db_read(char *fname);
|
||||||
|
|
||||||
|
MY_API int db_set_hash(struct db_table *db, char *key, void *value);
|
||||||
|
MY_API int db_set_hash_char(struct db_table *db, char *key, char *value);
|
||||||
|
MY_API int db_set_hash_int(struct db_table *db, char *key, int value);
|
||||||
|
MY_API int db_set_hash_float(struct db_table *db, char *key, float value);
|
||||||
|
|
||||||
|
MY_API int db_del_hash(struct db_table *db, char *key);
|
||||||
|
|
||||||
|
MY_API void *db_get_hash(struct db_table *db, char *key);
|
||||||
|
MY_API int db_get_hash_type(struct db_table *db, char *key);
|
||||||
|
|
||||||
|
MY_API char *db_get_hash_char(struct db_table *db, char *key);
|
||||||
|
MY_API int db_get_hash_int(struct db_table *db, char *key);
|
||||||
|
MY_API float db_get_hash_float(struct db_table *db, char *key);
|
||||||
|
|
||||||
|
#endif
|
17
lib/irc.h
17
lib/irc.h
@ -9,6 +9,9 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "db.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
@ -30,6 +33,9 @@ struct irc_conn
|
|||||||
char port[5];
|
char port[5];
|
||||||
char real_name[512];
|
char real_name[512];
|
||||||
|
|
||||||
|
char db_file[256];
|
||||||
|
struct db_table *db;
|
||||||
|
|
||||||
// I/O Buffers
|
// I/O Buffers
|
||||||
char *out;
|
char *out;
|
||||||
char *in;
|
char *in;
|
||||||
@ -37,16 +43,6 @@ struct irc_conn
|
|||||||
|
|
||||||
typedef struct handler event_handler;
|
typedef struct handler event_handler;
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#ifdef MY_DLL_EXPORTS
|
|
||||||
#define MY_API __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define MY_API __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define MY_API
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void irc_connect(struct irc_conn *bot);
|
void irc_connect(struct irc_conn *bot);
|
||||||
void irc_auth(struct irc_conn *bot);
|
void irc_auth(struct irc_conn *bot);
|
||||||
|
|
||||||
@ -58,6 +54,7 @@ MY_API void irc_part(struct irc_conn *bot, char *channel, char *reason);
|
|||||||
MY_API void irc_ban(struct irc_conn *bot, char *channel, char *nick);
|
MY_API void irc_ban(struct irc_conn *bot, char *channel, char *nick);
|
||||||
MY_API void irc_kick(struct irc_conn *bot, char *channel, char *user, char *reason);
|
MY_API void irc_kick(struct irc_conn *bot, char *channel, char *user, char *reason);
|
||||||
MY_API void irc_mode(struct irc_conn *bot, char *channel, char *mode);
|
MY_API void irc_mode(struct irc_conn *bot, char *channel, char *mode);
|
||||||
|
MY_API void irc_ctcp(struct irc_conn *bot, char *to, char *fmt, ...);
|
||||||
|
|
||||||
void irc_parse_raw(struct irc_conn *bot, char *raw);
|
void irc_parse_raw(struct irc_conn *bot, char *raw);
|
||||||
|
|
||||||
|
@ -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 unload_module(struct irc_conn *bot, char *where, char *file);
|
||||||
void list_modules(struct irc_conn *bot, char *where);
|
void list_modules(struct irc_conn *bot, char *where);
|
||||||
void set_bot(struct irc_conn *b);
|
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 register_module(char *name, char *author, char *version, char *description);
|
||||||
MY_API void unregister_module(char *name);
|
MY_API void unregister_module(char *name);
|
||||||
MY_API struct mods *get_mods();
|
MY_API struct mods *get_mods();
|
||||||
MY_API struct irc_conn *get_bot();
|
MY_API struct irc_conn *get_bot();
|
||||||
|
MY_API struct db_table *get_bot_db();
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
18
lib/util.h
18
lib/util.h
@ -12,17 +12,27 @@
|
|||||||
#define false FALSE
|
#define false FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifdef MY_DLL_EXPORTS
|
||||||
|
#define MY_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define MY_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define MY_API
|
||||||
|
#endif
|
||||||
|
|
||||||
void eprint(char *fmt, ...);
|
void eprint(char *fmt, ...);
|
||||||
|
|
||||||
#if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 38)) || defined(_WIN32)
|
#if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 38)) || defined(_WIN32)
|
||||||
void strlcpy(char *to, const char *from, int len);
|
MY_API void strlcpy(char *to, const char *from, int len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char *basename(char *path);
|
MY_API char *basename(char *path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *skip(char *s, char c);
|
MY_API char *skip(char *s, char c);
|
||||||
void trim(char *s);
|
MY_API void trim(char *s);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
78
mods/lua/README.md
Executable file
78
mods/lua/README.md
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
# API
|
||||||
|
|
||||||
|
## Events
|
||||||
|
|
||||||
|
### Event Types
|
||||||
|
|
||||||
|
- `PRIVMSG_SELF - user, host, message`
|
||||||
|
- `PRIVMSG_CHAN - user, host, channel, message`
|
||||||
|
- `JOIN - user, host, channel`
|
||||||
|
- `JOIN_MYSELF - channel`
|
||||||
|
- `PART - user, host, channel, reason`
|
||||||
|
- `PART_MYSELF - channel, reason`
|
||||||
|
- `QUIT - user, host, reason`
|
||||||
|
- `NICK - user, host, newnick`
|
||||||
|
- `NICK_MYSELF - newnick`
|
||||||
|
- `NICK_INUSE - newnick`
|
||||||
|
- `CTCP - user, host, to, message`
|
||||||
|
- `IRC_CONNECTED`
|
||||||
|
- `TICK`
|
||||||
|
|
||||||
|
### `add_handler(event, handler)`
|
||||||
|
|
||||||
|
Adds a handler for an event.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function msg(user, host, channel, message)
|
||||||
|
print(user .. " said: " .. message)
|
||||||
|
end
|
||||||
|
|
||||||
|
add_handler(PRIVMSG_CHAN, msg)
|
||||||
|
```
|
||||||
|
|
||||||
|
### `del_handler(event, handler)`
|
||||||
|
|
||||||
|
Removes a handler for an event.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
del_handler(PRIVMSG_CHAN, msg)
|
||||||
|
```
|
||||||
|
|
||||||
|
## IRC Commands
|
||||||
|
|
||||||
|
### `raw(message)`
|
||||||
|
|
||||||
|
Sends a raw message to the server.
|
||||||
|
|
||||||
|
### `privmsg(to, message)`
|
||||||
|
|
||||||
|
Sends a message to a channel or user.
|
||||||
|
|
||||||
|
### `notice(to, message)`
|
||||||
|
|
||||||
|
Sends a notice to a channel or user.
|
||||||
|
|
||||||
|
### `join(channel)`
|
||||||
|
|
||||||
|
Joins a channel.
|
||||||
|
|
||||||
|
### `part(channel, reason)`
|
||||||
|
|
||||||
|
Leaves a channel.
|
||||||
|
|
||||||
|
### `kick(channel, user, reason)`
|
||||||
|
|
||||||
|
Kicks a user from a channel. Reason is optional.
|
||||||
|
|
||||||
|
### `mode(channel, mode, target)`
|
||||||
|
|
||||||
|
Sets a mode on a channel.
|
||||||
|
|
||||||
|
### `ctcp(to, message)`
|
||||||
|
|
||||||
|
Sends a CTCP message to a channel or user.
|
||||||
|
|
163
mods/lua/lua.c
163
mods/lua/lua.c
@ -17,102 +17,102 @@
|
|||||||
struct lua_interp lua;
|
struct lua_interp lua;
|
||||||
struct irc_conn *instance;
|
struct irc_conn *instance;
|
||||||
|
|
||||||
char *scriptsfile = "./mods/lua/scripts";
|
|
||||||
|
|
||||||
int append_script(char *fname)
|
int append_script(char *fname)
|
||||||
{
|
{
|
||||||
int i;
|
char *scriptlist = db_get_hash_char(get_bot_db(), "lua.scripts");
|
||||||
FILE *fp;
|
char *newlist = (char *)malloc(sizeof(char) * 500);
|
||||||
char *buf = (char *)malloc(sizeof(char *) * 500);
|
char *p = scriptlist;
|
||||||
|
|
||||||
// check if the file is already in the list
|
if (scriptlist == NULL)
|
||||||
struct script_list list = get_scripts();
|
|
||||||
|
|
||||||
for (i = 0; i < list.count; i++)
|
|
||||||
{
|
{
|
||||||
if (strcmp(list.scripts[i], fname) == 0)
|
db_set_hash_char(get_bot_db(), "lua.scripts", fname);
|
||||||
{
|
db_write(get_bot_db(), instance->db_file);
|
||||||
free(buf);
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fp = fopen(scriptsfile, "a")) == NULL)
|
sprintf(newlist, "%s,%s", scriptlist, fname);
|
||||||
{
|
printf("newlist: %s\n", newlist);
|
||||||
free(buf);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(buf, "%s\n", fname);
|
db_set_hash_char(get_bot_db(), "lua.scripts", newlist);
|
||||||
fputs(buf, fp);
|
|
||||||
fclose(fp);
|
db_write(get_bot_db(), instance->db_file);
|
||||||
|
|
||||||
|
free(newlist);
|
||||||
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int remove_script(char *fname)
|
int remove_script(char *fname)
|
||||||
{
|
{
|
||||||
FILE *fp, *tmp;
|
char *scriptlist = db_get_hash_char(get_bot_db(), "lua.scripts");
|
||||||
char *buf = (char *)malloc(sizeof(char *) * 500);
|
char *newlist = (char *)malloc(sizeof(char) * 500);
|
||||||
char *tmpfile = "./mods/lua/scripts.tmp";
|
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 0;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = fopen(tmpfile, "w");
|
while (*p != '\0')
|
||||||
|
|
||||||
while (fgets(buf, 500, fp) != NULL)
|
|
||||||
{
|
{
|
||||||
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);
|
if (found == 0)
|
||||||
fclose(tmp);
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
remove(scriptsfile);
|
*q = '\0';
|
||||||
rename(tmpfile, scriptsfile);
|
|
||||||
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct script_list get_scripts()
|
struct script_list get_scripts()
|
||||||
{
|
{
|
||||||
FILE *fp;
|
char *scriptlist = db_get_hash_char(get_bot_db(), "lua.scripts");
|
||||||
char *buf = (char *)malloc(sizeof(char *) * 500);
|
struct script_list list = {0};
|
||||||
struct script_list list;
|
char *p = scriptlist;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if ((fp = fopen(scriptsfile, "r")) == NULL)
|
if (scriptlist == NULL)
|
||||||
{
|
{
|
||||||
free(buf);
|
|
||||||
|
|
||||||
list.count = 0;
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(buf, 500, fp) != NULL)
|
while (*p != '\0')
|
||||||
{
|
{
|
||||||
list.scripts[i] = (char *)malloc(sizeof(char *) * 150);
|
list.scripts[i] = p;
|
||||||
strlcpy(list.scripts[i], buf, 150);
|
p = skip(p, ',');
|
||||||
|
|
||||||
// remove newline
|
|
||||||
list.scripts[i][strlen(list.scripts[i]) - 1] = '\0';
|
|
||||||
|
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
list.count = i;
|
list.count = i;
|
||||||
|
|
||||||
free(buf);
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,8 +326,10 @@ void mod_init()
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *buf = (char *)malloc(sizeof(char *) * 500);
|
char *buf = (char *)malloc(sizeof(char *) * 500);
|
||||||
struct script_list list = get_scripts();
|
struct script_list list = {0};
|
||||||
|
|
||||||
instance = get_bot();
|
instance = get_bot();
|
||||||
|
list = get_scripts();
|
||||||
|
|
||||||
lua.scripts = calloc(512, sizeof(struct lua_script));
|
lua.scripts = calloc(512, sizeof(struct lua_script));
|
||||||
lua.events = calloc(1024, sizeof(struct lua_event));
|
lua.events = calloc(1024, sizeof(struct lua_event));
|
||||||
@ -360,9 +362,54 @@ void mod_init()
|
|||||||
{
|
{
|
||||||
printf("Loading %s\n", list.scripts[i]);
|
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");
|
printf("Lua module loaded\n");
|
||||||
|
@ -63,6 +63,13 @@ void lua_fire_handlers(char *event, ...);
|
|||||||
void lua_init_wrappers();
|
void lua_init_wrappers();
|
||||||
void raw_wrapper(lua_State *L);
|
void raw_wrapper(lua_State *L);
|
||||||
void privmsg_wrapper(lua_State *L);
|
void privmsg_wrapper(lua_State *L);
|
||||||
|
void notice_wrapper(lua_State *L);
|
||||||
|
void join_wrapper(lua_State *L);
|
||||||
|
void part_wrapper(lua_State *L);
|
||||||
|
void ban_wrapper(lua_State *L);
|
||||||
|
void kick_wrapper(lua_State *L);
|
||||||
|
void mode_wrapper(lua_State *L);
|
||||||
|
void ctcp_wrapper(lua_State *L);
|
||||||
|
|
||||||
// handlers.c
|
// handlers.c
|
||||||
void lua_init_handlers();
|
void lua_init_handlers();
|
||||||
|
@ -3,3 +3,5 @@ cl /I "..\..\lib" /I "..\..\include\libconfig-1.7.3\lib" /I "..\..\include\lua5.
|
|||||||
cl /I "..\..\lib" /I "..\..\include\libconfig-1.7.3\lib" /I "..\..\include\lua5.3\include" /c wrappers.c
|
cl /I "..\..\lib" /I "..\..\include\libconfig-1.7.3\lib" /I "..\..\include\lua5.3\include" /c wrappers.c
|
||||||
cl /I "..\..\lib" /I "..\..\include\libconfig-1.7.3\lib" /I "..\..\include\lua5.3\include" /c lua.c
|
cl /I "..\..\lib" /I "..\..\include\libconfig-1.7.3\lib" /I "..\..\include\lua5.3\include" /c lua.c
|
||||||
link /DLL /out:..\lua.dll events.obj handlers.obj wrappers.obj lua.obj ..\..\Debug\xbot.lib ..\..\include\libconfig.lib ..\..\include\lua5.3\lua53.lib
|
link /DLL /out:..\lua.dll events.obj handlers.obj wrappers.obj lua.obj ..\..\Debug\xbot.lib ..\..\include\libconfig.lib ..\..\include\lua5.3\lua53.lib
|
||||||
|
del *.obj
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
hello.lua
|
|
||||||
test.lua
|
test.lua
|
||||||
|
hello.lua
|
@ -4,6 +4,13 @@ void lua_init_wrappers()
|
|||||||
{
|
{
|
||||||
lua_register(lua.L, "raw", raw_wrapper);
|
lua_register(lua.L, "raw", raw_wrapper);
|
||||||
lua_register(lua.L, "privmsg", privmsg_wrapper);
|
lua_register(lua.L, "privmsg", privmsg_wrapper);
|
||||||
|
lua_register(lua.L, "notice", notice_wrapper);
|
||||||
|
lua_register(lua.L, "join", join_wrapper);
|
||||||
|
lua_register(lua.L, "part", part_wrapper);
|
||||||
|
lua_register(lua.L, "ban", ban_wrapper);
|
||||||
|
lua_register(lua.L, "kick", kick_wrapper);
|
||||||
|
lua_register(lua.L, "mode", mode_wrapper);
|
||||||
|
lua_register(lua.L, "ctcp", ctcp_wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
void raw_wrapper(lua_State *L)
|
void raw_wrapper(lua_State *L)
|
||||||
@ -20,3 +27,70 @@ void privmsg_wrapper(lua_State *L)
|
|||||||
|
|
||||||
irc_privmsg(instance, where, text);
|
irc_privmsg(instance, where, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notice_wrapper(lua_State *L)
|
||||||
|
{
|
||||||
|
char *where = (char *)lua_tostring(L, 1);
|
||||||
|
char *text = (char *)lua_tostring(L, 2);
|
||||||
|
|
||||||
|
irc_notice(instance, where, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void join_wrapper(lua_State *L)
|
||||||
|
{
|
||||||
|
char *chan = (char *)lua_tostring(L, 1);
|
||||||
|
|
||||||
|
irc_join(instance, chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
void part_wrapper(lua_State *L)
|
||||||
|
{
|
||||||
|
char *chan = (char *)lua_tostring(L, 1);
|
||||||
|
char *reason = (char *)lua_tostring(L, 2);
|
||||||
|
|
||||||
|
if (!reason)
|
||||||
|
{
|
||||||
|
reason = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
irc_part(instance, chan, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ban_wrapper(lua_State *L)
|
||||||
|
{
|
||||||
|
char *chan = (char *)lua_tostring(L, 1);
|
||||||
|
char *user = (char *)lua_tostring(L, 2);
|
||||||
|
|
||||||
|
irc_ban(instance, chan, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
void kick_wrapper(lua_State *L)
|
||||||
|
{
|
||||||
|
char *chan = (char *)lua_tostring(L, 1);
|
||||||
|
char *user = (char *)lua_tostring(L, 2);
|
||||||
|
char *reason = (char *)lua_tostring(L, 3);
|
||||||
|
|
||||||
|
if (!reason)
|
||||||
|
{
|
||||||
|
reason = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
irc_kick(instance, chan, user, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mode_wrapper(lua_State *L)
|
||||||
|
{
|
||||||
|
char *chan = (char *)lua_tostring(L, 1);
|
||||||
|
char *mode = (char *)lua_tostring(L, 2);
|
||||||
|
|
||||||
|
irc_mode(instance, chan, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctcp_wrapper(lua_State *L)
|
||||||
|
{
|
||||||
|
char *to = (char *)lua_tostring(L, 1);
|
||||||
|
char *msg = (char *)lua_tostring(L, 2);
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
irc_ctcp(instance, to, msg);
|
||||||
|
}
|
||||||
|
37
src/config.c
37
src/config.c
@ -41,6 +41,37 @@ struct irc_conn read_config(struct irc_conn bot, char *file)
|
|||||||
if (config_lookup_string(cf, "bot.admin", &base))
|
if (config_lookup_string(cf, "bot.admin", &base))
|
||||||
strlcpy(bot.admin, base, sizeof bot.admin);
|
strlcpy(bot.admin, base, sizeof bot.admin);
|
||||||
|
|
||||||
|
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");
|
autoload = config_lookup(cf, "mods.autoload");
|
||||||
count = config_setting_length(autoload);
|
count = config_setting_length(autoload);
|
||||||
|
|
||||||
@ -48,14 +79,12 @@ struct irc_conn read_config(struct irc_conn bot, char *file)
|
|||||||
{
|
{
|
||||||
mod = config_setting_get_string_elem(autoload, n);
|
mod = config_setting_get_string_elem(autoload, n);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
sprintf(modpath, "./mods/%s.dll", mod);
|
sprintf(modpath, "./mods/%s.dll", mod);
|
||||||
#else
|
#else
|
||||||
sprintf(modpath, "./mods/%s.so", mod);
|
sprintf(modpath, "./mods/%s.so", mod);
|
||||||
#endif
|
#endif
|
||||||
load_module(&bot, "main", "runtime", modpath);
|
load_module(bot, "main", "runtime", modpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
config_destroy(cf);
|
config_destroy(cf);
|
||||||
|
|
||||||
return bot;
|
|
||||||
}
|
}
|
||||||
|
283
src/db.c
Executable file
283
src/db.c
Executable file
@ -0,0 +1,283 @@
|
|||||||
|
#include "util.h"
|
||||||
|
#include "irc.h"
|
||||||
|
#include "db.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int db_write(struct db_table *db, char *fname)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int i;
|
||||||
|
char *fullpath;
|
||||||
|
|
||||||
|
if ((fp = fopen(fname, "wb")) == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
db->db_magic = DB_MAGIC;
|
||||||
|
db->db_ver = DB_VER;
|
||||||
|
|
||||||
|
// get the full path to the db file
|
||||||
|
#ifdef _WIN32
|
||||||
|
fullpath = _fullpath(NULL, fname, 0);
|
||||||
|
#else
|
||||||
|
fullpath = realpath(fname, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("Writing db to file: %s\n", fullpath);
|
||||||
|
|
||||||
|
// write the header
|
||||||
|
fwrite(db, sizeof(struct db_table), 1, fp);
|
||||||
|
|
||||||
|
// write the hashes
|
||||||
|
fwrite(db->hashes, sizeof(struct db_hash), db->count, fp);
|
||||||
|
|
||||||
|
// write the keys and values
|
||||||
|
for (i = 0; i < db->count; i++)
|
||||||
|
{
|
||||||
|
fwrite(db->hashes[i].key, sizeof(char), db->hashes[i].key_len, fp);
|
||||||
|
fwrite(db->hashes[i].value, sizeof(char), db->hashes[i].value_len, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct db_table *db_read(char *fname)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
struct db_table *db;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
if ((fp = fopen(fname, "rb")) == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
db = (struct db_table *)malloc(sizeof(struct db_table));
|
||||||
|
|
||||||
|
fread(db, sizeof(struct db_table), 1, fp);
|
||||||
|
|
||||||
|
// check the magic value
|
||||||
|
if (db->db_magic != DB_MAGIC)
|
||||||
|
{
|
||||||
|
printf("Error: %s incompatible or unknown db file format: Bad Magic\n", fname);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// check the version
|
||||||
|
if (db->db_ver != DB_VER)
|
||||||
|
{
|
||||||
|
printf("Error: %s incompatible or unknown db file format: Incompatible Version\n", fname);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = db->count != 0 ? db->count : sizeof(struct db_hash);
|
||||||
|
db->hashes = (struct db_hash *)malloc(sizeof(struct db_hash) * tmp);
|
||||||
|
|
||||||
|
fread(db->hashes, sizeof(struct db_hash), db->count, fp);
|
||||||
|
|
||||||
|
// read the keys and values
|
||||||
|
for (tmp = 0; tmp < db->count; tmp++)
|
||||||
|
{
|
||||||
|
db->hashes[tmp].key = (char *)malloc(sizeof(char) * db->hashes[tmp].key_len);
|
||||||
|
db->hashes[tmp].value = (char *)malloc(sizeof(char) * db->hashes[tmp].value_len);
|
||||||
|
|
||||||
|
fread(db->hashes[tmp].key, sizeof(char), db->hashes[tmp].key_len, fp);
|
||||||
|
fread(db->hashes[tmp].value, sizeof(char), db->hashes[tmp].value_len, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (db->hashes[i].type == DB_TYPE_CHAR)
|
||||||
|
{
|
||||||
|
free(db->hashes[i].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
db->hashes[i].value = value;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db->hashes[db->count].key_len = strlen(key) + 1;
|
||||||
|
db->hashes[db->count].key = (char *)malloc(sizeof(char) * db->hashes[db->count].key_len);
|
||||||
|
|
||||||
|
memset(db->hashes[db->count].key, 0, sizeof(char) * db->hashes[db->count].key_len);
|
||||||
|
|
||||||
|
strlcpy(db->hashes[db->count].key, key, sizeof(char) * db->hashes[db->count].key_len);
|
||||||
|
|
||||||
|
db->hashes[db->count].value = value;
|
||||||
|
|
||||||
|
db->count++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
memset(&db->hashes[db->count], 0, sizeof(struct db_hash));
|
||||||
|
|
||||||
|
db->hashes[db->count].type = DB_TYPE_CHAR;
|
||||||
|
db->hashes[db->count].value_len = strlen(value) + 1;
|
||||||
|
db->hashes[db->count].value = (char *)malloc(sizeof(char) * db->hashes[db->count].value_len);
|
||||||
|
|
||||||
|
memset(db->hashes[db->count].value, 0, sizeof(char) * db->hashes[db->count].value_len);
|
||||||
|
|
||||||
|
strlcpy(db->hashes[db->count].value, value, sizeof(char) * db->hashes[db->count].value_len);
|
||||||
|
|
||||||
|
return db_set_hash(db, key, db->hashes[db->count].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));
|
||||||
|
|
||||||
|
// zero out reallocated memory
|
||||||
|
memset(&db->hashes[db->count], 0, sizeof(struct db_hash));
|
||||||
|
|
||||||
|
db->hashes[db->count].type = DB_TYPE_INT;
|
||||||
|
db->hashes[db->count].value_len = sizeof(int);
|
||||||
|
db->hashes[db->count].value = (int *)malloc(sizeof(int));
|
||||||
|
|
||||||
|
memcpy(db->hashes[db->count].value, &value, sizeof(int));
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < db->count; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(db->hashes[i].key, key) == 0)
|
||||||
|
{
|
||||||
|
free(db->hashes[i].key);
|
||||||
|
free(db->hashes[i].value);
|
||||||
|
memmove(&db->hashes[i], &db->hashes[i + 1], sizeof(struct db_hash) * (db->count - i));
|
||||||
|
db->count--;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *db_get_hash(struct db_table *db, char *key)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < db->count; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(db->hashes[i].key, key) == 0)
|
||||||
|
{
|
||||||
|
return db->hashes[i].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int db_get_hash_type(struct db_table *db, char *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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, 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;
|
||||||
|
}
|
||||||
|
|
32
src/main.c
32
src/main.c
@ -9,8 +9,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "irc.h"
|
#include "irc.h"
|
||||||
|
#include "db.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
@ -21,6 +23,7 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static time_t trespond;
|
static time_t trespond;
|
||||||
@ -43,13 +46,40 @@ int main()
|
|||||||
last_ping.tv_sec = time(NULL);
|
last_ping.tv_sec = time(NULL);
|
||||||
|
|
||||||
set_bot(&bot);
|
set_bot(&bot);
|
||||||
|
|
||||||
init_events();
|
init_events();
|
||||||
init_timers();
|
init_timers();
|
||||||
init_mods();
|
init_mods();
|
||||||
|
|
||||||
// Read the config
|
// Read the config
|
||||||
bot = read_config(bot, "xbot.cfg");
|
bot = read_config(bot, "xbot.cfg");
|
||||||
|
|
||||||
|
// check if the db exists, if not, create it
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (access(bot.db_file, 0) == -1)
|
||||||
|
#else
|
||||||
|
if (access(bot.db_file, F_OK) == -1)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
db_write(bot.db, bot.db_file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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
|
// Connect to the server
|
||||||
printf("Connecting to %s...\n", bot.host);
|
printf("Connecting to %s...\n", bot.host);
|
||||||
|
|
||||||
|
11
src/module.c
11
src/module.c
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
struct mods *mods;
|
struct mods *mods;
|
||||||
struct irc_conn *instance;
|
struct irc_conn *instance;
|
||||||
|
struct db_table *dbinstance;
|
||||||
|
|
||||||
void init_mods()
|
void init_mods()
|
||||||
{
|
{
|
||||||
@ -315,3 +316,13 @@ void set_bot(struct irc_conn *b)
|
|||||||
{
|
{
|
||||||
instance = b;
|
instance = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_bot_db(struct db_table *db)
|
||||||
|
{
|
||||||
|
dbinstance = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
MY_API struct db_table *get_bot_db()
|
||||||
|
{
|
||||||
|
return dbinstance;
|
||||||
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "irc.h"
|
#include "util.h"
|
||||||
|
|
||||||
void eprint(char *fmt, ...)
|
void eprint(char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -30,7 +30,7 @@ void eprint(char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 38)) || defined(_WIN32)
|
#if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 38)) || defined(_WIN32)
|
||||||
MY_API void strlcpy(char *to, const char *from, int len)
|
void strlcpy(char *to, const char *from, int len)
|
||||||
{
|
{
|
||||||
memccpy(to, from, '\0', len);
|
memccpy(to, from, '\0', len);
|
||||||
to[len-1] = '\0';
|
to[len-1] = '\0';
|
||||||
@ -38,14 +38,14 @@ MY_API void strlcpy(char *to, const char *from, int len)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
MY_API char *basename(char *path)
|
char *basename(char *path)
|
||||||
{
|
{
|
||||||
char *p = strrchr(path, '\\');
|
char *p = strrchr(path, '\\');
|
||||||
return p ? p + 1 : path;
|
return p ? p + 1 : path;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MY_API char *skip(char *s, char c)
|
char *skip(char *s, char c)
|
||||||
{
|
{
|
||||||
while (*s != c && *s != '\0')
|
while (*s != c && *s != '\0')
|
||||||
{
|
{
|
||||||
|
2
xbot.cfg
2
xbot.cfg
@ -6,6 +6,8 @@ bot:
|
|||||||
nick = "xbot";
|
nick = "xbot";
|
||||||
user = "xbot";
|
user = "xbot";
|
||||||
admin = "ab3800";
|
admin = "ab3800";
|
||||||
|
|
||||||
|
db = "xbot.db";
|
||||||
};
|
};
|
||||||
|
|
||||||
server:
|
server:
|
||||||
|
@ -105,6 +105,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="lib\channel.h" />
|
<ClInclude Include="lib\channel.h" />
|
||||||
<ClInclude Include="lib\config.h" />
|
<ClInclude Include="lib\config.h" />
|
||||||
|
<ClInclude Include="lib\db.h" />
|
||||||
<ClInclude Include="lib\events.h" />
|
<ClInclude Include="lib\events.h" />
|
||||||
<ClInclude Include="lib\irc.h" />
|
<ClInclude Include="lib\irc.h" />
|
||||||
<ClInclude Include="lib\module.h" />
|
<ClInclude Include="lib\module.h" />
|
||||||
@ -114,6 +115,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\channel.c" />
|
<ClCompile Include="src\channel.c" />
|
||||||
<ClCompile Include="src\config.c" />
|
<ClCompile Include="src\config.c" />
|
||||||
|
<ClCompile Include="src\db.c" />
|
||||||
<ClCompile Include="src\events.c" />
|
<ClCompile Include="src\events.c" />
|
||||||
<ClCompile Include="src\irc.c" />
|
<ClCompile Include="src\irc.c" />
|
||||||
<ClCompile Include="src\main.c" />
|
<ClCompile Include="src\main.c" />
|
||||||
|
Loading…
Reference in New Issue
Block a user