Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using System.Threading;
- using System.Net.Sockets;
- using System;
- using System.Net;
- using System.Diagnostics;
- public class CallController : MonoBehaviour
- {
- private static CallController controller = null;
- public static CallController Instance
- {
- get
- {
- return controller;
- }
- }
- [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
- private static void Init()
- {
- var go = new GameObject("Call controller");
- DontDestroyOnLoad(go);
- controller = go.AddComponent<CallController>();
- }
- private interface IOnCompleteCommandHandler
- {
- void OnComplete(CallController callController);
- }
- private abstract class Command
- {
- public virtual float CommandTimeout
- {
- get
- {
- return 4.0f;
- }
- }
- public abstract void Execute(CallController callController, Socket socket);
- }
- private class CallCommand : Command, IOnCompleteCommandHandler
- {
- private readonly string number;
- private readonly string audioName;
- private readonly float timeout;
- public override float CommandTimeout
- {
- get
- {
- return timeout + base.CommandTimeout;
- }
- }
- public CallCommand(string number, string audioName, float timeout)
- {
- this.timeout = timeout;
- this.number = number;
- this.audioName = audioName;
- }
- public override void Execute(CallController callController, Socket socket)
- {
- UnityEngine.Debug.Log("Executing call command to number: " + number);
- socket.Send(System.Text.Encoding.ASCII.GetBytes(string.Format("call {0} {1}", number, audioName)));
- callController.IsCalling = true;
- }
- void IOnCompleteCommandHandler.OnComplete(CallController callController)
- {
- callController.IsCalling = false;
- }
- }
- Thread controlThread;
- private volatile bool isRunning = true;
- private object commandLocker = new object();
- private Command command = null;
- private object ipLocker = new object();
- private string ip = string.Empty;
- public string Ip
- {
- get
- {
- lock (ipLocker)
- return ip;
- }
- set
- {
- lock (ipLocker)
- ip = value;
- }
- }
- private object isCallingLocker = new object();
- private bool isCalling = false;
- public bool IsCalling
- {
- get
- {
- lock (isCallingLocker)
- return isCalling;
- }
- private set
- {
- lock (isCallingLocker)
- isCalling = value;
- }
- }
- private void Start()
- {
- controlThread = new Thread(ControlThread);
- controlThread.IsBackground = true;
- controlThread.Start();
- }
- private void AddCommand(Command command)
- {
- lock (commandLocker)
- {
- if (this.command != null)
- {
- UnityEngine.Debug.Log("There is a command. You can't assign another one while this one is not finished");
- return;
- }
- this.command = command;
- }
- }
- public void Call(string number, string audioName, float timeout)
- {
- if (IsCalling)
- {
- UnityEngine.Debug.LogError("Can't call. We are already calling!");
- return;
- }
- AddCommand(new CallCommand(number, audioName, timeout));
- }
- private void ControlThread()
- {
- byte[] buffer = new byte[65535];
- while (isRunning)
- {
- Thread.Sleep(200);
- IPAddress ipAddress = default(IPAddress);
- EndPoint endPoint = default(EndPoint);
- try
- {
- ipAddress = IPAddress.Parse(Ip);
- endPoint = new IPEndPoint(ipAddress, 5551);
- }
- catch (System.Threading.ThreadAbortException abort)
- {
- UnityEngine.Debug.Log("Exiting control thread");
- return;
- }
- catch (System.Exception ex)
- {
- UnityEngine.Debug.LogException(ex);
- continue;
- }
- Command commandToExecute = null;
- lock (commandLocker)
- {
- if (command == null)
- continue;
- commandToExecute = command;
- command = null;
- }
- try
- {
- using (Socket socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
- {
- UnityEngine.Debug.Log("Executing command");
- socket.Connect(endPoint);
- commandToExecute.Execute(this, socket);
- bool continueCycle = true;
- string receivedString = string.Empty;
- Stopwatch stopwatch = new Stopwatch();
- stopwatch.Start();
- do
- {
- if (socket.Available > 0)
- {
- int received = socket.Receive(buffer);
- if (received <= 0)
- continue;
- receivedString = System.Text.Encoding.UTF8.GetString(buffer, 0, received);
- var callString = "calling";
- if (receivedString.StartsWith(callString))
- {
- UnityEngine.Debug.Log("Reseting timeout. Got some result");
- stopwatch.Reset();
- stopwatch.Start();
- }
- var finishString = "command finished";
- if (receivedString.StartsWith(finishString))
- break;
- }
- if (stopwatch.ElapsedMilliseconds > commandToExecute.CommandTimeout * 1000)
- {
- UnityEngine.Debug.LogError("Command has been timed out");
- break;
- }
- } while (isRunning);
- if (commandToExecute is IOnCompleteCommandHandler)
- (commandToExecute as IOnCompleteCommandHandler).OnComplete(this);
- UnityEngine.Debug.Log("Command execution has finished");
- }
- }
- catch (System.Threading.ThreadAbortException abort)
- {
- UnityEngine.Debug.Log("Exiting control thread");
- return;
- }
- catch (System.Exception ex)
- {
- UnityEngine.Debug.LogError("Error executing command");
- }
- }
- }
- private void OnDestroy()
- {
- isRunning = false;
- if (controlThread != null)
- controlThread.Abort();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement