Skip to content

Commit

Permalink
Merge pull request #40 from THEXN/master
Browse files Browse the repository at this point in the history
add 添加插件 PersonalPermission 玩家单独权限
  • Loading branch information
Controllerdestiny authored Apr 21, 2024
2 parents 8a3cbad + ccad916 commit 1b2d3f0
Show file tree
Hide file tree
Showing 6 changed files with 359 additions and 1 deletion.
96 changes: 96 additions & 0 deletions PersonalPermission/DB.cs
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;
}
}
}
218 changes: 218 additions & 0 deletions PersonalPermission/PPMain.cs
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;
}
}
}
5 changes: 5 additions & 0 deletions PersonalPermission/PersonalPermission.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\template.targets" />

</Project>
28 changes: 28 additions & 0 deletions PersonalPermission/README.md
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官方群等
10 changes: 10 additions & 0 deletions Plugin.sln
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShowArmors", "ShowArmors\Sh
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VeinMiner", "VeinMiner\VeinMiner.csproj", "{BC20D582-EBEF-4FC4-832C-49EC814CF9A9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PersonalPermission", "PersonalPermission\PersonalPermission.csproj", "{673A34A5-8C67-4909-885F-BD47AF0F58A4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -486,6 +488,14 @@ Global
{BC20D582-EBEF-4FC4-832C-49EC814CF9A9}.Release|Any CPU.Build.0 = Release|Any CPU
{BC20D582-EBEF-4FC4-832C-49EC814CF9A9}.Release|x64.ActiveCfg = Release|Any CPU
{BC20D582-EBEF-4FC4-832C-49EC814CF9A9}.Release|x64.Build.0 = Release|Any CPU
{673A34A5-8C67-4909-885F-BD47AF0F58A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{673A34A5-8C67-4909-885F-BD47AF0F58A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{673A34A5-8C67-4909-885F-BD47AF0F58A4}.Debug|x64.ActiveCfg = Debug|Any CPU
{673A34A5-8C67-4909-885F-BD47AF0F58A4}.Debug|x64.Build.0 = Debug|Any CPU
{673A34A5-8C67-4909-885F-BD47AF0F58A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{673A34A5-8C67-4909-885F-BD47AF0F58A4}.Release|Any CPU.Build.0 = Release|Any CPU
{673A34A5-8C67-4909-885F-BD47AF0F58A4}.Release|x64.ActiveCfg = Release|Any CPU
{673A34A5-8C67-4909-885F-BD47AF0F58A4}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
| [DataSync](DataSync/README.md) | 进度同步 ||
| [ProgressRestrict](ProgressRestrict/README.md) | 超进度检测 | DataSync |
| [PacketsStop](PacketsStop/README.md) | 数据包拦截 ||
| [DeathDrop](DeathDrop/README.md) | 怪物死亡随机和自定义掉落物品 ||
| [DeathDrop](DeathDrop/README.md) | 怪物死亡随机和自定义掉落物品 ||
| [DTEntryBlock](DTEntryBlock/README.md) | 阻止进入地牢或神庙 ||
| [PerPlayerLoot](PerPlayerLoot/README.md) | 玩家战利品单独箱子 ||
| [PvPer](PvPer/README.md) | 决斗系统 ||
Expand All @@ -77,3 +77,4 @@
| [EssentialsPlus](EssentialsPlus/README.md) | 更多管理指令 ||
| [ShowArmors](ShowArmors/README.md) | 展示装备栏 ||
| [VeinMiner](VeinMiner/README.md) | 连锁挖矿 ||
| [PersonalPermission](PersonalPermission/README.md) | 为玩家单独设置权限 ||

0 comments on commit 1b2d3f0

Please sign in to comment.