diff options
| author | ubq323 <ubq323@ubq323.website> | 2025-06-05 16:07:47 +0100 | 
|---|---|---|
| committer | ubq323 <ubq323@ubq323.website> | 2025-06-05 16:07:47 +0100 | 
| commit | 36df301ce86d7689de0b20735feffee969927e47 (patch) | |
| tree | d61b6943ee5a9de497c0b6e9c713d2119fadf866 | |
| parent | ded2684211826c9585b1c6d9c1036e233b65fd86 (diff) | |
things
| -rw-r--r-- | client/conf.lua | 1 | ||||
| l--------- | server/common.lua | 1 | ||||
| -rw-r--r-- | server/server.lua | 91 | 
3 files changed, 64 insertions, 29 deletions
diff --git a/client/conf.lua b/client/conf.lua new file mode 100644 index 0000000..faccea9 --- /dev/null +++ b/client/conf.lua @@ -0,0 +1 @@ +function love.conf(t) t.window.msaa=8 end diff --git a/server/common.lua b/server/common.lua new file mode 120000 index 0000000..a79312a --- /dev/null +++ b/server/common.lua @@ -0,0 +1 @@ +../common.lua
\ No newline at end of file diff --git a/server/server.lua b/server/server.lua index fa7f82f..d441989 100644 --- a/server/server.lua +++ b/server/server.lua @@ -4,52 +4,85 @@ local json = require'dkjson'  local Pos = require'r.pos'  local pairs_except = require'r.pairs_except'  local class = require'r.class' +local rle = require'r.rle' +local common = require 'common'  local host = enet.host_create('*:19683') +local n = 0 local function next_name() n=n+1  return 'helen'..n end -local n = 0 -local function next_name() n=n+1  return 'helen'..n end +local chunks = common.ChunkMap() +local Chunk = class() +function Chunk.make(cls, cp, d) local self = setmetatable({cp=cp,d=d},cls) +	chunks:add(cp,self) return self end +function Chunk.generate(cls,cp) +	print('\t','generating',cp) +	local d={} for i=1,common.SIZE^2 do d[i] = 1 == math.random(3) end +	return cls(cp,d) end +function Chunk.packet(self) +	return json.encode{ pos=self.cp, d=rle.encode(self.d), type='chunk' } end +local function filename(cp) return 'chunk'..cp:key()..'.json' end +function Chunk.load(cls, cp) local f = io.open(filename(cp),'r') +	if not f then return nil end  local j = json.decode(assert(f:read"a")) +	f:close()  return cls(cp,rle.decode(j.d)) end +function Chunk.save(self) local f = io.open(filename(self.cp),'w') +	assert(f:write(json.encode{d=rle.encode(self.d)})) f:close() end +function Chunk.obtain(cls,cp) +	if chunks:get(cp) then return chunks:get(cp) end +	local ch = cls:load(cp)  if ch then return ch end +	return cls:generate(cp) end  local Player = class()  function Player.make(cls, obj) return setmetatable(obj,cls) end -function Player.packet(self,packet_type) return json.encode     { -	name=self.name, x=self.pos.x, y=self.pos.y, type=packet_type } end - -local size = 64 -local chunk = {} -for i=1,size*size do chunk[i] = 1 == math.random(3) end -function chunk.packet(self,packet_type) -	local r = {type=packet_type,d={}}  for i,t in ipairs(self) do r.d[i]=t end -	return json.encode(r) end - +function Player.packet(self,packet_type) +	return json.encode { name=self.name, pos=self.pos, type=packet_type } end  local players = {}  local function find_player(arg) local k,v = next(arg)  	for pl in pairs(players) do if pl[k] == v then return pl end end end  local function other_players(player) return pairs_except(players, player) end -  local function send_others(player,data)  	data.from = player.name   local packet = json.encode(data)  	for player2 in other_players(player) do player2.peer:send(packet) end end  local function greet(player) +	print('greeting',player.name,player.peer)  	for player2 in other_players(player) do  		player.peer:send(player2:packet'player') -		player2.peer:send(player:packet'player') end -	player.peer:send(chunk:packet'chunk')        end +		player2.peer:send(player:packet'player') end end + +local function doctor_chunks() +	for player in pairs(players) do +		local pcp = player.pos:divmod(common.SIZE) +		for dx = -1,1 do for dy = -1,1 do local cp = pcp+Pos(dx,dy) +			if not player.loaded[cp:key()] then +				local chunk = Chunk:obtain(cp) +				player.peer:send(chunk:packet()) +				player.loaded[cp:key()] = true end end end +		for lcpk in pairs(player.loaded) do local lcp = Pos:unkey(lcpk) +			if (lcp-pcp):linf() > 2 then +				player.peer:send(json.encode{type='unchunk',pos=lcp}) +				player.loaded[lcp:key()] = nil end end end +	for k,chunk in pairs(chunks.d) do local cp = Pos:unkey(k) +		local used = false +		for player in pairs(players) do if player.loaded[k] then used=true end end +		if not used then print('unloading',cp) chunk:save() chunks:remove(cp) end end end -while true do  local ev = host:service(100)  if ev then -	local peer = ev.peer  local player = find_player{peer=peer} -	if ev.type=='connect' then -		print('connecting',peer) -		local player = Player{pos=Pos(0,0), peer=peer, name=next_name()} -		players[player] = true;  greet(player) -	elseif ev.type=='disconnect' then -		print('disconnecting',peer) -		send_others(player, {type='unplayer'}) -		players[player] = nil  -	else local j = json.decode(ev.data) -		-- todo handle json error -		if j.type == 'move' then player.pos=Pos(j.x,j.y)  send_others(player, j) +while true do +	local ev = host:service(100)  if ev then +		local peer = ev.peer  local player = find_player{peer=peer} +		if ev.type=='connect' then +			print('connecting',peer) +			local player = Player{pos=Pos(0,0), peer=peer, name=next_name(), loaded={}} +			players[player] = true;  greet(player) +		elseif ev.type=='disconnect' then +			print('disconnecting',peer) +			send_others(player, {type='unplayer'}) +			players[player] = nil  +		elseif ev.type=='receive' then local j = json.decode(ev.data) +			local pos  if j.pos then pos = Pos(j.pos.x,j.pos.y) end +				if j.type == 'move' then player.pos=pos send_others(player, j) +			elseif j.type == 'tile' then print('tile',pos,j.tile) chunks:set_tile(pos,j.tile) send_others(player,j) +			end  		end  	end -end end +	doctor_chunks() +end  | 
