SA:MP CR:MP ASI NoCollision [FYP rework]

g305noobo

Известный
Автор темы
Модератор
349
628
Версия SA-MP
  1. Любая
Описание: ремейк старого плагина от @FYP по всем хайповым канонам с красивым меню и работой на всех версиях сампа
Для меню используется WebView
Активация: /nocol
1766658781556.png


C++:
#include <entry.hpp>
#include <render.hpp>
//
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <thread>
// third-party
#include "safetyhook/easy.hpp"
#include <glaze/glaze.hpp>
// samp
#include "samp/classes/game.hpp"
#include <samp/classes/input.hpp>
// web
#include <cmrc/cmrc.hpp>
#include <webcore.hpp>

CMRC_DECLARE(webui);

namespace nocol
{

namespace dest
{
constexpr std::uintptr_t hook_entry = 0x0054BCEE;
constexpr std::uintptr_t orig_jump = 0x54CEFC;
constexpr std::uintptr_t run_col = 0x0054BCF4;
constexpr std::uintptr_t skip_col = 0x54CF8D;
constexpr std::uint32_t zf_flag = 0x40;
} // namespace dest

enum class type : std::uint8_t
{
    vehicle = 2,
    player = 3,
    object = 4
};

struct settings_t
{
    bool show_menu;
    //
    bool active;
    bool build;
    bool player;
    bool vehicle;
    bool object;
    static constexpr auto glz_obj() noexcept
    {
        return glz::object(settings_t{}, "show_menu", &settings_t::show_menu, "active", &settings_t::active, "build",
                           &settings_t::build, "player", &settings_t::player, "vehicle", &settings_t::vehicle, "object",
                           &settings_t::object);
    }
} inline cfg;

static safetyhook::MidHook col_hook;

[[nodiscard]] inline type get_type(void *ptr) noexcept
{
    return static_cast<type>(*reinterpret_cast<std::uint8_t *>(static_cast<std::byte *>(ptr) + 54) & 7);
}

[[nodiscard]] bool should_skip(void *src, void *dst) noexcept
{
    if (!src || !dst)
        return false;

    const auto t_src = get_type(src);
    const auto t_dst = get_type(dst);

    switch (t_dst)
    {
    case type::player:
    case type::vehicle:
        return (t_src == type::vehicle && cfg.vehicle) || (t_src == type::player && cfg.player) ||
               (t_src == type::object && cfg.object);
    default:
        return false;
    }
}

void on_col_hook(safetyhook::Context &ctx) noexcept
{
    if (!(ctx.eflags & dest::zf_flag) || (cfg.active && cfg.build))
    {
        ctx.eip = dest::orig_jump;
        return;
    }

    if (cfg.active && should_skip((void *)ctx.edi, (void *)ctx.esi))
    {
        ctx.eip = dest::skip_col;
        return;
    }

    ctx.eip = dest::run_col;
}

void on_js_message(webcore::CWebFrame *f, const std::wstring &message)
{
    std::string json(message.begin(), message.end());
    nocol::settings_t tmp{};

    [[maybe_unused]] auto e = glz::read_json(tmp, json);
    nocol::cfg = tmp;

    if (!tmp.show_menu)
        f->set_visible(false);
}

} // namespace nocol

namespace plugin
{
using namespace nocol;
using namespace samp;
entry::entry(HMODULE hmodule) : hmodule_(hmodule)
{
    std::thread(
        []
        {
            col_hook = safetyhook::create_mid(dest::hook_entry, on_col_hook);
            while (!classes::input())
            {
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            }

            render::init();
            using namespace render;

            core.execute(
                []()
                {
                    auto width = static_cast<std::uint32_t>(*reinterpret_cast<int *>(0xC9C040) / 2);
                    auto height = static_cast<std::uint32_t>(*reinterpret_cast<int *>(0xC9C040 + 4) / 2);
                    auto frame = core.create_frame(
                        "main", {.width = width, .height = height, .visible = false, .transparent = true});
                    frame->set_anchor(webcore::Anchor::Center);

                    frame->on_ready(
                        [](webcore::CWebFrame *f)
                        {
                            f->on_message(nocol::on_js_message);
                            auto fs = cmrc::webui::get_filesystem();
                            auto file = fs.open("index.html");
                            f->load_html(std::string(file.begin(), file.end()));
                        });
                });

            core.on_visibility_changed(
                [](bool visible)
                {
                    classes::game()->set_cursor_mode(visible ? 2 : 0, 1);
                    if (visible)
                        ((void (*)())0x53f1e0)();
                });

            classes::input()->add_command("nocol", []([[maybe_unused]] const char *s) { core.set_all_visible(true); });
        })
        .detach();
}
entry::~entry()
{
    col_hook.reset();
}
} // namespace plugin

std::unique_ptr<plugin::entry> instance;
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, [[maybe_unused]] LPVOID reversed)
{
    if (reason == DLL_PROCESS_ATTACH)
    {
        DisableThreadLibraryCalls(module);
        instance = std::make_unique<plugin::entry>(module);
    }
    else if (reason == DLL_PROCESS_DETACH)
    {
        instance.reset();
    }
    return TRUE;
}
 

Вложения

  • NoCollision_kichiro.asi
    146.5 KB · Просмотры: 17
Последнее редактирование:

Kraddy

Известный
116
49
А чем эта отличается? Так-же работает на арз
Кроме того чо либу другую юзает?
 
  • Нравится
Реакции: Deps

chromiusj

модерирую шмодерирую
Модератор
5,953
4,285
А чем эта отличается? Так-же работает на арз
Кроме того чо либу другую юзает?
используется другой метод коллизии, как у сыртима
 

g305noobo

Известный
Автор темы
Модератор
349
628
А чем эта отличается? Так-же работает на арз
Кроме того чо либу другую юзает?
самп любой версии, нет зависимости от SF, удобное меню.

используется другой метод коллизии, как у сыртима
все версии (фипа, сртима, моя) используют один и тот же хук, честно говоря не знал что сртим делал подобное
 

Deps

Известный
251
178
самп любой версии, нет зависимости от SF, удобное меню
И в уголке появилась зависимость от рантайма Webview, которая после поёбистского удаления Edge тоже сносится. Да и удобнее меню не стало, наоборот усложнённое из-за перевода на английский
 

g305noobo

Известный
Автор темы
Модератор
349
628
И в уголке появилась зависимость от рантайма Webview, которая после поёбистского удаления Edge тоже сносится. Да и удобнее меню не стало, наоборот усложнённое из-за перевода на английский
Webview идет в комплекте со всеми Windows начиная от Windows 10 21h2 - это означает, что у большинства юзеров он уже предустановлен. Сам по себе Webview довольно сильно распространен, например он используется в Telegram Desktop для отображения мини-апп, а если ты удаляешь себе вебвью который могут юзать вообще любые десктоп приложения для удобного создания UI - это твоя проблема, которой ты усложняешь себе жизнь самостоятельно из-за 500 мб на диске.

По поводу английского языка нет слов...
 
  • Влюблен
Реакции: waparabka

Deps

Известный
251
178
Webview идет в комплекте со всеми Windows начиная от Windows 10 21h2 - это означает, что у большинства юзеров он уже предустановлен. Сам по себе Webview довольно сильно распространен, например он используется в Telegram Desktop для отображения мини-апп, а если ты удаляешь себе вебвью который могут юзать вообще любые десктоп приложения для удобного создания UI - это твоя проблема, которой ты усложняешь себе жизнь самостоятельно из-за 500 мб на диске.

По поводу английского языка нет слов...
Ты читаешь, но суть упускаешь. Я говорю о реальности: многие твикеры и скрипты, которые удаляют Edge, виджеты и прочий мусор - вместе с ними часто сносят и WebView. У кого слабые компы ставят сборки, LTSC билды - у них в стоке никаких WebView нету.

Пример с мини-аппами в телеге вообще мимо кассы. Их используют минимум из минимума, ведь крипто кошельки всё еще посасывают у популярности обычных.

Я прекрасно разбираюсь в веб based UI, и именно поэтому прежде всего думаю: "А запустится ли это на машине юзера без ебли?"

Если для тебя идея писать интерфейсы для мелких скриптов на вебе (вместо гарантированно работающего имгуи с нулевым оверхедом) кажется адекватной - удачи. Но менять 30 строк нативного кода на тяжелую зависимость Webview - это архитектурный оверхед, а не "удобство"
 

g305noobo

Известный
Автор темы
Модератор
349
628
Ты читаешь, но суть упускаешь. Я говорю о реальности: многие твикеры и скрипты, которые удаляют Edge, виджеты и прочий мусор - вместе с ними часто сносят и WebView. У кого слабые компы ставят сборки, LTSC билды - у них в стоке никаких WebView нету.

Пример с мини-аппами в телеге вообще мимо кассы. Их используют минимум из минимума, ведь крипто кошельки всё еще посасывают у популярности обычных.

Я прекрасно разбираюсь в веб based UI, и именно поэтому прежде всего думаю: "А запустится ли это на машине юзера без ебли?"

Если для тебя идея писать интерфейсы для мелких скриптов на вебе (вместо гарантированно работающего имгуи с нулевым оверхедом) кажется адекватной - удачи. Но менять 30 строк нативного кода на тяжелую зависимость Webview - это архитектурный оверхед, а не "удобство"

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

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

Насчёт телеги - помимо криптокошельков существует тонна мини-аппок, которые также имеют сотни тысяч юзеров. К тому же помимо телеги вебвью активно используется в других приложениях, потому что это простое и удобное решение для разработки приложения с веб меню на с++.

Зачем я как разработчик должен тратить тонну времени для верстки имгуи, когда у меня под рукой весь браузер, в котором это делается в 100 раз быстрее? В отличии от MoonLoader, на плюсах верстка нормального имгуи это ебля еще та, с которой ты видимо не знаком.

Я не отрицаю, что имгуи - намного быстрее и легче чем тянуть за собой целиком браузер, особенно для таких небольших UI, но и ты хуйню не неси, к счастью плагины в сампе не ограничиваются на таких мелких меню и дохуя чему веб интерфейс легко мог бы подарить новую жизнь.
 
  • Грустно
Реакции: Deps