All pastes #552274 Raw Edit

jlulian38

public lua v1 · immutable
·published 2007-06-09 06:16 UTC
rendered paste body
--Server --No shared for brevity so we have to rethrow crap in.--ConstantsFLG_NEWSTREAM = 0FLG_DATA = 1TYP_NUM = 105TYP_STR = 106TYP_PTR = 107MAX_STR = 128--Variablesstream = {}streamc = {}filter = {}streams = {}function Stream(name,scp)	local strm = startStream(name)	table.insert(scp.strmindex,name)	for _,v in pairs(scp:GetPlayers())		strm:AddStream(startStreamPlayer(name,v))	end	strm.queue = {}	return strmendfunction StreamAdd(name,ply)	streams[name]:AddStream(ply)	for k,v in pairs(self.queue) do		streams[name]:Queue(v)	endendfunction startStream(name)	--this is a container	for k,v in pairs(streamc) do o[k]=v end	o.streams = {} --individual player streamsendfunction streamc:AddStream(strm)	table.insert(self.streams,strm)endfunction streamc:Run()	for _,v in pairs(self.streams) do		v:Run()	endendfunction startStreamPlayer(name,ply) 	local o = {}	--really dumb way to do this	for k,v in pairs(stream) do o[k]=v end	o.data = {} --holds local copy of data.	o.sync = {} --holds sync info (what to send etc etc)	o.name = name --stream name	o.rcp = RecipientFilter()	o.rcp:AddPlayer(ply)	o.wait = 10	o:Start()	return o;endfunction streamFilter()	return filter:New()endfunction stream:Start()	--notifies client of new stream (internal)	self:Send(FLG_NEWSTREAM,self.name,TYP_PTR)endfunction stream:Send(flag,name,typ,id,pid,data)	id = id or #self.data	pid = pid or 0	umsg.Start("stream_umsg")		umsg.Short(flag)		umsg.String(name)		umsg.Short(id)		umsg.Short(pid)		if (typ == TYP_NUM) then			umsg.Long(data)		elseif (typ = TYP_STR)			umsg.String(data)		end --num,string or nothing (pointer)	umsg.End()endfunction streamc:Queue(name,data,pid)	local typ = type(data)	local pid = pid or 0	if (typ == "number") then		table.insert(self.queue,{typ=TYP_NUM,data=data,pid=pid})		local id = #self.queue		local tab = self.queue[id]		tab.id=id		tab.pid=pid		tab.name=name	elseif (typ == "table") then		table.insert(self.queue,{typ=TYP_PRT_TAB,id=#self.queue+1,pid=pid})		self:TableParse(data,#self.queue) 	elseif (typ == "string") then		if #data > MAX_STR then			table.insert(self.queue,{typ=TYP_PRT_STR,id=#self.queue+1,pid=pid})			local sid = #self.queue			while (true) do				if #data > MAX_STR then					local addStr=data:sub(0,127)					data = data:gsub(addStr,'')					self:Queue("",addStr,sid)				else					break				end			end		else			table.insert(self.queue,{typ=TYP_STR,id=#self.queue+1,pid=pid})		end	endendfunction streamc:TableParse(t, tid)	for i,v in pairs(t) do		self:Queue(i,v,tid)	endendfunction stream:Run()	if not self.hook then self.hook = 0 end	self.hook = self.hook + 1	if self.hook > self.wait then		--do stream code here.	endendfunction filter:New()	local o = {}	for k,v in pairs(filter) do o[k]=v end	o.strmindex = {}	o.players = {}	o.playerhook = function (ply) if self.all then self:AddPlayer(ply) for k,v in pairs(self.strmindex) StreamAdd(v,ply) end end end	hook.Add("PlayerInitialSpawn","weird thing"..math.random(1,10000),o.playerhook)	return oendfunction filter:AddPlayer(ply)	table.insert(self.players,ply)endfunction filter:AddAllPlayers(ply)	self.all = true -- we're sending to all make sure of that	local a = player.GetAll()	for _,v in pairs(a) do		self:AddPlayer(v)	endendfunction filter:GetPlayers()	return self.playersendfunction streamHook()	for _,v in pairs(streams) do		stream:Run()	endendhook.Add("Think","server side stream hook",streamHook)--Client--No shared for brevity so we have to rethrow crap in.--ConstantsFLG_NEWSTREAM = 0 FLG_DATA = 1 --Data is being sentTYP_NUM = 105TYP_STR = 106TYP_PTR_STR = 107TYP_PTR_TAB = 107--Variablesstream = {}strTable = {} --holds all streams.function streamHook(data)	--shorts are friggen long, I was hoping for like flag passing, this could do fuckin' math.		local flags = data:ReadShort() --first short, is ALWAYS, the flags.	local name = data:ReadString() --first string is the 	if (flags == FLG_NEWSTREAM) then		stream:New(name)	elseif (flags == FLG_DATA) then		local sndtype = data:ReadShort() --second short is type		local sndid = data:ReadLong() --first long is this ones id		local sndpid = data:ReadLong() --2nd long is a pointer id (itself if not applicable)		local snddata		if (sndtype == TYP_NUM) then			snddata = data:ReadLong()		elseif (sndtype == TYP_STR) then			snddata = data:ReadString() --a part of a string probably		elseif (sndtype == TYP_PTR_STR or sndtype == TYP_PTR_TAB) then			snddata = true --PTR is a table or string (they're cut up into chunks)		end		--chuck all that into our function		strTable[name]:RecievePacket(name,sndtype,sndid,sndpid,snddata)	endendusermessage.Hook("stream_umsg",streamHook)function stream:New(name)	local o = {}	for k,v in paris(self) do o[k]=v end	o.queue = {}	o.data = {}	o.name = name	stream[name] = oendfunction stream:GetTable()	return self.dataendfunction stream:RecievePacket(name,stype,id,pid,data)	local tab = self.queue	if (pid ~= 0) then		if (tab[pid] ~= nil) then			if (tab[pid].type == TYP_PTR_TAB) then				tab = tab[pid].ptr			elseif (tab[pid].type == TYP_PTR_STR) then				self.data[tab[pid].ptr]=self.data[tab[pid].ptr]..data --gnarly line of code o_O				return			end	end	if (stype == TYP_PTR_TAB) then		tab[name] = {}		self.queue[id] = {}		self.queue[id].ptr = tab[name]		self.queue[id].type = stype	elseif (stype == TYP_PTR_STR) then		tab[name] = ""		self.queue[id] = {}		self.queue[id].ptr = 		self.queue[id].type = stype	end	if (tab ~= self.queue) then		tab = self.data --if we haven't changed to another table, change to self.data	end	tab[name]=data --short and sweet (finally)end