mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-15 18:28:11 -04:00
Don't convert percents to ampersands when part of url, fixes #420.
This commit is contained in:
parent
5ee8c9c576
commit
a933a360f8
@ -26,6 +26,8 @@ namespace MCGalaxy.Gui {
|
||||
public static void Format(string message, Action<char, string> output) {
|
||||
int index = 0;
|
||||
char col = 'S';
|
||||
message = Colors.Escape(message);
|
||||
|
||||
while (index < message.Length)
|
||||
OutputPart(ref col, ref index, message, output);
|
||||
}
|
||||
@ -47,7 +49,7 @@ namespace MCGalaxy.Gui {
|
||||
|
||||
static int Next(int start, string message) {
|
||||
for (int i = start; i < message.Length; i++) {
|
||||
if (!(message[i] == '&' || message[i] == '%')) continue;
|
||||
if (message[i] != '&') continue;
|
||||
// No colour code follows this
|
||||
if (i == message.Length - 1) return -1;
|
||||
|
||||
|
@ -189,26 +189,53 @@ namespace MCGalaxy {
|
||||
|
||||
|
||||
/// <summary> Converts percentage color codes to their actual/real color codes. </summary>
|
||||
/// <remarks> Does not escape percentage codes that are part of urls. </remarks>
|
||||
public static string Escape(string value) {
|
||||
if (value.IndexOf('%') == -1) return value;
|
||||
char[] chars = new char[value.Length];
|
||||
for (int i = 0; i < chars.Length; i++) { chars[i] = value[i]; }
|
||||
|
||||
for (int i = 0; i < value.Length; i++ ) {
|
||||
char c = value[i];
|
||||
bool validCode = c == '%' && i < value.Length - 1;
|
||||
if (!validCode) { chars[i] = c; continue; }
|
||||
for (int i = 0; i < chars.Length;) {
|
||||
int end = value.IndexOf(' ', i);
|
||||
if (end == -1) end = value.Length;
|
||||
|
||||
char color = value[i + 1];
|
||||
if (Map(ref color)) {
|
||||
chars[i] = '&';
|
||||
chars[i + 1] = color;
|
||||
i++; continue;
|
||||
}
|
||||
chars[i] = '%';
|
||||
if (!IsUrlAt(chars, i, end - i)) Escape(chars, i, end);
|
||||
i = end + 1;
|
||||
}
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
static bool IsUrlAt(char[] chars, int i, int len) {
|
||||
const int prefixLen = 7; // "http://".Length
|
||||
if (len < prefixLen) return false;
|
||||
|
||||
// skip color codes in url
|
||||
while (len > 0 && chars[i] == '&') { len -= 2; i += 2; }
|
||||
|
||||
// Starts with "http" ?
|
||||
if (len < prefixLen) return false;
|
||||
if (chars[i] != 'h' || chars[i + 1] != 't' || chars[i + 2] != 't' || chars[i + 3] != 'p') return false;
|
||||
len -= 4; i += 4;
|
||||
|
||||
// And then with "s://" or "://" ?
|
||||
if (len >= 4 && chars[i] == 's' && chars[i + 1] == ':' && chars[i + 2] == '/' && chars[i + 3] == '/') return true;
|
||||
if (len >= 3 && chars[i] == ':' && chars[i + 1] == '/' && chars[i + 2] == '/') return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Escape(char[] chars, int start, int end) {
|
||||
for (int i = start; i < end; i++ ) {
|
||||
char c = chars[i];
|
||||
bool validCode = c == '%' && i < chars.Length - 1;
|
||||
|
||||
if (!validCode) continue;
|
||||
char color = chars[i + 1];
|
||||
if (!Map(ref color)) continue;
|
||||
|
||||
chars[i] = '&'; i++; // skip over color code
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Removes all percentage and actual color codes from the given string. </summary>
|
||||
public static string Strip(string value) {
|
||||
if (value.IndexOf('%') == -1 && value.IndexOf('&') == -1) return value;
|
||||
@ -320,7 +347,7 @@ namespace MCGalaxy {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Describes information about a color code. </summary>
|
||||
/// <summary> Describes information about a color code. </summary>
|
||||
public struct ColorDesc {
|
||||
public char Code, Fallback;
|
||||
public byte R, G, B, A;
|
||||
|
@ -33,10 +33,10 @@ namespace MCGalaxy.Commands.Maintenance {
|
||||
if (!Formatter.ValidName(p, args[1], "player")) return;
|
||||
|
||||
if (PlayerInfo.FindExact(args[0]) != null) {
|
||||
Player.Message(p, "\"{0}\" must be offline to use /infoswap.", args[0]); return;
|
||||
Player.Message(p, "\"{0}\" must be offline to use %T/InfoSwap", args[0]); return;
|
||||
}
|
||||
if (PlayerInfo.FindExact(args[1]) != null) {
|
||||
Player.Message(p, "\"{0}\" must be offline to use /infoswap.", args[1]); return;
|
||||
Player.Message(p, "\"{0}\" must be offline to use %T/InfoSwap", args[1]); return;
|
||||
}
|
||||
|
||||
string src = PlayerInfo.FindName(args[0]);
|
||||
@ -51,10 +51,10 @@ namespace MCGalaxy.Commands.Maintenance {
|
||||
Group srcGroup = Group.GroupIn(src);
|
||||
Group dstGroup = Group.GroupIn(dst);
|
||||
if (p != null && srcGroup.Permission >= p.Rank) {
|
||||
Player.Message(p, "Cannot /infoswap for a player ranked equal or higher to yours."); return;
|
||||
Player.Message(p, "Cannot %T/InfoSwap %Sfor a player ranked equal or higher to yours."); return;
|
||||
}
|
||||
if (p != null && dstGroup.Permission >= p.Rank) {
|
||||
Player.Message(p, "Cannot /infoswap for a player ranked equal or higher to yours."); return;
|
||||
Player.Message(p, "Cannot %T/InfoSwap %Sfor a player ranked equal or higher to yours."); return;
|
||||
}
|
||||
|
||||
SwapStats(src, dst);
|
||||
|
Loading…
x
Reference in New Issue
Block a user