// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using System.Drawing;
using System.Net;
using ClassicalSharp.Gui;
using ClassicalSharp.Network;
using ClassicalSharp.TexturePack;
using OpenTK;
using OpenTK.Input;
namespace ClassicalSharp {
/// Represents a connection to either a multiplayer server, or an internal single player server.
public abstract class INetworkProcessor {
public abstract bool IsSinglePlayer { get; }
/// Opens a connection to the given IP address and port, and prepares the initial state of the client.
public abstract void Connect( IPAddress address, int port );
public abstract void SendChat( string text, bool partial );
/// Informs the server of the client's current position and orientation.
public abstract void SendPosition( Vector3 pos, float yaw, float pitch );
/// Informs the server that the client placed or deleted a block at the given coordinates.
public abstract void SendSetBlock( int x, int y, int z, bool place, byte block );
/// Informs the server that using the given mouse button,
/// the client clicked on a particular block or entity.
public abstract void SendPlayerClick( MouseButton button, bool buttonDown, byte targetId, PickedPos pos );
public abstract void Tick( double delta );
public abstract void Dispose();
public string ServerName;
public string ServerMotd;
/// Whether the network processor is currently connected to a server.
public bool Disconnected;
/// Whether the client should use extended player list management, with group names and ranks.
public bool UsingExtPlayerList;
/// Whether the server supports handling PlayerClick packets from the client.
public bool UsingPlayerClick;
/// Whether the server can handle partial message packets or not.
public bool ServerSupportsPartialMessages;
/// Whether the server supports receiving all code page 437 characters from this client.
public bool ServerSupportsFullCP437;
#region Texture pack / terrain.png
protected Game game;
protected void WarningScreenTick( WarningScreen screen ) {
string identifier = (string)screen.Metadata;
DownloadedItem item;
if( !game.AsyncDownloader.TryGetItem( identifier, out item ) || item.Data == null ) return;
long contentLength = (long)item.Data;
if( contentLength <= 0 ) return;
string url = identifier.Substring( 3 );
float contentLengthMB = (contentLength / 1024f / 1024f );
string address = url;
if( url.StartsWith( "https://" ) ) address = url.Substring( 8 );
if( url.StartsWith( "http://" ) ) address = url.Substring( 7 );
screen.SetText( "Do you want to download the server's texture pack?",
"Texture pack url:", address,
"Download size: " + contentLengthMB.ToString( "F3" ) + " MB" );
}
protected internal void RetrieveTexturePack( string url ) {
if( !game.AcceptedUrls.HasEntry( url ) && !game.DeniedUrls.HasEntry( url ) ) {
game.AsyncDownloader.RetrieveContentLength( url, true, "CL_" + url );
string address = url;
if( url.StartsWith( "https://" ) ) address = url.Substring( 8 );
if( url.StartsWith( "http://" ) ) address = url.Substring( 7 );
game.ShowWarning( new WarningScreen(
game, "CL_" + url, true, true, "Do you want to download the server's texture pack?",
DownloadTexturePack, null, WarningScreenTick,
"Texture pack url:", address,
"Download size: Determining..." ) );
} else {
DownloadTexturePack( url );
}
}
void DownloadTexturePack( WarningScreen screen ) {
DownloadTexturePack( ((string)screen.Metadata).Substring( 3 ) );
}
void DownloadTexturePack( string url ) {
if( game.DeniedUrls.HasEntry( url ) ) return;
DateTime lastModified = TextureCache.GetLastModifiedFromCache( url );
string etag = TextureCache.GetETagFromCache( url, game.ETags );
if( url.Contains( ".zip" ) )
game.AsyncDownloader.DownloadData( url, true, "texturePack",
lastModified, etag );
else
game.AsyncDownloader.DownloadImage( url, true, "terrain",
lastModified, etag );
}
protected void ExtractDefault() {
TexturePackExtractor extractor = new TexturePackExtractor();
extractor.Extract( game.DefaultTexturePack, game );
game.World.TextureUrl = null;
}
protected void CheckAsyncResources() {
DownloadedItem item;
if( game.AsyncDownloader.TryGetItem( "terrain", out item ) ) {
if( item.Data != null ) {
Bitmap bmp = (Bitmap)item.Data;
game.World.TextureUrl = item.Url;
game.Events.RaiseTexturePackChanged();
if( !FastBitmap.CheckFormat( bmp.PixelFormat ) ) {
Utils.LogDebug( "Converting terrain atlas to 32bpp image" );
game.Drawer2D.ConvertTo32Bpp( ref bmp );
}
if( !game.ChangeTerrainAtlas( bmp ) ) { bmp.Dispose(); return; }
TextureCache.AddToCache( item.Url, bmp );
TextureCache.AddETagToCache( item.Url, item.ETag, game.ETags );
} else if( item.ResponseCode == HttpStatusCode.NotModified ) {
Bitmap bmp = TextureCache.GetBitmapFromCache( item.Url );
if( bmp == null ) {// Should never happen, but handle anyways.
ExtractDefault();
} else if( item.Url != game.World.TextureUrl ) {
game.Events.RaiseTexturePackChanged();
if( !game.ChangeTerrainAtlas( bmp ) ) { bmp.Dispose(); return; }
}
if( bmp != null ) game.World.TextureUrl = item.Url;
} else {
ExtractDefault();
}
}
if( game.AsyncDownloader.TryGetItem( "texturePack", out item ) ) {
if( item.Data != null ) {
game.World.TextureUrl = item.Url;
TexturePackExtractor extractor = new TexturePackExtractor();
extractor.Extract( (byte[])item.Data, game );
TextureCache.AddToCache( item.Url, (byte[])item.Data );
TextureCache.AddETagToCache( item.Url, item.ETag, game.ETags );
} else if( item.ResponseCode == HttpStatusCode.NotModified ) {
byte[] data = TextureCache.GetDataFromCache( item.Url );
if( data == null ) { // Should never happen, but handle anyways.
ExtractDefault();
} else if( item.Url != game.World.TextureUrl ) {
TexturePackExtractor extractor = new TexturePackExtractor();
extractor.Extract( data, game );
}
if( data != null ) game.World.TextureUrl = item.Url;
} else {
ExtractDefault();
}
}
}
#endregion
}
}