public void OnOperationResponse(OperationResponse operationResponse)
{
if (PhotonNetwork.networkingPeer.State == global::PeerState.Disconnecting)
{
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
{
Debug.Log("OperationResponse ignored while disconnecting. Code: " + operationResponse.OperationCode);
}
return;
}
// extra logging for error debugging (helping developers with a bit of automated analysis)
if (operationResponse.ReturnCode == 0)
{
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
Debug.Log(operationResponse.ToString());
}
else
{
if (operationResponse.ReturnCode == ErrorCode.OperationNotAllowedInCurrentState)
{
Debug.LogError("Operation " + operationResponse.OperationCode + " could not be executed (yet). Wait for state JoinedLobby or ConnectedToMaster and their callbacks before calling operations. WebRPCs need a server-side configuration. Enum OperationCode helps identify the operation.");
}
else if (operationResponse.ReturnCode == ErrorCode.PluginReportedError)
{
Debug.LogError("Operation " + operationResponse.OperationCode + " failed in a server-side plugin. Check the configuration in the Dashboard. Message from server-plugin: " + operationResponse.DebugMessage);
}
else if (operationResponse.ReturnCode == ErrorCode.NoRandomMatchFound)
{
Debug.LogWarning("Operation failed: " + operationResponse.ToStringFull());
}
else
{
Debug.LogError("Operation failed: " + operationResponse.ToStringFull() + " Server: " + this.server);
}
}
// use the "secret" or "token" whenever we get it. doesn't really matter if it's in AuthResponse.
if (operationResponse.Parameters.ContainsKey(ParameterCode.Secret))
{
if (this.CustomAuthenticationValues == null)
{
this.CustomAuthenticationValues = new AuthenticationValues();
// this.DebugReturn(DebugLevel.ERROR, "Server returned secret. Created CustomAuthenticationValues.");
}
this.CustomAuthenticationValues.Token = operationResponse[ParameterCode.Secret] as string;
}
switch (operationResponse.OperationCode)
{
case OperationCode.Authenticate:
{
// PeerState oldState = this.State;
if (operationResponse.ReturnCode != 0)
{
if (operationResponse.ReturnCode == ErrorCode.InvalidOperation)
{
Debug.LogError(string.Format("If you host Photon yourself, make sure to start the 'Instance LoadBalancing' "+ this.ServerAddress));
}
else if (operationResponse.ReturnCode == ErrorCode.InvalidAuthentication)
{
Debug.LogError(string.Format("The appId this client sent is unknown on the server (Cloud). Check settings. If using the Cloud, check account."));
SendMonoMessage(PhotonNetworkingMessage.OnFailedToConnectToPhoton, DisconnectCause.InvalidAuthentication);
}
else if (operationResponse.ReturnCode == ErrorCode.CustomAuthenticationFailed)
{
Debug.LogError(string.Format("Custom Authentication failed (either due to user-input or configuration or AuthParameter string format). Calling: OnCustomAuthenticationFailed()"));
SendMonoMessage(PhotonNetworkingMessage.OnCustomAuthenticationFailed, operationResponse.DebugMessage);
}
else
{
Debug.LogError(string.Format("Authentication failed: '{0}' Code: {1}", operationResponse.DebugMessage, operationResponse.ReturnCode));
}
this.State = global::PeerState.Disconnecting;
this.Disconnect();
if (operationResponse.ReturnCode == ErrorCode.MaxCcuReached)
{
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
Debug.LogWarning(string.Format("Currently, the limit of users is reached for this title. Try again later. Disconnecting"));
SendMonoMessage(PhotonNetworkingMessage.OnPhotonMaxCccuReached);
SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, DisconnectCause.MaxCcuReached);
}
else if (operationResponse.ReturnCode == ErrorCode.InvalidRegion)
{
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
Debug.LogError(string.Format("The used master server address is not available with the subscription currently used. Got to Photon Cloud Dashboard or change URL. Disconnecting."));
SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, DisconnectCause.InvalidRegion);
}
else if (operationResponse.ReturnCode == ErrorCode.AuthenticationTicketExpired)
{
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
Debug.LogError(string.Format("The authentication ticket expired. You need to connect (and authenticate) again. Disconnecting."));
SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, DisconnectCause.AuthenticationTicketExpired);
}
break;
}
else
{
if (this.server == ServerConnection.NameServer)
{
// on the NameServer, authenticate returns the MasterServer address for a region and we hop off to there
this.MasterServerAddress = operationResponse[ParameterCode.Address] as string;
this.DisconnectToReconnect();
}
else if (this.server == ServerConnection.MasterServer)
{
if (PhotonNetwork.autoJoinLobby)
{
this.State = global::PeerState.Authenticated;
this.OpJoinLobby(this.lobby);
}
else
{
this.State = global::PeerState.ConnectedToMaster;
NetworkingPeer.SendMonoMessage(PhotonNetworkingMessage.OnConnectedToMaster);
}
}
else if (this.server == ServerConnection.GameServer)
{
this.State = global::PeerState.Joining;
this.enterRoomParamsCache.PlayerProperties = GetLocalActorProperties();
this.enterRoomParamsCache.OnGameServer = true;
if (this.mLastJoinType == JoinType.JoinGame || this.mLastJoinType == JoinType.JoinRandomGame || this.mLastJoinType == JoinType.JoinOrCreateOnDemand)
{
// if we just "join" the game, do so. if we wanted to "create the room on demand", we have to send this to the game server as well.
this.OpJoinRoom(this.enterRoomParamsCache);
}
else if (this.mLastJoinType == JoinType.CreateGame)
{
this.OpCreateGame(this.enterRoomParamsCache);
}
break;
}
}
break;
}
case OperationCode.GetRegions:
// Debug.Log("GetRegions returned: " + operationResponse.ToStringFull());
if (operationResponse.ReturnCode == ErrorCode.InvalidAuthentication)
{
Debug.LogError(string.Format("The appId this client sent is unknown on the server (Cloud). Check settings. If using the Cloud, check account."));
SendMonoMessage(PhotonNetworkingMessage.OnFailedToConnectToPhoton, DisconnectCause.InvalidAuthentication);
this.State = global::PeerState.Disconnecting;
this.Disconnect();
break;
}
if (operationResponse.ReturnCode != ErrorCode.Ok)
{
Debug.LogError("GetRegions failed. Can't provide regions list. Error: " + operationResponse.ReturnCode + ": " + operationResponse.DebugMessage);
break;
}
string[] regions = operationResponse[ParameterCode.Region] as string[];
string[] servers = operationResponse[ParameterCode.Address] as string[];
if (regions == null || servers == null || regions.Length != servers.Length)
{
Debug.LogError("The region arrays from Name Server are not ok. Must be non-null and same length. " + (regions ==null)+ " " + (servers==null) + "\n"+operationResponse.ToStringFull());
break;
}
this.AvailableRegions = new List<Region>(regions.Length);
for (int i = 0; i < regions.Length; i++)
{
string regionCodeString = regions[i];
if (string.IsNullOrEmpty(regionCodeString))
{
continue;
}
regionCodeString = regionCodeString.ToLower();
CloudRegionCode code = Region.Parse(regionCodeString);
// check if enabled (or ignored by PhotonServerSettings.EnabledRegions)
bool enabledRegion = true;
if (PhotonNetwork.PhotonServerSettings.HostType == ServerSettings.HostingOption.BestRegion && PhotonNetwork.PhotonServerSettings.EnabledRegions != 0)
{
CloudRegionFlag flag = Region.ParseFlag(regionCodeString);
enabledRegion = ((PhotonNetwork.PhotonServerSettings.EnabledRegions & flag) != 0);
if (!enabledRegion && PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
{
Debug.Log("Skipping region because it's not in PhotonServerSettings.EnabledRegions: " + code);
}
}
if (enabledRegion) this.AvailableRegions.Add(new Region() { Code = code, HostAndPort = servers[i] });
}
// PUN assumes you fetch the name-server's list of regions to ping them
if (PhotonNetwork.PhotonServerSettings.HostType == ServerSettings.HostingOption.BestRegion)
{
PhotonHandler.PingAvailableRegionsAndConnectToBest();
}
break;
case OperationCode.CreateGame:
{
if (this.server == ServerConnection.GameServer)
{
this.GameEnteredOnGameServer(operationResponse);
}
else
{
if (operationResponse.ReturnCode != 0)
{
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
Debug.LogWarning(string.Format("CreateRoom failed, client stays on masterserver: {0}.", operationResponse.ToStringFull()));
SendMonoMessage(PhotonNetworkingMessage.OnPhotonCreateRoomFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
break;
}
string gameID = (string) operationResponse[ParameterCode.RoomName];
if (!string.IsNullOrEmpty(gameID))
{
// is only sent by the server's response, if it has not been
// sent with the client's request before!
this.enterRoomParamsCache.RoomName = gameID;
}
this.mGameserver = (string)operationResponse[ParameterCode.Address];
this.DisconnectToReconnect();
}
break;
}
case OperationCode.JoinGame:
{
if (this.server != ServerConnection.GameServer)
{
if (operationResponse.ReturnCode != 0)
{
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
Debug.Log(string.Format("JoinRoom failed (room maybe closed by now). Client stays on masterserver: {0}. State: {1}", operationResponse.ToStringFull(), this.State));
SendMonoMessage(PhotonNetworkingMessage.OnPhotonJoinRoomFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
break;
}
this.mGameserver = (string)operationResponse[ParameterCode.Address];
this.DisconnectToReconnect();
}
else
{
this.GameEnteredOnGameServer(operationResponse);
}
break;
}
case OperationCode.JoinRandomGame:
{
// happens only on master. on gameserver, this is a regular join (we don't need to find a random game again)
// the operation OpJoinRandom either fails (with returncode 8) or returns game-to-join information
if (operationResponse.ReturnCode != 0)
{
if (operationResponse.ReturnCode == ErrorCode.NoRandomMatchFound)
{
if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
Debug.Log("JoinRandom failed: No open game. Calling: OnPhotonRandomJoinFailed() and staying on master server.");
}
else if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
{
Debug.LogWarning(string.Format("JoinRandom failed: {0}.", operationResponse.ToStringFull()));
}
SendMonoMessage(PhotonNetworkingMessage.OnPhotonRandomJoinFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
break;
}
string roomName = (string)operationResponse[ParameterCode.RoomName];
this.enterRoomParamsCache.RoomName = roomName;
this.mGameserver = (string)operationResponse[ParameterCode.Address];
this.DisconnectToReconnect();
break;
}
case OperationCode.JoinLobby:
this.State = global::PeerState.JoinedLobby;
this.insideLobby = true;
SendMonoMessage(PhotonNetworkingMessage.OnJoinedLobby);
// this.mListener.joinLobbyReturn();
break;
case OperationCode.LeaveLobby:
this.State = global::PeerState.Authenticated;
this.LeftLobbyCleanup(); // will set insideLobby = false
break;
case OperationCode.Leave:
this.DisconnectToReconnect();
break;
case OperationCode.SetProperties:
// this.mListener.setPropertiesReturn(returnCode, debugMsg);
break;
case OperationCode.GetProperties:
{
Hashtable actorProperties = (Hashtable)operationResponse[ParameterCode.PlayerProperties];
Hashtable gameProperties = (Hashtable)operationResponse[ParameterCode.GameProperties];
this.ReadoutProperties(gameProperties, actorProperties, 0);
// RemoveByteTypedPropertyKeys(actorProperties, false);
// RemoveByteTypedPropertyKeys(gameProperties, false);
// this.mListener.getPropertiesReturn(gameProperties, actorProperties, returnCode, debugMsg);
break;
}
case OperationCode.RaiseEvent:
// this usually doesn't give us a result. only if the caching is affected the server will send one.
break;
case OperationCode.FindFriends:
bool[] onlineList = operationResponse[ParameterCode.FindFriendsResponseOnlineList] as bool[];
string[] roomList = operationResponse[ParameterCode.FindFriendsResponseRoomIdList] as string[];
if (onlineList != null && roomList != null && this.friendListRequested != null && onlineList.Length == this.friendListRequested.Length)
{
List<FriendInfo> friendList = new List<FriendInfo>(this.friendListRequested.Length);
for (int index = 0; index < this.friendListRequested.Length; index++)
{
FriendInfo friend = new FriendInfo();
friend.Name = this.friendListRequested[index];
friend.Room = roomList[index];
friend.IsOnline = onlineList[index];
friendList.Insert(index, friend);
}
PhotonNetwork.Friends = friendList;
}
else
{
// any of the lists is null and shouldn't. print a error
Debug.LogError("FindFriends failed to apply the result, as a required value wasn't provided or the friend list length differed from result.");
}
this.friendListRequested = null;
this.isFetchingFriends = false;
this.friendListTimestamp = Environment.TickCount;
if (this.friendListTimestamp == 0)
{
this.friendListTimestamp = 1; // makes sure the timestamp is not accidentally 0
}
SendMonoMessage(PhotonNetworkingMessage.OnUpdatedFriendList);
break;
case OperationCode.WebRpc:
SendMonoMessage(PhotonNetworkingMessage.OnWebRpcResponse, operationResponse);
break;
default:
Debug.LogWarning(string.Format("OperationResponse unhandled: {0}", operationResponse.ToString()));
break;
}
//this.externalListener.OnOperationResponse(operationResponse);
}