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