client/server comm. porblems

Options
eyewitness4560
edited August 2014 in DotNet
Hi everyone, we need some help with Unity/Photon communication.
We'd like to authenticate the user by sending the username and password to the master and gameserver inside a hashtable (ExitGames.Client.Photon.Hashtable). The thing is, the master server receives it without problems, but when the client tries to send it to the game server, we get an error message:
NullReferenceException: Object reference not set to an instance of an object
ExitGames.Client.Photon.DictionaryEntryEnumerator.MoveNext ()
ExitGames.Client.Photon.Protocol.SerializeHashTable (System.IO.MemoryStream dout, ExitGames.Client.Photon.Hashtable serObject, Boolean setType)
ExitGames.Client.Photon.Protocol.Serialize (System.IO.MemoryStream dout, System.Object serObject, Boolean setType)
ExitGames.Client.Photon.Protocol.SerializeParameterTable (System.IO.MemoryStream memStream, System.Collections.Generic.Dictionary`2 parameters)
ExitGames.Client.Photon.Protocol.SerializeOperationRequest (System.IO.MemoryStream memStream, Byte operationCode, System.Collections.Generic.Dictionary`2 parameters, Boolean setType)
ExitGames.Client.Photon.EnetPeer.SerializeOperationToMessage (Byte opc, System.Collections.Generic.Dictionary`2 parameters, EgMessageType messageType, Boolean encrypt)
ExitGames.Client.Photon.EnetPeer.EnqueueOperation (System.Collections.Generic.Dictionary`2 parameters, Byte opCode, Boolean sendReliable, Byte channelId, Boolean encrypt, EgMessageType messageType)
ExitGames.Client.Photon.PeerBase.EnqueueOperation (System.Collections.Generic.Dictionary`2 parameters, Byte opCode, Boolean sendReliable, Byte channelId, Boolean encrypted)
ExitGames.Client.Photon.PhotonPeer.OpCustom (Byte customOpCode, System.Collections.Generic.Dictionary`2 customOpParameters, Boolean sendReliable, Byte channelId)
ExitGames.Client.Photon.PhotonPeer.OpCustom (Byte customOpCode, System.Collections.Generic.Dictionary`2 customOpParameters, Boolean sendReliable)
ExitGames.Client.Photon.LoadBalancing.LoadBalancingPeer.OpCustom (OperationCode customOpCode, System.Collections.Generic.Dictionary`2 customOpParameters, Boolean sendReliable) (at Assets/Scripts/LoadBalancing/LoadBalancingPeer.cs:134)
ExitGames.Client.Photon.LoadBalancing.LoadBalancingClient.GamePeerEncryptionEstablished () (at Assets/Scripts/LoadBalancing/LoadBalancingClient.cs:289)
ExitGames.Client.Photon.LoadBalancing.LoadBalancingPeer.OnStatusChanged (StatusCode statusCode) (at Assets/Scripts/LoadBalancing/LoadBalancingPeer.cs:118)
ExitGames.Client.Photon.PeerBase+<>c__DisplayClass6.<EnqueueStatusCallback>b__4 ()
ExitGames.Client.Photon.EnetPeer.DispatchIncomingCommands ()
ExitGames.Client.Photon.PhotonPeer.DispatchIncomingCommands ()
ExitGames.Client.Photon.PhotonPeer.Service ()
ExitGames.Client.Photon.LoadBalancing.LoadBalancingClient.Service () (at Assets/Scripts/LoadBalancing/LoadBalancingClient.cs:97)
Game.Update () (at Assets/Scripts/Game/Game.cs:28)

The funny part is, that if I send a different instance of the same hashtable (ie: I write a function that packs the variables into a new hashtable) it works without a hitch. Any ideas?

Thanks,

Andrew

Comments

  • vadim
    Options
    Hi,
    Where and how do you set Hashtable with username and password?
    Probably client fails on 'authenticate' operation when trying to serialize AuthenticationValues.
    AuthenticationValues works only with strings or byte[], I don't see any options to put Hashtables in it.
  • We skipped the AuthenticationValues class altogether, we just defined a new key in the operations' Properties dictionary.

    Like this:
    Dictionary<byte, object> opParameters = new Dictionary<byte, object>();
                opParameters[ParameterCode.AppVersion] = AppVersion;
                opParameters[ParameterCode.ApplicationId] = AppId;
                opParameters[ParameterCode.PlayerProperties] = LoginData;
                masterPeer.OpCustom(OperationCode.Authenticate, opParameters, true, (byte)0, masterPeer.IsEncryptionAvailable);
    

    Where the LoginData is a previously defined Hashtable.


    The same code is used when authenticating on a gameserver, except using gamePeer instead of masterPeer.
    And then we get the error when it reaches the game peer.

    The "fix" we did was to write a class that has a "toHashtable" method, and we insert that instead of the "LoginData" hashtable, which creates a new hashtable, inserts the username and password, and returns that.

    Needless to say, it's not a very elegant fix, and we were wondering if there's a neater way to disarm this problem.

    Thanks,
    Andrew
  • vadim
    Options
    Can you please send us a dump of opParameters before masterPeer.OpCustom and gamePeer.OpCustom calls?
    Use ExitGames.Client.Photon.SupportClass.DictionaryToString(opParameters, true); for dump
  • Here's what's happening on both the master and gameserver:
    {(Byte)220=(String)1.0, (Byte)224=(String)StarsEnd, (Byte)249=(Hashtable){(String)userName=(String)stemy, (String)userPass=(String)password}}
    UnityEngine.Debug:Log(Object)
    ExitGames.Client.Photon.LoadBalancing.LoadBalancingClient:MasterPeerEncryptionEstablished() (at Assets/Scripts/LoadBalancing/LoadBalancingClient.cs:178)
    ExitGames.Client.Photon.LoadBalancing.LoadBalancingPeer:OnStatusChanged(StatusCode) (at Assets/Scripts/LoadBalancing/LoadBalancingPeer.cs:115)
    ExitGames.Client.Photon.<>c__DisplayClass6:<EnqueueStatusCallback>b__4()
    ExitGames.Client.Photon.EnetPeer:DispatchIncomingCommands()
    ExitGames.Client.Photon.PhotonPeer:DispatchIncomingCommands()
    ExitGames.Client.Photon.PhotonPeer:Service()
    ExitGames.Client.Photon.LoadBalancing.LoadBalancingClient:Service() (at Assets/Scripts/LoadBalancing/LoadBalancingClient.cs:96)
    Game:Update() (at Assets/Scripts/Game/Game.cs:93)
    
    {(Byte)220=(String)1.0, (Byte)224=(String)StarsEnd, (Byte)249=(Hashtable){(String)userName=(String)stemy, (String)userPass=(String)password}}
    UnityEngine.Debug:Log(Object)
    ExitGames.Client.Photon.LoadBalancing.LoadBalancingClient:GamePeerEncryptionEstablished() (at Assets/Scripts/LoadBalancing/LoadBalancingClient.cs:293)
    ExitGames.Client.Photon.LoadBalancing.LoadBalancingPeer:OnStatusChanged(StatusCode) (at Assets/Scripts/LoadBalancing/LoadBalancingPeer.cs:115)
    ExitGames.Client.Photon.<>c__DisplayClass6:<EnqueueStatusCallback>b__4()
    ExitGames.Client.Photon.EnetPeer:DispatchIncomingCommands()
    

    Plus a picture of what's happening, hope it helps :)
  • Tobias
    Options
    I fail to reproduce this so far but it's an interesting case which I would like to fix.
    Could we get your repro case or can I ask you to do a few tests?

    It seems you use the LoadBalancing API from the regular Photon Unity SDK.
    Which version do you use? Can you re-try this in the latest SDK (released yesterday)?

    It looks like you use this Hashtable in response to a OnStatusChanged callback. If you can reproduce it again, could you also try to send the Hashtable in the next Update AFTER the state callback? Use a bool "doWhateverTheStateTriggers" in OnStatusChanged and Update (don't forget to reset it to false).
    Maybe it has something to do with the Hashtable being used in a call-loop?! Just an idea...
  • It seems that switching to the new SDK fixes the issue, thanks for the tip. :)
    Should we still send you the code/test out the other ideas?
  • Tobias
    Options
    When the new SDK fixed things, then I'm happy and don't need the test code.
    Unless something is still odd/broken, of course.