工具
ILSpy_6.0 https://github.com/icsharpcode/ILSpy
Visual Studio 2017
需求是对某款单机游戏做本地修改,查看内置的游戏数值,便于制定游戏策略。
PS:试用过dnSpy但是某种原因修改不方便且保存出错。
核心.net代码位于下述路径:
\TPH\TPH_Data\Managed\Assembly-CSharp.dll
使用ILSpy载入dll,傻瓜操作"保存代码",得到工程"Assembly-CSharp.dll.csproj"。
运用VS打开Assembly-CSharp.dll.csproj项目文件。
之后的编程类似C#。
解决几个问题。
/langversion的选项8.0无效。
疑似是VS2017不支持8.0以上,因为懒得更新IDE,就做点别的修改。
使用文本编辑器打开Assembly-CSharp.dll.csproj,修改
项的值为7.3。 同时在VS内,右键项目,属性,生成,高级,语言版本,选择c#7.3。
不选用低版本是因为“命名参数规范必须出现在所有固定参数都已指定完毕后。请使用语言版本 7.2 或更高版本,以允许非尾随命名参数。”
部分引用问题,需要把原\managed\目录下的各种dll文件复制到工程目录下的references目录中,在VS内添加相应引用。
未能找到类型或命名空间名“IReadOnlyList<>”(是否缺少 using 指令或程序集引用?)
网上查了一下是在.net 4.5中引入的类,目标框架改成4.5就行了。(原本是4.0)
无法在此范围中声明名为“item”的局部变量或参数,因为该名称在封闭局部范围中用于定义局部变量或参数 \TH20.ExtContent\WorkshopInstalledItem.cs,93行。
原来的程序员写的item已经是局部变量名了,不能作为匿名函数里的变量名。
把"item"修改成任意不重复的名字就行,比如"_item"。
在 checked 模式下,运算在编译时溢出
TH20\RequestResponseContainer.cs , 48行
RequestResponseContainer这个类是TPH在4月份刚更新的,我看了下3.14备份的dll里面没有这个类。
作用不明。
解决方案是改成unchecked模式去运算。
------------
添加,新建文件夹MyUtils,然后添加现有项。
一共写了5个类。
先加几个成员对象、成员方法。
在TH20\Patient.cs类文件中,添加自定义成员。
//自定义
public float firstDiagnosisCertainty_ = 0f;
public DiagnosisCalculationBreakdown firstDiagnosisBreakdown_ {
get;set;
}
public DiagnosisCalculationBreakdown lastDiagnosisBreakdown_{
get;set;
}
public List lifeProcessLog_;//=new List();
public int successlog_ = -1;
//自定义结束
在TH20\Character.cs类文件中,添加成员方法。
public string GetCharacterFullName()
{ //自定义方法
//效果为返回"中文名_中文姓"
//内置的函数返回的是"中文名点中文姓",但点不能作为windows系统的文件名字符,不符合要求。
return string.Format("{0}_{1}",FirstName.Translation,LastName.Translation);
}
在TH20\IllnessDefinition.cs类文件中,DiagnosisType成员类下,添加成员_typeName。
public class IllnessDefinition : IPriceModifier
{
[UsedImplicitly(ImplicitUseKindFlags.Assign | ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature, ImplicitUseTargetFlags.Members)]
public class DiagnosisType
{
public float _durationMultiplier = 1f;
public float _diagnosisCertaintyIncrease = 10f;
public SharedInstance _room;
//自定义
public string _typeName => Enum.GetName(typeof(RoomDefinition.Type), _room.Instance._type);
//自定义结束
}
类似地,在TH20\IllnessDefinition.cs类文件中,TreatmentType成员类下,添加成员_typeName。
public class TreatmentType
{
public int _treatmentCost = 100;
public float _durationMultiplier = 1f;
public float _effectiveness = 50f;
public float _effectivenessMax = 100f;
public SharedInstance _room;
public SharedInstance _research;
//自定义
public string _typeName => Enum.GetName(typeof(RoomDefinition.Type), _room.Instance._type);
//自定义结束
}
在TH20\DiagnosisCalculationBreakdown.cs类文件中,添加成员
public struct DiagnosisCalculationBreakdown
{
public float Certainty;//单次诊断的最终certainty
public float Illness;//疾病基础
public float RoomMultiplier;
public float ItemMultiplier;
public float RevistGP;
public float UpgradeMultiplier;
public float StaffMultiplier;
//自定义
//补充成员
public IllnessDefinition.DiagnosisType DiagnosisType;
//自定义结束
}
----
添加入口。
在入口处获得想要的信息。
在TH20\DiagnosisTreatmentComponent.cs中,Process()函数下,添加一行调用tracker的代码。
public void Process()
{
Patient owner = GetOwner();
float diagnosisCertainty = owner.DiagnosisCertainty;
float num = (owner.Happiness != null) ? owner.Happiness.Value() : 0f;
bool flag = owner.ReasonUsingRoom == ReasonUseRoom.Diagnosis;
bool flag2 = owner.ReasonUsingRoom == ReasonUseRoom.Treatment;
if (flag)
{
ProcessDiagnosis(owner);
//自定义开始
diagnosisTracker.writeDiagnosisLog(owner,_room);
//自定义结束
}
然后需要去MyUtils\diagnosisTracker.cs中,将_enable设为true才能正常使用tracker。
疾病数据整理。
在TH20\CharacterManager.cs中,CreatePatient函数下,添加
public Patient CreatePatient(IllnessDefinition illnessDefinition, Vector3 position, PatientDefinition patientDefinition)
{
Character.Sex sex = (UnityEngine.Random.Range(0, 2) != 0) ? Character.Sex.Female : Character.Sex.Male;
CharacterName name = _nameGenerator.Generate(sex);
int numSpawned = _totalIllnessSpawnCount.ContainsKey(illnessDefinition) ? _totalIllnessSpawnCount[illnessDefinition] : 0;
Patient patient = new Patient(patientDefinition, illnessDefinition.ChooseDefinition(numSpawned), _level, _visualManager, sex, name, TakeNextCharacterID(), position);
//自定义
//每次创建一个病人时,将疾病更新到全局字典中
IllnessStorage.Instance.Add(patient.Illness);
IllnessStorage.Instance.Check();
FileIOTools.WriteLine(TimeTools.Time + " illness storage checked", "illstorage.txt");
//自定义结束