local keysTable = {
['Y'] = {
incar = { value = 1, specKey = true },
onfoot = { value = 1, specKey = true }
},
['N'] = {
incar = { value = 2, specKey = true },
onfoot = { value = 2, specKey = true }
},
['H'] = {
incar = { value = 2, specKey = false },
onfoot = { value = 3, specKey = true }
},
['C'] = {
incar = { value = nil, specKey = false },
onfoot = { value = 2, specKey = false }
},
['F'] = {
incar = { value = nil, specKey = false },
onfoot = { value = 16, specKey = false }
},
['ALT'] = {
incar = { value = 4, specKey = false },
onfoot = { value = 1024, specKey = false }
},
['TAB'] = {
incar = { value = nil, specKey = false },
onfoot = { value = 1, specKey = false }
},
['RMB'] = {
incar = { value = 4, specKey = false },
onfoot = { value = 128, specKey = false }
},
['LMB'] = {
incar = { value = nil, specKey = false },
onfoot = { value = 4, specKey = false }
},
['SPRINT'] = {
incar = { value = nil, specKey = false },
onfoot = { value = 8, specKey = false }
},
['JUMP'] = {
incar = { value = 128, specKey = false },
onfoot = { value = 32, specKey = false }
}
}
function sendSyncKey(key)
if key == nil then return end
local inCar = isCharInAnyCar(PLAYER_PED)
local data = inCar and samp_create_sync_data('vehicle') or samp_create_sync_data('player')
local keyData = inCar and keysTable[key].incar or keysTable[key].onfoot
if keyData.value == nil then return end
if keyData.specKey then data.specialKey = keyData.value else data.keysData = keyData.value end
data.send()
end
function samp_create_sync_data(sync_type, copy_from_player)
local ffi = require 'ffi'
local sampfuncs = require 'sampfuncs'
local raknet = require 'samp.raknet'
require 'samp.synchronization'
copy_from_player = copy_from_player or true
local sync_traits = {
player = { 'PlayerSyncData', raknet.PACKET.PLAYER_SYNC, sampStorePlayerOnfootData },
vehicle = { 'VehicleSyncData', raknet.PACKET.VEHICLE_SYNC, sampStorePlayerIncarData },
passenger = { 'PassengerSyncData', raknet.PACKET.PASSENGER_SYNC, sampStorePlayerPassengerData },
aim = { 'AimSyncData', raknet.PACKET.AIM_SYNC, sampStorePlayerAimData },
trailer = { 'TrailerSyncData', raknet.PACKET.TRAILER_SYNC, sampStorePlayerTrailerData },
unoccupied = { 'UnoccupiedSyncData', raknet.PACKET.UNOCCUPIED_SYNC, nil },
bullet = { 'BulletSyncData', raknet.PACKET.BULLET_SYNC, nil },
spectator = { 'SpectatorSyncData', raknet.PACKET.SPECTATOR_SYNC, nil }
}
local sync_info = sync_traits[sync_type]
local data_type = 'struct ' .. sync_info[1]
local data = ffi.new(data_type, {})
local raw_data_ptr = tonumber(ffi.cast('uintptr_t', ffi.new(data_type .. '*', data)))
if copy_from_player then
local copy_func = sync_info[3]
if copy_func then
local _, player_id
if copy_from_player == true then
_, player_id = sampGetPlayerIdByCharHandle(PLAYER_PED)
else
player_id = tonumber(copy_from_player)
end
copy_func(player_id, raw_data_ptr)
end
end
local func_send = function()
local bs = raknetNewBitStream()
raknetBitStreamWriteInt8(bs, sync_info[2])
raknetBitStreamWriteBuffer(bs, raw_data_ptr, ffi.sizeof(data))
raknetSendBitStreamEx(bs, sampfuncs.HIGH_PRIORITY, sampfuncs.UNRELIABLE_SEQUENCED, 1)
raknetDeleteBitStream(bs)
end
local mt = {
__index = function(t, index)
return data[index]
end,
__newindex = function(t, index, value)
data[index] = value
end
}
return setmetatable({ send = func_send }, mt)
end