extern int account_set_ladder_rank(t_account * account, char const * clienttag, t_ladder_id id, unsigned int rank) { char key[256]; unsigned int oldrank; int retval=0; if (!clienttag || strlen(clienttag)!=4) { eventlog(eventlog_level_error,"account_set_ladder_rank","got bad clienttag"); return -1; } if (rank==0) eventlog(eventlog_level_warn,"account_set_ladder_rank","setting rank to zero?"); sprintf(key,"Record\\%s\\%d\\rank",clienttag,(int)id); if (account_set_numattr(account,key,rank)<0) retval = -1; oldrank = account_get_ladder_high_rank(account,clienttag,id); if (oldrank==0 || rank<oldrank) { sprintf(key,"Record\\%s\\%d\\high rank",clienttag,(int)id); if (account_set_numattr(account,key,rank)<0) retval = -1; } return retval; }
extern int account_adjust_ladder_rating(t_account * account, char const * clienttag, t_ladder_id id, int delta) { char key[256]; unsigned int oldrating; unsigned int newrating; int retval=0; if (!clienttag || strlen(clienttag)!=4) { eventlog(eventlog_level_error,"account_adjust_ladder_rating","got bad clienttag"); return -1; } sprintf(key,"Record\\%s\\%d\\rating",clienttag,(int)id); /* don't allow rating to go below 1 */ oldrating = account_get_ladder_rating(account,clienttag,id); if (delta<0 && oldrating<=(unsigned int)-delta) newrating = 1; else newrating = oldrating+delta; if (account_set_numattr(account,key,newrating)<0) retval = -1; if (newrating>account_get_ladder_high_rating(account,clienttag,id)) { sprintf(key,"Record\\%s\\%d\\high rating",clienttag,(int)id); if (account_set_numattr(account,key,newrating)<0) retval = -1; } return retval; }
extern int account_inc_normal_disconnects(t_account * account, char const * clienttag) { char key[256]; if (!clienttag || strlen(clienttag)!=4) { eventlog(eventlog_level_error,"account_inc_normal_disconnects","got bad clienttag"); return -1; } sprintf(key,"Record\\%s\\0\\disconnects",clienttag); return account_set_numattr(account,key,account_get_normal_disconnects(account,clienttag)+1); }
extern int account_set_normal_level(t_account * account, char const * clienttag, unsigned int level) { char key[256]; if (!clienttag || strlen(clienttag)!=4) { eventlog(eventlog_level_error,"account_set_normal_level","got bad clienttag"); return -1; } sprintf(key,"BNET\\Record\\%s\\0\\level",clienttag); return account_set_numattr(account,key,level); }
extern int account_inc_ladder_draws(t_account * account, char const * clienttag, t_ladder_id id) { char key[256]; if (!clienttag || strlen(clienttag)!=4) { eventlog(eventlog_level_error,"account_inc_ladder_draws","got bad clienttag"); return -1; } sprintf(key,"Record\\%s\\%d\\draws",clienttag,(int)id); return account_set_numattr(account,key,account_get_ladder_draws(account,clienttag,id)+1); }
extern int account_set_ladder_active_rank(t_account * account, char const * clienttag, t_ladder_id id, unsigned int rank) { char key[256]; if (!clienttag || strlen(clienttag)!=4) { eventlog(eventlog_level_error,"account_set_ladder_active_rank","got bad clienttag"); return -1; } sprintf(key,"Record\\%s\\%d\\active rank",clienttag,(int)id); return account_set_numattr(account,key,rank); }
extern t_account * create_vaccount(const char *username, unsigned int uid) { /* this is a modified(?) version of account_create */ t_account * account; account = malloc(sizeof(t_account)); if (!account) { eventlog(eventlog_level_error,"create_vaccount","could not allocate memory for account"); return NULL; } account->attrs = NULL; account->age = 0; CLEAR_FLAGS(account); account->namehash = 0; /* hash it later */ account->uid = 0; account->filename = NULL; /* there is no local account file */ account->bits_state = account_state_unknown; if (username) { if (username[0]!='#') { if (strchr(username,' ')) { eventlog(eventlog_level_error,"create_vaccount","username contains spaces"); account_destroy(account); return NULL; } if (strlen(username)>=MAX_USER_NAME) { eventlog(eventlog_level_error,"create_vaccount","username \"%s\" is too long (%u chars)",username,strlen(username)); account_destroy(account); return NULL; } account_set_strattr(account,"BNET\\acct\\username",username); account->namehash = account_hash(username); } else { if (str_to_uint(&username[1],&account->uid)<0) { eventlog(eventlog_level_warn,"create_vaccount","invalid username \"%s\"",username); } } } account_set_numattr(account,"BNET\\acct\\userid",account->uid); return account; }
static t_account * account_create3(char const * username, char const * passhash1, char const * email) { t_account * account; if (username && !passhash1) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL passhash1"); return NULL; } if (username && account_check_name(username)) { eventlog(eventlog_level_error,__FUNCTION__,"got invalid chars in username"); return NULL; } account = xmalloc(sizeof(t_account)); account->name = NULL; account->clanmember = NULL; account->attrgroup = NULL; account->friends = NULL; account->teams = NULL; account->conn = NULL; FLAG_ZERO(&account->flags); account->namehash = 0; /* hash it later before inserting */ account->uid = 0; /* hash it later before inserting */ if (username) { /* actually making a new account */ /* first check if such a username already owns an account. * we search in the memory hash mainly for non-indexed storage types. * indexed storage types check themselves if the username exists already * in the storage (see storage_sql.c) */ if (accountlist_find_account(username)) { eventlog(eventlog_level_debug,__FUNCTION__,"user \"%s\" already has an account",username); goto err; } account->attrgroup = attrgroup_create_newuser(username); if(!account->attrgroup) { eventlog(eventlog_level_error,__FUNCTION__,"failed to add user"); goto err; } account->name = xstrdup(username); if (account_set_strattr(account,"BNET\\acct\\username",username)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not set username"); goto err; } if (account_set_numattr(account,"BNET\\acct\\userid",maxuserid+1)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not set userid"); goto err; } if (account_set_strattr(account,"BNET\\acct\\passhash1",passhash1)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not set passhash1"); goto err; } if (account_set_numattr(account,"BNET\\acct\\ctime",(unsigned int)now)) { eventlog(eventlog_level_error,__FUNCTION__,"could not set ctime"); goto err; } if (account_set_strattr(account,"BNET\\acct\\email",email)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not set email"); goto err; } if (account_set_numattr(account,"BNET\\auth\\vip_expire",(unsigned int)now+prefs_get_vip_experience())) { eventlog(eventlog_level_error,__FUNCTION__,"could not set vip_expire"); goto err; } } return account; err: account_destroy(account); return NULL; }
/* Set account attribute value * (Return 0 if attribute is not set, and 1 if set) */ extern int __account_set_attr(lua_State* L) { const char *username, *attrkey; int attrtype; std::map<std::string, std::string> o_account; int result = 0; try { lua::stack st(L); // get args st.at(1, username); st.at(2, attrkey); st.at(3, attrtype); if (t_account *account = accountlist_find_account(username)) { switch ((t_attr_type)attrtype) { case attr_type_str: const char * strvalue; st.at(4, strvalue); if (account_set_strattr(account, attrkey, strvalue) >= 0) result = 1; break; case attr_type_num: int numvalue; st.at(4, numvalue); if (account_set_numattr(account, attrkey, numvalue) >= 0) result = 1; break; case attr_type_bool: bool boolvalue; st.at(4, boolvalue); if (account_set_boolattr(account, attrkey, boolvalue ? 1 : 0) >= 0) result = 1; break; case attr_type_raw: const char * rawvalue; int length; st.at(4, rawvalue); st.at(5, length); if (account_set_rawattr(account, attrkey, rawvalue, length) >= 0) result = 1; break; } } st.push(result); } catch (const std::exception& e) { eventlog(eventlog_level_error, __FUNCTION__, e.what()); } catch (...) { eventlog(eventlog_level_error, __FUNCTION__, "lua exception\n"); } return 1; }
extern int account_set_ll_connection(t_account * account, unsigned int connection) { return account_set_numattr(account,"BNET\\acct\\lastlogin_connection",connection); }
extern int account_set_ll_time(t_account * account, unsigned int t) { return account_set_numattr(account,"BNET\\acct\\lastlogin_time",t); }
extern t_account * account_create(char const * username, char const * passhash1) { t_account * account; if (username && account_check_name(username)<0) { eventlog(eventlog_level_error,"account_create","got bad account name"); return NULL; } if (!(account = malloc(sizeof(t_account)))) { eventlog(eventlog_level_error,"account_create","could not allocate memory for account"); return NULL; } account->filename = NULL; account->attrs = NULL; account->age = 0; CLEAR_FLAGS(account); account->namehash = 0; /* hash it later before inserting */ #ifndef ACCT_DYN_LOAD account->uid = 0; #endif /* !ACCT_DYN_LOAD */ #ifdef ACCT_DYN_UNLOAD account->ref = 0; #endif /* ACCT_DYN_UNLOAD */ if (username) /* actually making a new account */ { char * temp; if (account_check_name(username)<0) { eventlog(eventlog_level_error,"account_create","invalid account name \"%s\"",username); account_destroy(account); return NULL; } if (!passhash1) { eventlog(eventlog_level_error,"account_create","got NULL passhash1"); account_destroy(account); return NULL; } #ifdef WITH_STORAGE_DB /* In DB (MySQL) storage i always use the real login name as id */ if (!(temp = malloc(strlen(username)+1))) /* name + NUL */ { eventlog(eventlog_level_error,"account_create","could not allocate memory for temp"); account_destroy(account); return NULL; } sprintf(temp,"%s",username); #else # ifndef ACCT_DYN_LOAD if (prefs_get_savebyname()==0) { if (!(temp = malloc(strlen(prefs_get_userdir())+1+8+1))) /* dir + / + uid + NUL */ { eventlog(eventlog_level_error,"account_create","could not allocate memory for temp"); account_destroy(account); return NULL; } sprintf(temp,"%s/%06u",prefs_get_userdir(),maxuserid+1); /* FIXME: hmm, maybe up the %06 to %08... */ } else # endif /* ! ACCT_DYN_LOAD */ { char const * safename; char * filename; if (!(filename = strdup(username))) { eventlog(eventlog_level_error,"account_create","could not allocate memory for filename"); account_destroy(account); return NULL; } str_to_lower(filename); if (!(safename = escape_fs_chars(filename,strlen(filename)))) { eventlog(eventlog_level_error,"account_create","could not escape username"); account_destroy(account); free(filename); return NULL; } free(filename); if (!(temp = malloc(strlen(prefs_get_userdir())+1+strlen(safename)+1))) /* dir + / + name + NUL */ { eventlog(eventlog_level_error,"account_create","could not allocate memory for temp"); account_destroy(account); return NULL; } sprintf(temp,"%s/%s",prefs_get_userdir(),safename); free((void *)safename); /* avoid warning */ } #endif /* WITH_DB_STORAGE */ account->filename = temp; SET_FLAG(account,account_flag_loaded); if (account_set_strattr(account,"BNET\\acct\\username",username)<0) { eventlog(eventlog_level_error,"account_create","could not set username"); account_destroy(account); return NULL; } #ifndef ACCT_DYN_LOAD if (account_set_numattr(account,"BNET\\acct\\userid",maxuserid+1)<0) { eventlog(eventlog_level_error,"account_create","could not set userid"); account_destroy(account); return NULL; } #endif /* !ACCT_DYN_LOAD */ if (account_set_strattr(account,"BNET\\acct\\passhash1",passhash1)<0) { eventlog(eventlog_level_error,"account_create","could not set passhash1"); account_destroy(account); return NULL; } #ifdef WITH_BITS account_set_bits_state(account,account_state_valid); if (!bits_master) { eventlog(eventlog_level_warn,"account_create","account_create should not be called on BITS clients"); } #endif /* WITH_BITS */ } #ifdef WITH_BITS else /* empty account to be filled in later */ account_set_bits_state(account,account_state_valid); #endif /* WITH_BITS */ return account; }