最新消息

欢迎您,这里是向导的冒险者营地!

通过向我们注册,您将能够与我们营地的其他成员讨论、共享和私信.

立即加入!

教程相关 [插件编写]TShock5插件编写入门教程

这是一个教程相关的扫盲内容
主题 作者

Cai

Moderator
管理成员
09
186
0

前言:

  • 本教程是插件入门教程而不是C#入门教程
  • C#入门相关教程请移步B站
  • 本教程的作者本身也是个菜鸡,没办法写得特别清楚.jpg
  • 本教程将使用Windows系统演示(推荐系统Windows10+)
  • 如果有那个段落听不懂或者出现错误,欢迎大家留下建议!

章节目录

Part 0.配置开发环境

本章你将学到:
  • 如何安装Microsoft Visual Studio

1.下载Microsoft Visual Studio安装程序​

进入Visual Studio官方下载地址: https://visualstudio.microsoft.com/zh-hans/downloads/
选择Community版本下载(Professional、Enterprise版是付费版本)

1692965150135.png



2.打开VisualStudioSetup.exe

点击继续即可,然后会开始安装VisualStudio安装器

3.选择.NET 桌面开发并安装


1692966114824.png


注: 请不要自以为是随便勾选组件和工作负载,每个工作负载都要占用相当大的储存空间。 修改安装位置可能导致一些玄学的安装问题,为了避免出现问题,请直接默认即可,如果你要修改部分安装设置,那么请你对你的修改有十足的把握!!!

4.等待安装

1692966713652.png



注:若提示需要重启,重启即可

5.启动VisualStudio

VisualStudio一般会出现在开始菜单下,你可以使用如下方法创建快捷方式(如果没有快捷方式)
1692967698634.png


初次启动可能会要求登录,登录完成后可以选择自定义主题(反正我喜欢黑色主题),按照自己的偏好选择即可
至此,VisualStudio安装教程结束
 
主题 作者

Cai

Moderator
管理成员
09
186
0

Part 1.编写你的第一个插件

本章你将学到:
  • 使用Visual Studio创建插件项目
  • 使用Nuget程序包管理器添加插件依赖项
  • 初步了解编写一个插件的流程

1.创建新项目

浏览附件6384
选择类库选项,然后下一步

注: 一定要看清楚是C#.NET
浏览附件6385
项目名称填写插件名,位置建议默认,具体可以参考下图配置

注:
一般来讲,项目名只由字母(A-Z,a-z),数字(0-9),下划线(_)组成,并且项目名具有实际意义

不要使用中文!不要使用中文!不要使用中文!(引自棱镜)
解决方案中可以包含多个插件项目。使用同一个解决方案存放多个插件项目可以方便管理多个插件代码,并且方便项目之间互相引用。
浏览附件6386
此处一定要选择.NET 6.0,否则可能会导致一些插件兼容问题
浏览附件6391

2.进入VS项目

我相信有C#基础的你一定对VS的界面十分熟悉,所以不做过多介绍,但请你熟记下图的代码区域
浏览附件6379
*重命名(非必要)
解决方案资源管理器找到如图.cs文件可以对其右键进行重命名
当然同样要遵循命名规范不随意使用中文
浏览附件6392

3.添加TShock插件依赖项

TShock插件依赖许多相关程序集,好消息是你可以通过NuGet程序包快速引用他们

解决方案资源管理器右键依赖项,点击管理NuGet程序包
浏览附件6393
根据下图步骤安装TShock的NuGet程序包
浏览附件6394
弹出提示点击确定、接受即可

4.开始编写代码

显然你现在并不会写,但是你可以先复制下面的TShock插件模板
C#:
//代码来源:https://github.com/chi-rei-den/PluginTemplate/blob/master/src/PluginTemplate/Program.cs
//恋恋的TShock插件模板,有改动(为了配合章节名)
//来自棱镜的插件教程

using System;
using System.Collections.Generic;
using System.Reflection;
using Terraria;
using TerrariaApi.Server;
using TShockAPI;

namespace Plugin
{
    [ApiVersion(2, 1)]
    public class Plugin : TerrariaPlugin
    {
        //定义插件的作者名称
        public override string Author => "插件的作者";

        //插件的一句话描述
        public override string Description => "插件的描述";

        //插件的名称
        public override string Name => "插件的名字";

        //插件的版本
        public override Version Version => Assembly.GetExecutingAssembly().GetName().Version;

        //插件的构造器
        public Plugin(Main game) : base(game)
        {
        }

        //插件加载时执行的代码
        public override void Initialize()
        {
            //恋恋给出的模板代码中展示了如何为TShock添加一个指令
            Commands.ChatCommands.Add(new Command(
                permissions: new List<string> { "plugin.permission1", "plugin.permission2", },
                cmd: this.Cmd,
                "helloworld", "hw"));
        }
        
        //插件卸载时执行的代码

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                //移除所有由本插件添加的所有指令

                var asm = Assembly.GetExecutingAssembly();
                Commands.ChatCommands.RemoveAll(c => c.CommandDelegate.Method?.DeclaringType?.Assembly == asm);
            }
            base.Dispose(disposing);
        }

        //执行指令时对指令进行处理的方法
        private void Cmd(CommandArgs args)
        {
            args.Player.SendSuccessMessage("Hello world!");
        }
    }
}
相信你看到这串代码大概是一脸懵逼的,但是没关系,你只要知道它的功能
添加命令/helloworld,执行此命令会向执行命令的人发送一个绿色的HelloWorld
浏览附件6388
粘贴代码后,当你发现代码编辑区左下角的错误数已经变成0之后,恭喜你可以开始编译插件
浏览附件6381

注:如果有错误存在,可能是你复制漏了某些地方。

5.编译生成你的插件

点击工具栏处的绿色小三角(或者快捷键Ctrl+B)即可开始编译
浏览附件6380
开始编译后,输出区会打印编译的一些日志,最后打印编译结果
当出现"1 成功"的字样,说明插件代码已经成功编译
浏览附件6395

6.找到并安装你的插件

解决方案资源管理器右键当前项目(HelloWorld),点击在文件资源管理器中打开文件夹
浏览附件6396浏览附件6397
此时会蹦出一个文件夹,按照下图目录找到net6.0文件夹
浏览附件6389
将图示两个文件移动或复制到TShock目录中的ServerPlugins文件夹中
浏览附件6390


7.测试你的插件

启动TShock,可以发现你的插件已经被TShock成功识别并安装了

浏览附件6398
使用/help命令查看命令列表,可以发现插件添加的命令已经在命令列表中显示
执行/helloworld,控制台打印出绿色Hello world!
说明插件功能正常

浏览附件6378
 
主题 作者

Cai

Moderator
管理成员
09
186
0

Part 2.初步了解TShock插件模板

本章你将学到:
  • TShock插件模板各部分的作用
  • TShock插件的初始化顺序

插件模板

以下是一个常用的TShock插件模板其实似乎也就是Part 1把HelloWorld删掉的样子
C#:
//代码来源:https://github.com/chi-rei-den/PluginTemplate/blob/master/src/PluginTemplate/Program.cs
//恋恋的TShock插件模板,有改动(为了配合章节名)
//来自棱镜的插件教程

using System;
using System.Collections.Generic;
using System.Reflection;
using Terraria;
using TerrariaApi.Server;
using TShockAPI;

namespace Plugin
{
    [ApiVersion(2, 1)]
    public class Plugin : TerrariaPlugin
    {
        //定义插件的作者名称
        public override string Author => "插件的作者";

        //插件的一句话描述
        public override string Description => "插件的描述";

        //插件的名称
        public override string Name => "插件的名字";

        //插件的版本
        public override Version Version => Assembly.GetExecutingAssembly().GetName().Version;

        //插件的构造器
        public Plugin(Main game) : base(game)
        {
        }

        //插件加载时执行的代码
        public override void Initialize()
        {
        }
        
        //插件卸载时执行的代码
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
            }
            base.Dispose(disposing);
        }

    }
}

插件基本信息

以下代码可以设置插件的一些基本信息,插件名建议按照功能命名不要起奇怪名字(例如"炸裂")
C#:
//定义插件的作者名称
public override string Author => "插件的作者";

//插件的一句话描述
public override string Description => "插件的描述";

//插件的名称
public override string Name => "插件的名字";

//插件的版本
public override Version Version => Assembly.GetExecutingAssembly().GetName().Version;
Author(插件作者)、Name(插件名字)、Version(插件版本)将会在插件初始化完成时显示
浏览附件6412
其中,Version可以通过new Version修改,如下:
C#:
//插件的版本
public override Version Version => new Version(1, 0, 0, 0);
//public override Version Version => Assembly.GetExecutingAssembly().GetName().Version;
使用new Version()将会显示此方法参数为版本号(例如本例子中的"1.0.0.0")
而使用Assembly.GetExecutingAssembly().GetName().Version获取的是程序集的版本号, 程序集版本号需要在项目属性中修改

注: 如果你使用new Version()作为版本号,将会以你Version()的参数作为版本号,而不是程序集版本
1.右键解决方案资源管理器中的项目(这里是HelloWorld),然后点击属性
浏览附件6407浏览附件6408
2.在属性选项卡中依次找到包—常规—程序集版本
浏览附件6410
3.修改程序集版本即可

插件的构造器

插件的构造器,也叫构造函数构造函数中的代码会比Initialize(初始化)函数更先执行
服务端会先按照读取到插件的顺序(取决于插件的文件名)执行所有插件的构造函数,再按照Order(等下会讲)由小到大执行Initialize(初始化)函数

C#:
//插件的构造器
public Plugin(Main game) : base(game)
{
    base.Order = 1; //插件加载顺序,默认为1,数字越小越先加载
}
通常情况下,构造函数的执行会在TShock初始化之前,如果在构造函数中编写代码(例如建表),可能会导致十分玄学的问题,
所以没有特殊需要下一般插件的构造函数都会直接放空

*在构建函数中修改Order(听不懂没事)

构造函数常常会用来修改插件的初始化顺序—Order
Order是一个int类型的整数,Order可以在取int类型范围内的任何数,当然也可以是负数
Order越小插件的初始化就越优先,Order为1的插件会比Order为2的插件先初始化, TShock的Order为0,
插件的Order在默认情况下(不修改)为1,而TShock的Order为0所以TShock会比其他插件更先初始化
1.编写两个插件,在执行构造函数初始化函数执行时打印文本
浏览附件6415浏览附件6416
2.重命名并安装插件
Order为1的插件在文件夹中更靠前时(以文件名排序),Order为1的插件的构造函数将会先被执行
浏览附件6419浏览附件6420
相反,当Order为2的插件在文件夹中更靠前时(以文件名排序),Order为2的插件的构造函数将会先被执行

浏览附件6417浏览附件6418
由此可知,插件构造函数执行顺序取决于插件的文件名,与Order无关
但是无论文件名如何修改,Order为1的插件总会先初始化,如下图:
浏览附件6421
由此可知,插件初始化函数执行顺序取决于Order,与插件的文件名无关

插件的初始化函数

初始化函数是TShock插件中非常重要的部分,这个函数主要负责插件的初始化,可以用来注册钩子、添加命令、注册REST API命令、初始化配置文件、初始化数据库
C#:
//插件加载时执行的代码
public override void Initialize()
{
    ServerApi.Hooks.ServerChat.Register(this, this.OnChat); //注册钩子
    Commands.ChatCommands.Add(new Command(permissions: new List<string> {""}, cmd: this.Fish, "钓鱼排行")); //添加命令
    TShock.RestApi.Register(new SecureRestCommand("/XSB/GetMap", GetMap, "rest.xsb.admin")); //注册REST API命令
    Config.GetConfig(); //初始化配置文件
    DB.Connect(); //初始化数据库
}

插件的卸载函数

相较于初始化函数,卸载函数显得没什么存在感(你甚至可以不写卸载函数)
但是为了代码规范,还是建议你把注册过的钩子卸载,删除添加的命令
C#:
//插件卸载时执行的代码
protected override void Dispose(bool disposing)
{
     if (disposing)
     {
         ServerApi.Hooks.ServerChat.Deregister(this, this.OnChat);  //卸载钩子
         Commands.ChatCommands.RemoveAll(c => c.CommandDelegate.Method?.DeclaringType?.Assembly == Assembly.GetExecutingAssembly());
         //移除插件添加的命令
     }
     base.Dispose(disposing);
}
 
主题 作者

Cai

Moderator
管理成员
09
186
0

Extra Part.一些额外的东西

本章你将学到:

  • Visual Studio常见奇怪问题解决办法​

  • 创建新的插件项目​

  • 让Visual Studio自动复制插件、重载调试服务器​


Visual Studio常见奇怪问题解决办法


解决方案资源管理器消失

1.在工具栏中选择视图
浏览附件6423
2.点击解决方案资源管理,然后就会发现解决方案资源管理又回来啦!
浏览附件6424
注: 当然输出、错误列表等没了也可以用这个办法

在中间输入代码会删除后面的代码

可能是你按到INS键切换成了OVR模式,此时代码编辑区的右下角就会显示OVR

浏览附件6425

解决办法:按下键盘上的INS键再次切换到INS编辑模式

工具栏下方出现报错横幅

如果你看到如下提示,那么恭喜你,你下载的是正版的Microsoft Visual Studio
浏览附件6426
这些报错会导致代码提示等出现故障

解决办法: 重新启动Visual Studio


创建新的插件项目

1.在解决方案资源管理器中右键解决方案
浏览附件6427
2.选择添加,点击新建项目然后重复和Part1一样的步骤即可
浏览附件6429
3.点击工具栏启动的白色小箭头,再点击配置启动项目
浏览附件6432
4.按照下图修改配置
浏览附件6433


生成后事件(自动复制插件/重启服务器)

1.在解决方案资源管理器中右键项目
浏览附件6452
2.点击属性
浏览附件6453
3在属性选项卡找到生成—事件—生成后事件
浏览附件6454
4.如果你只想自动复制插件在其中输入下面的命令即可
代码:
copy bin\Debug\net6.0\*.dll C:\Users\13110\Desktop\code\TShock144\ServerPlugins
copy bin\Debug\net6.0\*.pdb C:\Users\13110\Desktop\code\TShock144\ServerPlugins
注: C:\Users\13110\Desktop\code\TShock144\ServerPlugins要替换为自己调试服务器的插件目录
(可选)5.自动重启服务器
如果你是像我这样的终极懒鬼,你可以尝试一下下面的方法让你解放双手
1.先在生成后事件加上一句
代码:
taskkill /F /IM TShock.Server.exe
2.新建自启动脚本(如果你已经有了可以跳过这个步骤)
然后编辑个打开记事本编辑以下内容,并保存为编码UTF-8,后缀.bat的文件,放在和TShock.Server.exe同目录

Bash:
chcp 65001
@echo off
@echo.*自启动脚本 by Cai
set restart=1
:restart
set ip=0.0.0.0
set port=7777
set map_path=C:\Users\13110\Desktop\code\TShock144\测试.wld
set lang=7
@echo.*服务器准备启动: 语言: %lang%,IP: %ip%,端口: %port%,地图路径: %map_path%
TShock.Server.exe -lang %lang% -ip %ip% -port %port% -world %map_path%
@echo.*服务器崩溃准备重启, 目前重启次数%restart%
timeout /t 0 /NOBREAK
set/a restart=restart+1
goto restart
注: map_path要改成自己地图的路径(注意\使用/可能无法识别)port改成自己想要的端口,ip请不要更改(0.0.0.0是绑定本机所有IP的意思,请你不要自以为是的修改),lang 7是中文语言启动(你没必要修改)
用这个脚本启动服务器,然后编译插件就会自动帮你重启服务器啦!
使用效果

[BILIBILI]BV1J8411z7ut[/BILIBILI]
 
顶部