diff --git "a/2-j\303\241t\303\251kablak_v\303\241zlat_magyar\303\241zattal.png" "b/2-j\303\241t\303\251kablak_v\303\241zlat_magyar\303\241zattal.png" new file mode 100644 index 0000000000000000000000000000000000000000..156f34505092693db67fac10143584c2f4ed3e66 Binary files /dev/null and "b/2-j\303\241t\303\251kablak_v\303\241zlat_magyar\303\241zattal.png" differ diff --git a/Thumbs.db b/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..72862da20a2918dc58f5ec8e52f1bd71044b8540 Binary files /dev/null and b/Thumbs.db differ diff --git a/Thumbs.db:encryptable b/Thumbs.db:encryptable new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git "a/csapatalak\303\255t\303\263_k\303\251perny\305\221.png" "b/csapatalak\303\255t\303\263_k\303\251perny\305\221.png" new file mode 100644 index 0000000000000000000000000000000000000000..4411e3e6b638f1ddcb55a48600c6910c16ae60d9 Binary files /dev/null and "b/csapatalak\303\255t\303\263_k\303\251perny\305\221.png" differ diff --git "a/ind\303\255t\303\263k\303\251perny\305\221.png" "b/ind\303\255t\303\263k\303\251perny\305\221.png" new file mode 100644 index 0000000000000000000000000000000000000000..d58bae3c58564d7572bf1ab340a76aa6e59d02f1 Binary files /dev/null and "b/ind\303\255t\303\263k\303\251perny\305\221.png" differ diff --git "a/j\303\241t\303\251k_v\303\251ge_ablak.png" "b/j\303\241t\303\251k_v\303\251ge_ablak.png" new file mode 100644 index 0000000000000000000000000000000000000000..acc24361d7f14fa22b32b4b3096edeb45436d3ff Binary files /dev/null and "b/j\303\241t\303\251k_v\303\251ge_ablak.png" differ diff --git "a/j\303\241t\303\251kablak_v\303\241zlat.png" "b/j\303\241t\303\251kablak_v\303\241zlat.png" new file mode 100644 index 0000000000000000000000000000000000000000..cef6777b2650463af021a60fb79471e14f83dd72 Binary files /dev/null and "b/j\303\241t\303\251kablak_v\303\241zlat.png" differ diff --git "a/j\303\241t\303\251kablak_v\303\241zlat_magyar\303\241zattal.png" "b/j\303\241t\303\251kablak_v\303\241zlat_magyar\303\241zattal.png" new file mode 100644 index 0000000000000000000000000000000000000000..47c67c816f65f67b7adaaeb8078b7cf4a32b0d36 Binary files /dev/null and "b/j\303\241t\303\251kablak_v\303\241zlat_magyar\303\241zattal.png" differ diff --git a/zsirozas.sln b/zsirozas.sln index 9a060ba945ac017d69ba18edb4e8e859d475f350..8c5153201f35217a0ce5acf1b6002c7dfe454fd4 100644 --- a/zsirozas.sln +++ b/zsirozas.sln @@ -15,4 +15,3 @@ Global {6D2F04D2-0452-4934-BBC3-D6BBE565CF28}.Release|x86.Build.0 = Release|x86 EndGlobalSection EndGlobal - diff --git a/zsirozas/Common.cs b/zsirozas/Common.cs new file mode 100644 index 0000000000000000000000000000000000000000..1174eeea8d4a8865730c01e9c38fa66ec8b91e51 --- /dev/null +++ b/zsirozas/Common.cs @@ -0,0 +1,65 @@ +using System; +using System.IO; +using System.Net; + +namespace zsirozas +{ + //egy generikus szerver API interfész. Emögött lehet a + //-- tényleges szerver (állapot-módosító műveletek, játékos-üzenetek küldése) + //-- "távoli szerver" SignalR hívásokra fordítás, ellenirányú üzenet-fogadás és továbbítás + interface IServerApiProvider + { + string CreateRoom(string userID); + void LeaveRoom(string userID); + void JoinRoom(string userID, string roomID); + //void InviteUser(string roomID, string userID); + + //string CreateUser(string nickname, IPAddress IP, int port); helyett + string CreateUser(string nickname, ConnectionType type, object backTalk); + void RemoveUser(string userID); + string NewGame(string roomID); + + void ParseNextMessage(Stream s, object param); + } + + //ahogy a szerver látja (és kezeli) a klienst + //ez NEM a kliens kifelé (UI felé) fordított inerfésze + //a SignalR nem tud visszatérési értéket, szerencsére itt nem is használok + interface IAppClient + { + void SimpleNotify(ServerEvent @event, object param0); + void InGameNotify(GameEvent @event, object param0); + /// <summary> + /// Deprecated! Only use while transitioning from old! + /// </summary> + /// <param name="s">a message that will be written to the network stream</param> + void SendMessage(string s); + } + + //2 féle csatlakozási módot kínálok + enum ConnectionType + { + RawTCP, SignalR + } + + //kapcsolat-felépítős rész + partial class User + { + //a szervert ne érdekelje, hogy milyen kapcsolatot használunk + public void ConnectClient(ConnectionType type, object backTalk) + { + connectionType = type; + switch (type) + { + case ConnectionType.SignalR: + //client = new AppClientWithSignalR((string)backTalk); + break; + case ConnectionType.RawTCP: + client = new AppClientWithTcp((IPEndPoint)backTalk); + break; + default: + throw new NotSupportedException("Connection type " + type + "is not supported"); + } + } + } +} \ No newline at end of file diff --git a/zsirozas/Game.cs b/zsirozas/Game.cs index 87789809603b25068591832d10072c0153235bc7..b4de704235e62fd10bd005720c81f882a574f062 100644 --- a/zsirozas/Game.cs +++ b/zsirozas/Game.cs @@ -8,7 +8,7 @@ namespace zsirozas class Game { public string gameID; - public Server gameServer; + public GameServer gameServer; public Dictionary<string, Player> playersByID; public string[] playersByOrder; public Round currentRound; @@ -48,11 +48,11 @@ namespace zsirozas } for (int i = 0; i < playersByOrder.Length; i++) { - gameServer.UsersByID[playersByOrder[i]].SendMessage(message); + gameServer.UsersByID[playersByOrder[i]].client.SendMessage(message); } } - public Game(Server _gameServer, IEnumerable<string> _playerIDs, string _gameID) + public Game(GameServer _gameServer, IEnumerable<string> _playerIDs, string _gameID) { //reference the server gameServer = _gameServer; @@ -238,33 +238,5 @@ namespace zsirozas }; } - public struct MidGameState - { - public CardValue[] cardsOnTable; - public int[] numofCardsInHands; - public int nextUp; - public int startingPlayer; - public int lastToHit; - public int remainsInDeck; - public override string ToString() - { - return new JavaScriptSerializer().Serialize(this); - } - public static MidGameState Parse(string s) - { - return new JavaScriptSerializer().Deserialize<MidGameState>(s); - } - //TODO: ezt a részt átdobni majd a játékszobás logikához - public string[] playersByOrder; - } - } - public class InvalidActionException : Exception - { - public InvalidActionException(string message) : base(message) { } - } - - public class GameOverException : Exception - { - public GameOverException(string message) : base(message) { } } } \ No newline at end of file diff --git a/zsirozas/GameClient.cs b/zsirozas/GameClient.cs index 4e0b23c1f23a616898833588543625b571d3ffaf..dafceaf73a1eb2cbed10e7f9fc0e0ca3e3fd68d9 100644 --- a/zsirozas/GameClient.cs +++ b/zsirozas/GameClient.cs @@ -242,7 +242,7 @@ namespace zsirozas switch (gameEvent) { case GameEvent.NewTurn: - gameState = new JavaScriptSerializer().Deserialize<Game.MidGameState>(sr.ReadLine()); + gameState = new JavaScriptSerializer().Deserialize<MidGameState>(sr.ReadLine()); //TODO: ezt majd valahol máshol nézegetni... playerIDX = Array.IndexOf<string>(gameState.playersByOrder, userID); @@ -251,7 +251,7 @@ namespace zsirozas SendRequest(ServerAction.GameAction, PlayerAction.GetCards + "\n0"); break; case GameEvent.CardAction: - gameState = new JavaScriptSerializer().Deserialize<Game.MidGameState>(sr.ReadLine()); + gameState = new JavaScriptSerializer().Deserialize<MidGameState>(sr.ReadLine()); gameStateCanged(this, gameEvent); break; case GameEvent.GameOver: @@ -313,7 +313,7 @@ namespace zsirozas return SendRequest(ServerAction.GameAction, PlayerAction.EndTurn + "\n0"); } - public Game.MidGameState gameState; + public MidGameState gameState; public event EventHandler<GameEvent> gameStateCanged; //névtelen típusra cast-oláshoz diff --git a/zsirozas/Server.cs b/zsirozas/GameServer.cs similarity index 88% rename from zsirozas/Server.cs rename to zsirozas/GameServer.cs index d075da43f9a815a99ad2485f6f12bd46176cf1c5..2d3a55780afd24f03a8b9debc8c83195e277698a 100644 --- a/zsirozas/Server.cs +++ b/zsirozas/GameServer.cs @@ -6,9 +6,12 @@ using System.Net.Sockets; namespace zsirozas { - class Server + class GameServer : IServerApiProvider { - public Server() + //TODO: megoldani, hogy legyen egy szép referenciája + public ServerWrapper wrapper; + + public GameServer() { Users = new List<string>(); Rooms = new List<string>(); @@ -128,7 +131,7 @@ namespace zsirozas line = sr.ReadLine(); try { - string ID = CreateUser(line, (IPAddress)param, int.Parse(sr.ReadLine())); + string ID = CreateUser(line, ConnectionType.RawTCP, new IPEndPoint((IPAddress)param, int.Parse(sr.ReadLine()))); sw.WriteLine("OK"); sw.WriteLine(ID); } @@ -187,7 +190,9 @@ namespace zsirozas private void Shutdown() { Console.WriteLine("Server shut down succesfully."); - System.Environment.Exit(0); + //TODO: leállási feladatok + wrapper.Exit(); + //System.Environment.Exit(0); } @@ -216,8 +221,9 @@ namespace zsirozas /// </summary> public bool bigRoom = true; - public string CreateUser(string nickname, IPAddress IP, int port) + public string CreateUser(string nickname, ConnectionType type, object backTalk) { + var U = new User(); //making sure the userID is unique @@ -228,11 +234,13 @@ namespace zsirozas UsersByID.Add(U.userID, U); Users.Add(U.userID); //estabilishing server-to-client link - U.msgConn = new TcpClient(); - U.msgConn.Connect(IP, port); - U.messageStreamW = new StreamWriter(U.msgConn.GetStream()); + U.ConnectClient(type, backTalk); - Console.WriteLine("[LOG] " + U.userID + " logged in"); + //U.msgConn = new TcpClient(); + //U.msgConn.Connect(IP, port); + //U.messageStreamW = new StreamWriter(U.msgConn.GetStream()); + + Console.WriteLine("[LOG] " + U.userID + " logged in via " + type + " ( " + backTalk.ToString()+" )"); if (bigRoom) { @@ -244,9 +252,7 @@ namespace zsirozas public void RemoveUser(string userID) { LeaveRoom(userID); - UsersByID[userID].SendMessage("Logout"); - UsersByID[userID].messageStreamW.Close(); - UsersByID[userID].msgConn.Close(); + UsersByID[userID].client.SimpleNotify(ServerEvent.Logout, null); UsersByID.Remove(userID); Users.Remove(userID); Console.WriteLine("[LOG] " + userID + " logged out"); @@ -300,23 +306,28 @@ namespace zsirozas enum ServerEvent { - GameEvent, Logout + GameEvent, Invitation, Logout, Notice, Ping } - class User + partial class User { public string nickname; public string userID; public string roomID; public bool occupied = false; - public TcpClient msgConn; - public StreamWriter messageStreamW; - public void SendMessage(string message) - { - messageStreamW.WriteLine(message); - messageStreamW.Flush(); - } + //public TcpClient msgConn; + //public StreamWriter messageStreamW; + //public void SendMessage(string message) + //{ + // messageStreamW.WriteLine(message); + // messageStreamW.Flush(); + //} + + //absztraháltuk a kapcsolat típusát + public IAppClient client; + //de diagnosztikai célból azért számon tarjuk + public ConnectionType connectionType { get; protected set; } } struct Room @@ -324,4 +335,5 @@ namespace zsirozas public string roomID; public List<string> userList; } + } diff --git a/zsirozas/Program.cs b/zsirozas/Program.cs index 3f7a3a20b0bd11067bf0f8fdc420068595338a08..8b8182d8caf138ff15590fd55170ecc7ccf6f086 100644 --- a/zsirozas/Program.cs +++ b/zsirozas/Program.cs @@ -21,7 +21,7 @@ namespace zsirozas //args = new string[]{ "--server" }; if (args.Contains("--server")) { - new Server().Loop(); + new ServerWrapper(new GameServer()).Run(); } else { diff --git a/zsirozas/RawTcpTransport.cs b/zsirozas/RawTcpTransport.cs new file mode 100644 index 0000000000000000000000000000000000000000..2d5dc60b56bd85be3b5bfaa5f885d7d7e3344ad9 --- /dev/null +++ b/zsirozas/RawTcpTransport.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.IO; +using System.Threading.Tasks; +using System.Net; + +namespace zsirozas +{ + //szerver oldalon kezelt + //objektum + class AppClientWithTcp : IAppClient + { + + public TcpClient msgConn; + public StreamWriter messageStreamW; + + + public void SendMessage(string message) + { + messageStreamW.WriteLine(message); + messageStreamW.Flush(); + } + + + public AppClientWithTcp(IPEndPoint backTalk) + { + msgConn = new TcpClient(); + msgConn.Connect(backTalk.Address, backTalk.Port); + messageStreamW = new StreamWriter(msgConn.GetStream()); + } + + public void InGameNotify(GameEvent @event, object param0) + { + //Ráírom a stream-re, ahogy a másikban is + throw new NotImplementedException(); + } + + public void SimpleNotify(ServerEvent @event, object param0) + { + //Ráírom a stream-re, ahogy a másikban is + + messageStreamW.Flush(); + if (@event == ServerEvent.Logout) + { + messageStreamW.Close(); + msgConn.Close(); + } + throw new NotImplementedException(); + } + } + +} \ No newline at end of file diff --git a/zsirozas/Round.cs b/zsirozas/Round.cs index fe2c279ebbe5e44b4508e5e4a1696675a44853b3..bf4c5960165bc15dbb259dcc4fc85609632ee9dd 100644 --- a/zsirozas/Round.cs +++ b/zsirozas/Round.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Web.Script.Serialization; namespace zsirozas { @@ -70,5 +71,33 @@ namespace zsirozas /// </summary> public bool[] givenUpThisRound; } + struct MidGameState + { + public CardValue[] cardsOnTable; + public int[] numofCardsInHands; + public int nextUp; + public int startingPlayer; + public int lastToHit; + public int remainsInDeck; + public override string ToString() + { + return new JavaScriptSerializer().Serialize(this); + } + public static MidGameState Parse(string s) + { + return new JavaScriptSerializer().Deserialize<MidGameState>(s); + } + //TODO: ezt a részt átdobni majd a játékszobás logikához + public string[] playersByOrder; + } + public class InvalidActionException : Exception + { + public InvalidActionException(string message) : base(message) { } + } + + public class GameOverException : Exception + { + public GameOverException(string message) : base(message) { } + } } diff --git a/zsirozas/ServerWrapper.cs b/zsirozas/ServerWrapper.cs new file mode 100644 index 0000000000000000000000000000000000000000..7fc7a1bca454ae2c453f97475378c761dca6a697 --- /dev/null +++ b/zsirozas/ServerWrapper.cs @@ -0,0 +1,107 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Threading; + +namespace zsirozas +{ + //a kommunikációs és vezérlési feladatot megvalósító környezet + //TODO: utánanézni, hogy SignalR-nél hogy megy a párhuzamosság + //TODO: biztosítani a szerver adatkonzisztenciáját + class ServerWrapper + { + //TODO: eleintézni hogy "szépen" megkapja a referenciát + public IServerApiProvider serverInstance; + + public ServerWrapper(IServerApiProvider _serverInstance) + { + this.serverInstance = _serverInstance; + } + + private Thread controlThread; + + public void Run(bool enableSignalR = false, bool enableTCP = true) + { + if (enableSignalR) + { + //startSignalR(); + } + if (enableTCP) + { + startTcpListener(); + } + Start(); + controlThread.Join(); + } + + public void Start() + { + controlThread = new Thread(loop_func); + controlThread.Start(); + } + + //ezzel lehet leállítani a szervert (pl szerver meghívhatja ezt, ha le akar állni) + public void Exit() + { + //stopSignalR(); + stopTcpListener(); + controlThread.Abort(); + } + + //private ezúttal indokolt + private void loop_func() + { + while (true) + { + //ha TCP-zek + if (requestQueue != null) + { + //listen for connections and invoke parseNextMessage + var clientRequest = requestQueue.AcceptTcpClient(); + serverInstance.ParseNextMessage(clientRequest.GetStream(), ((IPEndPoint)clientRequest.Client.RemoteEndPoint).Address); + clientRequest.Close(); + } + //ha bármi mást csinálok (SignalR, közvetlen API birizgálás, stb.) + else + { + Thread.Sleep(10000); + } + } + } + + //................................................................................................ + public void startTcpListener() + { + requestQueue = new TcpListener(tcp_listening_address, tcp_listening_port); + requestQueue.Start(); + } + + public void stopTcpListener() + { + requestQueue.Stop(); //.... + } + public IPAddress tcp_listening_address = IPAddress.Any; + public int tcp_listening_port = 6500; + + private TcpListener requestQueue; + ////............................................................................................... + //public void stopSignalR() + //{ + // if (webapp != null) + // { + // webapp.Dispose(); + // webapp = null; + // } + //} + //public void startSignalR() + //{ + + // webapp = WebApp.Start(signalr_server_url, Configuration); + // SignalRServerHub.appServer = serverInstance; + // GlobalHost.DependencyResolver.Register(typeof(SignalRServerHub), () => new SignalRServerHub(serverInstance)); + //} + //private IDisposable webapp; + //private string signalr_server_url = "http://localhost:9080"; + //private void Configuration(IAppBuilder app) { app.MapSignalR(); } + } +} \ No newline at end of file diff --git a/zsirozas/zsirozas.csproj b/zsirozas/zsirozas.csproj index 25472d75bfe661bf5fcf6fb3e490913dfd72d8fd..f934d83f5f1abf3f10c597137fc9b82ad9d09460 100644 --- a/zsirozas/zsirozas.csproj +++ b/zsirozas/zsirozas.csproj @@ -49,8 +49,11 @@ <Compile Include="Deck.cs" /> <Compile Include="Round.cs" /> <Compile Include="Game.cs" /> - <Compile Include="Server.cs" /> + <Compile Include="GameServer.cs" /> <Compile Include="GameClient.cs" /> + <Compile Include="ServerWrapper.cs" /> + <Compile Include="Common.cs" /> + <Compile Include="RawTcpTransport.cs" /> </ItemGroup> <ItemGroup> <None Include="app.config" />