Example #1
0
        public void TickSocket(Socket sock, ref byte[] rd, ref int rdsf)
        {
            int avail = sock.Available;

            if (avail <= 0)
            {
                return;
            }
            if (avail + rdsf > MAX)
            {
                avail = MAX - rdsf;
                if (avail == 0)
                {
                    throw new Exception("Received overly massive packet?!");
                }
            }
            sock.Receive(rd, rdsf, avail, SocketFlags.None);
            rdsf += avail;
            if (rdsf < 5)
            {
                return;
            }
            while (true)
            {
                byte[] len_bytes = new byte[4];
                Array.Copy(rd, len_bytes, 4);
                int len = Utilities.BytesToInt(len_bytes);
                if (len + 5 > MAX)
                {
                    throw new Exception("Unreasonably huge packet!");
                }
                if (rdsf < 5 + len)
                {
                    return;
                }
                ServerToClientPacket packetID = (ServerToClientPacket)rd[4];
                byte[] data = new byte[len];
                Array.Copy(rd, 5, data, 0, len);
                byte[] rem_data = new byte[rdsf - (len + 5)];
                if (rem_data.Length > 0)
                {
                    Array.Copy(rd, len + 5, rem_data, 0, rem_data.Length);
                    Array.Copy(rem_data, rd, rem_data.Length);
                }
                rdsf -= len + 5;
                AbstractPacketIn packet;
                bool             asyncable = false;
                NetUsageType     usage;
                switch (packetID) // TODO: Packet registry!
                {
                case ServerToClientPacket.PING:
                    packet = new PingPacketIn();
                    usage  = NetUsageType.PINGS;
                    break;

                case ServerToClientPacket.YOUR_POSITION:
                    packet = new YourPositionPacketIn();
                    usage  = NetUsageType.PLAYERS;
                    break;

                case ServerToClientPacket.SPAWN_ENTITY:
                    packet = new SpawnEntityPacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.PHYSICS_ENTITY_UPDATE:
                    packet = new PhysicsEntityUpdatePacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.MESSAGE:
                    packet = new MessagePacketIn();
                    usage  = NetUsageType.GENERAL;
                    break;

                case ServerToClientPacket.CHARACTER_UPDATE:
                    packet = new CharacterUpdatePacketIn();
                    usage  = NetUsageType.PLAYERS;
                    break;

                case ServerToClientPacket.TOPS:
                    packet = new TopsPacketIn();
                    usage  = NetUsageType.CHUNKS;
                    break;

                case ServerToClientPacket.DESPAWN_ENTITY:
                    packet = new DespawnEntityPacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.NET_STRING:
                    packet = new NetStringPacketIn();
                    usage  = NetUsageType.GENERAL;
                    break;

                case ServerToClientPacket.SPAWN_ITEM:
                    packet = new SpawnItemPacketIn();
                    usage  = NetUsageType.GENERAL;
                    break;

                case ServerToClientPacket.YOUR_STATUS:
                    packet = new YourStatusPacketIn();
                    usage  = NetUsageType.PLAYERS;
                    break;

                case ServerToClientPacket.ADD_JOINT:
                    packet = new AddJointPacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.YOUR_EID:
                    packet = new YourEIDPacketIn();
                    usage  = NetUsageType.GENERAL;
                    break;

                case ServerToClientPacket.DESTROY_JOINT:
                    packet = new DestroyJointPacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.TOPS_DATA:
                    packet = new TopsDataPacketIn();
                    usage  = NetUsageType.CHUNKS;
                    break;

                case ServerToClientPacket.PRIMITIVE_ENTITY_UPDATE:
                    packet = new PrimitiveEntityUpdatePacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.ANIMATION:
                    packet = new AnimationPacketIn();
                    usage  = NetUsageType.PLAYERS;
                    break;

                case ServerToClientPacket.FLASHLIGHT:
                    packet = new FlashLightPacketIn();
                    usage  = NetUsageType.PLAYERS;
                    break;

                case ServerToClientPacket.REMOVE_ITEM:
                    packet = new RemoveItemPacketIn();
                    usage  = NetUsageType.GENERAL;
                    break;

                case ServerToClientPacket.SET_ITEM:
                    packet = new SetItemPacketIn();
                    usage  = NetUsageType.GENERAL;
                    break;

                case ServerToClientPacket.CVAR_SET:
                    packet = new CVarSetPacketIn();
                    usage  = NetUsageType.GENERAL;
                    break;

                case ServerToClientPacket.SET_HELD_ITEM:
                    packet = new SetHeldItemPacketIn();
                    usage  = NetUsageType.GENERAL;
                    break;

                case ServerToClientPacket.CHUNK_INFO:
                    packet = new ChunkInfoPacketIn();
                    usage  = NetUsageType.CHUNKS;
                    break;

                case ServerToClientPacket.BLOCK_EDIT:
                    packet = new BlockEditPacketIn();
                    usage  = NetUsageType.CHUNKS;
                    break;

                case ServerToClientPacket.SUN_ANGLE:
                    packet = new SunAnglePacketIn();
                    usage  = NetUsageType.EFFECTS;
                    break;

                case ServerToClientPacket.TELEPORT:
                    packet = new TeleportPacketIn();
                    usage  = NetUsageType.PLAYERS;
                    break;

                case ServerToClientPacket.OPERATION_STATUS:
                    packet = new OperationStatusPacketIn();
                    usage  = NetUsageType.GENERAL;
                    break;

                case ServerToClientPacket.PARTICLE_EFFECT:
                    packet = new ParticleEffectPacketIn();
                    usage  = NetUsageType.EFFECTS;
                    break;

                case ServerToClientPacket.PATH:
                    packet = new PathPacketIn();
                    usage  = NetUsageType.EFFECTS;
                    break;

                case ServerToClientPacket.CHUNK_FORGET:
                    packet = new ChunkForgetPacketIn();
                    usage  = NetUsageType.CHUNKS;
                    break;

                case ServerToClientPacket.FLAG_ENTITY:
                    packet = new FlagEntityPacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.DEFAULT_SOUND:
                    packet = new DefaultSoundPacketIn();
                    usage  = NetUsageType.EFFECTS;
                    break;

                case ServerToClientPacket.GAIN_CONTROL_OF_VEHICLE:
                    packet = new GainControlOfVehiclePacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.ADD_CLOUD:
                    packet = new AddCloudPacketIn();
                    usage  = NetUsageType.CLOUDS;
                    break;

                case ServerToClientPacket.REMOVE_CLOUD:
                    packet = new RemoveCloudPacketIn();
                    usage  = NetUsageType.CLOUDS;
                    break;

                case ServerToClientPacket.ADD_TO_CLOUD:
                    packet = new AddToCloudPacketIn();
                    usage  = NetUsageType.CLOUDS;
                    break;

                case ServerToClientPacket.YOUR_VEHICLE:
                    packet = new YourVehiclePacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.SET_STATUS:
                    packet = new SetStatusPacketIn();
                    usage  = NetUsageType.PLAYERS;
                    break;

                case ServerToClientPacket.HIGHLIGHT:
                    packet = new HighlightPacketIn();
                    usage  = NetUsageType.EFFECTS;
                    break;

                case ServerToClientPacket.PLAY_SOUND:
                    packet = new PlaySoundPacketIn();
                    usage  = NetUsageType.EFFECTS;
                    break;

                case ServerToClientPacket.LOD_MODEL:
                    packet = new LODModelPacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.LOSE_CONTROL_OF_VEHICLE:
                    packet = new LoseControlOfVehiclePacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                case ServerToClientPacket.JOINT_UPDATE:
                    packet = new JointUpdatePacketIn();
                    usage  = NetUsageType.ENTITIES;
                    break;

                default:
                    throw new Exception("Invalid packet ID: " + packetID);
                }
                UsagesThisSecond[(int)usage] += 5 + data.Length;
                UsagesTotal[(int)usage]      += 5 + data.Length;
                packet.TheClient              = TheClient;
                packet.ChunkN = sock == ChunkSocket;
                ServerToClientPacket pid = packetID;
                if (asyncable)
                {
                    // TODO: StartAsyncTask?
                    if (!packet.ParseBytesAndExecute(data))
                    {
                        SysConsole.Output(OutputType.ERROR, "Bad async packet (ID=" + pid + ") data!");
                    }
                }
                else
                {
                    TheClient.Schedule.ScheduleSyncTask(() =>
                    {
                        try
                        {
                            if (!packet.ParseBytesAndExecute(data))
                            {
                                SysConsole.Output(OutputType.ERROR, "Bad sync packet (ID=" + pid + ") data!");
                            }
                        }
                        catch (Exception ex)
                        {
                            if (ex is ThreadAbortException)
                            {
                                throw ex;
                            }
                            SysConsole.Output(OutputType.ERROR, "Bad sync packet (ID=" + pid + ") data: " + ex.ToString());
                        }
                    });
                }
            }
        }
Example #2
0
        /// <summary>
        /// Tick the entire network engine.
        /// </summary>
        public static void Tick()
        {
            if (!Connected)
            {
                return;
            }
            try
            {
                int waiting = Connection.Available;
                if (waiting > 1024 * 1024 - bufferpos)
                {
                    waiting = 1024 * 1024 - bufferpos;
                }
                if (waiting > 0)
                {
                    Connection.Receive(buffer, bufferpos, waiting, SocketFlags.None);
                    bufferpos += waiting;
                    while (true)
                    {
                        if (bufferpos < 5)
                        {
                            break;
                        }
                        if (!Connected)
                        {
                            break;
                        }
                        int recd = BitConverter.ToInt32(buffer, 0);
                        if (bufferpos < 5 + recd)
                        {
                            break;
                        }
                        byte[] packet = new byte[recd];
                        Array.Copy(buffer, 5, packet, 0, recd);
                        int ID = buffer[4];
                        Array.Copy(buffer, recd + 5, buffer, 0, bufferpos - (recd + 5));
                        bufferpos -= recd + 5;
                        AbstractPacketIn apacket = null;
                        switch (ID)
                        {
                        case 1:
                            apacket = new PingPacketIn();
                            break;

                        case 2:
                            apacket = new ConfirmPositionPacketIn();
                            break;

                        case 3:
                            apacket = new MessagePacketIn();
                            break;

                        case 4:
                            apacket = new NewEntityPacketIn();
                            break;

                        case 5:
                            apacket = new DespawnEntityPacketIn();
                            break;

                        case 6:
                            apacket = new EntityPositionPacketIn();
                            break;

                        case 255:
                            apacket = new DisconnectPacketIn();
                            break;

                        default:
                            UIConsole.WriteLine("Invalid packet from server, ID " + ID);
                            break;
                        }
                        if (apacket != null)
                        {
                            ReceivePacket(ID, apacket, packet, false);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                SysConsole.Output(OutputType.ERROR, "Networking: " + ex.ToString());
                Disconnect();
            }
            try
            {
                int waiting = ChunkConnection.Available;
                if (waiting > 1024 * 1024 - bufferpos2)
                {
                    waiting = 1024 * 1024 - bufferpos2;
                }
                if (waiting > 0)
                {
                    ChunkConnection.Receive(buffer2, bufferpos2, waiting, SocketFlags.None);
                    bufferpos2 += waiting;
                    while (true)
                    {
                        if (bufferpos2 < 5)
                        {
                            break;
                        }
                        if (!Connected)
                        {
                            break;
                        }
                        int recd = BitConverter.ToInt32(buffer2, 0);
                        if (bufferpos2 < 5 + recd)
                        {
                            break;
                        }
                        byte[] packet = new byte[recd];
                        Array.Copy(buffer2, 5, packet, 0, recd);
                        int ID = buffer2[4];
                        Array.Copy(buffer2, recd + 5, buffer2, 0, bufferpos2 - (recd + 5));
                        bufferpos2 -= recd + 5;
                        AbstractPacketIn apacket = null;
                        switch (ID)
                        {
                        case 0:
                            apacket = new ChunkPacketIn();
                            break;

                        case 1:
                            apacket = new PingPacketIn();
                            break;

                        case 4:
                            apacket = new BlockPacketIn();
                            break;

                        default:
                            UIConsole.WriteLine("Invalid secondary packet from server, ID " + ID);
                            break;
                        }
                        if (apacket != null)
                        {
                            ReceivePacket(ID, apacket, packet, true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                SysConsole.Output(OutputType.ERROR, "Networking (Secondary): " + ex.ToString());
                Disconnect();
            }
        }