Пример #1
0
	protected bool Send( int connectionId, byte[] key, InternalMessage message, ChannelIndex channel, BitWriter writer, bool sendImmediately, out string error )
	{
		MessageSecurity security = AlpacaConstant.GetSecurity( channel );
		if( !WrapMessage( message, security, writer, key, out error ) )
		{
			return false;
		}

		//_profiler.StartEvent(TickType.Send, (uint)stream.Length, channelName, AlpacaConstant.INTERNAL_MESSAGE_NAME[messageType]);
		DataStream s = writer.GetStream();		
		byte errorAsByte;
		if( sendImmediately )
		{
			NetworkTransport.Send                  ( 0, connectionId, channel.GetIndex(), s.GetBuffer(), s.GetByteLength(), out errorAsByte);
		}
		else
		{
			NetworkTransport.QueueMessageForSending( 0, connectionId, channel.GetIndex(), s.GetBuffer(), s.GetByteLength(), out errorAsByte);
		}
		//_profiler.EndEvent();

		if( (NetworkError)errorAsByte != NetworkError.Ok )
		{
			error = $"Send {AlpacaConstant.GetName(message)} to node {connectionId} failed with error{StringFromError(errorAsByte)}";
			return false;
		}

		return true;
	}
	bool Send( NodeIndex client, InternalMessage message, ChannelIndex channel, BitWriter writer, bool sendImmediately, out string error )
	{
		int clientIndex = client.GetClientIndex();	
		byte[] key = _connection.GetAt(clientIndex-1).GetSharedSecretKey();
		// for the server, connectionId == clientIndex
		return base.Send( clientIndex, key, message, channel, writer, sendImmediately, out error );
	}
Пример #3
0
	// Initializes the network transport and builds the _channel array.
	// Returns null on failure, and sets error string with description.
	protected ConnectionConfig InitializeNetwork( out string error )
	{
		_maxEventCount = _commonSettings.maxEventCount > 0 ? _commonSettings.maxEventCount : UInt32.MaxValue;

		GlobalConfig gConfig = new GlobalConfig(); // default settings
		gConfig.MaxPacketSize = _commonSettings.messageBufferSize;
		NetworkTransport.Init();

		ConnectionConfig config = new ConnectionConfig();
		config.SendDelay = 0;

		int channelCount = AlpacaConstant.InternalChannelCount + _commonSettings.customChannel.Length;
		_channel = new Channel[channelCount];

		// add internal channels
		for( int i = 0; i < AlpacaConstant.InternalChannelCount; ++i )
		{
			string name = AlpacaConstant.INTERNAL_CHANNEL_NAME[i];
			QosType qos = AlpacaConstant.INTERNAL_CHANNEL_TYPE[i];

			int index = config.AddChannel( qos );
			if( index != i )
			{
				error = Log.PrefixMessage( string.Format( "Unexpected channel index {0} while attempting to create {1}", index, name ) );
				return null;
			}

			_channel[i] = new Channel( ChannelIndex.CreateInternal( (InternalChannel)i ), name, qos );
		}

		// add custom channels
		for( int i = 0; i < _commonSettings.customChannel.Length; ++i )
		{
			CustomChannelSettings c = _commonSettings.customChannel[i];
			
			int index = config.AddChannel( c.type );
			int offsetIndex = i + AlpacaConstant.InternalChannelCount;
			if( index != offsetIndex )
			{
				error = Log.PrefixMessage( string.Format( "Unexpected channel index {0} while attempting to create {1}", index, c.name ) );
				return null;
			}

			_channel[offsetIndex] = new Channel( ChannelIndex.CreateCustom( (UInt32)i ), c.name, c.type );
		}

		error = "";
		return config;
	}
Пример #4
0
	void HandleMessage( BitReader reader, ChannelIndex channel )
	{
		InternalMessage messageType = UnwrapMessage( reader, NodeIndex.SERVER_NODE_INDEX );
		if( messageType == InternalMessage.INVALID ) { return; }

		//_profiler.StartEvent(TickType.Receive, size, channelId, messageType);

		Log.Info( $"Handling message {AlpacaConstant.GetName(messageType)} from server" );

		if( (_status == Status.WaitingForChallenge) && (messageType != InternalMessage.ConnectionChallenge) )
		{
			Log.Error( $"We are waiting for challenge, but server sent message {AlpacaConstant.GetName(messageType)} instead." );
			return;
		}

		if( (_status == Status.WaitingForConnectionApproval) && (messageType != InternalMessage.ConnectionApproved ) )
		{
			Log.Error( $"We are waiting for connection approval, but server sent message {AlpacaConstant.GetName(messageType)} instead." );
			return;
		}

		switch( messageType )
		{
			case InternalMessage.ConnectionChallenge:
				// TODO: cozeroff crypto implementation
				Log.Error( "Crypto not implemented yet!" );
				break;
			case InternalMessage.ConnectionApproved:
				OnMessageConnectionApproved( reader );
				break;

			// TODO: cozeroff handle sibling connect/disconnect

			case InternalMessage.EntityCreate:
				OnEntityCreate( reader );
				break;
			
			case InternalMessage.CustomClient:
				OnMessageCustomClient( reader );
				break;
			default:
				Log.Error( $"Read unrecognized messageType{AlpacaConstant.GetName(messageType)}" );
				break;
		}

		//_profiler.EndEvent();
	}
Пример #5
0
	// polls the underlying UNET transport for packets. Note that we return the connectionId without
	// converting it into a NodeIndex because the interpretation depends on whether or not the node
	// executing this function is a ServerNode or a ClientNode
	protected ReceiveEvent PollReceive( DataStream stream, out int connectionId, out ChannelIndex channel )
	{
		int hostId;    // this will always be the same port, we don't care about this
		int channelId; // corresponds to ChannelIndex
		int receivedSize;
		byte errorByte;

		NetworkEventType unetEvent = NetworkTransport.Receive( out hostId, out connectionId, out channelId, stream.GetBuffer(), stream.GetByteCapacity(), out receivedSize, out errorByte );
		stream.SetByteLength( receivedSize );

		NetworkError error = (NetworkError)errorByte;
		if(  error != NetworkError.Ok
		  && error != NetworkError.Timeout
		  )
		{
			// polling failed
			Log.Error( StringFromError( errorByte ) );
			channel = new ChannelIndex();
			return ReceiveEvent.Error;
		}

		channel = _channel[channelId].GetIndex();

		// translate UNET NetworkEventType to EventType
		if( error == NetworkError.Timeout )
		{
			return ReceiveEvent.Disconnect;
		}
		else
		{
			switch( unetEvent )
			{
				case NetworkEventType.DataEvent:
					return ReceiveEvent.Message;
				case NetworkEventType.ConnectEvent:
					return ReceiveEvent.Connect;
				case NetworkEventType.DisconnectEvent:
					return ReceiveEvent.Disconnect;
				case NetworkEventType.Nothing:				
					return ReceiveEvent.NoMoreEvents;
				case NetworkEventType.BroadcastEvent:
				default:
					Log.Error( "Received Broadcast or unknown message type from UNET transport layer" );
					return ReceiveEvent.Error;
			}
		}
	}
	void HandleMessage( BitReader reader, NodeIndex client, ChannelIndex channel )
	{
		InternalMessage messageType = UnwrapMessage( reader, client );
		if( messageType == InternalMessage.INVALID ) { return; }

		//_profiler.StartEvent(TickType.Receive, size, channelId, messageType);

		Log.Info( $"Handling message {AlpacaConstant.GetName(messageType)} from client {client.GetClientIndex()}" );

		ClientConnection connection = _connection.GetAt( client.GetClientIndex() - 1 );
		ClientConnection.Status state = connection.GetState();
		
		if( (state == ClientConnection.Status.PendingConnectionChallengeResponse) && (messageType != InternalMessage.ConnectionResponse ) )
		{
			Log.Error( $"Client {client.GetClientIndex()} is pending connection response, but client sent message {AlpacaConstant.GetName(messageType)} instead." );
			return;
		}

		if( (state == ClientConnection.Status.PendingConnectionRequest) && (messageType != InternalMessage.ConnectionRequest) )
		{
			Log.Error( $"Client {client.GetClientIndex()} is pending connection request, but client sent message {AlpacaConstant.GetName(messageType)} instead." );
			return;
		}

		switch( messageType )
		{
			case InternalMessage.ConnectionRequest:
				OnMessageConnectionRequest( client, reader );
				break;
			case InternalMessage.ConnectionResponse:
				// TODO: cozeroff crypto implementation
				Log.Error( "Crypto not implemented yet!" );
				break;
			case InternalMessage.CustomServer:
				OnMessageCustomServer( client, reader );
				break;
			default:
				Log.Error( $"Read unrecognized messageType{AlpacaConstant.GetName(messageType)}" );
				break;
		}

		//_profiler.EndEvent();
	}
Пример #7
0
	public static MessageSecurity GetSecurity( ChannelIndex index ) { return INTERNAL_CHANNEL_SECURITY[(int)index.GetIndex()]; }
Пример #8
0
	bool Send( InternalMessage message, ChannelIndex channel, BitWriter writer, bool sendImmediately, out string error )
	{
		// for the client, connectionId == 1 always (server)
		return base.Send( 1, _serverKey, message, channel, writer, sendImmediately, out error );
	}
Пример #9
0
	// PRIVATE

	// sends an internal message to the server (Alpaca layer)
	bool SendInternal( InternalMessage message, InternalChannel channel, BitWriter writer, bool sendImmediately, out string error )
	{
		return Send( message, ChannelIndex.CreateInternal(channel), writer, sendImmediately, out error );
	}
Пример #10
0
	// sends a custom message to the server
	public bool SendCustomServer( uint customChannel, BitWriter writer, bool sendImmediately, out string error )
	{
		return Send( InternalMessage.CustomServer, ChannelIndex.CreateCustom( customChannel ), writer, sendImmediately, out error );
	}
Пример #11
0
	// sends a custom message to the server via the default channel
	public bool SendCustomServer( BitWriter writer, bool sendImmediately, out string error )
	{
		return Send( InternalMessage.CustomServer, ChannelIndex.CreateInternal( InternalChannel.ClientReliable ), writer, sendImmediately, out error );
	}
Пример #12
0
	public Channel( ChannelIndex index, string name, QosType type )
	{
		_index = index;
		_name = name;
		_quality = type;
	}
	// sends a custom message to the server
	public bool SendCustomClient( NodeIndex client, uint customChannel, BitWriter writer, bool sendImmediately, out string error )
	{
		return Send( client, InternalMessage.CustomClient, ChannelIndex.CreateCustom( customChannel ), writer, sendImmediately, out error );
	}