Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Клуб программистов > Обсуждение статей
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.06.2010, 10:56   #451
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

1.
Цитата:
Сообщение от Beermonza Посмотреть сообщение
Нужно понять одно, что len - переменная длины вырезки, если из строки вырезать длину символов больше чем там есть, то в конец результата пойдет неопределенный добавочный символ, т.к. String - не ограничен и расширяется автоматически. Если вы запишете s: String[10] и вылезете за рамки, будет ошибка. В вашем случае идет пустой символ, который не виден, может это пробел, я не знаю, ...вот и видно, что результат одинаковый, но len := length(text) - 2; математически корректен.
Ошибка была в этом блоке
Код:
Клиент
    // Примем строку списка пользователей
    1: begin      
      // Очищаем список клиентов
      UserListView.Items.Clear;
      // Добавим ключ конца строки (т.к. вырезка символов с задержкой)
      text := text + Chr(152);
      // Укажем начальный символ
      pos2 := 3;
      // Обнулим счетчик символов
      x := 0;
      // Пробегаем по длине строки списка
      for j := 3 to len + 2 do // До этого тут было значение 1
        begin
          // Записываем в счетчик сдвиг
          x := x + 1;
2.
Цитата:
Если вы выбираете пользователя, то должны знать его индекс, ...несколько раз говорил про взятие со списка, или через поиск по массиву, ...только после этого отправлять бан кому-то, а не последнему i - 1 пользователю.
Это имеется ввиду
Цитата:
Что касается сервера, ...у него есть список подключившихся, мышью выбираем клиента (так же как и в привате), в цикле ищем имя в массиве UserMas[j].Name, по совпадению отправляем пакет так же, но по j, почему? ...массив числится от 0 до ActiveConnections-1.
3. Тогда данный код на получение данных какого-то юзера тоже не верен
Код:
     
      // Получим IP забаненого
      GetBannedIP := ServerSocket.Socket.Connections[i - 1].RemoteAddress;
      // Отошлём команду бана
      ServerSocket.Socket.Connections[i - 1].SendText('21');
IP будет взят не тот, который нужен и соответсвенно пакет будет отослан тоже не по тому адресу. И код на бан удалённым администратором тоже будет неверным
Код:
ServerSocket.Socket.Connections[i - 1].SendText('21');
он дастся тому, кто банит, что я и вижу.

4. Давайте по порядку. Как правильно организовать отсылку команды с сервера в нужный канал и как правильно организовать отсылку команды в нужный канал при удалённом администировании, зная ник забанившего и ник забаненного?

Последний раз редактировалось Shouldercannon; 17.06.2010 в 16:57.
Shouldercannon вне форума Ответить с цитированием
Старый 17.06.2010, 17:52   #452
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Цитата:
Сообщение от Shouldercannon
Давайте по порядку. Как правильно организовать отсылку команды с сервера в нужный канал и как правильно организовать отсылку команды в нужный канал при удалённом администировании, зная ник забанившего и ник забаненного?
Ну, здрастЕ ...вся тема нашпигована алгоритмами получения номера канала, что в массиве сервера, что по имени из списка. Удаленный администратор шлет имя жертвы, сервер точно так же ищет имя в массиве, и найдя, отправляет команду в канал конкретному пользователю, условие ведь сработало на конкретном шаге цикла перебора, этот шаг и есть номер канала, если счет от 0 до ActiveConnections - 1.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 17.06.2010, 20:48   #453
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
Восклицание

Всё разобрался
Код:
ServerSocket.Socket.Connections[UserListView.Selected.Index - 1].Какое-то действие;
всё исправил.

1. Используя данный код (Code.txt) удалённого бана иногда у кого-то из юзеров игнорируется удалённый бан/разбан на всех. У кого-то вообще банится только один юзер. И ногда бывает, что IP меняются местами, баню юзера1, а бан приходит на меня.
P.S. Думал пакеты не доходят поэтому и действие не происходит, но нет всё прекрасно доходит и где-то заступоривается.

2. Юзеры, не пускаемые в чат из-за диапазона или занятого IP, в процедуре клиента Disconnect при переподключении начинают мучить список юзеров в процедуре сервера procedure TForm1.ServerSocketClientConnect(Se nder: TObject;
Socket: TCustomWinSocket);
кодом // Разрешаем обновление
UpdMas := True;

Если нельзя на клиенте закрывать канал, может можно Disconnect сделать при получении соответвующей команды?
Вложения
Тип файла: txt Code.txt (15.7 Кб, 129 просмотров)

Последний раз редактировалось Shouldercannon; 18.06.2010 в 11:31.
Shouldercannon вне форума Ответить с цитированием
Старый 18.06.2010, 20:46   #454
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

1 Ошибка по невнимательности, вот кусок ваш на бан:

Код:
// Бан удалённым администратором
                1: begin
                  // Заполняем BannedUnbannedNick, AdminReason
                  a := Pos(Chr(156), text);
                  BannedUnbannedNick := Copy(text, 3, a - 3);
                  AdminReason := Copy(text, a + 1, length (text));

                  // Поиск IP по нику в UserListView
                  for c := 0 to UserListView.Items.Count - 1 do
                    begin
                      if Pos(BannedUnbannedNick, UserListView.Items.Item[c].Caption) <> 0 then
                        BannedIP := Copy(UserListView.Items.Item[c].SubItems.Text, 1, length(UserListView.Items.Item[c].SubItems.Text) - 2);
                    end;
                  if not (BannedIP = '127.0.0.1') then
                    begin
                      // Поместим IP забаненого в базу
                      BanIP.Add(BannedIP);
                      // Создаем цикл поиска забаненого пользователя
                      for i3 := 0 to ServerSocket.Socket.ActiveConnections - 1 do
                        begin
                          // Если пользователь найден

                          // !!!!!!!!! почему i ? ...цикл идет по i3.
                          if UserMas[i + 1].Name = BannedUnbannedNick then
                            begin
                              // Отошлём команду бана

                              // !!!!!!!!! тут тоже самое.

                              ServerSocket.Socket.Connections[i].SendText('21');

                              // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                              // Добавим событие бана в ServerLog
                              ServerLog.Add('[' + DateTimeToStr(Now) + '] ' + UserMas[i].Name + ' забанил IP: ' + BannedIP + '. Причина: ' + AdminReason + '.');
                              // Сохраняем ServerLog, BanIP и обновляем массив бана
                              SaveServerLogBanIP;
i - номер канала удаленного администратора в данном случае (i-1 точнее), по его каналу i-1 пришел пакет с именем нарушителя, ...это имя ищется по циклу i3, вот и нужно искать имя в массиве по i3+1, а команду слать в i3 канал.
Ниже в коде по файлу в снятии бана аналогичная ошибка.

2 Можно использовать команду перехода GoTo, чтобы при закрытии канала нежелательного пользователя программа переходила в конец процедуры коннекта, минуя флаг UpdMas:

Код:
procedure TForm1.ServerSocketClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
Label G;    // метка
var
  i: Integer;
begin
  // Получим IP подключающегося
  GetConnectIP := Socket.RemoteAddress;

  // Проверка на разрешённый диапазон IP
  d := 0;
  for b := 1 to Range do
    begin
      if (IPtoDWORD(GetConnectIP) >= IPtoDWORD(IPRange[b].IP1)) and (IPtoDWORD(GetConnectIP) <= IPtoDWORD(IPRange[b].IP2)) then
        d := d + 1;
    end;

  // Закрыть канал
  if d = 0 then
    begin
      Socket.Close;
      GoTo G;           // переход в метку
    end;

  StatusBar1.Panels[2].Text := '[' + TimeToStr(Now) + '] Клиент подключился';

  // Разрешаем обновление
  UpdMas := True;

G:  // сюда перейдет программа
 
end;
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 18.06.2010, 21:20   #455
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

Здесь нужно что-то делать?
Код:
G:  // сюда перейдет программа
Список снова обновляется даже с меткой.
Shouldercannon вне форума Ответить с цитированием
Старый 18.06.2010, 21:49   #456
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Делать ничего не нужно, это метка строки, следом идет конец процедуры.
Цитата:
Сообщение от Shouldercannon
Список снова обновляется даже с меткой.
Потому, что есть еще ServerSocketClientDisconnect, в нем тоже нужно принять меры. Например, при коннекте включить какой-то созданный заранее флаг сразу после команды закрытия. В дисконнекте прописать условие типа: если флаг ложный, включить UpdMas, а этот выключить.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 18.06.2010, 22:22   #457
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

1.
Цитата:
Сообщение от Beermonza Посмотреть сообщение
Делать ничего не нужно, это метка строки, следом идет конец процедуры.

Потому, что есть еще ServerSocketClientDisconnect, в нем тоже нужно принять меры. Например, при коннекте включить какой-то созданный заранее флаг сразу после команды закрытия. В дисконнекте прописать условие типа: если флаг ложный, включить UpdMas, а этот выключить.
Вот что получилось и работает довольно не плохо
Код:
procedure TForm1.ServerSocketClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
Label G; // Метка
var
  d: Integer;
begin
  // Получим IP подключающегося
  GetConnectIP := Socket.RemoteAddress;

  // Проверка на разрешённый диапазон IP
  d := 0;
  for a := 1 to Range do
    begin
      if (IPtoDWORD(GetConnectIP) >= IPtoDWORD(IPRange[a].IP1)) and (IPtoDWORD(GetConnectIP) <= IPtoDWORD(IPRange[a].IP2)) then
        d := d + 1;
    end;

  // Закрыть канал
  if d = 0 then
    begin
      Socket.Close;
      CheckConnect := True;
      GoTo G; // Переход в метку
    end;

  StatusBar1.Panels[2].Text := '[' + TimeToStr(Now) + '] Клиент подключился';

  // Разрешаем обновление
  UpdMas := True;

  G: // Сюда перейдёт программа
end;

procedure TForm1.ServerSocketClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  if CheckConnect = False then
    begin
      StatusBar1.Panels[2].Text := '[' + TimeToStr(Now) + '] Клиент отключился';

      // Разрешаем обновление
      UpdMas := True;
    end;
end;
CheckConnect потом сбрасывать надо?

2. После теста выяснилось, что удалённая админка работает лучще, чем админка серверная. В ходе теста было выяснено, что происходит сдвиг. В чате было 3 юзера и естественно сам сервер. Мы давали друг другу бан/разбан с клиентов и всё было нормально. Но при бан/разбан с сервера происходило следующее:

Список
Server
Voks
Lennox
Shouldercannon

Разбан
Voks -> Shouldercannon
Lennox - > Voks
Shouldercannon -> Lennox

Бан
Voks -> Shouldercannon
Lennox - > Voks
Shouldercannon -> Lennox

С данным кодом.
Вложения
Тип файла: txt Code.txt (4.1 Кб, 128 просмотров)

Последний раз редактировалось Shouldercannon; 19.06.2010 в 17:00.
Shouldercannon вне форума Ответить с цитированием
Старый 19.06.2010, 18:57   #458
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Цитата:
Сообщение от Shouldercannon
CheckConnect потом сбрасывать надо?
Конечно
Цитата:
Сообщение от Beermonza
если флаг ложный, включить UpdMas, а этот выключить
Код:
procedure TForm1.ServerSocketClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  if CheckConnect = False then
    begin
      StatusBar1.Panels[2].Text := '[' + TimeToStr(Now) + '] Клиент отключился';

      // Разрешаем обновление
      UpdMas := True;
    end;

  CheckConnect := False; // сброс флага

end;
Цитата:
Сообщение от Shouldercannon
После теста выяснилось, что удалённая админка работает лучще, чем админка серверная. В ходе теста было выяснено, что происходит сдвиг.
В смысле? ...бан/разбан на нужный канал, но путает имена пользователей?
Все операции со списком нужно проводить через UserListView.Selected, только тогда Caption будет верный.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его

Последний раз редактировалось Beermonza; 19.06.2010 в 19:08.
Beermonza вне форума Ответить с цитированием
Старый 19.06.2010, 20:41   #459
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
В смысле? ...бан/разбан на нужный канал, но путает имена пользователей?
Все операции со списком нужно проводить через UserListView.Selected, только тогда Caption будет верный.
Он неправильно определяет IP и канал, в который нужно делать отправку работая с ServerSocket.Socket.Connections[UserListView.Selected.Index - 1].

При выборе первого, он отсылает третьему, при выборе второго первому и при выборе третьего второму. Вот такой весёлый сервер

P.S. Так ServerSocket.Socket.Connections[UserListView.Selected.Caption]? Фига Incompatible types: 'Integer' and 'String'

Последний раз редактировалось Shouldercannon; 19.06.2010 в 23:18.
Shouldercannon вне форума Ответить с цитированием
Старый 19.06.2010, 23:30   #460
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Очевидно у вас само выполнение команды отделено от клика по списку. Если сделать выделение и нажать на кнопку или сделать клик по другому объекту, выделение теряется. Храните индекс в переменной, которая заполняется через UserListView.Selected.Index - 1 в событии UserListViewClick.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
обновление в блоге - Создание клиент-сервера Pblog Обсуждение статей 0 03.10.2007 17:12
обновление в блоге - Диплом. Создание и продвижение сайта - готовь сани летом, а дипл Pblog Обсуждение статей 0 31.08.2007 20:00
обновление в блоге - USB Холодильник Pblog Обсуждение статей 0 25.06.2007 14:13
обновление в блоге - О ярлыках Pblog Обсуждение статей 0 27.05.2007 03:17