internal void ProcessPacket(Packet_Server packet)
    {
        if (game.packetHandlers[packet.Id] != null)
        {
            game.packetHandlers[packet.Id].Handle(game, packet);
        }
        switch (packet.Id)
        {
        case Packet_ServerIdEnum.ServerIdentification:
        {
            string invalidversionstr = game.language.InvalidVersionConnectAnyway();

            game.serverGameVersion = packet.Identification.MdProtocolVersion;
            if (game.serverGameVersion != game.platform.GetGameVersion())
            {
                game.ChatLog("[GAME] Different game versions");
                string q = game.platform.StringFormat2(invalidversionstr, game.platform.GetGameVersion(), game.serverGameVersion);
                game.invalidVersionDrawMessage          = q;
                game.invalidVersionPacketIdentification = packet;
            }
            else
            {
                game.ProcessServerIdentification(packet);
            }
            game.ReceivedMapLength = 0;
        }
        break;

        case Packet_ServerIdEnum.Ping:
        {
            game.SendPingReply();
            game.ServerInfo.ServerPing.Send(game.platform);
        }
        break;

        case Packet_ServerIdEnum.PlayerPing:
        {
            game.ServerInfo.ServerPing.Receive(game.platform);
        }
        break;

        case Packet_ServerIdEnum.LevelInitialize:
        {
            game.ChatLog("[GAME] Initialized map loading");
            game.ReceivedMapLength = 0;
            game.InvokeMapLoadingProgress(0, 0, game.language.Connecting());
        }
        break;

        case Packet_ServerIdEnum.LevelDataChunk:
        {
            game.InvokeMapLoadingProgress(packet.LevelDataChunk.PercentComplete, game.ReceivedMapLength, packet.LevelDataChunk.Status);
        }
        break;

        case Packet_ServerIdEnum.LevelFinalize:
        {
            game.ChatLog("[GAME] Finished map loading");
        }
        break;

        case Packet_ServerIdEnum.SetBlock:
        {
            int x    = packet.SetBlock.X;
            int y    = packet.SetBlock.Y;
            int z    = packet.SetBlock.Z;
            int type = packet.SetBlock.BlockType;
            //try
            {
                game.SetTileAndUpdate(x, y, z, type);
            }
            //catch { Console.WriteLine("Cannot update tile!"); }
        }
        break;

        case Packet_ServerIdEnum.FillArea:
        {
            int ax = packet.FillArea.X1;
            int ay = packet.FillArea.Y1;
            int az = packet.FillArea.Z1;
            int bx = packet.FillArea.X2;
            int by = packet.FillArea.Y2;
            int bz = packet.FillArea.Z2;

            int startx = MathCi.MinInt(ax, bx);
            int endx   = MathCi.MaxInt(ax, bx);
            int starty = MathCi.MinInt(ay, by);
            int endy   = MathCi.MaxInt(ay, by);
            int startz = MathCi.MinInt(az, bz);
            int endz   = MathCi.MaxInt(az, bz);

            int blockCount = packet.FillArea.BlockCount;
            {
                for (int x = startx; x <= endx; x++)
                {
                    for (int y = starty; y <= endy; y++)
                    {
                        for (int z = startz; z <= endz; z++)
                        {
                            // if creative mode is off and player run out of blocks
                            if (blockCount == 0)
                            {
                                return;
                            }
                            //try
                            {
                                game.SetTileAndUpdate(x, y, z, packet.FillArea.BlockType);
                            }
                            //catch
                            //{
                            //    Console.WriteLine("Cannot update tile!");
                            //}
                            blockCount--;
                        }
                    }
                }
            }
        }
        break;

        case Packet_ServerIdEnum.FillAreaLimit:
        {
            game.fillAreaLimit = packet.FillAreaLimit.Limit;
            if (game.fillAreaLimit > 100000)
            {
                game.fillAreaLimit = 100000;
            }
        }
        break;

        case Packet_ServerIdEnum.Freemove:
        {
            game.AllowFreemove = packet.Freemove.IsEnabled != 0;
            if (!game.AllowFreemove)
            {
                game.controls.SetFreemove(FreemoveLevelEnum.None);
                game.movespeed = game.basemovespeed;
                game.Log(game.language.MoveNormal());
            }
        }
        break;

        case Packet_ServerIdEnum.PlayerSpawnPosition:
        {
            int x = packet.PlayerSpawnPosition.X;
            int y = packet.PlayerSpawnPosition.Y;
            int z = packet.PlayerSpawnPosition.Z;
            game.playerPositionSpawnX = x;
            game.playerPositionSpawnY = z;
            game.playerPositionSpawnZ = y;
            game.Log(game.platform.StringFormat(game.language.SpawnPositionSetTo(), game.platform.StringFormat3("{0},{1},{2}", game.platform.IntToString(x), game.platform.IntToString(y), game.platform.IntToString(z))));
        }
        break;

        case Packet_ServerIdEnum.Message:
        {
            game.AddChatline(packet.Message.Message);
            game.ChatLog(packet.Message.Message);
        }
        break;

        case Packet_ServerIdEnum.DisconnectPlayer:
        {
            game.ChatLog(game.platform.StringFormat("[GAME] Disconnected by the server ({0})", packet.DisconnectPlayer.DisconnectReason));
            //Exit mouse pointer lock if necessary
            if (game.platform.IsMousePointerLocked())
            {
                game.platform.ExitMousePointerLock();
            }
            //When server disconnects player, return to main menu
            game.platform.MessageBoxShowError(packet.DisconnectPlayer.DisconnectReason, "Disconnected from server");
            game.ExitToMainMenu_();
            break;
        }

        case Packet_ServerIdEnum.PlayerStats:
        {
            Packet_ServerPlayerStats p = packet.PlayerStats;
            game.PlayerStats = p;
        }
        break;

        case Packet_ServerIdEnum.FiniteInventory:
        {
            //check for null so it's possible to connect
            //to old versions of game (before 2011-05-05)
            if (packet.Inventory.Inventory != null)
            {
                //d_Inventory.CopyFrom(ConvertInventory(packet.Inventory.Inventory));
                game.UseInventory(packet.Inventory.Inventory);
            }
            //FiniteInventory = packet.FiniteInventory.BlockTypeAmount;
            //ENABLE_FINITEINVENTORY = packet.FiniteInventory.IsFinite;
            //FiniteInventoryMax = packet.FiniteInventory.Max;
        }
        break;

        case Packet_ServerIdEnum.Season:
        {
            packet.Season.Hour -= 1;
            if (packet.Season.Hour < 0)
            {
                //shouldn't happen
                packet.Season.Hour = 12 * Game.HourDetail;
            }
            int sunlight = game.NightLevels[packet.Season.Hour];
            game.SkySphereNight = sunlight < 8;
            game.d_SunMoonRenderer.day_length_in_seconds = 60 * 60 * 24 / packet.Season.DayNightCycleSpeedup;
            int hour = packet.Season.Hour / Game.HourDetail;
            if (game.d_SunMoonRenderer.GetHour() != hour)
            {
                game.d_SunMoonRenderer.SetHour(hour);
            }

            if (game.sunlight_ != sunlight)
            {
                game.sunlight_ = sunlight;
                //d_Shadows.ResetShadows();
                game.RedrawAllBlocks();
            }
        }
        break;

        case Packet_ServerIdEnum.BlobInitialize:
        {
            game.blobdownload = new CitoMemoryStream();
            //blobdownloadhash = ByteArrayToString(packet.BlobInitialize.hash);
            game.blobdownloadname = packet.BlobInitialize.Name;
            game.blobdownloadmd5  = packet.BlobInitialize.Md5;
        }
        break;

        case Packet_ServerIdEnum.BlobPart:
        {
            int length = game.platform.ByteArrayLength(packet.BlobPart.Data);
            game.blobdownload.Write(packet.BlobPart.Data, 0, length);
            game.ReceivedMapLength += length;
        }
        break;

        case Packet_ServerIdEnum.BlobFinalize:
        {
            byte[] downloaded = game.blobdownload.ToArray();

            if (game.blobdownloadname != null)         // old servers
            {
                game.SetFile(game.blobdownloadname, game.blobdownloadmd5, downloaded, game.blobdownload.Length());
            }
            game.blobdownload = null;
        }
        break;

        case Packet_ServerIdEnum.Sound:
        {
            game.PlaySoundAt(packet.Sound.Name, packet.Sound.X, packet.Sound.Y, packet.Sound.Z);
        }
        break;

        case Packet_ServerIdEnum.RemoveMonsters:
        {
            for (int i = Game.entityMonsterIdStart; i < Game.entityMonsterIdStart + Game.entityMonsterIdCount; i++)
            {
                game.entities[i] = null;
            }
        }
        break;

        case Packet_ServerIdEnum.Translation:
            game.language.Override(packet.Translation.Lang, packet.Translation.Id, packet.Translation.Translation);
            break;

        case Packet_ServerIdEnum.BlockType:
            game.NewBlockTypes[packet.BlockType.Id] = packet.BlockType.Blocktype;
            break;

        case Packet_ServerIdEnum.SunLevels:
            game.NightLevels = packet.SunLevels.Sunlevels;
            break;

        case Packet_ServerIdEnum.LightLevels:
            for (int i = 0; i < packet.LightLevels.LightlevelsCount; i++)
            {
                game.mLightLevels[i] = game.DeserializeFloat(packet.LightLevels.Lightlevels[i]);
            }
            break;

        case Packet_ServerIdEnum.Follow:
            IntRef oldFollowId = game.FollowId();
            game.Follow = packet.Follow.Client;
            if (packet.Follow.Tpp != 0)
            {
                game.SetCamera(CameraType.Overhead);
                game.player.position.rotx = Game.GetPi();
                game.GuiStateBackToGame();
            }
            else
            {
                game.SetCamera(CameraType.Fpp);
            }
            break;

        case Packet_ServerIdEnum.Bullet:
            game.EntityAddLocal(game.CreateBulletEntity(
                                    game.DeserializeFloat(packet.Bullet.FromXFloat),
                                    game.DeserializeFloat(packet.Bullet.FromYFloat),
                                    game.DeserializeFloat(packet.Bullet.FromZFloat),
                                    game.DeserializeFloat(packet.Bullet.ToXFloat),
                                    game.DeserializeFloat(packet.Bullet.ToYFloat),
                                    game.DeserializeFloat(packet.Bullet.ToZFloat),
                                    game.DeserializeFloat(packet.Bullet.SpeedFloat)));
            break;

        case Packet_ServerIdEnum.Ammo:
            if (!game.ammostarted)
            {
                game.ammostarted = true;
                for (int i = 0; i < packet.Ammo.TotalAmmoCount; i++)
                {
                    Packet_IntInt k = packet.Ammo.TotalAmmo[i];
                    game.LoadedAmmo[k.Key_] = MathCi.MinInt(k.Value_, game.blocktypes[k.Key_].AmmoMagazine);
                }
            }
            game.TotalAmmo = new int[GlobalVar.MAX_BLOCKTYPES];
            for (int i = 0; i < packet.Ammo.TotalAmmoCount; i++)
            {
                game.TotalAmmo[packet.Ammo.TotalAmmo[i].Key_] = packet.Ammo.TotalAmmo[i].Value_;
            }
            break;

        case Packet_ServerIdEnum.Explosion:
        {
            Entity entity = new Entity();
            entity.expires          = new Expires();
            entity.expires.timeLeft = game.DeserializeFloat(packet.Explosion.TimeFloat);
            entity.push             = packet.Explosion;
            game.EntityAddLocal(entity);
        }
        break;

        case Packet_ServerIdEnum.Projectile:
        {
            Entity entity = new Entity();

            Sprite sprite = new Sprite();
            sprite.image          = "ChemicalGreen.png";
            sprite.size           = 14;
            sprite.animationcount = 0;
            sprite.positionX      = game.DeserializeFloat(packet.Projectile.FromXFloat);
            sprite.positionY      = game.DeserializeFloat(packet.Projectile.FromYFloat);
            sprite.positionZ      = game.DeserializeFloat(packet.Projectile.FromZFloat);
            entity.sprite         = sprite;

            Grenade_ grenade = new Grenade_();
            grenade.velocityX    = game.DeserializeFloat(packet.Projectile.VelocityXFloat);
            grenade.velocityY    = game.DeserializeFloat(packet.Projectile.VelocityYFloat);
            grenade.velocityZ    = game.DeserializeFloat(packet.Projectile.VelocityZFloat);
            grenade.block        = packet.Projectile.BlockId;
            grenade.sourcePlayer = packet.Projectile.SourcePlayerID;
            entity.grenade       = grenade;

            entity.expires = Expires.Create(game.DeserializeFloat(packet.Projectile.ExplodesAfterFloat));

            game.EntityAddLocal(entity);
        }
        break;

        case Packet_ServerIdEnum.BlockTypes:
            game.blocktypes    = game.NewBlockTypes;
            game.NewBlockTypes = new Packet_BlockType[GlobalVar.MAX_BLOCKTYPES];

            int      textureInAtlasIdsCount = 1024;
            string[] textureInAtlasIds      = new string[textureInAtlasIdsCount];
            int      lastTextureId          = 0;
            for (int i = 0; i < GlobalVar.MAX_BLOCKTYPES; i++)
            {
                if (game.blocktypes[i] != null)
                {
                    string[] to_load       = new string[7];
                    int      to_loadLength = 7;
                    {
                        to_load[0] = game.blocktypes[i].TextureIdLeft;
                        to_load[1] = game.blocktypes[i].TextureIdRight;
                        to_load[2] = game.blocktypes[i].TextureIdFront;
                        to_load[3] = game.blocktypes[i].TextureIdBack;
                        to_load[4] = game.blocktypes[i].TextureIdTop;
                        to_load[5] = game.blocktypes[i].TextureIdBottom;
                        to_load[6] = game.blocktypes[i].TextureIdForInventory;
                    }
                    for (int k = 0; k < to_loadLength; k++)
                    {
                        if (!Contains(textureInAtlasIds, textureInAtlasIdsCount, to_load[k]))
                        {
                            textureInAtlasIds[lastTextureId++] = to_load[k];
                        }
                    }
                }
            }
            game.d_Data.UseBlockTypes(game.platform, game.blocktypes, GlobalVar.MAX_BLOCKTYPES);
            for (int i = 0; i < GlobalVar.MAX_BLOCKTYPES; i++)
            {
                Packet_BlockType b = game.blocktypes[i];
                if (b == null)
                {
                    continue;
                }
                //Indexed by block id and TileSide.
                if (textureInAtlasIds != null)
                {
                    game.TextureId[i][0]          = IndexOf(textureInAtlasIds, textureInAtlasIdsCount, b.TextureIdTop);
                    game.TextureId[i][1]          = IndexOf(textureInAtlasIds, textureInAtlasIdsCount, b.TextureIdBottom);
                    game.TextureId[i][2]          = IndexOf(textureInAtlasIds, textureInAtlasIdsCount, b.TextureIdFront);
                    game.TextureId[i][3]          = IndexOf(textureInAtlasIds, textureInAtlasIdsCount, b.TextureIdBack);
                    game.TextureId[i][4]          = IndexOf(textureInAtlasIds, textureInAtlasIdsCount, b.TextureIdLeft);
                    game.TextureId[i][5]          = IndexOf(textureInAtlasIds, textureInAtlasIdsCount, b.TextureIdRight);
                    game.TextureIdForInventory[i] = IndexOf(textureInAtlasIds, textureInAtlasIdsCount, b.TextureIdForInventory);
                }
            }
            game.UseTerrainTextures(textureInAtlasIds, textureInAtlasIdsCount);
            game.handRedraw = true;
            game.RedrawAllBlocks();
            break;

        case Packet_ServerIdEnum.ServerRedirect:
            game.ChatLog("[GAME] Received server redirect");
            //Leave current server
            game.SendLeave(Packet_LeaveReasonEnum.Leave);
            //Exit game screen and create new game instance
            game.ExitAndSwitchServer(packet.Redirect);
            break;
        }
    }
Beispiel #2
0
    public Game()
    {
        one = 1;
        map = new Map();
        performanceinfo = new DictionaryStringString();
        AudioEnabled = true;
        AutoJumpEnabled = false;
        playerPositionSpawnX = 15 + one / 2;
        playerPositionSpawnY = 64;
        playerPositionSpawnZ = 15 + one / 2;

        TextureId = new int[MaxBlockTypes][];
        for (int i = 0; i < MaxBlockTypes; i++)
        {
            TextureId[i] = new int[6];
        }
        TextureIdForInventory = new int[MaxBlockTypes];
        language = new Language();
        lastplacedblockX = -1;
        lastplacedblockY = -1;
        lastplacedblockZ = -1;
        mLightLevels = new float[16];
        sunlight_ = 15;
        mvMatrix = new StackMatrix4();
        pMatrix = new StackMatrix4();
        mvMatrix.Push(Mat4.Create());
        pMatrix.Push(Mat4.Create());
        whitetexture = -1;
        cachedTextTexturesMax = 1024;
        cachedTextTextures = new CachedTextTexture[cachedTextTexturesMax];
        for (int i = 0; i < cachedTextTexturesMax; i++)
        {
            cachedTextTextures[i] = null;
        }
        packetLen = new IntRef();
        ENABLE_DRAW2D = true;
        AllowFreemove = true;
        enableCameraControl = true;
        textures = new DictionaryStringInt1024();
        ServerInfo = new ServerInformation();
        menustate = new MenuState();
        mouseleftclick = false;
        mouseleftdeclick = false;
        wasmouseleft = false;
        mouserightclick = false;
        mouserightdeclick = false;
        wasmouseright = false;
        ENABLE_LAG = 0;
        znear = one / 10;
        CameraMatrix = new GetCameraMatrix();
        ENABLE_ZFAR = true;
        TotalAmmo = new int[GlobalVar.MAX_BLOCKTYPES];
        LoadedAmmo = new int[GlobalVar.MAX_BLOCKTYPES];
        AllowedFontsCount = 1;
        AllowedFonts = new string[AllowedFontsCount];
        AllowedFonts[0] = "Verdana";
        fov = Game.GetPi() / 3;
        cameratype = CameraType.Fpp;
        ENABLE_TPP_VIEW = false;
        basemovespeed = 5;
        movespeed = 5;
        RadiusWhenMoving = one * 3 / 10;
        playervelocity = new Vector3Ref();
        LocalPlayerId = -1;
        dialogs = new VisibleDialog[512];
        dialogsCount = 512;
        blockHealth = new DictionaryVector3Float();
        playertexturedefault = -1;
        a = new AnimationState();
        constRotationSpeed = one * 180 / 20;
        modmanager = new ClientModManager1();
        particleEffectBlockBreak = new ModDrawParticleEffectBlockBreak();
        PICK_DISTANCE = 4.1f;
        selectedmodelid = -1;
        grenadetime = 3;
        rotationspeed = one * 15 / 100;
        entities = new Entity[entitiesMax];
        for (int i = 0; i < entitiesMax; i++)
        {
            entities[i] = null;
        }
        entitiesCount = 512;
        PlayerPushDistance = 2;
        const int KeysMax = 256;
        keyboardState = new bool[KeysMax];
        for (int i = 0; i < KeysMax; i++)
        {
            keyboardState[i] = false;
        }
        keyboardStateRaw = new bool[KeysMax];
        for (int i = 0; i < KeysMax; i++)
        {
            keyboardStateRaw[i] = false;
        }
        overheadcameradistance = 10;
        tppcameradistance = 3;
        TPP_CAMERA_DISTANCE_MIN = 1;
        TPP_CAMERA_DISTANCE_MAX = 10;
        options = new OptionsCi();
        overheadcameraK = new Kamera();
        fillAreaLimit = 200;
        speculativeCount = 0;
        speculative = new Speculative[speculativeMax];
        typinglog = new string[1024 * 16];
        typinglogCount = 0;
        NewBlockTypes = new Packet_BlockType[GlobalVar.MAX_BLOCKTYPES];
        localplayeranim = new AnimationState();
        localplayeranimationhint = new AnimationHint();
        enable_move = true;
        handTexture = -1;
        modelViewInverted = new float[16];
        GLScaleTempVec3 = Vec3.Create();
        GLRotateTempVec3 = Vec3.Create();
        GLTranslateTempVec3 = Vec3.Create();
        identityMatrix = Mat4.Identity_(Mat4.Create());
        Set3dProjectionTempMat4 = Mat4.Create();
        getAsset = new string[1024 * 2];
        PlayerStats = new Packet_ServerPlayerStats();
        mLightLevels = new float[16];
        for (int i = 0; i < 16; i++)
        {
            mLightLevels[i] = one * i / 15;
        }
        soundnow = new BoolRef();
        camera = Mat4.Create();
        packetHandlers = new ClientPacketHandler[256];
        player = new Entity();
        player.position = new EntityPosition_();
        currentlyAttackedEntity = -1;
        ChatLinesMax = 1;
        ChatLines = new Chatline[ChatLinesMax];
        ChatLineLength = 64;
        audio = new AudioControl();
        CameraEyeX = -1;
        CameraEyeY = -1;
        CameraEyeZ = -1;
        controls = new Controls();
        movedz = 0;
        taskScheduler = new TaskScheduler();
        commitActions = ListAction.Create(16 * 1024);
        constWallDistance = 0.3f;
        mouseSmoothing = true;
    }