Index: applications/SLProxy/ScriptInject.cs =================================================================== --- applications/SLProxy/ScriptInject.cs (revision 0) +++ applications/SLProxy/ScriptInject.cs (revision 0) @@ -0,0 +1,128 @@ +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 ScriptInject : ProxyPlugin +{ + private ProxyFrame frame; + private Proxy proxy; + private Dictionary xfers = new Dictionary(); + private bool swapIt = false; + private byte[] newdata = null; + + private class Upload { + uint nextpacket = 0; int length = 0; + Dictionary packets = new Dictionary(); + private byte[] newdata; + public Upload(ulong xferid, byte[] newdata) { + this.newdata = newdata; + } + + public Packet GotPacket(SendXferPacketPacket xfer) { lock(this) { + uint packetno = xfer.XferID.Packet & 0x7fffffff; + byte[] pdata = xfer.DataPacket.Data; + if(newdata == null) return xfer; + if(packetno > nextpacket) { + // Can't fix up this packet until we know the size of the previous ones. + Console.WriteLine("Got xfer packet "+packetno+" expecting "+nextpacket+"; dropping"); + return null; + } else if(packetno == nextpacket) { + if(packetno == 0) { + length = (int)(pdata[0] + (pdata[1] << 8) + (pdata[2] << 16) + (pdata[3] << 24)); + if(length != newdata.Length) { + Console.WriteLine("Can't replace "+length+" bytes with "+newdata.Length+" bytes"); + packetno += 1; newdata = null; return xfer; + } + packets[0] = pdata.Length - 4; + } else { + packets[packetno] = packets[packetno - 1] + pdata.Length; + } + Console.WriteLine("Replacing xfer packet "+packetno); + nextpacket += 1; + } else { + Console.WriteLine("Got duplicate xfer packet "+packetno); + } + + if(packetno == 0) { + Array.Copy(newdata, 0, pdata, 4, pdata.Length - 4); + } else { + Array.Copy(newdata,packets[packetno-1],pdata,0,pdata.Length); + } + + return xfer; + }} + } + + public ScriptInject(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)); + frame.AddCommand("/lso", new ProxyFrame.CommandDelegate(CmdLso)); + } + + // CmdLog: handle a /log command + private void CmdLso(string[] words) + { + if (words.Length != 2) { + frame.SayToUser("Usage: /lso "); + return; + } + FileStream fin = File.Open(words[1], FileMode.Open, FileAccess.Read); + byte[] data = new byte[fin.Length]; + int count = 0; + while(count < data.Length) { + int ret = fin.Read(data,count,data.Length-count); + if(ret <= 0) { + frame.SayToUser("Read failed?"); + fin.Close(); return; + } + count += ret; + } + fin.Close(); + lock(this) { newdata = data; } + frame.SayToUser("Upload swap prepared!"); + } + + + private Packet OnAssetUploadRequest(Packet packet, IPEndPoint endPoint) { lock(this) { + AssetUploadRequestPacket upload = (AssetUploadRequestPacket) packet; + Console.WriteLine("Asset transfer: "+upload.AssetBlock.TransactionID.ToStringHyphenated() + "-" + upload.AssetBlock.Type); + if(upload.AssetBlock.AssetData.Length == 0 && upload.AssetBlock.Type == 11 && newdata != null) { + swapIt = true; + } + return packet; + }} + + private Packet OnRequestXfer(Packet packet, IPEndPoint endPoint) { lock(this) { + RequestXferPacket xfer = (RequestXferPacket)packet; + if(swapIt && xfer.XferID.FilePath == 0 && xfer.XferID.VFileType == 11) { + xfers.Add(xfer.XferID.ID, new Upload(xfer.XferID.ID,newdata)); + newdata = null; swapIt = false; + } + return packet; + }} + + private Packet OnSendXferPacket(Packet packet, IPEndPoint endPoint) { lock(this) { + SendXferPacketPacket xfer = (SendXferPacketPacket)packet; + if(xfers.ContainsKey(xfer.XferID.ID)) { + return xfers[xfer.XferID.ID].GotPacket(xfer); + } + return packet; + }} +} \ No newline at end of file Index: applications/SLProxy/SLProxy.build =================================================================== --- applications/SLProxy/SLProxy.build (revision 803) +++ applications/SLProxy/SLProxy.build (working copy) @@ -43,7 +43,7 @@ - @@ -104,6 +104,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: applications/SLProxy/DumpAssetUpload.cs =================================================================== --- applications/SLProxy/DumpAssetUpload.cs (revision 0) +++ applications/SLProxy/DumpAssetUpload.cs (revision 0) @@ -0,0 +1,106 @@ +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; + } +} \ No newline at end of file