From 3ee30bb2261ff056b7d4a5d27d5ee6714e875ac3 Mon Sep 17 00:00:00 2001 From: pk910 Date: Tue, 16 Aug 2011 23:40:25 +0200 Subject: [PATCH] added language system --- IRCParser.c | 21 +++++++++- Makefile | 1 + UserNode.c | 21 ++++++++++ UserNode.h | 18 ++++++--- bot_NeonServ.c | 4 ++ lang.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ lang.h | 30 ++++++++++++++ main.c | 3 ++ main.h | 1 + mysqlConn.c | 2 +- 10 files changed, 197 insertions(+), 8 deletions(-) create mode 100644 lang.c create mode 100644 lang.h diff --git a/IRCParser.c b/IRCParser.c index 4280866..c52659e 100644 --- a/IRCParser.c +++ b/IRCParser.c @@ -6,6 +6,7 @@ #include "IRCEvents.h" #include "ClientSocket.h" #include "WHOHandler.h" +#include "lang.h" struct irc_cmd *irc_commands = NULL; @@ -367,6 +368,24 @@ void free_parser() { } void reply(struct ClientSocket *client, struct UserNode *user, const char *text, ...) { - //following + char *reply_format = get_language_string(user, text); + if(reply_format == NULL) + reply_format = text; + if((user->flags & USERFLAG_ISAUTHED) && !(user->flags & USERFLAG_LOADED_SETTINGS)) + load_user_settings(user); + char formatBuf[MAXLEN]; + sprintf(formatBuf, "%s %s :%s", ((user->flags & USERFLAG_REPLY_PRIVMSG) ? "PRIVMSG" : "NOTICE"), user->nick, reply_format); + va_list arg_list; + char sendBuf[MAXLEN]; + int pos; + if (!(client->flags & SOCKET_FLAG_CONNECTED)) return; + sendBuf[0] = '\0'; + va_start(arg_list, formatBuf); + pos = vsnprintf(sendBuf, MAXLEN - 2, formatBuf, arg_list); + va_end(arg_list); + if (pos < 0 || pos > (MAXLEN - 2)) pos = MAXLEN - 2; + sendBuf[pos] = '\n'; + sendBuf[pos+1] = '\0'; + write_socket(client, sendBuf, pos+1); } diff --git a/Makefile b/Makefile index 2b0716e..498f79e 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ all: gcc -g -O2 ${LIBS} -c WHOHandler.c -o WHOHandler.o ${CFLAGS} gcc -g -O2 ${LIBS} -c modcmd.c -o modcmd.o ${CFLAGS} gcc -g -O2 ${LIBS} -c mysqlConn.c -o mysqlConn.o ${CFLAGS} + gcc -g -O2 ${LIBS} -c lang.c -o lang.o ${CFLAGS} gcc -g -O2 ${LIBS} -c bots.c -o bots.o ${CFLAGS} gcc -g -O2 ${LIBS} -c bot_NeonServ.c -o bot_NeonServ.o ${CFLAGS} diff --git a/UserNode.c b/UserNode.c index 3b18cbd..b2e3c7a 100644 --- a/UserNode.c +++ b/UserNode.c @@ -1,5 +1,7 @@ #include "UserNode.h" #include "ChanUser.h" +#include "mysqlConn.h" +#include "lang.h" static struct UserNode **userList; @@ -260,3 +262,22 @@ void clearTempUsers() { last_user = cuser; } } + + +void load_user_settings(struct UserNode *user) { + if(!(user->flags & USERFLAG_ISAUTHED) || (user->flags & USERFLAG_LOADED_SETTINGS)) + return; + check_mysql(); + MYSQL_RES *res; + MYSQL_ROW row; + printf_mysql_query("SELECT `user_lang`, `user_reply_privmsg` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth)); + res = mysql_use(); + if ((row = mysql_fetch_row(res)) != NULL) { + user->language = get_language_by_tag(row[0]); + if(user->language == NULL) user->language = get_default_language(); + if(strcmp(row[1], "0")) + user->flags |= USERFLAG_REPLY_PRIVMSG; + } else + user->language = lang_c; + user->flags |= USERFLAG_LOADED_SETTINGS +} diff --git a/UserNode.h b/UserNode.h index c96f9a1..3402c7d 100644 --- a/UserNode.h +++ b/UserNode.h @@ -2,14 +2,17 @@ #define _UserNode_h #include "main.h" -#define USERFLAG_ISBOT 0x0001 -#define USERFLAG_ISAUTHED 0x0002 -#define USERFLAG_ISIRCOP 0x0004 -#define USERFLAG_ISTMPUSER 0x0008 -#define USERFLAG_ISSERVER 0x0010 -#define USERFLAG_FREETMPUSER 0x0020 +#define USERFLAG_ISBOT 0x0001 +#define USERFLAG_ISAUTHED 0x0002 +#define USERFLAG_ISIRCOP 0x0004 +#define USERFLAG_ISTMPUSER 0x0008 +#define USERFLAG_ISSERVER 0x0010 +#define USERFLAG_FREETMPUSER 0x0020 +#define USERFLAG_LOADED_SETTINGS 0x0040 +#define USERFLAG_REPLY_PRIVMSG 0x0080 struct ChanUser; +struct language; struct UserNode { char nick[NICKLEN+1]; @@ -20,6 +23,7 @@ struct UserNode { unsigned int flags; time_t created; struct ChanUser *channel; + struct language *language; struct UserNode *next; }; @@ -37,4 +41,6 @@ int renameUser(struct UserNode* user, const char *new_nick); void delUser(struct UserNode* user, int freeUser); void clearTempUsers(); +void load_user_settings(struct UserNode* user); + #endif diff --git a/bot_NeonServ.c b/bot_NeonServ.c index a466c57..9c3b004 100644 --- a/bot_NeonServ.c +++ b/bot_NeonServ.c @@ -11,6 +11,10 @@ #define BOTID 1 #define CLASSNAME "NeonServ" +static const struct default_language_entry msgtab[] = { + +}; + static CMD_BIND(neonserv_cmd_users) { struct ChanUser *chanuser; putsock(client, "PRIVMSG %s :[BOT JOIN] Users on this Channel:", chan->name); diff --git a/lang.c b/lang.c new file mode 100644 index 0000000..f2880bc --- /dev/null +++ b/lang.c @@ -0,0 +1,104 @@ +#include "lang.h" +#include "UserNode.h" + +#define DEFAULT_LANG_TAG "EN" +#define DEFAULT_LANG_NAME "English" + +static struct language **langdict; +static struct language *lang_c; + +void init_lang() { + langdict = calloc(MAXLANGUAGES, sizeof(*langdict)); +} + +void free_lang() { + +} + +static struct language* add_language(char *langtag, char *langname) { + int index; + for(index = 0; index < MAXLANGUAGES; index++) { + if(langdict[index] == NULL) break; + if(!strcmp(langdict[index]->langname, langname) || !strcmp(langdict[index]->langtag, langtag)) + return langdict[index]; + } + if(index == MAXLANGUAGES) return NULL; + struct language *lang = malloc(sizeof(*lang)); + if (!lang) { + perror("malloc() failed"); + return NULL; + } + lang->langtag = strdup(langtag); + lang->langname = strdup(langname); + struct language_table **entrys = calloc(27, sizeof(*entrys)); + lang->entrys = entrys; + return lang; +} + +static int get_entry_index(const char *ident) { + const char *underscore = strstr(ident, "_"); + if(!underscore || !(underscore[1] >= 65 && underscore[1] <= 90)) return 26; + return (underscore[1] - 'A'); +} + +struct language* get_language_by_tag(char *tag) { + int index; + for(index = 0; index < MAXLANGUAGES; index++) { + if(langdict[index] == NULL) break; + if(!strcmp(langdict[index]->langtag, tag)) + return langdict[index]; + } + return NULL; +} + +struct language* get_language_by_name(char *name) { + int index; + for(index = 0; index < MAXLANGUAGES; index++) { + if(langdict[index] == NULL) break; + if(!strcmp(langdict[index]->langname, name)) + return langdict[index]; + } + return NULL; +} + +struct language* get_default_language() { + if(lang_c == NULL) + lang_c = add_language(DEFAULT_LANG_TAG, DEFAULT_LANG_NAME); + return lang_c; +} + +void register_default_language_table(const struct default_language_entry *msgtab) { + if(lang_c == NULL) + lang_c = add_language(DEFAULT_LANG_TAG, DEFAULT_LANG_NAME); + struct language_table *lang_entry; + int index; + while(msgtab->ident) { + index = get_entry_index(msgtab->ident); + lang_entry = malloc(sizeof(*lang_entry)); + if (!lang_entry) { + perror("malloc() failed"); + return; + } + lang_entry->ident = strdup(msgtab->ident); + lang_entry->text = strdup(msgtab->text); + lang_entry->next = lang_c->entrys[index]; + lang_c->entrys[index] = lang_entry; + msgtab++; + } +} + +char *get_language_string(struct UserNode *user, char* msg_ident) { + struct language* lang; + if((user->flags & USERFLAG_ISAUTHED)) { + if(!(user->flags & USERFLAG_LOADED_SETTINGS)) + load_user_settings(user); + lang = user->language; + } else + lang = lang_c; + int index = get_entry_index(msg_ident); + struct language_table* entry; + for(entry = lang->entrys[index]; entry; entry = entry->next) { + if(!strcmp(entry->ident, msg_ident)) + return entry->text; + } +} diff --git a/lang.h b/lang.h new file mode 100644 index 0000000..68961d3 --- /dev/null +++ b/lang.h @@ -0,0 +1,30 @@ +#ifndef _lang_h +#define _lang_h + +struct UserNode; + +struct default_language_entry { + char *ident; + char *text; +}; + +struct language_table { + char *ident; + char *text; + + struct language_table *next; +}; + +struct language { + char *langtag; + char *langname; + struct language_table **entrys; +}; + +struct language* get_language_by_tag(char *tag); +struct language* get_language_by_name(char *name); +struct language* get_default_language(); +void register_default_language_table(const struct default_language_entry **msgtab); +char *get_language_string(struct UserNode *user, char* msg_ident); + +#endif \ No newline at end of file diff --git a/main.c b/main.c index 0870d96..4127e33 100644 --- a/main.c +++ b/main.c @@ -9,6 +9,7 @@ #include "WHOHandler.h" #include "bots.h" #include "mysqlConn.h" +#include "lang.h" void cleanup() { free_sockets(); @@ -19,6 +20,7 @@ void cleanup() { free_modcmd(); free_whoqueue(); free_bots(); + free_lang(); free_mysql(); } @@ -30,6 +32,7 @@ int main(void) init_ChanNode(); init_bind(); init_modcmd(); + init_lang(); init_bots(); time_t socket_wait; diff --git a/main.h b/main.h index c154da3..9286185 100644 --- a/main.h +++ b/main.h @@ -43,6 +43,7 @@ #define MAXLEN 512 #define TRIGGERLEN 50 #define MAXNUMPARAMS 200 /* maximum number of parameters in one line */ +#define MAXLANGUAGES 5 //valid nick chars #define VALID_NICK_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890{|}~[\\]^_`" diff --git a/mysqlConn.c b/mysqlConn.c index cafda66..81fa038 100644 --- a/mysqlConn.c +++ b/mysqlConn.c @@ -22,7 +22,7 @@ void check_mysql() { } MYSQL_RES *mysql_use() { - MYSQL_RES *res = mysql_use_result(mysql_conn); + MYSQL_RES *res = mysql_store_result(mysql_conn); struct used_result *result = malloc(sizeof(*result)); if (!result) { mysql_free_result(res); -- 2.20.1