diff --git a/ClassicalSharp/2D/Drawing/IDrawer2D.cs b/ClassicalSharp/2D/Drawing/IDrawer2D.cs
index 82abb87fa..9a196e304 100644
--- a/ClassicalSharp/2D/Drawing/IDrawer2D.cs
+++ b/ClassicalSharp/2D/Drawing/IDrawer2D.cs
@@ -184,8 +184,9 @@ namespace ClassicalSharp {
}
}
+ /// Splits the input string by recognised colour codes. (e.g &f)
protected void SplitText( string value ) {
- char code = 'F';
+ char code = 'f';
for( int i = 0; i < value.Length; i++ ) {
int nextAnd = value.IndexOf( '&', i );
int partLength = nextAnd == -1 ? value.Length - i : nextAnd - i;
@@ -199,8 +200,8 @@ namespace ClassicalSharp {
if( nextAnd >= 0 && nextAnd + 1 < value.Length ) {
if( !ValidColour( value[nextAnd + 1] ) ) {
- code = 'F';
- i--; // include the character that isn't a colour code.
+ code = 'f';
+ i--; // include character that isn't a valid colour code.
} else {
code = value[nextAnd + 1];
}
@@ -208,8 +209,27 @@ namespace ClassicalSharp {
}
}
- internal bool ValidColour( char c ) {
+ /// Returns whenever the given character is a valid colour code.
+ public bool ValidColour( char c ) {
return (int)c < 256 && Colours[c].A > 0;
}
+
+ /// Returns the last valid colour code in the given input,
+ /// or \0 if no valid colour code was found.
+ public char LastColour( string input, int start ) {
+ if( start >= input.Length )
+ start = input.Length - 1;
+
+ for( int i = start; i >= 0; i--) {
+ if( input[i] != '&' ) continue;
+ if( i < input.Length - 1 && ValidColour( input[i + 1] ) )
+ return input[i + 1];
+ }
+ return '\0';
+ }
+
+ public static bool IsWhiteColour( char c ) {
+ return c == '\0' || c == 'f' || c == 'F';
+ }
}
}
diff --git a/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.Handlers.cs b/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.Handlers.cs
index 1ad4286b1..c046082b5 100644
--- a/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.Handlers.cs
+++ b/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.Handlers.cs
@@ -81,7 +81,7 @@ namespace ClassicalSharp {
buffer.Append( ref index, " matching names: " );
foreach( string match in matches ) {
- if( (match.Length + 1 + buffer.Length) > 64 ) break;
+ if( (match.Length + 1 + buffer.Length) > LineLength ) break;
buffer.Append( ref index, match );
buffer.Append( ref index, ' ' );
}
@@ -163,9 +163,9 @@ namespace ClassicalSharp {
void UpKey( bool controlDown ) {
if( controlDown ) {
int pos = caretPos == -1 ? chatInputText.Length : caretPos;
- if( pos < 64 ) return;
+ if( pos < LineLength ) return;
- caretPos = pos - 64;
+ caretPos = pos - LineLength;
CalculateCaretData();
return;
}
@@ -185,8 +185,8 @@ namespace ClassicalSharp {
void DownKey( bool controlDown ) {
if( controlDown ) {
- if( caretPos == -1 || caretPos >= (lines - 1) * 64 ) return;
- caretPos += 64;
+ if( caretPos == -1 || caretPos >= (lines - 1) * LineLength ) return;
+ caretPos += LineLength;
CalculateCaretData();
return;
}
@@ -290,7 +290,7 @@ namespace ClassicalSharp {
CalculateCaretData(); return;
}
}
- offset += partLens[y];
+ offset += line.Length;
}
caretPos = -1;
CalculateCaretData();
diff --git a/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs b/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs
index 91c6b54fb..778c7d8b4 100644
--- a/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs
+++ b/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs
@@ -42,7 +42,7 @@ namespace ClassicalSharp {
graphicsApi.Texturing = false;
int y = Y, x = X;
for( int i = 0; i < sizes.Length; i++ ) {
- bool caretAtEnd = caretTex.Y1 == y && (indexX == 64 || caretPos == -1);
+ bool caretAtEnd = caretTex.Y1 == y && (indexX == LineLength || caretPos == -1);
int offset = caretAtEnd ? defaultWidth : 0;
graphicsApi.Draw2DQuad( x + 5, y, sizes[i].Width + offset, sizes[i].Height, backColour );
y += sizes[i].Height;
@@ -64,9 +64,11 @@ namespace ClassicalSharp {
int indexX, indexY;
bool shownWarning;
+ int LineLength { get { return game.Network.ServerSupportsPartialMessages ? 64 : 62; } }
+
public override void Init() {
X = 5;
- chatInputText.WordWrap( game.Drawer2D, ref parts, ref partLens, 64 );
+ chatInputText.WordWrap( game.Drawer2D, ref parts, ref partLens, LineLength );
maxWidth = 0;
DrawTextArgs args = new DrawTextArgs( null, font, true );
@@ -77,10 +79,10 @@ namespace ClassicalSharp {
}
bool supports = game.Network.ServerSupportsPartialMessages;
- if( chatInputText.Length > 64 && !shownWarning && !supports ) {
+ if( chatInputText.Length > LineLength && !shownWarning && !supports ) {
game.Chat.Add( "&eNote: Each line will be sent as a separate packet.", MessageType.ClientStatus6 );
shownWarning = true;
- } else if( chatInputText.Length <= 64 && shownWarning ) {
+ } else if( chatInputText.Length <= LineLength && shownWarning ) {
game.Chat.Add( null, MessageType.ClientStatus6 );
shownWarning = false;
}
@@ -89,14 +91,14 @@ namespace ClassicalSharp {
altText.texture.Y1 = game.Height - (YOffset + Height + altText.texture.Height);
altText.Y = altText.texture.Y1;
CalculateCaretData();
- }
+ }
void CalculateCaretData() {
if( caretPos >= chatInputText.Length ) caretPos = -1;
chatInputText.MakeCoords( caretPos, partLens, out indexX, out indexY );
DrawTextArgs args = new DrawTextArgs( null, font, true );
- if( indexX == 64 ) {
+ if( indexX == LineLength ) {
caretTex.X1 = 10 + sizes[indexY].Width;
caretCol = FastColour.Yellow;
} else {
@@ -111,7 +113,7 @@ namespace ClassicalSharp {
caretCol = FastColour.Scale( FastColour.White, 0.8f );
}
caretTex.Y1 = sizes[0].Height * indexY + Y;
- CalculateCaretCol();
+ CalcCaretColour();
}
void DrawString() {
@@ -130,6 +132,9 @@ namespace ClassicalSharp {
for( int i = 0; i < parts.Length; i++ ) {
if( parts[i] == null ) break;
args.Text = parts[i];
+ char lastCol = GetLastColour( 0, i );
+ if( !IDrawer2D.IsWhiteColour( lastCol ) )
+ args.Text = "&" + lastCol + args.Text;
drawer.DrawChatText( ref args, 0, realHeight );
realHeight += sizes[i].Height;
@@ -143,20 +148,23 @@ namespace ClassicalSharp {
Width = size.Width;
}
- void CalculateCaretCol() {
+ void CalcCaretColour() {
+ IDrawer2D drawer = game.Drawer2D;
+ char code = GetLastColour( indexX, indexY );
+ if( code != '\0' )
+ caretCol = drawer.Colours[code];
+ }
+
+ char GetLastColour( int indexX, int indexY ) {
int x = indexX;
IDrawer2D drawer = game.Drawer2D;
for( int y = indexY; y >= 0; y-- ) {
string part = parts[y];
- if( x == partLens[y] ) x = partLens[y] - 1;
- int start = part.LastIndexOf( '&', x, x + 1 );
- bool validIndex = start >= 0 && start < partLens[y] - 1;
-
- if( validIndex && drawer.ValidColour( part[start + 1] ) ) {
- caretCol = drawer.Colours[part[start + 1]]; return;
- }
- if( y > 0 ) x = partLens[y - 1] - 1;
+ char code = drawer.LastColour( part, x );
+ if( code != '\0' ) return code;
+ if( y > 0 ) x = parts[y - 1].Length;
}
+ return '\0';
}
public override void Dispose() {
@@ -197,26 +205,40 @@ namespace ClassicalSharp {
string allText = chatInputText.GetString();
game.Chat.InputLog.Add( allText );
- if( game.Network.ServerSupportsPartialMessages ) {
- // don't automatically word wrap the message.
- while( allText.Length > 64 ) {
- game.Chat.Send( allText.Substring( 0, 64 ), true );
- allText = allText.Substring( 64 );
- }
- game.Chat.Send( allText, false );
- return;
+ if( game.Network.ServerSupportsPartialMessages )
+ SendWithPartial( allText );
+ else
+ SendNormal();
+ }
+
+ void SendWithPartial( string allText ) {
+ // don't automatically word wrap the message.
+ while( allText.Length > 64 ) {
+ game.Chat.Send( allText.Substring( 0, 64 ), true );
+ allText = allText.Substring( 64 );
}
-
+ game.Chat.Send( allText, false );
+ }
+
+ void SendNormal() {
int packetsCount = 0;
for( int i = 0; i < parts.Length; i++ ) {
if( parts[i] == null ) break;
packetsCount++;
}
+
// split up into both partial and final packet.
- for( int i = 0; i < packetsCount - 1; i++ ) {
- game.Chat.Send( parts[i], true );
- }
- game.Chat.Send( parts[packetsCount - 1], false );
+ for( int i = 0; i < packetsCount - 1; i++ )
+ SendNormalText( i, true );
+ SendNormalText( packetsCount - 1, false );
+ }
+
+ void SendNormalText( int i, bool partial ) {
+ string text = parts[i];
+ char lastCol = GetLastColour( 0, i );
+ if( !IDrawer2D.IsWhiteColour( lastCol ) )
+ text = "&" + lastCol + text;
+ game.Chat.Send( text, partial );
}
public void Clear() {
diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj
index fc7401889..adbbdae1f 100644
--- a/ClassicalSharp/ClassicalSharp.csproj
+++ b/ClassicalSharp/ClassicalSharp.csproj
@@ -4,7 +4,7 @@
{BEB1C785-5CAD-48FF-A886-876BF0A318D4}
Debug
AnyCPU
- Exe
+ WinExe
ClassicalSharp
ClassicalSharp
v2.0
diff --git a/ClassicalSharp/Network/NetworkProcessor.cs b/ClassicalSharp/Network/NetworkProcessor.cs
index 8798c25d7..7690696a2 100644
--- a/ClassicalSharp/Network/NetworkProcessor.cs
+++ b/ClassicalSharp/Network/NetworkProcessor.cs
@@ -137,7 +137,6 @@ namespace ClassicalSharp {
lastOpcode = (PacketId)opcode;
Action handler = handlers[opcode];
lastPacket = DateTime.UtcNow;
- Console.WriteLine( "IN " + lastOpcode );
if( handler == null )
throw new NotImplementedException( "Unsupported packet:" + (PacketId)opcode );
diff --git a/ClassicalSharp/Singleplayer/Server.cs b/ClassicalSharp/Singleplayer/Server.cs
index a855e4dc2..c612ca4b9 100644
--- a/ClassicalSharp/Singleplayer/Server.cs
+++ b/ClassicalSharp/Singleplayer/Server.cs
@@ -37,9 +37,20 @@ namespace ClassicalSharp.Singleplayer {
GenMap( 128, 64, 128, seed, new NotchyGenerator() );
}
+ char lastCol = '\0';
public override void SendChat( string text, bool partial ) {
- if( String.IsNullOrEmpty( text ) ) return;
+ if( !String.IsNullOrEmpty( text ) )
+ AddChat( text );
+ if( !partial ) lastCol = '\0';
+ }
+
+ void AddChat( string text ) {
text = text.TrimEnd().Replace( '%', '&' );
+ if( !IDrawer2D.IsWhiteColour( lastCol ) )
+ text = "&" + lastCol + text;
+
+ char col = game.Drawer2D.LastColour( text, text.Length );
+ if( col != '\0' ) lastCol = col;
game.Chat.Add( text, MessageType.Normal );
}
diff --git a/ClassicalSharp/Utils/WrappableStringBuffer.cs b/ClassicalSharp/Utils/WrappableStringBuffer.cs
index 5d7f4f806..30ba6f1bd 100644
--- a/ClassicalSharp/Utils/WrappableStringBuffer.cs
+++ b/ClassicalSharp/Utils/WrappableStringBuffer.cs
@@ -68,9 +68,8 @@ namespace ClassicalSharp {
value[i] = '&';
}
- for( int i = 0; i < Math.Max( 1, linesCount ); i++ ) {
+ for( int i = 0; i < Math.Max( 1, linesCount ); i++ )
lines[i] = new String( value, i * lineSize, lineLens[i] );
- }
}
int WrapLine( int index, int lineSize ) {