package com.lbry.globe.thread; import java.io.InputStream; import java.net.InetAddress; import java.net.Socket; import java.util.*; import com.lbry.globe.api.API; import com.lbry.globe.object.Node; import com.lbry.globe.object.Service; import com.lbry.globe.util.GeoIP; import org.json.JSONArray; import org.json.JSONObject; public class HubNodeFinderThread implements Runnable{ public static final String[] HUBS = { "spv11.lbry.com", "spv12.lbry.com", "spv13.lbry.com", "spv14.lbry.com", "spv15.lbry.com", "spv16.lbry.com", "spv17.lbry.com", "spv18.lbry.com", "spv19.lbry.com", "hub.lbry.grin.io", "hub.lizard.technology", "s1.lbry.network", "hub.lbry.nl", }; private static final Map LAST_SEEN = new TreeMap<>(Comparator.comparing(InetAddress::getHostAddress)); @Override public void run() { while(true){ for(String hostname : HubNodeFinderThread.HUBS){ try{ for(InetAddress ip : InetAddress.getAllByName(hostname)){ new Thread(() -> { try{ Socket s = new Socket(ip,50001); JSONObject obj = new JSONObject(); obj.put("id",new Random().nextInt()); obj.put("method","server.banner"); obj.put("params",new JSONArray()); s.getOutputStream().write((obj+"\n").getBytes()); s.getOutputStream().flush(); InputStream in = s.getInputStream(); StringBuilder sb = new StringBuilder(); int b; while((b = in.read())!='\n'){ sb.append(new String(new byte[]{(byte) (b & 0xFF)})); } in.close(); JSONObject respObj = new JSONObject(sb.toString()); boolean successful = respObj.has("result") && !respObj.isNull("result"); if(successful){ LAST_SEEN.put(ip,System.currentTimeMillis()); } }catch(Exception e){ } }).start(); } }catch(Exception e){ e.printStackTrace(); } } List removeIPs = new ArrayList<>(); for(Map.Entry entry : HubNodeFinderThread.LAST_SEEN.entrySet()){ long difference = System.currentTimeMillis()-entry.getValue(); if(difference>60_000){ removeIPs.add(entry.getKey()); } } for(InetAddress removeIP : removeIPs){ HubNodeFinderThread.LAST_SEEN.remove(removeIP); Node n = API.NODES.get(removeIP); if(n!=null){ List removeServices = new ArrayList<>(); for(Service s : n.getServices()){ if(s.getPort()==50001 && "hub".equals(s.getType())){ removeServices.add(s); } } n.getServices().removeAll(removeServices); } } for(Map.Entry entry : HubNodeFinderThread.LAST_SEEN.entrySet()){ Node existingNode = API.NODES.get(entry.getKey()); if(existingNode==null){ JSONObject geoData = GeoIP.getCachedGeoIPInformation(entry.getKey()); Double[] coords = GeoIP.getCoordinateFromLocation(geoData.has("loc")?geoData.getString("loc"):null); existingNode = new Node(entry.getKey(),coords[0],coords[1]); API.NODES.put(entry.getKey(),existingNode); } Service hubService = null; for(Service s : existingNode.getServices()){ if(s.getPort()==50001 && "hub".equals(s.getType())){ hubService = s; break; } } if(hubService==null){ existingNode.getServices().add(new Service(UUID.randomUUID(),50001,"hub")); }else{ hubService.updateLastSeen(); } } try { Thread.sleep(10_000); } catch (InterruptedException e) { throw new RuntimeException(e); } } } }