سؤال

Ive got this problem:

Line 20 (LOOT_FromContainer(container) I need that to use as Invoke, because the process I want to exec takes some time, so ServerMessageHandler won't handle it...

If I just simply rewrite that line to LOOT_FromContainer.BeginInvoke(container); then I have this error:

error CS0119: 'LOOT.LOOT_FromContainer(Phoenix.Serial)' is a 'method', which is not valid in the given context

I'm new to C#, came from PHP, and about Invoke I don't know much really. I've been trying to sort this out for a couple of days, not even google helped...

  [ServerMessageHandler(0x3C)]
  public CallbackResult ContainerContains(byte[] data, CallbackResult prevResult)
  {
     PacketReader reader = new PacketReader(data);
     reader.Skip(3);

     ushort len = reader.ReadUInt16();
     for (int i = 0; i < len; i++)
     {
        Serial serial = (Serial)(reader.ReadUInt32());
        ushort graphic = (ushort)(reader.ReadUInt16());

        reader.Skip(7);

        Serial container = (Serial)(reader.ReadUInt32());
        ushort color = (ushort)(reader.ReadUInt16());

        if (((int)graphic == 0x0E76) && ((int)color == 0x049A))
        {
           LOOT_FromContainer.BeginInvoke(container);
        }
     }
     return CallbackResult.Normal;
  }

  [Command]
  public static void LOOT_FromContainer(Serial target)
  {
        UOItem lootCorpse = new UOItem(target);
        if (lootCorpse.Graphic == 0x2006)
        {
            if (((draw == 1) && (World.Player.Backpack.AllItems.Count(draw_knife[0], draw_knife[1]) > 0)) || (World.Player.Layers[Layer.RightHand].Exist))
            {
                if ((lootCorpse.Amount != 400) && (lootCorpse.Amount != 401))
                {
                    if (draw == 0)
                    {
                        UO.WaitTargetObject(lootCorpse);
                        UO.UseObject(World.Player.Layers[Layer.RightHand].Serial);
                    }
                    else
                    {
                        UO.WaitTargetObject(lootCorpse);
                        UO.UseType(draw_knife[0], draw_knife[1]);
                    }
                    UO.Wait(500);
                }
            }
            else
        {
               UO.Print("Neni cim rezat, pouze lootim");
        }

            for (int i = 0; i < loot.Length; i++)
            {
           if (lootCorpse.Items.Count(loot[i][0], loot[i][1]) > 0)
                {
              if (loot[i][2] == 1)
              {
                 if (loot[i][4] == 1)
                 {
                    UO.MoveItem(lootCorpse.Items.FindType(loot[i][0], loot[i][1]), 0, Aliases.GetObject("loot_bag"), loot[i][5], loot[i][6]);
                      UO.Wait(200);
                 }
                 else
                 {
                    UO.MoveItem(lootCorpse.Items.FindType(loot[i][0], loot[i][1]), 0, World.Player.Backpack);
                        UO.Wait(200);
                 }
              }
                }
            }
        }
  }
هل كانت مفيدة؟

المحلول

I think this is what you need. You need to declare a delegate with the same return type and input parameters as your method, instantiate this delegate pointing it at your method and then call BeginInvoke on it passing in your serial variable, followed by null, null:

public delegate void LFC(Serial target);

[ServerMessageHandler(0x3C)]
  public CallbackResult ContainerContains(byte[] data, CallbackResult prevResult)
  {
   PacketReader reader = new PacketReader(data);
   reader.Skip(3);

   ushort len = reader.ReadUInt16();
   for (int i = 0; i < len; i++)
   {
      Serial serial = (Serial)(reader.ReadUInt32());
      ushort graphic = (ushort)(reader.ReadUInt16());

      reader.Skip(7);

      Serial container = (Serial)(reader.ReadUInt32());
      ushort color = (ushort)(reader.ReadUInt16());

    LFC = lootfromcontainer = new LFC(LOOT_FromContainer);

      if (((int)graphic == 0x0E76) && ((int)color == 0x049A))
      {
        lootfromcontainer.BeginInvoke(container, null, null);
         //LOOT_FromContainer.BeginInvoke(container);
      }
   }
   return CallbackResult.Normal;
  }


[Command]
public static void LOOT_FromContainer(Serial target)
{
   UOItem lootCorpse = new UOItem(target);
      if (lootCorpse.Graphic == 0x2006)
      {
          if (((draw == 1) && (World.Player.Backpack.AllItems.Count(draw_knife[0], draw_knife[1]) > 0)) || (World.Player.Layers[Layer.RightHand].Exist))
          {
              if ((lootCorpse.Amount != 400) && (lootCorpse.Amount != 401))
              {
                  if (draw == 0)
                  {
                      UO.WaitTargetObject(lootCorpse);
                      UO.UseObject(World.Player.Layers[Layer.RightHand].Serial);
                  }
                  else
                  {
                      UO.WaitTargetObject(lootCorpse);
                      UO.UseType(draw_knife[0], draw_knife[1]);
                  }
                  UO.Wait(500);
              }
          }
          else
      {
             UO.Print("Neni cim rezat, pouze lootim");
      }

          for (int i = 0; i < loot.Length; i++)
          {
         if (lootCorpse.Items.Count(loot[i][0], loot[i][1]) > 0)
              {
            if (loot[i][2] == 1)
            {
               if (loot[i][4] == 1)
               {
                  UO.MoveItem(lootCorpse.Items.FindType(loot[i][0], loot[i][1]), 0, Aliases.GetObject("loot_bag"), loot[i][5], loot[i][6]);
                    UO.Wait(200);
               }
               else
               {
                  UO.MoveItem(lootCorpse.Items.FindType(loot[i][0], loot[i][1]), 0, World.Player.Backpack);
                      UO.Wait(200);
               }
            }
              }
          }
      }
}

نصائح أخرى

If you simply need to run that in another thread you can use ThreadPool.

For this you would need few easy things:

Instead of:

LOOT_FromContainer.BeginInvoke(container);

You would use:

ThreadPool.QueueUserWorkItem(LOOT_FromContainer, container);

And slightly modify your LOOT_FromContainer method to:

public static void LOOT_FromContainer(object prm)
{
   var target = (Serial)prm;
   // ...

I'm assuming LOOT_FromCotainer is a control, and given the error your compiler returns, one can roughly guess the problem is that you're calling BeginInvoke with a non-delegate. BeginInvoke is called as follows:

LOOT_FromContainer.BeginInvoke(container); //where container is a delegate that maybe declared as follows

private delegate void container; //may also contain parameters eg container(string s);

So just rework your code to follow in this manner. See this document for example on how to use BeginInvoke.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top