Can I change the region in runtime using PUN?

Hi,

I've been trying for a long time to find a way to change the region in runtime, but I can't find it... I've tried the LoadBalancingClient class but it doesn't work, I don't know if it's because I use the PhotonNetwork class for everything else... I would like this to work (code below) but I think it should not be that simple hahaha


using Photon.Pun;
using Photon.Realtime;
using UnityEngine;


public class RegionManager : MonoBehaviourPunCallbacks
{
    bool showRegionMenu = false;


    [SerializeField] GameObject regionMenu;


    string currRegion;


    public bool changingRegion { get; private set; }


    public void UpdateRegion(string code)
    {
        PhotonNetwork.Disconnect();


        changingRegion = true;
        currRegion = code;
    }


    public override void OnDisconnected(DisconnectCause cause)
    {
        PhotonNetwork.ConnectToRegion(currRegion);
        
    }


    public override void OnConnectedToMaster()
    {
        changingRegion = false;
    }


    public void ShowHideRegionMenu()
    {
        showRegionMenu = !showRegionMenu;


        if (showRegionMenu) regionMenu.SetActive(true);
        else regionMenu.SetActive(false);
    }
}


Every time I get this error


OperationResponse 230: ReturnCode: 32767 (Regions mismatch). Parameters: {} Server: MasterServer Address: 91.199.81.131:5055
UnityEngine.Debug:LogError (object)
Photon.Realtime.LoadBalancingClient:DebugReturn (ExitGames.Client.Photon.DebugLevel,string) (at Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs:2564)
Photon.Realtime.LoadBalancingClient:OnOperationResponse (ExitGames.Client.Photon.OperationResponse) (at Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs:2644)
ExitGames.Client.Photon.PeerBase:DeserializeMessageAndCallback (ExitGames.Client.Photon.StreamBuffer) (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/PeerBase.cs:872)
ExitGames.Client.Photon.EnetPeer:DispatchIncomingCommands () (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/EnetPeer.cs:565)
ExitGames.Client.Photon.PhotonPeer:DispatchIncomingCommands () (at D:/Dev/Work/photon-dotnet-sdk/PhotonDotNet/PhotonPeer.cs:1771)
Photon.Pun.PhotonHandler:Dispatch () (at Assets/Photon/PhotonUnityNetworking/Code/PhotonHandler.cs:222)
Photon.Pun.PhotonHandler:FixedUpdate () (at Assets/Photon/PhotonUnityNetworking/Code/PhotonHandler.cs:145)


Is it possible that in PUN this cannot be done?


Best Regards!

Lucas

Answers

  • For some reason, the internally stored AuthToken is not discarded before you call PhotonNetwork.ConnectToRegion(currRegion). The token is provided for one region and you need to authenticate on the Name Server again to get a new one.

    Are you maybe not running a recent PUN version?

    You could try to clear the token yourself. Before ConnectToRegion, set PhotonNetwork.AuthValues.Token = null.

  • Hi!

    Thanks for answering and so quickly!

    I have tried what you have told me and Token is an object protected with an internal set, even so I have tried to make it public in the LoadbalancingPeer class, where this object is declared, but I still get the same message in the console: "Disconnected from Server: InvalidAuthentication" and the initial error of this discussion... I am currently using PUN2 Version 2.41, I don't know if there is a higher version than this...

    My code looks like this...


    using Photon.Pun;
    using Photon.Realtime;
    using UnityEngine;
    
    
    public class RegionManager : MonoBehaviourPunCallbacks
    {
        public Launcher launcher;
    
    
        bool showRegionMenu = false;
    
    
        [SerializeField] GameObject regionMenu;
    
    
        string currRegion;
    
    
        public bool changingRegion { get; private set; }
    
    
        public void UpdateRegion(string code)
        {
            changingRegion = true;
    
    
            currRegion = code;
    
    
            PhotonNetwork.Disconnect();
    
    
            //This give me an error because is a protected object
            PhotonNetwork.AuthValues.Token = null;
        }
    
    
        public override void OnDisconnected(DisconnectCause cause)
        {
            if (!changingRegion) return;
    
    
            try
            {
                PhotonNetwork.ConnectToRegion(currRegion);
            }
            finally
            {
                changingRegion = false;
                PhotonNetwork.ConnectUsingSettings();
                launcher.errorText.text = "Can't connect to " + currRegion + " servers... Try again later";
                MenuManager.Instance.OpenMenu("error");
            }
            
    
    
        }
    
    
        public override void OnConnectedToMaster()
        {
            changingRegion = false;
            
        }
    
    
        public void ShowHideRegionMenu()
        {
            showRegionMenu = !showRegionMenu;
    
            regionMenu.SetActive(showRegionMenu);
        }
    }
    
  • Tobias
    Tobias admin
    edited January 2023

    Is this a recent question or did it get a new timestamp when I got it out of the spam queue?

    Invalid Authentication is a different error from the first one and will depend on how you setup Authentication for your AppId and how it's used client side.

    Please mail us to developer@photonengine.com and name the AppId and the region you are setting in ConnectToRegion(currRegion).

  • Hi Tobias!

    Thank you for your answer and sorry for the inconvenience, I was able to solve it a while ago, and the truth is that it works correctly for me, in my game I have not received any type of complaint about it from the users.

    I leave here what the script looks like in case someone has the same problem that I had at the time.

    Thank you very much and best regards!

    Lucas

    using Photon.Pun;
    using Photon.Realtime;
    using UnityEngine;
    
    public class RegionManager : MonoBehaviourPunCallbacks
    {
        bool showRegionMenu = false;
    
        [SerializeField] GameObject regionMenu;
    
        string currRegion;
    
        public bool changingRegion { get; private set; }
    
    //The method that is called from a button to change the region
        public void ChangeRegion(string code)
        {
            changingRegion = true;
    
    
            currRegion = code;
            
            PhotonNetwork.Disconnect();
        }
    
    
        public override void OnDisconnected(DisconnectCause cause)
        {
            if (!changingRegion) return;
    
    
            PhotonNetwork.PhotonServerSettings.AppSettings.FixedRegion = currRegion;
            PhotonNetwork.PhotonServerSettings.DevRegion = currRegion;
            PhotonNetwork.ConnectUsingSettings();
    
    
        }
    
    
        public override void OnConnectedToMaster()
        {
            if (changingRegion) changingRegion = false;
            
        }
    
    
        public void ShowHideRegionMenu()
        {
            showRegionMenu = !showRegionMenu;
    
    
            regionMenu.SetActive(showRegionMenu);
        }
    }
    
  • Thanks for the update, Lucas. Much appreciated.

    Glad this works in-game :)