Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sathyarajshetigar/572efb950399ced9a9125790f945a85f to your computer and use it in GitHub Desktop.
Save sathyarajshetigar/572efb950399ced9a9125790f945a85f to your computer and use it in GitHub Desktop.
connect4 PUN
using ExitGames.Client.Photon;
using Photon;
// using Photon.Chat;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace WinZoFourInARow
{
public class PlayfabFriendData
{
public string playfabID;
public string playfabName;
public bool isOnline;
public PlayfabFriendData(string playfabID, string playfabName, bool isOnline)
{
this.playfabID = playfabID;
this.playfabName = playfabName;
this.isOnline = isOnline;
}
}
public struct PunEventCache
{
public byte eventCode;
public object eventcontent;
public RaiseEventOptions options;
public PunEventCache(byte eventCode, object eventcontent, RaiseEventOptions options)
{
this.eventCode = eventCode;
this.eventcontent = eventcontent;
this.options = options;
}
}
public class PhotonManager : PunBehaviour
{
protected PhotonManager()
{
}
public static PhotonManager instance = null;
public delegate void PhotonPingBroadcastEvent(int ping);
public static PhotonPingBroadcastEvent onPhotonPingBroadcastEvent;
public delegate void OnGameStart(GameModes mode);
public static OnGameStart onGameStartEvent;
public delegate void OnPunFriendsReady(bool ready);
public static OnPunFriendsReady onPunFriendsReadyEvent;
public delegate void OnPUNConnected(bool success);
//when trying to join random room and if player is not in the lobby lsiten to this and join the room
static OnPUNConnected onConnectToPun;
public delegate void OnLeaveGame();
private static OnLeaveGame onLeaveGameEvent;
public delegate void OnCreatedPrivateRoom(bool success);
public static OnCreatedPrivateRoom onCreatedPrivateRoomEvent;
private bool manualDisconnection = false;
public bool showLogs = false;
[SerializeField]
private string photonID;
/// <summary>
/// This client's version number. Users are separated from each other by gameversion (which allows you to make breaking changes).
/// </summary>
private const int GAMEVERSION = 1;
private const int CHATVERSION = 1;
private const int WAITTIMEFORROOM = 20;
private bool didQuitApplication = false;
private PunEventCache punEventCache;
public PhotonPlayer localPlayer { get { return PhotonNetwork.player; } }
public bool isMasterClient { get { return PhotonNetwork.player.IsMasterClient; } }
public bool isInRoom { get { return PhotonNetwork.inRoom; } }
public int totalPlayersCount
{
get
{
return PhotonNetwork.playerList.Length;
}
}
public bool retryingGame { get; private set; }
public bool isConnectedToPhotonChat { get; private set; }
public string joinedRoomName { get; private set; }
public const string PLAYERWENTTOBG = "pWentToBG";
// setup our OnEvent as callback:
private void OnEnable()
{
PhotonNetwork.OnEventCall += this.OnEvent;
FourInARow.onTurnEvent += onTurnOver;
FourInARow.onGameOverEvent += onGameOver;
}
private void OnDisable()
{
PhotonNetwork.OnEventCall -= this.OnEvent;
FourInARow.onTurnEvent -= onTurnOver;
FourInARow.onGameOverEvent -= onGameOver;
}
private void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(gameObject);
PhotonView photonView = gameObject.AddComponent<PhotonView>();
List<Component> ObservedComponents = new List<Component>();
ObservedComponents.Add(this);
photonView.ObservedComponents = ObservedComponents;
photonView.viewID = 1;
}
else if (instance != this)
{
Destroy(gameObject);
}
}
private void Start()
{
// #Critical
PhotonNetwork.autoJoinLobby = false;
PhotonNetwork.automaticallySyncScene = false;
PhotonNetwork.networkingPeer.MaximumTransferUnit = 520;
PhotonNetwork.CrcCheckEnabled = true;
PhotonNetwork.QuickResends = 3;
PhotonNetwork.MaxResendsBeforeDisconnect = 10;
PhotonNetwork.BackgroundTimeout = 60;
InvokeRepeating("CheckPing", 1, 5);
}
/// <summary>
/// Prints logs with colors
/// https://www.w3schools.com/colors/colors_picker.asp
/// </summary>
/// <param name="message"></param>
/// <param name="color"></param>
private void PrintLog(string message, bool isError = false, Color? color = null)
{
if (showLogs)
{
message = "PUN_" + message;
if (color == null)
color = Color.cyan;
#if UNITY_EDITOR
if (isError)
Debug.LogError(string.Format("<size=12><i><b><color=#{0:X2}{1:X2}{2:X2}>{3}</color></b></i></size>",
(byte)(color.Value.r * 255f), (byte)(color.Value.g * 255f), (byte)(color.Value.b * 255f), message));
else
Debug.Log(string.Format("<size=12><i><b><color=#{0:X2}{1:X2}{2:X2}>{3}</color></b></i></size>",
(byte)(color.Value.r * 255f), (byte)(color.Value.g * 255f), (byte)(color.Value.b * 255f), message));
#else
Debug.Log(message);
#endif
}
}
public bool CheckForNewVersion()
{
PrintLog("CheckForVersionUpdate " + Game.photonRemoteGameVersion + " cur Version " + GAMEVERSION);
if (Game.photonRemoteGameVersion > -1)
{
if (Game.photonRemoteGameVersion > GAMEVERSION)
DialogBox.Show("Alert", "Please update the game \nto the latest version \nto play online", "Update", "Later", (update, didCancel) =>
{
//Update the game
if (update) OpenStore();
});
return (Game.photonRemoteGameVersion > GAMEVERSION);
}
return false;
}
private void OpenStore()
{
#if UNITY_ANDROID
Application.OpenURL("http://play.google.com/store/apps/details?id=" + Application.identifier);
#elif UNITY_IOS
Application.OpenURL("itms-apps://itunes.apple.com/app/id"+GameManager.instance.gameData.appleAppID);
#endif
}
//Photon Entry Point
public void InitPhoton()
{
Debug.Log("InitPhoton connected? " + PhotonNetwork.connected);
PhotonNetwork.PhotonServerSettings.AppID = photonID;
if (!PhotonNetwork.connected)
Connect(null);
}
private void CheckPing()
{
if (PhotonNetwork.connectedAndReady)
{
if (onPhotonPingBroadcastEvent != null)
onPhotonPingBroadcastEvent(PhotonNetwork.GetPing());
}
}
/// <summary>
/// Start the connection process.
/// - If already connected, we attempt joining a random room
/// - if not yet connected, Connect this application instance to Photon Cloud Network
/// </summary>
private void Connect(OnPUNConnected callback)
{
onConnectToPun = callback;
if (Game.isConnectedToInternet)
{
PrintLog("****Connecting to Photon****", false, new Color32(102, 0, 51, 1));
PhotonNetwork.ConnectUsingSettings(GAMEVERSION.ToString());
}
}
#region IPunCallbacks
public override void OnConnectedToPhoton()
{
PrintLog("OnConnectedToPhoton connectedAndReady? " + PhotonNetwork.connectedAndReady + " connected? " + PhotonNetwork.connected);
// InitPhotonChat();
}
public override void OnConnectedToMaster()
{
PrintLog("OnConnectedToMaster connectedAndReady? " + PhotonNetwork.connectedAndReady + " connected? " + PhotonNetwork.connected);
if (onConnectToPun != null)
onConnectToPun(true);
onConnectToPun = null;
}
public override void OnLeftRoom()
{
PrintLog("OnLeftRoom manualDisconnection? " + manualDisconnection);
if (onLeaveGameEvent != null)
onLeaveGameEvent.Invoke();
onLeaveGameEvent = null;
if (!manualDisconnection)
{
retryingGame = true;
_reconnected = false;
if (!_handlingReconnection)
{
_handlingReconnection = true;
StartCoroutine(RetryForAWhile());
}
}
}
public override void OnMasterClientSwitched(PhotonPlayer newMasterClient)
{
PrintLog("OnMasterClientSwitched");
}
public override void OnPhotonCreateRoomFailed(object[] codeAndMsg)
{
PrintLog("OnPhotonCreateRoomFailed");
if (Game.gameMode == GameModes.OnlinePrivate && onCreatedPrivateRoomEvent != null)
onCreatedPrivateRoomEvent(false);
}
public override void OnPhotonJoinRoomFailed(object[] codeAndMsg)
{
PrintLog("OnPhotonJoinRoomFailed " + codeAndMsg[0].ToString() + " Game.acceptingInvite " + Game.acceptingInvite + " wasinroom " + _wasInRoom);
_wasInRoom = false;
int errorCode = 0;
int.TryParse(codeAndMsg[0].ToString(), out errorCode);
if (Game.acceptingInvite)
{
//DialogBox.Show("Alert", PushNotificationManager.instance.senderName + " disconnected the game", "OK", (ok, didCancel) =>
// {
// DialogBox.HideLoadingScreen();
// GameManager.instance.uiGameSceneController.ShowHideJoinPrivateGameWindow(false);
// GameManager.instance.uiGameSceneController.PlayPlayerVsAI(false);
// });
}
if (errorCode == 32748 && Game.isOnlineGame)//User does not exist in this game
{
DialogBox.Show("Alert", "You got disconnected \nfrom the game.", "OK", (ok, didCancel) =>
{
//TODO: Windzo kill the game
});
}
else if (errorCode == 32758 && Game.isOnlineGame)//game does not exist error
{
DialogBox.Show("Alert", "Invalid room code \nor the game ended", "OK", (ok, didCancel) =>
{
if (Game.acceptingInvite)
{
DialogBox.HideLoadingScreen();
GameManager.instance.uiGameSceneController.ShowHideJoinPrivateGameWindow(false);
GameManager.instance.uiGameSceneController.PlayPlayerVsAI(false);
}
else
{
if (_wasInRoom)
{
DialogBox.Show("Oops", "You got disconnected \nfrom the game.", "OK", (_, __) =>
{
GameManager.instance.uiGameSceneController.ShowHideSharePrivateGameWindow(false);
GameManager.instance.uiGameSceneController.ShowHideJoinPrivateGameWindow(false);
ResetMultiplayerGame();
});
}
// GameManager.instance.uiGameSceneController.ShowHideJoinPrivateGameWindow(true);
}
});
}
else if (errorCode == 32765 && Game.isOnlineGame)//game room is full error
{
DialogBox.Show("Alert", "Room is full. \nYou cannot join", "OK", (ok, didCancel) =>
{
DialogBox.HideLoadingScreen();
GameManager.instance.uiGameSceneController.ShowHideJoinPrivateGameWindow(false);
GameManager.instance.uiGameSceneController.PlayPlayerVsAI(false);
});
}
Game.acceptingInvite = false;
}
public override void OnCreatedRoom()
{
PrintLog("OnCreatedRoom " + PhotonNetwork.room.Name);
}
public override void OnJoinedLobby()
{
PrintLog("OnJoinedLobby " + PhotonNetwork.lobby.Name);
//Trigger this event which is subscribed from leaveroom
//if (onRetryJoinRandomRoomEvent != null)
// onRetryJoinRandomRoomEvent(true);
//onRetryJoinRandomRoomEvent = null;
}
public override void OnLeftLobby()
{
PrintLog("OnLeftLobby");
// if (onJoinedPUNLobbyEvent != null)
// onJoinedPUNLobbyEvent(false);
if (onConnectToPun != null)
onConnectToPun(false);
onConnectToPun = null;
}
public override void OnFailedToConnectToPhoton(DisconnectCause cause)
{
PrintLog("OnFailedToConnectToPhoton " + cause);
}
public override void OnConnectionFail(DisconnectCause cause)
{
// _wasInRoom = false;
PrintLog("OnConnectionFail " + cause.ToString());
}
public override void OnDisconnectedFromPhoton()
{
PrintLog("OnDisconnectedFromPhoton " + manualDisconnection + " _handlingReconnection " + _handlingReconnection);
// GameManager.instance.uiGameSceneController.CachePauseTime();
if (!manualDisconnection)//&& PhotonNetwork.connected && Game.isConnectedToInternet)
{
//bool reconnected = PhotonNetwork.ReconnectAndRejoin();
//PrintLog("OnDisconnectedFromPhoton reconnected: " + reconnected);
retryingGame = true;
_reconnected = false;
// GameManager.instance.ResetBoard();
//bool reconnected = PhotonNetwork.ReconnectAndRejoin();
if (!_handlingReconnection)
{
_handlingReconnection = true;
StartCoroutine(RetryForAWhile());
}
// if player disconnected from the game unintentionally, try to reconnect to the same game
// PhotonNetwork.ReJoinRoom(joinedRoomName);
}
else
{
Game.rejoinedGameAfterDisconnection = false;
if (Game.isOnlineGame)
{
DialogBox.Show("Oops", "You got disconnected \nfrom the game.", "OK", (ok, didCancel) =>
{
// AdsManager.instance.ShowInterstitial();
GameManager.instance.uiGameSceneController.ShowHideSharePrivateGameWindow(false);
GameManager.instance.uiGameSceneController.ShowHideJoinPrivateGameWindow(false);
ResetMultiplayerGame();
// GameManager.instance.PlayPlayerVsAI(false, false);
});
}
}
manualDisconnection = false;
}
bool _reconnected = false;
bool _handlingReconnection = false;
bool _didCallHandleReconnection = false;
bool _wasInRoom;
bool _handlingDisconnection;
System.Collections.IEnumerator RetryForAWhile()
{
if (_handlingReconnection)
{
_didCallHandleReconnection = true;
PrintLog("RetryForAWhile _wasInRoom? " + _wasInRoom);
_handlingDisconnection = false;
int timer = 29; //30 secs
DialogBox.ShowLoadingScreen(manualDisconnection ? "Please wait" : "Retrying connection");
while (!_reconnected && timer > 0)
{
timer--;
yield return new WaitForSeconds(1f);
if (Game.isConnectedToInternet)
{
if (_wasInRoom)
{
PrintLog("Was in room reconnecting");
_reconnected = PhotonNetwork.ReconnectAndRejoin();
Game.rejoinedGameAfterDisconnection = _reconnected;
}
else
{
PrintLog("Was not in room reconnecting");
_reconnected = PhotonNetwork.Reconnect();
Game.rejoinedGameAfterDisconnection = false;
}
}
PrintLog("retry count " + timer + " _reconnected? " + _reconnected + " isMasterClient " + isMasterClient);
if (_reconnected)
break;
else
yield return null;
}
OnTryReconnect(_reconnected);
}
}
public void OnTryReconnect(bool success)
{
PrintLog("PhotonManager.cs: OnTryReconnect success " + success + " isMasterClient " + isMasterClient + " roomName " + Game.roomName);
DialogBox.HideLoadingScreen();
if (success)
{
_didCallHandleReconnection = false;
Player localPlayer = GameManager.instance.localPlayer;
if (localPlayer != null)
Debug.Log("isMyTurn " + localPlayer.isMyTurn + " playedCurrentTurn " + localPlayer.playedCurrentTurn + " timer " + GameManager.instance.uiGameSceneController.turnTimer);
if (localPlayer != null && localPlayer.isMyTurn)
{
if (GameManager.instance.uiGameSceneController.turnTimer <= 0)
{
Debug.Log("turn ended when player was in the background");
GameManager.instance.OnOnlineTurnTimer(true);
}
}
}
else
{
if (Game.isOnlineGame)
{
DialogBox.Show("Oops", "You got disconnected \nfrom the game.", "OK", (ok, didCancel) =>
{
// AdsManager.instance.ShowInterstitial();
GameManager.instance.uiGameSceneController.ShowHideSharePrivateGameWindow(false);
GameManager.instance.uiGameSceneController.ShowHideJoinPrivateGameWindow(false);
ResetMultiplayerGame();
GameManager.instance.PlayPlayerVsAI(false, false);
});
}
}
_handlingReconnection = false;
}
private PhotonPlayer GetOtherPlayerWhoIsInForground()
{
PhotonPlayer nextPlayer = null;
PhotonPlayer[] otherPlayers = Array.FindAll(PhotonNetwork.otherPlayers, p => !p.IsInactive);
int otherPlayersCount = otherPlayers.Length;
Debug.Log("GetOtherPlayerWhoIsInForground otherPlayersCount " + otherPlayersCount);
for (int i = 0; i < otherPlayersCount; i++)
{
bool isInBackground = false;
nextPlayer = otherPlayers[i];
if (nextPlayer != null)
isInBackground = (bool)GetCustomProperties(PLAYERWENTTOBG, otherPlayers[i]);
Debug.Log("nextPlayer " + i + " null? " + nextPlayer == null + " isInBackground " + isInBackground);
return !isInBackground && nextPlayer != null ? nextPlayer : null;
}
return null;
}
public object GetCustomProperties(string key, PhotonPlayer player)
{
object value = null;
if (player.CustomProperties.ContainsKey(key))
{
value = player.CustomProperties[key];
}
else
{
Debug.Log("Key " + key + " Not Found PlayerID : " + player);
}
return value;
}
public void UpdateCustomProperties(string key, object value, PhotonPlayer player)
{
//Debug.Log("Updating Custom Property : " + key + " to "+ value);
ExitGames.Client.Photon.Hashtable customProperties = player.CustomProperties;
if (customProperties.ContainsKey(key))
{
customProperties[key] = value;
}
else
{
customProperties.Add(key, value);
}
player.SetCustomProperties(customProperties);
}
public override void OnJoinedRoom()
{
UpdateCustomProperties(PLAYERWENTTOBG, false, localPlayer);
Debug.Log("OnJoinedRoom rejoinedGameAfterDisconnection? " + Game.rejoinedGameAfterDisconnection);
if (Game.rejoinedGameAfterDisconnection)
{
PhotonNetwork.SendOutgoingCommands();
if (GameManager.instance.localPlayer != null && GameManager.instance.uiGameSceneController.turnTimer > 0 && GameManager.instance.localPlayer.isMyTurn)
GameManager.instance.uiGameSceneController.CorrectTimerAfterPause(0);
PrintLog("Rejoined the game " + PhotonNetwork.room.Name + " GameMode " + Game.gameMode + " player ID " + localPlayer.ID + " isMC " + isMasterClient);
if (!EqualityComparer<PunEventCache>.Default.Equals(punEventCache, default(PunEventCache)))
{
Debug.Log("resending cached event " + punEventCache.eventCode);
RaiseEvent(punEventCache.eventCode, punEventCache.eventcontent, punEventCache.options);
switch (punEventCache.eventCode)
{
case PunEvents.GAMEOVER: OnPunGameOver(punEventCache.eventcontent, false); break;
default:
break;
}
punEventCache = default(PunEventCache);
}
//ask for latest state with other player
//PhotonPlayer otherPlayer = GetOtherPlayerWhoIsInForground();
//if (otherPlayer != null)
//{
// Debug.Log($"asking other active player {otherPlayer.ID} for game instance ");
// RaiseEvent(PunEvents.ON_RECONNECTED_PLAYER_ASK_FOR_GAME_INSTANCE, null, new RaiseEventOptions() { CachingOption = EventCaching.DoNotCache, TargetActors = new int[] { otherPlayer.ID } });
//}
}
else
{
for (int i = 0; i < PhotonNetwork.room.ExpectedUsers.Length; i++)
{
Debug.Log("expected player " + PhotonNetwork.room.ExpectedUsers[i]);
}
punEventCache = default(PunEventCache);
_handlingReconnection = false;
_wasInRoom = true;
PrintLog("OnJoinedRoom " + PhotonNetwork.room.Name + " GameMode " + Game.gameMode + " player ID " + localPlayer.ID + " isMC " + isMasterClient);
manualDisconnection = false;
PhotonNetwork.playerName = PlayerProfile.playerName;
joinedRoomName = PhotonNetwork.room.Name;
Game.roomName = joinedRoomName;
if (Game.gameMode == GameModes.OnlinePrivate && isMasterClient && onCreatedPrivateRoomEvent != null)
onCreatedPrivateRoomEvent(true);
if (Game.gameMode == GameModes.OnlinePrivate && isMasterClient)
{
DialogBox.ShowLoadingScreen("Waiting for opponent");
// DialogBox.HideLoadingScreen();
// GameManager.instance.uiGameSceneController.ShowHideSharePrivateGameWindow(true);
}
if (Game.gameMode == GameModes.OnlineRandom && isMasterClient)
Invoke("CheckIfAnyRandomPlayerFound", WAITTIMEFORROOM);
if (!retryingGame)
{
if (isMasterClient)
WaitForOpponent();
else
SendProfileToMC();
}
}
}
public override void OnPhotonPlayerConnected(PhotonPlayer newPlayer)
{
PrintLog("OnPhotonPlayerConnected " + newPlayer.NickName + " id " + newPlayer.ID + " PlayersCount " + PhotonNetwork.playerList.Length);
// PhotonNetwork.room.IsOpen = false;
// PhotonNetwork.room.IsVisible = false;
}
public override void OnPhotonPlayerDisconnected(PhotonPlayer otherPlayer)
{
PhotonPlayer leftPlayer = Array.Find(PhotonNetwork.playerList, p => p.ID == (otherPlayer.ID));
PrintLog("PhotonManager : OnPlayerLeftRoom leftPlayer is null? " + (leftPlayer == null).ToString() + " Length " + PhotonNetwork.playerList.Length + " otherPlayer.ID " + otherPlayer.ID);
if (leftPlayer == null)
{
ResetMultiplayerGame();
string onlineRandomGameMessage = "Opponent left the game.\nLooking for a new game";
string privateGameMessage = "Opponent left the game.";
string message = (Game.gameMode == GameModes.OnlineRandom) ? onlineRandomGameMessage : privateGameMessage;
PrintLog("OnPhotonPlayerDisconnected " + otherPlayer.NickName + " message " + message + " Game.gameMode " + Game.gameMode);
DialogBox.ShowLoadingScreen(message, false, false, true);
this.InvokeDelayed(() =>
{
WinzoManager.instance.onGameOver(GameManager.instance.localPlayer.id, false);
// PrintLog("Looking for new game");
//look for a new game if playing online random
//if (Game.gameMode == GameModes.OnlineRandom)
//{
// if (isInRoom)
// {
// LeaveGame(LookForNewOnlineRandomGame);
// }
// else
// LookForNewOnlineRandomGame();
//}
//else
//{
// DialogBox.HideLoadingScreen();
// GameManager.instance.PlayPlayerVsAI(false, false);
//}
}, 2f);
}
}
private void LookForNewOnlineRandomGame()
{
GameManager.instance.PlayOnlineRandomGame(false);
}
private void ResetMultiplayerGame()
{
GameManager.instance.ResetBoard();
LeaveRoom();
}
public override void OnPhotonRandomJoinFailed(object[] codeAndMsg)
{
//codeAndMsg codeAndMsg[0] is short ErrorCode. codeAndMsg[1] is string debug msg.
_wasInRoom = false;
PrintLog("OnPhotonRandomJoinFailed " + codeAndMsg[1].ToString() + " GameMode " + Game.gameMode);
//Create new room
CreateRoom(Game.gameMode + "_" + DateTime.Now.ToLongTimeString(), Game.MAXPLAYERS,
new Hashtable() { { "GameMode", Game.gameMode.ToString() } }, new string[] { "GameMode" }, true);
}
public override void OnPhotonMaxCccuReached()
{
PrintLog("OnPhotonMaxCccuReached");
}
public override void OnUpdatedFriendList()
{
PrintLog("OnUpdatedFriendList");
}
#endregion IPunCallbacks
private void CreateRoom(string roomName, byte maxPlayers, Hashtable roomProperties, string[] lobbyProperties, bool isVisible)
{
retryingGame = false;
if (PhotonNetwork.connectedAndReady)
{
RoomOptions roomOptions = new RoomOptions()
{
MaxPlayers = maxPlayers,
CustomRoomProperties = roomProperties,
CustomRoomPropertiesForLobby = lobbyProperties,
IsVisible = isVisible,
IsOpen = true,
PlayerTtl = 30000,
EmptyRoomTtl = 300
};
PhotonNetwork.CreateRoom(roomName, roomOptions, TypedLobby.Default);
}
else
{
PrintLog("Error : Not inside lobby. Join lobby before creating a room");
Connect((success) => { if (success) CreatePrivateRoom(); });
}
}
public void JoinRandomRoom()
{
//CreateOrJoinRoom("123", new string[] {"Dell", "aone" });
//return;
Game.rejoinedGameAfterDisconnection = false;
CancelInvoke("CheckIfAnyRandomPlayerFound");
PrintLog("JoinRandomRoom ");
retryingGame = false;
if (Game.isOnlineGame)
{
if (Game.isConnectedToInternet)
{
if (PhotonNetwork.connectedAndReady)
PhotonNetwork.JoinRandomRoom(new Hashtable() { { "GameMode", Game.gameMode.ToString() } }, Game.MAXPLAYERS);
else
{
PrintLog("Error : Not inside lobby. Join lobby before creating a room");
Connect((success) => { if (success) JoinRandomRoom(); });
}
}
//else
// ShowNoInternetDialog();
}
}
//public void JoinLobby(OnPUNConnected callback)
//{
// //PrintLog("Joining Lobby PhotonNetwork.connected ? " + PhotonNetwork.connected.ToString());
// //onRetryJoinRandomRoomEvent = callback;
// //if (PhotonNetwork.connected)
// // PhotonNetwork.JoinLobby();
// //else
// // Connect();
//}
public void CreatePrivateRoom()
{
if (PhotonNetwork.connectedAndReady)
{
_CreatePrivateRoom();
}
else
{
Connect((success) =>
{
if (success)
{
_CreatePrivateRoom();
}
});
}
}
void _CreatePrivateRoom()
{
Game.rejoinedGameAfterDisconnection = false;
CancelInvoke("CheckIfAnyRandomPlayerFound");
retryingGame = false;
string roomName = UnityEngine.Random.Range(1000, 9999).ToString();
//Create new room
CreateRoom(roomName, Game.MAXPLAYERS,
new Hashtable() { { "GameMode", Game.gameMode.ToString() } }, new string[] { "GameMode" }, false);
}
public void JoinPrivateRoom(string roomName)
{
Game.rejoinedGameAfterDisconnection = false;
CancelInvoke("CheckIfAnyRandomPlayerFound");
retryingGame = false;
if (PhotonNetwork.connectedAndReady)
PhotonNetwork.JoinRoom(roomName);
else
{
PrintLog("Error : Not inside lobby. Join lobby before creating a room");
Connect((success) => { if (success) JoinPrivateRoom(roomName); });
}
}
public void CreateOrJoinRoom(string roomName, string[] expectedPlayers)
{
_wasInRoom = false;
Game.rejoinedGameAfterDisconnection = false;
Debug.Log("CreateOrJoinRoom roomName " + roomName + " localPlayerID " + WinzoManager.instance.localPlayerID + " localPlayerName " + WinzoManager.instance.localPlayerName);
PhotonNetwork.player.UserId = WinzoManager.instance.localPlayerID;
PhotonNetwork.player.NickName = WinzoManager.instance.localPlayerName;
//for (int i = 0; i < expectedPlayers.Length; i++)
//{
// Debug.Log($"expected player {expectedPlayers[i]} local userID {PhotonNetwork.player.UserId}");
//}
if (PhotonNetwork.connectedAndReady)
{
RoomOptions roomOptions = new RoomOptions()
{
MaxPlayers = 4,
//IsVisible = true,
//IsOpen = true,
PlayerTtl = 30000,
EmptyRoomTtl = 30000,
PublishUserId = true
};
PhotonNetwork.JoinOrCreateRoom(roomName, roomOptions, TypedLobby.Default, expectedPlayers);
}
else
Connect((success) => { if (success) CreateOrJoinRoom(roomName, expectedPlayers); });
}
private void LeaveRoom()
{
PrintLog("leave Room");
manualDisconnection = true;
if (PhotonNetwork.inRoom)
PhotonNetwork.LeaveRoom();
}
public void DisconnectFromPhoton()
{
Debug.Log("DisconnectFromPhoton.......................");
manualDisconnection = true;
PhotonNetwork.Disconnect();
}
public void JoinRoom(string roomName)
{
if (PhotonNetwork.insideLobby)
PhotonNetwork.JoinRoom(roomName);
}
/// <summary>
/// You can send a private message to another photon player in this specific format ("Message|MessageTag")
/// </summary>
/// <param name="to"></param>
/// <param name="message"></param>
public void SendPrivateMessage(string message)
{
photonView.RPC("ChatMessage", PhotonTargets.All, message, PlayerProfile.winzoID);
}
/// <summary>
/// Send a friend request to playfab player who is online. Friend request is processed through Photon chat.
/// </summary>
/// <param name="playfabID"></param>
/// <param name="playerName"></param>
public void AddFriend(string playfabID, string playerName)
{
PrintLog("AddFriend " + playfabID);
if (Game.onGameNotificationEvent != null)
Game.onGameNotificationEvent("Sent friend request to " + playerName);
// SendPrivateMessage(playfabID, PlayerProfile.playerName + "|FRIENDREQUEST");
}
/// <summary>
/// Callback sent to all game objects before the application is quit.
/// </summary>
private void OnApplicationQuit()
{
if (PhotonNetwork.connected)
PhotonNetwork.networkingPeer.Disconnect();
}
private void OnApplicationPause(bool pause)
{
if (pause)
{
Debug.Log("goin to background BackgroundTimeout " + PhotonNetwork.BackgroundTimeout);
if (PhotonNetwork.connected)
UpdateCustomProperties(PLAYERWENTTOBG, true, localPlayer);
if (GameManager.instance.localPlayer != null)
{
PUNOnPlayerPause data = new PUNOnPlayerPause(true, GameManager.instance.localPlayer.id, DateTime.Now.GetUnixEpoch());
string json = JSONHelper.SerializeJSON(data);
RaiseEvent(PunEvents.ON_PLAYER_PAUSED, json, new RaiseEventOptions() { CachingOption = EventCaching.DoNotCache, Receivers = ReceiverGroup.Others });
PhotonNetwork.SendOutgoingCommands();
}
}
else
{
if (PhotonNetwork.connected)
{
UpdateCustomProperties(PLAYERWENTTOBG, false, localPlayer);
if (GameManager.instance.localPlayer != null)
{
PUNOnPlayerPause data = new PUNOnPlayerPause(false, GameManager.instance.localPlayer.id, DateTime.Now.GetUnixEpoch());
string json = JSONHelper.SerializeJSON(data);
RaiseEvent(PunEvents.ON_PLAYER_PAUSED, json, new RaiseEventOptions() { CachingOption = EventCaching.DoNotCache, Receivers = ReceiverGroup.Others });
PhotonNetwork.SendOutgoingCommands();
}
}
}
}
private void CheckIfAnyRandomPlayerFound()
{
Debug.Log("CheckIfAnyRandomPlayerFound " + PhotonNetwork.playerList.Length);
if (PhotonNetwork.playerList.Length < 2 && isInRoom && Game.gameMode == GameModes.OnlineRandom)
{
//if second player did not join the game in time
//create fake player and continue the game
PhotonNetwork.room.IsOpen = false;
PhotonNetwork.room.IsVisible = false;
//create fake player entity
// FakeProfile fp = PlayFabManager.instance.fakeProfiles[UnityEngine.Random.Range(0, PlayFabManager.instance.fakeProfiles.Count - 1)];
PlayerProfileCC fakePlayerProfile = new PlayerProfileCC("Opponent", "", "");
Player clinetPlayer = new Player(PlayerType.Opponent, ChipColor.Chip2, 1, true, fakePlayerProfile);
GameManager.instance.CreateOnlinePlayerEntity(clinetPlayer);
GameManager.instance.uiGameSceneController.PopulateOpponentProfile(fakePlayerProfile, ChipColor.Chip2);//chip 2 is player
GameManager.instance.uiGameSceneController.localPlayerChipImage.sprite = GameManager.instance.GetChip(ChipColor.Chip1);
GameManager.instance.uiGameSceneController.opponentChipImage.sprite = GameManager.instance.GetChip(ChipColor.Chip2);
StartTheOnlineGame();
}
}
#region RPC
[PunRPC]
private void ChatMessage(string message, string winzoID)
{
Debug.Log("ChatMessage " + message + " " + winzoID);
if (winzoID.Equals(PlayerProfile.winzoID))//if its local user then break
return;
GameManager.instance.uiGameSceneController.ShowChatBubble(message);
// Game.onMessageRecievedEvent?.Invoke(winzoID, message);
}
#endregion RPC
#region PUNEvents
public void RaiseEvent(byte eventCode, object content, RaiseEventOptions options)
{
if (Game.isOnlineGame)
{
//if (Game.isConnectedToInternet)
{
bool raised = PhotonNetwork.RaiseEvent(eventCode, content, true, options);
PrintLog("****RaiseEvent **** " + eventCode + " connected? " + Game.isConnectedToInternet + " content " + (content != null ? content.ToString() : "Null") + " sent? " + raised, false, new Color32(0, 128, 255, 1));
if (!raised)
punEventCache = new PunEventCache(eventCode, content, options);
}
//else
//{
// ShowNoInternetDialog();
//}
}
}
private void OnEvent(byte eventCode, object content, int senderId)
{
PrintLog("****OnEvent **** " + eventCode + " senderId " + senderId + " localPlayer.ID " + localPlayer.ID, false, new Color32(0, 51, 204, 1));
switch (eventCode)
{
case PunEvents.SENDPROFILETOMC:
{
string profilecc = (string)((Hashtable)content)["profile"];
PrintLog("****OnEvent **** SENDPROFILETOMC");
//MC recieved profile data from opponent
Debug.Log("SENDPROFILETOMC " + profilecc);
PlayerProfileCC clientProfile = PlayerProfile.ParseProfileCCJSON(profilecc);
Player clinetPlayer = new Player(PlayerType.Opponent, ChipColor.Chip2, 1, false, clientProfile);
GameManager.instance.CreateOnlinePlayerEntity(clinetPlayer);
GameManager.instance.uiGameSceneController.PopulateOpponentProfile(clientProfile, ChipColor.Chip2);//chip 2 is player
GameManager.instance.uiGameSceneController.localPlayerChipImage.sprite = GameManager.instance.GetChip(ChipColor.Chip1);
StartTheOnlineGame();
//Remove from cache
{
PrintLog("Clearing SENDPROFILETOMC");
RaiseEventOptions raiseOption = new RaiseEventOptions
{
CachingOption = EventCaching.RemoveFromRoomCache
};
PhotonNetwork.RaiseEvent(eventCode, (Hashtable)content, true, raiseOption);//content must be a hashtable
}
}
break;
case PunEvents.SENDPROFILETOCLIENT:
{
string profilecc = (string)((Hashtable)content)["profile"];
PrintLog("****OnEvent **** SENDPROFILETOCLIENT rejoinedGameAfterDisconnection " + Game.rejoinedGameAfterDisconnection);
//Client recieved profile data from MC. Create MC
// if (!Game.rejoinedGameAfterDisconnection)
{
Debug.Log("SENDPROFILETOCLIENT " + profilecc);
PlayerProfileCC mcProfile = PlayerProfile.ParseProfileCCJSON(profilecc);
Player mcPlayer = new Player(PlayerType.Opponent, ChipColor.Chip1, 0, false, mcProfile);
GameManager.instance.CreateOnlinePlayerEntity(mcPlayer);
GameManager.instance.uiGameSceneController.PopulateOpponentProfile(mcProfile, ChipColor.Chip1); //chip 1 is mc
GameManager.instance.uiGameSceneController.localPlayerChipImage.sprite = GameManager.instance.GetChip(ChipColor.Chip2);
}
Game.rejoinedGameAfterDisconnection = false;
//Remove from cache
{
PrintLog("Clearing SENDPROFILETOCLIENT");
RaiseEventOptions raiseOption = new RaiseEventOptions
{
CachingOption = EventCaching.RemoveFromRoomCache
};
PhotonNetwork.RaiseEvent(eventCode, (Hashtable)content, true, raiseOption);//content must be a hashtable
}
}
break;
case PunEvents.ONTAP:
{
PrintLog("****OnEvent **** ONTAP");
//Other player recieves the message. Just spawn the cell now
int cellIndex = (int)((Hashtable)content)["cellIndex"];
if (cellIndex >= 0 && senderId != localPlayer.ID)//spawn opponents chip on the board
GameManager.instance.fourInARow.SpawnOpponentChip(cellIndex);
//Remove from cache
{
PrintLog("Clearing ONTAP");
RaiseEventOptions raiseOption = new RaiseEventOptions
{
CachingOption = EventCaching.RemoveFromRoomCache
};
PhotonNetwork.RaiseEvent(eventCode, (Hashtable)content, true, raiseOption);//content must be a hashtable
}
}
break;
case PunEvents.CHANGETURNTO:
{
PrintLog("****OnEvent **** CHANGETURNTO");
OnChangeTurnTo(content);
//Remove from cache
{
PrintLog("Clearing CHANGETURNTO");
RaiseEventOptions raiseOption = new RaiseEventOptions
{
CachingOption = EventCaching.RemoveFromRoomCache
};
PhotonNetwork.RaiseEvent(eventCode, (Hashtable)content, true, raiseOption);//content must be a hashtable
}
}
break;
case PunEvents.GAMEOVER:
{
PrintLog("****OnEvent **** GAMEOVER");
OnPunGameOver(content, false);
//Remove from cache
{
PrintLog("Clearing GAMEOVER");
RaiseEventOptions raiseOption = new RaiseEventOptions
{
CachingOption = EventCaching.RemoveFromRoomCache
};
PhotonNetwork.RaiseEvent(eventCode, (Hashtable)content, true, raiseOption);//content must be a hashtable
}
}
break;
//case PunEvents.RESTARTGAME:
// {
// PrintLog($"****OnEvent **** RESTARTGAME");
// OnGameRestart(content);
// //Remove from cache
// {
// PrintLog($"Clearing RESTARTGAME");
// RaiseEventOptions raiseOption = new RaiseEventOptions
// {
// CachingOption = EventCaching.RemoveFromRoomCache
// };
// PhotonNetwork.RaiseEvent(eventCode, (Hashtable)content, true, raiseOption);//content must be a hashtable
// }
// }
// break;
case PunEvents.GAMESTART:
{
PrintLog("****OnEvent **** GAMESTART");
OnPunGameStart();
//Remove from cache
{
PrintLog("Clearing GAMESTART");
RaiseEventOptions raiseOption = new RaiseEventOptions
{
CachingOption = EventCaching.RemoveFromRoomCache
};
PhotonNetwork.RaiseEvent(eventCode, (Hashtable)content, true, raiseOption);//content must be a hashtable
}
}
break;
case PunEvents.ADDEDASFRIEND:
{
PrintLog("****OnEvent **** ADDEDASFRIEND");
string message = (string)content;
//other player recieves the message. Show a toast message
DialogBox.ShowToastMessage(message, 2f);
//GameManager.instance.uiGameSceneController.addFriendButton.gameObject.SetActive(false);
}
break;
case PunEvents.ON_PLAYER_PAUSED:
{
Debug.Log("ON_PLAYER_PAUSED content " + (string)content);
PUNOnPlayerPause data = JSONHelper.DeSerializeJSON<PUNOnPlayerPause>((string)content);
DateTime time = data.time.GetDateTimeFromUnixEpoch();
Debug.Log("ON_PLAYER_PAUSED isPaused " + data.isPaused + " playerID " + data.playerID + " time " + time);
if (data.isPaused)
{
Player player = GameManager.instance.FindPlayerWithID(data.playerID);
if (player != null)
Debug.Log("player isNull? " + player == null + " senderID " + senderId + " currentPlayer " + (GameManager.instance.currentPlayer.id).ToString() + " player " + (player.id).ToString());
if (player != null)
{
// if (player.isMyTurn || SkipBoGameManager.instance.currentPlayer.id == player.id)
{
if (senderId != this.localPlayer.ID)//dont do it if sent player is the local player
DialogBox.ShowToastMessage(player.playerProfile.playerName + " minimised", 5);
this.InvokeDelayed(() =>
{
PhotonPlayer punPlayer = Array.Find(PhotonNetwork.playerList, p => p.ID == senderId);
bool isPaused = false;
if (punPlayer != null)
isPaused = (bool)GetCustomProperties(PLAYERWENTTOBG, punPlayer);
if (isPaused)
{
//if he is still paused after 30 secs
if (player != null && (player.isMyTurn || GameManager.instance.currentPlayer.id == player.id))
{
if (senderId != this.localPlayer.ID)//dont do it if sent player is the local player
DialogBox.ShowToastMessage(player.playerProfile.playerName + " still minimised", 5);
}
}
}, 10);
}
}
}
else
{
DialogBox.HideLoadingScreen();
}
}
break;
//case PunEvents.ON_RECONNECTED_PLAYER_ASK_FOR_GAME_INSTANCE://when reconnected player asks any other active player for the latest instance
// {
// // Game.handlingDisconnectedPlayerSync = true;
// Debug.Log($"ON_RECONNECTED_PLAYER_ASK_FOR_GAME_INSTANCE");
// if (GameManager.instance?.localPlayer?.isMyTurn ?? false)
// DialogBox.ShowLoadingScreen($"Please wait");
// string gameJSON = string.Empty;
// if (!string.IsNullOrEmpty(gameJSON))
// RaiseEvent(PunEvents.ON_OPPONENT_SEND_LATEST_DATA, gameJSON, new RaiseEventOptions() { CachingOption = EventCaching.DoNotCache, TargetActors = new int[] { senderId } });
// else
// Debug.Log($"ON_RECONNECTED_PLAYER_ASK_FOR_GAME_INSTANCE game is null");
// }
// break;
//case PunEvents.ON_OPPONENT_SEND_LATEST_DATA://When other player sends the latest data to the reconnected player
// {
// }
// break;
default:
break;
}
}
#endregion PUNEvents
#region GameLogic
private void OnChangeTurnTo(object content)
{
//When MC changes the Turn. Everyone including MC gets this event
int currentPlayerIndex = (int)((Hashtable)content)["currentPlayerIndex"];
int cellIndex = (int)((Hashtable)content)["cellIndex"];
PrintLog("CHANGETURNTO currentPlayerIndex " + currentPlayerIndex + " cellIndex " + cellIndex);
// if (cellIndex >= 0 && senderId != localPlayer.ID)//spawn opponents chip on the board
// GameManager.instance.fourInARow.SpawnOpponentChip(cellIndex);
GameManager.instance.SetPlayersTurn(currentPlayerIndex, cellIndex);
}
private void OnPunGameOver(object content, bool isSender)//when sender calls this dont call the game over screen
{
// PhotonNetwork.BackgroundTimeout = 60;
//On Game over other player recieves this message and show game over message
int winner = (int)((Hashtable)content)["winner"];
bool isDraw = (bool)((Hashtable)content)["isDraw"];
if (!isSender)
GameManager.instance.onGameOver(winner, isDraw); //called for opponent
//if there is game restart else comment this and take em to main menu
//if (Game.isOnlineGame)
// this.InvokeDelayed(() => OnGameRestart((byte)winner), 2f);
LeaveRoom();
}
private void OnGameRestart(byte winner)
{
// byte winner = (byte)((Hashtable)content)["winner"];
//PhotonNetwork.BackgroundTimeout = 20;
GameManager.instance.RestartGame(winner);
}
private void OnPunGameStart()
{
GameManager.instance.ResetSkippedTurns();
// PhotonNetwork.BackgroundTimeout = 20;
//Both players recieve game start event
if (onGameStartEvent != null)
onGameStartEvent(Game.gameMode);
DialogBox.HideLoadingScreen();
//Masterclient set the turn and start the game
if (isMasterClient)
{
onTurnOver(-1, -1);
}
}
/// <summary>
/// After joining if local player is MC wait for the opponenet
/// </summary>
private void WaitForOpponent()
{
//create local player entity
Player localPlayer = new Player(PlayerType.LocalPlayer, ChipColor.Chip1, 0, false, PlayerProfile.GetProfileCC());
GameManager.instance.CreateOnlinePlayerEntity(localPlayer);
SendProfileToClient();
//Show waiting/searching for opponent message
}
/// <summary>
/// After joining if its not mc send player profile to MC
/// </summary>
private void SendProfileToMC()
{
PrintLog("SendProfileToMC");
//create local player entity for the client
Player localPlayer = new Player(PlayerType.LocalPlayer, ChipColor.Chip2, 1, false, PlayerProfile.GetProfileCC());
GameManager.instance.CreateOnlinePlayerEntity(localPlayer);
object content = new Hashtable() { { "profile", PlayerProfile.GetProfileCCJSON() } };
//send PlayerProfileCC to MC
RaiseEvent(PunEvents.SENDPROFILETOMC, content,
new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Receivers = ReceiverGroup.MasterClient });
}
/// <summary>
/// Send local player profile to client and cache it. when a player is connected he gets the message
/// </summary>
private void SendProfileToClient()
{
object content = new Hashtable() { { "profile", PlayerProfile.GetProfileCCJSON() } };
PrintLog("SendProfileToClient");
RaiseEvent(PunEvents.SENDPROFILETOCLIENT, content,
new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Receivers = ReceiverGroup.Others });
}
private void StartTheOnlineGame()
{
PrintLog("Both players joined. " + GameManager.instance.totalPlayers);
RaiseEvent(PunEvents.GAMESTART, null,
new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Receivers = ReceiverGroup.Others });
//for mc handle from here itself
OnPunGameStart();
}
public void onTurnOver(int turnIndex, int cellIndex)
{
if (Game.isOnlineGame)
{
if (Game.isConnectedToInternet && GameManager.instance.localPlayer.isMyTurn)
{
PrintLog("onTurn " + turnIndex + " totalPlayers " + GameManager.instance.totalPlayers);
if (GameManager.instance.currentPlayer != null)
GameManager.instance.currentPlayer.OnTurnOver();
int currentPlayerIndex = turnIndex;
currentPlayerIndex++;
if (currentPlayerIndex >= GameManager.instance.totalPlayers)
currentPlayerIndex = 0;
GameManager.instance.currentPlayerIndex = currentPlayerIndex;
object content = new Hashtable() { { "currentPlayerIndex", currentPlayerIndex }, { "cellIndex", cellIndex } };
RaiseEvent(PunEvents.CHANGETURNTO, content, new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Receivers = ReceiverGroup.Others });
//for localUser hanlde it from here itself
OnChangeTurnTo(content);
}
//else
//{
// ShowNoInternetDialog((ok, didCancel) => { });
//}
}
}
/// <summary>
/// On Valid tap start the animation on opponent Game as well
/// </summary>
public void OnTap(int turnIndex, int cellIndex)
{
RaiseEvent(PunEvents.ONTAP, new Hashtable() { { "turnIndex", turnIndex }, { "cellIndex", cellIndex } },
new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Receivers = ReceiverGroup.Others });
}
/// <summary>
/// Called when player did not play the turn in time
/// </summary>
public void SurrenderGame(int winner)
{
object content = new Hashtable() { { "winner", winner }, { "isDraw", false } };
RaiseEvent(PunEvents.GAMEOVER, content,
new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Receivers = ReceiverGroup.Others });
//for mc handle from here itself
OnPunGameOver(content, false);
}
private void onGameOver(int winner, bool isDraw)
{
object content = new Hashtable() { { "winner", winner }, { "isDraw", isDraw } };
RaiseEvent(PunEvents.GAMEOVER, content,
new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Receivers = ReceiverGroup.Others });
//for mc handle from here itself
OnPunGameOver(content, true);
}
//public void RestartGame()
//{
// if (isMasterClient && Game.isConnectedToInternet)
// {
// object content = new Hashtable() { { "winner", GameManager.instance.currentGameWinner } };
// RaiseEvent(PunEvents.RESTARTGAME, content,
// new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache, Receivers = ReceiverGroup.Others });
// //for mc handle from here itself
// OnGameRestart(content);
// }
//}
public void LeaveGame(OnLeaveGame callback)
{
//todo: send left room message to opponent and then disconnect
onLeaveGameEvent = callback;
manualDisconnection = true;
if (PhotonNetwork.inRoom)
{
LeaveRoom();
}
}
void ShowNoInternetDialog(Action<bool, bool> callback = null)
{
Debug.Log("ShowNoInternetDialog");
DialogBox.Show("Alert", "Check your Internet connection", "OK", (ok, didCancel) => { if (callback != null) callback(ok, didCancel); });
}
#endregion GameLogic
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment