当创建Valheim模组时,有时需要在游戏客户端和服务器之间发送自定义数据。使用BepInEx和Jotunn等工具,你可以创建自定义的远程过程调用(RPC)来实现这一目标。这个示例将演示如何创建一个Valheim模组,用于在游戏客户端和服务器之间发送字符串数据。
前提条件:
在开始之前,确保已经安装了以下工具:
步骤1:设置模组项目
首先,创建一个新的C#项目,引用BepInEx和Jotunn库。确保项目的基础结构已经配置好。
步骤2:创建模组类
在项目中创建一个新的类,用于定义模组。此类必须继承BaseUnityPlugin
,并包含必要的属性和方法。以下是示例代码:
using BepInEx;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using System;
using UnityEngine;
using System.Collections;
namespace YourPluginNamespace
{
[BepInDependency(Jotunn.Main.ModGuid)]
[BepInPlugin(mod_GUID, mod_NAME, mod_VERSION)]
public class YourPluginName : BaseUnityPlugin
{
private const string mod_GUID = "YourPluginNamespace.YourPluginName";
private const string mod_NAME = "你的模组名称";
private const string mod_VERSION = "1.0.0";
private readonly Harmony harmony = new Harmony(mod_GUID);
private static CustomRPC myCustomRPC;
[Obsolete]
private void Awake()
{
Harmony.DEBUG = true;
Logger.LogInfo($"模组 {mod_GUID} 已加载!");
harmony.PatchAll();
}
// 其他模组方法和代码...
}
}
确保替换YourPluginNamespace
和YourPluginName
为你自己模组的命名空间和名称。
步骤3:初始化CustomRPC
在模组的Awake
方法中,初始化CustomRPC并指定处理接收数据的方法。CustomRPC将用于在客户端和服务器之间传递数据。
private void Awake()
{
Harmony.DEBUG = true;
Logger.LogInfo($"模组 {mod_GUID} 已加载!");
NetworkManager networkManager = NetworkManager.Instance;
myCustomRPC = networkManager.AddRPC("MyCustomRPC", ServerReceive, ClientReceive);
harmony.PatchAll();
}
步骤4:处理数据发送和接收
在模组类中创建两方法,用于处理数据的发送和接收。这些方法将在CustomRPC中使用。
private static IEnumerator ServerReceive(long sender, ZPackage pkg)
{
string data = pkg.ReadString();
Debug.LogError($"从客户端接收到的数据是:{data}");
if (data == "66666")
{
Debug.LogWarning("服务器收到 '66666' 数据并向客户端发送 '7777777'");
SendDataToClient(sender, "7777777");
}
return null;
}
private static IEnumerator ClientReceive(long sender, ZPackage message)
{
string data = message.ReadString();
Debug.LogError($"从服务器接收到的数据是:{data}");
if (data == "7777777")
{
Debug.LogWarning("客户端收到 '7777777' 数据");
}
return null;
}
这些方法将根据接收到的数据执行不同的操作。服务器收到”66666″后将发送”7777777″到客户端。
步骤5:数据发送
在模组中,可以使用以下方法将数据发送到服务器。
private static void SendDataToServer(string data)
{
ZPackage package = new ZPackage();
package.Write(data);
long serverPeerID = (long)ReflectionHelper.InvokePrivate(ZRoutedRpc.instance, "GetServerPeerID");
myCustomRPC.SendPackage(serverPeerID, package);
Debug.LogWarning($"通过自定义 RPC 向服务器发送数据:{data}");
}
步骤6:数据发送触发
你可以通过在Update
方法中添加触发来发送数据。以下示例在按下F3键时发送数据到服务器:
private void Update()
{
if (Input.GetKey(KeyCode.F3) && ZNet.instance.IsClientInstance())
{
SendDataToServer("66666");
}
}
步骤7:完成模组
完整代码:
using BepInEx;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using System;
using UnityEngine;
using System.Collections;
using Jotunn;
namespace valhallaRPC
{
[BepInDependency(Jotunn.Main.ModGuid)]
[BepInPlugin(mod_GUID, mod_NAME, mod_VERSION)]
public class valhallaRPC : BaseUnityPlugin
{
private const string mod_GUID = "HsgtLgt.valhallaRPC";
private const string mod_NAME = "英灵神殿RPC注册收发数据示例";
private const string mod_VERSION = "0.0.13";
private readonly Harmony harmony = new Harmony(mod_GUID);
private static CustomRPC myCustomRPC;
[Obsolete]
private void Awake()
{
Harmony.DEBUG = true;
Logger.LogInfo($"插件 {mod_GUID} 已加载!");
harmony.PatchAll();
}
private void Start()
{
NetworkManager networkManager = NetworkManager.Instance;
myCustomRPC = networkManager.AddRPC("MyCustomRPC", ServerReceive, ClientReceive);
}
[HarmonyPatch(typeof(Game), "Start")]
public static class GameStartPatch
{
[HarmonyPostfix]
public static void Initialize()
{
if (ZNet.instance.IsServer())
{
Debug.Log("这是服务器");
}
else
{
Debug.Log("这是客户端");
}
}
}
private void Update()
{
if (Input.GetKey(KeyCode.F3) && ZNet.instance.IsClientInstance())
{
SendDataToServer("66666");
}
}
private static void SendDataToServer(string data)
{
ZPackage package = new ZPackage();
package.Write(data);
long serverPeerID = (long)ReflectionHelper.InvokePrivate(ZRoutedRpc.instance, "GetServerPeerID");
myCustomRPC.SendPackage(serverPeerID, package);
Debug.LogWarning($"通过自定义 RPC 向服务器发送数据: {data}");
}
private static IEnumerator ServerReceive(long sender, ZPackage pkg)
{
string data = pkg.ReadString();
Debug.LogError($"接收客户端的数据是:{data}");
if (data == "66666")
{
Debug.LogWarning("服务器收到 66666 数据,向客户端发送 7777777");
SendDataToClient(sender, "7777777");
}
return null;
}
private static IEnumerator ClientReceive(long sender, ZPackage message)
{
string data = message.ReadString();
Debug.LogError($"接收服务端的数据是:{data}");
if (data == "7777777")
{
Debug.LogWarning("客户端收到 7777777 数据");
}
return null;
}
private static void SendDataToClient(long sender, string data)
{
ZPackage package = new ZPackage();
package.Write(data);
myCustomRPC.SendPackage(sender, package);
Debug.LogWarning($"通过自定义 RPC 向客户端发送数据: {data}");
}
}
}
现在,你已经创建了一个模组,可以在Valheim游戏中发送和接收自定义数据。确保构建模组并将其放入Valheim的模组目录中以进行测试。
这个示例展示了如何使用BepInEx和Jotunn创建Valheim模组,以便在游戏客户端和服务器之间发送自定义字符串数据。你可以根据自己的需求扩展这个示例,以创建更复杂的功能。希望这篇文章对你有所帮助!
没有回复内容