--[[ Gamestates/Multiplayer/Local.lua Local connect menu by piernov Comment: we really miss a Bonjour/Avahi Lua binding, only Android NSD is (barely) supported… ]]-- local Local = {} require "enet" local Gui = require "Quickie" local Utils = require "Utils" local Protocol = require "Gamestates/Multiplayer/Protocol" local connect, connected = false, false Local.server_host = { text = "" } Local.myservice = { name = "BlueMind", ip = "*", port = 5678 } Local.client = {} -- Android NSD events callback if love.system.getOS() == "Android" then -- Won't work on other OS… Local.services = {} function love.handlers.serviceregistered(a,b,c,d) SDL.log("ServiceRegistered: " .. a) Local.myservice.name = a end function love.handlers.discoverystarted(a,b,c,d) SDL.log("Discovery Started: " .. a) end function love.handlers.serviceresolved(a,b,c,d) SDL.log("Service Discovered: " .. a .. b .. c .. d) a = a:gsub("\\032", " ") if a == Local.myservice.name then Local.myservice.ip = c Local.myservice.port = d else Local.services[a] = { ip = c, port = d} end end function love.handlers.servicelost(a,b,c,d) SDL.log("Service Lost: " .. a .. b) Local.services[a] = nil end end -- End function Local:enter() Previous = "Gamestates/Multiplayer" connect, connected = false, false end function Local:init() Local.host = enet.host_create(Local.myservice.ip .. ":" .. Local.myservice.port) -- Open network socket local i = Local.myservice.port while not Local.host do -- unable to create socket: most likely port is already used if i > Local.myservice.port+20 then print("Error while creating socket") return 1 end Local.myservice.port = Local.myservice.port+1 -- try next port Local.host = enet.host_create(Local.myservice.ip .. ":" .. Local.myservice.port) end Local.myservice.name = Config.player_name.text -- Get player_name from user config if love.system.getOS() == "Android" then -- Start Android NSD discovery and publish love.android.registerService(Local.myservice.name, "_bluemind._tcp.", Local.myservice.port) love.android.discoverServices("_bluemind._tcp.") end end function Local:update(dt) Gui.group.push{grow = "right"} Gui.group.push{grow = "down", pos = {Utils.percentCoordinates(10, 0)}} if love.system.getOS() == "Android" then -- List discovered services for name, host in pairs(Local.services) do if Gui.Button{text = name .. " " .. host.ip .. ":" .. host.port, size = {Utils.percentCoordinates(60, 10)}} then Local.server_host.text = host.ip.. ":" .. host.port if connected then Local.host:disconnect() connected = false end connect = true return end end end -- Manually entering peer's address Gui.Label{text = "Host", size = {Utils.percentCoordinates(10, 10)}} Gui.Input{info = Local.server_host, size = {Utils.percentCoordinates(50, 10)}} if Gui.Button{text = "Connect", size = {Utils.percentCoordinates(60, 10)}} then if string.find(Local.server_host.text, ":") then connect = true else Gui.Label{text = "Please enter port"} end end -- End -- Handle connection and display a proposition message if Local.client.name and not connect then Gui.Label{text = args .. " connected to you. Play a game ?"} Gui.group.push{grow = "right"} if Gui.Button{text = "Yes", size = {Utils.percentCoordinates(10, 10)}} then Protocol.acceptGame(Local.host, Local.client.index, true) Gamestate.switch(require("Gamestates/Multiplayer/InGame")) end if Gui.Button{text = "No", size = {Utils.percentCoordinates(10, 10)}} then Protocol.acceptGame(Local.host, Local.client.index, false) Local.client = {} end Gui.group.pop{} end -- End Gui.group.pop{} -- Show local player name and host love.graphics.setFont(Fonts[3]) Gui.group.push{grow = "down", pos = {Utils.percentCoordinates(10, 0)}} Gui.Label{text = "My infos"} Gui.Label{text = "Name: " .. Local.myservice.name} Gui.Label{text = "Host: " .. Local.myservice.ip .. ":" .. Local.myservice.port} Gui.group.pop{} love.graphics.setFont(Fonts[4]) -- End Gui.group.pop{} if connect and not connected then Local.host:connect(Local.server_host.text) connected = true end local event = Local.host:service() while event ~= nil do -- Process network events Protocol.parseGlobalEvents(event) if event.type == "receive" then command, args = event.data:match("(.*): (.*)") if command == "CONNECT" then Local.client.name = args event.peer:send("CONNECTED: ".. Local.myservice.name, 0, "reliable") elseif command == "CONNECTED" then Local.client.name = args elseif command == "ACCEPT" then if args == "YES" then Gamestate.switch(require("Gamestates/Multiplayer/InGame")) elseif args == "NO" then event.peer:disconnect() connect, connected = false, false Local.client = {} end end elseif event.type == "connect" then if event.peer:index() <= 1 then Local.client.index = event.peer:index() end if connected then event.peer:send("CONNECT: ".. Local.myservice.name, 0, "reliable") end end event = Local.host:service() end end function Local:draw() Gui.core.draw() end function Local:keypressed(key, code) Gui.keyboard.pressed(key) end -- LÖVE 0.9 function love.textinput(str) Gui.keyboard.textinput(str) end function Local:leave() love.keyboard.setTextInput(false) end return Local