using SLProxy; using libsecondlife; using Nwc.XmlRpc; using libsecondlife.Packets; using System.Reflection; using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; using System.Text.RegularExpressions; public class DumpAssetUpload : ProxyPlugin { private ProxyFrame frame; private Proxy proxy; private Dictionary xfers = new Dictionary(); private class Upload { LLUUID trans; int type; uint nextpacket = 0; int length = 0; int got = 0; bool done = false; FileStream wout; Dictionary packets; public Upload(LLUUID transaction, int type, ulong xferid) { this.trans = transaction; this.type = type; wout = File.Create(trans.ToStringHyphenated() + "-" + type + ".bin"); } public Packet GotPacket(SendXferPacketPacket xfer) { lock(this) { uint packetno = xfer.XferID.Packet & 0x7fffffff; if(packetno > nextpacket) { // FIXME - evil! Console.WriteLine("Got xfer packet "+packetno+" expecting "+nextpacket+"; dropping"); return null; } else if(packetno == nextpacket) { Console.WriteLine("Got xfer packet "+packetno); HandleNextPacket(xfer.DataPacket.Data, (xfer.XferID.Packet & 0x80000000U) != 0); } else { Console.WriteLine("Got duplicate xfer packet "+packetno); } return xfer; }} private void HandleNextPacket(byte[] data, bool islast) { if(nextpacket == 0) { length = (int)(data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)); Console.WriteLine(trans.ToStringHyphenated() + "-" + type + ": length "+length); wout.Write(data,4,data.Length-4); got += data.Length-4; } else { wout.Write(data,0,data.Length); got += data.Length; } nextpacket += 1; if(islast) { wout.Close(); wout = null; Console.WriteLine(trans.ToStringHyphenated() + "-" + type + ": done, "+got+" bytes transferred"); done = true; } } } public DumpAssetUpload(ProxyFrame frame) { this.frame = frame; this.proxy = frame.proxy; } public override void Init() { proxy.AddDelegate(PacketType.AssetUploadRequest, Direction.Outgoing, new PacketDelegate(OnAssetUploadRequest)); proxy.AddDelegate(PacketType.RequestXfer, Direction.Incoming, new PacketDelegate(OnRequestXfer)); proxy.AddDelegate(PacketType.SendXferPacket, Direction.Outgoing, new PacketDelegate(OnSendXferPacket)); } private LLUUID trans; private int type; private Packet OnAssetUploadRequest(Packet packet, IPEndPoint endPoint) { AssetUploadRequestPacket upload = (AssetUploadRequestPacket) packet; Console.WriteLine("Asset transfer: "+upload.AssetBlock.TransactionID.ToStringHyphenated() + "-" + upload.AssetBlock.Type); if(upload.AssetBlock.AssetData.Length > 0) { FileStream wout = File.Create(upload.AssetBlock.TransactionID.ToStringHyphenated() + "-" + upload.AssetBlock.Type + ".bin"); wout.Write(upload.AssetBlock.AssetData,0,upload.AssetBlock.AssetData.Length); wout.Close(); } else { trans = upload.AssetBlock.TransactionID; type = upload.AssetBlock.Type; } return packet; } private Packet OnRequestXfer(Packet packet, IPEndPoint endPoint) { RequestXferPacket xfer = (RequestXferPacket)packet; if(trans != null && xfer.XferID.FilePath == 0 && xfer.XferID.VFileType == type) { xfers.Add(xfer.XferID.ID, new Upload(trans,type,xfer.XferID.ID)); } return packet; } private Packet OnSendXferPacket(Packet packet, IPEndPoint endPoint) { SendXferPacketPacket xfer = (SendXferPacketPacket)packet; if(xfers.ContainsKey(xfer.XferID.ID)) { return xfers[xfer.XferID.ID].GotPacket(xfer); } return packet; } }