open-card-table/lobby.lua

203 lines
6.8 KiB
Lua

require("oct_utils")
require("termbox_defs")
json = require "json"
-- begin message type constants
OCT_LOBBY_MSG_CLIENTREG = 0; -- Client registration message
OCT_LOBBY_MSG_CLIENTUNREG = 1; -- Client unreg message
OCT_LOBBY_MSG_CLIENTLIST = 2; -- Client list broadcast message
OCT_LOBBY_MSG_START = 3; -- Start the game message
OCT_LOBBY_MSG_PING = 4; -- Querying connection
OCT_LOBBY_MSG_ACK = 5; -- "yes", used to respond to ping and other stuff
OCT_LOBBY_MSG_NAK = 6; -- "no"
-- end message type constants
oct_lobby_clientlist = {};
oct_lobby_timers = {};
oct_lobby_timers["clientlist"] = 1000; -- Every 1000 calls to lobby_client broadcast client list
server_needs_broadcast_client_list = false
function lobby_server(maxplayers)
msg,addr,port = oct_recv();
if (msg ~= "") then
msg_obj = json.decode(msg)[1] -- dumps to 1-elem array, get first elem
if (msg_obj == nil) then
OCT_LOG_WARNING("Malformed json received")
end
-- The main state machine
if (msg_obj["msg_type"] == OCT_LOBBY_MSG_CLIENTREG) then
-- Client registration
req_name = msg_obj["name"]
req_port = msg_obj["port"]
req_addr = convert_known_host_to_ip(addr)
-- First, check if clientlist contains a conflicting username
if (oct_lobby_clientlist[req_name] ~= nil) then
response = json.encode({
{ msg_type = OCT_LOBBY_MSG_NAK }
})
OCT_LOG_WARNING("Rejected attempt to register from client: " .. req_name .. " @ " .. req_addr .. ":" .. req_port)
oct_send(response, req_addr, req_port)
else
response = json.encode({
{ msg_type = OCT_LOBBY_MSG_ACK }
})
oct_lobby_clientlist[req_name] = {}
oct_lobby_clientlist[req_name]["addr"] = req_addr
oct_lobby_clientlist[req_name]["port"] = req_port
OCT_LOG_INFO("Registered new client: " .. req_name .. " @ " .. req_addr .. ":" .. req_port)
oct_send(response, req_addr, req_port)
-- Everytime client is registered, need to broadcast client list
server_needs_broadcast_client_list = true
end
end
end
if (server_needs_broadcast_client_list == true) then
msg = json.encode({
{ msg_type = OCT_LOBBY_MSG_CLIENTLIST,
clientlist = oct_lobby_clientlist,
}
})
for k,v in pairs(oct_lobby_clientlist) do
oct_send(msg, v["addr"], v["port"])
end
server_needs_broadcast_client_list = false
end
end
-- Variables for lobby client
lobby_first_call = true;
client_connected = false;
oct_started = false;
client_wait_for_reg_response = false;
client_filling_in_connect_form = true;
-- UI elements for lobby client
lobby_ip_textbox = nil
lobby_port_textbox = nil
lobby_name_textbox = nil
lobby_connect_message = nil -- messages displayed when attempting connection
client_connect_ip = nil
client_connect_port = nil
client_connect_name = nil
-- Once connected, these elements display
client_clientlist_sprite = oct_tb_sprite_new()
function lobby_clear_connect_form()
lobby_ip_textbox["sprite"]["x"] = 1000
lobby_port_textbox["sprite"]["x"] = 1000
lobby_name_textbox["sprite"]["x"] = 1000
lobby_connect_message["x"] = 1000
lobby_ip_textbox["sprite"]["y"] = 1000
lobby_port_textbox["sprite"]["y"] = 1000
lobby_name_textbox["sprite"]["y"] = 1000
lobby_connect_message["y"] = 1000
unregister_textbox(lobby_ip_textbox)
unregister_textbox(lobby_port_textbox)
unregister_textbox(lobby_name_textbox)
end
--function lobby_client(ip, port, name, my_port)
function lobby_client(key, ch, my_port)
if (lobby_first_call)
then
lobby_ip_textbox = create_textbox("lobby_ip_textbox", 50, 10, 15, "IP: ")
lobby_port_textbox = create_textbox("lobby_port_textbox", 50, 12, 15, "Port: ")
lobby_name_textbox = create_textbox("lobby_name_textbox", 50, 14, 15, "Name: ")
lobby_connect_message = oct_tb_sprite_new()
lobby_connect_message["x"] = 50
lobby_connect_message["y"] = 16
lobby_connect_message["shape"] = ""
register_textbox(lobby_port_textbox)
register_textbox(lobby_name_textbox)
register_textbox(lobby_ip_textbox)
lobby_first_call = false;
end
if (client_filling_in_connect_form)
then
connect_info = handle_textbox(key, ch)
if (connect_info)
then
if (connect_info["lobby_name_textbox"] == "" or
connect_info["lobby_port_textbox"] == "" or
connect_info["lobby_name_textbox"] == "")
then
OCT_LOG_WARNING("Not all lobby connect information filled in")
lobby_connect_message["shape"] = "Please fill out all fields"
lobby_connect_message["fg"] = TB_RED
else
lobby_connect_message["shape"] = "Connecting..."
lobby_connect_message["fg"] = TB_WHITE
OCT_LOG_INFO("Trying to connect as " .. connect_info["lobby_name_textbox"] .. " to " .. connect_info["lobby_ip_textbox"] .. ":" .. connect_info["lobby_port_textbox"])
client_connect_ip = connect_info["lobby_ip_textbox"]
client_connect_port = connect_info["lobby_port_textbox"]
client_connect_name = connect_info["lobby_name_textbox"]
client_filling_in_connect_form = false
end
end
end
-- If not already connected, connect sending info
if (not client_connected and not client_wait_for_reg_response and not client_filling_in_connect_form) then
msg_to_server = json.encode({
{ name = client_connect_name, msg_type=OCT_LOBBY_MSG_CLIENTREG, port=my_port }
})
oct_send(msg_to_server, client_connect_ip, client_connect_port)
client_wait_for_reg_response = true -- prevent this from being run again
end
msg,addr,port = oct_recv()
if (msg ~= "") then
msg_obj = json.decode(msg)[1]
-- State machine code here
-- Registration was successful
if (client_wait_for_reg_response == true and
msg_obj["msg_type"] == OCT_LOBBY_MSG_ACK) then
OCT_LOG_INFO("Server accepted registration request!")
lobby_connect_message["shape"] = "Connected"
lobby_connect_message["fg"] = TB_GREEN
client_connected = true
client_wait_for_reg_response = false
client_filling_in_connect_form = false
lobby_clear_connect_form()
-- Registration was unsuccessful
elseif (client_wait_for_reg_response == true and
msg_obj["msg_type"] == OCT_LOBBY_MSG_NAK) then
OCT_LOG_ERROR("Server rejected registration request, try using a different name")
lobby_connect_message["shape"] = "Server rejected request, try changing name or port"
lobby_connect_message["fg"] = TB_RED
client_connected = false
client_wait_for_reg_response = false
client_filling_in_connect_form = true
-- We received a clientlist from the server
elseif (msg_obj["msg_type"] == OCT_LOBBY_MSG_CLIENTLIST) then
oct_lobby_clientlist = msg_obj["clientlist"]
OCT_LOG_DEBUG("My client list: " .. table_to_string(oct_lobby_clientlist))
client_clientlist_sprite["x"] = 0
client_clientlist_sprite["y"] = 20
client_clientlist_sprite["shape"] = "CLIENT LIST\n----------"
for k,v in pairs(oct_lobby_clientlist)
do
client_clientlist_sprite["shape"] = client_clientlist_sprite["shape"] .. "\n" .. k
end
end
end
end