Merge pull request #485 from CoderCow/general-devel-cc

Some Region Command Changes and General Improvements
This commit is contained in:
Zack 2013-06-27 08:17:15 -07:00
commit f3f5f9e3e2
5 changed files with 588 additions and 238 deletions

View file

@ -2835,26 +2835,66 @@ namespace TShockAPI
{
if (args.Parameters.Count > 1)
{
string regionName = String.Join(" ", args.Parameters.GetRange(1, args.Parameters.Count - 1));
Region r = TShock.Regions.GetRegionByName(regionName);
if (r == null)
string regionName = args.Parameters[1];
Region region = TShock.Regions.GetRegionByName(regionName);
if (region == null)
{
args.Player.SendMessage("Region {0} does not exist");
args.Player.SendErrorMessage("Region {0} does not exist.", regionName);
break;
}
args.Player.SendMessage(r.Name + ": P: " + r.DisableBuild + " X: " + r.Area.X + " Y: " + r.Area.Y + " W: " +
r.Area.Width + " H: " + r.Area.Height);
foreach (int s in r.AllowedIDs)
int pageNumber;
if (!PaginationTools.TryParsePageNumber(args.Parameters, 2, args.Player, out pageNumber))
break;
List<string> lines = new List<string>
{
var user = TShock.Users.GetUserByID(s);
args.Player.SendMessage(r.Name + ": " + (user != null ? user.Name : "Unknown"));
string.Format("X: {0}; Y: {1}; W: {2}; H: {3}, Z: {4}", region.Area.X, region.Area.Y, region.Area.Width, region.Area.Height, region.Z),
string.Concat("Owner: ", region.Owner),
string.Concat("Protected: ", region.DisableBuild.ToString()),
};
if (region.AllowedIDs.Count > 0)
{
IEnumerable<string> sharedUsersSelector = region.AllowedIDs.Select(userId =>
{
User user = TShock.Users.GetUserByID(userId);
if (user != null)
return user.Name;
else
return string.Concat("{ID: ", userId, "}");
});
List<string> extraLines = PaginationTools.BuildLinesFromTerms(sharedUsersSelector.Distinct());
extraLines[0] = "Shared with: " + extraLines[0];
lines.AddRange(extraLines);
}
else
{
lines.Add("Region is not shared with any users.");
}
if (region.AllowedGroups.Count > 0)
{
List<string> extraLines = PaginationTools.BuildLinesFromTerms(region.AllowedGroups.Distinct());
extraLines[0] = "Shared with groups: " + extraLines[0];
lines.AddRange(extraLines);
}
else
{
lines.Add("Region is not shared with any groups.");
}
PaginationTools.SendPage(
args.Player, pageNumber, lines, new PaginationTools.Settings
{
HeaderFormat = string.Format("Information About Region \"{0}\" ({{0}}/{{1}}):", region.Name),
FooterFormat = "Type /region info {0} for more information."
}
);
}
else
{
args.Player.SendMessage("Invalid syntax! Proper syntax: /region info [name]", Color.Red);
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /region info [name]");
}
break;
@ -2940,13 +2980,37 @@ namespace TShockAPI
case "help":
default:
{
args.Player.SendMessage("Avialable region commands:", Color.Green);
args.Player.SendMessage("/region set [1/2] /region define [name] /region protect [name] [true/false]",
Color.Yellow);
args.Player.SendMessage("/region name (provides region name)", Color.Yellow);
args.Player.SendMessage("/region delete [name] /region clear (temporary region)", Color.Yellow);
args.Player.SendMessage("/region allow [name] [regionname]", Color.Yellow);
args.Player.SendMessage("/region resize [regionname] [u/d/l/r] [amount]", Color.Yellow);
int pageNumber;
int pageParamIndex = 0;
if (args.Parameters.Count > 1)
pageParamIndex = 1;
if (!PaginationTools.TryParsePageNumber(args.Parameters, pageParamIndex, args.Player, out pageNumber))
return;
PaginationTools.SendPage(
args.Player, pageNumber, new[]
{
"set [1/2] - Sets the temporary region points.",
"clear - Clears the temporary region points.",
"define [name] - Defines the region.",
"delete [name] - Deletes the given region.",
"name - Shows the name of the region at the given point.",
"list - Lists all regions.",
"resize [region] [u/d/l/r] [amount] - Resizes a region.",
"allow [user] [region] - Allows a user to a region.",
"remove [user] [region] - Removes a user from a region.",
"allowg [group] [region] - Allows a user group to a region.",
"removeg [group] [region] - Removes a user group from a region.",
"info [region] - Displays several information about the given region.",
"protect [name] [true/false] - Sets whether the tiles inside the region are protected or not.",
"z [name] [#] - Sets the z-order of the region.",
},
new PaginationTools.Settings
{
HeaderFormat = "Available Region Sub-Commands ({0}/{1}):",
FooterFormat = "Type /region {0} for more sub-commands."
}
);
break;
}
}

View file

@ -381,30 +381,36 @@ namespace TShockAPI.DB
return false;
}
public bool AddNewUser(string regionName, String userName)
public bool AddNewUser(string regionName, string userName)
{
try
{
string MergedIDs = string.Empty;
string mergedIDs = string.Empty;
using (
var reader = database.QueryReader("SELECT * FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName,
var reader = database.QueryReader("SELECT UserIds FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName,
Main.worldID.ToString()))
{
if (reader.Read())
MergedIDs = reader.Get<string>("UserIds");
mergedIDs = reader.Get<string>("UserIds");
}
if (string.IsNullOrEmpty(MergedIDs))
MergedIDs = Convert.ToString(TShock.Users.GetUserID(userName));
else
MergedIDs = MergedIDs + "," + Convert.ToString(TShock.Users.GetUserID(userName));
string userIdToAdd = Convert.ToString(TShock.Users.GetUserID(userName));
string[] ids = mergedIDs.Split(',');
// Is the user already allowed to the region?
if (ids.Contains(userIdToAdd))
return true;
int q = database.Query("UPDATE Regions SET UserIds=@0 WHERE RegionName=@1 AND WorldID=@2", MergedIDs,
if (string.IsNullOrEmpty(mergedIDs))
mergedIDs = userIdToAdd;
else
mergedIDs = string.Concat(mergedIDs, ",", userIdToAdd);
int q = database.Query("UPDATE Regions SET UserIds=@0 WHERE RegionName=@1 AND WorldID=@2", mergedIDs,
regionName, Main.worldID.ToString());
foreach (var r in Regions)
{
if (r.Name == regionName && r.WorldID == Main.worldID.ToString())
r.setAllowedIDs(MergedIDs);
r.setAllowedIDs(mergedIDs);
}
return q != 0;
}
@ -467,27 +473,33 @@ namespace TShockAPI.DB
return false;
}
public bool AllowGroup(string regionName, string groups)
public bool AllowGroup(string regionName, string groupName)
{
string groupsNew = "";
string mergedGroups = "";
using (
var reader = database.QueryReader("SELECT * FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName,
var reader = database.QueryReader("SELECT Groups FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName,
Main.worldID.ToString()))
{
if (reader.Read())
groupsNew = reader.Get<string>("Groups");
mergedGroups = reader.Get<string>("Groups");
}
if (groupsNew != "")
groupsNew += ",";
groupsNew += groups;
int q = database.Query("UPDATE Regions SET Groups=@0 WHERE RegionName=@1 AND WorldID=@2", groupsNew,
string[] groups = mergedGroups.Split(',');
// Is the group already allowed to the region?
if (groups.Contains(groupName))
return true;
if (mergedGroups != "")
mergedGroups += ",";
mergedGroups += groupName;
int q = database.Query("UPDATE Regions SET Groups=@0 WHERE RegionName=@1 AND WorldID=@2", mergedGroups,
regionName, Main.worldID.ToString());
Region r = GetRegionByName(regionName);
if (r != null)
{
r.SetAllowedGroups(groupsNew);
r.SetAllowedGroups(mergedGroups);
}
else
{

View file

@ -0,0 +1,253 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TShockAPI {
public static class PaginationTools {
public delegate Tuple<string, Color> LineFormatterDelegate(object lineData, int lineIndex, int pageNumber);
#region [Nested: Settings Class]
public class Settings {
public bool IncludeHeader { get; set; }
private string headerFormat;
public string HeaderFormat
{
get { return this.headerFormat; }
set
{
if (value == null)
throw new ArgumentNullException();
this.headerFormat = value;
}
}
public Color HeaderTextColor { get; set; }
public bool IncludeFooter { get; set; }
private string footerFormat;
public string FooterFormat
{
get { return this.footerFormat; }
set
{
if (value == null)
throw new ArgumentNullException();
this.footerFormat = value;
}
}
public Color FooterTextColor { get; set; }
public string NothingToDisplayString { get; set; }
public LineFormatterDelegate LineFormatter { get; set; }
public Color LineTextColor { get; set; }
private int maxLinesPerPage;
public int MaxLinesPerPage
{
get { return this.maxLinesPerPage; }
set
{
if (value <= 0)
throw new ArgumentException("The value has to be greater than zero.");
this.maxLinesPerPage = value;
}
}
private int pageLimit;
public int PageLimit
{
get { return this.pageLimit; }
set
{
if (value < 0)
throw new ArgumentException("The value has to be greater than or equal to zero.");
this.pageLimit = value;
}
}
public Settings()
{
this.IncludeHeader = true;
this.headerFormat = "Page {0} of {1}";
this.HeaderTextColor = Color.Green;
this.IncludeFooter = true;
this.footerFormat = "Type /<command> {0} for more.";
this.FooterTextColor = Color.Yellow;
this.NothingToDisplayString = null;
this.LineFormatter = null;
this.LineTextColor = Color.White;
this.maxLinesPerPage = 4;
this.pageLimit = 0;
}
}
#endregion
public static void SendPage(
TSPlayer player, int pageNumber, IEnumerable dataToPaginate, int dataToPaginateCount, Settings settings = null)
{
if (settings == null)
settings = new Settings();
if (dataToPaginateCount == 0)
{
if (settings.NothingToDisplayString != null)
player.SendMessage(settings.NothingToDisplayString, settings.HeaderTextColor);
return;
}
int pageCount = ((dataToPaginateCount - 1) / settings.MaxLinesPerPage) + 1;
if (settings.PageLimit > 0 && pageCount > settings.PageLimit)
pageCount = settings.PageLimit;
if (pageNumber > pageCount)
pageNumber = pageCount;
if (settings.IncludeHeader)
player.SendMessage(string.Format(settings.HeaderFormat, pageNumber, pageCount), settings.HeaderTextColor);
int listOffset = (pageNumber - 1) * settings.MaxLinesPerPage;
int offsetCounter = 0;
int lineCounter = 0;
foreach (object lineData in dataToPaginate)
{
if (lineData == null)
continue;
if (offsetCounter++ < listOffset)
continue;
if (lineCounter++ == settings.MaxLinesPerPage)
break;
string lineMessage;
Color lineColor = settings.LineTextColor;
if (lineData is Tuple<string, Color>)
{
var lineFormat = (Tuple<string, Color>)lineData;
lineMessage = lineFormat.Item1;
lineColor = lineFormat.Item2;
}
else if (settings.LineFormatter != null)
{
try
{
Tuple<string, Color> lineFormat = settings.LineFormatter(lineData, offsetCounter, pageNumber);
if (lineFormat == null)
continue;
lineMessage = lineFormat.Item1;
lineColor = lineFormat.Item2;
}
catch (Exception ex)
{
throw new InvalidOperationException(
"The method referenced by LineFormatter has thrown an exception. See inner exception for details.", ex);
}
}
else
{
lineMessage = lineData.ToString();
}
if (lineMessage != null)
player.SendMessage(lineMessage, lineColor);
}
if (lineCounter == 0)
{
if (settings.NothingToDisplayString != null)
player.SendMessage(settings.NothingToDisplayString, settings.HeaderTextColor);
}
else if (settings.IncludeFooter && pageNumber + 1 <= pageCount)
{
player.SendMessage(string.Format(settings.FooterFormat, pageNumber + 1, pageNumber, pageCount), settings.FooterTextColor);
}
}
public static void SendPage(TSPlayer player, int pageNumber, IList dataToPaginate, Settings settings = null)
{
PaginationTools.SendPage(player, pageNumber, dataToPaginate, dataToPaginate.Count, settings);
}
public static List<string> BuildLinesFromTerms(
IEnumerable terms, Func<object, string> termFormatter = null, string separator = ", ", int maxCharsPerLine = 80)
{
List<string> lines = new List<string>();
StringBuilder lineBuilder = new StringBuilder();
foreach (object term in terms)
{
if (term == null && termFormatter == null)
continue;
string termString;
if (termFormatter != null)
{
try {
termString = termFormatter(term);
if (termString == null)
continue;
} catch (Exception ex)
{
throw new ArgumentException(
"The method represented by termFormatter has thrown an exception. See inner exception for details.", ex);
}
}
else
{
termString = term.ToString();
}
bool goesOnNextLine = (lineBuilder.Length + termString.Length > maxCharsPerLine);
if (!goesOnNextLine)
{
if (lineBuilder.Length > 0) {
lineBuilder.Append(separator);
}
lineBuilder.Append(termString);
}
else
{
// A separator should always be at the end of a line as we know it is followed by another line.
lineBuilder.Append(separator);
lines.Add(lineBuilder.ToString());
lineBuilder.Clear();
lineBuilder.Append(termString);
}
}
if (lineBuilder.Length > 0)
lines.Add(lineBuilder.ToString());
return lines;
}
public static bool TryParsePageNumber(
List<string> commandParameters, int expectedParamterIndex, TSPlayer errorMessageReceiver, out int pageNumber)
{
pageNumber = 1;
if (commandParameters.Count <= expectedParamterIndex)
return true;
string pageNumberRaw = commandParameters[expectedParamterIndex];
if (!int.TryParse(pageNumberRaw, out pageNumber) || pageNumber < 1)
{
if (errorMessageReceiver != null)
errorMessageReceiver.SendErrorMessage(string.Format("\"{0}\" is not a valid page number.", pageNumberRaw));
pageNumber = 1;
return false;
}
return true;
}
}
}

View file

@ -604,21 +604,41 @@ namespace TShockAPI
SendMessage(msg, Color.Yellow);
}
public void SendInfoMessage(string format, params object[] args)
{
SendInfoMessage(string.Format(format, args));
}
public virtual void SendSuccessMessage(string msg)
{
SendMessage(msg, Color.Green);
}
public void SendSuccessMessage(string format, params object[] args)
{
SendSuccessMessage(string.Format(format, args));
}
public virtual void SendWarningMessage(string msg)
{
SendMessage(msg, Color.OrangeRed);
}
public void SendWarningMessage(string format, params object[] args)
{
SendWarningMessage(string.Format(format, args));
}
public virtual void SendErrorMessage(string msg)
{
SendMessage(msg, Color.Red);
}
public void SendErrorMessage(string format, params object[] args)
{
SendErrorMessage(string.Format(format, args));
}
[Obsolete("Use SendErrorMessage, SendInfoMessage, or SendWarningMessage, or a custom color instead.")]
public virtual void SendMessage(string msg)
{

View file

@ -85,6 +85,7 @@
<Compile Include="DB\RegionManager.cs" />
<Compile Include="Hooks\GeneralHooks.cs" />
<Compile Include="Hooks\PlayerHooks.cs" />
<Compile Include="PaginationTools.cs" />
<Compile Include="PluginUpdater\PluginUpdaterThread.cs" />
<Compile Include="PluginUpdater\PluginVersionCheck.cs" />
<Compile Include="PluginUpdater\VersionInfo.cs" />
@ -190,7 +191,7 @@
</PropertyGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildAction="Both" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_StartDate="2011/6/17" BuildVersion_IncrementBeforeBuild="False" />
<UserProperties BuildVersion_IncrementBeforeBuild="False" BuildVersion_StartDate="2011/6/17" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_BuildAction="Both" BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.