SA:MP Lua Arizona ModelChanger

Xmoore

Новичок
Автор темы
21
6
Версия SA-MP
  1. Любая
Скрипт заменяет лаунчерские модельки машин и игроков на обычные, что неплохо прибавляет Fps на слабом железе.
Так-же, в скрипте имеется удаление объектов и сохранение настроек в inicfg.
Функции удаления объектов и замены машин могут быть запрещены на некоторых серверах и вам могут сделать атата. Поэтому, юзайте на свой страх и риск.

Ниже приведены 2 версии скрипта, от меня и от Tema05. Они ничем не отличаются кроме кода, у Tema05 он лучше, поэтому желательно скачивайте именно эту версию. Единственное я в ней изменил команду с /fped на /fpls чтобы никто не запутался с способом активации.

Если вам интересно, можете послушать историю того, как мне в голову пришла идея этого второго "шедевра кремниевой долины", а так же P.S в котором я оправдываюсь за говнокод.

Я видел, многие хотят перенести лаунчерские модельки Аризоны с лаунчера на сборку, но я ненормальный, поэтому я буду делать сборку в лаунчере.
Я когда-то давно понял, что лаунчерские модельки скинов и каров сжирают очень много ресурсов ПК, и когда я это понял, я написал недо Fps UP, который работал через жопу и ломался при каждом действии другого игрока. Но потом я его довёл до ума и выложил сюда.


Установка: Закинуть ModelChanger.lua в moonloader

Использование:
Команды включают/выключают функции.
По умолчанию, все функции выключены.
/fpls - Замена скинов на CJ
/fveh - Замена машинок
/fobj - Удаление объектов

Зависимости: samp.lua moonloader

Благодарю Tema05 за то, что разобрал мой код и указал на мною совершённые ошибки.

P.S: Не кидайте в меня какашки за то, что я сделал функцию на 70 строк, которая длиннее всего остального кода и вместо которой я мог использовать raknetBitStreamSetWriteOffset(). У меня она почему то не работает и bs выдаёт какую-то хрень. При этом я использовал raknetBitStreamResetWritePointer() и это тоже не помогло. В общем, если будете что-то писать про это, значит вы не умеете читать и у вас IQ -1.
А так-же, я вкурсе, что можно было использовать вместо onReceiveRpc() везде sampev, но я не нашёл его нормальную структуру, поэтому выкрутился так.
 

Вложения

  • ModelChanger.lua
    4.5 KB · Просмотры: 12
  • ModelChanger by Tema05.lua
    1.3 KB · Просмотры: 2
Последнее редактирование:
  • Нравится
Реакции: Funny Rofl и takurox

Tema05

Известный
1,485
452
Скрипт заменяет лаунчерские модельки машин и игроков на обычные, что неплохо прибавляет Fps на слабом железе.
Так-же, в скрипте имеется удаление объектов и сохранение настроек в inicfg.

Если вам интересно, можете послушать историю того, как мне в голову пришла идея этого второго "шедевра кремниевой долины", а так же P.S в котором я оправдываюсь за говнокод.

Я видел, многие хотят перенести лаунчерские модельки Аризоны с лаунчера на сборку, но я ненормальный, поэтому я буду делать сборку в лаунчере.
Я когда-то давно понял, что лаунчерские модельки скинов и каров сжирают очень много ресурсов ПК, и когда я это понял, я написал недо Fps UP, который работал через жопу и ломался при каждом действии другого игрока. Но потом я его довёл до ума и выложил сюда.

Установка: Закинуть ModelChanger.lua в moonloader

Использование:
/fpls - Замена скинов на CJ
/fveh - Замена машинок
/fobj - Удаление объектов

Зависимости: samp.lua moonloader

P.S: Не кидайте в меня какашки за то, что я сделал функцию на 70 строк, которая длиннее всего остального кода и вместо которой я мог использовать raknetBitStreamSetWriteOffset(). У меня она почему то не работает и bs выдаёт какую-то хрень. При этом я использовал raknetBitStreamResetWritePointer() и это тоже не помогло. В общем, если будете что-то писать про это, значит вы не умеете читать и у вас IQ -1.
А так-же, я вкурсе, что можно было использовать вместо onReceiveRpc() везде sampev, но я не нашёл его нормальную структуру, поэтому выкрутился так.
Ну это прям кал. Идём по порядку:

1743668383312.png
1743668445630.png
1743669357268.png


1) По хорошему в начале main надо бы добавить проверку на то что самп загружен
Lua:
while not isSampAvailable() do
    wait(0)
end
2) Ты назвал одну из функций "load", тем самым перезаписал одноимённую встроенную функцию для загрузки кода.
3) inicfg.load всегда возвращает тебе таблицу двойной вложенности. И все обращения идут по ключу. Ты во первых обращаешься к вложенным таблицам(в нашем случаи 1 таблице), а не значениям так ещё и по индексам, а не ключам. Я могу понять логику, что ты пытаешься все по очереди к всем настройкам так обратиться, но даже если бы так можно было, суть в том что таблицы невозможно отсортировать по ключам и настройки могут быть вообще в рандомном порядке. В твоём случаи значения data[N] при любом И всегда равны nil (т.е. ничего). Только с божий помощью людей, придумавших тебе динамическую типизацию, это даже случайно работает. Все проверки if veh(nil) then не проходят, а по вводу команд veh = not veh значение инвестируется за счёт приведения true = not nil.
4) Переменные veh, pls и obj зачем-то глобальные и вообще не имеют никакого смысла. У тебя есть двумерная таблица data с настройками, её и используй. Нет никакого смысла в дополнительных буферных переменных.
5) Ты вместо того чтобы сохранить свой конфиг, зачем-то создаёшь новую таблицу тем самым стирая все настройки, которые были изменены не в этой сессии работы скрипта. И вообще у тебя data локальная переменная с области видимости только внутри функции
6) Ты допустил ошибку в ключах настроек, при загрузки у тебя veh, pls и obj, а при сохранении vehs, plss и objs.
1743669893562.png
7) Ты в фукнции cloneAndReplaceVehicle создаёшь структуру битстрима и выделяешь на это память при помощи raknetNewBitStream, но не удаляешь битстрим после отправки raknetEmulRpcReceiveBitStream. Это потенциальная утечка памяти, которая наебнёт игру со временем.
8) raknetBitStreamSetReadOffset(bs, 0) не имеет никакого смысла, поскольку ты нигде до не читаешь память, указатель чтения и так стоит на 0.

А теперь по мелочам:
1) При подключении библиотеке samp.event не обязательно дописывать "lib." в начале. Оно и так в папке lib ищет. (Я знаю что ты просто скопипастил)
1743670952712.png
2) Ты что олимпиадник по какой-то извращённой компрессии кода? Код не имеет единую структуру, переменные из 1 символа нечитаемые, зачем-то избегаются переносы строк, отсутствуют пробелы в очевидных местах. В целом почитай про правила хорошего тона в программировании, вообще любые для любого языка. База +- везде идентичная и она уже сделает намного лучше.
3) Вместо while true do wait(0) end достаточно wait(-1). Этот цикл не нужен
4) Не знаю зачем ты пытаешься работать с битстримом напрямую, темболее пересозданием рпс, и используешь onReceiveRpc если для спавна транспорта в samp.events есть событие
INCOMING_RPCS[RPC.WORLDVEHICLEADD] = {'onVehicleStreamIn', handler.rpc_vehicle_stream_in_reader, handler.rpc_vehicle_stream_in_writer} Фантастика как ты нашёл структуру для битстрима и даже правильно её выстроил, но структуру handler.rpc_vehicle_stream_in_reader, которая подключается из файла handlers.lua ты найти не смог, хотя это одна и та же структура по сути
local handler = require 'samp.events.handlers'
1743671613591.png

5) Для игроков вместо сокращения "pls", которая вообще не ясно что значит есть прекрасное "ped". Люди в игре так и называются педами.
6) У тебя во всех проверках сначала идёт условие работы, а только потом проверка включена ли она. Это неправильная расстановка приоритетов

После рефакторинга должно получиться что-то вроде

Lua:
local events = require 'samp.events'
local inicfg = require 'inicfg'

local cfg = inicfg.load({
    main = {
        ped = false,
        veh = false,
        obj = false
    }
}, 'ModelChanger')

local function save_cfg()
    inicfg.save(cfg, 'ModelChanger')
end

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then
        return
    end
    while not isSampAvailable() do
        wait(0)
    end

    sampRegisterChatCommand('fped', function()
        cfg.main.ped = not cfg.main.ped
        save_cfg()
    end)
    sampRegisterChatCommand('fveh', function()
        cfg.main.veh = not cfg.main.veh
        save_cfg()
    end)
    sampRegisterChatCommand('fobj', function()
        cfg.main.obj = not cfg.main.obj
        save_cfg()
    end)

    wait(-1)
end

function events.onPlayerStreamIn(id, team, model, position, rotation, color, fight)
    if cfg.main.ped and model > 311 then
        return { id, team, 74, position, rotation, color, fight }
    end
end

function events.onSetPlayerSkin(id, skin)
    if cfg.main.ped and id ~= select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)) and skin > 311 then
        return { id, 74 }
    end
end

function events.onVehicleStreamIn(id, data)
    if cfg.main.veh and data.type > 611 then
        data.type = 424
        return { id, data }
    end
end

function events.onCreateObject(id, data)
    if cfg.main.obj then
        return false
    end
end
 

Вложения

  • ModelChanger.lua
    1.3 KB · Просмотры: 3
Последнее редактирование:

hhhaaauuu764

Новичок
11
3
Ну это прям кал. Идём по порядку:

Посмотреть вложение 267064Посмотреть вложение 267065Посмотреть вложение 267066

1) По хорошему в начале main надо бы добавить проверку на то что самп загружен
Lua:
while not isSampAvailable() do
    wait(0)
end
2) Ты назвал одну из функций "load", тем самым перезаписал одноимённую встроенную функцию для загрузки кода.
3) inicfg.load всегда возвращает тебе таблицу двойной вложенности. И все обращения идут по ключу. Ты во первых обращаешься к вложенным таблицам(в нашем случаи 1 таблице), а не значениям так ещё и по индексам, а не ключам. Я могу понять логику, что ты пытаешься все по очереди к всем настройкам так обратиться, но даже если бы так можно было, суть в том что таблицы невозможно отсортировать по ключам и настройки могут быть вообще в рандомном порядке. В твоём случаи значения data[N] при любом И всегда равны nil (т.е. ничего). Только с божий помощью людей, придумавших тебе динамическую типизацию, это даже случайно работает. Все проверки if veh(nil) then не проходят, а по вводу команд veh = not veh значение инвестируется за счёт приведения true = not nil.
4) Переменные veh, pls и obj зачем-то глобальные и вообще не имеют никакого смысла. У тебя есть двумерная таблица data с настройками, её и используй. Нет никакого смысла в дополнительных буферных переменных.
5) Ты вместо того чтобы сохранить свой конфиг, зачем-то создаёшь новую таблицу тем самым стирая все настройки, которые были изменены не в этой сессии работы скрипта. И вообще у тебя data локальная переменная с области видимости только внутри функции
6) Ты допустил ошибку в ключах настроек, при загрузки у тебя veh, pls и obj, а при сохранении vehs, plss и objs.Посмотреть вложение 2670677) Ты в фукнции cloneAndReplaceVehicle создаёшь структуру битстрима и выделяешь на это память при помощи raknetNewBitStream, но не удаляешь битстрим после отправки raknetEmulRpcReceiveBitStream. Это потенциальная утечка памяти, которая наебнёт игру со временем.
8) raknetBitStreamSetReadOffset(bs, 0) не имеет никакого смысла, поскольку ты нигде до не читаешь память, указатель чтения и так стоит на 0.

А теперь по мелочам:
1) При подключении библиотеке samp.event не обязательно дописывать "lib." в начале. Оно и так в папке lib ищет. (Я знаю что ты просто скопипастил)Посмотреть вложение 2670682) Ты что олимпиадник по какой-то извращённой компрессии кода? Код не имеет единую структуру, переменные из 1 символа нечитаемые, зачем-то избегаются переносы строк, отсутствуют пробелы в очевидных местах. В целом почитай про правила хорошего тона в программировании, вообще любые для любого языка. База +- везде идентичная и она уже сделает намного лучше.
3) Вместо while true do wait(0) end достаточно wait(-1). Этот цикл не нужен
4) Не знаю зачем ты пытаешься работать с битстримом напрямую, темболее пересозданием рпс, и используешь onReceiveRpc если для спавна транспорта в samp.events есть событие
INCOMING_RPCS[RPC.WORLDVEHICLEADD] = {'onVehicleStreamIn', handler.rpc_vehicle_stream_in_reader, handler.rpc_vehicle_stream_in_writer} Фантастика как ты нашёл структуру для битстрима и даже правильно её выстроил, но структуру handler.rpc_vehicle_stream_in_reader, которая подключается из файла handlers.lua ты найти не смог, хотя это одна и та же структура по сути
local handler = require 'samp.events.handlers'
Посмотреть вложение 267069
5) Для игроков вместо сокращения "pls", которая вообще не ясно что значит есть прекрасное "ped". Люди в игре так и называются педами.
6) У тебя во всех проверках сначала идёт условие работы, а только потом проверка включена ли она. Это неправильная расстановка приоритетов
ура разбор скрипта на 100 строк
 

Funny Rofl

Участник
97
56
Ещё наверное можно с помощи rpc 43 (RemoveBuildingForPlayer) удалять новые встроенные в карту объекты, которые тоже жрут фпс.
 

Xmoore

Новичок
Автор темы
21
6
Ну это прям кал. Идём по порядку:

Посмотреть вложение 267064Посмотреть вложение 267065Посмотреть вложение 267066

1) По хорошему в начале main надо бы добавить проверку на то что самп загружен
Lua:
while not isSampAvailable() do
    wait(0)
end
2) Ты назвал одну из функций "load", тем самым перезаписал одноимённую встроенную функцию для загрузки кода.
3) inicfg.load всегда возвращает тебе таблицу двойной вложенности. И все обращения идут по ключу. Ты во первых обращаешься к вложенным таблицам(в нашем случаи 1 таблице), а не значениям так ещё и по индексам, а не ключам. Я могу понять логику, что ты пытаешься все по очереди к всем настройкам так обратиться, но даже если бы так можно было, суть в том что таблицы невозможно отсортировать по ключам и настройки могут быть вообще в рандомном порядке. В твоём случаи значения data[N] при любом И всегда равны nil (т.е. ничего). Только с божий помощью людей, придумавших тебе динамическую типизацию, это даже случайно работает. Все проверки if veh(nil) then не проходят, а по вводу команд veh = not veh значение инвестируется за счёт приведения true = not nil.
4) Переменные veh, pls и obj зачем-то глобальные и вообще не имеют никакого смысла. У тебя есть двумерная таблица data с настройками, её и используй. Нет никакого смысла в дополнительных буферных переменных.
5) Ты вместо того чтобы сохранить свой конфиг, зачем-то создаёшь новую таблицу тем самым стирая все настройки, которые были изменены не в этой сессии работы скрипта. И вообще у тебя data локальная переменная с области видимости только внутри функции
6) Ты допустил ошибку в ключах настроек, при загрузки у тебя veh, pls и obj, а при сохранении vehs, plss и objs.Посмотреть вложение 2670677) Ты в фукнции cloneAndReplaceVehicle создаёшь структуру битстрима и выделяешь на это память при помощи raknetNewBitStream, но не удаляешь битстрим после отправки raknetEmulRpcReceiveBitStream. Это потенциальная утечка памяти, которая наебнёт игру со временем.
8) raknetBitStreamSetReadOffset(bs, 0) не имеет никакого смысла, поскольку ты нигде до не читаешь память, указатель чтения и так стоит на 0.

А теперь по мелочам:
1) При подключении библиотеке samp.event не обязательно дописывать "lib." в начале. Оно и так в папке lib ищет. (Я знаю что ты просто скопипастил)Посмотреть вложение 2670682) Ты что олимпиадник по какой-то извращённой компрессии кода? Код не имеет единую структуру, переменные из 1 символа нечитаемые, зачем-то избегаются переносы строк, отсутствуют пробелы в очевидных местах. В целом почитай про правила хорошего тона в программировании, вообще любые для любого языка. База +- везде идентичная и она уже сделает намного лучше.
3) Вместо while true do wait(0) end достаточно wait(-1). Этот цикл не нужен
4) Не знаю зачем ты пытаешься работать с битстримом напрямую, темболее пересозданием рпс, и используешь onReceiveRpc если для спавна транспорта в samp.events есть событие
INCOMING_RPCS[RPC.WORLDVEHICLEADD] = {'onVehicleStreamIn', handler.rpc_vehicle_stream_in_reader, handler.rpc_vehicle_stream_in_writer} Фантастика как ты нашёл структуру для битстрима и даже правильно её выстроил, но структуру handler.rpc_vehicle_stream_in_reader, которая подключается из файла handlers.lua ты найти не смог, хотя это одна и та же структура по сути
local handler = require 'samp.events.handlers'
Посмотреть вложение 267069
5) Для игроков вместо сокращения "pls", которая вообще не ясно что значит есть прекрасное "ped". Люди в игре так и называются педами.
6) У тебя во всех проверках сначала идёт условие работы, а только потом проверка включена ли она. Это неправильная расстановка приоритетов

После рефакторинга должно получиться что-то вроде

Lua:
local events = require 'samp.events'
local inicfg = require 'inicfg'

local cfg = inicfg.load({
    main = {
        ped = false,
        veh = false,
        obj = false
    }
}, 'ModelChanger')

local function save_cfg()
    inicfg.save(cfg, 'ModelChanger')
end

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then
        return
    end
    while not isSampAvailable() do
        wait(0)
    end

    sampRegisterChatCommand('fped', function()
        cfg.main.ped = not cfg.main.ped
        save_cfg()
    end)
    sampRegisterChatCommand('fveh', function()
        cfg.main.veh = not cfg.main.veh
        save_cfg()
    end)
    sampRegisterChatCommand('fobj', function()
        cfg.main.obj = not cfg.main.obj
        save_cfg()
    end)

    wait(-1)
end

function events.onPlayerStreamIn(id, team, model, position, rotation, color, fight)
    if cfg.main.ped and model > 311 then
        return { id, team, 74, position, rotation, color, fight }
    end
end

function events.onSetPlayerSkin(id, skin)
    if cfg.main.ped and id ~= select(2, sampGetPlayerIdByCharHandle(PLAYER_PED)) and skin > 311 then
        return { id, 74 }
    end
end

function events.onVehicleStreamIn(id, data)
    if cfg.main.veh and data.type > 611 then
        data.type = 424
        return { id, data }
    end
end

function events.onCreateObject(id, data)
    if cfg.main.obj then
        return false
    end
end
Спасибо, приму всё к сведению <3
Кстати, pls, это сокращение от players.

Ещё наверное можно с помощи rpc 43 (RemoveBuildingForPlayer) удалять новые встроенные в карту объекты, которые тоже жрут фпс.
Оке, как будет время может добавлю.
Upd: Я посмотрел, это кажется объекты грубо говоря самой карты и если удалить их, то вероятно будет много дыр по карте, в которые можно провалиться.
В общем, это будет слишком большой ценой за FPS.
Ну или мне просто лень разбираться в этом.
 
Последнее редактирование: