summaryrefslogtreecommitdiff
path: root/server/server.lua
blob: ff3c3ebfbf576c99063e77e976e8b50e857b53ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
local enet = require"enet"
local json = require"common.dkjson"
local Chunk = require"common.chunk".Chunk
local unpack = unpack or table.unpack
local coords = require"common.coords"

math.randomseed(os.time())

local host = enet.host_create("*:8473")
print(host:get_socket_address())

-- sequential list of all players
local playerlist = {}
local nextid = 1

-- this is maybe suboptimal
-- but it is simplest for now
local function player_by_id(id)
	for i,pl in ipairs(playerlist) do
		if pl.id == id then return pl, i end
	end
	return nil
end
local function player_by_peer(peer)
	for i,pl in ipairs(playerlist) do
		if pl.peer == peer then return pl, i end
	end
	return nil
end

local function random_color()
	return {math.random(),math.random(),math.random()}
end
local function make_player(peer)
	local p = {pos={0,0},color=random_color(),peer=peer,id=nextid}
	nextid = nextid + 1
	return p
end

local function player_info_part(player)
	return {
		id=player.id,
		x=player.pos[1],
		y=player.pos[2],
		color=player.color,
	}
end
local function player_join_packet(player)
	return json.encode{t="join",pl=player_info_part(player)}
end
local function player_you_packet(player)
	return json.encode{t="you",pl=player_info_part(player)}
end
local function player_leave_packet(player)
	return json.encode{t="leave",id=player.id}
end
local function player_move_packet(player,x,y)
	return json.encode{t="move",id=player.id,x=x,y=y}
end

local the_chunk = Chunk.gen()

while true do
	local ev = host:service(100)
	if ev then
		if ev.type == "connect" then
			local player = make_player(ev.peer)
			table.insert(playerlist,player)
			print("connect",player.peer,player.id)
			player.peer:send(player_you_packet(player))
			player.peer:send(the_chunk:data_packet())

			for i,otherplayer in ipairs(playerlist) do
				if otherplayer ~= player then
					-- tell new player about each other player
					player.peer:send(player_join_packet(otherplayer))
					-- tell each other player about new player
					otherplayer.peer:send(player_join_packet(player))
				end
			end
		elseif ev.type == "disconnect" then
			local player, idx = player_by_peer(ev.peer)
			if not player then error("sneeze "..ev.peer) end
			print("disconnect",player.peer,player.id)
			table.remove(playerlist,idx)
			for i,otherplayer in ipairs(playerlist) do
				otherplayer.peer:send(player_leave_packet(player))
			end
		elseif ev.type == "receive" then
			local player = player_by_peer(ev.peer)
			if not player then error("sneezey "..ev.peer) end
			local j = json.decode(ev.data)
			local op = j.t
			if op == "ppos" then
				local x,y = j.x,j.y
				player.pos[1] = x
				player.pos[2] = y
				-- print(player.id,"-->",player.pos[1],player.pos[2])
				for i,otherplayer in ipairs(playerlist) do
					if otherplayer ~= player then
						otherplayer.peer:send(player_move_packet(player,x,y))
					end
				end
			elseif op == "settile" then
				local h = coords.Hex.make(j.q,j.r)
				the_chunk:set_at(h,j.tile)
				print(player.id,"settile",h,j.tile)
				for i,otherplayer in ipairs(playerlist) do
					if otherplayer ~= player then
						-- same packet structure s2c as c2s
						-- when multiple chunks exist and players only get info
						-- about stuff near to them, that won't be the case any more
						otherplayer.peer:send(ev.data)
					end
				end
			end

		end
		-- for k,v in pairs(ev) do io.write(tostring(k),":",tostring(v)," ") end
		-- print()
	end
end