コード例 #1
0
ファイル: Clients.cs プロジェクト: Reddit-Mud/RMUD
        internal static ClientAcceptanceStatus ClientConnected(NetworkClient Client)
        {
            var ban = ProscriptionList.IsBanned(Client.IPString);
            if (ban.Banned)
            {
                Core.LogError("Rejected connection from " + Client.IPString + ". Matched ban " + ban.SourceBan.Glob + " Reason: " + ban.SourceBan.Reason);
                return ClientAcceptanceStatus.Rejected;
            }

            ClientLock.WaitOne();

            var dummyPlayer = new Actor();
            dummyPlayer.CommandHandler = new LoginCommandHandler();
            Core.TiePlayerToClient(Client, dummyPlayer);

            MudObject.SendMessage(Client, Core.SettingsObject.Banner);
            MudObject.SendMessage(Client, Core.SettingsObject.MessageOfTheDay);

            ConnectedClients.Add(Client);

            Core.SendPendingMessages();

            ClientLock.ReleaseMutex();

            return ClientAcceptanceStatus.Accepted;
        }
コード例 #2
0
        public PasswordCommandHandler(Actor Actor, Action<Actor, String, String> AuthenticatingCommand, String UserName)
        {
            this.ParentHandler = Actor.CommandHandler;
            this.AuthenticatingCommand = AuthenticatingCommand;
            this.UserName = UserName;

            MudObject.SendMessage(Actor, "Password: ");
        }
コード例 #3
0
ファイル: SendMessage.cs プロジェクト: Reddit-Mud/RMUD
        public static void SendMessage(Actor Actor, String Message, params Object[] MentionedObjects)
        {
            if (String.IsNullOrEmpty(Message)) return;
            if (Core.SilentFlag) return;
            Core.OutputQueryTriggered = true;

            if (Actor != null && Actor.ConnectedClient != null)
                Core.PendingMessages.Add(new PendingMessage(Actor.ConnectedClient, Core.FormatMessage(Actor, Message, MentionedObjects)));
        }
コード例 #4
0
		public String Expand(Actor Viewer, MudObject Source)
		{
			switch (TextType)
			{
				case DescriptiveTextType.LambdaText:
					return LambdaText(Viewer, Source);
				case DescriptiveTextType.TaggedText:
					return RawText;
			}
			return null;
		}
コード例 #5
0
ファイル: TypeExtensions.cs プロジェクト: Reddit-Mud/RMUD
 public static void OfferQuest(this MudObject This, Actor Actor, MudObject Quest)
 {
     var player = Actor as Player;
     if (player != null)
     {
         MudObject.SendMessage(Actor, "[To accept this quest, enter the command 'accept quest'.]");
         if (player.GetProperty<MudObject>("active-quest") != null)
             MudObject.SendMessage(Actor, "[Accepting this quest will abandon your active quest.]");
         player.SetProperty("offered-quest", Quest);
     }
 }
コード例 #6
0
		void IOpenable.HandleOpen(Actor Actor)
		{
			if (!Open)
			{
				if (Actor.ConnectedClient != null)
					Mud.SendEventMessage(Actor, EventMessageScope.Single, "You open the door.\r\n");
				Mud.SendEventMessage(Actor, EventMessageScope.External, Actor.Short + " opens the door.\r\n");
			}

			Open = true;
		}
コード例 #7
0
		void IOpenable.HandleClose(Actor Actor)
		{
			if (Open)
			{
				if (Actor.ConnectedClient != null)
					Mud.SendEventMessage(Actor, EventMessageScope.Single, "You close the door.\r\n");
				Mud.SendEventMessage(Actor, EventMessageScope.External, Actor.Short + " closes the door.\r\n");
			}

			Open = false;
		}
コード例 #8
0
ファイル: Kick.cs プロジェクト: Reddit-Mud/RMUD
        public static void KickPlayer(Actor Player, Actor Actor)
        {
            if (Player.ConnectedClient != null)
            {
                Core.MarkLocaleForUpdate(Player);

                MudObject.SendMessage(Player, Actor.Short + " has removed you from the server.");
                Player.ConnectedClient.Disconnect();
                Clients.SendGlobalMessage(Actor.Short + " has removed " + Player.Short + " from the server.");
            }
        }
コード例 #9
0
ファイル: Login.cs プロジェクト: Reddit-Mud/RMUD
        public void Authenticate(Actor Actor, String UserName, String Password)
        {
            var existingAccount = Accounts.LoadAccount(UserName);
            if (existingAccount == null || Accounts.VerifyAccount(existingAccount, Password) == false)
            {
                MudObject.SendMessage(Actor, "Could not verify account.");
                return;
            }

            LoginCommandHandler.LogPlayerIn(Actor.ConnectedClient as NetworkClient, existingAccount);
        }
コード例 #10
0
ファイル: ExecuteCommand.cs プロジェクト: Reddit-Mud/RMUD
 public static void ProcessPlayerCommand(CommandEntry Command, PossibleMatch Match, Actor Actor)
 {
     ExecutingCommand = Match;
     try
     {
         ExecuteCommand(Command, Match, Actor);
     }
     finally
     {
         ExecutingCommand = null;
     }
 }
コード例 #11
0
ファイル: SendMessage.cs プロジェクト: Reddit-Mud/RMUD
        public static void SendExternalMessage(Actor Actor, String Message, params Object[] MentionedObjects)
        {
            if (String.IsNullOrEmpty(Message)) return;
            if (Core.SilentFlag) return;
            Core.OutputQueryTriggered = true;

            if (Actor == null) return;
            var location = Actor.Location as Room;
            if (location == null) return;

            foreach (var other in location.EnumerateObjects<Actor>().Where(a => !Object.ReferenceEquals(a, Actor) && (a.ConnectedClient != null)))
                Core.PendingMessages.Add(new PendingMessage(other.ConnectedClient, Core.FormatMessage(other, Message, MentionedObjects)));
        }
コード例 #12
0
ファイル: ExecuteCommand.cs プロジェクト: Reddit-Mud/RMUD
 /// <summary>
 /// Try to execute a command immediately. This does not bypass the before and after command rules. This is intended
 /// to be used by rules to implement implicit actions. For example, the 'go' command will attempt to open closed
 /// doors by calling
 ///     Core.Try("StandardActions:Open", Core.ExecutingCommand.With("SUBJECT", link), actor);
 /// </summary>
 /// <param name="CommandID">The ID of the command to try, assigned when the command is created.</param>
 /// <param name="Match"></param>
 /// <param name="Actor"></param>
 /// <returns>The result of the command's proceedural rules.</returns>
 public static PerformResult Try(String CommandID, PossibleMatch Match, Actor Actor)
 {
     var parentCommand = ExecutingCommand;
     try
     {
         var command = Core.DefaultParser.FindCommandWithID(CommandID);
         if (command == null) return PerformResult.Stop;
         return ExecuteCommand(command, Match, Actor);
     }
     finally
     {
         ExecutingCommand = parentCommand;
     }
 }
コード例 #13
0
        internal MatchedCommand ParseCommand(String Command, Actor Actor)
        {
			var tokens = new LinkedList<String>(Command.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries));
			var rootMatch = new PossibleMatch(tokens.First);

			//Find all objects in scope
			var matchContext = new MatchContext { ExecutingActor = Actor };

			foreach (var command in Commands)
			{
				var matches = command.Matcher.Match(rootMatch, matchContext);
				var firstGoodMatch = matches.Find(m => m.Next == null);
				if (firstGoodMatch != null) return new MatchedCommand(command, firstGoodMatch);
			}
            return null;
        }
コード例 #14
0
ファイル: Register.cs プロジェクト: Reddit-Mud/RMUD
        public void Authenticate(Actor Actor, String UserName, String Password)
        {
            var existingAccount = Accounts.LoadAccount(UserName);
            if (existingAccount != null)
            {
                MudObject.SendMessage(Actor, "Account already exists.");
                return;
            }

            var newAccount = Accounts.CreateAccount(UserName, Password);
            if (newAccount == null)
            {
                MudObject.SendMessage(Actor, "Could not create account.");
                return;
            }

            LoginCommandHandler.LogPlayerIn(Actor.ConnectedClient as NetworkClient, newAccount);
        }
コード例 #15
0
ファイル: MudCore.cs プロジェクト: Reddit-Mud/RMUD
 public static void AddPlayer(Actor Actor)
 {
     Actor.Rank = 500;
     GlobalRules.ConsiderPerformRule("player joined", Actor);
 }
コード例 #16
0
ファイル: Hatch.cs プロジェクト: Blecki/GaSiProMo
 public bool Match(string Word, Actor Actor)
 {
     return CouldMatch(Word);
 }
コード例 #17
0
		public void Perform(PossibleMatch Match, Actor Actor)
		{
			Processor(Match, Actor);
		}
コード例 #18
0
        public DisambigCommandHandler(
            Actor Actor, 
            CommandParser.MatchedCommand MatchedCommand, 
            ParserCommandHandler ParentHandler)
        {
            this.ParentHandler = ParentHandler;
            this.MatchedCommand = MatchedCommand;

            // Find an object parameter such that
            //  a) each match has a parameter with that name
            //  b) at least one match has a value different from the others

            var foundAmbiguousArgument = false;

            // Note that we iterate only over the arguments in the first match. If the first match doesn't have the
            // argument, that argument can't satisfy condition a above.
            foreach (var argument in MatchedCommand.Matches[0])
            {
                // It's only possible to disambiguate on MudObjects. If any match - including the first one - has
                // a value for that argument that is not a MudObject, disambiguation will fail.
                if (argument.Value is MudObject)
                {
                    var uniqueMatchables = new List<MudObject>();
                    var rejected = false;

                    foreach (var match in MatchedCommand.Matches)
                    {
                        if (match.ContainsKey(argument.Key) &&
                            match[argument.Key] is MudObject)
                        {
                            var matchableObject = match[argument.Key] as MudObject;
                            if (!uniqueMatchables.Contains(matchableObject))
                                uniqueMatchables.Add(matchableObject);
                        }
                        else
                        {
                            rejected = true;
                            break;
                        }
                    }

                    if (!rejected && uniqueMatchables.Count > 1)
                    {
                        // Disambiguate on this object.
                        DisambigArgument = argument.Key;
                        DisambigObjects = uniqueMatchables;

                        foundAmbiguousArgument = true;
                        break;
                    }
                }
            }

            if (foundAmbiguousArgument)
            {
                var response = new StringBuilder();
                response.Append("Which did you mean?\r\n");
                for (var i = 0; i < DisambigObjects.Count; ++i)
                    response.Append(String.Format("{0}: {1}\r\n", i, Core.GlobalRules.ConsiderValueRule<String>("printed name", Actor, DisambigObjects[i], "the")));
                MudObject.SendMessage(Actor, response.ToString());
            }
            else
            {
                MudObject.SendMessage(Actor, "I couldn't figure out how to disambiguate that command.");
            }
        }
コード例 #19
0
		bool Commands.ITakeRules.CanTake(Actor Actor)
		{
			return false;
		}
コード例 #20
0
		bool IOpenable.CanClose(Actor Actor)
		{
			return Open;
		}
コード例 #21
0
ファイル: NounList.cs プロジェクト: Reddit-Mud/RMUD
 public bool Match(String Word, Actor Actor)
 {
     foreach (var noun in Nouns)
         if (noun.Match(Word, Actor)) return true;
     return false;
 }
コード例 #22
0
ファイル: FormatMessage.cs プロジェクト: Reddit-Mud/RMUD
        /// <summary>
        /// Parse and format a message intended for a specific recipient.
        /// </summary>
        /// <param name="Recipient"></param>
        /// <param name="Message">The message, possibly containing specifiers.</param>
        /// <param name="Objects">Specifier indicies refer to this list of objects.</param>
        /// <returns></returns>
        public static String FormatMessage(Actor Recipient, String Message, params Object[] Objects)
        {
            //A leading @ indicates that the message should be interpretted as an entry in the global message table.
            if (Message[0] == '@') Message = Core.GetMessage(Message.Substring(1));

            var formattedMessage = new StringBuilder();
            var iterator = new StringIterator(Message);

            while (!iterator.AtEnd)
            {
                if (iterator.Next == '<') //We have located a specifier.
                {
                    var type = "";
                    var index = 0;
                    if (MessageFormatParser.ReadSpecifier(iterator, out type, out index))
                    {
                        if (index < 0 || index >= Objects.Length) continue; //A blank in the output is preferable to crashing.

                        #region Expand Specifier
                        if (type == "the" && Objects[index] is MudObject)
                        {
                            //'the' overrides the object's article property.
                            formattedMessage.Append(GlobalRules.ConsiderValueRule<String>("printed name", Recipient, Objects[index], "the"));
                        }
                        else if (type == "a" && Objects[index] is MudObject)
                        {
                            formattedMessage.Append(GlobalRules.ConsiderValueRule<String>("printed name", Recipient, Objects[index], (Objects[index] as MudObject).Article));
                        }
                        else if (type == "l") //No connective clause is used for this style of list. eg 1, 2, 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "");
                        }
                        else if (type == "lor") //Use or. eg 1, 2, or 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "or");
                        }
                        else if (type == "land") //Use and. eg 1, 2, and 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "and");
                        }
                        else if (type == "lnor") //Use nor. eg 1, 2, nor 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "nor");
                        }
                        else if (type == "s")
                        {
                            formattedMessage.Append(Objects[index].ToString());
                        }
                        #endregion
                    }
                }
                else
                {
                    formattedMessage.Append(iterator.Next);
                    iterator.Advance();
                }
            }

            Message = formattedMessage.ToString();
            formattedMessage.Clear();
            iterator = new StringIterator(Message);

            //Apply the ^ transform: Capitalize the letter following the ^ and remove the ^.
            while (!iterator.AtEnd)
            {
                if (iterator.Next == '^')
                {
                    iterator.Advance();
                    if (iterator.AtEnd) break;
                    formattedMessage.Append(new String(iterator.Next, 1).ToUpper());
                    iterator.Advance();
                }
                else
                {
                    formattedMessage.Append(iterator.Next);
                    iterator.Advance();
                }
            }

            return formattedMessage.ToString();
        }
コード例 #23
0
		bool IOpenable.CanOpen(Actor Actor)
		{
			return !Open;
		}
コード例 #24
0
ファイル: FormatMessage.cs プロジェクト: Reddit-Mud/RMUD
        /// <summary>
        /// Format a list of mud objects using commas and a coordinating conjunction. EG, into the form 'a, b, and c'.
        /// </summary>
        /// <param name="Recipient">The actor that will, eventually, see the output.</param>
        /// <param name="ListObject">Either a MudObject or a List<MudObject>. The actual items to format.</param>
        /// <param name="FormattedMessage">Append the formatted message to this StringBuilder.</param>
        /// <param name="CoordinatingConjunction">The word that separates the final item of a list from those proceeding it. EG, and, or, nor.</param>
        private static void FormatList(
            Actor Recipient, 
            Object ListObject, 
            StringBuilder FormattedMessage,
            String CoordinatingConjunction)
        {
            // ListObject can be a MudObject or a List<MudObject>. The algorithm expects a list, so transform it.
            List<MudObject> list = null;
            if (ListObject is MudObject)
            {
                list = new List<MudObject>();
                list.Add(ListObject as MudObject);
            }
            else
                list = ListObject as List<MudObject>;

            // If ListObject was neither a MudObject nor a List<MudObject>...
            if (list == null) return;

            for (int x = 0; x < list.Count; ++x)
            {
                FormattedMessage.Append(GlobalRules.ConsiderValueRule<String>("printed name", Recipient, list[x], list[x].Article));
                if (x != list.Count - 1) FormattedMessage.Append(", ");
                if (x == list.Count - 2 && !String.IsNullOrEmpty(CoordinatingConjunction)) FormattedMessage.Append(CoordinatingConjunction + " ");
            }
        }
コード例 #25
0
ファイル: NounList.cs プロジェクト: Reddit-Mud/RMUD
 public bool Match(String Word, Actor Actor)
 {
     if (!Value.Contains(Word)) return false;
     if (Available != null) return Available(Actor);
     return true;
 }
コード例 #26
0
ファイル: NounList.cs プロジェクト: Reddit-Mud/RMUD
 public bool Match(String Word, Actor Actor)
 {
     if (Word != Value) return false;
     if (Available != null) return Available(Actor);
     return true;
 }
コード例 #27
0
ファイル: ExecuteCommand.cs プロジェクト: Reddit-Mud/RMUD
 /// <summary>
 /// Actually carryout the command, following all of it's rules, including the before and after command rules.
 /// </summary>
 /// <param name="Command"></param>
 /// <param name="Match"></param>
 /// <param name="Actor"></param>
 /// <returns>The result of the command's procedural rules.</returns>
 private static PerformResult ExecuteCommand(CommandEntry Command, PossibleMatch Match, Actor Actor)
 {
     var result = PerformResult.Stop;
     Match.Upsert("COMMAND", Command);
     if (GlobalRules.ConsiderMatchBasedPerformRule("before command", Match, Actor) == PerformResult.Continue)
     {
         result = Command.ProceduralRules.Consider(Match, Actor);
         GlobalRules.ConsiderMatchBasedPerformRule("after command", Match, Actor);
     }
     GlobalRules.ConsiderPerformRule("after every command", Actor);
     return result;
 }
コード例 #28
0
ファイル: MudCore.cs プロジェクト: Reddit-Mud/RMUD
 public static void RemovePlayer(Actor Actor)
 {
     GlobalRules.ConsiderPerformRule("player left", Actor);
     Actor.ConnectedClient = null;
     MudObject.Move(Actor, null);
 }
コード例 #29
0
ファイル: MudCore.cs プロジェクト: Reddit-Mud/RMUD
 public static void TiePlayerToClient(Client Client, Actor Actor)
 {
     Client.Player = Actor;
     Actor.ConnectedClient = Client;
 }
コード例 #30
0
		public static void SendEventMessage(Actor Actor, EventMessageScope Scope, String Message)
		{
            DatabaseLock.WaitOne();

			switch (Scope)
			{
				//Send message only to the player
				case EventMessageScope.Single:
					{
						if (Actor == null) break;
						if (Actor.ConnectedClient == null) break;
						PendingMessages.Add(new RawPendingMessage(Actor.ConnectedClient, Message));
					}
					break;

				//Send message to everyone in the same location as the player
				case EventMessageScope.Local:
					{
						if (Actor == null) break;
						var location = Actor.Location as Room;
						if (location == null) break;
						foreach (var thing in location.Contents)
						{
							var other = thing as Actor;
							if (other == null) continue;
							if (other.ConnectedClient == null) continue;
							PendingMessages.Add(new RawPendingMessage(other.ConnectedClient, Message));
						}
					}
					break;

				//Send message to everyone in the same location EXCEPT the player.
				case EventMessageScope.External:
					{
						if (Actor == null) break;
						var location = Actor.Location as Room;
						if (location == null) break;
						foreach (var thing in location.Contents)
						{
							var other = thing as Actor;
							if (other == null) continue;
							if (Object.ReferenceEquals(other, Actor)) continue;
							if (other.ConnectedClient == null) continue;
							PendingMessages.Add(new RawPendingMessage(other.ConnectedClient, Message));
						}
					}
					break;
			}

            DatabaseLock.ReleaseMutex();
        }