-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from THEXN/master
add 添加插件 PersonalPermission 玩家单独权限
- Loading branch information
Showing
6 changed files
with
359 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Data; | ||
using System.Linq; | ||
using TShockAPI; | ||
using TShockAPI.DB; | ||
|
||
namespace PersonalPermission | ||
{ | ||
class DB | ||
{ | ||
public static void TryCreateTable() | ||
{ | ||
try | ||
{ | ||
SqlTable sqlTable = new SqlTable("PersonalPermission", new SqlColumn[] | ||
{ | ||
new SqlColumn("UserID", MySql.Data.MySqlClient.MySqlDbType.Int32){ Primary = true }, | ||
new SqlColumn("Permissions", MySql.Data.MySqlClient.MySqlDbType.Text) | ||
}); | ||
IDbConnection db = TShock.DB; | ||
IQueryBuilder queryBuilder2; | ||
if (DbExt.GetSqlType(TShock.DB) != SqlType.Sqlite) | ||
{ | ||
IQueryBuilder queryBuilder = new MysqlQueryCreator(); | ||
queryBuilder2 = queryBuilder; | ||
} | ||
else | ||
{ | ||
IQueryBuilder queryBuilder = new SqliteQueryCreator(); | ||
queryBuilder2 = queryBuilder; | ||
} | ||
new SqlTableCreator(db, queryBuilder2).EnsureTableStructure(sqlTable); | ||
} | ||
catch (Exception ex) { TShock.Log.Error(ex.Message); } | ||
} | ||
public static bool AddUser(int id) | ||
{ | ||
try { return DbExt.Query(TShock.DB, $"INSERT INTO PersonalPermission (UserID) VALUES ({id});") != -1; } | ||
catch (Exception ex) { TShock.Log.ConsoleError($"添加玩家信息失败.\n" + ex); return false; } | ||
} | ||
public static List<string> GetPermissions(int id) | ||
{ | ||
using (var reader = DbExt.QueryReader(TShock.DB, $"SELECT * FROM PersonalPermission WHERE UserID='{id}';")) | ||
{ | ||
var list = new List<string>(); | ||
if (reader.Read()) | ||
{ | ||
try { | ||
var text = reader.Get<string>("Permissions") ?? ""; | ||
if (text.Contains(",")) | ||
{ | ||
text.Split(',').ForEach(p => { if (!list.Contains(p)) list.Add(p); }); | ||
} | ||
else if (!string.IsNullOrWhiteSpace(text)) list.Add(text); | ||
} | ||
catch (Exception ex) { TShock.Log.ConsoleError($"[PersonalPermission] 读取数据库时发生错误.\n{ex}"); } | ||
} | ||
else AddUser(id); | ||
return list; | ||
} | ||
} | ||
public static Dictionary<int, List<string>> GetAllPermissions() | ||
{ | ||
using (var reader = DbExt.QueryReader(TShock.DB, $"SELECT * FROM PersonalPermission;")) | ||
{ | ||
var list = new Dictionary<int, List<string>>(); | ||
while (reader.Read()) | ||
{ | ||
try | ||
{ | ||
var permissions = new List<string>(); | ||
var text = reader.Get<string>("Permissions") ?? ""; | ||
if (text.Contains(",")) | ||
{ | ||
text.Split(',').ForEach(p => { if (!permissions.Contains(p)) permissions.Add(p); }); | ||
} | ||
else if (!string.IsNullOrWhiteSpace(text)) permissions.Add(text); | ||
list.Add(reader.Get<int>("UserID"), permissions); | ||
} | ||
catch (Exception ex) { TShock.Log.ConsoleError($"[PersonalPermission] 读取数据库时发生错误.\n{ex}"); } | ||
} | ||
return list; | ||
} | ||
} | ||
public static bool SetPermissions(int id, List<string> list) | ||
{ | ||
if (DbExt.Query(TShock.DB, $"UPDATE PersonalPermission SET Permissions=@0 WHERE UserID={id};", new object[] { string.Join(",", list) }) != -1) | ||
{ | ||
return true; | ||
} | ||
TShock.Log.ConsoleError("保存玩家权限失败."); | ||
return false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Terraria; | ||
using TerrariaApi.Server; | ||
using TShockAPI; | ||
using TShockAPI.DB; | ||
using TShockAPI.Hooks; | ||
|
||
namespace PersonalPermission | ||
{ | ||
[ApiVersion(2, 1)] | ||
public class PPMain : TerrariaPlugin | ||
{ | ||
public override string Name => "PersonalPermission"; | ||
public override Version Version => new Version(1, 1, 0, 0); | ||
public override string Author => "Megghy,肝帝熙恩更新1449"; | ||
public override string Description => "允许为玩家单独设置权限."; | ||
public PPMain(Main game) : base(game) | ||
{ | ||
} | ||
public override void Initialize() | ||
{ | ||
DB.TryCreateTable(); | ||
ServerApi.Hooks.GamePostInitialize.Register(this, OnPostInitialize); | ||
} | ||
public void OnPostInitialize(EventArgs args) | ||
{ | ||
ServerApi.Hooks.ServerJoin.Register(this, OnJoin, int.MinValue); | ||
PlayerHooks.PlayerPermission += OnPermissionCheck; | ||
GeneralHooks.ReloadEvent += OnReload; | ||
Commands.ChatCommands.Add(new Command("personalpermission.admin", PPCommand, "pp")); | ||
} | ||
void OnJoin(JoinEventArgs args) | ||
{ | ||
var plr = TShock.Players[args.Who]; | ||
var account = TShock.UserAccounts.GetUserAccountByName(plr.Name); | ||
plr.SetData("PersonalPermission", GetPPGroup(account == null ? new List<string>() : DB.GetPermissions(account.ID))); | ||
} | ||
void OnReload(ReloadEventArgs args) | ||
{ | ||
TShock.Players.Where(p => p != null && p.Account != null).ForEach(p => p.SetData("PersonalPermission", GetPPGroup(DB.GetPermissions(p.Account.ID)))); | ||
TShock.Log.ConsoleInfo("已重载玩家个人权限."); | ||
} | ||
Group GetPPGroup(List<string> list) | ||
{ | ||
var group = new Group("PersonalPermission"); | ||
list?.ForEach(p => group.AddPermission(p)); | ||
return group; | ||
} | ||
public void OnPermissionCheck(PlayerPermissionEventArgs args) | ||
{ | ||
try | ||
{ | ||
var plr = args.Player; | ||
if (!plr.RealPlayer || plr.Group.TotalPermissions.Contains("*") || plr.Group.Name == "superadmin") | ||
{ | ||
args.Result = PermissionHookResult.Granted; | ||
return; | ||
} | ||
var group = args.Player.GetData<Group>("PersonalPermission"); | ||
group.Parent = args.Player.Group; | ||
args.Result = args.Player.GetData<Group>("PersonalPermission").HasPermission(args.Permission) | ||
? PermissionHookResult.Granted | ||
: PermissionHookResult.Denied; | ||
} | ||
catch (Exception ex) { TShock.Log.ConsoleError(ex.Message); args.Result = PermissionHookResult.Denied; } | ||
} | ||
public void PPCommand(CommandArgs args) | ||
{ | ||
var plr = args.Player; | ||
var cmd = args.Parameters; | ||
try | ||
{ | ||
|
||
if (cmd.Count >= 1) | ||
{ | ||
switch (cmd[0].ToLower()) | ||
{ | ||
case "add": | ||
if (cmd.Count >= 3) | ||
{ | ||
var acclist = TShock.UserAccounts.GetUserAccountsByName(cmd[1]); | ||
if (acclist.Count > 1) | ||
{ | ||
plr.SendMultipleMatchError(acclist); | ||
} | ||
else if (acclist.Count == 0) | ||
{ | ||
plr.SendErrorMessage($"未找到名称中包含 {cmd[1]} 的玩家."); | ||
} | ||
else | ||
{ | ||
Add(acclist.First(), cmd[2]); | ||
} | ||
} | ||
else | ||
{ | ||
plr.SendInfoMessage($"无效的命令. /pp add [C/66E5B5:玩家名] [C/66E5B5:权限]"); | ||
} | ||
break; | ||
case "del": | ||
if (cmd.Count >= 3) | ||
{ | ||
var acclist = TShock.UserAccounts.GetUserAccountsByName(cmd[1]); | ||
if (acclist.Count > 1) | ||
{ | ||
plr.SendMultipleMatchError(acclist); | ||
} | ||
else if (acclist.Count == 0) | ||
{ | ||
plr.SendErrorMessage($"未找到名称中包含 {cmd[1]} 的玩家."); | ||
} | ||
else | ||
{ | ||
Del(acclist.First(), cmd[2]); | ||
} | ||
} | ||
else | ||
{ | ||
plr.SendInfoMessage($"无效的命令. /pp del [C/66E5B5:玩家名] [C/66E5B5:权限]"); | ||
} | ||
break; | ||
case "list": | ||
if (cmd.Count >= 2) | ||
{ | ||
var acclist = TShock.UserAccounts.GetUserAccountsByName(cmd[1]); | ||
if (acclist.Count > 1) | ||
{ | ||
plr.SendMultipleMatchError(acclist); | ||
} | ||
else if (acclist.Count == 0) | ||
{ | ||
plr.SendErrorMessage($"未找到名称中包含 {cmd[1]} 的玩家."); | ||
} | ||
else | ||
{ | ||
var data = DB.GetPermissions(acclist[0].ID); | ||
plr.SendInfoMessage($"玩家 {acclist[0].Name} 的所有权限: ({data.Count} 条)\n{string.Join(", ", data)}"); | ||
} | ||
} | ||
else | ||
{ | ||
plr.SendInfoMessage($"无效的命令. /pp list [C/66E5B5:玩家名]"); | ||
} | ||
break; | ||
case "search": | ||
if (cmd.Count >= 2) | ||
{ | ||
var list = new List<string>(); | ||
DB.GetAllPermissions().Where(data => data.Value.Contains(cmd[1])).ForEach(data => list.Add((TShock.UserAccounts.GetUserAccountByID(data.Key) ?? new UserAccount()).Name)); | ||
plr.SendInfoMessage($"拥有权限 {cmd[1]} 的所有玩家: ({list.Count} 位)\n{string.Join(", ", list)}"); | ||
} | ||
else | ||
{ | ||
plr.SendInfoMessage($"无效的命令. /pp search [C/66E5B5:权限名]"); | ||
} | ||
break; | ||
default: | ||
Help(); | ||
break; | ||
} | ||
} | ||
else | ||
{ | ||
Help(); | ||
} | ||
} | ||
catch (Exception ex) { TShock.Log.ConsoleError(ex.Message); } | ||
void Help() | ||
{ | ||
plr.SendInfoMessage($"可用命令:\n" + | ||
$"/pp add [C/66E5B5:玩家名] [C/66E5B5:权限]\n" + | ||
$"/pp del [C/66E5B5:玩家名] [C/66E5B5:权限]\n" + | ||
$"/pp list [C/66E5B5:玩家名]\n" + | ||
$"/pp search [C/66E5B5:权限名]\n"); | ||
} | ||
void Add(UserAccount account, string perm) | ||
{ | ||
var data = DB.GetPermissions(account.ID); | ||
if (data != null && !data.Contains(perm)) | ||
{ | ||
data.Add(perm); | ||
if (DB.SetPermissions(account.ID, data)) | ||
{ | ||
TShock.Players.FirstOrDefault(p => p?.Name == account.Name).GetData<Group>("PersonalPermission")?.AddPermission(perm); | ||
plr.SendSuccessMessage($"已为玩家 {account.Name} 添加权限 {perm}."); | ||
} | ||
else plr.SendErrorMessage($"添加权限失败."); | ||
} | ||
else plr.SendErrorMessage($"玩家 {account.Name} 已存在权限 {perm}."); | ||
} | ||
void Del(UserAccount account, string perm) | ||
{ | ||
var data = DB.GetPermissions(account.ID); | ||
if (data != null && data.Contains(perm)) | ||
{ | ||
data.Remove(perm); | ||
if (DB.SetPermissions(account.ID, data)) | ||
{ | ||
TShock.Players.FirstOrDefault(p => p?.Name == account.Name).GetData<Group>("PersonalPermission")?.RemovePermission(perm); | ||
plr.SendSuccessMessage($"已为玩家 {account.Name} 移除权限 {perm}."); | ||
} | ||
else | ||
plr.SendErrorMessage($"移除权限失败."); | ||
} | ||
else | ||
plr.SendErrorMessage($"玩家 {account.Name} 未存在权限 {perm}."); | ||
} | ||
} | ||
protected override void Dispose(bool disposing) | ||
{ | ||
ServerApi.Hooks.ServerJoin.Deregister(this, OnJoin); | ||
PlayerHooks.PlayerPermission -= OnPermissionCheck; | ||
GeneralHooks.ReloadEvent -= OnReload; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<Import Project="..\template.targets" /> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# PersonalPermission 玩家单独权限 | ||
|
||
- 作者: Megghy,肝帝熙恩更新1449 | ||
- 出处: [github](https://github.com/Megghy/PersonalPermission) | ||
- 以给玩家给予一个单独的权限而不是添加给所在用户组. | ||
- 对于开发者:可使用 <玩家对象(TSPlayer)>.GetData<Group>("PersonalPermission"); 来获取一个包含独立权限的用户组对象, 同时直接调用 .HasPermission 也会自动判断权限. | ||
|
||
|
||
## 更新日志 | ||
|
||
``` | ||
暂无 | ||
``` | ||
|
||
## 指令 | ||
|
||
| 语法 | 权限 | 说明 | | ||
| -------------- | :-----------------: | :------: | | ||
| /pp | personalpermission.admin | 为玩家添/删加权限等指令| | ||
|
||
## 配置 | ||
|
||
``` | ||
暂无 | ||
``` | ||
## 反馈 | ||
- 共同维护的插件库:https://github.com/THEXN/TShockPlugin/ | ||
- 国内社区trhub.cn 或 TShock官方群等 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters