This commit is contained in:
HarpyWar 2014-04-11 20:01:23 +04:00
commit 68ed78fb91
54 changed files with 1371 additions and 134 deletions

View file

@ -4,10 +4,10 @@ set(OUTPUT_CONFS ad.conf anongame_infos.conf address_translation.conf
bnhelp.conf bnissue.txt bnmaps.conf bnxpcalc.conf bnmotd-enUS.txt
bnmotd-csCZ.txt bnmotd-deDE.txt bnmotd-esES.txt bnmotd-frFR.txt
bnmotd-nlNL.txt bnmotd-plPL.txt bnmotd-ruRU.txt bnmotd-zhCN.txt
bnmotd-zhTW.txt bnmotd-ptBR.txt
bnmotd-zhTW.txt bnmotd-ptBR.txt bnmotd_w3.txt
bnxplevel.conf channel.conf command_groups.conf news.txt realm.conf
sql_DB_layout2.conf sql_DB_layout.conf supportfile.conf topics.conf
tournament.conf versioncheck.conf)
tournament.conf versioncheck.conf icons.conf)
foreach(CONF ${OUTPUT_CONFS})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${CONF}.in ${CMAKE_CURRENT_BINARY_DIR}/${CONF} @ONLY)
endforeach(CONF)
@ -23,18 +23,18 @@ if(WITH_BNETD)
bnetd_default_user.plain bnhelp.conf bnissue.txt bnmaps.conf bnmotd-enUS.txt
bnmotd-csCZ.txt bnmotd-deDE.txt bnmotd-esES.txt bnmotd-frFR.txt bnmotd-nlNL.txt
bnmotd-plPL.txt bnmotd-ruRU.txt bnmotd-zhCN.txt bnmotd-zhTW.txt bnmotd-ptBR.txt
bnxpcalc.conf bnxplevel.conf channel.conf command_groups.conf news.txt
bnxpcalc.conf bnxplevel.conf channel.conf command_groups.conf news.txt bnmotd_w3.txt
realm.conf sql_DB_layout.conf sql_DB_layout2.conf supportfile.conf topics.conf
tournament.conf versioncheck.conf)
tournament.conf versioncheck.conf icons.conf)
# special treatement for non .in files
# special treatment for non .in files
install(FILES bnetd_default_user.cdb DESTINATION ${SYSCONFDIR})
endif(WITH_BNETD)
if(WITH_D2CS)
set(D2CS_CONFS d2cs.conf anongame_infos.conf)
# special treatement for non .in files
# special treatment for non .in files
install(FILES d2server.ini DESTINATION ${SYSCONFDIR})
endif(WITH_D2CS)

View file

@ -81,7 +81,8 @@ storage_path = "file:mode=plain;dir=${LOCALSTATEDIR}/users;clan=${LOCALSTATEDIR}
filedir = "${LOCALSTATEDIR}/files"
reportdir = "${LOCALSTATEDIR}/reports"
chanlogdir = "${LOCALSTATEDIR}/chanlogs"
motdfile = "${SYSCONFDIR}/bnmotd-enUS.txt"
motdfile = "${SYSCONFDIR}/bnmotd.txt"
motdw3file = "${SYSCONFDIR}/bnmotd_w3.txt"
issuefile = "${SYSCONFDIR}/bnissue.txt"
channelfile = "${SYSCONFDIR}/channel.conf"
newsfile = "${SYSCONFDIR}/news.txt"
@ -107,6 +108,7 @@ anongame_infos_file = "${SYSCONFDIR}/anongame_infos.conf"
DBlayoutfile = "${SYSCONFDIR}/sql_DB_layout.conf"
supportfile = "${SYSCONFDIR}/supportfile.conf"
transfile = "${SYSCONFDIR}/address_translation.conf"
customicons_file = "${SYSCONFDIR}/icons.conf"
fortunecmd = /usr/games/fortune

View file

@ -62,6 +62,7 @@ filedir = files
reportdir = var\reports
chanlogdir = var\chanlogs
motdfile = conf\bnmotd.txt
motdw3file = conf\bnmotd_w3.txt
issuefile = conf\bnissue.txt
channelfile = conf\channel.conf
newsfile = conf\news.txt
@ -85,6 +86,7 @@ aliasfile = conf\bnalias.conf
anongame_infos_file = conf\anongame_infos.conf
DBlayoutfile = conf\sql_DB_layout.conf
supportfile = conf\supportfile.conf
customicons_file = conf\icons.conf
fortunecmd = bin\fortune.exe

View file

@ -53,7 +53,8 @@ whois <player> - looks up some basic information on a user, including their acco
%lusers
/lusers - shows list of banned players in this channel
%games
/games [<gametag>] - displays current game list
/games [<gametag>] - displays current game list of client type gametag, e.g. W3XP - Warcraft 3 TFT
/games [lobby], /games [l] - displays current list of games that are in the lobby (i.e. haven't started)
%channels chs
/channels /chs [all] - displays current channel list
%connections con
@ -114,6 +115,7 @@ whois <player> - looks up some basic information on a user, including their acco
/friends promote <username> - promote user in your friends list
/friends demote <username> - demote user in your friends list
/friends list - list all users in your friends list
/friends online - list all online users in your friends list
/friends msg <msgtext> - whispers to all your online friends
%mail
/mail <command> [<options>] - mail management commands
@ -200,5 +202,12 @@ Disband your clan
/clearstats - used to clear game statistics of a given user/clienttag
Syntax: /clearstats <user> <clienttag>
<clienttag> can be one of DSHR,DRTL,SSHR,STAR,SEXP,W2BNE,WAR3,W3XP,ALL
%find
/find - used to find users with similar name
Syntax: /find <substring to find>
<substring to find> needs to be in lower case
%save
/save - used to force save accounts changes from a cache into database
Syntax: /save
# #
##############################################################################

View file

@ -1,4 +1,4 @@
%IЗдравей %l, добре дошъл в %s!
%EЗдравей %l, добре дошъл в %s!
%IВерсията на сървъра е %v на %h.
%IТози сървър се хоства от %H
%I
@ -8,4 +8,6 @@
%IИмате проблем с команда? Въведете /help за да
%Iнаучите повече за нея.
%I
%I(edit this text in conf/bnmotd-bgBG.txt)
%I
%I%m

View file

@ -1,14 +1,14 @@
%IAhoj %l,
%EAhoj %l,
%IVitej na serveru %s, verze %v.
%I
%I
%IMomentalne je zde registrovanych %a uzivatelu, z toho je %u online, hrajicich %g hry.
%I
%I%N si muzes zahrat s %U hraci, v %G prave probihajicich hrach nebo si muzes pokecat v %c chatech.
%I
%I
%INevis si rady ? Napis /help pro napovedu.
%I
%I
%ITvoje IP adresa: %r, tvoje ID %i a tvuj klient %t.
%ICZ MOTD by Machy_CZ
%I
%I(edit this text in conf/bnmotd-csCZ.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%IHallo %l, willkommen zu %s!
%EHallo %l, willkommen zu %s!
%ILaufende Version %v auf %h.
%IDer Server ist von %H gehostet
%I
@ -8,4 +8,6 @@
%IEin Problem mit den Kommandos? Schreibe /help und
%Ilerne mehr über die Kommandos.
%I
%I%m
%I(edit this text in conf/bnmotd-deDE.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%IHello %l, welcome to %s!
%EHello %l, welcome to %s!
%IRunning version %v on %h.
%IThis server is hosted by %H
%I
@ -8,4 +8,6 @@
%IHaving trouble with a command? Type /help to
%Ilearn more about it.
%I
%I%m
%I(edit this text in conf/bnmotd-enUS.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%IHola %l, bienvenido a %s!
%EHola %l, bienvenido a %s!
%IEn %h se usa la versión %v
%IEste servidor es alojado por %H
%I
@ -8,4 +8,6 @@
%ITiene problemas con algun comando? Teclee "/help" para
%Iaprender más sobre los comandos.
%I
%I%m
%I(edit this text in conf/bnmotd-ptBR.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%IBonjour %l, bienvenue sur %s!
%EBonjour %l, bienvenue sur %s!
%IUtilisant la version %v sur %h.
%ICe serveur est hébergé par %H
%I
@ -8,4 +8,6 @@
%IUn problème avec une commande ? Tappez /help pour
%Ien savoir plus.
%I
%I%m
%I(edit this text in conf/bnmotd-ptBR.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%I%l さん, PvPGN サーバへようこそ!
%E%l さん, PvPGN サーバへようこそ!
%I%h さんが %v を運用します。
%Iこのサーバは今 %H さんがホスティング中です。
%I
@ -8,4 +8,6 @@
%I%c 個のチャンネが生成しました。
%Iコマンド・リストは「/help」をタイプして下さい。
%I
%I%m
%I(edit this text in conf/bnmotd-ptBR.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%I안녕하세요 %l 님, PvPGN 서버에 오신것을 환영합니다!
%E안녕하세요 %l 님, PvPGN 서버에 오신것을 환영합니다!
%I%h 님이 %v 를 구동하고 계십니다.
%I본 서버는 %H 님이 호스팅하고 계십니다.
%I
@ -8,4 +8,6 @@
%I명령어의 대해 궁금한 사항이 있으시다구요?
%I/help 명령어를 이용해 보세요.
%I
%I%m
%I(edit this text in conf/bnmotd-ptBR.txt)
%I
%M%m

View file

@ -1,5 +1,5 @@
%IHallo %l, welom bij %s!
%IWe draaien versie %v op %h.
%EWe draaien versie %v op %h.
%IDeze server wordt gehost bij %H
%I
%IEr zijn %a gebruikers accounts op deze server.
@ -8,4 +8,6 @@
%IProblemen met een commando? Type /help om
%Ier meer te weten over te komen.
%I
%I%m
%I(edit this text in conf/bnmotd-nlNL.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%ICześć %l, witaj w %s!
%ECześć %l, witaj w %s!
%IWersja serwera %v uruchomiona na %h.
%ISerwer obsługuje %H
%I
@ -8,4 +8,6 @@
%IJeśli masz jakieś problemy z poleceniami, to napiszsz /help aby
%Idowiedzieć się wiecej.
%I
%I%m
%I(edit this text in conf/bnmotd-plPL.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%IOlá %l, Bem vindo a %s!
%EOlá %l, Bem vindo a %s!
%IRodando a versão %v em %h.
%IEste servidor é hosteado por %H
%I
@ -8,4 +8,6 @@
%ITendo algum problema com comando? Digite /help ra
%Aprender mais sobre.
%I
%I%m
%I(edit this text in conf/bnmotd-ptBR.txt)
%I
%M%m

View file

@ -1,11 +1,13 @@
%IПривет %l, добро пожаловать на %s!
%EПривет %l, добро пожаловать на %s!
%IВерсия сервера %v.
%IСервер расположен у %h (%H)
%IСервер расположен у %H (%h)
%I
%IСейчас на сервере %a игроков.
%IВ %G играх находятся %U игроков %N
%Iиз них %u играют в %g играх и сидят на %c каналах.
%IНа сервере зарегистрировано %a аккаунтов.
%IСейчас %G игр и %U игроков в %N
%Iиз них %u находятся в %g играх и общаются на %c каналах.
%I
%IВведите /help для получения помощи по командам чата
%IВведите /help для получения помощи по командам чата
%I
%I%m
%I(измените этот текст в файле conf/bnmotd-ruRU.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%IHej %l, välkommen till %s!
%EHej %l, välkommen till %s!
%IKör version %v på %h.
%IVärden för den här servern är %H
%I
@ -8,4 +8,6 @@
%IHar du problem med ett kommando? Skriv /help för
%Iatt lära dig mer om det.
%I
%I%m
%I(edit this text in conf/bnmotd-svSE.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%I%l你好。欢迎来到 %s
%E%l你好。欢迎来到 %s
%I现在 %h 正在运行的版本为 %v
%I本服务器由 %H 管理维护
%I
@ -8,4 +8,6 @@
%I还不了解可以使用哪些命令
%I输入 /help 就可以学习了
%I
%I%m
%I(edit this text in conf/bnmotd-zhCB.txt)
%I
%M%m

View file

@ -1,4 +1,4 @@
%I哈囉! %l, 歡迎蒞臨 %s!
%E哈囉! %l, 歡迎蒞臨 %s!
%I本伺服器由 %H 架設於 %h.
%I現行的伺服器版本是 %v.
%I
@ -7,4 +7,6 @@
%I其中有 %u 個玩家一邊在玩 %g 個遊戲一邊在 %c 個聊天頻道.
%I不懂使用指令? 請輸入 /help 來了解更多...
%I
%I%m
%I(edit this text in conf/bnmotd-zhTW.txt)
%I
%M%m

12
conf/bnmotd_w3.txt.in Normal file
View file

@ -0,0 +1,12 @@
Welcome to the greatest PvPGN server!
|c00FF0000Here |c00FF9933you |c0000CCFFcan |c00A8A8A8 use |c0000CC00coloured |c00FFFF00text |c009999FFas |c00FF66FFfollow|c00FFFFFF:
"|00HEXCOLOR your text here"
(edit this text in conf/bnmotd_w3.txt)
This text will not displayed, because there is limitation of 11 lines

View file

@ -158,9 +158,9 @@
6 /operator /admin /flag /tag
7 /set /commandgroups /cg /clearstats
7 /set /commandgroups /cg /clearstats /icon
8 /shutdown /rehash /save
8 /shutdown /rehash /find /save
# //////////////////////////////////////
# ///// End of Command Groups File /////

106
conf/icons.conf.in Normal file
View file

@ -0,0 +1,106 @@
##############################################################################
# icons.conf - Custom icons configuration file #
#----------------------------------------------------------------------------#
# #
# Allowed clients: #
# W3XP, WAR3, STAR, SEXP, JSTR, SSHR, W2BN, DRTL, DSHR #
# #
# W3XP: It also disables icon selection from user portrait #
# #
# [icons] table format (first variable always corresponds to icon_key: #
# icon_key | rank | icon_code #
# #
# [stats] output format: #
# initialize variables under a client tag #
# band variables with figure brackets {{var}} #
# use {{variable->rank}} to display an icon rank for a custom variable #
# #
##############################################################################
##############################################################################
# General settings #
#----------------------------------------------------------------------------#
# Enable icon sets below
custom_icons = false
##############################################################################
# Warcraft 3 icon set #
# Use MPQ editor to edit icons-WAR3.bni (just change extension bni->mpq) #
#----------------------------------------------------------------------------#
[W3XP]
solo_level = "Record\W3XP\solo_level"
solo_xp = "Record\W3XP\solo_xp"
solo_wins = "Record\W3XP\solo_wins"
solo_losses = "Record\W3XP\solo_losses"
team_level = "Record\W3XP\team_level"
team_xp = "Record\W3XP\team_xp"
team_wins = "Record\W3XP\team_wins"
team_losses = "Record\W3XP\team_losses"
ffa_level = "Record\W3XP\ffa_level"
ffa_xp = "Record\W3XP\ffa_xp"
ffa_wins = "Record\W3XP\ffa_wins"
ffa_losses = "Record\W3XP\ffa_losses"
username = "BNET\acct\username"
[icons]
0 Beginner KBKB
1 Dungeon KBKD
2 Expert KBKE
3 Mid KBKM
4 Pro KBKP
5 World KBKW
6 Universe WCYB
[/icons]
[stats]
{{username}}'s record:
Solo games: [{{solo_level->rank}}] {{solo_xp}} xp ({{solo_wins}} - {{solo_losses}})
Team games: [{{team_level->rank}}] {{team_xp}} xp ({{team_wins}} - {{team_losses}})
FFA games: [{{ffa_level->rank}}] {{ffa_xp}} xp ({{ffa_wins}} - {{ffa_losses}})
[/stats]
##############################################################################
# Starcraft icon set #
# Use Bni Icon Builder to edit icons.bni (icons_STAR.bni is not used) #
# https://github.com/HarpyWar/bni-icon-builder #
#----------------------------------------------------------------------------#
[SEXP]
rating1 = "Record\SEXP\1_rating"
wins1 = "Record\SEXP\1_wins"
losses1 = "Record\SEXP\1_losses"
disconnects1 = "Record\SEXP\1_disconnects"
rating0 = "Record\SEXP\0_rating"
wins0 = "Record\SEXP\0_wins"
losses0 = "Record\SEXP\0_losses"
disconnects0 = "Record\SEXP\0_disconnects"
username = "BNET\acct\username"
[icons]
1000 n00b NOOB
1250 Chobo+ CHO1
1500 Chobo++ CHO2
1750 Chobo+++ CHO3
2000 Hasu+ HAS1
2300 Hasu++ HAS2
2650 Hasu+++ HAS3
3000 Gosu+ GOS1
3300 Gosu++ GOS2
3650 Gosu+++ GOS3
4000 Mega Gosu GOSU
5500 Father MEGA
[/icons]
[stats]
{{username}}'s record:
Ladder games: [{{rating1->rank}}] {{rating1}} pts ({{wins1}}/{{losses1}}/{{disconnects1}})
Normal games: [{{rating0->rank}}] {{rating0}} pts ({{wins0}}/{{losses0}}/{{disconnects0}})
[/stats]

View file

@ -1,26 +1,32 @@
{03/28/2014}
(edit this text in conf/news.txt)
Note that Warcraft 3 client caches news in bncache.dat
(remove the file on the client side before login to see the changes immediately)
New support channel at:
http://pvpgn.pro
{10/01/2004}
Welcome To The Player-vs-Player Gaming Network!
Bringing Emulation To New Levels!
=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=
** IF YOU EXPERIENCE PROBLEMS USING THIS SERVER PLEASE REPORT IT TO THE **
********* ADMINISTRATOR OF THE SERVER NOT TO THE PVPGN TEAM ************
Project development homepage: http://pvpgn.berlios.de
Support channels (ONLY for the admins):
========================================
1. BugTracker (preffered support method):
http://sourceforge.net/tracker/?atid=470605&group_id=53514&func=browse
2. Mailing List: pvpgn-users@lists.sourceforge.net (to subscribe go here
http://lists.sourceforge.net/lists/listinfo/pvpgn-users )
3. Forums: http://forums.pvpgn.org
4. IRC live support: #pvpgn on irc.pvpgn.org
1. Forums: http://forums.pvpgn.org
2. IRC live support: #pvpgn on irc.pvpgn.org
Enjoy!
The PvPGN Team
http://www.PvPGN.org

Binary file not shown.

View file

@ -19,3 +19,5 @@ Battle.net(R) and Blizzard Entertainment(R) are trademarks or registered tradema
Besides all this... Happy gaming..
PvPGN Project Page: http://pvpgn.berlios.de/
(edit this text in var/files/newaccount-default.txt)

View file

@ -19,3 +19,5 @@ Battle.net(R) and Blizzard Entertainment(R) are trademarks or registered tradema
Besides all this... Happy gaming..
PvPGN Project Page: http://pvpgn.berlios.de/
(edit this text in var/files/newaccount-enUS.txt)

View file

@ -19,3 +19,5 @@ Battle.net(R) and Blizzard Entertainment(R) are trademarks or registered tradema
Besides all this... Happy gaming..
PvPGN Project Page: http://pvpgn.berlios.de/
(edit this text in var/files/termsofservice-default.txt)

View file

@ -19,3 +19,5 @@ Battle.net(R) and Blizzard Entertainment(R) are trademarks or registered tradema
Besides all this... Happy gaming..
PvPGN Project Page: http://pvpgn.berlios.de/
(edit this text in var/files/termsofservice-enUS.txt)

View file

@ -19,3 +19,5 @@ Battle.net(R) and Blizzard Entertainment(R) are trademarks or registered tradema
Besides all this... Happy gaming..
PvPGN Project Page: http://pvpgn.berlios.de/
(edit this text in var/files/tos-unicode_default.txt)

View file

@ -19,3 +19,5 @@ Battle.net(R) and Blizzard Entertainment(R) are trademarks or registered tradema
Besides all this... Happy gaming..
PvPGN Project Page: http://pvpgn.berlios.de/
(edit this text in var/files/tos.txt)

View file

@ -19,3 +19,5 @@ Battle.net(R) and Blizzard Entertainment(R) are trademarks or registered tradema
Besides all this... Happy gaming..
PvPGN Project Page: http://pvpgn.berlios.de/
(edit this text in var/files/tos-defaut.txt)

View file

@ -31,7 +31,7 @@ set(BNETD_SOURCES
storage.cpp storage_file.cpp storage_file.h storage.h storage_sql2.cpp
storage_sql2.h storage_sql.cpp storage_sql.h support.cpp support.h
team.cpp team.h tick.cpp tick.h timer.cpp timer.h topic.cpp topic.h
tournament.cpp tournament.h tracker.cpp tracker.h udptest_send.cpp
tournament.cpp tournament.h icons.cpp icons.h tracker.cpp tracker.h udptest_send.cpp
udptest_send.h versioncheck.cpp versioncheck.h watch.cpp watch.h
anongame_wol.cpp anongame_wol.h handle_wserv.cpp handle_wserv.h
../win32/winmain.cpp ../win32/winmain.h

View file

@ -545,6 +545,38 @@ namespace pvpgn
}
extern char const *accountlist_find_vague_account(t_account * account, char const *vague_username)
{
char const *tname;
int i;
if (!vague_username) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL vague_username");
return NULL;
}
if (!account) {
eventlog(eventlog_level_error, __FUNCTION__, "got NULL account");
return NULL;
}
if (tname = account_get_name(account)) {
char temp[MAX_USERNAME_LEN];
for (i = 0; i < std::strlen(tname); i++) {
temp[i] = tname[i];
if (isupper((int)temp[i])) {
temp[i] = tolower((int)temp[i]);
}
}
if (strstr(temp, vague_username)) {
return tname;
}
return NULL;
}
return NULL;
}
extern int accountlist_allow_add(void)
{
if (force_account_add)

View file

@ -106,6 +106,7 @@ namespace pvpgn
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 char const *accountlist_find_vague_account(t_account * account, char const *vague_username);
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 *);

View file

@ -453,6 +453,11 @@ namespace pvpgn
/****************************************************************/
/* Account creation time */
extern unsigned int account_get_ll_ctime(t_account * account)
{
return account_get_numattr(account, "BNET\\acct\\ctime");
}
extern unsigned int account_get_ll_time(t_account * account)
{

View file

@ -89,6 +89,7 @@ namespace pvpgn
extern char const * account_get_desc(t_account * account);
/* last login */
extern unsigned int account_get_ll_ctime(t_account * account);
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);

View file

@ -50,6 +50,7 @@
#include "common/xstr.h"
#include "common/trans.h"
#include "common/lstr.h"
#include "common/hashtable.h"
#include "connection.h"
#include "message.h"
@ -75,6 +76,7 @@
#include "clan.h"
#include "common/setup_after.h"
#include "common/flags.h"
#include "icons.h"
#include "attrlayer.h"
@ -333,6 +335,7 @@ namespace pvpgn
static int _handle_gameinfo_command(t_connection * c, char const * text);
static int _handle_ladderactivate_command(t_connection * c, char const * text);
static int _handle_rehash_command(t_connection * c, char const * text);
static int _handle_find_command(t_connection * c, char const *text);
static int _handle_save_command(t_connection * c, char const * text);
//static int _handle_rank_all_accounts_command(t_connection * c, char const * text);
@ -358,6 +361,7 @@ namespace pvpgn
static int _handle_moderate_command(t_connection * c, char const * text);
static int _handle_clearstats_command(t_connection * c, char const * text);
static int _handle_tos_command(t_connection * c, char const * text);
static int _handle_icon_command(t_connection * c, char const * text);
static const t_command_table_row standard_command_table[] =
{
@ -445,6 +449,7 @@ namespace pvpgn
{ "/gameinfo", _handle_gameinfo_command },
{ "/ladderactivate", _handle_ladderactivate_command },
{ "/rehash", _handle_rehash_command },
{ "/find", _handle_find_command },
{ "/save", _handle_save_command },
// { "/rank_all_accounts" , _handle_rank_all_accounts_command },
{ "/shutdown", _handle_shutdown_command },
@ -473,6 +478,7 @@ namespace pvpgn
{ "/topic", _handle_topic_command },
{ "/moderate", _handle_moderate_command },
{ "/clearstats", _handle_clearstats_command },
{ "/icon", _handle_icon_command },
{ NULL, NULL }
@ -1665,7 +1671,7 @@ namespace pvpgn
return 0;
}
}
else if (strstart(text, "list") == 0 || strstart(text, "l") == 0) {
else if (strstart(text, "list") == 0 || strstart(text, "l") == 0 || strstart(text, "online") == 0 || strstart(text, "o") == 0) {
char const * frienduid;
char status[128];
char software[64];
@ -1678,8 +1684,17 @@ namespace pvpgn
t_list * flist;
int num;
unsigned int uid;
bool online_only = false;
message_send_text(c, message_type_info, c, "Your PvPGN - Friends List");
if (strstart(text, "online") == 0 || strstart(text, "o") == 0) {
online_only = true;
}
if (!online_only) {
message_send_text(c, message_type_info, c, "Your PvPGN - Friends List");
}
else {
message_send_text(c, message_type_info, c, "Your PvPGN - Online Friends List");
}
message_send_text(c, message_type_info, c, "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
num = account_get_friendcount(my_acc);
@ -1694,8 +1709,12 @@ namespace pvpgn
}
software[0] = '\0';
friend_acc = friend_get_account(fr);
if (!(dest_c = connlist_find_connection_by_account(friend_acc)))
if (!(dest_c = connlist_find_connection_by_account(friend_acc))) {
if (online_only) {
continue;
}
std::sprintf(status, ", offline");
}
else {
std::sprintf(software, " using %s", clienttag_get_title(conn_get_clienttag(dest_c)));
@ -1737,6 +1756,7 @@ namespace pvpgn
message_send_text(c, message_type_info, c, "Type: /f promote <username> (promote a friend in your list)");
message_send_text(c, message_type_info, c, "Type: /f demote <username> (demote a friend in your list)");
message_send_text(c, message_type_info, c, "Type: /f list (shows your full friends list)");
message_send_text(c, message_type_info, c, "Type: /f online (shows your online friends list)");
message_send_text(c, message_type_info, c, "Type: /f msg (whispers a message to all your friends at once)");
}
@ -2168,6 +2188,29 @@ namespace pvpgn
clienttag_uint = tag_case_str_to_uint(clienttag);
// custom stats
if (prefs_get_custom_icons() == 1)
{
const char *text;
// if text is not empty
if (text = get_custom_stats_text(account, clienttag_uint))
{
// split by lines
char* output_array = strtok((char*)text, "\n");
while (output_array)
{
message_send_text(c, message_type_info, c, output_array);
output_array = strtok(NULL, "\n");
}
xfree((char*)text);
return 0;
}
}
switch (clienttag_uint)
{
case CLIENTTAG_BNCHATBOT_UINT:
@ -2982,6 +3025,7 @@ namespace pvpgn
t_game_difficulty diff;
t_clienttag tag;
t_connection *c;
bool lobby;
};
static int _glist_cb(t_game *game, void *data)
@ -2990,7 +3034,8 @@ namespace pvpgn
if ((!cbdata->tag || !prefs_get_hide_pass_games() || game_get_flag(game) != game_flag_private) &&
(!cbdata->tag || game_get_clienttag(game) == cbdata->tag) &&
(cbdata->diff == game_difficulty_none || game_get_difficulty(game) == cbdata->diff))
(cbdata->diff == game_difficulty_none || game_get_difficulty(game) == cbdata->diff) &&
(cbdata->lobby == false || (game_get_status(game) != game_status_started && game_get_status(game) != game_status_done)))
{
snprintf(msgtemp, sizeof(msgtemp), " %-16.16s %1.1s %-8.8s %-21.21s %5u ",
game_get_name(game),
@ -3020,7 +3065,7 @@ namespace pvpgn
unsigned int i;
unsigned int j;
char clienttag_str[5];
char dest[5];
char dest[6];
struct glist_cb_struct cbdata;
for (i = 0; text[i] != ' ' && text[i] != '\0'; i++); /* skip command */
@ -3031,6 +3076,7 @@ namespace pvpgn
for (; text[i] == ' '; i++);
cbdata.c = c;
cbdata.lobby = false;
if (std::strcmp(&text[i], "norm") == 0)
cbdata.diff = game_difficulty_normal;
@ -3051,6 +3097,12 @@ namespace pvpgn
cbdata.tag = 0;
message_send_text(c, message_type_info, c, "All current games:");
}
else if (strcasecmp(&dest[0], "lobby") == 0 || strcasecmp(&dest[0], "l") == 0)
{
cbdata.tag = conn_get_clienttag(c);
cbdata.lobby = true;
message_send_text(c, message_type_info, c, "Games in lobby:");
}
else
{
cbdata.tag = tag_case_str_to_uint(&dest[0]);
@ -3415,6 +3467,8 @@ namespace pvpgn
char const * ip;
char * tok;
t_clanmember * clanmemb;
std::time_t then;
struct std::tm * tmthen;
for (i = 0; text[i] != ' ' && text[i] != '\0'; i++); /* skip command */
for (; text[i] == ' '; i++);
@ -3434,12 +3488,19 @@ namespace pvpgn
message_send_text(c, message_type_error, c, "Invalid user.");
return 0;
}
then = account_get_ll_ctime(account);
tmthen = std::localtime(&then); /* FIXME: determine user's timezone */
snprintf(msgtemp, sizeof(msgtemp), "Login: %-16.16s "UID_FORMAT" Sex: %.14s",
account_get_name(account),
account_get_uid(account),
account_get_sex(account));
message_send_text(c, message_type_info, c, msgtemp);
std::strftime(msgtemp, sizeof(msgtemp), "Created: %a %b %d %H:%M %Y ", tmthen);
message_send_text(c, message_type_info, c, msgtemp);
if ((clanmemb = account_get_clanmember(account)))
{
t_clan * clan;
@ -3491,8 +3552,6 @@ namespace pvpgn
ip = "unknown";
{
std::time_t then;
struct std::tm * tmthen;
then = account_get_ll_time(account);
tmthen = std::localtime(&then); /* FIXME: determine user's timezone */
@ -3514,13 +3573,17 @@ namespace pvpgn
if ((account_get_command_groups(conn_get_account(c)) & command_get_group("/admin-addr")))
{
/* the player who requested /finger has admin privileges
give him more info about the one he querys;
is_admin, is_operator, is_locked, email */
snprintf(msgtemp, sizeof(msgtemp), "email:%.128s , is_operator: %d , is_admin: %d , is_acc_locked: %d",
give him more info about the one he querys;
is_admin, is_operator, is_locked, email */
snprintf(msgtemp, sizeof(msgtemp), "Email: %.128s, Operator: %s, Admin: %s, Locked: %s, Muted: %s",
account_get_email(account),
account_get_auth_operator(account, NULL),
account_get_auth_admin(account, NULL),
account_get_auth_lock(account));
account_get_auth_operator(account, NULL) == 1 ? "Yes" : "No",
account_get_auth_admin(account, NULL) == 1 ? "Yes" : "No",
account_get_auth_lock(account) == 1 ? "Yes" : "No",
account_get_auth_mute(account) == 1 ? "Yes" : "No");
message_send_text(c, message_type_info, c, msgtemp);
snprintf(msgtemp, sizeof(msgtemp), "Last login Owner: %.128s",
account_get_ll_owner(account));
message_send_text(c, message_type_info, c, msgtemp);
}
@ -3854,6 +3917,48 @@ namespace pvpgn
return 0;
}
/**
* /find <substr to search for inside username>
*/
static int _handle_find_command(t_connection * c, char const *text)
{
unsigned int i = 0;
t_account *account;
char const *tname;
t_entry *curr;
t_hashtable *accountlist_head = accountlist();
text = skip_command(text);
if (text[0] == '\0') {
/* In need of a better description */
message_send_text(c, message_type_info, c, "Usage: /find <substring to search in acct name>");
message_send_text(c, message_type_info, c, " <substring> has to be in lower case");
return -1;
}
std::sprintf(msgtemp, " -- name -- similar to %s", text);
message_send_text(c, message_type_info, c, msgtemp);
HASHTABLE_TRAVERSE(accountlist_head, curr)
{
if (!curr)
{
eventlog(eventlog_level_error, __FUNCTION__, "found NULL account in list");
}
else
{
account = (t_account *)entry_get_data(curr);
if ((tname = accountlist_find_vague_account(account, text)) != NULL) {
message_send_text(c, message_type_info, c, tname);
return 0;
}
}
}
return 0;
}
/**
* Save changes of accounts and clans from the cache to a storage
*/
@ -4599,11 +4704,22 @@ namespace pvpgn
key = arg2;
value = arg3;
// disallow get/set value for password hash and username (hash can be cracked easily, account name should be permanent)
if (strcasecmp(key, "bnet\\acct\\passhash1") == 0 || strcasecmp(key, "bnet\\acct\\username") == 0 || strcasecmp(key, "bnet\\username") == 0)
{
message_send_text(c, message_type_info, c, "Access denied due to security reason.");
return 0;
}
if ((arg1[0] == '\0') || (arg2[0] == '\0'))
{
message_send_text(c, message_type_info, c, "usage: /set <username> <key> [value]");
message_send_text(c, message_type_info, c, " example: /set joe BNET\\auth\\botlogin true");
message_send_text(c, message_type_info, c, " example: /set joe Record\\W3XP\\ffa_wins 123");
message_send_text(c, message_type_info, c, " (set value = null to unset value)");
return 0;
}
if (!(account = accountlist_find_account(accname)))
{
message_send_text(c, message_type_error, c, "Invalid user.");
@ -4614,7 +4730,7 @@ namespace pvpgn
{
if (account_get_strattr(account, key))
{
snprintf(msgtemp, sizeof(msgtemp), "current value of %.64s is \"%.128s\"", key, account_get_strattr(account, key));
snprintf(msgtemp, sizeof(msgtemp), "Current value of %.64s is \"%.128s\"", key, account_get_strattr(account, key));
message_send_text(c, message_type_error, c, msgtemp);
}
else
@ -4622,11 +4738,22 @@ namespace pvpgn
return 0;
}
if (account_set_strattr(account, key, value) < 0)
message_send_text(c, message_type_error, c, "Unable to set key");
else{
message_send_text(c, message_type_error, c, "Key set succesfully");
// unset value
if (strcasecmp(value, "null") == 0)
value = NULL;
std::sprintf(msgtemp, "for \"%s\" (%.64s = \"%.128s\")", account_get_name(account), key, value);
if (account_set_strattr(account, key, value) < 0)
{
std::sprintf(msgtemp2, "Unable to set key %s", msgtemp);
message_send_text(c, message_type_error, c, msgtemp2);
}
else
{
std::sprintf(msgtemp2, "Key set succesfully %s", msgtemp);
message_send_text(c, message_type_error, c, msgtemp2);
eventlog(eventlog_level_warn, __FUNCTION__, "Key set by \"%s\" %s", account_get_name(conn_get_account(c)), msgtemp);
}
return 0;
}
@ -5201,6 +5328,94 @@ namespace pvpgn
return 0;
}
/* Set usericon */
static int _handle_icon_command(t_connection * c, char const *text)
{
t_account * user_account;
t_connection * user_c;
char *accname;
char *code;
const char *usericon;
t_clienttag user_clienttag;
char t[MAX_MESSAGE_LEN];
unsigned int i, j;
char arg1[256];
char arg2[256];
std::strncpy(t, text, MAX_MESSAGE_LEN - 1);
for (i = 0; t[i] != ' ' && t[i] != '\0'; i++); /* skip command /icon */
for (; t[i] == ' '; i++); /* skip spaces */
for (j = 0; t[i] != ' ' && t[i] != '\0'; i++) /* get username */
if (j < sizeof(arg1)-1) arg1[j++] = t[i];
arg1[j] = '\0';
for (; t[i] == ' '; i++); /* skip spaces */
for (j = 0; t[i] != ' ' && t[i] != '\0'; i++) /* get code */
if (j < sizeof(arg2)-1) arg2[j++] = t[i];
arg2[j] = '\0';
accname = arg1;
code = arg2;
if (accname == '\0')
{
message_send_text(c, message_type_info, c, "usage: /icon <username> [CODE]");
message_send_text(c, message_type_info, c, " for example: /icon joe W3D6");
message_send_text(c, message_type_info, c, " (set code = null to unset icon)");
return 0;
}
if (!(user_account = accountlist_find_account(accname)))
{
message_send_text(c, message_type_error, c, "Invalid user.");
return 0;
}
if (user_c = account_get_conn(user_account))
user_clienttag = conn_get_clienttag(user_c);
else
user_clienttag = account_get_ll_clienttag(user_account); // if user offline then retrieve last clienttag
// output current usericon code
if (code == '\0' || strlen(arg2) != 4)
{
if (usericon = account_get_user_icon(user_account, user_clienttag))
{
snprintf(msgtemp, sizeof(msgtemp), "%.64s has custom icon \"%.4s\"", account_get_name(user_account), strreverse((char*)usericon));
message_send_text(c, message_type_error, c, msgtemp);
}
else
{
snprintf(msgtemp, sizeof(msgtemp), "Custom icon for %.64s currently not set", account_get_name(user_account));
message_send_text(c, message_type_error, c, msgtemp);
}
return 0;
}
for (int i = 0; i < strlen(code); i++)
code[i] = toupper(code[i]);
// unset value
if (strcasecmp(code, "null") == 0)
usericon = NULL;
else
usericon = strreverse(xstrdup(code));
snprintf(msgtemp, sizeof(msgtemp), "Set icon \"%.4s\" to %.64s", code, account_get_name(user_account));
message_send_text(c, message_type_error, c, msgtemp);
account_set_user_icon(user_account, user_clienttag, usericon);
// if user online then force him to rejoin channel
if (user_c)
{
conn_update_w3_playerinfo(user_c);
channel_rejoin(user_c);
}
}
}
}

View file

@ -74,6 +74,7 @@
#include "attrlayer.h"
#include "anongame_wol.h"
#include "common/setup_after.h"
#include "icons.h"
namespace pvpgn
{
@ -2521,13 +2522,14 @@ namespace pvpgn
return 0;
}
/* Player icon that displayed in a channel in all games (except Warcraft 3) */
extern char const * conn_get_playerinfo(t_connection const * c)
{
t_account * account;
static char playerinfo[MAX_PLAYERINFO_STR];
t_clienttag clienttag;
char revtag[5];
char const * usericon;
if (!c)
{
@ -2547,7 +2549,23 @@ namespace pvpgn
}
tag_uint_to_revstr(revtag, clienttag);
if (clienttag == CLIENTTAG_BNCHATBOT_UINT)
// allow set icon to a user directly from the database (override default tag always if not null)
if (usericon = account_get_user_icon(account, clienttag))
std::sprintf(revtag, usericon);
// if custom_icons is enabled then set a custom client tag by player rating
if (prefs_get_custom_icons() == 1)
{
t_icon_info * icon;
// do not override userselectedicon if it's not null
if (!usericon && (icon = get_custom_icon(account, clienttag)))
strcpy(revtag, icon->icon_code);
// FIXME: it replaces tag with icon on a client side for all clients (HarpyWar)
std::strcpy(playerinfo, revtag);
}
else if (clienttag == CLIENTTAG_BNCHATBOT_UINT)
{
std::strcpy(playerinfo, revtag); /* FIXME: what to return here? */
}
@ -3674,6 +3692,7 @@ namespace pvpgn
return count;
}
/* Warcraft 3 icon that displayed in a channel */
extern int conn_update_w3_playerinfo(t_connection * c)
{
t_account * account;
@ -3725,15 +3744,35 @@ namespace pvpgn
while ((*clantag_str) == 0) clantag_str++;
}
if (acctlevel == 0) {
// allow set icon to a user directly from the database (override default icon always if not null)
usericon = account_get_user_icon(account, clienttag);
// if custom stats is enabled then set a custom client icon by player rating
if (prefs_get_custom_icons() == 1)
{
t_icon_info * icon;
// do not override userselectedicon if it's not null
if (!usericon && (icon = get_custom_icon(account, clienttag)))
usericon = xstrdup(icon->icon_code);
acctlevel = 0;
if (clantag)
std::sprintf(tempplayerinfo, "%s %s %u %s", revtag, usericon, acctlevel, clantag_str);
else
std::sprintf(tempplayerinfo, "%s %s %u", revtag, usericon, acctlevel);
}
// default icon "WAR3" or "W3XP"
else if (acctlevel == 0 && !usericon) {
if (clantag)
std::sprintf(tempplayerinfo, "%s %s 0 %s", revtag, revtag, clantag_str);
else
std::strcpy(tempplayerinfo, revtag);
eventlog(eventlog_level_info, __FUNCTION__, "[%d] %s", conn_get_socket(c), revtag);
}
else {
usericon = account_get_user_icon(account, clienttag);
// display race icon with a level number
else
{
if (!usericon) {
if (clantag)
std::sprintf(tempplayerinfo, "%s %1u%c3W %u %s", revtag, raceiconnumber, raceicon, acctlevel, clantag_str);

View file

@ -38,6 +38,7 @@
#include "tournament.h"
#include "channel.h"
#include "common/setup_after.h"
#include "icons.h"
namespace pvpgn
{
@ -439,10 +440,10 @@ namespace pvpgn
return 0;
}
/* Open portrait in Warcraft 3 user profile */
static int _client_anongame_get_icon(t_connection * c, t_packet const * const packet)
{
t_packet * rpacket;
//BlacKDicK 04/20/2003 Need some huge re-work on this.
{
struct
@ -491,7 +492,16 @@ namespace pvpgn
packet_set_type(rpacket, SERVER_FINDANONGAME_ICONREPLY);
bn_int_set(&rpacket->u.server_findanongame_iconreply.count, bn_int_get(packet->u.client_findanongame_inforeq.count));
bn_byte_set(&rpacket->u.server_findanongame_iconreply.option, CLIENT_FINDANONGAME_GET_ICON);
if ((uicon = account_get_user_icon(acc, clienttag)))
if (prefs_get_custom_icons() == 1)
{
// get current custom icon
t_icon_info * icon;
if (icon = get_custom_icon(acc, clienttag))
std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon, icon->icon_code, 4);
}
else if ((uicon = account_get_user_icon(acc, clienttag)))
{
std::memcpy(&rpacket->u.server_findanongame_iconreply.curricon, uicon, 4);
}
@ -517,7 +527,10 @@ namespace pvpgn
//Building the icon for the races
bn_short_set(&tempicon.required_wins, icon_req_race_wins);
if (account_get_racewins(acc, race[i], clienttag) >= icon_req_race_wins) {
tempicon.client_enabled = 1;
if (prefs_get_custom_icons() == 1)
tempicon.client_enabled = 0;
else
tempicon.client_enabled = 1;
}
else{
tempicon.client_enabled = 0;
@ -528,7 +541,10 @@ namespace pvpgn
icon_req_tourney_wins = anongame_infos_get_ICON_REQ_TOURNEY(j + 1);
bn_short_set(&tempicon.required_wins, icon_req_tourney_wins);
if (account_get_racewins(acc, race[i], clienttag) >= icon_req_tourney_wins) {
tempicon.client_enabled = 1;
if (prefs_get_custom_icons() == 1)
tempicon.client_enabled = 0;
else
tempicon.client_enabled = 1;
}
else{
tempicon.client_enabled = 0;
@ -544,6 +560,7 @@ namespace pvpgn
return 0;
}
/* Choose icon by user from profile > portrait */
static int _client_anongame_set_icon(t_connection * c, t_packet const * const packet)
{
//BlacKDicK 04/20/2003
@ -552,6 +569,12 @@ namespace pvpgn
t_account * account;
t_clienttag ctag;
// disable with custom icons
if (prefs_get_custom_icons() == 1)
{
return 0;
}
/*FIXME: In this case we do not get a 'count' but insted of it we get the icon
that the client wants to set.'W3H2' for an example. For now it is ok, since they share
the same position on the packet*/
@ -568,6 +591,7 @@ namespace pvpgn
account = conn_get_account(c);
// ICON SWITCH HACK PROTECTION
if (check_user_icon(account, user_icon) == 0)
{
eventlog(eventlog_level_info, __FUNCTION__, "[%s] \"%s\" ICON SWITCH hack attempt, icon set to default ", conn_get_username(c), user_icon);
@ -585,7 +609,7 @@ namespace pvpgn
return 0;
}
// check user for illegal icon
/* Check user choice for illegal icon */
static int check_user_icon(t_account * account, const char * user_icon)
{
unsigned int i, len;

View file

@ -23,6 +23,8 @@
#include "common/setup_before.h"
#include "handle_bnet.h"
#include <fstream>
#include <cerrno>
#include <sstream>
#include <cstring>
#include <cctype>
@ -2700,6 +2702,7 @@ namespace pvpgn
return 0;
}
// motd for warcraft 3 (http://img21.imageshack.us/img21/1808/j2py.png)
static int _client_motdw3(t_connection * c, t_packet const *const packet)
{
t_packet *rpacket;
@ -2740,7 +2743,19 @@ namespace pvpgn
bn_int_set(&rpacket->u.server_motd_w3.timestamp, motdd.fnews + 1);
bn_int_set(&rpacket->u.server_motd_w3.timestamp2, SERVER_MOTD_W3_WELCOME);
snprintf(serverinfo, sizeof(serverinfo), "Welcome to the " PVPGN_SOFTWARE " Version " PVPGN_VERSION "\r\n\r\nThere are currently %u user(s) in %u games of %s, and %u user(s) playing %u games and chatting in %u channels in %s.\r\n%s", conn_get_user_count_by_clienttag(conn_get_clienttag(c)), game_get_count_by_clienttag(ctag), clienttag_get_title(conn_get_clienttag(c)), connlist_login_get_length(), gamelist_get_length(), channellist_get_length(), prefs_get_servername(), prefs_get_server_info());
// read text from bnmotd_w3.txt
char const * filename;
char * buff;
std::FILE * fp;
std::ifstream in(filename = prefs_get_motdw3file());
if (in) {
std::string contents((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
strcpy(serverinfo, contents.substr(0,511).c_str());
} else
eventlog(eventlog_level_error, __FUNCTION__, "Could not open file motdw3 \"%s\" (std::fopen: %s)", filename, std::strerror(errno));
packet_append_string(rpacket, serverinfo);

513
src/bnetd/icons.cpp Normal file
View file

@ -0,0 +1,513 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "common/setup_before.h"
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include "compat/strcasecmp.h"
#include "compat/snprintf.h"
#include "common/token.h"
#include "common/list.h"
#include "common/eventlog.h"
#include "common/xalloc.h"
#include "common/xstring.h"
#include "common/util.h"
#include "common/tag.h"
#include "account.h"
#include "connection.h"
#include "icons.h"
#include "account_wrap.h"
#include "common/setup_after.h"
namespace pvpgn
{
namespace bnetd
{
static t_list * icon_head = NULL;
// TODO: wrapper to get value
static int enable_custom_icons = 0;
static int skip_comments(char *buff);
static t_icon_var_info * _read_option(char *str, unsigned lineno);
static t_icon_info * _find_custom_icon(int rating, char * clienttag);
static char * _find_attr_key(char * clienttag);
extern int prefs_get_custom_icons()
{
return enable_custom_icons;
}
/* Format stats text, with attributes from a storage, and output text to a user */
extern const char * get_custom_stats_text(t_account * account, t_clienttag clienttag)
{
const char *value;
const char *text;
char clienttag_str[5], tmp[64];
t_icon_info * icon;
t_iconset_info * iconset;
t_icon_var_info * var;
t_elem * curr;
t_elem * curr_var;
tag_uint_to_str(clienttag_str, clienttag);
text = NULL;
if (icon_head) {
LIST_TRAVERSE(icon_head, curr)
{
if (!(iconset = (t_iconset_info*)elem_get_data(curr)))
{
eventlog(eventlog_level_error, __FUNCTION__, "icon list contains NULL item");
continue;
}
// find a needed tag
if (std::strcmp(iconset->clienttag, clienttag_str) != 0)
continue;
if (!iconset->stats)
return NULL;
text = xstrdup(iconset->stats);
LIST_TRAVERSE(iconset->vars, curr_var)
{
if (!(var = (t_icon_var_info*)elem_get_data(curr_var)))
{
eventlog(eventlog_level_error, __FUNCTION__, "vars list contains NULL item");
continue;
}
// replace NULL attributes to "0"
if (!(value = account_get_strattr(account, var->value)))
value = "0";
// replace in a text
snprintf(tmp, sizeof(tmp), "{{%s}}", var->key);
text = str_replace((char*)text, tmp, (char*)value);
// also replace {var}->rank
if (icon = _find_custom_icon(atoi(value), clienttag_str))
{
snprintf(tmp, sizeof(tmp), "{{%s->rank}}", var->key);
text = str_replace((char*)text, tmp, icon->rank);
}
}
}
}
return text;
}
/* find icon code by rating for the clienttag */
extern t_icon_info * get_custom_icon(t_account * account, t_clienttag clienttag)
{
char * attr_key;
int rating;
char clienttag_str[5];
t_icon_info * icon;
t_icon_info * uicon;
const char * usericon;
tag_uint_to_str(clienttag_str, clienttag);
// get attribute field name from a storage
if (!(attr_key = _find_attr_key((char*)clienttag_str)))
{
eventlog(eventlog_level_trace, __FUNCTION__, "could not find attr_key in iconset for tag %s", clienttag_str);
return NULL;
}
rating = account_get_numattr(account, attr_key);
icon = _find_custom_icon(rating, clienttag_str);
return icon;
}
extern int customicons_unload(void)
{
t_elem * curr;
t_iconset_info * iconset;
if (icon_head) {
LIST_TRAVERSE(icon_head, curr)
{
if (!(iconset = (t_iconset_info*)elem_get_data(curr))) {
eventlog(eventlog_level_error, __FUNCTION__, "icon list contains NULL item");
continue;
}
if (list_remove_elem(icon_head, &curr) < 0)
eventlog(eventlog_level_error, __FUNCTION__, "could not remove item from list");
xfree(iconset);
}
if (list_destroy(icon_head) < 0)
return -1;
icon_head = NULL;
}
return 0;
}
/*****/
extern int customicons_load(char const * filename)
{
std::FILE * fp;
unsigned int line, pos, counter = 0;
bool end_of_iconset = false;
char *buff, *value;
char *rating, *rank, *icon;
t_icon_var_info * option;
icon_head = list_create();
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;
}
/* 1) parse root config options */
for (line = 1; (buff = file_get_line(fp)); line++)
{
if (skip_comments(buff) > 0)
{
continue;
}
// read root options
if (option = _read_option(buff, line))
{
if (std::strcmp(option->key, "custom_icons") == 0)
if (std::strcmp(option->value, "true") == 0)
enable_custom_icons = 1;
else
enable_custom_icons = 0;
}
/* 2) parse clienttags */
if (std::strcmp(buff, "[W3XP]") == 0 ||
std::strcmp(buff, "[WAR3]") == 0 ||
std::strcmp(buff, "[STAR]") == 0 ||
std::strcmp(buff, "[SEXP]") == 0 ||
std::strcmp(buff, "[JSTR]") == 0 ||
std::strcmp(buff, "[SSHR]") == 0 ||
std::strcmp(buff, "[W2BN]") == 0 ||
std::strcmp(buff, "[DRTL]") == 0 ||
std::strcmp(buff, "[DSHR]") == 0)
{
if (skip_comments(buff) > 0)
{
continue;
}
value = std::strtok(buff, " []");
// new iconset for a clienttag
t_iconset_info * icon_set = (t_iconset_info*)xmalloc(sizeof(t_iconset_info));
icon_set->clienttag = xstrdup(value);
icon_set->attr_key = NULL;
icon_set->icon_info = list_create();
icon_set->vars = list_create();
icon_set->stats = NULL;
/* 3) parse inner options under a clienttag */
for (; (buff = file_get_line(fp)); line++)
{
if (end_of_iconset)
{
end_of_iconset = false;
break;
}
if (skip_comments(buff) > 0)
{
continue;
}
// fill variables list
if (option = _read_option(buff, line))
{
// set attr_key with a first variable
if (!icon_set->attr_key)
icon_set->attr_key = xstrdup(option->value);
// add to variables
list_append_data(icon_set->vars, option);
}
/* 3) parse icons section */
if (std::strcmp(buff, "[icons]") == 0)
{
counter = 0;
for (; (buff = file_get_line(fp)); line++)
{
if (skip_comments(buff) > 0)
{
continue;
}
// end if icons
if (std::strcmp(buff, "[/icons]") == 0) {
break;
}
pos = 0;
if (!(rating = next_token(buff, &pos)))
{
eventlog(eventlog_level_error, __FUNCTION__, "missing value in line %u in file \"%s\"", line, filename);
continue;
}
if (!(rank = next_token(buff, &pos)))
{
eventlog(eventlog_level_error, __FUNCTION__, "missing rank in line %u in file \"%s\"", line, filename);
continue;
}
if (!(icon = next_token(buff, &pos)))
{
eventlog(eventlog_level_error, __FUNCTION__, "missing icon in line %u in file \"%s\"", line, filename);
continue;
}
counter++;
t_icon_info * icon_info = (t_icon_info*)xmalloc(sizeof(t_icon_info));
icon_info->rating = atoi(rating);
icon_info->rank = xstrdup(rank);
icon_info->icon_code = xstrdup(strreverse(icon)); // save reversed icon code
list_prepend_data(icon_set->icon_info, icon_info);
}
}
/* 3) parse stats section */
if (std::strcmp(buff, "[stats]") == 0)
{
std::string tmp;
for (; (buff = file_get_line(fp)); line++)
{
// end of stats
if (std::strcmp(buff, "[/stats]") == 0) {
// put whole text of stats after read
icon_set->stats = xstrdup(tmp.c_str());
end_of_iconset = true;
break;
}
tmp = tmp + buff + "\n";
}
}
}
if (!icon_set->attr_key)
{
eventlog(eventlog_level_error, __FUNCTION__, "attr_key is null for iconset %s", icon_set->clienttag);
continue;
}
list_append_data(icon_head, icon_set);
eventlog(eventlog_level_trace, __FUNCTION__, "loaded %u custom icons for %s", counter, icon_set->clienttag);
}
}
return 0;
}
static int skip_comments(char *buff)
{
char *temp;
int pos;
for (pos = 0; buff[pos] == '\t' || buff[pos] == ' '; pos++);
if (buff[pos] == '\0' || buff[pos] == '#') {
return 1;
}
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';
}
return 0;
}
/* Read an option like "key = value" from a str line, and split in into a pair: key, value */
static t_icon_var_info * _read_option(char *str, unsigned lineno)
{
char *cp, prev, *directive;
t_icon_var_info * icon_var = (t_icon_var_info*)xmalloc(sizeof(t_icon_var_info));
directive = str;
str = str_skip_word(str + 1);
if (*str) *(str++) = '\0';
str = str_skip_space(str);
if (*str != '=') {
return NULL;
}
str = str_skip_space(str + 1);
if (!*str) {
eventlog(eventlog_level_error, __FUNCTION__, "missing value at line %u", lineno);
return NULL;
}
if (*str == '"') {
for (cp = ++str, prev = '\0'; *cp; cp++) {
switch (*cp) {
case '"':
if (prev != '\\') break;
prev = '"';
continue;
case '\\':
if (prev == '\\') prev = '\0';
else prev = '\\';
continue;
default:
prev = *cp;
continue;
}
break;
}
if (*cp != '"') {
eventlog(eventlog_level_error, __FUNCTION__, "missing end quota at line %u", lineno);
return NULL;
}
*cp = '\0';
cp = str_skip_space(cp + 1);
if (*cp) {
eventlog(eventlog_level_error, __FUNCTION__, "extra characters in value after ending quote at line %u", lineno);
return NULL;
}
}
else {
cp = str_skip_word(str);
if (*cp) {
*cp = '\0';
cp = str_skip_space(cp + 1);
if (*cp) {
eventlog(eventlog_level_error, __FUNCTION__, "extra characters after the value at line %u", lineno);
return NULL;
}
}
}
//if (!find && std::strcmp(find, directive) == 0)
// return str_skip_space(str);
//else
// return NULL;
icon_var->key = xstrdup(directive);
icon_var->value = xstrdup(str_skip_space(str));
return icon_var;
}
/* Get custom icon by rating for clienttag */
static t_icon_info * _find_custom_icon(int rating, char * clienttag)
{
t_elem * curr;
t_elem * curr_icon;
t_iconset_info * iconset;
t_icon_info * icon;
if (icon_head) {
LIST_TRAVERSE(icon_head, curr)
{
if (!(iconset = (t_iconset_info*)elem_get_data(curr)))
{
eventlog(eventlog_level_error, __FUNCTION__, "icon list contains NULL item");
continue;
}
// find a needed tag
if (std::strcmp(iconset->clienttag, clienttag) != 0)
continue;
// iterate all icons for the tag
LIST_TRAVERSE(iconset->icon_info, curr_icon)
{
if (!(icon = (t_icon_info*)elem_get_data(curr_icon)))
{
eventlog(eventlog_level_error, __FUNCTION__, "icon list contains NULL item");
continue;
}
if (rating >= icon->rating)
return icon;
}
// if nothing found then return last icon
return icon;
}
}
return NULL;
}
/* Get attr_key for clienttag */
static char * _find_attr_key(char * clienttag)
{
t_elem * curr;
t_elem * curr_icon;
t_iconset_info * iconset;
if (icon_head) {
LIST_TRAVERSE(icon_head, curr)
{
if (!(iconset = (t_iconset_info*)elem_get_data(curr)))
{
eventlog(eventlog_level_error, __FUNCTION__, "icon list contains NULL item");
continue;
}
// find a needed tag
if (std::strcmp(iconset->clienttag, clienttag) == 0)
return iconset->attr_key;
}
}
return NULL;
}
}
}

80
src/bnetd/icons.h Normal file
View file

@ -0,0 +1,80 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef INCLUDED_ICONS_TYPES
#define INCLUDED_ICONS_TYPES
namespace pvpgn
{
namespace bnetd
{
typedef struct
{
unsigned int rating; // rating or something else
char * rank; // any string value
char * icon_code; // icon code
} t_icon_info;
typedef struct
{
char * clienttag;
char * attr_key;
t_list * icon_info; // list of t_icon_info
t_list * vars; // list of t_icon_var_info
const char * stats;
} t_iconset_info;
typedef struct
{
char * key;
char * value;
} t_icon_var_info;
}
}
#endif
#ifndef JUST_NEED_TYPES
#ifndef INCLUDED_ICONS_PROTOS
#define INCLUDED_ICONS_PROTOS
#define JUST_NEED_TYPES
# include "account.h"
#undef JUST_NEED_TYPES
namespace pvpgn
{
namespace bnetd
{
extern int prefs_get_custom_icons();
extern t_icon_info * get_custom_icon(t_account * account, t_clienttag clienttag);
extern const char * get_custom_stats_text(t_account * account, t_clienttag clienttag);
extern int customicons_load(char const * filename);
extern int customicons_unload(void);
}
}
/*****/
#endif
#endif

View file

@ -81,6 +81,7 @@
#include "command_groups.h"
#include "alias_command.h"
#include "tournament.h"
#include "icons.h"
#include "anongame_infos.h"
#include "anongame_wol.h"
#include "clan.h"
@ -294,6 +295,7 @@ char * write_to_pidfile(void)
return pidfile;
}
/* Initialize config files */
int pre_server_startup(void)
{
pvpgn_greeting();
@ -364,6 +366,7 @@ int pre_server_startup(void)
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());
customicons_load(prefs_get_customicons_file());
anongame_infos_load(prefs_get_anongame_infos_file());
anongame_wol_matchlist_create();
clanlist_load();

View file

@ -43,6 +43,7 @@ namespace pvpgn
char const * logfile;
char const * loglevels;
char const * motdfile;
char const * motdw3file;
char const * newsfile;
char const * channelfile;
char const * pidfile;
@ -142,6 +143,7 @@ namespace pvpgn
unsigned int account_force_username;
char const * command_groups_file;
char const * tournament_file;
char const * customicons_file;
char const * aliasfile;
char const * anongame_infos_file;
char const * magicfile;
@ -198,6 +200,10 @@ namespace pvpgn
static const char *conf_get_motdfile(void);
static int conf_setdef_motdfile(void);
static int conf_set_motdw3file(const char *valstr);
static const char *conf_get_motdw3file(void);
static int conf_setdef_motdw3file(void);
static int conf_set_newsfile(const char *valstr);
static const char *conf_get_newsfile(void);
static int conf_setdef_newsfile(void);
@ -586,6 +592,10 @@ namespace pvpgn
static const char *conf_get_tournament_file(void);
static int conf_setdef_tournament_file(void);
static int conf_set_customicons_file(const char *valstr);
static const char *conf_get_customicons_file(void);
static int conf_setdef_customicons_file(void);
static int conf_set_aliasfile(const char *valstr);
static const char *conf_get_aliasfile(void);
static int conf_setdef_aliasfile(void);
@ -712,6 +722,7 @@ namespace pvpgn
{ "logfile", conf_set_logfile, conf_get_logfile, conf_setdef_logfile },
{ "loglevels", conf_set_loglevels, conf_get_loglevels, conf_setdef_loglevels },
{ "motdfile", conf_set_motdfile, conf_get_motdfile, conf_setdef_motdfile },
{ "motdw3file", conf_set_motdw3file, conf_get_motdw3file, conf_setdef_motdw3file },
{ "newsfile", conf_set_newsfile, conf_get_newsfile, conf_setdef_newsfile },
{ "channelfile", conf_set_channelfile, conf_get_channelfile, conf_setdef_channelfile },
{ "pidfile", conf_set_pidfile, conf_get_pidfile, conf_setdef_pidfile },
@ -809,6 +820,7 @@ namespace pvpgn
{ "account_force_username", conf_set_account_force_username, conf_get_account_force_username, conf_setdef_account_force_username },
{ "command_groups_file", conf_set_command_groups_file, conf_get_command_groups_file, conf_setdef_command_groups_file },
{ "tournament_file", conf_set_tournament_file, conf_get_tournament_file, conf_setdef_tournament_file },
{ "customicons_file", conf_set_customicons_file, conf_get_customicons_file, conf_setdef_customicons_file },
{ "aliasfile", conf_set_aliasfile, conf_get_aliasfile, conf_setdef_aliasfile },
{ "anongame_infos_file", conf_set_anongame_infos_file, conf_get_anongame_infos_file, conf_setdef_anongame_infos_file },
@ -982,6 +994,27 @@ namespace pvpgn
}
extern char const * prefs_get_motdw3file(void)
{
return prefs_runtime_config.motdw3file;
}
static int conf_set_motdw3file(const char *valstr)
{
return conf_set_str(&prefs_runtime_config.motdw3file, valstr, NULL);
}
static int conf_setdef_motdw3file(void)
{
return conf_set_str(&prefs_runtime_config.motdw3file, NULL, BNETD_MOTDW3_FILE);
}
static const char* conf_get_motdw3file(void)
{
return prefs_runtime_config.motdw3file;
}
extern char const * prefs_get_newsfile(void)
{
return prefs_runtime_config.newsfile;
@ -3031,6 +3064,27 @@ namespace pvpgn
}
extern char const * prefs_get_customicons_file(void)
{
return prefs_runtime_config.customicons_file;
}
static int conf_set_customicons_file(const char *valstr)
{
return conf_set_str(&prefs_runtime_config.customicons_file, valstr, NULL);
}
static int conf_setdef_customicons_file(void)
{
return conf_set_str(&prefs_runtime_config.customicons_file, NULL, BNETD_CUSTOMICONS_FILE);
}
static const char* conf_get_customicons_file(void)
{
return prefs_runtime_config.customicons_file;
}
extern char const * prefs_get_aliasfile(void)
{
return prefs_runtime_config.aliasfile;

View file

@ -40,6 +40,7 @@ namespace pvpgn
extern char const * prefs_get_logfile(void);
extern char const * prefs_get_loglevels(void);
extern char const * prefs_get_motdfile(void);
extern char const * prefs_get_motdw3file(void);
extern char const * prefs_get_newsfile(void);
extern char const * prefs_get_adfile(void);
extern char const * prefs_get_topicfile(void);
@ -156,6 +157,7 @@ namespace pvpgn
extern char const * prefs_get_command_groups_file(void);
extern char const * prefs_get_tournament_file(void);
extern char const * prefs_get_customicons_file(void);
extern char const * prefs_get_aliasfile(void);
extern char const * prefs_get_anongame_infos_file(void);

View file

@ -83,6 +83,7 @@
#include "command_groups.h"
#include "alias_command.h"
#include "tournament.h"
#include "icons.h"
#include "anongame_infos.h"
#include "topic.h"
#include "common/setup_after.h"
@ -1409,6 +1410,9 @@ namespace pvpgn
tournament_reload(prefs_get_tournament_file());
customicons_unload();
customicons_load(prefs_get_customicons_file());
anongame_infos_unload();
anongame_infos_load(prefs_get_anongame_infos_file());

View file

@ -132,6 +132,7 @@ namespace
char curr_gamepass[MAX_GAMEPASS_LEN];
int count, clantag;
char const * inviter;
int ignoreversion;
} t_user_info;
@ -368,6 +369,7 @@ namespace
" -o NAME, --owner=NAME report CD owner as NAME\n"
" -k KEY, --cdkey=KEY report CD key as KEY\n"
" -l LANG --lang=LANG report language as LANG (default \"enUS\")\n"
" -i, --ignore-version ignore version request (do not send game version, CD owner/key)\n"
" -h, --help, --usage show this information and exit\n"
" -v, --version print version number and exit\n");
std::exit(EXIT_FAILURE);
@ -382,6 +384,7 @@ namespace
char const * * cdowner,
char const * * cdkey,
char const * * gamelang,
int * ignoreversion,
int * useansi)
{
int a;
@ -636,6 +639,10 @@ namespace
std::fprintf(stderr, "%s: option \"%s\" requires an argument\n", argv[0], argv[a]);
usage(argv[0]);
}
else if (std::strcmp(argv[a], "-i") == 0 || std::strcmp(argv[a], "--ignore-version") == 0)
{
*ignoreversion = 1;
}
else
{
std::fprintf(stderr, "%s: unknown option \"%s\"\n", argv[0], argv[a]);
@ -721,9 +728,10 @@ extern int main(int argc, char * argv[])
/* default values */
user.archtag = ARCHTAG_WINX86;
user.gamelang = CLIENT_COUNTRYINFO_109_GAMELANG;
user.ignoreversion = 0;
read_commandline(argc, argv, &servname, &servport, &user.clienttag, &user.archtag, &changepass,
&newacct, &user.channel, &user.cdowner, &user.cdkey, &user.gamelang, &client.useansi);
&newacct, &user.channel, &user.cdowner, &user.cdkey, &user.gamelang, &user.ignoreversion, &client.useansi);
client.fd_stdin = fileno(stdin);
if (tcgetattr(client.fd_stdin, &client.in_attr_old) >= 0)
@ -771,7 +779,7 @@ extern int main(int argc, char * argv[])
}
if ((client.sd = client_connect(argv[0],
servname, servport, user.cdowner, user.cdkey, user.clienttag,
servname, servport, user.cdowner, user.cdkey, user.clienttag, user.ignoreversion,
&client.saddr, &client.sessionkey, &client.sessionnum, user.archtag, user.gamelang)) < 0)
{
std::fprintf(stderr, "%s: fatal error during handshake\n", argv[0]);

View file

@ -97,6 +97,7 @@ namespace
std::fprintf(stderr,
" -o NAME, --owner=NAME report CD owner as NAME\n"
" -k KEY, --cdkey=KEY report CD key as KEY\n"
" -i, --ignore-version ignore version request (do not send game version, CD owner/key)\n"
" -p PLR, --player=PLR print stats for player PLR\n"
" --bnetd also print BNETD-specific stats\n"
" --fsgs also print FSGS-specific stats\n"
@ -134,6 +135,7 @@ extern int main(int argc, char * argv[])
int use_fsgs = 0;
unsigned int screen_width, screen_height;
int munged = 0;
int ignoreversion = 0;
if (argc < 1 || !argv || !argv[0])
{
@ -332,6 +334,8 @@ extern int main(int argc, char * argv[])
else if (std::strcmp(argv[a], "-h") == 0 || std::strcmp(argv[a], "--help") == 0 || std::strcmp(argv[a], "--usage")
== 0)
usage(argv[0]);
else if (std::strcmp(argv[a], "-i") == 0 || std::strcmp(argv[a], "--ignore-version") == 0)
ignoreversion = 1;
else if (std::strcmp(argv[a], "-v") == 0 || std::strcmp(argv[a], "--version") == 0)
{
std::printf("version "PVPGN_VERSION"\n");
@ -388,7 +392,7 @@ extern int main(int argc, char * argv[])
}
}
if ((sd = client_connect(argv[0], servname, servport, cdowner, cdkey, clienttag, &saddr, &sessionkey, &sessionnum, ARCHTAG_WINX86, CLIENT_COUNTRYINFO_109_GAMELANG)) < 0)
if ((sd = client_connect(argv[0], servname, servport, cdowner, cdkey, clienttag, ignoreversion, &saddr, &sessionkey, &sessionnum, ARCHTAG_WINX86, CLIENT_COUNTRYINFO_109_GAMELANG)) < 0)
{
std::fprintf(stderr, "%s: fatal error during handshake\n", argv[0]);
if (changed_in)

View file

@ -142,6 +142,9 @@ namespace {
*exeinfo = "";
*checksum = 0;
if (std::strcmp(clienttag, CLIENTTAG_BNCHATBOT) == 0)
return 0;
std::fprintf(stderr, "%s: unsupported clienttag \"%s\"\n", progname, clienttag);
// aaron: dunno what we should return in case of this.. but returning nothing was definetly wrong
return -1;
@ -155,7 +158,7 @@ namespace pvpgn
namespace client
{
extern int client_connect(char const * progname, char const * servname, unsigned short servport, char const * cdowner, char const * cdkey, char const * clienttag, struct sockaddr_in * saddr, unsigned int * sessionkey, unsigned int * sessionnum, char const * archtag, char const * gamelang)
extern int client_connect(char const * progname, char const * servname, unsigned short servport, char const * cdowner, char const * cdkey, char const * clienttag, int ignoreversion, struct sockaddr_in * saddr, unsigned int * sessionkey, unsigned int * sessionnum, char const * archtag, char const * gamelang)
{
struct hostent * host;
char const * username;
@ -329,45 +332,49 @@ namespace pvpgn
*sessionnum = bn_int_get(rpacket->u.server_authreq_109.sessionnum);
/* FIXME: also get filename and equation */
if (!(packet = packet_create(packet_class_bnet)))
if (!ignoreversion)
{
std::fprintf(stderr, "%s: could not create packet\n", progname);
goto error_rpacket;
}
packet_set_size(packet, sizeof(t_client_authreq_109));
packet_set_type(packet, CLIENT_AUTHREQ_109);
bn_int_set(&packet->u.client_authreq_109.ticks, std::time(NULL));
{
t_cdkey_info cdkey_info;
if (!(packet = packet_create(packet_class_bnet)))
{
std::fprintf(stderr, "%s: could not create packet\n", progname);
goto error_rpacket;
}
packet_set_size(packet, sizeof(t_client_authreq_109));
packet_set_type(packet, CLIENT_AUTHREQ_109);
bn_int_set(&packet->u.client_authreq_109.ticks, std::time(NULL));
bn_int_set(&packet->u.client_authreq_109.gameversion, gameversion);
{
t_cdkey_info cdkey_info;
bn_int_set(&packet->u.client_authreq_109.cdkey_number, 1); /* only one */
std::memset(&cdkey_info, '0', sizeof(cdkey_info));
/* FIXME: put the input cdkey here */
packet_append_data(packet, &cdkey_info, sizeof(cdkey_info));
packet_append_string(packet, exeinfo);
packet_append_string(packet, cdowner);
}
bn_int_set(&packet->u.client_authreq_109.spawn, 0x0000);
bn_int_set(&packet->u.client_authreq_109.checksum, checksum);
client_blocksend_packet(sd, packet);
packet_del_ref(packet);
bn_int_set(&packet->u.client_authreq_109.gameversion, gameversion);
/* now wait for reply */
do
if (client_blockrecv_packet(sd, rpacket) < 0)
{
std::fprintf(stderr, "%s: server closed connection\n", progname);
goto error_rpacket;
}
while (packet_get_type(rpacket) != SERVER_AUTHREPLY_109);
//FIXME: check if AUTHREPLY_109 is success or fail
if (bn_int_get(rpacket->u.server_authreply_109.message) != SERVER_AUTHREPLY_109_MESSAGE_OK)
{
std::fprintf(stderr, "AUTHREPLY_109 failed - closing connection\n");
goto error_rpacket;
bn_int_set(&packet->u.client_authreq_109.cdkey_number, 1); /* only one */
std::memset(&cdkey_info, '0', sizeof(cdkey_info));
/* FIXME: put the input cdkey here */
packet_append_data(packet, &cdkey_info, sizeof(cdkey_info));
packet_append_string(packet, exeinfo);
packet_append_string(packet, cdowner);
}
bn_int_set(&packet->u.client_authreq_109.spawn, 0x0000);
bn_int_set(&packet->u.client_authreq_109.checksum, checksum);
client_blocksend_packet(sd, packet);
packet_del_ref(packet);
/* now wait for reply */
do
if (client_blockrecv_packet(sd, rpacket) < 0)
{
std::fprintf(stderr, "%s: server closed connection\n", progname);
goto error_rpacket;
}
while (packet_get_type(rpacket) != SERVER_AUTHREPLY_109);
//FIXME: check if AUTHREPLY_109 is success or fail
if (bn_int_get(rpacket->u.server_authreply_109.message) != SERVER_AUTHREPLY_109_MESSAGE_OK)
{
std::fprintf(stderr, "AUTHREPLY_109 failed - closing connection\n");
goto error_rpacket;
}
}
}
else

View file

@ -83,10 +83,9 @@ namespace pvpgn
namespace client
{
extern int client_connect(char const * progname, char const * servname, unsigned short servport, char const * cdowner, char const * cdkey, char const * clienttag, struct sockaddr_in * saddr, unsigned int * sessionkey, unsigned int * sessionnum, char const * archtag, char const * gamelang);
extern int client_connect(char const * progname, char const * servname, unsigned short servport, char const * cdowner, char const * cdkey, char const * clienttag, int ignoreversion, struct sockaddr_in * saddr, unsigned int * sessionkey, unsigned int * sessionnum, char const * archtag, char const * gamelang);
}
}
#endif
#endif

View file

@ -130,6 +130,7 @@ const char * const BNETD_STORAGE_PATH = "";
const char * const BNETD_REPORT_DIR = "reports";
const char * const BNETD_LOG_FILE = "logs/bnetd.log";
const char * const BNETD_MOTD_FILE = "conf/bnmotd.txt";
const char * const BNETD_MOTDW3_FILE = "conf/bnmotd_w3.txt";
const char * const BNETD_NEWS_DIR = "news";
const char * const BNETD_AD_FILE = "conf/ad.conf";
const char * const BNETD_CHANNEL_FILE = "conf/channel.conf";
@ -152,6 +153,7 @@ const char * const BNETD_SUPPORT_FILE = "conf/supportfile.conf";
const char * const BNETD_COMMAND_GROUPS_FILE = "conf/command_groups.conf";
const char * const BNETD_TOURNAMENT_FILE = "conf/tournament.conf";
const char * const BNETD_CUSTOMICONS_FILE = "conf/icons.conf";
const char * const BNETD_ALIASFILE = "conf/bnalias.conf";
/* time limit for new member as newer(whom cannot be promoted) in clan, (hrs) */
const unsigned CLAN_NEWER_TIME = 168;

View file

@ -14,7 +14,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef PVPGN_VERSION
#define PVPGN_VERSION "1.99.0-SVN"
#define PVPGN_VERSION "1.99.0-GIT"
#endif
#ifndef PVPGN_SOFTWARE
#define PVPGN_SOFTWARE "PvPGN"

View file

@ -21,6 +21,7 @@
#include <cstdio>
#include <cctype>
#include <cstring>
#include <string>
#include "compat/strdup.h"
#include "common/xalloc.h"
@ -267,4 +268,51 @@ namespace pvpgn
return result;
}
// You must free the result if result is non-NULL.
extern const char *str_replace(char *orig, char *rep, char *with)
{
char *result; // the return string
char *ins; // the next insert point
char *tmp; // varies
int len_rep; // length of rep
int len_with; // length of with
int len_front; // distance between rep and end of last rep
int count; // number of replacements
if (!orig)
return NULL;
if (!rep)
rep = "";
len_rep = strlen(rep);
if (!with)
with = "";
len_with = strlen(with);
ins = orig;
for (count = 0; tmp = strstr(ins, rep); ++count) {
ins = tmp + len_rep;
}
// first time through the loop, all the variable are set correctly
// from here on,
// tmp points to the end of the result string
// ins points to the next occurrence of rep in orig
// orig points to the remainder of orig after "end of rep"
tmp = result = (char*)malloc(strlen(orig) + (len_with - len_rep) * count + 1);
if (!result)
return NULL;
while (count--) {
ins = strstr(orig, rep);
len_front = ins - orig;
tmp = strncpy(tmp, orig, len_front) + len_front;
tmp = strcpy(tmp, with) + len_with;
orig += len_front + len_rep; // move to next "end of rep"
}
strcpy(tmp, orig);
return result;
}
}

View file

@ -28,6 +28,8 @@ namespace pvpgn
extern char * * strtoargv(char const * str, unsigned int * count);
extern char * arraytostr(char * * array, char const * delim, int count);
extern char * str_strip_affix(char * str, char const * affix);
extern const char *str_replace(char *orig, char *rep, char *with);
}