Client: Fix crashing when caret has been moved to partway through a colour code which is the first 2 characters in the text input, and you then do backspace. (Thanks lavacraft)

This commit is contained in:
UnknownShadow200 2016-10-27 21:53:15 +11:00
parent df0582d4c8
commit c781af2d85
2 changed files with 47 additions and 35 deletions

View file

@ -13,11 +13,25 @@ namespace ClassicalSharp.Gui.Widgets {
int typingLogPos;
string originalText;
bool shownWarning;
public ChatInputWidget( Game game, Font font ) : base( game, font ) {
typingLogPos = game.Chat.InputLog.Count; // Index of newest entry + 1.
}
public override void Init() {
base.Init();
bool supports = game.Server.SupportsPartialMessages;
if( buffer.Length > LineLength && !shownWarning && !supports ) {
game.Chat.Add( "&eNote: Each line will be sent as a separate packet.", MessageType.ClientStatus6 );
shownWarning = true;
} else if( buffer.Length <= LineLength && shownWarning ) {
game.Chat.Add( null, MessageType.ClientStatus6 );
shownWarning = false;
}
}
public override bool HandlesKeyDown( Key key ) {
if( game.HideGui ) return key < Key.F1 || key > Key.F35;
bool controlDown = ControlDown();

View file

@ -9,7 +9,6 @@ using Android.Graphics;
namespace ClassicalSharp.Gui.Widgets {
public abstract class InputWidget : Widget {
internal const int lines = 3;
public InputWidget( Game game, Font font ) : base( game ) {
HorizontalAnchor = Anchor.LeftOrTop;
VerticalAnchor = Anchor.BottomOrRight;
@ -27,14 +26,16 @@ namespace ClassicalSharp.Gui.Widgets {
this.font = font;
}
internal Texture inputTex, caretTex, prefixTex;
internal int caretPos = -1;
internal int defaultCaretWidth, defaultWidth, defaultHeight;
internal const int lines = 3;
internal WrappableStringBuffer buffer;
protected readonly Font font;
protected int caretPos = -1;
Texture inputTex, caretTex, prefixTex;
readonly Font font;
int defaultCaretWidth, defaultWidth, defaultHeight;
FastColour caretCol;
static FastColour backColour = new FastColour( 0, 0, 0, 127 );
public override void Render( double delta ) {
gfx.Texturing = false;
int y = Y, x = X;
@ -61,7 +62,6 @@ namespace ClassicalSharp.Gui.Widgets {
Size[] sizes = new Size[lines];
int maxWidth = 0;
int indexX, indexY;
bool shownWarning;
internal int LineLength { get { return game.Server.SupportsPartialMessages ? 64 : 62; } }
internal int TotalChars { get { return LineLength * lines; } }
@ -70,6 +70,13 @@ namespace ClassicalSharp.Gui.Widgets {
X = 5;
buffer.WordWrap( game.Drawer2D, ref parts, ref partLens, LineLength, TotalChars );
CalculateLineSizes();
RemakeTexture();
UpdateCaret();
}
/// <summary> Calculates the sizes of each line in the text buffer. </summary>
public void CalculateLineSizes() {
for( int y = 0; y < sizes.Length; y++ )
sizes[y] = Size.Empty;
sizes[0].Width = defaultWidth;
@ -83,18 +90,6 @@ namespace ClassicalSharp.Gui.Widgets {
maxWidth = Math.Max( maxWidth, sizes[y].Width );
}
if( sizes[0].Height == 0 ) sizes[0].Height = defaultHeight;
bool supports = game.Server.SupportsPartialMessages;
if( buffer.Length > LineLength && !shownWarning && !supports ) {
game.Chat.Add( "&eNote: Each line will be sent as a separate packet.", MessageType.ClientStatus6 );
shownWarning = true;
} else if( buffer.Length <= LineLength && shownWarning ) {
game.Chat.Add( null, MessageType.ClientStatus6 );
shownWarning = false;
}
RemakeTexture();
UpdateCaret();
}
/// <summary> Calculates the location and size of the caret character </summary>
@ -280,8 +275,8 @@ namespace ClassicalSharp.Gui.Widgets {
return true;
}
#region Input handling
#region Input handling
void BackspaceKey( bool controlDown ) {
if( controlDown ) {
@ -305,10 +300,13 @@ namespace ClassicalSharp.Gui.Widgets {
int index = caretPos == -1 ? buffer.Length - 1 : caretPos;
if( CheckColour( index - 1 ) ) {
DeleteChar(); // backspace XYZ%e to XYZ
index -= 1;
} else if( CheckColour( index - 2 ) ) {
DeleteChar(); DeleteChar(); // backspace XYZ%eH to XYZ
index -= 2;
}
DeleteChar();
if( index > 0 ) DeleteChar();
Recreate();
}
}