diff --git a/2D/Widgets/PlayerListWidget.cs b/2D/Widgets/PlayerListWidget.cs
index 888fe95ba..d75c9e5c0 100644
--- a/2D/Widgets/PlayerListWidget.cs
+++ b/2D/Widgets/PlayerListWidget.cs
@@ -43,7 +43,6 @@ namespace ClassicalSharp {
SortPlayerInfo();
Window.EntityAdded += PlayerSpawned;
Window.EntityRemoved += PlayerDespawned;
- Window.EntityInfoChanged += PlayerInfoChanged;
}
public override void Render( double delta ) {
@@ -62,7 +61,6 @@ namespace ClassicalSharp {
}
Window.EntityAdded -= PlayerSpawned;
Window.EntityRemoved -= PlayerDespawned;
- Window.EntityInfoChanged -= PlayerInfoChanged;
}
void PlayerSpawned( object sender, IdEventArgs e ) {
@@ -84,18 +82,6 @@ namespace ClassicalSharp {
}
}
}
-
- void PlayerInfoChanged( object sender, IdEventArgs e ) {
- for( int i = 0; i < info.Count; i++ ) {
- PlayerInfo pInfo = info[i];
- if( pInfo.PlayerId == e.Id ) {
- GraphicsApi.DeleteTexture( ref pInfo.Texture );
- info[i] = new PlayerInfo( GraphicsApi, Window.NetPlayers[e.Id], font );
- SortPlayerInfo();
- break;
- }
- }
- }
void CreateInitialPlayerInfo() {
for( int i = 0; i < Window.NetPlayers.Length; i++ ) {
diff --git a/Entities/Player.cs b/Entities/Player.cs
index 1a3ea8bd9..a49ae72fa 100644
--- a/Entities/Player.cs
+++ b/Entities/Player.cs
@@ -1,6 +1,7 @@
using System;
using System.Drawing;
using OpenTK;
+using ClassicalSharp.Network;
using ClassicalSharp.Model;
using ClassicalSharp.Renderers;
@@ -105,9 +106,10 @@ namespace ClassicalSharp {
}
protected void CheckSkin() {
- Bitmap bmp;
- Window.AsyncDownloader.TryGetImage( "skin_" + SkinName, out bmp );
- if( bmp != null ) {
+ DownloadedItem item;
+ Window.AsyncDownloader.TryGetItem( "skin_" + SkinName, out item );
+ if( item != null && item.Bmp != null ) {
+ Bitmap bmp = item.Bmp;
Window.Graphics.DeleteTexture( renderer.TextureId );
renderer.TextureId = Window.Graphics.LoadTexture( bmp );
SkinType = Utils.GetSkinType( bmp );
diff --git a/Game/Game.Events.cs b/Game/Game.Events.cs
index 9688a9fe5..865304ad0 100644
--- a/Game/Game.Events.cs
+++ b/Game/Game.Events.cs
@@ -9,10 +9,6 @@ namespace ClassicalSharp {
/// Raised when a player is spawned in the current world.
public event EventHandler EntityAdded;
- /// Raised when information(display name and/or skin name) is changed about a player.
- /// Note this event is only raised when using the CPE player list extension.
- public event EventHandler EntityInfoChanged;
-
/// Raised when a player is despawned from the current world.
public event EventHandler EntityRemoved;
@@ -55,11 +51,6 @@ namespace ClassicalSharp {
RaiseEvent( EntityAdded, e );
}
- internal void RaiseEntityInfoChange( byte id ) {
- IdEventArgs e = new IdEventArgs( id );
- RaiseEvent( EntityInfoChanged, e );
- }
-
internal void RaiseEntityRemoved( byte id ) {
IdEventArgs e = new IdEventArgs( id );
RaiseEvent( EntityRemoved, e );
diff --git a/Network/AsyncDownloader.cs b/Network/AsyncDownloader.cs
index 383187631..e55da11fe 100644
--- a/Network/AsyncDownloader.cs
+++ b/Network/AsyncDownloader.cs
@@ -15,76 +15,38 @@ namespace ClassicalSharp.Network {
readonly object requestLocker = new object();
List requests = new List();
readonly object downloadedLocker = new object();
- Dictionary downloaded = new Dictionary();
+ Dictionary downloaded = new Dictionary();
string skinServer = null;
public AsyncDownloader( string skinServer ) {
this.skinServer = skinServer;
client = new WebClient();
client.Proxy = null;
+
worker = new Thread( DownloadThreadWorker );
worker.Name = "ClassicalSharp.ImageDownloader";
worker.IsBackground = true;
worker.Start();
}
- class DownloadedRequest {
-
- public Bitmap Bmp;
- public string Page;
- public DateTime Timestamp;
-
- public DownloadedRequest( Bitmap bmp, string page ) {
- Bmp = bmp;
- Page = page;
- Timestamp = DateTime.UtcNow;
- }
- }
-
- class DownloadRequest {
-
- public string Url;
- public string Identifier;
- public bool IsImage;
-
- public DownloadRequest( string url, string identifier, bool isImage ) {
- Url = url;
- Identifier = identifier;
- IsImage = isImage;
- }
- }
-
public void DownloadSkin( string skinName ) {
string strippedSkinName = Utils.StripColours( skinName );
- string url = skinServer + strippedSkinName + ".png";
- DownloadImage( url, false, "skin_" + strippedSkinName );
+ string url = Utils.IsUrl( skinName ) ? skinName :
+ skinServer + strippedSkinName + ".png";
+ AddRequestToQueue( url, true, "skin_" + strippedSkinName, true );
}
- /// Downloads an image, asynchronously, from the specified url.
- /// URL the image is located at.
- /// If this is true, the request is added straight to the
- /// start of the requests queue. (otherwise added to the end)
- /// Unique identifier for the image. (e.g. skin_test)
public void DownloadImage( string url, bool priority, string identifier ) {
- lock( requestLocker ) {
- DownloadRequest request = new DownloadRequest( url, identifier, true );
- if( priority ) {
- requests.Insert( 0, request );
- } else {
- requests.Add( request );
- }
- }
- handle.Set();
+ AddRequestToQueue( url, priority, identifier, true );
}
- /// Downloads a page, asynchronously, from the specified url.
- /// URL the image is located at.
- /// If this is true, the request is added straight to the
- /// start of the requests queue. (otherwise added to the end)
- /// Unique identifier for the image. (e.g. skin_test)
public void DownloadPage( string url, bool priority, string identifier ) {
+ AddRequestToQueue( url, priority, identifier, false );
+ }
+
+ void AddRequestToQueue( string url, bool priority, string identifier, bool image ) {
lock( requestLocker ) {
- DownloadRequest request = new DownloadRequest( url, identifier, false );
+ DownloadRequest request = new DownloadRequest( url, identifier, image );
if( priority ) {
requests.Insert( 0, request );
} else {
@@ -105,54 +67,35 @@ namespace ClassicalSharp.Network {
client.Dispose();
}
- /// Removes all entries from the downloaded images queue that are
- /// older (relative to the current time) than the given number of seconds.
public void PurgeOldEntries( int seconds ) {
lock( downloadedLocker ) {
DateTime now = DateTime.UtcNow;
- List requestsToRemove = new List( downloaded.Count );
+ List itemsToRemove = new List( downloaded.Count );
foreach( var item in downloaded ) {
- DateTime timestamp = item.Value.Timestamp;
+ DateTime timestamp = item.Value.TimeDownloaded;
if( ( now - timestamp ).TotalSeconds > seconds ) {
- requestsToRemove.Add( item.Key );
+ itemsToRemove.Add( item.Key );
}
}
- for( int i = 0; i < requestsToRemove.Count; i++ ) {
- string key = requestsToRemove[i];
- DownloadedRequest req;
- downloaded.TryGetValue( key, out req );
+ for( int i = 0; i < itemsToRemove.Count; i++ ) {
+ string key = itemsToRemove[i];
+ DownloadedItem item;
+ downloaded.TryGetValue( key, out item );
downloaded.Remove( key );
- if( req.Bmp != null ) {
- req.Bmp.Dispose();
+ if( item.Bmp != null ) {
+ item.Bmp.Dispose();
}
}
}
}
- public bool TryGetImage( string identifier, out Bitmap bmp ) {
+ public bool TryGetItem( string identifier, out DownloadedItem item ) {
bool success = false;
- bmp = null;
- DownloadedRequest req;
lock( downloadedLocker ) {
- success = downloaded.TryGetValue( identifier, out req );
+ success = downloaded.TryGetValue( identifier, out item );
if( success ) {
- bmp = req.Bmp;
- downloaded.Remove( identifier );
- }
- }
- return success;
- }
-
- public bool TryGetPage( string identifier, out string page ) {
- bool success = false;
- page = null;
- DownloadedRequest req;
- lock( downloadedLocker ) {
- success = downloaded.TryGetValue( identifier, out req );
- if( success ) {
- page = req.Page;
downloaded.Remove( identifier );
}
}
@@ -167,53 +110,85 @@ namespace ClassicalSharp.Network {
if( requests.Count > 0 ) {
request = requests[0];
requests.RemoveAt( 0 );
- if( request == null ) return;
+ if( request == null )
+ return;
}
}
if( request != null ) {
- string url = request.Url;
- bool isImage = request.IsImage;
- Utils.LogDebug( "Downloading " + ( isImage ? "image" : "page" ) + " from: " + url );
- Bitmap bmp = null;
- string page = null;
-
- try {
- if( isImage ) {
- bmp = DownloadImage( request.Url, client );
- } else {
- page = DownloadPage( request.Url, client );
- }
- Utils.LogDebug( "Downloaded from: " + request.Url );
- } catch( Exception ex ) {
- if( !( ex is WebException || ex is ArgumentException ) ) throw;
- bmp = null;
- page = null;
- Utils.LogDebug( "Failed to download from: " + request.Url );
- }
-
- lock( downloadedLocker ) {
- DownloadedRequest old;
- if( downloaded.TryGetValue( request.Identifier, out old ) ) {
- Utils.LogDebug( "{0} is already in the queue, replacing it..", request.Identifier );
- if( old.Bmp != null ) old.Bmp.Dispose();
- }
- downloaded[request.Identifier] = new DownloadedRequest( bmp, page );
- }
+ DownloadItem( request );
} else {
handle.WaitOne();
}
}
}
- static Bitmap DownloadImage( string uri, WebClient client ) {
- byte[] data = client.DownloadData( uri );
- using( MemoryStream stream = new MemoryStream( data ) ) {
- return new Bitmap( stream );
+ void DownloadItem( DownloadRequest request ) {
+ string url = request.Url;
+ bool isImage = request.IsImage;
+ Utils.LogDebug( "Downloading " + ( isImage ? "image" : "page" ) + " from: " + url );
+ Bitmap bmp = null;
+ string page = null;
+
+ try {
+ if( isImage ) {
+ byte[] data = client.DownloadData( url );
+ using( MemoryStream stream = new MemoryStream( data ) ) {
+ bmp = new Bitmap( stream );
+ }
+ } else {
+ page = client.DownloadString( url );
+ }
+ Utils.LogDebug( "Downloaded from: " + request.Url );
+ } catch( Exception ex ) {
+ if( !( ex is WebException || ex is ArgumentException ) ) throw;
+ Utils.LogDebug( "Failed to download from: " + request.Url );
+ }
+
+ lock( downloadedLocker ) {
+ DownloadedItem oldItem;
+ DownloadedItem newItem = new DownloadedItem( bmp, page, request.TimeAdded );
+
+ if( downloaded.TryGetValue( request.Identifier, out oldItem ) ) {
+ if( oldItem.TimeAdded > newItem.TimeAdded ) {
+ DownloadedItem old = oldItem;
+ oldItem = newItem;
+ newItem = old;
+ }
+
+ if( oldItem.Bmp != null )
+ oldItem.Bmp.Dispose();
+ }
+ downloaded[request.Identifier] = newItem;
}
}
- static string DownloadPage( string uri, WebClient client ) {
- return client.DownloadString( uri );
+ class DownloadRequest {
+
+ public string Url;
+ public string Identifier;
+ public bool IsImage;
+ public DateTime TimeAdded;
+
+ public DownloadRequest( string url, string identifier, bool isImage ) {
+ Url = url;
+ Identifier = identifier;
+ IsImage = isImage;
+ TimeAdded = DateTime.UtcNow;
+ }
+ }
+ }
+
+ public class DownloadedItem {
+
+ public Bitmap Bmp;
+ public string Page;
+ public DateTime TimeAdded, TimeDownloaded;
+
+ public DownloadedItem( Bitmap bmp, string page, DateTime timeAdded ) {
+ Bmp = bmp;
+ Page = page;
+ TimeAdded = timeAdded;
+ TimeDownloaded = DateTime.UtcNow;
}
}
}
\ No newline at end of file
diff --git a/Network/NetworkProcessor.cs b/Network/NetworkProcessor.cs
index ec674a2a7..e693df71d 100644
--- a/Network/NetworkProcessor.cs
+++ b/Network/NetworkProcessor.cs
@@ -6,6 +6,7 @@ using System.IO.Compression;
using System.Net;
using System.Net.Sockets;
using System.Text;
+using ClassicalSharp.Network;
using OpenTK;
namespace ClassicalSharp {
@@ -65,10 +66,10 @@ namespace ClassicalSharp {
}
void CheckForNewTerrainAtlas() {
- Bitmap bmp;
- Window.AsyncDownloader.TryGetImage( "terrain", out bmp );
- if( bmp != null ) {
- Window.ChangeTerrainAtlas( bmp );
+ DownloadedItem item;
+ Window.AsyncDownloader.TryGetItem( "terrain", out item );
+ if( item != null && item.Bmp != null ) {
+ Window.ChangeTerrainAtlas( item.Bmp );
}
}
@@ -353,7 +354,7 @@ namespace ClassicalSharp {
{
byte entityId = reader.ReadUInt8();
string name = reader.ReadString();
- AddEntity( entityId, name, name );
+ AddEntity( entityId, name, name, true );
} break;
case PacketId.EntityTeleport:
@@ -494,18 +495,7 @@ namespace ClassicalSharp {
byte entityId = reader.ReadUInt8();
string displayName = reader.ReadString();
string skinName = reader.ReadString();
- if( entityId != 0xFF ) {
- Window.AsyncDownloader.DownloadSkin( skinName );
- Player oldPlayer = Window.NetPlayers[entityId];
- if( oldPlayer != null ) {
- oldPlayer.DisplayName = displayName;
- oldPlayer.SkinName = skinName;
- Window.RaiseEntityInfoChange( entityId );
- } else {
- Window.NetPlayers[entityId] = new NetPlayer( entityId, displayName, skinName, Window );
- Window.RaiseEntityAdded( entityId );
- }
- }
+ AddEntity( entityId, displayName, skinName, false );
} break;
case PacketId.CpeExtRemovePlayerName:
@@ -631,7 +621,7 @@ namespace ClassicalSharp {
byte entityId = reader.ReadUInt8();
string displayName = reader.ReadString();
string skinName = reader.ReadString();
- AddEntity( entityId, displayName, skinName );
+ AddEntity( entityId, displayName, skinName, true );
} break;
default:
@@ -639,7 +629,7 @@ namespace ClassicalSharp {
}
}
- void AddEntity( byte entityId, string displayName, string skinName ) {
+ void AddEntity( byte entityId, string displayName, string skinName, bool readPosition ) {
if( entityId != 0xFF ) {
Window.AsyncDownloader.DownloadSkin( skinName );
// This shouldn't usually happen, but just in case..
@@ -651,9 +641,11 @@ namespace ClassicalSharp {
Window.NetPlayers[entityId] = new NetPlayer( entityId, displayName, skinName, Window );
Window.RaiseEntityAdded( entityId );
}
- ReadAbsoluteLocation( entityId, false );
- if( entityId == 0xFF ) {
- Window.LocalPlayer.SpawnPoint = Window.LocalPlayer.Position;
+ if( readPosition ) {
+ ReadAbsoluteLocation( entityId, false );
+ if( entityId == 0xFF ) {
+ Window.LocalPlayer.SpawnPoint = Window.LocalPlayer.Position;
+ }
}
}
diff --git a/Network/WomConfigHandler.cs b/Network/WomConfigHandler.cs
index ee35eabdf..4e825b28b 100644
--- a/Network/WomConfigHandler.cs
+++ b/Network/WomConfigHandler.cs
@@ -2,6 +2,7 @@
using System;
using System.Drawing;
using System.IO;
+using ClassicalSharp.Network;
namespace ClassicalSharp {
@@ -9,19 +10,15 @@ namespace ClassicalSharp {
string womEnvIdentifier = "womenv_0", womTerrainIdentifier = "womterrain_0";
void CheckForWomEnvironment() {
- string page;
- Window.AsyncDownloader.TryGetPage( womEnvIdentifier, out page );
- if( page != null ) {
- ParseWomConfig( page );
+ DownloadedItem item;
+ Window.AsyncDownloader.TryGetItem( womEnvIdentifier, out item );
+ if( item != null && item.Page != null ) {
+ ParseWomConfig( item.Page );
}
- CheckWomBitmaps();
- }
-
- void CheckWomBitmaps() {
- Bitmap terrainBmp;
- Window.AsyncDownloader.TryGetImage( womTerrainIdentifier, out terrainBmp );
- if( terrainBmp != null ) {
- Window.ChangeTerrainAtlas( terrainBmp );
+
+ Window.AsyncDownloader.TryGetItem( womTerrainIdentifier, out item );
+ if( item != null && item.Bmp != null ) {
+ Window.ChangeTerrainAtlas( item.Bmp );
}
}
diff --git a/Utils/Utils.cs b/Utils/Utils.cs
index a62d6e5ea..10c9b350a 100644
--- a/Utils/Utils.cs
+++ b/Utils/Utils.cs
@@ -35,6 +35,10 @@ namespace ClassicalSharp {
return next;
}
+ public static bool IsUrl( string value ) {
+ return value.StartsWith( "http://" ) || value.StartsWith( "https://" );
+ }
+
public static string StripColours( string value ) {
if( value.IndexOf( '&' ) == -1 ) {
return value;