Правила форума Гаранты форума
Размещение рекламы AMX-X компилятор

Здравствуйте, гость Вход | Регистрация

Наши новости:

14-дек
24-апр
10-апр
11-апр

> Правила форума

Раздел для общения на любые темы, для которых не нашлось места в остальных разделах. Если Вашу тему можно отнести по смыслу к другому разделу, лучше создайте её там, иначе Вас накажут.

В данном форуме немного понижены требования к Общим правилам форума, а именно:
1. Информативность темы
2. Отходить от первоначального смысла темы

!
В разделе запрещено создавать темы связанные с раскруткой игровых серверов

msgrabber

, Получить список серверов с мастер-сервера
Статус пользователя Gecko
сообщение 12.6.2023, 0:01
Сообщение #1
Стаж: 7 лет 4 месяца

Сообщений: 1247
Благодарностей: 518
Полезность: 346

Сегодня нужно было протестировать свой мастер-сервер с загрузкой пару тысяч серверов, написал небольшой скриптик, делюсь им тут.

Это просто граббер, он отправляет запрос к мастер-серверу, получает список серверов, фильтрует сервера (по порту, по стране и по городу) и сохраняет в файл ms-servers.txt

Код
usage linux:
./msgrabber -master 88.198.47.43:27010 -city Kyiv

usage windows:
msgrabber.exe -master 88.198.47.43:27010 -port 27018 -country RU -city Moscow

// 88.198.47.43:27010 замените на свой мастер-сервер ))
// Если нужно получить просто все сервера, не указывайте никакие другие параметры кроме -master


Исходники
msgrabber.go
Код
package main

import (
    "flag"
    "fmt"
    "io/ioutil"
    "net"
    "strings"

    "github.com/oschwald/geoip2-golang"
)

func main() {
    masterServerFlag := flag.String("master", "127.0.0.1:27010", "Адрес и порт мастер-сервера")
    portFilterFlag := flag.String("port", "", "Порт для фильтрации серверов (например, 27015)")
    countryFilterFlag := flag.String("country", "", "Код страны для фильтрации серверов (например, RU)")
    cityFilterFlag := flag.String("city", "", "Название города для фильтрации серверов")
    flag.Parse()

    masterServerAddr, err := net.ResolveUDPAddr("udp4", *masterServerFlag)
    if err != nil {
        fmt.Printf("Не удалось разрешить адрес мастер-сервера: %v\n", err)
        return
    }

    conn, err := net.DialUDP("udp4", nil, masterServerAddr)
    if err != nil {
        fmt.Printf("Не удалось подключиться к мастер-серверу: %v\n", err)
        return
    }
    defer conn.Close()

    // query := []byte("\x31 ... \x00")
    query := []byte("\x31")
    _, err = conn.Write(query)
    if err != nil {
        fmt.Printf("Не удалось отправить запрос: %v\n", err)
        return
    }

    buffer := make([]byte, 8192)
    n, _, err := conn.ReadFromUDP(buffer)
    if err != nil {
        fmt.Printf("Не удалось получить ответ: %v\n", err)
        return
    }

    servers := parseServerList(buffer[6:n])

    if *portFilterFlag != "" {
        servers = filterServersByPort(servers, *portFilterFlag)
    }

    if *countryFilterFlag != "" {
        servers, err = filterServersByCountry(servers, *countryFilterFlag)
        if err != nil {
            fmt.Printf("Ошибка при фильтрации серверов по стране: %v\n", err)
            return
        }
    }

    if *cityFilterFlag != "" {
        servers, err = filterServersByCity(servers, *cityFilterFlag)
        if err != nil {
            fmt.Printf("Ошибка при фильтрации серверов по городу: %v\n", err)
            return
        }
    }

    err = ioutil.WriteFile("ms-servers.txt", []byte(strings.Join(servers, "\n")), 0644)
    if err != nil {
        fmt.Printf("Не удалось сохранить список серверов: %v\n", err)
        return
    }

    fmt.Println("Список серверов успешно сохранен в файле ms-servers.txt")
}

func parseServerList(data []byte) []string {
    var servers []string

    for i := 6; i < len(data); {
        ip := fmt.Sprintf("%d.%d.%d.%d", data[i], data[i+1], data[i+2], data[i+3])
        port := int(data[i+4])<<8 + int(data[i+5])
        server := fmt.Sprintf("%s:%d", ip, port)
        servers = append(servers, server)

        i += 6
    }

    return servers
}

func filterServersByPort(servers []string, portFilter string) []string {
    var filteredServers []string

    for _, server := range servers {
        parts := strings.Split(server, ":")
        if len(parts) != 2 {
            continue
        }

        if parts[1] == portFilter {
            filteredServers = append(filteredServers, server)
        }
    }

    return filteredServers
}

func filterServersByCountry(servers []string, countryFilter string) ([]string, error) {
    db, err := geoip2.Open("GeoLite2-Country.mmdb")
    if err != nil {
        return nil, fmt.Errorf("не удалось открыть базу данных GeoIP: %v", err)
    }
    defer db.Close()

    var filteredServers []string

    for _, server := range servers {
        parts := strings.Split(server, ":")
        if len(parts) != 2 {
            continue
        }

        ip := net.ParseIP(parts[0])
        record, err := db.Country(ip)
        if err != nil {
            continue
        }

        if record.Country.IsoCode == countryFilter {
            filteredServers = append(filteredServers, server)
        }
    }

    return filteredServers, nil
}

func filterServersByCity(servers []string, cityFilter string) ([]string, error) {
    db, err := geoip2.Open("GeoLite2-City.mmdb")
    if err != nil {
        return nil, fmt.Errorf("не удалось открыть базу данных GeoIP: %v", err)
    }
    defer db.Close()

    var filteredServers []string

    for _, server := range servers {
        parts := strings.Split(server, ":")
        if len(parts) != 2 {
            continue
        }

        ip := net.ParseIP(parts[0])
        record, err := db.City(ip)
        if err != nil {
            continue
        }

        if record.City.Names["en"] == cityFilter {
            filteredServers = append(filteredServers, server)
        }
    }

    return filteredServers, nil
}


Компиляция: (нужно установить go)
Код
go build msgabber.go


Скачать
В архиве каталог с исходниками src/
исполняемые файлы: msgrabber (Linux) и msgabber.exe (Windows)
Базы ip-адресов: *.mmdb (страны и города)

Отредактировал: Gecko, - 21.10.2023, 16:25


Не отвечаю на ЛС.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   Цитировать сообщение
Статус пользователя Metal Messiah
сообщение 12.6.2023, 22:01
Сообщение #2


Иконка группы

Стаж: 13 лет

Сообщений: 2458
Благодарностей: 1482
Полезность: 772

HostGame.cf
Кажется, по количеству строк даже меньше моего решения на PHP. Потому меряться количеством строк кода с тобой не буду. Еще бы объяснить широким массам как это все на не самом распространенном языке программирования запустить на винде и линуксе соответственно. Конечно, как отдельную статью.


Полезные публикации - ссылки у меня в профиле. Ссылка на плагин против спама на сервере StopServerSpam там же.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя Gecko
сообщение 12.6.2023, 22:24
Сообщение #3
Стаж: 7 лет 4 месяца

Сообщений: 1247
Благодарностей: 518
Полезность: 346

Цитата(Metal Messiah @ 12.6.2023, 22:01) *
Кажется, по количеству строк даже меньше моего решения на PHP. Потому меряться количеством строк кода с тобой не буду. Еще бы объяснить широким массам как это все на не самом распространенном языке программирования запустить на винде и линуксе соответственно. Конечно, как отдельную статью.

На порядок а то и на два порядка быстрее твоего скрипта на php
Код
./msgrabber -master 88.198.47.43:27010 -port 27018 -country RU -city Moscow

real  0m0,050s
user 0m0,003s
sys   0m0,000s


На винде:
создаем файл run.bat и кладем его рядом с файлом msgrabber.exe

Содержание файла run.bat
Код
start msgrabber.exe -master 88.198.47.43:27010 -port 27018 -country RU -city Moscow
pause


Ну либо жмем Win+R > cmd
и в консоле вводим
Код
msgrabber.exe -master 88.198.47.43:27010 -port 27018 -country RU -city Moscow


88.198.47.43:27010 - это рандомный мс из сети.


Цитата
... на не самом распространенном языке программирования ...

Мало кто понимает насколько мощную и классную вещь придумали ребята из гугла.

Отредактировал: Gecko, - 13.6.2023, 0:42


Не отвечаю на ЛС.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
  Ответить в данную темуНачать новую тему
 
0 пользователей и 1 гостей читают эту тему: