Update main screenshot on github.

This commit is contained in:
UnknownShadow200 2016-06-01 22:01:21 +10:00
parent a7842f48d7
commit 3795352c85
13 changed files with 53 additions and 73 deletions

View File

@ -23,7 +23,7 @@ namespace ClassicalSharp.Gui {
MakeBool( -1, -100, "Invert mouse", OptionsKey.InvertMouse, MakeBool( -1, -100, "Invert mouse", OptionsKey.InvertMouse,
OnWidgetClick, g => g.InvertMouse, (g, v) => g.InvertMouse = v ), OnWidgetClick, g => g.InvertMouse, (g, v) => g.InvertMouse = v ),
Make2( -1, -50, "View distance", OnWidgetClick, MakeOpt( -1, -50, "View distance", OnWidgetClick,
g => g.ViewDistance.ToString(), g => g.ViewDistance.ToString(),
(g, v) => g.SetViewDistance( Int32.Parse( v ), true ) ), (g, v) => g.SetViewDistance( Int32.Parse( v ), true ) ),
@ -43,7 +43,7 @@ namespace ClassicalSharp.Gui {
MakeBool( 1, -50, "View bobbing", OptionsKey.ViewBobbing, MakeBool( 1, -50, "View bobbing", OptionsKey.ViewBobbing,
OnWidgetClick, g => g.ViewBobbing, (g, v) => g.ViewBobbing = v ), OnWidgetClick, g => g.ViewBobbing, (g, v) => g.ViewBobbing = v ),
Make2( 1, 0, "FPS mode", OnWidgetClick, MakeOpt( 1, 0, "FPS mode", OnWidgetClick,
g => g.FpsLimit.ToString(), g => g.FpsLimit.ToString(),
(g, v) => { object raw = Enum.Parse( typeof(FpsLimitMethod), v ); (g, v) => { object raw = Enum.Parse( typeof(FpsLimitMethod), v );
g.SetFpsLimitMethod( (FpsLimitMethod)raw ); g.SetFpsLimitMethod( (FpsLimitMethod)raw );
@ -65,10 +65,10 @@ namespace ClassicalSharp.Gui {
Widget MakeControlsWidget() { Widget MakeControlsWidget() {
if( !game.ClassicHacks ) if( !game.ClassicHacks )
return Make( 0, 110, "Controls", LeftOnly( return MakeTitle( 0, 110, "Controls", LeftOnly(
(g, w) => g.SetNewScreen( new ClassicKeyBindingsScreen( g ) ) ), null, null ); (g, w) => g.SetNewScreen( new ClassicKeyBindingsScreen( g ) ) ) );
return Make( 0, 110, "Controls", LeftOnly( return MakeTitle( 0, 110, "Controls", LeftOnly(
(g, w) => g.SetNewScreen( new ClassicHacksKeyBindingsScreen( g ) ) ), null, null ); (g, w) => g.SetNewScreen( new ClassicHacksKeyBindingsScreen( g ) ) ) );
} }
void MakeValidators() { void MakeValidators() {

View File

@ -70,6 +70,7 @@ namespace ClassicalSharp.Gui {
string flags = HotkeyListScreen.MakeFlagsString( curHotkey.Flags ); string flags = HotkeyListScreen.MakeFlagsString( curHotkey.Flags );
if( curHotkey.Text == null ) curHotkey.Text = ""; if( curHotkey.Text == null ) curHotkey.Text = "";
string staysOpen = curHotkey.StaysOpen ? "yes" : "no"; string staysOpen = curHotkey.StaysOpen ? "yes" : "no";
bool existed = origHotkey.BaseKey != Key.Unknown;
widgets = new Widget[] { widgets = new Widget[] {
Make( 0, -150, "Key: " + curHotkey.BaseKey, Make( 0, -150, "Key: " + curHotkey.BaseKey,
@ -84,9 +85,9 @@ namespace ClassicalSharp.Gui {
Make( -100, 10, "Input stays open: " + staysOpen, Make( -100, 10, "Input stays open: " + staysOpen,
301, 40, titleFont, LeaveOpenClick ), 301, 40, titleFont, LeaveOpenClick ),
Make( 0, 80, "Save changes", Make( 0, 80, existed ? "Save changes" : "Add hotkey",
301, 40, titleFont, SaveChangesClick ), 301, 40, titleFont, SaveChangesClick ),
Make( 0, 130, "Remove hotkey", Make( 0, 130, existed ? "Remove hotkey" : "Cancel",
301, 40, titleFont, RemoveHotkeyClick ), 301, 40, titleFont, RemoveHotkeyClick ),
MakeBack( false, titleFont, MakeBack( false, titleFont,

View File

@ -19,44 +19,44 @@ namespace ClassicalSharp.Gui {
widgets = new Widget[] { widgets = new Widget[] {
// Column 1 // Column 1
Make2( -1, -150, "Clouds col", OnWidgetClick, MakeOpt( -1, -150, "Clouds col", OnWidgetClick,
g => g.World.Env.CloudsCol.ToRGBHexString(), g => g.World.Env.CloudsCol.ToRGBHexString(),
(g, v) => g.World.Env.SetCloudsColour( FastColour.Parse( v ) ) ), (g, v) => g.World.Env.SetCloudsColour( FastColour.Parse( v ) ) ),
Make2( -1, -100, "Sky col", OnWidgetClick, MakeOpt( -1, -100, "Sky col", OnWidgetClick,
g => g.World.Env.SkyCol.ToRGBHexString(), g => g.World.Env.SkyCol.ToRGBHexString(),
(g, v) => g.World.Env.SetSkyColour( FastColour.Parse( v ) ) ), (g, v) => g.World.Env.SetSkyColour( FastColour.Parse( v ) ) ),
Make2( -1, -50, "Fog col", OnWidgetClick, MakeOpt( -1, -50, "Fog col", OnWidgetClick,
g => g.World.Env.FogCol.ToRGBHexString(), g => g.World.Env.FogCol.ToRGBHexString(),
(g, v) => g.World.Env.SetFogColour( FastColour.Parse( v ) ) ), (g, v) => g.World.Env.SetFogColour( FastColour.Parse( v ) ) ),
Make2( -1, 0, "Clouds speed", OnWidgetClick, MakeOpt( -1, 0, "Clouds speed", OnWidgetClick,
g => g.World.Env.CloudsSpeed.ToString( "F2" ), g => g.World.Env.CloudsSpeed.ToString( "F2" ),
(g, v) => g.World.Env.SetCloudsSpeed( Single.Parse( v ) ) ), (g, v) => g.World.Env.SetCloudsSpeed( Single.Parse( v ) ) ),
Make2( -1, 50, "Clouds height", OnWidgetClick, MakeOpt( -1, 50, "Clouds height", OnWidgetClick,
g => g.World.Env.CloudHeight.ToString(), g => g.World.Env.CloudHeight.ToString(),
(g, v) => g.World.Env.SetCloudsLevel( Int32.Parse( v ) ) ), (g, v) => g.World.Env.SetCloudsLevel( Int32.Parse( v ) ) ),
// Column 2 // Column 2
Make2( 1, -150, "Sunlight col", OnWidgetClick, MakeOpt( 1, -150, "Sunlight col", OnWidgetClick,
g => g.World.Env.Sunlight.ToRGBHexString(), g => g.World.Env.Sunlight.ToRGBHexString(),
(g, v) => g.World.Env.SetSunlight( FastColour.Parse( v ) ) ), (g, v) => g.World.Env.SetSunlight( FastColour.Parse( v ) ) ),
Make2( 1, -100, "Shadow col", OnWidgetClick, MakeOpt( 1, -100, "Shadow col", OnWidgetClick,
g => g.World.Env.Shadowlight.ToRGBHexString(), g => g.World.Env.Shadowlight.ToRGBHexString(),
(g, v) => g.World.Env.SetShadowlight( FastColour.Parse( v ) ) ), (g, v) => g.World.Env.SetShadowlight( FastColour.Parse( v ) ) ),
Make2( 1, -50, "Weather", OnWidgetClick, MakeOpt( 1, -50, "Weather", OnWidgetClick,
g => g.World.Env.Weather.ToString(), g => g.World.Env.Weather.ToString(),
(g, v) => g.World.Env.SetWeather( (Weather)Enum.Parse( typeof(Weather), v ) ) ), (g, v) => g.World.Env.SetWeather( (Weather)Enum.Parse( typeof(Weather), v ) ) ),
Make2( 1, 0, "Rain/Snow speed", OnWidgetClick, MakeOpt( 1, 0, "Rain/Snow speed", OnWidgetClick,
g => g.World.Env.WeatherSpeed.ToString( "F2" ), g => g.World.Env.WeatherSpeed.ToString( "F2" ),
(g, v) => g.World.Env.SetWeatherSpeed( Single.Parse( v ) ) ), (g, v) => g.World.Env.SetWeatherSpeed( Single.Parse( v ) ) ),
Make2( 1, 50, "Water level", OnWidgetClick, MakeOpt( 1, 50, "Water level", OnWidgetClick,
g => g.World.Env.EdgeHeight.ToString(), g => g.World.Env.EdgeHeight.ToString(),
(g, v) => g.World.Env.SetEdgeLevel( Int32.Parse( v ) ) ), (g, v) => g.World.Env.SetEdgeLevel( Int32.Parse( v ) ) ),

View File

@ -17,23 +17,23 @@ namespace ClassicalSharp.Gui {
widgets = new Widget[] { widgets = new Widget[] {
Make2( -1, -50, "FPS mode", OnWidgetClick, MakeOpt( -1, -50, "FPS mode", OnWidgetClick,
g => g.FpsLimit.ToString(), g => g.FpsLimit.ToString(),
(g, v) => { object raw = Enum.Parse( typeof(FpsLimitMethod), v ); (g, v) => { object raw = Enum.Parse( typeof(FpsLimitMethod), v );
g.SetFpsLimitMethod( (FpsLimitMethod)raw ); g.SetFpsLimitMethod( (FpsLimitMethod)raw );
Options.Set( OptionsKey.FpsLimit, v ); } ), Options.Set( OptionsKey.FpsLimit, v ); } ),
Make2( -1, 0, "View distance", OnWidgetClick, MakeOpt( -1, 0, "View distance", OnWidgetClick,
g => g.ViewDistance.ToString(), g => g.ViewDistance.ToString(),
(g, v) => g.SetViewDistance( Int32.Parse( v ), true ) ), (g, v) => g.SetViewDistance( Int32.Parse( v ), true ) ),
Make2( 1, -50, "Names", OnWidgetClick, MakeOpt( 1, -50, "Names", OnWidgetClick,
g => g.Entities.NamesMode.ToString(), g => g.Entities.NamesMode.ToString(),
(g, v) => { object raw = Enum.Parse( typeof(NameMode), v ); (g, v) => { object raw = Enum.Parse( typeof(NameMode), v );
g.Entities.NamesMode = (NameMode)raw; g.Entities.NamesMode = (NameMode)raw;
Options.Set( OptionsKey.NamesMode, v ); } ), Options.Set( OptionsKey.NamesMode, v ); } ),
Make2( 1, 0, "Shadows", OnWidgetClick, MakeOpt( 1, 0, "Shadows", OnWidgetClick,
g => g.Entities.ShadowMode.ToString(), g => g.Entities.ShadowMode.ToString(),
(g, v) => { object raw = Enum.Parse( typeof(EntityShadow), v ); (g, v) => { object raw = Enum.Parse( typeof(EntityShadow), v );
g.Entities.ShadowMode = (EntityShadow)raw; g.Entities.ShadowMode = (EntityShadow)raw;

View File

@ -19,14 +19,14 @@ namespace ClassicalSharp.Gui {
MakeBool( -1, -100, "Show FPS", OptionsKey.ShowFPS, MakeBool( -1, -100, "Show FPS", OptionsKey.ShowFPS,
OnWidgetClick, g => g.ShowFPS, (g, v) => g.ShowFPS = v ), OnWidgetClick, g => g.ShowFPS, (g, v) => g.ShowFPS = v ),
Make2( -1, -50, "Hotbar scale", OnWidgetClick, MakeOpt( -1, -50, "Hotbar scale", OnWidgetClick,
g => g.HotbarScale.ToString( "F1" ), g => g.HotbarScale.ToString( "F1" ),
(g, v) => { g.HotbarScale = Single.Parse( v ); (g, v) => { g.HotbarScale = Single.Parse( v );
Options.Set( OptionsKey.HotbarScale, v ); Options.Set( OptionsKey.HotbarScale, v );
g.RefreshHud(); g.RefreshHud();
} ), } ),
Make2( -1, 0, "Inventory scale", OnWidgetClick, MakeOpt( -1, 0, "Inventory scale", OnWidgetClick,
g => g.InventoryScale.ToString( "F1" ), g => g.InventoryScale.ToString( "F1" ),
(g, v) => { g.InventoryScale = Single.Parse( v ); (g, v) => { g.InventoryScale = Single.Parse( v );
Options.Set( OptionsKey.InventoryScale, v ); Options.Set( OptionsKey.InventoryScale, v );
@ -40,14 +40,14 @@ namespace ClassicalSharp.Gui {
MakeBool( 1, -150, "Clickable chat", OptionsKey.ClickableChat, MakeBool( 1, -150, "Clickable chat", OptionsKey.ClickableChat,
OnWidgetClick, g => g.ClickableChat, (g, v) => g.ClickableChat = v ), OnWidgetClick, g => g.ClickableChat, (g, v) => g.ClickableChat = v ),
Make2( 1, -100, "Chat scale", OnWidgetClick, MakeOpt( 1, -100, "Chat scale", OnWidgetClick,
g => g.ChatScale.ToString( "F1" ), g => g.ChatScale.ToString( "F1" ),
(g, v) => { g.ChatScale = Single.Parse( v ); (g, v) => { g.ChatScale = Single.Parse( v );
Options.Set( OptionsKey.ChatScale, v ); Options.Set( OptionsKey.ChatScale, v );
g.RefreshHud(); g.RefreshHud();
} ), } ),
Make2( 1, -50, "Chat lines", OnWidgetClick, MakeOpt( 1, -50, "Chat lines", OnWidgetClick,
g => g.ChatLines.ToString(), g => g.ChatLines.ToString(),
(g, v) => { g.ChatLines = Int32.Parse( v ); (g, v) => { g.ChatLines = Int32.Parse( v );
Options.Set( OptionsKey.ChatLines, v ); Options.Set( OptionsKey.ChatLines, v );
@ -58,7 +58,7 @@ namespace ClassicalSharp.Gui {
OnWidgetClick, g => !g.Drawer2D.UseBitmappedChat, OnWidgetClick, g => !g.Drawer2D.UseBitmappedChat,
(g, v) => { g.Drawer2D.UseBitmappedChat = !v; HandleFontChange(); } ), (g, v) => { g.Drawer2D.UseBitmappedChat = !v; HandleFontChange(); } ),
Make2( 1, 50, "Font", OnWidgetClick, MakeOpt( 1, 50, "Font", OnWidgetClick,
g => g.FontName, g => g.FontName,
(g, v) => { g.FontName = v; (g, v) => { g.FontName = v;
Options.Set( OptionsKey.FontName, v ); Options.Set( OptionsKey.FontName, v );

View File

@ -21,7 +21,7 @@ namespace ClassicalSharp.Gui {
(g, v) => { g.LocalPlayer.Hacks.Enabled = v; (g, v) => { g.LocalPlayer.Hacks.Enabled = v;
g.LocalPlayer.CheckHacksConsistency(); } ), g.LocalPlayer.CheckHacksConsistency(); } ),
Make2( -1, -100, "Speed multiplier", OnWidgetClick, MakeOpt( -1, -100, "Speed multiplier", OnWidgetClick,
g => g.LocalPlayer.Hacks.SpeedMultiplier.ToString( "F2" ), g => g.LocalPlayer.Hacks.SpeedMultiplier.ToString( "F2" ),
(g, v) => { g.LocalPlayer.Hacks.SpeedMultiplier = Single.Parse( v ); (g, v) => { g.LocalPlayer.Hacks.SpeedMultiplier = Single.Parse( v );
Options.Set( OptionsKey.Speed, v ); } ), Options.Set( OptionsKey.Speed, v ); } ),
@ -29,7 +29,7 @@ namespace ClassicalSharp.Gui {
MakeBool( -1, -50, "Camera clipping", OptionsKey.CameraClipping, MakeBool( -1, -50, "Camera clipping", OptionsKey.CameraClipping,
OnWidgetClick, g => g.CameraClipping, (g, v) => g.CameraClipping = v ), OnWidgetClick, g => g.CameraClipping, (g, v) => g.CameraClipping = v ),
Make2( -1, 0, "Jump height", OnWidgetClick, MakeOpt( -1, 0, "Jump height", OnWidgetClick,
g => g.LocalPlayer.JumpHeight.ToString( "F3" ), g => g.LocalPlayer.JumpHeight.ToString( "F3" ),
(g, v) => g.LocalPlayer.physics.CalculateJumpVelocity( Single.Parse( v ) ) ), (g, v) => g.LocalPlayer.physics.CalculateJumpVelocity( Single.Parse( v ) ) ),
@ -53,7 +53,7 @@ namespace ClassicalSharp.Gui {
OnWidgetClick, g => g.LocalPlayer.Hacks.NoclipSlide, OnWidgetClick, g => g.LocalPlayer.Hacks.NoclipSlide,
(g, v) => g.LocalPlayer.Hacks.NoclipSlide = v ), (g, v) => g.LocalPlayer.Hacks.NoclipSlide = v ),
Make2( 1, 50, "Field of view", OnWidgetClick, MakeOpt( 1, 50, "Field of view", OnWidgetClick,
g => g.Fov.ToString(), g => g.Fov.ToString(),
(g, v) => { g.Fov = Int32.Parse( v ); (g, v) => { g.Fov = Int32.Parse( v );
Options.Set( OptionsKey.FieldOfView, v ); Options.Set( OptionsKey.FieldOfView, v );

View File

@ -104,15 +104,13 @@ namespace ClassicalSharp.Gui {
protected virtual void InputClosed() { } protected virtual void InputClosed() { }
protected ButtonWidget Make( int dir, int y, string text, ClickHandler onClick, protected ButtonWidget MakeTitle( int dir, int y, string text, ClickHandler onClick ) {
Func<Game, string> getter, Action<Game, string> setter ) {
ButtonWidget widget = ButtonWidget.Create( game, 160 * dir, y, 301, 41, text, Anchor.Centre, ButtonWidget widget = ButtonWidget.Create( game, 160 * dir, y, 301, 41, text, Anchor.Centre,
Anchor.Centre, titleFont, onClick ); Anchor.Centre, titleFont, onClick );
widget.GetValue = getter; widget.SetValue = setter;
return widget; return widget;
} }
protected ButtonWidget Make2( int dir, int y, string text, ClickHandler onClick, protected ButtonWidget MakeOpt( int dir, int y, string text, ClickHandler onClick,
Func<Game, string> getter, Action<Game, string> setter ) { Func<Game, string> getter, Action<Game, string> setter ) {
ButtonWidget widget = ButtonWidget.Create( game, 160 * dir, y, 301, 41, ButtonWidget widget = ButtonWidget.Create( game, 160 * dir, y, 301, 41,
text + ": " + getter( game ), text + ": " + getter( game ),

View File

@ -17,7 +17,7 @@ namespace ClassicalSharp.Gui {
widgets = new Widget[] { widgets = new Widget[] {
// Column 1 // Column 1
!network.IsSinglePlayer ? null : !network.IsSinglePlayer ? null :
Make2( -1, -100, "Click distance", OnWidgetClick, MakeOpt( -1, -100, "Click distance", OnWidgetClick,
g => g.LocalPlayer.ReachDistance.ToString(), g => g.LocalPlayer.ReachDistance.ToString(),
(g, v) => g.LocalPlayer.ReachDistance = Single.Parse( v ) ), (g, v) => g.LocalPlayer.ReachDistance = Single.Parse( v ) ),
@ -45,7 +45,7 @@ namespace ClassicalSharp.Gui {
MakeBool( 1, 0, "Invert mouse", OptionsKey.InvertMouse, MakeBool( 1, 0, "Invert mouse", OptionsKey.InvertMouse,
OnWidgetClick, g => g.InvertMouse, (g, v) => g.InvertMouse = v ), OnWidgetClick, g => g.InvertMouse, (g, v) => g.InvertMouse = v ),
Make2( 1, 50, "Mouse sensitivity", OnWidgetClick, MakeOpt( 1, 50, "Mouse sensitivity", OnWidgetClick,
g => g.MouseSensitivity.ToString(), g => g.MouseSensitivity.ToString(),
(g, v) => { g.MouseSensitivity = Int32.Parse( v ); (g, v) => { g.MouseSensitivity = Int32.Parse( v );
Options.Set( OptionsKey.Sensitivity, v ); } ), Options.Set( OptionsKey.Sensitivity, v ); } ),

View File

@ -112,10 +112,10 @@ namespace Launcher.Gui.Screens {
if( !Options.Load() ) if( !Options.Load() )
return; return;
Options.Set( "launcher-dc-username", data.RealUsername ); Options.Set( "launcher-dc-username", data.Username );
Options.Set( "launcher-dc-ip", data.Ip ); Options.Set( "launcher-dc-ip", data.Ip );
Options.Set( "launcher-dc-port", data.Port ); Options.Set( "launcher-dc-port", data.Port );
Options.Set( "launcher-dc-mppass", Secure.Encode( data.Mppass, data.RealUsername ) ); Options.Set( "launcher-dc-mppass", Secure.Encode( data.Mppass, data.Username ) );
Options.Set( "launcher-dc-ccskins", ccSkins ); Options.Set( "launcher-dc-ccskins", ccSkins );
Options.Save(); Options.Save();
} }

View File

@ -102,7 +102,6 @@
<Compile Include="Updater\Scripts.cs" /> <Compile Include="Updater\Scripts.cs" />
<Compile Include="Updater\Applier.cs" /> <Compile Include="Updater\Applier.cs" />
<Compile Include="Utils\Client.cs" /> <Compile Include="Utils\Client.cs" />
<Compile Include="Utils\ClientStartData.cs" />
<Compile Include="Utils\JSON.cs" /> <Compile Include="Utils\JSON.cs" />
<Compile Include="Utils\LauncherSkin.cs" /> <Compile Include="Utils\LauncherSkin.cs" />
<Compile Include="Utils\Secure.cs" /> <Compile Include="Utils\Secure.cs" />

View File

@ -64,7 +64,7 @@ namespace Launcher {
} }
} }
internal static void CheckSettings( ClientStartData data, bool classiCubeSkins, out bool shouldExit ) { internal static void CheckSettings( ClientStartData data, bool ccSkins, out bool shouldExit ) {
shouldExit = false; shouldExit = false;
// Make sure if the client has changed some settings in the meantime, we keep the changes // Make sure if the client has changed some settings in the meantime, we keep the changes
if( !Options.Load() ) if( !Options.Load() )
@ -72,12 +72,23 @@ namespace Launcher {
shouldExit = Options.GetBool( OptionsKey.AutoCloseLauncher, false ); shouldExit = Options.GetBool( OptionsKey.AutoCloseLauncher, false );
if( data == null ) return; if( data == null ) return;
Options.Set( "launcher-username", data.RealUsername ); Options.Set( "launcher-username", data.Username );
Options.Set( "launcher-ip", data.Ip ); Options.Set( "launcher-ip", data.Ip );
Options.Set( "launcher-port", data.Port ); Options.Set( "launcher-port", data.Port );
Options.Set( "launcher-mppass", Secure.Encode( data.Mppass, data.RealUsername ) ); Options.Set( "launcher-mppass", Secure.Encode( data.Mppass, data.Username ) );
Options.Set( "launcher-ccskins", classiCubeSkins ); Options.Set( "launcher-ccskins", ccSkins );
Options.Save(); Options.Save();
} }
} }
public class ClientStartData {
public string Username, Mppass, Ip, Port;
public ClientStartData( string user, string mppass, string ip, string port ) {
Username = user;
Mppass = mppass;
Ip = ip;
Port = port;
}
}
} }

View File

@ -1,29 +0,0 @@
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
namespace Launcher {
public class ClientStartData {
public string Username;
public string RealUsername;
public string Mppass;
public string Ip;
public string Port;
public ClientStartData() {
}
public ClientStartData( string user, string mppass, string ip, string port ) {
Username = user;
RealUsername = user;
Mppass = mppass;
Ip = ip;
Port = port;
}
}
}

View File

@ -1,7 +1,7 @@
ClassicalSharp is a custom Minecraft Classic client written in C# that works on Windows, Linux and OSX. ClassicalSharp is a custom Minecraft Classic client written in C# that works on Windows, Linux and OSX.
**It is not affiliated with (or supported by) Mojang AB, Minecraft, or Microsoft in any way.** **It is not affiliated with (or supported by) Mojang AB, Minecraft, or Microsoft in any way.**
![screenshot_n](https://cloud.githubusercontent.com/assets/6509348/10800494/288b4f00-7e06-11e5-8344-5df33625cc8b.png) ![screenshot_n](https://cloud.githubusercontent.com/assets/6509348/15698451/0e6f61ae-2808-11e6-9d9b-486a8acd467e.png)
You can grab the latest stable binaries [here](https://github.com/UnknownShadow200/ClassicalSharp/releases). You can grab the latest stable binaries [here](https://github.com/UnknownShadow200/ClassicalSharp/releases).