You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

361 lines
13 KiB

using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.Net.Sockets;
using UnityEngine;
using Utilities;
using System.Net;
using System;
using Empty = Google.Protobuf.WellKnownTypes.Empty;
public class Client : MonoBehaviour {
private static ConnectionImpl reference;
public static void Connect(string name, string address = "127.0.0.1:50052") {
reference = new ConnectionImpl(name, address);
}
public static ref ConnectionImpl GetConnection() {
return ref reference;
}
public static void CloseConnection() {
if (reference != null) {
reference.Close();
reference = null;
}
}
void Update() {
if (reference != null) {
reference.eventManager.Update();
}
}
public class NetEventManager {
private Dictionary<string, Action<Common.Name>> returnNameHandlers = new Dictionary<string, Action<Common.Name>>();
private Dictionary<string, Action<Connection.UserID>> returnConnectHandlers = new Dictionary<string, Action<Connection.UserID>>();
private Dictionary<string, Action<Connection.LobbyCode>> returnCreateLobbyHandlers = new Dictionary<string, Action<Connection.LobbyCode>>();
private Dictionary<string, Action<Protocol.Games>> returnGamesHandlers = new Dictionary<string, Action<Protocol.Games>>();
private Dictionary<string, Action<Protocol.LobbyCodes>> returnPublicLobbiesHandlers = new Dictionary<string, Action<Protocol.LobbyCodes>>();
public ConcurrentQueue<Protocol.ServerClientPacket> queue;
public void Update() {
Protocol.ServerClientPacket p = null;
while (queue.TryDequeue(out p)) {
Debug.Log("Message " + p.DataCase);
switch (p.DataCase) {
case Protocol.ServerClientPacket.DataOneofCase.ReturnName: {
var v = new Action<Common.Name>[this.returnNameHandlers.Count];
this.returnNameHandlers.Values.CopyTo(v, 0);
foreach (var n in v) {
n(p.ReturnName);
}
}
break;
case Protocol.ServerClientPacket.DataOneofCase.ReturnConnect: {
var v = new Action<Connection.UserID>[this.returnConnectHandlers.Count];
this.returnConnectHandlers.Values.CopyTo(v, 0);
foreach (var n in v) {
n(p.ReturnConnect);
}
}
break;
case Protocol.ServerClientPacket.DataOneofCase.ReturnCreateLobby: {
var v = new Action<Connection.LobbyCode>[this.returnCreateLobbyHandlers.Count];
this.returnCreateLobbyHandlers.Values.CopyTo(v, 0);
foreach (var n in v) {
n(p.ReturnCreateLobby);
}
}
break;
case Protocol.ServerClientPacket.DataOneofCase.ReturnGames: {
var v = new Action<Protocol.Games>[this.returnGamesHandlers.Count];
this.returnGamesHandlers.Values.CopyTo(v, 0);
foreach (var n in v) {
n(p.ReturnGames);
}
}
break;
case Protocol.ServerClientPacket.DataOneofCase.ReturnPublicLobbies: {
var v = new Action<Protocol.LobbyCodes>[this.returnPublicLobbiesHandlers.Count];
this.returnPublicLobbiesHandlers.Values.CopyTo(v, 0);
foreach (var n in v) {
n(p.ReturnPublicLobbies);
}
}
break;
default:
break;
}
}
}
public void AddHandler(string name, Action<Common.Name> handler) {
returnNameHandlers.Add(name, handler);
}
public void AddHandler(string name, Action<Connection.UserID> handler) {
returnConnectHandlers.Add(name, handler);
}
public void AddHandler(string name, Action<Connection.LobbyCode> handler) {
returnCreateLobbyHandlers.Add(name, handler);
}
public void AddHandler(string name, Action<Protocol.Games> handler) {
returnGamesHandlers.Add(name, handler);
}
public void AddHandler(string name, Action<Protocol.LobbyCodes> handler) {
returnPublicLobbiesHandlers.Add(name, handler);
}
public void RemoveHandler(Protocol.ServerClientPacket.DataOneofCase kind, string name) {
switch (kind) {
case Protocol.ServerClientPacket.DataOneofCase.ReturnName:
returnNameHandlers.Remove(name);
break;
case Protocol.ServerClientPacket.DataOneofCase.ReturnConnect:
returnConnectHandlers.Remove(name);
break;
case Protocol.ServerClientPacket.DataOneofCase.ReturnCreateLobby:
returnCreateLobbyHandlers.Remove(name);
break;
case Protocol.ServerClientPacket.DataOneofCase.ReturnGames:
returnGamesHandlers.Remove(name);
break;
case Protocol.ServerClientPacket.DataOneofCase.ReturnPublicLobbies:
returnPublicLobbiesHandlers.Remove(name);
break;
default:
break;
}
}
}
public class ConnectionImpl // : MonoBehaviour
{
public TcpConnection conn;
private string connId;
private uint? lobby = null;
private string address;
public NetEventManager eventManager;
private Modifiable<Lobby.LobbyStatus> lobby_status = null;
public ConnectionImpl(string user, string address) {
Debug.Log("Connecting with the tcp channel");
conn = new TcpConnection(address);
conn.SendMessage(new Protocol.ClientServerPacket() { Connect = new Common.Name { Name_ = user } });
Protocol.ServerClientPacket p = null;
Debug.Log("Waiting for response");
while (p == null) {
conn.q.TryDequeue(out p);
}
if (p.ReturnConnect == null) {
throw new Exception("Unexpected non ReturnConnect packet");
}
connId = p.ReturnConnect.Id;
this.address = address;
this.eventManager = new NetEventManager() { queue = conn.q };
}
public void QueryName() {
conn.SendMessage(new Protocol.ClientServerPacket() { QueryName = new Google.Protobuf.WellKnownTypes.Empty() });
// 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 void CreateLobby(bool isPublic) {
conn.SendMessage(new Protocol.ClientServerPacket() {CreateLobby = new Connection.LobbyConfig {Public = isPublic}});
// lobby = connection.createLobby(new ConnectionService.LobbyConfig {Public = isPublic}, new Metadata { new Metadata.Entry("client_id", connId) }).Code;
}
public string GetLobby() {
if (lobby != null) {
return Base32.ToString((uint)lobby);
} else {
return null;
}
}
public List<string> GetUsersInSameLobby() {
// AsyncServerStreamingCall<Common.Name> stream = lobby_client.users(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) });
List<string> l = new List<string>();
// 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.LobbyStatus>(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;
// }
return null;
}
public List<Lobby.Vote> GetLobbyVotes(uint game) {
bool _b = false;
Google.Protobuf.Collections.RepeatedField<Lobby.Vote> votes = GetLobbyStatus(out _b).Votes;
var gameVotes = new List<Lobby.Vote>();
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<Lobby.Vote> votes = GetLobbyStatus(out _b).Votes;
var gameVotes = new List<Lobby.Vote>();
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<Lobby.Vote> 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<string> GetPublicLobbies() {
// AsyncServerStreamingCall<ConnectionService.LobbyCode> stream = connection.getPublicLobbies(new Google.Protobuf.WellKnownTypes.Empty());
List<string> l = new List<string>();
// 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<Game.MessageStatus.Types.Pile> 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<string, Dictionary<string, Game.GameStatus.Types.Pile>> 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<string, Dictionary<string, Game.GameStatus.Types.Pile>>();
// var playerPilesMap = status.PlayerPiles[status.Names.IndexOf(new Common.Name() { Name_ = user })].Piles_;
// var playerPiles = new Dictionary<string, Game.MessageStatus.Types.Pile>();
// foreach(string key in playerPilesMap.Keys) {
// playerPiles.Add(key, playerPilesMap[key]);
// }
// var commonPilesMap = status.CommonPiles.Piles_;
// var commonPiles = new Dictionary<string, Game.MessageStatus.Types.Pile>();
// 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<string, Dictionary<string, Game.MessageStatus.Types.Pile>> 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<ConnectionService.Game> GetGames()
// {
// AsyncServerStreamingCall<ConnectionService.Game> stream = connection.getGames(new Google.Protobuf.WellKnownTypes.Empty());
// List<ConnectionService.Game> l = new List<ConnectionService.Game>();
// 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<T>(Task<T> 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();
}
}
}