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) {
|
public static void Format(string message, Action<char, string> output) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
char col = 'S';
|
char col = 'S';
|
||||||
|
message = Colors.Escape(message);
|
||||||
|
|
||||||
while (index < message.Length)
|
while (index < message.Length)
|
||||||
OutputPart(ref col, ref index, message, output);
|
OutputPart(ref col, ref index, message, output);
|
||||||
}
|
}
|
||||||
@ -47,7 +49,7 @@ namespace MCGalaxy.Gui {
|
|||||||
|
|
||||||
static int Next(int start, string message) {
|
static int Next(int start, string message) {
|
||||||
for (int i = start; i < message.Length; i++) {
|
for (int i = start; i < message.Length; i++) {
|
||||||
if (!(message[i] == '&' || message[i] == '%')) continue;
|
if (message[i] != '&') continue;
|
||||||
// No colour code follows this
|
// No colour code follows this
|
||||||
if (i == message.Length - 1) return -1;
|
if (i == message.Length - 1) return -1;
|
||||||
|
|
||||||
|
@ -185,30 +185,57 @@ namespace MCGalaxy {
|
|||||||
if (col == 'T') { col = ServerConfig.HelpSyntaxColor[1]; return true; }
|
if (col == 'T') { col = ServerConfig.HelpSyntaxColor[1]; return true; }
|
||||||
if (col == 'I') { col = ServerConfig.IRCColor[1]; return true; }
|
if (col == 'I') { col = ServerConfig.IRCColor[1]; return true; }
|
||||||
return IsDefined(col);
|
return IsDefined(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Converts percentage color codes to their actual/real color codes. </summary>
|
/// <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) {
|
public static string Escape(string value) {
|
||||||
if (value.IndexOf('%') == -1) return value;
|
if (value.IndexOf('%') == -1) return value;
|
||||||
char[] chars = new char[value.Length];
|
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++ ) {
|
for (int i = 0; i < chars.Length;) {
|
||||||
char c = value[i];
|
int end = value.IndexOf(' ', i);
|
||||||
bool validCode = c == '%' && i < value.Length - 1;
|
if (end == -1) end = value.Length;
|
||||||
if (!validCode) { chars[i] = c; continue; }
|
|
||||||
|
|
||||||
char color = value[i + 1];
|
if (!IsUrlAt(chars, i, end - i)) Escape(chars, i, end);
|
||||||
if (Map(ref color)) {
|
i = end + 1;
|
||||||
chars[i] = '&';
|
|
||||||
chars[i + 1] = color;
|
|
||||||
i++; continue;
|
|
||||||
}
|
|
||||||
chars[i] = '%';
|
|
||||||
}
|
}
|
||||||
return new string(chars);
|
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>
|
/// <summary> Removes all percentage and actual color codes from the given string. </summary>
|
||||||
public static string Strip(string value) {
|
public static string Strip(string value) {
|
||||||
if (value.IndexOf('%') == -1 && value.IndexOf('&') == -1) return 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 struct ColorDesc {
|
||||||
public char Code, Fallback;
|
public char Code, Fallback;
|
||||||
public byte R, G, B, A;
|
public byte R, G, B, A;
|
||||||
|
@ -33,10 +33,10 @@ namespace MCGalaxy.Commands.Maintenance {
|
|||||||
if (!Formatter.ValidName(p, args[1], "player")) return;
|
if (!Formatter.ValidName(p, args[1], "player")) return;
|
||||||
|
|
||||||
if (PlayerInfo.FindExact(args[0]) != null) {
|
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) {
|
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]);
|
string src = PlayerInfo.FindName(args[0]);
|
||||||
@ -51,10 +51,10 @@ namespace MCGalaxy.Commands.Maintenance {
|
|||||||
Group srcGroup = Group.GroupIn(src);
|
Group srcGroup = Group.GroupIn(src);
|
||||||
Group dstGroup = Group.GroupIn(dst);
|
Group dstGroup = Group.GroupIn(dst);
|
||||||
if (p != null && srcGroup.Permission >= p.Rank) {
|
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) {
|
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);
|
SwapStats(src, dst);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user