Multiplayer Sock Issue

Hi! I have found this code for multiplayer and I keep getting “Attempt to index upvalue ‘sock’ (a boolean value) File: main.lua - Line: 152” when I try to connect to server.

Im very new to making multiplayer games. Please help!

Thank you!

main.lua

----------------------------------------------------------------------------------------- display.setStatusBar(display.HiddenStatusBar) ----------------------------------------------------------------------------------------- system.activate( "multitouch" ) ----------------------------------------------------------------------------------------- local loadsave = require("loadsave") local physics = require("physics") physics.start() --physics.setDrawMode("hybrid") physics.setGravity(0,9.8) ----------------------------------------------------------------------------------------- local bg = display.newRect(0,0,display.contentWidth,display.contentHeight) bg.x = display.contentWidth/2 bg.y = display.contentHeight/2 bg:setFillColor(0.3) ----------------------------------------------------------------------------------------- local group = require("group") local player = require("players") local battleRoom = require("battleRoom") local HUD = require("HUD") local camera = require("camera") ----------------------------------------------------------------------------------------- function LazyRequire(name) local mod return setmetatable({}, { \_\_index = function(\_, k) mod = mod or require(name) return mod[k] end }) end ----------------------------------------------------------------------------------------- local socket = require("socket") local server = require("server") server\_ip = 0 local getClientIP local findServer local connectToServer local createClientLoop getClientIP = function() local s = socket.udp() --creates a UDP object s:setpeername( "74.125.115.104", 80 ) --Google website local ip, sock = s:getsockname() print( "Client IP / socket:", ip, sock ) return ip end findServer = function() local newServers = {} local msg = "AwesomeGameServer" local listen = socket.udp() listen:setsockname( "226.192.1.1", 1234 ) --this only works if the device supports multicast local name = listen:getsockname() if ( name ) then --test to see if device supports multicast listen:setoption( "ip-add-membership", { multiaddr="226.192.1.1", interface = getClientIP() } ) else --the device doesn't support multicast so we'll listen for broadcast listen:close() --first we close the old socket; this is important listen = socket.udp() --make a new socket listen:setsockname( getClientIP(), 1234 ) --set the socket name to the real IP address end listen:settimeout( 0 ) --move along if there is nothing to hear local stop local counter = 0 --pulse counter local function look() repeat local data, ip, port = listen:receivefrom() --print( "data: ", data, "IP: ", ip, "port: ", port ) if data and data == msg then if not newServers[ip] then print( "Client hears a server at IP " .. ip .. " and port " .. port ) local params = { ["ip"]=ip, ["port"]=1235 } newServers[ip] = params server\_ip = ip end end until not data counter = counter + 1 if counter == 20 then --stop after 2 seconds stop() end end --pulse 10 times per second local beginLooking = timer.performWithDelay( 100, look, 0 ) function stop() timer.cancel( beginLooking ) --evaluateServerList( newServers ) --do something with your found servers listen:close() --never forget to close the socket! end end connectToServer = function( ip, port ) print("Sending message to IP " .. ip .. " and port " .. port) local sock, err = socket.connect( ip, port ) if sock == nil then return false end sock:settimeout( 0 ) sock:setoption( "tcp-nodelay", true ) --disable Nagle's algorithm sock:send("CLIENT " ..ip .. " " .. port .. "\n") return sock end createClientLoop = function( sock, ip, port ) local buffer = {} local clientPulse local function cPulse() local allData = {} local data, err -- Get line by line of data and store in allData repeat data, err = sock:receive() if data then allData[#allData+1] = data end if ( err == "closed" and clientPulse ) then --try again if connection closed print("Client connection closed. Re-connect and try to receive again.") connectToServer( ip, port ) data, err = sock:receive() if data then allData[#allData+1] = data end end until not data if ( #allData \> 0 ) then for i, thisData in ipairs( allData ) do print( "Client received from server:", thisData ) --------------------------- --react to incoming data --------------------------- end end -- TO DO: set a buffer to send, depending on action for i, msg in pairs( buffer ) do local data, err = sock:send(msg) if ( err == "closed" and clientPulse ) then --try to reconnect and resend print("Client connection closed. Re-connect and try to send again.") connectToServer( ip, port ) data, err = sock:send( msg ) end end end --pulse 10 times per second clientPulse = timer.performWithDelay( 100, cPulse, 0 ) local function stopClient() timer.cancel( clientPulse ) --cancel timer clientPulse = nil sock:close() end return stopClient end ------------------------------------------------------------------------------------ ----------------------- local startServer = display.newText("Start server", 150, 100, "pixelDR", 36) function startServ(e) if e.phase == "ended" then server.createServer() end end startServer:addEventListener("touch", startServ) ----------------------- -- server\_b local serverb = display.newText("Advertise server", 400, 150, "pixelDR", 36) serverb:setTextColor(255, 0, 0) -- Advertise the server ----------------------------- serverbF = function(event) server.advertiseServer() end ----------------------------- serverb:addEventListener("tap",serverbF) -- client\_b local clientb = display.newText("Get client IP", 400, 200, "pixelDR", 36) clientb:setTextColor(0, 255, 0) -- Client finds out its IP address ----------------------- clientbF = function(event) findServer() end ----------------------- clientb:addEventListener("tap",clientbF) -- send\_b local sendb = display.newText("Connect to Server", 400, 100, "pixelDR", 36) sendb:setTextColor(255, 0, 255) -- Connect to server ----------------------- sendbF = function(event) -- Get a session ID ("sock") from server local sock = connectToServer(server\_ip,1235) createClientLoop(sock,server\_ip,1235) end ----------------------- sendb:addEventListener("tap",sendbF)

server.lua

local S = {} local socket = require( "socket" ) local clientList = {} local clientBuffer = {} S.getServerIP = function() local s = socket.udp() s:setpeername( "74.125.115.104", 80 ) local ip, sock = s:getsockname() print( "Server IP / socket:", ip, sock ) return ip end S.createServer = function() local tcp, err = socket.bind( S.getServerIP(), 1235 ) --create a server object tcp:settimeout( 0 ) local function sPulse() ------------------------------------------------------ -- Check for available clients ------------------------------------------------------ repeat local client = tcp:accept() --allow a new client to connect if client then print( "Server detected a client" ) client:settimeout( 0 ) --just check the socket and keep going --TO DO: implement a way to check to see if the client has connected previously --consider assigning the client a session ID and use it on reconnect. clientList[#clientList+1] = client -- TO DO clientBuffer[client] = { "hello\_client\n" } --just including something to send below end until not client -- Check to see which client connections are available local ready, writeReady, err = socket.select( clientList, clientList, 0 ) ------------------------------------------------------- -- Look for data from clients ------------------------------------------------------- if err == nil then for i = 1, #ready do --list of clients who are available local client = ready[i] local allData = {} --this holds all lines from a given client -- From current client, get line by line of data and store in allData repeat local data, err = client:receive() -- get a line of data from the client, if any if data then allData[#allData+1] = data end until not data if ( #allData \> 0 ) then --figure out what the client said to the server -- Get each line from allData for i, thisData in ipairs( allData ) do print( "Server received from client:", thisData ) --------------------- -- Do stuff with data --------------------- end end end ------------------------------------------------------ -- Send whatever is in the server's buffer ------------------------------------------------------ for sock, buffer in pairs( clientBuffer ) do -- Grab each line from the buffer meant for current client, and send it for \_, msg in pairs( buffer ) do --might be empty print("Server sends to clients:", msg) local data, err = sock:send( msg ) --send the message to the clients print("Err: ",err) print("\n") end end end end -- Call above function every 100 ms local serverPulse = timer.performWithDelay( 100, sPulse, 0 ) local function stopServer() timer.cancel( serverPulse ) --cancel timer tcp:close() for i, v in pairs( clientList ) do v:close() end end return stopServer end S.advertiseServer = function() print("Advertise server") local send = socket.udp() send:settimeout( 0 ) --this is important (how long to wait before moving on) local stop local counter = 0 --using this, we can advertise our IP address for a limited time local function broadcast() local msg = "AwesomeGameServer" --multicast IP range from 224.0.0.0 to 239.255.255.255 send:sendto( msg, "226.192.1.1", 1234 ) --not all devices can multicast so it's a good idea to broadcast too --however, for broadcast to work, the network has to allow it send:setoption( "broadcast", true ) --turn on broadcast send:sendto( msg, "255.255.255.255", 1234 ) send:setoption( "broadcast", false ) --turn off broadcast counter = counter + 1 if ( counter == 80 ) then --stop after 8 seconds stop() -- variable to a function end end --pulse 10 times per second local serverBroadcast = timer.performWithDelay( 100, broadcast, 0 ) stop = function() timer.cancel( serverBroadcast ) --cancel timer stop = nil print("Stop server broadcast") end end return S