Client not receiving data from Plugin Broadcast event

Options
Hello,

I've trying to send information from a plugin down to a client using a scheduled event and a timer, the event code fires in the client but the Hashtable is empty.
                Dictionary<byte, object> wDataToSend = new Dictionary<byte, object>();
                wDataToSend.Add(1, (int)recDisStruct.X);
                wDataToSend.Add((byte)2, (int)recDisStruct.Y);
                wDataToSend.Add((byte)3, (int)recDisStruct.Z);
                wDataToSend.Add((byte)4, recDisStruct.A);
                wDataToSend.Add((byte)5, recDisStruct.B);
                wDataToSend.Add((byte)6, recDisStruct.C);
                this.RaiseEvent(12, wDataToSend);
        public void RaiseEvent(
            byte eventCode, 
            object eventData,
            byte receiverGroup = ReciverGroup.All,
            int senderActorNumber = 0,
            byte cachingOption = CacheOperations.DoNotCache,
            byte interestGroup = 0,
            SendParameters sendParams = default(SendParameters))
        {
            Dictionary<byte, object> parameters = new Dictionary<byte, object>();
            parameters.Add(245, eventData);
            parameters.Add(254, senderActorNumber);
            PluginHost.BroadcastEvent(receiverGroup, senderActorNumber, interestGroup, eventCode, parameters, cachingOption, sendParams);
        }
In the client:
void DTListener::customEventAction(int playerNr, nByte eventCode, const Object& eventContentObj)
{
	ExitGames::Common::Hashtable eventContent = ExitGames::Common::ValueObject<ExitGames::Common::Hashtable>(eventContentObj).getDataCopy();
	
	if (eventCode == 12)
	{
            ...
         }
}
I also tried without the helper or wrapper classes, but there isn't any data in the received Object?

Comments

  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @eza,

    Thank you for choosing Photon!

    This looks like a native client-side issue.
    You are sending Dictionary<byte, object>() from plugin code and expecting ExitGames::Common::Hashtable from client code.
    You should use the same data structure from both ends.

    My colleague @Kaiserludi will confirm this and help you when he's available.
  • Kaiserludi
    Kaiserludi admin
    edited March 2019
    Options
    Hi @eza.

    @JohnTube is correct:
    If you send a Dictionary from C#, then it will arrive as a ExitGames::Common::Dictionary on a receiving C++ client.

    You can find a table about which type in the C++ client matches which one in the C# layer of the server at http://doc-api.photonengine.com/en/cpp/current/html/a05589.html. As you see, it is really straightforward without such nasty surprises like a Dictionary magically becoming a Hashtable.

    When you are unsure about the types of the data inside some container, then you can of course always just print them out for debugging by calling toString(true) on the container (when passing 'false' or nothing at all, then toString() will only return the data itself, but without type information).

    Assumed X, Y and Z have the values 10, 20 and 30 and A, B and C are strings with the values "A", "B" and "C"
    the code
    
    EGLOG(ExitGames::Common::DebugLevel::INFO, (L"eventContentObj payload: "+eventContentObj.toString(true)).cstr());
    
    should give you a log output similar to this:
    
    2019-03-08 13:49:29,525 INFO    NetworkLogic.cpp               NetworkLogic::NetworkLogic()                                 160   eventContentObj payload: (Dictionary<uchar,Object>){1=(int)10, 2=(int)20, 3=(int)30, 4=(JString)"A", 5=(JString)"B", 6=(JString)"C"}
    
  • eza
    Options
    Thank you, I feel silly now.

    I also did not know about the true flag for toString, I was wondering why it only printed 'Object' when I was debugging.
  • Kaiserludi
    Options
    Hi @eza.

    Note that printing the full payload of the data container on which it is called (included all nested data containers, if there are such), optionally including type-info (when passing true, otherwise types are omitted, but the rest of the payload is still printed, hence in the example the returned string would be "{1=10, 2=20, 3=30, 4="A", 5="B", 6="C"}" when passing 'false' or nothing at all for the 'withTypes' flag) is a feature of the toString() API that is provided by the Photon C++ client.

    The toString() function of the .NET framework would simply print 'Object' without any information about the payload and it does not offer an optional parameter to include type info. On the C# side you would need to add such an API yourself.