mirror of
https://github.com/FriendshipIsEpic/FiE-Game.git
synced 2024-11-29 00:27:59 +01:00
3387 lines
98 KiB
C#
3387 lines
98 KiB
C#
using ExitGames.Client.Photon;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
|
|
internal class NetworkingPeer : LoadBalancingPeer, IPhotonPeerListener
|
|
{
|
|
protected internal string AppId;
|
|
|
|
private string tokenCache;
|
|
|
|
public AuthModeOption AuthMode;
|
|
|
|
public EncryptionMode EncryptionMode;
|
|
|
|
public const string NameServerHost = "ns.exitgames.com";
|
|
|
|
public const string NameServerHttp = "http://ns.exitgamescloud.com:80/photon/n";
|
|
|
|
private static readonly Dictionary<ConnectionProtocol, int> ProtocolToNameServerPort = new Dictionary<ConnectionProtocol, int>
|
|
{
|
|
{
|
|
ConnectionProtocol.Udp,
|
|
5058
|
|
},
|
|
{
|
|
ConnectionProtocol.Tcp,
|
|
4533
|
|
},
|
|
{
|
|
ConnectionProtocol.WebSocket,
|
|
9093
|
|
},
|
|
{
|
|
ConnectionProtocol.WebSocketSecure,
|
|
19093
|
|
}
|
|
};
|
|
|
|
public bool IsInitialConnect;
|
|
|
|
public bool insideLobby;
|
|
|
|
protected internal List<TypedLobbyInfo> LobbyStatistics = new List<TypedLobbyInfo>();
|
|
|
|
public Dictionary<string, RoomInfo> mGameList = new Dictionary<string, RoomInfo>();
|
|
|
|
public RoomInfo[] mGameListCopy = new RoomInfo[0];
|
|
|
|
private string playername = string.Empty;
|
|
|
|
private bool mPlayernameHasToBeUpdated;
|
|
|
|
private Room currentRoom;
|
|
|
|
private JoinType lastJoinType;
|
|
|
|
protected internal EnterRoomParams enterRoomParamsCache;
|
|
|
|
private bool didAuthenticate;
|
|
|
|
private string[] friendListRequested;
|
|
|
|
private int friendListTimestamp;
|
|
|
|
private bool isFetchingFriendList;
|
|
|
|
public Dictionary<int, PhotonPlayer> mActors = new Dictionary<int, PhotonPlayer>();
|
|
|
|
public PhotonPlayer[] mOtherPlayerListCopy = new PhotonPlayer[0];
|
|
|
|
public PhotonPlayer[] mPlayerListCopy = new PhotonPlayer[0];
|
|
|
|
public bool hasSwitchedMC;
|
|
|
|
private HashSet<int> allowedReceivingGroups = new HashSet<int>();
|
|
|
|
private HashSet<int> blockSendingGroups = new HashSet<int>();
|
|
|
|
protected internal Dictionary<int, PhotonView> photonViewList = new Dictionary<int, PhotonView>();
|
|
|
|
private readonly PhotonStream readStream = new PhotonStream(write: false, null);
|
|
|
|
private readonly PhotonStream pStream = new PhotonStream(write: true, null);
|
|
|
|
private readonly Dictionary<int, ExitGames.Client.Photon.Hashtable> dataPerGroupReliable = new Dictionary<int, ExitGames.Client.Photon.Hashtable>();
|
|
|
|
private readonly Dictionary<int, ExitGames.Client.Photon.Hashtable> dataPerGroupUnreliable = new Dictionary<int, ExitGames.Client.Photon.Hashtable>();
|
|
|
|
protected internal short currentLevelPrefix;
|
|
|
|
protected internal bool loadingLevelAndPausedNetwork;
|
|
|
|
protected internal const string CurrentSceneProperty = "curScn";
|
|
|
|
public static bool UsePrefabCache = true;
|
|
|
|
internal IPunPrefabPool ObjectPool;
|
|
|
|
public static Dictionary<string, GameObject> PrefabCache = new Dictionary<string, GameObject>();
|
|
|
|
private Dictionary<Type, List<MethodInfo>> monoRPCMethodsCache = new Dictionary<Type, List<MethodInfo>>();
|
|
|
|
private readonly Dictionary<string, int> rpcShortcuts;
|
|
|
|
private static readonly string OnPhotonInstantiateString = 18.ToString();
|
|
|
|
private Dictionary<int, object[]> tempInstantiationData = new Dictionary<int, object[]>();
|
|
|
|
public static int ObjectsInOneUpdate = 10;
|
|
|
|
public const int SyncViewId = 0;
|
|
|
|
public const int SyncCompressed = 1;
|
|
|
|
public const int SyncNullValues = 2;
|
|
|
|
public const int SyncFirstValue = 3;
|
|
|
|
protected internal string AppVersion => string.Format("{0}_{1}", PhotonNetwork.gameVersion, "1.80");
|
|
|
|
public AuthenticationValues AuthValues
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
private string TokenForInit
|
|
{
|
|
get
|
|
{
|
|
if (AuthMode == AuthModeOption.Auth)
|
|
{
|
|
return null;
|
|
}
|
|
return (AuthValues == null) ? null : AuthValues.Token;
|
|
}
|
|
}
|
|
|
|
public bool IsUsingNameServer
|
|
{
|
|
get;
|
|
protected internal set;
|
|
}
|
|
|
|
public string NameServerAddress => GetNameServerAddress();
|
|
|
|
public string MasterServerAddress
|
|
{
|
|
get;
|
|
protected internal set;
|
|
}
|
|
|
|
public string GameServerAddress
|
|
{
|
|
get;
|
|
protected internal set;
|
|
}
|
|
|
|
protected internal ServerConnection Server
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public ClientState State
|
|
{
|
|
get;
|
|
internal set;
|
|
}
|
|
|
|
public TypedLobby lobby
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
private bool requestLobbyStatistics => PhotonNetwork.EnableLobbyStatistics && Server == ServerConnection.MasterServer;
|
|
|
|
public string PlayerName
|
|
{
|
|
get
|
|
{
|
|
return playername;
|
|
}
|
|
set
|
|
{
|
|
if (!string.IsNullOrEmpty(value) && !value.Equals(playername))
|
|
{
|
|
if (LocalPlayer != null)
|
|
{
|
|
LocalPlayer.NickName = value;
|
|
}
|
|
playername = value;
|
|
if (CurrentRoom != null)
|
|
{
|
|
SendPlayerName();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public Room CurrentRoom
|
|
{
|
|
get
|
|
{
|
|
if (currentRoom != null && currentRoom.IsLocalClientInside)
|
|
{
|
|
return currentRoom;
|
|
}
|
|
return null;
|
|
}
|
|
private set
|
|
{
|
|
currentRoom = value;
|
|
}
|
|
}
|
|
|
|
public PhotonPlayer LocalPlayer
|
|
{
|
|
get;
|
|
internal set;
|
|
}
|
|
|
|
public int PlayersOnMasterCount
|
|
{
|
|
get;
|
|
internal set;
|
|
}
|
|
|
|
public int PlayersInRoomsCount
|
|
{
|
|
get;
|
|
internal set;
|
|
}
|
|
|
|
public int RoomsCount
|
|
{
|
|
get;
|
|
internal set;
|
|
}
|
|
|
|
protected internal int FriendListAge => (!isFetchingFriendList && friendListTimestamp != 0) ? (Environment.TickCount - friendListTimestamp) : 0;
|
|
|
|
public bool IsAuthorizeSecretAvailable => AuthValues != null && !string.IsNullOrEmpty(AuthValues.Token);
|
|
|
|
public List<Region> AvailableRegions
|
|
{
|
|
get;
|
|
protected internal set;
|
|
}
|
|
|
|
public CloudRegionCode CloudRegion
|
|
{
|
|
get;
|
|
protected internal set;
|
|
}
|
|
|
|
public int mMasterClientId
|
|
{
|
|
get
|
|
{
|
|
if (PhotonNetwork.offlineMode)
|
|
{
|
|
return LocalPlayer.ID;
|
|
}
|
|
return (CurrentRoom != null) ? CurrentRoom.MasterClientId : 0;
|
|
}
|
|
private set
|
|
{
|
|
if (CurrentRoom != null)
|
|
{
|
|
CurrentRoom.MasterClientId = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public NetworkingPeer(string playername, ConnectionProtocol connectionProtocol)
|
|
: base(connectionProtocol)
|
|
{
|
|
base.Listener = this;
|
|
base.LimitOfUnreliableCommands = 40;
|
|
lobby = TypedLobby.Default;
|
|
PlayerName = playername;
|
|
LocalPlayer = new PhotonPlayer(isLocal: true, -1, this.playername);
|
|
AddNewPlayer(LocalPlayer.ID, LocalPlayer);
|
|
rpcShortcuts = new Dictionary<string, int>(PhotonNetwork.PhotonServerSettings.RpcList.Count);
|
|
for (int i = 0; i < PhotonNetwork.PhotonServerSettings.RpcList.Count; i++)
|
|
{
|
|
string key = PhotonNetwork.PhotonServerSettings.RpcList[i];
|
|
rpcShortcuts[key] = i;
|
|
}
|
|
State = ClientState.PeerCreated;
|
|
}
|
|
|
|
private string GetNameServerAddress()
|
|
{
|
|
ConnectionProtocol transportProtocol = base.TransportProtocol;
|
|
int value = 0;
|
|
ProtocolToNameServerPort.TryGetValue(transportProtocol, out value);
|
|
string arg = string.Empty;
|
|
switch (transportProtocol)
|
|
{
|
|
case ConnectionProtocol.WebSocket:
|
|
arg = "ws://";
|
|
break;
|
|
case ConnectionProtocol.WebSocketSecure:
|
|
arg = "wss://";
|
|
break;
|
|
}
|
|
return string.Format("{0}{1}:{2}", arg, "ns.exitgames.com", value);
|
|
}
|
|
|
|
public override bool Connect(string serverAddress, string applicationName)
|
|
{
|
|
Debug.LogError("Avoid using this directly. Thanks.");
|
|
return false;
|
|
}
|
|
|
|
public bool ReconnectToMaster()
|
|
{
|
|
if (AuthValues == null)
|
|
{
|
|
Debug.LogWarning("ReconnectToMaster() with AuthValues == null is not correct!");
|
|
AuthValues = new AuthenticationValues();
|
|
}
|
|
AuthValues.Token = tokenCache;
|
|
return Connect(MasterServerAddress, ServerConnection.MasterServer);
|
|
}
|
|
|
|
public bool ReconnectAndRejoin()
|
|
{
|
|
if (AuthValues == null)
|
|
{
|
|
Debug.LogWarning("ReconnectAndRejoin() with AuthValues == null is not correct!");
|
|
AuthValues = new AuthenticationValues();
|
|
}
|
|
AuthValues.Token = tokenCache;
|
|
if (!string.IsNullOrEmpty(GameServerAddress) && enterRoomParamsCache != null)
|
|
{
|
|
lastJoinType = JoinType.JoinRoom;
|
|
enterRoomParamsCache.RejoinOnly = true;
|
|
return Connect(GameServerAddress, ServerConnection.GameServer);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool Connect(string serverAddress, ServerConnection type)
|
|
{
|
|
if (PhotonHandler.AppQuits)
|
|
{
|
|
Debug.LogWarning("Ignoring Connect() because app gets closed. If this is an error, check PhotonHandler.AppQuits.");
|
|
return false;
|
|
}
|
|
if (State == ClientState.Disconnecting)
|
|
{
|
|
Debug.LogError("Connect() failed. Can't connect while disconnecting (still). Current state: " + PhotonNetwork.connectionStateDetailed);
|
|
return false;
|
|
}
|
|
SetupProtocol(type);
|
|
bool flag = base.Connect(serverAddress, string.Empty, TokenForInit);
|
|
if (flag)
|
|
{
|
|
switch (type)
|
|
{
|
|
case ServerConnection.NameServer:
|
|
State = ClientState.ConnectingToNameServer;
|
|
break;
|
|
case ServerConnection.MasterServer:
|
|
State = ClientState.ConnectingToMasterserver;
|
|
break;
|
|
case ServerConnection.GameServer:
|
|
State = ClientState.ConnectingToGameserver;
|
|
break;
|
|
}
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
public bool ConnectToNameServer()
|
|
{
|
|
if (PhotonHandler.AppQuits)
|
|
{
|
|
Debug.LogWarning("Ignoring Connect() because app gets closed. If this is an error, check PhotonHandler.AppQuits.");
|
|
return false;
|
|
}
|
|
IsUsingNameServer = true;
|
|
CloudRegion = CloudRegionCode.none;
|
|
if (State == ClientState.ConnectedToNameServer)
|
|
{
|
|
return true;
|
|
}
|
|
SetupProtocol(ServerConnection.NameServer);
|
|
if (!base.Connect(NameServerAddress, "ns", TokenForInit))
|
|
{
|
|
return false;
|
|
}
|
|
State = ClientState.ConnectingToNameServer;
|
|
return true;
|
|
}
|
|
|
|
public bool ConnectToRegionMaster(CloudRegionCode region)
|
|
{
|
|
if (PhotonHandler.AppQuits)
|
|
{
|
|
Debug.LogWarning("Ignoring Connect() because app gets closed. If this is an error, check PhotonHandler.AppQuits.");
|
|
return false;
|
|
}
|
|
IsUsingNameServer = true;
|
|
CloudRegion = region;
|
|
if (State == ClientState.ConnectedToNameServer)
|
|
{
|
|
return CallAuthenticate();
|
|
}
|
|
SetupProtocol(ServerConnection.NameServer);
|
|
if (!base.Connect(NameServerAddress, "ns", TokenForInit))
|
|
{
|
|
return false;
|
|
}
|
|
State = ClientState.ConnectingToNameServer;
|
|
return true;
|
|
}
|
|
|
|
protected internal void SetupProtocol(ServerConnection serverType)
|
|
{
|
|
ConnectionProtocol connectionProtocol = base.TransportProtocol;
|
|
if (AuthMode == AuthModeOption.AuthOnceWss)
|
|
{
|
|
if (serverType != ServerConnection.NameServer)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.ErrorsOnly)
|
|
{
|
|
Debug.LogWarning("Using PhotonServerSettings.Protocol when leaving the NameServer (AuthMode is AuthOnceWss): " + PhotonNetwork.PhotonServerSettings.Protocol);
|
|
}
|
|
connectionProtocol = PhotonNetwork.PhotonServerSettings.Protocol;
|
|
}
|
|
else
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.ErrorsOnly)
|
|
{
|
|
Debug.LogWarning("Using WebSocket to connect NameServer (AuthMode is AuthOnceWss).");
|
|
}
|
|
connectionProtocol = ConnectionProtocol.WebSocketSecure;
|
|
}
|
|
}
|
|
Type type = Type.GetType("ExitGames.Client.Photon.SocketWebTcp, Assembly-CSharp", throwOnError: false);
|
|
if (type == null)
|
|
{
|
|
type = Type.GetType("ExitGames.Client.Photon.SocketWebTcp, Assembly-CSharp-firstpass", throwOnError: false);
|
|
}
|
|
if (type != null)
|
|
{
|
|
SocketImplementationConfig[ConnectionProtocol.WebSocket] = type;
|
|
SocketImplementationConfig[ConnectionProtocol.WebSocketSecure] = type;
|
|
}
|
|
if (PhotonHandler.PingImplementation == null)
|
|
{
|
|
PhotonHandler.PingImplementation = typeof(PingMono);
|
|
}
|
|
if (base.TransportProtocol != connectionProtocol)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.ErrorsOnly)
|
|
{
|
|
Debug.LogWarning("Protocol switch from: " + base.TransportProtocol + " to: " + connectionProtocol + ".");
|
|
}
|
|
base.TransportProtocol = connectionProtocol;
|
|
}
|
|
}
|
|
|
|
public override void Disconnect()
|
|
{
|
|
if (base.PeerState == PeerStateValue.Disconnected)
|
|
{
|
|
if (!PhotonHandler.AppQuits)
|
|
{
|
|
Debug.LogWarning($"Can't execute Disconnect() while not connected. Nothing changed. State: {State}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
State = ClientState.Disconnecting;
|
|
base.Disconnect();
|
|
}
|
|
}
|
|
|
|
private bool CallAuthenticate()
|
|
{
|
|
object authenticationValues = AuthValues;
|
|
if (authenticationValues == null)
|
|
{
|
|
AuthenticationValues authenticationValues2 = new AuthenticationValues();
|
|
authenticationValues2.UserId = PlayerName;
|
|
authenticationValues = authenticationValues2;
|
|
}
|
|
AuthenticationValues authValues = (AuthenticationValues)authenticationValues;
|
|
if (AuthMode == AuthModeOption.Auth)
|
|
{
|
|
return OpAuthenticate(AppId, AppVersion, authValues, CloudRegion.ToString(), requestLobbyStatistics);
|
|
}
|
|
return OpAuthenticateOnce(AppId, AppVersion, authValues, CloudRegion.ToString(), EncryptionMode, PhotonNetwork.PhotonServerSettings.Protocol);
|
|
}
|
|
|
|
private void DisconnectToReconnect()
|
|
{
|
|
switch (Server)
|
|
{
|
|
case ServerConnection.NameServer:
|
|
State = ClientState.DisconnectingFromNameServer;
|
|
base.Disconnect();
|
|
break;
|
|
case ServerConnection.MasterServer:
|
|
State = ClientState.DisconnectingFromMasterserver;
|
|
base.Disconnect();
|
|
break;
|
|
case ServerConnection.GameServer:
|
|
State = ClientState.DisconnectingFromGameserver;
|
|
base.Disconnect();
|
|
break;
|
|
}
|
|
}
|
|
|
|
public bool GetRegions()
|
|
{
|
|
if (Server != ServerConnection.NameServer)
|
|
{
|
|
return false;
|
|
}
|
|
bool flag = OpGetRegions(AppId);
|
|
if (flag)
|
|
{
|
|
AvailableRegions = null;
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
public override bool OpFindFriends(string[] friendsToFind)
|
|
{
|
|
if (isFetchingFriendList)
|
|
{
|
|
return false;
|
|
}
|
|
friendListRequested = friendsToFind;
|
|
isFetchingFriendList = true;
|
|
return base.OpFindFriends(friendsToFind);
|
|
}
|
|
|
|
public bool OpCreateGame(EnterRoomParams enterRoomParams)
|
|
{
|
|
bool flag = enterRoomParams.OnGameServer = (Server == ServerConnection.GameServer);
|
|
enterRoomParams.PlayerProperties = GetLocalActorProperties();
|
|
if (!flag)
|
|
{
|
|
enterRoomParamsCache = enterRoomParams;
|
|
}
|
|
lastJoinType = JoinType.CreateRoom;
|
|
return base.OpCreateRoom(enterRoomParams);
|
|
}
|
|
|
|
public override bool OpJoinRoom(EnterRoomParams opParams)
|
|
{
|
|
if (!(opParams.OnGameServer = (Server == ServerConnection.GameServer)))
|
|
{
|
|
enterRoomParamsCache = opParams;
|
|
}
|
|
lastJoinType = ((!opParams.CreateIfNotExists) ? JoinType.JoinRoom : JoinType.JoinOrCreateRoom);
|
|
return base.OpJoinRoom(opParams);
|
|
}
|
|
|
|
public override bool OpJoinRandomRoom(OpJoinRandomRoomParams opJoinRandomRoomParams)
|
|
{
|
|
enterRoomParamsCache = new EnterRoomParams();
|
|
enterRoomParamsCache.Lobby = opJoinRandomRoomParams.TypedLobby;
|
|
enterRoomParamsCache.ExpectedUsers = opJoinRandomRoomParams.ExpectedUsers;
|
|
lastJoinType = JoinType.JoinRandomRoom;
|
|
return base.OpJoinRandomRoom(opJoinRandomRoomParams);
|
|
}
|
|
|
|
public virtual bool OpLeave()
|
|
{
|
|
if (State != ClientState.Joined)
|
|
{
|
|
Debug.LogWarning("Not sending leave operation. State is not 'Joined': " + State);
|
|
return false;
|
|
}
|
|
return OpCustom(254, null, sendReliable: true, 0);
|
|
}
|
|
|
|
public override bool OpRaiseEvent(byte eventCode, object customEventContent, bool sendReliable, RaiseEventOptions raiseEventOptions)
|
|
{
|
|
if (PhotonNetwork.offlineMode)
|
|
{
|
|
return false;
|
|
}
|
|
return base.OpRaiseEvent(eventCode, customEventContent, sendReliable, raiseEventOptions);
|
|
}
|
|
|
|
private void ReadoutProperties(ExitGames.Client.Photon.Hashtable gameProperties, ExitGames.Client.Photon.Hashtable pActorProperties, int targetActorNr)
|
|
{
|
|
if (pActorProperties != null && pActorProperties.Count > 0)
|
|
{
|
|
if (targetActorNr > 0)
|
|
{
|
|
PhotonPlayer playerWithId = GetPlayerWithId(targetActorNr);
|
|
if (playerWithId != null)
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable = ReadoutPropertiesForActorNr(pActorProperties, targetActorNr);
|
|
playerWithId.InternalCacheProperties(hashtable);
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonPlayerPropertiesChanged, playerWithId, hashtable);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (object key in pActorProperties.Keys)
|
|
{
|
|
int num = (int)key;
|
|
ExitGames.Client.Photon.Hashtable hashtable2 = (ExitGames.Client.Photon.Hashtable)pActorProperties[key];
|
|
string name = (string)hashtable2[(byte)byte.MaxValue];
|
|
PhotonPlayer photonPlayer = GetPlayerWithId(num);
|
|
if (photonPlayer == null)
|
|
{
|
|
photonPlayer = new PhotonPlayer(isLocal: false, num, name);
|
|
AddNewPlayer(num, photonPlayer);
|
|
}
|
|
photonPlayer.InternalCacheProperties(hashtable2);
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonPlayerPropertiesChanged, photonPlayer, hashtable2);
|
|
}
|
|
}
|
|
}
|
|
if (CurrentRoom != null && gameProperties != null)
|
|
{
|
|
CurrentRoom.InternalCacheProperties(gameProperties);
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonCustomRoomPropertiesChanged, gameProperties);
|
|
if (PhotonNetwork.automaticallySyncScene)
|
|
{
|
|
LoadLevelIfSynced();
|
|
}
|
|
}
|
|
}
|
|
|
|
private ExitGames.Client.Photon.Hashtable ReadoutPropertiesForActorNr(ExitGames.Client.Photon.Hashtable actorProperties, int actorNr)
|
|
{
|
|
if (actorProperties.ContainsKey(actorNr))
|
|
{
|
|
return (ExitGames.Client.Photon.Hashtable)actorProperties[actorNr];
|
|
}
|
|
return actorProperties;
|
|
}
|
|
|
|
public void ChangeLocalID(int newID)
|
|
{
|
|
if (LocalPlayer == null)
|
|
{
|
|
Debug.LogWarning($"LocalPlayer is null or not in mActors! LocalPlayer: {LocalPlayer} mActors==null: {mActors == null} newID: {newID}");
|
|
}
|
|
if (mActors.ContainsKey(LocalPlayer.ID))
|
|
{
|
|
mActors.Remove(LocalPlayer.ID);
|
|
}
|
|
LocalPlayer.InternalChangeLocalID(newID);
|
|
mActors[LocalPlayer.ID] = LocalPlayer;
|
|
RebuildPlayerListCopies();
|
|
}
|
|
|
|
private void LeftLobbyCleanup()
|
|
{
|
|
mGameList = new Dictionary<string, RoomInfo>();
|
|
mGameListCopy = new RoomInfo[0];
|
|
if (insideLobby)
|
|
{
|
|
insideLobby = false;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnLeftLobby);
|
|
}
|
|
}
|
|
|
|
private void LeftRoomCleanup()
|
|
{
|
|
bool flag = CurrentRoom != null;
|
|
bool flag2 = (CurrentRoom == null) ? PhotonNetwork.autoCleanUpPlayerObjects : CurrentRoom.AutoCleanUp;
|
|
hasSwitchedMC = false;
|
|
CurrentRoom = null;
|
|
mActors = new Dictionary<int, PhotonPlayer>();
|
|
mPlayerListCopy = new PhotonPlayer[0];
|
|
mOtherPlayerListCopy = new PhotonPlayer[0];
|
|
allowedReceivingGroups = new HashSet<int>();
|
|
blockSendingGroups = new HashSet<int>();
|
|
mGameList = new Dictionary<string, RoomInfo>();
|
|
mGameListCopy = new RoomInfo[0];
|
|
isFetchingFriendList = false;
|
|
ChangeLocalID(-1);
|
|
if (flag2)
|
|
{
|
|
LocalCleanupAnythingInstantiated(destroyInstantiatedGameObjects: true);
|
|
PhotonNetwork.manuallyAllocatedViewIds = new List<int>();
|
|
}
|
|
if (flag)
|
|
{
|
|
SendMonoMessage(PhotonNetworkingMessage.OnLeftRoom);
|
|
}
|
|
}
|
|
|
|
protected internal void LocalCleanupAnythingInstantiated(bool destroyInstantiatedGameObjects)
|
|
{
|
|
if (tempInstantiationData.Count > 0)
|
|
{
|
|
Debug.LogWarning("It seems some instantiation is not completed, as instantiation data is used. You should make sure instantiations are paused when calling this method. Cleaning now, despite this.");
|
|
}
|
|
if (destroyInstantiatedGameObjects)
|
|
{
|
|
HashSet<GameObject> hashSet = new HashSet<GameObject>();
|
|
foreach (PhotonView value in photonViewList.Values)
|
|
{
|
|
if (value.isRuntimeInstantiated)
|
|
{
|
|
hashSet.Add(value.gameObject);
|
|
}
|
|
}
|
|
foreach (GameObject item in hashSet)
|
|
{
|
|
RemoveInstantiatedGO(item, localOnly: true);
|
|
}
|
|
}
|
|
tempInstantiationData.Clear();
|
|
PhotonNetwork.lastUsedViewSubId = 0;
|
|
PhotonNetwork.lastUsedViewSubIdStatic = 0;
|
|
}
|
|
|
|
private void GameEnteredOnGameServer(OperationResponse operationResponse)
|
|
{
|
|
if (operationResponse.ReturnCode != 0)
|
|
{
|
|
switch (operationResponse.OperationCode)
|
|
{
|
|
case 227:
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log("Create failed on GameServer. Changing back to MasterServer. Msg: " + operationResponse.DebugMessage);
|
|
}
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonCreateRoomFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
|
|
break;
|
|
case 226:
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log("Join failed on GameServer. Changing back to MasterServer. Msg: " + operationResponse.DebugMessage);
|
|
if (operationResponse.ReturnCode == 32758)
|
|
{
|
|
Debug.Log("Most likely the game became empty during the switch to GameServer.");
|
|
}
|
|
}
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonJoinRoomFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
|
|
break;
|
|
case 225:
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log("Join failed on GameServer. Changing back to MasterServer. Msg: " + operationResponse.DebugMessage);
|
|
if (operationResponse.ReturnCode == 32758)
|
|
{
|
|
Debug.Log("Most likely the game became empty during the switch to GameServer.");
|
|
}
|
|
}
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonRandomJoinFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
|
|
break;
|
|
}
|
|
DisconnectToReconnect();
|
|
}
|
|
else
|
|
{
|
|
Room room = new Room(enterRoomParamsCache.RoomName, null);
|
|
room.IsLocalClientInside = true;
|
|
CurrentRoom = room;
|
|
State = ClientState.Joined;
|
|
if (operationResponse.Parameters.ContainsKey(252))
|
|
{
|
|
int[] actorsInRoom = (int[])operationResponse.Parameters[252];
|
|
UpdatedActorList(actorsInRoom);
|
|
}
|
|
int newID = (int)operationResponse[254];
|
|
ChangeLocalID(newID);
|
|
ExitGames.Client.Photon.Hashtable pActorProperties = (ExitGames.Client.Photon.Hashtable)operationResponse[249];
|
|
ExitGames.Client.Photon.Hashtable gameProperties = (ExitGames.Client.Photon.Hashtable)operationResponse[248];
|
|
ReadoutProperties(gameProperties, pActorProperties, 0);
|
|
if (!CurrentRoom.serverSideMasterClient)
|
|
{
|
|
CheckMasterClient(-1);
|
|
}
|
|
if (mPlayernameHasToBeUpdated)
|
|
{
|
|
SendPlayerName();
|
|
}
|
|
switch (operationResponse.OperationCode)
|
|
{
|
|
case 227:
|
|
SendMonoMessage(PhotonNetworkingMessage.OnCreatedRoom);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AddNewPlayer(int ID, PhotonPlayer player)
|
|
{
|
|
if (!mActors.ContainsKey(ID))
|
|
{
|
|
mActors[ID] = player;
|
|
RebuildPlayerListCopies();
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("Adding player twice: " + ID);
|
|
}
|
|
}
|
|
|
|
private void RemovePlayer(int ID, PhotonPlayer player)
|
|
{
|
|
mActors.Remove(ID);
|
|
if (!player.IsLocal)
|
|
{
|
|
RebuildPlayerListCopies();
|
|
}
|
|
}
|
|
|
|
private void RebuildPlayerListCopies()
|
|
{
|
|
mPlayerListCopy = new PhotonPlayer[mActors.Count];
|
|
mActors.Values.CopyTo(mPlayerListCopy, 0);
|
|
List<PhotonPlayer> list = new List<PhotonPlayer>();
|
|
for (int i = 0; i < mPlayerListCopy.Length; i++)
|
|
{
|
|
PhotonPlayer photonPlayer = mPlayerListCopy[i];
|
|
if (!photonPlayer.IsLocal)
|
|
{
|
|
list.Add(photonPlayer);
|
|
}
|
|
}
|
|
mOtherPlayerListCopy = list.ToArray();
|
|
}
|
|
|
|
private void ResetPhotonViewsOnSerialize()
|
|
{
|
|
foreach (PhotonView value in photonViewList.Values)
|
|
{
|
|
value.lastOnSerializeDataSent = null;
|
|
}
|
|
}
|
|
|
|
private void HandleEventLeave(int actorID, EventData evLeave)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log("HandleEventLeave for player ID: " + actorID + " evLeave: " + evLeave.ToStringFull());
|
|
}
|
|
PhotonPlayer playerWithId = GetPlayerWithId(actorID);
|
|
if (playerWithId == null)
|
|
{
|
|
Debug.LogError($"Received event Leave for unknown player ID: {actorID}");
|
|
}
|
|
else
|
|
{
|
|
bool isInactive = playerWithId.IsInactive;
|
|
if (evLeave.Parameters.ContainsKey(233))
|
|
{
|
|
playerWithId.IsInactive = (bool)evLeave.Parameters[233];
|
|
if (playerWithId.IsInactive && isInactive)
|
|
{
|
|
Debug.LogWarning("HandleEventLeave for player ID: " + actorID + " isInactive: " + playerWithId.IsInactive + ". Stopping handling if inactive.");
|
|
return;
|
|
}
|
|
}
|
|
if (evLeave.Parameters.ContainsKey(203))
|
|
{
|
|
if ((int)evLeave[203] != 0)
|
|
{
|
|
mMasterClientId = (int)evLeave[203];
|
|
UpdateMasterClient();
|
|
}
|
|
}
|
|
else if (!CurrentRoom.serverSideMasterClient)
|
|
{
|
|
CheckMasterClient(actorID);
|
|
}
|
|
if (!playerWithId.IsInactive || isInactive)
|
|
{
|
|
if (CurrentRoom != null && CurrentRoom.AutoCleanUp)
|
|
{
|
|
DestroyPlayerObjects(actorID, localOnly: true);
|
|
}
|
|
RemovePlayer(actorID, playerWithId);
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonPlayerDisconnected, playerWithId);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CheckMasterClient(int leavingPlayerId)
|
|
{
|
|
bool flag = mMasterClientId == leavingPlayerId;
|
|
bool flag2 = leavingPlayerId > 0;
|
|
if (!flag2 || flag)
|
|
{
|
|
int num;
|
|
if (mActors.Count <= 1)
|
|
{
|
|
num = LocalPlayer.ID;
|
|
}
|
|
else
|
|
{
|
|
num = 2147483647;
|
|
foreach (int key in mActors.Keys)
|
|
{
|
|
if (key < num && key != leavingPlayerId)
|
|
{
|
|
num = key;
|
|
}
|
|
}
|
|
}
|
|
mMasterClientId = num;
|
|
if (flag2)
|
|
{
|
|
SendMonoMessage(PhotonNetworkingMessage.OnMasterClientSwitched, GetPlayerWithId(num));
|
|
}
|
|
}
|
|
}
|
|
|
|
protected internal void UpdateMasterClient()
|
|
{
|
|
SendMonoMessage(PhotonNetworkingMessage.OnMasterClientSwitched, PhotonNetwork.masterClient);
|
|
}
|
|
|
|
private static int ReturnLowestPlayerId(PhotonPlayer[] players, int playerIdToIgnore)
|
|
{
|
|
if (players == null || players.Length == 0)
|
|
{
|
|
return -1;
|
|
}
|
|
int num = 2147483647;
|
|
foreach (PhotonPlayer photonPlayer in players)
|
|
{
|
|
if (photonPlayer.ID != playerIdToIgnore && photonPlayer.ID < num)
|
|
{
|
|
num = photonPlayer.ID;
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
|
|
protected internal bool SetMasterClient(int playerId, bool sync)
|
|
{
|
|
if (mMasterClientId == playerId || !mActors.ContainsKey(playerId))
|
|
{
|
|
return false;
|
|
}
|
|
if (sync && !OpRaiseEvent(208, new ExitGames.Client.Photon.Hashtable
|
|
{
|
|
{
|
|
(byte)1,
|
|
playerId
|
|
}
|
|
}, sendReliable: true, null))
|
|
{
|
|
return false;
|
|
}
|
|
hasSwitchedMC = true;
|
|
CurrentRoom.MasterClientId = playerId;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnMasterClientSwitched, GetPlayerWithId(playerId));
|
|
return true;
|
|
}
|
|
|
|
public bool SetMasterClient(int nextMasterId)
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable.Add((byte)248, nextMasterId);
|
|
ExitGames.Client.Photon.Hashtable gameProperties = hashtable;
|
|
hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable.Add((byte)248, mMasterClientId);
|
|
ExitGames.Client.Photon.Hashtable expectedProperties = hashtable;
|
|
return OpSetPropertiesOfRoom(gameProperties, expectedProperties);
|
|
}
|
|
|
|
protected internal PhotonPlayer GetPlayerWithId(int number)
|
|
{
|
|
if (mActors == null)
|
|
{
|
|
return null;
|
|
}
|
|
PhotonPlayer value = null;
|
|
mActors.TryGetValue(number, out value);
|
|
return value;
|
|
}
|
|
|
|
private void SendPlayerName()
|
|
{
|
|
if (State == ClientState.Joining)
|
|
{
|
|
mPlayernameHasToBeUpdated = true;
|
|
}
|
|
else if (LocalPlayer != null)
|
|
{
|
|
LocalPlayer.NickName = PlayerName;
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable[(byte)byte.MaxValue] = PlayerName;
|
|
if (LocalPlayer.ID > 0)
|
|
{
|
|
OpSetPropertiesOfActor(LocalPlayer.ID, hashtable);
|
|
mPlayernameHasToBeUpdated = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private ExitGames.Client.Photon.Hashtable GetLocalActorProperties()
|
|
{
|
|
if (PhotonNetwork.player != null)
|
|
{
|
|
return PhotonNetwork.player.AllProperties;
|
|
}
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable[(byte)byte.MaxValue] = PlayerName;
|
|
return hashtable;
|
|
}
|
|
|
|
public void DebugReturn(DebugLevel level, string message)
|
|
{
|
|
switch (level)
|
|
{
|
|
case DebugLevel.ERROR:
|
|
Debug.LogError(message);
|
|
return;
|
|
case DebugLevel.WARNING:
|
|
Debug.LogWarning(message);
|
|
return;
|
|
case DebugLevel.INFO:
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log(message);
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
if (level == DebugLevel.ALL && PhotonNetwork.logLevel == PhotonLogLevel.Full)
|
|
{
|
|
Debug.Log(message);
|
|
}
|
|
}
|
|
|
|
public void OnOperationResponse(OperationResponse operationResponse)
|
|
{
|
|
if (PhotonNetwork.networkingPeer.State == ClientState.Disconnecting)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log("OperationResponse ignored while disconnecting. Code: " + operationResponse.OperationCode);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (operationResponse.ReturnCode == 0)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log(operationResponse.ToString());
|
|
}
|
|
}
|
|
else if (operationResponse.ReturnCode == -3)
|
|
{
|
|
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 == 32752)
|
|
{
|
|
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 == 32760)
|
|
{
|
|
Debug.LogWarning("Operation failed: " + operationResponse.ToStringFull());
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("Operation failed: " + operationResponse.ToStringFull() + " Server: " + Server);
|
|
}
|
|
if (operationResponse.Parameters.ContainsKey(221))
|
|
{
|
|
if (AuthValues == null)
|
|
{
|
|
AuthValues = new AuthenticationValues();
|
|
}
|
|
AuthValues.Token = (operationResponse[221] as string);
|
|
tokenCache = AuthValues.Token;
|
|
}
|
|
switch (operationResponse.OperationCode)
|
|
{
|
|
case 252:
|
|
case 253:
|
|
break;
|
|
case 230:
|
|
case 231:
|
|
if (operationResponse.ReturnCode != 0)
|
|
{
|
|
if (operationResponse.ReturnCode == -2)
|
|
{
|
|
Debug.LogError(string.Format("If you host Photon yourself, make sure to start the 'Instance LoadBalancing' " + base.ServerAddress));
|
|
}
|
|
else if (operationResponse.ReturnCode == 32767)
|
|
{
|
|
Debug.LogError($"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 == 32755)
|
|
{
|
|
Debug.LogError($"Custom Authentication failed (either due to user-input or configuration or AuthParameter string format). Calling: OnCustomAuthenticationFailed()");
|
|
SendMonoMessage(PhotonNetworkingMessage.OnCustomAuthenticationFailed, operationResponse.DebugMessage);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"Authentication failed: '{operationResponse.DebugMessage}' Code: {operationResponse.ReturnCode}");
|
|
}
|
|
State = ClientState.Disconnecting;
|
|
Disconnect();
|
|
if (operationResponse.ReturnCode == 32757)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.LogWarning($"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 == 32756)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.LogError($"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 == 32753)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.LogError($"The authentication ticket expired. You need to connect (and authenticate) again. Disconnecting.");
|
|
}
|
|
SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, DisconnectCause.AuthenticationTicketExpired);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Server == ServerConnection.NameServer || Server == ServerConnection.MasterServer)
|
|
{
|
|
if (operationResponse.Parameters.ContainsKey(225))
|
|
{
|
|
string text = (string)operationResponse.Parameters[225];
|
|
if (!string.IsNullOrEmpty(text))
|
|
{
|
|
if (AuthValues == null)
|
|
{
|
|
AuthValues = new AuthenticationValues();
|
|
}
|
|
AuthValues.UserId = text;
|
|
PhotonNetwork.player.UserId = text;
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
DebugReturn(DebugLevel.INFO, $"Received your UserID from server. Updating local value to: {text}");
|
|
}
|
|
}
|
|
}
|
|
if (operationResponse.Parameters.ContainsKey(202))
|
|
{
|
|
playername = (string)operationResponse.Parameters[202];
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
DebugReturn(DebugLevel.INFO, $"Received your NickName from server. Updating local value to: {playername}");
|
|
}
|
|
}
|
|
if (operationResponse.Parameters.ContainsKey(192))
|
|
{
|
|
SetupEncryption((Dictionary<byte, object>)operationResponse.Parameters[192]);
|
|
}
|
|
}
|
|
if (Server == ServerConnection.NameServer)
|
|
{
|
|
MasterServerAddress = (operationResponse[230] as string);
|
|
DisconnectToReconnect();
|
|
}
|
|
else if (Server == ServerConnection.MasterServer)
|
|
{
|
|
if (AuthMode != 0)
|
|
{
|
|
OpSettings(requestLobbyStatistics);
|
|
}
|
|
if (PhotonNetwork.autoJoinLobby)
|
|
{
|
|
State = ClientState.Authenticated;
|
|
OpJoinLobby(lobby);
|
|
}
|
|
else
|
|
{
|
|
State = ClientState.ConnectedToMaster;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnConnectedToMaster);
|
|
}
|
|
}
|
|
else if (Server == ServerConnection.GameServer)
|
|
{
|
|
State = ClientState.Joining;
|
|
enterRoomParamsCache.PlayerProperties = GetLocalActorProperties();
|
|
enterRoomParamsCache.OnGameServer = true;
|
|
if (lastJoinType == JoinType.JoinRoom || lastJoinType == JoinType.JoinRandomRoom || lastJoinType == JoinType.JoinOrCreateRoom)
|
|
{
|
|
OpJoinRoom(enterRoomParamsCache);
|
|
}
|
|
else if (lastJoinType == JoinType.CreateRoom)
|
|
{
|
|
OpCreateGame(enterRoomParamsCache);
|
|
}
|
|
}
|
|
if (operationResponse.Parameters.ContainsKey(245))
|
|
{
|
|
Dictionary<string, object> dictionary = (Dictionary<string, object>)operationResponse.Parameters[245];
|
|
if (dictionary != null)
|
|
{
|
|
SendMonoMessage(PhotonNetworkingMessage.OnCustomAuthenticationResponse, dictionary);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 220:
|
|
if (operationResponse.ReturnCode == 32767)
|
|
{
|
|
Debug.LogError($"The appId this client sent is unknown on the server (Cloud). Check settings. If using the Cloud, check account.");
|
|
SendMonoMessage(PhotonNetworkingMessage.OnFailedToConnectToPhoton, DisconnectCause.InvalidAuthentication);
|
|
State = ClientState.Disconnecting;
|
|
Disconnect();
|
|
}
|
|
else if (operationResponse.ReturnCode != 0)
|
|
{
|
|
Debug.LogError("GetRegions failed. Can't provide regions list. Error: " + operationResponse.ReturnCode + ": " + operationResponse.DebugMessage);
|
|
}
|
|
else
|
|
{
|
|
string[] array3 = operationResponse[210] as string[];
|
|
string[] array4 = operationResponse[230] as string[];
|
|
if (array3 == null || array4 == null || array3.Length != array4.Length)
|
|
{
|
|
Debug.LogError("The region arrays from Name Server are not ok. Must be non-null and same length. " + (array3 == null) + " " + (array4 == null) + "\n" + operationResponse.ToStringFull());
|
|
}
|
|
else
|
|
{
|
|
AvailableRegions = new List<Region>(array3.Length);
|
|
for (int j = 0; j < array3.Length; j++)
|
|
{
|
|
string text3 = array3[j];
|
|
if (!string.IsNullOrEmpty(text3))
|
|
{
|
|
text3 = text3.ToLower();
|
|
CloudRegionCode cloudRegionCode = Region.Parse(text3);
|
|
bool flag = true;
|
|
if (PhotonNetwork.PhotonServerSettings.HostType == ServerSettings.HostingOption.BestRegion && PhotonNetwork.PhotonServerSettings.EnabledRegions != 0)
|
|
{
|
|
CloudRegionFlag cloudRegionFlag = Region.ParseFlag(text3);
|
|
flag = ((PhotonNetwork.PhotonServerSettings.EnabledRegions & cloudRegionFlag) != (CloudRegionFlag)0);
|
|
if (!flag && PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log("Skipping region because it's not in PhotonServerSettings.EnabledRegions: " + cloudRegionCode);
|
|
}
|
|
}
|
|
if (flag)
|
|
{
|
|
AvailableRegions.Add(new Region
|
|
{
|
|
Code = cloudRegionCode,
|
|
HostAndPort = array4[j]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
if (PhotonNetwork.PhotonServerSettings.HostType == ServerSettings.HostingOption.BestRegion)
|
|
{
|
|
PhotonHandler.PingAvailableRegionsAndConnectToBest();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 227:
|
|
if (Server == ServerConnection.GameServer)
|
|
{
|
|
GameEnteredOnGameServer(operationResponse);
|
|
}
|
|
else if (operationResponse.ReturnCode != 0)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.LogWarning($"CreateRoom failed, client stays on masterserver: {operationResponse.ToStringFull()}.");
|
|
}
|
|
State = ((!insideLobby) ? ClientState.ConnectedToMaster : ClientState.JoinedLobby);
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonCreateRoomFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
|
|
}
|
|
else
|
|
{
|
|
string text2 = (string)operationResponse[byte.MaxValue];
|
|
if (!string.IsNullOrEmpty(text2))
|
|
{
|
|
enterRoomParamsCache.RoomName = text2;
|
|
}
|
|
GameServerAddress = (string)operationResponse[230];
|
|
DisconnectToReconnect();
|
|
}
|
|
break;
|
|
case 226:
|
|
if (Server != ServerConnection.GameServer)
|
|
{
|
|
if (operationResponse.ReturnCode != 0)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log($"JoinRoom failed (room maybe closed by now). Client stays on masterserver: {operationResponse.ToStringFull()}. State: {State}");
|
|
}
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonJoinRoomFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
|
|
}
|
|
else
|
|
{
|
|
GameServerAddress = (string)operationResponse[230];
|
|
DisconnectToReconnect();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GameEnteredOnGameServer(operationResponse);
|
|
}
|
|
break;
|
|
case 225:
|
|
if (operationResponse.ReturnCode != 0)
|
|
{
|
|
if (operationResponse.ReturnCode == 32760)
|
|
{
|
|
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($"JoinRandom failed: {operationResponse.ToStringFull()}.");
|
|
}
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonRandomJoinFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
|
|
}
|
|
else
|
|
{
|
|
string roomName = (string)operationResponse[byte.MaxValue];
|
|
enterRoomParamsCache.RoomName = roomName;
|
|
GameServerAddress = (string)operationResponse[230];
|
|
DisconnectToReconnect();
|
|
}
|
|
break;
|
|
case 229:
|
|
State = ClientState.JoinedLobby;
|
|
insideLobby = true;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnJoinedLobby);
|
|
break;
|
|
case 228:
|
|
State = ClientState.Authenticated;
|
|
LeftLobbyCleanup();
|
|
break;
|
|
case 254:
|
|
DisconnectToReconnect();
|
|
break;
|
|
case 251:
|
|
{
|
|
ExitGames.Client.Photon.Hashtable pActorProperties = (ExitGames.Client.Photon.Hashtable)operationResponse[249];
|
|
ExitGames.Client.Photon.Hashtable gameProperties = (ExitGames.Client.Photon.Hashtable)operationResponse[248];
|
|
ReadoutProperties(gameProperties, pActorProperties, 0);
|
|
break;
|
|
}
|
|
case 222:
|
|
{
|
|
bool[] array = operationResponse[1] as bool[];
|
|
string[] array2 = operationResponse[2] as string[];
|
|
if (array != null && array2 != null && friendListRequested != null && array.Length == friendListRequested.Length)
|
|
{
|
|
List<FriendInfo> list = new List<FriendInfo>(friendListRequested.Length);
|
|
for (int i = 0; i < friendListRequested.Length; i++)
|
|
{
|
|
FriendInfo friendInfo = new FriendInfo();
|
|
friendInfo.Name = friendListRequested[i];
|
|
friendInfo.Room = array2[i];
|
|
friendInfo.IsOnline = array[i];
|
|
list.Insert(i, friendInfo);
|
|
}
|
|
PhotonNetwork.Friends = list;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("FindFriends failed to apply the result, as a required value wasn't provided or the friend list length differed from result.");
|
|
}
|
|
friendListRequested = null;
|
|
isFetchingFriendList = false;
|
|
friendListTimestamp = Environment.TickCount;
|
|
if (friendListTimestamp == 0)
|
|
{
|
|
friendListTimestamp = 1;
|
|
}
|
|
SendMonoMessage(PhotonNetworkingMessage.OnUpdatedFriendList);
|
|
break;
|
|
}
|
|
case 219:
|
|
SendMonoMessage(PhotonNetworkingMessage.OnWebRpcResponse, operationResponse);
|
|
break;
|
|
default:
|
|
Debug.LogWarning($"OperationResponse unhandled: {operationResponse.ToString()}");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnStatusChanged(StatusCode statusCode)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log($"OnStatusChanged: {statusCode.ToString()} current State: {State}");
|
|
}
|
|
switch (statusCode)
|
|
{
|
|
case StatusCode.QueueOutgoingReliableWarning:
|
|
case StatusCode.QueueOutgoingUnreliableWarning:
|
|
case StatusCode.QueueOutgoingAcksWarning:
|
|
case StatusCode.QueueSentWarning:
|
|
break;
|
|
case StatusCode.SendError:
|
|
break;
|
|
case StatusCode.Connect:
|
|
if (State == ClientState.ConnectingToNameServer)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
|
|
{
|
|
Debug.Log("Connected to NameServer.");
|
|
}
|
|
Server = ServerConnection.NameServer;
|
|
if (AuthValues != null)
|
|
{
|
|
AuthValues.Token = null;
|
|
}
|
|
}
|
|
if (State == ClientState.ConnectingToGameserver)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
|
|
{
|
|
Debug.Log("Connected to gameserver.");
|
|
}
|
|
Server = ServerConnection.GameServer;
|
|
State = ClientState.ConnectedToGameserver;
|
|
}
|
|
if (State == ClientState.ConnectingToMasterserver)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
|
|
{
|
|
Debug.Log("Connected to masterserver.");
|
|
}
|
|
Server = ServerConnection.MasterServer;
|
|
State = ClientState.Authenticating;
|
|
if (IsInitialConnect)
|
|
{
|
|
IsInitialConnect = false;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnConnectedToPhoton);
|
|
}
|
|
}
|
|
if (base.TransportProtocol != ConnectionProtocol.WebSocketSecure)
|
|
{
|
|
if (Server == ServerConnection.NameServer || AuthMode == AuthModeOption.Auth)
|
|
{
|
|
EstablishEncryption();
|
|
}
|
|
break;
|
|
}
|
|
if (DebugOut == DebugLevel.INFO)
|
|
{
|
|
Debug.Log("Skipping EstablishEncryption. Protocol is secure.");
|
|
}
|
|
goto case StatusCode.EncryptionEstablished;
|
|
case StatusCode.EncryptionEstablished:
|
|
if (Server == ServerConnection.NameServer)
|
|
{
|
|
State = ClientState.ConnectedToNameServer;
|
|
if (!didAuthenticate && CloudRegion == CloudRegionCode.none)
|
|
{
|
|
OpGetRegions(AppId);
|
|
}
|
|
}
|
|
if ((Server == ServerConnection.NameServer || (AuthMode != AuthModeOption.AuthOnce && AuthMode != AuthModeOption.AuthOnceWss)) && !didAuthenticate && (!IsUsingNameServer || CloudRegion != CloudRegionCode.none))
|
|
{
|
|
didAuthenticate = CallAuthenticate();
|
|
if (didAuthenticate)
|
|
{
|
|
State = ClientState.Authenticating;
|
|
}
|
|
}
|
|
break;
|
|
case StatusCode.EncryptionFailedToEstablish:
|
|
{
|
|
Debug.LogError("Encryption wasn't established: " + statusCode + ". Going to authenticate anyways.");
|
|
object authenticationValues = AuthValues;
|
|
if (authenticationValues == null)
|
|
{
|
|
AuthenticationValues authenticationValues2 = new AuthenticationValues();
|
|
authenticationValues2.UserId = PlayerName;
|
|
authenticationValues = authenticationValues2;
|
|
}
|
|
AuthenticationValues authValues = (AuthenticationValues)authenticationValues;
|
|
OpAuthenticate(AppId, AppVersion, authValues, CloudRegion.ToString(), requestLobbyStatistics);
|
|
break;
|
|
}
|
|
case StatusCode.Disconnect:
|
|
didAuthenticate = false;
|
|
isFetchingFriendList = false;
|
|
if (Server == ServerConnection.GameServer)
|
|
{
|
|
LeftRoomCleanup();
|
|
}
|
|
if (Server == ServerConnection.MasterServer)
|
|
{
|
|
LeftLobbyCleanup();
|
|
}
|
|
if (State == ClientState.DisconnectingFromMasterserver)
|
|
{
|
|
if (Connect(GameServerAddress, ServerConnection.GameServer))
|
|
{
|
|
State = ClientState.ConnectingToGameserver;
|
|
}
|
|
}
|
|
else if (State == ClientState.DisconnectingFromGameserver || State == ClientState.DisconnectingFromNameServer)
|
|
{
|
|
SetupProtocol(ServerConnection.MasterServer);
|
|
if (Connect(MasterServerAddress, ServerConnection.MasterServer))
|
|
{
|
|
State = ClientState.ConnectingToMasterserver;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (AuthValues != null)
|
|
{
|
|
AuthValues.Token = null;
|
|
}
|
|
State = ClientState.PeerCreated;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnDisconnectedFromPhoton);
|
|
}
|
|
break;
|
|
case StatusCode.SecurityExceptionOnConnect:
|
|
case StatusCode.ExceptionOnConnect:
|
|
{
|
|
State = ClientState.PeerCreated;
|
|
if (AuthValues != null)
|
|
{
|
|
AuthValues.Token = null;
|
|
}
|
|
DisconnectCause disconnectCause = (DisconnectCause)statusCode;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnFailedToConnectToPhoton, disconnectCause);
|
|
break;
|
|
}
|
|
case StatusCode.Exception:
|
|
if (IsInitialConnect)
|
|
{
|
|
Debug.LogError("Exception while connecting to: " + base.ServerAddress + ". Check if the server is available.");
|
|
if (base.ServerAddress == null || base.ServerAddress.StartsWith("127.0.0.1"))
|
|
{
|
|
Debug.LogWarning("The server address is 127.0.0.1 (localhost): Make sure the server is running on this machine. Android and iOS emulators have their own localhost.");
|
|
if (base.ServerAddress == GameServerAddress)
|
|
{
|
|
Debug.LogWarning("This might be a misconfiguration in the game server config. You need to edit it to a (public) address.");
|
|
}
|
|
}
|
|
State = ClientState.PeerCreated;
|
|
DisconnectCause disconnectCause = (DisconnectCause)statusCode;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnFailedToConnectToPhoton, disconnectCause);
|
|
}
|
|
else
|
|
{
|
|
State = ClientState.PeerCreated;
|
|
DisconnectCause disconnectCause = (DisconnectCause)statusCode;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, disconnectCause);
|
|
}
|
|
Disconnect();
|
|
break;
|
|
case StatusCode.TimeoutDisconnect:
|
|
if (IsInitialConnect)
|
|
{
|
|
Debug.LogWarning(statusCode + " while connecting to: " + base.ServerAddress + ". Check if the server is available.");
|
|
DisconnectCause disconnectCause = (DisconnectCause)statusCode;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnFailedToConnectToPhoton, disconnectCause);
|
|
}
|
|
else
|
|
{
|
|
DisconnectCause disconnectCause = (DisconnectCause)statusCode;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, disconnectCause);
|
|
}
|
|
if (AuthValues != null)
|
|
{
|
|
AuthValues.Token = null;
|
|
}
|
|
Disconnect();
|
|
break;
|
|
case StatusCode.ExceptionOnReceive:
|
|
case StatusCode.DisconnectByServer:
|
|
case StatusCode.DisconnectByServerUserLimit:
|
|
case StatusCode.DisconnectByServerLogic:
|
|
if (IsInitialConnect)
|
|
{
|
|
Debug.LogWarning(statusCode + " while connecting to: " + base.ServerAddress + ". Check if the server is available.");
|
|
DisconnectCause disconnectCause = (DisconnectCause)statusCode;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnFailedToConnectToPhoton, disconnectCause);
|
|
}
|
|
else
|
|
{
|
|
DisconnectCause disconnectCause = (DisconnectCause)statusCode;
|
|
SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, disconnectCause);
|
|
}
|
|
if (AuthValues != null)
|
|
{
|
|
AuthValues.Token = null;
|
|
}
|
|
Disconnect();
|
|
break;
|
|
case StatusCode.QueueIncomingReliableWarning:
|
|
case StatusCode.QueueIncomingUnreliableWarning:
|
|
Debug.Log(statusCode + ". This client buffers many incoming messages. This is OK temporarily. With lots of these warnings, check if you send too much or execute messages too slow. " + ((!PhotonNetwork.isMessageQueueRunning) ? "Your isMessageQueueRunning is false. This can cause the issue temporarily." : string.Empty));
|
|
break;
|
|
default:
|
|
Debug.LogError("Received unknown status code: " + statusCode);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void OnEvent(EventData photonEvent)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log($"OnEvent: {photonEvent.ToString()}");
|
|
}
|
|
int num = -1;
|
|
PhotonPlayer photonPlayer = null;
|
|
if (photonEvent.Parameters.ContainsKey(254))
|
|
{
|
|
num = (int)photonEvent[254];
|
|
photonPlayer = GetPlayerWithId(num);
|
|
}
|
|
switch (photonEvent.Code)
|
|
{
|
|
case 228:
|
|
break;
|
|
case 209:
|
|
{
|
|
int[] array = (int[])photonEvent.Parameters[245];
|
|
int num3 = array[0];
|
|
int num4 = array[1];
|
|
PhotonView photonView = PhotonView.Find(num3);
|
|
if (photonView == null)
|
|
{
|
|
Debug.LogWarning("Can't find PhotonView of incoming OwnershipRequest. ViewId not found: " + num3);
|
|
}
|
|
else
|
|
{
|
|
if (PhotonNetwork.logLevel == PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log("Ev OwnershipRequest " + photonView.ownershipTransfer + ". ActorNr: " + num + " takes from: " + num4 + ". Current owner: " + photonView.ownerId + " isOwnerActive: " + photonView.isOwnerActive + ". MasterClient: " + mMasterClientId + ". This client's player: " + PhotonNetwork.player.ToStringFull());
|
|
}
|
|
switch (photonView.ownershipTransfer)
|
|
{
|
|
case OwnershipOption.Fixed:
|
|
Debug.LogWarning("Ownership mode == fixed. Ignoring request.");
|
|
break;
|
|
case OwnershipOption.Takeover:
|
|
if (num4 == photonView.ownerId || (num4 == 0 && photonView.ownerId == mMasterClientId))
|
|
{
|
|
photonView.OwnerShipWasTransfered = true;
|
|
photonView.ownerId = num;
|
|
if (PhotonNetwork.logLevel == PhotonLogLevel.Informational)
|
|
{
|
|
Debug.LogWarning(photonView + " ownership transfered to: " + num);
|
|
}
|
|
}
|
|
break;
|
|
case OwnershipOption.Request:
|
|
if ((num4 == PhotonNetwork.player.ID || PhotonNetwork.player.IsMasterClient) && (photonView.ownerId == PhotonNetwork.player.ID || (PhotonNetwork.player.IsMasterClient && !photonView.isOwnerActive)))
|
|
{
|
|
SendMonoMessage(PhotonNetworkingMessage.OnOwnershipRequest, photonView, photonPlayer);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 210:
|
|
{
|
|
int[] array6 = (int[])photonEvent.Parameters[245];
|
|
Debug.Log("Ev OwnershipTransfer. ViewID " + array6[0] + " to: " + array6[1] + " Time: " + Environment.TickCount % 1000);
|
|
int viewID = array6[0];
|
|
int ownerId = array6[1];
|
|
PhotonView photonView2 = PhotonView.Find(viewID);
|
|
if (photonView2 != null)
|
|
{
|
|
photonView2.OwnerShipWasTransfered = true;
|
|
photonView2.ownerId = ownerId;
|
|
}
|
|
break;
|
|
}
|
|
case 230:
|
|
{
|
|
mGameList = new Dictionary<string, RoomInfo>();
|
|
ExitGames.Client.Photon.Hashtable hashtable2 = (ExitGames.Client.Photon.Hashtable)photonEvent[222];
|
|
foreach (object key in hashtable2.Keys)
|
|
{
|
|
string text2 = (string)key;
|
|
mGameList[text2] = new RoomInfo(text2, (ExitGames.Client.Photon.Hashtable)hashtable2[key]);
|
|
}
|
|
mGameListCopy = new RoomInfo[mGameList.Count];
|
|
mGameList.Values.CopyTo(mGameListCopy, 0);
|
|
SendMonoMessage(PhotonNetworkingMessage.OnReceivedRoomListUpdate);
|
|
break;
|
|
}
|
|
case 229:
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable = (ExitGames.Client.Photon.Hashtable)photonEvent[222];
|
|
foreach (object key2 in hashtable.Keys)
|
|
{
|
|
string text = (string)key2;
|
|
RoomInfo roomInfo = new RoomInfo(text, (ExitGames.Client.Photon.Hashtable)hashtable[key2]);
|
|
if (roomInfo.removedFromList)
|
|
{
|
|
mGameList.Remove(text);
|
|
}
|
|
else
|
|
{
|
|
mGameList[text] = roomInfo;
|
|
}
|
|
}
|
|
mGameListCopy = new RoomInfo[mGameList.Count];
|
|
mGameList.Values.CopyTo(mGameListCopy, 0);
|
|
SendMonoMessage(PhotonNetworkingMessage.OnReceivedRoomListUpdate);
|
|
break;
|
|
}
|
|
case 226:
|
|
PlayersInRoomsCount = (int)photonEvent[229];
|
|
PlayersOnMasterCount = (int)photonEvent[227];
|
|
RoomsCount = (int)photonEvent[228];
|
|
break;
|
|
case byte.MaxValue:
|
|
{
|
|
ExitGames.Client.Photon.Hashtable properties = (ExitGames.Client.Photon.Hashtable)photonEvent[249];
|
|
if (photonPlayer == null)
|
|
{
|
|
bool isLocal = LocalPlayer.ID == num;
|
|
AddNewPlayer(num, new PhotonPlayer(isLocal, num, properties));
|
|
ResetPhotonViewsOnSerialize();
|
|
}
|
|
else
|
|
{
|
|
photonPlayer.InternalCacheProperties(properties);
|
|
photonPlayer.IsInactive = false;
|
|
}
|
|
if (num == LocalPlayer.ID)
|
|
{
|
|
int[] actorsInRoom = (int[])photonEvent[252];
|
|
UpdatedActorList(actorsInRoom);
|
|
if (lastJoinType == JoinType.JoinOrCreateRoom && LocalPlayer.ID == 1)
|
|
{
|
|
SendMonoMessage(PhotonNetworkingMessage.OnCreatedRoom);
|
|
}
|
|
SendMonoMessage(PhotonNetworkingMessage.OnJoinedRoom);
|
|
}
|
|
else
|
|
{
|
|
SendMonoMessage(PhotonNetworkingMessage.OnPhotonPlayerConnected, mActors[num]);
|
|
}
|
|
break;
|
|
}
|
|
case 254:
|
|
HandleEventLeave(num, photonEvent);
|
|
break;
|
|
case 253:
|
|
{
|
|
int num2 = (int)photonEvent[253];
|
|
ExitGames.Client.Photon.Hashtable gameProperties = null;
|
|
ExitGames.Client.Photon.Hashtable pActorProperties = null;
|
|
if (num2 == 0)
|
|
{
|
|
gameProperties = (ExitGames.Client.Photon.Hashtable)photonEvent[251];
|
|
}
|
|
else
|
|
{
|
|
pActorProperties = (ExitGames.Client.Photon.Hashtable)photonEvent[251];
|
|
}
|
|
ReadoutProperties(gameProperties, pActorProperties, num2);
|
|
break;
|
|
}
|
|
case 200:
|
|
ExecuteRpc(photonEvent[245] as ExitGames.Client.Photon.Hashtable, photonPlayer);
|
|
break;
|
|
case 201:
|
|
case 206:
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable4 = (ExitGames.Client.Photon.Hashtable)photonEvent[245];
|
|
int networkTime = (int)hashtable4[(byte)0];
|
|
short correctPrefix = -1;
|
|
byte b = 10;
|
|
int num6 = 1;
|
|
if (hashtable4.ContainsKey((byte)1))
|
|
{
|
|
correctPrefix = (short)hashtable4[(byte)1];
|
|
num6 = 2;
|
|
}
|
|
byte b2 = b;
|
|
while (b2 - b < hashtable4.Count - num6)
|
|
{
|
|
OnSerializeRead(hashtable4[b2] as object[], photonPlayer, networkTime, correctPrefix);
|
|
b2 = (byte)(b2 + 1);
|
|
}
|
|
break;
|
|
}
|
|
case 202:
|
|
DoInstantiate((ExitGames.Client.Photon.Hashtable)photonEvent[245], photonPlayer, null);
|
|
break;
|
|
case 203:
|
|
if (photonPlayer == null || !photonPlayer.IsMasterClient)
|
|
{
|
|
Debug.LogError("Error: Someone else(" + photonPlayer + ") then the masterserver requests a disconnect!");
|
|
}
|
|
else
|
|
{
|
|
PhotonNetwork.LeaveRoom();
|
|
}
|
|
break;
|
|
case 207:
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable3 = (ExitGames.Client.Photon.Hashtable)photonEvent[245];
|
|
int num7 = (int)hashtable3[(byte)0];
|
|
if (num7 >= 0)
|
|
{
|
|
DestroyPlayerObjects(num7, localOnly: true);
|
|
}
|
|
else
|
|
{
|
|
if ((int)DebugOut >= 3)
|
|
{
|
|
Debug.Log("Ev DestroyAll! By PlayerId: " + num);
|
|
}
|
|
DestroyAll(localOnly: true);
|
|
}
|
|
break;
|
|
}
|
|
case 204:
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable3 = (ExitGames.Client.Photon.Hashtable)photonEvent[245];
|
|
int num5 = (int)hashtable3[(byte)0];
|
|
PhotonView value = null;
|
|
if (photonViewList.TryGetValue(num5, out value))
|
|
{
|
|
RemoveInstantiatedGO(value.gameObject, localOnly: true);
|
|
}
|
|
else if ((int)DebugOut >= 1)
|
|
{
|
|
Debug.LogError("Ev Destroy Failed. Could not find PhotonView with instantiationId " + num5 + ". Sent by actorNr: " + num);
|
|
}
|
|
break;
|
|
}
|
|
case 208:
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable3 = (ExitGames.Client.Photon.Hashtable)photonEvent[245];
|
|
int playerId = (int)hashtable3[(byte)1];
|
|
SetMasterClient(playerId, sync: false);
|
|
break;
|
|
}
|
|
case 224:
|
|
{
|
|
string[] array2 = photonEvent[213] as string[];
|
|
byte[] array3 = photonEvent[212] as byte[];
|
|
int[] array4 = photonEvent[229] as int[];
|
|
int[] array5 = photonEvent[228] as int[];
|
|
LobbyStatistics.Clear();
|
|
for (int i = 0; i < array2.Length; i++)
|
|
{
|
|
TypedLobbyInfo typedLobbyInfo = new TypedLobbyInfo();
|
|
typedLobbyInfo.Name = array2[i];
|
|
typedLobbyInfo.Type = (LobbyType)array3[i];
|
|
typedLobbyInfo.PlayerCount = array4[i];
|
|
typedLobbyInfo.RoomCount = array5[i];
|
|
LobbyStatistics.Add(typedLobbyInfo);
|
|
}
|
|
SendMonoMessage(PhotonNetworkingMessage.OnLobbyStatisticsUpdate);
|
|
break;
|
|
}
|
|
case 251:
|
|
if (PhotonNetwork.OnEventCall != null)
|
|
{
|
|
object content2 = photonEvent[245];
|
|
PhotonNetwork.OnEventCall(photonEvent.Code, content2, num);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("Warning: Unhandled Event ErrorInfo (251). Set PhotonNetwork.OnEventCall to the method PUN should call for this event.");
|
|
}
|
|
break;
|
|
case 223:
|
|
if (AuthValues == null)
|
|
{
|
|
AuthValues = new AuthenticationValues();
|
|
}
|
|
AuthValues.Token = (photonEvent[221] as string);
|
|
tokenCache = AuthValues.Token;
|
|
break;
|
|
default:
|
|
if (photonEvent.Code < 200)
|
|
{
|
|
if (PhotonNetwork.OnEventCall != null)
|
|
{
|
|
object content = photonEvent[245];
|
|
PhotonNetwork.OnEventCall(photonEvent.Code, content, num);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("Warning: Unhandled event " + photonEvent + ". Set PhotonNetwork.OnEventCall.");
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void OnMessage(object messages)
|
|
{
|
|
}
|
|
|
|
private void SetupEncryption(Dictionary<byte, object> encryptionData)
|
|
{
|
|
if (AuthMode == AuthModeOption.Auth && DebugOut == DebugLevel.ERROR)
|
|
{
|
|
Debug.LogWarning("SetupEncryption() called but ignored. Not XB1 compiled. EncryptionData: " + encryptionData.ToStringFull());
|
|
}
|
|
else
|
|
{
|
|
if (DebugOut == DebugLevel.INFO)
|
|
{
|
|
Debug.Log("SetupEncryption() got called. " + encryptionData.ToStringFull());
|
|
}
|
|
switch ((byte)encryptionData[0])
|
|
{
|
|
case 0:
|
|
{
|
|
byte[] secret = (byte[])encryptionData[1];
|
|
InitPayloadEncryption(secret);
|
|
break;
|
|
}
|
|
case 10:
|
|
{
|
|
byte[] encryptionSecret = (byte[])encryptionData[1];
|
|
byte[] hmacSecret = (byte[])encryptionData[2];
|
|
InitDatagramEncryption(encryptionSecret, hmacSecret);
|
|
break;
|
|
}
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected internal void UpdatedActorList(int[] actorsInRoom)
|
|
{
|
|
foreach (int num in actorsInRoom)
|
|
{
|
|
if (LocalPlayer.ID != num && !mActors.ContainsKey(num))
|
|
{
|
|
AddNewPlayer(num, new PhotonPlayer(isLocal: false, num, string.Empty));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SendVacantViewIds()
|
|
{
|
|
Debug.Log("SendVacantViewIds()");
|
|
List<int> list = new List<int>();
|
|
foreach (PhotonView value in photonViewList.Values)
|
|
{
|
|
if (!value.isOwnerActive)
|
|
{
|
|
list.Add(value.viewID);
|
|
}
|
|
}
|
|
Debug.Log("Sending vacant view IDs. Length: " + list.Count);
|
|
OpRaiseEvent(211, list.ToArray(), sendReliable: true, null);
|
|
}
|
|
|
|
public static void SendMonoMessage(PhotonNetworkingMessage methodString, params object[] parameters)
|
|
{
|
|
HashSet<GameObject> hashSet = (PhotonNetwork.SendMonoMessageTargets == null) ? PhotonNetwork.FindGameObjectsWithComponent(PhotonNetwork.SendMonoMessageTargetType) : PhotonNetwork.SendMonoMessageTargets;
|
|
string methodName = methodString.ToString();
|
|
object value = (parameters == null || parameters.Length != 1) ? parameters : parameters[0];
|
|
foreach (GameObject item in hashSet)
|
|
{
|
|
if (item != null)
|
|
{
|
|
item.SendMessage(methodName, value, SendMessageOptions.DontRequireReceiver);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected internal void ExecuteRpc(ExitGames.Client.Photon.Hashtable rpcData, PhotonPlayer sender)
|
|
{
|
|
if (rpcData == null || !rpcData.ContainsKey((byte)0))
|
|
{
|
|
Debug.LogError("Malformed RPC; this should never occur. Content: " + SupportClass.DictionaryToString(rpcData));
|
|
}
|
|
else
|
|
{
|
|
int num = (int)rpcData[(byte)0];
|
|
int num2 = 0;
|
|
if (rpcData.ContainsKey((byte)1))
|
|
{
|
|
num2 = (short)rpcData[(byte)1];
|
|
}
|
|
string text;
|
|
if (rpcData.ContainsKey((byte)5))
|
|
{
|
|
int num3 = (byte)rpcData[(byte)5];
|
|
if (num3 > PhotonNetwork.PhotonServerSettings.RpcList.Count - 1)
|
|
{
|
|
Debug.LogError("Could not find RPC with index: " + num3 + ". Going to ignore! Check PhotonServerSettings.RpcList");
|
|
return;
|
|
}
|
|
text = PhotonNetwork.PhotonServerSettings.RpcList[num3];
|
|
}
|
|
else
|
|
{
|
|
text = (string)rpcData[(byte)3];
|
|
}
|
|
object[] array = null;
|
|
if (rpcData.ContainsKey((byte)4))
|
|
{
|
|
array = (object[])rpcData[(byte)4];
|
|
}
|
|
if (array == null)
|
|
{
|
|
array = new object[0];
|
|
}
|
|
PhotonView photonView = GetPhotonView(num);
|
|
if (photonView == null)
|
|
{
|
|
int num4 = num / PhotonNetwork.MAX_VIEW_IDS;
|
|
bool flag = num4 == LocalPlayer.ID;
|
|
bool flag2 = num4 == sender.ID;
|
|
if (flag)
|
|
{
|
|
Debug.LogWarning("Received RPC \"" + text + "\" for viewID " + num + " but this PhotonView does not exist! View was/is ours." + ((!flag2) ? " Remote called." : " Owner called.") + " By: " + sender.ID);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("Received RPC \"" + text + "\" for viewID " + num + " but this PhotonView does not exist! Was remote PV." + ((!flag2) ? " Remote called." : " Owner called.") + " By: " + sender.ID + " Maybe GO was destroyed but RPC not cleaned up.");
|
|
}
|
|
}
|
|
else if (photonView.prefix != num2)
|
|
{
|
|
Debug.LogError("Received RPC \"" + text + "\" on viewID " + num + " with a prefix of " + num2 + ", our prefix is " + photonView.prefix + ". The RPC has been ignored.");
|
|
}
|
|
else if (string.IsNullOrEmpty(text))
|
|
{
|
|
Debug.LogError("Malformed RPC; this should never occur. Content: " + SupportClass.DictionaryToString(rpcData));
|
|
}
|
|
else
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
|
|
{
|
|
Debug.Log("Received RPC: " + text);
|
|
}
|
|
if (photonView.group == 0 || allowedReceivingGroups.Contains(photonView.group))
|
|
{
|
|
Type[] array2 = new Type[0];
|
|
if (array.Length > 0)
|
|
{
|
|
array2 = new Type[array.Length];
|
|
int num5 = 0;
|
|
foreach (object obj in array)
|
|
{
|
|
if (obj == null)
|
|
{
|
|
array2[num5] = null;
|
|
}
|
|
else
|
|
{
|
|
array2[num5] = obj.GetType();
|
|
}
|
|
num5++;
|
|
}
|
|
}
|
|
int num6 = 0;
|
|
int num7 = 0;
|
|
if (!PhotonNetwork.UseRpcMonoBehaviourCache || photonView.RpcMonoBehaviours == null || photonView.RpcMonoBehaviours.Length == 0)
|
|
{
|
|
photonView.RefreshRpcMonoBehaviourCache();
|
|
}
|
|
for (int j = 0; j < photonView.RpcMonoBehaviours.Length; j++)
|
|
{
|
|
MonoBehaviour monoBehaviour = photonView.RpcMonoBehaviours[j];
|
|
if (monoBehaviour == null)
|
|
{
|
|
Debug.LogError("ERROR You have missing MonoBehaviours on your gameobjects!");
|
|
}
|
|
else
|
|
{
|
|
Type type = monoBehaviour.GetType();
|
|
List<MethodInfo> value = null;
|
|
if (!monoRPCMethodsCache.TryGetValue(type, out value))
|
|
{
|
|
List<MethodInfo> methods = SupportClass.GetMethods(type, typeof(PunRPC));
|
|
monoRPCMethodsCache[type] = methods;
|
|
value = methods;
|
|
}
|
|
if (value != null)
|
|
{
|
|
for (int k = 0; k < value.Count; k++)
|
|
{
|
|
MethodInfo methodInfo = value[k];
|
|
if (methodInfo.Name.Equals(text))
|
|
{
|
|
num7++;
|
|
ParameterInfo[] cachedParemeters = methodInfo.GetCachedParemeters();
|
|
if (cachedParemeters.Length == array2.Length)
|
|
{
|
|
if (CheckTypeMatch(cachedParemeters, array2))
|
|
{
|
|
num6++;
|
|
object obj2 = methodInfo.Invoke(monoBehaviour, array);
|
|
if (PhotonNetwork.StartRpcsAsCoroutine && methodInfo.ReturnType == typeof(IEnumerator))
|
|
{
|
|
monoBehaviour.StartCoroutine((IEnumerator)obj2);
|
|
}
|
|
}
|
|
}
|
|
else if (cachedParemeters.Length - 1 == array2.Length)
|
|
{
|
|
if (CheckTypeMatch(cachedParemeters, array2) && cachedParemeters[cachedParemeters.Length - 1].ParameterType == typeof(PhotonMessageInfo))
|
|
{
|
|
num6++;
|
|
int timestamp = (int)rpcData[(byte)2];
|
|
object[] array3 = new object[array.Length + 1];
|
|
array.CopyTo(array3, 0);
|
|
array3[array3.Length - 1] = new PhotonMessageInfo(sender, timestamp, photonView);
|
|
object obj3 = methodInfo.Invoke(monoBehaviour, array3);
|
|
if (PhotonNetwork.StartRpcsAsCoroutine && methodInfo.ReturnType == typeof(IEnumerator))
|
|
{
|
|
monoBehaviour.StartCoroutine((IEnumerator)obj3);
|
|
}
|
|
}
|
|
}
|
|
else if (cachedParemeters.Length == 1 && cachedParemeters[0].ParameterType.IsArray)
|
|
{
|
|
num6++;
|
|
object obj4 = methodInfo.Invoke(monoBehaviour, new object[1]
|
|
{
|
|
array
|
|
});
|
|
if (PhotonNetwork.StartRpcsAsCoroutine && methodInfo.ReturnType == typeof(IEnumerator))
|
|
{
|
|
monoBehaviour.StartCoroutine((IEnumerator)obj4);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (num6 != 1)
|
|
{
|
|
string text2 = string.Empty;
|
|
foreach (Type type2 in array2)
|
|
{
|
|
if (text2 != string.Empty)
|
|
{
|
|
text2 += ", ";
|
|
}
|
|
text2 = ((type2 != null) ? (text2 + type2.Name) : (text2 + "null"));
|
|
}
|
|
if (num6 == 0)
|
|
{
|
|
if (num7 == 0)
|
|
{
|
|
Debug.LogError("PhotonView with ID " + num + " has no method \"" + text + "\" marked with the [PunRPC](C#) or @PunRPC(JS) property! Args: " + text2);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("PhotonView with ID " + num + " has no method \"" + text + "\" that takes " + array2.Length + " argument(s): " + text2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("PhotonView with ID " + num + " has " + num6 + " methods \"" + text + "\" that takes " + array2.Length + " argument(s): " + text2 + ". Should be just one?");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool CheckTypeMatch(ParameterInfo[] methodParameters, Type[] callParameterTypes)
|
|
{
|
|
if (methodParameters.Length < callParameterTypes.Length)
|
|
{
|
|
return false;
|
|
}
|
|
for (int i = 0; i < callParameterTypes.Length; i++)
|
|
{
|
|
Type parameterType = methodParameters[i].ParameterType;
|
|
if (callParameterTypes[i] != null && !parameterType.IsAssignableFrom(callParameterTypes[i]) && (!parameterType.IsEnum || !Enum.GetUnderlyingType(parameterType).IsAssignableFrom(callParameterTypes[i])))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
internal ExitGames.Client.Photon.Hashtable SendInstantiate(string prefabName, Vector3 position, Quaternion rotation, int group, int[] viewIDs, object[] data, bool isGlobalObject)
|
|
{
|
|
int num = viewIDs[0];
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable[(byte)0] = prefabName;
|
|
if (position != Vector3.zero)
|
|
{
|
|
hashtable[(byte)1] = position;
|
|
}
|
|
if (rotation != Quaternion.identity)
|
|
{
|
|
hashtable[(byte)2] = rotation;
|
|
}
|
|
if (group != 0)
|
|
{
|
|
hashtable[(byte)3] = group;
|
|
}
|
|
if (viewIDs.Length > 1)
|
|
{
|
|
hashtable[(byte)4] = viewIDs;
|
|
}
|
|
if (data != null)
|
|
{
|
|
hashtable[(byte)5] = data;
|
|
}
|
|
if (currentLevelPrefix > 0)
|
|
{
|
|
hashtable[(byte)8] = currentLevelPrefix;
|
|
}
|
|
hashtable[(byte)6] = PhotonNetwork.ServerTimestamp;
|
|
hashtable[(byte)7] = num;
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.CachingOption = ((!isGlobalObject) ? EventCaching.AddToRoomCache : EventCaching.AddToRoomCacheGlobal);
|
|
OpRaiseEvent(202, hashtable, sendReliable: true, raiseEventOptions);
|
|
return hashtable;
|
|
}
|
|
|
|
internal GameObject DoInstantiate(ExitGames.Client.Photon.Hashtable evData, PhotonPlayer photonPlayer, GameObject resourceGameObject)
|
|
{
|
|
string text = (string)evData[(byte)0];
|
|
int timestamp = (int)evData[(byte)6];
|
|
int num = (int)evData[(byte)7];
|
|
Vector3 position = (!evData.ContainsKey((byte)1)) ? Vector3.zero : ((Vector3)evData[(byte)1]);
|
|
Quaternion rotation = Quaternion.identity;
|
|
if (evData.ContainsKey((byte)2))
|
|
{
|
|
rotation = (Quaternion)evData[(byte)2];
|
|
}
|
|
int num2 = 0;
|
|
if (evData.ContainsKey((byte)3))
|
|
{
|
|
num2 = (int)evData[(byte)3];
|
|
}
|
|
short prefix = 0;
|
|
if (evData.ContainsKey((byte)8))
|
|
{
|
|
prefix = (short)evData[(byte)8];
|
|
}
|
|
int[] array = (!evData.ContainsKey((byte)4)) ? new int[1]
|
|
{
|
|
num
|
|
} : ((int[])evData[(byte)4]);
|
|
object[] array2 = (!evData.ContainsKey((byte)5)) ? null : ((object[])evData[(byte)5]);
|
|
if (num2 != 0 && !allowedReceivingGroups.Contains(num2))
|
|
{
|
|
return null;
|
|
}
|
|
if (ObjectPool != null)
|
|
{
|
|
GameObject gameObject = ObjectPool.Instantiate(text, position, rotation);
|
|
PhotonView[] photonViewsInChildren = gameObject.GetPhotonViewsInChildren();
|
|
if (photonViewsInChildren.Length != array.Length)
|
|
{
|
|
throw new Exception("Error in Instantiation! The resource's PhotonView count is not the same as in incoming data.");
|
|
}
|
|
for (int i = 0; i < photonViewsInChildren.Length; i++)
|
|
{
|
|
photonViewsInChildren[i].didAwake = false;
|
|
photonViewsInChildren[i].viewID = 0;
|
|
photonViewsInChildren[i].prefix = prefix;
|
|
photonViewsInChildren[i].instantiationId = num;
|
|
photonViewsInChildren[i].isRuntimeInstantiated = true;
|
|
photonViewsInChildren[i].instantiationDataField = array2;
|
|
photonViewsInChildren[i].didAwake = true;
|
|
photonViewsInChildren[i].viewID = array[i];
|
|
}
|
|
gameObject.SendMessage(OnPhotonInstantiateString, new PhotonMessageInfo(photonPlayer, timestamp, null), SendMessageOptions.DontRequireReceiver);
|
|
return gameObject;
|
|
}
|
|
if (resourceGameObject == null)
|
|
{
|
|
if (!UsePrefabCache || !PrefabCache.TryGetValue(text, out resourceGameObject))
|
|
{
|
|
resourceGameObject = (GameObject)Resources.Load(text, typeof(GameObject));
|
|
if (UsePrefabCache)
|
|
{
|
|
PrefabCache.Add(text, resourceGameObject);
|
|
}
|
|
}
|
|
if (resourceGameObject == null)
|
|
{
|
|
Debug.LogError("PhotonNetwork error: Could not Instantiate the prefab [" + text + "]. Please verify you have this gameobject in a Resources folder.");
|
|
return null;
|
|
}
|
|
}
|
|
PhotonView[] photonViewsInChildren2 = resourceGameObject.GetPhotonViewsInChildren();
|
|
if (photonViewsInChildren2.Length != array.Length)
|
|
{
|
|
throw new Exception("Error in Instantiation! The resource's PhotonView count is not the same as in incoming data.");
|
|
}
|
|
for (int j = 0; j < array.Length; j++)
|
|
{
|
|
photonViewsInChildren2[j].viewID = array[j];
|
|
photonViewsInChildren2[j].prefix = prefix;
|
|
photonViewsInChildren2[j].instantiationId = num;
|
|
photonViewsInChildren2[j].isRuntimeInstantiated = true;
|
|
}
|
|
StoreInstantiationData(num, array2);
|
|
GameObject gameObject2 = UnityEngine.Object.Instantiate(resourceGameObject, position, rotation);
|
|
for (int k = 0; k < array.Length; k++)
|
|
{
|
|
photonViewsInChildren2[k].viewID = 0;
|
|
photonViewsInChildren2[k].prefix = -1;
|
|
photonViewsInChildren2[k].prefixBackup = -1;
|
|
photonViewsInChildren2[k].instantiationId = -1;
|
|
photonViewsInChildren2[k].isRuntimeInstantiated = false;
|
|
}
|
|
RemoveInstantiationData(num);
|
|
gameObject2.SendMessage(OnPhotonInstantiateString, new PhotonMessageInfo(photonPlayer, timestamp, null), SendMessageOptions.DontRequireReceiver);
|
|
return gameObject2;
|
|
}
|
|
|
|
private void StoreInstantiationData(int instantiationId, object[] instantiationData)
|
|
{
|
|
tempInstantiationData[instantiationId] = instantiationData;
|
|
}
|
|
|
|
public object[] FetchInstantiationData(int instantiationId)
|
|
{
|
|
object[] value = null;
|
|
if (instantiationId == 0)
|
|
{
|
|
return null;
|
|
}
|
|
tempInstantiationData.TryGetValue(instantiationId, out value);
|
|
return value;
|
|
}
|
|
|
|
private void RemoveInstantiationData(int instantiationId)
|
|
{
|
|
tempInstantiationData.Remove(instantiationId);
|
|
}
|
|
|
|
public void DestroyPlayerObjects(int playerId, bool localOnly)
|
|
{
|
|
if (playerId <= 0)
|
|
{
|
|
Debug.LogError("Failed to Destroy objects of playerId: " + playerId);
|
|
}
|
|
else
|
|
{
|
|
if (!localOnly)
|
|
{
|
|
OpRemoveFromServerInstantiationsOfPlayer(playerId);
|
|
OpCleanRpcBuffer(playerId);
|
|
SendDestroyOfPlayer(playerId);
|
|
}
|
|
HashSet<GameObject> hashSet = new HashSet<GameObject>();
|
|
foreach (PhotonView value in photonViewList.Values)
|
|
{
|
|
if (value != null && value.CreatorActorNr == playerId)
|
|
{
|
|
hashSet.Add(value.gameObject);
|
|
}
|
|
}
|
|
foreach (GameObject item in hashSet)
|
|
{
|
|
RemoveInstantiatedGO(item, localOnly: true);
|
|
}
|
|
foreach (PhotonView value2 in photonViewList.Values)
|
|
{
|
|
if (value2.ownerId == playerId)
|
|
{
|
|
value2.ownerId = value2.CreatorActorNr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DestroyAll(bool localOnly)
|
|
{
|
|
if (!localOnly)
|
|
{
|
|
OpRemoveCompleteCache();
|
|
SendDestroyOfAll();
|
|
}
|
|
LocalCleanupAnythingInstantiated(destroyInstantiatedGameObjects: true);
|
|
}
|
|
|
|
protected internal void RemoveInstantiatedGO(GameObject go, bool localOnly)
|
|
{
|
|
if (go == null)
|
|
{
|
|
Debug.LogError("Failed to 'network-remove' GameObject because it's null.");
|
|
}
|
|
else
|
|
{
|
|
PhotonView[] componentsInChildren = go.GetComponentsInChildren<PhotonView>(includeInactive: true);
|
|
if (componentsInChildren == null || componentsInChildren.Length <= 0)
|
|
{
|
|
Debug.LogError("Failed to 'network-remove' GameObject because has no PhotonView components: " + go);
|
|
}
|
|
else
|
|
{
|
|
PhotonView photonView = componentsInChildren[0];
|
|
int creatorActorNr = photonView.CreatorActorNr;
|
|
int instantiationId = photonView.instantiationId;
|
|
if (!localOnly)
|
|
{
|
|
if (!photonView.isMine)
|
|
{
|
|
Debug.LogError("Failed to 'network-remove' GameObject. Client is neither owner nor masterClient taking over for owner who left: " + photonView);
|
|
return;
|
|
}
|
|
if (instantiationId < 1)
|
|
{
|
|
Debug.LogError("Failed to 'network-remove' GameObject because it is missing a valid InstantiationId on view: " + photonView + ". Not Destroying GameObject or PhotonViews!");
|
|
return;
|
|
}
|
|
}
|
|
if (!localOnly)
|
|
{
|
|
ServerCleanInstantiateAndDestroy(instantiationId, creatorActorNr, photonView.isRuntimeInstantiated);
|
|
}
|
|
for (int num = componentsInChildren.Length - 1; num >= 0; num--)
|
|
{
|
|
PhotonView photonView2 = componentsInChildren[num];
|
|
if (!(photonView2 == null))
|
|
{
|
|
if (photonView2.instantiationId >= 1)
|
|
{
|
|
LocalCleanPhotonView(photonView2);
|
|
}
|
|
if (!localOnly)
|
|
{
|
|
OpCleanRpcBuffer(photonView2);
|
|
}
|
|
}
|
|
}
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
|
|
{
|
|
Debug.Log("Network destroy Instantiated GO: " + go.name);
|
|
}
|
|
if (ObjectPool != null)
|
|
{
|
|
PhotonView[] photonViewsInChildren = go.GetPhotonViewsInChildren();
|
|
for (int i = 0; i < photonViewsInChildren.Length; i++)
|
|
{
|
|
photonViewsInChildren[i].viewID = 0;
|
|
}
|
|
ObjectPool.Destroy(go);
|
|
}
|
|
else
|
|
{
|
|
UnityEngine.Object.Destroy(go);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ServerCleanInstantiateAndDestroy(int instantiateId, int creatorId, bool isRuntimeInstantiated)
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable[(byte)7] = instantiateId;
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.CachingOption = EventCaching.RemoveFromRoomCache;
|
|
raiseEventOptions.TargetActors = new int[1]
|
|
{
|
|
creatorId
|
|
};
|
|
RaiseEventOptions raiseEventOptions2 = raiseEventOptions;
|
|
OpRaiseEvent(202, hashtable, sendReliable: true, raiseEventOptions2);
|
|
ExitGames.Client.Photon.Hashtable hashtable2 = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable2[(byte)0] = instantiateId;
|
|
raiseEventOptions2 = null;
|
|
if (!isRuntimeInstantiated)
|
|
{
|
|
raiseEventOptions2 = new RaiseEventOptions();
|
|
raiseEventOptions2.CachingOption = EventCaching.AddToRoomCacheGlobal;
|
|
Debug.Log("Destroying GO as global. ID: " + instantiateId);
|
|
}
|
|
OpRaiseEvent(204, hashtable2, sendReliable: true, raiseEventOptions2);
|
|
}
|
|
|
|
private void SendDestroyOfPlayer(int actorNr)
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable[(byte)0] = actorNr;
|
|
OpRaiseEvent(207, hashtable, sendReliable: true, null);
|
|
}
|
|
|
|
private void SendDestroyOfAll()
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable[(byte)0] = -1;
|
|
OpRaiseEvent(207, hashtable, sendReliable: true, null);
|
|
}
|
|
|
|
private void OpRemoveFromServerInstantiationsOfPlayer(int actorNr)
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.CachingOption = EventCaching.RemoveFromRoomCache;
|
|
raiseEventOptions.TargetActors = new int[1]
|
|
{
|
|
actorNr
|
|
};
|
|
RaiseEventOptions raiseEventOptions2 = raiseEventOptions;
|
|
OpRaiseEvent(202, null, sendReliable: true, raiseEventOptions2);
|
|
}
|
|
|
|
protected internal void RequestOwnership(int viewID, int fromOwner)
|
|
{
|
|
Debug.Log("RequestOwnership(): " + viewID + " from: " + fromOwner + " Time: " + Environment.TickCount % 1000);
|
|
OpRaiseEvent(209, new int[2]
|
|
{
|
|
viewID,
|
|
fromOwner
|
|
}, sendReliable: true, new RaiseEventOptions
|
|
{
|
|
Receivers = ReceiverGroup.All
|
|
});
|
|
}
|
|
|
|
protected internal void TransferOwnership(int viewID, int playerID)
|
|
{
|
|
Debug.Log("TransferOwnership() view " + viewID + " to: " + playerID + " Time: " + Environment.TickCount % 1000);
|
|
OpRaiseEvent(210, new int[2]
|
|
{
|
|
viewID,
|
|
playerID
|
|
}, sendReliable: true, new RaiseEventOptions
|
|
{
|
|
Receivers = ReceiverGroup.All
|
|
});
|
|
}
|
|
|
|
public bool LocalCleanPhotonView(PhotonView view)
|
|
{
|
|
view.removedFromLocalViewList = true;
|
|
return photonViewList.Remove(view.viewID);
|
|
}
|
|
|
|
public PhotonView GetPhotonView(int viewID)
|
|
{
|
|
PhotonView value = null;
|
|
photonViewList.TryGetValue(viewID, out value);
|
|
if (value == null)
|
|
{
|
|
PhotonView[] array = UnityEngine.Object.FindObjectsOfType(typeof(PhotonView)) as PhotonView[];
|
|
foreach (PhotonView photonView in array)
|
|
{
|
|
if (photonView.viewID == viewID)
|
|
{
|
|
if (photonView.didAwake)
|
|
{
|
|
Debug.LogWarning("Had to lookup view that wasn't in photonViewList: " + photonView);
|
|
}
|
|
return photonView;
|
|
}
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public void RegisterPhotonView(PhotonView netView)
|
|
{
|
|
if (!Application.isPlaying)
|
|
{
|
|
photonViewList = new Dictionary<int, PhotonView>();
|
|
}
|
|
else if (netView.viewID == 0)
|
|
{
|
|
Debug.Log("PhotonView register is ignored, because viewID is 0. No id assigned yet to: " + netView);
|
|
}
|
|
else
|
|
{
|
|
PhotonView value = null;
|
|
if (photonViewList.TryGetValue(netView.viewID, out value))
|
|
{
|
|
if (!(netView != value))
|
|
{
|
|
return;
|
|
}
|
|
Debug.LogError($"PhotonView ID duplicate found: {netView.viewID}. New: {netView} old: {value}. Maybe one wasn't destroyed on scene load?! Check for 'DontDestroyOnLoad'. Destroying old entry, adding new.");
|
|
RemoveInstantiatedGO(value.gameObject, localOnly: true);
|
|
}
|
|
photonViewList.Add(netView.viewID, netView);
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
|
|
{
|
|
Debug.Log("Registered PhotonView: " + netView.viewID);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OpCleanRpcBuffer(int actorNumber)
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.CachingOption = EventCaching.RemoveFromRoomCache;
|
|
raiseEventOptions.TargetActors = new int[1]
|
|
{
|
|
actorNumber
|
|
};
|
|
RaiseEventOptions raiseEventOptions2 = raiseEventOptions;
|
|
OpRaiseEvent(200, null, sendReliable: true, raiseEventOptions2);
|
|
}
|
|
|
|
public void OpRemoveCompleteCacheOfPlayer(int actorNumber)
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.CachingOption = EventCaching.RemoveFromRoomCache;
|
|
raiseEventOptions.TargetActors = new int[1]
|
|
{
|
|
actorNumber
|
|
};
|
|
RaiseEventOptions raiseEventOptions2 = raiseEventOptions;
|
|
OpRaiseEvent(0, null, sendReliable: true, raiseEventOptions2);
|
|
}
|
|
|
|
public void OpRemoveCompleteCache()
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.CachingOption = EventCaching.RemoveFromRoomCache;
|
|
raiseEventOptions.Receivers = ReceiverGroup.MasterClient;
|
|
RaiseEventOptions raiseEventOptions2 = raiseEventOptions;
|
|
OpRaiseEvent(0, null, sendReliable: true, raiseEventOptions2);
|
|
}
|
|
|
|
private void RemoveCacheOfLeftPlayers()
|
|
{
|
|
Dictionary<byte, object> dictionary = new Dictionary<byte, object>();
|
|
dictionary[244] = (byte)0;
|
|
dictionary[247] = (byte)7;
|
|
OpCustom(253, dictionary, sendReliable: true, 0);
|
|
}
|
|
|
|
public void CleanRpcBufferIfMine(PhotonView view)
|
|
{
|
|
if (view.ownerId != LocalPlayer.ID && !LocalPlayer.IsMasterClient)
|
|
{
|
|
Debug.LogError("Cannot remove cached RPCs on a PhotonView thats not ours! " + view.owner + " scene: " + view.isSceneView);
|
|
}
|
|
else
|
|
{
|
|
OpCleanRpcBuffer(view);
|
|
}
|
|
}
|
|
|
|
public void OpCleanRpcBuffer(PhotonView view)
|
|
{
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable[(byte)0] = view.viewID;
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.CachingOption = EventCaching.RemoveFromRoomCache;
|
|
RaiseEventOptions raiseEventOptions2 = raiseEventOptions;
|
|
OpRaiseEvent(200, hashtable, sendReliable: true, raiseEventOptions2);
|
|
}
|
|
|
|
public void RemoveRPCsInGroup(int group)
|
|
{
|
|
foreach (PhotonView value in photonViewList.Values)
|
|
{
|
|
if (value.group == group)
|
|
{
|
|
CleanRpcBufferIfMine(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetLevelPrefix(short prefix)
|
|
{
|
|
currentLevelPrefix = prefix;
|
|
}
|
|
|
|
internal void RPC(PhotonView view, string methodName, PhotonTargets target, PhotonPlayer player, bool encrypt, params object[] parameters)
|
|
{
|
|
if (!blockSendingGroups.Contains(view.group))
|
|
{
|
|
if (view.viewID < 1)
|
|
{
|
|
Debug.LogError("Illegal view ID:" + view.viewID + " method: " + methodName + " GO:" + view.gameObject.name);
|
|
}
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
|
|
{
|
|
Debug.Log("Sending RPC \"" + methodName + "\" to target: " + target + " or player:" + player + ".");
|
|
}
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
hashtable[(byte)0] = view.viewID;
|
|
if (view.prefix > 0)
|
|
{
|
|
hashtable[(byte)1] = (short)view.prefix;
|
|
}
|
|
hashtable[(byte)2] = PhotonNetwork.ServerTimestamp;
|
|
int value = 0;
|
|
if (rpcShortcuts.TryGetValue(methodName, out value))
|
|
{
|
|
hashtable[(byte)5] = (byte)value;
|
|
}
|
|
else
|
|
{
|
|
hashtable[(byte)3] = methodName;
|
|
}
|
|
if (parameters != null && parameters.Length > 0)
|
|
{
|
|
hashtable[(byte)4] = parameters;
|
|
}
|
|
if (player != null)
|
|
{
|
|
if (LocalPlayer.ID == player.ID)
|
|
{
|
|
ExecuteRpc(hashtable, player);
|
|
}
|
|
else
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.TargetActors = new int[1]
|
|
{
|
|
player.ID
|
|
};
|
|
raiseEventOptions.Encrypt = encrypt;
|
|
RaiseEventOptions raiseEventOptions2 = raiseEventOptions;
|
|
OpRaiseEvent(200, hashtable, sendReliable: true, raiseEventOptions2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (target)
|
|
{
|
|
case PhotonTargets.All:
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.InterestGroup = (byte)view.group;
|
|
raiseEventOptions.Encrypt = encrypt;
|
|
RaiseEventOptions raiseEventOptions9 = raiseEventOptions;
|
|
OpRaiseEvent(200, hashtable, sendReliable: true, raiseEventOptions9);
|
|
ExecuteRpc(hashtable, LocalPlayer);
|
|
break;
|
|
}
|
|
case PhotonTargets.Others:
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.InterestGroup = (byte)view.group;
|
|
raiseEventOptions.Encrypt = encrypt;
|
|
RaiseEventOptions raiseEventOptions8 = raiseEventOptions;
|
|
OpRaiseEvent(200, hashtable, sendReliable: true, raiseEventOptions8);
|
|
break;
|
|
}
|
|
case PhotonTargets.AllBuffered:
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.CachingOption = EventCaching.AddToRoomCache;
|
|
raiseEventOptions.Encrypt = encrypt;
|
|
RaiseEventOptions raiseEventOptions6 = raiseEventOptions;
|
|
OpRaiseEvent(200, hashtable, sendReliable: true, raiseEventOptions6);
|
|
ExecuteRpc(hashtable, LocalPlayer);
|
|
break;
|
|
}
|
|
case PhotonTargets.OthersBuffered:
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.CachingOption = EventCaching.AddToRoomCache;
|
|
raiseEventOptions.Encrypt = encrypt;
|
|
RaiseEventOptions raiseEventOptions4 = raiseEventOptions;
|
|
OpRaiseEvent(200, hashtable, sendReliable: true, raiseEventOptions4);
|
|
break;
|
|
}
|
|
case PhotonTargets.MasterClient:
|
|
if (mMasterClientId == LocalPlayer.ID)
|
|
{
|
|
ExecuteRpc(hashtable, LocalPlayer);
|
|
}
|
|
else
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.Receivers = ReceiverGroup.MasterClient;
|
|
raiseEventOptions.Encrypt = encrypt;
|
|
RaiseEventOptions raiseEventOptions7 = raiseEventOptions;
|
|
OpRaiseEvent(200, hashtable, sendReliable: true, raiseEventOptions7);
|
|
}
|
|
break;
|
|
case PhotonTargets.AllViaServer:
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.InterestGroup = (byte)view.group;
|
|
raiseEventOptions.Receivers = ReceiverGroup.All;
|
|
raiseEventOptions.Encrypt = encrypt;
|
|
RaiseEventOptions raiseEventOptions5 = raiseEventOptions;
|
|
OpRaiseEvent(200, hashtable, sendReliable: true, raiseEventOptions5);
|
|
if (PhotonNetwork.offlineMode)
|
|
{
|
|
ExecuteRpc(hashtable, LocalPlayer);
|
|
}
|
|
break;
|
|
}
|
|
case PhotonTargets.AllBufferedViaServer:
|
|
{
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
raiseEventOptions.InterestGroup = (byte)view.group;
|
|
raiseEventOptions.Receivers = ReceiverGroup.All;
|
|
raiseEventOptions.CachingOption = EventCaching.AddToRoomCache;
|
|
raiseEventOptions.Encrypt = encrypt;
|
|
RaiseEventOptions raiseEventOptions3 = raiseEventOptions;
|
|
OpRaiseEvent(200, hashtable, sendReliable: true, raiseEventOptions3);
|
|
if (PhotonNetwork.offlineMode)
|
|
{
|
|
ExecuteRpc(hashtable, LocalPlayer);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
Debug.LogError("Unsupported target enum: " + target);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetReceivingEnabled(int group, bool enabled)
|
|
{
|
|
if (group <= 0)
|
|
{
|
|
Debug.LogError("Error: PhotonNetwork.SetReceivingEnabled was called with an illegal group number: " + group + ". The group number should be at least 1.");
|
|
}
|
|
else if (enabled)
|
|
{
|
|
if (!allowedReceivingGroups.Contains(group))
|
|
{
|
|
allowedReceivingGroups.Add(group);
|
|
byte[] groupsToAdd = new byte[1]
|
|
{
|
|
(byte)group
|
|
};
|
|
OpChangeGroups(null, groupsToAdd);
|
|
}
|
|
}
|
|
else if (allowedReceivingGroups.Contains(group))
|
|
{
|
|
allowedReceivingGroups.Remove(group);
|
|
byte[] groupsToRemove = new byte[1]
|
|
{
|
|
(byte)group
|
|
};
|
|
OpChangeGroups(groupsToRemove, null);
|
|
}
|
|
}
|
|
|
|
public void SetReceivingEnabled(int[] enableGroups, int[] disableGroups)
|
|
{
|
|
List<byte> list = new List<byte>();
|
|
List<byte> list2 = new List<byte>();
|
|
if (enableGroups != null)
|
|
{
|
|
foreach (int num in enableGroups)
|
|
{
|
|
if (num <= 0)
|
|
{
|
|
Debug.LogError("Error: PhotonNetwork.SetReceivingEnabled was called with an illegal group number: " + num + ". The group number should be at least 1.");
|
|
}
|
|
else if (!allowedReceivingGroups.Contains(num))
|
|
{
|
|
allowedReceivingGroups.Add(num);
|
|
list.Add((byte)num);
|
|
}
|
|
}
|
|
}
|
|
if (disableGroups != null)
|
|
{
|
|
foreach (int num2 in disableGroups)
|
|
{
|
|
if (num2 <= 0)
|
|
{
|
|
Debug.LogError("Error: PhotonNetwork.SetReceivingEnabled was called with an illegal group number: " + num2 + ". The group number should be at least 1.");
|
|
}
|
|
else if (list.Contains((byte)num2))
|
|
{
|
|
Debug.LogError("Error: PhotonNetwork.SetReceivingEnabled disableGroups contains a group that is also in the enableGroups: " + num2 + ".");
|
|
}
|
|
else if (allowedReceivingGroups.Contains(num2))
|
|
{
|
|
allowedReceivingGroups.Remove(num2);
|
|
list2.Add((byte)num2);
|
|
}
|
|
}
|
|
}
|
|
OpChangeGroups((list2.Count <= 0) ? null : list2.ToArray(), (list.Count <= 0) ? null : list.ToArray());
|
|
}
|
|
|
|
public void SetSendingEnabled(int group, bool enabled)
|
|
{
|
|
if (!enabled)
|
|
{
|
|
blockSendingGroups.Add(group);
|
|
}
|
|
else
|
|
{
|
|
blockSendingGroups.Remove(group);
|
|
}
|
|
}
|
|
|
|
public void SetSendingEnabled(int[] enableGroups, int[] disableGroups)
|
|
{
|
|
if (enableGroups != null)
|
|
{
|
|
foreach (int item in enableGroups)
|
|
{
|
|
if (blockSendingGroups.Contains(item))
|
|
{
|
|
blockSendingGroups.Remove(item);
|
|
}
|
|
}
|
|
}
|
|
if (disableGroups != null)
|
|
{
|
|
foreach (int item2 in disableGroups)
|
|
{
|
|
if (!blockSendingGroups.Contains(item2))
|
|
{
|
|
blockSendingGroups.Add(item2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void NewSceneLoaded()
|
|
{
|
|
if (loadingLevelAndPausedNetwork)
|
|
{
|
|
loadingLevelAndPausedNetwork = false;
|
|
PhotonNetwork.isMessageQueueRunning = true;
|
|
}
|
|
List<int> list = new List<int>();
|
|
foreach (KeyValuePair<int, PhotonView> photonView in photonViewList)
|
|
{
|
|
PhotonView value = photonView.Value;
|
|
if (value == null)
|
|
{
|
|
list.Add(photonView.Key);
|
|
}
|
|
}
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
int key = list[i];
|
|
photonViewList.Remove(key);
|
|
}
|
|
if (list.Count > 0 && PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log("New level loaded. Removed " + list.Count + " scene view IDs from last level.");
|
|
}
|
|
}
|
|
|
|
public void RunViewUpdate()
|
|
{
|
|
if (PhotonNetwork.connected && !PhotonNetwork.offlineMode && mActors != null && mActors.Count > 1)
|
|
{
|
|
int num = 0;
|
|
RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
|
|
foreach (PhotonView value3 in photonViewList.Values)
|
|
{
|
|
if (value3.synchronization != 0 && value3.isMine && value3.gameObject.activeInHierarchy && !blockSendingGroups.Contains(value3.group))
|
|
{
|
|
object[] array = OnSerializeWrite(value3);
|
|
if (array != null)
|
|
{
|
|
if (value3.synchronization == ViewSynchronization.ReliableDeltaCompressed || value3.mixedModeIsReliable)
|
|
{
|
|
ExitGames.Client.Photon.Hashtable value = null;
|
|
if (!dataPerGroupReliable.TryGetValue(value3.group, out value))
|
|
{
|
|
value = new ExitGames.Client.Photon.Hashtable(ObjectsInOneUpdate);
|
|
dataPerGroupReliable[value3.group] = value;
|
|
}
|
|
value.Add((byte)(value.Count + 10), array);
|
|
num++;
|
|
if (value.Count >= ObjectsInOneUpdate)
|
|
{
|
|
num -= value.Count;
|
|
raiseEventOptions.InterestGroup = (byte)value3.group;
|
|
value[(byte)0] = PhotonNetwork.ServerTimestamp;
|
|
if (currentLevelPrefix >= 0)
|
|
{
|
|
value[(byte)1] = currentLevelPrefix;
|
|
}
|
|
OpRaiseEvent(206, value, sendReliable: true, raiseEventOptions);
|
|
value.Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ExitGames.Client.Photon.Hashtable value2 = null;
|
|
if (!dataPerGroupUnreliable.TryGetValue(value3.group, out value2))
|
|
{
|
|
value2 = new ExitGames.Client.Photon.Hashtable(ObjectsInOneUpdate);
|
|
dataPerGroupUnreliable[value3.group] = value2;
|
|
}
|
|
value2.Add((byte)(value2.Count + 10), array);
|
|
num++;
|
|
if (value2.Count >= ObjectsInOneUpdate)
|
|
{
|
|
num -= value2.Count;
|
|
raiseEventOptions.InterestGroup = (byte)value3.group;
|
|
value2[(byte)0] = PhotonNetwork.ServerTimestamp;
|
|
if (currentLevelPrefix >= 0)
|
|
{
|
|
value2[(byte)1] = currentLevelPrefix;
|
|
}
|
|
OpRaiseEvent(201, value2, sendReliable: false, raiseEventOptions);
|
|
value2.Clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (num != 0)
|
|
{
|
|
foreach (int key in dataPerGroupReliable.Keys)
|
|
{
|
|
raiseEventOptions.InterestGroup = (byte)key;
|
|
ExitGames.Client.Photon.Hashtable hashtable = dataPerGroupReliable[key];
|
|
if (hashtable.Count != 0)
|
|
{
|
|
hashtable[(byte)0] = PhotonNetwork.ServerTimestamp;
|
|
if (currentLevelPrefix >= 0)
|
|
{
|
|
hashtable[(byte)1] = currentLevelPrefix;
|
|
}
|
|
OpRaiseEvent(206, hashtable, sendReliable: true, raiseEventOptions);
|
|
hashtable.Clear();
|
|
}
|
|
}
|
|
foreach (int key2 in dataPerGroupUnreliable.Keys)
|
|
{
|
|
raiseEventOptions.InterestGroup = (byte)key2;
|
|
ExitGames.Client.Photon.Hashtable hashtable2 = dataPerGroupUnreliable[key2];
|
|
if (hashtable2.Count != 0)
|
|
{
|
|
hashtable2[(byte)0] = PhotonNetwork.ServerTimestamp;
|
|
if (currentLevelPrefix >= 0)
|
|
{
|
|
hashtable2[(byte)1] = currentLevelPrefix;
|
|
}
|
|
OpRaiseEvent(201, hashtable2, sendReliable: false, raiseEventOptions);
|
|
hashtable2.Clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private object[] OnSerializeWrite(PhotonView view)
|
|
{
|
|
if (view.synchronization == ViewSynchronization.Off)
|
|
{
|
|
return null;
|
|
}
|
|
PhotonMessageInfo info = new PhotonMessageInfo(LocalPlayer, PhotonNetwork.ServerTimestamp, view);
|
|
pStream.ResetWriteStream();
|
|
pStream.SendNext(view.viewID);
|
|
pStream.SendNext(false);
|
|
pStream.SendNext(null);
|
|
view.SerializeView(pStream, info);
|
|
if (pStream.Count <= 3)
|
|
{
|
|
return null;
|
|
}
|
|
if (view.synchronization == ViewSynchronization.Unreliable)
|
|
{
|
|
return pStream.ToArray();
|
|
}
|
|
object[] array = pStream.ToArray();
|
|
if (view.synchronization == ViewSynchronization.UnreliableOnChange)
|
|
{
|
|
if (AlmostEquals(array, view.lastOnSerializeDataSent))
|
|
{
|
|
if (view.mixedModeIsReliable)
|
|
{
|
|
return null;
|
|
}
|
|
view.mixedModeIsReliable = true;
|
|
view.lastOnSerializeDataSent = array;
|
|
}
|
|
else
|
|
{
|
|
view.mixedModeIsReliable = false;
|
|
view.lastOnSerializeDataSent = array;
|
|
}
|
|
return array;
|
|
}
|
|
if (view.synchronization == ViewSynchronization.ReliableDeltaCompressed)
|
|
{
|
|
object[] result = DeltaCompressionWrite(view.lastOnSerializeDataSent, array);
|
|
view.lastOnSerializeDataSent = array;
|
|
return result;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void OnSerializeRead(object[] data, PhotonPlayer sender, int networkTime, short correctPrefix)
|
|
{
|
|
int num = (int)data[0];
|
|
PhotonView photonView = GetPhotonView(num);
|
|
if (photonView == null)
|
|
{
|
|
Debug.LogWarning("Received OnSerialization for view ID " + num + ". We have no such PhotonView! Ignored this if you're leaving a room. State: " + State);
|
|
}
|
|
else if (photonView.prefix > 0 && correctPrefix != photonView.prefix)
|
|
{
|
|
Debug.LogError("Received OnSerialization for view ID " + num + " with prefix " + correctPrefix + ". Our prefix is " + photonView.prefix);
|
|
}
|
|
else if (photonView.group == 0 || allowedReceivingGroups.Contains(photonView.group))
|
|
{
|
|
if (photonView.synchronization == ViewSynchronization.ReliableDeltaCompressed)
|
|
{
|
|
object[] array = DeltaCompressionRead(photonView.lastOnSerializeDataReceived, data);
|
|
if (array == null)
|
|
{
|
|
if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
|
|
{
|
|
Debug.Log("Skipping packet for " + photonView.name + " [" + photonView.viewID + "] as we haven't received a full packet for delta compression yet. This is OK if it happens for the first few frames after joining a game.");
|
|
}
|
|
return;
|
|
}
|
|
photonView.lastOnSerializeDataReceived = array;
|
|
data = array;
|
|
}
|
|
if (sender.ID != photonView.ownerId && (!photonView.OwnerShipWasTransfered || photonView.ownerId == 0) && photonView.currentMasterID == -1)
|
|
{
|
|
photonView.ownerId = sender.ID;
|
|
}
|
|
readStream.SetReadStream(data, 3);
|
|
photonView.DeserializeView(info: new PhotonMessageInfo(sender, networkTime, photonView), stream: readStream);
|
|
}
|
|
}
|
|
|
|
private object[] DeltaCompressionWrite(object[] previousContent, object[] currentContent)
|
|
{
|
|
if (currentContent == null || previousContent == null || previousContent.Length != currentContent.Length)
|
|
{
|
|
return currentContent;
|
|
}
|
|
if (currentContent.Length <= 3)
|
|
{
|
|
return null;
|
|
}
|
|
previousContent[1] = false;
|
|
int num = 0;
|
|
Queue<int> queue = null;
|
|
for (int i = 3; i < currentContent.Length; i++)
|
|
{
|
|
object obj = currentContent[i];
|
|
object two = previousContent[i];
|
|
if (AlmostEquals(obj, two))
|
|
{
|
|
num++;
|
|
previousContent[i] = null;
|
|
}
|
|
else
|
|
{
|
|
previousContent[i] = obj;
|
|
if (obj == null)
|
|
{
|
|
if (queue == null)
|
|
{
|
|
queue = new Queue<int>(currentContent.Length);
|
|
}
|
|
queue.Enqueue(i);
|
|
}
|
|
}
|
|
}
|
|
if (num > 0)
|
|
{
|
|
if (num == currentContent.Length - 3)
|
|
{
|
|
return null;
|
|
}
|
|
previousContent[1] = true;
|
|
if (queue != null)
|
|
{
|
|
previousContent[2] = queue.ToArray();
|
|
}
|
|
}
|
|
previousContent[0] = currentContent[0];
|
|
return previousContent;
|
|
}
|
|
|
|
private object[] DeltaCompressionRead(object[] lastOnSerializeDataReceived, object[] incomingData)
|
|
{
|
|
if (!(bool)incomingData[1])
|
|
{
|
|
return incomingData;
|
|
}
|
|
if (lastOnSerializeDataReceived == null)
|
|
{
|
|
return null;
|
|
}
|
|
int[] array = incomingData[2] as int[];
|
|
for (int i = 3; i < incomingData.Length; i++)
|
|
{
|
|
if ((array == null || !array.Contains(i)) && incomingData[i] == null)
|
|
{
|
|
object obj = incomingData[i] = lastOnSerializeDataReceived[i];
|
|
}
|
|
}
|
|
return incomingData;
|
|
}
|
|
|
|
private bool AlmostEquals(object[] lastData, object[] currentContent)
|
|
{
|
|
if (lastData == null && currentContent == null)
|
|
{
|
|
return true;
|
|
}
|
|
if (lastData == null || currentContent == null || lastData.Length != currentContent.Length)
|
|
{
|
|
return false;
|
|
}
|
|
for (int i = 0; i < currentContent.Length; i++)
|
|
{
|
|
object one = currentContent[i];
|
|
object two = lastData[i];
|
|
if (!AlmostEquals(one, two))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private bool AlmostEquals(object one, object two)
|
|
{
|
|
if (one == null || two == null)
|
|
{
|
|
return one == null && two == null;
|
|
}
|
|
if (!one.Equals(two))
|
|
{
|
|
if (one is Vector3)
|
|
{
|
|
Vector3 target = (Vector3)one;
|
|
Vector3 second = (Vector3)two;
|
|
if (target.AlmostEquals(second, PhotonNetwork.precisionForVectorSynchronization))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else if (one is Vector2)
|
|
{
|
|
Vector2 target2 = (Vector2)one;
|
|
Vector2 second2 = (Vector2)two;
|
|
if (target2.AlmostEquals(second2, PhotonNetwork.precisionForVectorSynchronization))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else if (one is Quaternion)
|
|
{
|
|
Quaternion target3 = (Quaternion)one;
|
|
Quaternion second3 = (Quaternion)two;
|
|
if (target3.AlmostEquals(second3, PhotonNetwork.precisionForQuaternionSynchronization))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else if (one is float)
|
|
{
|
|
float target4 = (float)one;
|
|
float second4 = (float)two;
|
|
if (target4.AlmostEquals(second4, PhotonNetwork.precisionForFloatSynchronization))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
protected internal static bool GetMethod(MonoBehaviour monob, string methodType, out MethodInfo mi)
|
|
{
|
|
mi = null;
|
|
if (monob == null || string.IsNullOrEmpty(methodType))
|
|
{
|
|
return false;
|
|
}
|
|
List<MethodInfo> methods = SupportClass.GetMethods(monob.GetType(), null);
|
|
for (int i = 0; i < methods.Count; i++)
|
|
{
|
|
MethodInfo methodInfo = methods[i];
|
|
if (methodInfo.Name.Equals(methodType))
|
|
{
|
|
mi = methodInfo;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected internal void LoadLevelIfSynced()
|
|
{
|
|
if (PhotonNetwork.automaticallySyncScene && !PhotonNetwork.isMasterClient && PhotonNetwork.room != null && PhotonNetwork.room.CustomProperties.ContainsKey("curScn"))
|
|
{
|
|
object obj = PhotonNetwork.room.CustomProperties["curScn"];
|
|
if (obj is int)
|
|
{
|
|
if (SceneManagerHelper.ActiveSceneBuildIndex != (int)obj)
|
|
{
|
|
PhotonNetwork.LoadLevel((int)obj);
|
|
}
|
|
}
|
|
else if (obj is string && SceneManagerHelper.ActiveSceneName != (string)obj)
|
|
{
|
|
PhotonNetwork.LoadLevel((string)obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected internal void SetLevelInPropsIfSynced(object levelId)
|
|
{
|
|
if (PhotonNetwork.automaticallySyncScene && PhotonNetwork.isMasterClient && PhotonNetwork.room != null)
|
|
{
|
|
if (levelId == null)
|
|
{
|
|
Debug.LogError("Parameter levelId can't be null!");
|
|
}
|
|
else
|
|
{
|
|
if (PhotonNetwork.room.CustomProperties.ContainsKey("curScn"))
|
|
{
|
|
object obj = PhotonNetwork.room.CustomProperties["curScn"];
|
|
if ((obj is int && SceneManagerHelper.ActiveSceneBuildIndex == (int)obj) || (obj is string && SceneManagerHelper.ActiveSceneName != null && SceneManagerHelper.ActiveSceneName.Equals((string)obj)))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
|
|
if (levelId is int)
|
|
{
|
|
hashtable["curScn"] = (int)levelId;
|
|
}
|
|
else if (levelId is string)
|
|
{
|
|
hashtable["curScn"] = (string)levelId;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("Parameter levelId must be int or string!");
|
|
}
|
|
PhotonNetwork.room.SetCustomProperties(hashtable);
|
|
SendOutgoingCommands();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetApp(string appId, string gameVersion)
|
|
{
|
|
AppId = appId.Trim();
|
|
if (!string.IsNullOrEmpty(gameVersion))
|
|
{
|
|
PhotonNetwork.gameVersion = gameVersion.Trim();
|
|
}
|
|
}
|
|
|
|
public bool WebRpc(string uriPath, object parameters)
|
|
{
|
|
Dictionary<byte, object> dictionary = new Dictionary<byte, object>();
|
|
dictionary.Add(209, uriPath);
|
|
dictionary.Add(208, parameters);
|
|
return OpCustom(219, dictionary, sendReliable: true);
|
|
}
|
|
}
|