using System; using System.Collections; using System.Collections.Generic; using System.Linq; using ExitGames.Client.Photon; using Photon.Pun; using Photon.Realtime; using Steamworks; using UnityEngine; using _Data.Variabales.DayWeather; public class MultiplayerManager : MonoBehaviourPunCallbacks { public enum State { Disconnected = 0, Connecting = 1, InLobby = 2, JoiningRoom = 3, InRoom = 4, EnteringRoomLocation = 5, InRoomLocation = 6 } public struct RoomInfoData { public string name; public int playerCount; public int maxPlayers; public int locationIndex; public int preferredLanguageIndex; public int time; public int weather; public RoomInfoData(string name, int playerCount, int maxPlayers, int locationIndex, int preferredLanguageIndex, int time, int weather) { this.name = name; this.playerCount = playerCount; this.maxPlayers = maxPlayers; this.locationIndex = locationIndex; this.preferredLanguageIndex = preferredLanguageIndex; this.time = time; this.weather = weather; } } public struct FriendInfoData { public string name; public string userID; } public static class RoomPropertyKeys { public const string LocationIndex = "locIdx"; public const string PreferredLanguageIndex = "prefLangIdx"; public const string Time = "tm"; public const string Weather = "wt"; } public class ConnectionSteps { public string[] regionSteps; public int currentStep; public ConnectionSteps() { regionSteps = new string[5] { "eu", "eu", "eu", "", "" }; currentStep = -1; } public bool AllStepsComplete() { return currentStep >= regionSteps.Length - 1; } public string GetNextRegionStep() { currentStep++; currentStep = Mathf.Clamp(currentStep, 0, regionSteps.Length - 1); return regionSteps[currentStep]; } } public static MultiplayerManager Instance; private State currentState; private List activeRooms = new List(); private ConnectionSteps connectionSteps; [SerializeField] private ScriptableEnumWeatherType weather; [SerializeField] private ScriptableTimeDayVariable dayTime; public static bool InRoomLocationStatic { get { if (!(Instance == null)) { return Instance.InRoomLocation; } return false; } } public State CurrentState => currentState; public List ActiveRooms => activeRooms; public string CloudRegion => PhotonNetwork.CloudRegion; public string UserId => PhotonNetwork.LocalPlayer.UserId; public RoomInfoData? CurrentRoom { get { RoomInfoData? result = null; if (PhotonNetwork.InRoom) { object value; int locationIndex = (PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue("locIdx", out value) ? Convert.ToInt32(value) : 0); object value2; int preferredLanguageIndex = (PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue("prefLangIdx", out value2) ? Convert.ToInt32(value2) : (-1)); object value3; int time = (PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue("tm", out value3) ? Convert.ToInt32(value3) : 0); object value4; int num = (PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue("wt", out value4) ? Convert.ToInt32(value4) : 0); result = new RoomInfoData(PhotonNetwork.CurrentRoom.Name, PhotonNetwork.CurrentRoom.PlayerCount, PhotonNetwork.CurrentRoom.MaxPlayers, locationIndex, preferredLanguageIndex, time, num); } return result; } } private RoomInfoData CurrentRoomNonNullable { get { if (!CurrentRoom.HasValue) { return default(RoomInfoData); } return CurrentRoom.Value; } } public List CurrentRoomPlayers { get { List list = new List(); if (PhotonNetwork.InRoom) { Player[] playerList = PhotonNetwork.PlayerList; foreach (Player player in playerList) { list.Add(new FriendInfoData { name = player.NickName, userID = player.UserId }); } } return list; } } public bool ClientRoomIsolation => !PhotonNetwork.IsMessageQueueRunning; public bool CanGameBePaused => CurrentState != State.InRoomLocation; public bool InRoomLocation { get; private set; } public bool RoomLocationEvacuation { get; private set; } public List Friends { get { if (!SteamManager.Initialized) { return new List(); } List list = new List(); int friendCount = SteamFriends.GetFriendCount(EFriendFlags.k_EFriendFlagImmediate); for (int i = 0; i < friendCount; i++) { CSteamID friendByIndex = SteamFriends.GetFriendByIndex(i, EFriendFlags.k_EFriendFlagImmediate); string friendPersonaName = SteamFriends.GetFriendPersonaName(friendByIndex); list.Add(new FriendInfoData { name = friendPersonaName, userID = friendByIndex.ToString() }); } return list; } } public List FriendsInfo { get; private set; } public static event Action On_ConnectedToMaster; public static event Action On_Disconnected; public static event Action On_JoinedLobby; public static event Action On_JoinedRoom; public static event Action On_LeftRoom; public static event Action On_CreateRoomFailed; public static event Action On_JoinRoomFailed; public static event Action On_RoomListUpdate; public static event Action On_FriendsInfoUpdate; public static event Action On_EnterRoomLocation; public List ActiveRoomsFiltered(int locationIndex = -1, int preferredLanguageIndex = -1) { return ActiveRooms.Where(delegate(RoomInfoData element) { if (locationIndex != -1 && locationIndex != element.locationIndex) { return false; } return (preferredLanguageIndex == -1 || preferredLanguageIndex == element.preferredLanguageIndex) ? true : false; }).ToList(); } public void ToggleRoomSynchronization(bool toggle) { PhotonNetwork.IsMessageQueueRunning = toggle; } public void Connect() { if (currentState == State.Disconnected) { ToggleRoomSynchronization(toggle: true); if (SteamManager.Initialized) { connectionSteps = new ConnectionSteps(); PhotonNetwork.AuthValues = new AuthenticationValues(); PhotonNetwork.AuthValues.UserId = SteamUser.GetSteamID().ToString(); PhotonNetwork.PhotonServerSettings.AppSettings.FixedRegion = connectionSteps.GetNextRegionStep(); PhotonNetwork.NickName = Singleton.Instance.GetCurrentPlayerData().PlayerName; currentState = State.Connecting; PhotonNetwork.ConnectUsingSettings(); } } } public void Disconnect() { if (currentState != State.Disconnected) { ToggleRoomSynchronization(toggle: true); connectionSteps = null; PhotonNetwork.Disconnect(); } } public void JoinRoom(string roomName) { if (currentState == State.InLobby) { currentState = State.JoiningRoom; PhotonNetwork.JoinRoom(roomName); } } public void JoinOrCreateRoomTournament(TournamentManager.CTournament tournament) { if (currentState == State.InLobby) { RoomOptions roomOptions = new RoomOptions { MaxPlayers = Mathf.Min(tournament.participantMaximum, 20), IsVisible = false, PublishUserId = true, IsOpen = true }; currentState = State.JoiningRoom; PhotonNetwork.JoinOrCreateRoom($"0_t_{tournament.id}", roomOptions, TypedLobby.Default); } } public void CreateRoom(string name, int maxPlayers = 10, int locationIndex = 0, int preferredLanguageIndex = -1, int time = 0, int weather = 0, bool visibleInLobby = true, List expectedUsers = null) { if (currentState == State.InLobby) { RoomOptions roomOptions = new RoomOptions(); roomOptions.MaxPlayers = maxPlayers; roomOptions.IsVisible = visibleInLobby; roomOptions.PublishUserId = true; roomOptions.CustomRoomProperties = new ExitGames.Client.Photon.Hashtable { { "locIdx", locationIndex }, { "prefLangIdx", preferredLanguageIndex }, { "tm", time }, { "wt", weather } }; roomOptions.CustomRoomPropertiesForLobby = new string[4] { "locIdx", "prefLangIdx", "tm", "wt" }; string[] expectedUsers2 = null; if (expectedUsers != null && expectedUsers.Count > 0) { expectedUsers2 = expectedUsers.ToArray(); } currentState = State.JoiningRoom; PhotonNetwork.CreateRoom(name, roomOptions, null, expectedUsers2); } } public void LeaveRoom() { if (currentState == State.InRoom || CurrentState == State.InRoomLocation) { ToggleRoomSynchronization(toggle: true); PhotonNetwork.LeaveRoom(); } } public void EnterRoomLocation(bool isTournament = false) { if (currentState == State.InRoom && CurrentRoom.HasValue) { currentState = State.EnteringRoomLocation; if (!isTournament) { GameManager.Instance.currentSceneLoadedType = GameManager.SceneLoadedType.FreeFishing; dayTime.SetDayTime((TimeOfDay)CurrentRoom.Value.time); weather.SetWeather(CurrentRoom.Value.weather); GameManager.Instance.UnloadAddectiveScene(); GameManager.Instance.LoadScene(GameManager.Instance.gameLocations[CurrentRoom.Value.locationIndex].sceneName); } } } public void FindFriends(string[] userIDs) { if (currentState == State.InLobby) { FriendsInfo = new List(); PhotonNetwork.FindFriends(userIDs); } } public override void OnConnectedToMaster() { connectionSteps = null; PhotonNetwork.JoinLobby(); MultiplayerManager.On_ConnectedToMaster?.Invoke(); } public override void OnDisconnected(DisconnectCause cause) { if (connectionSteps != null && !connectionSteps.AllStepsComplete() && SteamManager.Initialized) { PhotonNetwork.AuthValues = new AuthenticationValues(); PhotonNetwork.AuthValues.UserId = SteamUser.GetSteamID().ToString(); PhotonNetwork.PhotonServerSettings.AppSettings.FixedRegion = connectionSteps.GetNextRegionStep(); currentState = State.Connecting; PhotonNetwork.ConnectUsingSettings(); } else { string key = "DISCONNECTED_FROM_SERVER"; ShowMessagePopup(LanguageManager.Instance.GetText(key)); currentState = State.Disconnected; MultiplayerManager.On_Disconnected?.Invoke(); } } public override void OnJoinedLobby() { currentState = State.InLobby; MultiplayerManager.On_JoinedLobby?.Invoke(); } public override void OnJoinedRoom() { ToggleRoomSynchronization(toggle: false); currentState = State.InRoom; MultiplayerManager.On_JoinedRoom?.Invoke(); } public override void OnLeftRoom() { ToggleRoomSynchronization(toggle: true); PhotonNetwork.JoinLobby(); currentState = State.InLobby; MultiplayerManager.On_LeftRoom?.Invoke(); } public override void OnCreateRoomFailed(short returnCode, string message) { ShowMessagePopup(LanguageManager.Instance.GetText("ROOM_CREATION_FAILED")); ToggleRoomSynchronization(toggle: true); PhotonNetwork.JoinLobby(); currentState = State.InLobby; MultiplayerManager.On_CreateRoomFailed?.Invoke(); } public override void OnJoinRoomFailed(short returnCode, string message) { ShowMessagePopup(LanguageManager.Instance.GetText("ROOM_JOIN_FAILED")); ToggleRoomSynchronization(toggle: true); PhotonNetwork.JoinLobby(); currentState = State.InLobby; MultiplayerManager.On_JoinRoomFailed?.Invoke(); } public override void OnRoomListUpdate(List roomList) { activeRooms.Clear(); foreach (RoomInfo room in roomList) { if (!room.RemovedFromList) { object value; int locationIndex = (room.CustomProperties.TryGetValue("locIdx", out value) ? Convert.ToInt32(value) : 0); object value2; int preferredLanguageIndex = (room.CustomProperties.TryGetValue("prefLangIdx", out value2) ? Convert.ToInt32(value2) : (-1)); object value3; int time = (room.CustomProperties.TryGetValue("tm", out value3) ? Convert.ToInt32(value3) : 0); object value4; int num = (room.CustomProperties.TryGetValue("wt", out value4) ? Convert.ToInt32(value4) : 0); activeRooms.Add(new RoomInfoData(room.Name, room.PlayerCount, room.MaxPlayers, locationIndex, preferredLanguageIndex, time, num)); } } MultiplayerManager.On_RoomListUpdate?.Invoke(); } public override void OnFriendListUpdate(List friendsInfo) { FriendsInfo = friendsInfo; MultiplayerManager.On_FriendsInfoUpdate?.Invoke(); } private void SceneLoader_OnBeginSceneLoad(string sceneLoadName) { if (currentState == State.InRoom || currentState == State.InRoomLocation) { LeaveRoom(); InRoomLocation = false; } else if (currentState == State.EnteringRoomLocation) { InRoomLocation = true; } else { InRoomLocation = false; } RoomLocationEvacuation = false; } private void SceneLoader_OnSceneLoaded(string sceneLoadName) { if (currentState != State.EnteringRoomLocation) { Disconnect(); return; } ToggleRoomSynchronization(toggle: true); currentState = State.InRoomLocation; MultiplayerManager.On_EnterRoomLocation?.Invoke(); } private void Awake() { if (Instance != null && Instance != this) { UnityEngine.Object.Destroy(base.gameObject); } else { Instance = this; UnityEngine.Object.DontDestroyOnLoad(base.gameObject); } PhotonNetwork.AutomaticallySyncScene = false; PhotonNetwork.KeepAliveInBackground = 90f; } public override void OnEnable() { base.OnEnable(); SceneLoader.OnBeginSceneLoad += SceneLoader_OnBeginSceneLoad; SceneLoader.OnSceneLoaded += SceneLoader_OnSceneLoaded; } public override void OnDisable() { base.OnDisable(); SceneLoader.OnBeginSceneLoad -= SceneLoader_OnBeginSceneLoad; SceneLoader.OnSceneLoaded -= SceneLoader_OnSceneLoaded; } private void Update() { if (InRoomLocation && !CurrentRoom.HasValue && Singleton.Instance == null && !RoomLocationEvacuation) { RoomLocationEvacuation = true; StartCoroutine(EvacuateWithDelay(2f)); } } private void ShowMessagePopup(string msgText) { Canvas canvas = null; MainGameScene mainGameScene = UnityEngine.Object.FindObjectOfType(); if (mainGameScene != null) { canvas = mainGameScene.GetComponent(); } if (canvas == null) { canvas = UnityEngine.Object.FindObjectOfType(); } if (!(canvas == null) && !(GameManager.Instance == null)) { GameManager.Instance.ShowMessagePopup(msgText, canvas.transform, deleteLast: true); } } private IEnumerator EvacuateWithDelay(float delayInSeconds) { ShowMessagePopup(LanguageManager.Instance.GetText("SERVER_CONNECTION_LOST_LEAVING_LOCATION")); yield return new WaitForSeconds(delayInSeconds); if (InRoomLocation && !CurrentRoom.HasValue && Singleton.Instance == null) { GameManager.Instance.UnloadAddectiveScene(); GameManager.Instance.LoadScene("Startowa", goToMenu: true); } } }