开发教程 使用dnSpy修改版本号实现跨版本进入服务器

KangKangLoveS

Lv2
LV
0
 
IP属地
安徽省
2020/06/26
3
0
  • · 发布于未知
1、客户端方面
[适用于进入指定版本的服务器]
由于版本之间的游戏内容差异,会出现不可预料的Bug!!!
原理:修改SendData方法内向服务器发送的版本号.
如下:在 Terraria.NetMessage 类中找到 SendData 方法
public static void SendData(int msgType, int remoteClient = -1, int ignoreClient = -1, NetworkText text = null, int number = 0, float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0, int number6 = 0, int number7 = 0)
{
if (Main.netMode == 0)
{
return;
}
int num = 256;
if (text == null)
{
text = NetworkText.Empty;
}
if (Main.netMode == 2 && remoteClient >= 0)
{
num = remoteClient;
}
MessageBuffer obj = NetMessage.buffer[num];
lock (obj)
{
BinaryWriter writer = NetMessage.buffer[num].writer;
if (writer == null)
{
NetMessage.buffer[num].ResetWriter();
writer = NetMessage.buffer[num].writer;
}
writer.BaseStream.Position = 0L;
long position = writer.BaseStream.Position;
writer.BaseStream.Position += 2L;
writer.Write((byte)msgType);
switch (msgType)
{
case 1:
writer.Write("Terraria" + 248.ToString()); //将这里的248改为对应版本 示例:244为1.4.3.2,234为1.4.1.2
break; //省略后面的代码
将上面的 248 改为对应版本即可.


2、服务端方面
[适用于实现允许客户端跨版本加入服务器]
由于版本之间的游戏内容差异,会出现不可预料的Bug!!!
原理:修改GetData方法内对客户端发送的版本号的判断语句.
如下:在 Terraria.MessageBuffer 类中找到 GetData 方法
public void GetData(int start, int length, out int messageType)
{
if (this.whoAmI < 256)
{
Netplay.Clients[this.whoAmI].TimeOutTimer = 0;
}
else
{
Netplay.Connection.TimeOutTimer = 0;
}
int num = start + 1;
byte b = this.readBuffer[start];
messageType = (int)b;
if (b >= 141)
{
return;
}
Main.ActiveNetDiagnosticsUI.CountReadMessage((int)b, length);
if (Main.netMode == 1 && Netplay.Connection.StatusMax > 0)
{
Netplay.Connection.StatusCount++;
}
if (Main.verboseNetplay)
{
for (int i = start; i < start + length; i++)
{
}
for (int j = start; j < start + length; j++)
{
byte b2 = this.readBuffer[j];
}
}
if (Main.netMode == 2 && b != 38 && Netplay.Clients[this.whoAmI].State == -1)
{
NetMessage.TrySendData(2, this.whoAmI, -1, Lang.mp[1].ToNetworkText(), 0, 0f, 0f, 0f, 0, 0, 0);
return;
}
if (Main.netMode == 2)
{
if (Netplay.Clients[this.whoAmI].State < 10 && b > 12 && b != 93 && b != 16 && b != 42 && b != 50 && b != 38 && b != 68)
{
NetMessage.BootPlayer(this.whoAmI, Lang.mp[2].ToNetworkText());
}
if (Netplay.Clients[this.whoAmI].State == 0 && b != 1)
{
NetMessage.BootPlayer(this.whoAmI, Lang.mp[2].ToNetworkText());
}
}
if (this.reader == null)
{
this.ResetReader();
}
this.reader.BaseStream.Position = (long)num;
switch (b)
{
case 1:
if (Main.netMode != 2)
{
return;
}
if (Main.dedServ && Netplay.IsBanned(Netplay.Clients[this.whoAmI].Socket.GetRemoteAddress()))
{
NetMessage.TrySendData(2, this.whoAmI, -1, Lang.mp[3].ToNetworkText(), 0, 0f, 0f, 0f, 0, 0, 0);
return;
}
if (Netplay.Clients[this.whoAmI].State != 0)
{
return;
}
if (!(this.reader.ReadString() == "Terraria" + 234)) //在这里更改你需要的判断,如允许1.4.1.2后的版本加入,如下(随手写的,可能有语法错误)
//if(!((int)this.reader.ReadString().Replace("Terraria","").Trim() >= 234))
{
NetMessage.TrySendData(2, this.whoAmI, -1, Lang.mp[4].ToNetworkText(), 0, 0f, 0f, 0f, 0, 0, 0);
return; // 省略后面的代码
将上面的if判断条件改为你需要的即可
[不推荐这种方法,最好是用插件在服务端内实现相同的功能]

[吐槽一下插入代码的有BUG,插入后只有一行(只能手动染色了)]
 
最后编辑:

* 这是一则由 Google AdSense 自动推荐的广告,与本站无关,不对其真实性与可靠性负责

顶部