Skip to content

Commit

Permalink
Texture downloading *actually works*!
Browse files Browse the repository at this point in the history
Also catches an obscure error that was breaking everything.
  • Loading branch information
Katharine committed Jan 24, 2010
1 parent cd514ff commit 75ad911
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 179 deletions.
7 changes: 2 additions & 5 deletions client/AjaxLife.Texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ AjaxLife.Texture = function(parent, width, height, texture, slsearch, forceslsea
// size.
function replaceimage(src)
{
var img = new Image();
img.onload = function() {
elem.setAttribute('src',src);
elem.onload = function() {
elem.setStyle({
paddingLeft: '0px',
paddingRight: '0px',
Expand All @@ -45,7 +43,6 @@ AjaxLife.Texture = function(parent, width, height, texture, slsearch, forceslsea
height: height+'px'
});
loaded = true;
img.onload = function(){};
if(typeof(onloadcallback) == 'function')
{
try
Expand All @@ -58,7 +55,7 @@ AjaxLife.Texture = function(parent, width, height, texture, slsearch, forceslsea
}
}
}
img.src = src;
elem.setAttribute('src',src);
}

// This creates a spinner to indicate that something's happening.
Expand Down
1 change: 0 additions & 1 deletion server/AjaxLife.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@
<Compile Include="Html\LoginDetails.cs" />
<Compile Include="Main.cs" />
<Compile Include="MakeJson.cs" />
<Compile Include="TextureDirectory.cs" />
<Compile Include="User.cs" />
<Compile Include="Html\MakeFile.cs" />
<Compile Include="BanList.cs" />
Expand Down
4 changes: 0 additions & 4 deletions server/Converters/UUIDConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,13 @@

namespace AjaxLife.Converters
{
// Inherit from the generic JsonConverter.
class UUIDConverter : JsonConverter
{
// Convert JSON using UUID::ToStringHyphenated, which outputs as follows:
// 00000000-0000-0000-0000-000000000000
public override void WriteJson(JsonWriter writer, object value)
{
base.WriteJson(writer, ((OpenMetaverse.UUID)value).ToString());
}

// Check if we can created an UUID from whatever we're being given.
public override bool CanConvert(Type objectType)
{
return typeof(OpenMetaverse.UUID).IsAssignableFrom(objectType);
Expand Down
106 changes: 65 additions & 41 deletions server/Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenMetaverse.Assets;
Expand All @@ -39,6 +40,8 @@
using Affirma.ThreeSharp;
using Affirma.ThreeSharp.Query;

using Bitmap = System.Drawing.Bitmap;

namespace AjaxLife
{
public class Events
Expand Down Expand Up @@ -99,7 +102,8 @@ public Hashtable GetFooter(GridClient client)

private void enqueue(Hashtable message)
{
if(!message.ContainsKey("MessageType")) return;
if(!message.ContainsKey("MessageType")) return;
if(message == null) return;
if(user.RequestedEvents == null || user.RequestedEvents.Contains((string)message["MessageType"]))
{
this.pending.Enqueue(message);
Expand Down Expand Up @@ -405,35 +409,64 @@ public void Packet_MapItemReply(Packet packet, Simulator sim)
hash.Add("Items", items);
enqueue(hash);
}
/*
public void Assets_OnImageReceived(ImageDownload image, AssetTexture asset)

public void Assets_TextureDownloadCallback(TextureRequestState state, AssetTexture texture)
{
if (image.NotFound)
if(state == TextureRequestState.NotFound || state == TextureRequestState.Aborted || state == TextureRequestState.Timeout)
{
Console.WriteLine("Failed to download " + image.ID + " - not found.");
Console.WriteLine("Failed to download " + texture.AssetID + " - " + state.ToString() + ".");
Hashtable hash = new Hashtable();
hash.Add("MessageType", "ImageDownloaded");
hash.Add("UUID", image.ID);
hash.Add("UUID", texture.AssetID);
hash.Add("Success", false);
hash.Add("Error", "Image not found in database.");
hash.Add("Error", "Image could not be downloaded: " + state.ToString());
enqueue(hash);
}
else if (image.Success)
else if(state == TextureRequestState.Finished)
{
bool success = true;
string key = image.ID.ToString();
try
{
OpenMetaverse.Imaging.ManagedImage decoded;
OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(image.AssetData, out decoded);
byte[] img = decoded.ExportTGA();
decoded.Clear();
File.WriteAllBytes(AjaxLife.TEXTURE_CACHE + key + ".tga", img);
Process process = Process.Start("convert", AjaxLife.TEXTURE_CACHE + key + ".tga " + AjaxLife.TEXTURE_CACHE + key + ".png");
process.WaitForExit();
process.Dispose();
File.Delete(AjaxLife.TEXTURE_CACHE + key + ".tga");
Console.WriteLine("Downloaded image " + key + " - " + image.Size + " bytes.");
string key = texture.AssetID.ToString();
try
{
texture.Decode();
byte[] img = texture.Image.ExportRaw();
int size = img.Length;
int width = texture.Image.Width;
int height = texture.Image.Height;
texture.Image.Clear();

// Helpfully, it's upside-down, and has red and blue flipped.

// Assuming 32 bits (accurate) and a height as a multiple of two (accurate),
// this will vertically invert the image.
int length = width * 4;
byte[] fliptemp = new byte[length];
for(int i = 0; i < height / 2; ++i)
{
int index = i * width * 4;
int endindex = size - ((i+1) * width * 4);
Array.Copy(img, index, fliptemp, 0, length);
Array.Copy(img, endindex, img, index, length);
Array.Copy(fliptemp, 0, img, endindex, length);
}

// This changes RGBA to BGRA. Or possibly vice-versa. I don't actually know.
// The documentation is vague/nonexistent.
for(int i = 0; i < size; i += 4)
{
byte temp = img[i+2];
img[i+2] = img[i];
img[i] = temp;
}

// Use System.Drawing.Bitmap to create a PNG. This requires us to feed it a pointer to an array
// for whatever reason, so we temporarily pin the image array.
GCHandle handle = GCHandle.Alloc(img, GCHandleType.Pinned);
Bitmap bitmap = new Bitmap(texture.Image.Width, texture.Image.Height, texture.Image.Width * 4,
System.Drawing.Imaging.PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
bitmap.Save(AjaxLife.TEXTURE_CACHE + key + ".png", System.Drawing.Imaging.ImageFormat.Png);
bitmap.Dispose();
handle.Free();
if(AjaxLife.USE_S3)
{
try
Expand All @@ -442,41 +475,32 @@ public void Assets_OnImageReceived(ImageDownload image, AssetTexture asset)
Affirma.ThreeSharp.Model.ObjectAddRequest request = new Affirma.ThreeSharp.Model.ObjectAddRequest(AjaxLife.TEXTURE_BUCKET, key + ".png");
request.LoadStreamWithFile(AjaxLife.TEXTURE_CACHE + key + ".png");
request.Headers.Add("x-amz-acl", "public-read");
request.Headers.Add("Content-Type", "image/png");
service.ObjectAdd(request).DataStream.Close();
AjaxLife.CachedTextures.Add(image.ID);
AjaxLife.CachedTextures.Add(texture.AssetID);
File.Delete(AjaxLife.TEXTURE_CACHE + key + ".png");
}
catch
{
success = false;
}
File.Delete(AjaxLife.TEXTURE_CACHE + key + ".png");
}
}
catch(Exception e)
{
success = false;
AjaxLife.Debug("Events", "Texture download for "+key+" failed: "+e.Message);
}
}
catch(Exception e)
{
success = false;
AjaxLife.Debug("Events", "Texture download for "+key+" failed (" + e.GetType().Name + "): " + e.Message);
}
Hashtable hash = new Hashtable();
hash.Add("MessageType", "ImageDownloaded");
hash.Add("Success", success);
hash.Add("Size", image.Size);
hash.Add("UUID", key);
hash.Add("URL", AjaxLife.TEXTURE_ROOT + key + ".png");
enqueue(hash);
}
else
{
Console.WriteLine("Failed to download " + image.ID + ".");
Hashtable hash = new Hashtable();
hash.Add("MessageType", "ImageDownloaded");
hash.Add("UUID", image.ID);
hash.Add("Success", false);
hash.Add("Error", "Unknown error.");
enqueue(hash);
}

}
*/

public void Friends_OnFriendshipOffered(UUID agentID, string agentName, UUID imSessionID)
{
Hashtable hash = new Hashtable();
Expand Down
4 changes: 1 addition & 3 deletions server/Html/SendMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,7 @@ public void OnFileRequested(HttpRequest request, IDirectory directory)
// Notification will arrive later in the message queue.
else
{

//client.Assets.RequestImage(image, ImageType.Normal, 125000.0f, 0);
client.Assets.RequestImage(image, new TextureDownloadCallback(events.Assets_TextureDownloadCallback));
textwriter.Write("{Ready: false}");
}
}
Expand Down Expand Up @@ -468,7 +467,6 @@ public void OnFileRequested(HttpRequest request, IDirectory directory)
events.Assets_OnAssetReceived(transfer, asset, inventoryID);
}
);
textwriter.Write("{TransferID: \"" + POST["AssetID"] + "\", Fake: true}"); // Fix the client to not use this.
}
catch // Try catching the error that sometimes gets thrown... but sometimes doesn't.
{
Expand Down
2 changes: 1 addition & 1 deletion server/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ public AjaxLife(string[] arg)
// textures/ is only used if we aren't using S3 for textures.
if(!UseS3)
{
root.AddDirectory(new TextureDirectory("textures", root));
root.AddDirectory(new DriveDirectory("textures", AjaxLife.TEXTURE_CACHE, root));
}
// API stuff.
VirtualDirectory api = new VirtualDirectory("api", root);
Expand Down
11 changes: 9 additions & 2 deletions server/MakeJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,15 @@ public static string FromHashtableQueue(Queue<Hashtable> queue)
serializer.Converters.Add(UUID);
while (queue.Count > 0)
{
Hashtable hashtable = queue.Dequeue();
serializer.Serialize(jsonWriter, hashtable);
try
{
Hashtable hashtable = queue.Dequeue();
serializer.Serialize(jsonWriter, hashtable);
}
catch(Exception e)
{
AjaxLife.Debug("MakeJson.FromHashTable", e.Message);
}
}
jsonWriter.WriteEndArray();
jsonWriter.Flush();
Expand Down
122 changes: 0 additions & 122 deletions server/TextureDirectory.cs

This file was deleted.

1 change: 1 addition & 0 deletions server/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public GridClient GetClient()
client.Settings.ENABLE_SIMSTATS = true;
client.Settings.LOGOUT_TIMEOUT = 20000;
client.Settings.LOG_RESENDS = false;
client.Settings.USE_ASSET_CACHE = false;
client.Throttle.Cloud = 0;
client.Throttle.Task = 0;
client.Throttle.Wind = 0;
Expand Down

0 comments on commit 75ad911

Please sign in to comment.