Esempio n. 1
0
        private void StartIPC()
        {
            Task.Run(async() =>
            {
                try
                {
                    var pid   = m_process.Id;
                    m_inPipe  = new NamedPipeClientStream($"FXServer_Instance_MIn_{pid}");
                    m_outPipe = new NamedPipeClientStream($"FXServer_Instance_MOut_{pid}");

                    await Task.WhenAll(m_inPipe.ConnectAsync(20000), m_outPipe.ConnectAsync(20000));

                    m_hadPipe = true;

                    Serializer.SerializeWithLengthPrefix(m_outPipe, new BaseCommand()
                    {
                        Type = 1,
                        Data = null
                    }, PrefixStyle.Base128);

                    while (m_inPipe != null && m_inPipe.IsConnected && m_process != null && pid == m_process.Id)
                    {
                        var cmd = Serializer.DeserializeWithLengthPrefix <BaseCommand>(m_inPipe, PrefixStyle.Base128);

                        if (cmd != null)
                        {
                            await HandleCommand(cmd);
                        }
                    }
                }
                catch (Exception e) { Debug.WriteLine(e.ToString()); }
            });
        }
Esempio n. 2
0
        public async Task Monitor()
        {
            bool healthy = true;

            if (m_process.HasExited)
            {
                healthy = false;
            }

            if (m_hadPipe && m_peer == null)
            {
                healthy = false;
            }

            if (healthy && (DateTime.UtcNow - m_lastHealthCheck) > TimeSpan.FromSeconds(5))
            {
                healthy = await RunHealthCheck();
            }

            if (!healthy)
            {
                Debug.WriteLine($"^3?^7 {Name}");

                await Stop();

                await m_backoff.Delay();
                await Start();
            }
        }
Esempio n. 3
0
        private Task HandleCommand(BaseCommand command)
        {
            switch (command.Type)
            {
            case 2:
            {
                var cd = command.DeserializeAs <GetPortResponseCommand>();
                m_port = cd.Port;

                string urlBit = "";

                if (!string.IsNullOrWhiteSpace(cd.NucleusUrl))
                {
                    m_nucleusUrl = cd.NucleusUrl;
                    urlBit       = $", ^4{cd.NucleusUrl}^7";
                }

                Debug.WriteLine($"^2>^7 {Name} (:{m_port}{urlBit})");
                break;
            }

            case 3:
                m_nucleusUrl = command.DeserializeAs <NucleusConnectedCommand>().Url;
                m_backoff    = new ExponentialBackoff(int.MaxValue, 1000, 30000);
                Debug.WriteLine($"^2:^7 {Name} -> ^4{m_nucleusUrl}^7");
                break;
            }

            return(Task.CompletedTask);
        }
Esempio n. 4
0
        public TResult Execute(string query = null, IDictionary <string, object> parameters = null, bool debug = false)
        {
            if (string.IsNullOrEmpty(query))
            {
                this.query      = query;
                this.parameters = parameters;
                this.debug      = debug;
            }

            TResult   result    = default(TResult);
            Stopwatch stopwatch = new Stopwatch();

            try
            {
                stopwatch.Start();

                using (var connection = new MySqlConnection(ConnectionString))
                {
                    connection.Open();
                    var ConnectionTime = stopwatch.ElapsedMilliseconds;
                    stopwatch.Restart();

                    using (var command = CreateCommand(query, parameters, connection))
                    {
                        var QueryTime = stopwatch.ElapsedMilliseconds;
                        stopwatch.Restart();

                        result = Reader(command);
                        stopwatch.Stop();

                        if (debug)
                        {
                            Debug.WriteLine(string.Format("[{0}] [C: {1}ms, Q: {2}ms, R: {3}ms] {4}", "MySQL", ConnectionTime, QueryTime, stopwatch.ElapsedMilliseconds, QueryToString(query, parameters)));
                        }
                    }
                }
            }
            catch (AggregateException aggregateException)
            {
                var firstException = aggregateException.InnerExceptions.First();

                if (!(firstException is MySqlException))
                {
                    throw;
                }

                Debug.Write(string.Format("[ERROR] [{0}] An error happens on MySQL for query \"{1}\": {2}\n", "MySQL", QueryToString(query, parameters), firstException.Message));
            }
            catch (MySqlException mysqlException)
            {
                Debug.Write(string.Format("[ERROR] [{0}] An error happens on MySQL for query \"{1}\": {2}\n", "MySQL", QueryToString(query, parameters), mysqlException.Message));
            }
            catch (Exception exception)
            {
                Debug.Write(string.Format("[ERROR] [{0}] An critical error happens on MySQL for query \"{1}\": {2} {3}\n", "MySQL", QueryToString(query, parameters), exception.Message, exception.StackTrace));
            }

            return(result);
        }
Esempio n. 5
0
        private void StartIPC()
        {
            Task.Run(async() =>
            {
                // TODO: cleaner way?
                var nngFactory = new nng.Tests.TestFactory();

                while (!m_hadPipe)
                {
                    try
                    {
                        if (m_process == null)
                        {
                            return;
                        }

                        var pid = m_process.Id;

                        // c# isnt f# or rust
                        // why is this api trying to be both at once
                        var pairResult = nngFactory
                                         .PairOpen()
                                         .ThenListen($"ipc:///tmp/fxs_instance_{pid}");

                        if (pairResult.TryError(out var error))
                        {
                            await Task.Delay(500);
                            continue;
                        }

                        m_pair = pairResult.Unwrap();

                        m_peer = new PipePeer(m_pair);
                        m_peer.Start();

                        m_peer.CommandReceived += async cmd =>
                        {
                            await HandleCommand(cmd);
                        };

                        m_peer.TargetUnreachable += () =>
                        {
                            m_pair = null;
                        };

                        m_hadPipe = true;

                        while (m_pair != null && m_process != null && pid == m_process.Id)
                        {
                            await Task.Delay(500);
                        }

                        m_peer.Stop();
                    }
                    catch (Exception e) { Debug.WriteLine(e.ToString()); }
                }
            });
        }
Esempio n. 6
0
        public async void ExecuteAsync(string query, IDictionary <string, object> parameters, CallbackDelegate callback, bool debug = false)
        {
            TResult   result    = default(TResult);
            Stopwatch stopwatch = new Stopwatch();

            try
            {
                stopwatch.Start();

                using (var connection = new MySqlConnection(ConnectionString))
                {
                    await connection.OpenAsync();

                    var ConnectionTime = stopwatch.ElapsedMilliseconds;
                    stopwatch.Restart();

                    using (var command = CreateCommand(query, parameters, connection))
                    {
                        var QueryTime = stopwatch.ElapsedMilliseconds;
                        stopwatch.Restart();

                        result = await ReaderAsync(command);

                        stopwatch.Stop();

                        if (debug)
                        {
                            Debug.WriteLine(string.Format("[{0}] [C: {1}ms, Q: {2}ms, R: {3}ms] {4}", "MySQL", ConnectionTime, QueryTime, stopwatch.ElapsedMilliseconds, QueryToString(query, parameters)));
                        }

                        callback.Invoke(result);
                    }
                }
            }
            catch (AggregateException aggregateException)
            {
                var firstException = aggregateException.InnerExceptions.First();

                if (!(firstException is MySqlException))
                {
                    throw aggregateException;
                }

                Debug.Write(string.Format("[ERROR] [{0}] An error happens on MySQL for query \"{1}\": {2}\n", "MySQL", QueryToString(query, parameters), firstException.Message));
            }
            catch (MySqlException mysqlException)
            {
                Debug.Write(string.Format("[ERROR] [{0}] An error happens on MySQL for query \"{1}\": {2}\n", "MySQL", QueryToString(query, parameters), mysqlException.Message));
            }
            catch (ArgumentNullException)
            {
                Debug.Write(string.Format("[ERROR] [{0}] Check the error above, an error happens when executing the callback from the query : \"{1}\"\n", "MySQL", QueryToString(query, parameters)));
            }
            catch (Exception exception)
            {
                Debug.Write(string.Format("[ERROR] [{0}] An critical error happens on MySQL for query \"{1}\": {2} {3}\n", "MySQL", QueryToString(query, parameters), exception.Message, exception.StackTrace));
            }
        }
Esempio n. 7
0
 private void UpdateState(
     bool paused,
     float currentTime,
     float duration,
     float remainingTime,
     string currentSource,
     string currentType)
 {
     if (!this.scaleformTickActive && !paused && this.isInitialized)
     {
         Debug.WriteLine("synchronizing playback state..");
         API.SendDuiMessage(
             this.duiObj,
             JsonConvert.SerializeObject(
                 new { type = "update", currentTime, src = new { type = currentType, url = currentSource } }));
         this.scaleformTickActive = true;
         this.Tick += this.ShowVideo;
     }
 }
Esempio n. 8
0
        private async Task ShowVideo()
        {
            // draw call wrapped inside try block to be able to stop video playback on error
            try
            {
                if (this.scaleform.IsValid && !this.txdHasBeenSet)
                {
                    this.scaleform.CallFunction("SET_TEXTURE", this.TxdName, TxnName, 0, 0, this.width, this.height);
                    this.txdHasBeenSet = true;
                }

                if (this.scaleform.IsValid)
                {
                    this.scaleform.Render3D(this.scaleformPos, this.scaleformRot, this.scaleformScale);
                    //this.scaleform2.Render3D(this.scaleformPos + (Vector3.UnitX * 20), this.scaleformRot, this.scaleformScale);
                    var playerPos = Game.PlayerPed.Position;
                    var distance  = API.GetDistanceBetweenCoords(
                        playerPos.X,
                        playerPos.Y,
                        playerPos.Z,
                        this.scaleformPos.X,
                        this.scaleformPos.Y,
                        this.scaleformPos.Z,
                        true);

                    var sndFactor = this.CalculateSoundFactor(distance);
                    var volume    = sndFactor * this.sndGlobalVolume;
                    API.SendDuiMessage(
                        this.duiObj,
                        JsonConvert.SerializeObject(new { type = "volume", volume = volume / 100 }));
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine($"[Hypnonema]: Exception occured at attempt to play video: {e.Message}");
                this.StopVideo();
            }

            await Task.FromResult(0);
        }
Esempio n. 9
0
        public async Task Monitor()
        {
            bool healthy = true;

            if (m_process.HasExited)
            {
                healthy = false;
            }

            if (m_hadPipe && !m_inPipe.IsConnected)
            {
                healthy = false;
            }

            if (!healthy)
            {
                // TODO: various kinds of backoff
                Debug.WriteLine($"^3?^7 {Name}");

                await Stop();
                await Start();
            }
        }
Esempio n. 10
0
 [Conditional("DEBUG")] public static void Log(string message)
 {
     Debug.WriteLine($"{DateTime.Now:s} [SERVER]: {message}");
 }
Esempio n. 11
0
        private async Task StartNew()
        {
            var psi = new ProcessStartInfo();

            var arguments = new List <string>();

            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                psi.FileName = Path.Combine(GetConvar("citizen_root", ""), "FXServer.exe");
            }
            else
            {
                var r  = GetConvar("citizen_root", "");
                var lr = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(r))));

                psi.FileName = Path.Combine(r, "ld-musl-x86_64.so.1");
                arguments.Add("--library-path");
                arguments.Add($"{lr}/alpine/usr/lib/v8/:{lr}/alpine/lib/:{lr}/alpine/usr/lib/");
                arguments.Add("--");
                arguments.Add(Path.Combine(r, "FXServer"));

                arguments.Add("+start");
                arguments.Add("monitor");
            }

            foreach (var config in m_instanceConfig.ConfigFiles)
            {
                arguments.Add("+exec");
                arguments.Add(config);
            }

            var fixedConvars = new Dictionary <string, string>()
            {
                { "monitor_killServerOnBrokenPipe", "1" },
                { "citizen_dir", GetConvar("citizen_dir", "") },
                { "con_disableNonTTYReads", "true" }
            };

            foreach (var convar in m_instanceConfig.ConVars.Concat(fixedConvars))
            {
                arguments.Add("+set");
                arguments.Add(convar.Key);
                arguments.Add(convar.Value);
            }

            foreach (var command in m_instanceConfig.Commands)
            {
                // TODO: handle spaces
                var parts = command.Split(new char[] { ' ' }, 3);
                arguments.Add("+" + parts[0]);
                arguments.AddRange(parts.Skip(1));
            }

            psi.Arguments = string.Join(" ",
                                        arguments
                                        .Select(a => a.Replace("\"", "\\\""))
                                        .Select(a =>
                                                a.Contains(" ") || a.Contains("\"")
                            ? $"\"{a}\""
                            : a));

            psi.CreateNoWindow = false;
            psi.WindowStyle    = ProcessWindowStyle.Normal;

            psi.UseShellExecute        = false;
            psi.RedirectStandardError  = true;
            psi.RedirectStandardOutput = true;

            m_process           = new Process();
            m_process.StartInfo = psi;
            if (!m_process.Start())
            {
                await BaseScript.Delay(5000);
            }

            void PrintOutput(string data)
            {
                if (GetConvar("monitor_showServerOutput", "0") != "0")
                {
                    Debug.WriteLine("^5!^7 {0} => {1}", Name, data);
                }
            }

            void PrintTask(StreamReader source)
            {
                Task.Run(async() =>
                {
                    while (!source.EndOfStream)
                    {
                        try
                        {
                            var read = await source.ReadLineAsync();

                            PrintOutput(read);
                        }
                        catch { }
                    }
                });
            }

            PrintTask(m_process.StandardOutput);
            PrintTask(m_process.StandardError);

            // save a pidfile
            Directory.CreateDirectory(Path.Combine(ms_rootPath, "cache"));
            File.WriteAllText(Path.Combine(ms_rootPath, "cache", $"{Name}.pid"), m_process.Id.ToString());
        }
Esempio n. 12
0
 public static void Log(string message)
 {
     Debug.WriteLine($"{DateTime.Now:s} [SERVER:QUEUE]: {message}");
 }
Esempio n. 13
0
        private async Task OnClientResourceStart(string resourceName)
        {
            if (API.GetCurrentResourceName() != resourceName)
            {
                return;
            }

            Debug.WriteLine($"Using hypnonema version: {this.GetHypnonemaVersion()}");

            Debug.WriteLine("creating new scaleform");
            this.scaleform = new Scaleform(SfName);
            Debug.WriteLine("loaded new scaleform");

            var numberFormat = new CultureInfo("en-US").NumberFormat;

            this.TxdName = Guid.NewGuid().ToString();

            while (!this.scaleform.IsLoaded)
            {
                await Delay(0);
            }

            var url  = API.GetResourceMetadata(resourceName, "hypnonema_url", 0);
            var posX = API.GetResourceMetadata(resourceName, "hypnonema_position", 0);
            var posY = API.GetResourceMetadata(resourceName, "hypnonema_position", 1);
            var posZ = API.GetResourceMetadata(resourceName, "hypnonema_position", 2);

            this.scaleformPos = new Vector3(
                float.Parse(posX, numberFormat),
                float.Parse(posY, numberFormat),
                float.Parse(posZ, numberFormat));

            var rotX = API.GetResourceMetadata(resourceName, "hypnonema_rotation", 0);
            var rotY = API.GetResourceMetadata(resourceName, "hypnonema_rotation", 1);
            var rotZ = API.GetResourceMetadata(resourceName, "hypnonema_rotation", 2);

            this.scaleformRot = new Vector3(
                float.Parse(rotX, numberFormat),
                float.Parse(rotY, numberFormat),
                float.Parse(rotZ, numberFormat));

            var scaleX = API.GetResourceMetadata(resourceName, "hypnonema_scale", 0);
            var scaleY = API.GetResourceMetadata(resourceName, "hypnonema_scale", 1);
            var scaleZ = API.GetResourceMetadata(resourceName, "hypnonema_scale", 2);

            this.scaleformScale = new Vector3(
                float.Parse(scaleX, numberFormat),
                float.Parse(scaleY, numberFormat),
                float.Parse(scaleZ, numberFormat));

            this.height = int.Parse(API.GetResourceMetadata(resourceName, "hypnonema_height", 0));
            this.width  = int.Parse(API.GetResourceMetadata(resourceName, "hypnonema_width", 0));

            var txd = API.CreateRuntimeTxd(this.TxdName);

            this.duiObj = API.CreateDui(url, this.width, this.height);
            var dui = API.GetDuiHandle(this.duiObj);

            var txn = Function.Call <long>(Hash.CREATE_RUNTIME_TEXTURE_FROM_DUI_HANDLE, txd, TxnName, dui);

            this.isInitialized = true;
            this.isAceAllowed  = API.IsAceAllowed(
                $"command.{API.GetResourceMetadata(resourceName, "hypnonema_command_name", 0)}");
            Debug.WriteLine($"dui runtime texture handle: {txn}");
            await Delay(0);
        }
Esempio n. 14
0
 private async void HandleHttpRequest(dynamic request, dynamic response)
 {
     Debug.WriteLine("Ha");
 }
Esempio n. 15
0
 public Test()
 {
     Debug.WriteLine("Test Loaded");
     API.SetHttpHandler(new Action <dynamic, dynamic>(HandleHttpRequest));
 }