using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net.Sockets; using System.Text; namespace IdleMafiaBot { static class Bridge { #if LINUX public static readonly bool On = true; #elif OCRBRIDGE public static readonly bool On = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("OCR_BRIDGE")); #else public const bool On = false; #endif static TcpClient client; static NetworkStream net; static StreamReader reader; static readonly object gate = new object(); public struct Item { public string Text; public double X, Y, W, H; } static int Port { get { int p; return int.TryParse(Environment.GetEnvironmentVariable("OCR_BRIDGE"), out p) ? p : 8765; } } static void Connect() { client = new TcpClient("127.0.0.1", Port) { NoDelay = true }; client.ReceiveTimeout = 120000; net = client.GetStream(); reader = new StreamReader(net, new UTF8Encoding(false)); } static void Close() { try { if (client != null) client.Close(); } catch (Exception) { } client = null; net = null; reader = null; } public static List Ask(byte[] bgra, int w, int h) { lock (gate) { try { return Once(bgra, w, h); } catch (Exception) { Close(); } try { return Once(bgra, w, h); } catch (Exception) { Close(); throw; } } } static string Line() { var line = reader.ReadLine(); if (line == null) throw new IOException("the reader closed the connection"); return line; } static List Once(byte[] bgra, int w, int h) { if (client == null) Connect(); var head = new byte[8]; BitConverter.GetBytes(w).CopyTo(head, 0); BitConverter.GetBytes(h).CopyTo(head, 4); net.Write(head, 0, 8); net.Write(bgra, 0, w * 4 * h); net.Flush(); int n = int.Parse(Line(), CultureInfo.InvariantCulture); var list = new List(); for (int i = 0; i < n; i++) { var line = Line(); int tab = line.IndexOf('\t'); var p = line.Substring(0, tab).Split(' '); list.Add(new Item { X = double.Parse(p[0], CultureInfo.InvariantCulture), Y = double.Parse(p[1], CultureInfo.InvariantCulture), W = double.Parse(p[2], CultureInfo.InvariantCulture), H = double.Parse(p[3], CultureInfo.InvariantCulture), Text = line.Substring(tab + 1), }); } return list; } public static string Check() { try { Ask(new byte[16 * 16 * 4], 16, 16); return null; } catch (Exception e) { return "The text reader doesn't answer on port " + Port + " (" + e.Message + "), so the bot can't read the game."; } } } }