function readvu32u8(packet)
  local v={}
  local len=packet:r_s32()
  for i=1,len,1 do
    table.insert(v,packet:r_u8())
  end
  return v
end

function readvu8u8(packet)
  local v={}
  local len=8
  for i=1,len,1 do
    table.insert(v,packet:r_u8())
  end
  return v
end

function readvu32u16(packet)
  local v={}
  local len=packet:r_s32()
  for i=1,len,1 do
    table.insert(v,packet:r_u16())
  end
  return v
end

function writevu32u8(pk,v)
  local len=table.getn(v)
  pk:w_s32(len)
  for i=1,len,1 do
    pk:w_u8(v[i])
  end
end

function writevu8u8(pk,v)
  local len=8 --table.getn(v)
  for i=1,len,1 do
    pk:w_u8(v[i])
  end
end

function writevu32u16(pk,v)
  local len=table.getn(v)
  pk:w_s32(len)
  for i=1,len,1 do
    pk:w_u16(v[i])
  end
end

function parse_object_packet(ret,stpk,updpk)
  ret.gvid=stpk:r_u16()
  ret.obf32u1=stpk:r_float()
  ret.obs32u2=stpk:r_s32()
  ret.lvid=stpk:r_s32()
  ret.oflags=stpk:r_s32()
  ret.custom=stpk:r_stringZ()
  ret.sid=stpk:r_s32()
  ret.obs32u3=stpk:r_s32()
  return ret
end

function fill_object_packet(ret,stpk,updpk)
  stpk:w_u16(ret.gvid)
  stpk:w_float(ret.obf32u1)
  stpk:w_s32(ret.obs32u2)
  stpk:w_s32(ret.lvid)
  stpk:w_s32(ret.oflags)
  stpk:w_stringZ(ret.custom)
  stpk:w_s32(ret.sid)
  stpk:w_s32(ret.obs32u3)
end


function parse_visual_packet(ret,stpk,updpk)
  ret.visual=stpk:r_stringZ()
  ret.vsu8u1=stpk:r_u8()
  return ret
end

function fill_visual_packet(ret,stpk,updpk)
  stpk:w_stringZ(ret.visual)
  stpk:w_u8(ret.vsu8u1)
end

function parse_dynamic_object_visual(ret,stpk,updpk)
  parse_object_packet(ret,stpk,updpk)
  parse_visual_packet(ret,stpk,updpk)
  return ret
end

function fill_dynamic_object_visual(ret,stpk,updpk)
  fill_object_packet(ret,stpk,updpk)
  fill_visual_packet(ret,stpk,updpk)
end

function parse_creature_packet(ret,stpk,updpk)
  parse_dynamic_object_visual(ret,stpk,updpk)
  ret.team=stpk:r_u8()
  ret.squad=stpk:r_u8()
  ret.group=stpk:r_u8()
  ret.health=stpk:r_float()
  ret.crvu32u16u1=readvu32u16(stpk)
  ret.crvu32u16u2=readvu32u16(stpk)  
  ret.killerid=stpk:r_u16()
  ret.game_death_time=readvu8u8(stpk)

  ret.updhealth=updpk:r_float()
  ret.upds32u1=updpk:r_s32()
  ret.updu8u2=updpk:r_u8()
  ret.updpos={} -- или поставить вектор? ладно потом
  ret.updpos.x=updpk:r_float()
  ret.updpos.y=updpk:r_float()
  ret.updpos.z=updpk:r_float()
  ret.updmodel=updpk:r_float()
  ret.upddir={}
  ret.upddir.x=updpk:r_float()
  ret.upddir.y=updpk:r_float()
  ret.upddir.z=updpk:r_float()
  ret.updteam=updpk:r_u8()
  ret.updsquad=updpk:r_u8()
  ret.updgroup=updpk:r_u8()  
  return ret
end

function fill_creature_packet(ret,stpk,updpk)
  fill_dynamic_object_visual(ret,stpk,updpk)
  stpk:w_u8(ret.team)
  stpk:w_u8(ret.squad)
  stpk:w_u8(ret.group)
  stpk:w_float(ret.health)
  writevu32u16(stpk,ret.crvu32u16u1)
  writevu32u16(stpk,ret.crvu32u16u2)  
  stpk:w_u16(ret.killerid)
  writevu8u8(stpk,ret.game_death_time)

  updpk:w_float(ret.updhealth)
  updpk:w_s32(ret.upds32u1)
  updpk:w_u8(ret.updu8u2)
  updpk:w_float(ret.updpos.x)
  updpk:w_float(ret.updpos.y)
  updpk:w_float(ret.updpos.z)
  updpk:w_float(ret.updmodel)
  updpk:w_float(ret.upddir.x)
  updpk:w_float(ret.upddir.y)
  updpk:w_float(ret.upddir.z)
  updpk:w_u8(ret.updteam)
  updpk:w_u8(ret.updsquad)
  updpk:w_u8(ret.updgroup)
end

function parse_monster_packet(ret,stpk,updpk)
  parse_creature_packet(ret,stpk,updpk)
  ret.baseoutr=stpk:r_stringZ()
  ret.baseinr=stpk:r_stringZ()
  ret.smtrid=stpk:r_u16()
  ret.smtrtaskactive=stpk:r_u8()
  
  ret.updu16u1=updpk:r_u16()
  ret.updu16u2=updpk:r_u16()
  ret.upds32u3=updpk:r_s32()
  ret.upds32u4=updpk:r_s32()
  return ret
end

function fill_monster_packet(ret,stpk,updpk)
  fill_creature_packet(ret,stpk,updpk)
  stpk:w_stringZ(ret.baseoutr)
  stpk:w_stringZ(ret.baseinr)
  stpk:w_u16(ret.smtrid)
  stpk:w_u8(ret.smtrtaskactive)
  
  updpk:w_u16(ret.updu16u1)
  updpk:w_u16(ret.updu16u2)
  updpk:w_s32(ret.upds32u3)
  updpk:w_s32(ret.upds32u4)
end

function parse_trader_packet(ret,stpk,updpk)
  ret.money=stpk:r_s32()
  ret.profile=stpk:r_stringZ()
  ret.infammo=stpk:r_s32()
  ret.class=stpk:r_stringZ()
  ret.communityid=stpk:r_s32()
  ret.rank=stpk:r_s32()
  ret.reputation=stpk:r_s32()
  ret.charname=stpk:r_stringZ()  
  return ret
end

function fill_trader_packet(ret,stpk,updpk)
  stpk:w_s32(ret.money)
  stpk:w_stringZ(ret.profile)
  stpk:w_s32(ret.infammo)
  stpk:w_stringZ(ret.class)
  stpk:w_s32(ret.communityid)
  stpk:w_s32(ret.rank)
  stpk:w_s32(ret.reputation)
  stpk:w_stringZ(ret.charname)
end

function parse_human_packet(ret,stpk,updpk)
  parse_trader_packet(ret,stpk,updpk)
  parse_monster_packet(ret,stpk,updpk)
  ret.huvu32u8u1=readvu32u8(stpk)
  ret.huvu32u8u2=readvu32u8(stpk)  
  return ret
end

function fill_human_packet(ret,stpk,updpk)
  fill_trader_packet(ret,stpk,updpk)
  fill_monster_packet(ret,stpk,updpk)
  writevu32u8(stpk,ret.huvu32u8u1)
  writevu32u8(stpk,ret.huvu32u8u2)
end

function parse_skeleton_packet(ret,stpk,updpk)
  ret.skeleton=stpk:r_stringZ()
  ret.skeleton_flags=stpk:r_u8()
  ret.source_id=stpk:r_u16()
  
--  ret.updsku8u1=updpk:r_u8()
  return ret
end

function fill_skeleton_packet(ret,stpk,updpk)
  stpk:w_stringZ(ret.skeleton)
  stpk:w_u8(ret.skeleton_flags)
  stpk:w_u16(ret.source_id)
  
--  updpk:w_u8(ret.updsku8u1)
end

function parse_stalker_packet(ret,stpk,updpk,size)
  parse_human_packet(ret,stpk,updpk)
  parse_skeleton_packet(ret,stpk,updpk)
  ret.hellodlg=updpk:r_stringZ()
  ret.stunk1={}
  for i=stpk:r_tell(),size-1,1 do
    table.insert(ret.stunk1,stpk:r_u8())
  end
  return ret
end

function fill_stalker_packet(ret,stpk,updpk)
  fill_human_packet(ret,stpk,updpk)
  fill_skeleton_packet(ret,stpk,updpk)
  updpk:w_stringZ(ret.hellodlg)
  for i,v in ipairs(ret.stunk1) do
    stpk:w_u8(v)
  end
end

function parse_se_monster_packet(ret,stpk,updpk,size)
  parse_monster_packet(ret,stpk,updpk,size)
  parse_skeleton_packet(ret,stpk,updpk,size)
  ret.spec_obj_id=stpk:r_u16()
  ret.job_online=stpk:r_u8()
	if ret.job_online>3 then
		ret.state=true
		ret.job_online=ret.job_online-4
	else
		ret.state=false
	end
  if ret.job_online==3 then
    ret.job_online_condlist=stpk:r_stringZ()
  end
  ret.was_in_smtr=stpk:r_u8()
  ret.stunk1={}
  for i=stpk:r_tell(),size-1,1 do
    table.insert(ret.stunk1,stpk:r_u8())
  end
  return ret
end

function fill_se_monster_packet(ret,stpk,updpk)
  fill_monster_packet(ret,stpk,updpk)
  fill_skeleton_packet(ret,stpk,updpk)
  stpk:w_u16(ret.spec_obj_id)
	local st=0
	if ret.state then
		st=4
	end
  stpk:w_u8(ret.job_online+st)
  if ret.job_online==3 then
    stpk:w_stringZ(ret.job_online_condlist)
  end
  stpk:w_u8(ret.was_in_smtr)
  for i,v in ipairs(ret.stunk1) do
    stpk:w_u8(v)
  end  
end

function read_stalker_params(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local tbl=xrs_utils.parse_stalker_packet({},stpk,uppk,size)
  return tbl
end

function read_monster_params(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local tbl=xrs_utils.parse_se_monster_packet({},stpk,uppk,size)
  return tbl
end

-- таблица параметров и серверный объект на входе
function write_stalker_params(tbl,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  xrs_utils.fill_stalker_packet(tbl,stpk,uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

function write_monster_params(tbl,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  xrs_utils.fill_se_monster_packet(tbl,stpk,uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

function get_anomaly_data(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
	xrs_utils.parse_object_packet(t,stpk,uppk,size)
  xrs_utils.parse_shape_packet(t,stpk,uppk,size)

	t.restrictor_type = stpk:r_u8()
	
	t.max_power = stpk:r_float()
	t.owner_id = stpk:r_s32()
	t.enabled_time = stpk:r_s32()
	t.disabled_time = stpk:r_s32()
	t.start_time_shift = stpk:r_s32()
	
	t.offline_interactive_radius = stpk:r_float()
	t.artefact_spawn_count = stpk:r_u16()
	t.artefact_position_offset = stpk:r_s32()
	
	t.last_spawn_time_present = stpk:r_u8()
	
	if stpk:r_elapsed() ~= 0 then
	end
	return t
end

function set_anomaly_data(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
	
  xrs_utils.fill_object_packet(t,stpk,uppk)
  xrs_utils.fill_shape_packet(t,stpk,uppk)

	stpk:w_u8(t.restrictor_type)
	
	stpk:w_float(t.max_power)
	stpk:w_s32(t.owner_id)
	stpk:w_s32(t.enabled_time)
	stpk:w_s32(t.disabled_time)
	stpk:w_s32(t.start_time_shift)
	
	stpk:w_float(t.offline_interactive_radius)
	stpk:w_u16(t.artefact_spawn_count)
	stpk:w_s32(t.artefact_position_offset)
	
	stpk:w_u8(t.last_spawn_time_present)
	
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

function get_lc_data(obj)
	local packet = net_packet()
	obj:STATE_Write(packet)
	local t={}
	t.game_vertex_id = packet:r_u16()
	t.distance = packet:r_float()
	t.direct_control = packet:r_s32()
	t.level_vertex_id = packet:r_s32()
	t.object_flags = packet:r_s32()
	t.custom_data = packet:r_stringZ()
	t.story_id = packet:r_s32()
	t.spawn_story_id = packet:r_s32()
	
	t = xrs_utils.parse_shape_packet(t,packet)
	
	t.restrictor_type = packet:r_u8()
	t.dest_game_vertex_id = packet:r_u16()
	t.dest_level_vertex_id = packet:r_s32()
	t.dest_position = packet:r_vec3()
	t.dest_direction = packet:r_vec3()
	t.dest_level_name = packet:r_stringZ()
	t.dest_graph_point = packet:r_stringZ()
	t.silent_mode = packet:r_u8()

	if packet:r_elapsed() ~= 0 then
		abort("left=%d", packet:r_elapsed())
	end
	return t
end

function set_lc_data(t,obj)
	local packet = net_packet()
	obj:STATE_Write(packet)
	packet:w_begin(t.game_vertex_id)
	packet:w_float(t.distance)
	packet:w_s32(t.direct_control)
	packet:w_s32(t.level_vertex_id)
	packet:w_s32(t.object_flags)
	packet:w_stringZ(t.custom_data)
	packet:w_s32(t.story_id)
	packet:w_s32(t.spawn_story_id)
	
	xrs_utils.fill_shape_packet(t,packet)

	packet:w_u8(t.restrictor_type)
	packet:w_u16(t.dest_game_vertex_id)
	packet:w_s32(t.dest_level_vertex_id)
	packet:w_vec3(t.dest_position)
	packet:w_vec3(t.dest_direction)
	packet:w_stringZ(t.dest_level_name)
	packet:w_stringZ(t.dest_graph_point)
	packet:w_u8(t.silent_mode)

	packet:r_seek(0)
	obj:STATE_Read(packet, packet:w_tell())
end

function parse_object_physic_packet(ret,stpk,updpk)
	ret.physic_type=stpk:r_s32()
	ret.mass=stpk:r_float()
	ret.fixed_bones=stpk:r_stringZ()
  return ret
end

function fill_object_physic_packet(ret,stpk,updpk)
	stpk:w_s32(ret.physic_type)
	stpk:w_float(ret.mass)
	stpk:w_stringZ(ret.fixed_bones)
end

function get_breakable_data(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
	xrs_utils.parse_object_packet(t,stpk,uppk,size)
  xrs_utils.parse_visual_packet(t,stpk,uppk,size)
  xrs_utils.parse_object_physic_packet(t,stpk,uppk,size)
  return t
end

function set_breakable_data(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
	
  xrs_utils.fill_object_packet(t,stpk,uppk)
  xrs_utils.fill_visual_packet(t,stpk,uppk)
  xrs_utils.fill_object_physic_packet(t,stpk,uppk)
	
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

function get_spawner_data(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
	xrs_utils.parse_object_packet(t,stpk,uppk,size)
  xrs_utils.parse_shape_packet(t,stpk,uppk,size)
	
	t.restrictor_type = stpk:r_u8()
	t.spawned_obj_count = stpk:r_u8()
  return t
end

function set_spawner_data(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
	
  xrs_utils.fill_object_packet(t,stpk,uppk)
  xrs_utils.fill_shape_packet(t,stpk,uppk)
	stpk:w_u8(t.restrictor_type)
	stpk:w_u8(t.spawned_obj_count)
	
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

function parse_shape_packet(t,stpk,uppk)
	local shape_count = stpk:r_u8()
	t.shapes={}
	for i=1,shape_count do
		local shape_type = stpk:r_u8()
		t.shapes[i]={}
		t.shapes[i].shtype=shape_type
		if shape_type == 0 then
			-- sphere
			t.shapes[i].center = stpk:r_vec3()
			t.shapes[i].radius = stpk:r_float()
		else
			-- box
			t.shapes[i].v1 = stpk:r_vec3()
			t.shapes[i].v2 = stpk:r_vec3()
			t.shapes[i].v3 = stpk:r_vec3()
			t.shapes[i].offset = stpk:r_vec3()
		end
	end
end

function fill_shape_packet(t,stpk,updpk)
	stpk:w_u8(table.getn(t.shapes))
	for i=1,table.getn(t.shapes) do
		stpk:w_u8(t.shapes[i].shtype)
		if t.shapes[i].shtype == 0 then
			stpk:w_vec3(t.shapes[i].center)
			stpk:w_float(t.shapes[i].radius)
		else
			stpk:w_vec3(t.shapes[i].v1)
			stpk:w_vec3(t.shapes[i].v2)
			stpk:w_vec3(t.shapes[i].v3)
			stpk:w_vec3(t.shapes[i].offset)
		end
	end
end

function get_restrictor_data(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
	xrs_utils.parse_object_packet(t,stpk,uppk,size)
  xrs_utils.parse_shape_packet(t,stpk,uppk,size)
	
	t.restrictor_type = stpk:r_u8()
  return t
end

function set_restrictor_data(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
	
  xrs_utils.fill_object_packet(t,stpk,uppk)
  xrs_utils.fill_shape_packet(t,stpk,uppk)
	stpk:w_u8(t.restrictor_type)
	
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

function get_trader_data(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
	xrs_utils.parse_object_packet(t,stpk,uppk,size)
  xrs_utils.parse_visual_packet(t,stpk,uppk,size)
  xrs_utils.parse_trader_packet(t,stpk,uppk,size)
  return t
end

function set_trader_data(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
	
  xrs_utils.fill_object_packet(t,stpk,uppk)
  xrs_utils.fill_visual_packet(t,stpk,uppk)
  xrs_utils.fill_trader_packet(t,stpk,uppk)
	
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

function get_invbox_data(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
	xrs_utils.parse_object_packet(t,stpk,uppk,size)
  xrs_utils.parse_visual_packet(t,stpk,uppk,size)
  return t
end

function set_invbox_data(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
	
  xrs_utils.fill_object_packet(t,stpk,uppk)
  xrs_utils.fill_visual_packet(t,stpk,uppk)
	
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

function readvu8uN(packet,n)
  local v={}
  for i=1,n,1 do
    table.insert(v,packet:r_u8())
  end
  return v
end

function writevu8uN(pk,v)
  local len=table.getn(v)
  for i=1,len,1 do
    pk:w_u8(v[i])
  end
end

function parse_item_packet(ret,stpk,updpk)
	ret.condition=stpk:r_float()
	ret.updnum_items=updpk:r_u8()
  ret.updpos={} 
  ret.updpos.x=updpk:r_float()
  ret.updpos.y=updpk:r_float()
  ret.updpos.z=updpk:r_float()
	ret.updcse_alife_item__unk1_q8v4=readvu8uN(updpk,4)
	ret.updcse_alife_item__unk2_q8v3=readvu8uN(updpk,3)
	ret.updcse_alife_item__unk3_q8v3=readvu8uN(updpk,3)
  return ret
end

function fill_item_packet(ret,stpk,updpk)
	stpk:w_float(ret.condition)
	updpk:w_u8(ret.updnum_items)
  updpk:w_float(ret.updpos.x)
  updpk:w_float(ret.updpos.y)
  updpk:w_float(ret.updpos.z)
	writevu8uN(updpk,ret.updcse_alife_item__unk1_q8v4)
	writevu8uN(updpk,ret.updcse_alife_item__unk2_q8v3)
	writevu8uN(updpk,ret.updcse_alife_item__unk3_q8v3)
  return ret
end

function parse_item_ammo_packet(ret,stpk,updpk)
	ret.ammo_left=stpk:r_u16()
	ret.updammo_left=updpk:r_u16()
  return ret
end

function fill_item_ammo_packet(ret,stpk,updpk)
	stpk:w_u16(ret.ammo_left)
	updpk:w_u16(ret.updammo_left)
  return ret
end

function get_ammo_params(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
	xrs_utils.parse_object_packet(t,stpk,uppk,size)
  xrs_utils.parse_visual_packet(t,stpk,uppk,size)
  xrs_utils.parse_item_packet(t,stpk,uppk,size)
  xrs_utils.parse_item_ammo_packet(t,stpk,uppk,size)
  return t
end

function set_ammo_data(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
	
  xrs_utils.fill_object_packet(t,stpk,uppk)
  xrs_utils.fill_visual_packet(t,stpk,uppk)
  xrs_utils.fill_item_packet(t,stpk,uppk)
  xrs_utils.fill_item_ammo_packet(t,stpk,uppk)
	
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

function get_destroyable_data(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
	xrs_utils.parse_object_packet(t,stpk,uppk,size)
  xrs_utils.parse_visual_packet(t,stpk,uppk,size)
  xrs_utils.parse_skeleton_packet(t,stpk,uppk,size)
  xrs_utils.parse_object_physic_packet(t,stpk,uppk,size)
  return t
end

function set_destroyable_data(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
	
  xrs_utils.fill_object_packet(t,stpk,uppk)
  xrs_utils.fill_visual_packet(t,stpk,uppk)
  xrs_utils.fill_skeleton_packet(t,stpk,uppk)
  xrs_utils.fill_object_physic_packet(t,stpk,uppk)
	
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)

end

function get_weapon_data(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
  xrs_utils.parse_object_packet(t,stpk,uppk,size)
  xrs_utils.parse_visual_packet(t,stpk,uppk,size)
  xrs_utils.parse_item_packet(t,stpk,uppk,size)
  xrs_utils.parse_item_weapon_packet(t,stpk,uppk,size)
  return t
end

function set_weapon_data(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
	
  xrs_utils.fill_object_packet(t,stpk,uppk)
  xrs_utils.fill_visual_packet(t,stpk,uppk)
  xrs_utils.fill_item_packet(t,stpk,uppk)
  xrs_utils.fill_item_weapon_packet(t,stpk,uppk)
	
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)

end

function parse_item_weapon_packet(ret,stpk,updpk)
	ret.ammo_current = stpk:r_u16()
	ret.ammo_elapsed = stpk:r_u16()
	ret.weapon_state = stpk:r_u8()
	ret.addon_flags = stpk:r_u8()
	ret.ammo_type = stpk:r_u8()
	
	ret.updcondition = updpk:r_u8()
	ret.updweapon_flags = updpk:r_u8()
	ret.updammo_elapsed = updpk:r_u16()
	ret.updaddon_flags = updpk:r_u8()
	ret.updammo_type = updpk:r_u8()
	ret.updweapon_state = updpk:r_u8()
	ret.updweapon_zoom = updpk:r_u8()
	ret.updcurrent_fire_mode = updpk:r_u8()
  return ret
end

function fill_item_weapon_packet(ret,stpk,updpk)
	stpk:w_u16(ret.ammo_current)
	stpk:w_u16(ret.ammo_elapsed)
	stpk:w_u8(ret.weapon_state)
	stpk:w_u8(ret.addon_flags)
	stpk:w_u8(ret.ammo_type)
	
	updpk:w_u8(ret.updcondition)
	updpk:w_u8(ret.updweapon_flags)
	updpk:w_u16(ret.updammo_elapsed)
	updpk:w_u8(ret.updaddon_flags)
	updpk:w_u8(ret.updammo_type)
	updpk:w_u8(ret.updweapon_state)
	updpk:w_u8(ret.updweapon_zoom)
	updpk:w_u8(ret.updcurrent_fire_mode)
  return ret
end

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

function parse_ini_section_to_array(ini,section)
	local tmp={}
	if ini:section_exist(section) then
		local result, id, value = nil, nil, nil
		for a=0,ini:line_count(section)-1 do
			result, id, value = ini:r_line(section,a,"","")
			if id~=nil and trim(id)~="" and trim(id)~=nil then
				tmp[trim(id)]=trim(value)
			end
		end
	else
		mylog("no such section")
	end
	return tmp
end

function str_explode(div,str,clear)
	local t={}
	local cpt = string.find (str, div, 1, true)
	if cpt then
		repeat
			if clear then
				table.insert( t, trim(string.sub(str, 1, cpt-1)) )
			else
				table.insert( t, string.sub(str, 1, cpt-1) )
			end
			str = string.sub( str, cpt+string.len(div) )
			cpt = string.find (str, div, 1, true)
		until cpt==nil
	end
	if clear then
		table.insert(t, trim(str))
	else
		table.insert(t, str)
	end
	return t
end

function quotemeta(str)
	return (string.gsub(s, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%1"))
end

--для правильного парсинга запрещены комментарии!!!
function parse_custom_data(str)
	local t={}
	if str then
		for section, section_data in string.gfind(str,"%s*%[([^%]]*)%]%s*([^%[%z]*)%s*") do
			section = trim(section)
			t[section]={}
			for line in string.gfind(trim(section_data), "([^\n]*)\n*") do
				if string.find(line,"=")~=nil then
					for k, v in string.gfind(line, "([^=]-)%s*=%s*(.*)") do
						k = trim(k)
						if k~=nil and k~='' and v~=nil then 
							t[section][k]=trim(v) 
						end
					end
				else
					for k, v in string.gfind(line, "(.*)") do
						k = trim(k)
						if k~=nil and k~='' then
							t[section][k]="<<no_value>>" 
						end
					end
				end
			end
		end
	end
	return t
end

function trim (s)
	return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end

function gen_custom_data(tbl)
	local str=''
	for key, value in pairs(tbl) do
		str = str.."\n["..key.."]\n"
		for k, v in pairs(value) do
			if v~="<<no_value>>" then
				str=str..k.." = "..v.."\n"
			else
				str=str..k.."\n"
			end
		end
	end
	return str
end 

function dump_table(tbl)
  for k,v in pairs(tbl) do
    if type(v)=="table" then
      get_console():execute("load ~~~ "..tostring(k).." => ")
      dump_table(v)
    else
      str="load ~~~ "..tostring(k).." => "..tostring(v)
      if string.len(str)>200 then
        str=string.sub(str,1,200)
      end
      get_console():execute(str)
    end
  end
  get_console():execute("flush")
end

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

local bufferedmessages={}

function mylog(msg)
  --if is_debug then 
	  if msg==nil then
	    return 
	  end
	  if db and db.actor then
	    if bufferedmessages then
	      for k,v in ipairs(bufferedmessages) do
	        db.actor:give_game_news(v, "ui\\ui_iconsTotal", Frect():set(0,658,83,47), 0, 15000)
	      end
	      bufferedmessages=nil
	    end
	  db.actor:give_game_news(msg, "ui\\ui_iconsTotal", Frect():set(0,658,83,47), 0, 15000)
	  else
	    if bufferedmessages then
	      table.insert(bufferedmessages,msg)
	    end
	  end

	  if get_console() then
	    get_console():execute("load ~~~ "..string.sub(msg,1,200))
	    get_console():execute("flush")
	  end

	--end
end

