RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Email System Crash

LadyGaGa

Wanderer
System.FormatException: The specified string is not in the form required for an e-mail address.
at System.Net.Mime.MailBnfHelper.ReadMailAddress(String data, Int32& offset, String& displayName)
at System.Net.Mime.MailBnfHelper.ReadMailAddress(String data, Int32& offset)
at System.Net.Mail.MailAddressCollection.ParseValue(String addresses)
at System.Net.Mail.MailAddressCollection.Add(String addresses)
at Server.Misc.RegisterEmailClient.SendSingal(Object e)
at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)

Tried to duplicate it but failed.
 

Jeff

Lord
Hah, sure it does, worst email validation ever...
Code:
        public bool ValidateEmail(string s, string s2)
        {
            if (s == "" || s2 == "")
                return false;

            if (!s.Contains("@") || !s2.Contains("@"))
                return false;

            if (s != s2)
                return false;

            return true;
        }
At least 5-6 of the rules listed here can be broken still http://rumkin.com/software/email/rules.php

Best bet is to find a Regex (there are hundreds of them on the internet) to test the email address in that method i posted above.

For instance, using just '@' as the email, would probably break it... there is no check to see if there is even name@domain or a .com .net nothing...
 

Vorspire

Knight
MSDN lists all formats supported by the System.Net.MailAddress class.

Even using try-catch around the MailAddress constructor is better for testing that just letting it crash out though.
 

LadyGaGa

Wanderer
Isn't this system used in the uogamers shards? I also had another crash this time about password change

Code:
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Server.Gumps.ChangePasswordGump.OnResponse(NetState sender, RelayInfo info)
   at Server.Network.PacketHandlers.DisplayGumpResponse(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)
 

Jeff

Lord
Isn't this system used in the uogamers shards? I also had another crash this time about password change

Code:
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Server.Gumps.ChangePasswordGump.OnResponse(NetState sender, RelayInfo info)
   at Server.Network.PacketHandlers.DisplayGumpResponse(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)
This is NOT the system used on UOGamers. This entire system is riddled with flaws... you can crash it by added the email address @@@.

You need to post ChangePasswordGump.OnResponse code.
 

LadyGaGa

Wanderer
I am pretty sure its a similiar system even if not the same
 

Attachments

  • fghgfj_4-12_03.07.jpg
    fghgfj_4-12_03.07.jpg
    100.2 KB · Views: 14

LadyGaGa

Wanderer
Why isn't it released? The same system is used in all the runuo shards. Runuo is released, it only makes sense that this mail system should be released with it, doesn't it?

Anyways since there is a solid version of this mail system I would like it if I could get the codes for those crashing parts at least.
 

Jeff

Lord
Because its written for internal use. The custom scripts made for those servers aren't released because they were written for the UOGamers servers.... just like ALL the other servers that use custom scripts and don't release them. As for the crash i dont see any specific spot that jumps out at me as the problem, you need to run your server in debug mode to get the exact line number the crash happened on.
 

LadyGaGa

Wanderer
Here it is sir

Code:
System.FormatException: The specified string is not in the form required for an e-mail address.
   at System.Net.Mime.MailBnfHelper.ReadMailAddress(String data, Int32& offset, String& displayName)
   at System.Net.Mime.MailBnfHelper.ReadMailAddress(String data, Int32& offset)
   at System.Net.Mail.MailAddressCollection.ParseValue(String addresses)
   at System.Net.Mail.MailAddressCollection.Add(String addresses)
   at Server.Misc.RegisterEmailClient.SendSingal(Object e) in c:\Documents and Settings\Administrator\Desktop\Server\Scripts\XX Custom\PlayerCommands\Register Email\EmailClient.cs:line 103
   at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)

Code:
        private static void SendSingal(object e)
        {
            EmailEventArgs eea = (EmailEventArgs)e;

            string to = (string)eea.To;
            string sub = (string)eea.Subject;
            string msg = (string)eea.Message;

            mm.To.Add(to); //line 103
            mm.Subject += " " + sub;
            mm.Body = msg;

            try
            {
                client.Send(mm);
            }
            catch { }
            mm.To.Clear();
            mm.Body = "";
            mm.Subject = ServerName;

            return;
        }
 

Jeff

Lord
This error has already been explained to you and is different from the previous one we were talking about. The "to" email address is invalid and must be a correct email address. You need to write code to restrict the users from entering in invalid email addresses.
 

LadyGaGa

Wanderer
Here is the other one

Code:
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Server.Gumps.ChangePasswordGump.OnResponse(NetState sender, RelayInfo info) in c:\Documents and Settings\Administrator\Desktop\Server\Scripts\XX Custom\PlayerCommands\Register Email\Gumps\ChangePasswordGump.cs:line 83
   at Server.Network.PacketHandlers.DisplayGumpResponse(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)

Code:
using System;
using Server;
using Server.Commands;
using Server.Items;
using Server.Mobiles;
using System.Collections;
using System.Collections.Generic;
using Server.Accounting;
using Server.Network;
using Server.Misc;
using Server.Multis;
using Server.Targeting;
using Server.Gumps;
using System.Net.Mail;
using System.Threading;
using System.Net;

namespace Server.Gumps
{
    public class ChangePasswordGump : Gump
    {
        public ChangePasswordGump() : base(0, 0)
        {
            Closable = true;
            Dragable = true;
            Resizable = false;

            AddBackground( 203, 176, 415, 171, 9300 );
            AddBackground(209, 233, 402, 6, 9350);
            AddLabel(350, 182, 0, "Change Password");

            AddLabel(211, 208, 0, "Old PW:");
            AddImage(332, 204, 1143);
            AddTextEntry(340, 204, 257, 25, 0, 2, "");

            AddLabel(215, 249, 0, "New PW:");
            AddImage(333, 245, 1143);
            AddTextEntry(341, 246, 257, 25, 0, 3, "");

            AddLabel(218, 285, 0, "New PW:");
            AddImage(333, 279, 1143);
            AddTextEntry(341, 280, 256, 25, 0, 4, "");

            AddButton(277, 316, 4005, 4006, 1, GumpButtonType.Reply, 0);
            AddLabel(309, 317, 0, "OK");
        }

        public bool ValidatePassword(PlayerMobile m, string old, string new1, string new2)
        {
            Account acct = (Account)m.Account;

            if (!acct.CheckPassword(old))
                return false;
            if (new1 == "" || new2 == "")
                return false;
            if (new1 != new2)
                return false;

            return true;
        }

        public override void OnResponse( NetState sender, RelayInfo info )
        {
            PlayerMobile from = (PlayerMobile)sender.Mobile;

            Account acct = (Account)from.Account;

            string key = (string)acct.Username;

            switch (info.ButtonID)
            {
                case 0:
                    {
                        from.SendMessage("You choose to change you password.");
                        break;
                    }
                case 1:
                    {
                        TextRelay txt = (TextRelay)info.GetTextEntry(2);
                        string s = (string)txt.Text.Trim();

                        TextRelay txt2 = (TextRelay)info.GetTextEntry(3);
                        string s2 = (string)txt2.Text.Trim(); // line 83!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                        TextRelay txt3 = (TextRelay)info.GetTextEntry(4);
                        string s3 = (string)txt3.Text.Trim();

                        if (ValidatePassword(from, s, s2, s3))
                        {
                            acct.SetPassword(s2);
                            from.SendMessage("Your password has been changed.");

                            string msg = "Your new password: \n\n" + s2 + "\n\n Account:\n\n" + acct.Username + "\n\n This email send to prevent hacks. Time of the email: " + DateTime.Now.ToString() + " .\n \n Thank You \n \n ";
                            string email = (string)EmailHolder.Emails[acct.Username];
                            EmailEventArgs eea = new EmailEventArgs(true, null, email, "Your Password Changed", msg);
                            RegisterEmailClient.SendMail(eea);
                        }
                        else
                        {
                            from.SendMessage("Your old password wasn't true or your 2nd password was incorrect..");
                        }

                        break;
                    }
            }
        }
    }
}
 

Jeff

Lord
Ah ya... so you are doing txt2.Text.Trim() but Text is null, so you need to add a check (and should probably add the same check for each of the TextRelay values.

Code:
TextRelay txt2 = (TextRelay)info.GetTextEntry(3);
string s2 = string.Empty;

if(txt2.Text != null)
    s2 = txt2.Text.Trim();
 

LadyGaGa

Wanderer
Here is my little edit to prevent %90 of the crashes. I know that this is still not fool proof. I would appreciate it if there are more things I could add here?

And Vorspire , about that try-catch method, can you implant that in this script if it is not too much to ask?

Thanks
Code:
        public bool ValidateEmail(string s, string s2)
        {
            if (s == "" || s2 == "")
                return false;

            if (!s.Contains("@") || !s2.Contains("@"))
                return false;

            if (s != s2)
                return false;
            //--
            if (!s.Contains(".com") || !s2.Contains(".com"))
                {
                if (!s.Contains(".net") || !s2.Contains(".net"))
                    return false;
                }

            if (!s.Contains("hotmail") || !s2.Contains("hotmail"))
                {
                if (!s.Contains("gmail") || !s2.Contains("gmail"))
                    {
                    if (!s.Contains("windowslive") || !s2.Contains("windowslive"))
                        return false;
                    }
                }
            //--
            return true;
        }
 

Jeff

Lord
Here is a more fullproof way to check the email. Regular Expressions are a big help ;)
Code:
public bool IsValidEmail(string email)
{
    if(string.IsNullOrEmpty(email))
        return false;

    const string regexString = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
    return Regex.IsMatch(email, regexString);
}
 

Vorspire

Knight
The method I've used here doesn't require regex, although regex may be better for configuration, I haven't had any problems with this so far.

Code:
public static bool Validate( string email )
{
     MailAddress ma;
     return Validate( email, out ma );
}

public static bool Validate( string email, out MailAddress ma )
{
     try
     {
          ma = new MailAddress( email );
          return true;
     }
     catch
     {
          ma = null;
          return false;
     }
}

The MailAddress class should allow you to access all parts of a fully qualified email address.
 

Jeff

Lord
The method I've used here doesn't require regex, although regex may be better for configuration, I haven't had any problems with this so far.

Code:
public static bool Validate( string email )
{
     MailAddress ma;
     return Validate( email, out ma );
}

public static bool Validate( string email, out MailAddress ma )
{
     try
     {
          ma = new MailAddress( email );
          return true;
     }
     catch
     {
          ma = null;
          return false;
     }
}

The MailAddress class should allow you to access all parts of a fully qualified email address.
Using a try catch is amateur man... worst ever ;)
 
Top