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!

duplicated Names / Double Names

Soteric

Knight
Code:
            List<PlayerMobile> players = new List<PlayerMobile>( ); //Initialize a PlayerMobile collection

            foreach( Mobile wm in World.Mobiles.Values )
            {
                 if( wm is PlayerMobile && !wm.Deleted ) //Filter Mobiles by PlayerMobile type
                     players.Add( (PlayerMobile)wm );
            }
                   
            foreach( PlayerMobile pm in players )
            {
                if( Insensitive.Equals(pm.RawName, name) ) //Case-insensitive string equality
                {
                    players.Clear(); //Clear the list before the method exits to free allocated memory
                    return false;
                }
            }
           
            players.Clear(); //Clear the list before the method exits to free allocated memory
            return true;
Vorspire, why so serious? :)
Code:
            foreach( Mobile wm in World.Mobiles.Values )
                 if( wm is PlayerMobile && !wm.Deleted && Insensitive.Equals(wm.RawName, name))
                     return false;

            return true;
 

Vorspire

Knight
Vorspire, why so serious? :)

Run your code on an active shard with hundreds of thousands of Mobiles and create a character or add a new mobile at the same time, you will get an exception because the World.Mobiles collection is modified during enumeration.
 

Soteric

Knight
Not exactly. Core.cs
Code:
while( m_Signal.WaitOne() )
				{
					Mobile.ProcessDeltaQueue();
					Item.ProcessDeltaQueue();

					Timer.Slice();
					messagePump.Slice();
Timer.Slice() invokes OnTick method of the timers. messagePump.Slice() processes network requests. They don't work in parallel.
 

Vorspire

Knight
If they weren't threaded, there wouldn't be any need for all of the thread safe code in either file.

Main.cs
Code:
			Timer.TimerThread ttObj = new Timer.TimerThread();
			timerThread = new Thread( new ThreadStart( ttObj.TimerMain ) );
			timerThread.Name = "Timer Thread";
 

Soteric

Knight
Sorry, by 'they' I ment timers and network requests. Timers themselves works in separate thread, you are right. But it's util thread which just handles timer internals (add, remove, put to queue when the time comes). Logic which can influence RunUO core (mobiles, item, etc.) invokes sequentially. There is no thread safe code in RunUO Scripts.
 

Vorspire

Knight
You're fairly certain about that?

Code:
private static Queue m_ChangeQueue = Queue.Synchronized( new Queue() );
http://msdn.microsoft.com/en-us/library/system.collections.queue.synchronized.aspx said:
Returns a Queue wrapper that is synchronized (thread safe).


Code:
lock ( m_Queue )
	m_Queue.Enqueue( t );
Code:
public static void Slice()
{
	lock ( m_Queue )
	{
http://msdn.microsoft.com/en-us/library/c5kehkcz(v=vs.71).aspx said:
lock ensures that one thread does not enter a critical section while another thread is in the critical section of code. If another thread attempts to enter a locked code, it will wait (block) until the object is released.

Anyway, I think this thread has been derailed enough, we can start a new topic about threading if you like ;)
 

Soteric

Knight
Yes, I'm sure about that. You have main thread which gets timers from m_Queue and invokes OnTick. And you also have TimerThread which puts timers to m_Queue when their time comes. m_Queue is shared between threads so you need a lock here. But you won't see any locks in Mobile, PlayerMobile, Item or any other classes responsible for processing client requests.

I agree that this is offtopic but I don't see a reason to start another thread. I ran out of arguments and give up :)
 

Miracle99

Squire
Vorspire,

Seems to be a little bit of a problem with the code from #12 (the optimize code).
I am getting a name change gump each time a player logs in to change their name. One player name is Vjaepadnty and if i log him out and back in, the name change gump comes up.

I originally thought it was working correctly but that was only because i was logging in duplicate persons and it was coming up , which it should.

The code from #11 (looks through all world mobiles) works perfectly and does not give a player the name change gump when logging in (unless there is in fact a duplicate name).

I went back through from my original files and posted each step to see where it was happening and its definately the "optimized code"
 

Vorspire

Knight
Just an oversight I guess, it's comparing playerA.Name to playerA.Name :D

Need to make sure the PlayerMobile 'wm' being checked is not the same instance as PlayerMobile 'm' when filtering players.

Code:
if( wm != m && wm is PlayerMobile && !wm.Deleted )

(I've edited #12 to reflect the changes)
 

Miracle99

Squire
Here is my working copy for anyone looking to add to their shard.
I included the NameChangeGump that was posted earlier in the thread.
I have also included a NameChangeDeed script to work along with this system.

I have commented in the files where the edits need to be made.

Many thanks to Vorspire for walking me through all of this and getting it working.
 

Attachments

  • NamingSystem.zip
    14.2 KB · Views: 28

The_Man

Sorceror
Oh... well that's simple. I'm seriously going to read up a lot on LINQ expressions because that is really convenient. Thanks. I've came across LINQ before in various tuts and stuff for C# and ASP but never really looked into it indepth.
 

Vorspire

Knight
A good thing to remember when using Linq is to use the method chain (like in my example), it can be formatted as a query but the performance drops off significantly.

Query:
Code:
foreach( NetState state in World.Mobiles.Values where m != null select m.NetState)
{
}

Method Chain:
Code:
foreach( NetState state in World.Mobiles.Values.Where( m => m != null ).Select( m => m.NetState ) )
{
}
 
Top