Example #1
0
        public override void Start()
        {
            ReadSettings();
            Log.Info($"Starting HTTP Info Server on port {Port}");

            worker = new ThreadWorker <RequestInfo>();
            worker.QueueResponses = false;

            Server.OnUpdateEvent.Connect(() =>
            {
                worker.Respond(info =>
                {
                    info.Request.Respond();
                    return(info.Request);
                });
            });

            var listener = new HttpListener();

            Server.OnDestroyEvent.Connect(() =>
            {
                listener.Abort();
            });
            listener.Prefixes.Add($"http://*:{Port}/");
            if (PortHttps >= 0 && PortHttps != Port)
            {
                listener.Prefixes.Add($"https://*:{PortHttps}/");
            }
            listener.Start();
            listener.BeginGetContext(listenerCallback, listener);

            Log.Debug($"Started HTTP(S) Info Server on port {Port}");

            DistanceServerMain.GetEvent <Events.ClientToAllClients.ChatMessage>().Connect((data, info) =>
            {
                var playerMatch = Regex.Match(data.message_, @"^\[[0-9A-F]{6}\](.*?)\[FFFFFF\]: (.*)$");
                if (!playerMatch.Success)
                {
                    return;
                }
                var playerName = Regex.Replace(playerMatch.Groups[1].ToString(), @"\[.*\]", "").ToLower();
                var player     = Server.ValidPlayers.Find(distPlayer => distPlayer.Name.ToLower() == Regex.Replace(playerMatch.Groups[1].ToString(), @"\[.*\]", "").ToLower());
                if (player == null)
                {
                    return;
                }
                var message = playerMatch.Groups[2].ToString();

                Match match;
                match = Regex.Match(message, @"^/unlink$");
                if (match.Success)
                {
                    var keysToRemove = new List <string>();
                    foreach (var pair in Links)
                    {
                        if (pair.Value == player.UnityPlayerGuid)
                        {
                            keysToRemove.Add(pair.Key);
                        }
                    }
                    foreach (var key in keysToRemove)
                    {
                        Links.Remove(key);
                    }
                    Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("HttpServer:Link", $"Your game session has been unlinked from {keysToRemove.Count} web session{(keysToRemove.Count == 1 ? "s" : "")}"));
                    return;
                }

                match = Regex.Match(message, @"^/link (\w{6})$");
                if (match.Success)
                {
                    var code = match.Groups[1].ToString().ToUpper();
                    if (!CodesReverse.ContainsKey(code))
                    {
                        var add = "";
                        if (HelpTextWebsite != null)
                        {
                            add = $"\nVisit {HelpTextWebsite.Replace("$linkcode", GetOrGenerateCode(player.UnityPlayerGuid))} to view and vote online.";
                        }
                        Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("HttpServer:Link", "Invalid link code!" + add));
                    }
                    Links[CodesReverse[code]] = player.UnityPlayerGuid;
                    CodesReverse.Remove(code);
                    Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("HttpServer:Link", $"Your game session has been linked to a web session!\nType [00FFFF]/unlink[-] to undo this."));
                    return;
                }

                match = Regex.Match(message, @"^/link");
                if (match.Success)
                {
                    if (HelpTextWebsite != null)
                    {
                        Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("HttpServer:Link", $"Visit {HelpTextWebsite.Replace("$linkcode", GetOrGenerateCode(player.UnityPlayerGuid))} to view and vote online."));
                    }
                    return;
                }
            });

            Manager.Server.OnPlayerValidatedEvent.Connect(player =>
            {
                GetOrGenerateCode(player.UnityPlayerGuid);
            });

            var autoServer = Manager.GetPlugin <BasicAutoServer.BasicAutoServer>();

            if (autoServer != null)
            {
                Log.Debug("Set LinkCodeGetter in BasicAutoServer");
                autoServer.LinkCodeGetter = player =>
                {
                    return(GetOrGenerateCode(player.UnityPlayerGuid));
                };
            }

            Manager.Server.OnPlayerDisconnectedEvent.Connect(player =>
            {
                Expiry[player.UnityPlayerGuid] = DistanceServerMain.UnixTime + 5 * 60;
                string keyToRemove             = null;
                foreach (var pair in CodesForward)
                {
                    if (pair.Value == player.UnityPlayerGuid)
                    {
                        keyToRemove = pair.Key;
                        break;
                    }
                }
                if (keyToRemove != null)
                {
                    CodesForward.Remove(keyToRemove);
                }
            });

            double lastUpdate = 0;

            Manager.Server.OnUpdateEvent.Connect(() =>
            {
                var now = DistanceServerMain.UnixTime;
                if (now - lastUpdate >= 60)
                {
                    lastUpdate       = now;
                    var KeysToRemove = new List <string>();
                    foreach (var pair in Links)
                    {
                        if (IsExpired(pair.Key, now) || IsExpired(pair.Value, now))
                        {
                            KeysToRemove.Add(pair.Key);
                        }
                    }
                    foreach (var key in KeysToRemove)
                    {
                        Links.Remove(key);
                    }
                    KeysToRemove.Clear();
                    foreach (var pair in CodesForward)
                    {
                        if (IsExpired(pair.Value, now))
                        {
                            KeysToRemove.Add(pair.Key);
                        }
                    }
                    foreach (var key in KeysToRemove)
                    {
                        CodesForward.Remove(key);
                    }
                    KeysToRemove.Clear();
                    foreach (var pair in CodesReverse)
                    {
                        if (IsExpired(pair.Value, now))
                        {
                            KeysToRemove.Add(pair.Key);
                        }
                    }
                    foreach (var key in KeysToRemove)
                    {
                        CodesReverse.Remove(key);
                    }
                }
            });

            Log.Debug($"Started handling code linking");
        }