extends Node var _server := UDPServer.new() var _userInfo: Dictionary var _pendingPackets: Array var _metadataTimer: Timer var _lastPeers: Array # This array is of dictionary elements that contain: # "online": Will be true except when used to update the array. # "type": Either "pending" or "known", which is confusing. # "ip": IP address of this peer. # "user": User name on this IP. # "refresh": Do we need to redraw this entry? var peerArray: Array func _metadataTimerTimeout(): if _server.is_listening(): var method = {} # Request updated metadata from everyone on the network. method["method"] = "query" for peer in peerArray: _sendTo(peer["ip"], method) func _process(_delta): if _server.is_listening(): # Handle incoming data. _server.poll() if _server.is_connection_available(): var client: PacketPeerUDP = _server.take_connection() var packet = client.get_packet() var clientIP = client.get_packet_ip() var raw = packet.get_string_from_utf8() var jsonIn = JSON.new() var error = jsonIn.parse(raw) # DEBUG print("Raw: ", raw) if error == OK: # DEBUG print("JSON In: ", jsonIn.data) # Remote node wants our information. if jsonIn.data["method"] == "query": var payload = {} payload["method"] = "queryResponse" payload["user"] = _userInfo["user"] client.put_packet(JSON.stringify(payload).to_utf8_buffer()) # Remote node replied to our query. if jsonIn.data["method"] == "queryResponse": for i in range(0, peerArray.size() - 1): if peerArray[i]["ip"] == clientIP: peerArray[i]["user"] = jsonIn.data["user"] peerArray[i]["refresh"] = true break client.close() # Handle outgoing data. for outbound in _pendingPackets: # DEBUG print("Sending: ", outbound) var destination := PacketPeerUDP.new() destination.connect_to_host(outbound["ip"], _server.get_local_port()) var error = destination.put_packet(JSON.stringify(outbound["message"]).to_utf8_buffer()) if error: print("Sending packet error: ", error) destination.close() _pendingPackets.clear() func _ready(): clear() _metadataTimer = Timer.new() _metadataTimer.timeout.connect(_metadataTimerTimeout) Engine.get_main_loop().current_scene.add_child(_metadataTimer) _metadataTimer.start(5) func _sendTo(ipAddress, message): var pending = {} pending["ip"] = ipAddress pending["message"] = message _pendingPackets.append(pending) func _sort_by_ip(a, b): #***TODO*** Sort numerically against last three digits. if a["ip"] < b["ip"]: return true return false func clear(): peerArray.clear() func start_server(address, port, userInfo): _userInfo = userInfo if !_server.is_listening(): _server.listen(port, address) _pendingPackets.clear() func stop_server(): if _server.is_listening(): _server.stop() func update(peers: Array): var found var newArray: Array = [] print("Real peers: ", peers.size()) peers.sort_custom(_sort_by_ip) # Did the peer list change? if Util.deep_equal(peers, _lastPeers): # Does an existing peer need redrawn? found = false for peer in peerArray: if peer["refresh"] == true: peer["refresh"] = false found = true return found # Add everyone connected. for peer in peers: # Do we have this peer's information? found = false for oldPeer in peerArray: if oldPeer["ip"] == peer["ip"]: print("Updating ", peer) found = true peer = oldPeer if !found: # We didn't have them. Add needed records. peer["user"] = "" peer["online"] = true peer["refresh"] = false # Add them to the new list. newArray.append(peer) # Use new array. peerArray = newArray.duplicate(true) # Remember this pass. _lastPeers = peers.duplicate(true) return true