Skip to forum content

You are not logged in. Please login or register.


forums.pvpgn.pro → [RU] The Source Code → Помогите сделать команду /amhcheck

Pages 1

You must login or register to post a reply

RSS topic feed

Posts: 14

1

Topic: Помогите сделать команду /amhcheck

Короче хочу сделать команду, которая будет искать строку "ник игрока" в файле username.txt(в этом файле только ники, каждый ник - новая строка) ,  и если такой ник не найден - выкидывать командой /kill


вот код:

static int _handle_amhcheck_command(t_connection * c, char const *text)
{
  unsigned int i;
  t_connection *    user;
  t_game     *    game;

  for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
  for (; text[i]==' '; i++);

  if (text[i]=='\0')
    {
      if ((game=conn_get_game(c)))
    {
      for (i=0; i<game_get_count(game); i++)
        {
          if ((user = game_get_player_conn(game, i)))
        {
          snprintf(msgtemp2, sizeof(msgtemp), "%.64s",conn_get_username(user));
          //
          //...need search msgtemp2 in file ./files/usernames.dat
          //
        }
        }
      return 0;
    }
    }
  else if ((user = connlist_find_connection_by_accountname(&text[i])))
    snprintf(msgtemp2, sizeof(msgtemp), "%.64s",&text[i]);
  //
          //...need search msgtemp2 in file ./files/usernames.dat
          //
  else // if error
    { 
    snprintf(msgtemp, sizeof(msgtemp), "Выполните команду в игре или ник указан не верно"); 
    message_send_text(c,message_type_info,c,msgtemp);
  return 0;
    }
  return 0;
} 


Поможете ?:) а то не получается как-то

Добавлено: 10.02.2012 14:05

предварительно нужно переводить ники в нижний регистр.

Добавлено: 10.02.2012 14:05

// хотя  можно обойтись без перевода

2

Re: Помогите сделать команду /amhcheck

Пример построчного чтения из файла stackoverflow.com/questions/5510 … -from-file

Но из файла, как понимаешь, можно постоянно читать только при небольшом количестве строк.

Do not ask for support in PM.

3

Re: Помогите сделать команду /amhcheck

вот что у меня получилось... Ну там 800 строк, и 1000 раз нужно проверить эти 800 строк smile))

static int _handle_amhcheck_command(t_connection * c, char const *text)
{
  t_elem const * curr;
  t_connection * conn;
  char const * nickname;
  unsigned int   i;
  unsigned int o,l=0;
  FILE* f = fopen("usernames.dat", "r");
  
  message_send_text(c,message_type_info,c,"открыт файл");/* debug messages */
  for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
  for (; text[i]==' '; i++);
  
  if (text[i]=='\0')
    {
        LIST_TRAVERSE_CONST(connlist(),curr)
        {
        message_send_text(c,message_type_info,c,"1");
        conn = (t_connection*)elem_get_data(curr);
        if (conn_get_account(conn))
        {
        message_send_text(c,message_type_info,c,"Найден аккаунт");/* debug messages */

        char current_str[2000];
        unsigned long n,z=0;
        unsigned long k=0;
 
        nickname=conn_get_username(conn); 
         
        while(!feof(f))
        {
        char buf[MAX_USERNAME_LEN+MAX_REALMNAME_LEN];
        int len = 0;
        int MAXLEN = MAX_USERNAME_LEN+MAX_REALMNAME_LEN;
        fgets(buf, MAXLEN, f);
        len = strlen(buf);
        if(buf[len-1] == '\n')
            buf[len-1] = '\0';
        if(strcmp(buf, nickname) == 0)
            {
            ++k;
            }
        }
        
        if ((nickname=="OpenDiv") || ((nickname=="OpenDiv1") || (nickname=="OpenDiv2") || (nickname=="OpenDiv3") || (nickname=="OpenDiv4") || (nickname=="OpenDiv5") || (nickname=="OpenDiv6") || (nickname=="OpenDiv7") || (nickname=="OpenDiv8") || (nickname=="OpenDiv9") || (nickname=="OpenDiv10") || (nickname=="OpenDiv11") || (nickname=="OpenDiv12") || (nickname=="OpenDiv13") || (nickname=="OpenDiv14") || (nickname=="OpenDiv15") || (nickname=="OpenDiv16") || (nickname=="AMX") || (nickname=="CloseDiv") || (nickname=="ImbaDiv") || (nickname=="XXX") || (nickname=="AOP") || (nickname=="TR") || (nickname=="Buni") || (nickname=="Rita") || (nickname=="Omi") || (nickname=="Mark") || (nickname=="Mila") || (nickname=="Lara") || (nickname=="Void") )
        {
        k=0;
        goto killololo;
        }
        else if (k==0)
        {
        conn_set_state(conn,conn_state_destroy);
        k=0;
        o++;
        }
        else    
        {
        k=0;
        l++;
        }
        }

        killololo: return 0;
        }
      
    return 0;
    }
    
    snprintf(msgtemp, sizeof(msgtemp), "Обнаружено %9u игроков без античита",o); /* debug messages */
    snprintf(msgtemp2, sizeof(msgtemp2), "Обнаружено %9u игроков с античитом",l);/* debug messages */
   message_send_text(c,message_type_info,c,msgtemp);/* debug messages */
   message_send_text(c,message_type_info,c,msgtemp2);/* debug messages */
       fclose(f);
      message_send_text(c,message_type_info,c,"закрыт файл");/* debug messages */
  return 0;
}

Добавлено: 12.02.2012 10:11

как долго будет выполнятся этот код? smile

4

Re: Помогите сделать команду /amhcheck

Предполагаю, что после первого же прохода указатель останется в конце файла, поэтому его нужно его переводить в начало, чтобы можно было читать заново:

rewind(f);

Но 1000 раз считывать файл это как-то нерационально. Лучше бы в начале считать весь файл в массив и потом этот массив итерировать сколько хочешь.
Иначе такая команда будет считывать по ~7 мб данных с харда (800 юзеров * 9 байт каждый * 1000 раз).

Do not ask for support in PM.

5 (edited by Karaulov 12.02.2012 13:19)

Re: Помогите сделать команду /amhcheck

мне нужно постоянно этот файл заново открывать(после каждого ввода команды /amhcheck), так как число юзеров обновляется постоянно.


В файле usernames.dat хранятся ники игроков которые вошли с античитом, команда получает список всех игроков, и ищет каждый ник в файле usernames.dat.

rewind(f); куда вставить? что бы не получить ничего лишнего в подарок, или всё-таки не нужно?

Добавлено: 12.02.2012 12:20

ещё интересует вопрос, как переводить строки в нижний регистр?

может быть такое что в списке ник будет с большой буквы, а в реале с мелкой

6

Re: Помогите сделать команду /amhcheck

Я и говорю, чтобы открывать файл и считывать все данные в массив только один раз, в начале команды. Затем внутри LIST_TRAVERSE_CONST искать юзера в этом массиве.

rewind(f); перед или после блока while(!feof(f)). Но он ведь не нужен, если считывание из файла будет единожды.

Из таблицы bnet сравнивай username - он в lowercase. Ну или посимвольно приводи имя через tolower.

Do not ask for support in PM.

7

Re: Помогите сделать команду /amhcheck

Коллекции для лохов сделаны, не трогай их. Или их в С вообще нет?

8 (edited by Karaulov 13.02.2012 10:21)

Re: Помогите сделать команду /amhcheck

ну в общем вот команда:

static int _handle_amhcheck_command(t_connection * c, char const *text)
{
  t_elem const * curr;
  t_connection * conn;
  char const * nickname;
  unsigned int   i;
  unsigned long o,l=0;
  FILE* f = fopen("usernames.dat", "r");
  
  for (i=0; text[i]!=' ' && text[i]!='\0'; i++); /* skip command */
  for (; text[i]==' '; i++);
  
  if (text[i]=='\0')
    {
        LIST_TRAVERSE_CONST(connlist(),curr)
        {
        conn = (t_connection*)elem_get_data(curr);
        if (conn_get_account(conn))
        {

        unsigned long k=0;
 
        nickname=conn_get_username(conn); 
         
        while(!feof(f))
        {
        char buf[MAX_USERNAME_LEN+MAX_REALMNAME_LEN];
        int len = 0;
        int MAXLEN = MAX_USERNAME_LEN+MAX_REALMNAME_LEN;
        fgets(buf, MAXLEN, f);
        len = strlen(buf);
        if(buf[len-1] == '\n')
            buf[len-1] = '\0';
        if(strcmp(buf, nickname) == 0)
            {
            ++k;
             break;
            }
        }
        
        if ((nickname=="OpenDiv") || (nickname=="OpenDiv1") || (nickname=="OpenDiv2") || (nickname=="OpenDiv3") || (nickname=="OpenDiv4") || (nickname=="OpenDiv5") || (nickname=="OpenDiv6") || (nickname=="OpenDiv7") || (nickname=="OpenDiv8") || (nickname=="OpenDiv9") || (nickname=="OpenDiv10") || (nickname=="OpenDiv11") || (nickname=="OpenDiv12") || (nickname=="OpenDiv13") || (nickname=="OpenDiv14") || (nickname=="OpenDiv15") || (nickname=="OpenDiv16") || (nickname=="AMX") || (nickname=="CloseDiv") || (nickname=="ImbaDiv") || (nickname=="XXX") || (nickname=="AOP") || (nickname=="TR") || (nickname=="Buni") || (nickname=="Rita") || (nickname=="Omi") || (nickname=="Mark") || (nickname=="Mila") || (nickname=="Lara") || (nickname=="Void"))
        {
        k=0;
         break;
        }
        else if (k==0)
        {
        conn_set_state(conn,conn_state_destroy);
        k=0;
        o++;
        }
        else    
        {
        k=0;
        l++;
        }
        }
        }
    }
    
    snprintf(msgtemp, sizeof(msgtemp), "Обнаружено %9u игроков без античита",o);
    snprintf(msgtemp2, sizeof(msgtemp2), "Обнаружено %9u игроков с античитом",l);
   message_send_text(c,message_type_info,c,msgtemp);
   message_send_text(c,message_type_info,c,msgtemp2);
   fclose(f);
  return 0;
}

сейчас хочу узнать, что делает — break;  ? можно использовать как замену goto? или лучше всетаки goto использовать?

9

Re: Помогите сделать команду /amhcheck

break; останавливает цикл и выходит из него. В твоем случае, цикл while.
Про goto лучше вообще забудь, всегда можно обойтись без него.


xpeh, в C вообще ничего нет, раз уж на то пошло. Есть только простые функции, которые можно включать по мере необходимости, весь код которых можно посмотреть и изменить в инклюд директории, которая обычно лежит рядом с компилятором.

Do not ask for support in PM.

10

Re: Помогите сделать команду /amhcheck

HarpyWar wrote:

xpeh, в C вообще ничего нет, раз уж на то пошло.

Какая-то стандартная библиотека все-таки есть.

Cub_bone wrote:

сейчас хочу узнать, что делает — break;  ? можно использовать как замену goto? или лучше всетаки goto использовать?

Оу е.
И строки через == сравнивать нельзя. Ты хоть один язык программирования знаешь?

11 (edited by Karaulov 13.02.2012 19:37)

Re: Помогите сделать команду /amhcheck

интересно, просто у меня это работает, если я захожу с ником OpenDiv - пишет что ник зарезервирован smile))
(в моем коде дебаг сообщения просто есть, тут я их удалил)


HarpyWar wrote:

break; останавливает цикл и выходит из него. В твоем случае, цикл while.
Про goto лучше вообще забудь, всегда можно обойтись без него.


xpeh, в C вообще ничего нет, раз уж на то пошло. Есть только простые функции, которые можно включать по мере необходимости, весь код которых можно посмотреть и изменить в инклюд директории, которая обычно лежит рядом с компилятором.

да я знаю что он выходит из цикла, просто не совсем это понимаю: т.е если сработает break то выйдет из цикла и больше этот цикл не запустится ?:) типо попадётся ник OpenDiv  и дальше не будет проверять игроков?

Добавлено: 13.02.2012 18:46

xpeh, да ты прав не работает, ну я это только что исправил.

Ну думал раз компилятор не ругается , знач всё в порядке big_smile

12

Re: Помогите сделать команду /amhcheck

break останавливает выполнение кода в текущем цикле и полностью выходит из него (попадётся ник OpenDiv  и дальше не будет проверять игроков).
continue останавливает только текущую итерацию цикла, а затем цикл продолжается со следующей итерации.

Do not ask for support in PM.

13

Re: Помогите сделать команду /amhcheck

значит мне нужно использовать continue ? smile

14

Re: Помогите сделать команду /amhcheck

Cub_bone wrote:

значит мне нужно использовать continue ? smile

По всей видимости - да.

Do not ask for support in PM.

Posts: 14

Pages 1

You must login or register to post a reply

Who now at forum

Currently view post: 1 guest, 0 registered users

forums.pvpgn.pro → [RU] The Source Code → Помогите сделать команду /amhcheck