code format

This commit is contained in:
HarpyWar 2014-02-03 10:58:57 +04:00
parent 1df3c408f3
commit a66afd0d43
358 changed files with 96289 additions and 95809 deletions

File diff suppressed because it is too large Load diff

View file

@ -39,30 +39,30 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
struct connection;
struct _clanmember;
struct clan;
struct connection;
struct _clanmember;
struct clan;
typedef struct account_struct
typedef struct account_struct
#ifdef ACCOUNT_INTERNAL_ACCESS
{
t_attrgroup * attrgroup;
char * name; /* profiling proved 99% of getstrattr its from get_name */
unsigned int namehash; /* cached from attrs */
unsigned int uid; /* cached from attrs */
unsigned int flags;
struct connection * conn;
struct _clanmember * clanmember;
t_list * friends;
t_list * teams;
}
{
t_attrgroup * attrgroup;
char * name; /* profiling proved 99% of getstrattr its from get_name */
unsigned int namehash; /* cached from attrs */
unsigned int uid; /* cached from attrs */
unsigned int flags;
struct connection * conn;
struct _clanmember * clanmember;
t_list * friends;
t_list * teams;
}
#endif
t_account;
t_account;
}
}
}
@ -81,57 +81,57 @@ t_account;
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern unsigned int maxuserid;
extern unsigned int maxuserid;
extern int accountlist_reload(void);
extern int account_check_name(char const * name);
extern int accountlist_reload(void);
extern int account_check_name(char const * name);
#define account_get_uid(A) account_get_uid_real(A,__FILE__,__LINE__)
extern unsigned int account_get_uid_real(t_account const * account, char const * fn, unsigned int ln);
extern int account_match(t_account * account, char const * username);
extern int account_save(t_account *account, unsigned flags);
extern char const * account_get_strattr_real(t_account * account, char const * key, char const * fn, unsigned int ln);
extern unsigned int account_get_uid_real(t_account const * account, char const * fn, unsigned int ln);
extern int account_match(t_account * account, char const * username);
extern int account_save(t_account *account, unsigned flags);
extern char const * account_get_strattr_real(t_account * account, char const * key, char const * fn, unsigned int ln);
#define account_get_strattr(A,K) account_get_strattr_real(A,K,__FILE__,__LINE__)
extern int account_set_strattr(t_account * account, char const * key, char const * val);
extern int account_set_strattr(t_account * account, char const * key, char const * val);
extern int accountlist_create(void);
extern int accountlist_destroy(void);
extern t_hashtable * accountlist(void);
extern t_hashtable * accountlist_uid(void);
extern int accountlist_load_all(int flag);
extern unsigned int accountlist_get_length(void);
extern int accountlist_save(unsigned flags);
extern int accountlist_flush(unsigned flags);
extern t_account * accountlist_find_account(char const * username);
extern t_account * accountlist_find_account_by_uid(unsigned int uid);
extern int accountlist_allow_add(void);
extern t_account * accountlist_create_account(const char *username, const char *passhash1);
extern void accounts_get_attr(char const *);
/* names and passwords */
extern char const * account_get_name_real(t_account * account, char const * fn, unsigned int ln);
extern int accountlist_create(void);
extern int accountlist_destroy(void);
extern t_hashtable * accountlist(void);
extern t_hashtable * accountlist_uid(void);
extern int accountlist_load_all(int flag);
extern unsigned int accountlist_get_length(void);
extern int accountlist_save(unsigned flags);
extern int accountlist_flush(unsigned flags);
extern t_account * accountlist_find_account(char const * username);
extern t_account * accountlist_find_account_by_uid(unsigned int uid);
extern int accountlist_allow_add(void);
extern t_account * accountlist_create_account(const char *username, const char *passhash1);
extern void accounts_get_attr(char const *);
/* names and passwords */
extern char const * account_get_name_real(t_account * account, char const * fn, unsigned int ln);
# define account_get_name(A) account_get_name_real(A,__FILE__,__LINE__)
extern int account_check_mutual( t_account * account, int myuserid);
extern t_list * account_get_friends(t_account * account);
extern int account_check_mutual(t_account * account, int myuserid);
extern t_list * account_get_friends(t_account * account);
extern int account_set_clanmember(t_account * account, _clanmember * clanmember);
extern _clanmember * account_get_clanmember(t_account * account);
extern _clanmember * account_get_clanmember_forced(t_account * account);
extern clan * account_get_clan(t_account * account);
extern clan * account_get_creating_clan(t_account * account);
extern int account_set_clanmember(t_account * account, _clanmember * clanmember);
extern _clanmember * account_get_clanmember(t_account * account);
extern _clanmember * account_get_clanmember_forced(t_account * account);
extern clan * account_get_clan(t_account * account);
extern clan * account_get_creating_clan(t_account * account);
extern int account_set_conn(t_account * account, t_connection * conn);
extern t_connection * account_get_conn(t_account * account);
extern int account_set_conn(t_account * account, t_connection * conn);
extern t_connection * account_get_conn(t_account * account);
extern void account_add_team(t_account * account, t_team * team);
extern t_team * account_find_team_by_accounts(t_account * account, t_account **accounts, t_clienttag clienttag);
extern t_team * account_find_team_by_teamid(t_account * account, unsigned int teamid);
extern t_list * account_get_teams(t_account * account);
extern void account_add_team(t_account * account, t_team * team);
extern t_team * account_find_team_by_accounts(t_account * account, t_account **accounts, t_clienttag clienttag);
extern t_team * account_find_team_by_teamid(t_account * account, unsigned int teamid);
extern t_list * account_get_teams(t_account * account);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -35,212 +35,212 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
/* convenience functions */
extern unsigned int account_get_numattr_real(t_account * account, char const * key, char const * fn, unsigned int ln);
/* convenience functions */
extern unsigned int account_get_numattr_real(t_account * account, char const * key, char const * fn, unsigned int ln);
#define account_get_numattr(A,K) account_get_numattr_real(A,K,__FILE__,__LINE__)
extern int account_set_numattr(t_account * account, char const * key, unsigned int val);
extern int account_set_numattr(t_account * account, char const * key, unsigned int val);
extern int account_get_boolattr_real(t_account * account, char const * key, char const * fn, unsigned int ln);
extern int account_get_boolattr_real(t_account * account, char const * key, char const * fn, unsigned int ln);
#define account_get_boolattr(A,K) account_get_boolattr_real(A,K,__FILE__,__LINE__)
extern int account_set_boolattr(t_account * account, char const * key, int val);
extern int account_set_boolattr(t_account * account, char const * key, int val);
/* warning: unlike the other account_get_*attr functions this one allocates memory for returning data - its up to the caller to clean it up */
extern char const * account_get_rawattr_real(t_account * account, char const * key, char const * fn, unsigned int ln);
/* warning: unlike the other account_get_*attr functions this one allocates memory for returning data - its up to the caller to clean it up */
extern char const * account_get_rawattr_real(t_account * account, char const * key, char const * fn, unsigned int ln);
#define account_get_rawattr(A,K) account_get_rawattr_real(A,K,__FILE__,__LINE__)
extern int account_set_rawattr(t_account * account, char const * key, char const * val, int length);
extern int account_set_rawattr(t_account * account, char const * key, char const * val, int length);
extern char const * account_get_pass(t_account * account);
extern int account_set_pass(t_account * account, char const * passhash1);
extern char const * account_get_pass(t_account * account);
extern int account_set_pass(t_account * account, char const * passhash1);
extern char const * account_get_salt(t_account * account);
extern int account_set_salt(t_account * account, char const * salt);
extern char const * account_get_salt(t_account * account);
extern int account_set_salt(t_account * account, char const * salt);
extern char const * account_get_verifier(t_account * account);
extern int account_set_verifier(t_account * account, char const * verifier);
extern char const * account_get_verifier(t_account * account);
extern int account_set_verifier(t_account * account, char const * verifier);
/* authorization */
extern int account_get_auth_admin(t_account * account, char const * channelname);
extern int account_set_auth_admin(t_account * account, char const * channelname, int val);
extern int account_get_auth_announce(t_account * account);
extern int account_get_auth_botlogin(t_account * account);
extern int account_get_auth_bnetlogin(t_account * account);
extern int account_get_auth_operator(t_account * account, char const * channelname);
extern int account_set_auth_operator(t_account * account, char const * channelname, int val);
extern int account_get_auth_voice(t_account * account, char const * channelname);
extern int account_set_auth_voice(t_account * account, char const * channelname, int val);
extern int account_get_auth_changepass(t_account * account);
extern int account_get_auth_changeprofile(t_account * account);
extern int account_get_auth_createnormalgame(t_account * account);
extern int account_get_auth_joinnormalgame(t_account * account);
extern int account_get_auth_createladdergame(t_account * account);
extern int account_get_auth_joinladdergame(t_account * account);
extern int account_get_auth_lock(t_account * account);
extern int account_set_auth_lock(t_account * account, int val);
extern int account_set_auth_mute(t_account * account, int val);
extern int account_get_auth_mute(t_account * account);
/* authorization */
extern int account_get_auth_admin(t_account * account, char const * channelname);
extern int account_set_auth_admin(t_account * account, char const * channelname, int val);
extern int account_get_auth_announce(t_account * account);
extern int account_get_auth_botlogin(t_account * account);
extern int account_get_auth_bnetlogin(t_account * account);
extern int account_get_auth_operator(t_account * account, char const * channelname);
extern int account_set_auth_operator(t_account * account, char const * channelname, int val);
extern int account_get_auth_voice(t_account * account, char const * channelname);
extern int account_set_auth_voice(t_account * account, char const * channelname, int val);
extern int account_get_auth_changepass(t_account * account);
extern int account_get_auth_changeprofile(t_account * account);
extern int account_get_auth_createnormalgame(t_account * account);
extern int account_get_auth_joinnormalgame(t_account * account);
extern int account_get_auth_createladdergame(t_account * account);
extern int account_get_auth_joinladdergame(t_account * account);
extern int account_get_auth_lock(t_account * account);
extern int account_set_auth_lock(t_account * account, int val);
extern int account_set_auth_mute(t_account * account, int val);
extern int account_get_auth_mute(t_account * account);
/* profile */
extern char const * account_get_sex(t_account * account); /* the profile attributes are updated directly in bnetd.c */
extern char const * account_get_age(t_account * account);
extern char const * account_get_loc(t_account * account);
extern char const * account_get_desc(t_account * account);
/* profile */
extern char const * account_get_sex(t_account * account); /* the profile attributes are updated directly in bnetd.c */
extern char const * account_get_age(t_account * account);
extern char const * account_get_loc(t_account * account);
extern char const * account_get_desc(t_account * account);
/* last login */
extern unsigned int account_get_ll_time(t_account * account);
extern int account_set_ll_time(t_account * account, unsigned int t);
extern char const * account_get_ll_user(t_account * account);
extern int account_set_ll_user(t_account * account, char const * user);
extern t_clienttag account_get_ll_clienttag(t_account * account);
extern int account_set_ll_clienttag(t_account * account, t_clienttag clienttag);
extern char const * account_get_ll_owner(t_account * account);
extern int account_set_ll_owner(t_account * account, char const * owner);
extern char const * account_get_ll_ip(t_account * account);
extern int account_set_ll_ip(t_account * account, char const * ip);
/* last login */
extern unsigned int account_get_ll_time(t_account * account);
extern int account_set_ll_time(t_account * account, unsigned int t);
extern char const * account_get_ll_user(t_account * account);
extern int account_set_ll_user(t_account * account, char const * user);
extern t_clienttag account_get_ll_clienttag(t_account * account);
extern int account_set_ll_clienttag(t_account * account, t_clienttag clienttag);
extern char const * account_get_ll_owner(t_account * account);
extern int account_set_ll_owner(t_account * account, char const * owner);
extern char const * account_get_ll_ip(t_account * account);
extern int account_set_ll_ip(t_account * account, char const * ip);
/* normal stats */
extern unsigned int account_get_normal_wins(t_account * account, t_clienttag clienttag);
extern int account_inc_normal_wins(t_account * account, t_clienttag clienttag);
extern int account_set_normal_wins(t_account * account, t_clienttag clienttag, unsigned wins);
extern unsigned int account_get_normal_losses(t_account * account, t_clienttag clienttag);
extern int account_inc_normal_losses(t_account * account, t_clienttag clienttag);
extern int account_set_normal_losses(t_account * account, t_clienttag clienttag, unsigned losses);
extern unsigned int account_get_normal_draws(t_account * account, t_clienttag clienttag);
extern int account_inc_normal_draws(t_account * account, t_clienttag clienttag);
extern int account_set_normal_draws(t_account * account, t_clienttag clienttag, unsigned draws);
extern unsigned int account_get_normal_disconnects(t_account * account, t_clienttag clienttag);
extern int account_inc_normal_disconnects(t_account * account, t_clienttag clienttag);
extern int account_set_normal_disconnects(t_account * account, t_clienttag clienttag,unsigned discs);
extern int account_set_normal_last_time(t_account * account, t_clienttag clienttag, t_bnettime t);
extern int account_set_normal_last_result(t_account * account, t_clienttag clienttag, char const * result);
/* normal stats */
extern unsigned int account_get_normal_wins(t_account * account, t_clienttag clienttag);
extern int account_inc_normal_wins(t_account * account, t_clienttag clienttag);
extern int account_set_normal_wins(t_account * account, t_clienttag clienttag, unsigned wins);
extern unsigned int account_get_normal_losses(t_account * account, t_clienttag clienttag);
extern int account_inc_normal_losses(t_account * account, t_clienttag clienttag);
extern int account_set_normal_losses(t_account * account, t_clienttag clienttag, unsigned losses);
extern unsigned int account_get_normal_draws(t_account * account, t_clienttag clienttag);
extern int account_inc_normal_draws(t_account * account, t_clienttag clienttag);
extern int account_set_normal_draws(t_account * account, t_clienttag clienttag, unsigned draws);
extern unsigned int account_get_normal_disconnects(t_account * account, t_clienttag clienttag);
extern int account_inc_normal_disconnects(t_account * account, t_clienttag clienttag);
extern int account_set_normal_disconnects(t_account * account, t_clienttag clienttag, unsigned discs);
extern int account_set_normal_last_time(t_account * account, t_clienttag clienttag, t_bnettime t);
extern int account_set_normal_last_result(t_account * account, t_clienttag clienttag, char const * result);
/* ladder stats (active) */
extern unsigned int account_get_ladder_active_wins(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_wins(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int wins);
extern unsigned int account_get_ladder_active_losses(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_losses(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int losses);
extern unsigned int account_get_ladder_active_draws(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_draws(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int draws);
extern unsigned int account_get_ladder_active_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int disconnects);
extern unsigned int account_get_ladder_active_rating(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_rating(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int rating);
extern int account_get_ladder_active_rank(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_rank(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int rank);
extern char const * account_get_ladder_active_last_time(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_last_time(t_account * account, t_clienttag clienttag, t_ladder_id id, t_bnettime t);
/* ladder stats (active) */
extern unsigned int account_get_ladder_active_wins(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_wins(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int wins);
extern unsigned int account_get_ladder_active_losses(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_losses(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int losses);
extern unsigned int account_get_ladder_active_draws(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_draws(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int draws);
extern unsigned int account_get_ladder_active_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int disconnects);
extern unsigned int account_get_ladder_active_rating(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_rating(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int rating);
extern int account_get_ladder_active_rank(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_rank(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int rank);
extern char const * account_get_ladder_active_last_time(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_active_last_time(t_account * account, t_clienttag clienttag, t_ladder_id id, t_bnettime t);
/* ladder stats (current) */
extern unsigned int account_get_ladder_wins(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_inc_ladder_wins(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_wins(t_account * account, t_clienttag clienttag, t_ladder_id id,unsigned wins);
extern unsigned int account_get_ladder_losses(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_inc_ladder_draws(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_draws(t_account * account, t_clienttag clienttag, t_ladder_id id,unsigned draws);
extern unsigned int account_get_ladder_draws(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_inc_ladder_losses(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_losses(t_account * account, t_clienttag clienttag, t_ladder_id id,unsigned losses);
extern unsigned int account_get_ladder_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_inc_ladder_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id,unsigned discs);
extern unsigned int account_get_ladder_rating(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_rating(t_account * account, t_clienttag clienttag, t_ladder_id id,unsigned rating);
extern int account_adjust_ladder_rating(t_account * account, t_clienttag clienttag, t_ladder_id id, int delta);
extern int account_get_ladder_rank(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_rank(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int rank);
extern unsigned int account_get_ladder_high_rating(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern unsigned int account_get_ladder_high_rank(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_last_time(t_account * account, t_clienttag clienttag, t_ladder_id id, t_bnettime t);
extern char const * account_get_ladder_last_time(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_last_result(t_account * account, t_clienttag clienttag, t_ladder_id id, char const * result);
/* ladder stats (current) */
extern unsigned int account_get_ladder_wins(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_inc_ladder_wins(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_wins(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned wins);
extern unsigned int account_get_ladder_losses(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_inc_ladder_draws(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_draws(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned draws);
extern unsigned int account_get_ladder_draws(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_inc_ladder_losses(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_losses(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned losses);
extern unsigned int account_get_ladder_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_inc_ladder_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_disconnects(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned discs);
extern unsigned int account_get_ladder_rating(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_rating(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned rating);
extern int account_adjust_ladder_rating(t_account * account, t_clienttag clienttag, t_ladder_id id, int delta);
extern int account_get_ladder_rank(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_rank(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int rank);
extern unsigned int account_get_ladder_high_rating(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern unsigned int account_get_ladder_high_rank(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_last_time(t_account * account, t_clienttag clienttag, t_ladder_id id, t_bnettime t);
extern char const * account_get_ladder_last_time(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_last_result(t_account * account, t_clienttag clienttag, t_ladder_id id, char const * result);
/* Diablo normal stats */
extern unsigned int account_get_normal_level(t_account * account, t_clienttag clienttag);
extern int account_set_normal_level(t_account * account, t_clienttag clienttag, unsigned int level);
extern unsigned int account_get_normal_class(t_account * account, t_clienttag clienttag);
extern int account_set_normal_class(t_account * account, t_clienttag clienttag, unsigned int chclass);
extern unsigned int account_get_normal_diablo_kills(t_account * account, t_clienttag clienttag);
extern int account_set_normal_diablo_kills(t_account * account, t_clienttag clienttag, unsigned int diablo_kills);
extern unsigned int account_get_normal_strength(t_account * account, t_clienttag clienttag);
extern int account_set_normal_strength(t_account * account, t_clienttag clienttag, unsigned int strength);
extern unsigned int account_get_normal_magic(t_account * account, t_clienttag clienttag);
extern int account_set_normal_magic(t_account * account, t_clienttag clienttag, unsigned int magic);
extern unsigned int account_get_normal_dexterity(t_account * account, t_clienttag clienttag);
extern int account_set_normal_dexterity(t_account * account, t_clienttag clienttag, unsigned int dexterity);
extern unsigned int account_get_normal_vitality(t_account * account, t_clienttag clienttag);
extern int account_set_normal_vitality(t_account * account, t_clienttag clienttag, unsigned int vitality);
extern unsigned int account_get_normal_gold(t_account * account, t_clienttag clienttag);
extern int account_set_normal_gold(t_account * account, t_clienttag clienttag, unsigned int gold);
/* Diablo normal stats */
extern unsigned int account_get_normal_level(t_account * account, t_clienttag clienttag);
extern int account_set_normal_level(t_account * account, t_clienttag clienttag, unsigned int level);
extern unsigned int account_get_normal_class(t_account * account, t_clienttag clienttag);
extern int account_set_normal_class(t_account * account, t_clienttag clienttag, unsigned int chclass);
extern unsigned int account_get_normal_diablo_kills(t_account * account, t_clienttag clienttag);
extern int account_set_normal_diablo_kills(t_account * account, t_clienttag clienttag, unsigned int diablo_kills);
extern unsigned int account_get_normal_strength(t_account * account, t_clienttag clienttag);
extern int account_set_normal_strength(t_account * account, t_clienttag clienttag, unsigned int strength);
extern unsigned int account_get_normal_magic(t_account * account, t_clienttag clienttag);
extern int account_set_normal_magic(t_account * account, t_clienttag clienttag, unsigned int magic);
extern unsigned int account_get_normal_dexterity(t_account * account, t_clienttag clienttag);
extern int account_set_normal_dexterity(t_account * account, t_clienttag clienttag, unsigned int dexterity);
extern unsigned int account_get_normal_vitality(t_account * account, t_clienttag clienttag);
extern int account_set_normal_vitality(t_account * account, t_clienttag clienttag, unsigned int vitality);
extern unsigned int account_get_normal_gold(t_account * account, t_clienttag clienttag);
extern int account_set_normal_gold(t_account * account, t_clienttag clienttag, unsigned int gold);
/* Diablo II closed characters */
extern char const * account_get_closed_characterlist(t_account * account, t_clienttag clienttag, char const * realmname);
extern int account_set_closed_characterlist(t_account * account, t_clienttag clienttag, char const * charlist);
extern int account_add_closed_character(t_account * account, t_clienttag clienttag, t_character * ch);
extern int account_check_closed_character(t_account * account, t_clienttag clienttag, char const * realmname, char const * charname);
/* Diablo II closed characters */
extern char const * account_get_closed_characterlist(t_account * account, t_clienttag clienttag, char const * realmname);
extern int account_set_closed_characterlist(t_account * account, t_clienttag clienttag, char const * charlist);
extern int account_add_closed_character(t_account * account, t_clienttag clienttag, t_character * ch);
extern int account_check_closed_character(t_account * account, t_clienttag clienttag, char const * realmname, char const * charname);
extern int account_set_friend( t_account * account, int friendnum, unsigned int frienduid );
extern unsigned int account_get_friend( t_account * account, int friendnum);
extern int account_get_friendcount( t_account * account );
extern int account_add_friend( t_account * my_acc, t_account * facc );
extern int account_remove_friend( t_account * account, int friendnum );
extern int account_remove_friend2( t_account * account, const char * friendname );
extern int account_set_friend(t_account * account, int friendnum, unsigned int frienduid);
extern unsigned int account_get_friend(t_account * account, int friendnum);
extern int account_get_friendcount(t_account * account);
extern int account_add_friend(t_account * my_acc, t_account * facc);
extern int account_remove_friend(t_account * account, int friendnum);
extern int account_remove_friend2(t_account * account, const char * friendname);
extern char const * race_get_str(unsigned int race);
extern int account_set_admin( t_account * account );
extern int account_set_demoteadmin( t_account * account );
extern char const * race_get_str(unsigned int race);
extern int account_set_admin(t_account * account);
extern int account_set_demoteadmin(t_account * account);
extern unsigned int account_get_command_groups(t_account * account);
extern int account_set_command_groups(t_account * account, unsigned int groups);
extern unsigned int account_get_command_groups(t_account * account);
extern int account_set_command_groups(t_account * account, unsigned int groups);
extern int account_set_w3pgrace( t_account * account, t_clienttag clienttag, unsigned int race);
extern int account_get_w3pgrace( t_account * account, t_clienttag clienttag );
extern int account_set_w3pgrace(t_account * account, t_clienttag clienttag, unsigned int race);
extern int account_get_w3pgrace(t_account * account, t_clienttag clienttag);
extern void account_get_raceicon(t_account * account, char * raceicon, unsigned int * raceiconnumber, unsigned int * wins,t_clienttag clienttag);
//Used to call the save stats for all opponents
extern int account_set_saveladderstats(t_account *a, unsigned int gametype, t_game_result result, unsigned int opponlevel,t_clienttag clienttag);
extern void account_get_raceicon(t_account * account, char * raceicon, unsigned int * raceiconnumber, unsigned int * wins, t_clienttag clienttag);
//Used to call the save stats for all opponents
extern int account_set_saveladderstats(t_account *a, unsigned int gametype, t_game_result result, unsigned int opponlevel, t_clienttag clienttag);
extern int account_inc_racewins( t_account * account, unsigned int intrace, t_clienttag clienttag);
extern int account_get_racewins( t_account * account, unsigned int intrace, t_clienttag clienttag);
extern int account_inc_racelosses( t_account * account, unsigned int intrace, t_clienttag clienttag);
extern int account_get_racelosses( t_account * account, unsigned int intrace, t_clienttag clienttag);
extern int account_inc_racewins(t_account * account, unsigned int intrace, t_clienttag clienttag);
extern int account_get_racewins(t_account * account, unsigned int intrace, t_clienttag clienttag);
extern int account_inc_racelosses(t_account * account, unsigned int intrace, t_clienttag clienttag);
extern int account_get_racelosses(t_account * account, unsigned int intrace, t_clienttag clienttag);
extern int account_update_xp(t_account * account, t_clienttag clienttag, t_game_result gameresult, unsigned int opponlevel,int * xp_diff,t_ladder_id id);
extern int account_get_ladder_xp(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_xp(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int xp);
extern int account_get_ladder_level(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_level(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int level);
extern int account_adjust_ladder_level(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_update_xp(t_account * account, t_clienttag clienttag, t_game_result gameresult, unsigned int opponlevel, int * xp_diff, t_ladder_id id);
extern int account_get_ladder_xp(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_xp(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int xp);
extern int account_get_ladder_level(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_level(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int level);
extern int account_adjust_ladder_level(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_currentatteam(t_account * account, unsigned int teamcount);
extern int account_get_currentatteam(t_account * account);
extern int account_set_currentatteam(t_account * account, unsigned int teamcount);
extern int account_get_currentatteam(t_account * account);
extern int account_get_highestladderlevel(t_account * account,t_clienttag clienttag); //func will compare levels for AT, Solo/Team Ladder and out the higest level of the 3
extern int account_get_highestladderlevel(t_account * account, t_clienttag clienttag); //func will compare levels for AT, Solo/Team Ladder and out the higest level of the 3
// Determines the length of XP bar in profiles screen
extern int account_get_profile_calcs(t_account * account, int xp, unsigned int level);
extern unsigned int account_get_icon_profile(t_account * account,t_clienttag clienttag);
// Determines the length of XP bar in profiles screen
extern int account_get_profile_calcs(t_account * account, int xp, unsigned int level);
extern unsigned int account_get_icon_profile(t_account * account, t_clienttag clienttag);
extern int account_set_user_icon( t_account * account, t_clienttag clienttag,char const * usericon);
extern char const * account_get_user_icon( t_account * account, t_clienttag clienttag );
extern unsigned int account_icon_to_profile_icon(char const * icon,t_account * account, t_clienttag ctag);
extern char const * account_icon_default(t_account * account, t_clienttag clienttag);
extern int account_set_user_icon(t_account * account, t_clienttag clienttag, char const * usericon);
extern char const * account_get_user_icon(t_account * account, t_clienttag clienttag);
extern unsigned int account_icon_to_profile_icon(char const * icon, t_account * account, t_clienttag ctag);
extern char const * account_icon_default(t_account * account, t_clienttag clienttag);
extern int account_is_operator_or_admin(t_account * account, char const * channel);
extern int account_is_operator_or_admin(t_account * account, char const * channel);
extern int account_set_email(t_account * account, char const * email);
extern char const * account_get_email(t_account * account);
extern int account_set_email(t_account * account, char const * email);
extern char const * account_get_email(t_account * account);
/* Westwood Online Extensions */
extern char const * account_get_wol_apgar(t_account * account);
extern int account_set_wol_apgar(t_account * account, char const * apgar);
extern int account_get_locale(t_account * account);
extern int account_set_locale(t_account * account, int locale);
extern int account_get_ladder_points(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_points(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int points);
}
/* Westwood Online Extensions */
extern char const * account_get_wol_apgar(t_account * account);
extern int account_set_wol_apgar(t_account * account, char const * apgar);
extern int account_get_locale(t_account * account);
extern int account_set_locale(t_account * account, int locale);
extern int account_get_ladder_points(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int account_set_ladder_points(t_account * account, t_clienttag clienttag, t_ladder_id id, unsigned int points);
}
}

View file

@ -34,328 +34,328 @@
namespace pvpgn
{
namespace bnetd
{
scoped_ptr<AdBannerComponent> adbannerlist;
AdBanner::AdBanner(unsigned id_, bn_int extag, unsigned delay_, unsigned next_, const std::string& fname, const std::string& link_, t_clienttag client_, t_gamelang lang_)
:id(id_), extensiontag(bn_int_get(extag)), delay(delay_), next(next_), filename(fname), link(link_), client(client_), lang(lang_)
{
/* I'm aware that this statement looks stupid */
if (client && (!tag_check_client(client)))
throw std::runtime_error("banner with invalid clienttag \"" + std::string(clienttag_uint_to_str(client)) + "\"encountered");
char language[5];
eventlog(eventlog_level_debug,__FUNCTION__, "created ad id=0x%08x filename=\"%s\" extensiontag=0x%04x delay=%u link=\"%s\" next_id=0x%08x client=\"%s\" lang=\"%s\"", id, filename.c_str(), extensiontag, delay, link.c_str(), next, client ? clienttag_uint_to_str(client) : "NULL", lang ? tag_uint_to_str(language,lang) : "NULL");
}
AdBanner::~AdBanner() throw()
{
}
const AdBanner*
AdBannerComponent::find(t_clienttag ctag, t_gamelang lang, unsigned id) const
{
return find(std::make_pair(ctag,lang),id);
}
const AdBanner*
AdBannerComponent::find(AdKey adKey, unsigned id) const
{
const AdBanner* result;
if ((result = finder(adKey,id)))
return result;
else if ((result = finder(std::make_pair(adKey.first,0),id)))
return result;
else if ((result = finder(std::make_pair(0,adKey.second),id)))
return result;
else
return finder(std::make_pair(0,0),id);
}
const AdBanner*
AdBannerComponent::finder(AdKey adKey, unsigned id) const
{
AdCtagMap::const_iterator cit(adlist.find(adKey));
if (cit == adlist.end()) return 0;
AdIdMap::const_iterator iit(cit->second.find(id));
if (iit == cit->second.end()) return 0;
return &(iit->second);
}
const AdBanner*
AdBannerComponent::pick(t_clienttag ctag, t_gamelang lang, unsigned prev_id) const
{
return pick(std::make_pair(ctag,lang),prev_id);
}
const AdBanner*
AdBannerComponent::pick(AdKey adKey, unsigned prev_id) const
{
/* eventlog(eventlog_level_debug,__FUNCTION__,"prev_id=%u init_count=%u start_count=%u norm_count=%u",prev_id,adbannerlist_init_count,adbannerlist_start_count,adbannerlist_norm_count); */
/* if this is the first ad, randomly choose an init sequence (if there is one) */
if (prev_id==0 && !adlist_init.empty())
return findRandom(adlist_init, adKey);
// return list_get_data_by_pos(adbannerlist_init_head,((unsigned int)std::rand())%adbannerlist_init_count);
/* eventlog(eventlog_level_debug,__FUNCTION__,"not sending init banner"); */
unsigned next_id = 0;
const AdBanner* prev(find(adKey, prev_id));
if (prev) next_id = prev->getNextId();
/* return its next ad if there is one */
if (next_id)
namespace bnetd
{
const AdBanner* curr(find(adKey, next_id));
if (curr) return curr;
ERROR1("could not locate next requested ad with id 0x%06x", next_id);
}
/* eventlog(eventlog_level_debug,__FUNCTION__,"not sending next banner"); */
/* otherwise choose another starting point randomly */
if (!adlist_start.empty())
return findRandom(adlist_start, adKey);
scoped_ptr<AdBannerComponent> adbannerlist;
/* eventlog(eventlog_level_debug,__FUNCTION__,"not sending start banner... nothing to return"); */
return NULL; /* nothing else to return */
}
unsigned
AdBanner::getId() const
{
return id;
}
unsigned
AdBanner::getNextId() const
{
return next;
}
unsigned
AdBanner::getExtensionTag() const
{
return extensiontag;
}
char const *
AdBanner::getFilename() const
{
return filename.c_str();
}
char const *
AdBanner::getLink() const
{
return link.c_str();
}
t_clienttag
AdBanner::getClient() const
{
return client;
}
const AdBanner*
AdBannerComponent::findRandom(const AdCtagRefMap& where, AdKey adKey) const
{
const AdBanner* result;
// first try language and client specific ad
if ((result = randomFinder(where,adKey)))
return result;
// then try discarding language
else if ((result = randomFinder(where, std::make_pair(adKey.first,0))))
return result;
// now discard client
else if ((result = randomFinder(where, std::make_pair(0,adKey.second))))
return result;
// and finally look for a totally unspecific ad
else
return randomFinder(where, std::make_pair(0,0));
}
const AdBanner*
AdBannerComponent::randomFinder(const AdCtagRefMap& where, AdKey adKey) const
{
/* first try to lookup a random banner into the specific client tag map */
AdCtagRefMap::const_iterator cit(where.find(adKey));
if (cit == where.end() || cit->second.size() == 0)
return 0;
unsigned pos = (static_cast<unsigned>(std::rand())) % cit->second.size();
/* TODO: optimize this linear search ? */
for(AdIdRefMap::const_iterator it(cit->second.begin()); it != cit->second.end(); ++it)
{
if (!pos) return &(it->second->second);
--pos;
}
return 0;
}
void
AdBannerComponent::insert(AdCtagRefMap& where, const std::string& fname, unsigned id, unsigned delay, const std::string& link, unsigned next_id, const std::string& client, const std::string& lang)
{
std::string::size_type idx(fname.rfind('.'));
if (idx == std::string::npos || idx + 4 != fname.size())
{
ERROR1("Invalid extension for '%s'", fname.c_str());
return;
}
std::string ext(fname.substr(idx + 1));
bn_int bntag;
if (strcasecmp(ext.c_str(), "pcx") == 0)
bn_int_tag_set(&bntag, EXTENSIONTAG_PCX);
else if (strcasecmp(ext.c_str(), "mng") == 0)
bn_int_tag_set(&bntag, EXTENSIONTAG_MNG);
else if (strcasecmp(ext.c_str(), "smk") == 0)
bn_int_tag_set(&bntag, EXTENSIONTAG_SMK);
else {
ERROR1("unknown extension on filename \"%s\"", fname.c_str());
return;
}
t_clienttag ctag;
if (!strcasecmp(client.c_str(), "NULL"))
ctag = 0;
else
ctag = clienttag_str_to_uint(client.c_str());
t_gamelang ltag;
if (!strcasecmp(lang.c_str(), "any"))
ltag = 0;
else
{
ltag = tag_str_to_uint(lang.c_str());
if (!tag_check_gamelang(ltag))
AdBanner::AdBanner(unsigned id_, bn_int extag, unsigned delay_, unsigned next_, const std::string& fname, const std::string& link_, t_clienttag client_, t_gamelang lang_)
:id(id_), extensiontag(bn_int_get(extag)), delay(delay_), next(next_), filename(fname), link(link_), client(client_), lang(lang_)
{
eventlog(eventlog_level_error,__FUNCTION__,"got unknown language tag \"%s\"",lang.c_str());
return;
}
}
/* I'm aware that this statement looks stupid */
if (client && (!tag_check_client(client)))
throw std::runtime_error("banner with invalid clienttag \"" + std::string(clienttag_uint_to_str(client)) + "\"encountered");
AdKey adKey = std::make_pair(ctag,ltag);
// check if the ctag is known so far
AdCtagMap::iterator cit(adlist.find(adKey));
// if not register the ctag
if (cit == adlist.end())
{
std::pair<AdCtagMap::iterator, bool> res(adlist.insert(std::make_pair(adKey, AdIdMap())));
if (!res.second)
throw std::runtime_error("Could not insert unexistent element into map?!");
cit = res.first;
}
// insert the adbanner into the ctag specific AdIdMap
std::pair<AdIdMap::iterator, bool> res(cit->second.insert(std::make_pair(id, AdBanner(id, bntag, delay, next_id, fname, link, ctag, ltag))));
if (!res.second)
{
ERROR0("Couldnt insert new ad banner, duplicate banner IDs ?!");
return;
}
// check if where allready knows about ctag
AdCtagRefMap::iterator cit2(where.find(adKey));
// if not register ctag
if (cit2 == where.end())
{
std::pair<AdCtagRefMap::iterator, bool> res2(where.insert(std::make_pair(adKey, AdIdRefMap())));
if (!res2.second)
{
cit->second.erase(res.first);
throw std::runtime_error("Could not insert unexistent element into map?!");
}
cit2 = res2.first;
}
// insert reference to adbanner into the ctag specific AdIdRefMap
if (!cit2->second.insert(std::make_pair(id, res.first)).second)
{
cit->second.erase(res.first);
throw std::runtime_error("Could not insert unexistent element into map?!");
}
}
AdBannerComponent::AdBannerComponent(const std::string& fname)
:adlist(), adlist_init(), adlist_start(), adlist_norm()
{
std::ifstream fp(fname.c_str());
if (!fp)
{
ERROR2("could not open adbanner file \"%s\" for reading (std::fopen: %s)", fname.c_str(), std::strerror(errno));
throw SystemError("open");
}
unsigned delay;
unsigned next_id;
unsigned id;
std::string name, when, link, client,lang;
std::string buff;
for(unsigned line = 1; std::getline(fp, buff); ++line)
{
std::string::size_type idx(buff.find('#'));
if (idx != std::string::npos) buff.erase(idx);
idx = buff.find_first_not_of(" \t");
if (idx == std::string::npos) continue;
std::istringstream is(buff);
is >> name;
is >> id;
is >> when;
is >> delay;
is >> link;
is >> std::hex >> next_id;
is >> client;
is >> lang;
if (!is || name.size() < 2 || link.size() < 2 || client.size() < 2 || lang.size() < 2 || id < 1)
{
ERROR2("malformed line %u in file \"%s\"", line, fname.c_str());
continue;
char language[5];
eventlog(eventlog_level_debug, __FUNCTION__, "created ad id=0x%08x filename=\"%s\" extensiontag=0x%04x delay=%u link=\"%s\" next_id=0x%08x client=\"%s\" lang=\"%s\"", id, filename.c_str(), extensiontag, delay, link.c_str(), next, client ? clienttag_uint_to_str(client) : "NULL", lang ? tag_uint_to_str(language, lang) : "NULL");
}
name.erase(0, 1);
name.erase(name.size() - 1);
link.erase(0, 1);
link.erase(link.size() - 1);
client.erase(0, 1);
client.erase(client.size() - 1);
lang.erase(0, 1);
lang.erase(lang.size() -1);
if (when == "init")
insert(adlist_init, name, id, delay, link, next_id, client, lang);
else if (when == "start")
insert(adlist_start, name, id, delay, link, next_id, client, lang);
else if (when == "norm")
insert(adlist_norm, name, id, delay, link, next_id, client, lang);
else
/*
ERROR4("when field has unknown value on line %u in file \"%s\": \"%s\" when == init: %d", line, fname.c_str(), when.c_str(), when == "init");
*/
eventlog(eventlog_level_error, __FUNCTION__, "when field has unknown value on line %u in file \"%s\": \"%s\" when == init: %d", line, fname.c_str(), when.c_str(), when == "init");
AdBanner::~AdBanner() throw()
{
}
const AdBanner*
AdBannerComponent::find(t_clienttag ctag, t_gamelang lang, unsigned id) const
{
return find(std::make_pair(ctag, lang), id);
}
const AdBanner*
AdBannerComponent::find(AdKey adKey, unsigned id) const
{
const AdBanner* result;
if ((result = finder(adKey, id)))
return result;
else if ((result = finder(std::make_pair(adKey.first, 0), id)))
return result;
else if ((result = finder(std::make_pair(0, adKey.second), id)))
return result;
else
return finder(std::make_pair(0, 0), id);
}
const AdBanner*
AdBannerComponent::finder(AdKey adKey, unsigned id) const
{
AdCtagMap::const_iterator cit(adlist.find(adKey));
if (cit == adlist.end()) return 0;
AdIdMap::const_iterator iit(cit->second.find(id));
if (iit == cit->second.end()) return 0;
return &(iit->second);
}
const AdBanner*
AdBannerComponent::pick(t_clienttag ctag, t_gamelang lang, unsigned prev_id) const
{
return pick(std::make_pair(ctag, lang), prev_id);
}
const AdBanner*
AdBannerComponent::pick(AdKey adKey, unsigned prev_id) const
{
/* eventlog(eventlog_level_debug,__FUNCTION__,"prev_id=%u init_count=%u start_count=%u norm_count=%u",prev_id,adbannerlist_init_count,adbannerlist_start_count,adbannerlist_norm_count); */
/* if this is the first ad, randomly choose an init sequence (if there is one) */
if (prev_id == 0 && !adlist_init.empty())
return findRandom(adlist_init, adKey);
// return list_get_data_by_pos(adbannerlist_init_head,((unsigned int)std::rand())%adbannerlist_init_count);
/* eventlog(eventlog_level_debug,__FUNCTION__,"not sending init banner"); */
unsigned next_id = 0;
const AdBanner* prev(find(adKey, prev_id));
if (prev) next_id = prev->getNextId();
/* return its next ad if there is one */
if (next_id)
{
const AdBanner* curr(find(adKey, next_id));
if (curr) return curr;
ERROR1("could not locate next requested ad with id 0x%06x", next_id);
}
/* eventlog(eventlog_level_debug,__FUNCTION__,"not sending next banner"); */
/* otherwise choose another starting point randomly */
if (!adlist_start.empty())
return findRandom(adlist_start, adKey);
/* eventlog(eventlog_level_debug,__FUNCTION__,"not sending start banner... nothing to return"); */
return NULL; /* nothing else to return */
}
unsigned
AdBanner::getId() const
{
return id;
}
unsigned
AdBanner::getNextId() const
{
return next;
}
unsigned
AdBanner::getExtensionTag() const
{
return extensiontag;
}
char const *
AdBanner::getFilename() const
{
return filename.c_str();
}
char const *
AdBanner::getLink() const
{
return link.c_str();
}
t_clienttag
AdBanner::getClient() const
{
return client;
}
const AdBanner*
AdBannerComponent::findRandom(const AdCtagRefMap& where, AdKey adKey) const
{
const AdBanner* result;
// first try language and client specific ad
if ((result = randomFinder(where, adKey)))
return result;
// then try discarding language
else if ((result = randomFinder(where, std::make_pair(adKey.first, 0))))
return result;
// now discard client
else if ((result = randomFinder(where, std::make_pair(0, adKey.second))))
return result;
// and finally look for a totally unspecific ad
else
return randomFinder(where, std::make_pair(0, 0));
}
const AdBanner*
AdBannerComponent::randomFinder(const AdCtagRefMap& where, AdKey adKey) const
{
/* first try to lookup a random banner into the specific client tag map */
AdCtagRefMap::const_iterator cit(where.find(adKey));
if (cit == where.end() || cit->second.size() == 0)
return 0;
unsigned pos = (static_cast<unsigned>(std::rand())) % cit->second.size();
/* TODO: optimize this linear search ? */
for (AdIdRefMap::const_iterator it(cit->second.begin()); it != cit->second.end(); ++it)
{
if (!pos) return &(it->second->second);
--pos;
}
return 0;
}
void
AdBannerComponent::insert(AdCtagRefMap& where, const std::string& fname, unsigned id, unsigned delay, const std::string& link, unsigned next_id, const std::string& client, const std::string& lang)
{
std::string::size_type idx(fname.rfind('.'));
if (idx == std::string::npos || idx + 4 != fname.size())
{
ERROR1("Invalid extension for '%s'", fname.c_str());
return;
}
std::string ext(fname.substr(idx + 1));
bn_int bntag;
if (strcasecmp(ext.c_str(), "pcx") == 0)
bn_int_tag_set(&bntag, EXTENSIONTAG_PCX);
else if (strcasecmp(ext.c_str(), "mng") == 0)
bn_int_tag_set(&bntag, EXTENSIONTAG_MNG);
else if (strcasecmp(ext.c_str(), "smk") == 0)
bn_int_tag_set(&bntag, EXTENSIONTAG_SMK);
else {
ERROR1("unknown extension on filename \"%s\"", fname.c_str());
return;
}
t_clienttag ctag;
if (!strcasecmp(client.c_str(), "NULL"))
ctag = 0;
else
ctag = clienttag_str_to_uint(client.c_str());
t_gamelang ltag;
if (!strcasecmp(lang.c_str(), "any"))
ltag = 0;
else
{
ltag = tag_str_to_uint(lang.c_str());
if (!tag_check_gamelang(ltag))
{
eventlog(eventlog_level_error, __FUNCTION__, "got unknown language tag \"%s\"", lang.c_str());
return;
}
}
AdKey adKey = std::make_pair(ctag, ltag);
// check if the ctag is known so far
AdCtagMap::iterator cit(adlist.find(adKey));
// if not register the ctag
if (cit == adlist.end())
{
std::pair<AdCtagMap::iterator, bool> res(adlist.insert(std::make_pair(adKey, AdIdMap())));
if (!res.second)
throw std::runtime_error("Could not insert unexistent element into map?!");
cit = res.first;
}
// insert the adbanner into the ctag specific AdIdMap
std::pair<AdIdMap::iterator, bool> res(cit->second.insert(std::make_pair(id, AdBanner(id, bntag, delay, next_id, fname, link, ctag, ltag))));
if (!res.second)
{
ERROR0("Couldnt insert new ad banner, duplicate banner IDs ?!");
return;
}
// check if where allready knows about ctag
AdCtagRefMap::iterator cit2(where.find(adKey));
// if not register ctag
if (cit2 == where.end())
{
std::pair<AdCtagRefMap::iterator, bool> res2(where.insert(std::make_pair(adKey, AdIdRefMap())));
if (!res2.second)
{
cit->second.erase(res.first);
throw std::runtime_error("Could not insert unexistent element into map?!");
}
cit2 = res2.first;
}
// insert reference to adbanner into the ctag specific AdIdRefMap
if (!cit2->second.insert(std::make_pair(id, res.first)).second)
{
cit->second.erase(res.first);
throw std::runtime_error("Could not insert unexistent element into map?!");
}
}
AdBannerComponent::AdBannerComponent(const std::string& fname)
:adlist(), adlist_init(), adlist_start(), adlist_norm()
{
std::ifstream fp(fname.c_str());
if (!fp)
{
ERROR2("could not open adbanner file \"%s\" for reading (std::fopen: %s)", fname.c_str(), std::strerror(errno));
throw SystemError("open");
}
unsigned delay;
unsigned next_id;
unsigned id;
std::string name, when, link, client, lang;
std::string buff;
for (unsigned line = 1; std::getline(fp, buff); ++line)
{
std::string::size_type idx(buff.find('#'));
if (idx != std::string::npos) buff.erase(idx);
idx = buff.find_first_not_of(" \t");
if (idx == std::string::npos) continue;
std::istringstream is(buff);
is >> name;
is >> id;
is >> when;
is >> delay;
is >> link;
is >> std::hex >> next_id;
is >> client;
is >> lang;
if (!is || name.size() < 2 || link.size() < 2 || client.size() < 2 || lang.size() < 2 || id < 1)
{
ERROR2("malformed line %u in file \"%s\"", line, fname.c_str());
continue;
}
name.erase(0, 1);
name.erase(name.size() - 1);
link.erase(0, 1);
link.erase(link.size() - 1);
client.erase(0, 1);
client.erase(client.size() - 1);
lang.erase(0, 1);
lang.erase(lang.size() - 1);
if (when == "init")
insert(adlist_init, name, id, delay, link, next_id, client, lang);
else if (when == "start")
insert(adlist_start, name, id, delay, link, next_id, client, lang);
else if (when == "norm")
insert(adlist_norm, name, id, delay, link, next_id, client, lang);
else
/*
ERROR4("when field has unknown value on line %u in file \"%s\": \"%s\" when == init: %d", line, fname.c_str(), when.c_str(), when == "init");
*/
eventlog(eventlog_level_error, __FUNCTION__, "when field has unknown value on line %u in file \"%s\": \"%s\" when == init: %d", line, fname.c_str(), when.c_str(), when == "init");
}
}
AdBannerComponent::~AdBannerComponent() throw()
{}
}
}
AdBannerComponent::~AdBannerComponent() throw()
{}
}
}

View file

@ -28,66 +28,66 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
class AdBanner
{
public:
AdBanner(unsigned id_, bn_int extag, unsigned delay_, unsigned next_, const std::string& fname, const std::string& link_, t_clienttag client_, t_gamelang lang_);
~AdBanner() throw();
class AdBanner
{
public:
AdBanner(unsigned id_, bn_int extag, unsigned delay_, unsigned next_, const std::string& fname, const std::string& link_, t_clienttag client_, t_gamelang lang_);
~AdBanner() throw();
unsigned getId() const;
unsigned getNextId() const;
unsigned getExtensionTag() const;
char const * getFilename() const;
char const * getLink() const;
t_clienttag getClient() const;
t_gamelang getGameLang() const;
unsigned getId() const;
unsigned getNextId() const;
unsigned getExtensionTag() const;
char const * getFilename() const;
char const * getLink() const;
t_clienttag getClient() const;
t_gamelang getGameLang() const;
private:
unsigned id;
unsigned extensiontag;
unsigned delay; /* in seconds */
unsigned next; /* adid or 0 */
const std::string filename;
const std::string link;
t_clienttag client;
t_gamelang lang;
};
private:
unsigned id;
unsigned extensiontag;
unsigned delay; /* in seconds */
unsigned next; /* adid or 0 */
const std::string filename;
const std::string link;
t_clienttag client;
t_gamelang lang;
};
class AdBannerComponent
{
public:
explicit AdBannerComponent(const std::string& fname);
~AdBannerComponent() throw();
class AdBannerComponent
{
public:
explicit AdBannerComponent(const std::string& fname);
~AdBannerComponent() throw();
typedef std::pair<t_clienttag, t_gamelang> AdKey;
const AdBanner* pick(t_clienttag ctag, t_gamelang lang, unsigned prev_id) const;
const AdBanner* find(t_clienttag ctag, t_gamelang lang, unsigned id) const;
typedef std::pair<t_clienttag, t_gamelang> AdKey;
const AdBanner* pick(t_clienttag ctag, t_gamelang lang, unsigned prev_id) const;
const AdBanner* find(t_clienttag ctag, t_gamelang lang, unsigned id) const;
private:
typedef std::map<unsigned, AdBanner> AdIdMap;
typedef std::map<AdKey, AdIdMap> AdCtagMap;
typedef std::map<unsigned, AdIdMap::const_iterator> AdIdRefMap;
typedef std::map<AdKey, AdIdRefMap> AdCtagRefMap;
private:
typedef std::map<unsigned, AdBanner> AdIdMap;
typedef std::map<AdKey, AdIdMap> AdCtagMap;
typedef std::map<unsigned, AdIdMap::const_iterator> AdIdRefMap;
typedef std::map<AdKey, AdIdRefMap> AdCtagRefMap;
AdCtagMap adlist;
AdCtagRefMap adlist_init;
AdCtagRefMap adlist_start;
AdCtagRefMap adlist_norm;
AdCtagMap adlist;
AdCtagRefMap adlist_init;
AdCtagRefMap adlist_start;
AdCtagRefMap adlist_norm;
const AdBanner* pick(AdKey adKey, unsigned prev_id) const;
const AdBanner* find(AdKey adKey, unsigned id) const;
const AdBanner* finder(AdKey adKey, unsigned id) const;
const AdBanner* findRandom(const AdCtagRefMap& where, AdKey adKey) const;
const AdBanner* randomFinder(const AdCtagRefMap& where, AdKey adKey) const;
void insert(AdCtagRefMap& where, const std::string& fname, unsigned id, unsigned delay, const std::string& link, unsigned next_id, const std::string& client, const std::string& lang);
};
const AdBanner* pick(AdKey adKey, unsigned prev_id) const;
const AdBanner* find(AdKey adKey, unsigned id) const;
const AdBanner* finder(AdKey adKey, unsigned id) const;
const AdBanner* findRandom(const AdCtagRefMap& where, AdKey adKey) const;
const AdBanner* randomFinder(const AdCtagRefMap& where, AdKey adKey) const;
void insert(AdCtagRefMap& where, const std::string& fname, unsigned id, unsigned delay, const std::string& link, unsigned next_id, const std::string& client, const std::string& lang);
};
extern scoped_ptr<AdBannerComponent> adbannerlist;
extern scoped_ptr<AdBannerComponent> adbannerlist;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -32,23 +32,23 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef struct
{
char const * line;
int min;
int max;
} t_output;
typedef struct
{
char const * line;
int min;
int max;
} t_output;
typedef struct
{
char const * alias;
t_list * output; /* of t_output * */
} t_alias;
typedef struct
{
char const * alias;
t_list * output; /* of t_output * */
} t_alias;
}
}
}
@ -69,14 +69,14 @@ typedef struct
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int aliasfile_load(char const * filename);
extern int aliasfile_unload(void);
extern int handle_alias_command(t_connection * c, char const * text);
extern int aliasfile_load(char const * filename);
extern int aliasfile_unload(void);
extern int handle_alias_command(t_connection * c, char const * text);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -32,46 +32,46 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef struct
{
int currentplayers;
int totalplayers;
struct connection * player[ANONGAME_MAX_GAMECOUNT];
t_account * account[ANONGAME_MAX_GAMECOUNT];
int result[ANONGAME_MAX_GAMECOUNT];
t_anongame_gameresult * results[ANONGAME_MAX_GAMECOUNT];
} t_anongameinfo;
typedef struct
{
int currentplayers;
int totalplayers;
struct connection * player[ANONGAME_MAX_GAMECOUNT];
t_account * account[ANONGAME_MAX_GAMECOUNT];
int result[ANONGAME_MAX_GAMECOUNT];
t_anongame_gameresult * results[ANONGAME_MAX_GAMECOUNT];
} t_anongameinfo;
typedef struct
{
t_anongameinfo * info;
int count;
t_uint32 id;
t_uint32 tid;
struct connection * tc[ANONGAME_MAX_GAMECOUNT/2];
t_uint32 race;
t_uint32 handle;
unsigned int addr;
char loaded;
char joined;
t_uint8 playernum;
t_uint32 map_prefs;
t_uint8 type;
t_uint8 gametype;
int queue;
} t_anongame;
typedef struct
{
t_anongameinfo * info;
int count;
t_uint32 id;
t_uint32 tid;
struct connection * tc[ANONGAME_MAX_GAMECOUNT / 2];
t_uint32 race;
t_uint32 handle;
unsigned int addr;
char loaded;
char joined;
t_uint8 playernum;
t_uint32 map_prefs;
t_uint8 type;
t_uint8 gametype;
int queue;
} t_anongame;
typedef struct
{
struct connection * c;
t_uint32 map_prefs;
char const * versiontag;
} t_matchdata;
typedef struct
{
struct connection * c;
t_uint32 map_prefs;
char const * versiontag;
} t_matchdata;
}
}
}
@ -90,49 +90,49 @@ typedef struct
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int anongame_matchlists_create(void);
extern int anongame_matchlists_destroy(void);
extern int anongame_matchlists_create(void);
extern int anongame_matchlists_destroy(void);
extern int handle_anongame_search(t_connection * c, t_packet const * packet);
extern int anongame_unqueue(t_connection * c, int queue);
extern int handle_anongame_search(t_connection * c, t_packet const * packet);
extern int anongame_unqueue(t_connection * c, int queue);
extern char anongame_arranged(int queue);
extern int anongame_stats(t_connection * c);
extern char anongame_arranged(int queue);
extern int anongame_stats(t_connection * c);
extern t_anongameinfo * anongameinfo_create(int totalplayers);
extern void anongameinfo_destroy(t_anongameinfo * i);
extern t_anongameinfo * anongameinfo_create(int totalplayers);
extern void anongameinfo_destroy(t_anongameinfo * i);
extern t_anongameinfo * anongame_get_info(t_anongame * a);
extern int anongame_get_currentplayers(t_anongame *a);
extern int anongame_get_totalplayers(t_anongame *a);
extern t_connection * anongame_get_player(t_anongame * a, int plnum);
extern int anongame_get_count(t_anongame *a);
extern t_uint32 anongame_get_id(t_anongame * a);
extern t_connection * anongame_get_tc(t_anongame *a, int tpnumber);
extern t_uint32 anongame_get_race(t_anongame * a);
extern t_uint32 anongame_get_handle(t_anongame * a);
extern unsigned int anongame_get_addr(t_anongame * a);
extern char anongame_get_loaded(t_anongame * a);
extern char anongame_get_joined(t_anongame * a);
extern t_uint8 anongame_get_playernum(t_anongame * a);
extern t_uint8 anongame_get_queue(t_anongame *a);
extern t_anongameinfo * anongame_get_info(t_anongame * a);
extern int anongame_get_currentplayers(t_anongame *a);
extern int anongame_get_totalplayers(t_anongame *a);
extern t_connection * anongame_get_player(t_anongame * a, int plnum);
extern int anongame_get_count(t_anongame *a);
extern t_uint32 anongame_get_id(t_anongame * a);
extern t_connection * anongame_get_tc(t_anongame *a, int tpnumber);
extern t_uint32 anongame_get_race(t_anongame * a);
extern t_uint32 anongame_get_handle(t_anongame * a);
extern unsigned int anongame_get_addr(t_anongame * a);
extern char anongame_get_loaded(t_anongame * a);
extern char anongame_get_joined(t_anongame * a);
extern t_uint8 anongame_get_playernum(t_anongame * a);
extern t_uint8 anongame_get_queue(t_anongame *a);
extern void anongame_set_result(t_anongame * a, int result);
extern void anongame_set_gameresults(t_anongame * a, t_anongame_gameresult * results);
extern void anongame_set_handle(t_anongame *a, t_uint32 h);
extern void anongame_set_addr(t_anongame *a, unsigned int addr);
extern void anongame_set_loaded(t_anongame * a, char loaded);
extern void anongame_set_joined(t_anongame * a, char joined);
extern void anongame_set_result(t_anongame * a, int result);
extern void anongame_set_gameresults(t_anongame * a, t_anongame_gameresult * results);
extern void anongame_set_handle(t_anongame *a, t_uint32 h);
extern void anongame_set_addr(t_anongame *a, unsigned int addr);
extern void anongame_set_loaded(t_anongame * a, char loaded);
extern void anongame_set_joined(t_anongame * a, char joined);
extern int handle_w3route_packet(t_connection * c, t_packet const * const packet);
extern int handle_anongame_join(t_connection * c);
extern int handle_w3route_packet(t_connection * c, t_packet const * const packet);
extern int handle_anongame_join(t_connection * c);
/* Currently used by WOL RAL2 and YURI clients*/
extern const char * anongame_get_map_from_prefs(int queue, t_clienttag clienttag);
}
/* Currently used by WOL RAL2 and YURI clients*/
extern const char * anongame_get_map_from_prefs(int queue, t_clienttag clienttag);
}
}

View file

@ -30,157 +30,157 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int gameresult_destroy(t_anongame_gameresult * gameresult)
{
if (!(gameresult))
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL gameresult");
return -1;
}
extern int gameresult_destroy(t_anongame_gameresult * gameresult)
{
if (!(gameresult))
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL gameresult");
return -1;
}
if ((gameresult->players)) xfree((void *)gameresult->players);
if ((gameresult->heroes)) xfree((void *)gameresult->heroes);
xfree((void *)gameresult);
if ((gameresult->players)) xfree((void *)gameresult->players);
if ((gameresult->heroes)) xfree((void *)gameresult->heroes);
xfree((void *)gameresult);
return 0;
}
return 0;
}
extern t_anongame_gameresult * anongame_gameresult_parse(t_packet const * const packet)
{
t_anongame_gameresult * gameresult;
t_client_w3route_gameresult_player * player;
t_client_w3route_gameresult_part2 * part2;
t_client_w3route_gameresult_hero * hero;
t_client_w3route_gameresult_part3 * part3;
extern t_anongame_gameresult * anongame_gameresult_parse(t_packet const * const packet)
{
t_anongame_gameresult * gameresult;
t_client_w3route_gameresult_player * player;
t_client_w3route_gameresult_part2 * part2;
t_client_w3route_gameresult_hero * hero;
t_client_w3route_gameresult_part3 * part3;
int counter, heroes_count;
unsigned expectedsize; //still without hero infos
unsigned int offset = 0;
int counter, heroes_count;
unsigned expectedsize; //still without hero infos
unsigned int offset = 0;
int result_count = bn_byte_get(packet->u.client_w3route_gameresult.number_of_results);
expectedsize = sizeof(t_client_w3route_gameresult) +
sizeof(t_client_w3route_gameresult_player) * result_count +
sizeof(t_client_w3route_gameresult_part2) +
sizeof(t_client_w3route_gameresult_part3);
int result_count = bn_byte_get(packet->u.client_w3route_gameresult.number_of_results);
expectedsize = sizeof(t_client_w3route_gameresult)+
sizeof(t_client_w3route_gameresult_player)* result_count +
sizeof(t_client_w3route_gameresult_part2)+
sizeof(t_client_w3route_gameresult_part3);
if (packet_get_size(packet) < expectedsize)
{
eventlog(eventlog_level_error,__FUNCTION__,"gameresult packet is smaller than expected");
return NULL;
}
if (packet_get_size(packet) < expectedsize)
{
eventlog(eventlog_level_error, __FUNCTION__, "gameresult packet is smaller than expected");
return NULL;
}
gameresult = (t_anongame_gameresult*)xmalloc(sizeof(t_anongame_gameresult));
gameresult = (t_anongame_gameresult*)xmalloc(sizeof(t_anongame_gameresult));
gameresult->players = (t_anongame_player*)xmalloc(sizeof(t_anongame_player)*result_count);
gameresult->players = (t_anongame_player*)xmalloc(sizeof(t_anongame_player)*result_count);
gameresult->number_of_results = result_count;
gameresult->number_of_results = result_count;
offset+= sizeof(t_client_w3route_gameresult);
offset += sizeof(t_client_w3route_gameresult);
for (counter=0; counter<result_count;counter++)
{
player = (t_client_w3route_gameresult_player *)packet_get_raw_data_const(packet,offset);
for (counter = 0; counter < result_count; counter++)
{
player = (t_client_w3route_gameresult_player *)packet_get_raw_data_const(packet, offset);
gameresult->players[counter].number = bn_byte_get(player->number);
gameresult->players[counter].result = bn_int_get(player->result);
gameresult->players[counter].race = bn_int_get(player->race);
gameresult->players[counter].number = bn_byte_get(player->number);
gameresult->players[counter].result = bn_int_get(player->result);
gameresult->players[counter].race = bn_int_get(player->race);
offset+= sizeof(t_client_w3route_gameresult_player);
}
offset += sizeof(t_client_w3route_gameresult_player);
}
part2 = (t_client_w3route_gameresult_part2 *)packet_get_raw_data_const(packet,offset);
part2 = (t_client_w3route_gameresult_part2 *)packet_get_raw_data_const(packet, offset);
gameresult->unit_score = bn_int_get(part2->unit_score);
gameresult->heroes_score = bn_int_get(part2->heroes_score);
gameresult->resource_score = bn_int_get(part2->resource_score);
gameresult->units_produced = bn_int_get(part2->units_produced);
gameresult->units_killed = bn_int_get(part2->units_killed);
gameresult->buildings_produced = bn_int_get(part2->buildings_produced);
gameresult->buildings_razed = bn_int_get(part2->buildings_razed);
gameresult->largest_army = bn_int_get(part2->largest_army);
heroes_count = bn_int_get(part2->heroes_used_count);
gameresult->heroes_used_count = heroes_count;
gameresult->unit_score = bn_int_get(part2->unit_score);
gameresult->heroes_score = bn_int_get(part2->heroes_score);
gameresult->resource_score = bn_int_get(part2->resource_score);
gameresult->units_produced = bn_int_get(part2->units_produced);
gameresult->units_killed = bn_int_get(part2->units_killed);
gameresult->buildings_produced = bn_int_get(part2->buildings_produced);
gameresult->buildings_razed = bn_int_get(part2->buildings_razed);
gameresult->largest_army = bn_int_get(part2->largest_army);
heroes_count = bn_int_get(part2->heroes_used_count);
gameresult->heroes_used_count = heroes_count;
offset+= sizeof(t_client_w3route_gameresult_part2);
offset += sizeof(t_client_w3route_gameresult_part2);
if ((heroes_count))
{
gameresult->heroes = (t_anongame_hero*)xmalloc(sizeof(t_anongame_hero)*heroes_count);
if ((heroes_count))
{
gameresult->heroes = (t_anongame_hero*)xmalloc(sizeof(t_anongame_hero)*heroes_count);
if (packet_get_size(packet) < expectedsize + sizeof(t_client_w3route_gameresult_hero)*heroes_count)
{
eventlog(eventlog_level_error,__FUNCTION__,"gameresult packet is smaller than expected");
return NULL;
}
if (packet_get_size(packet) < expectedsize + sizeof(t_client_w3route_gameresult_hero)*heroes_count)
{
eventlog(eventlog_level_error, __FUNCTION__, "gameresult packet is smaller than expected");
return NULL;
}
for (counter=0; counter < heroes_count; counter++)
{
hero = (t_client_w3route_gameresult_hero *)packet_get_raw_data_const(packet,offset);
for (counter = 0; counter < heroes_count; counter++)
{
hero = (t_client_w3route_gameresult_hero *)packet_get_raw_data_const(packet, offset);
gameresult->heroes[counter].level = bn_int_get(hero->level);
gameresult->heroes[counter].race_and_name = bn_int_get(hero->race_and_name);
gameresult->heroes[counter].hero_xp = bn_int_get(hero->hero_xp);
gameresult->heroes[counter].level = bn_int_get(hero->level);
gameresult->heroes[counter].race_and_name = bn_int_get(hero->race_and_name);
gameresult->heroes[counter].hero_xp = bn_int_get(hero->hero_xp);
offset+= sizeof(t_client_w3route_gameresult_hero);
}
}
else
gameresult->heroes = NULL;
offset += sizeof(t_client_w3route_gameresult_hero);
}
}
else
gameresult->heroes = NULL;
part3 = (t_client_w3route_gameresult_part3 *)packet_get_raw_data_const(packet,offset);
part3 = (t_client_w3route_gameresult_part3 *)packet_get_raw_data_const(packet, offset);
gameresult->heroes_killed = bn_int_get(part3->heroes_killed);
gameresult->items_obtained = bn_int_get(part3->items_obtained);
gameresult->mercenaries_hired = bn_int_get(part3->mercenaries_hired);
gameresult->total_hero_xp = bn_int_get(part3->total_hero_xp);
gameresult->gold_mined = bn_int_get(part3->gold_mined);
gameresult->lumber_harvested = bn_int_get(part3->lumber_harvested);
gameresult->resources_traded_given = bn_int_get(part3->resources_traded_given);
gameresult->resources_traded_taken = bn_int_get(part3->resources_traded_taken);
gameresult->tech_percentage = bn_int_get(part3->tech_percentage);
gameresult->gold_lost_to_upkeep = bn_int_get(part3->gold_lost_to_upkeep);
gameresult->heroes_killed = bn_int_get(part3->heroes_killed);
gameresult->items_obtained = bn_int_get(part3->items_obtained);
gameresult->mercenaries_hired = bn_int_get(part3->mercenaries_hired);
gameresult->total_hero_xp = bn_int_get(part3->total_hero_xp);
gameresult->gold_mined = bn_int_get(part3->gold_mined);
gameresult->lumber_harvested = bn_int_get(part3->lumber_harvested);
gameresult->resources_traded_given = bn_int_get(part3->resources_traded_given);
gameresult->resources_traded_taken = bn_int_get(part3->resources_traded_taken);
gameresult->tech_percentage = bn_int_get(part3->tech_percentage);
gameresult->gold_lost_to_upkeep = bn_int_get(part3->gold_lost_to_upkeep);
return gameresult;
}
return gameresult;
}
extern char gameresult_get_number_of_results(t_anongame_gameresult * gameresult)
{
assert(gameresult);
extern char gameresult_get_number_of_results(t_anongame_gameresult * gameresult)
{
assert(gameresult);
return gameresult->number_of_results;
}
return gameresult->number_of_results;
}
extern int gameresult_get_player_result(t_anongame_gameresult * gameresult, int player)
{
if (!(gameresult))
return -1;
extern int gameresult_get_player_result(t_anongame_gameresult * gameresult, int player)
{
if (!(gameresult))
return -1;
if (player >= gameresult->number_of_results)
{
eventlog(eventlog_level_error,__FUNCTION__,"request for invalid player number");
return -1;
}
if (player >= gameresult->number_of_results)
{
eventlog(eventlog_level_error, __FUNCTION__, "request for invalid player number");
return -1;
}
return gameresult->players[player].result;
}
return gameresult->players[player].result;
}
extern int gameresult_get_player_number(t_anongame_gameresult * gameresult, int player)
{
if (!(gameresult))
return -1;
extern int gameresult_get_player_number(t_anongame_gameresult * gameresult, int player)
{
if (!(gameresult))
return -1;
if (player >= gameresult->number_of_results)
{
eventlog(eventlog_level_error,__FUNCTION__,"request for invalid player number");
return -1;
}
if (player >= gameresult->number_of_results)
{
eventlog(eventlog_level_error, __FUNCTION__, "request for invalid player number");
return -1;
}
return gameresult->players[player].number;
}
}
return gameresult->players[player].number;
}
}
}

View file

@ -19,55 +19,55 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
#ifdef ANONGAME_GAMERESULT_INTERNAL_ACCESS
typedef struct
{
char number;
int result;
int race;
} t_anongame_player;
typedef struct
{
char number;
int result;
int race;
} t_anongame_player;
typedef struct
{
int level;
int race_and_name;
int hero_xp;
} t_anongame_hero;
typedef struct
{
int level;
int race_and_name;
int hero_xp;
} t_anongame_hero;
#endif
typedef struct anongame_gameresult_struct
typedef struct anongame_gameresult_struct
#ifdef ANONGAME_GAMERESULT_INTERNAL_ACCESS
{
char number_of_results;
t_anongame_player *players;
int unit_score;
int heroes_score;
int resource_score;
int units_produced;
int units_killed;
int buildings_produced;
int buildings_razed;
int largest_army;
int heroes_used_count;
t_anongame_hero *heroes;
int heroes_killed;
int items_obtained;
int mercenaries_hired;
int total_hero_xp;
int gold_mined;
int lumber_harvested;
int resources_traded_given;
int resources_traded_taken;
int tech_percentage;
int gold_lost_to_upkeep;
}
{
char number_of_results;
t_anongame_player *players;
int unit_score;
int heroes_score;
int resource_score;
int units_produced;
int units_killed;
int buildings_produced;
int buildings_razed;
int largest_army;
int heroes_used_count;
t_anongame_hero *heroes;
int heroes_killed;
int items_obtained;
int mercenaries_hired;
int total_hero_xp;
int gold_mined;
int lumber_harvested;
int resources_traded_given;
int resources_traded_taken;
int tech_percentage;
int gold_lost_to_upkeep;
}
#endif
t_anongame_gameresult;
t_anongame_gameresult;
}
}
}
@ -84,17 +84,17 @@ t_anongame_gameresult;
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern t_anongame_gameresult * anongame_gameresult_parse(t_packet const * const packet);
extern int gameresult_destroy(t_anongame_gameresult * gameresult);
extern t_anongame_gameresult * anongame_gameresult_parse(t_packet const * const packet);
extern int gameresult_destroy(t_anongame_gameresult * gameresult);
extern char gameresult_get_number_of_results(t_anongame_gameresult * gameresult);
extern int gameresult_get_player_result(t_anongame_gameresult * gameresult, int player);
extern int gameresult_get_player_number(t_anongame_gameresult * gameresult, int player);
extern char gameresult_get_number_of_results(t_anongame_gameresult * gameresult);
extern int gameresult_get_player_result(t_anongame_gameresult * gameresult, int player);
extern int gameresult_get_player_number(t_anongame_gameresult * gameresult, int player);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -29,171 +29,171 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef enum
{
URL_server,
URL_player,
URL_tourney,
URL_clan,
typedef enum
{
URL_server,
URL_player,
URL_tourney,
URL_clan,
URL_ladder_PG_1v1,
URL_ladder_PG_ffa,
URL_ladder_PG_team,
URL_ladder_PG_1v1,
URL_ladder_PG_ffa,
URL_ladder_PG_team,
URL_ladder_AT_2v2,
URL_ladder_AT_3v3,
URL_ladder_AT_4v4,
URL_ladder_AT_2v2,
URL_ladder_AT_3v3,
URL_ladder_AT_4v4,
URL_ladder_clan_1v1,
URL_ladder_clan_2v2,
URL_ladder_clan_3v3,
URL_ladder_clan_4v4
} t_anongame_infos_URLs;
URL_ladder_clan_1v1,
URL_ladder_clan_2v2,
URL_ladder_clan_3v3,
URL_ladder_clan_4v4
} t_anongame_infos_URLs;
#define anongame_infos_DESC_count 38
typedef enum {
ladder_PG_1v1_desc,
ladder_PG_ffa_desc,
ladder_PG_team_desc,
typedef enum {
ladder_PG_1v1_desc,
ladder_PG_ffa_desc,
ladder_PG_team_desc,
ladder_AT_2v2_desc,
ladder_AT_3v3_desc,
ladder_AT_4v4_desc,
ladder_AT_2v2_desc,
ladder_AT_3v3_desc,
ladder_AT_4v4_desc,
ladder_clan_1v1_desc,
ladder_clan_2v2_desc,
ladder_clan_3v3_desc,
ladder_clan_4v4_desc,
ladder_clan_1v1_desc,
ladder_clan_2v2_desc,
ladder_clan_3v3_desc,
ladder_clan_4v4_desc,
gametype_1v1_short,
gametype_1v1_long,
gametype_2v2_short,
gametype_2v2_long,
gametype_3v3_short,
gametype_3v3_long,
gametype_4v4_short,
gametype_4v4_long,
gametype_ffa_short,
gametype_ffa_long,
gametype_2v2v2_short,
gametype_2v2v2_long,
gametype_1v1_short,
gametype_1v1_long,
gametype_2v2_short,
gametype_2v2_long,
gametype_3v3_short,
gametype_3v3_long,
gametype_4v4_short,
gametype_4v4_long,
gametype_ffa_short,
gametype_ffa_long,
gametype_2v2v2_short,
gametype_2v2v2_long,
gametype_sffa_short,
gametype_sffa_long,
gametype_tffa_short,
gametype_tffa_long,
gametype_3v3v3_short,
gametype_3v3v3_long,
gametype_4v4v4_short,
gametype_4v4v4_long,
gametype_2v2v2v2_short,
gametype_2v2v2v2_long,
gametype_3v3v3v3_short,
gametype_3v3v3v3_long,
gametype_5v5_short,
gametype_5v5_long,
gametype_6v6_short,
gametype_6v6_long
} t_anongame_infos_DESCs;
gametype_sffa_short,
gametype_sffa_long,
gametype_tffa_short,
gametype_tffa_long,
gametype_3v3v3_short,
gametype_3v3v3_long,
gametype_4v4v4_short,
gametype_4v4v4_long,
gametype_2v2v2v2_short,
gametype_2v2v2v2_long,
gametype_3v3v3v3_short,
gametype_3v3v3v3_long,
gametype_5v5_short,
gametype_5v5_long,
gametype_6v6_short,
gametype_6v6_long
} t_anongame_infos_DESCs;
typedef struct
{
char * langID;
char ** descs;
} t_anongame_infos_DESC;
typedef struct
{
char * langID;
char ** descs;
} t_anongame_infos_DESC;
#define anongame_infos_THUMBSDOWN_count 17
typedef enum {
PG_1v1,
PG_2v2,
PG_3v3,
PG_4v4,
PG_ffa,
AT_2v2,
AT_3v3,
AT_4v4,
PG_2v2v2,
AT_ffa,
PG_5v5,
PG_6v6,
PG_3v3v3,
PG_4v4v4,
PG_2v2v2v2,
PG_3v3v3v3,
AT_2v2v2
} t_anongame_infos_THUMBDOWNs;
typedef enum {
PG_1v1,
PG_2v2,
PG_3v3,
PG_4v4,
PG_ffa,
AT_2v2,
AT_3v3,
AT_4v4,
PG_2v2v2,
AT_ffa,
PG_5v5,
PG_6v6,
PG_3v3v3,
PG_4v4v4,
PG_2v2v2v2,
PG_3v3v3v3,
AT_2v2v2
} t_anongame_infos_THUMBDOWNs;
#define anongame_infos_ICON_REQ_count 14
typedef enum {
ICON_REQ_WAR3_Level1,
ICON_REQ_WAR3_Level2,
ICON_REQ_WAR3_Level3,
ICON_REQ_WAR3_Level4,
ICON_REQ_W3XP_Level1,
ICON_REQ_W3XP_Level2,
ICON_REQ_W3XP_Level3,
ICON_REQ_W3XP_Level4,
ICON_REQ_W3XP_Level5,
ICON_REQ_TRNY_Level1,
ICON_REQ_TRNY_Level2,
ICON_REQ_TRNY_Level3,
ICON_REQ_TRNY_Level4,
ICON_REQ_TRNY_Level5
} t_anongame_infos_ICON_REQs;
typedef enum {
ICON_REQ_WAR3_Level1,
ICON_REQ_WAR3_Level2,
ICON_REQ_WAR3_Level3,
ICON_REQ_WAR3_Level4,
ICON_REQ_W3XP_Level1,
ICON_REQ_W3XP_Level2,
ICON_REQ_W3XP_Level3,
ICON_REQ_W3XP_Level4,
ICON_REQ_W3XP_Level5,
ICON_REQ_TRNY_Level1,
ICON_REQ_TRNY_Level2,
ICON_REQ_TRNY_Level3,
ICON_REQ_TRNY_Level4,
ICON_REQ_TRNY_Level5
} t_anongame_infos_ICON_REQs;
typedef struct {
char * langID;
typedef struct {
char * langID;
char * desc_data;
char * ladr_data;
char * desc_data;
char * ladr_data;
char * desc_comp_data;
char * ladr_comp_data;
char * desc_comp_data;
char * ladr_comp_data;
int desc_len;
int ladr_len;
int desc_len;
int ladr_len;
int desc_comp_len;
int ladr_comp_len;
} t_anongame_infos_data_lang;
int desc_comp_len;
int ladr_comp_len;
} t_anongame_infos_data_lang;
typedef struct {
char * langID;
typedef struct {
char * langID;
char * url_comp_data;
char * url_comp_data_115;
char * map_comp_data;
char * type_comp_data;
char * desc_comp_data;
char * ladr_comp_data;
char * url_comp_data;
char * url_comp_data_115;
char * map_comp_data;
char * type_comp_data;
char * desc_comp_data;
char * ladr_comp_data;
int url_comp_len;
int url_comp_len_115;
int map_comp_len;
int type_comp_len;
int desc_comp_len;
int ladr_comp_len;
} t_anongame_infos_data;
int url_comp_len;
int url_comp_len_115;
int map_comp_len;
int type_comp_len;
int desc_comp_len;
int ladr_comp_len;
} t_anongame_infos_data;
typedef struct {
char ** anongame_infos_URL;
t_anongame_infos_DESC * anongame_infos_DESC; /* for default DESC */
t_list * anongame_infos_DESC_list; /* for localized DESC's */
char anongame_infos_THUMBSDOWN[anongame_infos_THUMBSDOWN_count];
int anongame_infos_ICON_REQ[anongame_infos_ICON_REQ_count];
t_anongame_infos_data * anongame_infos_data_war3;
t_anongame_infos_data * anongame_infos_data_w3xp;
t_list * anongame_infos_data_lang_war3;
t_list * anongame_infos_data_lang_w3xp;
} t_anongame_infos;
typedef struct {
char ** anongame_infos_URL;
t_anongame_infos_DESC * anongame_infos_DESC; /* for default DESC */
t_list * anongame_infos_DESC_list; /* for localized DESC's */
char anongame_infos_THUMBSDOWN[anongame_infos_THUMBSDOWN_count];
int anongame_infos_ICON_REQ[anongame_infos_ICON_REQ_count];
t_anongame_infos_data * anongame_infos_data_war3;
t_anongame_infos_data * anongame_infos_data_w3xp;
t_list * anongame_infos_data_lang_war3;
t_list * anongame_infos_data_lang_w3xp;
} t_anongame_infos;
}
}
}
@ -210,24 +210,24 @@ typedef struct {
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int anongame_infos_load(char const * filename);
extern int anongame_infos_unload(void);
extern int anongame_infos_load(char const * filename);
extern int anongame_infos_unload(void);
extern char anongame_infos_get_thumbsdown(int queue);
extern char anongame_infos_get_thumbsdown(int queue);
extern short anongame_infos_get_ICON_REQ(int Level,t_clienttag clienttag);
extern short anongame_infos_get_ICON_REQ_TOURNEY(int Level);
extern short anongame_infos_get_ICON_REQ(int Level, t_clienttag clienttag);
extern short anongame_infos_get_ICON_REQ_TOURNEY(int Level);
extern char * anongame_infos_data_get_url(t_clienttag clienttag, int versionid, int * len);
extern char * anongame_infos_data_get_map(t_clienttag clienttag, int versionid, int * len);
extern char * anongame_infos_data_get_type(t_clienttag clienttag, int versionid, int * len);
extern char * anongame_infos_data_get_desc(char const * langID, t_clienttag clienttag, int versionid, int * len);
extern char * anongame_infos_data_get_ladr(char const * langID, t_clienttag clienttag, int versionid, int * len);
extern char * anongame_infos_data_get_url(t_clienttag clienttag, int versionid, int * len);
extern char * anongame_infos_data_get_map(t_clienttag clienttag, int versionid, int * len);
extern char * anongame_infos_data_get_type(t_clienttag clienttag, int versionid, int * len);
extern char * anongame_infos_data_get_desc(char const * langID, t_clienttag clienttag, int versionid, int * len);
extern char * anongame_infos_data_get_ladr(char const * langID, t_clienttag clienttag, int versionid, int * len);
}
}
}

View file

@ -36,348 +36,352 @@
namespace pvpgn
{
namespace bnetd
{
static char * maplist_war3[MAXMAPS];
static char * maplist_w3xp[MAXMAPS];
static char * maplist_ral2[MAXMAPS];
static char * maplist_yuri[MAXMAPS];
static int number_maps_war3 = 0;
static int number_maps_w3xp = 0;
static int number_maps_ral2 = 0;
static int number_maps_yuri = 0;
static char maplists_war3[ANONGAME_TYPES][MAXMAPS_PER_QUEUE+1];
static char maplists_w3xp[ANONGAME_TYPES][MAXMAPS_PER_QUEUE+1];
static char maplists_ral2[ANONGAME_TYPES][MAXMAPS_PER_QUEUE+1];
static char maplists_yuri[ANONGAME_TYPES][MAXMAPS_PER_QUEUE+1];
static int _maplists_type_get_queue(const char * type);
static const char * _maplists_queue_get_type(int queue);
static void _maplists_add_map(t_clienttag clienttag, char * mapname, int queue);
/*****/
static const char * queue_names[ANONGAME_TYPES] = {
"1v1","2v2","3v3","4v4","sffa","at2v2","tffa","at3v3","at4v4",
"TY",
"5v5","6v6","2v2v2","3v3v3","4v4v4","2v2v2v2","3v3v3v3",
"at2v2v2"
};
/**********************************************************************************/
static int _maplists_type_get_queue(const char * type)
{
int i;
for (i = 0; i < ANONGAME_TYPES; i++)
if (std::strcmp(type, queue_names[i]) == 0)
return i;
return -1;
}
static const char * _maplists_queue_get_type(int queue)
{
return queue_names[queue];
}
static void _maplists_add_map(t_clienttag clienttag, char * mapname, int queue)
{
/* this function does two things
* 1. adds the mapname to maplist for MAPS section
* maplist[mapnumber] = mapname
* number_maps = total maps held in maplist[]
* 2. adds the mapnumber to maplists for TYPE section
* maplists[queue][0] = number of maps for queue
* maplists[queue][1..32] = mapnumber
* ie. maplist[maplists[queue][1..32]] = mapname
*/
int in_list = 0;
int j;
char clienttag_str[5];
if (clienttag==CLIENTTAG_WARCRAFT3_UINT) {
for (j = 0; j < number_maps_war3; j++) {
if (std::strcmp(maplist_war3[j], mapname) == 0) { /* already in list */
in_list = 1;
break;
}
}
if (!in_list)
maplist_war3[number_maps_war3++] = xstrdup(mapname);
if (maplists_war3[queue][0] < MAXMAPS_PER_QUEUE) {
maplists_war3[queue][0]++;
maplists_war3[queue][(int)maplists_war3[queue][0]] = j;
} else {
eventlog(eventlog_level_error,__FUNCTION__,
"cannot add map \"%s\" for gametype: %s (maxmaps per qametype: %d)",
mapname, _maplists_queue_get_type(queue), MAXMAPS_PER_QUEUE);
}
}
else if (clienttag==CLIENTTAG_WAR3XP_UINT) {
for (j = 0; j < number_maps_w3xp; j++) {
if (std::strcmp(maplist_w3xp[j], mapname) == 0) { /* already in list */
in_list = 1;
break;
}
}
if (!in_list)
maplist_w3xp[number_maps_w3xp++] = xstrdup(mapname);
if (maplists_w3xp[queue][0] < MAXMAPS_PER_QUEUE) {
maplists_w3xp[queue][0]++;
maplists_w3xp[queue][(int)maplists_w3xp[queue][0]] = j;
} else {
eventlog(eventlog_level_error,__FUNCTION__,
"cannot add map \"%s\" for gametype: %s (maxmaps per qametype: %d)",
mapname, _maplists_queue_get_type(queue), MAXMAPS_PER_QUEUE);
}
}
else if (clienttag==CLIENTTAG_REDALERT2_UINT) {
for (j = 0; j < number_maps_ral2; j++) {
if (std::strcmp(maplist_ral2[j], mapname) == 0) { /* already in list */
in_list = 1;
break;
}
}
if (!in_list)
maplist_ral2[number_maps_ral2++] = xstrdup(mapname);
if (maplists_ral2[queue][0] < MAXMAPS_PER_QUEUE) {
maplists_ral2[queue][0]++;
maplists_ral2[queue][(int)maplists_ral2[queue][0]] = j;
} else {
eventlog(eventlog_level_error,__FUNCTION__,
"cannot add map \"%s\" for gametype: %s (maxmaps per qametype: %d)",
mapname, _maplists_queue_get_type(queue), MAXMAPS_PER_QUEUE);
}
}
else if (clienttag==CLIENTTAG_YURISREV_UINT) {
for (j = 0; j < number_maps_yuri; j++) {
if (std::strcmp(maplist_yuri[j], mapname) == 0) { /* already in list */
in_list = 1;
break;
}
}
if (!in_list)
maplist_yuri[number_maps_yuri++] = xstrdup(mapname);
if (maplists_yuri[queue][0] < MAXMAPS_PER_QUEUE) {
maplists_yuri[queue][0]++;
maplists_yuri[queue][(int)maplists_yuri[queue][0]] = j;
} else {
eventlog(eventlog_level_error,__FUNCTION__,
"cannot add map \"%s\" for gametype: %s (maxmaps per qametype: %d)",
mapname, _maplists_queue_get_type(queue), MAXMAPS_PER_QUEUE);
}
}
else eventlog(eventlog_level_error,__FUNCTION__,"invalid clienttag: %s",tag_uint_to_str(clienttag_str,clienttag));
}
/**********************************************************************************/
extern int anongame_maplists_create(void)
{
std::FILE *mapfd;
char buffer[256];
int len, i, queue;
char *p, *q, *r, *u;
if (prefs_get_mapsfile() == NULL) {
eventlog(eventlog_level_error, "anongame_maplists_create","invalid mapsfile, check your config");
return -1;
}
if ((mapfd = std::fopen(prefs_get_mapsfile(), "rt")) == NULL) {
eventlog(eventlog_level_error, "anongame_maplists_create", "could not open mapsfile : \"%s\"", prefs_get_mapsfile());
return -1;
}
/* init the maps, they say static vars are 0-ed anyway but u never know :) */
for(i=0; i < ANONGAME_TYPES; i++) {
maplists_war3[i][0] = 0;
maplists_w3xp[i][0] = 0;
}
while(std::fgets(buffer, 256, mapfd)) {
len = std::strlen(buffer);
if (len < 1) continue;
if (buffer[len-1] == '\n') {
buffer[len-1] = '\0';
}
/* search for comments and comment them out */
for(p = buffer; *p ; p++)
if (*p == '#') {
*p = '\0';
break;
}
/* skip spaces and/or tabs */
for(p = buffer; *p && ( *p == ' ' || *p == '\t' ); p++); /* p = clienttag */
if (*p == '\0') continue;
/* find next delimiter */
for(q = p; *q && *q != ' ' && *q != '\t'; q++);
if (*q == '\0' || q - p != 4) continue; /* clienttag needs to have 4 chars */
*q = '\0'; /* end of clienttag */
/* skip spaces and/or tabs */
for (q++ ; *q && ( *q == ' ' || *q == '\t'); q++); /* q = type */
if (*q == '\0') continue;
/* find next delimiter */
for (r = q+1; *r && *r != ' ' && *r != '\t'; r++);
*r = '\0'; /* end of type */
/* skip spaces and/or tabs */
for (r++ ; *r && ( *r == ' ' || *r == '\t'); r++); /* r = mapname */
if (*r == '\0') continue;
if (*r!='\"') /* mapname without quotes */
/* find next delimiter */
for (u = r+1; *u && *u != ' ' && *u != '\t'; u++);
else /* mapname with quotes */
namespace bnetd
{
r++; /* skip quote */
for (u = r+1; *u && *u != '\"'; u++); /* find end quote or end of buffer */
if (*u!='\"')
{
eventlog(eventlog_level_error,__FUNCTION__,"missing \" at the end of the map name, presume it's ok anyway");
}
static char * maplist_war3[MAXMAPS];
static char * maplist_w3xp[MAXMAPS];
static char * maplist_ral2[MAXMAPS];
static char * maplist_yuri[MAXMAPS];
static int number_maps_war3 = 0;
static int number_maps_w3xp = 0;
static int number_maps_ral2 = 0;
static int number_maps_yuri = 0;
static char maplists_war3[ANONGAME_TYPES][MAXMAPS_PER_QUEUE + 1];
static char maplists_w3xp[ANONGAME_TYPES][MAXMAPS_PER_QUEUE + 1];
static char maplists_ral2[ANONGAME_TYPES][MAXMAPS_PER_QUEUE + 1];
static char maplists_yuri[ANONGAME_TYPES][MAXMAPS_PER_QUEUE + 1];
static int _maplists_type_get_queue(const char * type);
static const char * _maplists_queue_get_type(int queue);
static void _maplists_add_map(t_clienttag clienttag, char * mapname, int queue);
/*****/
static const char * queue_names[ANONGAME_TYPES] = {
"1v1", "2v2", "3v3", "4v4", "sffa", "at2v2", "tffa", "at3v3", "at4v4",
"TY",
"5v5", "6v6", "2v2v2", "3v3v3", "4v4v4", "2v2v2v2", "3v3v3v3",
"at2v2v2"
};
/**********************************************************************************/
static int _maplists_type_get_queue(const char * type)
{
int i;
for (i = 0; i < ANONGAME_TYPES; i++)
if (std::strcmp(type, queue_names[i]) == 0)
return i;
return -1;
}
static const char * _maplists_queue_get_type(int queue)
{
return queue_names[queue];
}
static void _maplists_add_map(t_clienttag clienttag, char * mapname, int queue)
{
/* this function does two things
* 1. adds the mapname to maplist for MAPS section
* maplist[mapnumber] = mapname
* number_maps = total maps held in maplist[]
* 2. adds the mapnumber to maplists for TYPE section
* maplists[queue][0] = number of maps for queue
* maplists[queue][1..32] = mapnumber
* ie. maplist[maplists[queue][1..32]] = mapname
*/
int in_list = 0;
int j;
char clienttag_str[5];
if (clienttag == CLIENTTAG_WARCRAFT3_UINT) {
for (j = 0; j < number_maps_war3; j++) {
if (std::strcmp(maplist_war3[j], mapname) == 0) { /* already in list */
in_list = 1;
break;
}
}
if (!in_list)
maplist_war3[number_maps_war3++] = xstrdup(mapname);
if (maplists_war3[queue][0] < MAXMAPS_PER_QUEUE) {
maplists_war3[queue][0]++;
maplists_war3[queue][(int)maplists_war3[queue][0]] = j;
}
else {
eventlog(eventlog_level_error, __FUNCTION__,
"cannot add map \"%s\" for gametype: %s (maxmaps per qametype: %d)",
mapname, _maplists_queue_get_type(queue), MAXMAPS_PER_QUEUE);
}
}
else if (clienttag == CLIENTTAG_WAR3XP_UINT) {
for (j = 0; j < number_maps_w3xp; j++) {
if (std::strcmp(maplist_w3xp[j], mapname) == 0) { /* already in list */
in_list = 1;
break;
}
}
if (!in_list)
maplist_w3xp[number_maps_w3xp++] = xstrdup(mapname);
if (maplists_w3xp[queue][0] < MAXMAPS_PER_QUEUE) {
maplists_w3xp[queue][0]++;
maplists_w3xp[queue][(int)maplists_w3xp[queue][0]] = j;
}
else {
eventlog(eventlog_level_error, __FUNCTION__,
"cannot add map \"%s\" for gametype: %s (maxmaps per qametype: %d)",
mapname, _maplists_queue_get_type(queue), MAXMAPS_PER_QUEUE);
}
}
else if (clienttag == CLIENTTAG_REDALERT2_UINT) {
for (j = 0; j < number_maps_ral2; j++) {
if (std::strcmp(maplist_ral2[j], mapname) == 0) { /* already in list */
in_list = 1;
break;
}
}
if (!in_list)
maplist_ral2[number_maps_ral2++] = xstrdup(mapname);
if (maplists_ral2[queue][0] < MAXMAPS_PER_QUEUE) {
maplists_ral2[queue][0]++;
maplists_ral2[queue][(int)maplists_ral2[queue][0]] = j;
}
else {
eventlog(eventlog_level_error, __FUNCTION__,
"cannot add map \"%s\" for gametype: %s (maxmaps per qametype: %d)",
mapname, _maplists_queue_get_type(queue), MAXMAPS_PER_QUEUE);
}
}
else if (clienttag == CLIENTTAG_YURISREV_UINT) {
for (j = 0; j < number_maps_yuri; j++) {
if (std::strcmp(maplist_yuri[j], mapname) == 0) { /* already in list */
in_list = 1;
break;
}
}
if (!in_list)
maplist_yuri[number_maps_yuri++] = xstrdup(mapname);
if (maplists_yuri[queue][0] < MAXMAPS_PER_QUEUE) {
maplists_yuri[queue][0]++;
maplists_yuri[queue][(int)maplists_yuri[queue][0]] = j;
}
else {
eventlog(eventlog_level_error, __FUNCTION__,
"cannot add map \"%s\" for gametype: %s (maxmaps per qametype: %d)",
mapname, _maplists_queue_get_type(queue), MAXMAPS_PER_QUEUE);
}
}
else eventlog(eventlog_level_error, __FUNCTION__, "invalid clienttag: %s", tag_uint_to_str(clienttag_str, clienttag));
}
/**********************************************************************************/
extern int anongame_maplists_create(void)
{
std::FILE *mapfd;
char buffer[256];
int len, i, queue;
char *p, *q, *r, *u;
if (prefs_get_mapsfile() == NULL) {
eventlog(eventlog_level_error, "anongame_maplists_create", "invalid mapsfile, check your config");
return -1;
}
if ((mapfd = std::fopen(prefs_get_mapsfile(), "rt")) == NULL) {
eventlog(eventlog_level_error, "anongame_maplists_create", "could not open mapsfile : \"%s\"", prefs_get_mapsfile());
return -1;
}
/* init the maps, they say static vars are 0-ed anyway but u never know :) */
for (i = 0; i < ANONGAME_TYPES; i++) {
maplists_war3[i][0] = 0;
maplists_w3xp[i][0] = 0;
}
while (std::fgets(buffer, 256, mapfd)) {
len = std::strlen(buffer);
if (len < 1) continue;
if (buffer[len - 1] == '\n') {
buffer[len - 1] = '\0';
}
/* search for comments and comment them out */
for (p = buffer; *p; p++)
if (*p == '#') {
*p = '\0';
break;
}
/* skip spaces and/or tabs */
for (p = buffer; *p && (*p == ' ' || *p == '\t'); p++); /* p = clienttag */
if (*p == '\0') continue;
/* find next delimiter */
for (q = p; *q && *q != ' ' && *q != '\t'; q++);
if (*q == '\0' || q - p != 4) continue; /* clienttag needs to have 4 chars */
*q = '\0'; /* end of clienttag */
/* skip spaces and/or tabs */
for (q++; *q && (*q == ' ' || *q == '\t'); q++); /* q = type */
if (*q == '\0') continue;
/* find next delimiter */
for (r = q + 1; *r && *r != ' ' && *r != '\t'; r++);
*r = '\0'; /* end of type */
/* skip spaces and/or tabs */
for (r++; *r && (*r == ' ' || *r == '\t'); r++); /* r = mapname */
if (*r == '\0') continue;
if (*r != '\"') /* mapname without quotes */
/* find next delimiter */
for (u = r + 1; *u && *u != ' ' && *u != '\t'; u++);
else /* mapname with quotes */
{
r++; /* skip quote */
for (u = r + 1; *u && *u != '\"'; u++); /* find end quote or end of buffer */
if (*u != '\"')
{
eventlog(eventlog_level_error, __FUNCTION__, "missing \" at the end of the map name, presume it's ok anyway");
}
}
*u = '\0'; /* end of mapname */
if ((queue = _maplists_type_get_queue(q)) < 0) continue; /* invalid queue */
_maplists_add_map(tag_case_str_to_uint(p), r, queue);
}
std::fclose(mapfd);
return 0;
}
/* used by the MAPS section */
extern int maplists_get_totalmaps(t_clienttag clienttag)
{
switch (clienttag) {
case CLIENTTAG_WARCRAFT3_UINT:
return number_maps_war3;
case CLIENTTAG_WAR3XP_UINT:
return number_maps_w3xp;
case CLIENTTAG_REDALERT2_UINT:
return number_maps_ral2;
case CLIENTTAG_YURISREV_UINT:
return number_maps_yuri;
default:
ERROR0("Unknown clienttag");
return 0;
}
return 0;
}
extern void maplists_add_maps_to_packet(t_packet * packet, t_clienttag clienttag)
{
int i;
if (clienttag == CLIENTTAG_WARCRAFT3_UINT)
for (i = 0; i < number_maps_war3; i++)
packet_append_string(packet, maplist_war3[i]);
if (clienttag == CLIENTTAG_WAR3XP_UINT)
for (i = 0; i < number_maps_w3xp; i++)
packet_append_string(packet, maplist_w3xp[i]);
}
/* used by TYPE section */
extern int maplists_get_totalmaps_by_queue(t_clienttag clienttag, int queue)
{
switch (clienttag) {
case CLIENTTAG_WARCRAFT3_UINT:
return maplists_war3[queue][0];
case CLIENTTAG_WAR3XP_UINT:
return maplists_w3xp[queue][0];
case CLIENTTAG_REDALERT2_UINT:
return maplists_ral2[queue][0];
case CLIENTTAG_YURISREV_UINT:
return maplists_yuri[queue][0];
default:
ERROR0("Unknown clienttag");
return 0;
}
return 0;
}
extern void maplists_add_map_info_to_packet(t_packet * rpacket, t_clienttag clienttag, int queue)
{
int i;
if (clienttag == CLIENTTAG_WARCRAFT3_UINT) {
for (i = 0; i < maplists_war3[queue][0] + 1; i++)
packet_append_data(rpacket, &maplists_war3[queue][i], 1);
}
if (clienttag == CLIENTTAG_WAR3XP_UINT) {
for (i = 0; i < maplists_w3xp[queue][0] + 1; i++)
packet_append_data(rpacket, &maplists_w3xp[queue][i], 1);
}
}
/* used by _get_map_from_prefs() */
extern char * maplists_get_map(int queue, t_clienttag clienttag, int mapnumber)
{
switch (clienttag) {
case CLIENTTAG_WARCRAFT3_UINT:
return maplist_war3[(int)maplists_war3[queue][mapnumber]];
case CLIENTTAG_WAR3XP_UINT:
return maplist_w3xp[(int)maplists_w3xp[queue][mapnumber]];
case CLIENTTAG_REDALERT2_UINT:
return maplist_ral2[(int)maplists_ral2[queue][mapnumber]];
case CLIENTTAG_YURISREV_UINT:
return maplist_yuri[(int)maplists_yuri[queue][mapnumber]];
default:
ERROR0("Unknown clienttag");
return NULL;
}
}
extern void anongame_maplists_destroy()
{
int i;
for (i = 0; i < MAXMAPS; i++) {
if (maplist_war3[i])
xfree((void *)maplist_war3[i]);
if (maplist_w3xp[i])
xfree((void *)maplist_w3xp[i]);
if (maplist_ral2[i])
xfree((void *)maplist_ral2[i]);
if (maplist_yuri[i])
xfree((void *)maplist_yuri[i]);
}
}
extern int anongame_add_tournament_map(t_clienttag clienttag, char * mapname)
{
_maplists_add_map(clienttag, mapname, ANONGAME_TYPE_TY);
return 0;
}
extern void anongame_tournament_maplists_destroy(void)
{
return; /* nothing to destroy */
}
}
*u = '\0'; /* end of mapname */
if ((queue = _maplists_type_get_queue(q)) < 0) continue; /* invalid queue */
_maplists_add_map(tag_case_str_to_uint(p), r, queue);
}
std::fclose(mapfd);
return 0;
}
/* used by the MAPS section */
extern int maplists_get_totalmaps(t_clienttag clienttag)
{
switch (clienttag) {
case CLIENTTAG_WARCRAFT3_UINT:
return number_maps_war3;
case CLIENTTAG_WAR3XP_UINT:
return number_maps_w3xp;
case CLIENTTAG_REDALERT2_UINT:
return number_maps_ral2;
case CLIENTTAG_YURISREV_UINT:
return number_maps_yuri;
default:
ERROR0("Unknown clienttag");
return 0;
}
return 0;
}
extern void maplists_add_maps_to_packet(t_packet * packet, t_clienttag clienttag)
{
int i;
if (clienttag==CLIENTTAG_WARCRAFT3_UINT)
for (i = 0; i < number_maps_war3; i++)
packet_append_string(packet, maplist_war3[i]);
if (clienttag==CLIENTTAG_WAR3XP_UINT)
for (i = 0; i < number_maps_w3xp; i++)
packet_append_string(packet, maplist_w3xp[i]);
}
/* used by TYPE section */
extern int maplists_get_totalmaps_by_queue(t_clienttag clienttag, int queue)
{
switch (clienttag) {
case CLIENTTAG_WARCRAFT3_UINT:
return maplists_war3[queue][0];
case CLIENTTAG_WAR3XP_UINT:
return maplists_w3xp[queue][0];
case CLIENTTAG_REDALERT2_UINT:
return maplists_ral2[queue][0];
case CLIENTTAG_YURISREV_UINT:
return maplists_yuri[queue][0];
default:
ERROR0("Unknown clienttag");
return 0;
}
return 0;
}
extern void maplists_add_map_info_to_packet(t_packet * rpacket, t_clienttag clienttag, int queue)
{
int i;
if (clienttag==CLIENTTAG_WARCRAFT3_UINT) {
for (i = 0; i < maplists_war3[queue][0] + 1; i++)
packet_append_data(rpacket, &maplists_war3[queue][i], 1);
}
if (clienttag==CLIENTTAG_WAR3XP_UINT) {
for (i = 0; i < maplists_w3xp[queue][0] + 1; i++)
packet_append_data(rpacket, &maplists_w3xp[queue][i], 1);
}
}
/* used by _get_map_from_prefs() */
extern char * maplists_get_map(int queue, t_clienttag clienttag, int mapnumber)
{
switch (clienttag) {
case CLIENTTAG_WARCRAFT3_UINT:
return maplist_war3[(int)maplists_war3[queue][mapnumber]];
case CLIENTTAG_WAR3XP_UINT:
return maplist_w3xp[(int)maplists_w3xp[queue][mapnumber]];
case CLIENTTAG_REDALERT2_UINT:
return maplist_ral2[(int)maplists_ral2[queue][mapnumber]];
case CLIENTTAG_YURISREV_UINT:
return maplist_yuri[(int)maplists_yuri[queue][mapnumber]];
default:
ERROR0("Unknown clienttag");
return NULL;
}
}
extern void anongame_maplists_destroy()
{
int i;
for (i = 0; i < MAXMAPS; i++) {
if (maplist_war3[i])
xfree((void *)maplist_war3[i]);
if (maplist_w3xp[i])
xfree((void *)maplist_w3xp[i]);
if (maplist_ral2[i])
xfree((void *)maplist_ral2[i]);
if (maplist_yuri[i])
xfree((void *)maplist_yuri[i]);
}
}
extern int anongame_add_tournament_map(t_clienttag clienttag, char * mapname)
{
_maplists_add_map(clienttag, mapname, ANONGAME_TYPE_TY);
return 0;
}
extern void anongame_tournament_maplists_destroy(void)
{
return; /* nothing to destroy */
}
}
}

View file

@ -33,24 +33,24 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int anongame_maplists_create(void);
extern void anongame_maplists_destroy(void);
extern int anongame_maplists_create(void);
extern void anongame_maplists_destroy(void);
extern int maplists_get_totalmaps(t_clienttag clienttag);
extern int maplists_get_totalmaps_by_queue(t_clienttag clienttag, int queue);
extern int maplists_get_totalmaps(t_clienttag clienttag);
extern int maplists_get_totalmaps_by_queue(t_clienttag clienttag, int queue);
extern void maplists_add_maps_to_packet(t_packet * packet, t_clienttag clienttag);
extern void maplists_add_map_info_to_packet(t_packet * rpacket, t_clienttag clienttag, int queue);
extern void maplists_add_maps_to_packet(t_packet * packet, t_clienttag clienttag);
extern void maplists_add_map_info_to_packet(t_packet * rpacket, t_clienttag clienttag, int queue);
extern char * maplists_get_map(int queue, t_clienttag clienttag, int mapnumber);
extern char * maplists_get_map(int queue, t_clienttag clienttag, int mapnumber);
extern int anongame_add_tournament_map(t_clienttag clienttag, char * mapname);
extern void anongame_tournament_maplists_destroy(void);
extern int anongame_add_tournament_map(t_clienttag clienttag, char * mapname);
extern void anongame_tournament_maplists_destroy(void);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -44,24 +44,24 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef struct anongame_wol_player
typedef struct anongame_wol_player
#ifdef ANONGAME_WOL_INTERNAL_ACCESS
{
t_connection * conn;
{
t_connection * conn;
/* Red Alert 2 and Yuri's Revnenge */
int address;
int port;
int country;
int colour;
}
/* Red Alert 2 and Yuri's Revnenge */
int address;
int port;
int country;
int colour;
}
#endif
t_anongame_wol_player;
t_anongame_wol_player;
}
}
}
@ -79,16 +79,16 @@ t_anongame_wol_player;
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int anongame_wol_matchlist_create(void);
extern int anongame_wol_matchlist_destroy(void);
extern int anongame_wol_matchlist_create(void);
extern int anongame_wol_matchlist_destroy(void);
extern int anongame_wol_destroy(t_connection * conn);
extern int anongame_wol_privmsg(t_connection * conn, int numparams, char ** params, char * text);
extern int anongame_wol_destroy(t_connection * conn);
extern int anongame_wol_privmsg(t_connection * conn, int numparams, char ** params, char * text);
}
}
}

View file

@ -25,73 +25,73 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef struct attr_struct {
const char *key;
const char *val;
int dirty;
t_hlist link;
} t_attr;
typedef struct attr_struct {
const char *key;
const char *val;
int dirty;
t_hlist link;
} t_attr;
static inline t_attr *attr_create(const char *key, const char *val)
{
t_attr *attr;
static inline t_attr *attr_create(const char *key, const char *val)
{
t_attr *attr;
attr = (t_attr*)xmalloc(sizeof(t_attr));
attr->dirty = 0;
hlist_init(&attr->link);
attr->key = key ? xstrdup(key) : NULL;
attr->val = val ? xstrdup(val) : NULL;
attr = (t_attr*)xmalloc(sizeof(t_attr));
attr->dirty = 0;
hlist_init(&attr->link);
attr->key = key ? xstrdup(key) : NULL;
attr->val = val ? xstrdup(val) : NULL;
return attr;
}
return attr;
}
static inline int attr_destroy(t_attr *attr)
{
if (attr->key) xfree((void*)attr->key);
if (attr->val) xfree((void*)attr->val);
static inline int attr_destroy(t_attr *attr)
{
if (attr->key) xfree((void*)attr->key);
if (attr->val) xfree((void*)attr->val);
xfree((void*)attr);
xfree((void*)attr);
return 0;
}
return 0;
}
static inline int attr_get_dirty(t_attr *attr)
{
return attr->dirty;
}
static inline int attr_get_dirty(t_attr *attr)
{
return attr->dirty;
}
static inline void attr_clear_dirty(t_attr *attr)
{
attr->dirty = 0;
}
static inline void attr_clear_dirty(t_attr *attr)
{
attr->dirty = 0;
}
static inline const char *attr_get_key(t_attr *attr)
{
return attr->key;
}
static inline const char *attr_get_key(t_attr *attr)
{
return attr->key;
}
static inline const char *attr_get_val(t_attr *attr)
{
return attr->val;
}
static inline const char *attr_get_val(t_attr *attr)
{
return attr->val;
}
static inline void attr_set_val(t_attr *attr, const char *val)
{
if (attr->val) xfree((void*)attr->val);
static inline void attr_set_val(t_attr *attr, const char *val)
{
if (attr->val) xfree((void*)attr->val);
if (val) attr->val = xstrdup(val);
else attr->val = NULL;
}
if (val) attr->val = xstrdup(val);
else attr->val = NULL;
}
static inline void attr_set_dirty(t_attr *attr)
{
attr->dirty = 1;
}
static inline void attr_set_dirty(t_attr *attr)
{
attr->dirty = 1;
}
}
}
}

View file

@ -39,402 +39,405 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
static inline void attrgroup_set_accessed(t_attrgroup *attrgroup)
{
FLAG_SET(&attrgroup->flags, ATTRGROUP_FLAG_ACCESSED);
attrgroup->lastaccess = now;
attrlayer_accessed(attrgroup);
}
static inline void attrgroup_set_accessed(t_attrgroup *attrgroup)
{
FLAG_SET(&attrgroup->flags, ATTRGROUP_FLAG_ACCESSED);
attrgroup->lastaccess = now;
attrlayer_accessed(attrgroup);
}
static inline void attrgroup_clear_accessed(t_attrgroup *attrgroup)
{
FLAG_CLEAR(&attrgroup->flags, ATTRGROUP_FLAG_ACCESSED);
}
static inline void attrgroup_clear_accessed(t_attrgroup *attrgroup)
{
FLAG_CLEAR(&attrgroup->flags, ATTRGROUP_FLAG_ACCESSED);
}
static inline void attrgroup_set_dirty(t_attrgroup *attrgroup)
{
if (FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_DIRTY)) return;
static inline void attrgroup_set_dirty(t_attrgroup *attrgroup)
{
if (FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_DIRTY)) return;
attrgroup->dirtytime = now;
FLAG_SET(&attrgroup->flags, ATTRGROUP_FLAG_DIRTY);
attrlayer_add_dirtylist(&attrgroup->dirtylist);
}
static inline void attrgroup_clear_dirty(t_attrgroup *attrgroup)
{
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_DIRTY)) return;
FLAG_CLEAR(&attrgroup->flags, ATTRGROUP_FLAG_DIRTY);
attrlayer_del_dirtylist(&attrgroup->dirtylist);
}
static inline void attrgroup_set_loaded(t_attrgroup *attrgroup)
{
if (FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED)) return;
FLAG_SET(&attrgroup->flags, ATTRGROUP_FLAG_LOADED);
attrlayer_add_loadedlist(&attrgroup->loadedlist);
}
static inline void attrgroup_clear_loaded(t_attrgroup *attrgroup)
{
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED)) return;
attrgroup->dirtytime = now;
FLAG_SET(&attrgroup->flags, ATTRGROUP_FLAG_DIRTY);
attrlayer_add_dirtylist(&attrgroup->dirtylist);
}
static inline void attrgroup_clear_dirty(t_attrgroup *attrgroup)
{
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_DIRTY)) return;
FLAG_CLEAR(&attrgroup->flags, ATTRGROUP_FLAG_DIRTY);
attrlayer_del_dirtylist(&attrgroup->dirtylist);
}
static inline void attrgroup_set_loaded(t_attrgroup *attrgroup)
{
if (FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED)) return;
FLAG_SET(&attrgroup->flags, ATTRGROUP_FLAG_LOADED);
attrlayer_add_loadedlist(&attrgroup->loadedlist);
}
static inline void attrgroup_clear_loaded(t_attrgroup *attrgroup)
{
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED)) return;
/* clear this because they are not valid if attrgroup is unloaded */
attrgroup_clear_dirty(attrgroup);
attrgroup_clear_accessed(attrgroup);
/* clear this because they are not valid if attrgroup is unloaded */
attrgroup_clear_dirty(attrgroup);
attrgroup_clear_accessed(attrgroup);
FLAG_CLEAR(&attrgroup->flags, ATTRGROUP_FLAG_LOADED);
attrlayer_del_loadedlist(&attrgroup->loadedlist);
}
FLAG_CLEAR(&attrgroup->flags, ATTRGROUP_FLAG_LOADED);
attrlayer_del_loadedlist(&attrgroup->loadedlist);
}
static t_attrgroup * attrgroup_create(void)
{
t_attrgroup *attrgroup;
static t_attrgroup * attrgroup_create(void)
{
t_attrgroup *attrgroup;
attrgroup = (t_attrgroup*)xmalloc(sizeof(t_attrgroup));
attrgroup = (t_attrgroup*)xmalloc(sizeof(t_attrgroup));
hlist_init(&attrgroup->list);
attrgroup->storage = NULL;
attrgroup->flags = ATTRGROUP_FLAG_NONE;
attrgroup->lastaccess = 0;
attrgroup->dirtytime = 0;
elist_init(&attrgroup->loadedlist);
elist_init(&attrgroup->dirtylist);
hlist_init(&attrgroup->list);
attrgroup->storage = NULL;
attrgroup->flags = ATTRGROUP_FLAG_NONE;
attrgroup->lastaccess = 0;
attrgroup->dirtytime = 0;
elist_init(&attrgroup->loadedlist);
elist_init(&attrgroup->dirtylist);
return attrgroup;
}
return attrgroup;
}
extern t_attrgroup * attrgroup_create_storage(t_storage_info *storage)
{
t_attrgroup *attrgroup;
extern t_attrgroup * attrgroup_create_storage(t_storage_info *storage)
{
t_attrgroup *attrgroup;
attrgroup = attrgroup_create();
attrgroup->storage = storage;
attrgroup = attrgroup_create();
attrgroup->storage = storage;
return attrgroup;
}
return attrgroup;
}
extern t_attrgroup * attrgroup_create_newuser(const char *name)
{
t_attrgroup *attrgroup;
t_storage_info *stmp;
extern t_attrgroup * attrgroup_create_newuser(const char *name)
{
t_attrgroup *attrgroup;
t_storage_info *stmp;
stmp = storage->create_account(name);
if (!stmp) {
eventlog(eventlog_level_error,__FUNCTION__,"failed to add user '%s' to storage", name);
return NULL;
}
stmp = storage->create_account(name);
if (!stmp) {
eventlog(eventlog_level_error, __FUNCTION__, "failed to add user '%s' to storage", name);
return NULL;
}
attrgroup = attrgroup_create_storage(stmp);
attrgroup = attrgroup_create_storage(stmp);
/* new accounts are born loaded */
attrgroup_set_loaded(attrgroup);
/* new accounts are born loaded */
attrgroup_set_loaded(attrgroup);
return attrgroup;
}
return attrgroup;
}
extern t_attrgroup * attrgroup_create_nameuid(const char *name, unsigned uid)
{
t_storage_info *info;
t_attrgroup *attrgroup;
extern t_attrgroup * attrgroup_create_nameuid(const char *name, unsigned uid)
{
t_storage_info *info;
t_attrgroup *attrgroup;
info = storage->read_account(name,uid);
if (!info) return NULL;
attrgroup = attrgroup_create_storage(info);
info = storage->read_account(name, uid);
if (!info) return NULL;
attrgroup = attrgroup_create_storage(info);
return attrgroup;
}
return attrgroup;
}
extern int attrgroup_destroy(t_attrgroup *attrgroup)
{
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return -1;
}
extern int attrgroup_destroy(t_attrgroup *attrgroup)
{
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return -1;
}
attrgroup_unload(attrgroup);
if (attrgroup->storage) storage->free_info(attrgroup->storage);
xfree(attrgroup);
attrgroup_unload(attrgroup);
if (attrgroup->storage) storage->free_info(attrgroup->storage);
xfree(attrgroup);
return 0;
}
return 0;
}
extern int attrgroup_save(t_attrgroup *attrgroup, int flags)
{
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return -1;
}
extern int attrgroup_save(t_attrgroup *attrgroup, int flags)
{
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return -1;
}
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED))
return 0;
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED))
return 0;
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_DIRTY))
return 0;
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_DIRTY))
return 0;
if (!FLAG_ISSET(flags, FS_FORCE) && now - attrgroup->dirtytime < prefs_get_user_sync_timer())
return 0;
if (!FLAG_ISSET(flags, FS_FORCE) && now - attrgroup->dirtytime < prefs_get_user_sync_timer())
return 0;
assert(attrgroup->storage);
assert(attrgroup->storage);
storage->write_attrs(attrgroup->storage, &attrgroup->list);
attrgroup_clear_dirty(attrgroup);
storage->write_attrs(attrgroup->storage, &attrgroup->list);
attrgroup_clear_dirty(attrgroup);
return 1;
}
return 1;
}
extern int attrgroup_flush(t_attrgroup *attrgroup, int flags)
{
t_attr *attr;
t_hlist *curr, *save;
extern int attrgroup_flush(t_attrgroup *attrgroup, int flags)
{
t_attr *attr;
t_hlist *curr, *save;
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return -1;
}
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED))
return 0;
if (!FLAG_ISSET(flags, FS_FORCE) &&
FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_ACCESSED) &&
now - attrgroup->lastaccess < prefs_get_user_flush_timer())
return 0;
/* sync data to disk if dirty */
attrgroup_save(attrgroup, FS_FORCE);
hlist_for_each_safe(curr, &attrgroup->list, save) {
attr = hlist_entry(curr, t_attr, link);
attr_destroy(attr);
}
hlist_init(&attrgroup->list); /* reset list */
attrgroup_clear_loaded(attrgroup);
return 1;
}
static int _cb_load_attr(const char *key, const char *val, void *data)
{
t_attrgroup *attrgroup = (t_attrgroup *)data;
return attrgroup_set_attr(attrgroup, key, val);
}
extern int attrgroup_load(t_attrgroup *attrgroup)
{
assert(attrgroup);
assert(attrgroup->storage);
if (FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED)) /* already done */
return 0;
if (FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_DIRTY)) { /* if not loaded, how dirty ? */
eventlog(eventlog_level_error, __FUNCTION__, "can't load modified account");
return -1;
}
attrgroup_set_loaded(attrgroup);
if (storage->read_attrs(attrgroup->storage, _cb_load_attr, attrgroup)) {
eventlog(eventlog_level_error, __FUNCTION__, "got error loading attributes");
return -1;
}
attrgroup_clear_dirty(attrgroup);
return 0;
}
extern int attrgroup_unload(t_attrgroup *attrgroup)
{
attrgroup_flush(attrgroup, FS_FORCE);
return 0;
}
typedef struct {
void *data;
t_attr_cb cb;
} t_attr_cb_data;
static int _cb_read_accounts(t_storage_info *info, void *data)
{
t_attrgroup *attrgroup;
t_attr_cb_data *cbdata = (t_attr_cb_data*)data;
attrgroup = attrgroup_create_storage(info);
return cbdata->cb(attrgroup, cbdata->data);
}
extern int attrgroup_read_accounts(int flag, t_attr_cb cb, void *data)
{
t_attr_cb_data cbdata;
cbdata.cb = cb;
cbdata.data = data;
return storage->read_accounts(flag, _cb_read_accounts, &cbdata);
}
static const char *attrgroup_escape_key(const char *key)
{
const char *newkey, *newkey2;
char *tmp;
newkey = key;
if (!strncasecmp(key, "DynKey", 6)) {
/* OLD COMMENT, MIGHT NOT BE VALID ANYMORE
* Recent Starcraft clients seems to query DynKey\*\1\rank instead of
* Record\*\1\rank. So replace Dynkey with Record for key lookup.
*/
tmp = xstrdup(key);
std::strncpy(tmp, "Record", 6);
newkey = tmp;
}
else if (!std::strncmp(key, "Star", 4)) {
/* OLD COMMENT
* Starcraft clients query Star instead of STAR on logon screen.
*/
tmp = xstrdup(key);
std::strncpy(tmp, "STAR", 4);
newkey = tmp;
}
if (newkey != key) {
newkey2 = storage->escape_key(newkey);
if (newkey2 != newkey) {
xfree((void*)newkey);
newkey = newkey2;
}
}
else newkey = storage->escape_key(key);
return newkey;
}
static t_attr *attrgroup_find_attr(t_attrgroup *attrgroup, const char *pkey[], int escape)
{
const char *val;
t_hlist *curr, *last, *last2;
t_attr *attr;
assert(attrgroup);
assert(pkey);
assert(*pkey);
/* trigger loading of attributes if not loaded already */
if (attrgroup_load(attrgroup)) return NULL; /* eventlog happens earlier */
/* only if the callers tell us to */
if (escape) *pkey = attrgroup_escape_key(*pkey);
/* we are doing attribute lookup so we are accessing it */
attrgroup_set_accessed(attrgroup);
last = &attrgroup->list;
last2 = NULL;
hlist_for_each(curr, &attrgroup->list) {
attr = hlist_entry(curr, t_attr, link);
if (!strcasecmp(attr_get_key(attr), *pkey)) {
val = attr_get_val(attr);
/* key found, promote it so it's found faster next time */
hlist_promote(curr, last, last2);
break;
}
last2 = last; last = curr;
}
if (curr == &attrgroup->list) { /* no key found in cached list */
attr = (t_attr*)storage->read_attr(attrgroup->storage, *pkey);
if (attr) hlist_add(&attrgroup->list, &attr->link);
}
/* "attr" here can either have a proper value found in the cached list, or
* a value returned by storage->read_attr, or NULL */
return attr;
}
/* low-level get attr, receives a flag to tell if it needs to escape key */
static const char *attrgroup_get_attrlow(t_attrgroup *attrgroup, const char *key, int escape)
{
const char *val = NULL;
const char *newkey = key;
t_attr *attr;
/* no need to check for attrgroup, key */
attr = attrgroup_find_attr(attrgroup, &newkey, escape);
if (attr) val = attr_get_val(attr);
if (!val && attrgroup != attrlayer_get_defattrgroup())
val = attrgroup_get_attrlow(attrlayer_get_defattrgroup(), newkey, 0);
if (newkey != key) xfree((void*)newkey);
return val;
}
extern const char *attrgroup_get_attr(t_attrgroup *attrgroup, const char *key)
{
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return NULL;
}
if (!key) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL key");
return NULL;
}
return attrgroup_get_attrlow(attrgroup, key, 1);
}
extern int attrgroup_set_attr(t_attrgroup *attrgroup, const char *key, const char *val)
{
t_attr *attr;
const char *newkey = key;
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return -1;
}
if (!key) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL key");
return -1;
}
attr = attrgroup_find_attr(attrgroup, &newkey, 1);
if (attr) {
if (attr_get_val(attr) == val ||
(attr_get_val(attr) && val && !std::strcmp(attr_get_val(attr), val)))
goto out; /* no need to modify anything, values are the same */
/* new value for existent key, replace the old one */
attr_set_val(attr, val);
}
else { /* unknown key so add new attr */
attr = attr_create(newkey, val);
hlist_add(&attrgroup->list, &attr->link);
}
/* we have modified this attr and attrgroup */
attr_set_dirty(attr);
attrgroup_set_dirty(attrgroup);
out:
if (newkey != key) xfree((void*)newkey);
return 0;
}
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return -1;
}
if (!FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED))
return 0;
if (!FLAG_ISSET(flags, FS_FORCE) &&
FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_ACCESSED) &&
now - attrgroup->lastaccess < prefs_get_user_flush_timer())
return 0;
/* sync data to disk if dirty */
attrgroup_save(attrgroup,FS_FORCE);
hlist_for_each_safe(curr,&attrgroup->list,save) {
attr = hlist_entry(curr,t_attr,link);
attr_destroy(attr);
}
hlist_init(&attrgroup->list); /* reset list */
attrgroup_clear_loaded(attrgroup);
return 1;
}
static int _cb_load_attr(const char *key, const char *val, void *data)
{
t_attrgroup *attrgroup = (t_attrgroup *)data;
return attrgroup_set_attr(attrgroup, key, val);
}
extern int attrgroup_load(t_attrgroup *attrgroup)
{
assert(attrgroup);
assert(attrgroup->storage);
if (FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_LOADED)) /* already done */
return 0;
if (FLAG_ISSET(attrgroup->flags, ATTRGROUP_FLAG_DIRTY)) { /* if not loaded, how dirty ? */
eventlog(eventlog_level_error, __FUNCTION__, "can't load modified account");
return -1;
}
attrgroup_set_loaded(attrgroup);
if (storage->read_attrs(attrgroup->storage, _cb_load_attr, attrgroup)) {
eventlog(eventlog_level_error, __FUNCTION__, "got error loading attributes");
return -1;
}
attrgroup_clear_dirty(attrgroup);
return 0;
}
extern int attrgroup_unload(t_attrgroup *attrgroup)
{
attrgroup_flush(attrgroup,FS_FORCE);
return 0;
}
typedef struct {
void *data;
t_attr_cb cb;
} t_attr_cb_data;
static int _cb_read_accounts(t_storage_info *info, void *data)
{
t_attrgroup *attrgroup;
t_attr_cb_data *cbdata = (t_attr_cb_data*)data;
attrgroup = attrgroup_create_storage(info);
return cbdata->cb(attrgroup,cbdata->data);
}
extern int attrgroup_read_accounts(int flag, t_attr_cb cb, void *data)
{
t_attr_cb_data cbdata;
cbdata.cb = cb;
cbdata.data = data;
return storage->read_accounts(flag, _cb_read_accounts, &cbdata);
}
static const char *attrgroup_escape_key(const char *key)
{
const char *newkey, *newkey2;
char *tmp;
newkey = key;
if (!strncasecmp(key,"DynKey",6)) {
/* OLD COMMENT, MIGHT NOT BE VALID ANYMORE
* Recent Starcraft clients seems to query DynKey\*\1\rank instead of
* Record\*\1\rank. So replace Dynkey with Record for key lookup.
*/
tmp = xstrdup(key);
std::strncpy(tmp,"Record",6);
newkey = tmp;
} else if (!std::strncmp(key,"Star",4)) {
/* OLD COMMENT
* Starcraft clients query Star instead of STAR on logon screen.
*/
tmp = xstrdup(key);
std::strncpy(tmp,"STAR",4);
newkey = tmp;
}
if (newkey != key) {
newkey2 = storage->escape_key(newkey);
if (newkey2 != newkey) {
xfree((void*)newkey);
newkey = newkey2;
}
} else newkey = storage->escape_key(key);
return newkey;
}
static t_attr *attrgroup_find_attr(t_attrgroup *attrgroup, const char *pkey[], int escape)
{
const char *val;
t_hlist *curr, *last, *last2;
t_attr *attr;
assert(attrgroup);
assert(pkey);
assert(*pkey);
/* trigger loading of attributes if not loaded already */
if (attrgroup_load(attrgroup)) return NULL; /* eventlog happens earlier */
/* only if the callers tell us to */
if (escape) *pkey = attrgroup_escape_key(*pkey);
/* we are doing attribute lookup so we are accessing it */
attrgroup_set_accessed(attrgroup);
last = &attrgroup->list;
last2 = NULL;
hlist_for_each(curr,&attrgroup->list) {
attr = hlist_entry(curr, t_attr, link);
if (!strcasecmp(attr_get_key(attr),*pkey)) {
val = attr_get_val(attr);
/* key found, promote it so it's found faster next time */
hlist_promote(curr, last, last2);
break;
}
last2 = last; last = curr;
}
if (curr == &attrgroup->list) { /* no key found in cached list */
attr = (t_attr*)storage->read_attr(attrgroup->storage, *pkey);
if (attr) hlist_add(&attrgroup->list, &attr->link);
}
/* "attr" here can either have a proper value found in the cached list, or
* a value returned by storage->read_attr, or NULL */
return attr;
}
/* low-level get attr, receives a flag to tell if it needs to escape key */
static const char *attrgroup_get_attrlow(t_attrgroup *attrgroup, const char *key, int escape)
{
const char *val = NULL;
const char *newkey = key;
t_attr *attr;
/* no need to check for attrgroup, key */
attr = attrgroup_find_attr(attrgroup, &newkey, escape);
if (attr) val = attr_get_val(attr);
if (!val && attrgroup != attrlayer_get_defattrgroup())
val = attrgroup_get_attrlow(attrlayer_get_defattrgroup(), newkey, 0);
if (newkey != key) xfree((void*)newkey);
return val;
}
extern const char *attrgroup_get_attr(t_attrgroup *attrgroup, const char *key)
{
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return NULL;
}
if (!key) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL key");
return NULL;
}
return attrgroup_get_attrlow(attrgroup, key, 1);
}
extern int attrgroup_set_attr(t_attrgroup *attrgroup, const char *key, const char *val)
{
t_attr *attr;
const char *newkey = key;
if (!attrgroup) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL attrgroup");
return -1;
}
if (!key) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL key");
return -1;
}
attr = attrgroup_find_attr(attrgroup, &newkey, 1);
if (attr) {
if (attr_get_val(attr) == val ||
(attr_get_val(attr) && val && !std::strcmp(attr_get_val(attr), val)))
goto out; /* no need to modify anything, values are the same */
/* new value for existent key, replace the old one */
attr_set_val(attr, val);
} else { /* unknown key so add new attr */
attr = attr_create(newkey, val);
hlist_add(&attrgroup->list, &attr->link);
}
/* we have modified this attr and attrgroup */
attr_set_dirty(attr);
attrgroup_set_dirty(attrgroup);
out:
if (newkey != key) xfree((void*)newkey);
return 0;
}
}
}

View file

@ -38,40 +38,40 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
/* attrgroup represents a group of attributes which are read/saved/flush together
* ex: each account stores it's data into a attrgroup */
typedef struct attrgroup_struct
/* attrgroup represents a group of attributes which are read/saved/flush together
* ex: each account stores it's data into a attrgroup */
typedef struct attrgroup_struct
#ifdef ATTRGROUP_INTERNAL_ACCESS
{
t_hlist list;
t_storage_info *storage;
int flags;
std::time_t lastaccess;
std::time_t dirtytime;
t_elist loadedlist;
t_elist dirtylist;
}
{
t_hlist list;
t_storage_info *storage;
int flags;
std::time_t lastaccess;
std::time_t dirtytime;
t_elist loadedlist;
t_elist dirtylist;
}
#endif
t_attrgroup;
t_attrgroup;
typedef int (*t_attr_cb)(t_attrgroup *, void *);
typedef int(*t_attr_cb)(t_attrgroup *, void *);
extern t_attrgroup *attrgroup_create_storage(t_storage_info *storage);
extern t_attrgroup *attrgroup_create_newuser(const char *name);
extern t_attrgroup *attrgroup_create_nameuid(const char *name, unsigned uid);
extern int attrgroup_destroy(t_attrgroup *attrgroup);
extern int attrgroup_load(t_attrgroup *attrgroup);
extern int attrgroup_unload(t_attrgroup *attrgroup);
extern int attrgroup_read_accounts(int flag, t_attr_cb cb, void *data);
extern const char *attrgroup_get_attr(t_attrgroup *attrgroup, const char *key);
extern int attrgroup_set_attr(t_attrgroup *attrgroup, const char *key, const char *val);
extern int attrgroup_save(t_attrgroup *attrgroup, int flags);
extern int attrgroup_flush(t_attrgroup *attrgroup, int flags);
extern t_attrgroup *attrgroup_create_storage(t_storage_info *storage);
extern t_attrgroup *attrgroup_create_newuser(const char *name);
extern t_attrgroup *attrgroup_create_nameuid(const char *name, unsigned uid);
extern int attrgroup_destroy(t_attrgroup *attrgroup);
extern int attrgroup_load(t_attrgroup *attrgroup);
extern int attrgroup_unload(t_attrgroup *attrgroup);
extern int attrgroup_read_accounts(int flag, t_attr_cb cb, void *data);
extern const char *attrgroup_get_attr(t_attrgroup *attrgroup, const char *key);
extern int attrgroup_set_attr(t_attrgroup *attrgroup, const char *key, const char *val);
extern int attrgroup_save(t_attrgroup *attrgroup, int flags);
extern int attrgroup_flush(t_attrgroup *attrgroup, int flags);
}
}
}

View file

@ -30,176 +30,176 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
static t_attrgroup *defattrs = NULL;
static t_attrgroup *defattrs = NULL;
static DECLARE_ELIST_INIT(loadedlist);
static DECLARE_ELIST_INIT(dirtylist);
static DECLARE_ELIST_INIT(loadedlist);
static DECLARE_ELIST_INIT(dirtylist);
static int attrlayer_unload_default(void);
static int attrlayer_unload_default(void);
extern int attrlayer_init(void)
{
elist_init(&loadedlist);
elist_init(&dirtylist);
attrlayer_load_default();
extern int attrlayer_init(void)
{
elist_init(&loadedlist);
elist_init(&dirtylist);
attrlayer_load_default();
return 0;
}
return 0;
}
extern int attrlayer_cleanup(void)
{
attrlayer_flush(FS_FORCE | FS_ALL);
attrlayer_unload_default();
extern int attrlayer_cleanup(void)
{
attrlayer_flush(FS_FORCE | FS_ALL);
attrlayer_unload_default();
return 0;
}
return 0;
}
extern int attrlayer_load_default(void)
{
if (defattrs) attrlayer_unload_default();
extern int attrlayer_load_default(void)
{
if (defattrs) attrlayer_unload_default();
defattrs = attrgroup_create_storage(storage->get_defacct());
if (!defattrs) {
eventlog(eventlog_level_error,__FUNCTION__,"could not create attrgroup");
return -1;
}
defattrs = attrgroup_create_storage(storage->get_defacct());
if (!defattrs) {
eventlog(eventlog_level_error, __FUNCTION__, "could not create attrgroup");
return -1;
}
return attrgroup_load(defattrs);
}
return attrgroup_load(defattrs);
}
static int attrlayer_unload_default(void)
{
attrgroup_destroy(defattrs);
defattrs = NULL;
static int attrlayer_unload_default(void)
{
attrgroup_destroy(defattrs);
defattrs = NULL;
return 0;
}
return 0;
}
/* FIXME: dont copy most of the functionality, a good place for a C++ template ;) */
/* FIXME: dont copy most of the functionality, a good place for a C++ template ;) */
extern int attrlayer_flush(int flags)
{
static t_elist *curr = &loadedlist;
static t_elist *next = NULL;
t_attrgroup *attrgroup;
unsigned int fcount;
unsigned int tcount;
extern int attrlayer_flush(int flags)
{
static t_elist *curr = &loadedlist;
static t_elist *next = NULL;
t_attrgroup *attrgroup;
unsigned int fcount;
unsigned int tcount;
fcount = tcount = 0;
if (curr == &loadedlist || FLAG_ISSET(flags, FS_ALL)) {
curr = elist_next(&loadedlist);
next = elist_next(curr);
}
fcount = tcount = 0;
if (curr == &loadedlist || FLAG_ISSET(flags, FS_ALL)) {
curr = elist_next(&loadedlist);
next = elist_next(curr);
}
/* elist_for_each_safe splitted into separate startup for userstep function */
for (; curr != &loadedlist; curr = next, next = elist_next(curr)) {
if (!FLAG_ISSET(flags, FS_ALL) && tcount >= prefs_get_user_step()) break;
/* elist_for_each_safe splitted into separate startup for userstep function */
for (; curr != &loadedlist; curr = next, next = elist_next(curr)) {
if (!FLAG_ISSET(flags, FS_ALL) && tcount >= prefs_get_user_step()) break;
attrgroup = elist_entry(curr, t_attrgroup, loadedlist);
switch (attrgroup_flush(attrgroup, flags)) {
case 0:
/* stop on the first account not flushed (ie accessed too early) */
goto loopout;
case 1:
fcount++;
break;
case -1:
eventlog(eventlog_level_error, __FUNCTION__, "could not flush account");
break;
default:
break;
}
tcount++;
}
loopout:
if (fcount > 0)
eventlog(eventlog_level_debug, __FUNCTION__, "flushed %u user accounts", fcount);
if (!FLAG_ISSET(flags, FS_ALL) && curr != &loadedlist) return 1;
return 0;
}
extern int attrlayer_save(int flags)
{
static t_elist *curr = &dirtylist;
static t_elist *next = NULL;
t_attrgroup *attrgroup;
unsigned int scount;
unsigned int tcount;
scount = tcount = 0;
if (curr == &dirtylist || FLAG_ISSET(flags, FS_ALL)) {
curr = elist_next(&dirtylist);
next = elist_next(curr);
}
/* elist_for_each_safe splitted into separate startup for userstep function */
for (; curr != &dirtylist; curr = next, next = elist_next(curr)) {
if (!FLAG_ISSET(flags, FS_ALL) && tcount >= prefs_get_user_step()) break;
attrgroup = elist_entry(curr, t_attrgroup, dirtylist);
switch (attrgroup_save(attrgroup, flags)) {
case 0:
/* stop on the first account not saved (ie dirty too early) */
goto loopout;
case 1:
scount++;
break;
case -1:
eventlog(eventlog_level_error, __FUNCTION__, "could not save account");
break;
default:
break;
}
tcount++;
}
loopout:
if (scount > 0)
eventlog(eventlog_level_debug, __FUNCTION__, "saved %u user accounts", scount);
if (!FLAG_ISSET(flags, FS_ALL) && curr != &dirtylist) return 1;
return 0;
}
extern void attrlayer_add_loadedlist(t_elist *what)
{
elist_add_tail(&loadedlist, what);
}
extern void attrlayer_del_loadedlist(t_elist *what)
{
elist_del(what);
}
extern void attrlayer_add_dirtylist(t_elist *what)
{
elist_add_tail(&dirtylist, what);
}
extern void attrlayer_del_dirtylist(t_elist *what)
{
elist_del(what);
}
extern t_attrgroup * attrlayer_get_defattrgroup(void)
{
return defattrs;
}
extern void attrlayer_accessed(t_attrgroup* attrgroup)
{
/* move the attrgroup at the end of loaded list for the "flush" loop */
elist_del(&attrgroup->loadedlist);
elist_add_tail(&loadedlist, &attrgroup->loadedlist);
}
attrgroup = elist_entry(curr, t_attrgroup, loadedlist);
switch(attrgroup_flush(attrgroup, flags)) {
case 0:
/* stop on the first account not flushed (ie accessed too early) */
goto loopout;
case 1:
fcount++;
break;
case -1:
eventlog(eventlog_level_error, __FUNCTION__, "could not flush account");
break;
default:
break;
}
tcount++;
}
loopout:
if (fcount>0)
eventlog(eventlog_level_debug, __FUNCTION__, "flushed %u user accounts", fcount);
if (!FLAG_ISSET(flags, FS_ALL) && curr != &loadedlist) return 1;
return 0;
}
extern int attrlayer_save(int flags)
{
static t_elist *curr = &dirtylist;
static t_elist *next = NULL;
t_attrgroup *attrgroup;
unsigned int scount;
unsigned int tcount;
scount = tcount = 0;
if (curr == &dirtylist || FLAG_ISSET(flags, FS_ALL)) {
curr = elist_next(&dirtylist);
next = elist_next(curr);
}
/* elist_for_each_safe splitted into separate startup for userstep function */
for (; curr != &dirtylist; curr = next, next = elist_next(curr)) {
if (!FLAG_ISSET(flags, FS_ALL) && tcount >= prefs_get_user_step()) break;
attrgroup = elist_entry(curr, t_attrgroup, dirtylist);
switch(attrgroup_save(attrgroup, flags)) {
case 0:
/* stop on the first account not saved (ie dirty too early) */
goto loopout;
case 1:
scount++;
break;
case -1:
eventlog(eventlog_level_error, __FUNCTION__, "could not save account");
break;
default:
break;
}
tcount++;
}
loopout:
if (scount>0)
eventlog(eventlog_level_debug, __FUNCTION__, "saved %u user accounts", scount);
if (!FLAG_ISSET(flags, FS_ALL) && curr != &dirtylist) return 1;
return 0;
}
extern void attrlayer_add_loadedlist(t_elist *what)
{
elist_add_tail(&loadedlist, what);
}
extern void attrlayer_del_loadedlist(t_elist *what)
{
elist_del(what);
}
extern void attrlayer_add_dirtylist(t_elist *what)
{
elist_add_tail(&dirtylist, what);
}
extern void attrlayer_del_dirtylist(t_elist *what)
{
elist_del(what);
}
extern t_attrgroup * attrlayer_get_defattrgroup(void)
{
return defattrs;
}
extern void attrlayer_accessed(t_attrgroup* attrgroup)
{
/* move the attrgroup at the end of loaded list for the "flush" loop */
elist_del(&attrgroup->loadedlist);
elist_add_tail(&loadedlist, &attrgroup->loadedlist);
}
}
}

View file

@ -30,22 +30,22 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int attrlayer_init(void);
extern int attrlayer_cleanup(void);
extern int attrlayer_load_default(void);
extern int attrlayer_save(int flags);
extern int attrlayer_flush(int flags);
extern t_attrgroup * attrlayer_get_defattrgroup(void);
extern void attrlayer_add_loadedlist(t_elist *what);
extern void attrlayer_del_loadedlist(t_elist *what);
extern void attrlayer_add_dirtylist(t_elist *what);
extern void attrlayer_del_dirtylist(t_elist *what);
extern void attrlayer_accessed(t_attrgroup* attrgroup);
extern int attrlayer_init(void);
extern int attrlayer_cleanup(void);
extern int attrlayer_load_default(void);
extern int attrlayer_save(int flags);
extern int attrlayer_flush(int flags);
extern t_attrgroup * attrlayer_get_defattrgroup(void);
extern void attrlayer_add_loadedlist(t_elist *what);
extern void attrlayer_del_loadedlist(t_elist *what);
extern void attrlayer_add_dirtylist(t_elist *what);
extern void attrlayer_del_dirtylist(t_elist *what);
extern void attrlayer_accessed(t_attrgroup* attrgroup);
}
}
}

View file

@ -36,208 +36,208 @@
namespace pvpgn
{
namespace bnetd
{
static t_list * autoupdate_head=NULL;
static std::FILE * fp = NULL;
/*
* Open the autoupdate configuration file, create a linked list of the
* clienttag and the update file for it. The format of the file is:
* archtag<tab>clienttag<tab>versiontag<tab>update file
*
* Comments begin with # and are ignored.
*
* The server assumes that the update file is in the "files" directory
* so do not include "/" in the filename - it won't be sent
* (because it is a security risk).
*/
extern int autoupdate_load(char const * filename)
{
unsigned int line;
unsigned int pos;
char * buff;
char * temp;
char const * archtag;
char const * clienttag;
char const * updatefile;
char const * versiontag;
char const * path;
t_autoupdate * entry;
if (!filename) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename");
return -1;
}
if (!(fp = std::fopen(filename,"r"))) {
eventlog(eventlog_level_error, __FUNCTION__, "could not open file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno));
return -1;
}
autoupdate_head = list_create();
for (line=1; (buff = file_get_line(fp)); line++) {
for (pos=0; buff[pos]=='\t' || buff[pos]==' '; pos++);
if (buff[pos]=='\0' || buff[pos]=='#') {
continue;
}
if ((temp = std::strrchr(buff,'#'))) {
unsigned int len;
unsigned int endpos;
*temp = '\0';
len = std::strlen(buff)+1;
for (endpos=len-1; buff[endpos]=='\t' || buff[endpos]==' '; endpos--);
buff[endpos+1] = '\0';
}
/* FIXME: use next_token instead of std::strtok */
if (!(archtag = std::strtok(buff, " \t"))) { /* std::strtok modifies the string it is passed */
eventlog(eventlog_level_error,__FUNCTION__,"missing archtag on line %u of file \"%s\"",line,filename);
continue;
}
if (!(clienttag = std::strtok(NULL," \t"))) {
eventlog(eventlog_level_error,__FUNCTION__,"missing clienttag on line %u of file \"%s\"",line,filename);
continue;
}
if (!(versiontag = std::strtok(NULL, " \t"))) {
eventlog(eventlog_level_error,__FUNCTION__,"missing versiontag on line %u of file \"%s\"",line,filename);
continue;
}
if (!(updatefile = std::strtok(NULL," \t"))) {
eventlog(eventlog_level_error,__FUNCTION__,"missing updatefile on line %u of file \"%s\"",line,filename);
continue;
}
if ((!(path = std::strtok(NULL," \t"))) && tag_check_wolv1(tag_str_to_uint(clienttag)) && tag_check_wolv2(tag_str_to_uint(clienttag))) { /* Only in WOL is needed to have path */
eventlog(eventlog_level_error,__FUNCTION__,"missing path on line %u of file \"%s\"",line,filename);
}
entry = (t_autoupdate*)xmalloc(sizeof(t_autoupdate));
if (!tag_check_arch((entry->archtag = tag_str_to_uint(archtag)))) {
eventlog(eventlog_level_error,__FUNCTION__,"got unknown archtag");
xfree(entry);
continue;
}
if (!tag_check_client((entry->clienttag = tag_str_to_uint(clienttag)))) {
eventlog(eventlog_level_error,__FUNCTION__,"got unknown clienttag");
xfree(entry);
continue;
}
entry->versiontag = xstrdup(versiontag);
entry->updatefile = xstrdup(updatefile);
if (path)
entry->path = xstrdup(path);
else
entry->path = NULL;
eventlog(eventlog_level_debug,__FUNCTION__,"update '%s' version '%s' with file %s",clienttag,versiontag,updatefile);
list_append_data(autoupdate_head,entry);
}
file_get_line(NULL); // clear file_get_line buffer
std::fclose(fp);
return 0;
}
/*
* Free up all of the elements in the linked list
*/
extern int autoupdate_unload(void)
{
if (autoupdate_head) {
t_elem * curr;
t_autoupdate * entry;
LIST_TRAVERSE(autoupdate_head,curr)
namespace bnetd
{
if (!(entry = (t_autoupdate*)elem_get_data(curr)))
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
else {
xfree((void *)entry->versiontag); /* avoid warning */
xfree((void *)entry->updatefile); /* avoid warning */
if (entry->path)
xfree((void *)entry->path); /* avoid warning */
xfree(entry);
}
list_remove_elem(autoupdate_head,&curr);
}
if (list_destroy(autoupdate_head)<0) return -1;
autoupdate_head = NULL;
}
return 0;
}
static t_list * autoupdate_head = NULL;
static std::FILE * fp = NULL;
/*
* Check to see if an update exists for the clients version
* return file name if there is one
* retrun NULL if no update exists
*/
extern char * autoupdate_check(t_tag archtag, t_tag clienttag, t_tag gamelang, char const * versiontag, char const * sku)
{
if (autoupdate_head) {
t_elem const * curr;
t_autoupdate * entry;
char * temp;
/*
* Open the autoupdate configuration file, create a linked list of the
* clienttag and the update file for it. The format of the file is:
* archtag<tab>clienttag<tab>versiontag<tab>update file
*
* Comments begin with # and are ignored.
*
* The server assumes that the update file is in the "files" directory
* so do not include "/" in the filename - it won't be sent
* (because it is a security risk).
*/
LIST_TRAVERSE_CONST(autoupdate_head,curr)
{
if (!(entry = (t_autoupdate*)elem_get_data(curr))) {
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
continue;
}
extern int autoupdate_load(char const * filename)
{
unsigned int line;
unsigned int pos;
char * buff;
char * temp;
char const * archtag;
char const * clienttag;
char const * updatefile;
char const * versiontag;
char const * path;
t_autoupdate * entry;
if (entry->archtag != archtag)
continue;
if (entry->clienttag != clienttag)
continue;
if (std::strcmp(entry->versiontag, versiontag) != 0)
continue;
if (!filename) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL filename");
return -1;
}
/* if we have a gamelang or SKU then add it to the update file name */
// so far only WAR3 uses gamelang specific MPQs!
if (((gamelang) && ((clienttag == CLIENTTAG_WARCRAFT3_UINT) || (clienttag == CLIENTTAG_WAR3XP_UINT)))
|| ((sku) && (tag_check_wolv2(clienttag)))) {
char gltag[5];
char * tempmpq;
char * extention;
char const * path = entry->path;
if (!(fp = std::fopen(filename, "r"))) {
eventlog(eventlog_level_error, __FUNCTION__, "could not open file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno));
return -1;
}
tempmpq = xstrdup(entry->updatefile);
autoupdate_head = list_create();
extention = std::strrchr(tempmpq,'.');
*extention = '\0';
extention++;
for (line = 1; (buff = file_get_line(fp)); line++) {
for (pos = 0; buff[pos] == '\t' || buff[pos] == ' '; pos++);
if ((clienttag == CLIENTTAG_WARCRAFT3_UINT) || (clienttag == CLIENTTAG_WAR3XP_UINT)) {
tag_uint_to_str(gltag,gamelang);
if (buff[pos] == '\0' || buff[pos] == '#') {
continue;
}
temp = (char*)xmalloc(std::strlen(entry->updatefile)+6);
std::sprintf(temp, "%s_%s.%s", tempmpq, gltag, extention);
}
else {
temp = (char*)xmalloc(std::strlen(path)+std::strlen(entry->updatefile)+std::strlen(sku)+3);
std::sprintf(temp, "%s %s_%s.%s", path, tempmpq, sku, extention);
if ((temp = std::strrchr(buff, '#'))) {
unsigned int len;
unsigned int endpos;
*temp = '\0';
len = std::strlen(buff) + 1;
for (endpos = len - 1; buff[endpos] == '\t' || buff[endpos] == ' '; endpos--);
buff[endpos + 1] = '\0';
}
/* FIXME: use next_token instead of std::strtok */
if (!(archtag = std::strtok(buff, " \t"))) { /* std::strtok modifies the string it is passed */
eventlog(eventlog_level_error, __FUNCTION__, "missing archtag on line %u of file \"%s\"", line, filename);
continue;
}
if (!(clienttag = std::strtok(NULL, " \t"))) {
eventlog(eventlog_level_error, __FUNCTION__, "missing clienttag on line %u of file \"%s\"", line, filename);
continue;
}
if (!(versiontag = std::strtok(NULL, " \t"))) {
eventlog(eventlog_level_error, __FUNCTION__, "missing versiontag on line %u of file \"%s\"", line, filename);
continue;
}
if (!(updatefile = std::strtok(NULL, " \t"))) {
eventlog(eventlog_level_error, __FUNCTION__, "missing updatefile on line %u of file \"%s\"", line, filename);
continue;
}
if ((!(path = std::strtok(NULL, " \t"))) && tag_check_wolv1(tag_str_to_uint(clienttag)) && tag_check_wolv2(tag_str_to_uint(clienttag))) { /* Only in WOL is needed to have path */
eventlog(eventlog_level_error, __FUNCTION__, "missing path on line %u of file \"%s\"", line, filename);
}
entry = (t_autoupdate*)xmalloc(sizeof(t_autoupdate));
if (!tag_check_arch((entry->archtag = tag_str_to_uint(archtag)))) {
eventlog(eventlog_level_error, __FUNCTION__, "got unknown archtag");
xfree(entry);
continue;
}
if (!tag_check_client((entry->clienttag = tag_str_to_uint(clienttag)))) {
eventlog(eventlog_level_error, __FUNCTION__, "got unknown clienttag");
xfree(entry);
continue;
}
entry->versiontag = xstrdup(versiontag);
entry->updatefile = xstrdup(updatefile);
if (path)
entry->path = xstrdup(path);
else
entry->path = NULL;
eventlog(eventlog_level_debug, __FUNCTION__, "update '%s' version '%s' with file %s", clienttag, versiontag, updatefile);
list_append_data(autoupdate_head, entry);
}
file_get_line(NULL); // clear file_get_line buffer
std::fclose(fp);
return 0;
}
/*
* Free up all of the elements in the linked list
*/
extern int autoupdate_unload(void)
{
if (autoupdate_head) {
t_elem * curr;
t_autoupdate * entry;
LIST_TRAVERSE(autoupdate_head, curr)
{
if (!(entry = (t_autoupdate*)elem_get_data(curr)))
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
else {
xfree((void *)entry->versiontag); /* avoid warning */
xfree((void *)entry->updatefile); /* avoid warning */
if (entry->path)
xfree((void *)entry->path); /* avoid warning */
xfree(entry);
}
list_remove_elem(autoupdate_head, &curr);
}
if (list_destroy(autoupdate_head) < 0) return -1;
autoupdate_head = NULL;
}
return 0;
}
/*
* Check to see if an update exists for the clients version
* return file name if there is one
* retrun NULL if no update exists
*/
extern char * autoupdate_check(t_tag archtag, t_tag clienttag, t_tag gamelang, char const * versiontag, char const * sku)
{
if (autoupdate_head) {
t_elem const * curr;
t_autoupdate * entry;
char * temp;
LIST_TRAVERSE_CONST(autoupdate_head, curr)
{
if (!(entry = (t_autoupdate*)elem_get_data(curr))) {
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
continue;
}
if (entry->archtag != archtag)
continue;
if (entry->clienttag != clienttag)
continue;
if (std::strcmp(entry->versiontag, versiontag) != 0)
continue;
/* if we have a gamelang or SKU then add it to the update file name */
// so far only WAR3 uses gamelang specific MPQs!
if (((gamelang) && ((clienttag == CLIENTTAG_WARCRAFT3_UINT) || (clienttag == CLIENTTAG_WAR3XP_UINT)))
|| ((sku) && (tag_check_wolv2(clienttag)))) {
char gltag[5];
char * tempmpq;
char * extention;
char const * path = entry->path;
tempmpq = xstrdup(entry->updatefile);
extention = std::strrchr(tempmpq, '.');
*extention = '\0';
extention++;
if ((clienttag == CLIENTTAG_WARCRAFT3_UINT) || (clienttag == CLIENTTAG_WAR3XP_UINT)) {
tag_uint_to_str(gltag, gamelang);
temp = (char*)xmalloc(std::strlen(entry->updatefile) + 6);
std::sprintf(temp, "%s_%s.%s", tempmpq, gltag, extention);
}
else {
temp = (char*)xmalloc(std::strlen(path) + std::strlen(entry->updatefile) + std::strlen(sku) + 3);
std::sprintf(temp, "%s %s_%s.%s", path, tempmpq, sku, extention);
}
xfree((void *)tempmpq);
return temp;
}
temp = xstrdup(entry->updatefile);
return temp;
}
}
return NULL;
}
xfree((void *)tempmpq);
return temp;
}
temp = xstrdup(entry->updatefile);
return temp;
}
}
return NULL;
}
}
}

View file

@ -26,21 +26,21 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
#ifdef AUTOUPDATE_INTERNAL_ACCESS
typedef struct
{
t_tag archtag;
t_tag clienttag;
char const * versiontag;
char const * updatefile; /* used for bnet *.mpq file or wol *.rtp file */
char const * path; /* Used only for WOL FTP update */
} t_autoupdate;
typedef struct
{
t_tag archtag;
t_tag clienttag;
char const * versiontag;
char const * updatefile; /* used for bnet *.mpq file or wol *.rtp file */
char const * path; /* Used only for WOL FTP update */
} t_autoupdate;
#endif
}
}
}
@ -55,14 +55,14 @@ typedef struct
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int autoupdate_load(char const * filename);
extern int autoupdate_unload(void);
extern char * autoupdate_check(t_tag archtag, t_tag clienttag, t_tag gamelang, char const * versiontag, char const * sku);
extern int autoupdate_load(char const * filename);
extern int autoupdate_unload(void);
extern char * autoupdate_check(t_tag archtag, t_tag clienttag, t_tag gamelang, char const * versiontag, char const * sku);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -49,63 +49,63 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
#ifdef CHANNEL_INTERNAL_ACCESS
typedef struct channelmember
{
/* standalone mode */
t_connection * connection;
struct channelmember * next;
} t_channelmember;
typedef struct channelmember
{
/* standalone mode */
t_connection * connection;
struct channelmember * next;
} t_channelmember;
#endif
typedef enum
{
channel_flags_none=0x00,
channel_flags_public=0x01,
channel_flags_moderated=0x02,
channel_flags_restricted=0x04,
channel_flags_thevoid=0x08,
channel_flags_system=0x10,
channel_flags_official=0x20,
channel_flags_permanent=0x40,
channel_flags_allowbots=0x80,
channel_flags_allowopers=0x100,
channel_flags_clan=0x200,
channel_flags_autoname=0x400
} t_channel_flags;
typedef enum
{
channel_flags_none = 0x00,
channel_flags_public = 0x01,
channel_flags_moderated = 0x02,
channel_flags_restricted = 0x04,
channel_flags_thevoid = 0x08,
channel_flags_system = 0x10,
channel_flags_official = 0x20,
channel_flags_permanent = 0x40,
channel_flags_allowbots = 0x80,
channel_flags_allowopers = 0x100,
channel_flags_clan = 0x200,
channel_flags_autoname = 0x400
} t_channel_flags;
typedef struct channel
typedef struct channel
#ifdef CHANNEL_INTERNAL_ACCESS
{
char const * name;
char const * shortname; /* short "alias" for permanent channels, NULL if none */
char const * country;
char const * realmname;
unsigned int flags;
int maxmembers;
int currmembers;
t_clienttag clienttag;
unsigned int id;
t_channelmember * memberlist;
t_list * banlist; /* of char * */
char * logname; /* NULL if not logged */
std::FILE * log; /* NULL if not logging */
{
char const * name;
char const * shortname; /* short "alias" for permanent channels, NULL if none */
char const * country;
char const * realmname;
unsigned int flags;
int maxmembers;
int currmembers;
t_clienttag clienttag;
unsigned int id;
t_channelmember * memberlist;
t_list * banlist; /* of char * */
char * logname; /* NULL if not logged */
std::FILE * log; /* NULL if not logging */
/**
* Westwood Online Extensions
*/
int minmembers;
/**
* Westwood Online Extensions
*/
int minmembers;
int gameType;
char * gameExtension;
}
int gameType;
char * gameExtension;
}
#endif
t_channel;
t_channel;
}
}
}
@ -129,62 +129,62 @@ t_channel;
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int channel_set_userflags(t_connection * c);
extern t_channel * channel_create(char const * fullname, char const * shortname, t_clienttag clienttag, int permflag, int botflag, int operflag, int logflag, char const * country, char const * realmname, int maxmembers, int moderated, int clanflag, int autoname, t_list * channellist);
extern t_channel * channel_create(char const * fullname, char const * shortname, t_clienttag clienttag, int permflag, int botflag, int operflag, int logflag, char const * country, char const * realmname, int maxmembers, int moderated, int clanflag, int autoname);
extern int channel_destroy(t_channel * channel, t_elem ** elem);
extern char const * channel_get_name(t_channel const * channel);
extern char const * channel_get_shortname(t_channel const * channel);
extern t_clienttag channel_get_clienttag(t_channel const * channel);
extern unsigned channel_get_flags(t_channel const * channel);
extern int channel_set_flags(t_channel * channel, unsigned flags);
extern int channel_get_permanent(t_channel const * channel);
extern unsigned int channel_get_channelid(t_channel const * channel);
extern int channel_set_channelid(t_channel * channel, unsigned int channelid);
extern int channel_add_connection(t_channel * channel, t_connection * connection);
extern int channel_del_connection(t_channel * channel, t_connection * connection, t_message_type mess, char const * text);
extern void channel_update_latency(t_connection * conn);
extern void channel_update_userflags(t_connection * conn);
extern void channel_message_log(t_channel const * channel, t_connection * me, int fromuser, char const * text);
extern void channel_message_send(t_channel const * channel, t_message_type type, t_connection * conn, char const * text);
extern int channel_ban_user(t_channel * channel, char const * user);
extern int channel_unban_user(t_channel * channel, char const * user);
extern int channel_check_banning(t_channel const * channel, t_connection const * user);
extern int channel_rejoin(t_connection * conn);
extern t_list * channel_get_banlist(t_channel const * channel);
extern int channel_get_length(t_channel const * channel);
extern int channel_get_max(t_channel const * channel);
extern int channel_set_max(t_channel * channel, int maxmembers);
extern int channel_get_curr(t_channel const * channel);
extern int channel_conn_is_tmpOP(t_channel const * channel, t_connection * c);
extern int channel_conn_has_tmpVOICE(t_channel const * channel, t_connection * c);
extern t_connection * channel_get_first(t_channel const * channel);
extern t_connection * channel_get_next(void);
extern int channel_set_userflags(t_connection * c);
extern t_channel * channel_create(char const * fullname, char const * shortname, t_clienttag clienttag, int permflag, int botflag, int operflag, int logflag, char const * country, char const * realmname, int maxmembers, int moderated, int clanflag, int autoname, t_list * channellist);
extern t_channel * channel_create(char const * fullname, char const * shortname, t_clienttag clienttag, int permflag, int botflag, int operflag, int logflag, char const * country, char const * realmname, int maxmembers, int moderated, int clanflag, int autoname);
extern int channel_destroy(t_channel * channel, t_elem ** elem);
extern char const * channel_get_name(t_channel const * channel);
extern char const * channel_get_shortname(t_channel const * channel);
extern t_clienttag channel_get_clienttag(t_channel const * channel);
extern unsigned channel_get_flags(t_channel const * channel);
extern int channel_set_flags(t_channel * channel, unsigned flags);
extern int channel_get_permanent(t_channel const * channel);
extern unsigned int channel_get_channelid(t_channel const * channel);
extern int channel_set_channelid(t_channel * channel, unsigned int channelid);
extern int channel_add_connection(t_channel * channel, t_connection * connection);
extern int channel_del_connection(t_channel * channel, t_connection * connection, t_message_type mess, char const * text);
extern void channel_update_latency(t_connection * conn);
extern void channel_update_userflags(t_connection * conn);
extern void channel_message_log(t_channel const * channel, t_connection * me, int fromuser, char const * text);
extern void channel_message_send(t_channel const * channel, t_message_type type, t_connection * conn, char const * text);
extern int channel_ban_user(t_channel * channel, char const * user);
extern int channel_unban_user(t_channel * channel, char const * user);
extern int channel_check_banning(t_channel const * channel, t_connection const * user);
extern int channel_rejoin(t_connection * conn);
extern t_list * channel_get_banlist(t_channel const * channel);
extern int channel_get_length(t_channel const * channel);
extern int channel_get_max(t_channel const * channel);
extern int channel_set_max(t_channel * channel, int maxmembers);
extern int channel_get_curr(t_channel const * channel);
extern int channel_conn_is_tmpOP(t_channel const * channel, t_connection * c);
extern int channel_conn_has_tmpVOICE(t_channel const * channel, t_connection * c);
extern t_connection * channel_get_first(t_channel const * channel);
extern t_connection * channel_get_next(void);
extern int channellist_create(void);
extern int channellist_destroy(void);
extern int channellist_reload(void);
extern t_list * channellist(void);
extern t_channel * channellist_find_channel_by_name(char const * name, char const * locale, char const * realmname);
extern t_channel * channellist_find_channel_bychannelid(unsigned int channelid);
extern int channellist_get_length(void);
extern int channellist_create(void);
extern int channellist_destroy(void);
extern int channellist_reload(void);
extern t_list * channellist(void);
extern t_channel * channellist_find_channel_by_name(char const * name, char const * locale, char const * realmname);
extern t_channel * channellist_find_channel_bychannelid(unsigned int channelid);
extern int channellist_get_length(void);
/**
* Westwood Online Extensions
*/
extern int channel_get_min(t_channel const * channel);
extern int channel_set_min(t_channel * channel, int minmembers);
/**
* Westwood Online Extensions
*/
extern int channel_get_min(t_channel const * channel);
extern int channel_set_min(t_channel * channel, int minmembers);
extern int channel_wol_get_game_type(t_channel const * channel);
extern int channel_wol_set_game_type(t_channel * channel, int gameType);
extern int channel_wol_get_game_type(t_channel const * channel);
extern int channel_wol_set_game_type(t_channel * channel, int gameType);
extern char const * channel_wol_get_game_extension(t_channel const * channel);
extern int channel_wol_set_game_extension(t_channel * channel, char const * gameExtension);
extern char const * channel_wol_get_game_extension(t_channel const * channel);
extern int channel_wol_set_game_extension(t_channel * channel, char const * gameExtension);
}
}
}

View file

@ -24,30 +24,30 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern unsigned int cflags_to_bncflags(unsigned flags)
{
unsigned int res;
extern unsigned int cflags_to_bncflags(unsigned flags)
{
unsigned int res;
res = 0;
if (flags&channel_flags_public)
res |= CF_PUBLIC;
if (flags&channel_flags_moderated)
res |= CF_MODERATED;
if (flags&channel_flags_restricted)
res |= CF_RESTRICTED;
if (flags&channel_flags_thevoid)
res |= CF_THEVOID;
if (flags&channel_flags_system)
res |= CF_SYSTEM;
if (flags&channel_flags_official)
res |= CF_OFFICIAL;
res = 0;
if (flags&channel_flags_public)
res |= CF_PUBLIC;
if (flags&channel_flags_moderated)
res |= CF_MODERATED;
if (flags&channel_flags_restricted)
res |= CF_RESTRICTED;
if (flags&channel_flags_thevoid)
res |= CF_THEVOID;
if (flags&channel_flags_system)
res |= CF_SYSTEM;
if (flags&channel_flags_official)
res |= CF_OFFICIAL;
return res;
}
}
return res;
}
}
}

View file

@ -31,12 +31,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern unsigned int cflags_to_bncflags(unsigned flags);
extern unsigned int cflags_to_bncflags(unsigned flags);
}
}
}

View file

@ -37,483 +37,483 @@
namespace pvpgn
{
namespace bnetd
{
static t_list * characterlist_head=NULL;
static t_character_class bncharacter_class_to_character_class(t_uint8 cclass)
{
switch (cclass)
{
case D2CHAR_INFO_CLASS_AMAZON:
return character_class_amazon;
case D2CHAR_INFO_CLASS_SORCERESS:
return character_class_sorceress;
case D2CHAR_INFO_CLASS_NECROMANCER:
return character_class_necromancer;
case D2CHAR_INFO_CLASS_PALADIN:
return character_class_paladin;
case D2CHAR_INFO_CLASS_BARBARIAN:
return character_class_barbarian;
case D2CHAR_INFO_CLASS_DRUID:
return character_class_druid;
case D2CHAR_INFO_CLASS_ASSASSIN:
return character_class_assassin;
default:
return character_class_none;
}
}
/* Function unused
static t_uint8 character_class_to_bncharacter_class(t_character_class class)
{
switch (class)
{
case character_class_amazon:
return D2CHAR_INFO_CLASS_AMAZON;
case character_class_sorceress:
return D2CHAR_INFO_CLASS_SORCERESS;
case character_class_necromancer:
return D2CHAR_INFO_CLASS_NECROMANCER;
case character_class_paladin:
return D2CHAR_INFO_CLASS_PALADIN;
case character_class_barbarian:
return D2CHAR_INFO_CLASS_BARBARIAN;
case character_class_druid:
return D2CHAR_INFO_CLASS_DRUID;
case character_class_assassin:
return D2CHAR_INFO_CLASS_ASSASSIN;
default:
eventlog(eventlog_level_error,__FUNCTION__,"got unknown class %d",(int)class);
case character_class_none:
return D2CHAR_INFO_FILLER;
}
}
*/
static const char * character_class_to_classname (t_character_class chclass)
{
switch (chclass)
{
case character_class_amazon:
return "Amazon";
case character_class_sorceress:
return "Sorceress";
case character_class_necromancer:
return "Necromancer";
case character_class_paladin:
return "Paladin";
case character_class_barbarian:
return "Barbarian";
case character_class_druid:
return "Druid";
case character_class_assassin:
return "Assassin";
default:
return "Unknown";
}
}
static const char * character_expansion_to_expansionname (t_character_expansion expansion)
{
switch (expansion)
{
case character_expansion_classic:
return "Classic";
case character_expansion_lod:
return "LordOfDestruction";
default:
return "Unknown";
}
}
static void decode_character_data(t_character * ch)
{
ch->unknownb1 = D2CHAR_INFO_UNKNOWNB1;
ch->unknownb2 = D2CHAR_INFO_UNKNOWNB2;
ch->helmgfx = D2CHAR_INFO_FILLER;
ch->bodygfx = D2CHAR_INFO_FILLER;
ch->leggfx = D2CHAR_INFO_FILLER;
ch->lhandweapon = D2CHAR_INFO_FILLER;
ch->lhandgfx = D2CHAR_INFO_FILLER;
ch->rhandweapon = D2CHAR_INFO_FILLER;
ch->rhandgfx = D2CHAR_INFO_FILLER;
ch->unknownb3 = D2CHAR_INFO_FILLER;
ch->unknownb4 = D2CHAR_INFO_FILLER;
ch->unknownb5 = D2CHAR_INFO_FILLER;
ch->unknownb6 = D2CHAR_INFO_FILLER;
ch->unknownb7 = D2CHAR_INFO_FILLER;
ch->unknownb8 = D2CHAR_INFO_FILLER;
ch->unknownb9 = D2CHAR_INFO_FILLER;
ch->unknownb10 = D2CHAR_INFO_FILLER;
ch->unknownb11 = D2CHAR_INFO_FILLER;
ch->unknown1 = 0xffffffff;
ch->unknown2 = 0xffffffff;
ch->unknown3 = 0xffffffff;
ch->unknown4 = 0xffffffff;
ch->level = 0x01;
ch->status = 0x80;
ch->title = 0x80;
ch->unknownb13 = 0x80;
ch->emblembgc = 0x80;
ch->emblemfgc = 0xff;
ch->emblemnum = 0xff;
ch->unknownb14 = D2CHAR_INFO_FILLER;
/*
b1 b2 hg bg lg lw lg rw rg b3 b4 b5 b6 b7 b8 b9 bA bB cl u1 u1 u1 u1 u2 u2 u2 u2 u3 u3 u3 u3 u4 u4 u4 u4 lv st ti bC eb ef en bD \0
amazon_qwer.std::log:
83 80 ff ff ff ff ff 43 ff 1b ff ff ff ff ff ff ff ff 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 80 80 ff ff ff 00
sor_Bent.std::log:
83 80 ff ff ff ff ff 53 ff ff ff ff ff ff ff ff ff ff 02 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 80 80 ff ff ff 00
necro_Thorsen.std::log:
83 80 ff ff ff ff ff 2b ff ff ff ff ff ff ff ff ff ff 03 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 80 80 ff ff ff 00
pal_QlexTEST.std::log:
87 80 01 01 01 01 01 ff ff ff 01 01 ff ff ff ff ff ff 04 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 ff ff ff 80 80 00
barb_Qlex.std::log:
83 80 ff ff ff ff ff 2f ff 1b ff ff ff ff ff ff ff ff 05 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 80 80 ff ff ff 00
*/
}
static int load_initial_data (t_character * character, t_character_class chclass, t_character_expansion expansion)
{
char const * data_in_hex;
eventlog(eventlog_level_debug,__FUNCTION__,"Initial Data for %s, %s %s",
character->name,
character_expansion_to_expansionname(expansion),
character_class_to_classname(chclass));
/* Ideally, this would be loaded from bnetd_default_user, but I don't want to hack account.c just now */
/* The "default" character info if everything else messes up; */
data_in_hex = NULL; /* FIXME: what should we do if expansion or class isn't known... */
switch (expansion)
{
case character_expansion_classic:
switch (chclass)
namespace bnetd
{
case character_class_amazon:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 01 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
case character_class_sorceress:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 02 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
case character_class_necromancer:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 03 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
case character_class_paladin:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 04 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
case character_class_barbarian:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 05 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
default: break; //should never reach that part ot the code... but to make compiler happy...
}
break;
case character_expansion_lod:
switch (chclass)
{
case character_class_amazon:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 01 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_sorceress:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 02 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_necromancer:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 03 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_paladin:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 04 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_barbarian:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 05 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_druid:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 06 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_assassin:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 07 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
default: break; // again we will never get here... but how can compiler know that?!?
}
default: break; // well... like I said 2 times before....
}
character->datalen = hex_to_str(data_in_hex, (char*)character->data, 33);
decode_character_data(character);
return 0;
}
static t_list * characterlist_head = NULL;
extern int character_create(t_account * account, t_clienttag clienttag, char const * realmname, char const * name, t_character_class chclass, t_character_expansion expansion)
{
t_character * ch;
if (!account)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL account");
return -1;
}
if (!clienttag)
{
eventlog(eventlog_level_error,__FUNCTION__,"got bad clienttag");
return -1;
}
if (!realmname)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL realmname");
return -1;
}
if (!name)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL name");
return -1;
}
ch = (t_character*)xmalloc(sizeof(t_character));
ch->name = xstrdup(name);
ch->realmname = xstrdup(realmname);
ch->guildname = xstrdup(""); /* FIXME: how does this work on Battle.net? */
if (account_check_closed_character(account, clienttag, realmname, name))
{
eventlog(eventlog_level_error,__FUNCTION__,"a character with the name \"%s\" does already exist in realm \"%s\"",name,realmname);
xfree((void *)ch->realmname); /* avoid warning */
xfree((void *)ch->name); /* avoid warning */
xfree(ch);
return -1;
}
load_initial_data (ch, chclass, expansion);
account_add_closed_character(account, clienttag, ch);
return 0;
}
static t_character_class bncharacter_class_to_character_class(t_uint8 cclass)
{
switch (cclass)
{
case D2CHAR_INFO_CLASS_AMAZON:
return character_class_amazon;
case D2CHAR_INFO_CLASS_SORCERESS:
return character_class_sorceress;
case D2CHAR_INFO_CLASS_NECROMANCER:
return character_class_necromancer;
case D2CHAR_INFO_CLASS_PALADIN:
return character_class_paladin;
case D2CHAR_INFO_CLASS_BARBARIAN:
return character_class_barbarian;
case D2CHAR_INFO_CLASS_DRUID:
return character_class_druid;
case D2CHAR_INFO_CLASS_ASSASSIN:
return character_class_assassin;
default:
return character_class_none;
}
}
extern char const * character_get_name(t_character const * ch)
{
if (!ch)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL character");
return NULL;
}
return ch->name;
}
/* Function unused
static t_uint8 character_class_to_bncharacter_class(t_character_class class)
{
switch (class)
{
case character_class_amazon:
return D2CHAR_INFO_CLASS_AMAZON;
case character_class_sorceress:
return D2CHAR_INFO_CLASS_SORCERESS;
case character_class_necromancer:
return D2CHAR_INFO_CLASS_NECROMANCER;
case character_class_paladin:
return D2CHAR_INFO_CLASS_PALADIN;
case character_class_barbarian:
return D2CHAR_INFO_CLASS_BARBARIAN;
case character_class_druid:
return D2CHAR_INFO_CLASS_DRUID;
case character_class_assassin:
return D2CHAR_INFO_CLASS_ASSASSIN;
default:
eventlog(eventlog_level_error,__FUNCTION__,"got unknown class %d",(int)class);
case character_class_none:
return D2CHAR_INFO_FILLER;
}
}
*/
static const char * character_class_to_classname(t_character_class chclass)
{
switch (chclass)
{
case character_class_amazon:
return "Amazon";
case character_class_sorceress:
return "Sorceress";
case character_class_necromancer:
return "Necromancer";
case character_class_paladin:
return "Paladin";
case character_class_barbarian:
return "Barbarian";
case character_class_druid:
return "Druid";
case character_class_assassin:
return "Assassin";
default:
return "Unknown";
}
}
extern char const * character_get_realmname(t_character const * ch)
{
if (!ch)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL character");
return NULL;
}
return ch->realmname;
}
static const char * character_expansion_to_expansionname(t_character_expansion expansion)
{
switch (expansion)
{
case character_expansion_classic:
return "Classic";
case character_expansion_lod:
return "LordOfDestruction";
default:
return "Unknown";
}
}
extern t_character_class character_get_class(t_character const * ch)
{
if (!ch)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL character");
return character_class_none;
}
return bncharacter_class_to_character_class(ch->chclass);
}
static void decode_character_data(t_character * ch)
{
ch->unknownb1 = D2CHAR_INFO_UNKNOWNB1;
ch->unknownb2 = D2CHAR_INFO_UNKNOWNB2;
ch->helmgfx = D2CHAR_INFO_FILLER;
ch->bodygfx = D2CHAR_INFO_FILLER;
ch->leggfx = D2CHAR_INFO_FILLER;
ch->lhandweapon = D2CHAR_INFO_FILLER;
ch->lhandgfx = D2CHAR_INFO_FILLER;
ch->rhandweapon = D2CHAR_INFO_FILLER;
ch->rhandgfx = D2CHAR_INFO_FILLER;
ch->unknownb3 = D2CHAR_INFO_FILLER;
ch->unknownb4 = D2CHAR_INFO_FILLER;
ch->unknownb5 = D2CHAR_INFO_FILLER;
ch->unknownb6 = D2CHAR_INFO_FILLER;
ch->unknownb7 = D2CHAR_INFO_FILLER;
ch->unknownb8 = D2CHAR_INFO_FILLER;
ch->unknownb9 = D2CHAR_INFO_FILLER;
ch->unknownb10 = D2CHAR_INFO_FILLER;
ch->unknownb11 = D2CHAR_INFO_FILLER;
ch->unknown1 = 0xffffffff;
ch->unknown2 = 0xffffffff;
ch->unknown3 = 0xffffffff;
ch->unknown4 = 0xffffffff;
ch->level = 0x01;
ch->status = 0x80;
ch->title = 0x80;
ch->unknownb13 = 0x80;
ch->emblembgc = 0x80;
ch->emblemfgc = 0xff;
ch->emblemnum = 0xff;
ch->unknownb14 = D2CHAR_INFO_FILLER;
/*
b1 b2 hg bg lg lw lg rw rg b3 b4 b5 b6 b7 b8 b9 bA bB cl u1 u1 u1 u1 u2 u2 u2 u2 u3 u3 u3 u3 u4 u4 u4 u4 lv st ti bC eb ef en bD \0
amazon_qwer.std::log:
83 80 ff ff ff ff ff 43 ff 1b ff ff ff ff ff ff ff ff 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 80 80 ff ff ff 00
sor_Bent.std::log:
83 80 ff ff ff ff ff 53 ff ff ff ff ff ff ff ff ff ff 02 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 80 80 ff ff ff 00
necro_Thorsen.std::log:
83 80 ff ff ff ff ff 2b ff ff ff ff ff ff ff ff ff ff 03 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 80 80 ff ff ff 00
pal_QlexTEST.std::log:
87 80 01 01 01 01 01 ff ff ff 01 01 ff ff ff ff ff ff 04 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 ff ff ff 80 80 00
barb_Qlex.std::log:
83 80 ff ff ff ff ff 2f ff 1b ff ff ff ff ff ff ff ff 05 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 80 80 80 80 ff ff ff 00
*/
}
extern char const * character_get_playerinfo(t_character const * ch)
{
t_d2char_info d2char_info;
static char playerinfo[sizeof(t_d2char_info)+4];
static int load_initial_data(t_character * character, t_character_class chclass, t_character_expansion expansion)
{
char const * data_in_hex;
if (!ch)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL character");
return NULL;
}
eventlog(eventlog_level_debug, __FUNCTION__, "Initial Data for %s, %s %s",
character->name,
character_expansion_to_expansionname(expansion),
character_class_to_classname(chclass));
/*
ff 0f 68 00 ..h.
0x0040: 01 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ................
0x0050: d8 94 f6 08 b1 65 77 02 65 76 69 6c 67 72 75 73 .....ew.evilgrus
0x0060: 73 6c 65 72 00 56 44 32 44 42 65 74 61 57 65 73 sler.VD2DBetaWes
0x0070: 74 2c 74 61 72 61 6e 2c 83 80 ff ff ff ff ff 2f t,taran,......./
0x0080: ff ff ff ff ff ff ff ff ff ff 03 ff ff ff ff ff ................
0x0090: ff ff ff ff ff ff ff ff ff ff ff 07 80 80 80 80 ................
0x00a0: ff ff ff 00
/* Ideally, this would be loaded from bnetd_default_user, but I don't want to hack account.c just now */
*/
bn_byte_set(&d2char_info.unknownb1,ch->unknownb1);
bn_byte_set(&d2char_info.unknownb2,ch->unknownb2);
bn_byte_set(&d2char_info.helmgfx,ch->helmgfx);
bn_byte_set(&d2char_info.bodygfx,ch->bodygfx);
bn_byte_set(&d2char_info.leggfx,ch->leggfx);
bn_byte_set(&d2char_info.lhandweapon,ch->lhandweapon);
bn_byte_set(&d2char_info.lhandgfx,ch->lhandgfx);
bn_byte_set(&d2char_info.rhandweapon,ch->rhandweapon);
bn_byte_set(&d2char_info.rhandgfx,ch->rhandgfx);
bn_byte_set(&d2char_info.unknownb3,ch->unknownb3);
bn_byte_set(&d2char_info.unknownb4,ch->unknownb4);
bn_byte_set(&d2char_info.unknownb5,ch->unknownb5);
bn_byte_set(&d2char_info.unknownb6,ch->unknownb6);
bn_byte_set(&d2char_info.unknownb7,ch->unknownb7);
bn_byte_set(&d2char_info.unknownb8,ch->unknownb8);
bn_byte_set(&d2char_info.unknownb9,ch->unknownb9);
bn_byte_set(&d2char_info.unknownb10,ch->unknownb10);
bn_byte_set(&d2char_info.unknownb11,ch->unknownb11);
bn_byte_set(&d2char_info.chclass,ch->chclass);
bn_int_set(&d2char_info.unknown1,ch->unknown1);
bn_int_set(&d2char_info.unknown2,ch->unknown2);
bn_int_set(&d2char_info.unknown3,ch->unknown3);
bn_int_set(&d2char_info.unknown4,ch->unknown4);
bn_byte_set(&d2char_info.level,ch->level);
bn_byte_set(&d2char_info.status,ch->status);
bn_byte_set(&d2char_info.title,ch->title);
bn_byte_set(&d2char_info.unknownb13,ch->unknownb13);
bn_byte_set(&d2char_info.emblembgc,ch->emblembgc);
bn_byte_set(&d2char_info.emblemfgc,ch->emblemfgc);
bn_byte_set(&d2char_info.emblemnum,ch->emblemnum);
bn_byte_set(&d2char_info.unknownb14,ch->unknownb14);
/* The "default" character info if everything else messes up; */
data_in_hex = NULL; /* FIXME: what should we do if expansion or class isn't known... */
std::memcpy(playerinfo,&d2char_info,sizeof(d2char_info));
std::strcpy(&playerinfo[sizeof(d2char_info)],ch->guildname);
switch (expansion)
{
case character_expansion_classic:
switch (chclass)
{
case character_class_amazon:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 01 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
case character_class_sorceress:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 02 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
case character_class_necromancer:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 03 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
case character_class_paladin:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 04 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
case character_class_barbarian:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 05 FF FF FF FF FF FF FF FF FF FF FF 01 81 80 80 80 FF FF FF";
break;
default: break; //should never reach that part ot the code... but to make compiler happy...
}
break;
case character_expansion_lod:
switch (chclass)
{
case character_class_amazon:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 01 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_sorceress:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 02 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_necromancer:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 03 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_paladin:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 04 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_barbarian:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 05 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_druid:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 06 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
case character_class_assassin:
data_in_hex = "84 80 FF FF FF FF FF FF FF FF FF FF FF 07 FF FF FF FF FF FF FF FF FF FF FF 01 A1 80 80 80 FF FF FF";
break;
default: break; // again we will never get here... but how can compiler know that?!?
}
default: break; // well... like I said 2 times before....
}
return playerinfo;
}
character->datalen = hex_to_str(data_in_hex, (char*)character->data, 33);
decode_character_data(character);
return 0;
}
extern char const * character_get_guildname(t_character const * ch)
{
if (!ch)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL character");
return NULL;
}
return ch->guildname;
}
extern int character_create(t_account * account, t_clienttag clienttag, char const * realmname, char const * name, t_character_class chclass, t_character_expansion expansion)
{
t_character * ch;
if (!account)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
return -1;
}
if (!clienttag)
{
eventlog(eventlog_level_error, __FUNCTION__, "got bad clienttag");
return -1;
}
if (!realmname)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL realmname");
return -1;
}
if (!name)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL name");
return -1;
}
ch = (t_character*)xmalloc(sizeof(t_character));
ch->name = xstrdup(name);
ch->realmname = xstrdup(realmname);
ch->guildname = xstrdup(""); /* FIXME: how does this work on Battle.net? */
if (account_check_closed_character(account, clienttag, realmname, name))
{
eventlog(eventlog_level_error, __FUNCTION__, "a character with the name \"%s\" does already exist in realm \"%s\"", name, realmname);
xfree((void *)ch->realmname); /* avoid warning */
xfree((void *)ch->name); /* avoid warning */
xfree(ch);
return -1;
}
load_initial_data(ch, chclass, expansion);
account_add_closed_character(account, clienttag, ch);
return 0;
}
extern int character_verify_charlist(t_character const * ch, char const * charlist)
{
char * temp;
char const * tok1;
char const * tok2;
extern char const * character_get_name(t_character const * ch)
{
if (!ch)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL character");
return NULL;
}
return ch->name;
}
if (!ch)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL character");
return -1;
}
if (!charlist)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL character");
return -1;
}
temp = xstrdup(charlist);
extern char const * character_get_realmname(t_character const * ch)
{
if (!ch)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL character");
return NULL;
}
return ch->realmname;
}
extern t_character_class character_get_class(t_character const * ch)
{
if (!ch)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL character");
return character_class_none;
}
return bncharacter_class_to_character_class(ch->chclass);
}
extern char const * character_get_playerinfo(t_character const * ch)
{
t_d2char_info d2char_info;
static char playerinfo[sizeof(t_d2char_info)+4];
if (!ch)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL character");
return NULL;
}
/*
ff 0f 68 00 ..h.
0x0040: 01 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ................
0x0050: d8 94 f6 08 b1 65 77 02 65 76 69 6c 67 72 75 73 .....ew.evilgrus
0x0060: 73 6c 65 72 00 56 44 32 44 42 65 74 61 57 65 73 sler.VD2DBetaWes
0x0070: 74 2c 74 61 72 61 6e 2c 83 80 ff ff ff ff ff 2f t,taran,......./
0x0080: ff ff ff ff ff ff ff ff ff ff 03 ff ff ff ff ff ................
0x0090: ff ff ff ff ff ff ff ff ff ff ff 07 80 80 80 80 ................
0x00a0: ff ff ff 00
*/
bn_byte_set(&d2char_info.unknownb1, ch->unknownb1);
bn_byte_set(&d2char_info.unknownb2, ch->unknownb2);
bn_byte_set(&d2char_info.helmgfx, ch->helmgfx);
bn_byte_set(&d2char_info.bodygfx, ch->bodygfx);
bn_byte_set(&d2char_info.leggfx, ch->leggfx);
bn_byte_set(&d2char_info.lhandweapon, ch->lhandweapon);
bn_byte_set(&d2char_info.lhandgfx, ch->lhandgfx);
bn_byte_set(&d2char_info.rhandweapon, ch->rhandweapon);
bn_byte_set(&d2char_info.rhandgfx, ch->rhandgfx);
bn_byte_set(&d2char_info.unknownb3, ch->unknownb3);
bn_byte_set(&d2char_info.unknownb4, ch->unknownb4);
bn_byte_set(&d2char_info.unknownb5, ch->unknownb5);
bn_byte_set(&d2char_info.unknownb6, ch->unknownb6);
bn_byte_set(&d2char_info.unknownb7, ch->unknownb7);
bn_byte_set(&d2char_info.unknownb8, ch->unknownb8);
bn_byte_set(&d2char_info.unknownb9, ch->unknownb9);
bn_byte_set(&d2char_info.unknownb10, ch->unknownb10);
bn_byte_set(&d2char_info.unknownb11, ch->unknownb11);
bn_byte_set(&d2char_info.chclass, ch->chclass);
bn_int_set(&d2char_info.unknown1, ch->unknown1);
bn_int_set(&d2char_info.unknown2, ch->unknown2);
bn_int_set(&d2char_info.unknown3, ch->unknown3);
bn_int_set(&d2char_info.unknown4, ch->unknown4);
bn_byte_set(&d2char_info.level, ch->level);
bn_byte_set(&d2char_info.status, ch->status);
bn_byte_set(&d2char_info.title, ch->title);
bn_byte_set(&d2char_info.unknownb13, ch->unknownb13);
bn_byte_set(&d2char_info.emblembgc, ch->emblembgc);
bn_byte_set(&d2char_info.emblemfgc, ch->emblemfgc);
bn_byte_set(&d2char_info.emblemnum, ch->emblemnum);
bn_byte_set(&d2char_info.unknownb14, ch->unknownb14);
std::memcpy(playerinfo, &d2char_info, sizeof(d2char_info));
std::strcpy(&playerinfo[sizeof(d2char_info)], ch->guildname);
return playerinfo;
}
extern char const * character_get_guildname(t_character const * ch)
{
if (!ch)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL character");
return NULL;
}
return ch->guildname;
}
extern int character_verify_charlist(t_character const * ch, char const * charlist)
{
char * temp;
char const * tok1;
char const * tok2;
if (!ch)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL character");
return -1;
}
if (!charlist)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL character");
return -1;
}
temp = xstrdup(charlist);
tok1 = (char const *)std::strtok(temp, ","); /* std::strtok modifies the string it is passed */
tok2 = std::strtok(NULL, ",");
while (tok1)
{
if (!tok2)
{
eventlog(eventlog_level_error, __FUNCTION__, "bad character list \"%s\"", temp);
break;
}
if (strcasecmp(tok1, ch->realmname) == 0 && strcasecmp(tok2, ch->name) == 0)
{
xfree(temp);
return 0;
}
tok1 = std::strtok(NULL, ",");
tok2 = std::strtok(NULL, ",");
}
xfree(temp);
return -1;
}
extern int characterlist_create(char const * dirname)
{
characterlist_head = list_create();
return 0;
}
extern int characterlist_destroy(void)
{
t_elem * curr;
t_character * ch;
if (characterlist_head)
{
LIST_TRAVERSE(characterlist_head, curr)
{
ch = (t_character*)elem_get_data(curr);
if (!ch) /* should not happen */
{
eventlog(eventlog_level_error, __FUNCTION__, "characterlist contains NULL item");
continue;
}
if (list_remove_elem(characterlist_head, &curr) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not remove item from list");
xfree(ch);
}
if (list_destroy(characterlist_head) < 0)
return -1;
characterlist_head = NULL;
}
return 0;
}
extern t_character * characterlist_find_character(char const * realmname, char const * charname)
{
t_elem * curr;
t_character * ch;
if (!realmname)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL realmname");
return NULL;
}
if (!charname)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL charname");
return NULL;
}
LIST_TRAVERSE(characterlist_head, curr)
{
ch = (t_character*)elem_get_data(curr);
if (strcasecmp(ch->name, charname) == 0 && strcasecmp(ch->realmname, realmname) == 0)
return ch;
}
return NULL;
}
tok1 = (char const *)std::strtok(temp,","); /* std::strtok modifies the string it is passed */
tok2 = std::strtok(NULL,",");
while (tok1)
{
if (!tok2)
{
eventlog(eventlog_level_error,__FUNCTION__,"bad character list \"%s\"",temp);
break;
}
if (strcasecmp(tok1,ch->realmname)==0 && strcasecmp(tok2,ch->name)==0)
{
xfree(temp);
return 0;
}
tok1 = std::strtok(NULL,",");
tok2 = std::strtok(NULL,",");
}
xfree(temp);
return -1;
}
extern int characterlist_create(char const * dirname)
{
characterlist_head = list_create();
return 0;
}
extern int characterlist_destroy(void)
{
t_elem * curr;
t_character * ch;
if (characterlist_head)
{
LIST_TRAVERSE(characterlist_head,curr)
{
ch = (t_character*)elem_get_data(curr);
if (!ch) /* should not happen */
{
eventlog(eventlog_level_error,__FUNCTION__,"characterlist contains NULL item");
continue;
}
if (list_remove_elem(characterlist_head,&curr)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not remove item from list");
xfree(ch);
}
if (list_destroy(characterlist_head)<0)
return -1;
characterlist_head = NULL;
}
return 0;
}
extern t_character * characterlist_find_character(char const * realmname, char const * charname)
{
t_elem * curr;
t_character * ch;
if (!realmname)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL realmname");
return NULL;
}
if (!charname)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL charname");
return NULL;
}
LIST_TRAVERSE(characterlist_head,curr)
{
ch = (t_character*)elem_get_data(curr);
if (strcasecmp(ch->name,charname)==0 && strcasecmp(ch->realmname,realmname)==0)
return ch;
}
return NULL;
}
}
}

View file

@ -33,78 +33,78 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef enum
{
character_class_none,
character_class_amazon,
character_class_sorceress,
character_class_necromancer,
character_class_paladin,
character_class_barbarian,
character_class_druid,
character_class_assassin
} t_character_class;
typedef enum
{
character_class_none,
character_class_amazon,
character_class_sorceress,
character_class_necromancer,
character_class_paladin,
character_class_barbarian,
character_class_druid,
character_class_assassin
} t_character_class;
typedef enum
{
character_expansion_none,
character_expansion_classic,
character_expansion_lod
} t_character_expansion;
typedef enum
{
character_expansion_none,
character_expansion_classic,
character_expansion_lod
} t_character_expansion;
typedef struct character
typedef struct character
#ifdef CHARACTER_INTERNAL_ACCESS
{
char const * name; /* max 15 chars */
char const * realmname;
char const * guildname; /* max 3 chars */
{
char const * name; /* max 15 chars */
char const * realmname;
char const * guildname; /* max 3 chars */
/* stored in Battle.net format for now */
t_uint8 helmgfx;
t_uint8 bodygfx;
t_uint8 leggfx;
t_uint8 lhandweapon;
t_uint8 lhandgfx;
t_uint8 rhandweapon;
t_uint8 rhandgfx;
t_uint8 chclass;
t_uint8 level;
t_uint8 status;
t_uint8 title;
t_uint8 emblembgc;
t_uint8 emblemfgc;
t_uint8 emblemnum;
/* stored in Battle.net format for now */
t_uint8 helmgfx;
t_uint8 bodygfx;
t_uint8 leggfx;
t_uint8 lhandweapon;
t_uint8 lhandgfx;
t_uint8 rhandweapon;
t_uint8 rhandgfx;
t_uint8 chclass;
t_uint8 level;
t_uint8 status;
t_uint8 title;
t_uint8 emblembgc;
t_uint8 emblemfgc;
t_uint8 emblemnum;
/* not sure what these represent */
t_uint32 unknown1;
t_uint32 unknown2;
t_uint32 unknown3;
t_uint32 unknown4;
t_uint8 unknownb1;
t_uint8 unknownb2;
t_uint8 unknownb3;
t_uint8 unknownb4;
t_uint8 unknownb5;
t_uint8 unknownb6;
t_uint8 unknownb7;
t_uint8 unknownb8;
t_uint8 unknownb9;
t_uint8 unknownb10;
t_uint8 unknownb11;
t_uint8 unknownb13;
t_uint8 unknownb14;
/* not sure what these represent */
t_uint32 unknown1;
t_uint32 unknown2;
t_uint32 unknown3;
t_uint32 unknown4;
t_uint8 unknownb1;
t_uint8 unknownb2;
t_uint8 unknownb3;
t_uint8 unknownb4;
t_uint8 unknownb5;
t_uint8 unknownb6;
t_uint8 unknownb7;
t_uint8 unknownb8;
t_uint8 unknownb9;
t_uint8 unknownb10;
t_uint8 unknownb11;
t_uint8 unknownb13;
t_uint8 unknownb14;
/* Keep some generic "data", basically the blob that is sent between client and server, in an array */
t_uint8 data[64];
t_uint8 datalen;
}
/* Keep some generic "data", basically the blob that is sent between client and server, in an array */
t_uint8 data[64];
t_uint8 datalen;
}
#endif
t_character;
t_character;
}
}
}
@ -124,22 +124,22 @@ t_character;
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int character_create(t_account * account, t_clienttag clienttag, char const * realmname, char const * name, t_character_class chclass, t_character_expansion expansion);
extern char const * character_get_name(t_character const * ch);
extern char const * character_get_realmname(t_character const * ch);
extern char const * character_get_playerinfo(t_character const * ch);
extern char const * character_get_guildname(t_character const * ch);
extern t_character_class character_get_class(t_character const * ch);
extern int character_verify_charlist(t_character const * ch, char const * charlist);
extern int character_create(t_account * account, t_clienttag clienttag, char const * realmname, char const * name, t_character_class chclass, t_character_expansion expansion);
extern char const * character_get_name(t_character const * ch);
extern char const * character_get_realmname(t_character const * ch);
extern char const * character_get_playerinfo(t_character const * ch);
extern char const * character_get_guildname(t_character const * ch);
extern t_character_class character_get_class(t_character const * ch);
extern int character_verify_charlist(t_character const * ch, char const * charlist);
extern int characterlist_create(char const * dirname);
extern int characterlist_destroy(void);
extern t_character * characterlist_find_character(char const * realmname, char const * charname);
extern int characterlist_create(char const * dirname);
extern int characterlist_destroy(void);
extern t_character * characterlist_find_character(char const * realmname, char const * charname);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -49,50 +49,50 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef t_tag t_clantag;
typedef t_tag t_clantag;
typedef struct clan
typedef struct clan
#ifdef CLAN_INTERNAL_ACCESS
{
unsigned int clanid;
t_clantag tag;
char const *clanname;
std::time_t creation_time;
char const *clan_motd;
t_list *members;
int created;
/* --by Soar
on create, set it to -count of invited members,
each accept packet will inc it by 1,
when it is increased to 0, means that all invited members have accepted,
then clan will be created and set this value to 1
*/
char modified;
char channel_type; /* 0--public 1--private */
}
{
unsigned int clanid;
t_clantag tag;
char const *clanname;
std::time_t creation_time;
char const *clan_motd;
t_list *members;
int created;
/* --by Soar
on create, set it to -count of invited members,
each accept packet will inc it by 1,
when it is increased to 0, means that all invited members have accepted,
then clan will be created and set this value to 1
*/
char modified;
char channel_type; /* 0--public 1--private */
}
#endif
t_clan;
t_clan;
typedef struct _clanmember
typedef struct _clanmember
#ifdef CLAN_INTERNAL_ACCESS
{
t_account * memberacc;
char status;
std::time_t join_time;
t_clan * clan;
int fullmember; /* PELISH: 0 -- clanmember is only invited,
1 -- clanmember is fullmember */
{
t_account * memberacc;
char status;
std::time_t join_time;
t_clan * clan;
int fullmember; /* PELISH: 0 -- clanmember is only invited,
1 -- clanmember is fullmember */
#ifdef WITH_SQL
char modified;
char modified;
#endif
}
}
#endif
t_clanmember;
t_clanmember;
}
}
}
#define CLAN_CHIEFTAIN 0x04
@ -115,85 +115,85 @@ t_clanmember;
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern t_list *clanlist(void);
extern int clanlist_load(void);
extern int clanlist_save(void);
extern int clanlist_unload(void);
extern int clanlist_remove_clan(t_clan * clan);
extern int clanlist_add_clan(t_clan * clan);
extern t_clan *clanlist_find_clan_by_clanid(unsigned cid);
extern t_clan *clanlist_find_clan_by_clantag(t_clantag clantag);
extern t_list *clanlist(void);
extern int clanlist_load(void);
extern int clanlist_save(void);
extern int clanlist_unload(void);
extern int clanlist_remove_clan(t_clan * clan);
extern int clanlist_add_clan(t_clan * clan);
extern t_clan *clanlist_find_clan_by_clanid(unsigned cid);
extern t_clan *clanlist_find_clan_by_clantag(t_clantag clantag);
extern t_account *clanmember_get_account(t_clanmember * member);
extern int clanmember_set_account(t_clanmember * member, t_account * memberacc);
extern t_connection *clanmember_get_conn(t_clanmember * member);
extern char clanmember_get_status(t_clanmember * member);
extern int clanmember_set_status(t_clanmember * member, char status);
extern int clanmember_set_join_time(t_clanmember * member, std::time_t join_time);
extern std::time_t clanmember_get_join_time(t_clanmember * member);
extern t_clan * clanmember_get_clan(t_clanmember * member);
extern int clanmember_set_online(t_connection * c);
extern int clanmember_set_offline(t_connection * c);
extern int clanmember_get_fullmember(t_clanmember * member);
extern int clanmember_set_fullmember(t_clanmember * member, int fullmember);
extern t_account *clanmember_get_account(t_clanmember * member);
extern int clanmember_set_account(t_clanmember * member, t_account * memberacc);
extern t_connection *clanmember_get_conn(t_clanmember * member);
extern char clanmember_get_status(t_clanmember * member);
extern int clanmember_set_status(t_clanmember * member, char status);
extern int clanmember_set_join_time(t_clanmember * member, std::time_t join_time);
extern std::time_t clanmember_get_join_time(t_clanmember * member);
extern t_clan * clanmember_get_clan(t_clanmember * member);
extern int clanmember_set_online(t_connection * c);
extern int clanmember_set_offline(t_connection * c);
extern int clanmember_get_fullmember(t_clanmember * member);
extern int clanmember_set_fullmember(t_clanmember * member, int fullmember);
extern const char *clanmember_get_online_status(t_clanmember * member, char *status);
extern int clanmember_on_change_status(t_clanmember * member);
extern const char *clanmember_get_online_status_by_connection(t_connection * conn, char *status);
extern int clanmember_on_change_status_by_connection(t_connection * conn);
extern const char *clanmember_get_online_status(t_clanmember * member, char *status);
extern int clanmember_on_change_status(t_clanmember * member);
extern const char *clanmember_get_online_status_by_connection(t_connection * conn, char *status);
extern int clanmember_on_change_status_by_connection(t_connection * conn);
extern t_clan *clan_create(t_account * chieftain_acc, t_clantag clantag, const char *clanname, const char *motd);
extern int clan_destroy(t_clan * clan);
extern t_clan *clan_create(t_account * chieftain_acc, t_clantag clantag, const char *clanname, const char *motd);
extern int clan_destroy(t_clan * clan);
extern int clan_unload_members(t_clan * clan);
extern int clan_remove_all_members(t_clan * clan);
extern int clan_unload_members(t_clan * clan);
extern int clan_remove_all_members(t_clan * clan);
extern int clan_save(t_clan * clan);
extern int clan_remove(t_clantag clantag);
extern int clan_save(t_clan * clan);
extern int clan_remove(t_clantag clantag);
extern int clan_get_created(t_clan * clan);
extern int clan_set_created(t_clan * clan, int created);
extern char clan_get_modified(t_clan * clan);
extern int clan_set_modified(t_clan * clan, char modified);
extern char clan_get_channel_type(t_clan * clan);
extern int clan_set_channel_type(t_clan * clan, char channel_type);
extern t_list *clan_get_members(t_clan * clan);
extern char const *clan_get_name(t_clan * clan);
extern t_clantag clan_get_clantag(t_clan * clan);
extern char const *clan_get_motd(t_clan * clan);
extern int clan_set_motd(t_clan * clan, const char *motd);
extern unsigned int clan_get_clanid(t_clan * clan);
extern int clan_set_creation_time(t_clan * clan, std::time_t c_time);
extern std::time_t clan_get_creation_time(t_clan * clan);
extern unsigned clan_get_member_count(t_clan * clan);
extern int clan_get_created(t_clan * clan);
extern int clan_set_created(t_clan * clan, int created);
extern char clan_get_modified(t_clan * clan);
extern int clan_set_modified(t_clan * clan, char modified);
extern char clan_get_channel_type(t_clan * clan);
extern int clan_set_channel_type(t_clan * clan, char channel_type);
extern t_list *clan_get_members(t_clan * clan);
extern char const *clan_get_name(t_clan * clan);
extern t_clantag clan_get_clantag(t_clan * clan);
extern char const *clan_get_motd(t_clan * clan);
extern int clan_set_motd(t_clan * clan, const char *motd);
extern unsigned int clan_get_clanid(t_clan * clan);
extern int clan_set_creation_time(t_clan * clan, std::time_t c_time);
extern std::time_t clan_get_creation_time(t_clan * clan);
extern unsigned clan_get_member_count(t_clan * clan);
extern t_clanmember *clan_add_member(t_clan * clan, t_account * memberacc, char status);
extern int clan_remove_member(t_clan * clan, t_clanmember * member);
extern t_clanmember *clan_add_member(t_clan * clan, t_account * memberacc, char status);
extern int clan_remove_member(t_clan * clan, t_clanmember * member);
extern t_clanmember *clan_find_member(t_clan * clan, t_account * memberacc);
extern t_clanmember *clan_find_member_by_name(t_clan * clan, char const *membername);
extern t_clanmember *clan_find_member_by_uid(t_clan * clan, unsigned int memberuid);
extern t_clanmember *clan_find_member(t_clan * clan, t_account * memberacc);
extern t_clanmember *clan_find_member_by_name(t_clan * clan, char const *membername);
extern t_clanmember *clan_find_member_by_uid(t_clan * clan, unsigned int memberuid);
extern int clan_send_message_to_online_members(t_clan * clan, t_message_type type, t_connection * me, char const * text);
extern int clan_send_packet_to_online_members(t_clan * clan, t_packet * packet);
extern int clan_get_possible_member(t_connection * c, t_packet const *const packet);
extern int clan_send_status_window(t_connection * c);
extern int clan_send_status_window_on_create(t_clan * clan);
extern int clan_close_status_window(t_connection * c);
extern int clan_close_status_window_on_disband(t_clan * clan);
extern int clan_send_memberlist(t_connection * c, t_packet const *const packet);
extern int clan_change_member_status(t_connection * c, t_packet const *const packet);
extern int clan_send_motd_reply(t_connection * c, t_packet const *const packet);
extern int clan_save_motd_chg(t_connection * c, t_packet const *const packet);
extern int clan_send_message_to_online_members(t_clan * clan, t_message_type type, t_connection * me, char const * text);
extern int clan_send_packet_to_online_members(t_clan * clan, t_packet * packet);
extern int clan_get_possible_member(t_connection * c, t_packet const *const packet);
extern int clan_send_status_window(t_connection * c);
extern int clan_send_status_window_on_create(t_clan * clan);
extern int clan_close_status_window(t_connection * c);
extern int clan_close_status_window_on_disband(t_clan * clan);
extern int clan_send_memberlist(t_connection * c, t_packet const *const packet);
extern int clan_change_member_status(t_connection * c, t_packet const *const packet);
extern int clan_send_motd_reply(t_connection * c, t_packet const *const packet);
extern int clan_save_motd_chg(t_connection * c, t_packet const *const packet);
extern t_clantag str_to_clantag(const char *str);
extern const char* clantag_to_str(t_clantag tag);
extern t_clantag str_to_clantag(const char *str);
extern const char* clantag_to_str(t_clantag tag);
}
}
}

View file

@ -38,326 +38,328 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
static struct {
static struct {
#ifdef DO_DAEMONIZE
unsigned foreground;
unsigned foreground;
#endif
const char *preffile;
const char *hexfile;
unsigned debug;
const char *preffile;
const char *hexfile;
unsigned debug;
#ifdef WIN32_GUI
unsigned console;
unsigned gui;
unsigned console;
unsigned gui;
#endif
} cmdline_config;
} cmdline_config;
static unsigned exitflag;
static const char *progname;
static unsigned exitflag;
static const char *progname;
#ifdef DO_DAEMONIZE
static int conf_set_foreground(const char *valstr);
static int conf_setdef_foreground(void);
static int conf_set_foreground(const char *valstr);
static int conf_setdef_foreground(void);
#endif
static int conf_set_preffile(const char *valstr);
static int conf_setdef_preffile(void);
static int conf_set_preffile(const char *valstr);
static int conf_setdef_preffile(void);
static int conf_set_hexfile(const char *valstr);
static int conf_setdef_hexfile(void);
static int conf_set_hexfile(const char *valstr);
static int conf_setdef_hexfile(void);
static int conf_set_debug(const char *valstr);
static int conf_setdef_debug(void);
static int conf_set_debug(const char *valstr);
static int conf_setdef_debug(void);
static int conf_set_help(const char *valstr);
static int conf_setdef_help(void);
static int conf_set_help(const char *valstr);
static int conf_setdef_help(void);
static int conf_set_version(const char *valstr);
static int conf_setdef_version(void);
static int conf_set_version(const char *valstr);
static int conf_setdef_version(void);
#ifdef WIN32
static int conf_set_service(const char *valstr);
static int conf_setdef_service(void);
static int conf_set_service(const char *valstr);
static int conf_setdef_service(void);
static int conf_set_servaction(const char *valstr);
static int conf_setdef_servaction(void);
static int conf_set_servaction(const char *valstr);
static int conf_setdef_servaction(void);
#endif
#ifdef WIN32_GUI
static int conf_set_console(char const * valstr);
static int conf_setdef_console(void);
static int conf_set_console(char const * valstr);
static int conf_setdef_console(void);
static int conf_set_gui(char const * valstr);
static int conf_setdef_gui(void);
static int conf_set_gui(char const * valstr);
static int conf_setdef_gui(void);
#endif
static t_conf_entry conftab[] = {
{ "c", conf_set_preffile, NULL, conf_setdef_preffile },
{ "config", conf_set_preffile, NULL, conf_setdef_preffile },
{ "d", conf_set_hexfile, NULL, conf_setdef_hexfile },
{ "hexdump", conf_set_hexfile, NULL, conf_setdef_hexfile },
static t_conf_entry conftab[] = {
{ "c", conf_set_preffile, NULL, conf_setdef_preffile },
{ "config", conf_set_preffile, NULL, conf_setdef_preffile },
{ "d", conf_set_hexfile, NULL, conf_setdef_hexfile },
{ "hexdump", conf_set_hexfile, NULL, conf_setdef_hexfile },
#ifdef DO_DAEMONIZE
{ "f", conf_set_foreground, NULL, conf_setdef_foreground },
{ "foreground", conf_set_foreground, NULL, conf_setdef_foreground },
{ "f", conf_set_foreground, NULL, conf_setdef_foreground },
{ "foreground", conf_set_foreground, NULL, conf_setdef_foreground },
#endif
{ "D", conf_set_debug, NULL, conf_setdef_debug },
{ "debug", conf_set_debug, NULL, conf_setdef_debug },
{ "h", conf_set_help, NULL, conf_setdef_help },
{ "help", conf_set_help, NULL, conf_setdef_help },
{ "usage", conf_set_help, NULL, conf_setdef_help },
{ "v", conf_set_version, NULL, conf_setdef_version },
{ "version", conf_set_version, NULL, conf_setdef_version },
{ "D", conf_set_debug, NULL, conf_setdef_debug },
{ "debug", conf_set_debug, NULL, conf_setdef_debug },
{ "h", conf_set_help, NULL, conf_setdef_help },
{ "help", conf_set_help, NULL, conf_setdef_help },
{ "usage", conf_set_help, NULL, conf_setdef_help },
{ "v", conf_set_version, NULL, conf_setdef_version },
{ "version", conf_set_version, NULL, conf_setdef_version },
#ifdef WIN32
{ "service", conf_set_service, NULL, conf_setdef_service },
{ "s", conf_set_servaction, NULL, conf_setdef_servaction },
{ "service", conf_set_service, NULL, conf_setdef_service },
{ "s", conf_set_servaction, NULL, conf_setdef_servaction },
#endif
#ifdef WIN32_GUI
{ "console", conf_set_console, NULL, conf_setdef_console },
{ "gui", conf_set_gui, NULL, conf_setdef_gui },
{ "console", conf_set_console, NULL, conf_setdef_console },
{ "gui", conf_set_gui, NULL, conf_setdef_gui },
#endif
{ NULL, NULL, NULL, NULL }
};
{ NULL, NULL, NULL, NULL }
};
static void usage(void)
{
std::fprintf(stderr,
"usage: %s [<options>]\n"
" -c FILE, --config=FILE use FILE as configuration file (default is " BNETD_DEFAULT_CONF_FILE ")\n"
" -d FILE, --hexdump=FILE do hex dump of packets into FILE\n"
static void usage(void)
{
std::fprintf(stderr,
"usage: %s [<options>]\n"
" -c FILE, --config=FILE use FILE as configuration file (default is " BNETD_DEFAULT_CONF_FILE ")\n"
" -d FILE, --hexdump=FILE do hex dump of packets into FILE\n"
#ifdef DO_DAEMONIZE
" -f, --foreground don't daemonize\n"
" -f, --foreground don't daemonize\n"
#endif
" -D, --debug run in debug mode (run in foreground and log to stdout)\n"
" -h, --help, --usage show this information and exit\n"
" -v, --version print version number and exit\n"
" -D, --debug run in debug mode (run in foreground and log to stdout)\n"
" -h, --help, --usage show this information and exit\n"
" -v, --version print version number and exit\n"
#ifdef WIN32
" Running as service functions:\n"
" --service run as service\n"
" -s install install service\n"
" -s uninstall uninstall service\n"
" Running as service functions:\n"
" --service run as service\n"
" -s install install service\n"
" -s uninstall uninstall service\n"
#endif
#ifdef WIN32GUI
" -console run in console mode\n"
" -console run in console mode\n"
#endif
,progname);
}
, progname);
}
extern int cmdline_load(int argc, char** argv)
{
int res;
extern int cmdline_load(int argc, char** argv)
{
int res;
if (argc<1 || !argv || !argv[0]) {
std::fprintf(stderr,"bad arguments\n");
return -1;
}
if (argc < 1 || !argv || !argv[0]) {
std::fprintf(stderr, "bad arguments\n");
return -1;
}
exitflag = 0;
progname = argv[0];
exitflag = 0;
progname = argv[0];
res = conf_load_cmdline(argc, argv, conftab);
if (res < 0) return -1;
return exitflag ? 0 : 1;
}
res = conf_load_cmdline(argc, argv, conftab);
if (res < 0) return -1;
return exitflag ? 0 : 1;
}
extern void cmdline_unload(void)
{
conf_unload(conftab);
}
extern void cmdline_unload(void)
{
conf_unload(conftab);
}
#ifdef DO_DAEMONIZE
extern int cmdline_get_foreground(void)
{
return cmdline_config.foreground;
}
extern int cmdline_get_foreground(void)
{
return cmdline_config.foreground;
}
static int conf_set_foreground(const char *valstr)
{
return conf_set_bool(&cmdline_config.foreground, valstr, 0);
}
static int conf_set_foreground(const char *valstr)
{
return conf_set_bool(&cmdline_config.foreground, valstr, 0);
}
static int conf_setdef_foreground(void)
{
return conf_set_bool(&cmdline_config.foreground, NULL, 0);
}
static int conf_setdef_foreground(void)
{
return conf_set_bool(&cmdline_config.foreground, NULL, 0);
}
#endif
extern const char* cmdline_get_preffile(void)
{
return cmdline_config.preffile;
}
extern const char* cmdline_get_preffile(void)
{
return cmdline_config.preffile;
}
static int conf_set_preffile(const char *valstr)
{
return conf_set_str(&cmdline_config.preffile, valstr, NULL);
}
static int conf_set_preffile(const char *valstr)
{
return conf_set_str(&cmdline_config.preffile, valstr, NULL);
}
static int conf_setdef_preffile(void)
{
return conf_set_str(&cmdline_config.preffile, NULL, BNETD_DEFAULT_CONF_FILE);
}
static int conf_setdef_preffile(void)
{
return conf_set_str(&cmdline_config.preffile, NULL, BNETD_DEFAULT_CONF_FILE);
}
extern const char* cmdline_get_hexfile(void)
{
return cmdline_config.hexfile;
}
extern const char* cmdline_get_hexfile(void)
{
return cmdline_config.hexfile;
}
static int conf_set_hexfile(const char *valstr)
{
return conf_set_str(&cmdline_config.hexfile, valstr, NULL);
}
static int conf_set_hexfile(const char *valstr)
{
return conf_set_str(&cmdline_config.hexfile, valstr, NULL);
}
static int conf_setdef_hexfile(void)
{
return conf_set_str(&cmdline_config.hexfile, NULL, NULL);
}
static int conf_setdef_hexfile(void)
{
return conf_set_str(&cmdline_config.hexfile, NULL, NULL);
}
static int conf_set_debug(const char *valstr)
{
conf_set_bool(&cmdline_config.debug, valstr, 0);
if (cmdline_config.debug) eventlog_set_debugmode(1);
static int conf_set_debug(const char *valstr)
{
conf_set_bool(&cmdline_config.debug, valstr, 0);
if (cmdline_config.debug) eventlog_set_debugmode(1);
#ifdef DO_DAEMONIZE
cmdline_config.foreground = 1;
cmdline_config.foreground = 1;
#endif
return 0;
}
return 0;
}
static int conf_setdef_debug(void)
{
return conf_set_bool(&cmdline_config.debug, NULL, 0);
}
static int conf_setdef_debug(void)
{
return conf_set_bool(&cmdline_config.debug, NULL, 0);
}
static int conf_set_help(const char *valstr)
{
unsigned tmp = 0;
static int conf_set_help(const char *valstr)
{
unsigned tmp = 0;
conf_set_bool(&tmp, valstr, 0);
if (tmp) {
usage();
exitflag = 1;
}
conf_set_bool(&tmp, valstr, 0);
if (tmp) {
usage();
exitflag = 1;
}
return 0;
}
return 0;
}
static int conf_setdef_help(void)
{
return 0;
}
static int conf_setdef_help(void)
{
return 0;
}
static int conf_set_version(const char *valstr)
{
unsigned tmp = 0;
static int conf_set_version(const char *valstr)
{
unsigned tmp = 0;
conf_set_bool(&tmp, valstr, 0);
if (tmp) {
printf(PVPGN_SOFTWARE" version "PVPGN_VERSION"\n");
exitflag = 1;
}
conf_set_bool(&tmp, valstr, 0);
if (tmp) {
printf(PVPGN_SOFTWARE" version "PVPGN_VERSION"\n");
exitflag = 1;
}
return 0;
}
return 0;
}
static int conf_setdef_version(void)
{
return 0;
}
static int conf_setdef_version(void)
{
return 0;
}
#ifdef WIN32
static int conf_set_service(const char *valstr)
{
unsigned tmp = 0;
static int conf_set_service(const char *valstr)
{
unsigned tmp = 0;
conf_set_bool(&tmp, valstr, 0);
if (tmp) {
Win32_ServiceRun();
exitflag = 1;
}
conf_set_bool(&tmp, valstr, 0);
if (tmp) {
Win32_ServiceRun();
exitflag = 1;
}
return 0;
}
return 0;
}
static int conf_setdef_service(void)
{
return 0;
}
static int conf_setdef_service(void)
{
return 0;
}
static int conf_set_servaction(const char *valstr)
{
const char* tmp = NULL;
static int conf_set_servaction(const char *valstr)
{
const char* tmp = NULL;
conf_set_str(&tmp, valstr, NULL);
conf_set_str(&tmp, valstr, NULL);
if (tmp) {
if (!strcasecmp(tmp, "install")) {
std::fprintf(stderr, "Installing service");
Win32_ServiceInstall();
} else if (!strcasecmp(tmp, "uninstall")) {
std::fprintf(stderr, "Uninstalling service");
Win32_ServiceUninstall();
} else {
std::fprintf(stderr, "Unknown service action '%s'\n", tmp);
}
if (tmp) {
if (!strcasecmp(tmp, "install")) {
std::fprintf(stderr, "Installing service");
Win32_ServiceInstall();
}
else if (!strcasecmp(tmp, "uninstall")) {
std::fprintf(stderr, "Uninstalling service");
Win32_ServiceUninstall();
}
else {
std::fprintf(stderr, "Unknown service action '%s'\n", tmp);
}
exitflag = 1;
xfree((void *)tmp);
}
exitflag = 1;
xfree((void *)tmp);
}
return 0;
}
return 0;
}
static int conf_setdef_servaction(void)
{
return 0;
}
static int conf_setdef_servaction(void)
{
return 0;
}
#endif
#ifdef WIN32_GUI
static int conf_set_console(const char *valstr)
{
conf_set_bool(&cmdline_config.console, valstr, 0);
if (cmdline_config.console){
conf_set_bool(&cmdline_config.gui, NULL, 0);
}
return 0;
}
static int conf_set_console(const char *valstr)
{
conf_set_bool(&cmdline_config.console, valstr, 0);
if (cmdline_config.console){
conf_set_bool(&cmdline_config.gui, NULL, 0);
}
return 0;
}
static int conf_setdef_console(void)
{
return conf_set_bool(&cmdline_config.console, NULL, 0);
}
static int conf_setdef_console(void)
{
return conf_set_bool(&cmdline_config.console, NULL, 0);
}
extern unsigned cmdline_get_console(void){
return cmdline_config.console;
}
extern unsigned cmdline_get_console(void){
return cmdline_config.console;
}
static int conf_set_gui(const char *valstr)
{
conf_set_bool(&cmdline_config.gui, valstr, 0);
if (cmdline_config.gui){
}
return 0;
}
static int conf_set_gui(const char *valstr)
{
conf_set_bool(&cmdline_config.gui, valstr, 0);
if (cmdline_config.gui){
}
return 0;
}
static int conf_setdef_gui(void)
{
return conf_set_bool(&cmdline_config.gui, NULL, 1);
}
static int conf_setdef_gui(void)
{
return conf_set_bool(&cmdline_config.gui, NULL, 1);
}
extern unsigned cmdline_get_gui(void){
return cmdline_config.gui;
}
extern unsigned cmdline_get_gui(void){
return cmdline_config.gui;
}
#endif
}
}
}

View file

@ -22,24 +22,24 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int cmdline_load(int argc, char * * argv);
extern void cmdline_unload(void);
extern int cmdline_load(int argc, char * * argv);
extern void cmdline_unload(void);
/* options exported by cmdline */
/* options exported by cmdline */
#ifdef DO_DAEMONIZE
extern int cmdline_get_foreground(void);
extern int cmdline_get_foreground(void);
#endif
extern const char* cmdline_get_preffile(void);
extern const char* cmdline_get_hexfile(void);
extern const char* cmdline_get_preffile(void);
extern const char* cmdline_get_hexfile(void);
#ifdef WIN32_GUI
extern unsigned cmdline_get_console(void);
extern unsigned cmdline_get_gui(void);
extern unsigned cmdline_get_console(void);
extern unsigned cmdline_get_gui(void);
#endif
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -27,12 +27,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_command(t_connection * c, char const * text);
extern int handle_command(t_connection * c, char const * text);
}
}
}

View file

@ -33,117 +33,117 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
static t_list * command_groups_head=NULL;
static std::FILE * fp = NULL;
static t_list * command_groups_head = NULL;
static std::FILE * fp = NULL;
extern int command_groups_load(char const * filename)
{
unsigned int line;
unsigned int pos;
char * buff;
char * temp;
char const * command;
unsigned int group;
t_command_groups * entry;
extern int command_groups_load(char const * filename)
{
unsigned int line;
unsigned int pos;
char * buff;
char * temp;
char const * command;
unsigned int group;
t_command_groups * entry;
if (!filename) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename");
return -1;
}
if (!(fp = std::fopen(filename,"r"))) {
eventlog(eventlog_level_error,__FUNCTION__,"could not open file \"%s\" for reading (std::fopen: %s)",filename,std::strerror(errno));
return -1;
}
if (!filename) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL filename");
return -1;
}
if (!(fp = std::fopen(filename, "r"))) {
eventlog(eventlog_level_error, __FUNCTION__, "could not open file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno));
return -1;
}
command_groups_head = list_create();
command_groups_head = list_create();
for (line=1; (buff = file_get_line(fp)); line++) {
for (pos=0; buff[pos]=='\t' || buff[pos]==' '; pos++);
if (buff[pos]=='\0' || buff[pos]=='#') {
continue;
}
if ((temp = std::strrchr(buff,'#'))) {
unsigned int len;
unsigned int endpos;
for (line = 1; (buff = file_get_line(fp)); line++) {
for (pos = 0; buff[pos] == '\t' || buff[pos] == ' '; pos++);
if (buff[pos] == '\0' || buff[pos] == '#') {
continue;
}
if ((temp = std::strrchr(buff, '#'))) {
unsigned int len;
unsigned int endpos;
*temp = '\0';
len = std::strlen(buff)+1;
for (endpos=len-1; buff[endpos]=='\t' || buff[endpos]==' '; endpos--);
buff[endpos+1] = '\0';
}
if (!(temp = std::strtok(buff," \t"))) { /* std::strtok modifies the string it is passed */
eventlog(eventlog_level_error,__FUNCTION__,"missing group on line %u of file \"%s\"",line,filename);
continue;
}
if (str_to_uint(temp,&group)<0) {
eventlog(eventlog_level_error,__FUNCTION__,"group '%s' not a valid group (1-8)",temp);
continue;
}
if (group == 0 || group > 8) {
eventlog(eventlog_level_error,__FUNCTION__,"group '%u' not within groups limits (1-8)",group);
continue;
}
while ((command = std::strtok(NULL," \t"))) {
entry = (t_command_groups*)xmalloc(sizeof(t_command_groups));
entry->group = 1 << (group-1);
entry->command = xstrdup(command);
list_append_data(command_groups_head,entry);
*temp = '\0';
len = std::strlen(buff) + 1;
for (endpos = len - 1; buff[endpos] == '\t' || buff[endpos] == ' '; endpos--);
buff[endpos + 1] = '\0';
}
if (!(temp = std::strtok(buff, " \t"))) { /* std::strtok modifies the string it is passed */
eventlog(eventlog_level_error, __FUNCTION__, "missing group on line %u of file \"%s\"", line, filename);
continue;
}
if (str_to_uint(temp, &group)<0) {
eventlog(eventlog_level_error, __FUNCTION__, "group '%s' not a valid group (1-8)", temp);
continue;
}
if (group == 0 || group > 8) {
eventlog(eventlog_level_error, __FUNCTION__, "group '%u' not within groups limits (1-8)", group);
continue;
}
while ((command = std::strtok(NULL, " \t"))) {
entry = (t_command_groups*)xmalloc(sizeof(t_command_groups));
entry->group = 1 << (group - 1);
entry->command = xstrdup(command);
list_append_data(command_groups_head, entry);
#ifdef COMMANDGROUPSDEBUG
eventlog(eventlog_level_info,__FUNCTION__,"Added command: %s - with group %u",entry->command,entry->group);
eventlog(eventlog_level_info, __FUNCTION__, "Added command: %s - with group %u", entry->command, entry->group);
#endif
}
}
file_get_line(NULL); // clear file_get_line buffer
std::fclose(fp);
return 0;
}
extern int command_groups_unload(void)
{
t_elem * curr;
t_command_groups * entry;
if (command_groups_head) {
LIST_TRAVERSE(command_groups_head, curr) {
if (!(entry = (t_command_groups*)elem_get_data(curr)))
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
else {
xfree(entry->command);
xfree(entry);
}
list_remove_elem(command_groups_head, &curr);
}
list_destroy(command_groups_head);
command_groups_head = NULL;
}
return 0;
}
extern unsigned int command_get_group(char const * command)
{
t_elem const * curr;
t_command_groups * entry;
if (command_groups_head) {
LIST_TRAVERSE(command_groups_head, curr) {
if (!(entry = (t_command_groups*)elem_get_data(curr)))
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
else if (!(std::strcmp(entry->command, command)))
return entry->group;
}
}
return 0;
}
extern int command_groups_reload(char const * filename)
{
command_groups_unload();
return command_groups_load(filename);
}
}
}
file_get_line(NULL); // clear file_get_line buffer
std::fclose(fp);
return 0;
}
extern int command_groups_unload(void)
{
t_elem * curr;
t_command_groups * entry;
if (command_groups_head) {
LIST_TRAVERSE(command_groups_head,curr) {
if (!(entry = (t_command_groups*)elem_get_data(curr)))
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
else {
xfree(entry->command);
xfree(entry);
}
list_remove_elem(command_groups_head,&curr);
}
list_destroy(command_groups_head);
command_groups_head = NULL;
}
return 0;
}
extern unsigned int command_get_group(char const * command)
{
t_elem const * curr;
t_command_groups * entry;
if (command_groups_head) {
LIST_TRAVERSE(command_groups_head,curr) {
if (!(entry = (t_command_groups*)elem_get_data(curr)))
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
else if (!(std::strcmp(entry->command,command)))
return entry->group;
}
}
return 0;
}
extern int command_groups_reload(char const * filename)
{
command_groups_unload();
return command_groups_load(filename);
}
}
}

View file

@ -19,20 +19,20 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
#ifdef COMMAND_GROUPS_INTERNAL_ACCESS
typedef struct
{
char * command;
unsigned int group;
} t_command_groups;
typedef struct
{
char * command;
unsigned int group;
} t_command_groups;
#endif
}
}
}
@ -45,15 +45,15 @@ typedef struct
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int command_groups_load(char const * filename);
extern int command_groups_unload(void);
extern int command_groups_reload(char const * filename);
extern unsigned int command_get_group(char const * command);
extern int command_groups_load(char const * filename);
extern int command_groups_unload(void);
extern int command_groups_reload(char const * filename);
extern unsigned int command_get_group(char const * command);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -62,163 +62,163 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef enum
{
conn_class_init,
conn_class_bnet,
conn_class_file,
conn_class_bot,
conn_class_telnet,
conn_class_ircinit, /* IRC based protocol INIT*/
conn_class_irc, /* Internet Relay Chat */
conn_class_wol, /* Westwood Chat and Game protocol (IRC based) */
conn_class_wserv, /* Westwood servserv (IRC based) */
conn_class_wgameres, /* Westwood Gameresolution */
conn_class_wladder, /* Westwood Ladder server */
conn_class_apireg, /* Westwood API Register */
conn_class_d2cs_bnetd,
conn_class_w3route,
conn_class_none
} t_conn_class;
typedef enum
{
conn_class_init,
conn_class_bnet,
conn_class_file,
conn_class_bot,
conn_class_telnet,
conn_class_ircinit, /* IRC based protocol INIT*/
conn_class_irc, /* Internet Relay Chat */
conn_class_wol, /* Westwood Chat and Game protocol (IRC based) */
conn_class_wserv, /* Westwood servserv (IRC based) */
conn_class_wgameres, /* Westwood Gameresolution */
conn_class_wladder, /* Westwood Ladder server */
conn_class_apireg, /* Westwood API Register */
conn_class_d2cs_bnetd,
conn_class_w3route,
conn_class_none
} t_conn_class;
typedef enum
{
conn_state_empty,
conn_state_initial,
conn_state_connected,
conn_state_loggedin,
conn_state_destroy,
conn_state_bot_username,
conn_state_bot_password,
conn_state_untrusted,
conn_state_pending_raw
} t_conn_state;
typedef enum
{
conn_state_empty,
conn_state_initial,
conn_state_connected,
conn_state_loggedin,
conn_state_destroy,
conn_state_bot_username,
conn_state_bot_password,
conn_state_untrusted,
conn_state_pending_raw
} t_conn_state;
#ifdef CONNECTION_INTERNAL_ACCESS
typedef enum
{
conn_flags_welcomed = 0x01,
conn_flags_udpok = 0x02,
conn_flags_joingamewhisper = 0x04,
conn_flags_leavegamewhisper = 0x08,
conn_flags_echoback = 0x10
typedef enum
{
conn_flags_welcomed = 0x01,
conn_flags_udpok = 0x02,
conn_flags_joingamewhisper = 0x04,
conn_flags_leavegamewhisper = 0x08,
conn_flags_echoback = 0x10
} t_conn_flags;
} t_conn_flags;
#endif
typedef struct connection
typedef struct connection
#ifdef CONNECTION_INTERNAL_ACCESS
{
struct {
int tcp_sock;
unsigned int tcp_addr;
unsigned short tcp_port;
int udp_sock;
unsigned int udp_addr;
unsigned short udp_port;
unsigned int local_addr;
unsigned short local_port;
unsigned int real_local_addr;
unsigned short real_local_port;
int fdw_idx;
} socket; /* IP and socket specific data */
struct {
t_conn_class cclass;
t_conn_state state;
unsigned int sessionkey;
unsigned int sessionnum;
unsigned int secret; /* random number... never sent over net unencrypted */
unsigned int flags;
unsigned int latency;
t_account * account;
struct {
t_tag archtag;
t_tag gamelang;
t_clienttag clienttag;
char const * clientver;
unsigned long versionid; /* AKA bnversion */
unsigned long gameversion;
unsigned long checksum;
char const * country;
int tzbias;
char const * host;
char const * user;
char const * clientexe;
char const * owner;
char const * cdkey;
t_versioncheck * versioncheck; /* equation and MPQ file used to validate game checksum */
} client; /* client program specific data */
struct {
t_queue * outqueue; /* packets waiting to be sent */
unsigned int outsize; /* amount sent from the current output packet */
unsigned int outsizep;
t_packet * inqueue; /* packet waiting to be processed */
unsigned int insize; /* amount received into the current input packet */
} queues; /* network queues and related data */
struct {
t_channel * channel;
char const * tmpOP_channel;
char const * tmpVOICE_channel;
char const * away;
char const * dnd;
t_account * * ignore_list;
unsigned int ignore_count;
t_quota quota;
std::time_t last_message;
char const * lastsender; /* last person to whisper to this connection */
struct {
char const * ircline; /* line cache for IRC connections */
unsigned int ircping; /* value of last ping */
char const * ircpass; /* hashed password for PASS authentication */
} irc; /* irc chat specific data */
} chat; /* chat and messages specific data */
t_game * game;
const char * loggeduser; /* username as logged in or given (not taken from account) */
struct connection * bound; /* matching Diablo II auth connection */
t_elist timers; /* cached list of timers for cleaning */
/* FIXME: this d2/w3 specific data could be unified into an union */
struct {
t_realm * realm;
t_rcm_regref realm_regref;
t_character * character;
char const * realminfo;
char const * charname;
} d2;
struct {
char const * w3_playerinfo; /* ADDED BY UNDYING SOULZZ 4/7/02 */
std::time_t anongame_search_starttime;
/* [zap-zero] 20020527 - matching w3route connection for game connection /
matching game connection for w3route connection */
/* FIXME: this "optimization" is so confusing leading to many possible bugs */
struct connection * routeconn;
t_anongame * anongame;
/* those will be filled when recieving 0x53ff and wiped out after 54ff */
char const * client_proof;
char const * server_proof;
} w3;
struct {
int ingame; /* Are we in a game channel? */
int codepage;
int findme; /* Allow others to find me? */
int pageme; /* Allow others to page me? */
char const * apgar; /* WOL User Password (encrypted) */
t_anongame_wol_player * anongame_player;
} wol;
int cr_time;
/* Pass fail count for bruteforce protection */
unsigned int passfail_count;
/* connection flag substituting some other values */
unsigned int cflags;
} protocol;
}
{
struct {
int tcp_sock;
unsigned int tcp_addr;
unsigned short tcp_port;
int udp_sock;
unsigned int udp_addr;
unsigned short udp_port;
unsigned int local_addr;
unsigned short local_port;
unsigned int real_local_addr;
unsigned short real_local_port;
int fdw_idx;
} socket; /* IP and socket specific data */
struct {
t_conn_class cclass;
t_conn_state state;
unsigned int sessionkey;
unsigned int sessionnum;
unsigned int secret; /* random number... never sent over net unencrypted */
unsigned int flags;
unsigned int latency;
t_account * account;
struct {
t_tag archtag;
t_tag gamelang;
t_clienttag clienttag;
char const * clientver;
unsigned long versionid; /* AKA bnversion */
unsigned long gameversion;
unsigned long checksum;
char const * country;
int tzbias;
char const * host;
char const * user;
char const * clientexe;
char const * owner;
char const * cdkey;
t_versioncheck * versioncheck; /* equation and MPQ file used to validate game checksum */
} client; /* client program specific data */
struct {
t_queue * outqueue; /* packets waiting to be sent */
unsigned int outsize; /* amount sent from the current output packet */
unsigned int outsizep;
t_packet * inqueue; /* packet waiting to be processed */
unsigned int insize; /* amount received into the current input packet */
} queues; /* network queues and related data */
struct {
t_channel * channel;
char const * tmpOP_channel;
char const * tmpVOICE_channel;
char const * away;
char const * dnd;
t_account * * ignore_list;
unsigned int ignore_count;
t_quota quota;
std::time_t last_message;
char const * lastsender; /* last person to whisper to this connection */
struct {
char const * ircline; /* line cache for IRC connections */
unsigned int ircping; /* value of last ping */
char const * ircpass; /* hashed password for PASS authentication */
} irc; /* irc chat specific data */
} chat; /* chat and messages specific data */
t_game * game;
const char * loggeduser; /* username as logged in or given (not taken from account) */
struct connection * bound; /* matching Diablo II auth connection */
t_elist timers; /* cached list of timers for cleaning */
/* FIXME: this d2/w3 specific data could be unified into an union */
struct {
t_realm * realm;
t_rcm_regref realm_regref;
t_character * character;
char const * realminfo;
char const * charname;
} d2;
struct {
char const * w3_playerinfo; /* ADDED BY UNDYING SOULZZ 4/7/02 */
std::time_t anongame_search_starttime;
/* [zap-zero] 20020527 - matching w3route connection for game connection /
matching game connection for w3route connection */
/* FIXME: this "optimization" is so confusing leading to many possible bugs */
struct connection * routeconn;
t_anongame * anongame;
/* those will be filled when recieving 0x53ff and wiped out after 54ff */
char const * client_proof;
char const * server_proof;
} w3;
struct {
int ingame; /* Are we in a game channel? */
int codepage;
int findme; /* Allow others to find me? */
int pageme; /* Allow others to page me? */
char const * apgar; /* WOL User Password (encrypted) */
t_anongame_wol_player * anongame_player;
} wol;
int cr_time;
/* Pass fail count for bruteforce protection */
unsigned int passfail_count;
/* connection flag substituting some other values */
unsigned int cflags;
} protocol;
}
#endif
t_connection;
t_connection;
}
}
}
@ -256,216 +256,216 @@ t_connection;
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern t_anongame * conn_create_anongame(t_connection * c);
extern void conn_destroy_anongame(t_connection * c);
extern t_anongame * conn_create_anongame(t_connection * c);
extern void conn_destroy_anongame(t_connection * c);
extern t_anongame * conn_get_anongame(t_connection *c);
extern t_anongame * conn_get_anongame(t_connection *c);
extern void conn_shutdown(t_connection * c, std::time_t now, t_timer_data foo);
extern void conn_test_latency(t_connection * c, std::time_t now, t_timer_data delta);
extern char const * conn_class_get_str(t_conn_class cclass) ;
extern char const * conn_state_get_str(t_conn_state state) ;
extern void conn_shutdown(t_connection * c, std::time_t now, t_timer_data foo);
extern void conn_test_latency(t_connection * c, std::time_t now, t_timer_data delta);
extern char const * conn_class_get_str(t_conn_class cclass);
extern char const * conn_state_get_str(t_conn_state state);
extern t_connection * conn_create(int tsock, int usock, unsigned int real_local_addr, unsigned short real_local_port, unsigned int local_addr, unsigned short local_port, unsigned int addr, unsigned short port) ;
extern void conn_destroy(t_connection * c, t_elem ** elem, int conn_or_dead_list);
extern int conn_match(t_connection const * c, char const * user);
extern t_conn_class conn_get_class(t_connection const * c) ;
extern void conn_set_class(t_connection * c, t_conn_class cclass);
extern t_conn_state conn_get_state(t_connection const * c) ;
extern void conn_set_state(t_connection * c, t_conn_state state);
extern unsigned int conn_get_sessionkey(t_connection const * c) ;
extern unsigned int conn_get_sessionnum(t_connection const * c) ;
extern unsigned int conn_get_secret(t_connection const * c) ;
extern unsigned int conn_get_addr(t_connection const * c) ;
extern unsigned short conn_get_port(t_connection const * c) ;
extern unsigned int conn_get_local_addr(t_connection const * c);
extern unsigned short conn_get_local_port(t_connection const * c) ;
extern unsigned int conn_get_real_local_addr(t_connection const * c) ;
extern unsigned short conn_get_real_local_port(t_connection const * c) ;
extern unsigned int conn_get_game_addr(t_connection const * c) ;
extern int conn_set_game_addr(t_connection * c, unsigned int game_addr);
extern unsigned short conn_get_game_port(t_connection const * c) ;
extern int conn_set_game_port(t_connection * c, unsigned short game_port);
extern void conn_set_host(t_connection * c, char const * host);
extern void conn_set_user(t_connection * c, char const * user);
extern const char * conn_get_user(t_connection const * c);
extern void conn_set_owner(t_connection * c, char const * owner);
extern const char * conn_get_owner(t_connection const * c);
extern void conn_set_cdkey(t_connection * c, char const * cdkey);
extern char const * conn_get_clientexe(t_connection const * c) ;
extern void conn_set_clientexe(t_connection * c, char const * clientexe);
extern t_tag conn_get_archtag(t_connection const * c) ;
extern void conn_set_archtag(t_connection * c, t_tag archtag);
extern t_tag conn_get_gamelang(t_connection const * c) ;
extern void conn_set_gamelang(t_connection * c, t_tag gamelang);
extern t_clienttag conn_get_clienttag(t_connection const * c) ;
extern t_clienttag conn_get_fake_clienttag(t_connection const * c) ;
extern void conn_set_clienttag(t_connection * c, t_clienttag clienttag);
extern unsigned long conn_get_versionid(t_connection const * c) ;
extern int conn_set_versionid(t_connection * c, unsigned long versionid);
extern unsigned long conn_get_gameversion(t_connection const * c) ;
extern int conn_set_gameversion(t_connection * c, unsigned long gameversion);
extern unsigned long conn_get_checksum(t_connection const * c) ;
extern int conn_set_checksum(t_connection * c, unsigned long checksum);
extern char const * conn_get_clientver(t_connection const * c) ;
extern void conn_set_clientver(t_connection * c, char const * clientver);
extern int conn_get_tzbias(t_connection const * c) ;
extern void conn_set_tzbias(t_connection * c, int tzbias);
extern int conn_set_loggeduser(t_connection * c, char const * username);
extern char const * conn_get_loggeduser(t_connection const * c);
extern unsigned int conn_get_flags(t_connection const * c) ;
extern int conn_set_flags(t_connection * c, unsigned int flags);
extern void conn_add_flags(t_connection * c, unsigned int flags);
extern void conn_del_flags(t_connection * c, unsigned int flags);
extern unsigned int conn_get_latency(t_connection const * c) ;
extern void conn_set_latency(t_connection * c, unsigned int ms);
extern char const * conn_get_awaystr(t_connection const * c) ;
extern int conn_set_awaystr(t_connection * c, char const * away);
extern char const * conn_get_dndstr(t_connection const * c) ;
extern int conn_set_dndstr(t_connection * c, char const * dnd);
extern int conn_add_ignore(t_connection * c, t_account * account);
extern int conn_del_ignore(t_connection * c, t_account const * account);
extern int conn_add_watch(t_connection * c, t_account * account, t_clienttag clienttag);
extern int conn_del_watch(t_connection * c, t_account * account, t_clienttag clienttag);
extern t_channel * conn_get_channel(t_connection const * c) ;
extern int conn_set_channel_var(t_connection * c, t_channel * channel);
extern int conn_set_channel(t_connection * c, char const * channelname);
extern int conn_part_channel(t_connection * c);
extern int conn_kick_channel(t_connection * c, char const * text);
extern int conn_quit_channel(t_connection * c, char const * text);
extern t_game * conn_get_game(t_connection const * c) ;
extern int conn_set_game(t_connection * c, char const * gamename, char const * gamepass, char const * gameinfo, t_game_type type, int version);
extern unsigned int conn_get_tcpaddr(t_connection * c) ;
extern t_packet * conn_get_in_queue(t_connection * c) ;
extern void conn_put_in_queue(t_connection * c, t_packet *packet) ;
extern unsigned int conn_get_in_size(t_connection const * c) ;
extern void conn_set_in_size(t_connection * c, unsigned int size);
extern unsigned int conn_get_out_size(t_connection const * c) ;
extern void conn_set_out_size(t_connection * c, unsigned int size);
extern int conn_push_outqueue(t_connection * c, t_packet * packet);
extern t_packet * conn_peek_outqueue(t_connection * c);
extern t_packet * conn_pull_outqueue(t_connection * c);
extern int conn_clear_outqueue(t_connection * c);
extern void conn_close_read(t_connection * c);
extern int conn_check_ignoring(t_connection const * c, char const * me) ;
extern t_account * conn_get_account(t_connection const * c) ;
extern void conn_login(t_connection * c, t_account * account, const char *loggeduser);
extern int conn_get_socket(t_connection const * c) ;
extern int conn_get_game_socket(t_connection const * c) ;
extern int conn_set_game_socket(t_connection * c, int usock);
extern char const * conn_get_username_real(t_connection const * c, char const * fn, unsigned int ln);
extern t_connection * conn_create(int tsock, int usock, unsigned int real_local_addr, unsigned short real_local_port, unsigned int local_addr, unsigned short local_port, unsigned int addr, unsigned short port);
extern void conn_destroy(t_connection * c, t_elem ** elem, int conn_or_dead_list);
extern int conn_match(t_connection const * c, char const * user);
extern t_conn_class conn_get_class(t_connection const * c);
extern void conn_set_class(t_connection * c, t_conn_class cclass);
extern t_conn_state conn_get_state(t_connection const * c);
extern void conn_set_state(t_connection * c, t_conn_state state);
extern unsigned int conn_get_sessionkey(t_connection const * c);
extern unsigned int conn_get_sessionnum(t_connection const * c);
extern unsigned int conn_get_secret(t_connection const * c);
extern unsigned int conn_get_addr(t_connection const * c);
extern unsigned short conn_get_port(t_connection const * c);
extern unsigned int conn_get_local_addr(t_connection const * c);
extern unsigned short conn_get_local_port(t_connection const * c);
extern unsigned int conn_get_real_local_addr(t_connection const * c);
extern unsigned short conn_get_real_local_port(t_connection const * c);
extern unsigned int conn_get_game_addr(t_connection const * c);
extern int conn_set_game_addr(t_connection * c, unsigned int game_addr);
extern unsigned short conn_get_game_port(t_connection const * c);
extern int conn_set_game_port(t_connection * c, unsigned short game_port);
extern void conn_set_host(t_connection * c, char const * host);
extern void conn_set_user(t_connection * c, char const * user);
extern const char * conn_get_user(t_connection const * c);
extern void conn_set_owner(t_connection * c, char const * owner);
extern const char * conn_get_owner(t_connection const * c);
extern void conn_set_cdkey(t_connection * c, char const * cdkey);
extern char const * conn_get_clientexe(t_connection const * c);
extern void conn_set_clientexe(t_connection * c, char const * clientexe);
extern t_tag conn_get_archtag(t_connection const * c);
extern void conn_set_archtag(t_connection * c, t_tag archtag);
extern t_tag conn_get_gamelang(t_connection const * c);
extern void conn_set_gamelang(t_connection * c, t_tag gamelang);
extern t_clienttag conn_get_clienttag(t_connection const * c);
extern t_clienttag conn_get_fake_clienttag(t_connection const * c);
extern void conn_set_clienttag(t_connection * c, t_clienttag clienttag);
extern unsigned long conn_get_versionid(t_connection const * c);
extern int conn_set_versionid(t_connection * c, unsigned long versionid);
extern unsigned long conn_get_gameversion(t_connection const * c);
extern int conn_set_gameversion(t_connection * c, unsigned long gameversion);
extern unsigned long conn_get_checksum(t_connection const * c);
extern int conn_set_checksum(t_connection * c, unsigned long checksum);
extern char const * conn_get_clientver(t_connection const * c);
extern void conn_set_clientver(t_connection * c, char const * clientver);
extern int conn_get_tzbias(t_connection const * c);
extern void conn_set_tzbias(t_connection * c, int tzbias);
extern int conn_set_loggeduser(t_connection * c, char const * username);
extern char const * conn_get_loggeduser(t_connection const * c);
extern unsigned int conn_get_flags(t_connection const * c);
extern int conn_set_flags(t_connection * c, unsigned int flags);
extern void conn_add_flags(t_connection * c, unsigned int flags);
extern void conn_del_flags(t_connection * c, unsigned int flags);
extern unsigned int conn_get_latency(t_connection const * c);
extern void conn_set_latency(t_connection * c, unsigned int ms);
extern char const * conn_get_awaystr(t_connection const * c);
extern int conn_set_awaystr(t_connection * c, char const * away);
extern char const * conn_get_dndstr(t_connection const * c);
extern int conn_set_dndstr(t_connection * c, char const * dnd);
extern int conn_add_ignore(t_connection * c, t_account * account);
extern int conn_del_ignore(t_connection * c, t_account const * account);
extern int conn_add_watch(t_connection * c, t_account * account, t_clienttag clienttag);
extern int conn_del_watch(t_connection * c, t_account * account, t_clienttag clienttag);
extern t_channel * conn_get_channel(t_connection const * c);
extern int conn_set_channel_var(t_connection * c, t_channel * channel);
extern int conn_set_channel(t_connection * c, char const * channelname);
extern int conn_part_channel(t_connection * c);
extern int conn_kick_channel(t_connection * c, char const * text);
extern int conn_quit_channel(t_connection * c, char const * text);
extern t_game * conn_get_game(t_connection const * c);
extern int conn_set_game(t_connection * c, char const * gamename, char const * gamepass, char const * gameinfo, t_game_type type, int version);
extern unsigned int conn_get_tcpaddr(t_connection * c);
extern t_packet * conn_get_in_queue(t_connection * c);
extern void conn_put_in_queue(t_connection * c, t_packet *packet);
extern unsigned int conn_get_in_size(t_connection const * c);
extern void conn_set_in_size(t_connection * c, unsigned int size);
extern unsigned int conn_get_out_size(t_connection const * c);
extern void conn_set_out_size(t_connection * c, unsigned int size);
extern int conn_push_outqueue(t_connection * c, t_packet * packet);
extern t_packet * conn_peek_outqueue(t_connection * c);
extern t_packet * conn_pull_outqueue(t_connection * c);
extern int conn_clear_outqueue(t_connection * c);
extern void conn_close_read(t_connection * c);
extern int conn_check_ignoring(t_connection const * c, char const * me);
extern t_account * conn_get_account(t_connection const * c);
extern void conn_login(t_connection * c, t_account * account, const char *loggeduser);
extern int conn_get_socket(t_connection const * c);
extern int conn_get_game_socket(t_connection const * c);
extern int conn_set_game_socket(t_connection * c, int usock);
extern char const * conn_get_username_real(t_connection const * c, char const * fn, unsigned int ln);
#define conn_get_username(C) conn_get_username_real(C,__FILE__,__LINE__)
extern char const * conn_get_chatname(t_connection const * c);
extern int conn_unget_chatname(t_connection const * c, char const * name);
extern char const * conn_get_chatcharname(t_connection const * c, t_connection const * dst);
extern int conn_unget_chatcharname(t_connection const * c, char const * name);
extern t_message_class conn_get_message_class(t_connection const * c, t_connection const * dst);
extern unsigned int conn_get_userid(t_connection const * c);
extern char const * conn_get_playerinfo(t_connection const * c);
extern int conn_set_playerinfo(t_connection const * c, char const * playerinfo);
extern char const * conn_get_realminfo(t_connection const * c);
extern int conn_set_realminfo(t_connection * c, char const * realminfo);
extern char const * conn_get_charname(t_connection const * c);
extern int conn_set_charname(t_connection * c, char const * charname);
extern int conn_set_idletime(t_connection * c);
extern unsigned int conn_get_idletime(t_connection const * c) ;
extern t_realm * conn_get_realm(t_connection const * c);
extern int conn_set_realm(t_connection * c, t_realm * realm);
extern int conn_set_character(t_connection * c, t_character * ch);
extern int conn_bind(t_connection * c1, t_connection * c2);
extern void conn_set_country(t_connection * c, char const * country);
extern char const * conn_get_country(t_connection const * c);
extern int conn_quota_exceeded(t_connection * c, char const * message);
extern int conn_set_lastsender(t_connection * c, char const * sender);
extern char const * conn_get_lastsender(t_connection const * c);
extern t_versioncheck * conn_get_versioncheck(t_connection * c) ;
extern int conn_set_versioncheck(t_connection * c, t_versioncheck * versioncheck);
extern int conn_get_echoback(t_connection * c) ;
extern void conn_set_echoback(t_connection * c, int echoback);
extern int conn_set_ircline(t_connection * c, char const * line);
extern char const * conn_get_ircline(t_connection const * c);
extern int conn_set_ircpass(t_connection * c, char const * pass);
extern char const * conn_get_ircpass(t_connection const * c);
extern int conn_set_ircping(t_connection * c, unsigned int ping);
extern unsigned int conn_get_ircping(t_connection const * c);
extern int conn_set_udpok(t_connection * c);
extern int conn_get_welcomed(t_connection const * c) ;
extern void conn_set_welcomed(t_connection * c, int welcomed);
extern char const * conn_get_chatname(t_connection const * c);
extern int conn_unget_chatname(t_connection const * c, char const * name);
extern char const * conn_get_chatcharname(t_connection const * c, t_connection const * dst);
extern int conn_unget_chatcharname(t_connection const * c, char const * name);
extern t_message_class conn_get_message_class(t_connection const * c, t_connection const * dst);
extern unsigned int conn_get_userid(t_connection const * c);
extern char const * conn_get_playerinfo(t_connection const * c);
extern int conn_set_playerinfo(t_connection const * c, char const * playerinfo);
extern char const * conn_get_realminfo(t_connection const * c);
extern int conn_set_realminfo(t_connection * c, char const * realminfo);
extern char const * conn_get_charname(t_connection const * c);
extern int conn_set_charname(t_connection * c, char const * charname);
extern int conn_set_idletime(t_connection * c);
extern unsigned int conn_get_idletime(t_connection const * c);
extern t_realm * conn_get_realm(t_connection const * c);
extern int conn_set_realm(t_connection * c, t_realm * realm);
extern int conn_set_character(t_connection * c, t_character * ch);
extern int conn_bind(t_connection * c1, t_connection * c2);
extern void conn_set_country(t_connection * c, char const * country);
extern char const * conn_get_country(t_connection const * c);
extern int conn_quota_exceeded(t_connection * c, char const * message);
extern int conn_set_lastsender(t_connection * c, char const * sender);
extern char const * conn_get_lastsender(t_connection const * c);
extern t_versioncheck * conn_get_versioncheck(t_connection * c);
extern int conn_set_versioncheck(t_connection * c, t_versioncheck * versioncheck);
extern int conn_get_echoback(t_connection * c);
extern void conn_set_echoback(t_connection * c, int echoback);
extern int conn_set_ircline(t_connection * c, char const * line);
extern char const * conn_get_ircline(t_connection const * c);
extern int conn_set_ircpass(t_connection * c, char const * pass);
extern char const * conn_get_ircpass(t_connection const * c);
extern int conn_set_ircping(t_connection * c, unsigned int ping);
extern unsigned int conn_get_ircping(t_connection const * c);
extern int conn_set_udpok(t_connection * c);
extern int conn_get_welcomed(t_connection const * c);
extern void conn_set_welcomed(t_connection * c, int welcomed);
extern int conn_set_w3_playerinfo( t_connection * c, char const * w3_playerinfo );
extern const char * conn_get_w3_playerinfo( t_connection * c );
extern int conn_set_w3_playerinfo(t_connection * c, char const * w3_playerinfo);
extern const char * conn_get_w3_playerinfo(t_connection * c);
extern int conn_get_crtime(t_connection *c);
extern int conn_get_crtime(t_connection *c);
extern int conn_set_w3_loginreq(t_connection * c, char const * loginreq);
extern char const * conn_get_w3_loginreq(t_connection * c);
extern int conn_set_w3_loginreq(t_connection * c, char const * loginreq);
extern char const * conn_get_w3_loginreq(t_connection * c);
extern int conn_set_routeconn(t_connection * c, t_connection * rc);
extern t_connection * conn_get_routeconn(t_connection const * c);
extern int connlist_create(void);
extern void connlist_reap(void);
extern int connlist_destroy(void);
extern t_list * connlist(void) ;
extern t_connection * connlist_find_connection_by_sessionkey(unsigned int sessionkey);
extern t_connection * connlist_find_connection_by_socket(int socket);
extern t_connection * connlist_find_connection_by_sessionnum(unsigned int sessionnum);
extern t_connection * connlist_find_connection_by_name(char const * name, t_realm * realm); /* any chat name format */
extern t_connection * connlist_find_connection_by_accountname(char const * username);
extern t_connection * connlist_find_connection_by_charname(char const * charname, char const * realmname);
extern t_connection * connlist_find_connection_by_account(t_account * account);
extern t_connection * connlist_find_connection_by_uid(unsigned int uid);
extern int connlist_get_length(void) ;
extern unsigned int connlist_login_get_length(void) ;
extern int connlist_total_logins(void) ;
extern int conn_set_joingamewhisper_ack(t_connection * c, unsigned int value);
extern int conn_get_joingamewhisper_ack(t_connection * c);
extern int conn_set_leavegamewhisper_ack(t_connection * c, unsigned int value);
extern int conn_get_leavegamewhisper_ack(t_connection * c);
extern int conn_set_anongame_search_starttime(t_connection * c, std::time_t t);
extern std::time_t conn_get_anongame_search_starttime(t_connection * c);
extern int conn_set_routeconn(t_connection * c, t_connection * rc);
extern t_connection * conn_get_routeconn(t_connection const * c);
extern int connlist_create(void);
extern void connlist_reap(void);
extern int connlist_destroy(void);
extern t_list * connlist(void);
extern t_connection * connlist_find_connection_by_sessionkey(unsigned int sessionkey);
extern t_connection * connlist_find_connection_by_socket(int socket);
extern t_connection * connlist_find_connection_by_sessionnum(unsigned int sessionnum);
extern t_connection * connlist_find_connection_by_name(char const * name, t_realm * realm); /* any chat name format */
extern t_connection * connlist_find_connection_by_accountname(char const * username);
extern t_connection * connlist_find_connection_by_charname(char const * charname, char const * realmname);
extern t_connection * connlist_find_connection_by_account(t_account * account);
extern t_connection * connlist_find_connection_by_uid(unsigned int uid);
extern int connlist_get_length(void);
extern unsigned int connlist_login_get_length(void);
extern int connlist_total_logins(void);
extern int conn_set_joingamewhisper_ack(t_connection * c, unsigned int value);
extern int conn_get_joingamewhisper_ack(t_connection * c);
extern int conn_set_leavegamewhisper_ack(t_connection * c, unsigned int value);
extern int conn_get_leavegamewhisper_ack(t_connection * c);
extern int conn_set_anongame_search_starttime(t_connection * c, std::time_t t);
extern std::time_t conn_get_anongame_search_starttime(t_connection * c);
extern int conn_get_user_count_by_clienttag(t_clienttag ct);
extern int conn_get_user_count_by_clienttag(t_clienttag ct);
extern unsigned int connlist_count_connections(unsigned int addr);
extern unsigned int connlist_count_connections(unsigned int addr);
extern int conn_update_w3_playerinfo(t_connection * c);
extern int conn_update_w3_playerinfo(t_connection * c);
extern int conn_get_passfail_count(t_connection * c);
extern int conn_set_passfail_count(t_connection * c, unsigned int failcount);
extern int conn_increment_passfail_count (t_connection * c);
extern int conn_get_passfail_count(t_connection * c);
extern int conn_set_passfail_count(t_connection * c, unsigned int failcount);
extern int conn_increment_passfail_count(t_connection * c);
extern char const * conn_get_client_proof(t_connection * c);
extern int conn_set_client_proof(t_connection * c, char const * client_proof);
extern char const * conn_get_client_proof(t_connection * c);
extern int conn_set_client_proof(t_connection * c, char const * client_proof);
extern char const * conn_get_server_proof(t_connection * c);
extern int conn_set_server_proof(t_connection * c, char const * server_proof);
extern char const * conn_get_server_proof(t_connection * c);
extern int conn_set_server_proof(t_connection * c, char const * server_proof);
extern int conn_set_tmpOP_channel(t_connection * c, char const * tmpOP_channel);
extern char const * conn_get_tmpOP_channel(t_connection * c);
extern int conn_set_tmpVOICE_channel(t_connection * c, char const * tmpVOICE_channel);
extern char const * conn_get_tmpVOICE_channel(t_connection * c);
extern t_elist *conn_get_timer(t_connection * c);
extern int conn_add_fdwatch(t_connection *c, fdwatch_handler handle);
extern int conn_is_irc_variant(t_connection * c);
extern int conn_set_tmpOP_channel(t_connection * c, char const * tmpOP_channel);
extern char const * conn_get_tmpOP_channel(t_connection * c);
extern int conn_set_tmpVOICE_channel(t_connection * c, char const * tmpVOICE_channel);
extern char const * conn_get_tmpVOICE_channel(t_connection * c);
extern t_elist *conn_get_timer(t_connection * c);
extern int conn_add_fdwatch(t_connection *c, fdwatch_handler handle);
extern int conn_is_irc_variant(t_connection * c);
/* Westwood Online Extensions */
extern int conn_get_wol(t_connection * c);
extern void conn_wol_set_apgar(t_connection * c, char const * apgar);
extern char const * conn_wol_get_apgar(t_connection * c);
extern void conn_wol_set_codepage(t_connection * c, int codepage);
extern int conn_wol_get_codepage(t_connection * c);
extern void conn_wol_set_findme(t_connection * c, bool findme);
extern bool conn_wol_get_findme(t_connection * c);
extern void conn_wol_set_pageme(t_connection * c, bool pageme);
extern bool conn_wol_get_pageme(t_connection * c);
extern void conn_wol_set_anongame_player(t_connection * c, t_anongame_wol_player * anongame_player);
extern t_anongame_wol_player * conn_wol_get_anongame_player(t_connection * c);
/* Westwood Online Extensions */
extern int conn_get_wol(t_connection * c);
extern void conn_wol_set_apgar(t_connection * c, char const * apgar);
extern char const * conn_wol_get_apgar(t_connection * c);
extern void conn_wol_set_codepage(t_connection * c, int codepage);
extern int conn_wol_get_codepage(t_connection * c);
extern void conn_wol_set_findme(t_connection * c, bool findme);
extern bool conn_wol_get_findme(t_connection * c);
extern void conn_wol_set_pageme(t_connection * c, bool pageme);
extern bool conn_wol_get_pageme(t_connection * c);
extern void conn_wol_set_anongame_player(t_connection * c, t_anongame_wol_player * anongame_player);
extern t_anongame_wol_player * conn_wol_get_anongame_player(t_connection * c);
}
}
}

View file

@ -46,226 +46,227 @@
namespace pvpgn
{
namespace bnetd
{
static char const * file_get_info(char const * rawname, unsigned int * len, bn_long * modtime);
static char * file_find_default(const char *rawname)
{
/* Add new default files here */
const char * defaultfiles[]={"termsofservice-",".txt",
"newaccount-",".txt",
"chathelp-war3-",".txt",
"matchmaking-war3-",".dat",
"tos_",".txt",
"tos-unicode_", ".txt",
NULL,NULL};
const char ** pattern, **extension;
char *filename = NULL;
for (pattern = defaultfiles, extension = defaultfiles + 1; *pattern; pattern+=2, extension+=2)
if (!std::strncmp(rawname, *pattern,std::strlen(*pattern))) { /* Check if there is a default file available for this kind of file */
filename = (char*)xmalloc(std::strlen(prefs_get_filedir()) + 1 + std::strlen(*pattern) + 7 + std::strlen(*extension) + 1);
std::strcpy(filename, prefs_get_filedir());
std::strcat(filename, "/");
std::strcat(filename, *pattern);
std::strcat(filename, "default");
std::strcat(filename, *extension);
break;
}
return filename;
}
static char const * file_get_info(char const * rawname, unsigned int * len, bn_long * modtime)
{
char *filename;
t_bnettime bt;
struct stat sfile;
if (!rawname) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL rawname");
return NULL;
}
if (!len) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL len");
return NULL;
}
if (!modtime) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL modtime");
return NULL;
}
if (std::strchr(rawname,'/') || std::strchr(rawname,'\\')) {
eventlog(eventlog_level_warn,__FUNCTION__,"got rawname containing '/' or '\\' \"%s\"",rawname);
return NULL;
}
filename = buildpath(prefs_get_filedir(), rawname);
if (stat(filename, &sfile)<0) { /* if it doesn't exist, try to replace with default file */
xfree((void*)filename);
filename = file_find_default(rawname);
if (!filename) return NULL; /* no default version */
if (stat(filename, &sfile)<0) { /* try again */
/* FIXME: check for lower-case version of filename */
xfree(filename);
return NULL;
}
}
*len = (unsigned int)sfile.st_size;
bt = time_to_bnettime(sfile.st_mtime,0);
bnettime_to_bn_long(bt,modtime);
return filename;
}
extern int file_to_mod_time(char const * rawname, bn_long * modtime)
{
char const * filename;
unsigned int len;
if (!rawname)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL rawname");
return -1;
}
if (!modtime)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL modtime");
return -1;
}
if (!(filename = file_get_info(rawname, &len, modtime)))
return -1;
xfree((void *)filename); /* avoid warning */
return 0;
}
/* Send a file. If the file doesn't exist we still need to respond
* to the file request. This will set filelen to 0 and send the server
* reply message and the client will be happy and not hang.
*/
extern int file_send(t_connection * c, char const * rawname, unsigned int adid, unsigned int etag, unsigned int startoffset, int need_header)
{
char const * filename;
t_packet * rpacket;
std::FILE * fp;
unsigned int filelen;
int nbytes;
if (!c)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
if (!rawname)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL rawname");
return -1;
}
if (!(rpacket = packet_create(packet_class_file)))
{
eventlog(eventlog_level_error,__FUNCTION__,"could not create file packet");
return -1;
}
packet_set_size(rpacket,sizeof(t_server_file_reply));
packet_set_type(rpacket,SERVER_FILE_REPLY);
if ((filename = file_get_info(rawname,&filelen,&rpacket->u.server_file_reply.timestamp)))
{
if (!(fp = std::fopen(filename,"rb")))
namespace bnetd
{
/* FIXME: check for lower-case version of filename */
eventlog(eventlog_level_error,__FUNCTION__, "stat() succeeded yet could not open file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno));
filelen = 0;
static char const * file_get_info(char const * rawname, unsigned int * len, bn_long * modtime);
static char * file_find_default(const char *rawname)
{
/* Add new default files here */
const char * defaultfiles[] = { "termsofservice-", ".txt",
"newaccount-", ".txt",
"chathelp-war3-", ".txt",
"matchmaking-war3-", ".dat",
"tos_", ".txt",
"tos-unicode_", ".txt",
NULL, NULL };
const char ** pattern, **extension;
char *filename = NULL;
for (pattern = defaultfiles, extension = defaultfiles + 1; *pattern; pattern += 2, extension += 2)
if (!std::strncmp(rawname, *pattern, std::strlen(*pattern))) { /* Check if there is a default file available for this kind of file */
filename = (char*)xmalloc(std::strlen(prefs_get_filedir()) + 1 + std::strlen(*pattern) + 7 + std::strlen(*extension) + 1);
std::strcpy(filename, prefs_get_filedir());
std::strcat(filename, "/");
std::strcat(filename, *pattern);
std::strcat(filename, "default");
std::strcat(filename, *extension);
break;
}
return filename;
}
static char const * file_get_info(char const * rawname, unsigned int * len, bn_long * modtime)
{
char *filename;
t_bnettime bt;
struct stat sfile;
if (!rawname) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL rawname");
return NULL;
}
if (!len) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL len");
return NULL;
}
if (!modtime) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL modtime");
return NULL;
}
if (std::strchr(rawname, '/') || std::strchr(rawname, '\\')) {
eventlog(eventlog_level_warn, __FUNCTION__, "got rawname containing '/' or '\\' \"%s\"", rawname);
return NULL;
}
filename = buildpath(prefs_get_filedir(), rawname);
if (stat(filename, &sfile) < 0) { /* if it doesn't exist, try to replace with default file */
xfree((void*)filename);
filename = file_find_default(rawname);
if (!filename) return NULL; /* no default version */
if (stat(filename, &sfile) < 0) { /* try again */
/* FIXME: check for lower-case version of filename */
xfree(filename);
return NULL;
}
}
*len = (unsigned int)sfile.st_size;
bt = time_to_bnettime(sfile.st_mtime, 0);
bnettime_to_bn_long(bt, modtime);
return filename;
}
extern int file_to_mod_time(char const * rawname, bn_long * modtime)
{
char const * filename;
unsigned int len;
if (!rawname)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL rawname");
return -1;
}
if (!modtime)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL modtime");
return -1;
}
if (!(filename = file_get_info(rawname, &len, modtime)))
return -1;
xfree((void *)filename); /* avoid warning */
return 0;
}
/* Send a file. If the file doesn't exist we still need to respond
* to the file request. This will set filelen to 0 and send the server
* reply message and the client will be happy and not hang.
*/
extern int file_send(t_connection * c, char const * rawname, unsigned int adid, unsigned int etag, unsigned int startoffset, int need_header)
{
char const * filename;
t_packet * rpacket;
std::FILE * fp;
unsigned int filelen;
int nbytes;
if (!c)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
return -1;
}
if (!rawname)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL rawname");
return -1;
}
if (!(rpacket = packet_create(packet_class_file)))
{
eventlog(eventlog_level_error, __FUNCTION__, "could not create file packet");
return -1;
}
packet_set_size(rpacket, sizeof(t_server_file_reply));
packet_set_type(rpacket, SERVER_FILE_REPLY);
if ((filename = file_get_info(rawname, &filelen, &rpacket->u.server_file_reply.timestamp)))
{
if (!(fp = std::fopen(filename, "rb")))
{
/* FIXME: check for lower-case version of filename */
eventlog(eventlog_level_error, __FUNCTION__, "stat() succeeded yet could not open file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno));
filelen = 0;
}
xfree((void *)filename); /* avoid warning */
}
else
{
fp = NULL;
filelen = 0;
bn_long_set_a_b(&rpacket->u.server_file_reply.timestamp, 0, 0);
}
if (fp)
{
if (startoffset < filelen) {
std::fseek(fp, startoffset, SEEK_SET);
}
else {
eventlog(eventlog_level_warn, __FUNCTION__, "[%d] startoffset is beyond end of file (%u>%u)", conn_get_socket(c), startoffset, filelen);
/* Keep the real filesize. Battle.net does it the same way ... */
std::fclose(fp);
fp = NULL;
}
}
if (need_header)
{
/* send the header from the server with the rawname and length. */
bn_int_set(&rpacket->u.server_file_reply.filelen, filelen);
bn_int_set(&rpacket->u.server_file_reply.adid, adid);
bn_int_set(&rpacket->u.server_file_reply.extensiontag, etag);
/* rpacket->u.server_file_reply.timestamp is set above */
packet_append_string(rpacket, rawname);
conn_push_outqueue(c, rpacket);
}
packet_del_ref(rpacket);
/* Now send the data. Since it may be longer than a packet; we use
* the raw packet class.
*/
if (!fp)
{
eventlog(eventlog_level_warn, __FUNCTION__, "[%d] sending no data for file \"%s\"", conn_get_socket(c), rawname);
return -1;
}
eventlog(eventlog_level_info, __FUNCTION__, "[%d] sending file \"%s\" of length %d", conn_get_socket(c), rawname, filelen);
for (;;)
{
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "could not create raw packet");
if (std::fclose(fp) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not close file \"%s\" after reading (std::fclose: %s)", rawname, std::strerror(errno));
return -1;
}
if ((nbytes = std::fread(packet_get_raw_data_build(rpacket, 0), 1, MAX_PACKET_SIZE, fp))<(int)MAX_PACKET_SIZE)
{
if (nbytes>0) /* send out last portion */
{
packet_set_size(rpacket, nbytes);
conn_push_outqueue(c, rpacket);
}
packet_del_ref(rpacket);
if (std::ferror(fp))
eventlog(eventlog_level_error, __FUNCTION__, "read failed before EOF on file \"%s\" (std::fread: %s)", rawname, std::strerror(errno));
break;
}
packet_set_size(rpacket, nbytes);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
if (std::fclose(fp) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not close file \"%s\" after reading (std::fclose: %s)", rawname, std::strerror(errno));
return 0;
}
}
xfree((void *)filename); /* avoid warning */
}
else
{
fp = NULL;
filelen = 0;
bn_long_set_a_b(&rpacket->u.server_file_reply.timestamp,0,0);
}
if (fp)
{
if (startoffset<filelen) {
std::fseek(fp,startoffset,SEEK_SET);
} else {
eventlog(eventlog_level_warn,__FUNCTION__,"[%d] startoffset is beyond end of file (%u>%u)",conn_get_socket(c),startoffset,filelen);
/* Keep the real filesize. Battle.net does it the same way ... */
std::fclose(fp);
fp = NULL;
}
}
if (need_header)
{
/* send the header from the server with the rawname and length. */
bn_int_set(&rpacket->u.server_file_reply.filelen,filelen);
bn_int_set(&rpacket->u.server_file_reply.adid,adid);
bn_int_set(&rpacket->u.server_file_reply.extensiontag,etag);
/* rpacket->u.server_file_reply.timestamp is set above */
packet_append_string(rpacket,rawname);
conn_push_outqueue(c,rpacket);
}
packet_del_ref(rpacket);
/* Now send the data. Since it may be longer than a packet; we use
* the raw packet class.
*/
if (!fp)
{
eventlog(eventlog_level_warn,__FUNCTION__,"[%d] sending no data for file \"%s\"",conn_get_socket(c),rawname);
return -1;
}
eventlog(eventlog_level_info,__FUNCTION__,"[%d] sending file \"%s\" of length %d",conn_get_socket(c),rawname,filelen);
for (;;)
{
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"could not create raw packet");
if (std::fclose(fp)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not close file \"%s\" after reading (std::fclose: %s)",rawname,std::strerror(errno));
return -1;
}
if ((nbytes = std::fread(packet_get_raw_data_build(rpacket,0),1,MAX_PACKET_SIZE,fp))<(int)MAX_PACKET_SIZE)
{
if (nbytes>0) /* send out last portion */
{
packet_set_size(rpacket,nbytes);
conn_push_outqueue(c,rpacket);
}
packet_del_ref(rpacket);
if (std::ferror(fp))
eventlog(eventlog_level_error,__FUNCTION__,"read failed before EOF on file \"%s\" (std::fread: %s)",rawname,std::strerror(errno));
break;
}
packet_set_size(rpacket,nbytes);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
if (std::fclose(fp)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not close file \"%s\" after reading (std::fclose: %s)",rawname,std::strerror(errno));
return 0;
}
}
}

View file

@ -30,13 +30,13 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int file_to_mod_time(char const * rawname, bn_long * modtime);
extern int file_send(t_connection * c, char const * rawname, unsigned int adid, unsigned int etag, unsigned int startoffset, int need_header);
extern int file_to_mod_time(char const * rawname, bn_long * modtime);
extern int file_send(t_connection * c, char const * rawname, unsigned int adid, unsigned int etag, unsigned int startoffset, int need_header);
}
}
}

View file

@ -29,226 +29,228 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
/* cdb file storage API functions */
/* cdb file storage API functions */
static int cdb_read_attrs(const char *filename, t_read_attr_func cb, void *data);
static t_attr * cdb_read_attr(const char *filename, const char *key);
static int cdb_write_attrs(const char *filename, const t_hlist *attributes);
static int cdb_read_attrs(const char *filename, t_read_attr_func cb, void *data);
static t_attr * cdb_read_attr(const char *filename, const char *key);
static int cdb_write_attrs(const char *filename, const t_hlist *attributes);
/* file_engine struct populated with the functions above */
/* file_engine struct populated with the functions above */
t_file_engine file_cdb = {
cdb_read_attr,
cdb_read_attrs,
cdb_write_attrs
};
t_file_engine file_cdb = {
cdb_read_attr,
cdb_read_attrs,
cdb_write_attrs
};
/* start of actual cdb file storage code */
/* start of actual cdb file storage code */
//#define CDB_ON_DEMAND 1
//#define CDB_ON_DEMAND 1
static int cdb_write_attrs(const char *filename, const t_hlist *attributes)
{
std::FILE *cdbfile;
t_hlist *curr;
t_attr *attr;
struct cdb_make cdbm;
if ((cdbfile = std::fopen(filename, "w+b")) == NULL) {
eventlog(eventlog_level_error, __FUNCTION__, "unable to open file \"%s\" for writing ",filename);
return -1;
}
cdb_make_start(&cdbm, cdbfile);
hlist_for_each(curr,attributes) {
attr = hlist_entry(curr, t_attr, link);
if (attr_get_key(attr) && attr_get_val(attr)) {
if (std::strncmp("BNET\\CharacterDefault\\", attr_get_key(attr), 20) == 0) {
eventlog(eventlog_level_debug, __FUNCTION__, "skipping attribute key=\"%s\"",attr_get_key(attr));
} else {
eventlog(eventlog_level_debug, __FUNCTION__, "saving attribute key=\"%s\" val=\"%s\"",attr_get_key(attr),attr_get_val(attr));
if (cdb_make_add(&cdbm, attr_get_key(attr), std::strlen(attr_get_key(attr)), attr_get_val(attr), std::strlen(attr_get_val(attr)))<0)
static int cdb_write_attrs(const char *filename, const t_hlist *attributes)
{
eventlog(eventlog_level_error, __FUNCTION__, "got error on cdb_make_add ('%s' = '%s')", attr_get_key(attr), attr_get_val(attr));
cdb_make_finish(&cdbm); /* try to bail out nicely */
std::fclose(cdbfile);
return -1;
std::FILE *cdbfile;
t_hlist *curr;
t_attr *attr;
struct cdb_make cdbm;
if ((cdbfile = std::fopen(filename, "w+b")) == NULL) {
eventlog(eventlog_level_error, __FUNCTION__, "unable to open file \"%s\" for writing ", filename);
return -1;
}
cdb_make_start(&cdbm, cdbfile);
hlist_for_each(curr, attributes) {
attr = hlist_entry(curr, t_attr, link);
if (attr_get_key(attr) && attr_get_val(attr)) {
if (std::strncmp("BNET\\CharacterDefault\\", attr_get_key(attr), 20) == 0) {
eventlog(eventlog_level_debug, __FUNCTION__, "skipping attribute key=\"%s\"", attr_get_key(attr));
}
else {
eventlog(eventlog_level_debug, __FUNCTION__, "saving attribute key=\"%s\" val=\"%s\"", attr_get_key(attr), attr_get_val(attr));
if (cdb_make_add(&cdbm, attr_get_key(attr), std::strlen(attr_get_key(attr)), attr_get_val(attr), std::strlen(attr_get_val(attr))) < 0)
{
eventlog(eventlog_level_error, __FUNCTION__, "got error on cdb_make_add ('%s' = '%s')", attr_get_key(attr), attr_get_val(attr));
cdb_make_finish(&cdbm); /* try to bail out nicely */
std::fclose(cdbfile);
return -1;
}
}
}
else eventlog(eventlog_level_error, __FUNCTION__, "could not save attribute key=\"%s\"", attr_get_key(attr));
attr_clear_dirty(attr);
}
if (cdb_make_finish(&cdbm) < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "got error on cdb_make_finish");
std::fclose(cdbfile);
return -1;
}
if (std::fclose(cdbfile) < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "got error on std::fclose()");
return -1;
}
return 0;
}
}
} else eventlog(eventlog_level_error, __FUNCTION__,"could not save attribute key=\"%s\"",attr_get_key(attr));
attr_clear_dirty(attr);
}
if (cdb_make_finish(&cdbm)<0) {
eventlog(eventlog_level_error, __FUNCTION__, "got error on cdb_make_finish");
std::fclose(cdbfile);
return -1;
}
if (std::fclose(cdbfile)<0) {
eventlog(eventlog_level_error, __FUNCTION__, "got error on std::fclose()");
return -1;
}
return 0;
}
#ifndef CDB_ON_DEMAND
/* code adapted from tinycdb-0.73/cdb.c */
/* code adapted from tinycdb-0.73/cdb.c */
static int fget(std::FILE * fd, unsigned char *b, cdbi_t len, cdbi_t *posp, cdbi_t limit)
{
if (posp && limit - *posp < len) {
eventlog(eventlog_level_error, __FUNCTION__, "invalid cdb database format");
return -1;
}
static int fget(std::FILE * fd, unsigned char *b, cdbi_t len, cdbi_t *posp, cdbi_t limit)
{
if (posp && limit - *posp < len) {
eventlog(eventlog_level_error, __FUNCTION__, "invalid cdb database format");
return -1;
}
if (std::fread(b, 1, len, fd) != len) {
if (std::ferror(fd)) {
eventlog(eventlog_level_error, __FUNCTION__, "got error reading from db file");
return -1;
}
eventlog(eventlog_level_error, __FUNCTION__, "unable to read from cdb file, incomplete file");
return -1;
}
if (std::fread(b, 1, len, fd) != len) {
if (std::ferror(fd)) {
eventlog(eventlog_level_error, __FUNCTION__, "got error reading from db file");
return -1;
}
eventlog(eventlog_level_error, __FUNCTION__, "unable to read from cdb file, incomplete file");
return -1;
}
if (posp) *posp += len;
return 0;
}
if (posp) *posp += len;
return 0;
}
static const char * fcpy(std::FILE *fd, cdbi_t len, cdbi_t *posp, cdbi_t limit, unsigned char * buf)
{
static char *str;
static unsigned strl;
unsigned int res = 0, no = 0;
static const char * fcpy(std::FILE *fd, cdbi_t len, cdbi_t *posp, cdbi_t limit, unsigned char * buf)
{
static char *str;
static unsigned strl;
unsigned int res = 0, no = 0;
if (strl < len + 1) {
char *tmp;
if (strl < len + 1) {
char *tmp;
tmp = (char*)xmalloc(len + 1);
if (str) xfree((void*)str);
str = tmp;
strl = len + 1;
}
tmp = (char*)xmalloc(len + 1);
if (str) xfree((void*)str);
str = tmp;
strl = len + 1;
}
while(len - res > 0) {
if (len > 2048) no = 2048;
else no = len;
while (len - res > 0) {
if (len > 2048) no = 2048;
else no = len;
if (fget(fd, buf, no, posp, limit)) return NULL;
std::memmove(str + res, buf, no);
res += no;
}
if (fget(fd, buf, no, posp, limit)) return NULL;
std::memmove(str + res, buf, no);
res += no;
}
if (res > strl - 1) {
eventlog(eventlog_level_error, __FUNCTION__, "BUG, this should not happen");
return NULL;
}
if (res > strl - 1) {
eventlog(eventlog_level_error, __FUNCTION__, "BUG, this should not happen");
return NULL;
}
str[res] = '\0';
return str;
}
str[res] = '\0';
return str;
}
static int cdb_read_attrs(const char *filename, t_read_attr_func cb, void *data)
{
cdbi_t eod, klen, vlen;
cdbi_t pos = 0;
const char *key;
const char *val;
unsigned char buf[2048];
std::FILE *f;
static int cdb_read_attrs(const char *filename, t_read_attr_func cb, void *data)
{
cdbi_t eod, klen, vlen;
cdbi_t pos = 0;
const char *key;
const char *val;
unsigned char buf[2048];
std::FILE *f;
if ((f = std::fopen(filename, "rb")) == NULL) {
eventlog(eventlog_level_error, __FUNCTION__, "got error opening file '%s'", filename);
return -1;
}
if ((f = std::fopen(filename, "rb")) == NULL) {
eventlog(eventlog_level_error, __FUNCTION__, "got error opening file '%s'", filename);
return -1;
}
if (fget(f, buf, 2048, &pos, 2048)) goto err_fd;
eod = cdb_unpack(buf);
while(pos < eod) {
if (fget(f, buf, 8, &pos, eod)) goto err_fd;
klen = cdb_unpack(buf);
vlen = cdb_unpack(buf + 4);
if ((key = fcpy(f, klen, &pos, eod, buf)) == NULL) {
eventlog(eventlog_level_error, __FUNCTION__, "error reading attribute key");
goto err_fd;
}
if (fget(f, buf, 2048, &pos, 2048)) goto err_fd;
eod = cdb_unpack(buf);
while (pos < eod) {
if (fget(f, buf, 8, &pos, eod)) goto err_fd;
klen = cdb_unpack(buf);
vlen = cdb_unpack(buf + 4);
if ((key = fcpy(f, klen, &pos, eod, buf)) == NULL) {
eventlog(eventlog_level_error, __FUNCTION__, "error reading attribute key");
goto err_fd;
}
key = xstrdup(key);
key = xstrdup(key);
if ((val = fcpy(f, vlen, &pos, eod, buf)) == NULL) {
eventlog(eventlog_level_error, __FUNCTION__, "error reading attribute val");
goto err_key;
}
if ((val = fcpy(f, vlen, &pos, eod, buf)) == NULL) {
eventlog(eventlog_level_error, __FUNCTION__, "error reading attribute val");
goto err_key;
}
// eventlog(eventlog_level_trace, __FUNCTION__, "read atribute : '%s' -> '%s'", key, val);
if (cb(key, val, data))
eventlog(eventlog_level_error, __FUNCTION__, "got error from callback on account file '%s'", filename);
xfree((void *)key);
}
// eventlog(eventlog_level_trace, __FUNCTION__, "read atribute : '%s' -> '%s'", key, val);
if (cb(key, val, data))
eventlog(eventlog_level_error, __FUNCTION__, "got error from callback on account file '%s'", filename);
xfree((void *)key);
}
std::fclose(f);
return 0;
std::fclose(f);
return 0;
err_key:
xfree((void *)key);
err_key:
xfree((void *)key);
err_fd:
std::fclose(f);
return -1;
}
err_fd:
std::fclose(f);
return -1;
}
#else /* CDB_ON_DEMAND */
static int cdb_read_attrs(const char *filename, t_read_attr_func cb, void *data)
{
return 0;
}
static int cdb_read_attrs(const char *filename, t_read_attr_func cb, void *data)
{
return 0;
}
#endif
static t_attr * cdb_read_attr(const char *filename, const char *key)
{
static t_attr * cdb_read_attr(const char *filename, const char *key)
{
#ifdef CDB_ON_DEMAND
std::FILE *cdbfile;
t_attr *attr;
char *val;
unsigned vlen = 1;
std::FILE *cdbfile;
t_attr *attr;
char *val;
unsigned vlen = 1;
// eventlog(eventlog_level_trace, __FUNCTION__, "reading key '%s'", key);
if ((cdbfile = std::fopen(filename, "rb")) == NULL) {
// eventlog(eventlog_level_debug, __FUNCTION__, "unable to open file \"%s\" for reading ",filename);
return NULL;
}
// eventlog(eventlog_level_trace, __FUNCTION__, "reading key '%s'", key);
if ((cdbfile = std::fopen(filename, "rb")) == NULL) {
// eventlog(eventlog_level_debug, __FUNCTION__, "unable to open file \"%s\" for reading ",filename);
return NULL;
}
if (cdb_seek(cdbfile, key, std::strlen(key), &vlen) <= 0) {
// eventlog(eventlog_level_debug, __FUNCTION__, "could not find key '%s'", key);
std:;std::fclose(cdbfile);
return NULL;
}
if (cdb_seek(cdbfile, key, std::strlen(key), &vlen) <= 0) {
// eventlog(eventlog_level_debug, __FUNCTION__, "could not find key '%s'", key);
std:; std::fclose(cdbfile);
return NULL;
}
/* FIXME: use attr_* API */
attr = xmalloc(sizeof(t_attr));
attr->key = xstrdup(key);
val = xmalloc(vlen + 1);
/* FIXME: use attr_* API */
attr = xmalloc(sizeof(t_attr));
attr->key = xstrdup(key);
val = xmalloc(vlen + 1);
cdb_bread(cdbfile, val, vlen);
std::fclose(cdbfile);
cdb_bread(cdbfile, val, vlen);
std::fclose(cdbfile);
val[vlen] = '\0';
val[vlen] = '\0';
attr->val = val;
attr->dirty = 0;
// eventlog(eventlog_level_trace, __FUNCTION__, "read key '%s' value '%s'", attr->key, attr->val);
return attr;
attr->val = val;
attr->dirty = 0;
// eventlog(eventlog_level_trace, __FUNCTION__, "read key '%s' value '%s'", attr->key, attr->val);
return attr;
#else
return NULL;
return NULL;
#endif
}
}
}
}
}

View file

@ -7,12 +7,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern t_file_engine file_cdb;
extern t_file_engine file_cdb;
}
}
}

View file

@ -31,145 +31,147 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
/* plain file storage API functions */
/* plain file storage API functions */
static t_attr * plain_read_attr(const char *filename, const char *key);
static int plain_read_attrs(const char *filename, t_read_attr_func cb, void *data);
static int plain_write_attrs(const char *filename, const t_hlist *attributes);
static t_attr * plain_read_attr(const char *filename, const char *key);
static int plain_read_attrs(const char *filename, t_read_attr_func cb, void *data);
static int plain_write_attrs(const char *filename, const t_hlist *attributes);
/* file_engine struct populated with the functions above */
/* file_engine struct populated with the functions above */
t_file_engine file_plain = {
plain_read_attr,
plain_read_attrs,
plain_write_attrs
};
t_file_engine file_plain = {
plain_read_attr,
plain_read_attrs,
plain_write_attrs
};
static int plain_write_attrs(const char *filename, const t_hlist *attributes)
{
std::FILE * accountfile;
t_hlist * curr;
t_attr * attr;
char const * key;
char const * val;
static int plain_write_attrs(const char *filename, const t_hlist *attributes)
{
std::FILE * accountfile;
t_hlist * curr;
t_attr * attr;
char const * key;
char const * val;
if (!(accountfile = std::fopen(filename,"w"))) {
eventlog(eventlog_level_error, __FUNCTION__, "unable to open file \"%s\" for writing (std::fopen: %s)",filename,std::strerror(errno));
return -1;
}
if (!(accountfile = std::fopen(filename, "w"))) {
eventlog(eventlog_level_error, __FUNCTION__, "unable to open file \"%s\" for writing (std::fopen: %s)", filename, std::strerror(errno));
return -1;
}
hlist_for_each(curr, attributes) {
attr = hlist_entry(curr, t_attr, link);
hlist_for_each(curr, attributes) {
attr = hlist_entry(curr, t_attr, link);
if (attr_get_key(attr))
key = escape_chars(attr_get_key(attr), std::strlen(attr_get_key(attr)));
else {
eventlog(eventlog_level_error, __FUNCTION__, "attribute with NULL key in list");
key = NULL;
}
if (attr_get_val(attr))
val = escape_chars(attr_get_val(attr), std::strlen(attr_get_val(attr)));
else {
eventlog(eventlog_level_error, __FUNCTION__, "attribute with NULL val in list");
val = NULL;
}
if (key && val) {
if (std::strncmp("BNET\\CharacterDefault\\", key, 20) == 0) {
eventlog(eventlog_level_debug, __FUNCTION__, "skipping attribute key=\"%s\"", attr->key);
}
else {
eventlog(eventlog_level_debug, __FUNCTION__, "saving attribute key=\"%s\" val=\"%s\"", attr->key, attr->val);
std::fprintf(accountfile, "\"%s\"=\"%s\"\n", key, val);
}
}
else eventlog(eventlog_level_error, __FUNCTION__, "could not save attribute key=\"%s\"", attr->key);
if (key) xfree((void *)key); /* avoid warning */
if (val) xfree((void *)val); /* avoid warning */
attr_clear_dirty(attr);
}
if (std::fclose(accountfile) < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "could not close account file \"%s\" after writing (std::fclose: %s)", filename, std::strerror(errno));
return -1;
}
return 0;
}
static int plain_read_attrs(const char *filename, t_read_attr_func cb, void *data)
{
std::FILE * accountfile;
unsigned int line;
char const * buff;
unsigned int len;
char * esckey;
char * escval;
char * key;
char * val;
if (!(accountfile = std::fopen(filename, "r"))) {
eventlog(eventlog_level_error, __FUNCTION__, "could not open account file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno));
return -1;
}
for (line = 1; (buff = file_get_line(accountfile)); line++) {
if (buff[0] == '#' || buff[0] == '\0') {
continue;
}
if (std::strlen(buff) < 6) /* "?"="" */ {
eventlog(eventlog_level_error, __FUNCTION__, "malformed line %d of account file \"%s\"", line, filename);
continue;
}
len = std::strlen(buff) - 5 + 1; /* - ""="" + NUL */
esckey = (char*)xmalloc(len);
escval = (char*)xmalloc(len);
if (std::sscanf(buff, "\"%[^\"]\" = \"%[^\"]\"", esckey, escval) != 2) {
if (std::sscanf(buff, "\"%[^\"]\" = \"\"", esckey) != 1) /* hack for an empty value field */ {
eventlog(eventlog_level_error, __FUNCTION__, "malformed entry on line %d of account file \"%s\"", line, filename);
xfree(escval);
xfree(esckey);
continue;
}
escval[0] = '\0';
}
key = unescape_chars(esckey);
val = unescape_chars(escval);
/* eventlog(eventlog_level_debug,__FUNCTION__,"std::strlen(esckey)=%u (%c), len=%u",std::strlen(esckey),esckey[0],len);*/
xfree(esckey);
xfree(escval);
if (cb(key, val, data))
eventlog(eventlog_level_error, __FUNCTION__, "got error from callback (key: '%s' val:'%s')", key, val);
if (key) xfree((void *)key); /* avoid warning */
if (val) xfree((void *)val); /* avoid warning */
}
file_get_line(NULL); // clear file_get_line buffer
if (std::fclose(accountfile) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not close account file \"%s\" after reading (std::fclose: %s)", filename, std::strerror(errno));
return 0;
}
static t_attr * plain_read_attr(const char *filename, const char *key)
{
/* flat file storage doesnt know to read selective attributes */
return NULL;
}
if (attr_get_key(attr))
key = escape_chars(attr_get_key(attr),std::strlen(attr_get_key(attr)));
else {
eventlog(eventlog_level_error, __FUNCTION__, "attribute with NULL key in list");
key = NULL;
}
if (attr_get_val(attr))
val = escape_chars(attr_get_val(attr),std::strlen(attr_get_val(attr)));
else {
eventlog(eventlog_level_error, __FUNCTION__, "attribute with NULL val in list");
val = NULL;
}
if (key && val) {
if (std::strncmp("BNET\\CharacterDefault\\", key, 20) == 0) {
eventlog(eventlog_level_debug, __FUNCTION__, "skipping attribute key=\"%s\"",attr->key);
} else {
eventlog(eventlog_level_debug, __FUNCTION__, "saving attribute key=\"%s\" val=\"%s\"",attr->key,attr->val);
std::fprintf(accountfile,"\"%s\"=\"%s\"\n",key,val);
}
} else eventlog(eventlog_level_error, __FUNCTION__,"could not save attribute key=\"%s\"",attr->key);
if (key) xfree((void *)key); /* avoid warning */
if (val) xfree((void *)val); /* avoid warning */
attr_clear_dirty(attr);
}
if (std::fclose(accountfile)<0) {
eventlog(eventlog_level_error, __FUNCTION__, "could not close account file \"%s\" after writing (std::fclose: %s)",filename,std::strerror(errno));
return -1;
}
return 0;
}
static int plain_read_attrs(const char *filename, t_read_attr_func cb, void *data)
{
std::FILE * accountfile;
unsigned int line;
char const * buff;
unsigned int len;
char * esckey;
char * escval;
char * key;
char * val;
if (!(accountfile = std::fopen(filename,"r"))) {
eventlog(eventlog_level_error, __FUNCTION__,"could not open account file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno));
return -1;
}
for (line=1; (buff=file_get_line(accountfile)); line++) {
if (buff[0]=='#' || buff[0]=='\0') {
continue;
}
if (std::strlen(buff)<6) /* "?"="" */ {
eventlog(eventlog_level_error, __FUNCTION__, "malformed line %d of account file \"%s\"", line, filename);
continue;
}
len = std::strlen(buff)-5+1; /* - ""="" + NUL */
esckey = (char*)xmalloc(len);
escval = (char*)xmalloc(len);
if (std::sscanf(buff,"\"%[^\"]\" = \"%[^\"]\"",esckey,escval)!=2) {
if (std::sscanf(buff,"\"%[^\"]\" = \"\"",esckey)!=1) /* hack for an empty value field */ {
eventlog(eventlog_level_error, __FUNCTION__,"malformed entry on line %d of account file \"%s\"", line, filename);
xfree(escval);
xfree(esckey);
continue;
}
escval[0] = '\0';
}
key = unescape_chars(esckey);
val = unescape_chars(escval);
/* eventlog(eventlog_level_debug,__FUNCTION__,"std::strlen(esckey)=%u (%c), len=%u",std::strlen(esckey),esckey[0],len);*/
xfree(esckey);
xfree(escval);
if (cb(key,val,data))
eventlog(eventlog_level_error, __FUNCTION__, "got error from callback (key: '%s' val:'%s')", key, val);
if (key) xfree((void *)key); /* avoid warning */
if (val) xfree((void *)val); /* avoid warning */
}
file_get_line(NULL); // clear file_get_line buffer
if (std::fclose(accountfile)<0)
eventlog(eventlog_level_error, __FUNCTION__, "could not close account file \"%s\" after reading (std::fclose: %s)", filename, std::strerror(errno));
return 0;
}
static t_attr * plain_read_attr(const char *filename, const char *key)
{
/* flat file storage doesnt know to read selective attributes */
return NULL;
}
}
}

View file

@ -7,12 +7,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern t_file_engine file_plain;
extern t_file_engine file_plain;
}
}
}

View file

@ -26,257 +26,257 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern t_account * friend_get_account(t_friend * fr)
{
if (fr == NULL)
{
eventlog(eventlog_level_error, __FUNCTION__,"got NULL account");
return NULL;
}
return fr->friendacc;
}
extern t_account * friend_get_account(t_friend * fr)
{
if (fr == NULL)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
return NULL;
}
return fr->friendacc;
}
extern int friend_set_account(t_friend * fr, t_account * acc)
{
if (fr == NULL)
{
eventlog(eventlog_level_error, __FUNCTION__,"got NULL account");
return -1;
}
fr->friendacc=acc;
return 0;
}
extern int friend_set_account(t_friend * fr, t_account * acc)
{
if (fr == NULL)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
return -1;
}
fr->friendacc = acc;
return 0;
}
extern char friend_get_mutual(t_friend * fr)
{
if (fr == NULL)
{
eventlog(eventlog_level_error, __FUNCTION__,"got NULL account");
return 0;
}
return fr->mutual;
}
extern char friend_get_mutual(t_friend * fr)
{
if (fr == NULL)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
return 0;
}
return fr->mutual;
}
extern int friend_set_mutual(t_friend * fr, char mutual)
{
if (fr == NULL)
{
eventlog(eventlog_level_error, __FUNCTION__,"got NULL account");
return -1;
}
fr->mutual=mutual;
return 0;
}
extern int friend_set_mutual(t_friend * fr, char mutual)
{
if (fr == NULL)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
return -1;
}
fr->mutual = mutual;
return 0;
}
extern int friendlist_unload(t_list * flist)
{
t_elem * curr;
t_friend * fr;
if(flist==NULL)
return -1;
LIST_TRAVERSE(flist,curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
continue;
}
fr->mutual=-1;
}
return 0;
}
extern int friendlist_unload(t_list * flist)
{
t_elem * curr;
t_friend * fr;
if (flist == NULL)
return -1;
LIST_TRAVERSE(flist, curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
continue;
}
fr->mutual = -1;
}
return 0;
}
extern int friendlist_close(t_list * flist)
{
t_elem * curr;
t_friend * fr;
extern int friendlist_close(t_list * flist)
{
t_elem * curr;
t_friend * fr;
if(flist==NULL)
return -1;
LIST_TRAVERSE(flist,curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
continue;
}
if (flist == NULL)
return -1;
LIST_TRAVERSE(flist, curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
continue;
}
if (list_remove_elem(flist, &curr) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not remove elem from flist");
xfree((void *) fr);
}
list_destroy(flist);
return 0;
}
if (list_remove_elem(flist, &curr) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not remove elem from flist");
xfree((void *)fr);
}
list_destroy(flist);
return 0;
}
extern int friendlist_purge(t_list * flist)
{
t_elem * curr;
t_friend * fr;
extern int friendlist_purge(t_list * flist)
{
t_elem * curr;
t_friend * fr;
if(flist==NULL)
return -1;
LIST_TRAVERSE(flist,curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
continue;
}
if (fr->mutual<0)
{
if(list_remove_elem(flist, &curr)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not remove item from list");
}
}
return 0;
}
if (flist == NULL)
return -1;
LIST_TRAVERSE(flist, curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
continue;
}
if (fr->mutual < 0)
{
if (list_remove_elem(flist, &curr) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not remove item from list");
}
}
return 0;
}
extern int friendlist_add_account(t_list * flist, t_account * acc, int mutual)
{
t_friend * fr;
extern int friendlist_add_account(t_list * flist, t_account * acc, int mutual)
{
t_friend * fr;
if(flist==NULL)
return -1;
if (flist == NULL)
return -1;
fr = (t_friend*)xmalloc(sizeof(t_friend));
fr->friendacc = acc;
fr->mutual = mutual;
list_append_data(flist, fr);
return 0;
}
fr = (t_friend*)xmalloc(sizeof(t_friend));
fr->friendacc = acc;
fr->mutual = mutual;
list_append_data(flist, fr);
return 0;
}
extern int friendlist_remove_friend(t_list * flist, t_friend * fr)
{
t_elem * elem;
extern int friendlist_remove_friend(t_list * flist, t_friend * fr)
{
t_elem * elem;
if(flist==NULL)
return -1;
if (flist == NULL)
return -1;
if(fr!=NULL)
{
if(list_remove_data(flist, fr, &elem)<0)
{
eventlog(eventlog_level_error,__FUNCTION__,"could not remove item from list");
return -1;
}
if (fr != NULL)
{
if (list_remove_data(flist, fr, &elem) < 0)
{
eventlog(eventlog_level_error, __FUNCTION__, "could not remove item from list");
return -1;
}
xfree((void *)fr);
return 0;
}
return -1;
}
xfree((void *)fr);
return 0;
}
return -1;
}
extern int friendlist_remove_account(t_list * flist, t_account * acc)
{
t_elem * elem;
t_friend * fr;
extern int friendlist_remove_account(t_list * flist, t_account * acc)
{
t_elem * elem;
t_friend * fr;
if(flist==NULL)
return -1;
if (flist == NULL)
return -1;
fr=friendlist_find_account(flist, acc);
if(fr!=NULL)
{
if(list_remove_data(flist, fr, &elem)<0)
{
eventlog(eventlog_level_error,__FUNCTION__,"could not remove item from list");
return -1;
}
fr = friendlist_find_account(flist, acc);
if (fr != NULL)
{
if (list_remove_data(flist, fr, &elem) < 0)
{
eventlog(eventlog_level_error, __FUNCTION__, "could not remove item from list");
return -1;
}
xfree((void *)fr);
return 0;
}
return -1;
}
xfree((void *)fr);
return 0;
}
return -1;
}
extern int friendlist_remove_username(t_list * flist, const char * accname)
{
t_elem * elem;
t_friend * fr;
extern int friendlist_remove_username(t_list * flist, const char * accname)
{
t_elem * elem;
t_friend * fr;
if(flist==NULL)
return -1;
if (flist == NULL)
return -1;
fr=friendlist_find_username(flist, accname);
if(fr!=NULL)
{
if(list_remove_data(flist, fr, &elem)<0)
{
eventlog(eventlog_level_error,__FUNCTION__,"could not remove item from list");
return -1;
}
fr = friendlist_find_username(flist, accname);
if (fr != NULL)
{
if (list_remove_data(flist, fr, &elem) < 0)
{
eventlog(eventlog_level_error, __FUNCTION__, "could not remove item from list");
return -1;
}
xfree((void *)fr);
return 0;
}
return -1;
}
xfree((void *)fr);
return 0;
}
return -1;
}
extern t_friend * friendlist_find_account(t_list * flist, t_account * acc)
{
t_elem * curr;
t_friend * fr;
extern t_friend * friendlist_find_account(t_list * flist, t_account * acc)
{
t_elem * curr;
t_friend * fr;
if(flist==NULL)
return NULL;
if (flist == NULL)
return NULL;
LIST_TRAVERSE(flist,curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
continue;
}
if (fr->friendacc == acc)
return fr;
}
return NULL;
}
LIST_TRAVERSE(flist, curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
continue;
}
if (fr->friendacc == acc)
return fr;
}
return NULL;
}
extern t_friend * friendlist_find_username(t_list * flist, const char * accname)
{
t_elem * curr;
t_friend * fr;
extern t_friend * friendlist_find_username(t_list * flist, const char * accname)
{
t_elem * curr;
t_friend * fr;
if(flist==NULL)
return NULL;
if (flist == NULL)
return NULL;
LIST_TRAVERSE(flist,curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
continue;
}
if (strcasecmp(account_get_name(fr->friendacc),accname)==0) return fr;
}
return NULL;
}
LIST_TRAVERSE(flist, curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
continue;
}
if (strcasecmp(account_get_name(fr->friendacc), accname) == 0) return fr;
}
return NULL;
}
extern t_friend * friendlist_find_uid(t_list * flist, unsigned uid)
{
t_elem * curr;
t_friend * fr;
extern t_friend * friendlist_find_uid(t_list * flist, unsigned uid)
{
t_elem * curr;
t_friend * fr;
if(flist==NULL)
return NULL;
if (flist == NULL)
return NULL;
LIST_TRAVERSE(flist,curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
continue;
}
if (account_get_uid(fr->friendacc)==uid) return fr;
}
return NULL;
}
}
LIST_TRAVERSE(flist, curr)
{
if (!(fr = (t_friend*)elem_get_data(curr)))
{
eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
continue;
}
if (account_get_uid(fr->friendacc) == uid) return fr;
}
return NULL;
}
}
}

View file

@ -22,35 +22,35 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef struct friend_struct {
char mutual; /* -1 - unloaded(used to remove deleted elems when reload); 0 - not mutual ; 1 - is mutual */
t_account *friendacc;
} t_friend;
typedef struct friend_struct {
char mutual; /* -1 - unloaded(used to remove deleted elems when reload); 0 - not mutual ; 1 - is mutual */
t_account *friendacc;
} t_friend;
#ifndef JUST_NEED_TYPES
extern t_account * friend_get_account(t_friend *);
extern int friend_set_account(t_friend *, t_account * acc);
extern char friend_get_mutual(t_friend *);
extern int friend_set_mutual(t_friend *, char);
extern t_account * friend_get_account(t_friend *);
extern int friend_set_account(t_friend *, t_account * acc);
extern char friend_get_mutual(t_friend *);
extern int friend_set_mutual(t_friend *, char);
extern int friendlist_unload(t_list *);
extern int friendlist_close(t_list *);
extern int friendlist_purge(t_list *);
extern int friendlist_add_account(t_list *, t_account *, int);
extern int friendlist_remove_friend(t_list * flist, t_friend *);
extern int friendlist_remove_account(t_list *, t_account *);
extern int friendlist_remove_username(t_list *, const char *);
extern t_friend * friendlist_find_account(t_list *, t_account *);
extern t_friend * friendlist_find_username(t_list *, const char *);
extern t_friend * friendlist_find_uid(t_list *, unsigned);
extern int friendlist_unload(t_list *);
extern int friendlist_close(t_list *);
extern int friendlist_purge(t_list *);
extern int friendlist_add_account(t_list *, t_account *, int);
extern int friendlist_remove_friend(t_list * flist, t_friend *);
extern int friendlist_remove_account(t_list *, t_account *);
extern int friendlist_remove_username(t_list *, const char *);
extern t_friend * friendlist_find_account(t_list *, t_account *);
extern t_friend * friendlist_find_username(t_list *, const char *);
extern t_friend * friendlist_find_uid(t_list *, unsigned);
#endif
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -42,195 +42,195 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef enum
{
game_type_none,
game_type_all,
game_type_topvbot,
game_type_melee,
game_type_ffa,
game_type_oneonone,
game_type_ctf,
game_type_greed,
game_type_slaughter,
game_type_sdeath,
game_type_ladder,
game_type_ironman,
game_type_mapset,
game_type_teammelee,
game_type_teamffa,
game_type_teamctf,
game_type_pgl,
game_type_diablo,
game_type_diablo2open,
game_type_diablo2closed,
game_type_anongame
} t_game_type;
typedef enum
{
game_type_none,
game_type_all,
game_type_topvbot,
game_type_melee,
game_type_ffa,
game_type_oneonone,
game_type_ctf,
game_type_greed,
game_type_slaughter,
game_type_sdeath,
game_type_ladder,
game_type_ironman,
game_type_mapset,
game_type_teammelee,
game_type_teamffa,
game_type_teamctf,
game_type_pgl,
game_type_diablo,
game_type_diablo2open,
game_type_diablo2closed,
game_type_anongame
} t_game_type;
typedef enum
{
game_status_started,
game_status_full,
game_status_open,
game_status_loaded,
game_status_done
} t_game_status;
typedef enum
{
game_status_started,
game_status_full,
game_status_open,
game_status_loaded,
game_status_done
} t_game_status;
typedef enum
{
game_result_none,
game_result_win,
game_result_loss,
game_result_draw,
game_result_disconnect,
game_result_observer,
game_result_playing
} t_game_result;
typedef enum
{
game_result_none,
game_result_win,
game_result_loss,
game_result_draw,
game_result_disconnect,
game_result_observer,
game_result_playing
} t_game_result;
typedef enum
{
game_option_none,
game_option_melee_normal,
game_option_ffa_normal,
game_option_oneonone_normal,
game_option_ctf_normal,
game_option_greed_10000,
game_option_greed_7500,
game_option_greed_5000,
game_option_greed_2500,
game_option_slaughter_60,
game_option_slaughter_45,
game_option_slaughter_30,
game_option_slaughter_15,
game_option_sdeath_normal,
game_option_ladder_countasloss,
game_option_ladder_nopenalty,
game_option_mapset_normal,
game_option_teammelee_4,
game_option_teammelee_3,
game_option_teammelee_2,
game_option_teamffa_4,
game_option_teamffa_3,
game_option_teamffa_2,
game_option_teamctf_4,
game_option_teamctf_3,
game_option_teamctf_2,
game_option_topvbot_7,
game_option_topvbot_6,
game_option_topvbot_5,
game_option_topvbot_4,
game_option_topvbot_3,
game_option_topvbot_2,
game_option_topvbot_1
} t_game_option;
typedef enum
{
game_option_none,
game_option_melee_normal,
game_option_ffa_normal,
game_option_oneonone_normal,
game_option_ctf_normal,
game_option_greed_10000,
game_option_greed_7500,
game_option_greed_5000,
game_option_greed_2500,
game_option_slaughter_60,
game_option_slaughter_45,
game_option_slaughter_30,
game_option_slaughter_15,
game_option_sdeath_normal,
game_option_ladder_countasloss,
game_option_ladder_nopenalty,
game_option_mapset_normal,
game_option_teammelee_4,
game_option_teammelee_3,
game_option_teammelee_2,
game_option_teamffa_4,
game_option_teamffa_3,
game_option_teamffa_2,
game_option_teamctf_4,
game_option_teamctf_3,
game_option_teamctf_2,
game_option_topvbot_7,
game_option_topvbot_6,
game_option_topvbot_5,
game_option_topvbot_4,
game_option_topvbot_3,
game_option_topvbot_2,
game_option_topvbot_1
} t_game_option;
typedef enum
{
game_maptype_none,
game_maptype_selfmade,
game_maptype_blizzard,
game_maptype_ladder,
game_maptype_pgl,
game_maptype_kbk,
game_maptype_compusa
} t_game_maptype;
typedef enum
{
game_maptype_none,
game_maptype_selfmade,
game_maptype_blizzard,
game_maptype_ladder,
game_maptype_pgl,
game_maptype_kbk,
game_maptype_compusa
} t_game_maptype;
typedef enum
{
game_tileset_none,
game_tileset_badlands,
game_tileset_space,
game_tileset_installation,
game_tileset_ashworld,
game_tileset_jungle,
game_tileset_desert,
game_tileset_ice,
game_tileset_twilight
} t_game_tileset;
typedef enum
{
game_tileset_none,
game_tileset_badlands,
game_tileset_space,
game_tileset_installation,
game_tileset_ashworld,
game_tileset_jungle,
game_tileset_desert,
game_tileset_ice,
game_tileset_twilight
} t_game_tileset;
typedef enum
{
game_speed_none,
game_speed_slowest,
game_speed_slower,
game_speed_slow,
game_speed_normal,
game_speed_fast,
game_speed_faster,
game_speed_fastest
} t_game_speed;
typedef enum
{
game_speed_none,
game_speed_slowest,
game_speed_slower,
game_speed_slow,
game_speed_normal,
game_speed_fast,
game_speed_faster,
game_speed_fastest
} t_game_speed;
typedef enum
{
game_difficulty_none,
game_difficulty_normal,
game_difficulty_nightmare,
game_difficulty_hell,
game_difficulty_hardcore_normal,
game_difficulty_hardcore_nightmare,
game_difficulty_hardcore_hell
} t_game_difficulty;
typedef enum
{
game_difficulty_none,
game_difficulty_normal,
game_difficulty_nightmare,
game_difficulty_hell,
game_difficulty_hardcore_normal,
game_difficulty_hardcore_nightmare,
game_difficulty_hardcore_hell
} t_game_difficulty;
typedef enum {
game_flag_none,
game_flag_private
} t_game_flag;
typedef enum {
game_flag_none,
game_flag_private
} t_game_flag;
typedef struct game
typedef struct game
#ifdef GAME_INTERNAL_ACCESS
{
char const * name;
char const * pass;
char const * info;
t_game_type type;
unsigned int realm;
char const * realmname;
t_clienttag clienttag; /* type of client (STAR, SEXP, etc) */
unsigned int addr; /* host IP */
unsigned short port; /* host port */
int startver;
unsigned long version;
t_game_status status;
unsigned int ref; /* current number of players */
unsigned int count; /* max number of players */
unsigned int id;
char const * mapname;
t_game_option option;
t_game_maptype maptype;
t_game_tileset tileset;
t_game_speed speed;
unsigned int mapsize_x;
unsigned int mapsize_y;
unsigned int maxplayers;
{
char const * name;
char const * pass;
char const * info;
t_game_type type;
unsigned int realm;
char const * realmname;
t_clienttag clienttag; /* type of client (STAR, SEXP, etc) */
unsigned int addr; /* host IP */
unsigned short port; /* host port */
int startver;
unsigned long version;
t_game_status status;
unsigned int ref; /* current number of players */
unsigned int count; /* max number of players */
unsigned int id;
char const * mapname;
t_game_option option;
t_game_maptype maptype;
t_game_tileset tileset;
t_game_speed speed;
unsigned int mapsize_x;
unsigned int mapsize_y;
unsigned int maxplayers;
t_connection * owner;
t_connection * * connections;
t_account * * players;
t_game_result * results;
t_game_result * * reported_results;
char const * * report_heads;
char const * * report_bodies;
t_channel * channel; /* For Games with server-side chat support */
t_connection * owner;
t_connection * * connections;
t_account * * players;
t_game_result * results;
t_game_result * * reported_results;
char const * * report_heads;
char const * * report_bodies;
std::time_t create_time;
std::time_t start_time;
std::time_t lastaccess_time;
int bad; /* if 1, then the results will be ignored */
unsigned difficulty;
char const * description;
t_game_flag flag;
t_elist glist_link;
}
t_channel * channel; /* For Games with server-side chat support */
std::time_t create_time;
std::time_t start_time;
std::time_t lastaccess_time;
int bad; /* if 1, then the results will be ignored */
unsigned difficulty;
char const * description;
t_game_flag flag;
t_elist glist_link;
}
#endif
t_game;
t_game;
typedef int (*t_glist_func)(t_game *, void *);
typedef int(*t_glist_func)(t_game *, void *);
}
}
}
@ -259,85 +259,85 @@ typedef int (*t_glist_func)(t_game *, void *);
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern char const * game_type_get_str(t_game_type type) ;
extern char const * game_status_get_str(t_game_status status) ;
extern char const * game_result_get_str(t_game_result result) ;
extern char const * game_option_get_str(t_game_option option) ;
extern char const * game_maptype_get_str(t_game_maptype maptype) ;
extern char const * game_tileset_get_str(t_game_tileset tileset) ;
extern char const * game_speed_get_str(t_game_speed speed) ;
extern char const * game_difficulty_get_str(unsigned difficulty) ;
extern t_game * game_create(char const * name, char const * pass, char const * info, t_game_type type, int startver, t_clienttag clienttag,unsigned long gameversion) ;
extern unsigned int game_get_id(t_game const * game);
extern char const * game_get_name(t_game const * game);
extern t_game_type game_get_type(t_game const * game);
extern t_game_maptype game_get_maptype(t_game const * game);
extern int game_set_maptype(t_game * game, t_game_maptype maptype);
extern t_game_tileset game_get_tileset(t_game const * game);
extern int game_set_tileset(t_game * game, t_game_tileset tileset);
extern t_game_speed game_get_speed(t_game const * game);
extern int game_set_speed(t_game * game, t_game_speed speed);
extern unsigned int game_get_mapsize_x(t_game const * game);
extern int game_set_mapsize_x(t_game * game, unsigned int x);
extern unsigned int game_get_mapsize_y(t_game const * game);
extern int game_set_mapsize_y(t_game * game, unsigned int y);
extern unsigned int game_get_maxplayers(t_game const * game);
extern int game_set_maxplayers(t_game * game, unsigned int maxplayers);
extern unsigned int game_get_difficulty(t_game const * game);
extern int game_set_difficulty(t_game * game, unsigned int difficulty);
extern char const * game_get_description(t_game const * game);
extern int game_set_description(t_game * game, char const * description);
extern char const * game_get_pass(t_game const * game);
extern char const * game_get_info(t_game const * game);
extern unsigned long game_get_version(t_game const * game);
extern int game_get_startver(t_game const * game);
extern unsigned int game_get_ref(t_game const * game);
extern unsigned int game_get_count(t_game const * game);
extern void game_set_status(t_game * game, t_game_status status);
extern t_game_status game_get_status(t_game const * game);
extern unsigned int game_get_addr(t_game const * game);
extern unsigned short game_get_port(t_game const * game);
extern unsigned int game_get_latency(t_game const * game);
extern t_connection * game_get_player_conn(t_game const * game, unsigned int i);
extern t_clienttag game_get_clienttag(t_game const * game);
extern int game_add_player(t_game * game, char const * pass, int startver, t_connection * c);
extern int game_del_player(t_game * game, t_connection * c);
extern t_account * game_get_player(t_game * game, unsigned int i);
extern int game_set_report(t_game * game, t_account * account, char const * head, char const * body);
extern int game_set_reported_results(t_game * game, t_account * account, t_game_result * results);
extern int game_set_self_report(t_game * game, t_account * account, t_game_result result);
extern t_game_result * game_get_reported_results(t_game * game, t_account * account);
extern char const * game_get_mapname(t_game const * game);
extern int game_set_mapname(t_game * game, char const * mapname);
extern t_connection * game_get_owner(t_game const * game);
extern std::time_t game_get_create_time(t_game const * game);
extern std::time_t game_get_start_time(t_game const * game);
extern int game_set_option(t_game * game, t_game_option option);
extern t_game_option game_get_option(t_game const * game);
extern int gamelist_create(void);
extern int gamelist_destroy(void);
extern int gamelist_get_length(void);
extern t_game * gamelist_find_game(char const * name, t_clienttag ctag, t_game_type type);
extern t_game * gamelist_find_game_available(char const * name, t_clienttag ctag, t_game_type type);
extern t_game * gamelist_find_game_byid(unsigned int id);
extern void gamelist_traverse(t_glist_func cb, void *data);
extern int gamelist_total_games(void);
extern int game_set_realm(t_game * game, unsigned int realm);
extern unsigned int game_get_realm(t_game const * game);
extern char const * game_get_realmname(t_game const * game);
extern int game_set_realmname(t_game * game, char const * realmname);
extern void gamelist_check_voidgame(void);
extern void game_set_flag(t_game * game, t_game_flag flag);
extern t_game_flag game_get_flag(t_game const * game);
extern int game_get_count_by_clienttag(t_clienttag ct);
extern int game_is_ladder(t_game *game);
extern int game_discisloss(t_game *game);
extern int game_set_channel(t_game * game, t_channel * channel);
extern t_channel * game_get_channel(t_game * game);
}
extern char const * game_type_get_str(t_game_type type);
extern char const * game_status_get_str(t_game_status status);
extern char const * game_result_get_str(t_game_result result);
extern char const * game_option_get_str(t_game_option option);
extern char const * game_maptype_get_str(t_game_maptype maptype);
extern char const * game_tileset_get_str(t_game_tileset tileset);
extern char const * game_speed_get_str(t_game_speed speed);
extern char const * game_difficulty_get_str(unsigned difficulty);
extern t_game * game_create(char const * name, char const * pass, char const * info, t_game_type type, int startver, t_clienttag clienttag, unsigned long gameversion);
extern unsigned int game_get_id(t_game const * game);
extern char const * game_get_name(t_game const * game);
extern t_game_type game_get_type(t_game const * game);
extern t_game_maptype game_get_maptype(t_game const * game);
extern int game_set_maptype(t_game * game, t_game_maptype maptype);
extern t_game_tileset game_get_tileset(t_game const * game);
extern int game_set_tileset(t_game * game, t_game_tileset tileset);
extern t_game_speed game_get_speed(t_game const * game);
extern int game_set_speed(t_game * game, t_game_speed speed);
extern unsigned int game_get_mapsize_x(t_game const * game);
extern int game_set_mapsize_x(t_game * game, unsigned int x);
extern unsigned int game_get_mapsize_y(t_game const * game);
extern int game_set_mapsize_y(t_game * game, unsigned int y);
extern unsigned int game_get_maxplayers(t_game const * game);
extern int game_set_maxplayers(t_game * game, unsigned int maxplayers);
extern unsigned int game_get_difficulty(t_game const * game);
extern int game_set_difficulty(t_game * game, unsigned int difficulty);
extern char const * game_get_description(t_game const * game);
extern int game_set_description(t_game * game, char const * description);
extern char const * game_get_pass(t_game const * game);
extern char const * game_get_info(t_game const * game);
extern unsigned long game_get_version(t_game const * game);
extern int game_get_startver(t_game const * game);
extern unsigned int game_get_ref(t_game const * game);
extern unsigned int game_get_count(t_game const * game);
extern void game_set_status(t_game * game, t_game_status status);
extern t_game_status game_get_status(t_game const * game);
extern unsigned int game_get_addr(t_game const * game);
extern unsigned short game_get_port(t_game const * game);
extern unsigned int game_get_latency(t_game const * game);
extern t_connection * game_get_player_conn(t_game const * game, unsigned int i);
extern t_clienttag game_get_clienttag(t_game const * game);
extern int game_add_player(t_game * game, char const * pass, int startver, t_connection * c);
extern int game_del_player(t_game * game, t_connection * c);
extern t_account * game_get_player(t_game * game, unsigned int i);
extern int game_set_report(t_game * game, t_account * account, char const * head, char const * body);
extern int game_set_reported_results(t_game * game, t_account * account, t_game_result * results);
extern int game_set_self_report(t_game * game, t_account * account, t_game_result result);
extern t_game_result * game_get_reported_results(t_game * game, t_account * account);
extern char const * game_get_mapname(t_game const * game);
extern int game_set_mapname(t_game * game, char const * mapname);
extern t_connection * game_get_owner(t_game const * game);
extern std::time_t game_get_create_time(t_game const * game);
extern std::time_t game_get_start_time(t_game const * game);
extern int game_set_option(t_game * game, t_game_option option);
extern t_game_option game_get_option(t_game const * game);
extern int gamelist_create(void);
extern int gamelist_destroy(void);
extern int gamelist_get_length(void);
extern t_game * gamelist_find_game(char const * name, t_clienttag ctag, t_game_type type);
extern t_game * gamelist_find_game_available(char const * name, t_clienttag ctag, t_game_type type);
extern t_game * gamelist_find_game_byid(unsigned int id);
extern void gamelist_traverse(t_glist_func cb, void *data);
extern int gamelist_total_games(void);
extern int game_set_realm(t_game * game, unsigned int realm);
extern unsigned int game_get_realm(t_game const * game);
extern char const * game_get_realmname(t_game const * game);
extern int game_set_realmname(t_game * game, char const * realmname);
extern void gamelist_check_voidgame(void);
extern void game_set_flag(t_game * game, t_game_flag flag);
extern t_game_flag game_get_flag(t_game const * game);
extern int game_get_count_by_clienttag(t_clienttag ct);
extern int game_is_ladder(t_game *game);
extern int game_discisloss(t_game *game);
extern int game_set_channel(t_game * game, t_channel * channel);
extern t_channel * game_get_channel(t_game * game);
}
}

File diff suppressed because it is too large Load diff

View file

@ -29,21 +29,21 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern t_game_type bngreqtype_to_gtype(t_clienttag clienttag, unsigned short bngtype) ;
extern t_game_type bngtype_to_gtype(t_clienttag clienttag, unsigned short bngtype) ;
extern unsigned short gtype_to_bngtype(t_game_type gtype) ;
extern t_game_option bngoption_to_goption(t_clienttag clienttag, t_game_type gtype, unsigned short bngoption) ;
extern t_game_result bngresult_to_gresult(unsigned int bngresult) ;
extern t_game_maptype bngmaptype_to_gmaptype(unsigned int bngmaptype) ;
extern t_game_tileset bngtileset_to_gtileset(unsigned int bngtileset) ;
extern t_game_speed bngspeed_to_gspeed(unsigned int bngspeed) ;
extern t_game_difficulty bngdifficulty_to_gdifficulty(unsigned int bngdifficulty) ;
extern int game_parse_info(t_game * game, char const * gameinfo);
extern t_game_type bngreqtype_to_gtype(t_clienttag clienttag, unsigned short bngtype);
extern t_game_type bngtype_to_gtype(t_clienttag clienttag, unsigned short bngtype);
extern unsigned short gtype_to_bngtype(t_game_type gtype);
extern t_game_option bngoption_to_goption(t_clienttag clienttag, t_game_type gtype, unsigned short bngoption);
extern t_game_result bngresult_to_gresult(unsigned int bngresult);
extern t_game_maptype bngmaptype_to_gmaptype(unsigned int bngmaptype);
extern t_game_tileset bngtileset_to_gtileset(unsigned int bngtileset);
extern t_game_speed bngspeed_to_gspeed(unsigned int bngspeed);
extern t_game_difficulty bngdifficulty_to_gdifficulty(unsigned int bngdifficulty);
extern int game_parse_info(t_game * game, char const * gameinfo);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -22,12 +22,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_anongame_packet(t_connection * c, t_packet const * const packet);
extern int handle_anongame_packet(t_connection * c, t_packet const * const packet);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -28,35 +28,35 @@
namespace pvpgn
{
namespace bnetd
{
typedef struct apiregmember
namespace bnetd
{
typedef struct apiregmember
#ifdef APIREGISTER_INTERNAL_ACCESS
{
t_connection * conn;
char const * email;
char const * bday;
char const * bmonth;
char const * byear;
char const * langcode;
char const * sku; /* here are SKUs of all installed games */
char const * ver; /* same as with SKU - versions of all installed games */
char const * serial; /* also serials of all installed games */
char const * sysid;
char const * syscheck;
char const * oldnick; /* client send also all nicks that was registerd in the past */
char const * oldpass; /* and passwords for oldnicks */
char const * newnick;
char const * newpass;
char const * newpass2;
char const * parentemail;
bool newsletter; /* do user want to sending news by e-mail? */
bool shareinfo; /* can EA/Westwood shared e-mail contact for sending news? :) */
char const * request; /* API Register request (knowed requests are defined below) */
}
{
t_connection * conn;
char const * email;
char const * bday;
char const * bmonth;
char const * byear;
char const * langcode;
char const * sku; /* here are SKUs of all installed games */
char const * ver; /* same as with SKU - versions of all installed games */
char const * serial; /* also serials of all installed games */
char const * sysid;
char const * syscheck;
char const * oldnick; /* client send also all nicks that was registerd in the past */
char const * oldpass; /* and passwords for oldnicks */
char const * newnick;
char const * newpass;
char const * newpass2;
char const * parentemail;
bool newsletter; /* do user want to sending news by e-mail? */
bool shareinfo; /* can EA/Westwood shared e-mail contact for sending news? :) */
char const * request; /* API Register request (knowed requests are defined below) */
}
#endif
t_apiregmember;
t_apiregmember;
#ifndef INCLUDED_HANDLE_APIREG_PROTOS
#define INCLUDED_HANDLE_APIREG_PROTOS
@ -64,12 +64,12 @@ t_apiregmember;
#define REQUEST_AGEVERIFY "apireg_ageverify"
#define REQUEST_GETNICK "apireg_getnick"
extern int apireglist_create(void);
extern int apireglist_destroy(void);
extern int apireglist_create(void);
extern int apireglist_destroy(void);
extern int handle_apireg_packet(t_connection * conn,t_packet const * const packet);
extern int handle_apireg_packet(t_connection * conn, t_packet const * const packet);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -30,12 +30,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_bnet_packet(t_connection * c, t_packet const * const packet);
extern int handle_bnet_packet(t_connection * c, t_packet const * const packet);
}
}
}

View file

@ -39,311 +39,311 @@
namespace pvpgn
{
namespace bnetd
{
extern int handle_bot_packet(t_connection * c, t_packet const * const packet)
{
t_packet * rpacket;
if (!c)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL connection",conn_get_socket(c));
return -1;
}
if (!packet)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL packet",conn_get_socket(c));
return -1;
}
if (packet_get_class(packet)!=packet_class_raw)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet));
return -1;
}
{
char const * const linestr=packet_get_str_const(packet,0,MAX_MESSAGE_LEN);
if (packet_get_size(packet)<2) /* empty line */
return 0;
if (!linestr)
namespace bnetd
{
eventlog(eventlog_level_warn,__FUNCTION__,"[%d] line too long",conn_get_socket(c));
return 0;
extern int handle_bot_packet(t_connection * c, t_packet const * const packet)
{
t_packet * rpacket;
if (!c)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL connection", conn_get_socket(c));
return -1;
}
if (!packet)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL packet", conn_get_socket(c));
return -1;
}
if (packet_get_class(packet) != packet_class_raw)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad packet (class %d)", conn_get_socket(c), (int)packet_get_class(packet));
return -1;
}
{
char const * const linestr = packet_get_str_const(packet, 0, MAX_MESSAGE_LEN);
if (packet_get_size(packet) < 2) /* empty line */
return 0;
if (!linestr)
{
eventlog(eventlog_level_warn, __FUNCTION__, "[%d] line too long", conn_get_socket(c));
return 0;
}
switch (conn_get_state(c))
{
case conn_state_connected:
conn_add_flags(c, MF_PLUG);
conn_set_clienttag(c, CLIENTTAG_BNCHATBOT_UINT);
{
char const * temp = linestr;
if (temp[0] == '\004') /* FIXME: no echo, ignore for now (we always do no echo) */
temp = &temp[1];
if (temp[0] == '\0') /* empty line */
{
conn_set_state(c, conn_state_bot_username); /* don't look for ^D or reset tag and flags */
break;
}
conn_set_state(c, conn_state_bot_password);
if (conn_set_loggeduser(c, temp) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not set username to \"%s\"", conn_get_socket(c), temp);
{
char const * const msg = "\r\nPassword: ";
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
#if 1 /* don't echo */
packet_append_ntstring(rpacket, conn_get_loggeduser(c));
#endif
packet_append_ntstring(rpacket, msg);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
}
break;
case conn_state_bot_username:
conn_set_state(c, conn_state_bot_password);
if (conn_set_loggeduser(c, linestr) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not set username to \"%s\"", conn_get_socket(c), linestr);
{
char const * const temp = "\r\nPassword: ";
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
#if 1 /* don't echo */
packet_append_ntstring(rpacket, linestr);
#endif
packet_append_ntstring(rpacket, temp);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
break;
case conn_state_bot_password:
{
char const * const tempa = "\r\nLogin failed.\r\n\r\nUsername: ";
char const * const tempb = "\r\nAccount has no bot access.\r\n\r\nUsername: ";
char const * loggeduser = conn_get_loggeduser(c);
t_account * account;
char const * oldstrhash1;
t_hash trypasshash1;
t_hash oldpasshash1;
char * testpass;
if (!loggeduser) /* error earlier in login */
{
/* no std::log message... */
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
if (connlist_find_connection_by_accountname(loggeduser))
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (already logged in)", conn_get_socket(c), loggeduser);
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
if (!(account = accountlist_find_account(loggeduser)))
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (bad account)", conn_get_socket(c), loggeduser);
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
if ((oldstrhash1 = account_get_pass(account)))
{
if (hash_set_str(&oldpasshash1, oldstrhash1) < 0)
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (corrupted passhash1?)", conn_get_socket(c), loggeduser);
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
testpass = xstrdup(linestr);
{
unsigned int i;
for (i = 0; i < std::strlen(testpass); i++)
if (std::isupper((int)testpass[i]))
testpass[i] = std::tolower((int)testpass[i]);
}
if (bnet_hash(&trypasshash1, std::strlen(testpass), testpass) < 0) /* FIXME: force to lowercase */
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (unable to hash password)", conn_get_socket(c), loggeduser);
conn_set_state(c, conn_state_bot_username);
xfree((void *)testpass);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
xfree((void *)testpass);
if (hash_eq(trypasshash1, oldpasshash1) != 1)
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (wrong password)", conn_get_socket(c), loggeduser);
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
if (account_get_auth_botlogin(account) != 1) /* default to false */
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (no bot access)", conn_get_socket(c), loggeduser);
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempb);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
else if (account_get_auth_lock(account) == 1) /* default to false */
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (this account is locked)", conn_get_socket(c), loggeduser);
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempb);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
eventlog(eventlog_level_info, __FUNCTION__, "[%d] \"%s\" bot logged in (correct password)", conn_get_socket(c), loggeduser);
}
else
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] \"%s\" bot logged in (no password)", conn_get_socket(c), loggeduser);
}
if (!(rpacket = packet_create(packet_class_raw))) /* if we got this far, let them std::log in even if this fails */
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
else
{
packet_append_ntstring(rpacket, "\r\n");
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
conn_login(c, account, loggeduser);
message_send_text(c, message_type_uniqueid, c, loggeduser);
if (conn_set_channel(c, CHANNEL_NAME_CHAT) < 0)
conn_set_channel(c, CHANNEL_NAME_BANNED); /* should not fail */
}
break;
case conn_state_loggedin:
{
t_channel const * channel;
conn_set_idletime(c);
if ((channel = conn_get_channel(c)))
channel_message_log(channel, c, 1, linestr);
/* we don't log game commands currently */
if (linestr[0] == '/')
handle_command(c, linestr);
else
if (channel && !conn_quota_exceeded(c, linestr))
channel_message_send(channel, message_type_talk, c, linestr);
/* else discard */
}
break;
default:
eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown bot connection state %d", conn_get_socket(c), (int)conn_get_state(c));
}
}
return 0;
}
}
switch (conn_get_state(c))
{
case conn_state_connected:
conn_add_flags(c,MF_PLUG);
conn_set_clienttag(c,CLIENTTAG_BNCHATBOT_UINT);
{
char const * temp=linestr;
if (temp[0]=='\004') /* FIXME: no echo, ignore for now (we always do no echo) */
temp = &temp[1];
if (temp[0]=='\0') /* empty line */
{
conn_set_state(c,conn_state_bot_username); /* don't look for ^D or reset tag and flags */
break;
}
conn_set_state(c,conn_state_bot_password);
if (conn_set_loggeduser(c,temp)<0)
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set username to \"%s\"",conn_get_socket(c),temp);
{
char const * const msg="\r\nPassword: ";
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
#if 1 /* don't echo */
packet_append_ntstring(rpacket,conn_get_loggeduser(c));
#endif
packet_append_ntstring(rpacket,msg);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
}
break;
case conn_state_bot_username:
conn_set_state(c,conn_state_bot_password);
if (conn_set_loggeduser(c,linestr)<0)
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set username to \"%s\"",conn_get_socket(c),linestr);
{
char const * const temp="\r\nPassword: ";
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
#if 1 /* don't echo */
packet_append_ntstring(rpacket,linestr);
#endif
packet_append_ntstring(rpacket,temp);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
break;
case conn_state_bot_password:
{
char const * const tempa="\r\nLogin failed.\r\n\r\nUsername: ";
char const * const tempb="\r\nAccount has no bot access.\r\n\r\nUsername: ";
char const * loggeduser=conn_get_loggeduser(c);
t_account * account;
char const * oldstrhash1;
t_hash trypasshash1;
t_hash oldpasshash1;
char * testpass;
if (!loggeduser) /* error earlier in login */
{
/* no std::log message... */
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
if (connlist_find_connection_by_accountname(loggeduser))
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (already logged in)",conn_get_socket(c),loggeduser);
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
if (!(account = accountlist_find_account(loggeduser)))
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (bad account)",conn_get_socket(c),loggeduser);
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
if ((oldstrhash1 = account_get_pass(account)))
{
if (hash_set_str(&oldpasshash1,oldstrhash1)<0)
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (corrupted passhash1?)",conn_get_socket(c),loggeduser);
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
testpass = xstrdup(linestr);
{
unsigned int i;
for (i=0; i<std::strlen(testpass); i++)
if (std::isupper((int)testpass[i]))
testpass[i] = std::tolower((int)testpass[i]);
}
if (bnet_hash(&trypasshash1,std::strlen(testpass),testpass)<0) /* FIXME: force to lowercase */
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (unable to hash password)",conn_get_socket(c), loggeduser);
conn_set_state(c,conn_state_bot_username);
xfree((void *)testpass);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
xfree((void *)testpass);
if (hash_eq(trypasshash1,oldpasshash1)!=1)
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (wrong password)",conn_get_socket(c), loggeduser);
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
if (account_get_auth_botlogin(account)!=1) /* default to false */
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (no bot access)",conn_get_socket(c), loggeduser);
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempb);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
else if (account_get_auth_lock(account)==1) /* default to false */
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (this account is locked)",conn_get_socket(c), loggeduser);
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempb);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
eventlog(eventlog_level_info,__FUNCTION__,"[%d] \"%s\" bot logged in (correct password)",conn_get_socket(c), loggeduser);
}
else
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] \"%s\" bot logged in (no password)",conn_get_socket(c), loggeduser);
}
if (!(rpacket = packet_create(packet_class_raw))) /* if we got this far, let them std::log in even if this fails */
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
else
{
packet_append_ntstring(rpacket,"\r\n");
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
conn_login(c,account,loggeduser);
message_send_text(c,message_type_uniqueid,c,loggeduser);
if (conn_set_channel(c,CHANNEL_NAME_CHAT)<0)
conn_set_channel(c,CHANNEL_NAME_BANNED); /* should not fail */
}
break;
case conn_state_loggedin:
{
t_channel const * channel;
conn_set_idletime(c);
if ((channel = conn_get_channel(c)))
channel_message_log(channel,c,1,linestr);
/* we don't log game commands currently */
if (linestr[0]=='/')
handle_command(c,linestr);
else
if (channel && !conn_quota_exceeded(c,linestr))
channel_message_send(channel,message_type_talk,c,linestr);
/* else discard */
}
break;
default:
eventlog(eventlog_level_error,__FUNCTION__,"[%d] unknown bot connection state %d",conn_get_socket(c),(int)conn_get_state(c));
}
}
return 0;
}
}
}

View file

@ -30,12 +30,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_bot_packet(t_connection * c, t_packet const * const packet);
extern int handle_bot_packet(t_connection * c, t_packet const * const packet);
}
}
}

View file

@ -39,373 +39,384 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
static int on_d2cs_accountloginreq(t_connection * c, t_packet const * packet);
static int on_d2cs_charloginreq(t_connection * c, t_packet const * packet);
static int on_d2cs_authreply(t_connection * c, t_packet const * packet);
static int on_d2cs_gameinforeply(t_connection * c, t_packet const * packet);
static int on_d2cs_accountloginreq(t_connection * c, t_packet const * packet);
static int on_d2cs_charloginreq(t_connection * c, t_packet const * packet);
static int on_d2cs_authreply(t_connection * c, t_packet const * packet);
static int on_d2cs_gameinforeply(t_connection * c, t_packet const * packet);
extern int handle_d2cs_packet(t_connection * c, t_packet const * packet)
{
if (!c) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
if (!packet) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
return -1;
}
if (packet_get_class(packet)!=packet_class_d2cs_bnetd) {
eventlog(eventlog_level_error,__FUNCTION__,"got bad packet class %d",
packet_get_class(packet));
return -1;
}
switch (conn_get_state(c)) {
case conn_state_connected:
switch (packet_get_type(packet)) {
extern int handle_d2cs_packet(t_connection * c, t_packet const * packet)
{
if (!c) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
return -1;
}
if (!packet) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL packet");
return -1;
}
if (packet_get_class(packet) != packet_class_d2cs_bnetd) {
eventlog(eventlog_level_error, __FUNCTION__, "got bad packet class %d",
packet_get_class(packet));
return -1;
}
switch (conn_get_state(c)) {
case conn_state_connected:
switch (packet_get_type(packet)) {
case D2CS_BNETD_AUTHREPLY:
on_d2cs_authreply(c,packet);
on_d2cs_authreply(c, packet);
break;
default:
eventlog(eventlog_level_error,__FUNCTION__,
"got unknown packet type %d",packet_get_type(packet));
eventlog(eventlog_level_error, __FUNCTION__,
"got unknown packet type %d", packet_get_type(packet));
break;
}
break;
case conn_state_loggedin:
switch (packet_get_type(packet)) {
}
break;
case conn_state_loggedin:
switch (packet_get_type(packet)) {
case D2CS_BNETD_ACCOUNTLOGINREQ:
on_d2cs_accountloginreq(c,packet);
on_d2cs_accountloginreq(c, packet);
break;
case D2CS_BNETD_CHARLOGINREQ:
on_d2cs_charloginreq(c,packet);
on_d2cs_charloginreq(c, packet);
break;
case D2CS_BNETD_GAMEINFOREPLY:
on_d2cs_gameinforeply(c,packet);
on_d2cs_gameinforeply(c, packet);
break;
default:
eventlog(eventlog_level_error,__FUNCTION__,
"got unknown packet type %d",packet_get_type(packet));
eventlog(eventlog_level_error, __FUNCTION__,
"got unknown packet type %d", packet_get_type(packet));
break;
}
break;
default:
eventlog(eventlog_level_error, __FUNCTION__,
"got unknown connection state %d", conn_get_state(c));
break;
}
break;
default:
eventlog(eventlog_level_error,__FUNCTION__,
"got unknown connection state %d",conn_get_state(c));
break;
}
return 0;
}
static int on_d2cs_authreply(t_connection * c, t_packet const * packet)
{
t_packet * rpacket;
unsigned int version;
unsigned int try_version;
unsigned int reply;
char const * realmname;
t_realm * realm;
if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_authreply)) {
eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size");
return -1;
}
if (!(realmname=packet_get_str_const(packet,sizeof(t_d2cs_bnetd_authreply),MAX_REALMNAME_LEN))) {
eventlog(eventlog_level_error,__FUNCTION__,"got bad realmname");
return -1;
}
if (!(realm=realmlist_find_realm(realmname))) {
realm=realmlist_find_realm_by_ip(conn_get_addr(c)); /* should not fail - checked in handle_init_packet() handle_init.c */
eventlog(eventlog_level_warn,__FUNCTION__, "warn: realm name mismatch %s %s", realm_get_name(realm), realmname);
if (!(prefs_allow_d2cs_setname())) { /* fail if allow_d2cs_setname = false */
eventlog(eventlog_level_error,__FUNCTION__, "d2cs not allowed to set realm name");
return -1;
return 0;
}
if (realm_get_active(realm)) { /* fail if realm already active */
eventlog(eventlog_level_error,__FUNCTION__, "cannot set realm name to %s (realm already active)",realmname);
return -1;
}
realm_set_name(realm,realmname);
}
version=prefs_get_d2cs_version();
try_version=bn_int_get(packet->u.d2cs_bnetd_authreply.version);
if (version && version != try_version) {
eventlog(eventlog_level_error,__FUNCTION__,"d2cs version mismatch 0x%X - 0x%X",
try_version,version);
reply=BNETD_D2CS_AUTHREPLY_BAD_VERSION;
} else {
reply=BNETD_D2CS_AUTHREPLY_SUCCEED;
}
if (reply==BNETD_D2CS_AUTHREPLY_SUCCEED) {
eventlog(eventlog_level_info,__FUNCTION__,"d2cs %s authed",
addr_num_to_ip_str(conn_get_addr(c)));
conn_set_state(c,conn_state_loggedin);
realm_active(realm,c);
} else {
eventlog(eventlog_level_error,__FUNCTION__,"failed to auth d2cs %s",
addr_num_to_ip_str(conn_get_addr(c)));
}
if ((rpacket=packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(rpacket,sizeof(t_bnetd_d2cs_authreply));
packet_set_type(rpacket,BNETD_D2CS_AUTHREPLY);
bn_int_set(&rpacket->u.bnetd_d2cs_authreply.h.seqno,1);
bn_int_set(&rpacket->u.bnetd_d2cs_authreply.reply,reply);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
return 0;
}
static int on_d2cs_authreply(t_connection * c, t_packet const * packet)
{
t_packet * rpacket;
unsigned int version;
unsigned int try_version;
unsigned int reply;
char const * realmname;
t_realm * realm;
static int on_d2cs_accountloginreq(t_connection * c, t_packet const * packet)
{
unsigned int sessionkey;
unsigned int sessionnum;
unsigned int salt;
char const * account;
char const * tname;
t_connection * client;
int reply;
t_packet * rpacket;
struct
{
bn_int salt;
bn_int sessionkey;
bn_int sessionnum;
bn_int secret;
bn_int passhash[5];
} temp;
t_hash secret_hash;
char const * pass_str;
t_hash passhash;
t_hash try_hash;
if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_accountloginreq)) {
eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size");
return -1;
}
if (!(account=packet_get_str_const(packet,sizeof(t_d2cs_bnetd_accountloginreq),MAX_USERNAME_LEN))) {
eventlog(eventlog_level_error,__FUNCTION__,"missing or too long account name");
return -1;
}
sessionkey=bn_int_get(packet->u.d2cs_bnetd_accountloginreq.sessionkey);
sessionnum=bn_int_get(packet->u.d2cs_bnetd_accountloginreq.sessionnum);
salt=bn_int_get(packet->u.d2cs_bnetd_accountloginreq.seqno);
if (!(client=connlist_find_connection_by_sessionnum(sessionnum))) {
eventlog(eventlog_level_error,__FUNCTION__,"sessionnum %d not found",sessionnum);
reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
} else if (sessionkey!=conn_get_sessionkey(client)) {
eventlog(eventlog_level_error,__FUNCTION__,"sessionkey %d not match",sessionkey);
reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
} else if (!(tname=conn_get_username(client))) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL username");
reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
} else if (strcasecmp(account,tname)) {
eventlog(eventlog_level_error,__FUNCTION__,"username %s not match",account);
reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
} else {
bn_int_set(&temp.salt,salt);
bn_int_set(&temp.sessionkey,sessionkey);
bn_int_set(&temp.sessionnum,sessionnum);
bn_int_set(&temp.secret,conn_get_secret(client));
pass_str=account_get_pass(conn_get_account(client));
if (hash_set_str(&passhash,pass_str)<0) {
reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
} else {
hash_to_bnhash((t_hash const *)&passhash,temp.passhash);
bnet_hash(&secret_hash,sizeof(temp),&temp);
bnhash_to_hash(packet->u.d2cs_bnetd_accountloginreq.secret_hash,&try_hash);
if (hash_eq(try_hash,secret_hash)==1) {
eventlog(eventlog_level_debug,__FUNCTION__,"user %s loggedin on d2cs",
account);
reply=BNETD_D2CS_ACCOUNTLOGINREPLY_SUCCEED;
} else {
eventlog(eventlog_level_error,__FUNCTION__,"user %s hash not match",
account);
reply=BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
if (packet_get_size(packet) < sizeof(t_d2cs_bnetd_authreply)) {
eventlog(eventlog_level_error, __FUNCTION__, "got bad packet size");
return -1;
}
if (!(realmname = packet_get_str_const(packet, sizeof(t_d2cs_bnetd_authreply), MAX_REALMNAME_LEN))) {
eventlog(eventlog_level_error, __FUNCTION__, "got bad realmname");
return -1;
}
if (!(realm = realmlist_find_realm(realmname))) {
realm = realmlist_find_realm_by_ip(conn_get_addr(c)); /* should not fail - checked in handle_init_packet() handle_init.c */
eventlog(eventlog_level_warn, __FUNCTION__, "warn: realm name mismatch %s %s", realm_get_name(realm), realmname);
if (!(prefs_allow_d2cs_setname())) { /* fail if allow_d2cs_setname = false */
eventlog(eventlog_level_error, __FUNCTION__, "d2cs not allowed to set realm name");
return -1;
}
if (realm_get_active(realm)) { /* fail if realm already active */
eventlog(eventlog_level_error, __FUNCTION__, "cannot set realm name to %s (realm already active)", realmname);
return -1;
}
realm_set_name(realm, realmname);
}
version = prefs_get_d2cs_version();
try_version = bn_int_get(packet->u.d2cs_bnetd_authreply.version);
if (version && version != try_version) {
eventlog(eventlog_level_error, __FUNCTION__, "d2cs version mismatch 0x%X - 0x%X",
try_version, version);
reply = BNETD_D2CS_AUTHREPLY_BAD_VERSION;
}
else {
reply = BNETD_D2CS_AUTHREPLY_SUCCEED;
}
if (reply == BNETD_D2CS_AUTHREPLY_SUCCEED) {
eventlog(eventlog_level_info, __FUNCTION__, "d2cs %s authed",
addr_num_to_ip_str(conn_get_addr(c)));
conn_set_state(c, conn_state_loggedin);
realm_active(realm, c);
}
else {
eventlog(eventlog_level_error, __FUNCTION__, "failed to auth d2cs %s",
addr_num_to_ip_str(conn_get_addr(c)));
}
if ((rpacket = packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(rpacket, sizeof(t_bnetd_d2cs_authreply));
packet_set_type(rpacket, BNETD_D2CS_AUTHREPLY);
bn_int_set(&rpacket->u.bnetd_d2cs_authreply.h.seqno, 1);
bn_int_set(&rpacket->u.bnetd_d2cs_authreply.reply, reply);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
return 0;
}
static int on_d2cs_accountloginreq(t_connection * c, t_packet const * packet)
{
unsigned int sessionkey;
unsigned int sessionnum;
unsigned int salt;
char const * account;
char const * tname;
t_connection * client;
int reply;
t_packet * rpacket;
struct
{
bn_int salt;
bn_int sessionkey;
bn_int sessionnum;
bn_int secret;
bn_int passhash[5];
} temp;
t_hash secret_hash;
char const * pass_str;
t_hash passhash;
t_hash try_hash;
if (packet_get_size(packet) < sizeof(t_d2cs_bnetd_accountloginreq)) {
eventlog(eventlog_level_error, __FUNCTION__, "got bad packet size");
return -1;
}
if (!(account = packet_get_str_const(packet, sizeof(t_d2cs_bnetd_accountloginreq), MAX_USERNAME_LEN))) {
eventlog(eventlog_level_error, __FUNCTION__, "missing or too long account name");
return -1;
}
sessionkey = bn_int_get(packet->u.d2cs_bnetd_accountloginreq.sessionkey);
sessionnum = bn_int_get(packet->u.d2cs_bnetd_accountloginreq.sessionnum);
salt = bn_int_get(packet->u.d2cs_bnetd_accountloginreq.seqno);
if (!(client = connlist_find_connection_by_sessionnum(sessionnum))) {
eventlog(eventlog_level_error, __FUNCTION__, "sessionnum %d not found", sessionnum);
reply = BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
}
else if (sessionkey != conn_get_sessionkey(client)) {
eventlog(eventlog_level_error, __FUNCTION__, "sessionkey %d not match", sessionkey);
reply = BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
}
else if (!(tname = conn_get_username(client))) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL username");
reply = BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
}
else if (strcasecmp(account, tname)) {
eventlog(eventlog_level_error, __FUNCTION__, "username %s not match", account);
reply = BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
}
else {
bn_int_set(&temp.salt, salt);
bn_int_set(&temp.sessionkey, sessionkey);
bn_int_set(&temp.sessionnum, sessionnum);
bn_int_set(&temp.secret, conn_get_secret(client));
pass_str = account_get_pass(conn_get_account(client));
if (hash_set_str(&passhash, pass_str) < 0) {
reply = BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
}
else {
hash_to_bnhash((t_hash const *)&passhash, temp.passhash);
bnet_hash(&secret_hash, sizeof(temp), &temp);
bnhash_to_hash(packet->u.d2cs_bnetd_accountloginreq.secret_hash, &try_hash);
if (hash_eq(try_hash, secret_hash) == 1) {
eventlog(eventlog_level_debug, __FUNCTION__, "user %s loggedin on d2cs",
account);
reply = BNETD_D2CS_ACCOUNTLOGINREPLY_SUCCEED;
}
else {
eventlog(eventlog_level_error, __FUNCTION__, "user %s hash not match",
account);
reply = BNETD_D2CS_ACCOUNTLOGINREPLY_FAILED;
}
}
}
if ((rpacket = packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(rpacket, sizeof(t_bnetd_d2cs_accountloginreply));
packet_set_type(rpacket, BNETD_D2CS_ACCOUNTLOGINREPLY);
bn_int_set(&rpacket->u.bnetd_d2cs_accountloginreply.h.seqno,
bn_int_get(packet->u.d2cs_bnetd_accountloginreq.h.seqno));
bn_int_set(&rpacket->u.bnetd_d2cs_accountloginreply.reply, reply);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
return 0;
}
}
if ((rpacket=packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(rpacket,sizeof(t_bnetd_d2cs_accountloginreply));
packet_set_type(rpacket,BNETD_D2CS_ACCOUNTLOGINREPLY);
bn_int_set(&rpacket->u.bnetd_d2cs_accountloginreply.h.seqno,
bn_int_get(packet->u.d2cs_bnetd_accountloginreq.h.seqno));
bn_int_set(&rpacket->u.bnetd_d2cs_accountloginreply.reply,reply);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
return 0;
}
#define CHAR_PORTRAIT_LEN 0x30
static int on_d2cs_charloginreq(t_connection * c, t_packet const * packet)
{
t_connection * client;
char const * charname;
char const * portrait;
char const * clienttag;
char * temp;
unsigned int sessionnum;
t_realm * realm;
char const * realmname;
unsigned int pos, reply;
t_packet * rpacket;
static int on_d2cs_charloginreq(t_connection * c, t_packet const * packet)
{
t_connection * client;
char const * charname;
char const * portrait;
char const * clienttag;
char * temp;
unsigned int sessionnum;
t_realm * realm;
char const * realmname;
unsigned int pos, reply;
t_packet * rpacket;
if (packet_get_size(packet) < sizeof(t_d2cs_bnetd_charloginreq)) {
eventlog(eventlog_level_error, __FUNCTION__, "got bad packet size");
return -1;
}
sessionnum = bn_int_get(packet->u.d2cs_bnetd_charloginreq.sessionnum);
pos = sizeof(t_d2cs_bnetd_charloginreq);
if (!(charname = packet_get_str_const(packet, pos, MAX_CHARNAME_LEN))) {
eventlog(eventlog_level_error, __FUNCTION__, "got bad character name");
return -1;
}
pos += std::strlen(charname) + 1;
if (!(portrait = packet_get_str_const(packet, pos, CHAR_PORTRAIT_LEN))) {
eventlog(eventlog_level_error, __FUNCTION__, "got bad character portrait");
return -1;
}
if (!(client = connlist_find_connection_by_sessionnum(sessionnum))) {
eventlog(eventlog_level_error, __FUNCTION__, "user %d not found", sessionnum);
reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
}
else if (!(clienttag = clienttag_uint_to_str(conn_get_clienttag(client)))) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL clienttag");
reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
}
else if (!(realm = conn_get_realm(client))) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL realm");
reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
}
else {
char revtag[8];
realmname = realm_get_name(realm);
temp = (char*)xmalloc(std::strlen(clienttag) + std::strlen(realmname) + 1 + std::strlen(charname) + 1 +
std::strlen(portrait) + 1);
reply = BNETD_D2CS_CHARLOGINREPLY_SUCCEED;
std::strcpy(revtag, clienttag);
strreverse(revtag);
std::sprintf(temp, "%4s%s,%s,%s", revtag, realmname, charname, portrait);
conn_set_charname(client, charname);
conn_set_realminfo(client, temp);
xfree(temp);
eventlog(eventlog_level_debug, __FUNCTION__,
"loaded portrait for character %s", charname);
}
if ((rpacket = packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(rpacket, sizeof(t_bnetd_d2cs_charloginreply));
packet_set_type(rpacket, BNETD_D2CS_CHARLOGINREPLY);
bn_int_set(&rpacket->u.bnetd_d2cs_charloginreply.h.seqno,
bn_int_get(packet->u.d2cs_bnetd_charloginreq.h.seqno));
bn_int_set(&rpacket->u.bnetd_d2cs_charloginreply.reply, reply);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
return 0;
}
extern int handle_d2cs_init(t_connection * c)
{
t_packet * packet;
if ((packet = packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(packet, sizeof(t_bnetd_d2cs_authreq));
packet_set_type(packet, BNETD_D2CS_AUTHREQ);
bn_int_set(&packet->u.bnetd_d2cs_authreq.h.seqno, 1);
bn_int_set(&packet->u.bnetd_d2cs_authreq.sessionnum, conn_get_sessionnum(c));
conn_push_outqueue(c, packet);
packet_del_ref(packet);
}
eventlog(eventlog_level_info, __FUNCTION__, "sent init packet to d2cs (sessionnum=%d)",
conn_get_sessionnum(c));
return 0;
}
extern int send_d2cs_gameinforeq(t_connection * c)
{
t_packet * packet;
t_game * game;
t_realm * realm;
if (!(c))
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL conn");
return -1;
}
if (!(game = conn_get_game(c)))
{
eventlog(eventlog_level_error, __FUNCTION__, "conn had NULL game");
return -1;
}
if (!(realm = conn_get_realm(c)))
{
eventlog(eventlog_level_error, __FUNCTION__, "conn had NULL realm");
return -1;
}
if ((packet = packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(packet, sizeof(t_bnetd_d2cs_gameinforeq));
packet_set_type(packet, BNETD_D2CS_GAMEINFOREQ);
bn_int_set(&packet->u.bnetd_d2cs_gameinforeq.h.seqno, 0);
packet_append_string(packet, game_get_name(game));
conn_push_outqueue(realm_get_conn(realm), packet);
packet_del_ref(packet);
}
return 0;
}
static int on_d2cs_gameinforeply(t_connection * c, t_packet const * packet)
{
t_game * game;
char const * gamename;
unsigned int difficulty;
t_game_difficulty diff;
if (!(c)) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
return -1;
}
if (!(gamename = packet_get_str_const(packet, sizeof(t_d2cs_bnetd_gameinforeply), MAX_GAMENAME_LEN)))
{
eventlog(eventlog_level_error, __FUNCTION__, "missing or too long gamename");
return -1;
}
if (!(game = gamelist_find_game(gamename, CLIENTTAG_DIABLO2DV_UINT, game_type_diablo2closed))
&& !(game = gamelist_find_game(gamename, CLIENTTAG_DIABLO2XP_UINT, game_type_diablo2closed)))
{
eventlog(eventlog_level_error, __FUNCTION__, "reply for unknown game \"%s\"", gamename);
return -1;
}
difficulty = bn_byte_get(packet->u.d2cs_bnetd_gameinforeply.difficulty);
switch (difficulty)
{
case 0:
diff = game_difficulty_normal;
break;
case 1:
diff = game_difficulty_nightmare;
break;
case 2:
diff = game_difficulty_hell;
break;
default:
diff = game_difficulty_none;
}
game_set_difficulty(game, diff);
return 0;
}
if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_charloginreq)) {
eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size");
return -1;
}
sessionnum=bn_int_get(packet->u.d2cs_bnetd_charloginreq.sessionnum);
pos=sizeof(t_d2cs_bnetd_charloginreq);
if (!(charname=packet_get_str_const(packet,pos,MAX_CHARNAME_LEN))) {
eventlog(eventlog_level_error,__FUNCTION__,"got bad character name");
return -1;
}
pos+=std::strlen(charname)+1;
if (!(portrait=packet_get_str_const(packet,pos,CHAR_PORTRAIT_LEN))) {
eventlog(eventlog_level_error,__FUNCTION__,"got bad character portrait");
return -1;
}
if (!(client=connlist_find_connection_by_sessionnum(sessionnum))) {
eventlog(eventlog_level_error,__FUNCTION__,"user %d not found",sessionnum);
reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
} else if (!(clienttag=clienttag_uint_to_str(conn_get_clienttag(client)))) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL clienttag");
reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
} else if (!(realm=conn_get_realm(client))) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL realm");
reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
} else {
char revtag[8];
realmname = realm_get_name(realm);
temp=(char*)xmalloc(std::strlen(clienttag)+std::strlen(realmname)+1+std::strlen(charname)+1+
std::strlen(portrait)+1);
reply = BNETD_D2CS_CHARLOGINREPLY_SUCCEED;
std::strcpy(revtag,clienttag);
strreverse(revtag);
std::sprintf(temp, "%4s%s,%s,%s",revtag,realmname,charname,portrait);
conn_set_charname(client,charname);
conn_set_realminfo(client,temp);
xfree(temp);
eventlog(eventlog_level_debug,__FUNCTION__,
"loaded portrait for character %s",charname);
}
if ((rpacket=packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(rpacket,sizeof(t_bnetd_d2cs_charloginreply));
packet_set_type(rpacket,BNETD_D2CS_CHARLOGINREPLY);
bn_int_set(&rpacket->u.bnetd_d2cs_charloginreply.h.seqno,
bn_int_get(packet->u.d2cs_bnetd_charloginreq.h.seqno));
bn_int_set(&rpacket->u.bnetd_d2cs_charloginreply.reply,reply);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
return 0;
}
extern int handle_d2cs_init(t_connection * c)
{
t_packet * packet;
if ((packet=packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(packet,sizeof(t_bnetd_d2cs_authreq));
packet_set_type(packet,BNETD_D2CS_AUTHREQ);
bn_int_set(&packet->u.bnetd_d2cs_authreq.h.seqno,1);
bn_int_set(&packet->u.bnetd_d2cs_authreq.sessionnum,conn_get_sessionnum(c));
conn_push_outqueue(c,packet);
packet_del_ref(packet);
}
eventlog(eventlog_level_info,__FUNCTION__,"sent init packet to d2cs (sessionnum=%d)",
conn_get_sessionnum(c));
return 0;
}
extern int send_d2cs_gameinforeq(t_connection * c)
{
t_packet * packet;
t_game * game;
t_realm * realm;
if (!(c))
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn");
return -1;
}
if (!(game = conn_get_game(c)))
{
eventlog(eventlog_level_error,__FUNCTION__,"conn had NULL game");
return -1;
}
if (!(realm = conn_get_realm(c)))
{
eventlog(eventlog_level_error,__FUNCTION__,"conn had NULL realm");
return -1;
}
if ((packet=packet_create(packet_class_d2cs_bnetd))) {
packet_set_size(packet,sizeof(t_bnetd_d2cs_gameinforeq));
packet_set_type(packet,BNETD_D2CS_GAMEINFOREQ);
bn_int_set(&packet->u.bnetd_d2cs_gameinforeq.h.seqno,0);
packet_append_string(packet,game_get_name(game));
conn_push_outqueue(realm_get_conn(realm),packet);
packet_del_ref(packet);
}
return 0;
}
static int on_d2cs_gameinforeply(t_connection * c, t_packet const * packet)
{
t_game * game;
char const * gamename;
unsigned int difficulty;
t_game_difficulty diff;
if (!(c)) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
if (!(gamename = packet_get_str_const(packet,sizeof(t_d2cs_bnetd_gameinforeply),MAX_GAMENAME_LEN)))
{
eventlog(eventlog_level_error,__FUNCTION__,"missing or too long gamename");
return -1;
}
if (!(game = gamelist_find_game(gamename,CLIENTTAG_DIABLO2DV_UINT,game_type_diablo2closed))
&& !(game = gamelist_find_game(gamename,CLIENTTAG_DIABLO2XP_UINT,game_type_diablo2closed)))
{
eventlog(eventlog_level_error,__FUNCTION__,"reply for unknown game \"%s\"",gamename);
return -1;
}
difficulty = bn_byte_get(packet->u.d2cs_bnetd_gameinforeply.difficulty);
switch (difficulty)
{
case 0:
diff = game_difficulty_normal;
break;
case 1:
diff = game_difficulty_nightmare;
break;
case 2:
diff = game_difficulty_hell;
break;
default:
diff = game_difficulty_none;
}
game_set_difficulty(game,diff);
return 0;
}
}
}

View file

@ -24,14 +24,14 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_d2cs_packet(t_connection * c, t_packet const * packet);
extern int handle_d2cs_init(t_connection * c);
extern int send_d2cs_gameinforeq(t_connection * c);
extern int handle_d2cs_packet(t_connection * c, t_packet const * packet);
extern int handle_d2cs_init(t_connection * c);
extern int send_d2cs_gameinforeq(t_connection * c);
}
}
}

View file

@ -32,99 +32,99 @@
namespace pvpgn
{
namespace bnetd
{
extern int handle_file_packet(t_connection * c, t_packet const * const packet)
{
if (!c)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL connection",conn_get_socket(c));
return -1;
}
if (!packet)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL packet",conn_get_socket(c));
return -1;
}
/* REMOVED BY UNDYING SOULZZ 4/3/02 */
/*
if (packet_get_class(packet)!=packet_class_file)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet));
return -1;
}
*/
switch (conn_get_state(c))
{
case conn_state_connected:
switch (packet_get_type(packet))
namespace bnetd
{
case CLIENT_FILE_REQ:
{
char const * rawname;
if (!(rawname = packet_get_str_const(packet,sizeof(t_client_file_req),MAX_FILENAME_STR)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad FILE_REQ (missing or too long filename)",conn_get_socket(c));
extern int handle_file_packet(t_connection * c, t_packet const * const packet)
{
if (!c)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL connection", conn_get_socket(c));
return -1;
}
if (!packet)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL packet", conn_get_socket(c));
return -1;
}
/* REMOVED BY UNDYING SOULZZ 4/3/02 */
/*
if (packet_get_class(packet)!=packet_class_file)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet));
return -1;
}
*/
switch (conn_get_state(c))
{
case conn_state_connected:
switch (packet_get_type(packet))
{
case CLIENT_FILE_REQ:
{
char const * rawname;
return -1;
}
if (!(rawname = packet_get_str_const(packet, sizeof(t_client_file_req), MAX_FILENAME_STR)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad FILE_REQ (missing or too long filename)", conn_get_socket(c));
return -1;
}
file_send(c, rawname,
bn_int_get(packet->u.client_file_req.adid),
bn_int_get(packet->u.client_file_req.extensiontag),
bn_int_get(packet->u.client_file_req.startoffset),
1);
}
break;
case CLIENT_FILE_REQ2:
{
t_packet * rpacket = NULL;
if ((rpacket = packet_create(packet_class_raw))) {
packet_set_size(rpacket, sizeof(t_server_file_unknown1));
bn_int_set(&rpacket->u.server_file_unknown1.unknown, 0xdeadbeef);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
conn_set_state(c, conn_state_pending_raw);
break;
}
default:
eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown file packet type 0x%04x, len %u", conn_get_socket(c), packet_get_type(packet), packet_get_size(packet));
break;
}
break;
case conn_state_pending_raw:
switch (packet_get_type(packet))
{
case CLIENT_FILE_REQ3:
{
char rawname[MAX_FILENAME_STR];
psock_recv(conn_get_socket(c), rawname, MAX_FILENAME_STR, 0);
file_send(c, rawname, 0, 0, 0, 1);
}
break;
default:
eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown file packet type 0x%04x, len %u", conn_get_socket(c), packet_get_type(packet), packet_get_size(packet));
break;
}
break;
default:
eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown file connection state %d", conn_get_socket(c), (int)conn_get_state(c));
}
return 0;
}
file_send(c,rawname,
bn_int_get(packet->u.client_file_req.adid),
bn_int_get(packet->u.client_file_req.extensiontag),
bn_int_get(packet->u.client_file_req.startoffset),
1);
}
break;
case CLIENT_FILE_REQ2:
{
t_packet * rpacket = NULL;
if((rpacket = packet_create(packet_class_raw))) {
packet_set_size(rpacket,sizeof(t_server_file_unknown1));
bn_int_set( &rpacket->u.server_file_unknown1.unknown, 0xdeadbeef );
conn_push_outqueue(c, rpacket );
packet_del_ref( rpacket );
}
conn_set_state(c, conn_state_pending_raw);
break;
}
default:
eventlog(eventlog_level_error,__FUNCTION__,"[%d] unknown file packet type 0x%04x, len %u",conn_get_socket(c),packet_get_type(packet),packet_get_size(packet));
break;
}
break;
case conn_state_pending_raw:
switch (packet_get_type(packet))
{
case CLIENT_FILE_REQ3:
{
char rawname[MAX_FILENAME_STR];
psock_recv( conn_get_socket(c), rawname, MAX_FILENAME_STR, 0 );
file_send(c, rawname, 0, 0, 0, 1);
}
break;
default:
eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown file packet type 0x%04x, len %u",conn_get_socket(c),packet_get_type(packet),packet_get_size(packet));
break;
}
break;
default:
eventlog(eventlog_level_error,__FUNCTION__,"[%d] unknown file connection state %d",conn_get_socket(c),(int)conn_get_state(c));
}
return 0;
}
}
}

View file

@ -30,12 +30,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_file_packet(t_connection * c, t_packet const * const packet);
extern int handle_file_packet(t_connection * c, t_packet const * const packet);
}
}
}

View file

@ -34,104 +34,104 @@
namespace pvpgn
{
namespace bnetd
{
extern int handle_init_packet(t_connection * c, t_packet const * const packet)
{
if (!c)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL connection",conn_get_socket(c));
return -1;
}
if (!packet)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL packet",conn_get_socket(c));
return -1;
}
if (packet_get_class(packet)!=packet_class_init)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet));
return -1;
}
if ((prefs_get_max_conns_per_IP()!=0) &&
bn_byte_get(packet->u.client_initconn.cclass)!=CLIENT_INITCONN_CLASS_D2CS_BNETD &&
(connlist_count_connections(conn_get_addr(c)) > prefs_get_max_conns_per_IP()))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] too many connections from address %s (closing connection)",conn_get_socket(c),addr_num_to_addr_str(conn_get_addr(c),conn_get_port(c)));
return -1;
}
switch (packet_get_type(packet))
{
case CLIENT_INITCONN:
switch (bn_byte_get(packet->u.client_initconn.cclass))
namespace bnetd
{
case CLIENT_INITCONN_CLASS_BNET:
eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated bnet connection",conn_get_socket(c));
conn_set_state(c,conn_state_connected);
conn_set_class(c,conn_class_bnet);
break;
extern int handle_init_packet(t_connection * c, t_packet const * const packet)
{
if (!c)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL connection", conn_get_socket(c));
return -1;
}
if (!packet)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL packet", conn_get_socket(c));
return -1;
}
if (packet_get_class(packet) != packet_class_init)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad packet (class %d)", conn_get_socket(c), (int)packet_get_class(packet));
return -1;
}
if ((prefs_get_max_conns_per_IP() != 0) &&
bn_byte_get(packet->u.client_initconn.cclass) != CLIENT_INITCONN_CLASS_D2CS_BNETD &&
(connlist_count_connections(conn_get_addr(c)) > prefs_get_max_conns_per_IP()))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] too many connections from address %s (closing connection)", conn_get_socket(c), addr_num_to_addr_str(conn_get_addr(c), conn_get_port(c)));
return -1;
}
case CLIENT_INITCONN_CLASS_FILE:
eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated file download connection",conn_get_socket(c));
conn_set_state(c,conn_state_connected);
conn_set_class(c,conn_class_file);
switch (packet_get_type(packet))
{
case CLIENT_INITCONN:
switch (bn_byte_get(packet->u.client_initconn.cclass))
{
case CLIENT_INITCONN_CLASS_BNET:
eventlog(eventlog_level_info, __FUNCTION__, "[%d] client initiated bnet connection", conn_get_socket(c));
conn_set_state(c, conn_state_connected);
conn_set_class(c, conn_class_bnet);
break;
break;
case CLIENT_INITCONN_CLASS_BOT:
eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated chat bot connection",conn_get_socket(c));
conn_set_state(c,conn_state_connected);
conn_set_class(c,conn_class_bot);
case CLIENT_INITCONN_CLASS_FILE:
eventlog(eventlog_level_info, __FUNCTION__, "[%d] client initiated file download connection", conn_get_socket(c));
conn_set_state(c, conn_state_connected);
conn_set_class(c, conn_class_file);
break;
break;
case CLIENT_INITCONN_CLASS_TELNET:
eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated telnet connection",conn_get_socket(c));
conn_set_state(c,conn_state_connected);
conn_set_class(c,conn_class_telnet);
case CLIENT_INITCONN_CLASS_BOT:
eventlog(eventlog_level_info, __FUNCTION__, "[%d] client initiated chat bot connection", conn_get_socket(c));
conn_set_state(c, conn_state_connected);
conn_set_class(c, conn_class_bot);
break;
break;
case CLIENT_INITCONN_CLASS_D2CS_BNETD:
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated d2cs_bnetd connection",conn_get_socket(c));
case CLIENT_INITCONN_CLASS_TELNET:
eventlog(eventlog_level_info, __FUNCTION__, "[%d] client initiated telnet connection", conn_get_socket(c));
conn_set_state(c, conn_state_connected);
conn_set_class(c, conn_class_telnet);
if (!(realmlist_find_realm_by_ip(conn_get_addr(c))))
{
eventlog(eventlog_level_info,__FUNCTION__, "[%d] d2cs connection from unknown ip address %s",conn_get_socket(c),addr_num_to_addr_str(conn_get_addr(c),conn_get_port(c)));
return -1;
}
break;
conn_set_state(c,conn_state_connected);
conn_set_class(c,conn_class_d2cs_bnetd);
if (handle_d2cs_init(c)<0)
{
eventlog(eventlog_level_info,__FUNCTION__,"faild to init d2cs connection");
return -1;
}
}
break;
case CLIENT_INITCONN_CLASS_D2CS_BNETD:
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] client initiated d2cs_bnetd connection", conn_get_socket(c));
case CLIENT_INITCONN_CLASS_ENC:
eventlog(eventlog_level_info,__FUNCTION__,"[%d] client initiated encrypted connection (not supported)",conn_get_socket(c));
return -1;
if (!(realmlist_find_realm_by_ip(conn_get_addr(c))))
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] d2cs connection from unknown ip address %s", conn_get_socket(c), addr_num_to_addr_str(conn_get_addr(c), conn_get_port(c)));
return -1;
}
conn_set_state(c, conn_state_connected);
conn_set_class(c, conn_class_d2cs_bnetd);
if (handle_d2cs_init(c) < 0)
{
eventlog(eventlog_level_info, __FUNCTION__, "faild to init d2cs connection");
return -1;
}
}
break;
case CLIENT_INITCONN_CLASS_ENC:
eventlog(eventlog_level_info, __FUNCTION__, "[%d] client initiated encrypted connection (not supported)", conn_get_socket(c));
return -1;
default:
eventlog(eventlog_level_error, __FUNCTION__, "[%d] client requested unknown class 0x%02x (length %d) (closing connection)", conn_get_socket(c), (unsigned int)bn_byte_get(packet->u.client_initconn.cclass), packet_get_size(packet));
return -1;
}
break;
default:
eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown init packet type 0x%04x, len %u", conn_get_socket(c), packet_get_type(packet), packet_get_size(packet));
return -1;
}
return 0;
}
default:
eventlog(eventlog_level_error,__FUNCTION__,"[%d] client requested unknown class 0x%02x (length %d) (closing connection)",conn_get_socket(c),(unsigned int)bn_byte_get(packet->u.client_initconn.cclass),packet_get_size(packet));
return -1;
}
break;
default:
eventlog(eventlog_level_error,__FUNCTION__,"[%d] unknown init packet type 0x%04x, len %u",conn_get_socket(c),packet_get_type(packet),packet_get_size(packet));
return -1;
}
return 0;
}
}
}

View file

@ -30,12 +30,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_init_packet(t_connection * c, t_packet const * const packet);
extern int handle_init_packet(t_connection * c, t_packet const * const packet);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -29,14 +29,14 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_irc_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_irc_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_irc_welcome(t_connection * conn);
extern int handle_irc_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_irc_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_irc_welcome(t_connection * conn);
}
}
}

View file

@ -43,308 +43,312 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
static int handle_irc_common_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
static int handle_irc_common_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
if (!conn) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
return -1;
}
switch (conn_get_class(conn)) {
case conn_class_irc:
return handle_irc_con_command(conn, command, numparams, params, text);
case conn_class_wserv:
return handle_wserv_con_command(conn, command, numparams, params, text);
case conn_class_wol:
case conn_class_wladder:
case conn_class_wgameres:
return handle_wol_con_command(conn, command, numparams, params, text);
default:
return handle_irc_con_command(conn, command, numparams, params, text);
}
}
static int handle_irc_common_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
switch (conn_get_class(conn)) {
case conn_class_irc:
return handle_irc_log_command(conn, command, numparams, params, text);
case conn_class_wol:
case conn_class_wgameres:
return handle_wol_log_command(conn, command, numparams, params, text);
default:
return handle_irc_log_command(conn, command, numparams, params, text);
}
}
static int handle_irc_common_set_class(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
if (conn_get_class(conn) != conn_class_ircinit) {
DEBUG0("FIXME: conn_get_class(conn) != conn_class_ircinit");
return -1;
}
else {
if (strcasecmp(command, "VERCHK") == 0) {
DEBUG0("Got WSERV packet");
if (std::strcmp(prefs_get_wolv2_addrs(),"") != 0)
conn_set_class(conn,conn_class_wserv);
else
conn_set_state(conn,conn_state_destroy);
return 0;
}
else if (strcasecmp(command, "CVERS") == 0) {
DEBUG0("Got WOL packet");
/* FIXME: We can check it not by address but check if client is supported by tag_check_in_list() */
if ((std::strcmp(prefs_get_wolv1_addrs(),"") != 0) || (std::strcmp(prefs_get_wolv2_addrs(),"") != 0))
conn_set_class(conn,conn_class_wol);
else
conn_set_state(conn,conn_state_destroy);
return 0;
}
else if ((strcasecmp(command, "LISTSEARCH") == 0) ||
(strcasecmp(command, "RUNGSEARCH") == 0) ||
(strcasecmp(command, "HIGHSCORE") == 0)) {
DEBUG0("Got WOL Ladder packet");
if (std::strcmp(prefs_get_wolv2_addrs(),"") != 0)
conn_set_class(conn,conn_class_wladder); /* is handled in handle_wol.* now */
else
conn_set_state(conn,conn_state_destroy);
return 0;
}
else if ((strcasecmp(command, "CRYPT") == 0) ||
(strcasecmp(command, "LOGIN") == 0)) {
DEBUG0("Got GameSpy packet");
if (std::strcmp(prefs_get_irc_addrs(),"") != 0)
conn_set_class(conn,conn_class_irc);
// conn_set_class(conn,conn_class_gspy_peerchat);
else
conn_set_state(conn,conn_state_destroy);
return 0;
}
else {
DEBUG0("Got IRC packet");
if (std::strcmp(prefs_get_irc_addrs(),"") != 0)
conn_set_class(conn,conn_class_irc);
else
conn_set_state(conn,conn_state_destroy);
return 0;
}
}
}
static int handle_irc_common_line(t_connection * conn, char const * ircline)
{
/* [:prefix] <command> [[param1] [param2] ... [paramN]] [:<text>] */
char * line; /* copy of ircline */
char * prefix = NULL; /* optional; mostly NULL */
char * command; /* mandatory */
char ** params = NULL; /* optional (array of params) */
char * text = NULL; /* optional */
char * bnet_command = NULL; /* amadeo: used for battle.net.commands */
int unrecognized_before = 0;
int linelen; /* amadeo: counter for stringlenghts */
int numparams = 0;
char * tempparams;
int i;
char paramtemp[MAX_IRC_MESSAGE_LEN*2];
int first = 1;
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
if (!ircline) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL ircline");
return -1;
}
if (ircline[0] == '\0') {
/**
* PELISH: We dont send warning about that because it is client-side problem.
* eventlog(eventlog_level_error,__FUNCTION__,"got empty ircline");
*/
return -1;
}
//amadeo: code was sent by some unknown fellow of pvpgn, prevents buffer-overflow for
// too long irc-lines
//PELISH: According to RFC2812 we do truncation on 512 byte
if (std::strlen(ircline)>MAX_IRC_MESSAGE_LEN) {
char * tmp = (char *)ircline;
eventlog(eventlog_level_warn,__FUNCTION__,"line too long, truncation...");
tmp[MAX_IRC_MESSAGE_LEN]='\0';
}
line = xstrdup(ircline);
/* split the message */
if (line[0] == ':') {
/* The prefix is optional and is rarely provided */
prefix = line;
if (!(command = std::strchr(line,' '))) {
eventlog(eventlog_level_warn,__FUNCTION__,"got malformed line (missing command)");
xfree(line);
return -1;
}
*command++ = '\0';
}
else {
/* In most cases command is the first thing on the line */
command = line;
}
tempparams = std::strchr(command,' ');
if (tempparams) {
*tempparams++ = '\0';
if (tempparams[0]==':') {
text = tempparams+1; /* theres just text, no params. skip the colon */
} else {
for (i=0;tempparams[i]!='\0';i++) {
if ((tempparams[i]==' ')&&(tempparams[i+1]==':')) {
text = tempparams+i;
*text++ = '\0';
text++; /* skip the colon */
break; /* text found, stop search */
}
}
params = irc_get_paramelems(tempparams);
}
}
if (params) {
/* count parameters */
for (numparams=0;params[numparams];numparams++);
}
std::memset(paramtemp,0,sizeof(paramtemp));
for (i=0;((numparams>0)&&(params[i]));i++) {
if (!first)
std::strcat(paramtemp," ");
std::strcat(paramtemp,"\"");
std::strcat(paramtemp,params[i]);
std::strcat(paramtemp,"\"");
first = 0;
}
eventlog(eventlog_level_debug,__FUNCTION__,"[%d] got \"%s\" \"%s\" [%s] \"%s\"",conn_get_socket(conn),((prefix)?(prefix):("")),command,paramtemp,((text)?(text):("")));
if (conn_get_class(conn) == conn_class_ircinit) {
handle_irc_common_set_class(conn, command, numparams, params, text);
}
if (conn_get_state(conn)==conn_state_connected) {
conn_set_state(conn,conn_state_bot_username); /* PELISH: What is this for? */
if ((conn_get_class(conn) != conn_class_wserv) &&
(conn_get_class(conn) != conn_class_wladder)) {
t_timer_data temp;
temp.n = prefs_get_irc_latency();
conn_test_latency(conn,std::time(NULL),temp);
}
}
if (handle_irc_common_con_command(conn, command, numparams, params, text)!=-1) {}
else if (conn_get_state(conn)!=conn_state_loggedin) {
char temp[MAX_IRC_MESSAGE_LEN+1];
if ((38+std::strlen(command)+16+1)<sizeof(temp)) {
snprintf(temp, sizeof(temp), ":Unrecognized command \"%s\" (before login)", command);
irc_send(conn,ERR_UNKNOWNCOMMAND,temp);
} else {
irc_send(conn,ERR_UNKNOWNCOMMAND,":Unrecognized command (before login)");
}
} else {
/* command is handled later */
unrecognized_before = 1;
}
/* --- The following should only be executable after login --- */
if ((conn_get_state(conn)==conn_state_loggedin)&&(unrecognized_before)) {
if (handle_irc_common_log_command(conn, command, numparams, params, text)!=-1) {}
else if ((strstart(command,"LAG")!=0)&&(strstart(command,"JOIN")!=0)){
linelen = std::strlen (ircline);
bnet_command = (char*)xmalloc(linelen + 2);
bnet_command[0]='/';
std::strcpy(bnet_command + 1, ircline);
handle_command(conn,bnet_command);
xfree((void*)bnet_command);
switch (conn_get_class(conn)) {
case conn_class_irc:
return handle_irc_con_command(conn, command, numparams, params, text);
case conn_class_wserv:
return handle_wserv_con_command(conn, command, numparams, params, text);
case conn_class_wol:
case conn_class_wladder:
case conn_class_wgameres:
return handle_wol_con_command(conn, command, numparams, params, text);
default:
return handle_irc_con_command(conn, command, numparams, params, text);
}
}
} /* loggedin */
if (params)
irc_unget_paramelems(params);
xfree(line);
return 0;
}
static int handle_irc_common_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
if (!conn) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
return -1;
}
extern int handle_irc_common_packet(t_connection * conn, t_packet const * const packet)
{
unsigned int i;
char ircline[MAX_IRC_MESSAGE_LEN];
char const * data;
char test[MAX_IRC_MESSAGE_LEN];
if (!packet) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
return -1;
}
if ((conn_get_class(conn) != conn_class_ircinit) &&
(conn_get_class(conn) != conn_class_irc) &&
(conn_get_class(conn) != conn_class_wol) &&
(conn_get_class(conn) != conn_class_wserv) &&
(conn_get_class(conn) != conn_class_wladder)) {
eventlog(eventlog_level_error,__FUNCTION__,"FIXME: handle_irc_packet without any reason (conn->class != conn_class_irc/ircinit/wol/wserv...)");
return -1;
}
// eventlog(eventlog_level_debug,__FUNCTION__,"got \"%s\"",packet_get_raw_data_const(packet,0));
std::memset(ircline,0,sizeof(ircline));
data = conn_get_ircline(conn); /* fetch current status */
if (data)
std::strcpy(ircline,data);
unsigned ircpos = std::strlen(ircline);
data = (const char *)packet_get_raw_data_const(packet,0);
for (i=0; i < packet_get_size(packet); i++) {
if (data[i] == '\n') {
/* end of line */
handle_irc_common_line(conn,ircline);
std::memset(ircline,0,sizeof(ircline));
ircpos = 0;
} else {
if (ircpos < MAX_IRC_MESSAGE_LEN-1)
ircline[ircpos++] = data[i];
else {
ircpos++; /* for the statistic :) */
eventlog(eventlog_level_warn,__FUNCTION__,"[%d] client exceeded maximum allowed message length by %d characters",conn_get_socket(conn),ircpos-MAX_IRC_MESSAGE_LEN);
if (ircpos > 100 + MAX_IRC_MESSAGE_LEN) {
/* automatic flood protection */
eventlog(eventlog_level_error,__FUNCTION__,"[%d] excess flood",conn_get_socket(conn));
return -1;
switch (conn_get_class(conn)) {
case conn_class_irc:
return handle_irc_log_command(conn, command, numparams, params, text);
case conn_class_wol:
case conn_class_wgameres:
return handle_wol_log_command(conn, command, numparams, params, text);
default:
return handle_irc_log_command(conn, command, numparams, params, text);
}
}
}
static int handle_irc_common_set_class(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
if (!conn) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
return -1;
}
if (conn_get_class(conn) != conn_class_ircinit) {
DEBUG0("FIXME: conn_get_class(conn) != conn_class_ircinit");
return -1;
}
else {
if (strcasecmp(command, "VERCHK") == 0) {
DEBUG0("Got WSERV packet");
if (std::strcmp(prefs_get_wolv2_addrs(), "") != 0)
conn_set_class(conn, conn_class_wserv);
else
conn_set_state(conn, conn_state_destroy);
return 0;
}
else if (strcasecmp(command, "CVERS") == 0) {
DEBUG0("Got WOL packet");
/* FIXME: We can check it not by address but check if client is supported by tag_check_in_list() */
if ((std::strcmp(prefs_get_wolv1_addrs(), "") != 0) || (std::strcmp(prefs_get_wolv2_addrs(), "") != 0))
conn_set_class(conn, conn_class_wol);
else
conn_set_state(conn, conn_state_destroy);
return 0;
}
else if ((strcasecmp(command, "LISTSEARCH") == 0) ||
(strcasecmp(command, "RUNGSEARCH") == 0) ||
(strcasecmp(command, "HIGHSCORE") == 0)) {
DEBUG0("Got WOL Ladder packet");
if (std::strcmp(prefs_get_wolv2_addrs(), "") != 0)
conn_set_class(conn, conn_class_wladder); /* is handled in handle_wol.* now */
else
conn_set_state(conn, conn_state_destroy);
return 0;
}
else if ((strcasecmp(command, "CRYPT") == 0) ||
(strcasecmp(command, "LOGIN") == 0)) {
DEBUG0("Got GameSpy packet");
if (std::strcmp(prefs_get_irc_addrs(), "") != 0)
conn_set_class(conn, conn_class_irc);
// conn_set_class(conn,conn_class_gspy_peerchat);
else
conn_set_state(conn, conn_state_destroy);
return 0;
}
else {
DEBUG0("Got IRC packet");
if (std::strcmp(prefs_get_irc_addrs(), "") != 0)
conn_set_class(conn, conn_class_irc);
else
conn_set_state(conn, conn_state_destroy);
return 0;
}
}
}
static int handle_irc_common_line(t_connection * conn, char const * ircline)
{
/* [:prefix] <command> [[param1] [param2] ... [paramN]] [:<text>] */
char * line; /* copy of ircline */
char * prefix = NULL; /* optional; mostly NULL */
char * command; /* mandatory */
char ** params = NULL; /* optional (array of params) */
char * text = NULL; /* optional */
char * bnet_command = NULL; /* amadeo: used for battle.net.commands */
int unrecognized_before = 0;
int linelen; /* amadeo: counter for stringlenghts */
int numparams = 0;
char * tempparams;
int i;
char paramtemp[MAX_IRC_MESSAGE_LEN * 2];
int first = 1;
if (!conn) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
return -1;
}
if (!ircline) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL ircline");
return -1;
}
if (ircline[0] == '\0') {
/**
* PELISH: We dont send warning about that because it is client-side problem.
* eventlog(eventlog_level_error,__FUNCTION__,"got empty ircline");
*/
return -1;
}
//amadeo: code was sent by some unknown fellow of pvpgn, prevents buffer-overflow for
// too long irc-lines
//PELISH: According to RFC2812 we do truncation on 512 byte
if (std::strlen(ircline) > MAX_IRC_MESSAGE_LEN) {
char * tmp = (char *)ircline;
eventlog(eventlog_level_warn, __FUNCTION__, "line too long, truncation...");
tmp[MAX_IRC_MESSAGE_LEN] = '\0';
}
line = xstrdup(ircline);
/* split the message */
if (line[0] == ':') {
/* The prefix is optional and is rarely provided */
prefix = line;
if (!(command = std::strchr(line, ' '))) {
eventlog(eventlog_level_warn, __FUNCTION__, "got malformed line (missing command)");
xfree(line);
return -1;
}
*command++ = '\0';
}
else {
/* In most cases command is the first thing on the line */
command = line;
}
tempparams = std::strchr(command, ' ');
if (tempparams) {
*tempparams++ = '\0';
if (tempparams[0] == ':') {
text = tempparams + 1; /* theres just text, no params. skip the colon */
}
else {
for (i = 0; tempparams[i] != '\0'; i++) {
if ((tempparams[i] == ' ') && (tempparams[i + 1] == ':')) {
text = tempparams + i;
*text++ = '\0';
text++; /* skip the colon */
break; /* text found, stop search */
}
}
params = irc_get_paramelems(tempparams);
}
}
if (params) {
/* count parameters */
for (numparams = 0; params[numparams]; numparams++);
}
std::memset(paramtemp, 0, sizeof(paramtemp));
for (i = 0; ((numparams > 0) && (params[i])); i++) {
if (!first)
std::strcat(paramtemp, " ");
std::strcat(paramtemp, "\"");
std::strcat(paramtemp, params[i]);
std::strcat(paramtemp, "\"");
first = 0;
}
eventlog(eventlog_level_debug, __FUNCTION__, "[%d] got \"%s\" \"%s\" [%s] \"%s\"", conn_get_socket(conn), ((prefix) ? (prefix) : ("")), command, paramtemp, ((text) ? (text) : ("")));
if (conn_get_class(conn) == conn_class_ircinit) {
handle_irc_common_set_class(conn, command, numparams, params, text);
}
if (conn_get_state(conn) == conn_state_connected) {
conn_set_state(conn, conn_state_bot_username); /* PELISH: What is this for? */
if ((conn_get_class(conn) != conn_class_wserv) &&
(conn_get_class(conn) != conn_class_wladder)) {
t_timer_data temp;
temp.n = prefs_get_irc_latency();
conn_test_latency(conn, std::time(NULL), temp);
}
}
if (handle_irc_common_con_command(conn, command, numparams, params, text) != -1) {}
else if (conn_get_state(conn) != conn_state_loggedin) {
char temp[MAX_IRC_MESSAGE_LEN + 1];
if ((38 + std::strlen(command) + 16 + 1) < sizeof(temp)) {
snprintf(temp, sizeof(temp), ":Unrecognized command \"%s\" (before login)", command);
irc_send(conn, ERR_UNKNOWNCOMMAND, temp);
}
else {
irc_send(conn, ERR_UNKNOWNCOMMAND, ":Unrecognized command (before login)");
}
}
else {
/* command is handled later */
unrecognized_before = 1;
}
/* --- The following should only be executable after login --- */
if ((conn_get_state(conn) == conn_state_loggedin) && (unrecognized_before)) {
if (handle_irc_common_log_command(conn, command, numparams, params, text) != -1) {}
else if ((strstart(command, "LAG") != 0) && (strstart(command, "JOIN") != 0)){
linelen = std::strlen(ircline);
bnet_command = (char*)xmalloc(linelen + 2);
bnet_command[0] = '/';
std::strcpy(bnet_command + 1, ircline);
handle_command(conn, bnet_command);
xfree((void*)bnet_command);
}
} /* loggedin */
if (params)
irc_unget_paramelems(params);
xfree(line);
return 0;
}
extern int handle_irc_common_packet(t_connection * conn, t_packet const * const packet)
{
unsigned int i;
char ircline[MAX_IRC_MESSAGE_LEN];
char const * data;
char test[MAX_IRC_MESSAGE_LEN];
if (!packet) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL packet");
return -1;
}
if ((conn_get_class(conn) != conn_class_ircinit) &&
(conn_get_class(conn) != conn_class_irc) &&
(conn_get_class(conn) != conn_class_wol) &&
(conn_get_class(conn) != conn_class_wserv) &&
(conn_get_class(conn) != conn_class_wladder)) {
eventlog(eventlog_level_error, __FUNCTION__, "FIXME: handle_irc_packet without any reason (conn->class != conn_class_irc/ircinit/wol/wserv...)");
return -1;
}
// eventlog(eventlog_level_debug,__FUNCTION__,"got \"%s\"",packet_get_raw_data_const(packet,0));
std::memset(ircline, 0, sizeof(ircline));
data = conn_get_ircline(conn); /* fetch current status */
if (data)
std::strcpy(ircline, data);
unsigned ircpos = std::strlen(ircline);
data = (const char *)packet_get_raw_data_const(packet, 0);
for (i = 0; i < packet_get_size(packet); i++) {
if (data[i] == '\n') {
/* end of line */
handle_irc_common_line(conn, ircline);
std::memset(ircline, 0, sizeof(ircline));
ircpos = 0;
}
else {
if (ircpos < MAX_IRC_MESSAGE_LEN - 1)
ircline[ircpos++] = data[i];
else {
ircpos++; /* for the statistic :) */
eventlog(eventlog_level_warn, __FUNCTION__, "[%d] client exceeded maximum allowed message length by %d characters", conn_get_socket(conn), ircpos - MAX_IRC_MESSAGE_LEN);
if (ircpos > 100 + MAX_IRC_MESSAGE_LEN) {
/* automatic flood protection */
eventlog(eventlog_level_error, __FUNCTION__, "[%d] excess flood", conn_get_socket(conn));
return -1;
}
}
}
}
conn_set_ircline(conn, ircline); /* write back current status */
return 0;
}
}
}
conn_set_ircline(conn,ircline); /* write back current status */
return 0;
}
}
}

View file

@ -28,12 +28,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_irc_common_packet(t_connection * conn, t_packet const * const packet);
extern int handle_irc_common_packet(t_connection * conn, t_packet const * const packet);
}
}
}

View file

@ -39,309 +39,309 @@
namespace pvpgn
{
namespace bnetd
{
extern int handle_telnet_packet(t_connection * c, t_packet const * const packet)
{
t_packet * rpacket;
if (!c)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL connection",conn_get_socket(c));
return -1;
}
if (!packet)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL packet",conn_get_socket(c));
return -1;
}
if (packet_get_class(packet)!=packet_class_raw)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",conn_get_socket(c),(int)packet_get_class(packet));
return -1;
}
{
char const * const linestr=packet_get_str_const(packet,0,MAX_MESSAGE_LEN);
if (packet_get_size(packet)<2) /* empty line */
return 0;
if (!linestr)
namespace bnetd
{
eventlog(eventlog_level_warn,__FUNCTION__,"[%d] line too long",conn_get_socket(c));
return 0;
extern int handle_telnet_packet(t_connection * c, t_packet const * const packet)
{
t_packet * rpacket;
if (!c)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL connection", conn_get_socket(c));
return -1;
}
if (!packet)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL packet", conn_get_socket(c));
return -1;
}
if (packet_get_class(packet) != packet_class_raw)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad packet (class %d)", conn_get_socket(c), (int)packet_get_class(packet));
return -1;
}
{
char const * const linestr = packet_get_str_const(packet, 0, MAX_MESSAGE_LEN);
if (packet_get_size(packet) < 2) /* empty line */
return 0;
if (!linestr)
{
eventlog(eventlog_level_warn, __FUNCTION__, "[%d] line too long", conn_get_socket(c));
return 0;
}
switch (conn_get_state(c))
{
case conn_state_connected:
conn_add_flags(c, MF_PLUG);
conn_set_clienttag(c, CLIENTTAG_BNCHATBOT_UINT);
{
char const * temp = linestr;
if (temp[0] == '\004') /* FIXME: no echo, ignore for now (we always do no echo) */
temp = &temp[1];
if (temp[0] == '\0') /* empty line */
{
conn_set_state(c, conn_state_bot_username); /* don't look for ^D or reset tag and flags */
break;
}
conn_set_state(c, conn_state_bot_password);
if (conn_set_loggeduser(c, temp) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not set username to \"%s\"", conn_get_socket(c), temp);
{
char const * const msg = "\r\nPassword: ";
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
#if 0 /* don't echo */
packet_append_ntstring(rpacket, conn_get_loggeduser(c));
#endif
packet_append_ntstring(rpacket, msg);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
}
break;
case conn_state_bot_username:
conn_set_state(c, conn_state_bot_password);
if (conn_set_loggeduser(c, linestr) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not set username to \"%s\"", conn_get_socket(c), linestr);
{
char const * const temp = "\r\nPassword: ";
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
#if 0 /* don't echo */
packet_append_ntstring(rpacket, linestr);
#endif
packet_append_ntstring(rpacket, temp);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
break;
case conn_state_bot_password:
{
char const * const tempa = "\r\nLogin failed.\r\n\r\nUsername: ";
char const * const tempb = "\r\nAccount has no bot access.\r\n\r\nUsername: ";
char const * const loggeduser = conn_get_loggeduser(c);
t_account * account;
char const * oldstrhash1;
t_hash trypasshash1;
t_hash oldpasshash1;
char * testpass;
if (!loggeduser) /* error earlier in login */
{
/* no std::log message... */
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
if (connlist_find_connection_by_accountname(loggeduser))
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (already logged in)", conn_get_socket(c), loggeduser);
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
if (!(account = accountlist_find_account(loggeduser)))
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (bad account)", conn_get_socket(c), loggeduser);
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
if ((oldstrhash1 = account_get_pass(account)))
{
if (hash_set_str(&oldpasshash1, oldstrhash1) < 0)
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (corrupted passhash1?)", conn_get_socket(c), account_get_name(account));
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
testpass = xstrdup(linestr);
{
unsigned int i;
for (i = 0; i < std::strlen(testpass); i++)
if (std::isupper((int)testpass[i]))
testpass[i] = std::tolower((int)testpass[i]);
}
if (bnet_hash(&trypasshash1, std::strlen(testpass), testpass) < 0) /* FIXME: force to lowercase */
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (unable to hash password)", conn_get_socket(c), account_get_name(account));
xfree(testpass);
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
xfree(testpass);
if (hash_eq(trypasshash1, oldpasshash1) != 1)
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (wrong password)", conn_get_socket(c), account_get_name(account));
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempa);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
if (account_get_auth_botlogin(account) != 1) /* default to false */
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (no bot access)", conn_get_socket(c), account_get_name(account));
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempb);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
else if (account_get_auth_lock(account) == 1) /* default to false */
{
eventlog(eventlog_level_info, __FUNCTION__, "[%d] bot login for \"%s\" refused (this account is locked)", conn_get_socket(c), account_get_name(account));
conn_set_state(c, conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket, tempb);
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
break;
}
eventlog(eventlog_level_info, __FUNCTION__, "[%d] \"%s\" bot logged in (correct password)", conn_get_socket(c), account_get_name(account));
}
else
eventlog(eventlog_level_info, __FUNCTION__, "[%d] \"%s\" bot logged in (no password)", conn_get_socket(c), account_get_name(account));
if (!(rpacket = packet_create(packet_class_raw))) /* if we got this far, let them std::log in even if this fails */
eventlog(eventlog_level_error, __FUNCTION__, "[%d] could not create rpacket", conn_get_socket(c));
else
{
packet_append_ntstring(rpacket, "\r\n");
conn_push_outqueue(c, rpacket);
packet_del_ref(rpacket);
}
message_send_text(c, message_type_uniqueid, c, loggeduser);
conn_login(c, account, loggeduser);
if (conn_set_channel(c, CHANNEL_NAME_CHAT) < 0)
conn_set_channel(c, CHANNEL_NAME_BANNED); /* should not fail */
}
break;
case conn_state_loggedin:
{
t_channel const * channel;
conn_set_idletime(c);
if ((channel = conn_get_channel(c)))
channel_message_log(channel, c, 1, linestr);
/* we don't log game commands currently */
if (linestr[0] == '/')
handle_command(c, linestr);
else
if (channel && !conn_quota_exceeded(c, linestr))
channel_message_send(channel, message_type_talk, c, linestr);
/* else discard */
}
break;
default:
eventlog(eventlog_level_error, __FUNCTION__, "[%d] unknown telnet connection state %d", conn_get_socket(c), (int)conn_get_state(c));
}
}
return 0;
}
}
switch (conn_get_state(c))
{
case conn_state_connected:
conn_add_flags(c,MF_PLUG);
conn_set_clienttag(c,CLIENTTAG_BNCHATBOT_UINT);
{
char const * temp=linestr;
if (temp[0]=='\004') /* FIXME: no echo, ignore for now (we always do no echo) */
temp = &temp[1];
if (temp[0]=='\0') /* empty line */
{
conn_set_state(c,conn_state_bot_username); /* don't look for ^D or reset tag and flags */
break;
}
conn_set_state(c,conn_state_bot_password);
if (conn_set_loggeduser(c,temp)<0)
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set username to \"%s\"",conn_get_socket(c),temp);
{
char const * const msg="\r\nPassword: ";
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
#if 0 /* don't echo */
packet_append_ntstring(rpacket,conn_get_loggeduser(c));
#endif
packet_append_ntstring(rpacket,msg);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
}
break;
case conn_state_bot_username:
conn_set_state(c,conn_state_bot_password);
if (conn_set_loggeduser(c,linestr)<0)
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set username to \"%s\"",conn_get_socket(c),linestr);
{
char const * const temp="\r\nPassword: ";
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
#if 0 /* don't echo */
packet_append_ntstring(rpacket,linestr);
#endif
packet_append_ntstring(rpacket,temp);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
break;
case conn_state_bot_password:
{
char const * const tempa="\r\nLogin failed.\r\n\r\nUsername: ";
char const * const tempb="\r\nAccount has no bot access.\r\n\r\nUsername: ";
char const * const loggeduser=conn_get_loggeduser(c);
t_account * account;
char const * oldstrhash1;
t_hash trypasshash1;
t_hash oldpasshash1;
char * testpass;
if (!loggeduser) /* error earlier in login */
{
/* no std::log message... */
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
if (connlist_find_connection_by_accountname(loggeduser))
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (already logged in)",conn_get_socket(c),loggeduser);
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
if (!(account = accountlist_find_account(loggeduser)))
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (bad account)",conn_get_socket(c),loggeduser);
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
if ((oldstrhash1 = account_get_pass(account)))
{
if (hash_set_str(&oldpasshash1,oldstrhash1)<0)
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (corrupted passhash1?)",conn_get_socket(c),account_get_name(account));
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
testpass = xstrdup(linestr);
{
unsigned int i;
for (i=0; i<std::strlen(testpass); i++)
if (std::isupper((int)testpass[i]))
testpass[i] = std::tolower((int)testpass[i]);
}
if (bnet_hash(&trypasshash1,std::strlen(testpass),testpass)<0) /* FIXME: force to lowercase */
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (unable to hash password)",conn_get_socket(c),account_get_name(account));
xfree(testpass);
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
xfree(testpass);
if (hash_eq(trypasshash1,oldpasshash1)!=1)
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (wrong password)",conn_get_socket(c),account_get_name(account));
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempa);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
if (account_get_auth_botlogin(account)!=1) /* default to false */
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (no bot access)",conn_get_socket(c),account_get_name(account));
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempb);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
else if (account_get_auth_lock(account)==1) /* default to false */
{
eventlog(eventlog_level_info,__FUNCTION__,"[%d] bot login for \"%s\" refused (this account is locked)",conn_get_socket(c),account_get_name(account));
conn_set_state(c,conn_state_bot_username);
if (!(rpacket = packet_create(packet_class_raw)))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
break;
}
packet_append_ntstring(rpacket,tempb);
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
break;
}
eventlog(eventlog_level_info,__FUNCTION__,"[%d] \"%s\" bot logged in (correct password)",conn_get_socket(c),account_get_name(account));
}
else
eventlog(eventlog_level_info,__FUNCTION__,"[%d] \"%s\" bot logged in (no password)",conn_get_socket(c),account_get_name(account));
if (!(rpacket = packet_create(packet_class_raw))) /* if we got this far, let them std::log in even if this fails */
eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not create rpacket",conn_get_socket(c));
else
{
packet_append_ntstring(rpacket,"\r\n");
conn_push_outqueue(c,rpacket);
packet_del_ref(rpacket);
}
message_send_text(c,message_type_uniqueid,c,loggeduser);
conn_login(c,account,loggeduser);
if (conn_set_channel(c,CHANNEL_NAME_CHAT)<0)
conn_set_channel(c,CHANNEL_NAME_BANNED); /* should not fail */
}
break;
case conn_state_loggedin:
{
t_channel const * channel;
conn_set_idletime(c);
if ((channel = conn_get_channel(c)))
channel_message_log(channel,c,1,linestr);
/* we don't log game commands currently */
if (linestr[0]=='/')
handle_command(c,linestr);
else
if (channel && !conn_quota_exceeded(c,linestr))
channel_message_send(channel,message_type_talk,c,linestr);
/* else discard */
}
break;
default:
eventlog(eventlog_level_error,__FUNCTION__,"[%d] unknown telnet connection state %d",conn_get_socket(c),(int)conn_get_state(c));
}
}
return 0;
}
}
}

View file

@ -30,12 +30,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_telnet_packet(t_connection * c, t_packet const * const packet);
extern int handle_telnet_packet(t_connection * c, t_packet const * const packet);
}
}
}

View file

@ -30,114 +30,114 @@
namespace pvpgn
{
namespace bnetd
{
extern int handle_udp_packet(int usock, unsigned int src_addr, unsigned short src_port, t_packet const * const packet)
{
if (!packet)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got NULL packet",usock);
return -1;
}
if (packet_get_class(packet)!=packet_class_udp)
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad packet (class %d)",usock,(int)packet_get_class(packet));
return -1;
}
switch (packet_get_type(packet))
{
case SERVER_UDPTEST: /* we might get these if a client is running on the same machine as us */
if (packet_get_size(packet)<sizeof(t_server_udptest))
namespace bnetd
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad UDPTEST packet (expected %lu bytes, got %u)",usock,sizeof(t_server_udptest),packet_get_size(packet));
return -1;
extern int handle_udp_packet(int usock, unsigned int src_addr, unsigned short src_port, t_packet const * const packet)
{
if (!packet)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL packet", usock);
return -1;
}
if (packet_get_class(packet) != packet_class_udp)
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad packet (class %d)", usock, (int)packet_get_class(packet));
return -1;
}
switch (packet_get_type(packet))
{
case SERVER_UDPTEST: /* we might get these if a client is running on the same machine as us */
if (packet_get_size(packet) < sizeof(t_server_udptest))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad UDPTEST packet (expected %lu bytes, got %u)", usock, sizeof(t_server_udptest), packet_get_size(packet));
return -1;
}
eventlog(eventlog_level_debug, __FUNCTION__, "[%d] got UDPTEST packet from %s (myself?)", usock, addr_num_to_addr_str(src_addr, src_port));
return 0;
case CLIENT_UDPPING:
if (packet_get_size(packet) < sizeof(t_client_udpping))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad UDPPING packet (expected %lu bytes, got %u)", usock, sizeof(t_client_udpping), packet_get_size(packet));
return -1;
}
eventlog(eventlog_level_debug, __FUNCTION__, "[%d] got udpping unknown1=%u", usock, bn_int_get(packet->u.client_udpping.unknown1));
return 0;
case CLIENT_SESSIONADDR1:
if (packet_get_size(packet) < sizeof(t_client_sessionaddr1))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad SESSIONADDR1 packet (expected %lu bytes, got %u)", usock, sizeof(t_client_sessionaddr1), packet_get_size(packet));
return -1;
}
{
t_connection * c;
if (!(c = connlist_find_connection_by_sessionkey(bn_int_get(packet->u.client_sessionaddr1.sessionkey))))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] address not set (no connection with session key 0x%08x)", usock, bn_int_get(packet->u.client_sessionaddr1.sessionkey));
return -1;
}
if (conn_get_game_addr(c) != src_addr || conn_get_game_port(c) != src_port)
eventlog(eventlog_level_info, __FUNCTION__, "[%d][%d] SESSIONADDR1 set new UDP address to %s", conn_get_socket(c), usock, addr_num_to_addr_str(src_addr, src_port));
conn_set_game_socket(c, usock);
conn_set_game_addr(c, src_addr);
conn_set_game_port(c, src_port);
udptest_send(c);
}
return 0;
case CLIENT_SESSIONADDR2:
if (packet_get_size(packet) < sizeof(t_client_sessionaddr2))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad SESSIONADDR2 packet (expected %lu bytes, got %u)", usock, sizeof(t_client_sessionaddr2), packet_get_size(packet));
return -1;
}
{
t_connection * c;
if (!(c = connlist_find_connection_by_sessionnum(bn_int_get(packet->u.client_sessionaddr2.sessionnum))))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d] address not set (no connection with session number %u)", usock, bn_int_get(packet->u.client_sessionaddr2.sessionnum));
return -1;
}
if (conn_get_sessionkey(c) != bn_int_get(packet->u.client_sessionaddr2.sessionkey))
{
eventlog(eventlog_level_error, __FUNCTION__, "[%d][%d] address not set (expected session key 0x%08x, got 0x%08x)", conn_get_socket(c), usock, conn_get_sessionkey(c), bn_int_get(packet->u.client_sessionaddr2.sessionkey));
return -1;
}
if (conn_get_game_addr(c) != src_addr || conn_get_game_port(c) != src_port)
eventlog(eventlog_level_info, __FUNCTION__, "[%d][%d] SESSIONADDR2 set new UDP address to %s", conn_get_socket(c), usock, addr_num_to_addr_str(src_addr, src_port));
conn_set_game_socket(c, usock);
conn_set_game_addr(c, src_addr);
conn_set_game_port(c, src_port);
udptest_send(c);
}
return 0;
case CLIENT_SEARCH_LAN_GAMES: //added by Spider
{
eventlog(eventlog_level_debug, __FUNCTION__, "[%d] got SEARCH_LAN_GAMES packet from %s", usock, addr_num_to_addr_str(src_addr, src_port));
return 0;
}
default:
eventlog(eventlog_level_error, __FUNCTION__, "[%d] got unknown udp packet type 0x%04x, len %u from %s", usock, (unsigned int)packet_get_type(packet), packet_get_size(packet), addr_num_to_addr_str(src_addr, src_port));
}
return 0;
}
}
eventlog(eventlog_level_debug,__FUNCTION__,"[%d] got UDPTEST packet from %s (myself?)",usock,addr_num_to_addr_str(src_addr,src_port));
return 0;
case CLIENT_UDPPING:
if (packet_get_size(packet)<sizeof(t_client_udpping))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad UDPPING packet (expected %lu bytes, got %u)",usock,sizeof(t_client_udpping),packet_get_size(packet));
return -1;
}
eventlog(eventlog_level_debug,__FUNCTION__,"[%d] got udpping unknown1=%u",usock,bn_int_get(packet->u.client_udpping.unknown1));
return 0;
case CLIENT_SESSIONADDR1:
if (packet_get_size(packet)<sizeof(t_client_sessionaddr1))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad SESSIONADDR1 packet (expected %lu bytes, got %u)",usock,sizeof(t_client_sessionaddr1),packet_get_size(packet));
return -1;
}
{
t_connection * c;
if (!(c = connlist_find_connection_by_sessionkey(bn_int_get(packet->u.client_sessionaddr1.sessionkey))))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] address not set (no connection with session key 0x%08x)",usock,bn_int_get(packet->u.client_sessionaddr1.sessionkey));
return -1;
}
if (conn_get_game_addr(c)!=src_addr || conn_get_game_port(c)!=src_port)
eventlog(eventlog_level_info,__FUNCTION__,"[%d][%d] SESSIONADDR1 set new UDP address to %s",conn_get_socket(c),usock,addr_num_to_addr_str(src_addr,src_port));
conn_set_game_socket(c,usock);
conn_set_game_addr(c,src_addr);
conn_set_game_port(c,src_port);
udptest_send(c);
}
return 0;
case CLIENT_SESSIONADDR2:
if (packet_get_size(packet)<sizeof(t_client_sessionaddr2))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got bad SESSIONADDR2 packet (expected %lu bytes, got %u)",usock,sizeof(t_client_sessionaddr2),packet_get_size(packet));
return -1;
}
{
t_connection * c;
if (!(c = connlist_find_connection_by_sessionnum(bn_int_get(packet->u.client_sessionaddr2.sessionnum))))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d] address not set (no connection with session number %u)",usock,bn_int_get(packet->u.client_sessionaddr2.sessionnum));
return -1;
}
if (conn_get_sessionkey(c)!=bn_int_get(packet->u.client_sessionaddr2.sessionkey))
{
eventlog(eventlog_level_error,__FUNCTION__,"[%d][%d] address not set (expected session key 0x%08x, got 0x%08x)",conn_get_socket(c),usock,conn_get_sessionkey(c),bn_int_get(packet->u.client_sessionaddr2.sessionkey));
return -1;
}
if (conn_get_game_addr(c)!=src_addr || conn_get_game_port(c)!=src_port)
eventlog(eventlog_level_info,__FUNCTION__,"[%d][%d] SESSIONADDR2 set new UDP address to %s",conn_get_socket(c),usock,addr_num_to_addr_str(src_addr,src_port));
conn_set_game_socket(c,usock);
conn_set_game_addr(c,src_addr);
conn_set_game_port(c,src_port);
udptest_send(c);
}
return 0;
case CLIENT_SEARCH_LAN_GAMES: //added by Spider
{
eventlog(eventlog_level_debug,__FUNCTION__,"[%d] got SEARCH_LAN_GAMES packet from %s",usock,addr_num_to_addr_str(src_addr,src_port));
return 0;
}
default:
eventlog(eventlog_level_error,__FUNCTION__,"[%d] got unknown udp packet type 0x%04x, len %u from %s",usock,(unsigned int)packet_get_type(packet),packet_get_size(packet),addr_num_to_addr_str(src_addr,src_port));
}
return 0;
}
}
}

View file

@ -30,12 +30,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_udp_packet(int usock, unsigned int src_addr, unsigned short src_port, t_packet const * const packet);
extern int handle_udp_packet(int usock, unsigned int src_addr, unsigned short src_port, t_packet const * const packet);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -28,14 +28,14 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_wol_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_wol_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_wol_welcome(t_connection * conn);
extern int handle_wol_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_wol_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_wol_welcome(t_connection * conn);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -32,32 +32,32 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef enum {
wol_gameres_type_unknown = 0,
wol_gameres_type_byte = 1,
wol_gameres_type_bool = 2,
wol_gameres_type_time = 5,
wol_gameres_type_int = 6,
wol_gameres_type_string = 7,
wol_gameres_type_bigint = 20
} wol_gameres_type;
typedef enum {
wol_gameres_type_unknown = 0,
wol_gameres_type_byte = 1,
wol_gameres_type_bool = 2,
wol_gameres_type_time = 5,
wol_gameres_type_int = 6,
wol_gameres_type_string = 7,
wol_gameres_type_bigint = 20
} wol_gameres_type;
typedef struct wol_gameres_result
{
t_game * game;
t_game_result * results;
int senderid;
t_account * myaccount;
t_account * otheraccount;
} t_wol_gameres_result;
typedef struct wol_gameres_result
{
t_game * game;
t_game_result * results;
int senderid;
t_account * myaccount;
t_account * otheraccount;
extern int handle_wol_gameres_packet(t_connection * c, t_packet const * const packet);
} t_wol_gameres_result;
}
extern int handle_wol_gameres_packet(t_connection * c, t_packet const * const packet);
}
}

View file

@ -47,176 +47,176 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef int (* t_wserv_command)(t_connection * conn, int numparams, char ** params, char * text);
typedef int(*t_wserv_command)(t_connection * conn, int numparams, char ** params, char * text);
typedef struct {
const char * wserv_command_string;
t_wserv_command wserv_command_handler;
} t_wserv_command_table_row;
typedef struct {
const char * wserv_command_string;
t_wserv_command wserv_command_handler;
} t_wserv_command_table_row;
static int _handle_verchk_command(t_connection * conn, int numparams, char ** params, char * text);
static int _handle_lobcount_command(t_connection * conn, int numparams, char ** params, char * text);
static int _handle_whereto_command(t_connection * conn, int numparams, char ** params, char * text);
static int _handle_quit_command(t_connection * conn, int numparams, char ** params, char * text);
static int _handle_verchk_command(t_connection * conn, int numparams, char ** params, char * text);
static int _handle_lobcount_command(t_connection * conn, int numparams, char ** params, char * text);
static int _handle_whereto_command(t_connection * conn, int numparams, char ** params, char * text);
static int _handle_quit_command(t_connection * conn, int numparams, char ** params, char * text);
/* state "connected" handlers (on Westwood ServServ server are not loged-in) */
static const t_wserv_command_table_row wserv_con_command_table[] =
{
{ "VERCHK" , _handle_verchk_command },
{ "LOBCOUNT" , _handle_lobcount_command },
{ "WHERETO" , _handle_whereto_command },
{ "QUIT" , _handle_quit_command },
/* state "connected" handlers (on Westwood ServServ server are not loged-in) */
static const t_wserv_command_table_row wserv_con_command_table[] =
{
{ "VERCHK", _handle_verchk_command },
{ "LOBCOUNT", _handle_lobcount_command },
{ "WHERETO", _handle_whereto_command },
{ "QUIT", _handle_quit_command },
{ NULL , NULL }
};
{ NULL, NULL }
};
extern int handle_wserv_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
t_wserv_command_table_row const *p;
extern int handle_wserv_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
t_wserv_command_table_row const *p;
for (p = wserv_con_command_table; p->wserv_command_string != NULL; p++) {
if (strcasecmp(command, p->wserv_command_string)==0) {
if (p->wserv_command_handler != NULL)
return ((p->wserv_command_handler)(conn,numparams,params,text));
}
}
return -1;
}
for (p = wserv_con_command_table; p->wserv_command_string != NULL; p++) {
if (strcasecmp(command, p->wserv_command_string) == 0) {
if (p->wserv_command_handler != NULL)
return ((p->wserv_command_handler)(conn, numparams, params, text));
}
}
return -1;
}
static int _handle_verchk_command(t_connection * conn, int numparams, char ** params, char * text)
{
char temp[MAX_IRC_MESSAGE_LEN];
t_clienttag clienttag;
char *filestring;
char const *ftphostname;
char const *ftpusername;
char const *ftppassword;
static int _handle_verchk_command(t_connection * conn, int numparams, char ** params, char * text)
{
char temp[MAX_IRC_MESSAGE_LEN];
t_clienttag clienttag;
char *filestring;
char const *ftphostname;
char const *ftpusername;
char const *ftppassword;
/**
* Heres the imput expected:
* vercheck [SKU] [version]
*
* Here is output expected for ServServ server:
* 1) Update non-existant:
* :[servername] 602 [username] :Update record non-existant
* 2) Update existant:
* :[servername] 606 [username] :[ftpserveraddr] [ftpusername] [ftppaswd] [path] [file.rtp] [newversion] [SKU] REQ
*/
/**
* Heres the imput expected:
* vercheck [SKU] [version]
*
* Here is output expected for ServServ server:
* 1) Update non-existant:
* :[servername] 602 [username] :Update record non-existant
* 2) Update existant:
* :[servername] 606 [username] :[ftpserveraddr] [ftpusername] [ftppaswd] [path] [file.rtp] [newversion] [SKU] REQ
*/
if (numparams>=2) {
clienttag = tag_sku_to_uint(std::atoi(params[0]));
if (numparams >= 2) {
clienttag = tag_sku_to_uint(std::atoi(params[0]));
if (clienttag != CLIENTTAG_WWOL_UINT)
conn_set_clienttag(conn,clienttag);
if (clienttag != CLIENTTAG_WWOL_UINT)
conn_set_clienttag(conn, clienttag);
if (filestring = autoupdate_check(ARCHTAG_WINX86_UINT, clienttag, TAG_UNKNOWN_UINT, params[1], params[0])) {
//:westwood-patch.ea.com update world96 lore3/1.003 65539_65536_6400.rtp 65539 6400 REQ
ftphostname = prefs_get_wol_autoupdate_serverhost();
ftpusername = prefs_get_wol_autoupdate_username();
ftppassword = prefs_get_wol_autoupdate_password();
snprintf(temp, sizeof(temp), ":%s %s %s %s 131075 %s REQ", ftphostname, ftpusername, ftppassword, filestring, params[0]);
irc_send(conn,RPL_UPDATE_FTP,temp);
}
else
irc_send(conn,RPL_UPDATE_NONEX,":Update record non-existant");
}
else
irc_send(conn,ERR_NEEDMOREPARAMS,"VERCHK :Not enough parameters");
return 0;
}
if (filestring = autoupdate_check(ARCHTAG_WINX86_UINT, clienttag, TAG_UNKNOWN_UINT, params[1], params[0])) {
//:westwood-patch.ea.com update world96 lore3/1.003 65539_65536_6400.rtp 65539 6400 REQ
ftphostname = prefs_get_wol_autoupdate_serverhost();
ftpusername = prefs_get_wol_autoupdate_username();
ftppassword = prefs_get_wol_autoupdate_password();
snprintf(temp, sizeof(temp), ":%s %s %s %s 131075 %s REQ", ftphostname, ftpusername, ftppassword, filestring, params[0]);
irc_send(conn, RPL_UPDATE_FTP, temp);
}
else
irc_send(conn, RPL_UPDATE_NONEX, ":Update record non-existant");
}
else
irc_send(conn, ERR_NEEDMOREPARAMS, "VERCHK :Not enough parameters");
return 0;
}
static int _handle_lobcount_command(t_connection * conn, int numparams, char ** params, char * text)
{
/* Ignore command but, return 1 */
irc_send(conn,RPL_LOBCOUNT,"1");
static int _handle_lobcount_command(t_connection * conn, int numparams, char ** params, char * text)
{
/* Ignore command but, return 1 */
irc_send(conn, RPL_LOBCOUNT, "1");
return 0;
}
return 0;
}
static int _handle_whereto_command(t_connection * conn, int numparams, char ** params, char * text)
{
char temp[MAX_IRC_MESSAGE_LEN];
static int _handle_whereto_command(t_connection * conn, int numparams, char ** params, char * text)
{
char temp[MAX_IRC_MESSAGE_LEN];
/* Casted to avoid warnings */
const char * wolip;
const char * wolname = prefs_get_servername();
const char * woltimezone = prefs_get_wol_timezone();
const char * wollong = prefs_get_wol_longitude();
const char * wollat = prefs_get_wol_latitude();
/* Casted to avoid warnings */
const char * wolip;
const char * wolname = prefs_get_servername();
const char * woltimezone = prefs_get_wol_timezone();
const char * wollong = prefs_get_wol_longitude();
const char * wollat = prefs_get_wol_latitude();
{ /* trans support */
unsigned short port = conn_get_real_local_port(conn);
unsigned int addr = conn_get_real_local_addr(conn);
{ /* trans support */
unsigned short port = conn_get_real_local_port(conn);
unsigned int addr = conn_get_real_local_addr(conn);
trans_net(conn_get_addr(conn), &addr, &port);
trans_net(conn_get_addr(conn), &addr, &port);
wolip = addr_num_to_ip_str(addr);
}
wolip = addr_num_to_ip_str(addr);
}
//irc_send(conn,RPL_UPDATE_EXIST,":You must update before connecting!");
//irc_send(conn,RPL_UPDATE_EXIST,":You must update before connecting!");
// Check if it's an allowed client type
if (!tag_check_in_list(conn_get_clienttag(conn), prefs_get_allowed_clients())) {
// This is for anyone game but not for Emperor
if (conn_get_clienttag(conn) != CLIENTTAG_EMPERORBD_UINT) {
// a.xwis.net 4009 RA2
// c.xwis.net 4000 TSUN
// c.xwis.net 4010 RNGD
// a.xwis.net 4010 YURI
// snprintf(temp, sizeof(temp), ":a.xwis.net 4009 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat);
// snprintf(temp, sizeof(temp), ":c.xwis.net 4000 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat);
// snprintf(temp, sizeof(temp), ":c.xwis.net 4010 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat);
// snprintf(temp, sizeof(temp), ":a.xwis.net 4010 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat);
snprintf(temp, sizeof(temp), ":%s %d '0:%s' %s %s %s", wolip, BNETD_WOLV2_PORT, wolname, woltimezone, wollong, wollat);
irc_send(conn,RPL_WOLSERV,temp);
}
// Check if it's an allowed client type
if (!tag_check_in_list(conn_get_clienttag(conn), prefs_get_allowed_clients())) {
// This is for anyone game but not for Emperor
if (conn_get_clienttag(conn) != CLIENTTAG_EMPERORBD_UINT) {
// a.xwis.net 4009 RA2
// c.xwis.net 4000 TSUN
// c.xwis.net 4010 RNGD
// a.xwis.net 4010 YURI
// snprintf(temp, sizeof(temp), ":a.xwis.net 4009 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat);
// snprintf(temp, sizeof(temp), ":c.xwis.net 4000 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat);
// snprintf(temp, sizeof(temp), ":c.xwis.net 4010 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat);
// snprintf(temp, sizeof(temp), ":a.xwis.net 4010 '0:%s' %s %s %s", wolname, woltimezone, wollong, wollat);
snprintf(temp, sizeof(temp), ":%s %d '0:%s' %s %s %s", wolip, BNETD_WOLV2_PORT, wolname, woltimezone, wollong, wollat);
irc_send(conn, RPL_WOLSERV, temp);
}
// Only for Emperor: Battle for Dune
if (conn_get_clienttag(conn) == CLIENTTAG_EMPERORBD_UINT) {
snprintf(temp, sizeof(temp), ":%s %d '0:Emperor %s' %s %s %s", wolip, BNETD_WOLV2_PORT, wolname, woltimezone, wollong, wollat);
irc_send(conn,RPL_WOLSERV,temp);
}
// Only for Emperor: Battle for Dune
if (conn_get_clienttag(conn) == CLIENTTAG_EMPERORBD_UINT) {
snprintf(temp, sizeof(temp), ":%s %d '0:Emperor %s' %s %s %s", wolip, BNETD_WOLV2_PORT, wolname, woltimezone, wollong, wollat);
irc_send(conn, RPL_WOLSERV, temp);
}
// Only for CnC Renegade
if ((conn_get_clienttag(conn) == CLIENTTAG_RENEGADE_UINT) || (conn_get_clienttag(conn) == CLIENTTAG_RENGDFDS_UINT)) {
snprintf(temp, sizeof(temp), ":%s 0 'Ping server' %s %s %s", wolip, woltimezone, wollong, wollat);
irc_send(conn,RPL_PINGSERVER,temp);
//I dont know for what is this server...? (used in renegade and yuri)
//snprintf(temp, sizeof(temp), ":%s 4321 'Port Mangler' %s %s %s", wolip, woltimezone, wollong, wollat);
//irc_send(conn,RPL_MANGLERSERV,temp);
// on official server list is for Renegade also this server:
//:noxchat1.wol.abn-sjc.ea.com 613 UserName :ea4.str.ea.com 0 '0,1,2,3,4,5,6,7,8,9,10:EA Ticket Server' -8 36.1083 -115.0582
}
// Only for CnC Renegade
if ((conn_get_clienttag(conn) == CLIENTTAG_RENEGADE_UINT) || (conn_get_clienttag(conn) == CLIENTTAG_RENGDFDS_UINT)) {
snprintf(temp, sizeof(temp), ":%s 0 'Ping server' %s %s %s", wolip, woltimezone, wollong, wollat);
irc_send(conn, RPL_PINGSERVER, temp);
//I dont know for what is this server...? (used in renegade and yuri)
//snprintf(temp, sizeof(temp), ":%s 4321 'Port Mangler' %s %s %s", wolip, woltimezone, wollong, wollat);
//irc_send(conn,RPL_MANGLERSERV,temp);
// on official server list is for Renegade also this server:
//:noxchat1.wol.abn-sjc.ea.com 613 UserName :ea4.str.ea.com 0 '0,1,2,3,4,5,6,7,8,9,10:EA Ticket Server' -8 36.1083 -115.0582
}
// There are servers for anyone game
// FIXME: Check if is WOLv1 supported
snprintf(temp, sizeof(temp), ":%s %d 'Live chat server' %s %s %s", wolip, BNETD_WOLV1_PORT, woltimezone, wollong, wollat);
irc_send(conn,RPL_WOLSERV,temp);
}
// There are servers for anyone game
// FIXME: Check if is WOLv1 supported
snprintf(temp, sizeof(temp), ":%s %d 'Live chat server' %s %s %s", wolip, BNETD_WOLV1_PORT, woltimezone, wollong, wollat);
irc_send(conn, RPL_WOLSERV, temp);
}
// If game is not allowed than we still send this servers
snprintf(temp, sizeof(temp), ":%s %d 'Gameres server' %s %s %s", wolip, BNETD_WGAMERES_PORT, woltimezone, wollong, wollat);
irc_send(conn,RPL_GAMERESSERV,temp);
snprintf(temp, sizeof(temp), ":%s %d 'Ladder server' %s %s %s", wolip, BNETD_WOLV2_PORT, woltimezone, wollong, wollat);
irc_send(conn,RPL_LADDERSERV,temp);
// There is Word Domination Tour server for Firestorm (maybe for future coding)
//snprintf(temp, sizeof(temp), ":%s %d 'WDT server' %s %s %s", wolip, BNETD_WOLV2_PORT, woltimezone, wollong, wollat); //I dont know for what is this server...?
//irc_send(conn,RPL_WDTSERV,temp);
// If game is not allowed than we still send this servers
snprintf(temp, sizeof(temp), ":%s %d 'Gameres server' %s %s %s", wolip, BNETD_WGAMERES_PORT, woltimezone, wollong, wollat);
irc_send(conn, RPL_GAMERESSERV, temp);
snprintf(temp, sizeof(temp), ":%s %d 'Ladder server' %s %s %s", wolip, BNETD_WOLV2_PORT, woltimezone, wollong, wollat);
irc_send(conn, RPL_LADDERSERV, temp);
// There is Word Domination Tour server for Firestorm (maybe for future coding)
//snprintf(temp, sizeof(temp), ":%s %d 'WDT server' %s %s %s", wolip, BNETD_WOLV2_PORT, woltimezone, wollong, wollat); //I dont know for what is this server...?
//irc_send(conn,RPL_WDTSERV,temp);
return 0;
}
return 0;
}
static int _handle_quit_command(t_connection * conn, int numparams, char ** params, char * text)
{
irc_send(conn,RPL_QUIT,":goodbye");
conn_set_state(conn, conn_state_destroy);
static int _handle_quit_command(t_connection * conn, int numparams, char ** params, char * text)
{
irc_send(conn, RPL_QUIT, ":goodbye");
conn_set_state(conn, conn_state_destroy);
return 0;
}
}
return 0;
}
}
}

View file

@ -28,12 +28,12 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int handle_wserv_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_wserv_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
}
}
}

View file

@ -25,17 +25,17 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef int (* t_handler)(t_connection *, t_packet const * const);
typedef int(*t_handler)(t_connection *, t_packet const * const);
typedef struct {
int type;
t_handler handler;
} t_htable_row;
typedef struct {
int type;
t_handler handler;
} t_htable_row;
}
}
}

View file

@ -36,189 +36,189 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
static std::FILE* hfd=NULL; /* helpfile descriptor */
static std::FILE* hfd = NULL; /* helpfile descriptor */
static int list_commands(t_connection *);
static int describe_command(t_connection *, char const *);
static int list_commands(t_connection *);
static int describe_command(t_connection *, char const *);
extern int helpfile_init(char const *filename)
{
if (!filename)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename");
return -1;
}
if (!(hfd = std::fopen(filename,"r")))
{
eventlog(eventlog_level_error,__FUNCTION__,"could not open help file \"%s\" for reading (std::fopen: %s)",filename,std::strerror(errno));
return -1;
}
return 0;
}
extern int helpfile_unload(void)
{
if (hfd!=NULL)
{
if (std::fclose(hfd)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not close help file after reading (std::fclose: %s)",std::strerror(errno));
hfd = NULL;
}
return 0;
}
extern int handle_help_command(t_connection * c, char const * text)
{
unsigned int i,j;
char comm[MAX_COMMAND_LEN];
if (hfd == NULL)
{ /* an error ocured opening readonly the help file, helpfile_unload was called, or helpfile_init hasn't been called */
message_send_text(c,message_type_error,c,"Oops ! There is a problem with the help file. Please contact the administrator of the server.");
return 0;
}
std::rewind(hfd);
for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
for (; text[i]==' '; i++);
if (text[i]=='/') /* skip / in front of command (if present) */
i++;
for (j=0; text[i]!=' ' && text[i]!='\0'; i++) /* get comm */
if (j<sizeof(comm)-1) comm[j++] = text[i];
comm[j] = '\0';
/* just read the whole file and dump only the commands */
if (comm[0]=='\0')
{
list_commands(c);
return 0;
}
if (describe_command(c,comm)==0) return 0;
/* no description was found for this command. inform the user */
message_send_text(c,message_type_error,c," no help available for that command");
return 0;
}
static int list_commands(t_connection * c)
{
char * line;
int i;
message_send_text(c,message_type_info,c,"Chat commands:");
while ((line=file_get_line(hfd))!=NULL)
{
for (i=0;line[i]==' ' && line[i]!='\0';i++); /* skip spaces in front of %command */
if (line[i]=='%') /* is this a command ? */
{
char *p,*buffer;
int al;
int skip;
unsigned int length,position;
/* ok. now we must see if there are any aliases */
length=MAX_COMMAND_LEN+1; position=0;
buffer=(char*)xmalloc(length+1); /* initial memory allocation = pretty fair */
p=line+i;
do
{
al=0;
skip = 0;
for (i=1;p[i]!=' ' && p[i]!='\0' && p[i]!='#';i++); /* skip command */
if (p[i]==' ') al=1; /* we have something after the command.. must remember that */
p[i]='\0'; /* end the string at the end of the command */
p[0]='/'; /* change the leading character (% or space) read from the help file to / */
if (!(command_get_group(p) & account_get_command_groups(conn_get_account(c)))) skip=1;
if (length<std::strlen(p)+position+1)
/* if we don't have enough space in the buffer then get some */
length=std::strlen(p)+position+1; /* the new length */
buffer=(char*)xrealloc(buffer,length+1);
buffer[position++]=' '; /* put a space before each alias */
/* add the alias to the output string */
std::strcpy(buffer+position,p); position+=std::strlen(p);
if (al)
extern int helpfile_init(char const *filename)
{
for (;p[i+1]==' ' && p[i+1]!='\0' && p[i+1]!='#';i++); /* skip spaces */
if (p[i+1]=='\0' || p[i+1]=='#')
{
al=0; continue;
}
p+=i; /* jump to the next command */
}
} while (al);
if (!skip) message_send_text(c,message_type_info,c,buffer); /* print out the buffer */
xfree(buffer);
}
}
file_get_line(NULL); // clear file_get_line buffer
return 0;
}
static int describe_command(t_connection * c, char const * comm)
{
char * line;
int i;
/* ok. the client requested help for a specific command */
while ((line=file_get_line(hfd))!=NULL)
{
for (i=0;line[i]==' ' && line[i]!='\0';i++); /* skip spaces in front of %command */
if (line[i]=='%') /* is this a command ? */
{
char *p;
int al;
/* ok. now we must see if there are any aliases */
p=line+i;
do
{
al=0;
for (i=1;p[i]!=' ' && p[i]!='\0' && p[i]!='#';i++); /* skip command */
if (p[i]==' ') al=1; /* we have something after the command.. must remember that */
p[i]='\0'; /* end the string at the end of the command */
if (strcasecmp(comm,p+1)==0) /* is this the command the user asked for help ? */
{
while ((line=file_get_line(hfd))!=NULL)
{ /* write everything until we get another % or EOF */
for (i=0;line[i]==' ';i++); /* skip spaces in front of a possible % */
if (line[i]=='%')
if (!filename)
{
break; /* we reached another command */
}
if (line[0]!='#')
{ /* is this a whole line comment ? */
/* truncate the line when a comment starts */
for (;line[i]!='\0' && line[i]!='#';i++);
if (line[i]=='#') line[i]='\0';
message_send_text(c,message_type_info,c,line);
}
}
return 0;
}
if (al)
eventlog(eventlog_level_error, __FUNCTION__, "got NULL filename");
return -1;
}
if (!(hfd = std::fopen(filename, "r")))
{
eventlog(eventlog_level_error, __FUNCTION__, "could not open help file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno));
return -1;
}
return 0;
}
extern int helpfile_unload(void)
{
for (;p[i+1]==' ' && p[i+1]!='\0';i++); /* skip spaces */
if (p[i+1]=='\0')
{
al=0; continue;
}
p+=i; /* jump to the next command */
}
} while (al);
}
}
file_get_line(NULL); // clear file_get_line buffer
if (hfd != NULL)
{
if (std::fclose(hfd) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not close help file after reading (std::fclose: %s)", std::strerror(errno));
hfd = NULL;
}
return 0;
}
return -1;
}
}
extern int handle_help_command(t_connection * c, char const * text)
{
unsigned int i, j;
char comm[MAX_COMMAND_LEN];
if (hfd == NULL)
{ /* an error ocured opening readonly the help file, helpfile_unload was called, or helpfile_init hasn't been called */
message_send_text(c, message_type_error, c, "Oops ! There is a problem with the help file. Please contact the administrator of the server.");
return 0;
}
std::rewind(hfd);
for (i = 0; text[i] != ' ' && text[i] != '\0'; i++); /* skip command */
for (; text[i] == ' '; i++);
if (text[i] == '/') /* skip / in front of command (if present) */
i++;
for (j = 0; text[i] != ' ' && text[i] != '\0'; i++) /* get comm */
if (j < sizeof(comm)-1) comm[j++] = text[i];
comm[j] = '\0';
/* just read the whole file and dump only the commands */
if (comm[0] == '\0')
{
list_commands(c);
return 0;
}
if (describe_command(c, comm) == 0) return 0;
/* no description was found for this command. inform the user */
message_send_text(c, message_type_error, c, " no help available for that command");
return 0;
}
static int list_commands(t_connection * c)
{
char * line;
int i;
message_send_text(c, message_type_info, c, "Chat commands:");
while ((line = file_get_line(hfd)) != NULL)
{
for (i = 0; line[i] == ' ' && line[i] != '\0'; i++); /* skip spaces in front of %command */
if (line[i] == '%') /* is this a command ? */
{
char *p, *buffer;
int al;
int skip;
unsigned int length, position;
/* ok. now we must see if there are any aliases */
length = MAX_COMMAND_LEN + 1; position = 0;
buffer = (char*)xmalloc(length + 1); /* initial memory allocation = pretty fair */
p = line + i;
do
{
al = 0;
skip = 0;
for (i = 1; p[i] != ' ' && p[i] != '\0' && p[i] != '#'; i++); /* skip command */
if (p[i] == ' ') al = 1; /* we have something after the command.. must remember that */
p[i] = '\0'; /* end the string at the end of the command */
p[0] = '/'; /* change the leading character (% or space) read from the help file to / */
if (!(command_get_group(p) & account_get_command_groups(conn_get_account(c)))) skip = 1;
if (length < std::strlen(p) + position + 1)
/* if we don't have enough space in the buffer then get some */
length = std::strlen(p) + position + 1; /* the new length */
buffer = (char*)xrealloc(buffer, length + 1);
buffer[position++] = ' '; /* put a space before each alias */
/* add the alias to the output string */
std::strcpy(buffer + position, p); position += std::strlen(p);
if (al)
{
for (; p[i + 1] == ' ' && p[i + 1] != '\0' && p[i + 1] != '#'; i++); /* skip spaces */
if (p[i + 1] == '\0' || p[i + 1] == '#')
{
al = 0; continue;
}
p += i; /* jump to the next command */
}
} while (al);
if (!skip) message_send_text(c, message_type_info, c, buffer); /* print out the buffer */
xfree(buffer);
}
}
file_get_line(NULL); // clear file_get_line buffer
return 0;
}
static int describe_command(t_connection * c, char const * comm)
{
char * line;
int i;
/* ok. the client requested help for a specific command */
while ((line = file_get_line(hfd)) != NULL)
{
for (i = 0; line[i] == ' ' && line[i] != '\0'; i++); /* skip spaces in front of %command */
if (line[i] == '%') /* is this a command ? */
{
char *p;
int al;
/* ok. now we must see if there are any aliases */
p = line + i;
do
{
al = 0;
for (i = 1; p[i] != ' ' && p[i] != '\0' && p[i] != '#'; i++); /* skip command */
if (p[i] == ' ') al = 1; /* we have something after the command.. must remember that */
p[i] = '\0'; /* end the string at the end of the command */
if (strcasecmp(comm, p + 1) == 0) /* is this the command the user asked for help ? */
{
while ((line = file_get_line(hfd)) != NULL)
{ /* write everything until we get another % or EOF */
for (i = 0; line[i] == ' '; i++); /* skip spaces in front of a possible % */
if (line[i] == '%')
{
break; /* we reached another command */
}
if (line[0] != '#')
{ /* is this a whole line comment ? */
/* truncate the line when a comment starts */
for (; line[i] != '\0' && line[i] != '#'; i++);
if (line[i] == '#') line[i] = '\0';
message_send_text(c, message_type_info, c, line);
}
}
return 0;
}
if (al)
{
for (; p[i + 1] == ' ' && p[i + 1] != '\0'; i++); /* skip spaces */
if (p[i + 1] == '\0')
{
al = 0; continue;
}
p += i; /* jump to the next command */
}
} while (al);
}
}
file_get_line(NULL); // clear file_get_line buffer
return -1;
}
}
}

View file

@ -30,14 +30,14 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int helpfile_init(char const * filename);
extern int helpfile_unload(void);
extern int handle_help_command(t_connection *, char const *);
extern int helpfile_init(char const * filename);
extern int helpfile_unload(void);
extern int handle_help_command(t_connection *, char const *);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -38,29 +38,29 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef enum
{
ipban_type_exact, /* 192.168.0.10 */
ipban_type_wildcard, /* 192.168.*.* */
ipban_type_range, /* 192.168.0.10-192.168.0.25 */
ipban_type_netmask, /* 192.168.0.0/255.255.0.0 */
ipban_type_prefix /* 192.168.0.0/16 */
} t_ipban_type;
typedef enum
{
ipban_type_exact, /* 192.168.0.10 */
ipban_type_wildcard, /* 192.168.*.* */
ipban_type_range, /* 192.168.0.10-192.168.0.25 */
ipban_type_netmask, /* 192.168.0.0/255.255.0.0 */
ipban_type_prefix /* 192.168.0.0/16 */
} t_ipban_type;
typedef struct ipban_entry_struct
{
char * info1; /* third octet */
char * info2; /* third octet */
char * info3; /* third octet */
char * info4; /* fourth octet */
int type;
std::time_t endtime;
} t_ipban_entry;
typedef struct ipban_entry_struct
{
char * info1; /* third octet */
char * info2; /* third octet */
char * info3; /* third octet */
char * info4; /* fourth octet */
int type;
std::time_t endtime;
} t_ipban_entry;
}
}
}
@ -83,20 +83,20 @@ typedef struct ipban_entry_struct
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int ipbanlist_create(void);
extern int ipbanlist_destroy(void);
extern int ipbanlist_load(char const * filename);
extern int ipbanlist_save(char const * filename);
extern int ipbanlist_check(char const * addr);
extern int ipbanlist_add(t_connection * c, char const * cp, std::time_t endtime);
extern int ipbanlist_unload_expired(void);
extern std::time_t ipbanlist_str_to_time_t(t_connection * c, char const * timestr);
extern int handle_ipban_command(t_connection * c, char const * text);
extern int ipbanlist_create(void);
extern int ipbanlist_destroy(void);
extern int ipbanlist_load(char const * filename);
extern int ipbanlist_save(char const * filename);
extern int ipbanlist_check(char const * addr);
extern int ipbanlist_add(t_connection * c, char const * cp, std::time_t endtime);
extern int ipbanlist_unload_expired(void);
extern std::time_t ipbanlist_str_to_time_t(t_connection * c, char const * timestr);
extern int handle_ipban_command(t_connection * c, char const * text);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -31,37 +31,37 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int irc_send_cmd(t_connection * conn, char const * command, char const * params);
extern int irc_send(t_connection * conn, int code, char const * params);
extern int irc_send_ping(t_connection * conn);
extern int irc_send_pong(t_connection * conn, char const * params);
extern int irc_authenticate(t_connection * conn, char const * passhash);
extern char const * irc_convert_channel(t_channel const * channel, t_connection * c);
extern char const * irc_convert_ircname(char const * pircname);
extern char ** irc_get_listelems(char * list);
extern int irc_unget_listelems(char ** elems);
extern char ** irc_get_paramelems(char * list);
extern char ** irc_get_ladderelems(char * list);
extern int irc_unget_ladderelems(char ** elems);
extern int irc_unget_paramelems(char ** elems);
extern int irc_message_postformat(t_packet * packet, t_connection const * dest);
extern int irc_message_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags);
extern int irc_send_rpl_namreply(t_connection * c, t_channel const * channel);
extern int irc_who(t_connection * c, char const * name);
extern int irc_send_motd(t_connection * conn);
extern int _handle_nick_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_ping_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_pong_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_join_command(t_connection * conn, int numparams, char ** params, char * text);
extern int irc_send_topic(t_connection * c, t_channel const * channel);
extern int _handle_topic_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_kick_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_mode_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_time_command(t_connection * conn, int numparams, char ** params, char * text);
}
extern int irc_send_cmd(t_connection * conn, char const * command, char const * params);
extern int irc_send(t_connection * conn, int code, char const * params);
extern int irc_send_ping(t_connection * conn);
extern int irc_send_pong(t_connection * conn, char const * params);
extern int irc_authenticate(t_connection * conn, char const * passhash);
extern char const * irc_convert_channel(t_channel const * channel, t_connection * c);
extern char const * irc_convert_ircname(char const * pircname);
extern char ** irc_get_listelems(char * list);
extern int irc_unget_listelems(char ** elems);
extern char ** irc_get_paramelems(char * list);
extern char ** irc_get_ladderelems(char * list);
extern int irc_unget_ladderelems(char ** elems);
extern int irc_unget_paramelems(char ** elems);
extern int irc_message_postformat(t_packet * packet, t_connection const * dest);
extern int irc_message_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags);
extern int irc_send_rpl_namreply(t_connection * c, t_channel const * channel);
extern int irc_who(t_connection * c, char const * name);
extern int irc_send_motd(t_connection * conn);
extern int _handle_nick_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_ping_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_pong_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_join_command(t_connection * conn, int numparams, char ** params, char * text);
extern int irc_send_topic(t_connection * c, t_channel const * channel);
extern int _handle_topic_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_kick_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_mode_command(t_connection * conn, int numparams, char ** params, char * text);
extern int _handle_time_command(t_connection * conn, int numparams, char ** params, char * text);
}
}

File diff suppressed because it is too large Load diff

View file

@ -32,187 +32,187 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef enum
{
ladder_sort_highestrated,
ladder_sort_mostwins,
ladder_sort_mostgames,
ladder_sort_default
} t_ladder_sort;
typedef enum
{
ladder_sort_highestrated,
ladder_sort_mostwins,
ladder_sort_mostgames,
ladder_sort_default
} t_ladder_sort;
extern const char * bin_ladder_sort_str[];
extern const char * bin_ladder_sort_str[];
typedef enum
{
ladder_time_active,
ladder_time_current,
ladder_time_default
} t_ladder_time;
typedef enum
{
ladder_time_active,
ladder_time_current,
ladder_time_default
} t_ladder_time;
extern const char * bin_ladder_time_str[];
extern const char * bin_ladder_time_str[];
typedef enum
{
ladder_id_none=0,
ladder_id_normal=1,
ladder_id_ironman=3,
ladder_id_solo=5,
ladder_id_team=6,
ladder_id_ffa=7,
ladder_id_ateam=8
} t_ladder_id;
typedef enum
{
ladder_id_none = 0,
ladder_id_normal = 1,
ladder_id_ironman = 3,
ladder_id_solo = 5,
ladder_id_team = 6,
ladder_id_ffa = 7,
ladder_id_ateam = 8
} t_ladder_id;
const extern char * ladder_id_str[];
const extern char * bin_ladder_id_str[];
const extern char * ladder_id_str[];
const extern char * bin_ladder_id_str[];
typedef enum
{
ladder_option_none=0,
ladder_option_disconnectisloss=1
} t_ladder_option;
typedef enum
{
ladder_option_none = 0,
ladder_option_disconnectisloss = 1
} t_ladder_option;
typedef enum { referenceTypeAccount, referenceTypeTeam, referenceTypeClan } t_referenceType;
typedef enum { referenceTypeAccount, referenceTypeTeam, referenceTypeClan } t_referenceType;
class LadderKey
{
public:
LadderKey(t_ladder_id ladderId_, t_clienttag clienttag_, t_ladder_sort ladderSort_, t_ladder_time ladderTime_);
~LadderKey() throw ();
bool operator== (const LadderKey& right) const;
bool operator< (const LadderKey& right) const;
t_ladder_id getLadderId() const;
t_clienttag getClienttag() const;
t_ladder_sort getLadderSort() const;
t_ladder_time getLadderTime() const;
LadderKey getOpposingKey() const;
private:
t_ladder_id ladderId;
t_clienttag clienttag;
t_ladder_sort ladderSort;
t_ladder_time ladderTime;
};
class LadderReferencedObject
{
public:
explicit LadderReferencedObject(t_account *account_);
explicit LadderReferencedObject(t_team *team_);
~LadderReferencedObject() throw ();
bool getData(const LadderKey& ladderKey_, unsigned int& uid, unsigned int& primary_, unsigned int& secondary_, unsigned int& tertiary_) const;
unsigned int getRank(const LadderKey& ladderKey_) const;
bool setRank(const LadderKey& ladderKey_, unsigned int rank_) const;
t_account* getAccount() const;
t_team* getTeam() const;
void activate(const LadderKey& ladderKey_) const;
const t_referenceType getReferenceType() const;
private:
class LadderKey
{
public:
LadderKey(t_ladder_id ladderId_, t_clienttag clienttag_, t_ladder_sort ladderSort_, t_ladder_time ladderTime_);
~LadderKey() throw ();
bool operator== (const LadderKey& right) const;
bool operator< (const LadderKey& right) const;
t_ladder_id getLadderId() const;
t_clienttag getClienttag() const;
t_ladder_sort getLadderSort() const;
t_ladder_time getLadderTime() const;
LadderKey getOpposingKey() const;
private:
t_ladder_id ladderId;
t_clienttag clienttag;
t_ladder_sort ladderSort;
t_ladder_time ladderTime;
};
t_referenceType referenceType;
t_account * account;
t_team * team;
};
class LadderReferencedObject
{
public:
explicit LadderReferencedObject(t_account *account_);
explicit LadderReferencedObject(t_team *team_);
~LadderReferencedObject() throw ();
bool getData(const LadderKey& ladderKey_, unsigned int& uid, unsigned int& primary_, unsigned int& secondary_, unsigned int& tertiary_) const;
unsigned int getRank(const LadderKey& ladderKey_) const;
bool setRank(const LadderKey& ladderKey_, unsigned int rank_) const;
t_account* getAccount() const;
t_team* getTeam() const;
void activate(const LadderKey& ladderKey_) const;
const t_referenceType getReferenceType() const;
private:
class LadderEntry
{
public:
LadderEntry(unsigned int uid_, unsigned int primary_, unsigned int secondary_, unsigned int tertiary_, LadderReferencedObject referencedObject_);
~LadderEntry() throw ();
unsigned int getUid() const;
unsigned int getPrimary() const;
unsigned int getSecondary() const;
unsigned int getTertiary() const;
unsigned int getRank() const;
const LadderReferencedObject& getReferencedObject() const;
bool setRank(unsigned int rank_, const LadderKey& ladderKey_);
void update(unsigned int primary_, unsigned int secondary_, unsigned int tertiary_);
std::string status() const;
bool operator== (const LadderEntry& right) const;
bool operator< (const LadderEntry& right) const;
private:
unsigned int uid;
unsigned int primary;
unsigned int secondary;
unsigned int tertiary;
unsigned int rank;
LadderReferencedObject referencedObject;
};
t_referenceType referenceType;
t_account * account;
t_team * team;
};
class LadderList
{
public:
explicit LadderList(LadderKey ladderkey_, t_referenceType referenceType_);
~LadderList() throw ();
bool load();
bool save();
void addEntry(unsigned int uid_, unsigned int primary_, unsigned int secondary_, unsigned int tertiary_, const LadderReferencedObject& referencedObject_);
void updateEntry(unsigned int uid_, unsigned int primary_, unsigned int secondary_, unsigned int tertiary_ ,const LadderReferencedObject& referencedObject_);
bool delEntry(unsigned int uid_);
const LadderKey& getLadderKey() const;
const t_referenceType getReferenceType() const;
void sortAndUpdate();
const LadderReferencedObject* getReferencedObject(unsigned int rank) const;
unsigned int getRank(unsigned int uid_) const;
void activateFrom(const LadderList * currentLadder_);
void writeStatusfile() const;
class LadderEntry
{
public:
LadderEntry(unsigned int uid_, unsigned int primary_, unsigned int secondary_, unsigned int tertiary_, LadderReferencedObject referencedObject_);
~LadderEntry() throw ();
unsigned int getUid() const;
unsigned int getPrimary() const;
unsigned int getSecondary() const;
unsigned int getTertiary() const;
unsigned int getRank() const;
const LadderReferencedObject& getReferencedObject() const;
bool setRank(unsigned int rank_, const LadderKey& ladderKey_);
void update(unsigned int primary_, unsigned int secondary_, unsigned int tertiary_);
std::string status() const;
bool operator== (const LadderEntry& right) const;
bool operator< (const LadderEntry& right) const;
private:
unsigned int uid;
unsigned int primary;
unsigned int secondary;
unsigned int tertiary;
unsigned int rank;
LadderReferencedObject referencedObject;
};
private:
typedef std::vector<LadderEntry> LList;
LadderKey ladderKey;
LList ladder;
bool dirty;
bool saved;
std::string ladderFilename;
t_referenceType referenceType;
bool loadBinary();
bool saveBinary();
void readdata(std::ifstream &fp, unsigned int &data);
void readdata(std::ifstream &fp, unsigned int data[], unsigned int membercount);
void writedata(std::ofstream &fp, unsigned int &data);
void writedata(std::ofstream &fp, const unsigned int &data);
void writedata(std::ofstream &fp, unsigned int data[], unsigned int membercount);
class LadderList
{
public:
explicit LadderList(LadderKey ladderkey_, t_referenceType referenceType_);
~LadderList() throw ();
bool load();
bool save();
void addEntry(unsigned int uid_, unsigned int primary_, unsigned int secondary_, unsigned int tertiary_, const LadderReferencedObject& referencedObject_);
void updateEntry(unsigned int uid_, unsigned int primary_, unsigned int secondary_, unsigned int tertiary_, const LadderReferencedObject& referencedObject_);
bool delEntry(unsigned int uid_);
const LadderKey& getLadderKey() const;
const t_referenceType getReferenceType() const;
void sortAndUpdate();
const LadderReferencedObject* getReferencedObject(unsigned int rank) const;
unsigned int getRank(unsigned int uid_) const;
void activateFrom(const LadderList * currentLadder_);
void writeStatusfile() const;
};
private:
typedef std::vector<LadderEntry> LList;
LadderKey ladderKey;
LList ladder;
bool dirty;
bool saved;
std::string ladderFilename;
t_referenceType referenceType;
bool loadBinary();
bool saveBinary();
void readdata(std::ifstream &fp, unsigned int &data);
void readdata(std::ifstream &fp, unsigned int data[], unsigned int membercount);
void writedata(std::ofstream &fp, unsigned int &data);
void writedata(std::ofstream &fp, const unsigned int &data);
void writedata(std::ofstream &fp, unsigned int data[], unsigned int membercount);
class Ladders
{
public:
Ladders();
~Ladders() throw ();
LadderList* getLadderList(const LadderKey& ladderKey_);
void load();
void update();
void activate();
void save();
void status() const;
private:
void rebuild(std::list<LadderList*>& laddersToRebuild);
typedef std::map<LadderKey, LadderList> KeyLadderMap;
KeyLadderMap ladderMap;
};
};
extern Ladders ladders;
class Ladders
{
public:
Ladders();
~Ladders() throw ();
LadderList* getLadderList(const LadderKey& ladderKey_);
void load();
void update();
void activate();
void save();
void status() const;
private:
void rebuild(std::list<LadderList*>& laddersToRebuild);
typedef std::map<LadderKey, LadderList> KeyLadderMap;
KeyLadderMap ladderMap;
};
extern Ladders ladders;
#ifdef LADDER_INTERNAL_ACCESS
typedef struct
{
int startxp, neededxp, lossfactor, mingames;
} t_xplevel_entry;
typedef struct
{
int startxp, neededxp, lossfactor, mingames;
} t_xplevel_entry;
typedef struct
{
int higher_winxp, higher_lossxp, lower_winxp, lower_lossxp;
} t_xpcalc_entry;
typedef struct
{
int higher_winxp, higher_lossxp, lower_winxp, lower_lossxp;
} t_xpcalc_entry;
#endif
}
}
}
@ -233,30 +233,30 @@ typedef struct
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int ladder_update(t_clienttag clienttag, t_ladder_id id, unsigned int count, t_account * * players, t_game_result * results, t_ladder_info * info);
extern int ladder_update_wol(t_clienttag clienttag, t_ladder_id id, t_account * * players, t_game_result * results);
extern int ladder_init_account(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int ladder_init_account_wol(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int ladder_update(t_clienttag clienttag, t_ladder_id id, unsigned int count, t_account * * players, t_game_result * results, t_ladder_info * info);
extern int ladder_update_wol(t_clienttag clienttag, t_ladder_id id, t_account * * players, t_game_result * results);
extern int ladder_check_map(char const * mapname, t_game_maptype maptype, t_clienttag clienttag);
extern int ladder_init_account(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int ladder_init_account_wol(t_account * account, t_clienttag clienttag, t_ladder_id id);
extern int ladder_check_map(char const * mapname, t_game_maptype maptype, t_clienttag clienttag);
extern int ladder_createxptable(const char *xplevelfile, const char *xpcalcfile);
extern void ladder_destroyxptable(void);
extern int ladder_createxptable(const char *xplevelfile, const char *xpcalcfile);
extern void ladder_destroyxptable(void);
extern int ladder_war3_xpdiff(unsigned int winnerlevel, unsigned int looserlevel, int *, int *);
extern int ladder_war3_updatelevel(unsigned int oldlevel, int xp);
extern int ladder_war3_get_min_xp(unsigned int level);
extern int war3_get_maxleveldiff(void);
extern int ladder_war3_xpdiff(unsigned int winnerlevel, unsigned int looserlevel, int *, int *);
extern int ladder_war3_updatelevel(unsigned int oldlevel, int xp);
extern int ladder_war3_get_min_xp(unsigned int level);
extern int war3_get_maxleveldiff(void);
extern void ladder_reload_conf(void);
/* reloads relevant parameters from bnetd.conf (xml/std mode for ladder) */
}
extern void ladder_reload_conf(void);
/* reloads relevant parameters from bnetd.conf (xml/std mode for ladder) */
}
}

File diff suppressed because it is too large Load diff

View file

@ -22,19 +22,19 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef struct
{
double prob;
unsigned int k;
int adj;
unsigned int oldrating;
unsigned int oldrank;
} t_ladder_info;
typedef struct
{
double prob;
unsigned int k;
int adj;
unsigned int oldrating;
unsigned int oldrank;
} t_ladder_info;
}
}
}
@ -55,12 +55,12 @@ typedef struct
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int ladder_calc_info(t_clienttag clienttag, t_ladder_id id, unsigned int count, t_account * * players, t_game_result * results, t_ladder_info * info);
extern int ladder_calc_info(t_clienttag clienttag, t_ladder_id id, unsigned int count, t_account * * players, t_game_result * results, t_ladder_info * info);
}
}
}

View file

@ -43,446 +43,452 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
static int identify_mail_function(const std::string&);
static void mail_usage(t_connection*);
static void mail_func_send(t_connection*, std::istream&);
static void mail_func_read(t_connection*, std::istream&);
static void mail_func_delete(t_connection*, std::istream&);
static unsigned get_mail_quota(t_account *);
static int identify_mail_function(const std::string&);
static void mail_usage(t_connection*);
static void mail_func_send(t_connection*, std::istream&);
static void mail_func_read(t_connection*, std::istream&);
static void mail_func_delete(t_connection*, std::istream&);
static unsigned get_mail_quota(t_account *);
/* Mail API */
/* for now this functions are only for internal use */
/* Mail API */
/* for now this functions are only for internal use */
Mail::Mail(const std::string& sender, const std::string& message, const std::time_t timestamp)
:sender_(sender), message_(message), timestamp_(timestamp)
{
}
Mail::~Mail() throw()
{
}
const std::string&
Mail::sender() const
{
return sender_;
}
const std::string&
Mail::message() const
{
return message_;
}
const std::time_t&
Mail::timestamp() const
{
return timestamp_;
}
Mailbox::Mailbox(unsigned uid_)
:uid(uid_), path(buildPath(prefs_get_maildir())), mdir(path, true)
{
}
std::string
Mailbox::buildPath(const std::string& root) const
{
std::ostringstream ostr;
ostr << root << "/" << std::setfill('0') << std::setw(6) << uid;
return ostr.str();
}
void
Mailbox::createOpenDir()
{
p_mkdir(prefs_get_maildir(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
p_mkdir(path.c_str(), S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH);
mdir.open(path, false);
}
Mailbox::~Mailbox() throw()
{
}
unsigned
Mailbox::size() const
{
mdir.rewind();
unsigned count = 0;
while ((mdir.read())) count++;
return count;
}
bool
Mailbox::empty() const
{
mdir.rewind();
if (mdir.read()) return false;
return true;
}
void
Mailbox::deliver(const std::string& sender, const std::string& mess)
{
if (!mdir)
try {
createOpenDir();
} catch(const Directory::OpenError&) {
ERROR1("could not (re)open directory: '%s'", path.c_str());
throw DeliverError("could not (re)open directory: " + path);
Mail::Mail(const std::string& sender, const std::string& message, const std::time_t timestamp)
:sender_(sender), message_(message), timestamp_(timestamp)
{
}
std::ostringstream ostr;
ostr << path << '/' << std::setfill('0') << std::setw(15) << static_cast<unsigned long>(std::time(0));
std::ofstream fd(ostr.str().c_str());
if (!fd) {
ERROR1("error opening mail file. check permissions: '%s'", path.c_str());
throw DeliverError("error opening mail file. check permissions: " + path);
}
fd << sender << std::endl << mess << std::endl;
}
Mail
Mailbox::read(const std::string& fname, const std::time_t& timestamp) const
{
std::ifstream fd(fname.c_str());
if (!fd) {
ERROR1("error opening mail file: %s", fname.c_str());
throw ReadError("error opening mail file: " + fname);
}
std::string sender;
std::getline(fd, sender);
std::string message;
std::getline(fd, message);
return Mail(sender, message, timestamp);
}
Mail
Mailbox::read(unsigned int idx) const
{
mdir.rewind();
const char * dentry = mdir.read();
for(unsigned i = 0; i < idx && (dentry = mdir.read());)
if (dentry[0] != '.') ++i;
if (!dentry) {
INFO0("mail not found");
throw ReadError("mail not found");
}
std::string fname(path);
fname += '/';
fname += dentry;
return read(fname, std::atoi(dentry));
}
void
Mailbox::readAll(MailList& dest) const
{
mdir.rewind();
std::string fname(path);
fname += '/';
const char* dentry;
while((dentry = mdir.read())) {
if (dentry[0] == '.') continue;
try {
dest.push_back(read(fname + dentry, std::atoi(dentry)));
} catch (const ReadError&) {
/* ignore ReadError in reading a specific message and try to read as much as we can */
}
}
}
void
Mailbox::erase(unsigned int idx)
{
mdir.rewind();
const char* dentry = mdir.read();
for(unsigned i = 0; i < idx && (dentry = mdir.read());)
if (dentry[0] != '.') ++i;
if (!dentry) {
WARN0("index out of range");
return;
}
std::string fname(path);
fname += '/';
fname += dentry;
if (std::remove(fname.c_str()) < 0)
INFO2("could not remove file \"%s\" (std::remove: %s)", fname.c_str(), std::strerror(errno));
}
void
Mailbox::clear()
{
std::string fname(path);
fname += '/';
mdir.rewind();
const char* dentry;
while((dentry = mdir.read())) {
std::remove((fname + dentry).c_str());
}
}
extern int handle_mail_command(t_connection * c, char const * text)
{
if (!prefs_get_mail_support()) {
message_send_text(c,message_type_error,c,"This server has NO mail support.");
return -1;
}
std::istringstream istr(text);
std::string token;
/* stkip "/mail" */
istr >> token;
/* get the mail function */
token.clear();
istr >> token;
switch (identify_mail_function(token.c_str())) {
case MAIL_FUNC_SEND:
mail_func_send(c, istr);
break;
case MAIL_FUNC_READ:
mail_func_read(c, istr);
break;
case MAIL_FUNC_DELETE:
mail_func_delete(c, istr);
break;
case MAIL_FUNC_HELP:
message_send_text(c, message_type_info, c, "The mail command supports the following patterns.");
mail_usage(c);
break;
default:
message_send_text(c, message_type_error, c, "The command its incorrect. Use one of the following patterns.");
mail_usage(c);
}
return 0;
}
static int identify_mail_function(const std::string& funcstr)
{
if (funcstr.empty() || !strcasecmp(funcstr.c_str(), "read") || !strcasecmp(funcstr.c_str(), "r"))
return MAIL_FUNC_READ;
if (!strcasecmp(funcstr.c_str(), "send") || !strcasecmp(funcstr.c_str(), "s"))
return MAIL_FUNC_SEND;
if (!strcasecmp(funcstr.c_str(), "delete") || !strcasecmp(funcstr.c_str(), "del"))
return MAIL_FUNC_DELETE;
if (!strcasecmp(funcstr.c_str(), "help") || !strcasecmp(funcstr.c_str(), "h"))
return MAIL_FUNC_HELP;
return MAIL_FUNC_UNKNOWN;
}
static unsigned get_mail_quota(t_account * user)
{
int quota;
char const * user_quota = account_get_strattr(user,"BNET\\auth\\mailquota");
if (!user_quota) quota = prefs_get_mail_quota();
else {
quota = std::atoi(user_quota);
if (quota < 1) quota=1;
if (quota > MAX_MAIL_QUOTA) quota = MAX_MAIL_QUOTA;
}
return quota;
}
static void mail_func_send(t_connection * c, std::istream& istr)
{
if (!c) {
ERROR0("got NULL connection");
return;
}
std::string dest;
istr >> dest;
if (dest.empty()) {
message_send_text(c,message_type_error,c,"You must specify the receiver");
message_send_text(c,message_type_error,c,"Syntax: /mail send <receiver> <message>");
return;
}
std::string message;
std::getline(istr, message);
std::string::size_type pos(message.find_first_not_of(" \t"));
if (pos == std::string::npos) {
message_send_text(c,message_type_error,c,"Your message is empty!");
message_send_text(c,message_type_error,c,"Syntax: /mail send <receiver> <message>");
return;
}
t_account * recv = accountlist_find_account(dest.c_str());
if (!recv) {
message_send_text(c,message_type_error,c,"Receiver UNKNOWN!");
return;
}
Mailbox mbox(account_get_uid(recv));
if (get_mail_quota(recv) <= mbox.size()) {
message_send_text(c,message_type_error,c,"Receiver has reached his mail quota. Your message will NOT be sent.");
return;
}
try {
mbox.deliver(conn_get_username(c), message.substr(pos));
message_send_text(c, message_type_info, c, "Your mail has been sent successfully.");
} catch (const Mailbox::DeliverError&) {
message_send_text(c,message_type_error,c,"There was an error completing your request!");
}
}
bool NonNumericChar(const char ch)
{
if (ch < '0' || ch > '9') return true;
return false;
}
static void mail_func_read(t_connection * c, std::istream& istr)
{
if (!c) {
ERROR0("got NULL connection");
return;
}
std::string token;
istr >> token;
t_account * user = conn_get_account(c);
Mailbox mbox(account_get_uid(user));
if (token.empty()) { /* user wants to see the mail summary */
if (mbox.empty()) {
message_send_text(c,message_type_info,c,"You have no mail.");
return;
Mail::~Mail() throw()
{
}
MailList mlist;
mbox.readAll(mlist);
const std::string&
Mail::sender() const
{
return sender_;
}
std::ostringstream ostr;
ostr << "You have " << mbox.size() << " messages. Your mail quote is set to " << get_mail_quota(user) << '.';
message_send_text(c, message_type_info, c, ostr.str().c_str());
message_send_text(c, message_type_info, c, "ID Sender Date");
message_send_text(c, message_type_info, c, "-------------------------------------");
const std::string&
Mail::message() const
{
return message_;
}
for(MailList::const_iterator it(mlist.begin()); it != mlist.end(); ++it) {
ostr.str("");
ostr << std::setfill('0') << std::setw(2) << std::right << (it - mlist.begin()) << " "
<< std::setfill(' ') << std::setw(14) << std::left << it->sender() << ' ';
char buff[128];
std::strftime(buff, sizeof(buff), "%a %b %d %H:%M:%S %Y", std::localtime(&it->timestamp()));
ostr << buff;
message_send_text(c, message_type_info, c, ostr.str().c_str());
const std::time_t&
Mail::timestamp() const
{
return timestamp_;
}
Mailbox::Mailbox(unsigned uid_)
:uid(uid_), path(buildPath(prefs_get_maildir())), mdir(path, true)
{
}
message_send_text(c,message_type_info,c,"Use /mail read <ID> to read the content of any message");
} else { /* user wants to read a message */
if (std::find_if(token.begin(), token.end(), NonNumericChar) != token.end()) {
message_send_text(c,message_type_error,c,"Invalid index. Please use /mail read <index> where <index> is a number.");
return;
std::string
Mailbox::buildPath(const std::string& root) const
{
std::ostringstream ostr;
ostr << root << "/" << std::setfill('0') << std::setw(6) << uid;
return ostr.str();
}
void
Mailbox::createOpenDir()
{
p_mkdir(prefs_get_maildir(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
p_mkdir(path.c_str(), S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH);
mdir.open(path, false);
}
Mailbox::~Mailbox() throw()
{
}
try {
unsigned idx = std::atoi(token.c_str());
Mail mail(mbox.read(idx));
unsigned
Mailbox::size() const
{
mdir.rewind();
std::ostringstream ostr;
ostr << "Message #" << idx << " from " << mail.sender() << " on ";
char buff[128];
std::strftime(buff, sizeof(buff), "%a %b %d %H:%M:%S %Y", std::localtime(&mail.timestamp()));
ostr << buff << ':';
message_send_text(c, message_type_info, c, ostr.str().c_str());
message_send_text(c, message_type_info, c, mail.message().c_str());
} catch (const Mailbox::ReadError&) {
message_send_text(c,message_type_error,c,"There was an error completing your request.");
}
}
}
unsigned count = 0;
while ((mdir.read())) count++;
return count;
}
static void mail_func_delete(t_connection * c, std::istream& istr)
{
if (!c) {
ERROR0("got NULL connection");
return;
}
bool
Mailbox::empty() const
{
mdir.rewind();
std::string token;
istr >> token;
if (mdir.read()) return false;
return true;
}
if (token.empty()) {
message_send_text(c,message_type_error,c,"Please specify which message to delete. Use the following syntax: /mail delete {<index>|all} .");
return;
}
void
Mailbox::deliver(const std::string& sender, const std::string& mess)
{
if (!mdir)
try {
createOpenDir();
}
catch (const Directory::OpenError&) {
ERROR1("could not (re)open directory: '%s'", path.c_str());
throw DeliverError("could not (re)open directory: " + path);
}
t_account * user = conn_get_account(c);
Mailbox mbox(account_get_uid(user));
std::ostringstream ostr;
ostr << path << '/' << std::setfill('0') << std::setw(15) << static_cast<unsigned long>(std::time(0));
if (token == "all") {
mbox.clear();
message_send_text(c, message_type_info, c, "Successfully deleted messages.");
} else {
if (std::find_if(token.begin(), token.end(), NonNumericChar) != token.end()) {
message_send_text(c,message_type_error,c,"Invalid index. Please use /mail delete {<index>|all} where <index> is a number.");
return;
std::ofstream fd(ostr.str().c_str());
if (!fd) {
ERROR1("error opening mail file. check permissions: '%s'", path.c_str());
throw DeliverError("error opening mail file. check permissions: " + path);
}
fd << sender << std::endl << mess << std::endl;
}
Mail
Mailbox::read(const std::string& fname, const std::time_t& timestamp) const
{
std::ifstream fd(fname.c_str());
if (!fd) {
ERROR1("error opening mail file: %s", fname.c_str());
throw ReadError("error opening mail file: " + fname);
}
std::string sender;
std::getline(fd, sender);
std::string message;
std::getline(fd, message);
return Mail(sender, message, timestamp);
}
Mail
Mailbox::read(unsigned int idx) const
{
mdir.rewind();
const char * dentry = mdir.read();
for (unsigned i = 0; i < idx && (dentry = mdir.read());)
if (dentry[0] != '.') ++i;
if (!dentry) {
INFO0("mail not found");
throw ReadError("mail not found");
}
std::string fname(path);
fname += '/';
fname += dentry;
return read(fname, std::atoi(dentry));
}
void
Mailbox::readAll(MailList& dest) const
{
mdir.rewind();
std::string fname(path);
fname += '/';
const char* dentry;
while ((dentry = mdir.read())) {
if (dentry[0] == '.') continue;
try {
dest.push_back(read(fname + dentry, std::atoi(dentry)));
}
catch (const ReadError&) {
/* ignore ReadError in reading a specific message and try to read as much as we can */
}
}
}
void
Mailbox::erase(unsigned int idx)
{
mdir.rewind();
const char* dentry = mdir.read();
for (unsigned i = 0; i < idx && (dentry = mdir.read());)
if (dentry[0] != '.') ++i;
if (!dentry) {
WARN0("index out of range");
return;
}
std::string fname(path);
fname += '/';
fname += dentry;
if (std::remove(fname.c_str()) < 0)
INFO2("could not remove file \"%s\" (std::remove: %s)", fname.c_str(), std::strerror(errno));
}
void
Mailbox::clear()
{
std::string fname(path);
fname += '/';
mdir.rewind();
const char* dentry;
while ((dentry = mdir.read())) {
std::remove((fname + dentry).c_str());
}
}
extern int handle_mail_command(t_connection * c, char const * text)
{
if (!prefs_get_mail_support()) {
message_send_text(c, message_type_error, c, "This server has NO mail support.");
return -1;
}
std::istringstream istr(text);
std::string token;
/* stkip "/mail" */
istr >> token;
/* get the mail function */
token.clear();
istr >> token;
switch (identify_mail_function(token.c_str())) {
case MAIL_FUNC_SEND:
mail_func_send(c, istr);
break;
case MAIL_FUNC_READ:
mail_func_read(c, istr);
break;
case MAIL_FUNC_DELETE:
mail_func_delete(c, istr);
break;
case MAIL_FUNC_HELP:
message_send_text(c, message_type_info, c, "The mail command supports the following patterns.");
mail_usage(c);
break;
default:
message_send_text(c, message_type_error, c, "The command its incorrect. Use one of the following patterns.");
mail_usage(c);
}
return 0;
}
mbox.erase(std::atoi(token.c_str()));
message_send_text(c,message_type_info,c, "Succesfully deleted message.");
}
}
static int identify_mail_function(const std::string& funcstr)
{
if (funcstr.empty() || !strcasecmp(funcstr.c_str(), "read") || !strcasecmp(funcstr.c_str(), "r"))
return MAIL_FUNC_READ;
if (!strcasecmp(funcstr.c_str(), "send") || !strcasecmp(funcstr.c_str(), "s"))
return MAIL_FUNC_SEND;
if (!strcasecmp(funcstr.c_str(), "delete") || !strcasecmp(funcstr.c_str(), "del"))
return MAIL_FUNC_DELETE;
if (!strcasecmp(funcstr.c_str(), "help") || !strcasecmp(funcstr.c_str(), "h"))
return MAIL_FUNC_HELP;
static void mail_usage(t_connection * c)
{
message_send_text(c,message_type_info,c,"to print this information:");
message_send_text(c,message_type_info,c," /mail help");
message_send_text(c,message_type_info,c,"to print an index of you messages:");
message_send_text(c,message_type_info,c," /mail [read]");
message_send_text(c,message_type_info,c,"to send a message:");
message_send_text(c,message_type_info,c," /mail send <receiver> <message>");
message_send_text(c,message_type_info,c,"to read a message:");
message_send_text(c,message_type_info,c," /mail read <index num>");
message_send_text(c,message_type_info,c,"to delete a message:");
message_send_text(c,message_type_info,c," /mail delete {<index>|all}");
message_send_text(c,message_type_info,c,"Commands may be abbreviated as follows:");
message_send_text(c,message_type_info,c," help: h");
message_send_text(c,message_type_info,c," read: r");
message_send_text(c,message_type_info,c," send: s");
message_send_text(c,message_type_info,c," delete: del");
}
return MAIL_FUNC_UNKNOWN;
}
static unsigned get_mail_quota(t_account * user)
{
int quota;
char const * user_quota = account_get_strattr(user, "BNET\\auth\\mailquota");
if (!user_quota) quota = prefs_get_mail_quota();
else {
quota = std::atoi(user_quota);
if (quota < 1) quota = 1;
if (quota > MAX_MAIL_QUOTA) quota = MAX_MAIL_QUOTA;
}
return quota;
}
static void mail_func_send(t_connection * c, std::istream& istr)
{
if (!c) {
ERROR0("got NULL connection");
return;
}
std::string dest;
istr >> dest;
if (dest.empty()) {
message_send_text(c, message_type_error, c, "You must specify the receiver");
message_send_text(c, message_type_error, c, "Syntax: /mail send <receiver> <message>");
return;
}
std::string message;
std::getline(istr, message);
std::string::size_type pos(message.find_first_not_of(" \t"));
if (pos == std::string::npos) {
message_send_text(c, message_type_error, c, "Your message is empty!");
message_send_text(c, message_type_error, c, "Syntax: /mail send <receiver> <message>");
return;
}
t_account * recv = accountlist_find_account(dest.c_str());
if (!recv) {
message_send_text(c, message_type_error, c, "Receiver UNKNOWN!");
return;
}
Mailbox mbox(account_get_uid(recv));
if (get_mail_quota(recv) <= mbox.size()) {
message_send_text(c, message_type_error, c, "Receiver has reached his mail quota. Your message will NOT be sent.");
return;
}
try {
mbox.deliver(conn_get_username(c), message.substr(pos));
message_send_text(c, message_type_info, c, "Your mail has been sent successfully.");
}
catch (const Mailbox::DeliverError&) {
message_send_text(c, message_type_error, c, "There was an error completing your request!");
}
}
bool NonNumericChar(const char ch)
{
if (ch < '0' || ch > '9') return true;
return false;
}
static void mail_func_read(t_connection * c, std::istream& istr)
{
if (!c) {
ERROR0("got NULL connection");
return;
}
std::string token;
istr >> token;
t_account * user = conn_get_account(c);
Mailbox mbox(account_get_uid(user));
if (token.empty()) { /* user wants to see the mail summary */
if (mbox.empty()) {
message_send_text(c, message_type_info, c, "You have no mail.");
return;
}
MailList mlist;
mbox.readAll(mlist);
std::ostringstream ostr;
ostr << "You have " << mbox.size() << " messages. Your mail quote is set to " << get_mail_quota(user) << '.';
message_send_text(c, message_type_info, c, ostr.str().c_str());
message_send_text(c, message_type_info, c, "ID Sender Date");
message_send_text(c, message_type_info, c, "-------------------------------------");
for (MailList::const_iterator it(mlist.begin()); it != mlist.end(); ++it) {
ostr.str("");
ostr << std::setfill('0') << std::setw(2) << std::right << (it - mlist.begin()) << " "
<< std::setfill(' ') << std::setw(14) << std::left << it->sender() << ' ';
char buff[128];
std::strftime(buff, sizeof(buff), "%a %b %d %H:%M:%S %Y", std::localtime(&it->timestamp()));
ostr << buff;
message_send_text(c, message_type_info, c, ostr.str().c_str());
}
message_send_text(c, message_type_info, c, "Use /mail read <ID> to read the content of any message");
}
else { /* user wants to read a message */
if (std::find_if(token.begin(), token.end(), NonNumericChar) != token.end()) {
message_send_text(c, message_type_error, c, "Invalid index. Please use /mail read <index> where <index> is a number.");
return;
}
try {
unsigned idx = std::atoi(token.c_str());
Mail mail(mbox.read(idx));
std::ostringstream ostr;
ostr << "Message #" << idx << " from " << mail.sender() << " on ";
char buff[128];
std::strftime(buff, sizeof(buff), "%a %b %d %H:%M:%S %Y", std::localtime(&mail.timestamp()));
ostr << buff << ':';
message_send_text(c, message_type_info, c, ostr.str().c_str());
message_send_text(c, message_type_info, c, mail.message().c_str());
}
catch (const Mailbox::ReadError&) {
message_send_text(c, message_type_error, c, "There was an error completing your request.");
}
}
}
static void mail_func_delete(t_connection * c, std::istream& istr)
{
if (!c) {
ERROR0("got NULL connection");
return;
}
std::string token;
istr >> token;
if (token.empty()) {
message_send_text(c, message_type_error, c, "Please specify which message to delete. Use the following syntax: /mail delete {<index>|all} .");
return;
}
t_account * user = conn_get_account(c);
Mailbox mbox(account_get_uid(user));
if (token == "all") {
mbox.clear();
message_send_text(c, message_type_info, c, "Successfully deleted messages.");
}
else {
if (std::find_if(token.begin(), token.end(), NonNumericChar) != token.end()) {
message_send_text(c, message_type_error, c, "Invalid index. Please use /mail delete {<index>|all} where <index> is a number.");
return;
}
mbox.erase(std::atoi(token.c_str()));
message_send_text(c, message_type_info, c, "Succesfully deleted message.");
}
}
static void mail_usage(t_connection * c)
{
message_send_text(c, message_type_info, c, "to print this information:");
message_send_text(c, message_type_info, c, " /mail help");
message_send_text(c, message_type_info, c, "to print an index of you messages:");
message_send_text(c, message_type_info, c, " /mail [read]");
message_send_text(c, message_type_info, c, "to send a message:");
message_send_text(c, message_type_info, c, " /mail send <receiver> <message>");
message_send_text(c, message_type_info, c, "to read a message:");
message_send_text(c, message_type_info, c, " /mail read <index num>");
message_send_text(c, message_type_info, c, "to delete a message:");
message_send_text(c, message_type_info, c, " /mail delete {<index>|all}");
message_send_text(c, message_type_info, c, "Commands may be abbreviated as follows:");
message_send_text(c, message_type_info, c, " help: h");
message_send_text(c, message_type_info, c, " read: r");
message_send_text(c, message_type_info, c, " send: s");
message_send_text(c, message_type_info, c, " delete: del");
}
extern unsigned check_mail(t_connection const * c)
{
if (!c) {
ERROR0("got NULL connection");
return 0;
}
return Mailbox(account_get_uid(conn_get_account(c))).size();
}
extern unsigned check_mail(t_connection const * c)
{
if (!c) {
ERROR0("got NULL connection");
return 0;
}
return Mailbox(account_get_uid(conn_get_account(c))).size();
}
}
}

View file

@ -43,72 +43,72 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
class Mail
{
public:
Mail(const std::string& sender, const std::string& mess, const std::time_t timestamp);
~Mail() throw();
class Mail
{
public:
Mail(const std::string& sender, const std::string& mess, const std::time_t timestamp);
~Mail() throw();
const std::string& sender() const;
const std::string& message() const;
const std::time_t& timestamp() const;
const std::string& sender() const;
const std::string& message() const;
const std::time_t& timestamp() const;
private:
const std::string sender_;
const std::string message_;
const std::time_t timestamp_;
};
private:
const std::string sender_;
const std::string message_;
const std::time_t timestamp_;
};
typedef std::deque<Mail> MailList;
typedef std::deque<Mail> MailList;
class Mailbox {
public:
class ReadError: public std::runtime_error {
public:
ReadError(const std::string& mess)
:std::runtime_error(mess) {}
~ReadError() throw() {}
};
class Mailbox {
public:
class ReadError : public std::runtime_error {
public:
ReadError(const std::string& mess)
:std::runtime_error(mess) {}
~ReadError() throw() {}
};
class DeliverError: public std::runtime_error {
public:
DeliverError(const std::string& mess)
:std::runtime_error(mess) {}
~DeliverError() throw() {}
};
class DeliverError : public std::runtime_error {
public:
DeliverError(const std::string& mess)
:std::runtime_error(mess) {}
~DeliverError() throw() {}
};
explicit Mailbox(unsigned uid);
~Mailbox() throw();
explicit Mailbox(unsigned uid);
~Mailbox() throw();
unsigned size() const;
bool empty() const;
void deliver(const std::string& sender, const std::string& mess);
Mail read(unsigned int) const;
void readAll(MailList& dest) const;
void erase(unsigned int);
void clear();
unsigned size() const;
bool empty() const;
void deliver(const std::string& sender, const std::string& mess);
Mail read(unsigned int) const;
void readAll(MailList& dest) const;
void erase(unsigned int);
void clear();
private:
unsigned uid;
const std::string path;
mutable Directory mdir;
private:
unsigned uid;
const std::string path;
mutable Directory mdir;
std::string buildPath(const std::string& root) const;
void createOpenDir();
Mail read(const std::string& fname, const std::time_t& timestamp) const;
std::string buildPath(const std::string& root) const;
void createOpenDir();
Mail read(const std::string& fname, const std::time_t& timestamp) const;
Mailbox(const Mailbox&);
Mailbox& operator=(const Mailbox&);
};
Mailbox(const Mailbox&);
Mailbox& operator=(const Mailbox&);
};
extern int handle_mail_command(t_connection *, char const *);
extern unsigned check_mail(t_connection const * c);
extern int handle_mail_command(t_connection *, char const *);
extern unsigned check_mail(t_connection const * c);
}
}
}

View file

@ -100,37 +100,37 @@ void *oom_buffer = NULL;
static int bnetd_oom_handler(void)
{
/* no safety buffer, sorry :( */
if (!oom_buffer) return 0;
/* no safety buffer, sorry :( */
if (!oom_buffer) return 0;
/* free the safety buffer hoping next allocs will succeed */
free(oom_buffer);
oom_buffer = NULL;
/* free the safety buffer hoping next allocs will succeed */
free(oom_buffer);
oom_buffer = NULL;
eventlog(eventlog_level_fatal,__FUNCTION__,"out of memory, forcing immediate shutdown");
eventlog(eventlog_level_fatal, __FUNCTION__, "out of memory, forcing immediate shutdown");
/* shutdown immediatly */
server_quit_delay(-1);
/* shutdown immediatly */
server_quit_delay(-1);
return 1; /* ask xalloc codes to retry the allocation request */
return 1; /* ask xalloc codes to retry the allocation request */
}
static int oom_setup(void)
{
/* use calloc so it initilizez the memory so it will make some lazy
* allocators really alocate it (ex. the linux kernel)
*/
oom_buffer = calloc(1, OOM_SAFE_MEM);
if (!oom_buffer) return -1;
/* use calloc so it initilizez the memory so it will make some lazy
* allocators really alocate it (ex. the linux kernel)
*/
oom_buffer = calloc(1, OOM_SAFE_MEM);
if (!oom_buffer) return -1;
xalloc_setcb(bnetd_oom_handler);
return 0;
xalloc_setcb(bnetd_oom_handler);
return 0;
}
static void oom_free(void)
{
if (oom_buffer) free(oom_buffer);
oom_buffer = NULL;
if (oom_buffer) free(oom_buffer);
oom_buffer = NULL;
}
FILE *hexstrm = NULL;
@ -168,21 +168,21 @@ void pvpgn_greeting(void);
int eventlog_startup(void)
{
char const * levels;
char * temp;
char const * tok;
char const * levels;
char * temp;
char const * tok;
eventlog_clear_level();
if ((levels = prefs_get_loglevels())) {
temp = xstrdup(levels);
tok = std::strtok(temp,","); /* std::strtok modifies the string it is passed */
while (tok) {
if (eventlog_add_level(tok)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not add std::log level \"%s\"",tok);
tok = std::strtok(NULL,",");
eventlog_clear_level();
if ((levels = prefs_get_loglevels())) {
temp = xstrdup(levels);
tok = std::strtok(temp, ","); /* std::strtok modifies the string it is passed */
while (tok) {
if (eventlog_add_level(tok) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not add std::log level \"%s\"", tok);
tok = std::strtok(NULL, ",");
}
xfree(temp);
}
xfree(temp);
}
#ifdef WIN32_GUI
if (cmdline_get_gui()){
@ -190,275 +190,277 @@ int eventlog_startup(void)
}
#endif
if (eventlog_open(prefs_get_logfile())<0) {
if (prefs_get_logfile()) {
eventlog(eventlog_level_fatal,__FUNCTION__,"could not use file \"%s\" for the eventlog (exiting)",prefs_get_logfile());
} else {
eventlog(eventlog_level_fatal,__FUNCTION__,"no logfile specified in configuration file \"%s\" (exiting)",cmdline_get_preffile());
if (eventlog_open(prefs_get_logfile()) < 0) {
if (prefs_get_logfile()) {
eventlog(eventlog_level_fatal, __FUNCTION__, "could not use file \"%s\" for the eventlog (exiting)", prefs_get_logfile());
}
else {
eventlog(eventlog_level_fatal, __FUNCTION__, "no logfile specified in configuration file \"%s\" (exiting)", cmdline_get_preffile());
}
return -1;
}
return -1;
}
eventlog(eventlog_level_info,__FUNCTION__,"logging event levels: %s",prefs_get_loglevels());
return 0;
eventlog(eventlog_level_info, __FUNCTION__, "logging event levels: %s", prefs_get_loglevels());
return 0;
}
int fork_bnetd(int foreground)
{
int pid;
int pid;
#ifdef DO_DAEMONIZE
if (!foreground) {
if (chdir("/")<0) {
eventlog(eventlog_level_error,__FUNCTION__,"could not change working directory to / (chdir: %s)",std::strerror(errno));
return -1;
}
if (!foreground) {
if (chdir("/") < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "could not change working directory to / (chdir: %s)", std::strerror(errno));
return -1;
}
switch ((pid = fork())) {
case -1:
eventlog(eventlog_level_error,__FUNCTION__,"could not fork (fork: %s)",std::strerror(errno));
return -1;
case 0: /* child */
break;
default: /* parent */
return pid;
}
switch ((pid = fork())) {
case -1:
eventlog(eventlog_level_error, __FUNCTION__, "could not fork (fork: %s)", std::strerror(errno));
return -1;
case 0: /* child */
break;
default: /* parent */
return pid;
}
#ifndef WITH_D2
close(STDINFD);
close(STDOUTFD);
close(STDERRFD);
close(STDINFD);
close(STDOUTFD);
close(STDERRFD);
#endif
# ifdef HAVE_SETPGID
if (setpgid(0,0)<0) {
eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgid: %s)",std::strerror(errno));
return -1;
}
if (setpgid(0, 0) < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "could not create new process group (setpgid: %s)", std::strerror(errno));
return -1;
}
# else
# ifdef HAVE_SETPGRP
# ifdef SETPGRP_VOID
if (setpgrp()<0) {
eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)",std::strerror(errno));
return -1;
}
if (setpgrp() < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "could not create new process group (setpgrp: %s)", std::strerror(errno));
return -1;
}
# else
if (setpgrp(0,0)<0) {
eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)",std::strerror(errno));
return -1;
}
if (setpgrp(0, 0) < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "could not create new process group (setpgrp: %s)", std::strerror(errno));
return -1;
}
# endif
# else
# ifdef HAVE_SETSID
if (setsid()<0) {
eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setsid: %s)",std::strerror(errno));
return -1;
}
if (setsid() < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "could not create new process group (setsid: %s)", std::strerror(errno));
return -1;
}
# else
# error "One of setpgid(), setpgrp(), or setsid() is required"
# endif
# endif
# endif
}
return 0;
}
return 0;
#endif
return 0;
return 0;
}
char * write_to_pidfile(void)
{
char *pidfile = xstrdup(prefs_get_pidfile());
char *pidfile = xstrdup(prefs_get_pidfile());
if (pidfile[0]=='\0') {
xfree((void *)pidfile); /* avoid warning */
return NULL;
}
if (pidfile) {
if (pidfile[0] == '\0') {
xfree((void *)pidfile); /* avoid warning */
return NULL;
}
if (pidfile) {
#ifdef HAVE_GETPID
std::FILE * fp;
std::FILE * fp;
if (!(fp = std::fopen(pidfile,"w"))) {
eventlog(eventlog_level_error,__FUNCTION__,"unable to open pid file \"%s\" for writing (std::fopen: %s)",pidfile,std::strerror(errno));
xfree((void *)pidfile); /* avoid warning */
return NULL;
} else {
std::fprintf(fp,"%u",(unsigned int)getpid());
if (std::fclose(fp)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not close pid file \"%s\" after writing (std::fclose: %s)",pidfile,std::strerror(errno));
}
if (!(fp = std::fopen(pidfile, "w"))) {
eventlog(eventlog_level_error, __FUNCTION__, "unable to open pid file \"%s\" for writing (std::fopen: %s)", pidfile, std::strerror(errno));
xfree((void *)pidfile); /* avoid warning */
return NULL;
}
else {
std::fprintf(fp, "%u", (unsigned int)getpid());
if (std::fclose(fp) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not close pid file \"%s\" after writing (std::fclose: %s)", pidfile, std::strerror(errno));
}
#else
eventlog(eventlog_level_warn,__FUNCTION__,"no getpid() std::system call, disable pid file in bnetd.conf");
xfree((void *)pidfile); /* avoid warning */
return NULL;
eventlog(eventlog_level_warn, __FUNCTION__, "no getpid() std::system call, disable pid file in bnetd.conf");
xfree((void *)pidfile); /* avoid warning */
return NULL;
#endif
}
return pidfile;
}
return pidfile;
}
int pre_server_startup(void)
{
pvpgn_greeting();
if (oom_setup() < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "OOM init failed");
return STATUS_OOM_FAILURE;
}
if (storage_init(prefs_get_storage_path()) < 0) {
eventlog(eventlog_level_error, "pre_server_startup", "storage init failed");
return STATUS_STORAGE_FAILURE;
}
if (psock_init() < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "could not initialize socket functions");
return STATUS_PSOCK_FAILURE;
}
if (support_check_files(prefs_get_supportfile()) < 0) {
eventlog(eventlog_level_error, "pre_server_startup","some needed files are missing");
eventlog(eventlog_level_error, "pre_server_startup","please make sure you installed the supportfiles in %s",prefs_get_filedir());
return STATUS_SUPPORT_FAILURE;
}
if (anongame_maplists_create() < 0) {
eventlog(eventlog_level_error, "pre_server_startup", "could not load maps");
return STATUS_MAPLISTS_FAILURE;
}
if (anongame_matchlists_create() < 0) {
eventlog(eventlog_level_error, "pre_server_startup", "could not create matchlists");
return STATUS_MATCHLISTS_FAILURE;
}
if (fdwatch_init(prefs_get_max_connections())) {
eventlog(eventlog_level_error, __FUNCTION__, "error initilizing fdwatch");
return STATUS_FDWATCH_FAILURE;
}
connlist_create();
gamelist_create();
timerlist_create();
server_set_hostname();
channellist_create();
apireglist_create();
if (helpfile_init(prefs_get_helpfile())<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not load helpfile");
ipbanlist_create();
if (ipbanlist_load(prefs_get_ipbanfile())<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not load IP ban list");
adbannerlist.reset(new AdBannerComponent(prefs_get_adfile()));
if (autoupdate_load(prefs_get_mpqfile())<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not load autoupdate list");
if (versioncheck_load(prefs_get_versioncheck_file())<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not load versioncheck list");
if (news_load(prefs_get_newsfile())<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not load news list");
watchlist.reset(new WatchComponent());
output_init();
attrlayer_init();
accountlist_create();
if (ladder_createxptable(prefs_get_xplevel_file(),prefs_get_xpcalc_file())<0) {
eventlog(eventlog_level_error, "pre_server_startup", "could not load WAR3 xp calc tables");
return STATUS_WAR3XPTABLES_FAILURE;
}
ladders.load();
ladders.update();
if (characterlist_create("")<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not load character list");
if (prefs_get_track()) /* setup the tracking mechanism */
tracker_set_servers(prefs_get_trackserv_addrs());
if (command_groups_load(prefs_get_command_groups_file())<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not load command_groups list");
aliasfile_load(prefs_get_aliasfile());
if (trans_load(prefs_get_transfile(),TRANS_BNETD)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not load trans list");
tournament_init(prefs_get_tournament_file());
anongame_infos_load(prefs_get_anongame_infos_file());
anongame_wol_matchlist_create();
clanlist_load();
teamlist_load();
if (realmlist_create(prefs_get_realmfile())<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not load realm list");
topiclist_load(prefs_get_topicfile());
return 0;
pvpgn_greeting();
if (oom_setup() < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "OOM init failed");
return STATUS_OOM_FAILURE;
}
if (storage_init(prefs_get_storage_path()) < 0) {
eventlog(eventlog_level_error, "pre_server_startup", "storage init failed");
return STATUS_STORAGE_FAILURE;
}
if (psock_init() < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "could not initialize socket functions");
return STATUS_PSOCK_FAILURE;
}
if (support_check_files(prefs_get_supportfile()) < 0) {
eventlog(eventlog_level_error, "pre_server_startup", "some needed files are missing");
eventlog(eventlog_level_error, "pre_server_startup", "please make sure you installed the supportfiles in %s", prefs_get_filedir());
return STATUS_SUPPORT_FAILURE;
}
if (anongame_maplists_create() < 0) {
eventlog(eventlog_level_error, "pre_server_startup", "could not load maps");
return STATUS_MAPLISTS_FAILURE;
}
if (anongame_matchlists_create() < 0) {
eventlog(eventlog_level_error, "pre_server_startup", "could not create matchlists");
return STATUS_MATCHLISTS_FAILURE;
}
if (fdwatch_init(prefs_get_max_connections())) {
eventlog(eventlog_level_error, __FUNCTION__, "error initilizing fdwatch");
return STATUS_FDWATCH_FAILURE;
}
connlist_create();
gamelist_create();
timerlist_create();
server_set_hostname();
channellist_create();
apireglist_create();
if (helpfile_init(prefs_get_helpfile()) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not load helpfile");
ipbanlist_create();
if (ipbanlist_load(prefs_get_ipbanfile()) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not load IP ban list");
adbannerlist.reset(new AdBannerComponent(prefs_get_adfile()));
if (autoupdate_load(prefs_get_mpqfile()) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not load autoupdate list");
if (versioncheck_load(prefs_get_versioncheck_file()) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not load versioncheck list");
if (news_load(prefs_get_newsfile()) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not load news list");
watchlist.reset(new WatchComponent());
output_init();
attrlayer_init();
accountlist_create();
if (ladder_createxptable(prefs_get_xplevel_file(), prefs_get_xpcalc_file()) < 0) {
eventlog(eventlog_level_error, "pre_server_startup", "could not load WAR3 xp calc tables");
return STATUS_WAR3XPTABLES_FAILURE;
}
ladders.load();
ladders.update();
if (characterlist_create("") < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not load character list");
if (prefs_get_track()) /* setup the tracking mechanism */
tracker_set_servers(prefs_get_trackserv_addrs());
if (command_groups_load(prefs_get_command_groups_file()) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not load command_groups list");
aliasfile_load(prefs_get_aliasfile());
if (trans_load(prefs_get_transfile(), TRANS_BNETD) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not load trans list");
tournament_init(prefs_get_tournament_file());
anongame_infos_load(prefs_get_anongame_infos_file());
anongame_wol_matchlist_create();
clanlist_load();
teamlist_load();
if (realmlist_create(prefs_get_realmfile()) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not load realm list");
topiclist_load(prefs_get_topicfile());
return 0;
}
void post_server_shutdown(int status)
{
switch (status)
{
switch (status)
{
case 0:
topiclist_unload();
realmlist_destroy();
teamlist_unload();
clanlist_unload();
tournament_destroy();
anongame_infos_unload();
anongame_wol_matchlist_destroy();
trans_unload();
aliasfile_unload();
command_groups_unload();
tracker_set_servers(NULL);
characterlist_destroy();
ladder_destroyxptable();
case STATUS_WAR3XPTABLES_FAILURE:
topiclist_unload();
realmlist_destroy();
teamlist_unload();
clanlist_unload();
tournament_destroy();
anongame_infos_unload();
anongame_wol_matchlist_destroy();
trans_unload();
aliasfile_unload();
command_groups_unload();
tracker_set_servers(NULL);
characterlist_destroy();
ladder_destroyxptable();
case STATUS_WAR3XPTABLES_FAILURE:
case STATUS_LADDERLIST_FAILURE:
ladders.save();
output_dispose_filename();
accountlist_destroy();
attrlayer_cleanup();
watchlist.reset();
news_unload();
versioncheck_unload();
autoupdate_unload();
adbannerlist.reset();
ipbanlist_save(prefs_get_ipbanfile());
ipbanlist_destroy();
helpfile_unload();
apireglist_destroy();
channellist_destroy();
server_clear_hostname();
timerlist_destroy();
gamelist_destroy();
connlist_destroy();
fdwatch_close();
ladders.save();
output_dispose_filename();
accountlist_destroy();
attrlayer_cleanup();
watchlist.reset();
news_unload();
versioncheck_unload();
autoupdate_unload();
adbannerlist.reset();
ipbanlist_save(prefs_get_ipbanfile());
ipbanlist_destroy();
helpfile_unload();
apireglist_destroy();
channellist_destroy();
server_clear_hostname();
timerlist_destroy();
gamelist_destroy();
connlist_destroy();
fdwatch_close();
case STATUS_FDWATCH_FAILURE:
anongame_matchlists_destroy();
anongame_matchlists_destroy();
case STATUS_MATCHLISTS_FAILURE:
anongame_maplists_destroy();
anongame_maplists_destroy();
case STATUS_MAPLISTS_FAILURE:
case STATUS_SUPPORT_FAILURE:
if (psock_deinit())
eventlog(eventlog_level_error, __FUNCTION__, "got error from psock_deinit()");
if (psock_deinit())
eventlog(eventlog_level_error, __FUNCTION__, "got error from psock_deinit()");
case STATUS_PSOCK_FAILURE:
storage_close();
storage_close();
case STATUS_STORAGE_FAILURE:
oom_free();
oom_free();
case STATUS_OOM_FAILURE:
case -1:
break;
break;
default:
eventlog(eventlog_level_error,__FUNCTION__,"got bad status \"%d\" during shutdown",status);
}
return;
eventlog(eventlog_level_error, __FUNCTION__, "got bad status \"%d\" during shutdown", status);
}
return;
}
void pvpgn_greeting(void)
{
struct utsname utsbuf;
struct utsname utsbuf;
#ifdef HAVE_GETPID
eventlog(eventlog_level_info,__FUNCTION__,PVPGN_SOFTWARE" version "PVPGN_VERSION" process %u",(unsigned int)getpid());
eventlog(eventlog_level_info, __FUNCTION__, PVPGN_SOFTWARE" version "PVPGN_VERSION" process %u", (unsigned int)getpid());
#else
eventlog(eventlog_level_info,__FUNCTION__,PVPGN_SOFTWARE" version "PVPGN_VERSION);
eventlog(eventlog_level_info, __FUNCTION__, PVPGN_SOFTWARE" version "PVPGN_VERSION);
#endif
if (!(uname(&utsbuf)<0))
if (!(uname(&utsbuf) < 0))
{
eventlog(eventlog_level_info,__FUNCTION__,"running on %s %s %s (%s)",utsbuf.sysname, utsbuf.version, utsbuf.release, utsbuf.machine);
}
eventlog(eventlog_level_info, __FUNCTION__, "running on %s %s %s (%s)", utsbuf.sysname, utsbuf.version, utsbuf.release, utsbuf.machine);
}
printf("You are currently Running "PVPGN_SOFTWARE" "PVPGN_VERSION"\n");
printf("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
printf("If you need support:\n");
printf(" * READ the documentation at http://pvpgndocs.berlios.de/\n");
printf(" * you can subscribe to the pvpgn-users mailing list at \n");
printf(" https://lists.berlios.de/mailman/listinfo/pvpgn-users\n");
printf(" * check out the forums at http://forums.pvpgn.org\n");
printf(" * visit us on IRC on irc.pvpgn.org channel #pvpgn\n");
printf("\nServer is now running.\n");
printf("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
printf("You are currently Running "PVPGN_SOFTWARE" "PVPGN_VERSION"\n");
printf("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
printf("If you need support:\n");
printf(" * READ the documentation at http://pvpgndocs.berlios.de/\n");
printf(" * you can subscribe to the pvpgn-users mailing list at \n");
printf(" https://lists.berlios.de/mailman/listinfo/pvpgn-users\n");
printf(" * check out the forums at http://forums.pvpgn.org\n");
printf(" * visit us on IRC on irc.pvpgn.org channel #pvpgn\n");
printf("\nServer is now running.\n");
printf("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
return;
return;
}
#ifdef WIN32_GUI
@ -467,89 +469,91 @@ extern int app_main(int argc, char ** argv)
extern int main(int argc, char ** argv)
#endif
{
try {
int a;
char *pidfile;
try {
int a;
char *pidfile;
if ((a = cmdline_load(argc, argv)) != 1)
return a;
if ((a = cmdline_load(argc, argv)) != 1)
return a;
#ifdef DO_DAEMONIZE
if ((a = fork_bnetd(cmdline_get_foreground())) != 0)
return a < 0 ? a : 0; /* dont return code != 0 when things are OK! */
if ((a = fork_bnetd(cmdline_get_foreground())) != 0)
return a < 0 ? a : 0; /* dont return code != 0 when things are OK! */
#endif
eventlog_set(stderr);
/* errors to eventlog from here on... */
eventlog_set(stderr);
/* errors to eventlog from here on... */
if (prefs_load(cmdline_get_preffile())<0) {
eventlog(eventlog_level_fatal,__FUNCTION__,"could not parse configuration file (exiting)");
return -1;
}
if (prefs_load(cmdline_get_preffile()) < 0) {
eventlog(eventlog_level_fatal, __FUNCTION__, "could not parse configuration file (exiting)");
return -1;
}
/* Start logging to std::log file */
if (eventlog_startup() == -1)
/* Start logging to std::log file */
if (eventlog_startup() == -1)
return -1;
/* eventlog goes to std::log file from here on... */
/* Give up root privileges */
/* Hakan: That's way too late to give up root privileges... Have to look for a better place */
if (give_up_root_privileges(prefs_get_effective_user(), prefs_get_effective_group()) < 0) {
eventlog(eventlog_level_fatal, __FUNCTION__, "could not give up privileges (exiting)");
return -1;
}
/* Write the pidfile */
pidfile = write_to_pidfile();
if (cmdline_get_hexfile()) {
if (!(hexstrm = std::fopen(cmdline_get_hexfile(), "w")))
eventlog(eventlog_level_error, __FUNCTION__, "could not open file \"%s\" for writing the hexdump (std::fopen: %s)", cmdline_get_hexfile(), std::strerror(errno));
else
std::fprintf(hexstrm, "# dump generated by "PVPGN_SOFTWARE" version "PVPGN_VERSION"\n");
}
/* Run the pre server stuff */
a = pre_server_startup();
/* now process connections and network traffic */
if (a == 0) {
if (server_process() < 0)
eventlog(eventlog_level_fatal, __FUNCTION__, "failed to initialize network (exiting)");
}
// run post server stuff and exit
post_server_shutdown(a);
// Close hexfile
if (hexstrm) {
std::fprintf(hexstrm, "# end of dump\n");
if (std::fclose(hexstrm) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not close hexdump file \"%s\" after writing (std::fclose: %s)", cmdline_get_hexfile(), std::strerror(errno));
}
// Delete pidfile
if (pidfile) {
if (std::remove(pidfile) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not remove pid file \"%s\" (std::remove: %s)", pidfile, std::strerror(errno));
xfree((void *)pidfile); /* avoid warning */
}
if (a == 0)
eventlog(eventlog_level_info, __FUNCTION__, "server has shut down");
prefs_unload();
eventlog_close();
cmdline_unload();
if (a == 0)
return 0;
return -1;
}
catch (const std::exception& ex) {
std::cerr << "FATAL ERROR: " << ex.what() << std::endl;
}
catch (...) {
std::cerr << "UNKNOWN EXCEPTION TYPE" << std::endl;
}
return -1;
/* eventlog goes to std::log file from here on... */
/* Give up root privileges */
/* Hakan: That's way too late to give up root privileges... Have to look for a better place */
if (give_up_root_privileges(prefs_get_effective_user(),prefs_get_effective_group())<0) {
eventlog(eventlog_level_fatal,__FUNCTION__,"could not give up privileges (exiting)");
return -1;
}
/* Write the pidfile */
pidfile = write_to_pidfile();
if (cmdline_get_hexfile()) {
if (!(hexstrm = std::fopen(cmdline_get_hexfile(),"w")))
eventlog(eventlog_level_error,__FUNCTION__,"could not open file \"%s\" for writing the hexdump (std::fopen: %s)",cmdline_get_hexfile(),std::strerror(errno));
else
std::fprintf(hexstrm,"# dump generated by "PVPGN_SOFTWARE" version "PVPGN_VERSION"\n");
}
/* Run the pre server stuff */
a = pre_server_startup();
/* now process connections and network traffic */
if (a == 0) {
if (server_process() < 0)
eventlog(eventlog_level_fatal,__FUNCTION__,"failed to initialize network (exiting)");
}
// run post server stuff and exit
post_server_shutdown(a);
// Close hexfile
if (hexstrm) {
std::fprintf(hexstrm,"# end of dump\n");
if (std::fclose(hexstrm)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not close hexdump file \"%s\" after writing (std::fclose: %s)",cmdline_get_hexfile(),std::strerror(errno));
}
// Delete pidfile
if (pidfile) {
if (std::remove(pidfile)<0)
eventlog(eventlog_level_error,__FUNCTION__,"could not remove pid file \"%s\" (std::remove: %s)",pidfile,std::strerror(errno));
xfree((void *)pidfile); /* avoid warning */
}
if (a == 0)
eventlog(eventlog_level_info,__FUNCTION__,"server has shut down");
prefs_unload();
eventlog_close();
cmdline_unload();
if (a == 0)
return 0;
return -1;
} catch (const std::exception& ex) {
std::cerr << "FATAL ERROR: " << ex.what() << std::endl;
} catch (...) {
std::cerr << "UNKNOWN EXCEPTION TYPE" << std::endl;
}
return -1;
}

File diff suppressed because it is too large Load diff

View file

@ -35,79 +35,79 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef enum
{
message_type_adduser,
message_type_join,
message_type_part,
message_type_whisper,
message_type_talk,
message_type_broadcast,
message_type_channel,
message_type_userflags,
message_type_whisperack,
message_type_friendwhisperack,
message_type_channelfull,
message_type_channeldoesnotexist,
message_type_channelrestricted,
message_type_info,
message_type_error,
message_type_emote,
message_type_uniqueid,
message_type_mode,
message_type_kick,
message_type_quit,
/**
* IRC specific messages
*/
message_type_nick,
message_type_notice,
message_type_namreply,
message_type_topic,
typedef enum
{
message_type_adduser,
message_type_join,
message_type_part,
message_type_whisper,
message_type_talk,
message_type_broadcast,
message_type_channel,
message_type_userflags,
message_type_whisperack,
message_type_friendwhisperack,
message_type_channelfull,
message_type_channeldoesnotexist,
message_type_channelrestricted,
message_type_info,
message_type_error,
message_type_emote,
message_type_uniqueid,
message_type_mode,
message_type_kick,
message_type_quit,
/**
* Westwood Online Extensions
*/
message_type_host,
message_type_invmsg,
message_type_page,
message_wol_joingame,
message_type_gameopt_talk,
message_type_gameopt_whisper,
message_wol_start_game,
message_wol_advertr,
message_wol_chanchk,
message_wol_userip,
/**
* IRC specific messages
*/
message_type_nick,
message_type_notice,
message_type_namreply,
message_type_topic,
message_type_null
} t_message_type;
/**
* Westwood Online Extensions
*/
message_type_host,
message_type_invmsg,
message_type_page,
message_wol_joingame,
message_type_gameopt_talk,
message_type_gameopt_whisper,
message_wol_start_game,
message_wol_advertr,
message_wol_chanchk,
message_wol_userip,
typedef enum {
message_class_normal,
message_class_charjoin /* use char*account (if account isnt d2 char is "") */
} t_message_class;
message_type_null
} t_message_type;
typedef struct message
typedef enum {
message_class_normal,
message_class_charjoin /* use char*account (if account isnt d2 char is "") */
} t_message_class;
typedef struct message
#ifdef MESSAGE_INTERNAL_ACCESS
{
unsigned int num_cached;
t_packet * * packets; /* cached messages */
t_conn_class * classes; /* classes of cached message connections */
unsigned int * dstflags; /* overlaid flags of cached messages */
t_message_class * mclasses; /* classes of cached messages */
/* ---- */
t_message_type type; /* format of message */
t_connection * src; /* originator message */
char const * text; /* text of message */
}
{
unsigned int num_cached;
t_packet * * packets; /* cached messages */
t_conn_class * classes; /* classes of cached message connections */
unsigned int * dstflags; /* overlaid flags of cached messages */
t_message_class * mclasses; /* classes of cached messages */
/* ---- */
t_message_type type; /* format of message */
t_connection * src; /* originator message */
char const * text; /* text of message */
}
#endif
t_message;
t_message;
}
}
}
@ -126,22 +126,22 @@ t_message;
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern char * message_format_line(t_connection const * c, char const * in);
extern t_message * message_create(t_message_type type, t_connection * src, char const * text);
extern int message_destroy(t_message * message);
extern int message_send(t_message * message, t_connection * dst);
extern int message_send_all(t_message * message);
extern int message_send_admins(t_connection * src, t_message_type type, char const * text);
extern char * message_format_line(t_connection const * c, char const * in);
extern t_message * message_create(t_message_type type, t_connection * src, char const * text);
extern int message_destroy(t_message * message);
extern int message_send(t_message * message, t_connection * dst);
extern int message_send_all(t_message * message);
extern int message_send_admins(t_connection * src, t_message_type type, char const * text);
/* the following are "shortcuts" to avoid calling message_create(), message_send(), message_destroy() */
extern int message_send_text(t_connection * dst, t_message_type type, t_connection * src, char const * text);
extern int message_send_formatted(t_connection * dst, char const * text);
extern int message_send_file(t_connection * dst, std::FILE * fd);
/* the following are "shortcuts" to avoid calling message_create(), message_send(), message_destroy() */
extern int message_send_text(t_connection * dst, t_message_type type, t_connection * src, char const * text);
extern int message_send_formatted(t_connection * dst, char const * text);
extern int message_send_file(t_connection * dst, std::FILE * fd);
}
}
}

View file

@ -32,200 +32,202 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
static t_elist news_head;
static t_elist news_head;
static int _news_parsetime(char *buff, struct std::tm *date, unsigned line)
{
char *p;
static int _news_parsetime(char *buff, struct std::tm *date, unsigned line)
{
char *p;
date->tm_hour= 6;
date->tm_min = 6; // need to set non-zero values or else date is displayed wrong
date->tm_sec = 6;
date->tm_isdst=-1;
date->tm_hour = 6;
date->tm_min = 6; // need to set non-zero values or else date is displayed wrong
date->tm_sec = 6;
date->tm_isdst = -1;
if (!(p = std::strchr(buff,'/'))) return -1;
*p = '\0';
if (!(p = std::strchr(buff, '/'))) return -1;
*p = '\0';
date->tm_mon = std::atoi(buff) - 1;
if ((date->tm_mon<0) || (date->tm_mon>11)) {
eventlog(eventlog_level_error,__FUNCTION__,"found invalid month (%i) in news date. (format: {MM/DD/YYYY}) on line %u",date->tm_mon,line);
}
date->tm_mon = std::atoi(buff) - 1;
if ((date->tm_mon<0) || (date->tm_mon>11)) {
eventlog(eventlog_level_error, __FUNCTION__, "found invalid month (%i) in news date. (format: {MM/DD/YYYY}) on line %u", date->tm_mon, line);
}
buff = p + 1;
if (!(p = std::strchr(buff,'/'))) return -1;
*p = '\0';
buff = p + 1;
if (!(p = std::strchr(buff, '/'))) return -1;
*p = '\0';
date->tm_mday = std::atoi(buff);
if ((date->tm_mday<1) || (date->tm_mday>31)) {
eventlog(eventlog_level_error,__FUNCTION__,"found invalid month day (%i) in news date. (format: {MM/DD/YYYY}) on line %u",date->tm_mday,line);
return -1;
}
date->tm_mday = std::atoi(buff);
if ((date->tm_mday<1) || (date->tm_mday>31)) {
eventlog(eventlog_level_error, __FUNCTION__, "found invalid month day (%i) in news date. (format: {MM/DD/YYYY}) on line %u", date->tm_mday, line);
return -1;
}
buff = p + 1;
if (!(p = std::strchr(buff,'}'))) return -1;
*p = '\0';
buff = p + 1;
if (!(p = std::strchr(buff, '}'))) return -1;
*p = '\0';
date->tm_year=std::atoi(buff)-1900;
if (date->tm_year>137) //limited due to 32bit t_time
{
eventlog(eventlog_level_error,__FUNCTION__,"found invalid year (%i) (>2037) in news date. on line %u",date->tm_year+1900,line);
return -1;
}
date->tm_year = std::atoi(buff) - 1900;
if (date->tm_year > 137) //limited due to 32bit t_time
{
eventlog(eventlog_level_error, __FUNCTION__, "found invalid year (%i) (>2037) in news date. on line %u", date->tm_year + 1900, line);
return -1;
}
return 0;
}
return 0;
}
static void _news_insert_index(t_news_index *ni, const char *buff, unsigned len, int date_set)
{
t_elist *curr;
t_news_index *cni;
static void _news_insert_index(t_news_index *ni, const char *buff, unsigned len, int date_set)
{
t_elist *curr;
t_news_index *cni;
elist_for_each(curr,&news_head) {
cni = elist_entry(curr,t_news_index,list);
if (cni->date <= ni->date) break;
}
elist_for_each(curr, &news_head) {
cni = elist_entry(curr, t_news_index, list);
if (cni->date <= ni->date) break;
}
if (curr != &news_head && cni->date == ni->date) {
if (date_set == 1)
eventlog(eventlog_level_warn,__FUNCTION__,"found another news item for same date, trying to join both");
if (curr != &news_head && cni->date == ni->date) {
if (date_set == 1)
eventlog(eventlog_level_warn, __FUNCTION__, "found another news item for same date, trying to join both");
if ((lstr_get_len(&cni->body) + len + 2) > 1023)
eventlog(eventlog_level_error, __FUNCTION__, "failed in joining news, cause news too long - skipping");
else {
lstr_set_str(&cni->body, (char*)xrealloc(lstr_get_str(&cni->body), lstr_get_len(&cni->body) + len + 1 + 1));
std::strcpy(lstr_get_str(&cni->body) + lstr_get_len(&cni->body), buff);
*(lstr_get_str(&cni->body) + lstr_get_len(&cni->body) + len) = '\n';
*(lstr_get_str(&cni->body) + lstr_get_len(&cni->body) + len + 1) = '\0';
lstr_set_len(&cni->body, lstr_get_len(&cni->body) + len + 1);
}
xfree((void *)ni);
}
else {
/* adding new index entry */
lstr_set_str(&ni->body, (char*)xmalloc(len + 2));
std::strcpy(lstr_get_str(&ni->body), buff);
std::strcat(lstr_get_str(&ni->body), "\n");
lstr_set_len(&ni->body, len + 1);
elist_add_tail(curr, &ni->list);
}
}
static void _news_insert_default(void)
{
const char * deftext = "No news today";
t_news_index *ni;
ni = (t_news_index*)xmalloc(sizeof(t_news_index));
ni->date = std::time(NULL);
_news_insert_index(ni, deftext, std::strlen(deftext), 1);
}
extern int news_load(const char *filename)
{
std::FILE * fp;
unsigned int line;
unsigned int len;
char buff[256];
struct std::tm date;
char date_set;
t_news_index *ni;
elist_init(&news_head);
date_set = 0;
if (!filename) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL fullname");
return -1;
}
if ((fp = std::fopen(filename, "rt")) == NULL) {
eventlog(eventlog_level_warn, __FUNCTION__, "can't open news file");
_news_insert_default();
return 0;
}
for (line = 1; std::fgets(buff, sizeof(buff), fp); line++) {
len = std::strlen(buff);
while (len && (buff[len - 1] == '\n' || buff[len - 1] == '\r')) len--;
if (!len) continue; /* empty line */
buff[len] = '\0';
if (buff[0] == '{') {
if (_news_parsetime(buff + 1, &date, line)) {
eventlog(eventlog_level_error, __FUNCTION__, "error parsing news date on line %u", line);
return -1;
}
date_set = 1;
}
else {
ni = (t_news_index*)xmalloc(sizeof(t_news_index));
if (date_set)
ni->date = std::mktime(&date);
else {
ni->date = std::time(NULL);
eventlog(eventlog_level_warn, __FUNCTION__, "(first) news entry seems to be missing a timestamp, please check your news file on line %u", line);
}
_news_insert_index(ni, buff, len, date_set);
date_set = 2;
}
}
std::fclose(fp);
if (elist_empty(&news_head)) {
eventlog(eventlog_level_warn, __FUNCTION__, "no news configured");
_news_insert_default();
}
return 0;
}
/* Free up all of the elements in the linked list */
extern int news_unload(void)
{
t_elist * curr, *save;
t_news_index * ni;
elist_for_each_safe(curr, &news_head, save)
{
ni = elist_entry(curr, t_news_index, list);
elist_del(&ni->list);
xfree((void *)lstr_get_str(&ni->body));
xfree((void *)ni);
}
elist_init(&news_head);
return 0;
}
extern unsigned int news_get_lastnews(void)
{
if (elist_empty(&news_head)) return 0;
return ((elist_entry(news_head.next, t_news_index, list))->date);
}
extern unsigned int news_get_firstnews(void)
{
if (elist_empty(&news_head)) return 0;
return ((elist_entry(news_head.prev, t_news_index, list))->date);
}
extern void news_traverse(t_news_cb cb, void *data)
{
t_elist *curr;
t_news_index *cni;
assert(cb);
elist_for_each(curr, &news_head)
{
cni = elist_entry(curr, t_news_index, list);
if (cb(cni->date, &cni->body, data)) break;
}
}
if ((lstr_get_len(&cni->body) + len +2) > 1023)
eventlog(eventlog_level_error,__FUNCTION__,"failed in joining news, cause news too long - skipping");
else {
lstr_set_str(&cni->body,(char*)xrealloc(lstr_get_str(&cni->body),lstr_get_len(&cni->body) + len + 1 + 1));
std::strcpy(lstr_get_str(&cni->body) + lstr_get_len(&cni->body), buff);
*(lstr_get_str(&cni->body) + lstr_get_len(&cni->body) + len) = '\n';
*(lstr_get_str(&cni->body) + lstr_get_len(&cni->body) + len + 1) = '\0';
lstr_set_len(&cni->body,lstr_get_len(&cni->body) + len + 1);
}
xfree((void *)ni);
} else {
/* adding new index entry */
lstr_set_str(&ni->body,(char*)xmalloc(len + 2));
std::strcpy(lstr_get_str(&ni->body),buff);
std::strcat(lstr_get_str(&ni->body),"\n");
lstr_set_len(&ni->body,len + 1);
elist_add_tail(curr,&ni->list);
}
}
static void _news_insert_default(void)
{
const char * deftext = "No news today";
t_news_index *ni;
ni = (t_news_index*)xmalloc(sizeof(t_news_index));
ni->date = std::time(NULL);
_news_insert_index(ni, deftext, std::strlen(deftext), 1);
}
extern int news_load(const char *filename)
{
std::FILE * fp;
unsigned int line;
unsigned int len;
char buff[256];
struct std::tm date;
char date_set;
t_news_index *ni;
elist_init(&news_head);
date_set = 0;
if (!filename) {
eventlog(eventlog_level_error, __FUNCTION__,"got NULL fullname");
return -1;
}
if ((fp = std::fopen(filename,"rt"))==NULL) {
eventlog(eventlog_level_warn, __FUNCTION__,"can't open news file");
_news_insert_default();
return 0;
}
for (line=1; std::fgets(buff,sizeof(buff),fp); line++) {
len = std::strlen(buff);
while(len && (buff[len - 1] == '\n' || buff[len - 1] == '\r')) len--;
if (!len) continue; /* empty line */
buff[len] = '\0';
if (buff[0]=='{') {
if (_news_parsetime(buff + 1,&date, line)) {
eventlog(eventlog_level_error,__FUNCTION__,"error parsing news date on line %u",line);
return -1;
}
date_set = 1;
} else {
ni = (t_news_index*)xmalloc(sizeof(t_news_index));
if (date_set)
ni->date = std::mktime(&date);
else {
ni->date = std::time(NULL);
eventlog(eventlog_level_warn,__FUNCTION__,"(first) news entry seems to be missing a timestamp, please check your news file on line %u",line);
}
_news_insert_index(ni,buff,len,date_set);
date_set = 2;
}
}
std::fclose(fp);
if (elist_empty(&news_head)) {
eventlog(eventlog_level_warn,__FUNCTION__,"no news configured");
_news_insert_default();
}
return 0;
}
/* Free up all of the elements in the linked list */
extern int news_unload(void)
{
t_elist * curr, *save;
t_news_index * ni;
elist_for_each_safe(curr,&news_head,save)
{
ni = elist_entry(curr,t_news_index,list);
elist_del(&ni->list);
xfree((void *)lstr_get_str(&ni->body));
xfree((void *)ni);
}
elist_init(&news_head);
return 0;
}
extern unsigned int news_get_lastnews(void)
{
if (elist_empty(&news_head)) return 0;
return ((elist_entry(news_head.next,t_news_index,list))->date);
}
extern unsigned int news_get_firstnews(void)
{
if (elist_empty(&news_head)) return 0;
return ((elist_entry(news_head.prev,t_news_index,list))->date);
}
extern void news_traverse(t_news_cb cb, void *data)
{
t_elist *curr;
t_news_index *cni;
assert(cb);
elist_for_each(curr,&news_head)
{
cni = elist_entry(curr,t_news_index,list);
if (cb(cni->date,&cni->body,data)) break;
}
}
}
}

View file

@ -27,22 +27,22 @@
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
typedef struct news_index
typedef struct news_index
#ifdef NEWS_INTERNAL_ACCESS
{
std::time_t date;
t_lstr body;
t_elist list;
}
{
std::time_t date;
t_lstr body;
t_elist list;
}
#endif
t_news_index;
t_news_index;
typedef int (*t_news_cb)(std::time_t, t_lstr *, void *);
typedef int(*t_news_cb)(std::time_t, t_lstr *, void *);
}
}
}
@ -57,18 +57,18 @@ typedef int (*t_news_cb)(std::time_t, t_lstr *, void *);
namespace pvpgn
{
namespace bnetd
{
namespace bnetd
{
extern int news_load(const char *filename);
extern int news_unload(void);
extern int news_load(const char *filename);
extern int news_unload(void);
extern unsigned int news_get_firstnews(void);
extern unsigned int news_get_lastnews(void);
extern unsigned int news_get_firstnews(void);
extern unsigned int news_get_lastnews(void);
extern void news_traverse(t_news_cb cb, void *data);
extern void news_traverse(t_news_cb cb, void *data);
}
}
}

View file

@ -38,189 +38,189 @@
namespace pvpgn
{
namespace bnetd
{
char * status_filename;
int output_standard_writer(std::FILE * fp);
/*
* Initialisation Output *
*/
extern void output_init(void)
{
eventlog(eventlog_level_info,__FUNCTION__,"initializing output file");
if (prefs_get_XML_status_output())
status_filename = buildpath(prefs_get_outputdir(),"server.xml");
else
status_filename = buildpath(prefs_get_outputdir(),"server.dat");
return;
}
/*
* Write Functions *
*/
static int _glist_cb_xml(t_game *game, void *data)
{
char clienttag_str[5];
std::fprintf((std::FILE*)data,"\t\t<game><id>%u</id><name>%s</name><clienttag>%s</clienttag></game>\n",game_get_id(game),game_get_name(game),tag_uint_to_str(clienttag_str,game_get_clienttag(game)));
return 0;
}
static int _glist_cb_simple(t_game *game, void *data)
{
static int number;
char clienttag_str[5];
if (!data) {
number = 1;
return 0;
}
std::fprintf((std::FILE*)data,"game%d=%s,%u,%s\n",number,tag_uint_to_str(clienttag_str,game_get_clienttag(game)),game_get_id(game),game_get_name(game));
number++;
return 0;
}
int output_standard_writer(std::FILE * fp)
{
t_elem const *curr;
t_connection *conn;
t_channel const *channel;
t_game *game;
char const *channel_name;
int number;
char clienttag_str[5];
int uptime = server_get_uptime();
if (prefs_get_XML_status_output())
{
int seconds;
int minutes;
int hours;
int days;
days = (uptime/(60*60*24));
hours = (uptime/(60*60)) % 24;
minutes = (uptime/60) % 60;
seconds = uptime % 60;
std::fprintf(fp,"<?xml version=\"1.0\"?>\n<status>\n");
std::fprintf(fp,"\t\t<Version>%s</Version>\n",PVPGN_VERSION);
std::fprintf(fp,"\t\t<Uptime>\n");
std::fprintf(fp,"\t\t\t<Days>%d</Days>\n",days);
std::fprintf(fp,"\t\t\t<Hours>%d</Hours>\n",hours);
std::fprintf(fp,"\t\t\t<Minutes>%d</Minutes>\n",minutes);
std::fprintf(fp,"\t\t\t<Seconds>%d</Seconds>\n",seconds);
std::fprintf(fp,"\t\t</Uptime>\n");
std::fprintf(fp,"\t\t<Users>\n");
std::fprintf(fp,"\t\t<Number>%d</Number>\n",connlist_login_get_length());
LIST_TRAVERSE_CONST(connlist(),curr)
namespace bnetd
{
conn = (t_connection*)elem_get_data(curr);
if (conn_get_account(conn))
std::fprintf(fp,"\t\t<user><name>%s</name><clienttag>%s</clienttag><version>%s</version>",conn_get_username(conn),tag_uint_to_str(clienttag_str,conn_get_clienttag(conn)),conn_get_clientver(conn));
if ((game = conn_get_game(conn)))
std::fprintf(fp,"<gameid>%u</gameid>", game_get_id(game));
std::fprintf(fp,"</user>\n");
}
std::fprintf(fp,"\t\t</Users>\n");
std::fprintf(fp,"\t\t<Games>\n");
std::fprintf(fp,"\t\t<Number>%d</Number>\n",gamelist_get_length());
char * status_filename;
gamelist_traverse(_glist_cb_xml,fp);
int output_standard_writer(std::FILE * fp);
std::fprintf(fp,"\t\t</Games>\n");
std::fprintf(fp,"\t\t<Channels>\n");
std::fprintf(fp,"\t\t<Number>%d</Number>\n",channellist_get_length());
/*
* Initialisation Output *
*/
LIST_TRAVERSE_CONST(channellist(),curr)
{
channel = (t_channel*)elem_get_data(curr);
channel_name = channel_get_name(channel);
std::fprintf(fp,"\t\t<channel>%s</channel>\n",channel_name);
}
extern void output_init(void)
{
eventlog(eventlog_level_info, __FUNCTION__, "initializing output file");
std::fprintf(fp,"\t\t</Channels>\n");
std::fprintf(fp,"</status>\n");
return 0;
}
else
{
std::fprintf(fp,"[STATUS]\nVersion=%s\nUptime=%s\nGames=%d\nUsers=%d\nChannels=%d\nUserAccounts=%d\n",PVPGN_VERSION,seconds_to_timestr(uptime),gamelist_get_length(),connlist_login_get_length(),channellist_get_length(),accountlist_get_length()); // Status
std::fprintf(fp,"[CHANNELS]\n");
number=1;
LIST_TRAVERSE_CONST(channellist(),curr)
{
channel = (t_channel*)elem_get_data(curr);
channel_name = channel_get_name(channel);
std::fprintf(fp,"channel%d=%s\n",number,channel_name);
number++;
}
if (prefs_get_XML_status_output())
status_filename = buildpath(prefs_get_outputdir(), "server.xml");
else
status_filename = buildpath(prefs_get_outputdir(), "server.dat");
std::fprintf(fp,"[GAMES]\n");
_glist_cb_simple(NULL,NULL); /* init number */
gamelist_traverse(_glist_cb_simple,fp);
return;
}
std::fprintf(fp,"[USERS]\n");
number=1;
LIST_TRAVERSE_CONST(connlist(),curr)
{
conn = (t_connection*)elem_get_data(curr);
if (conn_get_account(conn))
{
std::fprintf(fp,"user%d=%s,%s,%s",number,tag_uint_to_str(clienttag_str,conn_get_clienttag(conn)),conn_get_username(conn),conn_get_clientver(conn));
/*
* Write Functions *
*/
if ((game = conn_get_game(conn)))
std::fprintf(fp,",%u", game_get_id(game));
std::fprintf(fp,"\n");
static int _glist_cb_xml(t_game *game, void *data)
{
char clienttag_str[5];
std::fprintf((std::FILE*)data, "\t\t<game><id>%u</id><name>%s</name><clienttag>%s</clienttag></game>\n", game_get_id(game), game_get_name(game), tag_uint_to_str(clienttag_str, game_get_clienttag(game)));
return 0;
}
static int _glist_cb_simple(t_game *game, void *data)
{
static int number;
char clienttag_str[5];
if (!data) {
number = 1;
return 0;
}
std::fprintf((std::FILE*)data, "game%d=%s,%u,%s\n", number, tag_uint_to_str(clienttag_str, game_get_clienttag(game)), game_get_id(game), game_get_name(game));
number++;
}
return 0;
}
int output_standard_writer(std::FILE * fp)
{
t_elem const *curr;
t_connection *conn;
t_channel const *channel;
t_game *game;
char const *channel_name;
int number;
char clienttag_str[5];
int uptime = server_get_uptime();
if (prefs_get_XML_status_output())
{
int seconds;
int minutes;
int hours;
int days;
days = (uptime / (60 * 60 * 24));
hours = (uptime / (60 * 60)) % 24;
minutes = (uptime / 60) % 60;
seconds = uptime % 60;
std::fprintf(fp, "<?xml version=\"1.0\"?>\n<status>\n");
std::fprintf(fp, "\t\t<Version>%s</Version>\n", PVPGN_VERSION);
std::fprintf(fp, "\t\t<Uptime>\n");
std::fprintf(fp, "\t\t\t<Days>%d</Days>\n", days);
std::fprintf(fp, "\t\t\t<Hours>%d</Hours>\n", hours);
std::fprintf(fp, "\t\t\t<Minutes>%d</Minutes>\n", minutes);
std::fprintf(fp, "\t\t\t<Seconds>%d</Seconds>\n", seconds);
std::fprintf(fp, "\t\t</Uptime>\n");
std::fprintf(fp, "\t\t<Users>\n");
std::fprintf(fp, "\t\t<Number>%d</Number>\n", connlist_login_get_length());
LIST_TRAVERSE_CONST(connlist(), curr)
{
conn = (t_connection*)elem_get_data(curr);
if (conn_get_account(conn))
std::fprintf(fp, "\t\t<user><name>%s</name><clienttag>%s</clienttag><version>%s</version>", conn_get_username(conn), tag_uint_to_str(clienttag_str, conn_get_clienttag(conn)), conn_get_clientver(conn));
if ((game = conn_get_game(conn)))
std::fprintf(fp, "<gameid>%u</gameid>", game_get_id(game));
std::fprintf(fp, "</user>\n");
}
std::fprintf(fp, "\t\t</Users>\n");
std::fprintf(fp, "\t\t<Games>\n");
std::fprintf(fp, "\t\t<Number>%d</Number>\n", gamelist_get_length());
gamelist_traverse(_glist_cb_xml, fp);
std::fprintf(fp, "\t\t</Games>\n");
std::fprintf(fp, "\t\t<Channels>\n");
std::fprintf(fp, "\t\t<Number>%d</Number>\n", channellist_get_length());
LIST_TRAVERSE_CONST(channellist(), curr)
{
channel = (t_channel*)elem_get_data(curr);
channel_name = channel_get_name(channel);
std::fprintf(fp, "\t\t<channel>%s</channel>\n", channel_name);
}
std::fprintf(fp, "\t\t</Channels>\n");
std::fprintf(fp, "</status>\n");
return 0;
}
else
{
std::fprintf(fp, "[STATUS]\nVersion=%s\nUptime=%s\nGames=%d\nUsers=%d\nChannels=%d\nUserAccounts=%d\n", PVPGN_VERSION, seconds_to_timestr(uptime), gamelist_get_length(), connlist_login_get_length(), channellist_get_length(), accountlist_get_length()); // Status
std::fprintf(fp, "[CHANNELS]\n");
number = 1;
LIST_TRAVERSE_CONST(channellist(), curr)
{
channel = (t_channel*)elem_get_data(curr);
channel_name = channel_get_name(channel);
std::fprintf(fp, "channel%d=%s\n", number, channel_name);
number++;
}
std::fprintf(fp, "[GAMES]\n");
_glist_cb_simple(NULL, NULL); /* init number */
gamelist_traverse(_glist_cb_simple, fp);
std::fprintf(fp, "[USERS]\n");
number = 1;
LIST_TRAVERSE_CONST(connlist(), curr)
{
conn = (t_connection*)elem_get_data(curr);
if (conn_get_account(conn))
{
std::fprintf(fp, "user%d=%s,%s,%s", number, tag_uint_to_str(clienttag_str, conn_get_clienttag(conn)), conn_get_username(conn), conn_get_clientver(conn));
if ((game = conn_get_game(conn)))
std::fprintf(fp, ",%u", game_get_id(game));
std::fprintf(fp, "\n");
number++;
}
}
return 0;
}
}
extern int output_write_to_file(void)
{
std::FILE * fp;
if (!status_filename)
{
eventlog(eventlog_level_error, __FUNCTION__, "got NULL filename");
return -1;
}
if (!(fp = std::fopen(status_filename, "w")))
{
eventlog(eventlog_level_error, __FUNCTION__, "could not open file \"%s\" for writing (std::fopen: %s)", status_filename, std::strerror(errno));
return -1;
}
output_standard_writer(fp);
std::fclose(fp);
return 0;
}
extern void output_dispose_filename(void)
{
if (status_filename) xfree(status_filename);
}
}
return 0;
}
}
extern int output_write_to_file(void)
{
std::FILE * fp;
if (!status_filename)
{
eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename");
return -1;
}
if (!(fp = std::fopen(status_filename,"w")))
{
eventlog(eventlog_level_error,__FUNCTION__,"could not open file \"%s\" for writing (std::fopen: %s)",status_filename,std::strerror(errno));
return -1;
}
output_standard_writer(fp);
std::fclose(fp);
return 0;
}
extern void output_dispose_filename(void)
{
if (status_filename) xfree(status_filename);
}
}
}

Some files were not shown because too many files have changed in this diff Show more