Advertisement
Alior

CallController

Jun 3rd, 2018
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.35 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.Threading;
  5. using System.Net.Sockets;
  6. using System;
  7. using System.Net;
  8. using System.Diagnostics;
  9.  
  10. public class CallController : MonoBehaviour
  11. {
  12.     private static CallController controller = null;
  13.     public static CallController Instance
  14.     {
  15.         get
  16.         {
  17.             return controller;
  18.         }
  19.     }
  20.  
  21.     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
  22.     private static void Init()
  23.     {
  24.         var go = new GameObject("Call controller");
  25.         DontDestroyOnLoad(go);
  26.  
  27.         controller = go.AddComponent<CallController>();
  28.     }
  29.  
  30.     private interface IOnCompleteCommandHandler
  31.     {
  32.         void OnComplete(CallController callController);
  33.     }
  34.  
  35.     private abstract class Command
  36.     {
  37.         public virtual float CommandTimeout
  38.         {
  39.             get
  40.             {
  41.                 return 4.0f;
  42.             }
  43.         }
  44.  
  45.         public abstract void Execute(CallController callController, Socket socket);
  46.     }
  47.  
  48.     private class CallCommand : Command, IOnCompleteCommandHandler
  49.     {
  50.         private readonly string number;
  51.         private readonly string audioName;
  52.         private readonly float timeout;
  53.  
  54.         public override float CommandTimeout
  55.         {
  56.             get
  57.             {
  58.                 return timeout + base.CommandTimeout;
  59.             }
  60.         }
  61.  
  62.         public CallCommand(string number, string audioName, float timeout)
  63.         {
  64.             this.timeout = timeout;
  65.             this.number = number;
  66.             this.audioName = audioName;
  67.         }
  68.  
  69.         public override void Execute(CallController callController, Socket socket)
  70.         {
  71.             UnityEngine.Debug.Log("Executing call command to number: " + number);
  72.             socket.Send(System.Text.Encoding.ASCII.GetBytes(string.Format("call {0} {1}", number, audioName)));
  73.  
  74.             callController.IsCalling = true;
  75.         }
  76.  
  77.         void IOnCompleteCommandHandler.OnComplete(CallController callController)
  78.         {
  79.             callController.IsCalling = false;
  80.         }
  81.     }
  82.  
  83.     Thread controlThread;
  84.  
  85.     private volatile bool isRunning = true;
  86.  
  87.     private object commandLocker = new object();
  88.     private Command command = null;
  89.  
  90.     private object ipLocker = new object();
  91.     private string ip = string.Empty;
  92.     public string Ip
  93.     {
  94.         get
  95.         {
  96.             lock (ipLocker)
  97.                 return ip;
  98.         }
  99.  
  100.         set
  101.         {
  102.             lock (ipLocker)
  103.                 ip = value;
  104.         }
  105.     }
  106.  
  107.     private object isCallingLocker = new object();
  108.     private bool isCalling = false;
  109.     public bool IsCalling
  110.     {
  111.         get
  112.         {
  113.             lock (isCallingLocker)
  114.                 return isCalling;
  115.         }
  116.  
  117.         private set
  118.         {
  119.             lock (isCallingLocker)
  120.                 isCalling = value;
  121.         }
  122.     }
  123.  
  124.     private void Start()
  125.     {
  126.         controlThread = new Thread(ControlThread);
  127.         controlThread.IsBackground = true;
  128.         controlThread.Start();
  129.     }
  130.  
  131.     private void AddCommand(Command command)
  132.     {
  133.         lock (commandLocker)
  134.         {
  135.             if (this.command != null)
  136.             {
  137.                 UnityEngine.Debug.Log("There is a command. You can't assign another one while this one is not finished");
  138.                 return;
  139.             }
  140.  
  141.             this.command = command;
  142.         }
  143.     }
  144.  
  145.     public void Call(string number, string audioName, float timeout)
  146.     {
  147.         if (IsCalling)
  148.         {
  149.             UnityEngine.Debug.LogError("Can't call. We are already calling!");
  150.             return;
  151.         }
  152.  
  153.         AddCommand(new CallCommand(number, audioName, timeout));
  154.     }
  155.  
  156.     private void ControlThread()
  157.     {
  158.         byte[] buffer = new byte[65535];
  159.         while (isRunning)
  160.         {
  161.             Thread.Sleep(200);
  162.  
  163.             IPAddress ipAddress = default(IPAddress);
  164.             EndPoint endPoint = default(EndPoint);
  165.  
  166.             try
  167.             {
  168.                 ipAddress = IPAddress.Parse(Ip);
  169.                 endPoint = new IPEndPoint(ipAddress, 5551);
  170.             }
  171.             catch (System.Threading.ThreadAbortException abort)
  172.             {
  173.                 UnityEngine.Debug.Log("Exiting control thread");
  174.                 return;
  175.             }
  176.             catch (System.Exception ex)
  177.             {
  178.                 UnityEngine.Debug.LogException(ex);
  179.                 continue;
  180.             }
  181.  
  182.             Command commandToExecute = null;
  183.             lock (commandLocker)
  184.             {
  185.                 if (command == null)
  186.                     continue;
  187.  
  188.                 commandToExecute = command;
  189.                 command = null;
  190.             }
  191.  
  192.             try
  193.             {
  194.                 using (Socket socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
  195.                 {
  196.                     UnityEngine.Debug.Log("Executing command");
  197.  
  198.                     socket.Connect(endPoint);
  199.                     commandToExecute.Execute(this, socket);
  200.                     bool continueCycle = true;
  201.                     string receivedString = string.Empty;
  202.                     Stopwatch stopwatch = new Stopwatch();
  203.                     stopwatch.Start();
  204.                     do
  205.                     {
  206.                         if (socket.Available > 0)
  207.                         {
  208.                             int received = socket.Receive(buffer);
  209.                             if (received <= 0)
  210.                                 continue;
  211.  
  212.                             receivedString = System.Text.Encoding.UTF8.GetString(buffer, 0, received);
  213.  
  214.                             var callString = "calling";
  215.                             if (receivedString.StartsWith(callString))
  216.                             {
  217.                                 UnityEngine.Debug.Log("Reseting timeout. Got some result");
  218.                                 stopwatch.Reset();
  219.                                 stopwatch.Start();
  220.                             }
  221.  
  222.                             var finishString = "command finished";
  223.                             if (receivedString.StartsWith(finishString))
  224.                                 break;
  225.                         }
  226.  
  227.                         if (stopwatch.ElapsedMilliseconds > commandToExecute.CommandTimeout * 1000)
  228.                         {
  229.                             UnityEngine.Debug.LogError("Command has been timed out");
  230.                             break;
  231.                         }
  232.  
  233.                     } while (isRunning);
  234.  
  235.                     if (commandToExecute is IOnCompleteCommandHandler)
  236.                         (commandToExecute as IOnCompleteCommandHandler).OnComplete(this);
  237.  
  238.                     UnityEngine.Debug.Log("Command execution has finished");
  239.                 }
  240.             }
  241.             catch (System.Threading.ThreadAbortException abort)
  242.             {
  243.                 UnityEngine.Debug.Log("Exiting control thread");
  244.                 return;
  245.             }
  246.             catch (System.Exception ex)
  247.             {
  248.                 UnityEngine.Debug.LogError("Error executing command");
  249.             }
  250.         }
  251.     }
  252.  
  253.     private void OnDestroy()
  254.     {
  255.         isRunning = false;
  256.         if (controlThread != null)
  257.             controlThread.Abort();
  258.     }
  259. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement