sclass StefansOS_ConnectToServer implements AutoCloseable { DialogIO io; volatile bool on, verbose; Set subs = synchroLinkedHashSet(); VF1 onLine; S server = "botcompany.de"; L onConnected = syncList(); event newLine(S text); void start { if (on) ret; on = true; _connect(); doEvery_daemon_highPriority(30000, r { if (io != null) sendLine("") }); } void cleanMeUp { on = false; closeIO(); } public void close { cleanMeUp(); } void _connect { thread "Connect" { while (licensed() && on) { if (!tryToConnect()) continue with sleepSeconds(1); try { var io = talkTo(server, 6000); io.getSocket().setSoTimeout(30000+10000); print("Connected."); pcallFAll(onConnected); temp tempAfterwards(r { print("Disconnected.") }); sendLine(io, format("computerID=*", computerID())); StefansOS_ConnectToServer.this.io = io; for (S channel : cloneList(subs)) sendLine(format("sub *", channel)); print("Sent computer ID: " + computerID()); S line; while ((line = io.readLine()) != null) { if (verbose) print("Server said: " + line); pcallF(onLine, line); newLine(line); } } catch e { // pcall would also do an annoying message box printShortException(e); } closeIO(); sleepSeconds(5); } } } void closeIO { if (io != null) { pcall { io.close(); } io = null; } } bool connected() { ret io != null; } void sub(S channel) { if (subs.add(channel) && io != null) pcall { sendLine(format("sub *", channel); } } void startWithSubs(S... channels) { for (S channel : channels) sub(channel); start(); } void sendLine(DialogIO io default io, S line) { if (io != null) { if (verbose) print("Sending to server: " + line); io.sendLine(line); } else print("Can't send, not connected: " + line); } swappable bool tryToConnect() { true; } }