Exemplo n.º 1
0
    private void AnalyzeMessage(IPEndPoint remoteEndpoint, Message message)
    {
        Debug.Log($"Received {message.Type} from address: {remoteEndpoint.Address}");

        switch (message.Type)
        {
        case MessageType.Ping:
            SendMessage(PONG, remoteEndpoint);
            break;

        case MessageType.Client_Request_Connect:
            Client_Request_Connect request_Connect = (Client_Request_Connect)message.Content;
            bool isNewPlayer = request_Connect.networkId == 0;
            // 分配用户id
            uint NetId = isNewPlayer ? networkId++ : request_Connect.networkId;
            // 服务器立即回应
            Server_Responses_Connect Responses_Connect = new Server_Responses_Connect()
            {
                networkId = NetId
            };
            SendMessage(new Message()
            {
                Type = MessageType.Server_Responses_Connect, Content = Responses_Connect
            }, remoteEndpoint);
            // 添加消息队列 广播所有玩家
            Broad_Connect broad_Connect = new Broad_Connect
            {
                networkId   = NetId,
                isReConnect = request_Connect.networkId != 0
            };
            server_broad_msgs.Enqueue(new Message()
            {
                Type = MessageType.Broad_Connect, Content = broad_Connect
            });

            if (isNewPlayer)
            {
                allPlayer[NetId] = remoteEndpoint;
                GameObject player = Instantiate(server_player_perfab, Vector3.zero, Quaternion.identity);
                allPlayer_Object[NetId] = player;
            }
            else
            {
                allPlayer[NetId] = remoteEndpoint;
            }
            break;

        case MessageType.Client_Request_Operation:
            Client_Request_Operation operation = (Client_Request_Operation)message.Content;
            server_input_msgs.Enqueue(operation);
            break;

        default:
            break;
        }
    }
Exemplo n.º 2
0
    private void ServerUpdate(float fixedDeltaTime)
    {
        while (this.server_input_msgs.Count > 0)
        {
            Client_Request_Operation operation = this.server_input_msgs.Dequeue();
            if (Time.time < operation.inputMessage.delivery_time)
            {
                continue;
            }

            Rigidbody    server_rigidbody = allPlayer_Object[operation.networkId].GetComponent <Rigidbody>();
            InputMessage input_msg        = operation.inputMessage;

            // 消息包含一个输入数组,计算最后一个帧
            uint max_tick = input_msg.start_tick_number + (uint)input_msg.inputs.Count - 1;

            // 如果输入帧 大于服务器 当前帧 客户端有输入
            if (max_tick >= server_tick_number)
            {
                // 数组中可能有一些我们已经有的输入,所以找出从哪里开始
                uint start_i = server_tick_number > input_msg.start_tick_number ? (server_tick_number - input_msg.start_tick_number) : 0;

                // 运行所有相关输入,并推动玩家前进
                for (int i = (int)start_i; i < input_msg.inputs.Count; ++i)
                {
                    this.PrePhysicsStep(server_rigidbody, input_msg.inputs[i]);
                    server_physics_scene.Simulate(fixedDeltaTime);

                    ++server_tick_number;
                    ++server_tick_accumulator;
                    if (server_tick_accumulator >= this.server_snapshot_rate)
                    {
                        server_tick_accumulator = 0;

                        if (Random.value > this.packet_loss_chance)
                        {
                            StateMessage state_msg;
                            state_msg.delivery_time    = Time.time + this.latency;
                            state_msg.tick_number      = server_tick_number;
                            state_msg.position         = server_rigidbody.position;
                            state_msg.rotation         = server_rigidbody.rotation;
                            state_msg.velocity         = server_rigidbody.velocity;
                            state_msg.angular_velocity = server_rigidbody.angularVelocity;
                            this.server_state_msgs.Enqueue(state_msg);
                        }
                    }
                }
            }
        }
    }