Парсер SA-MP сервера legacy.samp-rp.ru

roverman

Известный
Автор темы
14
0
Хочу спарсить список игроков с SA-MP сервера legacy.samp-rp.ru:7777 на Python
Сервер отвечает, но не отдает список игроков.
Что пробовал на Python:
Работает:
- Подключение к серверу - ок
- DNS legacy.samp-rp.ru -> 5.252.33.202
- Info запрос (opcode 'i') - показывает 130 игроков онлайн
- Rules запрос (opcode 'r') - отдает правила сервера

Не работает:
- Opcode 'd' (детальные игроки) - таймаут
- Opcode 'c' (базовые игроки) - таймаут
- Opcode 'p' - отвечает, но только 15 байт пустых данных

Вывод:
Сервер специально блокирует получение списка игроков.
Возвращает только базовую инфу, но самих игроков не отдает.

Вопрос:
Кто сталкивался с такой защитой на SA-MP серверах?
Как можно обойти на Python? Может есть другие методы получить список игроков?

Код:
# Запрос правил сервера - РАБОТАЕТ 
def get_rules(self):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(10)
        
        packet = b'SAMP'
        packet += socket.inet_aton(self.server_ip)
        packet += struct.pack('<H', self.server_port)
        packet += b'r'  # opcode для правил
        
        sock.sendto(packet, (self.server_ip, self.server_port))
        data, addr = sock.recvfrom(4096)
        return data  # Возвращает правила (101 байт)
    except:
        return None

Код:
# Запрос списка игроков - НЕ РАБОТАЕТ (таймаут)
def get_players_detailed(self):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(10)
        
        packet = b'SAMP'
        packet += socket.inet_aton(self.server_ip)
        packet += struct.pack('<H', self.server_port)
        packet += b'd'  # opcode для детального списка
        
        sock.sendto(packet, (self.server_ip, self.server_port))
        data, addr = sock.recvfrom(8192)  # Таймаут здесь
        return data
    except socket.timeout:
        return "TIMEOUT"

Код:
# Кастомный opcode 'p' - отвечает но без данных
def try_opcode_p(self):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(5)
        
        packet = b'SAMP'
        packet += socket.inet_aton(self.server_ip)
        packet += struct.pack('<H', self.server_port)
        packet += b'p'  # кастомный opcode
        
        sock.sendto(packet, (self.server_ip, self.server_port))
        data, addr = sock.recvfrom(1024)
        print(f"Opcode p response: {len(data)} bytes")  # Всего 15 байт
        print(f"Data: {data.hex()}")  # 53414d5005fc21ca611e7000000000
        return data
    except Exception as e:
        return f"Error: {e}"

Код:
# DNS разрешение - работает
def resolve_server(self):
    try:
        ip = socket.gethostbyname("legacy.samp-rp.ru")
        print(f"Server IP: {ip}")  # 5.252.33.202
        return ip
    except:
        return None

Код:
# Парсинг полученных данных
def parse_server_info(self, data):
    if len(data) > 11:
        offset = 11
        passworded = data[offset] == 1
        players = struct.unpack('<H', data[offset+1:offset+3])[0]
        max_players = struct.unpack('<H', data[offset+3:offset+5])[0]
        
        # Чтение hostname
        hostname_len = struct.unpack('<I', data[offset+5:offset+9])[0]
        hostname = data[offset+9:offset+9+hostname_len].decode('latin-1')
        
        return {
            'players': players,
            'max_players': max_players,
            'hostname': hostname
        }
    return None
 

Aniki

🐰
Администратор
1,238
1,604
Это нормальное поведение, фича со списком игроков в инфо запросе работает только до определенного количества игроков. Если условно игроков больше 100 на сервере - посмотреть список можно только собственно зайдя на сервер.
Как вариант можешь парсить список отсюда - https://sanek.love/members/online?server_id=103&faction_id=
Там бот как раз таки сидит на сервере и обновляет этот список раз в минуту
 

roverman

Известный
Автор темы
14
0
Это нормальное поведение, фича со списком игроков в инфо запросе работает только до определенного количества игроков. Если условно игроков больше 100 на сервере - посмотреть список можно только собственно зайдя на сервер.
Как вариант можешь парсить список отсюда - https://sanek.love/members/online?server_id=103&faction_id=
Там бот как раз таки сидит на сервере и обновляет этот список раз в минуту
Задумка про парсинг с sanek.love интересная! Более того - уже реализована давно в моём телеграм-боте. Беда в том, что этот сайт иногда выдаёт ложную информацию, и соответственно тг-бот тоже кидает ложняки о входе/выходе требуемого игрока на сервере. Поэтому нужно каким-то образом парсить напрямую с сервера. Есть задумка как-то написать скрипт который буквально заходит на сервер как полноценный игрок, парсит список и выходит. Но как всё это на Python сделать - сообразить не могу.
 

kyrtion

Известный
1,324
486
Есть задумка как-то написать скрипт который буквально заходит на сервер как полноценный игрок, парсит список и выходит. Но как всё это на Python сделать - сообразить не могу.
Про раксампа лайт не забываем))
там пишешь скрипт на заход, как получил информацию - отправил на сервере питона и вышел.
проблема: если на сервере оффлайн или превышает 1000 игроков, то заполнен (вряд ли кто это сделает, сейчас вижу что у его онлайн максимум 500)
 

roverman

Известный
Автор темы
14
0
Про раксампа лайт не забываем))
там пишешь скрипт на заход, как получил информацию - отправил на сервере питона и вышел.
проблема: если на сервере оффлайн или превышает 1000 игроков, то заполнен (вряд ли кто это сделает, сейчас вижу что у его онлайн максимум 500)
Та не. Это всё костыльный метод. Вот если бы взять какой-нибудь рабочий исходник этого-самого Раксампа, узнать как он заходит на сервер - вот там уже можно что-то думать на тему преобразования кода на Python. Но такого не наблюдаю на форуме. Может не туда смотрю.
 

overloader1

Новичок
1
0
Та не. Это всё костыльный метод. Вот если бы взять какой-нибудь рабочий исходник этого-самого Раксампа, узнать как он заходит на сервер - вот там уже можно что-то думать на тему преобразования кода на Python. Но такого не наблюдаю на форуме. Может не туда смотрю.
 

The Spark

frontend
Проверенный
755
764
Посмотри здесь, исходники есть на плюсах
Та не. Это всё костыльный метод. Вот если бы взять какой-нибудь рабочий исходник этого-самого Раксампа, узнать как он заходит на сервер - вот там уже можно что-то думать на тему преобразования кода на Python. Но такого не наблюдаю на форуме. Может не туда смотрю.
 
  • Нравится
Реакции: вайега52