diff --git a/Makefile b/Makefile index 91b221c..9b33d77 100755 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ main: $(CC) $(CFLAGS) $(SRC)/events.c -o $(OBJ)/events.o $(CC) $(CFLAGS) $(SRC)/module.c -o $(OBJ)/module.o $(CC) $(CFLAGS) $(SRC)/channel.c -o $(OBJ)/channel.o + $(CC) $(CFLAGS) $(SRC)/timers.c -o $(OBJ)/timers.o $(CC) -o $(EXEC) $(OBJECTS) $(BINFLAGS) @echo "All Done!" diff --git a/lib/events.h b/lib/events.h index 44bf486..1e9df58 100755 --- a/lib/events.h +++ b/lib/events.h @@ -19,6 +19,7 @@ #define IRC_END_MOTD "376" #define IRC_NAMREPLY "353" #define IRC_WHOREPLY "352" +#define TICK "TICK" struct ev_handler { diff --git a/lib/timers.h b/lib/timers.h new file mode 100755 index 0000000..60288d2 --- /dev/null +++ b/lib/timers.h @@ -0,0 +1,56 @@ +#ifndef TIMERS_H +#define TIMERS_H + +#include "irc.h" +#include "util.h" +#include +#ifdef _WIN32 +#include +#else +#include +#endif + +struct timer +{ + int id; + char name[50]; + int interval; + int repeat; + int repeat_count; + +#ifdef _WIN32 + BOOL active; +#else + bool active; +#endif + + time_t next_run; + struct irc_conn *bot; + + void *handler; + void *data; +}; + +struct timers +{ + int count; + struct timer *timers; +}; + +void init_timers(); + +MY_API int add_timer(struct irc_conn *bot, int interval, int repeat, void *handler, void *data); +MY_API void set_timer_name(int id, char *name); +MY_API int get_timer_repeat(int id); +MY_API void del_timer(int id); + +#ifdef _WIN32 +MY_API BOOL active_timers(); +#else +MY_API bool active_timers(); +#endif + +void add_to_delete_queue(int id); +void fire_timers(); + +#endif diff --git a/mods/hello/hello.c b/mods/hello/hello.c index dbbf4f9..5f09ea1 100755 --- a/mods/hello/hello.c +++ b/mods/hello/hello.c @@ -1,27 +1,61 @@ #define MY_DLL_EXPORTS 1 +#include "util.h" #include "irc.h" #include "events.h" #include "module.h" +#include "timers.h" #include #include #include +struct said_hi +{ + int timer_id; + int repeat; + + char user[50]; + char host[150]; + char chan[70]; +}; + +MY_API void said_h(struct irc_conn *bot, void *data) +{ + struct said_hi *hi = (struct said_hi *)data; + + irc_privmsg(bot, hi->chan, "[timer %d] %d : %s", hi->timer_id, get_timer_repeat(hi->timer_id), hi->user); + + if ((get_timer_repeat(hi->timer_id) + 1) > hi->repeat) + { + free(hi); + } +} + MY_API void hello(struct irc_conn *bot, char *user, char *host, char *chan, const char *text) { + struct said_hi *hi; + char *buf = (char *)malloc(sizeof(char *) * 500); sprintf(buf, "hi %s", bot->nick); if (!strcmp(text, buf)) { - irc_privmsg(bot, chan, "hi %s", user); + hi = calloc(1, sizeof(struct said_hi)); - printf("%s said hi to me\n", user); + irc_privmsg(bot, chan, "hi %s", user); + + sprintf(hi->user, "%s", user); + sprintf(hi->host, "%s", host); + sprintf(hi->chan, "%s", chan); + + hi->repeat = 3; + hi->timer_id = add_timer(bot, 10, hi->repeat, said_h, hi); } free(buf); } + MY_API void hello_join(struct irc_conn *bot, char *user, char *host, char *chan) { printf("%s!%s joined %s\n", user, host, chan); diff --git a/mods/uptime/uptime.c b/mods/uptime/uptime.c index c1d149a..784c032 100755 --- a/mods/uptime/uptime.c +++ b/mods/uptime/uptime.c @@ -13,15 +13,18 @@ DWORD startTick; void parseUptime(const char *output, struct irc_conn *bot, const char *where) { - // Variable definitions moved to the top const char *keyword = "Statistics since "; const char *uptime_start; int month, day, year, hour, minute; SYSTEMTIME uptime_systemtime, current_time; ULONGLONG uptime_ticks, current_ticks; ULONGLONG uptime_seconds; + char buf[BUFFER_SIZE]; int days, hours, minutes; + OSVERSIONINFOEX osInfo; + ZeroMemory(&osInfo, sizeof(OSVERSIONINFOEX)); + osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); uptime_start = strstr(output, keyword); if (uptime_start == NULL) { @@ -58,12 +61,50 @@ void parseUptime(const char *output, struct irc_conn *bot, const char *where) { uptime_seconds = (current_ticks - uptime_ticks) / 10000000UL; // Convert to seconds - uptime_seconds -= 1320; + uptime_seconds -= 1470; days = uptime_seconds / (24 * 3600); hours = (uptime_seconds % (24 * 3600)) / 3600; minutes = (uptime_seconds % 3600) / 60; - irc_privmsg(bot, where, "Uptime: %d days, %d hours, %d minutes\n", days, hours, minutes); + + if (GetVersionEx((OSVERSIONINFO*)&osInfo)) { + if (osInfo.dwMajorVersion == 10 && osInfo.dwMinorVersion == 0) { + sprintf(buf, "Windows 10"); + } else if (osInfo.dwMajorVersion == 6 && osInfo.dwMinorVersion == 3) { + sprintf(buf, "Windows 8.1"); + } else if (osInfo.dwMajorVersion == 6 && osInfo.dwMinorVersion == 2) { + sprintf(buf, "Windows 8"); + } else if (osInfo.dwMajorVersion == 6 && osInfo.dwMinorVersion == 1) { + // detect Windows 7 or Windows Server 2008 R2 + if (osInfo.wProductType == VER_NT_WORKSTATION) { + sprintf(buf, "Windows 7"); + } else { + sprintf(buf, "Windows Server 2008 R2"); + } + } else if (osInfo.dwMajorVersion == 6 && osInfo.dwMinorVersion == 0) { + // detect Windows Vista or Windows Server 2008 + + if (osInfo.wProductType == VER_NT_WORKSTATION) { + sprintf(buf, "Windows Vista"); + } else { + sprintf(buf, "Windows Server 2008"); + } + } else if (osInfo.dwMajorVersion == 5 && osInfo.dwMinorVersion == 1) { + // detect Windows XP or Windows Server 2003 + + if (osInfo.wProductType == VER_NT_WORKSTATION) { + sprintf(buf, "Windows XP"); + } else { + sprintf(buf, "Windows Server 2003"); + } + } else if (osInfo.dwMajorVersion == 5 && osInfo.dwMinorVersion == 0) { + sprintf(buf, "Windows 2000"); + } else { + sprintf(buf, "Windows"); + } + } + + irc_privmsg(bot, where, "%s: %d days, %d hours, and %d minutes up\n", buf, days, hours, minutes); } char *executeCommand(const char *command) @@ -111,8 +152,6 @@ MY_API void up(struct irc_conn *bot, char *user, char *host, char *chan, char *t char buf[100]; FILE* file; - printf("dbug up called: %s!%s %s\n", user, host, text); - if (!strcmp(text, "!uptime")) { file = popen("uptime", "r"); diff --git a/src/events.c b/src/events.c index e68e2ff..745dc4e 100755 --- a/src/events.c +++ b/src/events.c @@ -31,6 +31,7 @@ void init_event_type(char *type) void init_events() { + init_event_type(TICK); init_event_type(PRIVMSG_SELF); init_event_type(PRIVMSG_CHAN); init_event_type(JOIN); @@ -136,7 +137,7 @@ void fire_handler(struct irc_conn *bot, char *type, ...) irc_notice(bot, usr, "You are unauthorized to use this command."); } } - else if (!strcmp("PRINT_HANDLERS", cmd)) + else if (!strcmp("HANDLERS", cmd)) { if (!strcmp(bot->admin, usr)) { diff --git a/src/main.c b/src/main.c index 82c3cf5..762b439 100755 --- a/src/main.c +++ b/src/main.c @@ -15,6 +15,7 @@ #include "events.h" #include "module.h" #include "channel.h" +#include "timers.h" #ifdef _WIN32 #include @@ -32,11 +33,18 @@ int main() struct irc_conn bot; struct timeval tv; + struct timeval last_ping; + + + char *p; int bytesRecv; + + last_ping.tv_sec = time(NULL); init_events(); + init_timers(); init_mods(); // Read the config @@ -50,6 +58,9 @@ int main() for (;;) { + fire_timers(); + fire_handler(&bot, TICK, NULL); + FD_ZERO(&rd); #ifdef _WIN32 @@ -58,7 +69,7 @@ int main() FD_SET(0, &rd); FD_SET(fileno(bot.srv_fd), &rd); #endif - tv.tv_sec = 120; + tv.tv_sec = 1; tv.tv_usec = 0; #ifdef _WIN32 @@ -90,7 +101,12 @@ int main() return -1; } - irc_raw(&bot, "PING %s", bot.host); + if (time(NULL) - last_ping.tv_sec >= 120) + { + last_ping.tv_sec = time(NULL); + irc_raw(&bot, "PING %s", bot.host); + } + continue; } #ifdef _WIN32 @@ -145,6 +161,7 @@ int main() #endif trespond = time(NULL); } + } return 0; diff --git a/src/module.c b/src/module.c index 6e174e3..c1fdae7 100755 --- a/src/module.c +++ b/src/module.c @@ -23,14 +23,17 @@ void init_mods() void load_module(struct irc_conn *bot, char *where, char *stype, char *file) { + char *error = (char *)malloc(sizeof(char *)*1024); - strlcpy(mods->modules[mods->count].fname, file, 256); #ifdef _WIN32 + DWORD err; + strlcpy(mods->modules[mods->count].fname, file, 256); mods->modules[mods->count].handle = LoadLibrary(file); if (mods->modules[mods->count].handle == NULL) { - sprintf(error, "Error loading %s\n", file); + err = GetLastError(); + sprintf(error, "Error loading %s: %lu", file, err); if (strcmp("runtime", stype)) { @@ -39,7 +42,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } else if (strcmp(PRIVMSG_CHAN, stype)) { - irc_privmsg(bot, where, error); + irc_notice(bot, where, error); } else { @@ -63,7 +66,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } else if (strcmp(PRIVMSG_CHAN, stype)) { - irc_privmsg(bot, where, error); + irc_notice(bot, where, error); } else { @@ -89,7 +92,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } else if (strcmp(PRIVMSG_CHAN, stype)) { - irc_privmsg(bot, where, error); + irc_notice(bot, where, error); } else { @@ -101,7 +104,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) if (strcmp("runtime", stype)) { - irc_privmsg(bot, where, "Module '%s' loaded.", file); + irc_notice(bot, where, "Module '%s' loaded.", file); } else { @@ -111,6 +114,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) #else void (*mod_init)(); + strlcpy(mods->modules[mods->count].fname, file, 256); mods->modules[mods->count].handle = dlopen(file, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); if (!mods->modules[mods->count].handle) { @@ -123,7 +127,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } else if (strcmp(PRIVMSG_CHAN, stype)) { - irc_privmsg(bot, where, error); + irc_notice(bot, where, error); } else { @@ -148,7 +152,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } else if (strcmp(PRIVMSG_CHAN, stype)) { - irc_privmsg(bot, where, error); + irc_notice(bot, where, error); } else { @@ -170,7 +174,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } else if (strcmp(PRIVMSG_CHAN, stype)) { - irc_privmsg(bot, where, error); + irc_notice(bot, where, error); } else { @@ -189,7 +193,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } else if (strcmp(PRIVMSG_CHAN, stype)) { - irc_privmsg(bot, where, error); + irc_notice(bot, where, error); } else { @@ -200,7 +204,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) if (strcmp("runtime", stype)) { - irc_privmsg(bot, where, "Module '%s' loaded.", file); + irc_notice(bot, where, "Module '%s' loaded.", file); } else { @@ -229,7 +233,7 @@ void unload_module(struct irc_conn *bot, char *where, char *file) if (strcmp(PRIVMSG_CHAN, where)) { - irc_privmsg(bot, where, "Module '%s' unloaded.", file); + irc_notice(bot, where, "Module '%s' unloaded.", file); } else { @@ -242,6 +246,8 @@ void unload_module(struct irc_conn *bot, char *where, char *file) i++; } + mods->count--; + return; } } diff --git a/src/timers.c b/src/timers.c new file mode 100755 index 0000000..d26aebe --- /dev/null +++ b/src/timers.c @@ -0,0 +1,136 @@ +#include +#include +#include + +#include "timers.h" +#include "util.h" +#include "irc.h" + +struct timers *timers;; +int delete_queue[512]; + +void init_timers() +{ + timers = calloc(1, sizeof(struct timers)); + + timers->count = 1; + timers->timers = calloc(512, sizeof(struct timer)); +} + +MY_API int add_timer(struct irc_conn *bot, int interval, int repeat, void *handler, void *data) +{ + timers->timers[timers->count].interval = interval; + timers->timers[timers->count].handler = handler; + timers->timers[timers->count].id = timers->count; + timers->timers[timers->count].bot = bot; + timers->timers[timers->count].repeat = repeat; + timers->timers[timers->count].repeat_count = 0; + timers->timers[timers->count].data = data; + timers->timers[timers->count].active = true; + timers->timers[timers->count].next_run = time(NULL) + interval; + timers->count++; + + return timers->count - 1; +} + +MY_API void set_timer_name(int id, char *name) +{ + sprintf(timers->timers[id].name, "%s", name); +} + +MY_API int get_timer_repeat(int id) +{ + return timers->timers[id].repeat_count; +} + +#ifdef _WIN32 +MY_API BOOL active_timers() +#else +MY_API bool active_timers() +#endif +{ + int i; + + for (i = 0; i < timers->count; i++) + { + if (timers->timers[i].active) + { + return true; + } + } + + return false; +} + +void add_to_delete_queue(int id) +{ + int i; + + for (i = 0; i < 512; i++) + { + if (delete_queue[i] == 0) + { + delete_queue[i] = id; + break; + } + } +} + +MY_API void del_timer(int id) +{ + int i; + + for (i = 0; i < timers->count; i++) + { + if (timers->timers[i].id == id) + { + while (i < timers->count) + { + timers->timers[i] = timers->timers[i + 1]; + i++; + } + + timers->count--; + } + } +} + +void fire_timers() +{ + int i; + void (*handler)(); + + for (i = 0; i < timers->count; i++) + { + if (timers->timers[i].next_run <= time(NULL)) + { + timers->timers[i].next_run = time(NULL) + timers->timers[i].interval; + handler = timers->timers[i].handler; + + if (timers->timers[i].active) + (*handler)(timers->timers[i].bot, timers->timers[i].data); + + if (timers->timers[i].repeat > 0) + { + timers->timers[i].repeat_count++; + if (timers->timers[i].repeat_count >= timers->timers[i].repeat) + { + timers->timers[i].active = false; + add_to_delete_queue(timers->timers[i].id); + } + } + } + } + + if (active_timers() == false) + { + for (i = 0; i < 512; i++) + { + if (delete_queue[i] != 0) + { + del_timer(delete_queue[i]); + delete_queue[i] = 0; + } + } + } +} diff --git a/xbot.sln b/xbot.sln index d68fe82..7f0f1bb 100755 --- a/xbot.sln +++ b/xbot.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xbot", "xbot.vcxproj", "{F9EBC08A-C550-413C-8CC6-81A232859D94}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xbot-mods", "xbot-mods\xbot-mods.vcxproj", "{BB6BFF6F-3972-4F0D-86E9-06FF4EAC5C5A}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -15,10 +13,6 @@ Global {F9EBC08A-C550-413C-8CC6-81A232859D94}.Debug|Win32.Build.0 = Debug|Win32 {F9EBC08A-C550-413C-8CC6-81A232859D94}.Release|Win32.ActiveCfg = Release|Win32 {F9EBC08A-C550-413C-8CC6-81A232859D94}.Release|Win32.Build.0 = Release|Win32 - {BB6BFF6F-3972-4F0D-86E9-06FF4EAC5C5A}.Debug|Win32.ActiveCfg = Debug|Win32 - {BB6BFF6F-3972-4F0D-86E9-06FF4EAC5C5A}.Debug|Win32.Build.0 = Debug|Win32 - {BB6BFF6F-3972-4F0D-86E9-06FF4EAC5C5A}.Release|Win32.ActiveCfg = Release|Win32 - {BB6BFF6F-3972-4F0D-86E9-06FF4EAC5C5A}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/xbot.vcxproj b/xbot.vcxproj index d909a22..a628870 100755 --- a/xbot.vcxproj +++ b/xbot.vcxproj @@ -45,7 +45,7 @@ <_ProjectFileVersion>10.0.30319.1 Debug\ Debug\ - true + false Release\ Release\ true @@ -108,6 +108,7 @@ + @@ -117,6 +118,7 @@ +