Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/MultiplayerManager.cs
2026-03-04 10:03:45 +08:00

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);
}
}
}