Beispiel #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());
                        }
                    });
                }
            }
        }
Beispiel #2
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.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.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.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;
             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)
                 {
                     SysConsole.Output(OutputType.ERROR, "Bad sync packet (ID=" + pid + ") data: " + ex.ToString());
                 }
             });
         }
     }
 }