summaryrefslogtreecommitdiff
path: root/server/server.lua
diff options
context:
space:
mode:
Diffstat (limited to 'server/server.lua')
-rw-r--r--server/server.lua152
1 files changed, 99 insertions, 53 deletions
diff --git a/server/server.lua b/server/server.lua
index 701551d..5d17e5f 100644
--- a/server/server.lua
+++ b/server/server.lua
@@ -55,10 +55,18 @@ local map = MapS:make()
-local function on_player_connect(ev)
- local player = Player:make(ev.peer)
+
+
+-- set of peers currently within handshake procedure
+local connecting_peers = {}
+
+local function create_player(...)
+ -- advances connecting peer to player
+ local player = Player:make(...)
table.insert(playerlist, player)
+ connecting_peers[player.peer] = nil
+
player.peer:send(player_you_packet(player))
for i,otherplayer in ipairs(playerlist) do
@@ -71,64 +79,102 @@ local function on_player_connect(ev)
print("connect",player.id,player.peer)
end
-local function on_player_disconnect(ev)
- local player,idx = player_by_peer(ev.peer)
- if not player then error("sneeze"..ev.peer) end
- table.remove(playerlist,idx)
-
- for i,otherplayer in ipairs(playerlist) do
- otherplayer.peer:send(player_leave_packet(player))
+local function connecting_peer_ev()
+ local ev = coroutine.yield()
+ print("hello")
+ local j = json.decode(ev.data)
+ local op = j.t
+ if op == "handshake" then
+ print(ev,'handshake; username',j.username)
+ create_player(ev.peer,j.username)
+ else
+ error("weird handshake: "..op)
end
+end
+
- print("disconnect", player.id, player.peer)
+local function on_peer_connect(peer)
+ print("peer connect: ",peer)
+ local co = coroutine.create(connecting_peer_ev)
+ assert(coroutine.resume(co))
+ connecting_peers[peer] = co
end
-
-
-local function handle_ev(ev)
- -- handle network event
- if ev.type == "connect" then
- on_player_connect(ev)
- elseif ev.type == "disconnect" then
- on_player_disconnect(ev)
- 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)
- -- print(ev.channel,ev.data)
- local op = j.t
- if op == "ppos" then
- local x,y = j.x,j.y
- player.pos = coords.Pos:make(x,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),1)
- end
+
+local function on_peer_disconnect(peer)
+ print("peer disconnect: ",peer)
+ connecting_peers[peer] = nil
+ local player,idx = player_by_peer(peer)
+ if player then
+ table.remove(playerlist, idx)
+ for i,otherplayer in ipairs(playerlist) do
+ otherplayer.peer:send(player_leave_packet(player))
+ end
+ print("disconnect", player.id, player.peer)
+ end
+end
+
+local function handle_player_packet(player,ev)
+ print('player packet ',player,ev.data)
+ local j = json.decode(ev.data)
+ -- print(ev.channel,ev.data)
+ local op = j.t
+ if op == "ppos" then
+ local x,y = j.x,j.y
+ player.pos = coords.Pos:make(x,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),1)
end
- elseif op == "settile" then
- local h = coords.Hex:make(j.q,j.r)
- map: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
+ elseif op == "settile" then
+ local h = coords.Hex:make(j.q,j.r)
+ map: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
- elseif op == "reqchunk" then
- -- i am not certain this is the best way for this to work
- -- i might change it later
- local cp = coords.ChunkPos:make(j.u,j.v)
- local ch = map:obtain(cp)
- player.peer:send(ch:data_packet())
- elseif op == "chat" then
- print("chat ["..player.id.."] "..j.msg)
- for i,otherplayer in ipairs(playerlist) do
- otherplayer.peer:send(chat_packet(player,j.msg))
+ end
+ elseif op == "reqchunk" then
+ -- i am not certain this is the best way for this to work
+ -- i might change it later
+ local cp = coords.ChunkPos:make(j.u,j.v)
+ local ch = map:obtain(cp)
+ player.peer:send(ch:data_packet())
+ elseif op == "chat" then
+ print("chat ["..player.id.."] "..j.msg)
+ for i,otherplayer in ipairs(playerlist) do
+ otherplayer.peer:send(chat_packet(player,j.msg))
+ end
+ end
+end
+
+local function handle_ev(ev)
+ if ev.type == 'connect' then
+ on_peer_connect(ev.peer)
+ elseif ev.type == 'disconnect' then
+ on_peer_disconnect(ev.peer)
+ elseif ev.type == 'receive' then
+ print("recv:",ev.peer,ev.data)
+ if connecting_peers[ev.peer] then
+ local co = connecting_peers[ev.peer]
+ print("\t-> hshake",co,coroutine.status(co))
+ local ok,err = coroutine.resume(co, ev)
+ if not ok then
+ print("hshake error: ",ev.peer,err)
+ connecting_peers[ev.peer] = nil
+ ev.peer:disconnect_now()
end
+ else
+ local player = player_by_peer(ev.peer)
+ if not player then error("packet from unknown peer ",ev.peer) end
+ print("\t-> player",player)
+ handle_player_packet(player, ev)
end
end
end