Lokai

Moderator
@Voxpire, Tagging Voxpire, because I think you might be the best one to answer this.

It's possible VitaNexCore already does this or has the answer, but I still am not sure how all of that works.

What I am trying to find out is if the server knows what the properties of a gump Image are. In other words, let's say I add an image to a gump like AddImage(1234,10,10); There, I have added an image. But let's say that 1234 is pointing to an empty spot in the .MUL file or whatever. Does the server still think there is an image attached to the gump?

Does it know the properties of the image? Or the fact that the image has no dimensions?

What if it was an actual picture of something? Does it know how tall and wide is this image?

Is there an actual Bitmap property that we can use?
 
In case that is not clear enough, let me explain what I want to do with the information. Perhaps there is another way of going about this.

Let's say I would like to do something such as update the Compendium so that if someone creates a gump image, and enters a number for the gump id that does not actually exist in the "gumpartLegacyMUL.uop" or GumpArt.mul file as a valid image, that they get a message stating so. However, I do not want to hard-code in all of the possible ids for images, because everyone will be using a varied number of .MUL files or even possibly a custom one with custom art included. So what I want to do is say "if (*the id they entered* IS NOT in "*some master list of ids that was created dynamically when the server started*") then ... tell the user.
 
Since Ultima.dll is bundled with ServUO (upon compile), you can use the Ultima.Gumps factory to get any given GumpID as an image;

C#:
public static unsafe Bitmap GetGump(int index, Hue hue, bool onlyHueGrayPixels, out bool patched);

public static byte[] GetRawGump(int index, out int width, out int height)
 
Since Ultima.dll is bundled with ServUO (upon compile), you can use the Ultima.Gumps factory to get any given GumpID as an image;

C#:
public static unsafe Bitmap GetGump(int index, Hue hue, bool onlyHueGrayPixels, out bool patched);

public static byte[] GetRawGump(int index, out int width, out int height)

Interesting. Is there any documentation on this? All I see in Visual Studio is metadata. Do I instantiate a GumpFactory, then use the object reference to call GetGump? or assign the value of GetGump to a new Bitmap()?

It's possible VitaNexCore already does this or has the answer

Am I right that there is already a method in VNC that does what I am looking for?
 
If you're using VS with the ServUO.sln then you can find the source in the Ultima project in the Solution Explorer -> Gumps.cs

VNc does have a method, but it relies on the Ultima.dll otherwise you have to call the methods yourself;

C#:
var image = Ultima.Gumps.GetGump( gumpID );

var width = image.Width;
var height = image.Height;
 
If you're using VS with the ServUO.sln then you can find the source in the Ultima project in the Solution Explorer -> Gumps.cs

VNc does have a method, but it relies on the Ultima.dll otherwise you have to call the methods yourself;

C#:
var image = Ultima.Gumps.GetGump( gumpID );

var width = image.Width;
var height = image.Height;

Thanks. This is getting me very close to exactly what I need. However, when I use this, I get the following:

"Ultima" does not exist in the current context.

And if I use this:

Code:
var image = OpenUO.Ultima.Gumps.GetGump( gumpID );

I get: The Type or Namespace "Gumps" does not exist in Namespace OpenUO.Ultima.

*********** EDIT ************

I was not using the latest ServUO. I see the references in the latest, so I will update my code now.

Thanks.
 
Last edited:
If you're using VS with the ServUO.sln then you can find the source in the Ultima project in the Solution Explorer -> Gumps.cs

VNc does have a method, but it relies on the Ultima.dll otherwise you have to call the methods yourself;

C#:
var image = Ultima.Gumps.GetGump( gumpID );

var width = image.Width;
var height = image.Height;


OK, I have all the latest stuff. I am trying some test code, just to see if it can assign the value to a var. Here is my test code:

Code:
            bool trying = true;
            int count = 0;
               
            while (trying)
            {
                try
                {
                    var img = Ultima.Gumps.GetGump(count);
                   
                    // if it gets this far, it will stop...
                    Console.Write("success");
                    trying = false;
                }
                catch(Exception e)
                {
                    count++;
                    Console.Write(count);
                }
            }

And my result is the console counts to infinity...well, I watched it count from 0 to beyond 100,000. I will keep trying...
 
OK, so it turns out the problem might be in Ultima, as it relates to the latest patch of UO maybe?

I see this when I output e.Message:

Code:
16:07:50 The type initializer for 'Ultima.Gumps' threw an exception.
 
You're only incrasing 'count' if an error occurs, so if no errors occur, you're technically requesting the same id over and over.

Do ++count outside of your try/catch blocks.

There are 65,535 max gumps.

Gumps.GetGump( gumpID ) will either throw an exception, or produce a Bitmap object of 0 width/height, or return null if the slot is empty.

Can test with:
C#:
var count = 65535;

for(var id = 0; id < count; id++)
{
   try
   {
       var img = Ultima.Gumps.GetGump(id);

       Console.WriteLine("{0:X4}: {1}x{2}", id, img.Width, img.Height);
   }
   catch { }
}

Also, I think the legacy MUL files for gump art are needed for this version of Ultima.dll to work properly.
 
You're only incrasing 'count' if an error occurs, so if no errors occur, you're technically requesting the same id over and over.

Do ++count outside of your try/catch blocks.

There are 65,535 max gumps.

Gumps.GetGump( gumpID ) will either throw an exception, or produce a Bitmap object of 0 width/height, or return null if the slot is empty.

Can test with:
C#:
var count = 65535;

for(var id = 0; id < count; id++)
{
   try
   {
       var img = Ultima.Gumps.GetGump(id);

       Console.WriteLine("{0:X4}: {1}x{2}", id, img.Width, img.Height);
   }
   catch { }
}

Also, I think the legacy MUL files for gump art are needed for this version of Ultima.dll to work properly.

Actually, what I tried was this:

Code:
            try
            {
                var img = Ultima.Gumps.GetGump(m_Image);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

where m_Image was 0. That is what produced the line in my previous post. So, I think something is wrong with how Ultima Gumps interacts with the new UO Client.
 
Try making sure the MUL files are available in your data path, if you only have the UOP files then that's probably the reason why it's not working.

In recent ServUO DataPath.cs there is code that initializes the Ultima file paths, do you also have that code?
C#:
			foreach (var dir in Core.DataDirectories)
			{
				Ultima.Files.SetMulPath(dir);
			}
 
Yes, that code is in my Datapath.cs file. I just downloaded the latest ServUO code today. And, correct, I have ONLY the UOP file, no MUL files.
 
OK, I just used UOFiddler to create the GumpArt and GumpIdx .MUL files, and then copied them over to my UO Client folder. I am getting the same result: "The type initializer for 'Ultima.Gumps' threw an exception."
 
I'm out of ideas, I'll just be repeating myself at this point.

Last thing I can think of is running in debug mode so you get extended error output otherwise that message isn't very helpful.
 
I'm out of ideas, I'll just be repeating myself at this point.

Last thing I can think of is running in debug mode so you get extended error output otherwise that message isn't very helpful.

OK, I used InnerException instead of Message, and get this:

Code:
20:16:34 System.UnauthorizedAccessException: Access to the path 'C:\Program File
s\Electronic Arts\Ultima Online Classic\gumpartlegacymul.uop' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, I
nt32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions o
ptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolea
n useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access,
FileShare share)
   at Ultima.FileIndex..ctor(String idxFile, String mulFile, String uopFile, Int
32 length, Int32 file, String uopEntryExtension, Int32 idxLength, Boolean hasExt
ra) in c:\UO\ServUO-master\Ultima\FileIndex.cs:line 241
   at Ultima.Gumps..cctor() in c:\UO\ServUO-master\Ultima\Gumps.cs:line 13

Looks like a permissions issue.
 
Back