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!

Some quick help with arrays and lists

typhoonbot

Sorceror
No I am more than happy to make a "Jail System command Stone" that wont be a problem.

Have you got any answers with regards to my previous post ^^ ?

Thanks a lot for this help :)
 

typhoonbot

Sorceror
Ahh, damn cross posts :mad:

Uhm, I am still getting these errors with this script:

CS0120: Line 136: An object reference is required for the nonstatic field, m
ethod, or property 'Server.Commands.JailingSystem.m_inMates'

CS0120: Line 211: An object reference is required for the nonstatic field, m
ethod, or property 'Server.Commands.JailingSystem.OnTick(Server.Mobile)'

this is line 136:

Code:
return m_inMates.ContainsKey( from );

and this is line 211:

Code:
if ( JailingSystem.OnTick( Jailed ) ) //if the mobile is free, timer stops

thanks :)
 

Gargouille

Sorceror
First, as IsInMate is static, it does not care about instance, but must only refer to JailSystem class. The error you got means from which instance of JailSystem could I refer ?

Code:
public static bool IsInMate( Mobile from ) 
		{
			return m_inMates.ContainsKey( from );
		}

Just declare m_inMates as static to solve that problem. (static means that you don't have a different m-inMates for each instance of your stone, but just one, used by every instances)

And declare JailSystem OnTick method as static too, to solve the other problem.

And RemoveInMate too..
 

typhoonbot

Sorceror
Hmmm to fix this error:

CS0120: Line 126: An object reference is required for the nonstatic field, m
ethod, or property 'Server.Commands.JailingSystem.RemoveInMate(Server.Mobile)'

may I make my RemoveInMate method static as well:

public static void RemoveInMate( Mobile from )
{
if( m_inMates.ContainsKey( from ) )
{
from.Location = (m_inMates[from]).Posi;//go to original location
m_inMates.Remove( from );
}
}
 

typhoonbot

Sorceror
Okay, the server has compiled, I will do extensive testing, and post here if I have any further problems. IE: crashes :mad:

If I do not have any further problems, thank you very much for all your help and dedication, I really do appreciate it. New Knowledge is always good knowledge ;)

Regards
 

typhoonbot

Sorceror
I am having a problem with the deserialization of this system now, I just get this error when attempting to reboot server:

Before I forget, surely resuming the timer for each jailed mobile also needs to happen in the deserialization method ?

World: Loading...An error was encountered while loading a saved object
- Type: Server.Commands.JailingSystem
- Serial: 0x40001685
Delete the object? (y/n)
Delete all objects of that type? (y/n)
After pressing return an exception will be thrown and the server will terminate

Error:
System.Exception: Load failed (items=True, mobiles=False, guilds=False, type=Ser
ver.Commands.JailingSystem, serial=0x40001685) ---> System.ArgumentOutOfRangeExc
eption: Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Tick
s.
Parameter name: ticks
at System.DateTime..ctor(Int64 ticks)
at Server.BinaryFileReader.ReadDateTime()
at Server.Commands.JailingSystem.Deserialize(GenericReader reader) in c:\LoK
Server Files\Legends of Kaine Server\Scripts\Customs\Jailing System\Jail System.
cs:line 243
at Server.World.Load()
--- End of inner exception stack trace ---
at Server.World.Load()
at Server.ScriptCompiler.Compile(Boolean debug, Boolean cache)
at Server.Core.Main(String[] args)
This exception is fatal, press return to exit

Here is my Serialization and Deserialization methods:

Code:
public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

   			if( m_inMates != null ) 
   			{ 
      			writer.Write( true ); 
      			writer.Write( (int) m_inMates.Count );

				foreach( KeyValuePair<Mobile, MobileFields> kvp in m_inMates )
				{
					writer.Write( kvp.Key.Serial );	// Notice how we use Serial
					writer.Write( (Mobile) kvp.Key ); //Mobile
					writer.Write( (DateTime) kvp.Value.JailedTime );
					writer.Write( (DateTime) kvp.Value.ReleaseTime );
					writer.Write( (Point3D) kvp.Value.Posi );
					writer.Write( (Map) kvp.Value.map );
					writer.Write( (string) kvp.Value.Reason );
				}
			} 
			else 
			{ 
				writer.Write( false ); 
			} 
		}

		public override void Deserialize( GenericReader reader ) 
		{ 
			base.Deserialize( reader ); 
 			int version = reader.ReadInt();
 			
 			switch( version )
 			{
 				case 0:
 					{
 						int count = reader.ReadInt(); 

						for( int i = 0; i < count; i++ )
						{
							m_inMates.Add( reader.ReadMobile(), new MobileFields( reader.ReadDateTime(), reader.ReadDateTime(), reader.ReadPoint3D(), reader.ReadMap(), reader.ReadString() ));
						}
						break;
 					}
 			}
		}
 

Lichtblitz

Sorceror
This is what you save:

Code:
(bool)
(int)

LOOP
(Serial)
(Mobile)
(DateTime)
(DateTime)
(Point3D)
(Map)
(string)
END LOOP

This is what you read:

Code:
(int)
(int)

LOOP
(Mobile)
(DateTime)
(DateTime)
(Point3D)
(Map)
(String)
END LOOP

There are several things that don't match.

  • Don't serialize the "Serial"
  • Serialize the version!
  • Don't serialize the bool (a serialized count of 0 would be sufficient)


EDIT: Yes, the timers have to be resumed in deserialization.
 

Gargouille

Sorceror
Hi,

As Lichtblitz show you, you need to read exactly what you wrote...

And you don't need that:
Code:
if( m_inMates != null ) 
   			{ 
      			writer.Write( true ); 

else return false;

If m_inMates is null, you will write a count of 0, and the foreach loop will not loop, that's all.

If you really want your timers to reboot with the server, you have to serialize the left time before the timer tick (Begin+Delay)-DateTime.Now

And then in Deserialize, to launch a new timer, with that value for TimeSpan arg...

You can do it in the m_inMates loops...
 

typhoonbot

Sorceror
Hi, thanks for the replies...This is how my two methods look now:

Code:
public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

  
      		writer.Write( (int) m_inMates.Count );

			foreach( KeyValuePair<Mobile, MobileFields> kvp in m_inMates )
			{
				writer.Write( (Mobile) kvp.Key ); //Mobile
				writer.Write( (DateTime) kvp.Value.JailedTime );
				writer.Write( (DateTime) kvp.Value.ReleaseTime );
				writer.Write( (Point3D) kvp.Value.Posi );
				writer.Write( (Map) kvp.Value.map );
				writer.Write( (string) kvp.Value.Reason );
			}
		} 

		public override void Deserialize( GenericReader reader ) 
		{ 
			base.Deserialize( reader ); 
 			int version = reader.ReadInt();
 			
 			switch( version )
 			{
 				case 0:
 					{
						for( int i = 0; i < version; i++ )
						{
							m_inMates.Add( reader.ReadMobile(), new MobileFields( reader.ReadDateTime(), reader.ReadDateTime(), reader.ReadPoint3D(), reader.ReadMap(), reader.ReadString() ));
						}
						break;
 					}
 			}
		}

The server loads fine now, but when it has loaded, all the players who were currently in jail are released ? I think this is because they are no longer in the m_inMates dictionary...EDIT : Because in my OnLogin method for mobiles, I check to see if they are not part of the m_inMates dictionary and are in a "JAIL" region, they must be released (as setting a mobile's location property when they are offline does not move them there).

Why would this occur, and could you maybe give me some pointers in code form of how I would resume the timer on server start-up, I am really new to timers :eek:

Thanks
 

Lichtblitz

Sorceror
You were missing the part in red
typhoonbot;803824 said:
Code:
public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

  			[COLOR="Red"]writer.Write( (int)0 ); // version[/COLOR]
      			writer.Write( (int) m_inMates.Count );

			foreach( KeyValuePair<Mobile, MobileFields> kvp in m_inMates )
			{
				writer.Write( (Mobile) kvp.Key ); //Mobile
				writer.Write( (DateTime) kvp.Value.JailedTime );
				writer.Write( (DateTime) kvp.Value.ReleaseTime );
				writer.Write( (Point3D) kvp.Value.Posi );
				writer.Write( (Map) kvp.Value.map );
				writer.Write( (string) kvp.Value.Reason );
			}
		} 

		public override void Deserialize( GenericReader reader ) 
		{ 
			base.Deserialize( reader ); 
 			int version = reader.ReadInt();
 			
 			switch( version )
 			{
 				case 0:
 					{
						[COLOR="Red"]for( int i = 0; i < reader.ReadInt(); i++ )[/COLOR]
						{
							m_inMates.Add( reader.ReadMobile(), new MobileFields( reader.ReadDateTime(), reader.ReadDateTime(), reader.ReadPoint3D(), reader.ReadMap(), reader.ReadString() ));
						}
						break;
 					}
 			}
		}

Please show us your current timers. It depends on how their classes look like.
 

typhoonbot

Sorceror
lol Gargouille did a lot of my timer for me, so forgive me if I am not sure what is going on :eek:

Here is the timer class:

Code:
public class JailingTimer : Timer
	{
		private Mobile Jailed;//this is accessible in OnTick
		
		public JailingTimer(Mobile jailed)//you take a reference to the mobile jailed
			: base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ) )
		{
			Priority = TimerPriority.FiftyMS;
			
			Jailed = jailed; //assign the value to the private variable Jailed (which is accessible in OnTick)
		}

		protected override void OnTick() //every 5 seconds executes code in {}
		{
			if ( JailingSystem.OnTick( Jailed ) ) //if the mobile is free, timer stops
			{
				Stop();
			}
		}
	}

This was a custom bool OnTick method added to my Jailing System class:

Code:
public static bool OnTick(Mobile ToBeFree)
		{
			if( IsInMate( ToBeFree ) )
			{
				if( ( m_inMates[ToBeFree] ).ReleaseTime < DateTime.Now )
				{
					RemoveInMate( ToBeFree );
					return true;
				}
				return false;
			}
			return false;
		}

In my AddInMate method, I start the timer for each InMate added like this:

Code:
Timer timer = new JailingTimer( from );
			timer.Start();

Hope thats all you need :cool:
 

Gargouille

Sorceror
Maybe I not show you the best timer you need (it's a speed copy paste)

Here you got a Timer which ticks every 5 seconds, and then test if delay is finsih...

The best way should be a Timer which ticks just at the end of the delay...

Something like :
Code:
public class JailingTimer : Timer
	{
		private Mobile Jailed;//this is accessible in OnTick
		
		public JailingTimer(Mobile jailed[COLOR="Red"], TimeSpan delay[/COLOR])//you take a reference to the mobile jailed
			: base([COLOR="Red"]delay[/COLOR] )
		{
			Priority = TimerPriority.FiftyMS;
			
			Jailed = jailed; //assign the value to the private variable Jailed (which is accessible in OnTick)
		}

		protected override void OnTick() //every 5 seconds executes code in {}
		{
	                 JailingSystem.OnTick( Jailed );
                         Stop();		

[COLOR="PaleGreen"]
//REMOVE THAT PART you does not need to test if time is finish cause it ticks just when time is finish
if ( JailingSystem.OnTick( Jailed ) ) //if the mobile is free, timer stops
			{
				Stop();
			}[/COLOR]
		}
	}

Then JailSystem.Ontick does not need to declare bool anymore, let it declare void :
Code:
public static [COLOR="Red"]void[/COLOR] OnTick(Mobile ToBeFree)
		{
			if( IsInMate( ToBeFree ) )
                             RemoveInMate( ToBeFree );
	     }

And now that your Timer needs a second argument (delay), call it like that :
Code:
Timer timer = new JailingTimer( from[COLOR="Red"], delay[/COLOR] );
			timer.Start();

And now, what is delay ?
All that stuff would say that in MobileFields, you does not need ReleaseTime as DateTime anymore. Replace it by a TimeSpan delay.

And then, in your serialization, just save a value to begin with after reboot. That value is time left.

IMHO
 

typhoonbot

Sorceror
Okay, I have applied all of that to my script, the only problem I am still having, is in my deserialization method, when I need to create a new timer with the parameters for (mobile and TimeLeft) and then start it...

This is what I did:

ps: jTimer is a public declaration at the top of my JailingSystem class:

Code:
public JailingTimer jTimer;

Code:
public override void Deserialize( GenericReader reader ) 
		{ 
			base.Deserialize( reader ); 
 			int version = reader.ReadInt();
 			
 			switch( version )
 			{
 				case 0:
 					{
						for( int i = 0; i < reader.ReadInt(); i++ )
						{
							m_inMates.Add( reader.ReadMobile(), new MobileFields( reader.ReadDateTime(), reader.ReadTimeSpan(), reader.ReadPoint3D(), reader.ReadMap(), reader.ReadString() ));
							[COLOR="Red"]jTimer = new JailingTimer( (m_inMates[i]).Key, (m_inMates[i]).Sentance );
							jTimer.Start();[/COLOR]
						}
						break;
 					}
 			}
		}

These are the errors that line is giving (mainly because I think I have not referred to the mobile correctly). How can I access the mobile in that instance ?


Errors:
+ Customs/Jailing System/Jail System.cs:
CS1502: Line 275: The best overloaded method match for 'System.Collections.G
eneric.Dictionary<Server.Mobile,Server.Commands.JailingSystem.MobileFields>.this
[Server.Mobile]' has some invalid arguments
CS1503: Line 275: Argument '1': cannot convert from 'int' to 'Server.Mobile'

CS1502: Line 275: The best overloaded method match for 'System.Collections.G
eneric.Dictionary<Server.Mobile,Server.Commands.JailingSystem.MobileFields>.this
[Server.Mobile]' has some invalid arguments
CS1503: Line 275: Argument '1': cannot convert from 'int' to 'Server.Mobile'
 

Gargouille

Sorceror
Yep,

m_inMates does not work, as a Dictionary is not "sequential-indexed", you must access it by the Key.

You got to have from, but the line you fill m_inMates, you read it but not keep the value.
Since you got to use the serailized value twice, you got to do :

Code:
public override void Deserialize( GenericReader reader ) 
		{ 
			base.Deserialize( reader ); 
 			int version = reader.ReadInt();
 			
 			switch( version )
 			{
 				case 0:
 					{
						for( int i = 0; i < reader.ReadInt(); i++ )
						{
[COLOR="Red"]Mobile readmobile = reader.ReadMobile();[/COLOR]	
					
m_inMates.Add( [COLOR="Red"]readmobile [/COLOR], new MobileFields( reader.ReadDateTime(), reader.ReadTimeSpan(), reader.ReadPoint3D(), reader.ReadMap(), reader.ReadString() ));
							jTimer = new JailingTimer( ([COLOR="Red"]readmobile [/COLOR], (m_inMates[[COLOR="Red"]readmobile[/COLOR] ]).Sentance );
							jTimer.Start();
						}
						break;
 					}
 			}
		}
 

typhoonbot

Sorceror
Hmmm, sigh I have made those changes and recompiled. Server compiles fine but when I jail someone, and restart the server. they are still being released. I cannot understand it, its as if the Dictionary (inMates) is never serialized, but I clearly serialize it in my serialize method... ?

Here is my whole script for you to look at:

Code:
using System;
using Server.Mobiles;
using System.IO;
using System.Collections;
using System.Collections.Generic; 
using Server; 
using Server.Misc; 
using Server.Items; 
using Server.Gumps; 
using Server.Network;
using Server.Accounting;
using Server.Targeting;
using Server.ContextMenus;
using Server.Commands;
using Server.Regions;

namespace Server.Commands
{
	public class JailingSystem : Item
  	{
		#region Commands
		public static void Initialize()
		{
			CommandSystem.Register ( "jail", AccessLevel.GameMaster, new CommandEventHandler ( Jail_OnCommand ) );
			CommandSystem.Register ( "release", AccessLevel.GameMaster, new CommandEventHandler ( Release_OnCommand ) );
			CommandSystem.Register ( "jailtime", AccessLevel.Player, new CommandEventHandler ( JailTime_OnCommand ) );
			CommandSystem.Register ( "reason", AccessLevel.Player, new CommandEventHandler ( Reason_OnCommand ) );
		}
		public static void Jail_OnCommand( CommandEventArgs e )
		{
			e.Mobile.CloseGump( typeof ( JailGump ) );
			e.Mobile.SendGump( new JailGump() );
		}
		public static void Release_OnCommand( CommandEventArgs e )
		{
			ArrayList inMates = new ArrayList();
			foreach ( Mobile m in m_inMates.Keys )
			{
				inMates.Add( m );
			}
			e.Mobile.CloseGump( typeof ( ReleasingGump ) );
			e.Mobile.SendGump( new ReleasingGump( inMates ) );
		}
		public static void JailTime_OnCommand( CommandEventArgs e )
		{
			if ( IsInMate( e.Mobile ) )
			{
				TimeSpan RemainingTime = ((m_inMates[e.Mobile]).JailedTime + (m_inMates[e.Mobile]).Sentance) - DateTime.Now;
				double RemainingMins = Math.Round( RemainingTime.TotalMinutes );
				double RemainingHours = Math.Round( RemainingTime.TotalHours );
				e.Mobile.SendMessage(37, "You will be released in: Aprox Minutes: " + RemainingMins.ToString() + ". Aprox Hours: " + RemainingHours.ToString() );
			}
			else
			{
				e.Mobile.SendMessage(37, "You are not currently in jail.");
			}
		}
		public static void Reason_OnCommand( CommandEventArgs e )
		{
			if ( IsInMate( e.Mobile ) )
			{
				e.Mobile.SendMessage(37, "You were jailed for this reason: " + (m_inMates[e.Mobile]).Reason + ".");
			}
			else
			{
				e.Mobile.SendMessage(37, "You are not currently in jail.");
			}
		}
		#endregion
		
		[Constructable]
		public JailingSystem()
			: base(3796)
		{
        	Name = "Jail Command Stone";
        	Movable = false;
		}
		
		#region Mobile Fields
		public class MobileFields
		{
			private DateTime m_JailedTime;
			private TimeSpan m_Sentance;
			private Point3D m_Posi;
			private Map m_map;
			private string m_Reason;
	
			public DateTime JailedTime
			{ 
				get{ return m_JailedTime; } 
				set{ m_JailedTime = value; } 
			}
			public TimeSpan Sentance
			{ 
				get{ return m_Sentance; } 
				set{ m_Sentance = value; } 
			}
			public Point3D Posi
			{ 
				get{ return m_Posi; } 
				set{ m_Posi = value; } 
			}
			public Map map
			{ 
				get{ return m_map; } 
				set{ m_map = value; } 
			}
			public string Reason
			{ 
				get{ return m_Reason; } 
				set{ m_Reason = value; } 
			}
	
			public MobileFields( DateTime jailedTime, TimeSpan sen, Point3D posi, Map mapie, string reas )
			{
				m_JailedTime = jailedTime;
				m_Sentance = sen;
				m_Posi = posi;
				m_map = mapie;
				m_Reason = reas;
			}
		}
		#endregion
		
		public JailingTimer jTimer;
		
		public static Dictionary<Mobile, MobileFields> m_inMates = new Dictionary<Mobile, MobileFields>();
		
		public static Point3D[] defaultCells = new Point3D[]
		{
			#region Traditional runUO cells
			/*new Point3D(5276,1164,0),
			new Point3D(5286,1164,0),
			new Point3D(5296,1164,0),
			new Point3D(5306,1164,0),
			new Point3D(5276,1174,0),
			new Point3D(5286,1174,0),
			new Point3D(5296,1174,0),
			new Point3D(5306,1174,0),
			new Point3D(5283,1184,0),
			new Point3D(5300,1184,0)*/
			#endregion
			
			#region Yew Jail Cells
			new Point3D(286,776,0),
			new Point3D(280,776,0),
			new Point3D(274,776,0),
			new Point3D(268,776,0),
			new Point3D(262,776,0),
			
			new Point3D(286,766,0),
			new Point3D(280,766,0),
			new Point3D(274,766,0),
			new Point3D(268,766,0),
			new Point3D(262,766,0),
			
			new Point3D(286,776,20),
			new Point3D(280,776,20),
			new Point3D(274,776,20),
			new Point3D(268,776,20),
			new Point3D(262,776,20),
			
			new Point3D(286,766,20),
			new Point3D(280,766,20),
			new Point3D(274,766,20),
			new Point3D(268,766,20),
			new Point3D(262,766,20),
			#endregion
		};
		
		public static void AddInMate( Mobile from, DateTime TimeJailed, TimeSpan delay, Point3D origPos, Map theMap, string Reason )
		{
			if ( m_inMates.ContainsKey( from ) )
			{
				RemoveInMate( from );
			}
			
			m_inMates.Add( from, new MobileFields( TimeJailed, delay, origPos, theMap, Reason ));
			
			int rank = 0;
			foreach( Mobile key in m_inMates.Keys ) //each Mobile in the Key collection
			{
				if( key == from )
				{
					break;
				}
				
				rank++;	
			}
			
			if( rank > ( defaultCells.Length - 1 ) )
			{
				rank = 0; //or you got a serious problem
			}
			
			from.Location = defaultCells[rank];
			Timer timer = new JailingTimer( from, delay );
			timer.Start();
		}
        
        public static void RemoveInMate( Mobile from )
		{
        	if ( m_inMates.ContainsKey( from ) )
			{
				from.Location = (m_inMates[from]).Posi;//go to original location
				m_inMates.Remove( from );
				from.SendMessage(68, "You have been released from jail.");
				
				foreach ( Mobile m in World.Mobiles.Values )
				{
					if ( m.AccessLevel > AccessLevel.Player )
					{
						m.SendMessage(68, from.RawName + " has been released from jail.");
					}
				}
			}
		}
        
        public static void OnTick(Mobile ToBeFree)
		{
			if( IsInMate( ToBeFree ) )
			{
				RemoveInMate( ToBeFree );
			}
		}
        
        public static bool IsInMate( Mobile from ) 
		{
			return m_inMates.ContainsKey( from );
		}
        
        public static void JailMobile( Mobile offender, TimeSpan sentance, Point3D pos, Map tehMap, string Reason )
        {
        	//When calling JailMobile use "Server.Commands.JailingSystem.JailMobile( mobile, TimeSpan.From<Days / Hours / Minutes / Seconds>( 1.0 ), mobile.Location, mobile.Map, "Reason" );"
        	
        	AddInMate(offender, DateTime.Now, sentance, pos, tehMap, Reason);
        }
 
		public JailingSystem( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( (int) 0 ); // version
      		writer.Write( (int) m_inMates.Count );

			foreach( KeyValuePair<Mobile, MobileFields> kvp in m_inMates )
			{
				TimeSpan timeLeft = (kvp.Value.JailedTime + kvp.Value.Sentance) - DateTime.Now;
				
				writer.Write( (Mobile) kvp.Key ); //Mobile
				writer.Write( (DateTime) kvp.Value.JailedTime );
				writer.Write( (TimeSpan) timeLeft );
				writer.Write( (Point3D) kvp.Value.Posi );
				writer.Write( (Map) kvp.Value.map );
				writer.Write( (string) kvp.Value.Reason );
			}
		} 

		public override void Deserialize( GenericReader reader ) 
		{ 
			base.Deserialize( reader ); 
 			int version = reader.ReadInt();
 			
 			switch( version )
 			{
 				case 0:
 					{
						for( int i = 0; i < reader.ReadInt(); i++ )
						{
							Mobile readMobile = reader.ReadMobile();
							m_inMates.Add( readMobile, new MobileFields( reader.ReadDateTime(), reader.ReadTimeSpan(), reader.ReadPoint3D(), reader.ReadMap(), reader.ReadString() ));
							jTimer = new JailingTimer( readMobile, (m_inMates[readMobile]).Sentance );
							jTimer.Start();
						}
						break;
 					}
 			}
		}
	}
	
	public class JailingTimer : Timer
	{
		private Mobile Jailed; //this is accessible in OnTick
		
		public JailingTimer(Mobile jailed, TimeSpan delay)//you take a reference to the mobile jailed
			: base( delay )
		{
			Priority = TimerPriority.FiftyMS;
			
			Jailed = jailed;
		}

		protected override void OnTick()
		{
	    	JailingSystem.OnTick( Jailed );
            Stop();		
		}
	}
}

EDIT: I am quite sure that the dictionary is empty after restarting server, because I have a gump that adds all the people currently in the dictionary, and it is empty...

Do you maybe have an instant messenger, such as ICQ, Skype, or google talk that we can communicate on ? :)
 

typhoonbot

Sorceror
Oh, I just realized I had not actually created the item of type (Jailing System) which might lead to the serialize and deserialize problems ?

but, after creating the item, and restarting the server, it wants to delete all items of that type on startup, which means ser / deser still cannot be right :/

World: Loading...An error was encountered while loading a saved object
- Type: Server.Commands.JailingSystem
- Serial: 0x4001CF84
Delete the object? (y/n)
After pressing return an exception will be thrown and the server will terminate

Error:
System.Exception: Load failed (items=True, mobiles=False, guilds=False, type=Ser
ver.Commands.JailingSystem, serial=0x4001CF84) ---> System.IO.EndOfStreamExcepti
on: Unable to read beyond the end of the stream.
at System.IO.__Error.EndOfFile()
at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
at System.IO.BinaryReader.ReadInt32()
at Server.BinaryFileReader.ReadInt()
at Server.Commands.JailingSystem.Deserialize(GenericReader reader) in c:\LoK
Server Files\Legends of Kaine Server\Scripts\Customs\Jailing System\Jail System.
cs:line 272
at Server.World.Load()
--- End of inner exception stack trace ---
at Server.World.Load()
at Server.ScriptCompiler.Compile(Boolean debug, Boolean cache)
at Server.Core.Main(String[] args)
This exception is fatal, press return to exit
 

Gargouille

Sorceror
Note : Your Timer is a public class, and not inclued in JailSystem class. It works fine. Butyou can also declare it as private, and so, inside of JailSystem class.
And I does not see your JailGump, you can also declare it as private inside your JailSystem class.
As your MobileFields class can be declared as private too.

Now, you should take a look at Krrios sticky post, it talks about serialization.

Code:
int version = reader.ReadInt();
 			
 			switch( version )
 			{
 				case 0:[COLOR="Red"]//default value for an int is not 0, but null (as I think so)[/COLOR]

So at the first beginning, you can't pass through case 0...

So try :
Code:
public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			for( int i = 0; i < reader.ReadInt(); i++ )
			{
				Mobile readMobile = reader.ReadMobile();
				m_inMates.Add( readMobile, new MobileFields( reader.ReadDateTime(), reader.ReadTimeSpan(), reader.ReadPoint3D(), reader.ReadMap(), reader.ReadString() ));
				jTimer = new JailingTimer( readMobile, (m_inMates[readMobile]).Sentance );
				jTimer.Start();
			}
		}


You don't need any versioning test in serialize at the first beginning.

You just have to serialize a value, in order to test the additional values... But you can test a version, only when the object has been serialized once before (and got a real value (int)version )


PS: talking together via MSN or something else is not the goal of this forum ;)
 

typhoonbot

Sorceror
Hmmm, I have changed my deserialization method:

Code:
public override void Deserialize( GenericReader reader ) 
		{ 
			base.Deserialize( reader ); 
 			int version = reader.ReadInt();

			for( int i = 0; i < reader.ReadInt(); i++ )
			{
				Mobile readMobile = reader.ReadMobile();
				m_inMates.Add( readMobile, new MobileFields( reader.ReadDateTime(), reader.ReadTimeSpan(), reader.ReadPoint3D(), reader.ReadMap(), reader.ReadString() ));
				jTimer = new JailingTimer( readMobile, (m_inMates[readMobile]).Sentance );
				jTimer.Start();
			}
 		}

The dictionary is still empty after server reboot, any other ideas that might be causing this...GRRR :mad:


And the server still wants to delete all JailingSystem items when compiling ?
 
Top