summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLizzy Fleckenstein <lizzy@vlhl.dev>2026-06-08 20:00:53 +0200
committerLizzy Fleckenstein <lizzy@vlhl.dev>2026-06-08 20:07:54 +0200
commit2f53f7d8ee25acb45b45c31f58777b100112378d (patch)
tree8221a5b7e253bfb6ebd0e3c45add614ae7c1fa04
parent3d15c2db5d02aed71ee4f76f07e806e6d2f4c231 (diff)
downloadr6p-2f53f7d8ee25acb45b45c31f58777b100112378d.tar.xz
consider local addresses as candidates for connecting to server
-rw-r--r--client.lua39
-rw-r--r--common.lua4
-rw-r--r--main.lua1
-rwxr-xr-xmatchsrv.lua39
-rw-r--r--server.lua18
-rw-r--r--util.lua6
6 files changed, 82 insertions, 25 deletions
diff --git a/client.lua b/client.lua
index 30f886d..61fe8c2 100644
--- a/client.lua
+++ b/client.lua
@@ -12,12 +12,22 @@ local function create_client(secret)
return clt
end
-local function connect(clt, addr)
- clt.server = clt.host:connect(addr)
+local function connect(clt, addrs)
+ clt.server_candidates = {}
+ for _, addr in ipairs(addrs) do
+ clt.server_candidates[clt.host:connect(addr)] = true
+ end
clt.server_req = socket.gettime()
clt.status = "wait_server"
end
+local function remove_candidates(clt)
+ for s in pairs(clt.server_candidates) do
+ s:disconnect()
+ end
+ clt.server_candidates = nil
+end
+
function client.join(invite, match_addr)
local invite_dec = util.base64_dec(invite)
if not invite_dec then
@@ -38,17 +48,24 @@ end
function client.connect(addr, secret)
local clt = create_client(secret)
- connect(clt, addr)
+ connect(clt, { addr })
return clt
end
local function handle_match(clt, pkt)
if pkt.type == "client_join" then
- if type(pkt.peer_addr) ~= "string" then
- print("[client] client_join: invalid peer_addr")
+ if type(pkt.candidates) ~= "table" then
+ print("[client] client_join: invalid candidates")
return
end
- connect(clt, pkt.peer_addr)
+ for _, c in ipairs(pkt.candidates) do
+ if type(c) ~= "string" then
+ print("[client] client_join: invalid candidates")
+ return
+ end
+ end
+
+ connect(clt, pkt.candidates)
elseif pkt.type == "client_join_fail" then
clt.status = "fail_match"
end
@@ -83,17 +100,20 @@ function client.update(clt)
end
end
elseif event.type == "connect" then
- if event.peer == clt.match and clt.status == "wait_match" then
+ if clt.status == "wait_match" and event.peer == clt.match then
util.send(clt.match, { type = "match_join", game_id = util.base64_enc(clt.game_id) })
- elseif event.peer == clt.server and clt.status == "wait_server" then
+ elseif clt.status == "wait_server" and clt.server_candidates[event.peer] then
+ clt.server = event.peer
+ clt.server_candidates[clt.server] = nil
util.send(clt.server, { type = "server_hi", secret = util.base64_enc(clt.secret) })
+ remove_candidates(clt)
else
event.peer:disconnect_now()
end
print("[client] connect " .. tostring(event.peer))
elseif event.type == "disconnect" then
print("[client] disconnect " .. tostring(event.peer))
- if event.peer == clt.server and clt.status == "active" then
+ if event.peer == clt.server then
clt.status = "disco"
end
end
@@ -122,6 +142,7 @@ end
function client.close(clt)
if clt.match then clt.match:disconnect() end
if clt.server then clt.server:disconnect() end
+ if clt.server_candidates then remove_candidates(clt) end
clt.host:flush()
clt.host:destroy()
end
diff --git a/common.lua b/common.lua
index 6a04d0f..98268ab 100644
--- a/common.lua
+++ b/common.lua
@@ -1,5 +1,9 @@
return {
default_match_addr = "ivy.vlhl.dev:18252",
+ -- any public IP address (in this case: ivy.vlhl.dev)
+ -- this address is not pinged or connected to
+ -- used to look up our own local ip address
+ route_lookup_target = "94.16.117.28",
gameid_len = 8,
secret_len = 4,
}
diff --git a/main.lua b/main.lua
index 30f21a5..a5dd579 100644
--- a/main.lua
+++ b/main.lua
@@ -73,6 +73,7 @@ local function start_server(save)
else
srv = s
end
+ show(dialog.loading, "Registering game...")
end
local function create_save(save)
diff --git a/matchsrv.lua b/matchsrv.lua
index 315573c..a8ae92e 100755
--- a/matchsrv.lua
+++ b/matchsrv.lua
@@ -5,33 +5,44 @@ local common = require("common")
local host = enet.host_create("0.0.0.0:18252")
-local game_to_peer = {}
-local peer_to_game = {}
+local games_by_id = {}
+local games_by_peer = {}
local function remove_game(peer)
- local game = peer_to_game[peer]
+ local game = games_by_peer[peer]
if game then
- game_to_peer[game] = nil
- peer_to_game[peer] = nil
+ games_by_id[game.id] = nil
+ games_by_peer[game.peer] = nil
end
end
local function handle(peer, pkt)
if pkt.type == "match_register" then
+ if pkt.candidates ~= nil and type(pkt.candidates) ~= "table" then
+ return
+ end
+
+ local game = {
+ peer = peer,
+ id = util.rand_string(common.gameid_len),
+ candidates = pkt.candidates or {},
+ }
+ table.insert(game.candidates, tostring(peer))
+
remove_game(peer)
- local game_id = util.rand_string(common.gameid_len)
- peer_to_game[peer] = game_id
- game_to_peer[game_id] = peer
- util.send(peer, { type = "server_match", game_id = util.base64_enc(game_id) })
+ games_by_peer[game.peer] = game
+ games_by_id[game.id] = game
+
+ util.send(peer, { type = "server_match", game_id = util.base64_enc(game.id) })
print(peer, "registered game")
elseif pkt.type == "match_join" then
local game_id = type(pkt.game_id) == "string" and util.base64_dec(pkt.game_id)
if game_id then
- local server = game_id and game_to_peer[game_id]
- if server then
- util.send(server, { type = "server_join", peer_addr = tostring(peer) })
- util.send(peer, { type = "client_join", peer_addr = tostring(server) })
- print(peer, "joined game", server)
+ local game = games_by_id[game_id]
+ if game then
+ util.send(game.peer, { type = "server_join", peer_addr = tostring(peer) })
+ util.send(peer, { type = "client_join", peer_addr = tostring(game.peer), candidates = game.candidates })
+ print(peer, "joined game", game.peer)
else
util.send(peer, { type = "client_join_fail" })
print(peer, "failed to join game")
diff --git a/server.lua b/server.lua
index 8d85dcd..a51564c 100644
--- a/server.lua
+++ b/server.lua
@@ -3,9 +3,18 @@ local socket = require("socket")
local util = require("util")
local common = require("common")
local save_file = require("save_file")
+local socket = require("socket")
local server = {}
+local function get_local_ip()
+ local sock = socket.udp()
+ sock:setpeername(common.route_lookup_target, 1024)
+ local ip = sock:getsockname()
+ sock:close()
+ return ip
+end
+
local function migrate_save(save)
save.players = save.players or {}
end
@@ -108,7 +117,11 @@ function server.create(filename, match_addr)
end
function server.port(srv)
- return srv.host:get_socket_address():match(":([^:]*)$")
+ return util.split_addr(srv.host:get_socket_address()).port
+end
+
+function server.local_addr(srv)
+ return get_local_ip() .. ":" .. server.port(srv)
end
local function handle_match(srv, pkt)
@@ -214,7 +227,8 @@ function server.update(srv, wait)
end
elseif event.type == "connect" then
if event.peer == srv.match then
- util.send(srv.match, { type = "match_register" })
+ util.send(srv.match, { type = "match_register",
+ candidates = { server.local_addr(srv) } })
end
print("[server] connect " .. tostring(event.peer))
elseif event.type == "disconnect" then
diff --git a/util.lua b/util.lua
index dda250e..8eab1db 100644
--- a/util.lua
+++ b/util.lua
@@ -39,6 +39,11 @@ else
end
end
+local function split_addr(addr)
+ local host, port = addr:match("(.*):([^:]*)$")
+ return { host = host, port = port }
+end
+
return {
rand_string = rand_string,
mkdir = mkdir,
@@ -47,4 +52,5 @@ return {
json_dec = json_dec,
json_enc = json_enc,
send = send,
+ split_addr = split_addr,
}