From 0b20396ef1cceda571e7461810d855aff24c6593 Mon Sep 17 00:00:00 2001
From: xien <2383759126@qq.com>
Date: Sun, 14 Apr 2024 20:34:38 +0800
Subject: [PATCH 1/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8F=92=E4=BB=B6?=
=?UTF-8?q?=EF=BC=9ADeathDrop=20=E6=80=AA=E7=89=A9=E6=AD=BB=E9=9A=8F?=
=?UTF-8?q?=E6=9C=BA=E5=92=8C=E8=87=AA=E5=AE=9A=E4=B9=89=E7=89=A9=E5=93=81?=
=?UTF-8?q?=E6=8E=89=E8=90=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
DeathDrop/DeathDrop.cs | 154 +++++++++++++++++++++++++++++++++++
DeathDrop/DeathDrop.csproj | 3 +
DeathDrop/DeathDropConfig.cs | 62 ++++++++++++++
Plugin.sln | 10 +++
4 files changed, 229 insertions(+)
create mode 100644 DeathDrop/DeathDrop.cs
create mode 100644 DeathDrop/DeathDrop.csproj
create mode 100644 DeathDrop/DeathDropConfig.cs
diff --git a/DeathDrop/DeathDrop.cs b/DeathDrop/DeathDrop.cs
new file mode 100644
index 000000000..1ef59d837
--- /dev/null
+++ b/DeathDrop/DeathDrop.cs
@@ -0,0 +1,154 @@
+using System;
+using System.IO;
+using Microsoft.Xna.Framework;
+using Newtonsoft.Json;
+using Terraria;
+using TerrariaApi.Server;
+using TShockAPI;
+
+namespace DeathDrop
+{
+ [ApiVersion(2, 1)]
+ public class DeathDrop : TerrariaPlugin
+ {
+ public static Random RandomGenerator = new Random();
+
+ public override string Author => "大豆子,肝帝熙恩更新优化";
+ public override string Description => "自定义怪物死亡随机掉落物";
+ public override string Name => "死亡随机掉落";
+ public override Version Version => new Version(1, 0, 1);
+
+ public DeathDrop(Main game) : base(game) { }
+
+ public override void Initialize()
+ {
+ ServerApi.Hooks.NpcKilled.Register(this, NPCDead);
+ }
+
+ private void NPCDead(NpcKilledEventArgs args)
+ {
+ int npcNetID = args.npc.netID;
+ Vector2 npcPosition = args.npc.position;
+
+ // 获取击杀者玩家(可能为 null)
+ TSPlayer player = args.npc.lastInteraction != 255 && args.npc.lastInteraction >= 0
+ ? TShock.Players[args.npc.lastInteraction]
+ : null;
+
+ try
+ {
+ DeathDropConfig config = DeathDropConfig.GetConfig();
+
+ if (config.EnableRandomDrops)
+ {
+ int itemId = GetRandomItemIdFromGlobalConfig(config);
+
+ if (Candorp(config.RandomDropChance))
+ {
+ Item item = TShock.Utils.GetItemById(itemId);
+ int dropAmount = RandomGenerator.Next(config.MinRandomDropAmount, config.MaxRandomDropAmount + 1);
+
+ int itemNumber = Item.NewItem(
+ null,
+ (int)args.npc.position.X,
+ (int)args.npc.position.Y,
+ item.width,
+ item.height,
+ item.type,
+ dropAmount
+ );
+
+ // 只有当玩家不为 null 时才发送数据包
+ if (player != null)
+ {
+ player.SendData(PacketTypes.SyncExtraValue, null, itemNumber);
+ player.SendData(PacketTypes.ItemOwner, null, itemNumber);
+ player.SendData(PacketTypes.TweakItem, null, itemNumber, 255f, 63f);
+ }
+ }
+ }
+
+ if (config.EnableCustomDrops)
+ {
+ foreach (DeathDropConfig.Monster monster in config.DeathDropSet)
+ {
+ if (monster.NPCID == npcNetID && Candorp(monster.DropChance))
+ {
+ int dropItemId = GetRandomItemIdFromMonsterConfig(monster);
+
+ Item dropItem = TShock.Utils.GetItemById(dropItemId);
+ int dropAmount = RandomGenerator.Next(monster.RandomDropMinAmount, monster.RandomDropMaxAmount + 1);
+
+ int dropItemNumber = Item.NewItem(
+ null,
+ (int)npcPosition.X,
+ (int)npcPosition.Y,
+ dropItem.width,
+ dropItem.height,
+ dropItem.type,
+ dropAmount
+ );
+
+ // 只有当玩家不为 null 时才发送数据包
+ if (player != null)
+ {
+ player.SendData(PacketTypes.SyncExtraValue, null, dropItemNumber);
+ player.SendData(PacketTypes.ItemOwner, null, dropItemNumber);
+ player.SendData(PacketTypes.TweakItem, null, dropItemNumber, 255f, 63f);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"死亡掉落插件发生异常:{ex.Message}");
+ }
+ }
+
+ private int GetRandomItemIdFromGlobalConfig(DeathDropConfig config)
+ {
+ if (config.FullRandomDrops)
+ {
+ int itemId = RandomGenerator.Next(1, 5453);
+
+ while (config.FullRandomExcludedItems.Contains(itemId))
+ {
+ itemId = RandomGenerator.Next(1, 5453);
+ }
+
+ return itemId;
+ }
+ else
+ {
+ int randomIndex = RandomGenerator.Next(config.CommonRandomDrops.Count);
+ return config.CommonRandomDrops[randomIndex];
+ }
+ }
+
+ private int GetRandomItemIdFromMonsterConfig(DeathDropConfig.Monster monster)
+ {
+ if (monster.FullRandomDrops)
+ {
+ int itemId = RandomGenerator.Next(1, 5453);
+
+ while (monster.FullRandomExcludedItems.Contains(itemId))
+ {
+ itemId = RandomGenerator.Next(1, 5453);
+ }
+
+ return itemId;
+ }
+ else
+ {
+ int randomIndex = RandomGenerator.Next(monster.CommonRandomDrops.Count);
+ return monster.CommonRandomDrops[randomIndex];
+ }
+ }
+
+ private static bool Candorp(int probability)
+ {
+ return RandomGenerator.Next(100) <= probability;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DeathDrop/DeathDrop.csproj b/DeathDrop/DeathDrop.csproj
new file mode 100644
index 000000000..11a03c671
--- /dev/null
+++ b/DeathDrop/DeathDrop.csproj
@@ -0,0 +1,3 @@
+
+
+
diff --git a/DeathDrop/DeathDropConfig.cs b/DeathDrop/DeathDropConfig.cs
new file mode 100644
index 000000000..ab38cef08
--- /dev/null
+++ b/DeathDrop/DeathDropConfig.cs
@@ -0,0 +1,62 @@
+using System.Collections.Generic;
+using System.IO;
+using Newtonsoft.Json;
+using TShockAPI;
+
+namespace DeathDrop
+{
+ internal class DeathDropConfig
+ {
+ public class Monster
+ {
+ [JsonProperty("生物id")]
+ public int NPCID { get; set; } = 0;
+ [JsonProperty("完全随机掉落")]
+ public bool FullRandomDrops { get; set; } = false;
+ [JsonProperty("完全随机掉落排除物品ID")]
+ public List FullRandomExcludedItems { get; set; } = new List();
+ [JsonProperty("普通随机掉落物")]
+ public List CommonRandomDrops { get; set; } = new List();
+ [JsonProperty("随机掉落数量最小值")]
+ public int RandomDropMinAmount { get; set; } = 1;
+ [JsonProperty("随机掉落数量最大值")]
+ public int RandomDropMaxAmount { get; set; } = 1;
+ [JsonProperty("掉落概率")]
+ public int DropChance { get; set; } = 100;
+ }
+
+ [JsonProperty("是否开启随机掉落")]
+ public bool EnableRandomDrops { get; set; } = false;
+ [JsonProperty("完全随机掉落")]
+ public bool FullRandomDrops { get; set; } = false;
+ [JsonProperty("完全随机掉落排除物品ID")]
+ public List FullRandomExcludedItems { get; set; } = new List();
+ [JsonProperty("普通随机掉落物")]
+ public List CommonRandomDrops { get; set; } = new List();
+ [JsonProperty("随机掉落概率")]
+ public int RandomDropChance { get; set; } = 100;
+ [JsonProperty("随机掉落数量最小值")]
+ public int MinRandomDropAmount { get; set; } = 1;
+ [JsonProperty("随机掉落数量最大值")]
+ public int MaxRandomDropAmount { get; set; } = 1;
+ [JsonProperty("是否开启自定义掉落")]
+ public bool EnableCustomDrops { get; set; } = false;
+ [JsonProperty("自定义掉落设置")]
+ public Monster[] DeathDropSet { get; set; } = new Monster[1]
+ {
+ new Monster()
+ };
+
+ public static readonly string ConfigFilePath = Path.Combine(TShock.SavePath, "死亡掉落配置表.json");
+
+ public static DeathDropConfig GetConfig()
+ {
+ if (!File.Exists(ConfigFilePath))
+ {
+ File.WriteAllText(ConfigFilePath, JsonConvert.SerializeObject(new DeathDropConfig(), Formatting.Indented));
+ }
+
+ return JsonConvert.DeserializeObject(File.ReadAllText(ConfigFilePath));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Plugin.sln b/Plugin.sln
index 5808aefc9..3a1337e22 100644
--- a/Plugin.sln
+++ b/Plugin.sln
@@ -76,6 +76,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CriticalHit", "CriticalHit\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PacketsStop", "PacketsStop\PacketsStop.csproj", "{852705B7-607D-4591-8359-860D3DD2B6A9}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeathDrop", "DeathDrop\DeathDrop.csproj", "{7901BF97-3A58-4D80-B99F-FE9D41AB4729}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -356,6 +358,14 @@ Global
{852705B7-607D-4591-8359-860D3DD2B6A9}.Release|Any CPU.Build.0 = Release|Any CPU
{852705B7-607D-4591-8359-860D3DD2B6A9}.Release|x64.ActiveCfg = Release|Any CPU
{852705B7-607D-4591-8359-860D3DD2B6A9}.Release|x64.Build.0 = Release|Any CPU
+ {7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Debug|x64.Build.0 = Debug|Any CPU
+ {7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Release|x64.ActiveCfg = Release|Any CPU
+ {7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
From 1c5b611b904ebf3996bd691728a7fd99f8b77bac Mon Sep 17 00:00:00 2001
From: xien <2383759126@qq.com>
Date: Sun, 14 Apr 2024 21:26:40 +0800
Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=87=8D=E8=BD=BD?=
=?UTF-8?q?=E6=96=B9=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../{DeathDropConfig.cs => Configuration.cs} | 29 +++-
DeathDrop/DeathDrop.cs | 134 ++++++++++--------
DeathDrop/README.md | 47 ++++++
3 files changed, 145 insertions(+), 65 deletions(-)
rename DeathDrop/{DeathDropConfig.cs => Configuration.cs} (68%)
create mode 100644 DeathDrop/README.md
diff --git a/DeathDrop/DeathDropConfig.cs b/DeathDrop/Configuration.cs
similarity index 68%
rename from DeathDrop/DeathDropConfig.cs
rename to DeathDrop/Configuration.cs
index ab38cef08..4805366f9 100644
--- a/DeathDrop/DeathDropConfig.cs
+++ b/DeathDrop/Configuration.cs
@@ -5,7 +5,7 @@
namespace DeathDrop
{
- internal class DeathDropConfig
+ public class Configuration
{
public class Monster
{
@@ -47,16 +47,31 @@ public class Monster
new Monster()
};
- public static readonly string ConfigFilePath = Path.Combine(TShock.SavePath, "死亡掉落配置表.json");
-
- public static DeathDropConfig GetConfig()
+ public static readonly string FilePath = Path.Combine(TShock.SavePath, "死亡掉落配置表.json");
+ public void Write(string path)
{
- if (!File.Exists(ConfigFilePath))
+ using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write))
{
- File.WriteAllText(ConfigFilePath, JsonConvert.SerializeObject(new DeathDropConfig(), Formatting.Indented));
+ var str = JsonConvert.SerializeObject(this, Formatting.Indented);
+ using (var sw = new StreamWriter(fs))
+ {
+ sw.Write(str);
+ }
}
+ }
- return JsonConvert.DeserializeObject(File.ReadAllText(ConfigFilePath));
+ 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(sr.ReadToEnd());
+ return cf;
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/DeathDrop/DeathDrop.cs b/DeathDrop/DeathDrop.cs
index 1ef59d837..a808f3ab8 100644
--- a/DeathDrop/DeathDrop.cs
+++ b/DeathDrop/DeathDrop.cs
@@ -5,6 +5,7 @@
using Terraria;
using TerrariaApi.Server;
using TShockAPI;
+using TShockAPI.Hooks;
namespace DeathDrop
{
@@ -12,19 +13,45 @@ namespace DeathDrop
public class DeathDrop : TerrariaPlugin
{
public static Random RandomGenerator = new Random();
+ public static Configuration Config;
public override string Author => "大豆子,肝帝熙恩更新优化";
- public override string Description => "自定义怪物死亡随机掉落物";
- public override string Name => "死亡随机掉落";
- public override Version Version => new Version(1, 0, 1);
+ public override string Description => "怪物死亡随机和自定义掉落物品";
+ public override string Name => "死亡掉落";
+ public override Version Version => new Version(1, 0, 3);
- public DeathDrop(Main game) : base(game) { }
+ public DeathDrop(Main game) : base(game)
+ {
+ LoadConfig();
+ }
public override void Initialize()
{
+ GeneralHooks.ReloadEvent += ReloadConfig;
ServerApi.Hooks.NpcKilled.Register(this, NPCDead);
}
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ GeneralHooks.ReloadEvent -= ReloadConfig;
+ ServerApi.Hooks.NpcKilled.Deregister(this, NPCDead);
+ }
+ base.Dispose(disposing);
+ }
+ private static void LoadConfig()
+ {
+ Config = Configuration.Read(Configuration.FilePath);
+ Config.Write(Configuration.FilePath);
+ }
+
+ private static void ReloadConfig(ReloadEventArgs args)
+ {
+ LoadConfig();
+ args.Player?.SendSuccessMessage("[死亡掉落] 重新加载配置完毕。");
+ }
+
private void NPCDead(NpcKilledEventArgs args)
{
int npcNetID = args.npc.netID;
@@ -35,78 +62,69 @@ private void NPCDead(NpcKilledEventArgs args)
? TShock.Players[args.npc.lastInteraction]
: null;
- try
+ if (Config.EnableRandomDrops)
{
- DeathDropConfig config = DeathDropConfig.GetConfig();
+ int itemId = GetRandomItemIdFromGlobalConfig(Config);
- if (config.EnableRandomDrops)
+ if (Candorp(Config.RandomDropChance))
{
- int itemId = GetRandomItemIdFromGlobalConfig(config);
+ Item item = TShock.Utils.GetItemById(itemId);
+ int dropAmount = RandomGenerator.Next(Config.MinRandomDropAmount, Config.MaxRandomDropAmount + 1);
+
+ int itemNumber = Item.NewItem(
+ null,
+ (int)args.npc.position.X,
+ (int)args.npc.position.Y,
+ item.width,
+ item.height,
+ item.type,
+ dropAmount
+ );
+
+ // 只有当玩家不为 null 时才发送数据包
+ if (player != null)
+ {
+ player.SendData(PacketTypes.SyncExtraValue, null, itemNumber);
+ player.SendData(PacketTypes.ItemOwner, null, itemNumber);
+ player.SendData(PacketTypes.TweakItem, null, itemNumber, 255f, 63f);
+ }
+ }
+ }
- if (Candorp(config.RandomDropChance))
+ if (Config.EnableCustomDrops)
+ {
+ foreach (Configuration.Monster monster in Config.DeathDropSet)
+ {
+ if (monster.NPCID == npcNetID && Candorp(monster.DropChance))
{
- Item item = TShock.Utils.GetItemById(itemId);
- int dropAmount = RandomGenerator.Next(config.MinRandomDropAmount, config.MaxRandomDropAmount + 1);
+ int dropItemId = GetRandomItemIdFromMonsterConfig(monster);
- int itemNumber = Item.NewItem(
+ Item dropItem = TShock.Utils.GetItemById(dropItemId);
+ int dropAmount = RandomGenerator.Next(monster.RandomDropMinAmount, monster.RandomDropMaxAmount + 1);
+
+ int dropItemNumber = Item.NewItem(
null,
- (int)args.npc.position.X,
- (int)args.npc.position.Y,
- item.width,
- item.height,
- item.type,
+ (int)npcPosition.X,
+ (int)npcPosition.Y,
+ dropItem.width,
+ dropItem.height,
+ dropItem.type,
dropAmount
);
// 只有当玩家不为 null 时才发送数据包
if (player != null)
{
- player.SendData(PacketTypes.SyncExtraValue, null, itemNumber);
- player.SendData(PacketTypes.ItemOwner, null, itemNumber);
- player.SendData(PacketTypes.TweakItem, null, itemNumber, 255f, 63f);
- }
- }
- }
-
- if (config.EnableCustomDrops)
- {
- foreach (DeathDropConfig.Monster monster in config.DeathDropSet)
- {
- if (monster.NPCID == npcNetID && Candorp(monster.DropChance))
- {
- int dropItemId = GetRandomItemIdFromMonsterConfig(monster);
-
- Item dropItem = TShock.Utils.GetItemById(dropItemId);
- int dropAmount = RandomGenerator.Next(monster.RandomDropMinAmount, monster.RandomDropMaxAmount + 1);
-
- int dropItemNumber = Item.NewItem(
- null,
- (int)npcPosition.X,
- (int)npcPosition.Y,
- dropItem.width,
- dropItem.height,
- dropItem.type,
- dropAmount
- );
-
- // 只有当玩家不为 null 时才发送数据包
- if (player != null)
- {
- player.SendData(PacketTypes.SyncExtraValue, null, dropItemNumber);
- player.SendData(PacketTypes.ItemOwner, null, dropItemNumber);
- player.SendData(PacketTypes.TweakItem, null, dropItemNumber, 255f, 63f);
- }
+ player.SendData(PacketTypes.SyncExtraValue, null, dropItemNumber);
+ player.SendData(PacketTypes.ItemOwner, null, dropItemNumber);
+ player.SendData(PacketTypes.TweakItem, null, dropItemNumber, 255f, 63f);
}
}
}
}
- catch (Exception ex)
- {
- Console.WriteLine($"死亡掉落插件发生异常:{ex.Message}");
- }
}
- private int GetRandomItemIdFromGlobalConfig(DeathDropConfig config)
+ private int GetRandomItemIdFromGlobalConfig(Configuration config)
{
if (config.FullRandomDrops)
{
@@ -126,7 +144,7 @@ private int GetRandomItemIdFromGlobalConfig(DeathDropConfig config)
}
}
- private int GetRandomItemIdFromMonsterConfig(DeathDropConfig.Monster monster)
+ private int GetRandomItemIdFromMonsterConfig(Configuration.Monster monster)
{
if (monster.FullRandomDrops)
{
diff --git a/DeathDrop/README.md b/DeathDrop/README.md
new file mode 100644
index 000000000..d6378aa00
--- /dev/null
+++ b/DeathDrop/README.md
@@ -0,0 +1,47 @@
+# DeathDrop 死亡掉落
+
+- 作者: 大豆子,肝帝熙恩更新优化
+- 出处: TShock中文官方群
+- 允许自定义怪物死亡时的掉落物。
+- 随机or自定义,互不影响
+
+## 更新日志
+
+```
+- v1.0.3 使用reload来重载配置,原先是杀一只怪就重载一次,感觉会爆
+```
+
+## 指令
+
+```
+暂无
+```
+
+## 配置
+
+```json
+{
+ "是否开启随机掉落": false,//随机掉落的总开关,必须设置这个为true能设置除了自定义以外的内容
+ "完全随机掉落": false,//完全随机掉落,从1-5452里面选一个或多个物品
+ "完全随机掉落排除物品ID": [],//不会选择这里面的物品
+ "普通随机掉落物": [],//如果完全随机掉落为false,你可以在这里面自定义所有怪物一起的随机掉落物,随机掉落物从这里面选取
+ "随机掉落概率": 100,//概率,同时影响完全随机掉落和普通随机掉落
+ "随机掉落数量最小值": 1,//随机掉落数量最小值,同时影响完全随机掉落和普通随机掉落
+ "随机掉落数量最大值": 1,//随机掉落数量最小值,同时影响完全随机掉落和普通随机掉落
+ "是否开启自定义掉落": false,//自定义掉落,不受上面所有设置的影响,独立作用
+ "自定义掉落设置": [
+ {
+ "生物id": 0,
+ "完全随机掉落": false,
+ "完全随机掉落排除物品ID": [],
+ "普通随机掉落物": [],
+ "随机掉落数量最小值": 1,
+ "随机掉落数量最大值": 1,
+ "掉落概率": 100
+ }
+ ]
+}
+```
+## 反馈
+- 共同维护的插件库:https://github.com/THEXN/TShockPlugin/
+- 国内社区trhub.cn 或 TShock官方群等
\ No newline at end of file
From 3ee3fd61c96baf3662efd3ae374d73d8eab25594 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=82=9D=E5=B8=9D=E7=86=99=E6=81=A9?=
<111548550+THEXN@users.noreply.github.com>
Date: Sun, 14 Apr 2024 21:28:23 +0800
Subject: [PATCH 3/3] Update README.md
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 7d3563b3d..8273dd726 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,8 @@
| [RegionView](RegionView/README.md) | 显示区域边界 | 无 |
| [Noagent](Noagent/README.md) | 禁止代理 ip 进入 | 无 |
| [SwitchCommands](SwitchCommands/README.md) | 区域执行指令 | 无 |
-| [GolfRewards](GolfRewards/README.md) | 高尔夫奖励 | 无 |
+| [GolfRewards](GolfRewards/README.md) | 高尔夫奖励 | 无 |
| [DataSync](DataSync/README.md) | 进度同步 | 无 |
| [ProgressRestrict](ProgressRestrict/README.md) | 超进度检测 | DataSync |
-| [PacketsStop](PacketsStop/README.md) | 数据包拦截 | 无 |
+| [PacketsStop](PacketsStop/README.md) | 数据包拦截 | 无 |
+| [DeathDrop](DeathDrop/README.md) |怪物死亡随机和自定义掉落物品 | 无 |