Пример #1
0
        private void ServerRemote_SetRatesConfig(Dictionary <string, object> ratesDictionary)
        {
            var character = ServerRemoteContext.Character;

            if (!ServerOperatorSystem.SharedIsOperator(character) &&
                !(Server.Core.IsLocalServer &&
                  Server.Core.IsLocalServerHoster(character)))
            {
                throw new Exception("No access");
            }

            var ratesConfig = Server.Core.CreateNewServerRatesConfig();

            foreach (var serverRate in RatesManager.Rates)
            {
                if (ratesDictionary.TryGetValue(serverRate.Id, out var value))
                {
                    serverRate.SharedApplyToConfig(ratesConfig, value);
                }
            }

            if (Server.Core.ServerRatesConfig.IsMatches(ratesConfig))
            {
                Logger.Important("Server rates config change is not required");
                return;
            }

            Server.Game.SetServerConfig(ratesConfig);
            Logger.Important("Server rates config changed");
        }
Пример #2
0
        public static void Init(ICharacter currentCharacter)
        {
            Reset();

            isInitialized = true;

            if (currentCharacter is null)
            {
                return;
            }

            ClientCurrentCharacterHelper.Init(currentCharacter);
            InitCallback?.Invoke(currentCharacter);

            if (currentCharacter.ProtoCharacter == Api.GetProtoEntity <PlayerCharacter>() ||
                currentCharacter.ProtoCharacter == Api.GetProtoEntity <PlayerCharacterSpectator>() ||
                currentCharacter.ProtoCharacter == Api.GetProtoEntity <PlayerCharacterMob>())
            {
                InitGameplayMode(currentCharacter);
            }

            CreativeModeSystem.ClientRequestCurrentUserIsInCreativeMode();
            ServerOperatorSystem.ClientRequestCurrentUserIsOperator();

            InitEndCallback?.Invoke(currentCharacter);
        }
Пример #3
0
        private void ServerOnPlayerOnlineStateChangedHandler(ICharacter playerCharacter, bool isOnline)
        {
            ServerRefreshTotalPlayersCount();

            var name = playerCharacter.Name;
            var charactersDestination = Server.Characters.EnumerateAllPlayerCharacters(onlyOnline: true);

            this.CallClient(charactersDestination.ExceptOne(playerCharacter).ToList(),
                            _ => _.ClientRemote_OnlineStatusChanged(name, isOnline));

            if (!isOnline)
            {
                // player disconnected
                return;
            }

            // send to this character the list of online characters
            var onlineList = charactersDestination.Select(c => c.Name).ToList();

            this.CallClient(playerCharacter, _ => _.ClientRemote_OnlineList(onlineList));

            // provide info about the total players count only to a server operator
            var totalPlayersCount = ServerOperatorSystem.ServerIsOperator(playerCharacter.Name)
                                        ? serverLastTotalPlayersCount
                                        : 0;

            this.CallClient(playerCharacter,
                            _ => _.ClientRemote_TotalPlayerCharactersCountChanged(totalPlayersCount));
        }
Пример #4
0
        private static bool ServerIsOperatorOrModerator(ICharacter playerCharacter)
        {
            var name = playerCharacter.Name;

            return(ServerOperatorSystem.ServerIsOperator(name) ||
                   ServerModeratorSystem.ServerIsModerator(name));
        }
Пример #5
0
            public string ServerRemote_Teleport(Vector2D worldPosition)
            {
                try
                {
                    var character = ServerRemoteContext.Character;
                    if (character.ProtoCharacter is PlayerCharacterSpectator ||
                        ServerOperatorSystem.SharedIsOperator(character) ||
                        CreativeModeSystem.SharedIsInCreativeMode(character))
                    {
                        ServerTeleport(character, worldPosition);
                        var message = CreateResultMessage(character);
                        Logger.Important(message);
                        return(message);
                    }

                    return
                        ("Error: you're not in creative mode and not a spectator. You cannot use the teleport system.");
                }
                catch (Exception ex)
                {
                    var message = ex.Message;
                    Logger.Important(message);
                    return("Error: " + message);
                }
            }
        private static void PlayerLoginHook(string playerName, out string errorMessage)
        {
            if (ServerOperatorSystem.ServerIsOperator(playerName))
            {
                // operators cannot be banned, blocked or kicked
                errorMessage = null;
                return;
            }

            if (IsInBlackList(playerName))
            {
                errorMessage = CannotJoinBanned;
                return;
            }

            if (isWhiteListEnabled && !whiteList.Contains(playerName, StringComparer.OrdinalIgnoreCase))
            {
                errorMessage = CannotJoinNotInWhitelist;
                return;
            }

            if (IsKicked(playerName, out var secondsRemains))
            {
                errorMessage = string.Format(CannotJoinKicked,
                                             ClientTimeFormatHelper.FormatTimeDuration(secondsRemains));
                return;
            }

            // all checks passed successfully
            errorMessage = null;
        }
        public string Execute([CurrentCharacterIfNull] ICharacter character)
        {
            if (!ServerOperatorSystem.ServerIsOperator(character.Name))
            {
                return(character.Name + " is not a server operator");
            }

            ServerOperatorSystem.ServerRemove(character);
            return(character.Name + " removed from the server operators list");
        }
Пример #8
0
 protected override void WindowOpening()
 {
     base.WindowOpening();
     if (creativePanelCanvas != null)
     {
         creativePanelCanvas.Visibility = ServerOperatorSystem.ClientIsOperator()
             ? Visibility.Visible
             : Visibility.Collapsed;
     }
 }
Пример #9
0
        public string Execute([CurrentCharacterIfNull] ICharacter character)
        {
            if (ServerOperatorSystem.ServerIsOperator(character.Name))
            {
                return(character.Name + " is already a server operator");
            }

            ServerOperatorSystem.ServerAdd(character);
            return(character.Name + " added to the server operators list");
        }
Пример #10
0
        private void ControlWorldMapMouseRightButtonUpHandler(object sender, MouseButtonEventArgs e)
        {
            var mapPositionWithOffset = this.controlWorldMap.WorldMapController.PointedMapPositionWithOffset;

            this.CloseContextMenu();

            var contextMenu = new ContextMenu();

            contextMenu.Items.Add(new MenuItem()
            {
                Header  = ContextMenuCopyCoordinates,
                Command = new ActionCommand(
                    () => Api.Client.Core.CopyToClipboard(mapPositionWithOffset.ToString()))
            });

            var character = Api.Client.Characters.CurrentPlayerCharacter;

            if (character.ProtoCharacter is PlayerCharacterSpectator ||
                ServerOperatorSystem.SharedIsOperator(character) ||
                CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                var mapPositionWithoutOffset = this.controlWorldMap.WorldMapController.PointedMapPositionWithoutOffset;
                contextMenu.Items.Add(new MenuItem()
                {
                    Header  = ContextMenuTeleport,
                    Command = new ActionCommand(
                        () => this.CallTeleport(mapPositionWithoutOffset.ToVector2D()))
                });
            }

            var position = Mouse.GetPosition(this);

            contextMenu.PlacementRectangle = new Rect(position.X, position.Y, 0, 0);

            this.ContextMenu    = contextMenu;
            contextMenu.Closed += ContextMenuOnClosed;
            contextMenu.IsOpen  = true;

            void ContextMenuOnClosed(object s, RoutedEventArgs _)
            {
                contextMenu.Closed -= ContextMenuOnClosed;
                // remove context menu with the delay (to avoid teleport-on-click when context menu is closed)
                ClientTimersSystem.AddAction(
                    delaySeconds: 0.1,
                    () =>
                {
                    if (this.ContextMenu == contextMenu)
                    {
                        this.ContextMenu = null;
                    }
                });
            }
        }
Пример #11
0
        public override void ServerInitialize(IServerConfiguration serverConfiguration)
        {
            ServerPlayerSpawnManager.Setup(serverConfiguration);

            ServerOperatorSystem.Setup(serverConfiguration);

            serverConfiguration.SetupPlayerCharacterProto(
                Api.GetProtoEntity <PlayerCharacter>());

            serverConfiguration.SetupItemsContainerDefaultProto(
                Api.GetProtoEntity <ItemsContainerDefault>());
        }
Пример #12
0
        private void ServerOnPlayerOnlineStateChangedHandler(ICharacter playerCharacter, bool isOnline)
        {
            ServerRefreshTotalPlayersCount();

            var charactersDestination = Server.Characters
                                        .EnumerateAllPlayerCharacters(onlyOnline: true);

            // ReSharper disable once PossibleMultipleEnumeration
            this.CallClient(charactersDestination.ExceptOne(playerCharacter),
                            _ => _.ClientRemote_OnlineStatusChanged(
                                new Entry(playerCharacter.Name,
                                          ServerGetClanTag(playerCharacter)),
                                isOnline));

            if (!isOnline)
            {
                // player disconnected
                return;
            }

            // send to this character the list of online characters
            // ReSharper disable once PossibleMultipleEnumeration
            var onlineList = charactersDestination.Select(c => new Entry(c.Name,
                                                                         ServerGetClanTag(c)))
                             .ToList();

            // uncomment to test the online players list with some fake data
            //onlineList.Add(new Entry("Aaa1", "XXX"));
            //onlineList.Add(new Entry("Ссс1", "XXX"));
            //onlineList.Add(new Entry("Bbb1", "XXX"));
            //onlineList.Add(new Entry("Aaa", ""));
            //onlineList.Add(new Entry("Ссс", null));
            //onlineList.Add(new Entry("Bbb", ""));
            //onlineList.Add(new Entry("Aaa2", "YYY"));
            //onlineList.Add(new Entry("Ссс2", "YYY"));
            //onlineList.Add(new Entry("Bbb2", "YYY"));

            this.CallClient(playerCharacter, _ => _.ClientRemote_OnlineList(onlineList));

            // provide info about the total players count only to a server operator
            var totalPlayersCount = ServerOperatorSystem.ServerIsOperator(playerCharacter.Name)
                                        ? serverLastTotalPlayersCount
                                        : 0;

            this.CallClient(playerCharacter,
                            _ => _.ClientRemote_TotalPlayerCharactersCountChanged(totalPlayersCount));
        }
Пример #13
0
        private void MapClickHandler(Vector2D worldPosition)
        {
            if (this.ContextMenu != null)
            {
                // context menu is still exist, don't process this click
                return;
            }

            var character = ClientCurrentCharacterHelper.Character;

            if (character.ProtoCharacter is PlayerCharacterSpectator ||
                (CreativeModeSystem.ClientIsInCreativeMode() &&
                 ServerOperatorSystem.ClientIsOperator()))
            {
                this.CallTeleport(worldPosition);
            }
        }
Пример #14
0
        private static void PlayerLoginHook(string playerName, out string errorMessage)
        {
            if (ServerOperatorSystem.ServerIsOperator(playerName) ||
                ServerModeratorSystem.ServerIsModerator(playerName))
            {
                // operators/moderators cannot be blocked or kicked
                errorMessage = null;
                return;
            }

            if (IsInBlackList(playerName))
            {
                errorMessage = CannotJoinBanned;
                return;
            }

            if (IsWhiteListEnabled &&
                !WhiteList.Contains(playerName))
            {
                errorMessage = CannotJoinNotInWhitelist;
                return;
            }

            if (IsKicked(playerName,
                         out var secondsRemains,
                         out var message))
            {
                errorMessage = string.Format(CannotJoinKicked,
                                             ClientTimeFormatHelper.FormatTimeDuration(secondsRemains));

                if (!string.IsNullOrEmpty(message))
                {
                    errorMessage = message
                                   + Environment.NewLine
                                   + "[br][br]"
                                   + errorMessage;
                }

                return;
            }

            // all checks passed successfully
            errorMessage = null;
        }
Пример #15
0
        public static void ClientConfigureRatesOnServer(IServerRatesConfig ratesConfig)
        {
            if (Client.CurrentGame.ConnectionState != ConnectionState.Connected)
            {
                throw new Exception("Not connected");
            }

            var address       = Client.CurrentGame.ServerInfo.ServerAddress;
            var isLocalServer = address.IsLocalServer;

            if (!isLocalServer &&
                !ServerOperatorSystem.SharedIsOperator(ClientCurrentCharacterHelper.Character))
            {
                throw new Exception(
                          "Cannot change rates for current server - the player must be a server operator or connect to a local server");
            }

            instance.CallServer(_ => _.ServerRemote_SetRatesConfig(ratesConfig.ToDictionary()));
        }
Пример #16
0
        public static bool SharedIsModerator(ICharacter character)
        {
            if (ServerOperatorSystem.SharedIsOperator(character))
            {
                // all operators are moderators
                return(true);
            }

            if (character is null)
            {
                return(false);
            }

            if (IsServer)
            {
                return(ServerModerators.IsModerator(character.Name));
            }

            return(clientIsServerModerator &&
                   character == Client.Characters.CurrentPlayerCharacter);
        }
Пример #17
0
        public string Execute()
        {
            var player = this.ExecutionContextCurrentCharacter;

            if (player == null)
            {
                return("This command cannot be executed directly from the server console");
            }

            var stats = player.GetPublicState <PlayerCharacterPublicState>()
                        .CurrentStatsExtended;

            if (stats.HealthCurrent <= 0)
            {
                return("You're already dead.");
            }

            // ensure character is not invincible
            CharacterInvincibilitySystem.ServerRemove(player);

            if (!ServerOperatorSystem.SharedIsOperator(player))
            {
                // check cooldown
                var time = Server.Game.FrameTime;
                if (this.characterLastKillTime.TryGetValue(player, out var lastKillTime) &&
                    time < lastKillTime + CooldownSeconds)
                {
                    return(string.Format(
                               "You've already killed yourself recently... please wait for cooldown: {0} remaining.",
                               ClientTimeFormatHelper.FormatTimeDuration(lastKillTime + CooldownSeconds - time)));
                }

                this.characterLastKillTime[player] = time;
            }

            stats.ServerSetHealthCurrent(0);
            return("You've killed yourself.");
        }
Пример #18
0
        private static void ServerRefreshTotalPlayersCount()
        {
            var totalPlayersCount = Server.Characters.TotalPlayerCharactersCount;

            if (serverLastTotalPlayersCount == totalPlayersCount)
            {
                return;
            }

            serverLastTotalPlayersCount = totalPlayersCount;

            // provide the updated info about the total players count only to the server operators
            using var tempList = Api.Shared.GetTempList <ICharacter>();
            foreach (var character in Server.Characters.EnumerateAllPlayerCharacters(onlyOnline: true))
            {
                if (ServerOperatorSystem.ServerIsOperator(character.Name))
                {
                    tempList.Add(character);
                }
            }

            Instance.CallClient(tempList,
                                _ => _.ClientRemote_TotalPlayerCharactersCountChanged(serverLastTotalPlayersCount));
        }
Пример #19
0
 /// <summary>
 /// Returns true if character has the Operator role or it's null and we're on the server
 /// (it means the command is invoked from the server system console directly).
 /// </summary>
 public static bool ServerIsOperatorOrSystemConsole(ICharacter character)
 {
     return(ServerOperatorSystem.SharedIsOperator(character) ||
            character is null && Api.IsServer);
 }
Пример #20
0
        public string Execute(
            [CustomSuggestions(nameof(GetCommandNameSuggestions))]
            string searchCommand = null)
        {
            var allCommands = ConsoleCommandsSystem.AllCommands.ToList();

            if (Api.IsServer)
            {
                allCommands.RemoveAll(
                    // exclude client commands on Server-side
                    c => (c.Kind ^ ConsoleCommandKinds.Client) == default);
            }

            var currentCharacter = this.ExecutionContextCurrentCharacter;

            if (currentCharacter is not null)
            {
                var isOperator  = ServerOperatorSystem.SharedIsOperator(currentCharacter);
                var isModerator = ServerModeratorSystem.SharedIsModerator(currentCharacter);
                ConsoleCommandsSystem.SharedFilterAvailableCommands(allCommands, isOperator, isModerator);
            }

            var sb = new StringBuilder(capacity: 2047);

            sb.AppendLine().AppendLine();

            if (!string.IsNullOrEmpty(searchCommand))
            {
                var foundCommandsList =
                    allCommands.Where(
                        c => c.Name.StartsWith(searchCommand, StringComparison.OrdinalIgnoreCase) ||
                        c.Alias is not null &&
                        c.Alias.StartsWith(searchCommand, StringComparison.OrdinalIgnoreCase))
                    .ToList();
                if (foundCommandsList.Count == 0)
                {
                    sb.Append("No commands found.");
                    return(sb.ToString());
                }

                allCommands = foundCommandsList;
            }

            //AppendLegend(sb);
            //sb.AppendLine();
            sb.AppendLine("Commands: ");

            foreach (var consoleCommand in allCommands)
            {
                string prefix;
                switch (consoleCommand.Kind)
                {
                // add server suffix for server commands
                case ConsoleCommandKinds.ServerEveryone:
                case ConsoleCommandKinds.ServerOperator:
                case ConsoleCommandKinds.ServerModerator:
                    prefix = "/";
                    break;

                case ConsoleCommandKinds.ClientAndServerEveryone:
                case ConsoleCommandKinds.ClientAndServerOperatorOnly:
                    prefix = "(/)";
                    break;

                default:
                    prefix = string.Empty;
                    break;
                }

                AppendCommandInfo(sb, consoleCommand, prefix);
            }

            return(sb.ToString());
        }
Пример #21
0
        public string Execute(
            [CustomSuggestions(nameof(GetCommandNameSuggestions))]
            string searchCommand = null)
        {
            IEnumerable <BaseConsoleCommand> allCommands = ConsoleCommandsSystem.AllCommands;

            if (this.ExecutionContextCurrentCharacter != null &&
                !ServerOperatorSystem.SharedIsOperator(this.ExecutionContextCurrentCharacter))
            {
                // not a server operator - exclude server operator commands
                allCommands = allCommands.Where(c => c.Kind != ConsoleCommandKinds.ServerOperator);
            }

            var sb = new StringBuilder(capacity: 2047);

            sb.AppendLine().AppendLine();

            if (!string.IsNullOrEmpty(searchCommand))
            {
                var foundCommandsList =
                    allCommands.Where(
                        c => c.Name.StartsWith(searchCommand, StringComparison.OrdinalIgnoreCase) ||
                        c.Alias != null &&
                        c.Alias.StartsWith(searchCommand, StringComparison.OrdinalIgnoreCase))
                    .ToList();
                if (foundCommandsList.Count == 0)
                {
                    sb.Append("No commands found.");
                    return(sb.ToString());
                }

                allCommands = foundCommandsList;
            }

            //AppendLegend(sb);
            //sb.AppendLine();
            sb.AppendLine("Commands: ");

            foreach (var consoleCommand in allCommands)
            {
                string prefix;
                switch (consoleCommand.Kind)
                {
                // add server suffix for server commands
                case ConsoleCommandKinds.ServerEveryone:
                case ConsoleCommandKinds.ServerOperator:
                    prefix = "/";
                    break;

                case ConsoleCommandKinds.ClientAndServerEveryone:
                case ConsoleCommandKinds.ClientAndServerOperatorOnly:
                    prefix = "(/)";
                    break;

                default:
                    prefix = string.Empty;
                    break;
                }

                AppendCommandInfo(sb, consoleCommand, prefix);
            }

            return(sb.ToString());
        }
Пример #22
0
 public string Execute([CurrentCharacterIfNull] ICharacter character)
 {
     ServerOperatorSystem.ServerAdd(character);
     return(null);
 }
Пример #23
0
        public void Execute(ICharacter byCharacter, string[] args)
        {
            var sendNotification = Api.IsServer &&
                                   byCharacter is not null;

            try
            {
                var parsedArgs = this.ParseArguments(
                    byCharacter,
                    args,
                    throwExceptionOnUnparsedArgument: true,
                    successfullyParsedArgsCount: out _);
                var resultObj = this.MethodInfo.MethodInfo.Invoke(this.ConsoleCommand, parsedArgs);
                if (resultObj is not null)
                {
                    var result = resultObj.ToString();
                    Api.Logger.Important(
                        $"Console command \"{this.ConsoleCommand.Name}\" completed: {result}",
                        byCharacter);

                    if (sendNotification)
                    {
                        var maxLength = ServerOperatorSystem.ServerIsOperator(byCharacter.Name) ||
                                        ServerModeratorSystem.ServerIsModerator(byCharacter.Name)
                                            ? 30000
                                            : 5000;

                        if (result.Length > maxLength)
                        {
                            result = result.Substring(0, maxLength) + "... (server's response truncated)";
                        }

                        // send notification to this character
                        ConsoleCommandsSystem.ServerOnConsoleCommandResult(
                            byCharacter,
                            this.ConsoleCommand,
                            result);
                    }
                }
            }
            catch (ConsoleCommandWrongArgumentException ex)
            {
                var commandParameter = this.Parameters[ex.Index];
                var message          = new StringBuilder(capacity: 100)
                                       .Append(ex.IsMissing ? "Argument missing" : "Argument wrong/unknown value provided")
                                       .Append(" - argument #")
                                       .Append(ex.Index + 1)
                                       .Append(' ')
                                       .Append(commandParameter.Name).ToString();

                Api.Logger.Warning(message, byCharacter);

                if (sendNotification)
                {
                    // send notification to this character
                    NotificationSystem.ServerSendNotification(
                        byCharacter,
                        "Command cannot be executed: " + this.ConsoleCommand.Name,
                        message,
                        NotificationColor.Bad);
                }
            }
            catch (Exception ex)
            {
                ex = ex.InnerException ?? ex;
                Api.Logger.Warning(ex.Message, byCharacter);

                if (sendNotification)
                {
                    // send notification to this character
                    NotificationSystem.ServerSendNotification(
                        byCharacter,
                        "Command error: " + this.ConsoleCommand.Name,
                        ex.Message,
                        NotificationColor.Bad);
                }
            }
        }
Пример #24
0
 /// <summary>
 /// Returns true if character has the Operator role or it's null and we're on the server
 /// (it means the command is invoked from the server system console directly).
 /// </summary>
 public static bool ServerIsOperatorOrSystemConsole(ICharacter character)
 => ServerOperatorSystem.SharedIsOperator(character) ||
 character == null && Api.IsServer;