开发教程 [插件编写]TShock5插件编写入门教程

凌筱柒

Lv1
LV
0
 
IP属地
浙江省
2023/10/31
3
0
  • · 发布于浙江省
可以基于直播间弹幕或者礼物生产各种实体或者事件吗?类似于我的世界那种互动玩法,比方说直播间发出史莱姆王的弹幕在服务器生成一只史莱姆王
 

Cai233

Lv3
LV
0
 
IP属地
香港
2021/08/18
65
23
  • · 发布于陕西省
可以基于直播间弹幕或者礼物生产各种实体或者事件吗?类似于我的世界那种互动玩法,比方说直播间发出史莱姆王的弹幕在服务器生成一只史莱姆王
可以实现
 
最后编辑:

Cai233

Lv3
LV
0
 
IP属地
香港
2021/08/18
65
23
  • · 发布于香港
1
 
最后编辑:

Cai233

Lv3
LV
0
 
IP属地
香港
2021/08/18
65
23
  • · 发布于陕西省

Part 5.玩家对象

本章你将学到:
  • 学习TSPlayer类的字段、方法等
  • 学会Player类的常用字段、方法等

什么是TSPlayer类?

TSPlayerTShock的一个类,属于"TShock"的东西。这个类往往包含TShock服务器最常用玩家数据和方法,其中的方法字段几乎全部对服务端都是有效的

什么是Player类?

PlayerTerraria的一个类,属于"Terraria"的东西。这个类包含Terraria常用的玩家数据,这个类里的字段、方法繁多且杂乱,而且还包含了许多客户端才有效的字段、方法,只有部分方法、字段服务端可用

TSPlayer对象

1.获取TSPlayer对象
获取玩家对象的方法有多种,主要根据你的需要选择,下面的代码通过不同的方式获取TSPlayer玩家对象
TSPlayer.FindByNameOrID()方法 (主要用于命令)

TSPlayer.FindByNameOrID()会返回一个列表,包含所有匹配的玩家对象,当然没有匹配结果会返回一个空列表
C#:
private void Test(CommandArgs args)
{
    TSPlayer plr;
    List<TSPlayer> plrs = TSPlayer.FindByNameOrID(args.Parameters[0]);
    //args.Parameters[0]为玩家名字或索引
    //如果参数为 tsi:2 则表示索引为2的玩家
    //如果参数为 tsn:233 则表示名字为233的玩家
    if (plrs.Count == 0)
    {
        args.Player.SendErrorMessage("玩家不存在!"); //发送错误消息
        return;
    }
    else if (plrs.Count > 1)
    {
        args.Player.SendMultipleMatchError(plrs.Select(p => p.Name)); //发送多个匹配结果错误
        //会向玩家发送:
        //找到多个匹配项-无法判断哪个是正确的:
        //玩家1,玩家2....
        //用"半角双引号"包裹关键字来搜索名字带有空格的物品
        //使用 tsi:序号 或者 tsn:名称 来区分含有数字的名称.
        return;
    }
    else
    {
        plr = plrs[0];
        //找到匹配的玩家对象
    }
}
•Index索引获取
C#:
TSPlayer plr= TShock.Players[index]; //index为玩家索引
这种方法非常重要,常常用在ServerApi钩子获取TSPlayer对象
C#:
//插件加载时执行的代码
public override void Initialize()
{
    ServerApi.Hooks.ServerChat.Register(this, OnChat);
    Commands.ChatCommands.Add(new Command(Test, "test"));
}

private void OnChat(ServerChatEventArgs args)
{
    TSPlayer plr = TShock.Players[args.Who]; //获取钩子触发者的TSPlayer对象
}

//插件卸载时执行的代码
protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        ServerApi.Hooks.ServerChat.Deregister(this, OnChat);
    }
    base.Dispose(disposing);
}
•通过Where进行搜索
这种方法用于寻找特定条件的玩家,是一种万能的方法,示例代码如下: (p!=null 很重要,请务必写上)
C#:
string name = "233"; //假设的量
string acc = "233";
string ip = "127.0.0.1";

TSPlayer plr;
//var是推断类型的意思,使用var编译器会自己判断变量的类型,下面是一种偷懒的写法,完整的应该是IEnumerable<TSPlayer> plrs
var plrs= TShock.Players.Where(p => p!=null && p.Name == name); //通过玩家名字获取玩家对象
//var plrs = TShock.Players.Where(p => p != null && p.Account.Name == acc); //通过账号名字获取玩家对象
//var plrs = TShock.Players.Where(p => p != null && p.IP == ip); //通过IP获取玩家对象
//var plrs = TShock.Players.Where(p => p != null && p.Account.Name == acc && p.IP == ip ); //通过IP和账号名字获取玩家对象
//当然如果你需要的是单个玩家对象,你需要使用下列的代码进行判断
//如果你需要的符合条件的所有玩家,那么plrs就是结果
if (plrs.Count() == 0)
{
    //玩家对象不存在
    return;
}
else if (plrs.Count() > 1)
{
    //玩家对象存在多个
    return;
}
else
{
    plr = plrs.First();
    //plr即为玩家对象
}
2.TSPlayer类中的常用属性

名称类型作用/含义
Namestring玩家角色名
Indexint玩家索引
GroupGroup玩家所处的组对象
AccountUserAccount玩家的账号对象
TPlayerPlayer玩家的Player对象
UUIDstring玩家客户端的UUID
IPstring玩家IP地址
Xfloat玩家的X坐标
Yfloat玩家的Y坐标
TileXint玩家所处图格的X坐标
TileYint玩家所处图格的Y坐标
Teamint玩家队伍(无队伍0,红队1,绿队2,蓝队3,黄队4,粉队5)
RealPlayerbool正常玩家(true);控制台或REST(false)
RespawnTimerint玩家重生计时器(单位:秒)
LoginAttemptsint玩家登录尝试次数
Activebool玩家的活动状态(通常为true)
ConnectionAlivebool玩家的连接状态(正常为true)
DataWhenJoinedPlayerData玩家加入时的人物数据(非SSC)
InventoryIEnumerable<Item>玩家背包(前5行)
AccessoriesIEnumerable<Item>玩家的配饰
InventorySlotAvailablebool玩家背包是否有多余
SelectedItemItem玩家当前手持的物品
Stateint玩家的客户端状态(与加入服务器有关)
LastThreatDateTime玩家上次被冻结(Disable)的时间(Utc)
PaintThresholdint玩家在上一秒漆墙的数量
ProjectileThresholdint玩家在上一秒生成弹幕的数量
TileKillThresholdint玩家在上一秒破坏图格的数量
TileLiquidThresholdint玩家在上一秒放置液体的数量
TilePlaceThresholdint玩家在上一秒放置图格的数量
HealOtherThresholdint玩家在上一秒治疗玩家的次数
TilesCreatedDictionary<Vector2, ITile>玩家放置的待摧毁图格(与图格回弹有关)
TilesDestroyedDictionary<Vector2, ITile>玩家摧毁的待放置图格(与图格回弹有关)
AwaitingNamebool等待玩家获取区域名字
AwaitingNameParameterstring[]获取区域名字时,区域的控制字符(-u 包含保护的区域,-z 包含区域Z索引,-p 玩家将持续接受区域编辑信息?)
AwaitingTempPointint等待玩家设置区域临时点(0未等待,1点1等待中,2点2等待中)
 

Cai233

Lv3
LV
0
 
IP属地
香港
2021/08/18
65
23
  • · 发布于香港
2.TSPlayer类中的字段
字段名类型作用/含义
AcceptingWhispersbool玩家是否接受耳语(私聊) (/w)
ActiveChestint玩家当前打开的箱子ID (玩家没有开箱子则未-1)
AwaitingResponseDictionary<string, Action<object>>玩家等待特定命令的响应的列表(?)
Confusedbool玩家是否处于控制左右颠倒(已失效)
Countrystring玩家的国家代码(需要在Config开启EnableGeoIP)(无数据N/A, 代理A1)
CurrentRegionRegion玩家当前所处的区域
Deadbool玩家是否处于死亡状态
Difficultyint玩家的角色难度(软核0,中核1,硬核2,旅行3)
DisplayLogsbool是否向玩家发送服务器日志
GodModebool玩家是否已启用上帝模式(直接修改不影响玩家的无敌状态)
HasBeenNaggedAboutLoggingInbool玩家是否已经被提示过修改区域需要登录
IceTilesList<Point>玩家放置冰砖(冰杖)的点
IsDisabledForBannedWearablebool玩家是否由于携带禁用物品而被限制行动(Disable)
IsDisabledForSSCbool玩家是否由于没有登录以获取SSC数据而被限制行动(Disable)
IsDisabledForStackDetectionbool玩家是否由于恶意修改物品堆叠而被限制行动(Disable)
IsDisabledPendingTrashRemovalbool玩家是否由于在登录前在垃圾桶放置物品而被限制行动(Disable)
IsLoggedInbool玩家是否已经登录
ItemInHandItem玩家手持的物品
LastKilledProjectileint玩家上一次试图清除的最后一个弹幕
LastNetPositionVector2玩家最后更新时的图格坐标(TileXY)
lastPermissionWarninglong玩家上次被提示无权建筑警告的时间戳
LastPvPTeamChangeDateTime玩家上次切换队伍或PVP状态的时间
LastWhisperTSPlayer玩家上次进行耳语(私聊或被私聊)的对象
LoginHarassedbool玩家是否因为登录而被限制行动(?)
LoginMSlong玩家加入服务器时的时间戳
mutebool玩家是否处于禁言状态
PlayerDataPlayerData玩家的SSC人物数据
RecentFuseint玩家使用炸药的倒计时,即距离下次可用正常使用炸弹剩余时间(单位: 秒)
RecentlyCreatedProjectilesList<GetDataHandlers.ProjectileStruct>跟踪这个玩家最近创建的弹幕OnSecondUpdate() 在异步任务中删除这个。超过5秒的投射物将从这个集合中清除,因为它们不再是“最近的”。
RequestedSectionbool玩家是否已请求过获取地图区块
RequiresPasswordbool玩家是否被要求输入密码(加入服务器前)
RPPendingint玩家传送到上次离开服务器位置的倒计时(单位: 秒)
SilentJoinInProgressbool玩家是否静默加入服务器(不发送玩家加入服务器的提示)
SilentKickInProgressbool玩家是否静默踢出服务器(不发送玩家踢出服务器的提示)
sXint玩家出生点的X坐标
sYint玩家出生点的Y坐标
TeleportCoordsVector2不明,在TShock已弃用
tempGroupGroup玩家当前的临时组(会覆盖原来的组)
tempGroupTimerTimer玩家临时组有效期的计时器
TempPointsPoint[2]玩家设置的区域临时点
TPAllowbool玩家是否允许其他玩家对他使用TP类命令(tshock.tp.override忽略此限制)
2.TSPlayer类中的方法
方法名参数返回值作用
Banstring reason(封禁理由), string adminUserName = null(管理用户名)bool(封禁是否成功)封禁玩家
DamagePlayerint damage(造成伤害点数)void对玩家造成伤害
Disablestring reason = ""(理由), DisableFlags flags = DisableFlags.WriteToLog(日志记录模式)void限制玩家行动
Disconnectstring reason(理由)void断开玩家连接
GiveItemint type(物品ID), int stack(物品堆叠), int prefix = 0(物品修饰语ID)void给予玩家物品
GiveItemCheckint type(物品ID), string name(物品全名[用于检测是否属于封禁物品]), int stack(物品堆叠), int prefix = 0(物品修饰语ID)bool(检查结果)判断玩家是否能被给予某物品
HasBuildPermissionint x(TileX), int y(TileY), bool shouldWarnPlayer = true(是否警告玩家)bool(检查结果)判断玩家是否能编辑此图格
HasBuildPermissionForTileObjectint x(TileX), int y(TileY), int width(宽度), int height(高度), bool shouldWarnPlayer = true(是否警告玩家)bool(检查结果)判断玩家是否能编辑以(X,Y)为左下角,宽度为width,高度为height的矩形(只要范围内有一个图格玩家不能编辑就会返回false)
HasHackedItemStacksbool shouldWarnPlayer = false(是否警告玩家)bool(检查结果)检测玩家是否作弊堆叠(例如:堆叠999999土块)
HasModifiedIceSuccessfullyint x(TileX), int y(TileY), short tileType(图格类型), GetDataHandlers.EditAction editAction(编辑操作类型)bool(检查结果)判断玩家是否成功编辑冰(冰杖生成的)
HasPaintPermissionint x(TileX), int y(TileY)bool(检查结果)判断玩家是否能为此图格涂漆
HasPermissionstring permission(权限)bool(检查结果)判断玩家是否拥有某个权限
(优先级如下:
1.权限钩子修改的结果
2.临时组的权限
3.玩家当前组的权限)
[临时组和玩家组的权限不叠加]
Healint health = 600(治疗点数)void治疗一个玩家
IsBeingDisabledbool(检查结果)判断玩家是否被限制行动
IsBouncerThrottledbool(检查结果)判断玩家是否被Bouncer限制(?)
IsInRangeint x(TileX), int y(TileY), int range = 32(检查半径)bool(检查结果)判断玩家是否在以(X,Y)为圆点range为半径的圆内[当Config的RangeChecks被设为false后无论结果只返回true]
Kickstring reason(理由), bool force = false(强制踢出[无视tshock.admin.nokick权限]), bool silent = false(不发送广播), string adminUserName = null(管理员名), bool saveSSI = false(保存玩家SSC数据)bool(踢出结果)踢出一名玩家
KillPlayervoid杀死玩家(对上帝模式玩家无效)[原理是对玩家造成99999点伤害=DamagePlayer(99999)]
Logoutvoid使玩家登出
RemoveProjectileint index(弹幕ID), int owner(弹幕发射者索引)void移除一个弹幕(?)
SaveServerCharacterbool(保存结果)保存玩家的SSC云存档(服务器没有打开SSC时总返回false)
SetBuffint type(增益ID), int time = 3600(持续帧[1秒=60帧]), bool bypass = false(忽略Bouncer对玩家的限制)void添加玩家BUFF(若玩家已有该BUFF且持续时间更长,你添加的BUFF会被忽略)[BUFF时间不会叠加]
 
最后编辑:

凌筱柒

Lv1
LV
0
 
IP属地
浙江省
2023/10/31
3
0
  • · 发布于浙江省
可以实现
那像我这样的小白应该从哪方面入手啊,或者是现在已经有成熟的模板了
 

Cai233

Lv3
LV
0
 
IP属地
香港
2021/08/18
65
23
  • · 发布于香港
那像我这样的小白应该从哪方面入手啊,或者是现在已经有成熟的模板了
B站的事件得自己爬,但是Github上应该有这种。Terraria的东西建议是从头学了 (,弹幕之类的我也不是很会
 
  • 标签
    插件制作 插件教程
  • * 这是一则由 Google AdSense 自动推荐的广告,与本站无关,不对其真实性与可靠性负责

    顶部