コード例 #1
0
    public void OnPlayerDisconnected(NetworkPlayer player)
    {
        var distancePlayer = GetDistancePlayer(player);

        distancePlayer.unityPlayer = player;
        if (distancePlayer.ReceivedInfo)
        {
            ValidPlayers.Remove(distancePlayer);
            for (int i = distancePlayer.Index; i < ValidPlayers.Count; i++)
            {
                ValidPlayers[i].Index = i;
            }
        }
        DistancePlayers.Remove(player.guid);
        distancePlayer.Car = null;
        DistanceServerMain.GetEvent <Events.ServerToClient.RemovePlayerFromClientList>().Fire(
            RPCMode.Others,
            new Distance::Events.ServerToClient.RemovePlayerFromClientList.Data(player, distancePlayer.Index, Distance::DisconnectionType.Quit)
            );

        if (StartingMode)
        {
            AttemptToStartMode();
        }

        distancePlayer.LeftAt = DistanceServerMain.UnixTime;
        distancePlayer.OnDisconnectedEvent.Fire();
        OnPlayerDisconnectedEvent.Fire(distancePlayer);
    }
コード例 #2
0
ファイル: Sprint.cs プロジェクト: Ciastex/Distance-Server
 public void OnNeedToSyncLateClientToGameMode(DistancePlayer player)
 {
     DistanceServerMain.GetEvent <Events.ServerToClient.SyncMode>().Fire(
         player.UnityPlayer,
         new Distance::Events.GameMode.SyncMode.Data(Plugin.ServerStage == BasicAutoServer.Stage.AllFinished)
         );
 }
コード例 #3
0
ファイル: ReverseTag.cs プロジェクト: Ciastex/Distance-Server
        public void TagPlayer(DistancePlayer player)
        {
            if (TaggedPlayer == player)
            {
                Log.Debug("Player same");
                return;
            }
            if (player == null)
            {
                Log.Debug("Player null");
                TaggedPlayer = null;
                return;
            }

            var    lastTagData       = TaggedPlayer?.GetExternalData <ReverseTagData>();
            double lastSecondsTagged = lastTagData == null ? 0.0 : lastTagData.SecondsTagged;

            TimeOfLastTag = Plugin.Server.ModeTime;
            var networkTagData = new Distance::Events.ReverseTag.TaggedPlayer.Data(player.Index, lastSecondsTagged, TimeOfLastTag);

            DistanceServerMain.GetEvent <Events.ServerToClient.TaggedPlayer>().Fire(UnityEngine.RPCMode.Others, networkTagData);

            TaggedPlayer = player;

            LockTagBubbleFor(5);
        }
コード例 #4
0
    public void OnPlayerConnected(NetworkPlayer player)
    {
        var distancePlayer = new DistancePlayer(this, player.guid);

        DistancePlayers[player.guid] = distancePlayer;

        foreach (var existingPlayer in ValidPlayers)
        {
            DistanceServerMain.GetEvent <Events.ServerToClient.AddClient>().Fire(
                player,
                existingPlayer.GetAddClientData(false)
                );
        }

        foreach (var line in ChatLog)
        {
            distancePlayer.ChatLog.Add(line);
        }
        distancePlayer.ResendChat();

        SendLevelInfo(player);

        DistanceServerMain.GetEvent <Events.ServerToClient.Request>().Fire(
            player,
            new Distance::Events.ServerToClient.Request.Data(Distance::ServerRequest.SubmitClientInfo)
            );

        distancePlayer.JoinedAt = DistanceServerMain.UnixTime;
        OnPlayerConnectedEvent.Fire(distancePlayer);
    }
コード例 #5
0
 public void RequestSubmitGameModeInfo(NetworkPlayer player)
 {
     DistanceServerMain.GetEvent <Events.ServerToClient.Request>().Fire(
         player,
         new Distance::Events.ServerToClient.Request.Data(Distance::ServerRequest.SubmitGameModeInfo)
         );
 }
コード例 #6
0
 public void BroadcastDNF()
 {
     DistanceServerMain.GetEvent <Events.ServerToClient.GameModeFinished>().Fire(
         Player.UnityPlayer,
         new Distance::Events.GameMode.Finished.Data()
         );
 }
コード例 #7
0
 public void SayChat(DistanceChat chat, bool addMessage = true)
 {
     AddChat(chat);
     DistanceServerMain.GetEvent <Events.ClientToAllClients.ChatMessage>().Fire(
         RPCMode.Others,
         new Distance::Events.ClientToAllClients.ChatMessage.Data(chat.Message)
         );
 }
コード例 #8
0
 public void SayLocalChat(DistanceChat chat)
 {
     AddChat(chat);
     DistanceServerMain.GetEvent <Events.ClientToAllClients.ChatMessage>().Fire(
         UnityPlayer,
         new Distance::Events.ClientToAllClients.ChatMessage.Data(chat.Message)
         );
 }
コード例 #9
0
    public void ResendChat()
    {
        string chatString = GetChatLogString();

        Log.Debug($"Resending chat to {Name}:\n{chatString}");
        DistanceServerMain.GetEvent <Events.ServerToClient.SetServerChat>().Fire(
            UnityPlayer,
            new Distance::Events.ServerToClient.SetServerChat.Data(chatString)
            );
    }
コード例 #10
0
 public void SendLobbyServerInfo(NetworkPlayer player)
 {
     DistanceServerMain.GetEvent <Events.ServerToClient.SetServerName>().Fire(
         player,
         new Distance::Events.ServerToClient.SetServerName.Data(ServerName)
         );
     DistanceServerMain.GetEvent <Events.ServerToClient.SetMaxPlayers>().Fire(
         player,
         new Distance::Events.ServerToClient.SetMaxPlayers.Data(MaxPlayers)
         );
 }
コード例 #11
0
    public void SendPlayerToLobby(NetworkPlayer player)
    {
        var distancePlayer = GetDistancePlayer(player);

        distancePlayer.State   = DistancePlayer.PlayerState.LoadingLobbyScene;
        distancePlayer.LevelId = CurrentLevelId;
        DistanceServerMain.GetEvent <Events.ServerToClient.Request>().Fire(
            player,
            new Distance::Events.ServerToClient.Request.Data(Distance::ServerRequest.LoadLobbyScene)
            );
    }
コード例 #12
0
 public void SendLevelInfo(NetworkPlayer player)
 {
     DistanceServerMain.GetEvent <Events.ServerToClient.SetLevelName>().Fire(
         player,
         CurrentLevel.GetLevelNameData(HideLevelName, IsCustomPlaylist)
         );
     DistanceServerMain.GetEvent <Events.ServerToClient.SetGameMode>().Fire(
         player,
         CurrentLevel.GetGameModeData()
         );
 }
コード例 #13
0
ファイル: ReverseTag.cs プロジェクト: Ciastex/Distance-Server
 public void OnNeedToSyncLateClientToGameMode(DistancePlayer player)
 {
     DistanceServerMain.GetEvent <Events.ServerToClient.SyncMode>().Fire(
         player.UnityPlayer,
         new Distance::Events.GameMode.SyncMode.Data(Finished)
         );
     if (TaggedPlayer != null)
     {
         DistanceServerMain.GetEvent <Events.ServerToClient.TaggedPlayer>().Fire(
             player.UnityPlayer,
             new Distance::Events.ReverseTag.TaggedPlayer.Data(TaggedPlayer.Index, 0.0, TimeOfLastTag)
             );
     }
 }
コード例 #14
0
ファイル: ReverseTag.cs プロジェクト: Ciastex/Distance-Server
        public override void Start()
        {
            Connections.Add(
                DistanceServerMain.GetEvent <Events.Instanced.CarRespawn>().Connect(OnCarRespawn),
                DistanceServerMain.GetEvent <Events.ClientToServer.HitTagBubble>().Connect(OnHitTagBubble),
                Plugin.Server.OnNeedToSyncLateClientToGameMode.Connect(OnNeedToSyncLateClientToGameMode),
                Plugin.Server.OnCheckIfModeCanStartEvent.Connect(OnCheckIfModeCanStart),
                Plugin.OnCheckIfLevelCanAdvanceEvent.Connect(OnCheckIfModeCanAdvance),
                Plugin.Server.OnUpdateEvent.Connect(Update),
                Plugin.Server.OnPlayerConnectedEvent.Connect(OnPlayerConnected)
                );

            foreach (var player in Plugin.Server.DistancePlayers.Values)
            {
                player.AddExternalData(new ReverseTagData());
            }
        }
コード例 #15
0
 public void RequestLevelCompatibilityInfo(NetworkPlayer player)
 {
     DistanceServerMain.GetEvent <Events.ServerToClient.UpdatePlayerLevelCompatibilityStatus>().Fire(
         player,
         new Distance::Events.ServerToClient.UpdatePlayerLevelCompatibilityStatus.Data(player, Distance::LevelCompatabilityStatus.Unverified)
         );
     DistanceServerMain.GetEvent <Events.ServerToClient.RequestLevelCompatabilityInfo>().Fire(
         player,
         new Distance::Events.ServerToClient.RequestLevelCompatabilityInfo.Data()
     {
         gameMode_          = CurrentLevel.GameMode,
         levelCompatInfoID_ = CurrentLevelId,
         levelName_         = CurrentLevel.Name,
         relativeLevelPath_ = CurrentLevel.RelativeLevelPath
     }
         );
 }
コード例 #16
0
    public void SendPlayerToLevel(NetworkPlayer player)
    {
        SendLevelInfo(player);
        var distancePlayer = GetDistancePlayer(player);

        if (!UpdateLevelCompatabilityStatus(distancePlayer))
        {
            distancePlayer.State = DistancePlayer.PlayerState.WaitingForCompatibilityStatus;
            return;
        }
        distancePlayer.State   = DistancePlayer.PlayerState.LoadingGameModeScene;
        distancePlayer.Level   = CurrentLevel;
        distancePlayer.LevelId = CurrentLevelId;
        DistanceServerMain.GetEvent <Events.ServerToClient.Request>().Fire(
            player,
            new Distance::Events.ServerToClient.Request.Data(Distance::ServerRequest.LoadGameModeScene)
            );
    }
コード例 #17
0
    public System.Collections.IEnumerator StartModeAfterDelay(float delayTime)
    {
        StartingMode      = false;
        StartingModeDelay = false;

        foreach (var player in ValidPlayers)
        {
            if (!player.HasLoadedLevel(true))
            {
                player.Stuck = true;
            }
        }
        foreach (var player in ValidPlayers)
        {
            if (!player.Stuck && player.State == DistancePlayer.PlayerState.SubmittedGameModeInfo)
            {
                player.State = DistancePlayer.PlayerState.StartedMode;
            }
        }

        ModeStartTime  = Network.time + 7.0 + delayTime; // Shift start sooner/later
        ModeTimeOffset = -ModeStartTime;
        ModeTime       = 0.0;
        HasModeStarted = true;

        yield return(new WaitForSeconds(delayTime));

        foreach (var player in ValidPlayers)
        {
            if (player.State == DistancePlayer.PlayerState.StartedMode)
            {
                DistanceServerMain.GetEvent <Events.ServerToClient.StartMode>().Fire(
                    player.UnityPlayer,
                    new Distance::Events.ServerToClient.StartMode.Data(ModeStartTime, false)
                    );
            }
        }
        OnModeStartedEvent.Fire();
    }
コード例 #18
0
 public void UpdateCountdown(double value)
 {
     if (HasUnityPlayer && State == PlayerState.LoadedGameModeScene || State == PlayerState.SubmittedGameModeInfo || State == PlayerState.StartedMode)
     {
         if (value == -1.0)
         {
             if (Countdown != -1.0)
             {
                 DistanceServerMain.GetEvent <Events.ServerToClient.FinalCountdownCancel>().Fire(
                     UnityPlayer,
                     new Distance::Events.RaceMode.FinalCountdownCancel.Data()
                     );
             }
         }
         else
         {
             DistanceServerMain.GetEvent <Events.ServerToClient.FinalCountdownActivate>().Fire(
                 UnityPlayer,
                 new Distance::Events.RaceMode.FinalCountdownActivate.Data(value, (int)(value - Server.ModeTime + 0.5))
                 );
         }
     }
     Countdown = value;
 }
コード例 #19
0
ファイル: Entry.cs プロジェクト: REHERC/Distance-Server
        internal void RespondSummary()
        {
            Log.DebugLine("HTTP INFO SUMMARY", 0);
            var server = DistanceServerMain.Instance.Server;
            var writer = new JsonFx.Json.JsonWriter();

            var players = new List <PlayerJsonData>(server.DistancePlayers.Count);

            foreach (var player in server.DistancePlayers.Values)
            {
                var jsonPlayer = new PlayerJsonData();
                jsonPlayer.UnityPlayerGuid        = player.UnityPlayerGuid;
                jsonPlayer.State                  = player.State;
                jsonPlayer.Stuck                  = player.Stuck;
                jsonPlayer.LevelId                = player.LevelId;
                jsonPlayer.ReceivedInfo           = player.ReceivedInfo;
                jsonPlayer.Index                  = player.Index;
                jsonPlayer.Name                   = player.Name;
                jsonPlayer.JoinedAt               = player.JoinedAt;
                jsonPlayer.ValidatedAt            = player.ValidatedAt;
                jsonPlayer.Ready                  = player.Ready;
                jsonPlayer.LevelCompatibilityInfo = player.LevelCompatibilityInfo;
                jsonPlayer.LevelCompatibility     = player.LevelCompatability.ToString();
                jsonPlayer.Valid                  = player.Valid;
                if (IsPrivateMode)
                {
                    jsonPlayer.IpAddress = player.UnityPlayer.ipAddress;
                    jsonPlayer.Port      = player.UnityPlayer.port;
                }
                else
                {
                    jsonPlayer.IpAddress = "Hidden";
                    jsonPlayer.Port      = -1;
                }
                if (player.Car != null)
                {
                    var car     = player.Car;
                    var jsonCar = new CarJsonData();
                    jsonCar.CarColors = new float[][] {
                        new float[] { car.CarColors.primary_.r, car.CarColors.primary_.g, car.CarColors.primary_.b, car.CarColors.primary_.a },
                        new float[] { car.CarColors.secondary_.r, car.CarColors.secondary_.g, car.CarColors.secondary_.b, car.CarColors.secondary_.a },
                        new float[] { car.CarColors.glow_.r, car.CarColors.glow_.g, car.CarColors.glow_.b, car.CarColors.glow_.a },
                        new float[] { car.CarColors.sparkle_.r, car.CarColors.sparkle_.g, car.CarColors.sparkle_.b, car.CarColors.sparkle_.a },
                    };
                    jsonCar.CarName         = car.CarName;
                    jsonCar.Points          = car.Points;
                    jsonCar.Finished        = car.Finished;
                    jsonCar.FinishData      = car.FinishData;
                    jsonCar.FinishType      = car.FinishType;
                    jsonCar.Spectator       = car.Spectator;
                    jsonCar.Alive           = car.Alive;
                    jsonCar.WingsOpen       = car.WingsOpen;
                    jsonCar.Position        = new float[] { car.Rigidbody.position.x, car.Rigidbody.position.y, car.Rigidbody.position.z };
                    jsonCar.Rotation        = new float[] { car.Rigidbody.rotation.w, car.Rigidbody.rotation.x, car.Rigidbody.rotation.y, car.Rigidbody.rotation.z };
                    jsonCar.Velocity        = new float[] { car.Rigidbody.velocity.x, car.Rigidbody.velocity.y, car.Rigidbody.velocity.z };
                    jsonCar.AngularVelocity = new float[] { car.Rigidbody.angularVelocity.x, car.Rigidbody.angularVelocity.y, car.Rigidbody.angularVelocity.z };
                    jsonPlayer.Car          = jsonCar;
                }
                players.Add(jsonPlayer);
            }

            AutoServerJsonData autoServerJson = null;
            var autoServer = DistanceServerMain.Instance.GetPlugin <BasicAutoServer.BasicAutoServer>();

            if (autoServer != null)
            {
                autoServerJson                = new AutoServerJsonData();
                autoServerJson.IdleTimeout    = autoServer.IdleTimeout;
                autoServerJson.LevelTimeout   = autoServer.LevelTimeout;
                autoServerJson.WelcomeMessage = autoServer.WelcomeMessage;
                autoServerJson.AdvanceWhenStartingPlayersFinish = autoServer.AdvanceWhenStartingPlayersFinish;
                autoServerJson.LevelEndTime        = DistanceServerMain.NetworkTimeToUnixTime(autoServer.LevelEndTime);
                autoServerJson.StartingPlayerGuids = autoServer.StartingPlayerGuids.ToArray();
            }

            Log.DebugLine("HTTP INFO SUMMARY", 1);
            VotingJsonData votingJsonData = null;

            try
            {
                votingJsonData = RespondSummaryVote();
            }
            catch (Exception e) { } // TODO
            Log.DebugLine("HTTP INFO SUMMARY", 2);

            var chatLog = new List <ChatJsonData>();

            foreach (var chat in server.ChatLog)
            {
                var chatJson = new ChatJsonData();
                chatJson.Timestamp   = chat.Timestamp;
                chatJson.Chat        = chat.Message;
                chatJson.Sender      = chat.SenderGuid;
                chatJson.Guid        = chat.ChatGuid;
                chatJson.Type        = chat.ChatType.ToString();
                chatJson.Description = chat.ChatDescription;
                chatLog.Add(chatJson);
            }

            Response = writer.Write(new
            {
                Server = new
                {
                    CurrentLevelId               = server.CurrentLevelId,
                    MaxPlayers                   = server.MaxPlayers,
                    Port                         = server.Port,
                    ReportToMasterServer         = server.ReportToMasterServer,
                    MasterServerGameModeOverride = server.MasterServerGameModeOverride,
                    DistanceVersion              = server.DistanceVersion,
                    IsInLobby                    = server.IsInLobby,
                    HasModeStarted               = server.HasModeStarted,
                    ModeStartTime                = DistanceServerMain.NetworkTimeToUnixTime(server.ModeStartTime),
                },
                Level = new
                {
                    Name = server.CurrentLevel.Name,
                    RelativeLevelPath = server.CurrentLevel.RelativeLevelPath,
                    WorkshopFileId    = server.CurrentLevel.WorkshopFileId,
                    GameMode          = server.CurrentLevel.GameMode,
                },
                ChatLog      = chatLog,
                Players      = players,
                AutoServer   = autoServerJson,
                VoteCommands = votingJsonData,
            });
        }
コード例 #20
0
ファイル: ReverseTag.cs プロジェクト: Ciastex/Distance-Server
        public void Update()
        {
            if (Finished)
            {
                return;
            }
            if (Plugin.ServerStage != BasicAutoServer.Stage.Started)
            {
                return;
            }

            var playersInMode = GetModePlayers();

            if (playersInMode.Count <= 1)
            {
                IsInSinglePlayerMode = true;
                MaxModeTime         += UnityEngine.Time.deltaTime;
            }
            else if (IsInSinglePlayerMode)
            {
                IsInSinglePlayerMode = false;
                // When transitioning out of single-player mode, give the bubble to the new player to reset the timer:
                if (TaggedPlayer != null)
                {
                    var nonTagged = playersInMode.Find((player) => TaggedPlayer != player);
                    if (nonTagged != null)
                    {
                        TaggedPlayer.GetExternalData <ReverseTagData>().SecondsTagged = 0.0;
                        DistanceServerMainStarter.Instance.StartCoroutine(GiveTagBubbleSoon(TaggedPlayer, nonTagged));
                    }
                }
            }

            if (TaggedPlayer != null && !IsPlayerInMode(TaggedPlayer))
            {
                TagRandomLastPlacePlayer();
                if (!IsPlayerInMode(TaggedPlayer))
                {
                    TagPlayer(null);
                }
            }

            if (TaggedPlayer != null && !IsInSinglePlayerMode)
            {
                TaggedPlayer.GetExternalData <ReverseTagData>().AddSecondsTagged(UnityEngine.Time.deltaTime, WinTime);
            }

            var leader = GetFirstPlacePlayer();

            if (leader != Leader)
            {
                if (leader != null)
                {
                    var colorHex    = Distance::ColorEx.ColorToHexNGUI(Distance::ColorEx.PlayerRainbowColor(leader.Index));
                    var nameColored = $"[{colorHex}]{leader.Name}[-]";
                    var chat        = DistanceChat.Server("Vanilla:TakenTheLead", $"{nameColored} has taken the lead!");
                    chat.ChatType = DistanceChat.ChatTypeEnum.ServerVanilla;
                    Plugin.Server.SayChat(chat);
                }
                Leader = leader;
            }

            var leaderSecondsTagged = Leader == null ? 0.0 : Leader.GetExternalData <ReverseTagData>().SecondsTagged;

            if (leaderSecondsTagged >= WinTime || Plugin.Server.ModeTime >= MaxModeTime)
            {
                Finished = true;

                if (Leader != null)
                {
                    var networkFinishedData = new Distance::Events.ReverseTag.Finished.Data(Leader.Index, leaderSecondsTagged);
                    DistanceServerMain.GetEvent <Events.ServerToClient.ReverseTagFinished>().Fire(UnityEngine.RPCMode.Others, networkFinishedData);
                }

                Log.Debug($"Advancing level because win condition met: {leaderSecondsTagged} >= {WinTime} || {Plugin.Server.ModeTime} > {MaxModeTime}");
                Plugin.AdvanceLevel();
            }

            if (Finished)
            {
                return;
            }

            AdvanceLevelIfOnlyFinishedPlayers();

            var secondsLeft = Math.Max(0.0, Math.Min(WinTime - leaderSecondsTagged, MaxModeTime - Plugin.Server.ModeTime));

            if (secondsLeft <= 30 && !HasShown30SecondWarning)
            {
                HasShown30SecondWarning = true;
                var colorHex = Distance::ColorEx.ColorToHexNGUI(Distance::Colors.orangeRed);
                var chat     = DistanceChat.Server("Vanilla:TimeWarning", $"[{colorHex}]30 seconds left![-]");
                chat.ChatType = DistanceChat.ChatTypeEnum.ServerVanilla;
                Plugin.Server.SayChat(chat);
            }
            else if (secondsLeft <= 10 && !HasShown10SecondWarning)
            {
                HasShown10SecondWarning = true;
                var colorHex = Distance::ColorEx.ColorToHexNGUI(Distance::Colors.orangeRed);
                var chat     = DistanceChat.Server("Vanilla:TimeWarning", $"[{colorHex}]10 seconds left![-]");
                chat.ChatType = DistanceChat.ChatTypeEnum.ServerVanilla;
                Plugin.Server.SayChat(chat);
            }
        }
コード例 #21
0
 public override void Fire(UnityEngine.RPCMode target, Distance::IBitSerializable data)
 {
     DistanceServerMain.SendRPC("ReceiveServerToClientEvent", DistanceServerMain.ServerToClientEvents.IndexOf(this), target, data);
 }
コード例 #22
0
ファイル: Entry.cs プロジェクト: REHERC/Distance-Server
        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");
        }
コード例 #23
0
    ///

    public void Init()
    {
        DistanceServerMain.GetEvent <Events.ClientToServer.SubmitPlayerInfo>().Connect((data, info) =>
        {
            // ignore data.sender_, it should be sender
            var player          = GetDistancePlayer(info.sender);
            player.Name         = data.playerName_;
            player.ReceivedInfo = true;
            player.Index        = ValidPlayers.Count;
            player.ValidatedAt  = DistanceServerMain.UnixTime;
            ValidPlayers.Add(player);
            player.OnValidatedPreReplicationEvent.Fire();
            OnPlayerValidatedPreReplicationEvent.Fire(player);
            DistanceServerMain.GetEvent <Events.ServerToClient.AddClient>().Fire(
                RPCMode.Others,
                player.GetAddClientData(true)
                );
            player.OnValidatedEvent.Fire();
            OnPlayerValidatedEvent.Fire(player);
        });
        DistanceServerMain.GetEvent <Events.ClientToServer.CompletedRequest>().Connect((data, info) =>
        {
            // ignore data.networkPlayer_, it should be sender
            var distancePlayer = GetDistancePlayer(info.sender);
            if (data.request_ == Distance::ServerRequest.SubmitClientInfo)  // TODO: check if request was actually completed for security
            {
                distancePlayer.State = DistancePlayer.PlayerState.Initialized;
                SendPlayerToCurrentLocation(data.networkPlayer_);
            }
            else if (data.request_ == Distance::ServerRequest.LoadLobbyScene)
            {
                distancePlayer.Stuck = false;
                distancePlayer.State = DistancePlayer.PlayerState.LoadedLobbyScene;
                SendLobbyServerInfo(data.networkPlayer_);
                SendLevelInfo(data.networkPlayer_);
                RequestLevelCompatibilityInfo(data.networkPlayer_);
                RequestSubmitLobbyInfo(data.networkPlayer_);
                if (!IsInLobby)
                {
                    distancePlayer.State = DistancePlayer.PlayerState.CantLoadLevelSoInLobby;
                }
            }
            else if (data.request_ == Distance::ServerRequest.SubmitLobbyInfo)
            {
                distancePlayer.State = DistancePlayer.PlayerState.SubmittedLobbyInfo;
            }
            else if (data.request_ == Distance::ServerRequest.LoadGameModeScene)
            {
                distancePlayer.Stuck = false;
                distancePlayer.State = DistancePlayer.PlayerState.LoadedGameModeScene;
                if (distancePlayer.LevelId != CurrentLevelId)
                {
                    SendPlayerToLevel(distancePlayer.UnityPlayer);
                    return;
                }
                // fire CreatePlayer for sender for all existing cars (see WelcomeClientToGameMode.Data)
                foreach (var player in ValidPlayers)
                {
                    if (player.Car != null)
                    {
                        DistanceServerMain.GetEvent <Events.ServerToClient.CreatePlayer>().Fire(
                            data.networkPlayer_,
                            new Distance::Events.ServerToClient.CreatePlayer.Data(player.Car.GetPlayerInitializeData(), player.Car.GetPlayerLateInitializeData(), player.Index)
                            );
                        if (!player.Car.Finished && player.Car.Alive)
                        {
                            var gameObject = player.Car.Networker;
                            var transform  = gameObject.transform;
                            DistanceServerMain.GetEvent <Events.ServerToClient.CreateExistingCar>().Fire(
                                data.networkPlayer_,
                                new Distance::Events.ServerToClient.CreateExistingCar.Data(transform.position, transform.rotation, player.Car.WingsOpen, player.Index)
                                );
                        }
                    }
                }
                if (HasModeStarted)
                {
                    // TODO: sync game mode things if already started -- different for every game mode (see SyncLateClientToGameMode.Data and SyncMode.Data)
                    // NOTE: this should be handled entirely by the game mode programming, not by the base server programming
                    OnNeedToSyncLateClientToGameMode.Fire(distancePlayer);
                    if (distancePlayer.Countdown != -1.0)
                    {
                        DistanceServerMain.GetEvent <Events.ServerToClient.FinalCountdownActivate>().Fire(
                            data.networkPlayer_,
                            new Distance::Events.RaceMode.FinalCountdownActivate.Data(distancePlayer.Countdown, (int)(distancePlayer.Countdown - ModeTime))
                            );
                    }
                }
                RequestSubmitGameModeInfo(data.networkPlayer_);
            }
            else if (data.request_ == Distance::ServerRequest.SubmitGameModeInfo)
            {
                distancePlayer.State = DistancePlayer.PlayerState.SubmittedGameModeInfo;
                // If mode has not started, try to start it (check if all players have submitted info/loaded)
                // If mode has started, set state to StartedMode and fire StartClientLate
                // (see ServerLogic.OnEventCompletedRequest)
                if (StartingMode)
                {
                    AttemptToStartMode();
                }
                else
                {
                    distancePlayer.State = DistancePlayer.PlayerState.StartedMode;
                    DistanceServerMain.GetEvent <Events.ServerToClient.StartMode>().Fire(
                        data.networkPlayer_,
                        new Distance::Events.ServerToClient.StartMode.Data(ModeStartTime, true)
                        );
                }
            }
        });
        DistanceServerMain.GetEvent <Events.ClientToAllClients.ChatMessage>().Connect((data, info) =>
        {
            var chatTypeData   = new Tuple <DistanceChat.ChatTypeEnum, string>(DistanceChat.ChatTypeEnum.Unknown, "Unknown");
            var distancePlayer = GetDistancePlayer(info.sender);
            if (distancePlayer != null && distancePlayer.Valid)
            {
                chatTypeData = DistanceChat.DeduceChatType(data.message_, distancePlayer.Name);
            }
            var chat = new DistanceChat(data.message_)
            {
                SenderGuid      = info.sender.guid,
                ChatType        = chatTypeData.Item1,
                ChatDescription = chatTypeData.Item2,
            };
            AddChat(chat);
        });
        DistanceServerMain.GetEvent <Events.ClientToAllClients.SetReady>().Connect((data, info) =>
        {
            // ignore data.player_, it should be sender
            GetDistancePlayer(info.sender).Ready = data.ready_;
        });
        DistanceServerMain.GetEvent <Events.ClientToServer.SubmitLevelCompatabilityInfo>().Connect((data, info) =>
        {
            // ignore data.player_, it should be sender
            var distancePlayer = GetDistancePlayer(info.sender);
            distancePlayer.LevelCompatibilityInfo = new LevelCompatibilityInfo(data);
            Log.Debug($"Level compatibility versions test: {data.levelVersion_} : {CurrentLevel.LevelVersion}");
            // TODO: write proper level compat check code (the current computed version is incorrect, so version checking is ignored)
            DistanceServerMain.GetEvent <Events.ServerToClient.UpdatePlayerLevelCompatibilityStatus>().Fire(
                data.player_,
                new Distance::Events.ServerToClient.UpdatePlayerLevelCompatibilityStatus.Data(info.sender, distancePlayer.LevelCompatability)
                );
            if (distancePlayer.State == DistancePlayer.PlayerState.WaitingForCompatibilityStatus)
            {
                SendPlayerToLevel(distancePlayer.UnityPlayer);
            }
        });
        DistanceServerMain.GetEvent <Events.ClientToServer.SubmitPlayerData>().Connect((data, info) =>
        {
            // ignore data.player_, it should be sender
            var distancePlayer         = GetDistancePlayer(info.sender);
            distancePlayer.RestartTime = -1.0;
            distancePlayer.Car         = new DistanceCar(distancePlayer, data.data_);
            distancePlayer.Car.MakeNetworker();
            DistanceServerMain.GetEvent <Events.ServerToClient.CreatePlayer>().Fire(
                RPCMode.Others,
                new Distance::Events.ServerToClient.CreatePlayer.Data(distancePlayer.Car.GetPlayerInitializeData(), distancePlayer.Car.GetPlayerLateInitializeData(), distancePlayer.Index)
                );
        });
    }
コード例 #24
0
 public override void Fire(UnityEngine.NetworkPlayer target, Distance::IBitSerializable data)
 {
     DistanceServerMain.SendRPC("ReceiveBroadcastAllEvent", DistanceServerMain.ClientToClientEvents.IndexOf(this), target, data);
 }
コード例 #25
0
    public override void Awake()
    {
        Debug.LogError("Using Error to force Unity log to show...");
        ExecutableDirectory = new System.IO.DirectoryInfo(UnityEngine.Application.dataPath).Parent;
        Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
        Debug.unityLogger.filterLogType = LogType.Log;
        ServerDirectory = ExecutableDirectory;
        var launchArgs = Environment.GetCommandLineArgs();

        if (launchArgs.Length > 0)
        {
            List <CommandLineArg> finalArgs = new List <CommandLineArg>();
            string        name = "";
            List <string> args = new List <string>();
            for (int i = 0; i < launchArgs.Length; i++)
            {
                var lArg = launchArgs[i];
                if (lArg.Substring(0, 1) == "-")
                {
                    if (i != 0 || args.Count > 0)
                    {
                        finalArgs.Add(new CommandLineArg(name, args.ToArray()));
                    }
                    name = lArg;
                    args = new List <string>();
                }
                else
                {
                    args.Add(lArg);
                }
            }
            finalArgs.Add(new CommandLineArg(name, args.ToArray()));
            CommandLineArgs = finalArgs.ToArray();
        }

        Log.Info($"Target frame rate: {Application.targetFrameRate}");
        Application.targetFrameRate = 60;
        Log.Info($"New target frame rate: {Application.targetFrameRate}");

        foreach (var arg in CommandLineArgs)
        {
            if (arg.Name.ToLower() == "-serverdir" && arg.Arguments.Length > 0)
            {
                ServerDirectory = new System.IO.DirectoryInfo(arg.Arguments[0]);
                if (!ServerDirectory.Exists)
                {
                    Log.Error($"Server directory ({ServerDirectory}) does not exist! Not running server.");
                    return;
                }
            }
        }

        Log.Info($"Executable directory: {ExecutableDirectory}");
        Log.Info($"Server directory: {ServerDirectory}");

        ReadSettings();

        Instance = this;
        MasterServer.ipAddress     = "54.213.90.85";
        MasterServer.port          = 23466;
        Network.natFacilitatorIP   = "54.213.90.85";
        Network.natFacilitatorPort = 50005;

        View        = gameObject.GetComponent <NetworkView>();
        View.viewID = new NetworkViewID();

        Server = new DistanceServer();
        Server.Init();

        LoadPlugins();

        Log.WriteLine($"Starting server version {Server.DistanceVersion} on port {Server.Port} (UseNat: {Server.UseNat})");

        Network.InitializeServer(Server.MaxPlayers, Server.Port, Server.UseNat);
    }
コード例 #26
0
 public override void Fire(UnityEngine.RPCMode target, Distance::IBitSerializable data)
 {
     DistanceServerMain.SendRPC("ReceiveSerializeEvent", eventIndex, target, null, networkView);
 }
コード例 #27
0
 public override void ReceiveSerializeEvent(byte[] bytes, NetworkMessageInfo info)
 {
     DistanceServerMain.DebugBytes("ReceiveSerializeEvent", bytes, InstancedEvents);
     ReceiveRPC(bytes, InstancedEvents, info);
 }
コード例 #28
0
        public override void Start()
        {
            Log.Info("Basic Auto Server started!");
            Playlist.AddRange(OfficialPlaylist);
            Filters = new List <FilterWorkshopSearchDelegate>();
            ReadSettings();

            UnityEngine.MasterServer.dedicatedServer = ReportToMasterServerAsDedicatedServer;

            Server.MasterServerGameModeOverride = MasterServerGameModeOverride;
            Server.ServerName = ServerName;
            Server.MaxPlayers = MaxPlayers;
            Server.Port       = Port;
            Server.UseNat     = UseNat;
            if (ReportToMasterServerInitialDelay > 0)
            {
                Server.ReportToMasterServer = false;
                DistanceServerMainStarter.Instance.StartCoroutine(SetReportToMasterServerAfterDelay());
            }
            else
            {
                Server.ReportToMasterServer = ReportToMasterServer;
            }
            lastMasterServerRegistration = DistanceServerMain.UnixTime;
            if (PrivateServerPassword != null)
            {
                UnityEngine.Network.incomingPassword = PrivateServerPassword;
            }

            Server.OnPlayerConnectedEvent.Connect(player =>
            {
                player.Countdown = CountdownTime;
                player.OnCarAddedEvent.Connect(car =>
                {
                    car.AddExternalData(new LastMoveTimeData(DistanceServerMain.UnixTime));
                    OnCarAddedEvent.Fire(car);
                });
            });

            if (WelcomeMessage != null)
            {
                Server.OnPlayerValidatedEvent.Connect(player =>
                {
                    var message = WelcomeMessage;
                    if (message.Contains("$linkcode") && LinkCodeGetter != null)
                    {
                        message = message.Replace("$linkcode", LinkCodeGetter(player));
                    }
                    message = message.Replace("$player", player.Name);
                    if (!Server.HasModeStarted || player.Car != null)
                    {
                        Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("AutoServer:Welcome", message));
                    }
                    else
                    {
                        IEventConnection connection = null;
                        connection = player.OnCarAddedEvent.Connect(car =>
                        {
                            Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("AutoServer:Welcome", message));
                            connection.Disconnect();
                        });
                    }
                });
            }

            Server.OnLevelStartedEvent.Connect(() =>
            {
                CountdownTime = -1.0;
            });

            Server.OnModeStartedEvent.Connect(() =>
            {
                StartingPlayerGuids.Clear();
                foreach (var player in Server.ValidPlayers)
                {
                    if (player.Car != null)
                    {
                        player.Car.GetExternalData <LastMoveTimeData>().LastMoveTime = DistanceServerMain.UnixTime;
                        SetStartingPlayer(player.UnityPlayerGuid, true);
                    }
                }
                if (ServerStage == Stage.Starting)
                {
                    ServerStage = Stage.Started;
                }
            });

            OnAdvancingToNextLevel.Connect(() =>
            {
                if (TipMessages.Count > 0)
                {
                    var tip    = TipMessages[currentTip];
                    currentTip = (currentTip + 1) % TipMessages.Count;
                    Server.SayChat(DistanceChat.Server("AutoServer:Tip", tip));
                }
            });

            DistanceServerMain.GetEvent <Events.Instanced.Finished>().Connect((instance, data) =>
            {
                Log.WriteLine($"{((DistanceCar)instance).Player.Name} finished");
                AttemptToAdvanceLevel();
            });

            if (LoadWorkshopLevels)
            {
                DistanceServerMainStarter.Instance.StartCoroutine(DoLoadWorkshopLevels());
            }
            else
            {
                StartAutoServer();
            }
        }