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 --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, 20, 15, "IP: ") lobby_port_textbox = create_textbox("lobby_port_textbox", 50, 22, 15, "Port: ") lobby_name_textbox = create_textbox("lobby_name_textbox", 50, 24, 15, "Name: ") lobby_connect_message = oct_tb_sprite_new() lobby_connect_message["x"] = 50 lobby_connect_message["y"] = 26 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 client_wait_for_reg_response == false 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 = 1 client_wait_for_reg_response = false -- 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 = 0 client_wait_for_reg_response = false -- 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)) end end end