Rimworld Mod制作教程1 认识Mod结构
文章目录
- 废话
- 核心内容
- 1 认识mod结构
- 1.1 mod结构
- 2 认识开发工具
- 2.1 开发工具
- 2.2 visual studio开发环境
- 2.3 程序集构建
- 2.4 修改编译输出路径
- 2.5 添加引用库
- 2.6 编写代码及编译
- 3 案例
- 3.1 mod结构构建
- 3.2 修改简介
- 3.3 创建数据定义
- 3.4 编写C#代码
- 3.5 测试
- 3.6 本地化
废话
之前就有想尝试过mod制作,结果在网上看了N多教程还是不知道从何下手。后来想到解铃还须系铃人,无奈去看英文的文档,觉得会详细一些。
所以本篇参考了 wiki上的一篇教程。但是即便是非常详细的教程,对于第一次尝试的人来说还是有很多容易踩坑的地方,所以本篇记录踩坑过程。
核心内容
1 认识mod结构
1.1 mod结构
- Mod根目录
- Abount(存放mod的简介和mod的标题图片)
- Defs(数据定义)
- Assemblies(mod代码打包后的库文件)
- Languages(翻译的核心目录)
- Textures(纹理,mod中对象的素材)
- Sounds(声音)
- Patches(针对其他mod的补丁)
- Source(mod的源码,一般没有作者好心给出源码,不过我们可以反编译就是了,很少有加密的mod)
2 认识开发工具
2.1 开发工具
visual studio:用于编写mod核心代码
vscode:用于编辑xml数据定义
dsnpy:用于反编译原游戏或其他mod的源代码来学习新姿势
下载地址请直接百度, 要学会善用搜索引擎
本篇使用以上落后ide开发,目前有更好用的开发工具jetbrain rider, 体积更轻便,运行更快,并且可以完成上面3个工具的功能,你有什么理由拒绝最新的工具呢?后面会找时间写一篇教程介绍如何使用rider开发mod
2.2 visual studio开发环境
百度下载,安装时勾选.net桌面开发,否则无法创建C#程序集,也就是无法打包dll出来。剩下的一路下一步。
2.3 程序集构建
我们在vs上新建一个类库(.net framework),并把名字改成命名空间SR
wiki的教程提醒我们使用.net framework 3.5的框架版本,我尝试之后发现原游戏的版本已经高于3.5,于是我反编译其他mod看了一下其他作者使用的版本,选择了相同4.6.1
2.4 修改编译输出路径
在properties中点生成,把dll输出路径改到我们的mod路径E:\steam\steamapps\common\RimWorld\Mods\TestGun\Assemblies里
接下来点击高级,设置内部编译器错误报告为无,这样做是为了避免我们写出一些小bug导致整个游戏崩溃。
2.5 添加引用库
点击引用,选择原游戏下RimWorld\RimWorldWin64_Data\Managed路径下UnityEngine,UnityEngine.CoreModule和Assembly-CSharp.dll三个库文件。
右键选择引用文件,在属性中取消“复制到本地”,否则编译时会多复制一堆引用库文件,而这些文件已经被原游戏添加过一次了。
下图有部分内容是错的,实际不需要引用这么多库文件,只需要上面提到的3个,以及自带的部分。
2.6 编写代码及编译
代码编写过程略。
右键方案点击build即可打包编译。
3 案例
此部分暂时只做了解,能看懂多少算多少。
3.1 mod结构构建
为了区分哪些变量是游戏中的关键词,我更换了一下命名,我们的mod叫做TestGun(测试枪).
按照上面的教程,构建一套mod文件结构。并丢到rimworld的mod文件夹下,在这个文件夹下的mod会被游戏识别,并且可以随时发布。
3.2 修改简介
然后进入About目录,拖进去一张图片改名叫Preview.png,再创建一个txt文件,然后改成About.xml,如果你看不到.xml的后缀,在上方点击查看–选项,取消隐藏已知文件类型的扩展名
然后打开About.xml
复制以下代码,分别是这个mod的名字,作者,版本和描述
<?xml version="1.0" encoding="utf-8"?>
<ModMetaData><name>TestGun</name><author>Shadowrabbit</author><supportedVersions><li>1.1</li></supportedVersions><description>测试创造mod物品</description>
</ModMetaData>
完成了这一步,就可以在游戏中看到我们的mod
这里非常推荐一种mod命名规则:
[{作者名缩写}{支持的版本号}]{mod名称}
例如:[SR1.2]Test Gun
这种规范可以让人一眼了解这个mod是否适用于当前版本
3.3 创建数据定义
接下来在Defs那个文件夹内创建一个ThingDefs的文件夹,然后在ThingDefs内创建一个xml文件叫做RangedWeapon_TestGun
这是原游戏的命名规则,不遵守也可以正常运行,但我还是推荐认真一点命名。
接下来在xml中更改一下格式。
<?xml version="1.0" encoding="utf-8"?>
<Defs></Defs>
然后我们要去“抄”一下原游戏中某个枪的xml数据,这样我们才能知道默认都有哪些数据能修改。
我们在vscode中添加一个目录E:\steam\steamapps\common\RimWorld\Data\Core,这是我的游戏目录仅供参考,要填自己电脑安装的目录
core是原游戏的核心,可以发现它的结构和我们mod的定义是完全一样的。打开Defs可以找到所有的物品数据定义,但是太多了反而不知道从哪看起。我们在core中搜索Revolver(手枪),把手枪的数据复制过来
为了方便观察,我加了一些翻译注释
<?xml version="1.0" encoding="utf-8"?>
<!-- 子弹的数据 -->
<Defs>
<!-- 继承了哪个物品 --><ThingDef ParentName="BaseBullet"><!-- 代码中物品的名字 --><defName>Bullet_Revolver</defName><!-- 游戏中物品显示的名字 --><label>revolver bullet</label><graphicData><!-- 使用的纹理贴图 --><texPath>Things/Projectile/Bullet_Small</texPath><!-- 使用哪个图形类的代码 --><graphicClass>Graphic_Single</graphicClass></graphicData><projectile><!-- 子弹类型 --><damageDef>Bullet</damageDef><!-- 子弹基础伤害 --><damageAmountBase>12</damageAmountBase><!-- 取消射击的反应速度 --><stoppingPower>1</stoppingPower><!-- 子弹的速度 --><speed>55</speed></projectile></ThingDef><!-- 枪的数据 --><ThingDef ParentName="BaseHumanMakeableGun"><defName>Gun_Revolver</defName><label>revolver</label><!-- 描述 --><description>An ancient pattern double-action revolver. It's not very powerful, but has a decent range for a pistol and is quick on the draw.</description><graphicData><texPath>Things/Item/Equipment/WeaponRanged/Revolver</texPath><graphicClass>Graphic_Single</graphicClass></graphicData><!-- UI缩放 --><uiIconScale>1.4</uiIconScale><soundInteract>Interact_Revolver</soundInteract><!-- 个人猜测是艺术系统的标签 --><thingSetMakerTags><li>RewardStandardQualitySuper</li></thingSetMakerTags><!-- 基础属性 --><statBases><!-- 制作的工作量 --><WorkToMake>4000</WorkToMake><!-- 物品大小 --><Mass>1.4</Mass><!-- 贴脸的命中率 --><AccuracyTouch>0.80</AccuracyTouch><!-- 短距离命中率 --><AccuracyShort>0.75</AccuracyShort><!-- 中距离命中率 --><AccuracyMedium>0.45</AccuracyMedium><!-- 远距离命中率 --><AccuracyLong>0.35</AccuracyLong><RangedWeapon_Cooldown>1.6</RangedWeapon_Cooldown></statBases><!-- 武器标签 --><weaponTags><li>SimpleGun</li><li>Revolver</li></weaponTags><!-- 消耗列表 --><costList><Steel>30</Steel><ComponentIndustrial>2</ComponentIndustrial></costList><recipeMaker><!-- 技能需求 --><skillRequirements><Crafting>3</Crafting></skillRequirements></recipeMaker><!-- 动作 --><verbs><li><!-- 射击 --><verbClass>Verb_Shoot</verbClass><!-- 是否有标准命令 --><hasStandardCommand>true</hasStandardCommand><!-- 子弹类型 --><defaultProjectile>Bullet_Revolver</defaultProjectile><!-- 预热时间 --><warmupTime>0.3</warmupTime><!-- 射击距离 --><range>25.9</range><!-- 射击时使用的音效 --><soundCast>Shot_Revolver</soundCast><!-- 中弹时的音效 --><soundCastTail>GunTail_Light</soundCastTail><!-- 枪口光效的缩放 --><muzzleFlashScale>9</muzzleFlashScale></li></verbs><tools><li><label>grip</label><capacities><li>Blunt</li></capacities><power>9</power><cooldownTime>2</cooldownTime></li><li><label>barrel</label><capacities><li>Blunt</li><li>Poke</li></capacities><power>9</power><cooldownTime>2</cooldownTime></li></tools></ThingDef>
</Defs>
到这里为止就可以使用xml修改枪的各种参数,以及发射什么样的子弹(需要去core里再查查都有什么子弹,然后填在defaultProjectile里),还可以更换枪的贴图和音效。更多的物品参数需要查查wiki,然后翻译+自己理解,还有多看看core中的xml代码。
我们本次要制作的是带有瘟疫效果的枪,我们需要创建一种新的子弹,所以我们要在子弹的def里加几个新参数与C#代码交互
在子弹的xml数据中添加
<ThingDef Class="SR.ThingDef_TestBullet" ParentName="BaseBullet">
和三个自定义的新属性
<!-- 触发瘟疫的概率 --><AddHediffChance>0.5</AddHediffChance><!-- Hediff这个词是游戏里独一无二的名字,字典里查不到,他的含义是某个部位上的状态,比如感染,仿生部位,瘟疫Plague是原版游戏其中的一种 --><HediffToAdd>Plague</HediffToAdd><!-- 该物品在C#中使用的逻辑类 --><thingClass>SR.Projectile_PlagueBullet</thingClass>
然后修改子弹的命名避免和原版一样,修改后如下
<?xml version="1.0" encoding="utf-8"?>
<!-- 子弹的数据 -->
<Defs>
<!--该物品在C#中使用的数据类 继承了哪个物品 --><ThingDef Class="SR.ThingDef_TestBullet" ParentName="BaseBullet"><!-- 代码中物品的名字 --><defName>Bullet_TestBullet</defName><!-- 游戏中物品显示的名字 --><label>测试子弹</label><graphicData><!-- 使用的纹理贴图 --><texPath>Things/Projectile/Bullet_Small</texPath><!-- 使用哪个图形类的代码 --><graphicClass>Graphic_Single</graphicClass></graphicData><projectile><!-- 子弹类型 --><damageDef>Bullet</damageDef><!-- 子弹基础伤害 --><damageAmountBase>12</damageAmountBase><!-- 取消射击的反应速度 --><stoppingPower>1</stoppingPower><!-- 子弹的速度 --><speed>55</speed></projectile><!-- 触发瘟疫的概率 --><addHediffChance>0.5</addHediffChance><!-- Hediff这个词是游戏里独一无二的名字,字典里查不到,他的含义是某个部位上的状态,比如感染,仿生部位,瘟疫Plague是原版游戏其中的一种,我们定义的这个变量意义是储存附加给中弹生物的hediff类型 --><hediffToAdd>Plague</hediffToAdd><!-- 该物品在C#中使用的逻辑类 --><thingClass>SR.Projectile_TestBullet</thingClass></ThingDef><!-- 枪的数据 --><ThingDef ParentName="BaseHumanMakeableGun"><defName>SR_Gun_TestGun</defName><label>影兔的测试枪</label><!-- 描述 --><description>影兔测试瘟疫效果的枪</description><graphicData><texPath>Things/Item/Equipment/WeaponRanged/Revolver</texPath><graphicClass>Graphic_Single</graphicClass></graphicData><!-- UI缩放 --><uiIconScale>1.4</uiIconScale><!-- 交互的音效 --><soundInteract>Interact_Revolver</soundInteract><!-- 个人猜测是艺术系统的标签 --><thingSetMakerTags><li>RewardStandardQualitySuper</li></thingSetMakerTags><!-- 基础属性 --><statBases><!-- 制作的工作量 --><WorkToMake>4000</WorkToMake><!-- 物品大小 --><Mass>1.4</Mass><!-- 贴脸的命中率 --><AccuracyTouch>0.80</AccuracyTouch><!-- 短距离命中率 --><AccuracyShort>0.75</AccuracyShort><!-- 中距离命中率 --><AccuracyMedium>0.45</AccuracyMedium><!-- 远距离命中率 --><AccuracyLong>0.35</AccuracyLong><RangedWeapon_Cooldown>1.6</RangedWeapon_Cooldown></statBases><!-- 武器标签 --><weaponTags><li>SimpleGun</li><li>Revolver</li></weaponTags><!-- 消耗列表 --><costList><Steel>30</Steel><ComponentIndustrial>2</ComponentIndustrial></costList><recipeMaker><!-- 技能需求 --><skillRequirements><Crafting>3</Crafting></skillRequirements></recipeMaker><!-- 动作 --><verbs><li><!-- 射击 --><verbClass>Verb_Shoot</verbClass><!-- 是否有标准命令 --><hasStandardCommand>true</hasStandardCommand><!-- 子弹类型 --><defaultProjectile>Bullet_TestBullet</defaultProjectile><!-- 预热时间 --><warmupTime>0.3</warmupTime><!-- 射击距离 --><range>25.9</range><!-- 射击时使用的音效 --><soundCast>Shot_Revolver</soundCast><!-- 中弹时的音效 --><soundCastTail>GunTail_Light</soundCastTail><!-- 枪口光效的缩放 --><muzzleFlashScale>9</muzzleFlashScale></li></verbs><tools><li><label>grip</label><capacities><li>Blunt</li></capacities><power>9</power><cooldownTime>2</cooldownTime></li><li><label>barrel</label><capacities><li>Blunt</li><li>Poke</li></capacities><power>9</power><cooldownTime>2</cooldownTime></li></tools></ThingDef>
</Defs>
为了避免与其他mod命名冲突,我使用SR作为代码的命名空间,SR.XX表示C#类,SR_XX表示xml数据,这也是原游戏默认的命名规范,有两处SR.XX的数据是与C#进行交互的,命名必须一致。
至此xml部分就结束了。
3.4 编写C#代码
using RimWorld;
using Verse;
namespace SR
{public class Projectile_TestBullet:Bullet{}
}
using RimWorld;
using Verse;namespace SR
{public class ThingDef_TestBullet:ThingDef{}
}
我们把新添加的字段写入数据类中,名字要与xml中的一致,不需要给新变量赋默认值,因为会被xml中的数据覆盖,所以addHediffChance运行时为我们在xml中设置的0.5
using RimWorld;
using Verse;namespace SR
{public class ThingDef_TestBullet:ThingDef{public float addHediffChance; //默认值会被xml覆盖public HediffDef hediffToAdd;}
}
题外话,说一个wiki上关于老版本的问题,如果HediffDef类型的数据有默认值的话,在1.0版本之后是会报错的,因为这个时候HediffDefOf还没有初始化。不过假如你就是想留默认值也有解决方法,有一个回调函数,我们在回调的时候重新赋值即可。
public override void ResolveReferences()
{base.ResolveReferences();hediffToAdd = HediffDefOf.Plague;
}
之后是逻辑类,先定义一个变量存它的数据
#region data
public ThingDef_TestBullet ThingDef_TestBullet
{get{//底层通过名字读取了我们定义的ThingDef_TestBullet这个xml格式的新数据,并存放到了this.def中,我们将this.def拆箱拿到我们定义好的ThingDef_TestBullet格式数据return this.def as ThingDef_TestBullet}
}
#endregion
我们需要知道原版子弹击中目标会执行什么流程,打开dnspy反编译Assembly-CSharp.dll,原游戏所有代码都在Assembly-CSharp.dll中,然后搜索bullet子弹,可以看到子弹的源码里只有一个可以重载的方法impact,根据英文的意思知道他是中弹后执行的逻辑,里面写了什么我们暂时不需要关心,我们在测试子弹的类中继承子弹这个类,然后重写impact方法,在原逻辑执行完毕后添加我们关于瘟疫的设定
关于添加瘟疫的设定,wiki上给出了代码,我详细解读一下贴出来
using RimWorld;
using Verse;
namespace SR
{public class Projectile_TestBullet : Bullet{#region datapublic ThingDef_TestBullet ThingDef_TestBullet{get{//底层通过名字读取了我们定义的ThingDef_TestBullet这个xml格式的新数据,并存放到了this.def中,我们将this.def拆箱拿到我们定义好的ThingDef_TestBullet格式数据return this.def as ThingDef_TestBullet;}}#endregionprotected override void Impact(Thing hitThing){//子弹的影响,底层实现了伤害 击杀之类的方法,感兴趣的话可以用dnspy反编译Assembly-Csharp.dll研究里面到底写了什么base.Impact(hitThing);//绝大多数mod报错都是因为没判断好非空,写注释和判断非空是好习惯//大佬在这里用了一个语法糖hitThing is Pawn hitPawn//如果hitThing可以被拆箱为Pawn的话 这个值返回true并且会声明一个变量hitPawn=hitThing as Pawn//否则返回false hitPawn是nullif (ThingDef_TestBullet != null && hitThing != null && hitThing is Pawn hitPawn){var rand = Rand.Value; //这个方法封装了一个返回0%-100%随机数的函数//触发瘟疫if (rand <= ThingDef_TestBullet.addHediffChance){//在屏幕左上角显示提示,translate方法用于翻译不同语言之后再说,MessageTypeDefOf要设置一种事件Messages.Message("{0}使用测试枪导致{1}感染瘟疫".Translate(this.launcher.Label,hitPawn.Label),MessageTypeDefOf.NeutralEvent);//判断一下目标是否已经触发了瘟疫效果var plagueOnPawn = hitPawn.health?.hediffSet?.GetFirstHediffOfDef(ThingDef_TestBullet.hediffToAdd);//我们为本次触发的瘟疫随机生成一个严重程度var randomSeverity = Rand.Range(0.15f, 0.30f);//已经触发瘟疫if (plagueOnPawn != null){//严重程度叠加,超过100%会即死plagueOnPawn.Severity += randomSeverity;}else{//我们调用HediffMaker.MakeHediff生成一个新的hediff状态,类型就是我们之前设置过的HediffDefOf.Plague瘟疫类型Hediff hediff = HediffMaker.MakeHediff(ThingDef_TestBullet.hediffToAdd, hitPawn);//设置这个状态的严重程度hediff.Severity = randomSeverity;//把状态添加到被击中的目标身上hitPawn.health.AddHediff(hediff);}}//本次没有触发else{//这个方法可以在某个位置(这里是被击中目标的身旁)弹出一小行字,比如未击中,击中头部之类的,也是可以MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "{0}未触发瘟疫".Translate(hitPawn.Label), 12f);}}}}
}
至此新武器的mod就制作完毕了,我们选择打包生成新的dll,根据之前设置的目录,会打包在Assemblies中。
3.5 测试
很遗憾我们的新武器虽然已经有了数据,但是没有任何方法可以在游戏中自然生成,我们需要借助开发者模式来测试我们的新枪支,首先打开开发者模式(记得加载我们的mod),随便建个新地图,然后在上方选择open debug actions menu
在里面找到spawn weapon – SR_Gun_TestGun,然后把它丢在地上,让我们的角色捡起来,然后对着自己的小人开一枪试试,刚好触发了瘟疫效果
未触发的log也正常显示
叠加到100%瘟疫会直接死亡,也是正常的。至此新武器的制作就完成了。
3.6 本地化
本地化就是指翻译成各种语言,我们把之前message中的内容用一个变量代替,让这个变量在各种语言下显示不同的文字就可以了。
Messages.Message("{0}使用测试枪导致{1}感染瘟疫".Translate(this.launcher.Label,hitPawn.Label),MessageTypeDefOf.NeutralEvent);
我们更改为
Messages.Message("SR_Message_TestBullet_Success".Translate(this.launcher.Label,hitPawn.Label),MessageTypeDefOf.NeutralEvent);
之后在Languages中创建ChineseSimplified目录,然后在ChineseSimplified目录下创建Keyed目录,再在Keyed目录下创建一个xml文件,我们命名为SR_TestGun_Keys.xml(名称可以随便取,但还是遵循规范).复制默认的语言数据结构
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
</LanguageData>
之后添加两个新的key,对应我们上一步设置的key名字
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData><SR_Message_TestBullet_Success></SR_Message_TestBullet_Success><SR_Mote_TestBullet_Fail></SR_Mote_TestBullet_Fail>
</LanguageData>
再把中文的翻译写进去
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData><SR_Message_TestBullet_Success>{0}使用测试枪导致{1}感染瘟疫</SR_Message_TestBullet_Success><SR_Mote_TestBullet_Fail>{0}未触发瘟疫</SR_Mote_TestBullet_Fail>
</LanguageData>
至此中文版本就完成了,如果要加入英文版的话,就在Luaguages下创建English目录等等,然后创建相同的文件,在值里填入英文对应的文本即可,游戏会根据用户选择的语言自动选择语言数据加载。
源码下载
如果这篇文章对你有帮助,点赞收藏支持一下呗!
Rimworld Mod制作教程1 认识Mod结构相关推荐
- 【饥荒mod制作吧第四篇】mod制作教程系列
直奔主题算了! [1]吧内教程 第一部分: @XWJ249 毕竟教程基本都是他做的. 2016丨4-14丨[索引]我的mod教程 http://tieba.baidu.com/p/448580475 ...
- 饥荒mod制作教程--物品(武器)--01
武器模板(这是一个联机版的mod,要改成单机版的还需要做部分修改): 链接:https://pan.baidu.com/s/1P0lBxVRdQ3oV9VAB1-Kfhg 密码:n2sa 首先确定武器 ...
- 我的世界java怎么开创造,MOD制作教程JAVA篇
您尚未登录,立即登录享受更好的浏览体验! 您需要 登录 才可以下载或查看,没有帐号?注册(register) x 本帖最后由 heidada 于 2011-5-12 21:33 编辑 首先我阅读了这个 ...
- transport fever mod制作教程
前言 转载自贴吧 相信有不少喜欢火车的朋友都听说过transport fever这款游戏.相比于模拟火车系列来说,更自由的建设环境,更开放的操作方式和更多种类的交通工具的运用,使得这个游戏更加吸引人, ...
- Rimworld Mod制作教程3 使用Xpath制作patch(补丁)
文章目录 废话 核心内容 1 使用Xpath制作patch(补丁) 1.1 基本格式 1.2 手术类型 1.3 ~~偷窥~~ 参考他人代码 废话 rimworld在A17版本后提供了一个新的编写mod ...
- Rimworld Mod制作教程2 创建数据定义
文章目录 废话 核心内容 1 创建数据定义 1.1 定义一个新的抽象物品 手办基类 1.2 源源不断的手办(Garage Kid) 1.3 新材料(Stuff) 1.4 添加配方(Recipe) 1. ...
- Rimworld Mod制作教程12 集群AI机制介绍
文章目录 简介 什么是集群AI? RimWorld源码中有没有一个节点用于集群AI? 职责节点 集群AI如何与职责节点联系? 集群AI LordToil与Toil的关系? 集群AI的状态机 简介 相信 ...
- 饥荒mod制作教程--物品(食物)该篇主讲贴图--01
主要工具 mod tools(steam工具库可找到,用来上传mod,自动打包Spriter制作的动画文件为***.zip,转换PNG图片为***.tex图片) spriter(用于制作动画包括静态图 ...
- python之torchlight使用_《火炬之光2》功能型MOD制作教程
玩家首先要准备好几样工具,分别是PAK处理工具.文档转换工具.以及Python和Murmurhash,就可以开始制作功能型MOD啦. M准备工作: 1. 火炬之光Ⅱ游戏 2. PAK处理工具 3. 文 ...
最新文章
- 错误消息“禁止您没有访问此服务器上的权限/”(关闭)
- 扩展 日历_2021少林日历 | 以最美的方式记录时光
- CM: How to get the complete url of a product attachment
- OSPF——路由聚合【(汇总)含配置命令】||地址汇总计算方法——详解
- calendar操作详解
- java复制和上传_java文件上传复制等功能
- SIGIR2021推荐系统论文集锦(附论文原文及代码链接)
- 开源论坛程序 vBulletin 被曝严重且详情不明的漏洞,请立即修复
- 设计一台模型计算机 实现下列指令系统,基本模型机的设计与实现1
- 带grub的软盘镜像制作
- AIGC:自动化内容生成,AI 的下一个引爆点?
- 2011最新笔记本、一体机显卡性能排行
- 计算机一级字幕设置,如何开启电脑哔哩哔哩中的CC字幕功能
- 卡特兰数(Catalan UVa 991 10303 10007 1478)[11]
- TCP四次挥手的2MSL详解
- C语言文件操作(含详细步骤)
- 【规律】Cunning Friends
- python数据汇总_Python,将数据框中的每日数据汇总到每月和每季度
- L1-040. 最佳情侣身高差
- 安装破解PyCharm 2018.3.x
热门文章
- java 内置jetty_java内嵌jetty服务器
- 京东抢购失败?试试用Python准时自动抢购!七夕秒抢种礼物!
- Python入门经典笔记之安装numpy和matplotlib遇到的问题
- 中国制霸生成器火了/ 马斯克香水被炒至原价10倍/ 闽南话翻英语算法来了… 今日更多新鲜事在此...
- 深度学习寿命预测技术路线
- 获得“网管师”资格证书,开启新的网管职业生涯
- home assistant用esphome添加温湿度传感器
- [唐诗]秋夜喜遇王处士-王绩
- 干货 | 对象存储的跨地域复制概述
- 牛客网 - 在线编程 - 华为机试 - 求最小公倍数