не работает return false

libsamp.so

Активный
Автор темы
247
86
возникла такая проблема, не работает return false у sampev событий, тоесть пакет все равно отправляется или принимается от сервера, перед тем как данная проблема появилась я запихнул обработчик в lua_thread.create(function(), и после этого появилась данная проблема, я понял что событие перезаписалось, обновил либу самп евентс, скачал последний самп функс, не помогло, проблема также появляется и на другой сборке, не пойму в чем проблема
 

976h

Активный
271
88
возникла такая проблема, не работает return false у sampev событий, тоесть пакет все равно отправляется или принимается от сервера, перед тем как данная проблема появилась я запихнул обработчик в lua_thread.create(function(), и после этого появилась данная проблема, я понял что событие перезаписалось, обновил либу самп евентс, скачал последний самп функс, не помогло, проблема также появляется и на другой сборке, не пойму в чем проблема
Мб кинь код?
 

kyrtion

Известный
1,343
511
обработчик в lua_thread.create(function()
не нужно. обрабатывается по времени в луа, если корутины (потоки) и обрабатывать событие в samp.lua нет ничего не будет (или с поломкой).
чтобы гарантировать нужно следовать по примеру как описывал FYP или другое.
указывая:
- return false - просто выбрасывает в урну
- return true или nil - ничего не изменится, можно остановить процедуру используя просто return (он тот же return nil)
- return { данные тот же с аргумента } - сначала старый пакет выбрасывает и создает новую, затем отправляет в эмуляции или в настоящем. для синхронизации можно без return data (сами переписывают)

Если несколько раз используете function sampev.onServerMessage и LLS в VS Code предупреждает том что обнаружен дубль функции - специально для тех кто сидит под moonly:
src/event/types.lua:
---@class VectorXYZ
---@field x number
---@field y number
---@field z number

---@class SampKeys
---@field primaryFire boolean
---@field horn_crouch boolean
---@field secondaryFire_shoot boolean
---@field accel_zoomOut boolean
---@field enterExitCar boolean
---@field decel_jump boolean
---@field circleRight boolean
---@field aim boolean
---@field circleLeft boolean
---@field landingGear_lookback boolean
---@field unknown_walkSlow boolean
---@field specialCtrlUp boolean
---@field specialCtrlDown boolean
---@field specialCtrlLeft boolean
---@field specialCtrlRight boolean
---@field _unknown boolean

---@class InitGame.Settings
---@field zoneNames boolean
---@field useCJWalk boolean
---@field allowWeapons boolean
---@field limitGlobalChatRadius boolean
---@field globalChatRadius number
---@field stuntBonus boolean
---@field nametagDrawDist number
---@field disableEnterExits boolean
---@field nametagLOS boolean
---@field tirePopping boolean
---@field classesAvailable integer
---@field showPlayerTags boolean
---@field playerMarkersMode integer
---@field worldTime number
---@field worldWeather number
---@field gravity number
---@field lanMode boolean
---@field deathMoneyDrop integer
---@field instagib boolean
---@field normalOnfootSendrate integer
---@field normalIncarSendrate integer
---@field normalFiringSendrate integer
---@field sendMultiplier integer
---@field lagCompMode integer
---@field vehicleFriendlyFire boolean

---@class InitGame
---@field playerId integer
---@field hostName string
---@field settings InitGame.Settings
---@field vehicleModels number[]
---@field vehicleFriendlyFire boolean

---@class PlayerSyncData.AnimationFlags
---@field loop boolean
---@field lockX boolean
---@field lockY boolean
---@field freeze boolean
---@field time integer
---@field _unused integer
---@field regular boolean
---@field value integer

---@class PlayerSyncData.Animation
---@field id integer
---@field frameDelta integer
---@field flags PlayerSyncData.AnimationFlags?

---@class PlayerSyncData
---@field leftRightKeys integer
---@field upDownKeys integer
---@field keysData integer?
---@field keys PlayerSyncData?
---@field position VectorXYZ
---@field quaternion { [1]: number, [2]: number, [3]: number, [4]: number }
---@field health integer
---@field armor integer
---@field weapon integer
---@field specialKey integer
---@field specialAction integer
---@field moveSpeed VectorXYZ
---@field surfingOffsets VectorXYZ
---@field surfingVehicleId integer
---@field animation PlayerSyncData.Animation?
---@field animationId integer?
---@field animationFlags integer?

---@class VehicleSyncData
---@field vehicleId number
---@field leftRightKeys number
---@field upDownKeys number
---@field keysData number?
---@field keys SampKeys?
---@field quaternion { [1]: number, [2]: number, [3]: number, [4]: number }
---@field position VectorXYZ
---@field moveSpeed VectorXYZ
---@field vehicleHealth number
---@field playerHealth number
---@field armor number
---@field currentWeapon number
---@field specialKey number
---@field siren number
---@field landingGearState number
---@field trailerId number
---@field bikeLean number?
---@field trainSpeed number?
---@field hydraThrustAngle { [1]: number, [2]: number }?

---@class PassengerSyncData
---@field vehicleId number
---@field seatId number
---@field driveBy boolean
---@field cuffed boolean
---@field currentWeapon number
---@field specialKey number
---@field health number
---@field armor number
---@field leftRightKeys number
---@field upDownKeys number
---@field keysData number?
---@field keys SampKeys?
---@field position VectorXYZ

---@class UnoccupiedSyncData
---@field vehicleId number
---@field seatId number
---@field roll VectorXYZ
---@field direction VectorXYZ
---@field position VectorXYZ
---@field moveSpeed VectorXYZ
---@field turnSpeed VectorXYZ
---@field vehicleHealth number

---@class TrailerSyncData
---@field trailerId number
---@field position VectorXYZ
---@field quaternion { [1]: number, [2]: number, [3]: number, [4]: number }?
---@field moveSpeed VectorXYZ?
---@field turnSpeed VectorXYZ?
---@field roll VectorXYZ?
---@field direction VectorXYZ?
---@field speed VectorXYZ?
---@field unk number?

---@class SpectatorSyncData
---@field leftRightKeys number
---@field upDownKeys number
---@field keysData number?
---@field keys SampKeys?
---@field position VectorXYZ

---@class BulletSyncData
---@field targetType number
---@field targetId number
---@field origin VectorXYZ
---@field target VectorXYZ
---@field center VectorXYZ
---@field weaponId number

---@class AimSyncData
---@field camMode number
---@field camFront VectorXYZ
---@field camPos VectorXYZ
---@field aimZ number
---@field camExtZoom number
---@field weaponState number
---@field aspectRatio number
src/event/service.lua:
---@diagnostic disable: lowercase-global

local sampev = require('samp.events')

---@class EventService
local M = {
  handlers = {}
}

---@param event_name string
---@vararg any
function M:publish(event_name, ...)
  local handler = self.handlers[event_name]
  if handler ~= nil and type(handler) == 'table' then
    for _, event in ipairs(self.handlers[event_name]) do
      event.callback(...)
    end
  end
end

---@param event_name string
---@param callback function
---@param priority number? Default: `0`
function M:add(event_name, callback, priority)
  if self.handlers[event_name] == nil then
    self.handlers[event_name] = {}
  end
  priority = priority or 0 -- Default priority

  print('called new event', event_name, callback, type(callback), priority)
  table.insert(self.handlers[event_name], { callback = callback, priority = priority })
end

function M:init()
  local function autoAddEvent(samp_event)
    sampev[samp_event] = function(...) ---@diagnostic disable-line: assign-type-mismatch
      local handlers = self.handlers[samp_event] or {}
      table.sort(handlers, function(a, b)
        return (a.priority or 0) > (b.priority or 0)
      end)
      for i, handler_data in ipairs(handlers) do
        local cb = handler_data.callback
        local rets = cb(...)
        if rets ~= nil and (type(rets) == 'table' or type(rets) == 'boolean') then
          return rets
        end
      end
    end
  end

  for rpc_type, list in pairs({
    sampev.INTERFACE['INCOMING_RPCS'],
    sampev.INTERFACE['OUTCOMING_RPCS'],
    sampev.INTERFACE['INCOMING_PACKETS'],
    sampev.INTERFACE['OUTCOMING_PACKETS']
  }) do
    for rpc_id, data in pairs(list) do
      local multiple_event, data_multiple_event = false, {}
      if data and type(data[1]) == 'table' then
        for i, value in ipairs(data[1]) do
          if not multiple_event then
            multiple_event = true
          end
          table.insert(data_multiple_event, value)
        end
      end
      for i, samp_event in ipairs(multiple_event and data_multiple_event or { data[1] }) do
        autoAddEvent(samp_event)
      end
    end
  end
end

return M
src/event/data.lua:
---@diagnostic disable: lowercase-global

local EventService = require('event.service')

-- Loop in main func, usage wait only with os.clock
---@param cb fun(clock: number): boolean | nil
---@param pr number? Priority. Default: `0`
function onMainThread(cb, pr) EventService:add('onMainThread', cb, pr) end

---@param cb fun(): nil
---@param pr number? Priority. Default: `0`
function onTerminate(cb, pr) EventService:add('onTerminate', cb, pr) end

---@param cb fun(msg: integer, wparam: integer, lparam: number): boolean | nil
---@param pr number? Priority. Default: `0`
function onProcessMessage(cb, pr) EventService:add('onProcessMessage', cb, pr) end

-- ---@param cb fun(player_id: integer, hostname: string, settings: InitGame.Settings, vehicle_models: number[], vehicle_friendly_fire: boolean): { player_id: integer, hostname: string, settings: InitGame.Settings, vehicle_models: number[], vehicle_friendly_fire: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onInitGame(cb, pr) EventService:add('onInitGame', cb, pr) end

-- ---@param cb fun(): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onSendSpawn(cb, pr) EventService:add('onSendSpawn', cb, pr) end

-- ---@param cb fun(): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onDisconnect(cb, pr) EventService:add('onConnectionClosed', cb, pr) end

-- ---@param cb fun(color: number, text: string): { color: number, text: string } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onServerMessage(cb, pr) EventService:add('onServerMessage', cb, pr) end

-- ---@param cb fun(player_id: integer): { player_id: integer } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onPlayerQuit(cb, pr) EventService:add('onPlayerQuit', cb, pr) end

-- ---@param cb fun(state: boolean): { state: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onTogglePlayerSpectating(cb, pr) EventService:add('onTogglePlayerSpectating', cb, pr) end

-- ---@param cb fun(dialog_id: number, style: integer, title: string, button_1: string, button_2: string, text: string): { dialog_id: number, style: integer, title: string, button_1: string, button_2: string, text: string } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onShowDialog(cb, pr) EventService:add('onShowDialog', cb, pr) end

-- ---@param cb fun(player_id: integer, data: AimSyncData): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onAimSync(cb, pr) EventService:add('onAimSync', cb, pr) end

-- ---@param cb fun(player_id: integer, data: PlayerSyncData): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onPlayerSync(cb, pr) EventService:add('onPlayerSync', cb, pr) end

-- ---@param cb fun(controllable: boolean): { controllable: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onTogglePlayerControllable(cb, pr) EventService:add('onTogglePlayerControllable', cb, pr) end

-- ---@param cb fun(player_id: integer, anim_lib: string, anim_name: string, frame_delta: number, loop: boolean, lock_x: boolean, lock_y: boolean, freeze: boolean, time: number): { player_id: integer, anim_lib: string, anim_name: string, frame_delta: number, loop: boolean, lock_x: boolean, lock_y: boolean, freeze: boolean, time: number } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onApplyPlayerAnimation(cb, pr) EventService:add('onApplyPlayerAnimation', cb, pr) end

-- ---@param cb fun(player_id: integer): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onClearPlayerAnimation(cb, pr) EventService:add('onClearPlayerAnimation', cb, pr) end

-- ---@param cb fun(weapon_id: integer): {weapon_id: integer} | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onSetPlayerArmedWeapon(cb, pr) EventService:add('onSetPlayerArmedWeapon', cb, pr) end

-- ---@param cb fun(player_id: integer, damage: integer, weapon: number, body_part: number, is_take: boolean): { player_id: integer, damage: integer, weapon: number, body_part: number, is_take: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onSendGiveDamage(cb, pr) EventService:add('onSendGiveDamage', cb, pr) end

-- ---@param cb fun(player_id: integer, damage: integer, weapon: number, body_part: number, is_take: boolean): { player_id: integer, damage: integer, weapon: number, body_part: number, is_take: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onSendTakeDamage(cb, pr) EventService:add('onSendTakeDamage', cb, pr) end

---* CUSTOM * ---

-- ---@param cb fun(): nil
-- ---@param pr number? Priority. Default: `0`
-- function onFirstSpawn(cb, pr) EventService:add('onFirstSpawn', cb, pr) end
src/event/init.lua:
local Event = {}

function Event.init()
  local EventService = require('event.service')

  require('event.data')

  addEventHandler('onScriptTerminate', function(scr, quit_game)
    if scr == thisScript() then
      EventService:publish('onTerminate')
    end
  end)

  addEventHandler('onWindowMessage', function(...)
    EventService:publish('onProcessMessage', ...)
  end)

  EventService:init()
end

return Event

Примеры:
Пример:
local EventService = require('event.service')
-- Для публикации сообщение в кастомных событий указывать так:
-- на случай, сообщить если скрипт крашнулся
addEventHandler('onScriptTerminate', function(scr, quit_game)
  if scr == thisScript() then
      -- если в текущем скрипт - автоматически публикует в событие onTerminate(func)
    EventService:publish('onTerminate')
  end
end)

-- где-то в плагин на рендер допустим для погоня преступников
-- onTerminate, arg: func(args) [, priority(0)]
-- приоритет автоматически ставится 0, если повышаешь приоритет,
-- то в первую очередь это сделает затем другое
onTerminate(function()
  sampAddChatMessage('Рендер переходит в оффлайн, в связи отключение скрипта')
end, 100)

-----------------------------------------------------------------------------------

onMainThread(func(clock), priority) -- тот же самый цикл в main
-- или сам поменяешь на onUpdate, старые добрые времена в RakSAMP Lite

-- где-то в main:
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(0) end

  -- waiting for reload left script for auto-update
  wait(100)

  require('core').init()

  -- вот здесь начинается
  local EventService = require('event.service')
  while true do
    wait(0)
    EventService:publish('onMainThread', os.clock())
    -- сервис событиев публикует в конкретную, и аргумент чтобы добавить внутри функции
    -- пример, onMainThread(func( -> аргумент таймера <- ), priority)
  end
end

-- внедрил в data.lua:
-- Loop in main func, usage wait only with os.clock -- <------ вот здесь
---@param cb fun(clock: number): boolean | nil -- <----------- и здесь
---@param pr number? Priority. Default: `0`
function onMainThread(cb, pr) EventService:add('onMainThread', cb, pr) end

-- примеры в модули:
-- для задержки используйте с таймером, никаких wait и sleep
-- используя с таймером не пригодится для рендера, а для данных - нужно и советую
-- допустим обновить каждые 0.5 сек список педов в стриме
local timer = os.clock()
local trigger_sec = 0.5
onMainThread(function(current_clock)
  if (current_clock - timer) > trigger_sec then
    STREAM_PLAYERS = getAllPlayers(true) -- это я сам создал свою функцию
    timer = os.clock()
  end
end, 15)

спасибо @chapo за такой чудесный сниппет, ему низкий поклон до ногах
 

libsamp.so

Активный
Автор темы
247
86
не нужно. обрабатывается по времени в луа, если корутины (потоки) и обрабатывать событие в samp.lua нет ничего не будет (или с поломкой).
чтобы гарантировать нужно следовать по примеру как описывал FYP или другое.
указывая:
- return false - просто выбрасывает в урну
- return true или nil - ничего не изменится, можно остановить процедуру используя просто return (он тот же return nil)
- return { данные тот же с аргумента } - сначала старый пакет выбрасывает и создает новую, затем отправляет в эмуляции или в настоящем. для синхронизации можно без return data (сами переписывают)

Если несколько раз используете function sampev.onServerMessage и LLS в VS Code предупреждает том что обнаружен дубль функции - специально для тех кто сидит под moonly:
src/event/types.lua:
---@class VectorXYZ
---@field x number
---@field y number
---@field z number

---@class SampKeys
---@field primaryFire boolean
---@field horn_crouch boolean
---@field secondaryFire_shoot boolean
---@field accel_zoomOut boolean
---@field enterExitCar boolean
---@field decel_jump boolean
---@field circleRight boolean
---@field aim boolean
---@field circleLeft boolean
---@field landingGear_lookback boolean
---@field unknown_walkSlow boolean
---@field specialCtrlUp boolean
---@field specialCtrlDown boolean
---@field specialCtrlLeft boolean
---@field specialCtrlRight boolean
---@field _unknown boolean

---@class InitGame.Settings
---@field zoneNames boolean
---@field useCJWalk boolean
---@field allowWeapons boolean
---@field limitGlobalChatRadius boolean
---@field globalChatRadius number
---@field stuntBonus boolean
---@field nametagDrawDist number
---@field disableEnterExits boolean
---@field nametagLOS boolean
---@field tirePopping boolean
---@field classesAvailable integer
---@field showPlayerTags boolean
---@field playerMarkersMode integer
---@field worldTime number
---@field worldWeather number
---@field gravity number
---@field lanMode boolean
---@field deathMoneyDrop integer
---@field instagib boolean
---@field normalOnfootSendrate integer
---@field normalIncarSendrate integer
---@field normalFiringSendrate integer
---@field sendMultiplier integer
---@field lagCompMode integer
---@field vehicleFriendlyFire boolean

---@class InitGame
---@field playerId integer
---@field hostName string
---@field settings InitGame.Settings
---@field vehicleModels number[]
---@field vehicleFriendlyFire boolean

---@class PlayerSyncData.AnimationFlags
---@field loop boolean
---@field lockX boolean
---@field lockY boolean
---@field freeze boolean
---@field time integer
---@field _unused integer
---@field regular boolean
---@field value integer

---@class PlayerSyncData.Animation
---@field id integer
---@field frameDelta integer
---@field flags PlayerSyncData.AnimationFlags?

---@class PlayerSyncData
---@field leftRightKeys integer
---@field upDownKeys integer
---@field keysData integer?
---@field keys PlayerSyncData?
---@field position VectorXYZ
---@field quaternion { [1]: number, [2]: number, [3]: number, [4]: number }
---@field health integer
---@field armor integer
---@field weapon integer
---@field specialKey integer
---@field specialAction integer
---@field moveSpeed VectorXYZ
---@field surfingOffsets VectorXYZ
---@field surfingVehicleId integer
---@field animation PlayerSyncData.Animation?
---@field animationId integer?
---@field animationFlags integer?

---@class VehicleSyncData
---@field vehicleId number
---@field leftRightKeys number
---@field upDownKeys number
---@field keysData number?
---@field keys SampKeys?
---@field quaternion { [1]: number, [2]: number, [3]: number, [4]: number }
---@field position VectorXYZ
---@field moveSpeed VectorXYZ
---@field vehicleHealth number
---@field playerHealth number
---@field armor number
---@field currentWeapon number
---@field specialKey number
---@field siren number
---@field landingGearState number
---@field trailerId number
---@field bikeLean number?
---@field trainSpeed number?
---@field hydraThrustAngle { [1]: number, [2]: number }?

---@class PassengerSyncData
---@field vehicleId number
---@field seatId number
---@field driveBy boolean
---@field cuffed boolean
---@field currentWeapon number
---@field specialKey number
---@field health number
---@field armor number
---@field leftRightKeys number
---@field upDownKeys number
---@field keysData number?
---@field keys SampKeys?
---@field position VectorXYZ

---@class UnoccupiedSyncData
---@field vehicleId number
---@field seatId number
---@field roll VectorXYZ
---@field direction VectorXYZ
---@field position VectorXYZ
---@field moveSpeed VectorXYZ
---@field turnSpeed VectorXYZ
---@field vehicleHealth number

---@class TrailerSyncData
---@field trailerId number
---@field position VectorXYZ
---@field quaternion { [1]: number, [2]: number, [3]: number, [4]: number }?
---@field moveSpeed VectorXYZ?
---@field turnSpeed VectorXYZ?
---@field roll VectorXYZ?
---@field direction VectorXYZ?
---@field speed VectorXYZ?
---@field unk number?

---@class SpectatorSyncData
---@field leftRightKeys number
---@field upDownKeys number
---@field keysData number?
---@field keys SampKeys?
---@field position VectorXYZ

---@class BulletSyncData
---@field targetType number
---@field targetId number
---@field origin VectorXYZ
---@field target VectorXYZ
---@field center VectorXYZ
---@field weaponId number

---@class AimSyncData
---@field camMode number
---@field camFront VectorXYZ
---@field camPos VectorXYZ
---@field aimZ number
---@field camExtZoom number
---@field weaponState number
---@field aspectRatio number
src/event/service.lua:
---@diagnostic disable: lowercase-global

local sampev = require('samp.events')

---@class EventService
local M = {
  handlers = {}
}

---@param event_name string
---@vararg any
function M:publish(event_name, ...)
  local handler = self.handlers[event_name]
  if handler ~= nil and type(handler) == 'table' then
    for _, event in ipairs(self.handlers[event_name]) do
      event.callback(...)
    end
  end
end

---@param event_name string
---@param callback function
---@param priority number? Default: `0`
function M:add(event_name, callback, priority)
  if self.handlers[event_name] == nil then
    self.handlers[event_name] = {}
  end
  priority = priority or 0 -- Default priority

  print('called new event', event_name, callback, type(callback), priority)
  table.insert(self.handlers[event_name], { callback = callback, priority = priority })
end

function M:init()
  local function autoAddEvent(samp_event)
    sampev[samp_event] = function(...) ---@diagnostic disable-line: assign-type-mismatch
      local handlers = self.handlers[samp_event] or {}
      table.sort(handlers, function(a, b)
        return (a.priority or 0) > (b.priority or 0)
      end)
      for i, handler_data in ipairs(handlers) do
        local cb = handler_data.callback
        local rets = cb(...)
        if rets ~= nil and (type(rets) == 'table' or type(rets) == 'boolean') then
          return rets
        end
      end
    end
  end

  for rpc_type, list in pairs({
    sampev.INTERFACE['INCOMING_RPCS'],
    sampev.INTERFACE['OUTCOMING_RPCS'],
    sampev.INTERFACE['INCOMING_PACKETS'],
    sampev.INTERFACE['OUTCOMING_PACKETS']
  }) do
    for rpc_id, data in pairs(list) do
      local multiple_event, data_multiple_event = false, {}
      if data and type(data[1]) == 'table' then
        for i, value in ipairs(data[1]) do
          if not multiple_event then
            multiple_event = true
          end
          table.insert(data_multiple_event, value)
        end
      end
      for i, samp_event in ipairs(multiple_event and data_multiple_event or { data[1] }) do
        autoAddEvent(samp_event)
      end
    end
  end
end

return M
src/event/data.lua:
---@diagnostic disable: lowercase-global

local EventService = require('event.service')

-- Loop in main func, usage wait only with os.clock
---@param cb fun(clock: number): boolean | nil
---@param pr number? Priority. Default: `0`
function onMainThread(cb, pr) EventService:add('onMainThread', cb, pr) end

---@param cb fun(): nil
---@param pr number? Priority. Default: `0`
function onTerminate(cb, pr) EventService:add('onTerminate', cb, pr) end

---@param cb fun(msg: integer, wparam: integer, lparam: number): boolean | nil
---@param pr number? Priority. Default: `0`
function onProcessMessage(cb, pr) EventService:add('onProcessMessage', cb, pr) end

-- ---@param cb fun(player_id: integer, hostname: string, settings: InitGame.Settings, vehicle_models: number[], vehicle_friendly_fire: boolean): { player_id: integer, hostname: string, settings: InitGame.Settings, vehicle_models: number[], vehicle_friendly_fire: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onInitGame(cb, pr) EventService:add('onInitGame', cb, pr) end

-- ---@param cb fun(): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onSendSpawn(cb, pr) EventService:add('onSendSpawn', cb, pr) end

-- ---@param cb fun(): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onDisconnect(cb, pr) EventService:add('onConnectionClosed', cb, pr) end

-- ---@param cb fun(color: number, text: string): { color: number, text: string } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onServerMessage(cb, pr) EventService:add('onServerMessage', cb, pr) end

-- ---@param cb fun(player_id: integer): { player_id: integer } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onPlayerQuit(cb, pr) EventService:add('onPlayerQuit', cb, pr) end

-- ---@param cb fun(state: boolean): { state: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onTogglePlayerSpectating(cb, pr) EventService:add('onTogglePlayerSpectating', cb, pr) end

-- ---@param cb fun(dialog_id: number, style: integer, title: string, button_1: string, button_2: string, text: string): { dialog_id: number, style: integer, title: string, button_1: string, button_2: string, text: string } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onShowDialog(cb, pr) EventService:add('onShowDialog', cb, pr) end

-- ---@param cb fun(player_id: integer, data: AimSyncData): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onAimSync(cb, pr) EventService:add('onAimSync', cb, pr) end

-- ---@param cb fun(player_id: integer, data: PlayerSyncData): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onPlayerSync(cb, pr) EventService:add('onPlayerSync', cb, pr) end

-- ---@param cb fun(controllable: boolean): { controllable: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onTogglePlayerControllable(cb, pr) EventService:add('onTogglePlayerControllable', cb, pr) end

-- ---@param cb fun(player_id: integer, anim_lib: string, anim_name: string, frame_delta: number, loop: boolean, lock_x: boolean, lock_y: boolean, freeze: boolean, time: number): { player_id: integer, anim_lib: string, anim_name: string, frame_delta: number, loop: boolean, lock_x: boolean, lock_y: boolean, freeze: boolean, time: number } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onApplyPlayerAnimation(cb, pr) EventService:add('onApplyPlayerAnimation', cb, pr) end

-- ---@param cb fun(player_id: integer): boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onClearPlayerAnimation(cb, pr) EventService:add('onClearPlayerAnimation', cb, pr) end

-- ---@param cb fun(weapon_id: integer): {weapon_id: integer} | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onSetPlayerArmedWeapon(cb, pr) EventService:add('onSetPlayerArmedWeapon', cb, pr) end

-- ---@param cb fun(player_id: integer, damage: integer, weapon: number, body_part: number, is_take: boolean): { player_id: integer, damage: integer, weapon: number, body_part: number, is_take: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onSendGiveDamage(cb, pr) EventService:add('onSendGiveDamage', cb, pr) end

-- ---@param cb fun(player_id: integer, damage: integer, weapon: number, body_part: number, is_take: boolean): { player_id: integer, damage: integer, weapon: number, body_part: number, is_take: boolean } | boolean | nil
-- ---@param pr number? Priority. Default: `0`
-- function onSendTakeDamage(cb, pr) EventService:add('onSendTakeDamage', cb, pr) end

---* CUSTOM * ---

-- ---@param cb fun(): nil
-- ---@param pr number? Priority. Default: `0`
-- function onFirstSpawn(cb, pr) EventService:add('onFirstSpawn', cb, pr) end
src/event/init.lua:
local Event = {}

function Event.init()
  local EventService = require('event.service')

  require('event.data')

  addEventHandler('onScriptTerminate', function(scr, quit_game)
    if scr == thisScript() then
      EventService:publish('onTerminate')
    end
  end)

  addEventHandler('onWindowMessage', function(...)
    EventService:publish('onProcessMessage', ...)
  end)

  EventService:init()
end

return Event

Примеры:
Пример:
local EventService = require('event.service')
-- Для публикации сообщение в кастомных событий указывать так:
-- на случай, сообщить если скрипт крашнулся
addEventHandler('onScriptTerminate', function(scr, quit_game)
  if scr == thisScript() then
      -- если в текущем скрипт - автоматически публикует в событие onTerminate(func)
    EventService:publish('onTerminate')
  end
end)

-- где-то в плагин на рендер допустим для погоня преступников
-- onTerminate, arg: func(args) [, priority(0)]
-- приоритет автоматически ставится 0, если повышаешь приоритет,
-- то в первую очередь это сделает затем другое
onTerminate(function()
  sampAddChatMessage('Рендер переходит в оффлайн, в связи отключение скрипта')
end, 100)

-----------------------------------------------------------------------------------

onMainThread(func(clock), priority) -- тот же самый цикл в main
-- или сам поменяешь на onUpdate, старые добрые времена в RakSAMP Lite

-- где-то в main:
function main()
  if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while not isSampAvailable() do wait(0) end

  -- waiting for reload left script for auto-update
  wait(100)

  require('core').init()

  -- вот здесь начинается
  local EventService = require('event.service')
  while true do
    wait(0)
    EventService:publish('onMainThread', os.clock())
    -- сервис событиев публикует в конкретную, и аргумент чтобы добавить внутри функции
    -- пример, onMainThread(func( -> аргумент таймера <- ), priority)
  end
end

-- внедрил в data.lua:
-- Loop in main func, usage wait only with os.clock -- <------ вот здесь
---@param cb fun(clock: number): boolean | nil -- <----------- и здесь
---@param pr number? Priority. Default: `0`
function onMainThread(cb, pr) EventService:add('onMainThread', cb, pr) end

-- примеры в модули:
-- для задержки используйте с таймером, никаких wait и sleep
-- используя с таймером не пригодится для рендера, а для данных - нужно и советую
-- допустим обновить каждые 0.5 сек список педов в стриме
local timer = os.clock()
local trigger_sec = 0.5
onMainThread(function(current_clock)
  if (current_clock - timer) > trigger_sec then
    STREAM_PLAYERS = getAllPlayers(true) -- это я сам создал свою функцию
    timer = os.clock()
  end
end, 15)

спасибо @chapo за такой чудесный сниппет, ему низкий поклон до ногах
это проблему никак не решает
Lua:
function sampev.onSendClientJoin(version, mod, nickname, challengeResponse, joinAuthKey, clientVer, unknown)
  return false
end
На удивление на лаунчере аризоны все работает
 
Последнее редактирование:

chromiusj

модерирую шмодерирую
Модератор
5,985
4,296
спасибо что насрал текстом от нейронки тут
это не нейронка, человек так объясняет в связи с особенностями дефектов незначительных (это не рофл и тому подобное)
 
  • Ха-ха
Реакции: 01EG

chapo

tg/inst: @moujeek
Всефорумный модератор
9,204
12,535
спасибо что насрал текстом от нейронки тут
можно было догадаться что это не нейронка как минимум по кускам кода который он скинул -_-
1762684447870.png
 

alexroq

Участник
124
14

пишут что обновление sampfuncs помогло
 

libsamp.so

Активный
Автор темы
247
86

пишут что обновление sampfuncs помогло
прочитай еще раз что я писал в посте, самп функс обновлял