557 lines
14 KiB
C#
557 lines
14 KiB
C#
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<RoomInfoData> activeRooms = new List<RoomInfoData>();
|
|
|
|
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<RoomInfoData> 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<FriendInfoData> CurrentRoomPlayers
|
|
{
|
|
get
|
|
{
|
|
List<FriendInfoData> list = new List<FriendInfoData>();
|
|
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<FriendInfoData> Friends
|
|
{
|
|
get
|
|
{
|
|
if (!SteamManager.Initialized)
|
|
{
|
|
return new List<FriendInfoData>();
|
|
}
|
|
List<FriendInfoData> list = new List<FriendInfoData>();
|
|
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<FriendInfo> 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<RoomInfoData> 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<SaveDataManager>.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<string> 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<FriendInfo>();
|
|
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<RoomInfo> 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<FriendInfo> 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<SceneLoader>.Instance == null && !RoomLocationEvacuation)
|
|
{
|
|
RoomLocationEvacuation = true;
|
|
StartCoroutine(EvacuateWithDelay(2f));
|
|
}
|
|
}
|
|
|
|
private void ShowMessagePopup(string msgText)
|
|
{
|
|
Canvas canvas = null;
|
|
MainGameScene mainGameScene = UnityEngine.Object.FindObjectOfType<MainGameScene>();
|
|
if (mainGameScene != null)
|
|
{
|
|
canvas = mainGameScene.GetComponent<Canvas>();
|
|
}
|
|
if (canvas == null)
|
|
{
|
|
canvas = UnityEngine.Object.FindObjectOfType<Canvas>();
|
|
}
|
|
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<SceneLoader>.Instance == null)
|
|
{
|
|
GameManager.Instance.UnloadAddectiveScene();
|
|
GameManager.Instance.LoadScene("Startowa", goToMenu: true);
|
|
}
|
|
}
|
|
}
|