Topic: инфо об игроке
Всем хай форумчане
каким образом можно вывести инфо об игроке?
например команда /info <user>
PvPGN Community Forums |
forums.pvpgn.pro → [RU] The Source Code → инфо об игроке
Всем хай форумчане
каким образом можно вывести инфо об игроке?
например команда /info <user>
Всем хай форумчане
каким образом можно вывести инфо об игроке?
например команда /info <user>
смотря что именно должен выводить
например даю лок и причину
записывались в БД
и через /info вывести
Не очень понятно.
Причину лока можно указать в PvPGN Pro вроде бы
скажу по проще.
можно ли добавить к игроку комментарий, чтобы эти комменты записывались в отдельной таблице.
Ну да, очень легко кажется.
Но только смотря как, любой игрок должен видеть комментарии других игроков или только свои?
Легко будет если в одну строку писать комментарии в аккаунт с которого пишут команду.
типа 2 команды /comment User Text, /showcomments, первая добавит новый комментарий, а вторая выведет их
(как "записная книжка" )
Но если нужно сделать что бы любой игрок мог видеть комментарии к другому игроку, то это уже не так просто
У меня есть в созданных темах готовый код для комментирования друзей, может его возьми но он там сильно устаревший если используется PvPGN Pro)
комментирования друзей он же не записывается в БД?
Но если нужно сделать что бы любой игрок мог видеть комментарии к другому игроку, то это уже не так просто
помоги)))
Записывает, но там старый код, надо будет обновить его но пока что занят другим, там проще потому что всего один столбец создается в базе тех кто добавлен в друзья.
А если делать так как хочешь ты то это не знаю как сделать в один столбец. Если только разделителем по 2 строки (Ник/Коммент)
Хотя можно создать 2 столбца, без лимита на длину(если такое можно в настройках бд поставить)
и туда писать
В 1 список ников
В 2 список комментов
разделенных каким-нибудь символом
А потом при чтении, парсить в список строк, и выводить
Записывает, но там старый код, надо будет обновить его но пока что занят другим, там проще потому что всего один столбец создается в базе тех кто добавлен в друзья.
А если делать так как хочешь ты то это не знаю как сделать в один столбец. Если только разделителем по 2 строки (Ник/Коммент)
Хотя можно создать 2 столбца, без лимита на длину(если такое можно в настройках бд поставить)
и туда писать
В 1 список ников
В 2 список комментовразделенных каким-нибудь символом
А потом при чтении, парсить в список строк, и выводить
да вот в поисках не нашел такую же инфу.
Зач записывать создавая каждый раз новую колонку, когда в скл запросах есть апдейт. Самостоятельно создать колонку просто - всего делов то...
А где сказано про новые каждый раз?
Можно в один сделать, можно в два. (легче парсить если в два)
В PvPGN нет записи и чтения массива строк из mysql вроде бы
/comment User Text,
/showcomment user
сделать это ведь очень просто
В PvPGN нет записи и чтения массива строк из mysql вроде бы
А можно в PvPGN выводить данные из базы в вектор как в ботах устроено?
Пример: в боте, при записи данных в базу происходит также запись в вектор, через определённое время вектора сбрасываются до NULL т заполняются массивом информацией из базы. Поэтому причекадмин команде скажем - бот правильно распознает игрока как админа. Если же игрока нет в базе админов (скажем вы удалили вручную с базы напрямую), то бот считает игрока админом пока не обновится вектор.
Если в 1 строку писать через разделитель то можно легко строку в std::vector<std::string> поместить
просто удобнее будет в двух столбцах держать списки (список ников и список коммментариев) для каждого игрока
Например:
BNET//acct//Comments
BNET//acct//Comments_names
Заполнять так:
Comment1, Comment2,... + NewComment
Username1, Username2,... + NewName
Где ',' символ разделитель
Если в 1 строку писать через разделитель то можно легко строку в std::vector<std::string> поместить
просто удобнее будет в двух столбцах держать списки (список ников и список коммментариев) для каждого игрока
Например:
BNET//acct//Comments
BNET//acct//Comments_namesЗаполнять так:
Comment1, Comment2,... + NewComment
Username1, Username2,... + NewNameПросто если кто-то специально вставит символ-разделитель то сломает всю "систему", надо такой который нельзя через чат отправить )))
Или 2 символа | поставить как разделитель, они вроде бы в один сливаются если отправить через чат
а что если в отдельной таблице все это считывать?
т.е в таблице создается колона с именем игрока.
и в команде /info через это имя ищет все комментарии о него \n
ну игрок добавляет комментарий к другому игроку так?
я пишу /addcomment user test
и записывается ему в comment1 а если comment1 занято то comment2
и команда /showcomment user
показывает комментарий которые записывались
ну игрок добавляет комментарий к другому игроку так?
я пишу /addcomment user test
и записывается ему в comment1 а если comment1 занято то comment2
и команда /showcomment user
показывает комментарий которые записывались
нет только оп и админы могут добавить
Если в 1 строку писать через разделитель то можно легко строку в std::vector<std::string> поместить
просто удобнее будет в двух столбцах держать списки (список ников и список коммментариев) для каждого игрока
Например:
BNET//acct//Comments
BNET//acct//Comments_namesЗаполнять так:
Comment1, Comment2,... + NewComment
Username1, Username2,... + NewNameПросто если кто-то специально вставит символ-разделитель то сломает всю "систему", надо такой который нельзя через чат отправить )))
Или 2 символа | поставить как разделитель, они вроде бы в один сливаются если отправить через чат
Зачем такие сложности? Достаточно чекать по нику в таблице BNET и добавлять в новую созданную колонку ваш коммент в эту же таблицу. Что за костыли с каими-то разделителями ...
При вызове команды /addcomment name comment каждый раз обновлять колонку под чеком name в таблице. Зачем усложнять такую простую команду...
ну игрок добавляет комментарий к другому игроку так?
я пишу /addcomment user test
и записывается ему в comment1 а если comment1 занято то comment2
и команда /showcomment user
показывает комментарий которые записывались
в смысле создавать в бд каждый раз новый столбец: comment1 comment2 ... ?
Я предлагал сделать вектор для comment как это реализовано в боте. Чтобы каждый раз не обращаться к базе. А раз в некоторый промежуток времени обновлять этот вектор сбрасывая его и затем процедурой заполняя его запросом из базы.
P.S. Не уверен, что такое можно в PvPGN -> поэтому интересовался - возможно ли написать вектор подобного типа для PvPGN.
Что значит промежуток времени?
В момент добавления комментария прочитать список, добавить новый комментарий и сохранить обратно.
Что значит промежуток времени?
В момент добавления комментария прочитать список, добавить новый комментарий и сохранить обратно.
Когда в PvPGN обновляется информация о /stats или хэш пароля - это и есть промежуток времени.
То есть если изменить в базу напрямую информацию какую либо - сервер не сразу воспримет эти изменения.
Так сервер и не умеет напрямую писать в базу так что такой проблемы не возникнет)
Ладно щас сделаю готовый код рабочий все равно пока особо нечем заняться )
Добавлено: 19.02.2017 20:55
Я пока не могу проверить проверяйте сами:
account_wrap:
extern int account_get_comments( t_account * acc, std::vector<std::string> & usernames, std::vector<std::string> & comments )
{
const char * _Usernames = account_get_strattr( acc, "BNET\\acct\\comments_usernames" );
const char * _Comments = account_get_strattr( acc, "BNET\\acct\\comments_comments" );
if ( _Usernames && _Comments &&
_Usernames[ 0 ] != '\0' && _Comments[ 0 ] != '\0' )
{
usernames = SplitString( _Usernames, "\n" );
comments = SplitString( _Comments, "\n" );
if ( usernames.size( ) != comments.size( ) )
{
usernames.clear( );
comments.clear( );
//error, размеры списков не совпадают.
return -1;
}
return usernames.size( );
}
// no comments found
return 0;
}
extern int account_add_comment( t_account * acc, std::string username, std::string comment )
{
std::vector<std::string> ListOfUsernames, ListOfComments;
std::string OutUsernames, OutComments;
account_get_comments( acc, ListOfUsernames, ListOfComments );
ListOfUsernames.push_back( username );
ListOfComments.push_back( comment );
for ( std::string s : ListOfUsernames )
{
OutUsernames += s + "\n";
}
for ( std::string s : ListOfComments )
{
OutComments += s + "\n";
}
account_set_strattr( acc, "BNET\\acct\\comments_usernames", OutUsernames.c_str( ) );
account_set_strattr( acc, "BNET\\acct\\comments_comments", OutComments.c_str( ) );
return 0;
}
extern int account_del_comment( t_account * acc, int commentid )// commentid 1+
{
std::vector<std::string> ListOfUsernames, ListOfComments;
std::string OutUsernames, OutComments;
int commentscount = account_get_comments( acc, ListOfUsernames, ListOfComments );
if ( commentscount >= commentid && commentid > 1 )
{
ListOfUsernames.erase( ListOfUsernames.begin( ) + ( commentid - 1 ) );
ListOfComments.erase( ListOfUsernames.begin( ) + ( commentid - 1 ) );
for ( std::string s : ListOfUsernames )
{
OutUsernames += s + "\n";
}
for ( std::string s : ListOfComments )
{
OutComments += s + "\n";
}
account_set_strattr( acc, "BNET\\acct\\comments_usernames", OutUsernames.c_str( ) );
account_set_strattr( acc, "BNET\\acct\\comments_comments", OutComments.c_str( ) );
return 1;
}
else
{
// Неверный ID
return -1;
}
return 0;
}
commands:
static int _handle_addcomment_command( t_connection * c, char const * text )
{
std::vector<std::string> args = split_command( text, 2 );
t_account * acc;
//arg 1 = username, arg 2 = comment
if ( args[ 1 ].empty( ) )
{
msgtemp = localize( c, "Need enter username and comment!" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
else if ( args[ 2 ].empty( ) )
{
msgtemp = localize( c, "Need enter comment!" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
if ( !( acc = accountlist_find_account( args[ 1 ].c_str( ) ) ) )
{
msgtemp = localize( c, "User {} not found!", args[ 1 ].c_str( ) );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
account_add_comment( acc, args[ 1 ], args[ 2 ] );
return 0;
}
static int _handle_delcomment_command( t_connection * c, char const * text )
{
std::vector<std::string> args = split_command( text, 2 );
//arg 1 = username, arg 2 = commentid
t_account * acc;
if ( args[ 1 ].empty( ) )
{
msgtemp = localize( c, "Need enter username and comment id!" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
else if ( args[ 2 ].empty( ) )
{
msgtemp = localize( c, "Need enter comment id!(enter /showcomments for see id)" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
if ( !( acc = accountlist_find_account( args[ 1 ].c_str( ) ) ) )
{
msgtemp = localize( c, "User {} not found!", args[ 1 ].c_str( ) );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
account_del_comment( acc, std::atoi( args[ 2 ].c_str( ) ) );
return 0;
}
static int _handle_showcomment_command( t_connection * c, char const * text )
{
std::vector<std::string> args = split_command( text, 1 );
std::vector<std::string> ListOfUsernames, ListOfComments;
int commentscount = 0;
//arg 1 = username
t_account * acc;
if ( args[ 1 ].empty( ) )
{
msgtemp = localize( c, "Need enter username!" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
if ( !( acc = accountlist_find_account( args[ 1 ].c_str( ) ) ) )
{
msgtemp = localize( c, "User {} not found!", args[ 1 ].c_str( ) );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
if ( !( commentscount = account_get_comments( acc, ListOfUsernames, ListOfComments ) ) )
{
msgtemp = localize( c, "No comments for user {}.", args[ 1 ].c_str( ) );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
msgtemp = localize( c, "List comments for user {}.", args[ 1 ].c_str( ) );
message_send_text( c, message_type_info, c, msgtemp );
for ( int i = 0; i < commentscount; i++ )
{
msgtemp = localize( c, "#{}.{}:{}", i, ListOfUsernames[ i ].c_str( ), ListOfComments[ i ].c_str( ) );
message_send_text( c, message_type_info, c, msgtemp );
}
return 0;
}
xstring:
extern std::vector<std::string> SplitString( std::string s, std::string delim )
{
std::vector<std::string> Out;
size_t pos = 0;
std::string token;
while ( ( pos = s.find( delim ) ) != std::string::npos ) {
token = s.substr( 0, pos );
Out.push_back( token );
s.erase( 0, pos + delim.length( ) );
}
//Out.push_back( s );
return Out;
}
Если не будет работать завтра посмотрю, сегодня спешил и нет возможности проверить.
а индефикатор зачем?
или не прописывая ник ID игрока прописать ?
Добавлено: 19.02.2017 21:31
xstring: куда добавить его, в какой файл)))
почему то тут показывает ошибку?
Добавлено: 19.02.2017 21:35
у меня PVPGN 1.97
Код только для pvpgn pro
а ошибка потому что версия C++ старая
У меня c++ 2010. Можешь переписать код для 1 .9.7 и для 2010
Если тебе не трудно пжлста)) ну и если у тебя есть на это время
К тому же еще ошибку выдает account_add_comment с этим что делать?
Код для PVPGN PRO, но можешь перенести оттуда функцию split_command должно будет работать.
Ошибка т.к надо в '.h' файлы добавить тоже функции забыл скопировать)
А ошибка в 'for' т.к это добавлено было только в C++11 вроде бы)
Можно ведь после magic builder скачать студию 2017 бесплатную и пользоваться ей для редактирования кода.
SkyFall wrote:ну игрок добавляет комментарий к другому игроку так?
я пишу /addcomment user test
и записывается ему в comment1 а если comment1 занято то comment2
и команда /showcomment user
показывает комментарий которые записывалисьв смысле создавать в бд каждый раз новый столбец: comment1 comment2 ... ?
или проще добавить в одну столбцу всю коментарий
а ты пропустил все уже , я уже написал пример кода для хранения комментариев в двух столбцах (можно и в 1, но там менее удобно будет использовать)
Добавлено: 21.02.2017 13:10
Код работает только 1 ошибка была.
Немного улучшил.
Вот пример как работает:
account_wrap.h
extern int account_get_comments( t_connection * c, t_account * acc, std::vector<std::string> & usernames, std::vector<std::string> & comments );
extern int account_add_comment( t_connection * c, t_account * acc, std::string username, std::string comment );
extern int account_del_comment( t_connection * c, t_account * acc, int commentid );
account_wrap.cpp
extern int account_get_comments( t_connection * c, t_account * acc, std::vector<std::string> & usernames, std::vector<std::string> & comments )
{
std::string TempMsg;
const char * _Usernames = account_get_strattr( acc, "BNET\\acct\\comments_usernames" );
const char * _Comments = account_get_strattr( acc, "BNET\\acct\\comments_comments" );
if ( _Usernames && _Comments &&
_Usernames[ 0 ] != '\0' && _Comments[ 0 ] != '\0' )
{
usernames = SplitString( _Usernames, "'||" );
comments = SplitString( _Comments, "'||" );
if ( usernames.size( ) != comments.size( ) )
{
usernames.clear( );
comments.clear( );
if ( c != NULL )
{
TempMsg = localize( c, "Error. Bad comment/usernames count. Delete all for fix." );
message_send_text( c, message_type_error, c, TempMsg );
}
return -1;
}
return usernames.size( );
}
if ( c != NULL )
{
TempMsg = localize( c, "No comments found for {} user.", account_get_name( acc ) );
message_send_text( c, message_type_info, c, TempMsg );
}
//
return 0;
}
extern int account_add_comment( t_connection * c, t_account * acc, std::string username, std::string comment )
{
std::vector<std::string> ListOfUsernames, ListOfComments;
std::string OutUsernames, OutComments, TempMsg;
account_get_comments( NULL, acc, ListOfUsernames, ListOfComments );
ListOfUsernames.push_back( username );
ListOfComments.push_back( comment );
for ( std::string s : ListOfUsernames )
{
OutUsernames += s + "'||";
}
for ( std::string s : ListOfComments )
{
OutComments += s + "'||";
}
TempMsg = localize( c, "Comment {} added for {} user.", comment,
account_get_name( acc ) );
message_send_text( c, message_type_info, c, TempMsg );
account_set_strattr( acc, "BNET\\acct\\comments_usernames", OutUsernames.c_str( ) );
account_set_strattr( acc, "BNET\\acct\\comments_comments", OutComments.c_str( ) );
return 0;
}
extern int account_del_comment(t_connection * c, t_account * acc, int commentid )// commentid 1+
{
std::vector<std::string> ListOfUsernames, ListOfComments;
std::string OutUsernames, OutComments, TempMsg;
int commentscount = account_get_comments(NULL, acc, ListOfUsernames, ListOfComments );
if ( commentscount >= commentid && commentid >= 1 )
{
TempMsg = localize( c, "Comment #{} removed. (User {} comment {}).", commentid,
ListOfUsernames[ commentid - 1 ].c_str( ), ListOfComments[ commentid - 1 ].c_str( ));
message_send_text( c, message_type_info, c, TempMsg );
ListOfUsernames.erase( ListOfUsernames.begin( ) + ( commentid - 1 ) );
ListOfComments.erase( ListOfComments.begin( ) + ( commentid - 1 ) );
for ( std::string s : ListOfUsernames )
{
OutUsernames += s + "'||";
}
for ( std::string s : ListOfComments )
{
OutComments += s + "'||";
}
account_set_strattr( acc, "BNET\\acct\\comments_usernames", OutUsernames.c_str( ) );
account_set_strattr( acc, "BNET\\acct\\comments_comments", OutComments.c_str( ) );
return 1;
}
else
{
TempMsg = localize( c, "Error! Bad comment id!" );
message_send_text( c, message_type_error, c, TempMsg );
return -1;
}
return 0;
}
command.cpp
static int _handle_addcomment_command( t_connection * c, char const * text )
{
std::vector<std::string> args = split_command( text, 2 );
t_account * acc;
//arg 1 = username, arg 2 = comment
if ( args[ 1 ].empty( ) )
{
msgtemp = localize( c, "Need enter username and comment!" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
else if ( args[ 2 ].empty( ) )
{
msgtemp = localize( c, "Need enter comment!" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
else if ( args[ 2 ].length( ) < 5 || args[ 2 ].length( ) > 120 )
{
msgtemp = localize( c, "Error. Limit for comment length: 5-100 chars!" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
if ( !( acc = accountlist_find_account( args[ 1 ].c_str( ) ) ) )
{
msgtemp = localize( c, "User {} not found!", args[ 1 ].c_str( ) );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
account_add_comment(c, acc, args[ 1 ], args[ 2 ] );
return 0;
}
static int _handle_delcomment_command( t_connection * c, char const * text )
{
std::vector<std::string> args = split_command( text, 2 );
//arg 1 = username, arg 2 = commentid
t_account * acc;
if ( args[ 1 ].empty( ) )
{
msgtemp = localize( c, "Need enter username and comment id!" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
else if ( args[ 2 ].empty( ) )
{
msgtemp = localize( c, "Need enter comment id!(enter /showcomments for see id)" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
if ( !( acc = accountlist_find_account( args[ 1 ].c_str( ) ) ) )
{
msgtemp = localize( c, "User {} not found!", args[ 1 ].c_str( ) );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
account_del_comment( c, acc, std::atoi( args[ 2 ].c_str( ) ) );
return 0;
}
static int _handle_showcomment_command( t_connection * c, char const * text )
{
std::vector<std::string> args = split_command( text, 1 );
std::vector<std::string> ListOfUsernames, ListOfComments;
int commentscount = 0;
//arg 1 = username
t_account * acc;
if ( args[ 1 ].empty( ) )
{
msgtemp = localize( c, "Need enter username!" );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
if ( !( acc = accountlist_find_account( args[ 1 ].c_str( ) ) ) )
{
msgtemp = localize( c, "User {} not found!", args[ 1 ].c_str( ) );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
if ( !( commentscount = account_get_comments( c, acc, ListOfUsernames, ListOfComments ) ) )
{
msgtemp = localize( c, "No comments for user {}.", args[ 1 ].c_str( ) );
message_send_text( c, message_type_error, c, msgtemp );
return -1;
}
msgtemp = localize( c, "List comments for user {}.", args[ 1 ].c_str( ) );
message_send_text( c, message_type_info, c, msgtemp );
for ( int i = 0; i < commentscount; i++ )
{
msgtemp = localize( c, "#{}.{}:{}", i + 1, ListOfUsernames[ i ].c_str( ), ListOfComments[ i ].c_str( ) );
message_send_text( c, message_type_info, c, msgtemp );
}
return 0;
}
xstring.h
extern std::vector<std::string> SplitString( std::string s, std::string delim );
xstring.cpp
extern std::vector<std::string> SplitString( std::string s, std::string delim )
{
std::vector<std::string> Out;
size_t pos = 0;
std::string token;
while ( ( pos = s.find( delim ) ) != std::string::npos ) {
token = s.substr( 0, pos );
Out.push_back( token );
s.erase( 0, pos + delim.length( ) );
}
//Out.push_back( s );
return Out;
}
Требования:
1. PvPGN PRO / или перенести необходимое из pvpgn pro (#include <string>, #include <vector>, std::string msgtemp, split_command )
2. Сделать размер строк "BNET\\acct\\comments_usernames" и "BNET\\acct\\comments_comments" в бд неограниченным. (если есть какие-то ограничения )
Заменил "\n" на "'||" а то че-то у меня можно сломать все просто введя в комменте \n
можно ли как нибудь заменить
for ( std::string s : ListOfComments )
:
Добавлено: 21.02.2017 18:48
что делать если нету
xstring.cpp / h
можно ли как нибудь заменить
for ( std::string s : ListOfComments )
:
Добавлено: 21.02.2017 18:48
for (int i = 0; i < ListOfComments.size(); ++i)
{
std::string const& s = ListOfComments[ i];
...
что делать если нету
xstring.cpp / h
добавь не в xstring тогда, а перед extern int account_get_comments
добавь не в xstring тогда, а перед extern int account_get_comments
в wrap.cpp??
туда, куда extern int account_get_comments добавляешь
Да туда же где используется функция split
Ну да файлы могут отличаться я сейчас не работаю с обычной версией pvpgn так что точно сказать не могу.
account_add_comment(c, acc, args[ 1 ], args[ 2 ] );
не понимаю из за этого не компилит
6>command.obj : error LNK2019: unresolved external symbol "int __cdecl pvpgn::bnetd::account_add_comment(struct pvpgn::bnetd::connection *,struct pvpgn::bnetd::account_struct *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?account_add_comment@bnetd@pvpgn@@YAHPAUconnection@12@PAUaccount_struct@12@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2@Z) referenced in function "int __cdecl pvpgn::bnetd::_handle_i_command(struct pvpgn::bnetd::connection *,char const *)" (?_handle_i_command@bnetd@pvpgn@@YAHPAUconnection@12@PBD@Z)
forums.pvpgn.pro → [RU] The Source Code → инфо об игроке