[CSGO] Чиним подключение к серверу для клиентов

Сообщение перед темой (красное)
Команда форума: не рекомендуем ставить это расширение, т.к. нет возможности проверить на уязвимости.

Alley

Участник
Сообщения
48
Реакции
56
Если у вас сервер CS:GO и игроки с архивной версией (Steam appid 4465480) не могут зайти — это решение.
Клиенты со старой CS:GO получают ошибку:

C-подобный:
"S3: Client connected with ticket for the wrong game"
Я разобрал работу существующего фикса от eonexdev (csgo-sv-fix-engine), который распространялся только в виде бинарников без исходного кода, и написал свою реализацию с нуля. Исходный код полностью открытый — можно проверить, собрать самому и убедиться что нет ничего лишнего.
Расширение SourceMod патчит движок и пропускает подключения от любых версий CS:GO.
Установка:
  1. Скачать расширение: GitHub - Alleyv2/Allow-archived-CS-GO-clients-to-join-community-servers
  2. Закинуть на сервер:
    • csgo/addons/sourcemod/extensions/csgo_steamfix.ext.so (Linux)
    • csgo/addons/sourcemod/extensions/csgo_steamfix.autoload (пустой файл)
  3. Перезапустить сервер
После запуска в консоли должно появиться:

C-подобный:
[steamfixbyAlley] ============================================
[steamfixbyAlley]   steamfixbyAlley  by Alley
[steamfixbyAlley]   https://github.com/Alleyv2
[steamfixbyAlley]   based on eonexdev/csgo-sv-fix-engine
[steamfixbyAlley] ============================================
[steamfixbyAlley] loading..
[steamfixbyAlley] engine base=0xF3AE5000 size=0x2FFBE00
[steamfixbyAlley] sig hit rva=0x18A2BA
[steamfixbyAlley] jt[4]: 0xF3C6F3D8 -> 0xF3C6F498
[steamfixbyAlley] engine patched! archived clients can now connect
Готово. Теперь заходят все.

P.S. Только Linux. При выгрузке расширения движок безопасно возвращается в исходное состояние. Для сборки из исходников — инструкция в README на GitHub.

Исходный код:
C-подобный:
/*
 *   ██████╗████████╗███████╗ █████╗ ███╗   ███╗███████╗██╗██╗  ██╗
 *  ██╔════╝╚══██╔══╝██╔════╝██╔══██╗████╗ ████║██╔════╝██║╚██╗██╔╝
 *  ╚█████╗    ██║   █████╗  ███████║██╔████╔██║█████╗  ██║ ╚███╔╝
 *   ╚═══██╗   ██║   ██╔══╝  ██╔══██║██║╚██╔╝██║██╔══╝  ██║ ██╔██╗
 *  ██████╔╝   ██║   ███████╗██║  ██║██║ ╚═╝ ██║██║     ██║██╔╝╚██╗
 *  ╚═════╝    ╚═╝   ╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝╚═╝     ╚═╝╚═╝  ╚═╝
 *
 *  steamfixbyAlley — CS:GO SourceMod Extension
 *  Author  : Alley — https://github.com/Alleyv2
 *  Based on: eonexdev — https://github.com/eonexdev/csgo-sv-fix-engine
 *  License : MIT
 */

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <unistd.h>
#include <sys/mman.h>
#include <link.h>
#include <dlfcn.h>

#include "IExtensionSys.h"

using namespace SourceMod;

static const uint8_t SIG[]  = {
    0xFF, 0x24, 0x85, 0x00, 0x00, 0x00, 0x00,
    0x8D, 0xB4, 0x26, 0x00, 0x00, 0x00, 0x00,
    0x31, 0xF6
};
static const uint8_t MASK[] = {
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
    0xFF, 0xFF
};
static constexpr size_t SIG_LEN = sizeof(SIG);

static uint32_t *g_jt4_ptr  = nullptr;
static uint32_t  g_jt4_orig = 0;
static bool      g_patched  = false;

static bool make_writable(void *addr, size_t len)
{
    uintptr_t page = reinterpret_cast<uintptr_t>(addr);
    page &= ~static_cast<uintptr_t>(getpagesize() - 1);
    return mprotect(reinterpret_cast<void*>(page),
                    len + (reinterpret_cast<uintptr_t>(addr) - page),
                    PROT_READ | PROT_WRITE | PROT_EXEC) == 0;
}

static const uint8_t *find_sig(const uint8_t *base, size_t size)
{
    if (size < SIG_LEN) return nullptr;
    const uint8_t *end = base + size - SIG_LEN;
    for (const uint8_t *p = base; p <= end; ++p) {
        size_t i = 0;
        for (; i < SIG_LEN; ++i)
            if ((p[i] & MASK[i]) != (SIG[i] & MASK[i])) break;
        if (i == SIG_LEN) return p;
    }
    return nullptr;
}

struct EngineInfo { const uint8_t *base = nullptr; size_t size = 0; };

static int phdr_cb(struct dl_phdr_info *info, size_t, void *data)
{
    if (!info->dlpi_name || !strstr(info->dlpi_name, "engine.so"))
        return 0;
    auto *ei = static_cast<EngineInfo*>(data);
    ei->base = reinterpret_cast<const uint8_t*>(
                   static_cast<uintptr_t>(info->dlpi_addr));
    for (int i = 0; i < info->dlpi_phnum; ++i)
        if (info->dlpi_phdr[i].p_type == PT_LOAD) {
            uintptr_t end = info->dlpi_phdr[i].p_vaddr
                          + info->dlpi_phdr[i].p_memsz;
            if (end > ei->size) ei->size = end;
        }
    return 1;
}

static bool do_patch(char *err, size_t errlen)
{
    if (g_patched) return true;

    EngineInfo ei;
    dl_iterate_phdr(phdr_cb, &ei);

    if (!ei.base || !ei.size) {
        snprintf(err, errlen, "engine.so not found in process memory");
        return false;
    }

    printf("[steamfixbyAlley] engine base=0x%08X size=0x%zX\n",
           (uint32_t)(uintptr_t)ei.base, ei.size);

    const uint8_t *hit = find_sig(ei.base, ei.size);
    if (!hit) {
        snprintf(err, errlen, "signature not found — unsupported engine version");
        return false;
    }

    printf("[steamfixbyAlley] sig hit rva=0x%X\n", (uint32_t)(hit - ei.base));

    uint32_t jt_addr;
    memcpy(&jt_addr, hit + 3, sizeof(jt_addr));
    uint32_t *jt = reinterpret_cast<uint32_t*>((uintptr_t)jt_addr);

    printf("[steamfixbyAlley] jt=0x%08X  jt[0]=0x%08X  jt[4]=0x%08X\n",
           jt_addr, jt[0], jt[4]);

    if (jt[0] == jt[4]) {
        printf("[steamfixbyAlley] already patched\n");
        g_patched = true;
        return true;
    }

    if (!make_writable(&jt[4], sizeof(uint32_t))) {
        snprintf(err, errlen, "mprotect failed");
        return false;
    }

    g_jt4_ptr  = &jt[4];
    g_jt4_orig = jt[4];

    printf("[steamfixbyAlley] jt[4]: 0x%08X -> 0x%08X\n", jt[4], jt[0]);
    jt[4] = jt[0];
    g_patched = true;

    printf("[steamfixbyAlley] engine patched! archived clients can now connect\n");
    return true;
}

static void do_unpatch()
{
    if (!g_patched || !g_jt4_ptr) return;
    *g_jt4_ptr = g_jt4_orig;
    g_patched  = false;
    g_jt4_ptr  = nullptr;
    printf("[steamfixbyAlley] engine restored to original state\n");
}

class CSGOSteamFixByAlley : public IExtensionInterface
{
public:
    bool OnExtensionLoad(IExtension *me, IShareSys *sys,
                         char *error, size_t maxlength, bool late) override
    {
        printf("\n");
        printf("[steamfixbyAlley] ============================================\n");
        printf("[steamfixbyAlley]   steamfixbyAlley  by Alley\n");
        printf("[steamfixbyAlley]   https://github.com/Alleyv2\n");
        printf("[steamfixbyAlley]   based on eonexdev/csgo-sv-fix-engine\n");
        printf("[steamfixbyAlley] ============================================\n");
        printf("[steamfixbyAlley] loading..\n");

        if (late)
            return do_patch(error, maxlength);
        return true;
    }

    void OnExtensionUnload() override { do_unpatch(); }

    void OnExtensionsAllLoaded() override
    {
        if (!g_patched) {
            char err[256] = {};
            if (!do_patch(err, sizeof(err)))
                printf("[steamfixbyAlley] ERROR: %s\n", err);
        }
    }

    void OnExtensionPauseChange(bool) override { }
    bool QueryRunning(char*, size_t) override  { return true; }
    bool IsMetamodExtension() override         { return false; }
    void OnDependenciesDropped() override      { }

    const char *GetExtensionName()        override { return "steamfixbyAlley"; }
    const char *GetExtensionURL()         override { return "https://github.com/Alleyv2"; }
    const char *GetExtensionTag()         override { return "steamfixbyAlley"; }
    const char *GetExtensionAuthor()      override { return "Alley (based on eonexdev)"; }
    const char *GetExtensionVerString()   override { return "1.0.0"; }
    const char *GetExtensionDescription() override { return "Allow archived CS:GO clients (appid 4465480) to join community servers"; }
    const char *GetExtensionDateString()  override { return __DATE__; }
};

static CSGOSteamFixByAlley g_Extension;

extern "C" __attribute__((visibility("default")))
IExtensionInterface *GetSMExtAPI()
{
    return &g_Extension;
}
 

Вложения

  • Allow-archived-CS-GO-clients-to-join-community-servers-main.zip
    9.8 КБ · Просмотры: 40
Последнее редактирование:
Команда форума: не рекомендуем ставить это расширение, т.к. нет возможности проверить на уязвимости.

Ernest

Участник
Сообщения
294
Реакции
17
Так и не понял о чем речь данной темы, если вы о том что не можете подключится на сервер и идет бесконечное подключение
Поставьте этот плагин и все сразу подключится
он то работает как выше писал что люди заходят и через сек 10 выходят резко и онлайн даже не набирается когда везде набрал рекламы(раскрутку) и не только
 

Rimmer

Помогаю новичкам / Переводчик / Тестер / Заказчик
Сообщения
1,401
Реакции
786
он то работает как выше писал что люди заходят и через сек 10 выходят резко и онлайн даже не набирается когда везде набрал рекламы(раскрутку) и не только
Ну так это уже удержанием надо заниматься, заходят же, а выходят(вылетают) не из за ошибке в плагине
 

Z10Y

Участник
Сообщения
67
Реакции
61
Поднимаю тему добавил открытый исходный код расширения на GitHub, теперь можно собрать самому: GitHub - Alleyv2/Allow-archived-CS-GO-clients-to-join-community-servers
Если у вас сервер CS:GO и игроки с архивной версией (Steam appid 4465480) не могут зайти — это решение.
Перечитал несколько раз - не понял.
Этот фикс надо ставить на сервера которые уже переехали на 4465480 или на сервера которые на 730 остались?
 

Rimmer

Помогаю новичкам / Переводчик / Тестер / Заказчик
Сообщения
1,401
Реакции
786
Перечитал несколько раз - не понял.
Этот фикс надо ставить на сервера которые уже переехали на 4465480 или на сервера которые на 730 остались?
По сути да

Текст ниже сгенерирован с помощью AI
Этот плагин (расширение SourceMod) решает проблему подключения к серверам CS:GO от архивной версии игры.

Суть проблемы

Valley заархивировала CS:GO и выдала её отдельным приложением в Steam (appid 4465480). Когда игрок с этой архивной версией пытается зайти на обычный сервер, игра выдаёт ошибку:
RejectConnection: STEAM validation rejected
Причина — в коде движка (engine.so) проверка appid отправляет запросы от архивной версии по пути «отказ», а не «разрешить».

Как плагин это исправляет

Расширение находит в памяти сервера специальную таблицу переходов (jump table) и подменяет указатель для архивной версии (appid 4) с «пути отказа» на «путь разрешения». Все остальные версии остаются без изменений.

Важные особенности

  • Работает только на Linux серверах CS:GO (32-битных).
  • Требует установленный SourceMod (версии 1.10 или 1.11).
  • Установка проста — нужно скопировать два файла в папку csgo/addons/sourcemod/extensions/ и перезапустить сервер.
  • Изменения обратимы — при выгрузке плагина оригинальная настройка восстанавливается.
Коротко: плагин делает так, чтобы сервер «видел» владельцев архивной версии CS:GO как обычных игроков и пускал их, исправляя ошибку валидации Steam.
 

Z10Y

Участник
Сообщения
67
Реакции
61
что значит обычный сервер!? что вы считаете обычным!? тот который поддерживает легаси 730 или то что выкатили валве 4465480 .
Что вы понимаете по архивной версией!? ту которая осталась в легаси кс2 730 или то что валве официально не опубликовали 4465480
 

oleg_nelasy

Участник
Сообщения
674
Реакции
47
что значит обычный сервер!? что вы считаете обычным!? тот который поддерживает легаси 730 или то что выкатили валве 4465480 .
Что вы понимаете по архивной версией!? ту которая осталась в легаси кс2 730 или то что валве официально не опубликовали 4465480
я думаю валв со временем просто уберет версию 730. Может еще сделают патч для 4465480 где подправят файлы игры где подправят значения в файлах чтоб игроку не проходилось лезть в них чтоб зайти на серверы и на этом все.
 

Alley

Участник
Сообщения
48
Реакции
56
У кого не грузит база данных даже локальная попробуйте в core.cfg в SteamAuthstringValidation прописать с yes на no. Должно помочь. Путь до файла addons/sourcemod/configs/ core.cfg
 
Сверху Снизу