Don't let you type in multiple lines of chat on servers not supporting partial messages, this avoids confusion with PM/commands being incorrectly put on normal chat messages.

This commit is contained in:
UnknownShadow200 2017-10-23 17:52:25 +11:00
parent 2c33b99665
commit f8dd6b0e52
11 changed files with 44 additions and 70 deletions

View File

@ -247,7 +247,7 @@ namespace ClassicalSharp.Gui.Screens {
bottomRight.SetText(2 - (int)(type - MessageType.BottomRight1), e.Text); bottomRight.SetText(2 - (int)(type - MessageType.BottomRight1), e.Text);
} else if (type == MessageType.Announcement) { } else if (type == MessageType.Announcement) {
announcement.SetText(e.Text); announcement.SetText(e.Text);
} else if (type >= MessageType.ClientStatus1 && type <= MessageType.ClientStatus6) { } else if (type >= MessageType.ClientStatus1 && type <= MessageType.ClientStatus3) {
clientStatus.SetText((int)(type - MessageType.ClientStatus1), e.Text); clientStatus.SetText((int)(type - MessageType.ClientStatus1), e.Text);
UpdateChatYOffset(true); UpdateChatYOffset(true);
} }

View File

@ -11,7 +11,7 @@ using Android.Graphics;
namespace ClassicalSharp.Gui.Widgets { namespace ClassicalSharp.Gui.Widgets {
public sealed class ChatInputWidget : InputWidget { public sealed class ChatInputWidget : InputWidget {
public ChatInputWidget(Game game, Font font) : base(game, font) { public ChatInputWidget(Game game, Font font) : base(game, font, "> ", 3) {
typingLogPos = game.Chat.InputLog.Count; // Index of newest entry + 1. typingLogPos = game.Chat.InputLog.Count; // Index of newest entry + 1.
ShowCaret = true; ShowCaret = true;
Padding = 5; Padding = 5;
@ -20,28 +20,9 @@ namespace ClassicalSharp.Gui.Widgets {
static FastColour backColour = new FastColour(0, 0, 0, 127); static FastColour backColour = new FastColour(0, 0, 0, 127);
int typingLogPos; int typingLogPos;
string originalText; string originalText;
bool shownWarning;
public override int MaxLines { get { return game.ClassicMode ? 1 : 3; } } public override int UsedLines {
public override string Prefix { get { return "> "; } } get { return !game.ClassicMode && game.Server.SupportsPartialMessages ? 3 : 1; }
public override int MaxCharsPerLine {
get {
bool allChars = game.ClassicMode || game.Server.SupportsPartialMessages;
return allChars ? 64 : 62; // need 2 chars for colour in multilined chat, when server doesn't support partial messages
}
}
public override void Init() {
base.Init();
bool supports = game.Server.SupportsPartialMessages;
if (Text.Length > MaxCharsPerLine && !shownWarning && !supports) {
game.Chat.Add("&eNote: On this server, each line will be sent separately.", MessageType.ClientStatus6);
shownWarning = true;
} else if (Text.Length <= MaxCharsPerLine && shownWarning) {
game.Chat.Add(null, MessageType.ClientStatus6);
shownWarning = false;
}
} }
public override void Render(double delta) { public override void Render(double delta) {
@ -71,9 +52,8 @@ namespace ClassicalSharp.Gui.Widgets {
originalText = null; originalText = null;
typingLogPos = game.Chat.InputLog.Count; // Index of newest entry + 1. typingLogPos = game.Chat.InputLog.Count; // Index of newest entry + 1.
game.Chat.Add(null, MessageType.ClientStatus4); game.Chat.Add(null, MessageType.ClientStatus2);
game.Chat.Add(null, MessageType.ClientStatus5); game.Chat.Add(null, MessageType.ClientStatus3);
game.Chat.Add(null, MessageType.ClientStatus6);
base.EnterInput(); base.EnterInput();
} }
@ -167,7 +147,7 @@ namespace ClassicalSharp.Gui.Widgets {
void DownKey(bool controlDown) { void DownKey(bool controlDown) {
if (controlDown) { if (controlDown) {
if (caret == -1 || caret >= (lines.Length - 1) * MaxCharsPerLine) return; if (caret == -1 || caret >= (UsedLines - 1) * MaxCharsPerLine) return;
caret += MaxCharsPerLine; caret += MaxCharsPerLine;
UpdateCaret(); UpdateCaret();
return; return;
@ -200,7 +180,7 @@ namespace ClassicalSharp.Gui.Widgets {
string part = new String(value, start, pos + 1 - start); string part = new String(value, start, pos + 1 - start);
List<string> matches = new List<string>(); List<string> matches = new List<string>();
game.Chat.Add(null, MessageType.ClientStatus5); game.Chat.Add(null, MessageType.ClientStatus3);
TabListEntry[] entries = game.TabList.Entries; TabListEntry[] entries = game.TabList.Entries;
for (int i = 0; i < EntityList.MaxCount; i++) { for (int i = 0; i < EntityList.MaxCount; i++) {
@ -232,7 +212,7 @@ namespace ClassicalSharp.Gui.Widgets {
sb.Append(ref index, match); sb.Append(ref index, match);
sb.Append(ref index, ' '); sb.Append(ref index, ' ');
} }
game.Chat.Add(sb.ToString(), MessageType.ClientStatus5); game.Chat.Add(sb.ToString(), MessageType.ClientStatus3);
} }
} }

View File

@ -9,16 +9,17 @@ using Android.Graphics;
namespace ClassicalSharp.Gui.Widgets { namespace ClassicalSharp.Gui.Widgets {
public abstract class InputWidget : Widget { public abstract class InputWidget : Widget {
public InputWidget(Game game, Font font) : base(game) { public InputWidget(Game game, Font font, string prefix, int maxLines) : base(game) {
Text = new WrappableStringBuffer(Utils.StringLength * MaxLines); Text = new WrappableStringBuffer(Utils.StringLength * maxLines);
lines = new string[MaxLines]; lines = new string[maxLines];
lineSizes = new Size[MaxLines]; lineSizes = new Size[maxLines];
this.font = font;
Prefix = prefix;
DrawTextArgs args = new DrawTextArgs("_", font, true); DrawTextArgs args = new DrawTextArgs("_", font, true);
caretTex = game.Drawer2D.MakeTextTexture(ref args, 0, 0); caretTex = game.Drawer2D.MakeTextTexture(ref args, 0, 0);
caretTex.Width = (ushort)((caretTex.Width * 3) / 4); caretTex.Width = (ushort)((caretTex.Width * 3) / 4);
caretWidth = caretTex.Width; caretHeight = caretTex.Height; caretWidth = caretTex.Width; caretHeight = caretTex.Height;
this.font = font;
if (Prefix == null) return; if (Prefix == null) return;
args = new DrawTextArgs(Prefix, font, true); args = new DrawTextArgs(Prefix, font, true);
@ -45,13 +46,13 @@ namespace ClassicalSharp.Gui.Widgets {
public WrappableStringBuffer Text; public WrappableStringBuffer Text;
/// <summary> The maximum number of lines that may be entered. </summary> /// <summary> The maximum number of lines that may be entered. </summary>
public abstract int MaxLines { get; } public abstract int UsedLines { get; }
/// <summary> The maximum number of characters that can fit on one line. </summary> /// <summary> The maximum number of characters that can fit on one line. </summary>
public abstract int MaxCharsPerLine { get; } public int MaxCharsPerLine = Utils.StringLength;
/// <summary> The prefix string that is always shown before the input text. Can be null. </summary> /// <summary> The prefix string that is always shown before the input text. Can be null. </summary>
public abstract string Prefix { get; } public string Prefix;
/// <summary> The horizontal offset (in pixels) from the start of the box background /// <summary> The horizontal offset (in pixels) from the start of the box background
/// to the beginning of the input texture. </summary> /// to the beginning of the input texture. </summary>
@ -67,7 +68,7 @@ namespace ClassicalSharp.Gui.Widgets {
protected double caretAccumulator; protected double caretAccumulator;
public override void Init() { public override void Init() {
if (lines.Length > 1) { if (UsedLines > 1) {
Text.WordWrap(game.Drawer2D, lines, MaxCharsPerLine); Text.WordWrap(game.Drawer2D, lines, MaxCharsPerLine);
} else { } else {
lines[0] = Text.ToString(); lines[0] = Text.ToString();
@ -105,7 +106,7 @@ namespace ClassicalSharp.Gui.Widgets {
lineSizes[0].Width = prefixWidth; lineSizes[0].Width = prefixWidth;
DrawTextArgs args = new DrawTextArgs(null, font, true); DrawTextArgs args = new DrawTextArgs(null, font, true);
for (int y = 0; y < MaxLines; y++) { for (int y = 0; y < UsedLines; y++) {
args.Text = lines[y]; args.Text = lines[y];
lineSizes[y] += game.Drawer2D.MeasureSize(ref args); lineSizes[y] += game.Drawer2D.MeasureSize(ref args);
} }
@ -114,7 +115,8 @@ namespace ClassicalSharp.Gui.Widgets {
/// <summary> Calculates the location and size of the caret character </summary> /// <summary> Calculates the location and size of the caret character </summary>
public void UpdateCaret() { public void UpdateCaret() {
if (caret >= Text.Length) caret = -1; int maxChars = UsedLines * MaxCharsPerLine;
if (caret >= maxChars) caret = -1;
Text.GetCoords(caret, lines, out caretX, out caretY); Text.GetCoords(caret, lines, out caretX, out caretY);
DrawTextArgs args = new DrawTextArgs(null, font, false); DrawTextArgs args = new DrawTextArgs(null, font, false);
IDrawer2D drawer = game.Drawer2D; IDrawer2D drawer = game.Drawer2D;
@ -160,7 +162,7 @@ namespace ClassicalSharp.Gui.Widgets {
/// <remarks> Also updates the dimensions of the widget. </remarks> /// <remarks> Also updates the dimensions of the widget. </remarks>
public virtual void RemakeTexture() { public virtual void RemakeTexture() {
int totalHeight = 0, maxWidth = 0; int totalHeight = 0, maxWidth = 0;
for (int i = 0; i < MaxLines; i++) { for (int i = 0; i < UsedLines; i++) {
totalHeight += lineSizes[i].Height; totalHeight += lineSizes[i].Height;
maxWidth = Math.Max(maxWidth, lineSizes[i].Width); maxWidth = Math.Max(maxWidth, lineSizes[i].Width);
} }
@ -249,8 +251,8 @@ namespace ClassicalSharp.Gui.Widgets {
bool TryAppendChar(char c) { bool TryAppendChar(char c) {
int totalChars = MaxCharsPerLine * lines.Length; int maxChars = UsedLines * MaxCharsPerLine;
if (Text.Length == totalChars) return false; if (Text.Length >= maxChars) return false;
if (!AllowedChar(c)) return false; if (!AllowedChar(c)) return false;
AppendChar(c); AppendChar(c);
@ -409,15 +411,15 @@ namespace ClassicalSharp.Gui.Widgets {
static char[] trimChars = {'\r', '\n', '\v', '\f', ' ', '\t', '\0'}; static char[] trimChars = {'\r', '\n', '\v', '\f', ' ', '\t', '\0'};
bool OtherKey(Key key) { bool OtherKey(Key key) {
int totalChars = MaxCharsPerLine * lines.Length; int maxChars = UsedLines * MaxCharsPerLine;
if (key == Key.V && Text.Length < totalChars) { if (key == Key.V && Text.Length < maxChars) {
string text = null; string text = null;
try { try {
text = game.window.ClipboardText.Trim(trimChars); text = game.window.ClipboardText.Trim(trimChars);
} catch (Exception ex) { } catch (Exception ex) {
ErrorHandler.LogError("Paste from clipboard", ex); ErrorHandler.LogError("Paste from clipboard", ex);
const string warning = "&cError while trying to paste from clipboard."; const string warning = "&cError while trying to paste from clipboard.";
game.Chat.Add(warning, MessageType.ClientStatus4); game.Chat.Add(warning, MessageType.ClientStatus2);
return true; return true;
} }
@ -431,7 +433,7 @@ namespace ClassicalSharp.Gui.Widgets {
} catch (Exception ex) { } catch (Exception ex) {
ErrorHandler.LogError("Copy to clipboard", ex); ErrorHandler.LogError("Copy to clipboard", ex);
const string warning = "&cError while trying to copy to clipboard."; const string warning = "&cError while trying to copy to clipboard.";
game.Chat.Add(warning, MessageType.ClientStatus4); game.Chat.Add(warning, MessageType.ClientStatus2);
} }
return true; return true;
} }

View File

@ -9,7 +9,7 @@ using Android.Graphics;
namespace ClassicalSharp.Gui.Widgets { namespace ClassicalSharp.Gui.Widgets {
public sealed class MenuInputWidget : InputWidget { public sealed class MenuInputWidget : InputWidget {
public MenuInputWidget(Game game, Font font) : base(game, font) { } public MenuInputWidget(Game game, Font font) : base(game, font, null, 1) { }
public static MenuInputWidget Create(Game game, int width, int height, string text, public static MenuInputWidget Create(Game game, int width, int height, string text,
Font font, MenuInputValidator validator) { Font font, MenuInputValidator validator) {
@ -28,9 +28,7 @@ namespace ClassicalSharp.Gui.Widgets {
public int MinWidth, MinHeight; public int MinWidth, MinHeight;
public MenuInputValidator Validator; public MenuInputValidator Validator;
public override int MaxLines { get { return 1; } } public override int UsedLines { get { return 1; } }
public override string Prefix { get { return null; } }
public override int MaxCharsPerLine { get { return Utils.StringLength; } }
public override void Render(double delta) { public override void Render(double delta) {
gfx.Texturing = false; gfx.Texturing = false;
@ -85,7 +83,7 @@ namespace ClassicalSharp.Gui.Widgets {
protected override bool AllowedChar(char c) { protected override bool AllowedChar(char c) {
if (c == '&' || !Utils.IsValidInputChar(c, true)) return false; if (c == '&' || !Utils.IsValidInputChar(c, true)) return false;
if (!Validator.IsValidChar(c)) return false; if (!Validator.IsValidChar(c)) return false;
if (Text.Length == MaxCharsPerLine) return false; if (Text.Length == UsedLines * MaxCharsPerLine) return false;
// See if the new string is in valid format // See if the new string is in valid format
AppendChar(c); AppendChar(c);

View File

@ -11,7 +11,7 @@ namespace ClassicalSharp {
public ChatLine Status1, Status2, Status3, BottomRight1, public ChatLine Status1, Status2, Status3, BottomRight1,
BottomRight2, BottomRight3, Announcement; BottomRight2, BottomRight3, Announcement;
public ChatLine[] ClientStatus = new ChatLine[6]; public ChatLine[] ClientStatus = new ChatLine[3];
Game game; Game game;
public void Init(Game game) { public void Init(Game game) {
@ -63,7 +63,7 @@ namespace ClassicalSharp {
BottomRight3 = text; BottomRight3 = text;
} else if (type == MessageType.Announcement) { } else if (type == MessageType.Announcement) {
Announcement = text; Announcement = text;
} else if (type >= MessageType.ClientStatus1 && type <= MessageType.ClientStatus6) { } else if (type >= MessageType.ClientStatus1 && type <= MessageType.ClientStatus3) {
ClientStatus[(int)(type - MessageType.ClientStatus1)] = text; ClientStatus[(int)(type - MessageType.ClientStatus1)] = text;
} }
game.Events.RaiseChatReceived(text, type); game.Events.RaiseChatReceived(text, type);

View File

@ -66,12 +66,9 @@ namespace ClassicalSharp {
Announcement = 100, Announcement = 100,
// client defined message ids // client defined message ids
ClientStatus1 = 256, ClientStatus1 = 256, // cuboid messages
ClientStatus2 = 257, ClientStatus2 = 257, // clipboard invalid characters
ClientStatus3 = 258, // cuboid messages ClientStatus3 = 258, // tab list matching names
ClientStatus4 = 259, // clipboard invalid characters
ClientStatus5 = 260, // tab list matching names
ClientStatus6 = 261, // no LongerMessages warning
} }
public enum BlockFace { XMax, XMin, YMax, YMin, ZMax, ZMin, } public enum BlockFace { XMax, XMin, YMax, YMin, ZMax, ZMin, }

View File

@ -19,7 +19,7 @@ namespace ClassicalSharp {
/// <summary> Represents a connection to either a multiplayer server, or an internal single player server. </summary> /// <summary> Represents a connection to either a multiplayer server, or an internal single player server. </summary>
public abstract class IServerConnection { public abstract class IServerConnection {
public abstract bool IsSinglePlayer { get; } public bool IsSinglePlayer;
/// <summary> Opens a connection to the given IP address and port, and prepares the initial state of the client. </summary> /// <summary> Opens a connection to the given IP address and port, and prepares the initial state of the client. </summary>
public abstract void Connect(IPAddress address, int port); public abstract void Connect(IPAddress address, int port);

View File

@ -24,10 +24,9 @@ namespace ClassicalSharp.Network {
public NetworkProcessor(Game window) { public NetworkProcessor(Game window) {
game = window; game = window;
cpeData = new CPESupport(); game.Components.Add(cpeData); cpeData = new CPESupport(); game.Components.Add(cpeData);
IsSinglePlayer = false;
} }
public override bool IsSinglePlayer { get { return false; } }
Socket socket; Socket socket;
DateTime lastPacket; DateTime lastPacket;
byte lastOpcode; byte lastOpcode;

View File

@ -20,10 +20,9 @@ namespace ClassicalSharp.Singleplayer {
physics = new PhysicsBase(game); physics = new PhysicsBase(game);
SupportsFullCP437 = !game.ClassicMode; SupportsFullCP437 = !game.ClassicMode;
SupportsPartialMessages = true; SupportsPartialMessages = true;
IsSinglePlayer = true;
} }
public override bool IsSinglePlayer { get { return true; } }
public override void Connect(IPAddress address, int port) { public override void Connect(IPAddress address, int port) {
game.Chat.SetLogName("Singleplayer"); game.Chat.SetLogName("Singleplayer");
game.UseCPEBlocks = game.UseCPE; game.UseCPEBlocks = game.UseCPE;

View File

@ -370,7 +370,7 @@ void HotbarWidget_Reposition(Widget* elem) {
Real32 scale = Game_GetHotbarScale(); Real32 scale = Game_GetHotbarScale();
widget->BarHeight = (Real32)Math_Floor(22.0f * scale); widget->BarHeight = (Real32)Math_Floor(22.0f * scale);
elem->Width = (Int32)(182 * scale); elem->Width = (Int32)(182 * scale);
elem->Height = (Int32)widget->BarHeight; elem->Height = (Int32)widget->BarHeight;
widget->SelBlockSize = (Real32)Math_Ceil(24.0f * scale); widget->SelBlockSize = (Real32)Math_Ceil(24.0f * scale);

View File

@ -118,14 +118,13 @@ void SpecialInputWidget_UpdateCols(SpecialInputWidget* widget);
void SpecialInputWidget_SetActive(SpecialInputWidget* widget, bool active); void SpecialInputWidget_SetActive(SpecialInputWidget* widget, bool active);
#define INPUTWIDGET_MAX_LINES 4 #define INPUTWIDGET_MAX_LINES 3
struct InputWidget_; struct InputWidget_;
/* Remakes the raw texture containing all the chat lines. Also updates the dimensions of the widget. */ /* Remakes the raw texture containing all the chat lines. Also updates the dimensions of the widget. */
typedef struct InputWidget_ { typedef struct InputWidget_ {
Widget Base; Widget Base;
FontDesc Font; FontDesc Font;
Int32 MaxLines; Int32 (*GetMaxLines)(GuiElement* elem);
Int32 MaxCharsPerLine;
Int32 Padding; Int32 Padding;
void (*RemakeTexture)(GuiElement* elem); /* Remakes the raw texture containing all the chat lines. Also updates dimensions. */ void (*RemakeTexture)(GuiElement* elem); /* Remakes the raw texture containing all the chat lines. Also updates dimensions. */
void (*OnPressedEnter)(GuiElement* elem); /* Invoked when the user presses enter. */ void (*OnPressedEnter)(GuiElement* elem); /* Invoked when the user presses enter. */
@ -147,7 +146,7 @@ typedef struct InputWidget_ {
Real64 CaretAccumulator; Real64 CaretAccumulator;
} InputWidget; } InputWidget;
void InputWidget_Create(InputWidget* widget, FontDesc* font); void InputWidget_Create(InputWidget* widget, FontDesc* font, STRING_REF String* prefix);
/* Calculates the sizes of each line in the text buffer. */ /* Calculates the sizes of each line in the text buffer. */
void InputWidget_CalculateLineSizes(InputWidget* widget); void InputWidget_CalculateLineSizes(InputWidget* widget);
/* Calculates the location and size of the caret character. */ /* Calculates the location and size of the caret character. */