public void LoginRequest(Connection connection, string name, string password, string version, byte[] skinHash)
            {
                Console.WriteLine("< LoginRequest: {0} - {1} ({2})", name, version, skinHash.GetHexaString());

                byte[] nameData = Encoding.ASCII.GetBytes(name);
                byte[] passwordData = Encoding.ASCII.GetBytes(password);
                byte[] versionData = Encoding.ASCII.GetBytes(version);
                byte[] data = Connection.PrepareByteArray(MessageCodes.Login, nameData.Length + passwordData.Length + versionData.Length + 19);

                int offset = 5;

                data[offset] = (byte)nameData.Length;
                offset++;
                nameData.CopyTo(data, offset);
                offset += nameData.Length;

                data[offset] = (byte)passwordData.Length;
                offset++;
                passwordData.CopyTo(data, offset);
                offset += passwordData.Length;

                data[offset] = (byte)versionData.Length;
                offset++;
                versionData.CopyTo(data, offset);
                offset += versionData.Length;

                skinHash.CopyTo(data, offset);

                connection.SendMessage(ref data, NetworkChannels.ConnectingDisconnectingChannel);
            }
            public void DisconnectingNotification(Connection connection)
            {
                Console.WriteLine("< DisconnectingNotification");

                byte[] data = Connection.PrepareByteArray(MessageCodes.Disconnecting, 0);

                connection.SendMessage(ref data, NetworkChannels.ConnectingDisconnectingChannel);
            }
예제 #3
0
        internal void SetPlayer(long remoteId, Player player)
        {
            Connection connection = _RemoteIdConnections[remoteId];

            connection.Player = player;

            _EntityIdConnections[player.ID] = connection;
        }
예제 #4
0
        public void CheckFileExistRequest(Connection connection, byte exchangeType, byte[] hash)
        {
            string hashString = hash.GetHexaString();

             Console.WriteLine("> CheckFileExistRequest: {0} ({1})", exchangeType, hashString);

             bool exists = FileDataExchangeUtils.CheckCache(ref exchangeType, ref hash);

             ServerManager.Instance.ServerToClientProvider.CheckFileExistResponse(connection, exchangeType, hash, exists);
        }
예제 #5
0
        public void ChatMessage(Connection connection, string message)
        {
            Console.WriteLine("> ChatMessage: {0} - {1}", connection.Player.ID, message);
             message = connection.Player.PlayerName + ": " + message;

             // resend to all other players
             ushort senderId = connection.Player.ID;
             foreach (Connection other in ServerManager.Instance.GetAuthenticatedPlayers(senderId))
             {
            ServerManager.Instance.ServerToClientProvider.ChatMessage(other, message);
             }
        }
예제 #6
0
        internal void Start(MessagingConfiguration messagingSettings, IPEndPoint remoteEndPoint)
        {
            NetworkComms.AppendGlobalIncomingPacketHandler <byte[]>(Connection.TcpByteMessageName, ReceivedMessageTcpBytes);
            NetworkComms.AppendGlobalIncomingPacketHandler <string>("Message", ReceivedMessageTcpString);
            ConnectionInfo connectionInfo = new ConnectionInfo(ClientWorldManager.Instance.Configuration.Network.IpAddress, ClientWorldManager.Instance.Configuration.Network.PortTcp);

            _ClientTcp = TCPConnection.GetConnection(connectionInfo, true);

            _Client.Start();
            _Connection = new Connection(messagingSettings, _Client.Connect(remoteEndPoint), MultiPlayerProvider.ServerToClientProvider.ProcessReceivedMessage);
            _Connection.TcpConnection = _ClientTcp;
        }
예제 #7
0
        public void AddFile(Connection connection, byte exchangeType, byte[] hash, byte[] data)
        {
            string hashString = hash.GetHexaString();

             Console.WriteLine("> AddFile: {0} ({1})", exchangeType, hashString);

             FileDataExchangeUtils.CacheFile(ref exchangeType, ref hash, ref data);

             // distribute to connected clients
             foreach (Connection other in ServerManager.Instance.GetAuthenticatedPlayers())
             {
            ServerManager.Instance.ServerToClientProvider.CheckFileExistRequest(other, exchangeType, hash);
             }
        }
예제 #8
0
        public void CheckFileExistResponse(Connection connection, byte exchangeType, byte[] hash, bool exists)
        {
            string hashString = hash.GetHexaString();

             Console.WriteLine("> CheckFileExistResponse: {0} - {1} ({2})", exchangeType, exists, hashString);

             if (exists)
             {
            return;
             }

             byte[] fileData = FileDataExchangeUtils.GetCachedFile(ref exchangeType, ref hash);
             FileDataExchangeUtils.SendAddFileMessage(connection, ref exchangeType, ref hash, ref fileData);
        }
예제 #9
0
        internal void RemoveConnection(long remoteId)
        {
            Connection toRemove = _RemoteIdConnections[remoteId];

            if (toRemove.TcpConnection != null)
            {
                _TcpConnections.Remove(toRemove.TcpConnection);
            }
            _RemoteIdConnections.Remove(remoteId);

            if (toRemove.Player != null)
            {
                _EntityIdConnections.Remove(toRemove.Player.ID);
            }
        }
            public void ChatMessage(Connection connection, string message)
            {
                if (message.Length > 255)
                {
                   message = message.Substring(0, 255);
                }

                Console.WriteLine("< ChatMessage: {0}", message);

                byte[] chatData = Encoding.ASCII.GetBytes(message);
                byte[] data = Connection.PrepareByteArray(MessageCodes.Chat, message.Length + 1);

                data[5] = (byte)chatData.Length;
                chatData.CopyTo(data, 6);

                connection.SendMessage(ref data, NetworkChannels.ChatChannel);
            }
예제 #11
0
        internal void SetPlayerConnection(Connection connection, Player player)
        {
            // check if there's a previous session active
            Connection previous = _Clients[player.ID];

            if (previous != null)
            {
                Console.WriteLine("Disconnecting previous active session for player: " + player.PlayerName);

                _ClientWaits[player.ID] = new ManualResetEvent(false);
                ServerToClientProvider.DisconnectingNotification(previous, "New player session has been started");
                _Clients.RemoveConnection(player.ID);
                previous.Disconnect("New player session has been started");
                _ClientWaits[player.ID].WaitOne();
            }

            _Clients.SetPlayer(connection, player);
        }
예제 #12
0
 public void PlayerMovingNotification(Connection connection, sbyte moveX, sbyte moveY, sbyte moveZ, float rotationLeft, float rotationUp)
 {
     throw new NotImplementedException();
 }
 public void DisconnectingNotification(Connection connection)
 {
     // empty
 }
예제 #14
0
        public void PlayerMovedNotification(Connection connection, Point3D location, float rotationLeft, float rotationUp)
        {
            //Console.WriteLine("> PlayerMovedNotification: Pos {0}, L {1:0.0}, U {2:0.0}", location, rotationLeft, rotationUp);

             connection.Player.SetLocation(location, rotationLeft, rotationUp, true, Environment.TickCount);

             foreach (Connection other in ServerManager.Instance.GetAuthenticatedPlayers(connection.Player.ID))
             {
            ServerManager.Instance.ServerToClientProvider.EntityMovedNotification(other, connection.Player.ID, location, rotationLeft, rotationUp, connection.Player.LastLocationUpdate);
             }
        }
예제 #15
0
        private void ReceivedMessage(object peer)
        {
            NetIncomingMessage message;

            while ((message = _Server.ReadMessage()) != null)
            {
                try
                {
                    // handle incoming message
                    switch (message.MessageType)
                    {
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.ErrorMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.VerboseDebugMessage:
                        Console.WriteLine(message.ReadString());
                        break;

                    case NetIncomingMessageType.StatusChanged:
                        NetConnectionStatus status = (NetConnectionStatus)message.ReadByte();
                        if (status == NetConnectionStatus.Connected)
                        {
                            _Clients.AddConnection(message.SenderConnection, _ClientToServer.ProcessReceivedMessage);
                            Console.WriteLine("New connection: " + message.SenderEndPoint.ToString());
                        }
                        else if (status == NetConnectionStatus.Disconnected)
                        {
                            Player disconnectingPlayer = _Clients.GetPlayer(message.SenderConnection);
                            _Clients.RemoveConnection(message.SenderConnection);
                            Console.WriteLine("Disconnected: " + message.SenderEndPoint.ToString());

                            if (disconnectingPlayer != null)
                            {
                                ServerWorldManager.Instance.UnloadPlayer(disconnectingPlayer);

                                if (_ClientWaits.ContainsKey(disconnectingPlayer.ID))
                                {
                                    _ClientWaits[disconnectingPlayer.ID].Set();
                                    _ClientWaits[disconnectingPlayer.ID].Close();
                                    _ClientWaits.Remove(disconnectingPlayer.ID);
                                }

                                // inform all other about disconnected player
                                foreach (Connection other in GetAuthenticatedPlayers(disconnectingPlayer.ID))
                                {
                                    ServerToClientProvider.EntityDeleteNotification(other, disconnectingPlayer.ID);
                                }
                            }
                        }
                        break;

                    case NetIncomingMessageType.Data:
                        if (message.LengthBytes < 3)
                        {
                            break;
                        }
                        Connection connection  = _Clients[message.SenderConnection.RemoteUniqueIdentifier];
                        byte       messageCode = message.ReadByte();
                        int        length      = BitConverter.ToInt32(message.ReadBytes(4), 0);
                        byte[]     data        = message.ReadBytes(length);

                        _ClientToServer.ProcessReceivedMessage(connection, ref messageCode, ref data);
                        break;

                    default:
                        //Output("Unhandled type: " + im.MessageType + " " + im.LengthBytes + " bytes");
                        break;
                    }
                }
                catch (Exception ex)
                {
                    ExceptionHandler.LogException(ex);
                }
            }
        }
 public void PlayerMovedNotification(Connection connection, Point3D location, float rotationLeft, float rotationUp)
 {
     // empty
 }
 public void CheckFileExistRequest(Connection connection, byte exchangeType, byte[] hash)
 {
     // empty
 }
예제 #18
0
 public void DisconnectingNotification(Connection connection)
 {
     Console.WriteLine("> DisconnectingNotification: {0} ", connection.Player.PlayerName);
 }
예제 #19
0
        public void ProcessReceivedMessage(Connection connection, ref byte messageCode, ref byte[] data)
        {
            switch (messageCode)
             {
            case MessageCodes.Chat:
               string chatMessage = Encoding.ASCII.GetString(data, 1, data[0]);
               ChatMessage(connection, chatMessage);
               break;
            case MessageCodes.Disconnecting:
               DisconnectingNotification(connection);
               break;
            case MessageCodes.FileDataExchangeAdd:
               byte addExchangeType = 0;
               byte[] addHash = null;
               byte[] addFileData = null;
               FileDataExchangeUtils.ParseAddFileMessage(ref data, out addExchangeType, out addHash, out addFileData);

               AddFile(connection, addExchangeType, addHash, addFileData);
               break;
            case MessageCodes.FileDataExchangeRequest:
               byte requestExchangeType = 0;
               byte[] requestHash = null;
               FileDataExchangeUtils.ParseCheckFileExistRequest(ref data, out requestExchangeType, out requestHash);

               CheckFileExistRequest(connection, requestExchangeType, requestHash);
               break;
            case MessageCodes.FileDataExchangeResponse:
               byte responseExchangeType = 0;
               byte[] responseHash = null;
               bool responseExists = false;
               FileDataExchangeUtils.ParseCheckFileExistResponse(ref data, out responseExchangeType, out responseHash, out responseExists);

               CheckFileExistResponse(connection, responseExchangeType, responseHash, responseExists);
               break;
            case MessageCodes.FileDataRequest:
               byte fileExchangeType = 0;
               byte[] fileHash = null;

               FileDataExchangeUtils.ParseFileRequest(ref data, out fileExchangeType, out fileHash);

               RequestFile(connection, fileExchangeType, fileHash);
               break;
            case MessageCodes.GeneralNo:
               break;
            case MessageCodes.GeneralYes:
               break;
            case MessageCodes.Login:
               int offset = 0;

               int nameLength = data[offset];
               offset++;
               string name = Encoding.ASCII.GetString(data, offset, nameLength);
               offset += nameLength;

               int passwordLength = data[offset];
               offset++;
               string password = Encoding.ASCII.GetString(data, offset, passwordLength);
               offset += passwordLength;

               int versionLength = data[offset];
               offset++;
               string version = Encoding.ASCII.GetString(data, offset, versionLength);
               offset += versionLength;

               byte[] skinHash = new byte[16];
               for (int i = 0; i < 16; i++)
               {
                  skinHash[i] = data[offset + i];
               }

               LoginRequest(connection, name, password, version, skinHash);
               break;
            case MessageCodes.Moved:
               Point3D movedLocation = new Point3D();
               movedLocation.InitializeFromByteArray(ref data, 0);
               float rotationLeft = BitConverter.ToSingle(data, Point3D.SerializedSize);
               float rotationUp = BitConverter.ToSingle(data, Point3D.SerializedSize + 4);

               PlayerMovedNotification(connection, movedLocation, rotationLeft, rotationUp);
               break;
            case MessageCodes.Moving:
               break;
            //case MessageCodes.MultipartCompressed:
            //   connection.ProcessMultipartMessage(ref data);
            //   break;
            case MessageCodes.PlaceOrRemoveCube:
               bool place = (data[0] > 0);
               Point3D placeLocation = new Point3D();
               placeLocation.InitializeFromByteArray(ref data, 1);
               float placeRotationLeft = BitConverter.ToSingle(data, Point3D.SerializedSize + 1);
               float placeRotationUp = BitConverter.ToSingle(data, Point3D.SerializedSize + 5);
               ushort placeMaterialId = BitConverter.ToUInt16(data, Point3D.SerializedSize + 9);

               PlaceOrRemoveCubeNotification(connection, place, placeLocation, placeRotationLeft, placeRotationUp, placeMaterialId);
               break;
            case MessageCodes.Terrain:
               int terrainMessageId = BitConverter.ToInt32(data, 0);
               Point3D terrainLocation = new Point3D();
               terrainLocation.InitializeFromByteArray(ref data, 4);
               float terrainRotationLeft = BitConverter.ToSingle(data, Point3D.SerializedSize + 4);
               float terrainRotationUp = BitConverter.ToSingle(data, Point3D.SerializedSize + 8);

               TerrainDataRequest(connection, terrainMessageId, terrainLocation, terrainRotationLeft, terrainRotationUp);
               break;
             }
        }
 public void CheckFileExistResponse(Connection connection, byte exchangeType, byte[] hash, bool exists)
 {
     // empty
 }
예제 #21
0
        /// <summary>
        /// Sends a file request.
        /// </summary>
        /// <param name="connection">Connection object</param>
        /// <param name="exchangeType">Exchange type</param>
        /// <param name="hash">Content checksum</param>
        public static void SendRequestFile(Connection connection, ref byte exchangeType, ref byte[] hash)
        {
            string hashString = hash.GetHexaString();

             Console.WriteLine("< RequestFile: {0} ({1})", exchangeType, hashString);

             byte[] data = Connection.PrepareByteArray(MessageCodes.FileDataRequest, 18);

             data[5] = exchangeType;
             hash.CopyTo(data, 6);

             connection.SendMessage(ref data, NetworkChannels.FileDataExchangeChannel);
        }
예제 #22
0
        internal void Start(MessagingConfiguration messagingSettings, IPEndPoint remoteEndPoint)
        {
            NetworkComms.AppendGlobalIncomingPacketHandler<byte[]>(Connection.TcpByteMessageName, ReceivedMessageTcpBytes);
             NetworkComms.AppendGlobalIncomingPacketHandler<string>("Message", ReceivedMessageTcpString);
             ConnectionInfo connectionInfo = new ConnectionInfo(ClientWorldManager.Instance.Configuration.Network.IpAddress, ClientWorldManager.Instance.Configuration.Network.PortTcp);
             _ClientTcp = TCPConnection.GetConnection(connectionInfo, true);

             _Client.Start();
             _Connection = new Connection(messagingSettings, _Client.Connect(remoteEndPoint), MultiPlayerProvider.ServerToClientProvider.ProcessReceivedMessage);
             _Connection.TcpConnection = _ClientTcp;
        }
예제 #23
0
        /// <summary>
        /// Sends a response to check request.
        /// </summary>
        /// <param name="connection">Connection object</param>
        /// <param name="exchangeType">Exchange type</param>
        /// <param name="hash">Content checksum</param>
        /// <param name="exists">True if exists</param>
        public static void SendCheckFileExistResponse(Connection connection, ref byte exchangeType, ref byte[] hash, ref bool exists)
        {
            string hashString = hash.GetHexaString();

             Console.WriteLine("< CheckFileExistResponse: {0} - {1} ({2})", exchangeType, exists, hashString);

             byte[] data = Connection.PrepareByteArray(MessageCodes.FileDataExchangeResponse, 18);

             data[5] = exchangeType;
             hash.CopyTo(data, 6);
             data[22] = (byte)(exists ? 1 : 0);

             connection.SendMessage(ref data, NetworkChannels.FileDataExchangeChannel);
        }
예제 #24
0
        /// <summary>
        /// Sends an add file message to the other side.
        /// </summary>
        /// <param name="connection">Connection object</param>
        /// <param name="exchangeType">Exchange type</param>
        /// <param name="hash">Content checksum</param>
        /// <param name="fileData">File data</param>
        public static void SendAddFileMessage(Connection connection, ref byte exchangeType, ref byte[] hash, ref byte[] fileData)
        {
            string hashString = hash.GetHexaString();

             Console.WriteLine("< AddFile: {0} ({1})", exchangeType, hashString);

             byte[] data = Connection.PrepareByteArray(MessageCodes.FileDataExchangeAdd, fileData.Length + 21);

             data[5] = exchangeType;
             hash.CopyTo(data, 6);
             BitConverter.GetBytes(fileData.Length).CopyTo(data, 22);
             fileData.CopyTo(data, 26);

             connection.SendMessage(ref data, NetworkChannels.FileDataExchangeChannel);
        }
 public void TerrainDataRequest(Connection connection, int terrainMessageId, Point3D location, float rotationLeft, float rotationUp)
 {
     ClientWorldManager.Instance.LoadPlayerColumns(terrainMessageId);
 }
 public void RequestFile(Connection connection, byte exchangeType, byte[] hash)
 {
     // empty
 }
 public void PlayerMovingNotification(Connection connection, sbyte moveX, sbyte moveY, sbyte moveZ, float rotationLeft, float rotationUp)
 {
     // empty
 }
예제 #28
0
        public void RequestFile(Connection connection, byte exchangeType, byte[] hash)
        {
            string hashString = hash.GetHexaString();

             Console.WriteLine("> RequestFile: {0} ({1})", exchangeType, hashString);

             if (FileDataExchangeUtils.CheckCache(ref exchangeType, ref hash))
             {
            byte[] fileData = FileDataExchangeUtils.GetCachedFile(ref exchangeType, ref hash);
            FileDataExchangeUtils.SendAddFileMessage(connection, ref exchangeType, ref hash, ref fileData);
             }
        }
 public void LoginRequest(Connection connection, string name, string password, string version, byte[] skinHash)
 {
     // empty
 }
예제 #30
0
        public void TerrainDataRequest(Connection connection, int terrainMessageId, Point3D location, float rotationLeft, float rotationUp)
        {
            Console.WriteLine("> TerrainDataRequest: {0}", terrainMessageId);

             PlayerMovedNotification(connection, location, rotationLeft, rotationUp);

             ServerWorldManager.Instance.LoadClientColumns(terrainMessageId, connection.Player);
        }
예제 #31
0
 internal void SetPlayer(Connection connection, Player player)
 {
     SetPlayer(connection.NetConnection.RemoteUniqueIdentifier, player);
 }
 public void ChatMessage(Connection connection, string message)
 {
     // empty
 }
예제 #33
0
        internal void AddConnection(NetConnection connection, CompletedReceivedMultipartMessage callback)
        {
            Connection newConnection = new Connection(ServerWorldManager.Instance.Configuration.MessagingConfigurationNode, connection, callback);

            _RemoteIdConnections.Add(connection.RemoteUniqueIdentifier, newConnection);
        }
예제 #34
0
        public void LoginRequest(Connection connection, string name, string password, string version, byte[] skinHash)
        {
            Console.WriteLine("> LoginRequest: {0} - {1} ({2})", name, version, skinHash.GetHexaString());

             bool success = false;

             if (version != ServerWorldManager.Instance.Version)
             {
            // incorrect client version
            string message = "Login failed (incorrect client version: " + version + ", expected: " + ServerWorldManager.Instance.Version + ")";
            Console.WriteLine(message);
            ServerManager.Instance.ServerToClientProvider.LoginResponse(connection, LoginResults.VersionMismatch, 0, message);
             }
             else if (ServerWorldManager.Instance.Configuration.Security.BannedPlayers.Contains(name))
             {
            // banned player
            Console.WriteLine("Login failed (player banned)");
            ServerManager.Instance.ServerToClientProvider.LoginResponse(connection, LoginResults.Banned, 0, "Banned player");
             }
             else if (ServerWorldManager.Instance.Configuration.Security.BannedIpAddresses.Contains(connection.NetConnection.RemoteEndPoint.Address.ToString()))
             {
            // banned IP address
            Console.WriteLine("Login failed (IP address banned)");
            ServerManager.Instance.ServerToClientProvider.LoginResponse(connection, LoginResults.Banned, 0, "Banned IP address");
             }
             else if (ServerWorldManager.Instance.Configuration.Security.RequiresAuthentication)
             {
            // TODO: authenticate
            success = true;
             }
             else
             {
            success = true;
             }

             if (success)
             {
            Console.WriteLine("Login successful");

            // retrieve entity ID of the player
            ushort entityId = ServerWorldManager.Instance.GetPlayerId(name);

            // check player's skin existence in cache
            if (!SkinManager.IsSkinOnDisk(ref skinHash))
            {
               ServerManager.Instance.ServerToClientProvider.RequestFile(connection, FileDataExchangeTypes.Skin, skinHash);
            }

            // check if authenticated already
            Player newPlayer = (Player)ServerWorldManager.Instance.PrepareConnectedPlayer(entityId);
            newPlayer.SetSkinHash(skinHash);
            ServerManager.Instance.SetPlayerConnection(connection, newPlayer);
            ServerManager.Instance.ServerToClientProvider.LoginResponse(connection, LoginResults.Successful, entityId, "Login successful");

            // send all entities in the game to that player
            foreach (Entity entity in ServerWorldManager.Instance.Entities.Values)
            {
               if (entity.ID != entityId &&
                   !ServerWorldManager.Instance.IsPlayerConnected(entity as Player))
               {
                  continue;
               }
               ServerManager.Instance.ServerToClientProvider.EntityCreateOrUpdateNotification(connection, entity);
            }

            // send the newly logged in entity to all players
            foreach (Connection other in ServerManager.Instance.GetAuthenticatedPlayers(entityId))
            {
               ServerManager.Instance.ServerToClientProvider.EntityCreateOrUpdateNotification(other, newPlayer);
            }
             }

             // flush the send queue
             ServerManager.Instance.Flush();
        }
예제 #35
0
        internal void SetPlayerConnection(Connection connection, Player player)
        {
            // check if there's a previous session active
             Connection previous = _Clients[player.ID];
             if (previous != null)
             {
            Console.WriteLine("Disconnecting previous active session for player: " + player.PlayerName);

            _ClientWaits[player.ID] = new ManualResetEvent(false);
            ServerToClientProvider.DisconnectingNotification(previous, "New player session has been started");
            _Clients.RemoveConnection(player.ID);
            previous.Disconnect("New player session has been started");
            _ClientWaits[player.ID].WaitOne();
             }

             _Clients.SetPlayer(connection, player);
        }
예제 #36
0
        public void PlaceOrRemoveCubeNotification(Connection connection, bool place, Point3D location, float rotationLeft, float rotationUp, ushort materialId)
        {
            //Console.WriteLine("> PlaceOrRemoveCubeNotification");

             // adjust player's location and heading
             PlayerMovedNotification(connection, location, rotationLeft, rotationUp);

             // set material
             connection.Player.SelectedMaterial = materialId;

             int x = -1;
             int y = -1;
             int z = -1;
             uint version = 0;
             if (!connection.Player.PlaceOrRemoveBlock(place, out x, out y, out z, out version))
             {
            // ignore
            return;
             }

             // distribute info about changed terrain
             Segment segment = ServerWorldManager.Instance.GetSegmentBasedOnInsidePoint(x, y, z);
             foreach (Connection other in ServerManager.Instance.GetAuthenticatedPlayers())
             {
            if (ServerWorldManager.Instance.IsPlayersArea(other.Player, segment.Area.Key))
            {
               ServerManager.Instance.ServerToClientProvider.PlaceOrRemoveCubeNotification(other, place, segment, x, y, z, connection.Player.GetSelectedMaterial(), version);
            }
             }
        }
 public void PlaceOrRemoveCubeNotification(Connection connection, bool place, Point3D location, float rotationLeft, float rotationUp, ushort materialId)
 {
     ClientWorldManager.Instance.Player.PlaceOrRemoveBlock(place);
 }