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

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

Alley

Участник
Сообщения
47
Реакции
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 КБ · Просмотры: 30
Последнее редактирование:
Команда форума: не рекомендуем ставить это расширение, т.к. нет возможности проверить на уязвимости.

VeNoM`1K =))

Живи и ошибайся. В этом жизнь.
Сообщения
718
Реакции
284
Все отлично работает. Но такое вышло STEAM_ID_STOP_IGNORING_RETVALS , когда отключается.
А в кс го от стима , все ок
Сообщения автоматически склеены:

Проще говоря так же все) Просто пускает , но ранги , випки и админки не работают.
 

Z10Y

Участник
Сообщения
67
Реакции
61
при заходе с legacy на сервер csgo, грузит игрока так - STEAM_ID_STOP_IGNORING_RETVALS
 
Последнее редактирование:

Lev

Добрая душа
Сообщения
363
Реакции
319
Добрый день

@Alley, Исходники будут ?
 

Z10Y

Участник
Сообщения
67
Реакции
61
В итоге после этого все будет работать нормально?
нет,
1772882389435.png
 

DOK-26-RUS

Участник
Сообщения
272
Реакции
41
судя по описанию, это используется если вернуть сервер на appid=730, чтобы заходить из бета версий csgo-legacy и не менять appid у сервера для выделенной csgo
 

Z10Y

Участник
Сообщения
67
Реакции
61
судя по описанию, это используется если вернуть сервер на appid=730, чтобы заходить из бета версий csgo-legacy и не менять appid у сервера для выделенной csgo
неа, у меня 2 серва остались на 730
и при попытки с csgo зайти на них - всё равно ловил STEAM_ID_STOP_IGNORING_RETVALS
 

Ultras

Участник
Сообщения
2
Реакции
0
Установил всё по инструкции, в консоли вылезли строки "steamfix", но с пиратки входа нет, или не поддерживается? Именно с пиратской CS, а не с Легаси.

Вылетает ошибка: Steam validation rejected
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,805
Реакции
5,254
@Ultras, про пиратки в тексте не было ничего.
 

Bazol

Участник
Сообщения
128
Реакции
22
Ну пиратки уже пофиксили, заходит с 730 на 730 и 4465480
 

exes

Участник
Сообщения
36
Реакции
2
а решение этой проблемы актуально? просто сделал все как по инструкции но все равно не заходит
 

Ernest

Участник
Сообщения
294
Реакции
17
Client "Ricardo-only" connected
STEAMAUTH: Client Ricardo-only received failure code 6
Dropped Ricardo-only from server: No user logon
Вопрос как исправить поставил плагин?
 

Rimmer

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