Exemplo n.º 1
0
        private void HandleMessage(int start, int len)
        {
            if (statusTotal > 0)
            {
                statusCount++;
                if (statusCount == statusTotal)
                    statusTotal = 0;
                else
                    Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                    {
                        serverText.Text = ((int)((float)statusCount * 100.0 / (float)statusTotal)) + "% - " + status;
                    }));
            }
            int messageid = messages[start++];
            len--;
            int payload = start;
            switch (messageid)
            {
                case 0x01: // connect request - c2s only
                    break;
                case 0x02: //error
                    {
                        string error = Encoding.ASCII.GetString(messages, payload, len);
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                            {
                                MessageBox.Show(error);
                            }));
                        socket.Close();
                        busy = false;
                    }
                    break;
                case 0x03: //connection approved
                    {
                        if (loginLevel == 1) loginLevel = 2;
                        playerSlot = messages[payload];
                        SendMessage(4);
                        SendMessage(0x10);
                        SendMessage(0x2a);
                        //send buffs
                        //send inventory
                        //send dyes
                        SendMessage(6);
                        if (loginLevel == 2) loginLevel = 3;
                    }
                    break;
                case 0x04: //player appearance
                    //ignore other players
                    break;
                case 0x05: //inventory items
                    //ignore player inventory
                    break;
                case 0x06: //request world info - c2s only
                    break;
                case 0x07: //world info
                    {
                        gameTime = BitConverter.ToInt32(messages, payload); payload += 4;
                        dayNight = messages[payload++] == 1;
                        moonPhase = messages[payload++];
                        bloodMoon = messages[payload++] == 1;
                        payload++; //eclipse
                        tilesWide = BitConverter.ToInt32(messages, payload); payload += 4;
                        tilesHigh = BitConverter.ToInt32(messages, payload); payload += 4;
                        spawnX = BitConverter.ToInt32(messages, payload); payload += 4;
                        spawnY = BitConverter.ToInt32(messages, payload); payload += 4;
                        groundLevel = BitConverter.ToInt32(messages, payload); payload += 4;
                        rockLevel = BitConverter.ToInt32(messages, payload); payload += 4;
                        worldID = BitConverter.ToInt32(messages, payload); payload += 4;
                        payload++; //moon type
                        for (int i = 0; i < 3; i++)
                        {
                            treeX[i] = BitConverter.ToInt32(messages, payload); payload += 4;
                        }
                        for (int i = 0; i < 4; i++)
                            treeStyle[i] = messages[payload++];
                        for (int i = 0; i < 3; i++)
                        {
                            caveBackX[i] = BitConverter.ToInt32(messages, payload); payload += 4;
                        }
                        for (int i = 0; i < 4; i++)
                            caveBackStyle[i] = messages[payload++];
                        for (int i = 0; i < 8; i++)
                            styles[i] = messages[payload++];
                        iceBackStyle = messages[payload++];
                        jungleBackStyle = messages[payload++];
                        hellBackStyle = messages[payload++];
                        payload += 4; //wind speed
                        payload++; //number of clouds
                        byte flags = messages[payload++];
                        byte flags2 = messages[payload++];
                        payload += 4; //max rain
                        string title = Encoding.ASCII.GetString(messages, payload, start + len - payload);
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                        {
                            Title = title;
                        }));
                        smashedOrb = (flags & 1) == 1;
                        killedBoss1 = (flags & 2) == 2;
                        killedBoss2 = (flags & 4) == 4;
                        killedBoss3 = (flags & 8) == 8;
                        hardMode = (flags & 16) == 16;
                        killedClown = (flags & 32) == 32;
                        killedPlantBoss = (flags & 128) == 128;
                        killedMechBoss1 = (flags2 & 1) == 1;
                        killedMechBoss2 = (flags2 & 2) == 2;
                        killedMechBoss3 = (flags2 & 4) == 4;
                        killedMechBossAny = (flags2 & 8) == 8;
                        crimson = (flags2 & 32) == 32;
                        meteorSpawned = false;
                        killedFrost = false;
                        killedGoblins = false;
                        killedPirates = false;
                        killedQueenBee = false;
                        savedMechanic = false;
                        savedTinkerer = false;
                        savedWizard = false;
                        goblinsDelay = 0;
                        altarsSmashed = 0;
                        ResizeMap();
                        if (loginLevel == 3)
                        {
                            sectionsWide = (tilesWide / 200);
                            sectionsHigh = (tilesHigh / 150);
                            sentSections = new bool[sectionsWide, sectionsHigh];
                            loginLevel = 4;
                            for (int y = 0; y < tilesHigh; y++) //set all tiles to blank
                                for (int x = 0; x < tilesWide; x++)
                                {
                                    tiles[x, y].isActive = false;
                                    tiles[x, y].wall = 0;
                                    tiles[x, y].liquid = 0;
                                    tiles[x, y].hasRedWire = false;
                                    tiles[x, y].hasGreenWire = false;
                                    tiles[x, y].hasBlueWire = false;
                                    tiles[x, y].half = false;
                                    tiles[x, y].actuator = false;
                                    tiles[x, y].inactive = false;
                                    tiles[x, y].color = 0;
                                    tiles[x, y].wallColor = 0;
                                }
                            SendMessage(8); //request initial tile data
                        }
                        chests.Clear();
                        signs.Clear();
                        npcs.Clear();
                        loadPlayerMap();
                    }
                    break;
                case 0x08: //request initial tile data - c2s only
                    break;
                case 0x09: //status text
                    {
                        statusTotal = BitConverter.ToInt32(messages, payload); payload += 4;
                        statusCount = 0;
                        status = Encoding.ASCII.GetString(messages, payload, start + len - payload);
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                        {
                            serverText.Text = status;
                        }));
                    }
                    break;
                case 0x0a: //tile row data
                    {
                        int width = BitConverter.ToInt16(messages, payload); payload += 2;
                        int startx = BitConverter.ToInt32(messages, payload); payload += 4;
                        int y = BitConverter.ToInt32(messages, payload); payload += 4;
                        for (int x = startx; x < startx + width; x++)
                        {
                            Tile tile = tiles[x, y];
                            byte flags = messages[payload++];
                            byte flags2 = messages[payload++];
                            tile.isActive = (flags & 1) == 1;
                            tile.hasRedWire = (flags & 16) == 16;
                            tile.half = (flags & 32) == 32;
                            tile.actuator = (flags & 64) == 64;
                            tile.inactive = (flags & 128) == 128;
                            tile.hasGreenWire = (flags2 & 1) == 1;
                            tile.hasBlueWire = (flags2 & 2) == 2;
                            tile.slope = (byte)((flags2 & 0x30) >> 4);
                            if ((flags2 & 4) == 4)
                                tile.color = messages[payload++];
                            else
                                tile.color = 0;
                            if ((flags2 & 8) == 8)
                                tile.wallColor = messages[payload++];
                            else
                                tile.wallColor = 0;
                            if (tile.isActive)
                            {
                                tile.type = messages[payload++];
                                if (tileInfos[tile.type].hasExtra)
                                {
                                    tile.u = BitConverter.ToInt16(messages, payload); payload += 2;
                                    tile.v = BitConverter.ToInt16(messages, payload); payload += 2;
                                }
                                else
                                {
                                    tile.u = -1;
                                    tile.v = -1;
                                }
                            }
                            if ((flags & 4) == 4)
                            {
                                tile.wall = messages[payload++];
                                tile.wallu = -1;
                                tile.wallv = -1;
                            }
                            else
                                tile.wall = 0;
                            if ((flags & 8) == 8)
                            {
                                tile.liquid = messages[payload++];
                                tile.isLava = messages[payload] == 1;
                                tile.isHoney = messages[payload] == 2;
                                payload++;
                            }
                            else
                                tile.liquid = 0;
                            int rle = BitConverter.ToInt16(messages, payload); payload += 2;
                            for (int r = x + 1; r < x + 1 + rle; r++)
                            {
                                tiles[r, y].isActive = tiles[x, y].isActive;
                                tiles[r, y].type = tiles[x, y].type;
                                tiles[r, y].u = tiles[x, y].u;
                                tiles[r, y].v = tiles[x, y].v;
                                tiles[r, y].wall = tiles[x, y].wall;
                                tiles[r, y].wallu = -1;
                                tiles[r, y].wallv = -1;
                                tiles[r, y].liquid = tiles[x, y].liquid;
                                tiles[r, y].isLava = tiles[x, y].isLava;
                                tiles[r, y].isHoney = tiles[x, y].isHoney;
                                tiles[r, y].hasRedWire = tiles[x, y].hasRedWire;
                                tiles[r, y].hasGreenWire = tiles[x, y].hasGreenWire;
                                tiles[r, y].hasBlueWire = tiles[x, y].hasBlueWire;
                                tiles[r, y].half = tiles[x, y].half;
                                tiles[r, y].actuator = tiles[x, y].actuator;
                                tiles[r, y].inactive = tiles[x, y].inactive;
                                tiles[r, y].slope = tiles[x, y].slope;
                                tiles[r, y].color = tiles[x, y].color;
                                tiles[r, y].wallColor = tiles[x, y].wallColor;
                            }
                            x += rle;
                        }
                    }
                    break;
                case 0x0b: //recalculate u/v
                    {
                        int startx = BitConverter.ToInt16(messages, payload); payload += 4;
                        int starty = BitConverter.ToInt16(messages, payload); payload += 4;
                        int endx = BitConverter.ToInt16(messages, payload); payload += 2;
                        int endy = BitConverter.ToInt16(messages, payload);

                        for (int y = starty; y <= endy; y++)
                            for (int x = startx; x <= endx; x++)
                                sentSections[x, y] = true;

                        startx *= 200;
                        starty *= 150;
                        endx = (endx + 1) * 200;
                        endy = (endy + 1) * 150;

                        for (int y = starty; y < endy; y++)
                            for (int x = startx; x < endx; x++)
                            {
                                Tile tile = tiles[x, y];
                                if (tile.isActive && !tileInfos[tile.type].hasExtra)
                                {
                                    tile.u = -1;
                                    tile.v = -1;
                                }
                                if (tile.wall > 0)
                                {
                                    tile.wallu = -1;
                                    tile.wallv = -1;
                                }
                            }
                        if (loginLevel == 5)
                            fetchNextSection();
                    }
                    break;
                case 0x0c: //player spawned
                    break;
                case 0x0d: //player control
                    break;
                case 0x0e: //set active players
                    break;
                case 0x10: //player life
                    break;
                case 0x11: //modify tile
                    break;
                case 0x12: //set time
                    break;
                case 0x13: //open/close door
                    break;
                case 0x14: //update tile block
                    break;
                case 0x15: //update item
                    break;
                case 0x16: //set item owner
                    break;
                case 0x17: //update NPC
                    {
                        int slot = BitConverter.ToInt16(messages, payload); payload += 2;
                        float posx = BitConverter.ToSingle(messages, payload); payload += 4;
                        float posy = BitConverter.ToSingle(messages, payload); payload += 4;
                        payload += 9; //skip velocity and target
                        byte flags = messages[payload++];
                        payload += 4; //skip life
                        //skip any applicable AI
                        if ((flags & 32) == 32) payload += 4;
                        if ((flags & 16) == 16) payload += 4;
                        if ((flags & 8) == 8) payload += 4;
                        if ((flags & 4) == 4) payload += 4;
                        int id = BitConverter.ToInt16(messages, payload);
                        bool found = false;
                        for (int i = 0; i < npcs.Count; i++)
                        {
                            if (npcs[i].slot == slot)
                            {
                                npcs[i].x = posx;
                                npcs[i].y = posy;
                                npcs[i].sprite = id;
                                found = true;
                                addNPCToMenu(npcs[i]);
                            }
                        }
                        if (!found)
                        {
                            for (int i = 0; i < friendlyNPCs.Length; i++)
                                if (friendlyNPCs[i].id == id) //we found a friendly npc
                                {
                                    NPC npc = new NPC();
                                    npc.isHomeless = true; //homeless for now
                                    npc.title = friendlyNPCs[i].title;
                                    npc.name = "";
                                    npc.num = friendlyNPCs[i].num;
                                    npc.sprite = id;
                                    npc.x = posx;
                                    npc.y = posy;
                                    npc.slot = slot;
                                    npcs.Add(npc);
                                    addNPCToMenu(npc);
                                }
                        }
                    }
                    break;
                case 0x18: //strike npc
                    break;
                case 0x19: //chat
                    break;
                case 0x1a: //damage player
                    break;
                case 0x1b: //update projectile
                    break;
                case 0x1c: //damage npc
                    break;
                case 0x1d: //destroy projectile
                    break;
                case 0x1e: //pvp toggled
                    break;
                case 0x1f: //request open chest - c2s only
                    break;
                case 0x20: //set chest item
                    break;
                case 0x21: //open chest
                    break;
                case 0x22: //destroy chest
                    break;
                case 0x23: //heal player
                    break;
                case 0x24: //set zones
                    break;
                case 0x25: //request password.
                    {
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                        {
                            ServerPassword s = new ServerPassword();
                            if (s.ShowDialog() == true)
                                SendMessage(0x26, s.Password);
                            else
                            {
                                socket.Close();
                                serverText.Text = "Login cancelled.";
                                busy = false;
                            }
                        }));
                    }
                    break;
                case 0x26: //login - c2s only
                    break;
                case 0x27: //unassign item
                    break;
                case 0x28: //talk to npc
                    break;
                case 0x29: //animate flail
                    break;
                case 0x2a: //set mana
                    break;
                case 0x2b: //replenish mana
                    break;
                case 0x2c: //kill player
                    break;
                case 0x2d: //change party
                    break;
                case 0x2e: //read sign - c2s only
                    break;
                case 0x2f: //edit sign
                    break;
                case 0x30: //adjust liquids
                    break;
                case 0x31: //okay to spawn
                    if (loginLevel == 4)
                    {
                        loginLevel = 5;
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                            {
                                serverText.Text = "";
                                render.SetWorld(tilesWide, tilesHigh, groundLevel, rockLevel, styles, treeX, treeStyle, caveBackX, caveBackStyle, jungleBackStyle, hellBackStyle, npcs);
                                loaded = true;
                                curX = spawnX;
                                curY = spawnY;
                                if (render.Textures != null && render.Textures.Valid)
                                {
                                    UseTextures.IsChecked = true;
                                    curScale = 16.0;
                                }
                                RenderMap();
                            }));
                        SendMessage(0x0c); //spawn
                        if (tilesWide == 8400) //large world
                        {
                            //give the user a choice to map a remote large world
                            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                            {
                                if (MessageBox.Show(this, "Mapping remote large worlds is not recommend.\nContinue to map the rest of the world?", "Map Whole World",
                                MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                                {
                                    fetchNextSection(); //start fetching the world
                                }
                                else
                                {
                                    socket.Close();
                                    busy = false;
                                }
                            }));
                        }
                        else
                            fetchNextSection(); //start fetching the world
                    }
                    break;
                case 0x32: //set buffs
                    break;
                case 0x33: //old man answer
                    break;
                case 0x34: //unlock chest
                    break;
                case 0x35: //add npc buff
                    break;
                case 0x36: //set npc buffs
                    break;
                case 0x37: //add player buff
                    break;
                case 0x38: //set npc names
                    {
                        int id = BitConverter.ToInt16(messages, payload); payload += 2;
                        string name = Encoding.ASCII.GetString(messages, payload, start + len - payload);
                        for (int i = 0; i < npcs.Count; i++)
                        {
                            if (npcs[i].sprite == id)
                            {
                                npcs[i].name = name;
                                addNPCToMenu(npcs[i]);
                            }
                        }
                    }
                    break;
                case 0x39: //set balance stats
                    break;
                case 0x3a: //play harp
                    break;
                case 0x3b: //flip switch
                    break;
                case 0x3c: //move npc home
                    {
                        int slot = BitConverter.ToInt16(messages, payload); payload += 2;
                        int x = BitConverter.ToInt16(messages, payload); payload += 2;
                        int y = BitConverter.ToInt16(messages, payload); payload += 2;
                        byte homeless = messages[payload];
                        for (int i = 0; i < npcs.Count; i++)
                        {
                            if (npcs[i].slot == slot)
                            {
                                npcs[i].isHomeless = homeless == 1;
                                npcs[i].homeX = x;
                                npcs[i].homeY = y;
                                addNPCToMenu(npcs[i]);
                                break;
                            }
                        }
                    }
                    break;
                case 0x3d: //summon boss
                    break;
                case 0x3e: //ninja dodge
                    break;
                case 0x3f: //paint tile
                    break;
                case 0x40: //paint wall
                    break;
                case 0x41: //teleport npc
                    break;
                case 0x42: //heal player
                    break;
                case 0x44: //unknown
                    break;
                default: // ignore unknown messages
                    break;
            }
        }
Exemplo n.º 2
0
        private void HandleMessage(int start, int len)
        {
            if (statusTotal > 0)
            {
                statusCount++;
                if (statusCount == statusTotal)
                    statusTotal = 0;
                else
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                {
                    serverText.Text = ((int)((float)statusCount * 100.0 / (float)statusTotal)) + "% - " + status;
                }));
            }
            int messageid = messages[start++];
            len--;
            int payload = start;
            switch (messageid)
            {
                case 0x01: // connect request - c2s only
                    break;
                case 0x02: //error
                    {
                        string error = Encoding.ASCII.GetString(messages, payload, len);
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                            {
                                MessageBox.Show(error);
                            }));
                        socket.Close();
                        busy = false;
                    }
                    break;
                case 0x03: //connection approved
                    {
                        if (loginLevel == 1) loginLevel = 2;
                        playerSlot = messages[payload];
                        SendMessage(4);
                        SendMessage(0x10);
                        SendMessage(0x2a);
                        //send buffs
                        //send inventory
                        SendMessage(6);
                        if (loginLevel == 2) loginLevel = 3;
                    }
                    break;
                case 0x04: //player appearance
                    //ignore other players
                    break;
                case 0x05: //inventory items
                    //ignore player inventory
                    break;
                case 0x06: //request world info - c2s only
                    break;
                case 0x07: //world info
                    {
                        gameTime = BitConverter.ToInt32(messages, payload); payload += 4;
                        dayNight = messages[payload++] == 1;
                        moonPhase = messages[payload++];
                        bloodMoon = messages[payload++] == 1;
                        tilesWide = BitConverter.ToInt32(messages, payload); payload += 4;
                        tilesHigh = BitConverter.ToInt32(messages, payload); payload += 4;
                        spawnX = BitConverter.ToInt32(messages, payload); payload += 4;
                        spawnY = BitConverter.ToInt32(messages, payload); payload += 4;
                        groundLevel = BitConverter.ToInt32(messages, payload); payload += 4;
                        rockLevel = BitConverter.ToInt32(messages, payload); payload += 4;
                        payload += 4; //skip world id
                        byte flags = messages[payload++];
                        string title = Encoding.ASCII.GetString(messages, payload, start + len - payload);
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                        {
                            Title = title;
                        }));
                        smashedOrb = (flags & 1) == 1;
                        killedBoss1 = (flags & 2) == 2;
                        killedBoss2 = (flags & 4) == 4;
                        killedBoss3 = (flags & 8) == 8;
                        hardMode = (flags & 16) == 16;
                        killedClown = (flags & 32) == 32;
                        meteorSpawned = false;
                        killedFrost = false;
                        killedGoblins = false;
                        savedMechanic = false;
                        savedTinkerer = false;
                        savedWizard = false;
                        goblinsDelay = 0;
                        altarsSmashed = 0;
                        ResizeMap();
                        if (loginLevel == 3)
                        {
                            sectionsWide = (tilesWide / 200);
                            sectionsHigh = (tilesHigh / 150);
                            sentSections = new bool[sectionsWide, sectionsHigh];
                            loginLevel = 4;
                            for (int y = 0; y < tilesHigh; y++) //set all tiles to blank
                                for (int x = 0; x < tilesWide; x++)
                                {
                                    tiles[x, y].isActive = false;
                                    tiles[x, y].wall = 0;
                                    tiles[x, y].liquid = 0;
                                    tiles[x, y].hasWire = false;
                                }
                            SendMessage(8); //request initial tile data
                        }
                    }
                    break;
                case 0x08: //request initial tile data - c2s only
                    break;
                case 0x09: //status text
                    {
                        statusTotal = BitConverter.ToInt32(messages, payload); payload += 4;
                        statusCount = 0;
                        status = Encoding.ASCII.GetString(messages, payload, start + len - payload);
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                        {
                            serverText.Text = status;
                        }));
                    }
                    break;
                case 0x0a: //tile row data
                    {
                        int width = BitConverter.ToInt16(messages, payload); payload += 2;
                        int startx = BitConverter.ToInt32(messages, payload); payload += 4;
                        int y = BitConverter.ToInt32(messages, payload); payload += 4;
                        for (int x = startx; x < startx + width; x++)
                        {
                            Tile tile = tiles[x, y];
                            byte flags = messages[payload++];
                            tile.isActive = (flags & 1) == 1;
                            tile.hasWire = (flags & 16) == 16;
                            if (tile.isActive)
                            {
                                tile.type = messages[payload++];
                                if (tileInfos[tile.type].hasExtra)
                                {
                                    tile.u = BitConverter.ToInt16(messages, payload); payload += 2;
                                    tile.v = BitConverter.ToInt16(messages, payload); payload += 2;
                                }
                                else
                                {
                                    tile.u = -1;
                                    tile.v = -1;
                                }
                            }
                            if ((flags & 4) == 4)
                            {
                                tile.wall = messages[payload++];
                                tile.wallu = -1;
                                tile.wallv = -1;
                            }
                            else
                                tile.wall = 0;
                            if ((flags & 8) == 8)
                            {
                                tile.liquid = messages[payload++];
                                tile.isLava = messages[payload++] == 1;
                            }
                            else
                                tile.liquid = 0;
                            int rle = BitConverter.ToInt16(messages, payload); payload += 2;
                            for (int r = x + 1; r < x + 1 + rle; r++)
                            {
                                tiles[r, y].isActive = tiles[x, y].isActive;
                                tiles[r, y].type = tiles[x, y].type;
                                tiles[r, y].u = tiles[x, y].u;
                                tiles[r, y].v = tiles[x, y].v;
                                tiles[r, y].wall = tiles[x, y].wall;
                                tiles[r, y].wallu = -1;
                                tiles[r, y].wallv = -1;
                                tiles[r, y].liquid = tiles[x, y].liquid;
                                tiles[r, y].isLava = tiles[x, y].isLava;
                                tiles[r, y].hasWire = tiles[x, y].hasWire;
                            }
                            x += rle;
                        }
                    }
                    break;
                case 0x0b: //recalculate u/v
                    {
                        int startx = BitConverter.ToInt32(messages, payload); payload += 4;
                        int starty = BitConverter.ToInt32(messages, payload); payload += 4;
                        int endx = BitConverter.ToInt32(messages, payload); payload += 4;
                        int endy = BitConverter.ToInt32(messages, payload);

                        for (int y = starty; y<= endy; y++)
                            for (int x = startx; x <= endx; x++)
                                sentSections[x, y] = true;

                        startx *= 200;
                        starty *= 150;
                        endx = (endx + 1) * 200;
                        endy = (endy + 1) * 150;

                        for (int y=starty;y<endy;y++)
                            for (int x = startx; x < endx; x++)
                            {
                                Tile tile = tiles[x, y];
                                if (tile.isActive && !tileInfos[tile.type].hasExtra)
                                {
                                    tile.u = -1;
                                    tile.v = -1;
                                }
                                if (tile.wall > 0)
                                {
                                    tile.wallu = -1;
                                    tile.wallv = -1;
                                }
                            }
                        if (loginLevel == 5)
                            fetchNextSection();
                    }
                    break;
                case 0x0c: //player spawned
                    break;
                case 0x0d: //player control
                    break;
                case 0x0e: //set active players
                    break;
                case 0x10: //player life
                    break;
                case 0x11: //modify tile
                    break;
                case 0x12: //set time
                    break;
                case 0x13: //open/close door
                    break;
                case 0x14: //update tile block
                    break;
                case 0x15: //update item
                    break;
                case 0x16: //set item owner
                    break;
                case 0x17: //update NPC
                    {
                        int slot = BitConverter.ToInt16(messages, payload); payload += 2;
                        float posx = BitConverter.ToSingle(messages, payload); payload += 4;
                        float posy = BitConverter.ToSingle(messages, payload); payload += 4;
                        payload += 32; //don't care about velocity, target, ai, or direction
                        int id = BitConverter.ToInt16(messages, payload);
                        bool found = false;
                        for (int i = 0; i < npcs.Count; i++)
                        {
                            if (npcs[i].slot == slot)
                            {
                                npcs[i].x = posx;
                                npcs[i].y = posy;
                                npcs[i].sprite = id;
                                found = true;
                                addNPCToMenu(npcs[i]);
                            }
                        }
                        if (!found)
                        {
                            for (int i = 0; i < friendlyNPCs.Length; i++)
                                if (friendlyNPCs[i].id == id) //we found a friendly npc
                                {
                                    NPC npc = new NPC();
                                    npc.isHomeless = true; //homeless for now
                                    npc.title = friendlyNPCs[i].title;
                                    npc.name = "";
                                    npc.num = friendlyNPCs[i].num;
                                    npc.sprite = id;
                                    npc.x = posx;
                                    npc.y = posy;
                                    npc.slot = slot;
                                    npcs.Add(npc);
                                    addNPCToMenu(npc);
                                }
                        }
                    }
                    break;
                case 0x18: //strike npc
                    break;
                case 0x19: //chat
                    break;
                case 0x1a: //damage player
                    break;
                case 0x1b: //update projectile
                    break;
                case 0x1c: //damage npc
                    break;
                case 0x1d: //destroy projectile
                    break;
                case 0x1e: //pvp toggled
                    break;
                case 0x1f: //request open chest - c2s only
                    break;
                case 0x20: //set chest item
                    break;
                case 0x21: //open chest
                    break;
                case 0x22: //destroy chest
                    break;
                case 0x23: //heal player
                    break;
                case 0x24: //set zones
                    break;
                case 0x25: //request password.
                    {
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                        {
                            ServerPassword s = new ServerPassword();
                            if (s.ShowDialog() == true)
                                SendMessage(0x26, s.Password);
                            else
                            {
                                socket.Close();
                                serverText.Text = "Login cancelled.";
                                busy = false;
                            }
                        }));
                    }
                    break;
                case 0x26: //login - c2s only
                    break;
                case 0x27: //unassign item
                    break;
                case 0x28: //talk to npc
                    break;
                case 0x29: //animate flail
                    break;
                case 0x2a: //set mana
                    break;
                case 0x2b: //replenish mana
                    break;
                case 0x2c: //kill player
                    break;
                case 0x2d: //change party
                    break;
                case 0x2e: //read sign - c2s only
                    break;
                case 0x2f: //edit sign
                    break;
                case 0x30: //adjust liquids
                    break;
                case 0x31: //okay to spawn
                    if (loginLevel == 4)
                    {
                        loginLevel = 5;
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                            {
                                serverText.Text = "";
                                render.SetWorld(tilesWide, tilesHigh, groundLevel, rockLevel, npcs);
                                loaded = true;
                                curX = spawnX;
                                curY = spawnY;
                                if (render.Textures!=null && render.Textures.Valid)
                                {
                                    UseTextures.IsChecked = true;
                                    curScale = 16.0;
                                }
                                RenderMap();
                            }));
                        SendMessage(0x0c); //spawn
                        if (tilesWide == 8400) //large world
                        {
                            socket.Close();
                            busy = false;
                            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
                            {
                                MessageBox.Show("Will not map remote large worlds\nother than the spawn point");
                            }));
                        }
                        else
                            fetchNextSection(); //start fetching the world
                    }
                    break;
                case 0x32: //set buffs
                    break;
                case 0x33: //old man answer
                    break;
                case 0x34: //unlock chest
                    break;
                case 0x35: //add npc buff
                    break;
                case 0x36: //set npc buffs
                    break;
                case 0x37: //add player buff
                    break;
                case 0x38: //set npc names
                    {
                        int id = BitConverter.ToInt16(messages, payload); payload += 2;
                        string name = Encoding.ASCII.GetString(messages, payload, start + len - payload);
                        for (int i = 0; i < npcs.Count; i++)
                        {
                            if (npcs[i].sprite == id)
                            {
                                npcs[i].name = name;
                                addNPCToMenu(npcs[i]);
                            }
                        }
                    }
                    break;
                case 0x39: //set balance stats
                    break;
                case 0x3a: //play harp
                    break;
                case 0x3b: //flip switch
                    break;
                case 0x3c: //move npc home
                    {
                        int slot=BitConverter.ToInt16(messages,payload); payload+=2;
                        int x=BitConverter.ToInt16(messages,payload); payload+=2;
                        int y=BitConverter.ToInt16(messages,payload); payload+=2;
                        byte homeless=messages[payload];
                        for (int i = 0; i < npcs.Count; i++)
                        {
                            if (npcs[i].slot == slot)
                            {
                                npcs[i].isHomeless = homeless == 1;
                                npcs[i].homeX = x;
                                npcs[i].homeY = y;
                                addNPCToMenu(npcs[i]);
                                break;
                            }
                        }
                    }
                    break;
                default: // ignore unknown messages
                    break;
            }
        }