using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Serialization;
namespace LobbyRelaySample
{
[Flags] // Some UI elements will want to specify multiple states in which to be active, so this is Flags.
public enum LobbyState
{
Lobby = 1,
CountDown = 2,
InGame = 4
}
public enum LobbyColor
{
None = 0,
Orange = 1,
Green = 2,
Blue = 3
}
///
/// A local wrapper around a lobby's remote data, with additional functionality for providing that data to UI elements and tracking local player objects.
/// (The way that the Lobby service handles its data doesn't necessarily match our needs, so we need to map from that to this LocalLobby for use in the sample code.)
///
[System.Serializable]
public class LocalLobby : Observed
{
public bool CanSetChanged = true;
public Action> onUserListChanged;
Dictionary m_LocalPlayers = new Dictionary();
public Dictionary LocalPlayers => m_LocalPlayers;
#region LocalLobbyData
ServerAddress m_RelayServer;
public LocalLobby()
{
LastUpdated.Value = DateTime.Now.ToFileTimeUtc();
LobbyID.onChanged = (s) => { SetValueChanged(); };
LobbyCode.onChanged = (s) => { SetValueChanged(); };
RelayCode.onChanged = (s) => { SetValueChanged(); };
RelayNGOCode.onChanged = (s) => { SetValueChanged(); };
RelayServer.onChanged = (s) => { SetValueChanged(); };
LobbyName.onChanged = (s) => { SetValueChanged(); };
LocalLobbyState.onChanged = (s) => { SetValueChanged(); };
Private.onChanged = (s) => { SetValueChanged(); };
AvailableSlots.onChanged = (s) => { SetValueChanged(); };
MaxPlayerCount.onChanged = (s) => { SetValueChanged(); };
LocalLobbyColor.onChanged = (s) => { SetValueChanged(); };
LastUpdated.onChanged = (s) => { SetValueChanged(); };
}
/// Used only for visual output of the Relay connection info. The obfuscated Relay server IP is obtained during allocation in the RelayUtpSetup.
#endregion
public CallbackValue LobbyID = new CallbackValue();
public CallbackValue LobbyCode = new CallbackValue();
public CallbackValue RelayCode = new CallbackValue();
public CallbackValue RelayNGOCode = new CallbackValue();
public CallbackValue RelayServer = new CallbackValue();
public CallbackValue LobbyName = new CallbackValue();
public CallbackValue LocalLobbyState = new CallbackValue();
public CallbackValue Private = new CallbackValue();
public CallbackValue AvailableSlots = new CallbackValue();
public CallbackValue MaxPlayerCount = new CallbackValue();
public CallbackValue LocalLobbyColor = new CallbackValue();
public CallbackValue LastUpdated = new CallbackValue();
public int PlayerCount => m_LocalPlayers.Count;
public void ResetLobby()
{
m_LocalPlayers.Clear();
LobbyName.Value = "";
LobbyID.Value = "";
LobbyCode.Value = "";
Private.Value = false;
LocalLobbyColor.Value = LobbyRelaySample.LobbyColor.None;
AvailableSlots.Value = 4;
MaxPlayerCount.Value = 4;
}
///
/// A locking mechanism for registering when something has looked at the Lobby to see if anything has changed
///
///
public bool IsLobbyChanged()
{
bool isChanged = m_ValuesChanged;
m_ValuesChanged = false;
return isChanged;
}
void SetValueChanged()
{
if(CanSetChanged)
m_ValuesChanged = true;
}
bool m_ValuesChanged;
public void AddPlayer(LocalPlayer user)
{
if (m_LocalPlayers.ContainsKey(user.ID.Value))
{
Debug.LogError($"Cant add player {user.DisplayName}({user.ID}) to lobby: {LobbyID} twice");
return;
}
Debug.Log($"Adding User: {user.DisplayName} - {user.ID}");
m_LocalPlayers.Add(user.ID.Value, user);
onUserListChanged?.Invoke(m_LocalPlayers);
}
public void RemovePlayer(LocalPlayer user)
{
DoRemoveUser(user);
onUserListChanged?.Invoke(m_LocalPlayers);
}
void DoRemoveUser(LocalPlayer user)
{
if (!m_LocalPlayers.ContainsKey(user.ID.Value))
{
Debug.LogWarning($"Player {user.DisplayName}({user.ID}) does not exist in lobby: {LobbyID}");
return;
}
m_LocalPlayers.Remove(user.ID.Value);
}
public override string ToString()
{
StringBuilder sb = new StringBuilder("Lobby : ");
sb.AppendLine(LobbyName.Value);
sb.Append("ID: ");
sb.AppendLine(LobbyID.Value);
sb.Append("Code: ");
sb.AppendLine(LobbyCode.Value);
sb.Append("Private: ");
sb.AppendLine(Private.Value.ToString());
sb.Append("AvailableSlots: ");
sb.AppendLine(AvailableSlots.Value.ToString());
sb.Append("Max Players: ");
sb.AppendLine(MaxPlayerCount.Value.ToString());
sb.Append("LocalLobbyState: ");
sb.AppendLine(LocalLobbyState.Value.ToString());
sb.Append("Lobby LocalLobbyState Last Edit: ");
sb.AppendLine(new DateTime(LastUpdated.Value).ToString());
sb.Append("LocalLobbyColor: ");
sb.AppendLine(LocalLobbyColor.Value.ToString());
sb.Append("RelayCode: ");
sb.AppendLine(RelayCode.Value);
sb.Append("RelayNGO: ");
sb.AppendLine(RelayNGOCode.Value);
return sb.ToString();
}
// This ends up being called from the lobby list when we get data about a lobby without having joined it yet.
public override void CopyObserved(LocalLobby oldObserved)
{
// CopyObserved(oldObserved.Data, oldObserved.m_LocalPlayers);
}
}
}