summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2023-06-18 03:31:03 +0100
committerubq323 <ubq323@ubq323.website>2023-06-18 03:31:03 +0100
commit1490cf19a950d99b045fe68d7151a6cd54c57e27 (patch)
treec05a14cd80f8ff2623da0e47cc274ba85b6d96d1
parentd5e264125994b6e5943ffb42f607362b3e79bcba (diff)
add handshaking system, and refactor server a bit
-rw-r--r--client/game.lua8
-rw-r--r--server/player.lua6
-rw-r--r--server/server.lua152
3 files changed, 109 insertions, 57 deletions
diff --git a/client/game.lua b/client/game.lua
index 50b74f9..31e02b8 100644
--- a/client/game.lua
+++ b/client/game.lua
@@ -342,12 +342,16 @@ local function draw()
end
local connected = false
+local sent_hshake = false
function SCENE.update(dt)
if connected then
return update(dt)
else
handle_net()
- if peer:state() == "connected" and local_player then
+ if peer:state() == "connected" and not sent_hshake then
+ peer:send(json.encode{t='handshake',username=username})
+ sent_hshake = true
+ elseif peer:state() == "connected" and local_player then
connected = true
msgbox.add("connected to "..SERVER_HOSTNAME..":8473")
msgbox.add("press F1 for controls help")
@@ -363,7 +367,7 @@ function SCENE.draw()
end
end
-function SCENE.load()
+function SCENE.load(username)
love.keyboard.setKeyRepeat(true)
-- require"profile".start(10,io.open("./trace","w"))
host = enet.host_create()
diff --git a/server/player.lua b/server/player.lua
index 365eadc..bd7b52a 100644
--- a/server/player.lua
+++ b/server/player.lua
@@ -8,23 +8,25 @@ local function random_color()
end
local Player = class()
-function Player.make(cls,peer)
+function Player.make(cls,peer,username)
local self = {
pos = Pos:make(0,0),
color = random_color(),
peer = peer,
id = nextid,
+ username = username,
}
nextid = nextid + 1
return setmetatable(self,cls)
end
function Player.info_part(self)
- -- eh
+ -- eh
return {
id=self.id,
x=self.pos.x,
y=self.pos.y,
color=self.color,
+ username=self.username,
}
end
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