/// <summary> /// Function sets internal player data pack with param playerData /// This pack will be sent on next [NET_Update] call /// </summary> /// <param name="playerData"> /// Param (playerData) a [NET_DataPack] representing current players data /// </param> public void NET_SetData(NET_DataPack playerData) { if (this.playerID != 0) { playersGameData[playerID - 1] = playerData; } }
public void Disconnect(int playerID) { if (state == TCP_Connection_State.TCPC_Connected) { NET_Debug.InjectMessage("[NET_TCP_CN]", "[OK] Disconnected"); NET_Messages.NET_Message_Disconnect disconnectMessage = new NET_Messages.NET_Message_Disconnect(DateTime.Now); NET_DataPack pack = new NET_DataPack(); pack.SetData("PlayerID", playerID); disconnectMessage.SetData(pack.SerializeData()); lock (tcpOUT_MessageQueue) { tcpOUT_MessageQueue.Enqueue(disconnectMessage); } TCP_Sending(); this.state = TCP_Connection_State.TCPC_Disconnected; } }
/// <summary> /// Central network control. /// </summary> /// <param name="isHost">Sets the NET_Main to server or client mode</param> /// <param name="timeStep">Heartbeat of the server</param> /// <param name="name">Servername</param> /// <param name="log"></param> public NET_Main(bool isHost, float timeStep, string name, bool log) { this.name = name; this.timeStep = timeStep; this.isHost = isHost; if (isHost == true) { this.playerID = 1; } if (log == false) { NET_Debug.DeactivateLogging(); } playersGameData[0] = new NET_DataPack(); playersGameData[1] = new NET_DataPack(); playersGameData[2] = new NET_DataPack(); playersGameData[3] = new NET_DataPack(); }
//---------------------------------------------------------------------------------------------// //Private functions: //---------------------------------------------------------------------------------------------// private void NET_MainThread() { if (isHost == true) { while (state != NET_State.NET_Shutdown) { //Broadcast server infos NET_Messages.NET_Message_ServerBroadcast message = new NET_Messages.NET_Message_ServerBroadcast(DateTime.Now); NET_DataPack pack = new NET_DataPack(); pack.SetData("PlayerSlotsUsed", playerCount); pack.SetData("ServerIPAddress", localIP.ToString()); pack.SetData("GameState", gameState); pack.SetData("ServerName", name); message.SetData(pack.SerializeData()); udpSystem.UDP_EnqueueMessage(message); Thread.Sleep(200); } } }
private void NET_ProcessMessage(NET_Messages.IMessage message) { //---------------------------------------------------------------------------------------------// //Message handling: //---------------------------------------------------------------------------------------------// if (message != null) { //Host message handling if (isHost == true) { //Update message if (message as NET_Messages.NET_Message_Update != null) { object objectBuffer = 0; byte[] byteBuffer = new byte[1]; message.GetData(ref byteBuffer, ref objectBuffer, false); NET_DataPack pack = new NET_DataPack(byteBuffer); //Set update data to internal slots int messagePID = (int)pack.GetData("PlayerID"); playersGameData[messagePID - 1] = pack; } //Event call message else if (message as NET_Messages.NET_Message_EventCall != null) { object objectBuffer = 0; byte[] byteBuffer = new byte[1]; message.GetData(ref byteBuffer, ref objectBuffer, false); NET_DataPack pack = new NET_DataPack(byteBuffer); //Add event to list NET_EventCall call = new NET_EventCall(pack); eventCalls.Add(call); } //Disconnect message else if (message as NET_Messages.NET_Message_Disconnect != null) { object objectBuffer = 0; byte[] byteBuffer = new byte[1]; message.GetData(ref byteBuffer, ref objectBuffer, false); NET_DataPack pack = new NET_DataPack(byteBuffer); int messagePID = (int)pack.GetData("PlayerID"); tcpServer.TCP_Server_ClientDisconnected(messagePID); } } //Client message handling else { //Server broadcast if (message as NET_Messages.NET_Message_ServerBroadcast != null) { object objectBuffer = 0; byte[] byteBuffer = new byte[1]; message.GetData(ref byteBuffer, ref objectBuffer, false); NET_DataPack pack = new NET_DataPack(byteBuffer); string ipAddress = (string)pack.GetData("ServerIPAddress"); int playerC = (int)pack.GetData("PlayerSlotsUsed"); string serName = (string)pack.GetData("ServerName"); GAME_State state = (GAME_State)pack.GetData("GameState"); if (serverInfos.ContainsKey(ipAddress) == false) { NET_ServerInfo info = new NET_ServerInfo(ipAddress, playerC, gameState, serName); serverInfos.Add(ipAddress, info); } else { NET_ServerInfo info = serverInfos[ipAddress]; info.INFO_SetPlayerCount(playerC); info.INFO_SetState(gameState); serverInfos[ipAddress] = info; } //If server broadcast is from connected server --> set player count if (ipAddress == this.serverIP.ToString()) { this.playerCount = playerC; } } //Update message else if (message as NET_Messages.NET_Message_Update != null) { object objectBuffer = 0; byte[] byteBuffer = new byte[1]; message.GetData(ref byteBuffer, ref objectBuffer, false); NET_UberPack uberPack = new NET_UberPack(byteBuffer); //Unpack uber pack NET_DataPack packP1 = uberPack.GetPack(1); NET_DataPack packP2 = uberPack.GetPack(2); NET_DataPack packP3 = uberPack.GetPack(3); NET_DataPack packP4 = uberPack.GetPack(4); //Set update data to internal slots if (packP1 != null && playerID != 1) { playersGameData[0] = packP1; } if (packP2 != null && playerID != 2) { playersGameData[1] = packP2; } if (packP3 != null && playerID != 3) { playersGameData[2] = packP3; } if (packP4 != null && playerID != 4) { playersGameData[3] = packP4; } } //Event call message else if (message as NET_Messages.NET_Message_EventCall != null) { object objectBuffer = 0; byte[] byteBuffer = new byte[1]; message.GetData(ref byteBuffer, ref objectBuffer, false); NET_DataPack pack = new NET_DataPack(byteBuffer); NET_EventCall call = new NET_EventCall(pack); eventCalls.Add(call); } //Welcome message --> Set playerID for clients else if (message as NET_Messages.NET_Message_Welcome != null) { object objectBuffer = 0; byte[] byteBuffer = new byte[1]; message.GetData(ref byteBuffer, ref objectBuffer, false); NET_DataPack pack = new NET_DataPack(byteBuffer); this.playerID = (int)pack.GetData("YourPlayerID"); } //Disconnect message else if (message as NET_Messages.NET_Message_Disconnect != null) { object objectBuffer = 0; byte[] byteBuffer = new byte[1]; message.GetData(ref byteBuffer, ref objectBuffer, false); NET_DataPack pack = new NET_DataPack(byteBuffer); int messagePID = (int)pack.GetData("PlayerID"); if (messagePID == playerID) { tcpClient.TCP_Disconnected(); playerID = 0; } } } } }
/// <summary> /// Function to call on every update cycle /// </summary> public void NET_Update() { //Record current time thisTime = DateTime.Now; //Process all enqueued udp messages NET_Messages.IMessage[] udpMessages = udpSystem.UDP_DequeueMessages(); if (udpMessages != null) { foreach (NET_Messages.IMessage MS in udpMessages) { NET_ProcessMessage(MS); } } //Process all enqueued tcp messages if (isHost == true) { this.playerCount = tcpServer.TCP_Server_GetPlayerCount(); NET_Messages.IMessage[] playerSlot2Messages = tcpServer.TCP_DequeueMessages(2); if (playerSlot2Messages != null) { foreach (NET_Messages.IMessage MS in playerSlot2Messages) { NET_ProcessMessage(MS); } } NET_Messages.IMessage[] playerSlot3Messages = tcpServer.TCP_DequeueMessages(3); if (playerSlot3Messages != null) { foreach (NET_Messages.IMessage MS in playerSlot3Messages) { NET_ProcessMessage(MS); } } NET_Messages.IMessage[] playerSlot4Messages = tcpServer.TCP_DequeueMessages(4); if (playerSlot4Messages != null) { foreach (NET_Messages.IMessage MS in playerSlot4Messages) { NET_ProcessMessage(MS); } } } else { NET_Messages.IMessage[] playersMessages = tcpClient.TCP_DequeueMessages(); if (playersMessages != null) { foreach (NET_Messages.IMessage MS in playersMessages) { NET_ProcessMessage(MS); } } } //TimeStepping V1 float delta = thisTime.Subtract(lastTime).Milliseconds; if ((float)Math.Abs(delta) > timeStep) { this.lastTime = DateTime.Now; //Create update message V2 //Old system: //3 messages in / 12 messages out //New system: //3 messages in / 3 messages out if (playerID != 0 && playerCount > 1) { NET_Messages.NET_Message_Update update = new NET_Messages.NET_Message_Update(DateTime.Now); if (isHost == true) { NET_DataPack packP1 = null; NET_DataPack packP2 = null; NET_DataPack packP3 = null; NET_DataPack packP4 = null; if (playersGameData[0] != null) { packP1 = playersGameData[0]; packP1.SetData("PlayerID", 1); } if (playersGameData[1] != null) { packP2 = playersGameData[1]; packP2.SetData("PlayerID", 2); } if (playersGameData[2] != null) { packP3 = playersGameData[2]; packP3.SetData("PlayerID", 3); } if (playersGameData[3] != null) { packP4 = playersGameData[3]; packP4.SetData("PlayerID", 4); } //Create uber-pack containing packs from all players (System 1 to reduce message count by factor 3 --> but rise message size by 4) NET_UberPack uberPack = new NET_UberPack(packP1, packP2, packP3, packP4); update.SetData(uberPack.SerializePacks()); //Enqueue update message tcpServer.TCP_EnqueueMessage(update, 2); tcpServer.TCP_EnqueueMessage(update, 3); tcpServer.TCP_EnqueueMessage(update, 4); } else { if (playersGameData[playerID - 1] != null) { NET_DataPack pack = playersGameData[playerID - 1]; pack.SetData("PlayerID", playerID); update.SetData(pack.SerializeData()); tcpClient.TCP_EnqueueMessage(update); } } } } }
//---------------------------------------------------------------------------------------------// //Private functions: //---------------------------------------------------------------------------------------------// private void TCP_MainThread() { while (serverStatus != TCP_Status.TCP_Shutdown) { while (serverStatus == TCP_Status.TCP_Running) { //Connect to pending connections if (clientCount < 3) { int emptySlot = -1; if (connections[0] == null) { emptySlot = 0; } else if (connections[1] == null) { emptySlot = 1; } else if (connections[2] == null) { emptySlot = 2; } if (this.server.Pending() && blockNewClients == false) { //Build welcome message for new player NET_Messages.NET_Message_Welcome welcomeMessage = new NET_Messages.NET_Message_Welcome(DateTime.Now); NET_DataPack pack = new NET_DataPack(); pack.SetData("YourPlayerID", emptySlot + 2); welcomeMessage.SetData(pack.SerializeData()); //Build new connection to player TcpClient client = server.AcceptTcpClient(); connections[emptySlot] = new NET_TcpConnection(client); connections[emptySlot].Connected(); //Enqueue welcome message connections[emptySlot].TCP_EnqueueMessage(welcomeMessage); clientCount++; } } //Delete disconnected clients for (int x = 0; x < 3; x++) { if (connections[x] != null) { if (connections[x].GetState() == "TCPC_DeleteMe") { connections[x] = null; clientCount--; } } } Thread.Sleep(20); } //Delete disconnected clients for (int x = 0; x < 3; x++) { if (connections[x] != null) { if (connections[x].GetState() == "TCPC_DeleteMe") { connections[x] = null; clientCount--; } } } Thread.Sleep(10); } server.Stop(); //Game is closing! --> Exit thread }