Moved Controls to bottom of screen
[clanbomber-xamarin-client.git] / src / full_system / ConnectionTest / ConnectionTest / ConnectionTest / TcpJsonConnection.cs
1 ´╗┐using Newtonsoft.Json;
2 using System;
3 using System.Collections.Generic;
4 using System.Diagnostics;
5 using System.Linq;
6 using System.Net;
7 using System.Net.Sockets;
8 using System.Runtime.Serialization;
9 using System.Text;
10 using System.Threading;
11 using System.Threading.Tasks;
12
13 namespace Bomberman
14 {
15
16     public class TcpJsonConnection
17     {
18         private void Print(string msg)
19         {
20             //Console.WriteLine(msg);
21         }
22
23         protected const int c_serverPort = 11000;
24         protected Formatting c_JsonStyle = Formatting.None;
25
26         public delegate void UpdateFieldDelegate(ServerPackage pkg);
27         private UpdateFieldDelegate m_UpdateFieldDel;
28
29
30         public TcpJsonConnection(UpdateFieldDelegate UpdateField)
31         {
32             m_UpdateFieldDel = UpdateField;
33         }
34
35
36         Socket m_Connection;
37         Task m_receiveTask;
38         private CancellationTokenSource m_receiveTaskCancellationTokenSource;
39
40         private const int c_ConnectTimeout = 1200;
41
42         public void Connect(IPAddress ipAddress)
43         {
44
45             Print("Connecting to " + ipAddress);
46
47             IPEndPoint remoteEP = new IPEndPoint(ipAddress, c_serverPort);
48
49             m_Connection = new Socket(ipAddress.AddressFamily,
50                     SocketType.Stream, ProtocolType.Tcp);
51
52             m_Connection.ConnectAsync(remoteEP).Wait(c_ConnectTimeout);
53             if(!m_Connection.Connected)
54             {
55                 throw new TcpJsonException();
56             }
57
58             Print("-Connected.");
59
60             //Start Receive
61             m_receiveTaskCancellationTokenSource = new CancellationTokenSource();
62             m_receiveTask = new Task(new Action(ReceivePackage), m_receiveTaskCancellationTokenSource.Token);
63             m_receiveTask.Start();
64
65
66             //Say hello by sending initial state
67             SendClientPackage();
68
69         }
70
71         public void Close()
72         {
73             m_receiveTaskCancellationTokenSource.Cancel();
74
75             m_Connection.Shutdown(SocketShutdown.Both);
76             m_Connection.Close();
77             m_Connection = null;
78         }
79
80         ClientPackage m_clientSendPackage = new ClientPackage()
81         {
82             State = InputState.Idle,
83             Bomb = InputBomb.Idle,
84         };
85
86         public void SendEvent(InputState state)
87         {
88             m_clientSendPackage.State = state;
89             SendClientPackage();
90         }
91
92
93         public void SendEvent(InputBomb bomb)
94         {
95             m_clientSendPackage.Bomb = bomb;
96             SendClientPackage();
97         }
98
99         private void SendClientPackage()
100         {
101             string jsonClientPackage = JsonConvert.SerializeObject(m_clientSendPackage, c_JsonStyle);
102
103             SendClientPackage(jsonClientPackage);
104         }
105
106
107         private void ReceivePackage()
108         {
109             string restFromPreviousReception = "";
110
111             while (!m_receiveTaskCancellationTokenSource.Token.IsCancellationRequested)
112             {
113                 string[] recvPkgs = null;
114
115                 {
116                     // Incoming data from the client.  
117                     string data = null;
118                     byte[] bytes = new Byte[8192];
119                     while (!m_receiveTaskCancellationTokenSource.Token.IsCancellationRequested)
120                     {
121                         int bytesRec = m_Connection.Receive(bytes);
122                         data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
123                         if (data.Contains('\0'))
124                         {
125                             string msgWithRestFromPrecedingMsg = restFromPreviousReception + data;
126                             recvPkgs = msgWithRestFromPrecedingMsg.Split('\0');
127                             restFromPreviousReception = "";
128                             if (recvPkgs[recvPkgs.Length - 1] != "" + char.MinValue)
129                             {
130                                 restFromPreviousReception = recvPkgs[recvPkgs.Length - 1];
131                                 string[] recvPkgsWithoutIncomplete = new string[recvPkgs.Length - 1];
132                                 for (int i = 0; i < recvPkgs.Length - 1; i++)
133                                 {
134                                     recvPkgsWithoutIncomplete[i] = recvPkgs[i];
135                                 }
136                                 recvPkgs = recvPkgsWithoutIncomplete;
137                                 if (restFromPreviousReception != "")
138                                 {
139                                     Print("Incomplete MSG: " + restFromPreviousReception);
140                                 }
141                             }
142
143                             break;
144                         }
145                     }
146                 }
147
148
149                 // Show the data on the console and forward to handler
150                 string lastReceivedPackage = "";
151                 for (int i = 0; i < recvPkgs.Length; i++)
152                 {
153                     if (recvPkgs[i].Length > 0) // Filter '\0' strings..
154                     {
155                         Print("Text received : " + recvPkgs[i]);
156                         lastReceivedPackage = recvPkgs[i];
157                         //HandleServerPackage(recvPkgs[i]); // We would use this if we would handle every pkg
158                     }
159
160                 }
161                 HandleServerPackage(lastReceivedPackage);
162
163
164             }
165         }
166
167         private void HandleServerPackage(string v)
168         {
169             ServerPackage pkg;
170             try
171             {
172                 pkg = JsonConvert.DeserializeObject<ServerPackage>(v);
173                 m_UpdateFieldDel(pkg);
174             }
175             catch (JsonException e)
176             {
177                 Console.Error.WriteLine(e);
178             }
179         }
180
181         void SendClientPackage(string package)
182         {
183             Print("Sending: " + package);
184
185             byte[] buffer = Encoding.ASCII.GetBytes(package + char.MinValue);
186
187
188             SocketAsyncEventArgs e = new SocketAsyncEventArgs();
189             e.SetBuffer(buffer, 0, buffer.Length);
190             e.Completed += E_Completed;
191
192             m_Connection.SendAsync(e);
193
194         }
195
196         private void E_Completed(object sender, SocketAsyncEventArgs e)
197         {
198             Print("-Package sent successfully");
199         }
200
201
202
203
204         public enum InputState
205         {
206             Idle = 0,
207             Up = 1,
208             Down = 2,
209             Left = 3,
210             Right = 4,
211         }
212
213         public enum InputBomb
214         {
215             Idle = 0,
216             PlaceBomb = 1,
217         }
218
219
220         protected class ClientPackage
221         {
222             [JsonProperty("state")]
223             public InputState State { get; set; }
224
225
226             [JsonProperty("bomb")]
227             public InputBomb Bomb { get; set; }
228         }
229
230
231         public class ServerPackage
232         {
233             public ServerPackage()
234             {
235                 Field = new List<List<FieldTypes>>();
236                 Players = new List<Player>();
237                 Bombs = new List<Bomb>();
238                 Flames = new List<Flame>();
239             }
240
241             [JsonProperty("id")]
242             public int Id { get; set; }
243
244             [JsonProperty("state")]
245             public ServerState State { get; set; }
246             public enum ServerState
247             {
248                 PreGamePhase = 0,
249                 InGamePhase = 1,
250                 PostGamePhase = 2,
251             }
252
253             [JsonProperty("timeout")]
254             public double Timeout { get; set; }
255
256             [JsonProperty("field")]
257             public List<List<FieldTypes>> Field { get; set; }
258             public enum FieldTypes
259             {
260                 EmptyField = 0,
261                 StaticOrUndestroyableBlock = 1,
262                 DynamicOrDestroyableBlock = 2,
263                 ItemOrMoreBombs = 3,
264             }
265
266             [JsonProperty("players")]
267             public List<Player> Players { get; set; }
268             public class Player
269             {
270                 [JsonProperty("id")]
271                 public int Id { get; set; }
272
273                 [JsonProperty("x")]
274                 public double X { get; set; }
275
276                 [JsonProperty("y")]
277                 public double Y { get; set; }
278
279                 [JsonProperty("live")]
280                 public int Life { get; set; }
281             }
282
283             [JsonProperty("bombs")]
284             public List<Bomb> Bombs { get; set; }
285             public class Bomb
286             {
287                 [JsonProperty("id")]
288                 public int Id { get; set; }
289
290                 [JsonProperty("x")]
291                 public double X { get; set; }
292
293                 [JsonProperty("y")]
294                 public double Y { get; set; }
295
296                 [JsonProperty("timeout")]
297                 public double Timeout { get; set; }
298             }
299
300             [JsonProperty("flames")]
301             public List<Flame> Flames { get; set; }
302             public class Flame
303             {
304                 [JsonProperty("id")]
305                 public int Id { get; set; }
306
307                 [JsonProperty("x")]
308                 public double X { get; set; }
309
310                 [JsonProperty("y")]
311                 public double Y { get; set; }
312
313                 [JsonProperty("timeout")]
314                 public double Timeout { get; set; }
315             }
316         }
317
318     }
319
320     [Serializable]
321     internal class TcpJsonException : Exception
322     {
323         public TcpJsonException()
324         {
325         }
326
327         public TcpJsonException(string message) : base(message)
328         {
329         }
330
331         public TcpJsonException(string message, Exception innerException) : base(message, innerException)
332         {
333         }
334
335         protected TcpJsonException(SerializationInfo info, StreamingContext context) : base(info, context)
336         {
337         }
338     }
339 }