Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加插件:Autoclear智能自动扫地 #32

Merged
merged 7 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions Autoclear/Autoclear.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
using System;
using System.Configuration;
using Terraria;
using TerrariaApi.Server;
using TShockAPI;
using TShockAPI.Hooks;

namespace Autoclear
{
[ApiVersion(2, 1)]
public class Autoclear : TerrariaPlugin
{
public override string Author => "大豆子[Mute适配1447],肝帝熙恩更新";
public override string Description => "智能扫地机";
public override string Name => "智能自动扫地";
public override Version Version => new Version(1, 0, 3);
public static Configuration Config;
private bool _sweepScheduled = false;
private DateTime _sweepScheduledAt;
private int _updateCounter;

public Autoclear(Main game) : base(game)
{
LoadConfig();
}

private static void LoadConfig()
{
Config = Configuration.Read(Configuration.FilePath);
Config.Write(Configuration.FilePath);
}

private static void ReloadConfig(ReloadEventArgs args)
{
LoadConfig();
args.Player?.SendSuccessMessage("[{0}] 重新加载配置完毕。", typeof(Autoclear).Name);
}

public override void Initialize()
{
GeneralHooks.ReloadEvent += ReloadConfig;
ServerApi.Hooks.GameUpdate.Register(this, OnUpdate);
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
ServerApi.Hooks.GameUpdate.Deregister(this, OnUpdate);
}
base.Dispose(disposing);
}

private void OnUpdate(EventArgs args)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

添加时检参数,避免过度频繁检测

{
_updateCounter++;

if (_updateCounter % (60 * Config.detectionIntervalSeconds) == 0)
{
int totalItems2 = 0;
for (int i = 0; i < Main.item.Length; i++)
{
if (Main.item[i].active && !Config.NonSweepableItemIDs.Contains(Main.item[i].type))
{
totalItems2++;
}
}

if (totalItems2 >= Config.SmartSweepThreshold)
{
if (!_sweepScheduled)
{
_sweepScheduled = true;
_sweepScheduledAt = DateTime.UtcNow.AddSeconds(Config.DelayedSweepTimeoutSeconds);

// 发送倒计时消息
if (Config.SpecificMessage)
{
TSPlayer.All.SendSuccessMessage($"{Config.DelayedSweepCustomMessage}");
}
}
}
if (_sweepScheduled && DateTime.UtcNow >= _sweepScheduledAt)
{
// 到达清扫时间,执行清扫任务
_sweepScheduled = false;
PerformSmartSweep();
}
}
}

private void PerformSmartSweep()
{
int totalItems = 0;
int totalThrowable = 0;
int totalSwinging = 0;
int totalRegular = 0;
int totalEquipment = 0;
int totalVanity = 0;

for (int i = 0; i < Main.item.Length; i++)
{
if (Main.item[i].active && !Config.NonSweepableItemIDs.Contains(Main.item[i].type))
{
bool isThrowable = Main.item[i].damage > 0 && Main.item[i].maxStack > 1;
bool isSwinging = Main.item[i].damage > 0 && Main.item[i].maxStack == 1;
bool isRegular = Main.item[i].damage < 0 && Main.item[i].maxStack > 1;
bool isEquipment = Main.item[i].damage == 0 && Main.item[i].maxStack == 1;
bool isVanity = Main.item[i].damage < 0 && Main.item[i].maxStack == 1;

if ((Config.SweepThrowable && isThrowable) ||
(Config.SweepSwinging && isSwinging) ||
(Config.SweepRegular && isRegular) ||
(Config.SweepEquipment && isEquipment) ||
(Config.SweepVanity && isVanity))
{
Main.item[i].active = false;
TSPlayer.All.SendData(PacketTypes.ItemDrop, " ", i, 0f, 0f, 0f, 0);
totalItems++;

if (isThrowable) totalThrowable++;
if (isSwinging) totalSwinging++;
if (isRegular) totalRegular++;
if (isEquipment) totalEquipment++;
if (isVanity) totalVanity++;
}
}
}

if (totalItems > 0)
{
if (!string.IsNullOrEmpty(Config.CustomMessage))
{
TSPlayer.All.SendSuccessMessage($"{Config.CustomMessage}");
}

if (Config.SpecificMessage)
{
TSPlayer.All.SendSuccessMessage($"智能扫地机已清扫:[c/FFFFFF:{totalItems}]种物品");
TSPlayer.All.SendSuccessMessage($"包含:【投掷武器[c/FFFFFF:{totalThrowable}]】-【挥动武器[c/FFFFFF:{totalSwinging}]】-【普通物品[c/FFFFFF:{totalRegular}]】-【装备[c/FFFFFF:{totalEquipment}]】-【时装[c/FFFFFF:{totalVanity}]】");
}
}
}
}
}
5 changes: 5 additions & 0 deletions Autoclear/Autoclear.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>
75 changes: 75 additions & 0 deletions Autoclear/Configuration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using TShockAPI;

namespace Autoclear
{
public class Configuration
{
public static readonly string FilePath = Path.Combine(TShock.SavePath, "AutoClear.json");

[JsonProperty("多久检测一次(s)")]
public int SmartSweepThreshold { get; set; } = 100;

[JsonProperty("不清扫的物品ID列表")]
public List<int> NonSweepableItemIDs { get; set; } = new List<int>();

[JsonProperty("智能清扫数量临界值")]
public int detectionIntervalSeconds { get; set; } = 10;

[JsonProperty("延迟清扫(s)")]
public int DelayedSweepTimeoutSeconds { get; set; } = 10;

[JsonProperty("延迟清扫自定义消息")]
public string DelayedSweepCustomMessage { get; set; } = "";

[JsonProperty("是否清扫挥动武器")]
public bool SweepSwinging { get; set; } = true;

[JsonProperty("是否清扫投掷武器")]
public bool SweepThrowable { get; set; } = true;

[JsonProperty("是否清扫普通物品")]
public bool SweepRegular { get; set; } = true;

[JsonProperty("是否清扫装备")]
public bool SweepEquipment { get; set; } = true;

[JsonProperty("是否清扫时装")]
public bool SweepVanity { get; set; } = true;

[JsonProperty("完成清扫自定义消息")]
public string CustomMessage { get; set; } = "";

[JsonProperty("具体消息")]
public bool SpecificMessage { get; set; } = true;


public void Write(string path)
{
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write))
{
var str = JsonConvert.SerializeObject(this, Formatting.Indented);
using (var sw = new StreamWriter(fs))
{
sw.Write(str);
}
}
}

public static Configuration Read(string path)
{
if (!File.Exists(path))
return new Configuration();
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var sr = new StreamReader(fs))
{
var cf = JsonConvert.DeserializeObject<Configuration>(sr.ReadToEnd());
return cf;
}
}
}
}
}
40 changes: 40 additions & 0 deletions Autoclear/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Autoclear 智能自动扫地

- 作者: 大豆子[Mute适配1447],肝帝熙恩更新
- 出处: TShock中文官方群
- 当地面物品数量到达一定值开始清扫倒计时
- 可自定义哪些/哪类物品不被清扫

## 更新日志

```
暂无
```

## 指令

```
暂无
```

## 配置

```json
{
"多久检测一次(s)": 10,
"不清扫的物品ID列表": [],
"智能清扫数量临界值": 100,
"延迟清扫(s)": 10,
"延迟清扫自定义消息": "",
"是否清扫挥动武器": true,
"是否清扫投掷武器": true,
"是否清扫普通物品": true,
"是否清扫装备": true,
"是否清扫时装": true,
"完成清扫自定义消息": "",
"具体消息": true
}
```
## 反馈
- 共同维护的插件库: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 @@ -94,6 +94,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Invincibility", "Invincibil
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ezperm", "Ezperm\Ezperm.csproj", "{4AB96380-C0D3-4746-87FF-D5FF0AFF1AE3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Autoclear", "Autoclear\Autoclear.csproj", "{75442E3B-E8FD-4B36-BA0B-7113005E5D11}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -446,6 +448,14 @@ Global
{4AB96380-C0D3-4746-87FF-D5FF0AFF1AE3}.Release|Any CPU.Build.0 = Release|Any CPU
{4AB96380-C0D3-4746-87FF-D5FF0AFF1AE3}.Release|x64.ActiveCfg = Release|Any CPU
{4AB96380-C0D3-4746-87FF-D5FF0AFF1AE3}.Release|x64.Build.0 = Release|Any CPU
{75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Debug|x64.ActiveCfg = Debug|Any CPU
{75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Debug|x64.Build.0 = Debug|Any CPU
{75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Release|Any CPU.Build.0 = Release|Any CPU
{75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Release|x64.ActiveCfg = Release|Any CPU
{75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,4 @@
| [History](History/README.md) | 历史图格记录 | 无 |
| [Invincibility](Invincibility/README.md) | 限时无敌 | 无 |
| [Ezperm](Ezperm/README.md) | 批量改权限 | 无 |
| [AutoClear](AutoClear/README.md) | 智能自动扫地 | 无 |
Loading