local ffi = require 'ffi'
local sampfuncs = require "sampfuncs"
require 'samp.synchronization'
local storePackets = {
[PACKET_PLAYER_SYNC] = 0,
[PACKET_VEHICLE_SYNC] = 0,
[PACKET_AIM_SYNC] = 0
}
local syncTypes = {
[PACKET_PLAYER_SYNC] = "PlayerSyncData",
[PACKET_VEHICLE_SYNC] = "VehicleSyncData",
[PACKET_AIM_SYNC] = "AimSyncData"
}
registerHandler("onSendPacket", function(id, bs)
if storePackets[id] ~= nil and syncTypes[id] ~= nil then
local copyBs = bitStream.new()
copyBs:writeBitStream(bs)
copyBs:resetWritePointer()
storePackets[id] = copyBs
end
end)
function storeSyncData(pointer, packet_id)
local bs = storePackets[packet_id]
local new_sync_data = ffi.new(syncTypes[packet_id])
local syncPointer = ffi.cast('intptr_t', ffi.cast('void*', new_sync_data))
bs:writeBuffer(pointer, ffi.sizeof(syncPointer))
end
function samp_create_sync_data(sync_type, copy_from_player)
local raknet = require 'samp.raknet'
copy_from_player = copy_from_player or true
local sync_traits = {
player = {'PlayerSyncData', raknet.PACKET.PLAYER_SYNC},
vehicle = {'VehicleSyncData', raknet.PACKET.VEHICLE_SYNC},
passenger = {'PassengerSyncData', raknet.PACKET.PASSENGER_SYNC},
aim = {'AimSyncData', raknet.PACKET.AIM_SYNC},
trailer = {'TrailerSyncData', raknet.PACKET.TRAILER_SYNC},
unoccupied = {'UnoccupiedSyncData', raknet.PACKET.UNOCCUPIED_SYNC},
bullet = {'BulletSyncData', raknet.PACKET.BULLET_SYNC},
spectator = {'SpectatorSyncData', raknet.PACKET.SPECTATOR_SYNC}
}
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)))
-- copy player's sync data to the allocated memory
if copy_from_player then
storeSyncData(raw_data_ptr, sync_info[2])
end
-- function to send packet
local func_send = function()
local bs = bitStream.new()
bs:writeInt8(sync_info[2])
bs:writeBuffer(raw_data_ptr, ffi.sizeof(data))
bs:sendPacketEx(HIGH_PRIORITY, UNRELIABLE_SEQUENCED, 1)
end
-- metatable to access sync data and 'send' function
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