Implement CustomTextColors.

This commit is contained in:
UnknownShadow200 2016-01-22 22:33:17 +11:00
parent ec19f0166a
commit f1926f8874
12 changed files with 236 additions and 22 deletions

View File

@ -0,0 +1,151 @@
/*
Copyright 2015 MCGalaxy
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.Drawing;
namespace MCGalaxy.Commands {
public sealed class CmdCustomColors : Command {
public override string name { get { return "customcolors"; } }
public override string shortcut { get { return "ccols"; } }
public override string type { get { return CommandTypes.Chat; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
public override void Use(Player p, string message) {
string[] args = message.Split(' ');
if (message == "") { Help(p); return; }
switch (args[0].ToLower()) {
case "add":
case "create":
case "new":
AddHandler(p, args); break;
case "remove":
case "delete":
RemoveHandler(p, args); break;
case "list":
ListHandler(p, args); break;
default:
Help(p); break;
}
}
void AddHandler(Player p, string[] args) {
if (args.Length < 4) { Help(p); return; }
char code = args[1][0];
if (Chat.IsStandardColor(code)) {
Player.SendMessage(p, code + " is a standard color code, and thus cannot be removed."); return;
}
if (code <= ' ' || code > '~' || code == '%' || code == '&') {
Player.SendMessage(p, code + " must be a standard ASCII character.");
Player.SendMessage(p, "It also cannot be a space, percentage, or ampersand.");
return;
}
char code2 = code;
if (Chat.Map(ref code2)) {
Player.SendMessage(p, "There is already a custom or server defined color with the code " + code +
", you must either use a different code or use \"/ccols remove " + code + "\"");
return;
}
char fallback = args[2][0];
if (!Chat.IsStandardColor(fallback)) {
Player.SendMessage(p, fallback + " must be a standard color code."); return;
}
string hex = args[3];
if (hex.Length > 0 && hex[0] == '#')
hex = hex.Substring(1);
if (hex.Length != 6 || !IsValidHex(hex)) {
Player.SendMessage(p, "\"#" + hex + "\" is not a valid hex color."); return;
}
CustomColor col = default(CustomColor);
col.Code = code; col.Fallback = fallback; col.A = 255;
Color rgb = ColorTranslator.FromHtml("#" + hex);
col.R = rgb.R; col.G = rgb.G; col.B = rgb.B;
Chat.AddExtColor(col);
Player.SendMessage(p, "Successfully added a custom color.");
}
void RemoveHandler(Player p, string[] args) {
if (args.Length < 2) { Help(p); return; }
char code = args[1][0];
if (Chat.IsStandardColor(code)) {
Player.SendMessage(p, code + " is a standard color, and thus cannot be removed."); return;
}
if ((int)code >= 256 || Chat.ExtColors[code].Undefined) {
Player.SendMessage(p, "There is no custom color with the code " + code + ".");
Player.SendMessage(p, "Use \"%T/ccols list\" %Sto see a list of custom colors.");
return;
}
Chat.RemoveExtColor(code);
Player.SendMessage(p, "Successfully removed a custom color.");
}
void ListHandler(Player p, string[] args) {
int offset = 0, index = 0, count = 0;
if (args.Length > 1) int.TryParse(args[1], out offset);
CustomColor[] cols = Chat.ExtColors;
for( int i = 0; i < cols.Length; i++ ) {
CustomColor col = cols[i];
if (col.Undefined) continue;
if (index >= offset) {
count++;
const string format = "%{0} displays as {1}, and falls back to {2}";
Player.SendMessage(p, String.Format(format, col.Code, Hex(col), col.Fallback), false);
if (count >= 8) {
const string helpFormat = "To see the next set of custom colors, type %T/ccols list {0}";
Player.SendMessage(p, String.Format(helpFormat, offset + 8));
return;
}
}
index++;
}
}
public override void Help(Player p) {
Player.SendMessage(p, "%T/ccols <add/remove/list>");
Player.SendMessage(p, "%H/ccols add [code] [fallback] [hex]");
Player.SendMessage(p, "%H code is in ASCII. You cannot replace the standard color codes.");
Player.SendMessage(p, "%H fallback is the standard color code shown to non-supporting clients.");
Player.SendMessage(p, "%H/ccols remove [code]");
Player.SendMessage(p, "%H/ccols list [offset] - lists all custom color codes.");
}
static bool IsValidHex(string hex) {
for (int i = 0; i < hex.Length; i++) {
if (!Chat.IsStandardColor(hex[i])) return false;
}
return true;
}
static string Hex(CustomColor c) {
return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}
}
}

View File

@ -36,7 +36,7 @@ namespace MCGalaxy.Commands {
float dist;
if( !float.TryParse(message, out dist)) {
Player.SendMessage(p, "\"" + message + "\", is not a valid distance.");
Player.SendMessage(p, "\"" + message + "\", is not a valid distance."); return;
}
int packedDist = (int)(dist * 32);
if (packedDist < 0) packedDist = 160;

View File

@ -75,6 +75,7 @@ namespace MCGalaxy
all.Add(new CmdCrashServer());
all.Add(new CmdCTF());
all.Add(new CmdCuboid());
all.Add(new CmdCustomColors());
all.Add(new CmdDelete());
all.Add(new CmdDeleteLvl());
all.Add(new CmdDelTempRank());

View File

@ -48,6 +48,7 @@ namespace MCGalaxy.Commands
Player.SendMessage(p, playerNames);
playerDb.Dispose();
System.Math.Sign(System.Convert.ToInt32(0));
}
public override void Help(Player p)
{

View File

@ -282,8 +282,7 @@ namespace MCGalaxy.Commands {
static bool IsValidHex(string hex) {
for (int i = 0; i < hex.Length; i++) {
if (!Chat.IsStandardColor(hex[i]))
return false;
if (!Chat.IsStandardColor(hex[i])) return false;
}
return true;
}

View File

@ -136,7 +136,6 @@
<Compile Include="Commands\Building\CmdWrite.cs" />
<Compile Include="Commands\building\DrawCmd.cs" />
<Compile Include="Commands\building\ReplaceCmd.cs" />
<Compile Include="Commands\Chat\Class1.cs" />
<Compile Include="Commands\Chat\CmdAdminChat.cs" />
<Compile Include="Commands\Chat\CmdChatRoom.cs" />
<Compile Include="Commands\Chat\CmdGcaccept.cs" />
@ -156,6 +155,7 @@
<Compile Include="Commands\CommandKeywords.cs" />
<Compile Include="Commands\CommandList.cs" />
<Compile Include="Commands\CommandOtherPerms.cs" />
<Compile Include="Commands\CPE\CmdCustomColors.cs" />
<Compile Include="Commands\CPE\CmdModel.cs" />
<Compile Include="Commands\CPE\CmdReachDistance.cs" />
<Compile Include="Commands\CPE\CmdXModel.cs" />

View File

@ -223,7 +223,7 @@ namespace MCGalaxy {
if (Chat.IsStandardColor((char)i)) continue;
CustomColor col = Chat.ExtColors[i];
if (col.Fallback == '\0' || !hasTextColors)
if (col.Undefined || !hasTextColors)
sb.Replace("&" + (char)i, "");
}
}

View File

@ -14,6 +14,7 @@ permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
@ -152,14 +153,8 @@ namespace MCGalaxy {
if (color == 'i' || color == 'I') { color = Server.IRCColour[1]; return true; }
if (color == 'g' || color == 'G') { color = Server.GlobalChatColor[1]; return true; }
if (color == 'r' || color == 'R') { color = 'f'; return true; }
return GetFallback(color) != '\0';
}
public static CustomColor[] ExtColors = new CustomColor[256];
public static char GetFallback(char c) {
return (int)c >= 256 ? '\0' : ExtColors[c].Fallback;
}
public static string StripColours(string value) {
if (value.IndexOf('%') == -1)
@ -310,10 +305,70 @@ namespace MCGalaxy {
Player.SendMessage(p, Server.DefaultColor + "[<] " + who.FullName + ": &f" + message);
Player.SendMessage(who, "&9[>] " + fullName + ": &f" + message);
}
public static CustomColor[] ExtColors = new CustomColor[256];
public static char GetFallback(char c) {
return (int)c >= 256 ? '\0' : ExtColors[c].Fallback;
}
public static void AddExtColor(CustomColor col) { SetExtCol(col); }
public static void RemoveExtColor(char code) {
CustomColor col = default(CustomColor);
col.Code = code;
SetExtCol(col);
}
static void SetExtCol(CustomColor col) {
ExtColors[col.Code] = col;
foreach (Player p in Player.players) {
if (!p.HasCpeExt(CpeExt.TextColors)) continue;
SendSetTextColor(p, col);
}
SaveExtColors();
}
internal static void SendSetTextColor(Player p, CustomColor col) {
byte[] buffer = new byte[6];
buffer[0] = Opcode.CpeSetTextColor;
buffer[1] = col.R; buffer[2] = col.G; buffer[3] = col.B; buffer[4] = col.A;
buffer[5] = (byte)col.Code;
p.SendRaw(buffer);
}
internal static void SaveExtColors() {
using (StreamWriter w = new StreamWriter("text/colors.txt")) {
foreach (CustomColor col in ExtColors) {
if (col.Undefined) continue;
w.Write(col.Code + " " + col.Fallback + " " +
col.R + " " + col.G + " " + col.B + " " + col.A);
}
}
}
internal static void LoadExtColors() {
if (!File.Exists("text/colors.txt")) return;
string[] lines = File.ReadAllLines("text/colors.txt");
CustomColor col = default(CustomColor);
for (int i = 0; i < lines.Length; i++) {
string[] parts = lines[i].Split(' ');
if (parts.Length != 6) continue;
col.Code = parts[0][0]; col.Fallback = parts[1][0];
if (!Byte.TryParse(parts[2], out col.R) || !Byte.TryParse(parts[3], out col.G) ||
!Byte.TryParse(parts[4], out col.B) || !Byte.TryParse(parts[5], out col.A))
continue;
ExtColors[col.Code] = col;
}
}
}
public struct CustomColor {
public char Code, Fallback;
public byte R, G, B, A;
public bool Undefined { get { return Fallback == '\0'; } }
}
}

View File

@ -135,7 +135,12 @@ namespace MCGalaxy
BlockDefinitionsExt = version; break;
case CpeExt.TextColors:
hasTextColors = true;
TextColors = version; break;
TextColors = version;
for (int i = 0; i < Chat.ExtColors.Length; i++) {
if (Chat.ExtColors[i].Undefined) continue;
Chat.SendSetTextColor(this, Chat.ExtColors[i]);
} break;
}
}
@ -161,6 +166,7 @@ namespace MCGalaxy
case CpeExt.FullCP437: return FullCP437 == version;
case CpeExt.BlockDefinitions: return BlockDefinitions == version;
case CpeExt.BlockDefinitionsExt: return BlockDefinitionsExt == version;
case CpeExt.TextColors: return TextColors == version;
default: return false;
}
}

View File

@ -2196,7 +2196,7 @@ return;
case "mapload": cmd = "load"; break;
case "colour": cmd = "color"; break;
case "materials": cmd = "blocks"; break;
case "zz": cmd = "static"; message = "cuboid"; break;
case "zz": cmd = "static"; message = "cuboid " + message; break;
case "fetch": cmd = "summon"; break;
case "ranks": cmd = "help"; message = "ranks"; break;

View File

@ -123,7 +123,7 @@ namespace MCGalaxy {
for (int i = 0; i < 128; i++) {
CustomColor col = Chat.ExtColors[i];
if (col.Fallback == '\0') continue;
if (col.Undefined) continue;
sb.Replace("&" + col.Code, "&" + col.Fallback);
}

View File

@ -1057,6 +1057,7 @@ namespace MCGalaxy
ProfanityFilter.Init();
Alias.Load();
BlockDefinition.LoadGlobal("blocks.json");
Chat.LoadExtColors();
}
public static void Setup()