Add tile banning, because such whine, much desire (doge).
I am sure this will result in someone whining for wall banning as well, but that can wait another couple of months.
This commit is contained in:
parent
eb8ffe5cfb
commit
7a8422de5c
6 changed files with 449 additions and 3 deletions
|
|
@ -240,6 +240,10 @@ namespace TShockAPI
|
|||
{
|
||||
HelpText = "Manages projectile bans."
|
||||
});
|
||||
add(new Command(Permissions.managetile, TileBan, "tileban")
|
||||
{
|
||||
HelpText = "Manages tile bans."
|
||||
});
|
||||
add(new Command(Permissions.manageregion, Region, "region")
|
||||
{
|
||||
HelpText = "Manages regions."
|
||||
|
|
@ -3090,9 +3094,178 @@ namespace TShockAPI
|
|||
}
|
||||
#endregion Projectile Management
|
||||
|
||||
#region Server Config Commands
|
||||
#region Tile Management
|
||||
private static void TileBan(CommandArgs args)
|
||||
{
|
||||
string subCmd = args.Parameters.Count == 0 ? "help" : args.Parameters[0].ToLower();
|
||||
switch (subCmd)
|
||||
{
|
||||
case "add":
|
||||
#region Add tile
|
||||
{
|
||||
if (args.Parameters.Count != 2)
|
||||
{
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /tileban add <tile id>");
|
||||
return;
|
||||
}
|
||||
short id;
|
||||
if (Int16.TryParse(args.Parameters[1], out id) && id >= 0 && id < Main.maxTileSets)
|
||||
{
|
||||
TShock.TileBans.AddNewBan(id);
|
||||
args.Player.SendSuccessMessage("Banned tile {0}.", id);
|
||||
}
|
||||
else
|
||||
args.Player.SendErrorMessage("Invalid tile ID!");
|
||||
}
|
||||
#endregion
|
||||
return;
|
||||
case "allow":
|
||||
#region Allow group to place tile
|
||||
{
|
||||
if (args.Parameters.Count != 3)
|
||||
{
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /tileban allow <id> <group>");
|
||||
return;
|
||||
}
|
||||
|
||||
private static void SetSpawn(CommandArgs args)
|
||||
short id;
|
||||
if (Int16.TryParse(args.Parameters[1], out id) && id >= 0 && id < Main.maxTileSets)
|
||||
{
|
||||
if (!TShock.Groups.GroupExists(args.Parameters[2]))
|
||||
{
|
||||
args.Player.SendErrorMessage("Invalid group.");
|
||||
return;
|
||||
}
|
||||
|
||||
TileBan ban = TShock.TileBans.GetBanById(id);
|
||||
if (ban == null)
|
||||
{
|
||||
args.Player.SendErrorMessage("Tile {0} is not banned.", id);
|
||||
return;
|
||||
}
|
||||
if (!ban.AllowedGroups.Contains(args.Parameters[2]))
|
||||
{
|
||||
TShock.TileBans.AllowGroup(id, args.Parameters[2]);
|
||||
args.Player.SendSuccessMessage("{0} has been allowed to place tile {1}.", args.Parameters[2], id);
|
||||
}
|
||||
else
|
||||
args.Player.SendWarningMessage("{0} is already allowed to place tile {1}.", args.Parameters[2], id);
|
||||
}
|
||||
else
|
||||
args.Player.SendErrorMessage("Invalid tile ID!");
|
||||
}
|
||||
#endregion
|
||||
return;
|
||||
case "del":
|
||||
#region Delete tile ban
|
||||
{
|
||||
if (args.Parameters.Count != 2)
|
||||
{
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /tileban del <id>");
|
||||
return;
|
||||
}
|
||||
|
||||
short id;
|
||||
if (Int16.TryParse(args.Parameters[1], out id) && id >= 0 && id < Main.maxTileSets)
|
||||
{
|
||||
TShock.TileBans.RemoveBan(id);
|
||||
args.Player.SendSuccessMessage("Unbanned tile {0}.", id);
|
||||
return;
|
||||
}
|
||||
else
|
||||
args.Player.SendErrorMessage("Invalid tile ID!");
|
||||
}
|
||||
#endregion
|
||||
return;
|
||||
case "disallow":
|
||||
#region Disallow group from placing tile
|
||||
{
|
||||
if (args.Parameters.Count != 3)
|
||||
{
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /tileban disallow <id> <group name>");
|
||||
return;
|
||||
}
|
||||
|
||||
short id;
|
||||
if (Int16.TryParse(args.Parameters[1], out id) && id >= 0 && id < Main.maxTileSets)
|
||||
{
|
||||
if (!TShock.Groups.GroupExists(args.Parameters[2]))
|
||||
{
|
||||
args.Player.SendErrorMessage("Invalid group.");
|
||||
return;
|
||||
}
|
||||
|
||||
TileBan ban = TShock.TileBans.GetBanById(id);
|
||||
if (ban == null)
|
||||
{
|
||||
args.Player.SendErrorMessage("Tile {0} is not banned.", id);
|
||||
return;
|
||||
}
|
||||
if (ban.AllowedGroups.Contains(args.Parameters[2]))
|
||||
{
|
||||
TShock.TileBans.RemoveGroup(id, args.Parameters[2]);
|
||||
args.Player.SendSuccessMessage("{0} has been disallowed from placing tile {1}.", args.Parameters[2], id);
|
||||
return;
|
||||
}
|
||||
else
|
||||
args.Player.SendWarningMessage("{0} is already prevented from placing tile {1}.", args.Parameters[2], id);
|
||||
}
|
||||
else
|
||||
args.Player.SendErrorMessage("Invalid tile ID!");
|
||||
}
|
||||
#endregion
|
||||
return;
|
||||
case "help":
|
||||
#region Help
|
||||
{
|
||||
int pageNumber;
|
||||
if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber))
|
||||
return;
|
||||
|
||||
var lines = new List<string>
|
||||
{
|
||||
"add <tile ID> - Adds a tile ban.",
|
||||
"allow <tile ID> <group> - Allows a group to place a tile.",
|
||||
"del <tile ID> - Deletes a tile ban.",
|
||||
"disallow <tile ID> <group> - Disallows a group from place a tile.",
|
||||
"list [page] - Lists all tile bans."
|
||||
};
|
||||
|
||||
PaginationTools.SendPage(args.Player, pageNumber, lines,
|
||||
new PaginationTools.Settings
|
||||
{
|
||||
HeaderFormat = "Tile Ban Sub-Commands ({0}/{1}):",
|
||||
FooterFormat = "Type /tileban help {0} for more sub-commands."
|
||||
}
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
return;
|
||||
case "list":
|
||||
#region List tile bans
|
||||
{
|
||||
int pageNumber;
|
||||
if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber))
|
||||
return;
|
||||
IEnumerable<Int16> tileIds = from tileBan in TShock.TileBans.TileBans
|
||||
select tileBan.ID;
|
||||
PaginationTools.SendPage(args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(tileIds),
|
||||
new PaginationTools.Settings
|
||||
{
|
||||
HeaderFormat = "Tile bans ({0}/{1}):",
|
||||
FooterFormat = "Type /tileban list {0} for more.",
|
||||
NothingToDisplayString = "There are currently no banned tiles."
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endregion Tile Management
|
||||
|
||||
#region Server Config Commands
|
||||
|
||||
private static void SetSpawn(CommandArgs args)
|
||||
{
|
||||
Main.spawnTileX = args.Player.TileX + 1;
|
||||
Main.spawnTileY = args.Player.TileY + 3;
|
||||
|
|
|
|||
253
TShockAPI/DB/TileManager.cs
Normal file
253
TShockAPI/DB/TileManager.cs
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2014 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public class TileManager
|
||||
{
|
||||
private IDbConnection database;
|
||||
public List<TileBan> TileBans = new List<TileBan>();
|
||||
|
||||
public TileManager(IDbConnection db)
|
||||
{
|
||||
database = db;
|
||||
|
||||
var table = new SqlTable("TileBans",
|
||||
new SqlColumn("TileId", MySqlDbType.Int32) { Primary = true },
|
||||
new SqlColumn("AllowedGroups", MySqlDbType.Text)
|
||||
);
|
||||
var creator = new SqlTableCreator(db,
|
||||
db.GetSqlType() == SqlType.Sqlite
|
||||
? (IQueryBuilder)new SqliteQueryCreator()
|
||||
: new MysqlQueryCreator());
|
||||
creator.EnsureExists(table);
|
||||
UpdateBans();
|
||||
}
|
||||
|
||||
public void UpdateBans()
|
||||
{
|
||||
TileBans.Clear();
|
||||
|
||||
using (var reader = database.QueryReader("SELECT * FROM TileBans"))
|
||||
{
|
||||
while (reader != null && reader.Read())
|
||||
{
|
||||
TileBan ban = new TileBan((short)reader.Get<Int32>("TileId"));
|
||||
ban.SetAllowedGroups(reader.Get<string>("AllowedGroups"));
|
||||
TileBans.Add(ban);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddNewBan(short id = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
database.Query("INSERT INTO TileBans (TileId, AllowedGroups) VALUES (@0, @1);",
|
||||
id, "");
|
||||
|
||||
if (!TileIsBanned(id, null))
|
||||
TileBans.Add(new TileBan(id));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveBan(short id)
|
||||
{
|
||||
if (!TileIsBanned(id, null))
|
||||
return;
|
||||
try
|
||||
{
|
||||
database.Query("DELETE FROM TileBans WHERE TileId=@0;", id);
|
||||
TileBans.Remove(new TileBan(id));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public bool TileIsBanned(short id)
|
||||
{
|
||||
if (TileBans.Contains(new TileBan(id)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TileIsBanned(short id, TSPlayer ply)
|
||||
{
|
||||
if (TileBans.Contains(new TileBan(id)))
|
||||
{
|
||||
TileBan b = GetBanById(id);
|
||||
return !b.HasPermissionToPlaceTile(ply);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AllowGroup(short id, string name)
|
||||
{
|
||||
string groupsNew = "";
|
||||
TileBan b = GetBanById(id);
|
||||
if (b != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
groupsNew = String.Join(",", b.AllowedGroups);
|
||||
if (groupsNew.Length > 0)
|
||||
groupsNew += ",";
|
||||
groupsNew += name;
|
||||
b.SetAllowedGroups(groupsNew);
|
||||
|
||||
int q = database.Query("UPDATE TileBans SET AllowedGroups=@0 WHERE TileId=@1", groupsNew,
|
||||
id);
|
||||
|
||||
return q > 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool RemoveGroup(short id, string group)
|
||||
{
|
||||
TileBan b = GetBanById(id);
|
||||
if (b != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
b.RemoveGroup(group);
|
||||
string groups = string.Join(",", b.AllowedGroups);
|
||||
int q = database.Query("UPDATE TileBans SET AllowedGroups=@0 WHERE TileId=@1", groups,
|
||||
id);
|
||||
|
||||
if (q > 0)
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public TileBan GetBanById(short id)
|
||||
{
|
||||
foreach (TileBan b in TileBans)
|
||||
{
|
||||
if (b.ID == id)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class TileBan : IEquatable<TileBan>
|
||||
{
|
||||
public short ID { get; set; }
|
||||
public List<string> AllowedGroups { get; set; }
|
||||
|
||||
public TileBan(short id)
|
||||
: this()
|
||||
{
|
||||
ID = id;
|
||||
AllowedGroups = new List<string>();
|
||||
}
|
||||
|
||||
public TileBan()
|
||||
{
|
||||
ID = 0;
|
||||
AllowedGroups = new List<string>();
|
||||
}
|
||||
|
||||
public bool Equals(TileBan other)
|
||||
{
|
||||
return ID == other.ID;
|
||||
}
|
||||
|
||||
public bool HasPermissionToPlaceTile(TSPlayer ply)
|
||||
{
|
||||
if (ply == null)
|
||||
return false;
|
||||
|
||||
if (ply.Group.HasPermission(Permissions.canusebannedtiles))
|
||||
return true;
|
||||
|
||||
var cur = ply.Group;
|
||||
var traversed = new List<Group>();
|
||||
while (cur != null)
|
||||
{
|
||||
if (AllowedGroups.Contains(cur.Name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (traversed.Contains(cur))
|
||||
{
|
||||
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name));
|
||||
}
|
||||
traversed.Add(cur);
|
||||
cur = cur.Parent;
|
||||
}
|
||||
return false;
|
||||
// could add in the other permissions in this class instead of a giant if switch.
|
||||
}
|
||||
|
||||
public void SetAllowedGroups(String groups)
|
||||
{
|
||||
// prevent null pointer exceptions
|
||||
if (!string.IsNullOrEmpty(groups))
|
||||
{
|
||||
List<String> groupArr = groups.Split(',').ToList();
|
||||
|
||||
for (int i = 0; i < groupArr.Count; i++)
|
||||
{
|
||||
groupArr[i] = groupArr[i].Trim();
|
||||
//Console.WriteLine(groupArr[i]);
|
||||
}
|
||||
AllowedGroups = groupArr;
|
||||
}
|
||||
}
|
||||
|
||||
public bool RemoveGroup(string groupName)
|
||||
{
|
||||
return AllowedGroups.Remove(groupName);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ID + (AllowedGroups.Count > 0 ? " (" + String.Join(",", AllowedGroups) + ")" : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1910,6 +1910,17 @@ namespace TShockAPI
|
|||
Item selectedItem = args.Player.SelectedItem;
|
||||
int lastKilledProj = args.Player.LastKilledProjectile;
|
||||
Tile tile = Main.tile[tileX, tileY];
|
||||
|
||||
if (action == EditAction.PlaceTile)
|
||||
{
|
||||
if (TShock.TileBans.TileIsBanned(editData, args.Player))
|
||||
{
|
||||
args.Player.SendTileSquare(tileX, tileY, 1);
|
||||
args.Player.SendErrorMessage("You do not have permission to place this tile.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (action == EditAction.KillTile && !Main.tileCut[tile.type] && !breakableTiles.Contains(tile.type))
|
||||
{
|
||||
// If the tile is an axe tile and they aren't selecting an axe, they're hacking.
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ namespace TShockAPI
|
|||
[Description("User can manage projectile bans.")]
|
||||
public static readonly string manageprojectile = "tshock.admin.projectileban";
|
||||
|
||||
[Description("User can manage tile bans.")]
|
||||
public static readonly string managetile = "tshock.admin.tileban";
|
||||
|
||||
[Description("User can manage groups.")]
|
||||
public static readonly string managegroup = "tshock.admin.group";
|
||||
|
||||
|
|
@ -343,6 +346,9 @@ namespace TShockAPI
|
|||
[Description("Player can use banned projectiles.")]
|
||||
public static readonly string canusebannedprojectiles = "tshock.projectiles.usebanned";
|
||||
|
||||
[Description("Player can place banned tiles.")]
|
||||
public static readonly string canusebannedtiles = "tshock.tiles.usebanned";
|
||||
|
||||
/// <summary>
|
||||
/// Lists all commands associated with a given permission
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ namespace TShockAPI
|
|||
public static UserManager Users;
|
||||
public static ItemManager Itembans;
|
||||
public static ProjectileManagager ProjectileBans;
|
||||
public static TileManager TileBans;
|
||||
public static RememberedPosManager RememberedPos;
|
||||
public static CharacterManager CharacterDB;
|
||||
public static ConfigFile Config { get; set; }
|
||||
|
|
@ -231,6 +232,7 @@ namespace TShockAPI
|
|||
Groups = new GroupManager(DB);
|
||||
Itembans = new ItemManager(DB);
|
||||
ProjectileBans = new ProjectileManagager(DB);
|
||||
TileBans = new TileManager(DB);
|
||||
RememberedPos = new RememberedPosManager(DB);
|
||||
CharacterDB = new CharacterManager(DB);
|
||||
RestApi = new SecureRest(Netplay.serverListenIP, Config.RestApiPort);
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@
|
|||
<Compile Include="BackupManager.cs" />
|
||||
<Compile Include="DB\ProjectileManager.cs" />
|
||||
<Compile Include="DB\RegionManager.cs" />
|
||||
<Compile Include="DB\TileManager.cs" />
|
||||
<Compile Include="Hooks\GeneralHooks.cs" />
|
||||
<Compile Include="Hooks\PlayerHooks.cs" />
|
||||
<Compile Include="PaginationTools.cs" />
|
||||
|
|
@ -180,7 +181,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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue