added language system
authorpk910 <philipp@zoelle1.de>
Tue, 16 Aug 2011 21:40:25 +0000 (23:40 +0200)
committerpk910 <philipp@zoelle1.de>
Tue, 16 Aug 2011 21:40:25 +0000 (23:40 +0200)
IRCParser.c
Makefile
UserNode.c
UserNode.h
bot_NeonServ.c
lang.c [new file with mode: 0644]
lang.h [new file with mode: 0644]
main.c
main.h
mysqlConn.c

index 4280866facdfd06475c12fa5bf92d358063b3c65..c52659ed21f3c795511d429d3e221a19449193a9 100644 (file)
@@ -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);
 }
 
index 2b0716e68badbafe720593adc61fa948cfdefe3d..498f79ef2291098efc0593849d957293f2a68a66 100644 (file)
--- 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}
 
index 3b18cbd0e1c55d7ef254790b2576ce3a4257d166..b2e3c7aedcb82cceb1898b56d1473f51fcb2799d 100644 (file)
@@ -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
+}
index c96f9a128d7bdd77715ef98bd8e43864784086d4..3402c7d97ac1e0eb5afbe4c380687367ab1c7605 100644 (file)
@@ -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
index a466c57634edc8268499b8f399d2829b09a38b72..9c3b004511e1ae6287c4b736b579895dae150ae1 100644 (file)
 #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 (file)
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 (file)
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 0870d968c321b81ec688dfecd13adb37d4a49903..4127e3313503f6d5620a497aa80052366293689f 100644 (file)
--- 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 c154da3014f4f9661a9ea4419c7d8101c803f3ce..92861853f784cadb9cd055e488f952f93fe585bc 100644 (file)
--- 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{|}~[\\]^_`"
index cafda6641123a3888253987f599d78c75e0fa30b..81fa038cbbc3af2086ea15e5f11d4c121b005cc8 100644 (file)
@@ -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);