using Grpc.Core; using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; using Utilities; public static class Client { private static Connection reference; public static void Connect(string name, string address = "127.0.0.1:50052") { reference = new Connection(name, address); } public static ref Connection GetConnection() { return ref reference; } public static void CloseConnection() { if (reference != null) { reference.Close(); reference = null; } } public class Connection // : MonoBehaviour { private ConnectionService.Connection.ConnectionClient connection; private Lobby.Lobby.LobbyClient lobby_client; private Game.Game.GameClient game_client; private Channel channel; private string connId; private uint? lobby = null; private string address; private Modifiable lobby_status = null; public Connection(string user, string address) { channel = new Channel(address, ChannelCredentials.Insecure); connection = new ConnectionService.Connection.ConnectionClient(channel); lobby_client = new Lobby.Lobby.LobbyClient(channel); game_client = new Game.Game.GameClient(channel); connId = connection.connect(new Common.Name { Name_ = user }).Id; this.address = address; } public string Name() { return connection.name(new Google.Protobuf.WellKnownTypes.Empty()).Name_; } public string GetServerAddress() { return address; } public void JoinLobby(string code) { lobby = Base32.FromString(code); connection.joinLobbyWithCode(new ConnectionService.LobbyCode { Code = (uint)lobby }, new Metadata { new Metadata.Entry("client_id", connId) }); } public string CreateLobby(bool isPublic) { lobby = connection.createLobby(new ConnectionService.LobbyConfig {Public = isPublic}, new Metadata { new Metadata.Entry("client_id", connId) }).Code; return Base32.ToString((uint)lobby); } public string GetLobby() { if (lobby != null) { return Base32.ToString((uint)lobby); } else { return null; } } public List GetUsersInSameLobby(){ AsyncServerStreamingCall stream = lobby_client.users(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }); List l = new List(); while (runSync(stream.ResponseStream.MoveNext())) { Common.Name g = stream.ResponseStream.Current; l.Add(g.Name_); // Debug.Log("Received " + feature.ToString()); } // Debug.Log(stream.ResponseStream.Current); return l; } public Lobby.LobbyStatus GetLobbyStatus(out bool hasChanged) { hasChanged = false; if (lobby != null) { if (lobby_status != null) { var hasNew = lobby_client.pollStatus( new Common.LastStatusTimestamp { Time = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(lobby_status.GetLastModfication()), Lobby = (uint)lobby, }, new Metadata { new Metadata.Entry("client_id", connId) } ).Value; Debug.Log("HasNewStatus: " + hasNew); if (hasNew) { lobby_status.Set(lobby_client.getStatus(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) })); hasChanged = true; } } else { Debug.Log("Getting status"); lobby_status = new Modifiable(lobby_client.getStatus(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) })); hasChanged = true; } return lobby_status.Get(); } else { return null; } } public List GetLobbyVotes(uint game) { bool _b = false; Google.Protobuf.Collections.RepeatedField votes = GetLobbyStatus(out _b).Votes; var gameVotes = new List(); foreach (Lobby.Vote vote in votes) { if (vote.Game == game) { gameVotes.Add(vote); } } return gameVotes; } public int GetLobbyVoteCount(uint game) { bool _b = false; Google.Protobuf.Collections.RepeatedField votes = GetLobbyStatus(out _b).Votes; var gameVotes = new List(); foreach (Lobby.Vote vote in votes) { if (vote.Game == game) { gameVotes.Add(vote); } } return gameVotes.Count; } public Lobby.Vote GetSelfVote(string player) { bool _b = false; Google.Protobuf.Collections.RepeatedField votes = GetLobbyStatus(out _b).Votes; foreach (Lobby.Vote vote in votes) { Debug.Log(vote); if (vote.Player == player) { return vote; } } return null; } public void Vote(uint game) { lobby_client.vote(new Lobby.SingleVote() { Game = game }, new Metadata { new Metadata.Entry("client_id", connId) }); } public void SetReady() { lobby_client.ready(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }); } public void LeaveLobby() { lobby_client.leave(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }); lobby = null; } public List GetPublicLobbies() { AsyncServerStreamingCall stream = connection.getPublicLobbies(new Google.Protobuf.WellKnownTypes.Empty()); List l = new List(); while (runSync(stream.ResponseStream.MoveNext())) { ConnectionService.LobbyCode g = stream.ResponseStream.Current; l.Add(Base32.ToString(g.Code)); // Debug.Log("Received " + feature.ToString()); } // Debug.Log(stream.ResponseStream.Current); return l; } public Game.Image GetCardImage(string cardKind) { return game_client.getCardImage(new Game.CardKind() { Kind = cardKind }, new Metadata { new Metadata.Entry("client_id", connId) }); } public ICollection GetCards(string user) { var status = game_client.status(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }); return status.PlayerPiles[status.Names.IndexOf(new Common.Name() { Name_ = user })].Piles_.Values; } public Dictionary> GetPiles(string user) { var status = game_client.status(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }); var piles = new Dictionary>(); var playerPilesMap = status.PlayerPiles[status.Names.IndexOf(new Common.Name() { Name_ = user })].Piles_; var playerPiles = new Dictionary(); foreach(string key in playerPilesMap.Keys) { playerPiles.Add(key, playerPilesMap[key]); } var commonPilesMap = status.CommonPiles.Piles_; var commonPiles = new Dictionary(); foreach (string key in commonPilesMap.Keys) { commonPiles.Add(key, commonPilesMap[key]); } piles.Add("Owned", playerPiles); piles.Add("Common", commonPiles); return piles; } public int GetUserIndex(string user) { var status = game_client.status(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }); return status.Names.IndexOf(new Common.Name { Name_ = user }); } public Dictionary> OnClickCard(string pileName, bool isCommonPile, int cardIdx, string user) { Game.PileKind pileKind = new Game.PileKind() { Owned = (uint)GetUserIndex(user) }; game_client.onClick(new Game.CardId { PileKind = pileKind, CardIndex = new Game.CardIndex { Index = (uint)cardIdx }, PileName = pileName }, new Metadata { new Metadata.Entry("client_id", connId) }); return GetPiles(user); } public List GetGames() { AsyncServerStreamingCall stream = connection.getGames(new Google.Protobuf.WellKnownTypes.Empty()); List l = new List(); while (runSync(stream.ResponseStream.MoveNext())) { ConnectionService.Game g = stream.ResponseStream.Current; l.Add(g); // Debug.Log("Received " + feature.ToString()); } // Debug.Log(stream.ResponseStream.Current); return l; } static T runSync(Task task) { task.Wait(); return task.Result; } public void Close() { connection.disconnect(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }); channel.ShutdownAsync().Wait(); } } }