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"); }