Example #1
0
        private void ParseIndex(Stream stream, int i)
        {
            using (var br = new BinaryReader(stream))
            {
                stream.Seek(-12, SeekOrigin.End);
                int count = br.ReadInt32();
                stream.Seek(0, SeekOrigin.Begin);

                if (count * (16 + 4 + 4) > stream.Length)
                    throw new Exception("ParseIndex failed");

                for (int j = 0; j < count; ++j)
                {
                    byte[] key = br.ReadBytes(16);

                    if (key.IsZeroed()) // wtf?
                        key = br.ReadBytes(16);

                    if (key.IsZeroed()) // wtf?
                        throw new Exception("key.IsZeroed()");

                    IndexEntry entry = new IndexEntry();
                    entry.Index = i;
                    entry.Size = br.ReadInt32BE();
                    entry.Offset = br.ReadInt32BE();

                    CDNIndexData.Add(key, entry);
                }
            }
        }
        public static ShapefileHeader Read(BinaryReader reader)
        {
            ShapefileHeader header = new ShapefileHeader();

            int fileType = reader.ReadInt32BE();
            if (fileType != 9994)
                throw new Exception("The first four bytes of this file indicate this is not a shape file.");

            // skip 5 unsed bytes
            reader.BaseStream.Seek(20L, SeekOrigin.Current);

            header.FileLength = reader.ReadInt32BE();

            int version = reader.ReadInt32();
            if (version != 1000)
                throw new Exception("Shapefile is not the proper version");

            header.ShapeType = (ShapefileGeometryType)reader.ReadInt32();

            double[] coords = new double[4];
            for (int i = 0; i < 4; i++)
                coords[i] = reader.ReadDouble();
            header.Bounds = new Envelope(coords[0], coords[2], coords[1], coords[3]);

            // Skip to end of header
            reader.BaseStream.Seek(100L, SeekOrigin.Begin);

            return header;
        }
Example #3
0
        public Sample(BinaryReader reader)
            : this()
        {
            SourceStart = reader.ReadInt32BE();
            SourceLength = reader.ReadUInt16BE()*2;
            LoopStart = reader.ReadInt32BE();

            Data = new byte[SourceLength];
        }
Example #4
0
        public InstallHandler(BinaryReader stream, BackgroundWorkerEx worker)
        {
            worker?.ReportProgress(0, "Loading \"install\"...");

            stream.ReadBytes(2); // IN

            byte b1 = stream.ReadByte();
            byte b2 = stream.ReadByte();
            short numTags = stream.ReadInt16BE();
            int numFiles = stream.ReadInt32BE();

            int numMaskBytes = (numFiles + 7) / 8;

            List<InstallTag> Tags = new List<InstallTag>();

            for (int i = 0; i < numTags; i++)
            {
                InstallTag tag = new InstallTag();
                tag.Name = stream.ReadCString();
                tag.Type = stream.ReadInt16BE();

                byte[] bits = stream.ReadBytes(numMaskBytes);

                for (int j = 0; j < numMaskBytes; j++)
                    bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023);

                tag.Bits = new BitArray(bits);

                Tags.Add(tag);
            }

            for (int i = 0; i < numFiles; i++)
            {
                InstallEntry entry = new InstallEntry();
                entry.Name = stream.ReadCString();
                entry.MD5 = stream.ReadBytes(16);
                entry.Size = stream.ReadInt32BE();

                InstallData.Add(entry);

                entry.Tags = Tags.FindAll(tag => tag.Bits[i]);

                worker?.ReportProgress((int)((i + 1) / (float)numFiles * 100));
            }
        }
Example #5
0
        public InstallHandler(BinaryReader stream)
        {
            stream.ReadBytes(2); // IN

            byte b1 = stream.ReadByte();
            byte b2 = stream.ReadByte();
            short numTags = stream.ReadInt16BE();
            int numFiles = stream.ReadInt32BE();
            int numMaskBytes = (numFiles + 7) / 8;

            List<InstallTag> Tags = new List<InstallTag>();

            for (int i = 0; i < numTags; i++)
            {
                InstallTag tag = new InstallTag();
                tag.Name = stream.ReadCString();
                tag.Type = stream.ReadInt16BE();

                byte[] bits = stream.ReadBytes(numMaskBytes);

                for (int j = 0; j < numMaskBytes; j++)
                    bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023);

                tag.Bits = new BitArray(bits);
                Tags.Add(tag);
            }

            for (int i = 0; i < numFiles; i++)
            {
                InstallEntry entry = new InstallEntry();
                entry.Name = stream.ReadCString();
                entry.MD5 = stream.Read<MD5Hash>();
                entry.Size = stream.ReadInt32BE();

                InstallData.Add(entry);

                entry.Tags = Tags.FindAll(tag => tag.Bits[i]);
            }
        }
        public static void ValidateIndex(string shapefilePath)
        {
            string indexPath = Path.ChangeExtension(shapefilePath, ".shx");

            int posShouldBe = 50, recordNum = 1;
            using (BinaryReader shape = new BinaryReader(new FileStream(shapefilePath, FileMode.Open)))
            using (BinaryReader index = new BinaryReader(new FileStream(indexPath, FileMode.Open)))
            {
                ShapefileHeader shapeHeader = ShapefileHeader.Read(shape);
                ShapefileHeader indexHeader = ShapefileHeader.Read(index);

                if (shapeHeader.FileLength * 2 != new FileInfo(shapefilePath).Length)
                    Console.WriteLine("length");

                if (indexHeader.FileLength * 2 != new FileInfo(indexPath).Length)
                    Console.WriteLine("length");

                while (index.BaseStream.Position < index.BaseStream.Length)
                {
                    int filePos = index.ReadInt32BE();

                    if (filePos != posShouldBe)
                        Console.WriteLine("Ding");

                    int indexContentLength = index.ReadInt32BE();

                    shape.BaseStream.Seek(filePos * 2, SeekOrigin.Begin);

                    int shapeRecordNumber = shape.ReadInt32BE();
                    int shapeContentLength = shape.ReadInt32BE();

                    if (shapeRecordNumber != recordNum++ || shapeContentLength != indexContentLength)
                        Console.WriteLine("Ding");

                    posShouldBe += indexContentLength + 4;
                }
            }
        }
        public DownloadHandler(BinaryReader stream, BackgroundWorkerEx worker)
        {
            worker?.ReportProgress(0, "Loading \"download\"...");

            stream.Skip(2); // DL

            byte b1 = stream.ReadByte();
            byte b2 = stream.ReadByte();
            byte b3 = stream.ReadByte();

            int numFiles = stream.ReadInt32BE();

            short numTags = stream.ReadInt16BE();

            int numMaskBytes = (numFiles + 7) / 8;

            for (int i = 0; i < numFiles; i++)
            {
                MD5Hash key = stream.Read<MD5Hash>();

                //byte[] unk = stream.ReadBytes(0xA);
                stream.Skip(0xA);

                //var entry = new DownloadEntry() { Index = i, Unk = unk };
                var entry = new DownloadEntry() { Index = i };

                DownloadData.Add(key, entry);

                worker?.ReportProgress((int)((i + 1) / (float)numFiles * 100));
            }

            for (int i = 0; i < numTags; i++)
            {
                DownloadTag tag = new DownloadTag();
                string name = stream.ReadCString();
                tag.Type = stream.ReadInt16BE();

                byte[] bits = stream.ReadBytes(numMaskBytes);

                for (int j = 0; j < numMaskBytes; j++)
                    bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023);

                tag.Bits = new BitArray(bits);

                Tags.Add(name, tag);
            }
        }
Example #8
0
        private void ParseIndex(string idx)
        {
            using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            using (var br = new BinaryReader(fs))
            {
                int h2Len = br.ReadInt32();
                int h2Check = br.ReadInt32();
                byte[] h2 = br.ReadBytes(h2Len);

                long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0;
                fs.Position = padPos;

                int dataLen = br.ReadInt32();
                int dataCheck = br.ReadInt32();

                int numBlocks = dataLen / 18;

                for (int i = 0; i < numBlocks; i++)
                {
                    IndexEntry info = new IndexEntry();
                    byte[] key = br.ReadBytes(9);
                    byte indexHigh = br.ReadByte();
                    int indexLow = br.ReadInt32BE();

                    info.Index = (indexHigh << 2 | (byte)((indexLow & 0xC0000000) >> 30));
                    info.Offset = (indexLow & 0x3FFFFFFF);
                    info.Size = br.ReadInt32();

                    // duplicate keys wtf...
                    //IndexData[key] = info; // use last key
                    if (!LocalIndexData.ContainsKey(key)) // use first key
                        LocalIndexData.Add(key, info);
                }

                padPos = (dataLen + 0x0FFF) & 0xFFFFF000;
                fs.Position = padPos;

                fs.Position += numBlocks * 18;
                //for (int i = 0; i < numBlocks; i++)
                //{
                //    var bytes = br.ReadBytes(18); // unknown data
                //}

                //if (fs.Position != fs.Length)
                //    throw new Exception("idx file under read");
            }
        }
Example #9
0
        public DownloadHandler(BinaryReader stream)
        {
            stream.Skip(2); // DL

            byte b1 = stream.ReadByte();
            byte b2 = stream.ReadByte();
            byte b3 = stream.ReadByte();

            int numFiles = stream.ReadInt32BE();

            short numTags = stream.ReadInt16BE();

            int numMaskBytes = numFiles / 8 + (numFiles % 8 > 0 ? 1 : 0);

            for (int i = 0; i < numFiles; i++)
            {
                byte[] key = stream.ReadBytes(0x10);
                byte[] unk = stream.ReadBytes(0xA);
                DownloadEntry entry = new DownloadEntry() { Index = i, Unk = unk };

                DownloadData.Add(key, entry);
            }

            for (int i = 0; i < numTags; i++)
            {
                DownloadTag tag = new DownloadTag();
                string name = stream.ReadCString();
                tag.Type = stream.ReadInt16BE();

                byte[] bits = stream.ReadBytes(numMaskBytes);

                for (int j = 0; j < numMaskBytes; j++)
                    bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023);

                tag.Bits = new BitArray(bits);

                Tags.Add(name, tag);
            }
        }
Example #10
0
        public SonicArrangerFile(Stream stream)
        {
            var reader = new BinaryReader(stream, Encoding.ASCII);
            string soar = new string(reader.ReadChars(4));
            if(soar != "SOAR")
            {
                stream.Position = 0;
                long start = ReadTo(reader, pcstart);
                int songptr = 0x28;
                int ovtbptr = reader.ReadInt32BE();
                int notbptr = reader.ReadInt32BE();
                int intbptr = reader.ReadInt32BE();
                int syntptr = reader.ReadInt32BE();

                stream.Position = start+songptr;
                int songs = (ovtbptr-songptr)/12;
                Songs = new Song[songs];
                for(int i = 0; i < songs; i++)
                {
                    Songs[i] = new Song(reader);
                }

                stream.Position = start+ovtbptr;
                int voices = (notbptr-ovtbptr)/4;
                Voices = new Voice[voices];
                for(int i = 0; i < voices; i++)
                {
                    Voices[i] = new Voice(reader);
                }

                stream.Position = start+notbptr;
                int notes = (intbptr-notbptr)/4;
                Notes = new Note[notes];
                for(int i = 0; i < notes; i++)
                {
                    Notes[i] = new Note(reader);
                }

                stream.Position = start+intbptr;
                int instrs = (syntptr-intbptr)/152;
                Instruments = new Instrument[instrs];
                for(int i = 0; i < instrs; i++)
                {
                    Instruments[i] = new Instrument(reader);
                }
            }else{
                Version = new string(reader.ReadChars(4));

                string tag;
                while(true)
                {
                    tag = new string(reader.ReadChars(4));
                    switch(tag)
                    {
                        case "STBL":
                            Songs = new SongTable(reader).Songs;
                            break;
                        case "OVTB":
                            Voices = new OverTable(reader).Voices;
                            break;
                        case "NTBL":
                            Notes = new NoteTable(reader).Notes;
                            break;
                        case "INST":
                            Instruments = new InstrumentTable(reader).Instruments;
                            break;
                        default:
                            return;
                    }
                }
            }
        }
Example #11
0
 public SongTable(BinaryReader reader)
 {
     Count = reader.ReadInt32BE();
     Songs = new Song[Count];
     for(int i = 0; i < Count; i++)
     {
         Songs[i] = new Song(reader);
     }
 }
Example #12
0
 public OverTable(BinaryReader reader)
 {
     Count = reader.ReadInt32BE();
     Voices = new Voice[Count*4];
     for(int i = 0; i < Count*4; i++)
     {
         Voices[i] = new Voice(reader);
     }
 }
Example #13
0
 public NoteTable(BinaryReader reader)
 {
     Count = reader.ReadInt32BE();
     Notes = new Note[Count];
     for(int i = 0; i < Count; i++)
     {
         Notes[i] = new Note(reader);
     }
 }
Example #14
0
 public InstrumentTable(BinaryReader reader)
 {
     Count = reader.ReadInt32BE();
     Instruments = new Instrument[Count];
     for(int i = 0; i < Count; i++)
     {
         Instruments[i] = new Instrument(reader);
     }
 }
Example #15
0
        public static Texture LoadPng(Stream stream)
        {
            List<byte> idat = new List<byte> ();
            byte bitDepth = 0;
            ColorType colorType = ColorType.Grayscale;
            ByteColor[] palette = null;
            int width = 0, height = 0;
            using (var reader = new BinaryReader (stream)) {
                if (reader.ReadUInt64 () != PNG_SIGNATURE) {
                    throw new Exception ("Not a PNG file");
                }
                string chunktype = "";
                byte[] typeBuf = new byte[4];
                while (chunktype != "IEND") {
                    var length = reader.ReadInt32BE ();
                    reader.Read (typeBuf, 0, 4);
                    chunktype = Encoding.ASCII.GetString (typeBuf);
                    switch (chunktype) {
                    case "IHDR":
                        width = reader.ReadInt32BE ();
                        height = reader.ReadInt32BE ();
                        bitDepth = reader.ReadByte ();
                        colorType = (ColorType)reader.ReadByte ();
                        if (reader.ReadByte () != 0) {
                            throw new Exception (); //Compression method
                        }
                        if (reader.ReadByte () != 0) {
                            throw new Exception (); //Filter method
                        }
                        if (reader.ReadByte () != 0) {
                            throw new NotImplementedException (); //Interlacing
                        }
                        break;
                    case "PLTE":
                        if (length % 3 != 0)
                            throw new Exception (); //Invalid Palette
                        int count = length / 3;
                        palette = new ByteColor[length / 3];
                        for (int i = 0; i < count; i++) {
                            palette [i] = new ByteColor (
                                reader.ReadByte (),
                                reader.ReadByte (),
                                reader.ReadByte (),
                                255);
                        }
                        break;
                    case "tRNS":
                        if (colorType == ColorType.Palette) {
                            for (int i = 0; i < length; i++) {
                                palette [i].A = reader.ReadByte ();
                            }
                        } else {
                            throw new NotImplementedException (); //Are the others BigEndian? Investigate
                        }
                        break;
                    case "IDAT":
                        idat.AddRange (reader.ReadBytes (length));
                        break;
                    default:
                        reader.BaseStream.Seek (length, SeekOrigin.Current);
                        break;
                    }
                    reader.BaseStream.Seek (4, SeekOrigin.Current); //Skip CRC
                }
            }
            byte[] decompressedBytes = null;
            using (var compressedStream = new MemoryStream (idat.ToArray (), 2, idat.Count - 6)) { //skip zlib header
                using (var decompressedStream = new MemoryStream ()) {
                    try {
                        using (var deflateStream = new DeflateStream (compressedStream, CompressionMode.Decompress)) {
                            deflateStream.CopyTo (decompressedStream);
                        }
                        decompressedBytes = decompressedStream.ToArray ();
                    } catch (Exception exception) {
                        throw new Exception ("An error occurred during DEFLATE decompression.", exception);
                    }
                }

            }
            var scanlines = GetScanlines (decompressedBytes, bitDepth, colorType, width);
            var colors = GetData (scanlines, width, height, colorType, bitDepth, palette);
            var texture = new Texture (width, height);
            texture.SetData (colors, null);
            return texture;
        }
        public void run()
        {
            try
            {
                for (;;)
                {
                    if (!this.mParent.connectionAlive)
                    {
                        this.mParent.forceDisconnect("Connection Lost");
                        return;
                    }

                    if (this.mParent.kickTargetTimestamp != 0)
                    {
                        if (this.mParent.kickTargetTimestamp < Utils.getTimestamp())
                        {
                            this.mParent.forceDisconnect("Kicked from server");
                            return;
                        }
                        continue;
                    }

                    #region Process Packet
                    //Packet ID and Vaildity Check.
                    uint temp = this.mInput.ReadVarUInt32();
                    if (temp < 1 || temp > 48)
                    {
                        this.mParent.errorDisconnect(mDirection, "Sent invalid packet ID [" + temp + "].");
                        return;
                    }
                    Packet packetID = (Packet)temp;

                    //Packet Size and Compression Check.
                    bool compressed = false;
                    int packetSize = this.mInput.ReadVarInt32();
                    if (packetSize < 0)
                    {
                        packetSize = -packetSize;
                        compressed = true;
                    }

                    //Create buffer for forwarding
                    byte[] dataBuffer = this.mInput.ReadFully(packetSize);

                    //Do decompression
                    MemoryStream ms = new MemoryStream();
                    if (compressed)
                    {
                        ZlibStream compressedStream = new ZlibStream(new MemoryStream(dataBuffer), CompressionMode.Decompress);
                        byte[] buffer = new byte[32768];
                        for (;;)
                        {
                            int read = compressedStream.Read(buffer, 0, buffer.Length);
                            if (read <= 0)
                                break;
                            ms.Write(buffer, 0, read);
                        }
                        ms.Seek(0, SeekOrigin.Begin);
                    }
                    else
                    {
                        ms = new MemoryStream(dataBuffer);
                    }

                    //Create packet parser
                    BinaryReader packetData = new BinaryReader(ms);
                    #endregion

                    //Return data for packet processor
                    object returnData = true;

                    if (packetID != Packet.Heartbeat && packetID != Packet.UniverseTimeUpdate)
                    {
                        if (mDirection == Direction.Client)
                        #region Handle Client Packets
                        {
                            #region Protocol State Security
                            ClientState curState = this.mParent.clientState;
                            if (curState != ClientState.Connected)
                            {
                                if (curState == ClientState.PendingConnect && packetID != Packet.ClientConnect)
                                {
                                    this.mParent.forceDisconnect("Violated PendingConnect protocol state with " + packetID);
                                }
                                else if (curState == ClientState.PendingAuthentication && packetID != Packet.HandshakeResponse)
                                {
                                    this.mParent.forceDisconnect("Violated PendingAuthentication protocol state with " + packetID);
                                }
                                else if (curState == ClientState.PendingConnectResponse)
                                {
                                    this.mParent.forceDisconnect("Violated PendingConnectResponse protocol state with " + packetID);
                                }
                            }
                            #endregion

                            if (packetID == Packet.ChatSend)
                            {
                                returnData = new Packet11ChatSend(this.mParent, packetData, this.mDirection).onReceive();
                            }
                            else if (packetID == Packet.ClientConnect)
                            {
                                this.mParent.clientState = ClientState.PendingAuthentication;
                                returnData = new Packet7ClientConnect(this.mParent, packetData, this.mDirection).onReceive();
                                MemoryStream packet = new MemoryStream();
                                BinaryWriter packetWrite = new BinaryWriter(packet);

                                passwordSalt = Utils.GenerateSecureSalt();
                                packetWrite.WriteStarString("");
                                packetWrite.WriteStarString(passwordSalt);
                                packetWrite.WriteBE(StarryboundServer.config.passwordRounds);
                                this.mParent.sendClientPacket(Packet.HandshakeChallenge, packet.ToArray());
                            }
                            else if (packetID == Packet.HandshakeResponse)
                            {
                                string claimResponse = packetData.ReadStarString();
                                string passwordHash = packetData.ReadStarString();

                                string verifyHash = Utils.StarHashPassword(StarryboundServer.config.proxyPass, this.mParent.playerData.account + passwordSalt, StarryboundServer.config.passwordRounds);
                                if (passwordHash != verifyHash)
                                {
                                    this.mParent.rejectPreConnected("Your password was incorrect.");
                                }

                                this.mParent.clientState = ClientState.PendingConnectResponse;
                                returnData = false;
                            }
                            else if (packetID == Packet.WarpCommand)
                            {
                                uint warp = packetData.ReadUInt32BE();
                                WorldCoordinate coord = packetData.ReadStarWorldCoordinate();
                                string player = packetData.ReadStarString();
                                WarpType cmd = (WarpType)warp;
                                if (cmd == WarpType.WarpToHomePlanet)
                                {
                                    this.mParent.playerData.inPlayerShip = false;
                                }
                                else if (cmd == WarpType.WarpToOrbitedPlanet)
                                {
                                    this.mParent.playerData.inPlayerShip = false;
                                }
                                else if (cmd == WarpType.WarpToOwnShip)
                                {
                                    this.mParent.playerData.inPlayerShip = true;
                                }
                                else if (cmd == WarpType.WarpToPlayerShip)
                                {
                                    this.mParent.playerData.inPlayerShip = true;
                                }

                                StarryboundServer.logDebug("WarpCommand", "[" + this.mParent.playerData.client + "][" + warp + "]" + (coord != null ? "[" + coord.ToString() + "]" : "") + "[" + player + "]");
                            }
                            else if (packetID == Packet.ModifyTileList || packetID == Packet.DamageTileGroup || packetID == Packet.DamageTile || packetID == Packet.ConnectWire || packetID == Packet.DisconnectAllWires)
                            {
                                if (!this.mParent.playerData.canBuild) continue;
                                if (this.mParent.playerData.loc != null)
                                {
                                    string planetCheck = this.mParent.playerData.loc.ToString();
                                    string spawnPlanet = StarryboundServer.serverConfig.defaultWorldCoordinate;

                                    if (StarryboundServer.serverConfig.defaultWorldCoordinate.Split(':').Length == 5) spawnPlanet = spawnPlanet + ":0";

                                    if ((planetCheck == spawnPlanet) && !this.mParent.playerData.group.hasPermission("admin.spawnbuild") && !this.mParent.playerData.inPlayerShip)
                                    {
                                        continue;
                                    }
                                }
                            }
                        }
                        #endregion
                        else
                        #region Handle Server Packets
                        {
                            if (packetID == Packet.ChatReceive)
                            {
                                returnData = new Packet5ChatReceive(this.mParent, packetData, this.mDirection).onReceive();
                            }
                            else if (packetID == Packet.ProtocolVersion)
                            {
                                uint protocolVersion = packetData.ReadUInt32BE();
                                if (protocolVersion != StarryboundServer.ProtocolVersion)
                                {
                                    MemoryStream packet = new MemoryStream();
                                    BinaryWriter packetWrite = new BinaryWriter(packet);
                                    packetWrite.WriteBE(protocolVersion);
                                    this.mParent.sendClientPacket(Packet.ProtocolVersion, packet.ToArray());

                                    this.mParent.rejectPreConnected("Starrybound Server was unable to handle the parent server protocol version.");
                                    returnData = false;
                                }
                            }
                            else if (packetID == Packet.HandshakeChallenge)
                            {
                                string claimMessage = packetData.ReadString();
                                string passwordSalt = packetData.ReadStarString();
                                int passwordRounds = packetData.ReadInt32BE();

                                MemoryStream packet = new MemoryStream();
                                BinaryWriter packetWrite = new BinaryWriter(packet);
                                string passwordHash = Utils.StarHashPassword(StarryboundServer.config.serverPass, StarryboundServer.config.serverAccount + passwordSalt, passwordRounds);
                                packetWrite.WriteStarString("");
                                packetWrite.WriteStarString(passwordHash);
                                this.mParent.sendServerPacket(Packet.HandshakeResponse, packet.ToArray());

                                returnData = false;
                            }
                            else if (packetID == Packet.ConnectResponse)
                            {
                                while (this.mParent.clientState != ClientState.PendingConnectResponse) { } //TODO: needs timeout
                                returnData = new Packet2ConnectResponse(this.mParent, packetData, this.mDirection).onReceive();
                            }
                            else if (packetID == Packet.WorldStart)
                            {
                                if (!this.mParent.playerData.sentMotd)
                                {
                                    this.mParent.sendChatMessage(Config.GetMotd());
                                    this.mParent.playerData.sentMotd = true;
                                }

                                byte[] planet = packetData.ReadStarByteArray();
                                byte[] worldStructure = packetData.ReadStarByteArray();
                                byte[] sky = packetData.ReadStarByteArray();
                                byte[] serverWeather = packetData.ReadStarByteArray();
                                float spawnX = packetData.ReadSingleBE();
                                float spawnY = packetData.ReadSingleBE();
                                uint mapParamsSize = packetData.ReadVarUInt32();
                                Dictionary<string, object> mapParams = new Dictionary<string, object>();
                                for (int i = 0; i < mapParamsSize; i++)
                                {
                                    mapParams.Add(packetData.ReadStarString(), packetData.ReadStarVariant());
                                }
                                uint clientID = packetData.ReadUInt32BE();
                                bool bool1 = packetData.ReadBoolean();
                                WorldCoordinate coords = Utils.findGlobalCoords(sky);
                                if (coords != null)
                                {
                                    this.mParent.playerData.loc = coords;
                                    StarryboundServer.logDebug("WorldStart", "[" + this.mParent.playerData.client + "][" + bool1 + ":" + clientID + "] CurLoc:[" + this.mParent.playerData.loc.ToString() + "][" + this.mParent.playerData.inPlayerShip + "]");
                                }
                            }
                            else if (packetID == Packet.WorldStop)
                            {
                                string status = packetData.ReadStarString();
                            }
                            else if (packetID == Packet.GiveItem)
                            {
                                string name = packetData.ReadStarString();
                                uint count = packetData.ReadVarUInt32();
                                List<object> itemDesc = packetData.ReadStarVariant();
                            }
                            else if (packetID == Packet.EnvironmentUpdate)
                            {
                                byte[] sky = packetData.ReadStarByteArray();
                                byte[] serverWeather = packetData.ReadStarByteArray();
                                /*WorldCoordinate coords = Utils.findGlobalCoords(sky);
                                if (coords != null)
                                {
                                    this.mParent.playerData.loc = coords;
                                    StarryboundServer.logDebug("EnvUpdate", "[" + this.mParent.playerData.client + "] CurLoc:[" + this.mParent.playerData.loc.ToString() + "]");
                                }*/
                            }
                            else if (packetID == Packet.ClientContextUpdate)
                            {
                                try
                                {
                                    byte[] clientContextData = packetData.ReadStarByteArray();
                                    if (clientContextData.Length != 0)
                                    {
                                        BinaryReader clientContextReader = new BinaryReader(new MemoryStream(clientContextData));
                                        byte[] data = clientContextReader.ReadStarByteArray();
                                        if (data.Length > 8) //Should at least be more than 8 bytes for it to contain the data we want.
                                        {
                                            BinaryReader dataReader = new BinaryReader(new MemoryStream(data));
                                            byte dataBufferLength = dataReader.ReadByte();
                                            if (dataBufferLength == 2)
                                            {
                                                byte arrayLength = dataReader.ReadByte();
                                                if (arrayLength == 2 || arrayLength == 4) //Only observed these being used so far for what we want.
                                                {
                                                    byte dataType = dataReader.ReadByte(); //04 = String, 0E = CelestialLog
                                                    if (dataType == 4)
                                                    {
                                                        string string1 = dataReader.ReadStarString();
                                                        if (dataReader.BaseStream.Position != dataReader.BaseStream.Length)
                                                        {
                                                            if (string1 == "null")
                                                            {
                                                                byte[] worldHeader = dataReader.ReadStarByteArray(); //0008020A000C
                                                                byte[] worldData = dataReader.ReadStarByteArray();
                                                                byte typeByte = dataReader.ReadByte(); //0E = CelestialLog
                                                                if (typeByte == 14)
                                                                {
                                                                    Dictionary<string, WorldCoordinate> log = dataReader.ReadStarCelestialLog();
                                                                    log.TryGetValue("loc", out this.mParent.playerData.loc);
                                                                    if (!log.TryGetValue("home", out this.mParent.playerData.home))
                                                                        this.mParent.playerData.home = this.mParent.playerData.loc;
                                                                    StarryboundServer.logDebug("ClientContext", "[" + this.mParent.playerData.client + "] CurLoc:[" + this.mParent.playerData.loc.ToString() + "][" + this.mParent.playerData.inPlayerShip + "]");
                                                                    StarryboundServer.logDebug("ClientContext", "[" + this.mParent.playerData.client + "] CurHome:[" + this.mParent.playerData.home.ToString() + "]");
                                                                }
                                                            }
                                                        }
                                                    }
                                                    else if (dataType == 14)
                                                    {
                                                        Dictionary<string, WorldCoordinate> log = dataReader.ReadStarCelestialLog();
                                                        log.TryGetValue("loc", out this.mParent.playerData.loc);
                                                        if (!log.TryGetValue("home", out this.mParent.playerData.home))
                                                            this.mParent.playerData.home = this.mParent.playerData.loc;
                                                        StarryboundServer.logDebug("ClientContext", "[" + this.mParent.playerData.client + "] CurLoc:[" + this.mParent.playerData.loc.ToString() + "][" + this.mParent.playerData.inPlayerShip + "]");
                                                        StarryboundServer.logDebug("ClientContext", "[" + this.mParent.playerData.client + "] CurHome:[" + this.mParent.playerData.home.ToString() + "]");
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    StarryboundServer.logException("[" + this.mParent.playerData.client + "] Failed to parse ClientContextUpdate from Server: " + e.Message);
                                }
                            }
                        }
                        #endregion
                    }

                    #if DEBUG
                    if(packetID != Packet.Heartbeat)
                    {
                        //if (ms.Position != ms.Length)
                            //StarryboundServer.logDebug("ForwardThread", "[" + this.mParent.playerData.client + "] [" + this.mDirection.ToString() + "][" + packetID + "] failed parse (" + ms.Position + " != " + ms.Length + ")");
                        //StarryboundServer.logDebug("ForwardThread", "[" + this.mParent.playerData.client + "] [" + this.mDirection.ToString() + "][" + packetID + "] Dumping " + ms.Length + " bytes: " + Utils.ByteArrayToString(ms.ToArray()));
                    }
                    #endif

                    //Check return data
                    if (returnData is Boolean)
                    {
                        if ((Boolean)returnData == false) continue;
                    }
                    else if (returnData is int)
                    {
                        if ((int)returnData == -1)
                        {
                            this.mParent.forceDisconnect("Command processor requested to drop client");
                        }
                    }

                    #region Forward Packet
                    //Write data to dest
                    this.mOutput.WriteVarUInt32((uint)packetID);
                    if (compressed)
                    {
                        this.mOutput.WriteVarInt32(-packetSize);
                        this.mOutput.Write(dataBuffer, 0, packetSize);
                    }
                    else
                    {
                        this.mOutput.WriteVarInt32(packetSize);
                        this.mOutput.Write(dataBuffer, 0, packetSize);
                    }
                    this.mOutput.Flush();
                    #endregion

                    //If disconnect was forwarded to client, lets disconnect.
                    if(packetID == Packet.ServerDisconnect && mDirection == Direction.Server)
                    {
                        this.mParent.forceDisconnect();
                    }
                }
            }
            catch (EndOfStreamException)
            {
                this.mParent.forceDisconnect();
            }
            catch (Exception e)
            {
                this.mParent.errorDisconnect(mDirection, "ForwardThread Exception: " + e.ToString());
            }
        }
Example #17
0
        public EncodingHandler(BinaryReader stream)
        {
            stream.Skip(2); // EN
            byte b1 = stream.ReadByte();
            byte checksumSizeA = stream.ReadByte();
            byte checksumSizeB = stream.ReadByte();
            ushort flagsA = stream.ReadUInt16();
            ushort flagsB = stream.ReadUInt16();
            int numEntriesA = stream.ReadInt32BE();
            int numEntriesB = stream.ReadInt32BE();
            byte b4 = stream.ReadByte();
            int stringBlockSize = stream.ReadInt32BE();

            stream.Skip(stringBlockSize);
            stream.Skip(numEntriesA * 32);

            long chunkStart = stream.BaseStream.Position;

            for (int i = 0; i < numEntriesA; ++i)
            {
                ushort keysCount;

                while ((keysCount = stream.ReadUInt16()) != 0)
                {
                    int fileSize = stream.ReadInt32BE();
                    MD5Hash hash = stream.Read<MD5Hash>();

                    EncodingEntry entry = new EncodingEntry();
                    entry.Size = fileSize;

                    // how do we handle multiple keys?
                    for (int ki = 0; ki < keysCount; ++ki)
                    {
                        MD5Hash key = stream.Read<MD5Hash>();

                        // use first key for now
                        if (ki == 0)
                            entry.Key = key;
                        else
                            Log.Write("Multiple encoding keys for MD5 hash {0} -> {1}", hash.ToHexString(), key.ToHexString());
                    }

                    EncodingData.Add(hash, entry);
                }

                // each chunk is 4096 bytes, and zero padding at the end
                long remaining = CHUNK_SIZE - ((stream.BaseStream.Position - chunkStart) % CHUNK_SIZE);

                if (remaining > 0)
                    stream.BaseStream.Position += remaining;
            }

            for (int i = 0; i < numEntriesB; ++i)
            {
                byte[] firstKey = stream.ReadBytes(16);
                byte[] blockHash = stream.ReadBytes(16);
            }

            long chunkStart2 = stream.BaseStream.Position;

            for (int i = 0; i < numEntriesB; ++i)
            {
                byte[] key = stream.ReadBytes(16);
                int stringIndex = stream.ReadInt32BE();
                byte unk1 = stream.ReadByte();
                int fileSize = stream.ReadInt32BE();

                // each chunk is 4096 bytes, and zero padding at the end
                long remaining = CHUNK_SIZE - ((stream.BaseStream.Position - chunkStart2) % CHUNK_SIZE);

                if (remaining > 0)
                    stream.BaseStream.Position += remaining;
            }
        }
Example #18
0
        public CASCHandler(CASCFolder root, BackgroundWorker worker)
        {
            if (!OnlineMode)
            {
                var idxFiles = GetIdxFiles(Properties.Settings.Default.WowPath);

                if (idxFiles.Count == 0)
                    throw new FileNotFoundException("idx files missing!");

                worker.ReportProgress(0);

                int idxIndex = 0;

                foreach (var idx in idxFiles)
                {
                    using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    using (var br = new BinaryReader(fs))
                    {
                        int h2Len = br.ReadInt32();
                        int h2Check = br.ReadInt32();
                        byte[] h2 = br.ReadBytes(h2Len);

                        long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0;
                        fs.Position = padPos;

                        int dataLen = br.ReadInt32();
                        int dataCheck = br.ReadInt32();

                        int numBlocks = dataLen / 18;

                        for (int i = 0; i < numBlocks; i++)
                        {
                            IndexEntry info = new IndexEntry();
                            byte[] key = br.ReadBytes(9);
                            int indexHigh = br.ReadByte();
                            int indexLow = br.ReadInt32BE();

                            info.Index = (int)((byte)(indexHigh << 2) | ((indexLow & 0xC0000000) >> 30));
                            info.Offset = (indexLow & 0x3FFFFFFF);
                            info.Size = br.ReadInt32();

                            // duplicate keys wtf...
                            //IndexData[key] = info; // use last key
                            if (!LocalIndexData.ContainsKey(key)) // use first key
                                LocalIndexData.Add(key, info);
                        }

                        padPos = (dataLen + 0x0FFF) & 0xFFFFF000;
                        fs.Position = padPos;

                        fs.Position += numBlocks * 18;
                        //for (int i = 0; i < numBlocks; i++)
                        //{
                        //    var bytes = br.ReadBytes(18); // unknown data
                        //}

                        if (fs.Position != fs.Position)
                            throw new Exception("idx file under read");
                    }

                    worker.ReportProgress((int)((float)++idxIndex / (float)idxFiles.Count * 100));
                }

                Logger.WriteLine("CASCHandler: loaded {0} indexes", LocalIndexData.Count);
            }

            worker.ReportProgress(0);

            using (var fs = OpenEncodingFile())
            using (var br = new BinaryReader(fs))
            {
                br.ReadBytes(2); // EN
                byte b1 = br.ReadByte();
                byte b2 = br.ReadByte();
                byte b3 = br.ReadByte();
                ushort s1 = br.ReadUInt16();
                ushort s2 = br.ReadUInt16();
                int numEntries = br.ReadInt32BE();
                int i1 = br.ReadInt32BE();
                byte b4 = br.ReadByte();
                int entriesOfs = br.ReadInt32BE();

                fs.Position += entriesOfs; // skip strings

                fs.Position += numEntries * 32;
                //for (int i = 0; i < numEntries; ++i)
                //{
                //    br.ReadBytes(16);
                //    br.ReadBytes(16);
                //}

                for (int i = 0; i < numEntries; ++i)
                {
                    ushort keysCount;

                    while ((keysCount = br.ReadUInt16()) != 0)
                    {
                        int fileSize = br.ReadInt32BE();
                        byte[] md5 = br.ReadBytes(16);

                        var entry = new EncodingEntry();
                        entry.Size = fileSize;

                        for (int ki = 0; ki < keysCount; ++ki)
                        {
                            byte[] key = br.ReadBytes(16);

                            entry.Keys.Add(key);
                        }

                        //Encodings[md5] = entry;
                        EncodingData.Add(md5, entry);
                    }

                    //br.ReadBytes(28);
                    while (br.PeekChar() == 0)
                        fs.Position++;

                    worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100));
                }
                //var pos = br.BaseStream.Position;
                //for (int i = 0; i < i1; ++i)
                //{
                //    br.ReadBytes(16);
                //    br.ReadBytes(16);
                //}
                Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingData.Count);
            }

            worker.ReportProgress(0);

            using (var fs = OpenRootFile())
            using (var br = new BinaryReader(fs))
            {
                while (fs.Position < fs.Length)
                {
                    int count = br.ReadInt32();

                    RootBlock block = new RootBlock();
                    block.Unk1 = br.ReadUInt32();
                    block.Flags = (LocaleFlags)br.ReadUInt32();

                    if (block.Flags == LocaleFlags.None)
                        throw new Exception("block.Flags == LocaleFlags.None");

                    RootEntry[] entries = new RootEntry[count];

                    for (var i = 0; i < count; ++i)
                    {
                        entries[i] = new RootEntry();
                        entries[i].Block = block;
                        entries[i].Unk1 = br.ReadInt32();
                    }

                    for (var i = 0; i < count; ++i)
                    {
                        entries[i].MD5 = br.ReadBytes(16);

                        ulong hash = br.ReadUInt64();
                        entries[i].Hash = hash;

                        // don't load other locales
                        //if (block.Flags != LocaleFlags.All && (block.Flags & LocaleFlags.enUS) == 0)
                        //    continue;

                        if (!RootData.ContainsKey(hash))
                        {
                            RootData[hash] = new List<RootEntry>();
                            RootData[hash].Add(entries[i]);
                        }
                        else
                            RootData[hash].Add(entries[i]);
                    }

                    worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100));
                }

                Logger.WriteLine("CASCHandler: loaded {0} root data", RootData.Count);
            }

            worker.ReportProgress(0);

            if (File.Exists(listFile))
            {
                FolderNames[Hasher.ComputeHash("root")] = "root";

                using (StreamReader sr = new StreamReader(listFile))
                {
                    string file;
                    int filesCount = 0;

                    CASCFolder folder = root;

                    while ((file = sr.ReadLine()) != null)
                    {
                        ulong fileHash = Hasher.ComputeHash(file);

                        // skip invalid names
                        if (!RootData.ContainsKey(fileHash))
                        {
                            Logger.WriteLine("Invalid file name: {0}", file);
                            continue;
                        }

                        filesCount++;

                        string[] parts = file.Split('\\');

                        for (int i = 0; i < parts.Length; ++i)
                        {
                            bool isFile = (i == parts.Length - 1);

                            ulong hash = isFile ? fileHash : Hasher.ComputeHash(parts[i]);

                            ICASCEntry entry = folder.GetEntry(hash);

                            if (entry == null)
                            {
                                if (isFile)
                                {
                                    entry = new CASCFile(hash);
                                    FileNames[hash] = file;
                                }
                                else
                                {
                                    entry = new CASCFolder(hash);
                                    FolderNames[hash] = parts[i];
                                }

                                folder.SubEntries[hash] = entry;

                                if (isFile)
                                {
                                    folder = root;
                                    break;
                                }
                            }

                            folder = entry as CASCFolder;
                        }

                        if ((filesCount % 1000) == 0)
                            worker.ReportProgress((int)((float)sr.BaseStream.Position / (float)sr.BaseStream.Length * 100));
                    }

                    Logger.WriteLine("CASCHandler: loaded {0} file names", FileNames.Count);
                }
            }
            else
            {
                throw new FileNotFoundException("list file missing!");
            }
        }
Example #19
0
        public void run()
        {
            try
            {
                for (;;)
                {
                    if (!this.client.connectionAlive)
                    {
                        this.client.forceDisconnect(direction, "Connection no longer alive");
                        return;
                    }

                    if (this.client.kickTargetTimestamp != 0)
                    {
                        if (this.client.kickTargetTimestamp < Utils.getTimestamp())
                        {
                            this.client.closeConnection();
                            return;
                        }
                        continue;
                    }

                    #region Process Packet
                    //Packet ID and Vaildity Check.
                    uint temp = this.incoming.ReadVarUInt32();
                    if (temp < 1 || temp > 48)
                    {
                        this.client.forceDisconnect(direction, "Sent invalid packet ID [" + temp + "].");
                        return;
                    }
                    Packet packetID = (Packet)temp;

                    //Packet Size and Compression Check.
                    bool compressed = false;
                    int packetSize = this.incoming.ReadVarInt32();
                    if (packetSize < 0)
                    {
                        packetSize = -packetSize;
                        compressed = true;
                    }

                    //Create buffer for forwarding
                    byte[] dataBuffer = this.incoming.ReadFully(packetSize);

                    //Do decompression
                    MemoryStream ms = new MemoryStream();
                    if (compressed)
                    {
                        ZlibStream compressedStream = new ZlibStream(new MemoryStream(dataBuffer), CompressionMode.Decompress);
                        byte[] buffer = new byte[32768];
                        for (;;)
                        {
                            int read = compressedStream.Read(buffer, 0, buffer.Length);
                            if (read <= 0)
                                break;
                            ms.Write(buffer, 0, read);
                        }
                        ms.Seek(0, SeekOrigin.Begin);
                    }
                    else
                    {
                        ms = new MemoryStream(dataBuffer);
                    }

                    //Create packet parser
                    BinaryReader packetData = new BinaryReader(ms);
                    #endregion

                    //Return data for packet processor
                    object returnData = true;

                    if (packetID != Packet.Heartbeat && packetID != Packet.UniverseTimeUpdate)
                    {
                        if (direction == Direction.Client)
                        #region Handle Client Packets
                        {
                            #region Protocol State Security
                            ClientState curState = this.client.state;
                            if (curState != ClientState.Connected)
                            {
                                if (curState == ClientState.PendingConnect && packetID != Packet.ClientConnect)
                                {
                                    this.client.rejectPreConnected("Violated PendingConnect protocol state with " + packetID);
                                    return;
                                }
                                else if (curState == ClientState.PendingAuthentication && packetID != Packet.HandshakeResponse)
                                {
                                    this.client.rejectPreConnected("Violated PendingAuthentication protocol state with " + packetID);
                                    return;
                                }
                                else if (curState == ClientState.PendingConnectResponse)
                                {
                                    int startTime = Utils.getTimestamp();
                                    while (true)
                                    {
                                        if (this.client.state == ClientState.Connected) break;
                                        if (Utils.getTimestamp() > startTime + StarryboundServer.config.connectTimeout)
                                        {
                                            this.client.rejectPreConnected("Connection Failed: Server did not respond in time.");
                                            return;
                                        }
                                    }
                                }
                            }
                            #endregion

                            if (packetID == Packet.ChatSend)
                            {
                                returnData = new Packet11ChatSend(this.client, packetData, this.direction).onReceive();
                            }
                            else if (packetID == Packet.ClientConnect)
                            {
                                this.client.state = ClientState.PendingAuthentication;
                                returnData = new Packet7ClientConnect(this.client, packetData, this.direction).onReceive();
                                MemoryStream packet = new MemoryStream();
                                BinaryWriter packetWrite = new BinaryWriter(packet);

                                passwordSalt = Utils.GenerateSecureSalt();
                                packetWrite.WriteStarString("");
                                packetWrite.WriteStarString(passwordSalt);
                                packetWrite.WriteBE(StarryboundServer.config.passwordRounds);
                                this.client.sendClientPacket(Packet.HandshakeChallenge, packet.ToArray());
                            }
                            else if (packetID == Packet.HandshakeResponse)
                            {
                                string claimResponse = packetData.ReadStarString();
                                string passwordHash = packetData.ReadStarString();

                                string verifyHash = Utils.StarHashPassword(StarryboundServer.config.proxyPass, this.client.playerData.account + passwordSalt, StarryboundServer.config.passwordRounds);
                                if (passwordHash != verifyHash)
                                {
                                    this.client.rejectPreConnected("Your password was incorrect.");
                                    return;
                                }

                                this.client.state = ClientState.PendingConnectResponse;
                                returnData = false;
                            }
                            else if (packetID == Packet.WarpCommand)
                            {
                                WarpType cmd = (WarpType)packetData.ReadUInt32BE();
                                WorldCoordinate coord = packetData.ReadStarWorldCoordinate();
                                string player = packetData.ReadStarString();
                                if (cmd == WarpType.WarpToPlayerShip)
                                {
                                    Client target = StarryboundServer.getClient(player);
                                    if (target != null)
                                    {
                                        if (!this.client.playerData.canAccessShip(target.playerData))
                                        {
                                            this.client.sendChatMessage("^#5dc4f4;You cannot access this player's ship due to their ship access settings.");
                                            StarryboundServer.logDebug("ShipAccess", "Preventing " + this.client.playerData.name + " from accessing " + target.playerData.name + "'s ship.");
                                            MemoryStream packetWarp = new MemoryStream();
                                            BinaryWriter packetWrite = new BinaryWriter(packetWarp);
                                            packetWrite.WriteBE((uint)WarpType.WarpToOwnShip);
                                            packetWrite.Write(new WorldCoordinate());
                                            packetWrite.WriteStarString("");
                                            client.sendServerPacket(Packet.WarpCommand, packetWarp.ToArray());
                                            returnData = false;
                                        }
                                    }
                                }
                                StarryboundServer.logDebug("WarpCommand", "[" + this.client.playerData.client + "][" + cmd + "]" + (coord != null ? "[" + coord.ToString() + "]" : "") + "[" + player + "]");
                            }
                            else if (packetID == Packet.ModifyTileList || packetID == Packet.DamageTileGroup || packetID == Packet.DamageTile || packetID == Packet.ConnectWire || packetID == Packet.DisconnectAllWires)
                            {
                                if(!this.client.playerData.canIBuild()) returnData = false;
                            }
                            else if (packetID == Packet.EntityCreate)
                            {
                                while(true)
                                {
                                    EntityType type = (EntityType)packetData.Read();
                                    if(type == EntityType.EOF) break;
                                    byte[] entityData = packetData.ReadStarByteArray();
                                    int entityId = packetData.ReadVarInt32();
                                    if(type == EntityType.Projectile)
                                    {
                                        BinaryReader entity = new BinaryReader(new MemoryStream(entityData));
                                        string projectileKey = entity.ReadStarString();
                                        object projParams = entity.ReadStarVariant();
                                        if (StarryboundServer.config.projectileBlacklist.Contains(projectileKey))
                                        {
                                            MemoryStream packet = new MemoryStream();
                                            BinaryWriter packetWrite = new BinaryWriter(packet);
                                            packetWrite.WriteVarInt32(entityId);
                                            packetWrite.Write(false);
                                            this.client.sendClientPacket(Packet.EntityDestroy, packet.ToArray());
                                            returnData = false;
                                        }
                                        if (StarryboundServer.serverConfig.useDefaultWorldCoordinate && StarryboundServer.config.spawnWorldProtection)
                                        {
                                            if (this.client.playerData.loc != null)
                                            {
                                                if (StarryboundServer.config.projectileBlacklistSpawn.Contains(projectileKey) && StarryboundServer.spawnPlanet.Equals(this.client.playerData.loc) && !this.client.playerData.group.hasPermission("admin.spawnbuild") && !this.client.playerData.inPlayerShip)
                                                {
                                                    MemoryStream packet = new MemoryStream();
                                                    BinaryWriter packetWrite = new BinaryWriter(packet);
                                                    packetWrite.WriteVarInt32(entityId);
                                                    packetWrite.Write(false);
                                                    this.client.sendClientPacket(Packet.EntityDestroy, packet.ToArray());
                                                    returnData = false;
                                                }
                                            }
                                            else
                                            {
                                                MemoryStream packet = new MemoryStream();
                                                BinaryWriter packetWrite = new BinaryWriter(packet);
                                                packetWrite.WriteVarInt32(entityId);
                                                packetWrite.Write(false);
                                                this.client.sendClientPacket(Packet.EntityDestroy, packet.ToArray());
                                                returnData = false;
                                            }
                                        }
                                    }
                                    else if (type == EntityType.Object || type == EntityType.Plant || type == EntityType.PlantDrop || type == EntityType.Monster)
                                    {
                                        if (!this.client.playerData.canIBuild())
                                        {
                                            MemoryStream packet = new MemoryStream();
                                            BinaryWriter packetWrite = new BinaryWriter(packet);
                                            packetWrite.WriteVarInt32(entityId);
                                            packetWrite.Write(false);
                                            this.client.sendClientPacket(Packet.EntityDestroy, packet.ToArray());
                                            returnData = false;
                                        }
                                    }
                                }
                            }
                            else if (packetID == Packet.SpawnEntity)
                            {
                                while(true)
                                {
                                    EntityType type = (EntityType)packetData.Read();
                                    if (type == EntityType.EOF) break;
                                    byte[] entityData = packetData.ReadStarByteArray();
                                    if (type == EntityType.Projectile)
                                    {
                                        BinaryReader entity = new BinaryReader(new MemoryStream(entityData));
                                        string projectileKey = entity.ReadStarString();
                                        object projParams = entity.ReadStarVariant();
                                        if (StarryboundServer.config.projectileBlacklist.Contains(projectileKey))
                                        {
                                            returnData = false;
                                        }
                                        if (StarryboundServer.serverConfig.useDefaultWorldCoordinate && StarryboundServer.config.spawnWorldProtection)
                                        {
                                            if (this.client.playerData.loc != null)
                                            {
                                                if (StarryboundServer.config.projectileBlacklistSpawn.Contains(projectileKey) ^ StarryboundServer.config.projectileSpawnListIsWhitelist)
                                                {
                                                    if (StarryboundServer.spawnPlanet.Equals(this.client.playerData.loc) && !this.client.playerData.group.hasPermission("admin.spawnbuild") && !this.client.playerData.inPlayerShip)
                                                    {
                                                        returnData = false;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                returnData = false;
                                            }
                                        }
                                    }
                                    else if (type == EntityType.Object || type == EntityType.Plant || type == EntityType.PlantDrop || type == EntityType.Monster)
                                    {
                                        if (!this.client.playerData.canIBuild()) returnData = false;
                                    }
                                }
                            }
                        }
                        #endregion
                        else
                        #region Handle Server Packets
                        {
                            if (packetID == Packet.ChatReceive)
                            {
                                returnData = new Packet5ChatReceive(this.client, packetData, this.direction).onReceive();
                            }
                            else if (packetID == Packet.ProtocolVersion)
                            {
                                uint protocolVersion = packetData.ReadUInt32BE();
                                if (protocolVersion != StarryboundServer.ProtocolVersion)
                                {
                                    MemoryStream packet = new MemoryStream();
                                    BinaryWriter packetWrite = new BinaryWriter(packet);
                                    packetWrite.WriteBE(protocolVersion);
                                    this.client.sendClientPacket(Packet.ProtocolVersion, packet.ToArray());

                                    this.client.rejectPreConnected("Connection Failed: Unable to handle parent server protocol version.");
                                    return;
                                }
                            }
                            else if (packetID == Packet.HandshakeChallenge)
                            {
                                string claimMessage = packetData.ReadString();
                                string passwordSalt = packetData.ReadStarString();
                                int passwordRounds = packetData.ReadInt32BE();

                                MemoryStream packet = new MemoryStream();
                                BinaryWriter packetWrite = new BinaryWriter(packet);
                                string passwordHash = Utils.StarHashPassword(StarryboundServer.privatePassword, passwordSalt, passwordRounds);
                                packetWrite.WriteStarString("");
                                packetWrite.WriteStarString(passwordHash);
                                this.client.sendServerPacket(Packet.HandshakeResponse, packet.ToArray());

                                returnData = false;
                            }
                            else if (packetID == Packet.ConnectResponse)
                            {
                                int startTime = Utils.getTimestamp();
                                while (true)
                                {
                                    if (this.client.state == ClientState.PendingConnectResponse) break;
                                    if (Utils.getTimestamp() > startTime + StarryboundServer.config.connectTimeout)
                                    {
                                        this.client.rejectPreConnected("Connection Failed: Client did not respond with handshake.");
                                        return;
                                    }
                                }
                                returnData = new Packet2ConnectResponse(this.client, packetData, this.direction).onReceive();
                            }
                            else if (packetID == Packet.WorldStart)
                            {
                                if (!this.client.playerData.sentMotd)
                                {
                                    this.client.sendChatMessage(Config.GetMotd());

                                    if (!this.client.playerData.group.hasPermission("world.build"))
                                        this.client.sendChatMessage("^#f75d5d;" + StarryboundServer.config.buildErrorMessage);

                                    this.client.playerData.sentMotd = true;
                                }

                                byte[] planet = packetData.ReadStarByteArray();
                                byte[] worldStructure = packetData.ReadStarByteArray();
                                byte[] sky = packetData.ReadStarByteArray();
                                byte[] serverWeather = packetData.ReadStarByteArray();
                                float spawnX = packetData.ReadSingleBE();
                                float spawnY = packetData.ReadSingleBE();
                                uint mapParamsSize = packetData.ReadVarUInt32();
                                Dictionary<string, object> mapParams = new Dictionary<string, object>();
                                int isPlayerShip = 0;
                                for (int i = 0; i < mapParamsSize; i++)
                                {
                                    string key = packetData.ReadStarString();
                                    var value = packetData.ReadStarVariant();
                                    mapParams.Add(key, value);
                                    if(key == "fuel.level")
                                    {
                                        isPlayerShip++;
                                    }
                                    else if(key == "fuel.max")
                                    {
                                        isPlayerShip++;
                                    }
                                }
                                this.client.playerData.inPlayerShip = (isPlayerShip == 2);
                                uint clientID = packetData.ReadUInt32BE();
                                bool bool1 = packetData.ReadBoolean();
                                WorldCoordinate coords = Utils.findGlobalCoords(sky);
                                if (coords != null)
                                {
                                    this.client.playerData.loc = coords;
                                    StarryboundServer.logDebug("WorldStart", "[" + this.client.playerData.client + "][" + bool1 + ":" + clientID + "] CurLoc:[" + this.client.playerData.loc.ToString() + "][" + this.client.playerData.inPlayerShip + "]");
                                }
                                else
                                    StarryboundServer.logDebug("WorldStart", "[" + this.client.playerData.client + "][" + bool1 + ":" + clientID + "] InPlayerShip:[" + this.client.playerData.inPlayerShip + "]");
                            }
                            else if (packetID == Packet.WorldStop)
                            {
                                string status = packetData.ReadStarString();
                            }
                            else if (packetID == Packet.GiveItem)
                            {
                                string name = packetData.ReadStarString();
                                uint count = packetData.ReadVarUInt32();
                                var itemDesc = packetData.ReadStarVariant();
                            }
                            else if (packetID == Packet.EnvironmentUpdate)
                            {
                                byte[] sky = packetData.ReadStarByteArray();
                                byte[] serverWeather = packetData.ReadStarByteArray();
                                if (this.client.playerData.loc == null)
                                {
                                    WorldCoordinate coords = Utils.findGlobalCoords(sky);
                                    if (coords != null)
                                    {
                                        this.client.playerData.loc = coords;
                                        StarryboundServer.logDebug("EnvUpdate", "[" + this.client.playerData.client + "] CurLoc:[" + this.client.playerData.loc.ToString() + "]");
                                    }
                                }
                            }
                            else if (packetID == Packet.ClientContextUpdate)
                            {
                                try
                                {
                                    byte[] clientContextData = packetData.ReadStarByteArray();
                                    if (clientContextData.Length != 0)
                                    {
                                        BinaryReader clientContextReader = new BinaryReader(new MemoryStream(clientContextData));
                                        byte[] data = clientContextReader.ReadStarByteArray();
                                        if (data.Length > 8) //Should at least be more than 8 bytes for it to contain the data we want.
                                        {
                                            BinaryReader dataReader = new BinaryReader(new MemoryStream(data));
                                            byte dataBufferLength = dataReader.ReadByte();
                                            if (dataBufferLength == 2)
                                            {
                                                byte arrayLength = dataReader.ReadByte();
                                                if (arrayLength == 2 || arrayLength == 4) //Only observed these being used so far for what we want.
                                                {
                                                    byte dataType = dataReader.ReadByte(); //04 = String, 0E = CelestialLog
                                                    if (dataType == 4)
                                                    {
                                                        string string1 = dataReader.ReadStarString();
                                                        if (dataReader.BaseStream.Position != dataReader.BaseStream.Length)
                                                        {
                                                            if (string1 == "null")
                                                            {
                                                                byte[] worldHeader = dataReader.ReadStarByteArray(); //0008020A000C
                                                                byte[] worldData = dataReader.ReadStarByteArray();
                                                                byte typeByte = dataReader.ReadByte(); //0E = CelestialLog
                                                                if (typeByte == 14)
                                                                {
                                                                    Dictionary<string, WorldCoordinate> log = dataReader.ReadStarCelestialLog();
                                                                    log.TryGetValue("loc", out this.client.playerData.loc);
                                                                    if (!log.TryGetValue("home", out this.client.playerData.home))
                                                                        this.client.playerData.home = this.client.playerData.loc;
                                                                    StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] CurLoc:[" + this.client.playerData.loc.ToString() + "][" + this.client.playerData.inPlayerShip + "]");
                                                                    StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] CurHome:[" + this.client.playerData.home.ToString() + "]");
                                                                }
                                                            }
                                                        }
                                                    }
                                                    else if (dataType == 14)
                                                    {
                                                        Dictionary<string, WorldCoordinate> log = dataReader.ReadStarCelestialLog();
                                                        log.TryGetValue("loc", out this.client.playerData.loc);
                                                        if (!log.TryGetValue("home", out this.client.playerData.home))
                                                            this.client.playerData.home = this.client.playerData.loc;
                                                        StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] CurLoc:[" + this.client.playerData.loc.ToString() + "][" + this.client.playerData.inPlayerShip + "]");
                                                        StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] CurHome:[" + this.client.playerData.home.ToString() + "]");
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] Failed to parse ClientContextUpdate from Server: " + e.ToString());
                                }
                            }
                            else if (packetID == Packet.EntityCreate)
                            {
                                MemoryStream sendStream = new MemoryStream();
                                BinaryWriter sendWriter = new BinaryWriter(sendStream);
                                bool test = true;
                                while (true)
                                {
                                    EntityType type = (EntityType)packetData.Read();
                                    if (type == EntityType.EOF) break;
                                    byte[] entityData = packetData.ReadStarByteArray();
                                    int entityId = packetData.ReadVarInt32();
                                    if (type == EntityType.Player)
                                    {
                                        byte[] buffer = new byte[16];
                                        Buffer.BlockCopy(entityData, 0, buffer, 0, 16);
                                        buffer = Utils.HashUUID(buffer);
                                        Buffer.BlockCopy(buffer, 0, entityData, 0, 16);
                                        returnData = test = false;
                                    }
                                    sendWriter.Write((byte)type);
                                    sendWriter.WriteVarUInt64((ulong)entityData.Length);
                                    sendWriter.Write(entityData);
                                    sendWriter.WriteVarInt32(entityId);
                                }
                                if(test == false)
                                {
                                    this.outgoing.WriteVarUInt32((uint)packetID);
                                    this.outgoing.WriteVarInt32((int)sendStream.Length);
                                    this.outgoing.Write(sendStream.ToArray());
                                    this.outgoing.Flush();
                                }
                            }
                        }
                        #endregion
                    }

                    //Check return data
                    if (returnData is Boolean)
                    {
                        if ((Boolean)returnData == false) continue;
                    }
                    else if (returnData is int)
                    {
                        if ((int)returnData == -1)
                        {
                            this.client.forceDisconnect(direction, "Command processor requested to drop client");
                            return;
                        }
                    }

                    #region Forward Packet
                    //Write data to dest
                    this.outgoing.WriteVarUInt32((uint)packetID);
                    if (compressed)
                    {
                        this.outgoing.WriteVarInt32(-packetSize);
                        this.outgoing.Write(dataBuffer, 0, packetSize);
                    }
                    else
                    {
                        this.outgoing.WriteVarInt32(packetSize);
                        this.outgoing.Write(dataBuffer, 0, packetSize);
                    }
                    this.outgoing.Flush();
                    #endregion

                    //If disconnect was forwarded to client, lets disconnect.
                    if(packetID == Packet.ServerDisconnect && direction == Direction.Server)
                    {
                        this.client.closeConnection();
                    }
                }
            }
            catch (ThreadAbortException) { }
            catch (EndOfStreamException)
            {
                this.client.forceDisconnect(direction, "End of stream");
            }
            catch (Exception e)
            {
                if(e.InnerException != null)
                {
                    if(e.InnerException is System.Net.Sockets.SocketException)
                    {
                        this.client.forceDisconnect(direction, e.InnerException.Message);
                        return;
                    }

                }
                this.client.forceDisconnect(direction, "ForwardThread Exception: " + e.ToString());
            }
        }
        private unsafe void ParseIndex(string idx)
        {
            using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            using (var br = new BinaryReader(fs))
            {
                int h2Len = br.ReadInt32();
                int h2Check = br.ReadInt32();
                byte[] h2 = br.ReadBytes(h2Len);

                long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0;
                fs.Position = padPos;

                int dataLen = br.ReadInt32();
                int dataCheck = br.ReadInt32();

                int numBlocks = dataLen / 18;

                //byte[] buf = new byte[8];

                for (int i = 0; i < numBlocks; i++)
                {
                    IndexEntry info = new IndexEntry();
                    byte[] keyBytes = br.ReadBytes(9);
                    Array.Resize(ref keyBytes, 16);

                    MD5Hash key;

                    fixed (byte *ptr = keyBytes)
                        key = *(MD5Hash*)ptr;

                    byte indexHigh = br.ReadByte();
                    int indexLow = br.ReadInt32BE();

                    info.Index = (indexHigh << 2 | (byte)((indexLow & 0xC0000000) >> 30));
                    info.Offset = (indexLow & 0x3FFFFFFF);

                    //for (int j = 3; j < 8; j++)
                    //    buf[7 - j] = br.ReadByte();

                    //long val = BitConverter.ToInt64(buf, 0);
                    //info.Index = (int)(val / 0x40000000);
                    //info.Offset = (int)(val % 0x40000000);

                    info.Size = br.ReadInt32();

                    // duplicate keys wtf...
                    //IndexData[key] = info; // use last key
                    if (!LocalIndexData.ContainsKey(key)) // use first key
                        LocalIndexData.Add(key, info);
                }

                padPos = (dataLen + 0x0FFF) & 0xFFFFF000;
                fs.Position = padPos;

                fs.Position += numBlocks * 18;
                //for (int i = 0; i < numBlocks; i++)
                //{
                //    var bytes = br.ReadBytes(18); // unknown data
                //}

                //if (fs.Position != fs.Length)
                //    throw new Exception("idx file under read");
            }
        }
Example #21
0
        public HippelCosoFile(Stream stream, byte[] sampleData)
        {
            long pos = stream.Position;
            var reader = new BinaryReader(stream, Encoding.ASCII);
            string coso = new string(reader.ReadChars(4));
            if(coso == "COSO")
            {
                int frqseqs = reader.ReadInt32BE();
                int volseqs = reader.ReadInt32BE();
                int patternsPtr = reader.ReadInt32BE();
                int voicesPtr = reader.ReadInt32BE();
                int songsData = reader.ReadInt32BE();
                int headers = reader.ReadInt32BE();
                int samplesPtr = reader.ReadInt32BE();

                /*string tfmx = new string(reader.ReadChars(4));
                if(tfmx == "TFMX")
                {
                    reader.ReadInt16BE();
                    reader.ReadInt16BE();
                    reader.ReadInt16BE();
                    int npatterns = reader.ReadInt16BE()+1;
                    reader.ReadInt16BE();
                    reader.ReadInt16BE();
                    short nsongs = reader.ReadInt16BE();
                    short nsamples = reader.ReadInt16BE();
                }*/

                int nsamples = (samplesPtr-headers)/10 - 1;
                stream.Position = pos+headers;

                Samples = new Sample[nsamples];
                for(int i = 0; i < nsamples; i++)
                {
                    Samples[i] = new Sample(reader);
                }

                if(sampleData == null)
                {
                    int endPos = Samples.Max(i => i.SourceStart+i.SourceLength);
                    stream.Position = samplesPtr;
                    sampleData = reader.ReadBytes(endPos);
                }
                if(sampleData.Length > 0)
                {
                    for(int i = 0; i < nsamples; i++)
                    {
                        var inst = Samples[i];
                        Array.Copy(sampleData, inst.SourceStart, inst.Data, 0, inst.SourceLength);
                    }
                }

                int nsongs = (headers-songsData)/6;
                stream.Position = pos+songsData;

                Songs = new Song[nsongs];
                for(int i = 0; i < nsongs; i++)
                {
                    Songs[i] = new Song(reader);
                }

                int nvoices = (songsData-voicesPtr)/3;
                stream.Position = pos+voicesPtr;

                Voices = new Voice[nvoices];
                for(int i = 0; i < nvoices; i++)
                {
                    Voices[i] = new Voice(reader);
                }

                stream.Position = pos+patternsPtr;

                int npatterns = (voicesPtr-patternsPtr)/2;
                Patterns = new Pattern[npatterns];

                for(int i = 0; i < npatterns; i++)
                {
                    Patterns[i] = new Pattern(reader);
                }

                /*var patterns = new List<Pattern>();
                while(stream.Position < pos+voicesPtr)
                {
                    patterns.Add(new Pattern(reader));
                }
                int c = patterns.Count;
                int x = voices.Max(v => v.PatternAddress);*/

                //int npatterns = (voicesPtr-patternsPtr)/

                /*stream.Position = pos+tracks;
                Pattern[] notes = new Pattern[nnotes];
                for(int i = 0; i < nnotes; i++)
                {
                    notes[i] = new Pattern(reader);
                }

                for(int j = 0; j < 12; j++)
                {
                    Console.WriteLine("Byte "+j);
                    Console.WriteLine(notes.Select(n => n.Data).Any(d => d[j] > 10));
                }*/
            }
        }
Example #22
0
        private void ParseIndex(string idx)
        {
            using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            using (var br = new BinaryReader(fs))
            {
                int h2Len = br.ReadInt32();
                int h2Check = br.ReadInt32();
                byte[] h2 = br.ReadBytes(h2Len);

                long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0;
                fs.Position = padPos;

                int dataLen = br.ReadInt32();
                int dataCheck = br.ReadInt32();

                int numBlocks = dataLen / 18;

                for (int i = 0; i < numBlocks; i++)
                {
                    IndexEntry info = new IndexEntry();
                    MD5Hash key = br.Read<MD5Hash>();
                    byte indexHigh = br.ReadByte();
                    int indexLow = br.ReadInt32BE();

                    info.Index = (indexHigh << 2 | (byte)((indexLow & 0xC0000000) >> 30));
                    info.Offset = (indexLow & 0x3FFFFFFF);
                    info.Size = br.ReadInt32();

                    if (!LocalIndexData.ContainsKey(key))
                        LocalIndexData.Add(key, info);
                }

                padPos = (dataLen + 0x0FFF) & 0xFFFFF000;
                fs.Position = padPos;

                fs.Position += numBlocks * 18;
            }
        }
Example #23
0
        private CASCHandler(CASCConfig config, CDNHandler cdn, BackgroundWorker worker)
        {
            this.config = config;
            this.cdn = cdn;
            if (!config.OnlineMode)
            {
                var idxFiles = GetIdxFiles(this.config.BasePath);

                if (idxFiles.Count == 0)
                    throw new FileNotFoundException("idx files missing!");

                if (worker != null) worker.ReportProgress(0);

                int idxIndex = 0;

                foreach (var idx in idxFiles)
                {
                    using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    using (var br = new BinaryReader(fs))
                    {
                        int h2Len = br.ReadInt32();
                        int h2Check = br.ReadInt32();
                        byte[] h2 = br.ReadBytes(h2Len);

                        long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0;
                        fs.Position = padPos;

                        int dataLen = br.ReadInt32();
                        int dataCheck = br.ReadInt32();

                        int numBlocks = dataLen / 18;

                        for (int i = 0; i < numBlocks; i++)
                        {
                            IndexEntry info = new IndexEntry();
                            byte[] key = br.ReadBytes(9);
                            int indexHigh = br.ReadByte();
                            int indexLow = br.ReadInt32BE();

                            info.Index = (int)((byte)(indexHigh << 2) | ((indexLow & 0xC0000000) >> 30));
                            info.Offset = (indexLow & 0x3FFFFFFF);
                            info.Size = br.ReadInt32();

                            // duplicate keys wtf...
                            //IndexData[key] = info; // use last key
                            if (!LocalIndexData.ContainsKey(key)) // use first key
                                LocalIndexData.Add(key, info);
                        }

                        padPos = (dataLen + 0x0FFF) & 0xFFFFF000;
                        fs.Position = padPos;

                        fs.Position += numBlocks * 18;
                        //for (int i = 0; i < numBlocks; i++)
                        //{
                        //    var bytes = br.ReadBytes(18); // unknown data
                        //}

                        if (fs.Position != fs.Position)
                            throw new Exception("idx file under read");
                    }

                    if (worker != null) worker.ReportProgress((int)((float)++idxIndex / (float)idxFiles.Count * 100));
                }

                Logger.WriteLine("CASCHandler: loaded {0} indexes", LocalIndexData.Count);
            }

            if (worker != null) worker.ReportProgress(0);

            using (var fs = OpenEncodingFile())
            using (var br = new BinaryReader(fs))
            {
                br.ReadBytes(2); // EN
                byte b1 = br.ReadByte();
                byte b2 = br.ReadByte();
                byte b3 = br.ReadByte();
                ushort s1 = br.ReadUInt16();
                ushort s2 = br.ReadUInt16();
                int numEntries = br.ReadInt32BE();
                int i1 = br.ReadInt32BE();
                byte b4 = br.ReadByte();
                int entriesOfs = br.ReadInt32BE();

                fs.Position += entriesOfs; // skip strings

                fs.Position += numEntries * 32;
                //for (int i = 0; i < numEntries; ++i)
                //{
                //    br.ReadBytes(16);
                //    br.ReadBytes(16);
                //}

                for (int i = 0; i < numEntries; ++i)
                {
                    ushort keysCount;

                    while ((keysCount = br.ReadUInt16()) != 0)
                    {
                        int fileSize = br.ReadInt32BE();
                        byte[] md5 = br.ReadBytes(16);

                        var entry = new EncodingEntry();
                        entry.Size = fileSize;

                        for (int ki = 0; ki < keysCount; ++ki)
                        {
                            byte[] key = br.ReadBytes(16);

                            entry.Keys.Add(key);
                        }

                        //Encodings[md5] = entry;
                        EncodingData.Add(md5, entry);
                    }

                    //br.ReadBytes(28);
                    while (br.PeekChar() == 0)
                        fs.Position++;

                    if (worker != null) worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100));
                }
                //var pos = br.BaseStream.Position;
                //for (int i = 0; i < i1; ++i)
                //{
                //    br.ReadBytes(16);
                //    br.ReadBytes(16);
                //}
                Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingData.Count);
            }

            if (worker != null) worker.ReportProgress(0);

            using (var fs = OpenRootFile())
            using (var br = new BinaryReader(fs))
            {
                while (fs.Position < fs.Length)
                {
                    int count = br.ReadInt32();

                    RootBlock block = new RootBlock();
                    block.Unk1 = br.ReadUInt32();
                    block.Flags = (LocaleFlags)br.ReadUInt32();

                    if (block.Flags == LocaleFlags.None)
                        throw new Exception("block.Flags == LocaleFlags.None");

                    RootEntry[] entries = new RootEntry[count];

                    for (var i = 0; i < count; ++i)
                    {
                        entries[i] = new RootEntry();
                        entries[i].Block = block;
                        entries[i].Unk1 = br.ReadInt32();
                    }

                    for (var i = 0; i < count; ++i)
                    {
                        entries[i].MD5 = br.ReadBytes(16);

                        ulong hash = br.ReadUInt64();
                        entries[i].Hash = hash;

                        // don't load other locales
                        //if (block.Flags != LocaleFlags.All && (block.Flags & LocaleFlags.enUS) == 0)
                        //    continue;

                        if (!RootData.ContainsKey(hash))
                        {
                            RootData[hash] = new List<RootEntry>();
                            RootData[hash].Add(entries[i]);
                        }
                        else
                            RootData[hash].Add(entries[i]);
                    }

                    if (worker != null) worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100));
                }

                Logger.WriteLine("CASCHandler: loaded {0} root data", RootData.Count);
            }

            if (worker != null) worker.ReportProgress(0);
        }
Example #24
0
#pragma warning disable CS0219
			public override string GetTitle(BinaryReader fileStream)
			{
				// using the official id3 tag documentation
				// http://id3.org/id3v2.3.0#ID3_tag_version_2.3.0

				int read_count = 10;

				// read + validate header                                    [10 bytes]
				// skipped for TagID                                         >03 bytes
				byte version_major = fileStream.ReadByte(); //               >01 bytes
				byte version_minor = fileStream.ReadByte(); //               >01 bytes
				byte data_flags = fileStream.ReadByte(); //                  >01 bytes
				byte[] tag_size = fileStream.ReadBytes(4); //                >04 bytes
				int tag_size_int = 0;
				for (int i = 0; i < 4; i++)
					tag_size_int |= tag_size[3 - i] << (i * 7);
				read_count += 10;

				#region ID3v2											     
				if (version_major == 2)
				{
					while (read_count < tag_size_int + 10)
					{
						// frame header                                      [06 bytes]
						int frame_id = fileStream.ReadInt24BE(); //          >03 bytes
						int frame_size = fileStream.ReadInt24BE(); //        >03 bytes
						read_count += 6;

						if (frame_id == v2_TT2)
						{
							string title;
							byte[] textBuffer = fileStream.ReadBytes(frame_size);
							if (textBuffer[0] == 0)
								title = Encoding.GetEncoding(28591).GetString(textBuffer, 1, frame_size - 1);
							else
								throw new FormatException("The id3 tag is damaged");
							return title;
						}
						else
						{
							fileStream.ReadBytes(frame_size);
							read_count += frame_size;
						}
					}
					throw new FormatException("The id3 tag contains no title");
				}
				#endregion
				#region ID3v3/4
				else if (version_major == 3 || version_major == 4)
				{
					while (read_count < tag_size_int + 10)
					{
						// frame header                                      [10 bytes]
						uint frame_id = fileStream.ReadUInt32BE(); //        >04 bytes
						int frame_size = fileStream.ReadInt32BE(); //        >04 bytes
						ushort frame_flags = fileStream.ReadUInt16BE(); //   >02 bytes 
						read_count += 10;

						// content
						if (frame_id == v3_TIT2)
						{
							string title;
							byte[] textBuffer = fileStream.ReadBytes(frame_size);
							// is a string, so the first byte is a indicator byte
							switch (textBuffer[0])
							{
							case 0:
								title = Encoding.GetEncoding(28591).GetString(textBuffer, 1, frame_size - 1); break;
							case 1:
								title = Encoding.Unicode.GetString(textBuffer, 1, frame_size - 1); break;
							case 2:
								title = new UnicodeEncoding(true, false).GetString(textBuffer, 1, frame_size - 1); break;
							case 3:
								title = Encoding.UTF8.GetString(textBuffer, 1, frame_size - 1); break;
							default:
								throw new FormatException("The id3 tag is damaged");
							}
							return title;
						}
						else if (frame_id == 0)
							break;
						else
						{
							fileStream.ReadBytes(frame_size);
							read_count += frame_size;
						}
					}
					throw new FormatException("The id3 tag contains no title");
				}
				#endregion
				return null;
			}
Example #25
0
        public AssetCabinet(Stream stream, UnityParser parser)
        {
            Parser = parser;
            BinaryReader reader = new BinaryReader(stream);

            UsedLength = reader.ReadInt32BE();
            ContentLengthCopy = reader.ReadInt32BE();
            Format = reader.ReadInt32BE();
            DataPosition = reader.ReadInt32BE();
            Unknown6 = reader.ReadInt32BE();
            Version = reader.ReadName0();

            Unknown7 = reader.ReadInt32();

            int numTypes = reader.ReadInt32();
            Types = new List<TypeDefinition>(numTypes);
            for (int i = 0; i < numTypes; i++)
            {
                TypeDefinition t = new TypeDefinition();
                t.typeId = reader.ReadInt32();
                t.definitions = new TypeDefinitionString();
                ReadType(reader, t.definitions);
                Types.Add(t);
            }

            Unknown8 = reader.ReadInt32();

            int numComponents = reader.ReadInt32();
            Components = new List<Component>(numComponents);
            for (int i = 0; i < numComponents; i++)
            {
                int pathID = reader.ReadInt32();
                uint offset = (uint)(parser.HeaderLength + parser.Offset) + (uint)DataPosition + reader.ReadUInt32();
                uint size = reader.ReadUInt32();
                NotLoaded comp = new NotLoaded(this, pathID, (UnityClassID)reader.ReadInt32(), (UnityClassID)reader.ReadInt32());
                comp.offset = offset;
                comp.size = size;
                Components.Add(comp);
            }

            int numRefs = reader.ReadInt32();
            References = new Reference[numRefs];
            for (int i = 0; i < numRefs; i++)
            {
                References[i] = new Reference();
                References[i].guid = new Guid(reader.ReadBytes(16));
                References[i].type = reader.ReadInt32();
                References[i].filePath = reader.ReadName0();
                References[i].assetPath = reader.ReadName0();
            }
            if (stream.Position != UsedLength + (parser.HeaderLength + parser.Offset) + 0x13)
            {
                Report.ReportLog("Unexpected Length Pos=" + stream.Position.ToString("X") + " UsedLength=" + UsedLength.ToString("X"));
            }
            long padding = (stream.Position + 16) & ~(long)15;
            if (padding != parser.HeaderLength + parser.Offset + DataPosition)
            {
                Report.ReportLog("Unexpected DataPosition");
            }

            RemovedList = new List<NotLoaded>();
            loadingReferencials = false;
            reported = new HashSet<string>();

            for (int i = 0; i < Components.Count; i++)
            {
                Component asset = Components[i];
                if (asset.classID1 == UnityClassID.AssetBundle)
                {
                    Bundle = LoadComponent(stream, i, (NotLoaded)asset);
                    break;
                }
            }
        }
Example #26
0
        public EncodingHandler(BinaryReader stream, BackgroundWorkerEx worker)
        {
            worker?.ReportProgress(0, "Loading \"encoding\"...");

            stream.Skip(2); // EN
            byte b1 = stream.ReadByte();
            byte checksumSizeA = stream.ReadByte();
            byte checksumSizeB = stream.ReadByte();
            ushort flagsA = stream.ReadUInt16();
            ushort flagsB = stream.ReadUInt16();
            int numEntriesA = stream.ReadInt32BE();
            int numEntriesB = stream.ReadInt32BE();
            byte b4 = stream.ReadByte();
            int stringBlockSize = stream.ReadInt32BE();

            stream.Skip(stringBlockSize);
            //string[] strings = Encoding.ASCII.GetString(stream.ReadBytes(stringBlockSize)).Split(new[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);

            stream.Skip(numEntriesA * 32);
            //for (int i = 0; i < numEntriesA; ++i)
            //{
            //    byte[] firstHash = stream.ReadBytes(16);
            //    byte[] blockHash = stream.ReadBytes(16);
            //}

            long chunkStart = stream.BaseStream.Position;

            for (int i = 0; i < numEntriesA; ++i)
            {
                ushort keysCount;

                while ((keysCount = stream.ReadUInt16()) != 0)
                {
                    int fileSize = stream.ReadInt32BE();
                    byte[] md5 = stream.ReadBytes(16);

                    EncodingEntry entry = new EncodingEntry();
                    entry.Size = fileSize;

                    // how do we handle multiple keys?
                    for (int ki = 0; ki < keysCount; ++ki)
                    {
                        byte[] key = stream.ReadBytes(16);

                        // use first key for now
                        if (ki == 0)
                            entry.Key = key;
                        else
                            Logger.WriteLine("Multiple encoding keys for MD5 {0}: {1}", md5.ToHexString(), key.ToHexString());
                    }

                    //Encodings[md5] = entry;
                    EncodingData.Add(md5, entry);
                }

                // each chunk is 4096 bytes, and zero padding at the end
                long remaining = CHUNK_SIZE - ((stream.BaseStream.Position - chunkStart) % CHUNK_SIZE);

                if (remaining > 0)
                    stream.BaseStream.Position += remaining;

                worker?.ReportProgress((int)((i + 1) / (float)numEntriesA * 100));
            }

            stream.Skip(numEntriesB * 32);
            //for (int i = 0; i < numEntriesB; ++i)
            //{
            //    byte[] firstKey = stream.ReadBytes(16);
            //    byte[] blockHash = stream.ReadBytes(16);
            //}

            long chunkStart2 = stream.BaseStream.Position;

            for (int i = 0; i < numEntriesB; ++i)
            {
                byte[] key = stream.ReadBytes(16);
                int stringIndex = stream.ReadInt32BE();
                byte unk1 = stream.ReadByte();
                int fileSize = stream.ReadInt32BE();

                // each chunk is 4096 bytes, and zero padding at the end
                long remaining = CHUNK_SIZE - ((stream.BaseStream.Position - chunkStart2) % CHUNK_SIZE);

                if (remaining > 0)
                    stream.BaseStream.Position += remaining;
            }

            // string block till the end of file
        }