local socket = Socket or require("socket") function network_send(data) client:send(data) end function network_accept_client() server = assert(socket.bind("*", 25000)) client = nil local ip, port = server:getsockname() print("Server listening on " .. ip .. ":" .. port) client = server:accept() client:settimeout(0) local ip, port = client:getsockname() print("Connection from " .. ip .. ":" .. port) end function network_update() local sim = GSim local line, err = client:receive() if not err then local data = {} local i = 1 line = line:gsub(";;", "; ;") line = line:gsub(";$", "; ") for str in string.gmatch(line, "([^;]+)") do data[i] = str or "" i = i + 1 end local i = 1 while i <= #data do if data[i] == "W" then local min = vectotable(data[i+3]) local max = vectotable(data[i+4]) local bounds = {min[1], min[2], min[3], max[1], max[2], max[3]} local wire = Wire.new(tonumber(data[i+1]), tonumber(data[i+2]), bounds) Simulation.addwire(sim, wire) i = i + 4 elseif data[i] == "G" then local objref = tonumber(data[i+1]) local definition = Simulation.getdefinitionbyref(sim, tonumber(data[i+2])) assert(definition, "No gate definition for objref "..objref.." defref "..tonumber(data[i+1])) local position = vectotable(data[i+3]) local rotation = tonumber(data[i+4]) local gate = GateDefinition.constructgate(definition, objref, position, rotation) Simulation.addgate(sim, gate) i = i + 4 elseif data[i] == "RW" then Simulation.removewire(sim, tonumber(data[i+1])) i = i + 1 elseif data[i] == "RG" then Simulation.removegate(sim, tonumber(data[i+1])) i = i + 1 elseif data[i] == "GD" then --print("---------------------------------------[[[[") --print(table.concat(data, "]]]]\n[[[[", i, math.min(#data, i+100))) --print("]]]]---------------------------------------") local objref = tonumber(data[i+1]) local name = data[i+2] local desc = data[i+3] local init = data[i+4] local logic = data[i+5] local input = data[i+6] local global = data[i+7] local numports = tonumber(data[i+8]) i = i + 8 local ports = {} for a = i+1, numports*5+i, 5 do local portd = { type = tonumber(data[a]), position = vectotable(data[a+1]), direction = tonumber(data[a+2]), causeupdate = toboolean(data[a+3]), name = data[a+4], } ports[#ports+1] = portd if not portd.direction then print(line) end end local definition = GateDefinition.new(objref, name, desc, init, logic, input, global, ports) Simulation.addgatedefinition(sim, definition) i = i + numports*5 elseif data[i] == "SL" then local wire = Simulation.getwirebyref(sim, tonumber(data[i+1])) if wire ~= nil then Wire.setlayer(wire, tonumber(data[i+2])) else error("Setlayer: no wire for objref "..tonumber(data[i+1])) end i = i + 2 elseif data[i] == "OPT" then local option = data[i+1] local value = tonumber(data[i+2]) if option == "TICK_ENABLED" then OPT_TICK_ENABLED = toboolean(value) elseif option == "TICK_TIME" then if value < 0 or value > 999999 then value = 0 end if value<=0.001 then value = 0.001 end OPT_TICK_TIME = value elseif option == "FX_UPDATES" then OPT_FX_UPDATES = toboolean(value) elseif option == "FX_TIME" then if value < 0 or value > 999999 then value = 0 end OPT_FX_TIME = value elseif option=="TICK_MULT" then OPT_TICK_MULT = value end i = i + 2 elseif data[i] == "GINFO" then local userid = data[i+1] local objref = tonumber(data[i+2]) local info = "" local wire = Simulation.getwirebyref(sim, objref) if wire then local group = Wire.getgroup(wire) local numwires = 0; for k, wire2 in pairs(group.wires ) do numwires = numwires +1 end local numportsi = 0; for k, port in pairs(group.in_ports ) do numportsi = numportsi+1 end local numgatesu = group.num_gates_update[0] local numportso = 0; local numportson=0; for k, port in pairs(group.out_ports) do numportso = numportso+1 if Port.getstate(port)==1 then numportson = numportson+1 end end info = "\\c5Net " .. tostring(group):match("table: 0x(.+)"):upper() .. "\n" .. (Wire.getgroup(wire).state[0]==1 and "\\c2On" or "\\c0Off") .. "\n" .. "Wires: "..numwires.."\n".. "In Ports: " ..numportsi.."\n".. "Out Ports: "..numportso.."\n".. "Gates Update: "..numgatesu.."\n".. "Out Ports On: "..(group.state_num[0]) ; end local gate = Simulation.getgatebyref(sim, objref) if gate then local def = Gate.getdefinition(gate) info = "\\c5" .. def.name .. "
" for i = 1, #gate.ports do local port = gate.ports[i] local state if port.type==PortTypes.input then state = Gate.getportstate(gate, i) else state = Port.getstate(port) end info = info .. (state==1 and "\\c2" or "\\c0") .. def.ports[i].name .. (i ~= #gate.ports and " " or "") end end if info ~= "" then network_send("GINFO\t" .. userid .. "\t" .. expandescape(info) .. "\n") end i = i + 2 elseif data[i] == "SINFO" then network_send("SINFO\t" .. data[i+1] .. "\t" .. sim.nwires .. "\t" .. sim.ngates .. "\t" .. sim.ninports .. "\t" .. sim.noutports .. "\n") i = i + 1 elseif data[i] == "TICK" then Simulation.tickinit(sim) Simulation.tickinput(sim) Simulation.ticklogic(sim) --ticks = ticks + 1 elseif data[i] == "IN" then local gate = Simulation.getgatebyref(sim, tonumber(data[i+1])) local argc = tonumber(data[i+2]) local argv = {} for a = i+3, i+3+argc-1 do argv[#argv+1] = collapseescape(data[a]) end if gate then Simulation.queuegateinput(sim, gate, argv) end i = i+2+argc elseif data[i] == "SAVE" then print("saving all data") logicsave() else print("invalid data "..data[i]) end i = i + 1 end elseif err == "closed" then print("Connection closed") error() end end