Photon Server + Plugin + Unity bug?

StarKist
StarKist
edited December 2019 in Photon Server
Hi,

I'm wokring with photon plugin for self hosted server for quite a while now and everything is nice.

However, recently I came across a bug which I cannot explain from my code.

I have the following instantiation function run from the photon plugin:
public void Instantiate(List<int> targetPlayers)
{         
           // remove a player that joined earlier (to recreate the bug) right before sending the instantiate of the new player event to everyone
            if(targetPlayers.Count > 4) {               
                myPlugin.PluginHost.RemoveActor(targetPlayers[1], "test");
                for(int i=0;i<100000000;i++); // let photon start removal process
            }

            // send the instantiate event to the players interested (THIS calls pluginHost.BroadcastEvent()  )
            PunFunctions.Instantiate(this.myPlugin, viewIDs, targetPlayers, this.actorNr,
                  RoleKeys.prefabs[entityDynamicStats.playerRole], entityTransform.position, entityTransform.rotation, 0, playerInfo);

}

When I join the 5th player the following happens:

The "targetPlayers" are: 1, 2, 3, 4, 5 (ActorNrs)
I'm removing actorNr = 2 from the game, but not from the list to whom to send the instantiation event (targetPlayers)

=> all players after actorNr 2 in the list DO NOT GET EVENT.
so in this case, only player 1 gets the instantiation event of joining player 5.

This is a bug in my opinion, since, only player 2 is leaving, I expect all other players to get the event.
It seems pluginHost.BroadcastEvent() just stops sending the events once it runs into an issue sending to player 2 which is leaving.

I do not see any issues in the photon server logs, and no exceptions in VS when I run in debug mode.

Any help?

Comments

  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi @StarKist,

    What Photon Server SDK version do you use?
    Could you share the code of "PunFunctions.Instantiate" or at least the call of pluginHost.BroadcastEvent() so we could try to reproduce.
    Well it's better if you start by trying to reproduce yourself using a simple pluginHost.BroadcastEvent()

    Otherwise, if this is a blocker for you, could you (as workarounds):

    1. wait until the actor is removed and send the instantiate after?
    2. send the instantiate to each actor one by one
  • StarKist
    StarKist
    edited December 2019
    @JohnTube , This code DOES reproduce the issue.

    == Core ==
    PhotonSocketServer.2013
    x64 Unicode Release
    BuildDate: 2016-02-05 13:04:36
    Version: 4.0.28.2962
    SVN repository: photon-socketserver
    SVN revisions of...
    ... this project: 2962
    == SDK ==
    BuildDate: 2016-02-08 15:38:54
    Version: 4.0.29.11263
    SVN repository: photon-socketserver-sdk
    SVN revisions of...
    ... this project: 11263

    1. sounds slow? every time a player is being removed I poll and not let OTHER players instantiate?
    2. also sounds kinda slow?

    Missing code:
    public static void Instantiate(MyTestPlugin myPlugin, int[] viewIDs, List<int> targetPlayers, int actorNr, string prefabName, Vector3 position, Quaternion rotation, byte group, object[] data)
            {
                // first viewID is now also the gameobject's instantiateId
                int instantiateId = viewIDs[0];   // LIMITS PHOTONVIEWS&PLAYERS
    
                //TODO: reduce hashtable key usage by using a parameter array for the various values
                Hashtable instantiateEvent = new Hashtable(); // This players info is sent via ActorID
                instantiateEvent[(byte)0] = prefabName;
    
                if(position != Vector3.zero) {
                    instantiateEvent[(byte)1] = position;
                }
    
                if(rotation != Quaternion.identity) {
                    instantiateEvent[(byte)2] = rotation;
                }
    
                if(group != 0) {
                    instantiateEvent[(byte)3] = group;
                }
    
                // send the list of viewIDs only if there are more than one. else the instantiateId is the viewID
                if(viewIDs.Length > 1) {
                    instantiateEvent[(byte)4] = viewIDs; // LIMITS PHOTONVIEWS&PLAYERS
                }
    
                if(data != null) {
                    instantiateEvent[(byte)5] = data;
                }
    
                //if(this.currentLevelPrefix > 0) {
                instantiateEvent[(byte)8] = (short)0;    // photonview's / object's level prefix (scene number?) set to 0 cause OnPhotonSerialize  wants 0??
                //}
    
                instantiateEvent[(byte)6] = 0;
                instantiateEvent[(byte)7] = instantiateId;
    
                Dictionary<byte, object> evDict = new Dictionary<byte, object>() { { ParameterCode.Data, instantiateEvent }, { ParameterCode.ActorNr, actorNr } };
    
                myPlugin.eventHanlder_c.RaiseEvent(myPlugin.PluginHost, PunEvent_e.Instantiation, instantiateEvent, targetPlayers, actorNr, CacheOperations.DoNotCache, CacheOperations.AddToRoomCache);
    
            }
    
    
    
       public void RaiseEvent(IPluginHost pluginHost,
                byte eventCode,
                object eventData,
                List<int> targetPlayers,
                int senderActorNumber = 0,
                byte cachingOption = CacheOperations.DoNotCache,
                byte cachingOptionLocal = CacheOperations.DoNotCache,
                SendParameters sendParams = default(SendParameters))
            {
                Dictionary<byte, object> parameters = new Dictionary<byte, object>();
                parameters.Add(ParameterCode.Data, eventData);
                parameters.Add(ParameterCode.ActorNr, senderActorNumber);
    
                if(eventCode == PunEvent_e.Instantiation) {
                    string targets = "";
                    for(int i = 0; i < targetPlayers.Count; i++) { targets += targetPlayers[i] + " "; }
                    Debug.WriteLine("RaiseEvent targets: " + targets);
                }
                pluginHost.BroadcastEvent(targetPlayers.ToList(), senderActorNumber, eventCode, parameters, cachingOption, sendParams);
                        
            }      
    
    
  • Hi, @StarKist
    We had a similar issue and was fixed but I do not remember details right now.

    We are going to release a new SDK quite soon. Please wait if you can

    best,
    ilya
  • @chvetsov, well I hope a workaround I made will hold for now.
    Hope its fixed in your new release, thanks!