You are viewing a potentially older version of this package.
View all versions.
MirrorPlumber
Utility Mod that allows modders to insert and use new NetworkActions (Commands, ClientRpcs, and TargetRpcs)
| Date uploaded | 5 months ago |
| Version | 0.1.1 |
| Download link | darmuh-MirrorPlumber-0.1.1.zip |
| Downloads | 96 |
| Dependency string | darmuh-MirrorPlumber-0.1.1 |
README
Mirror Plumber
Utility BepInEx Mod that allows modders to insert and use new NetworkActions (Commands, ClientRpcs, and TargetRpcs)
- This was built for YAPYAP, however, it should work in any other unity game that utilizes the same style of Mirror Networking.
Mirror Network Prefabs
Note: These steps assume you have some prior Unity modding knowledge.
If you do not need a background on Mirror Networking and just wnat to know how to use this utility, skip to Using MirrorPlumber for your NetworkBehaviour
Create a GameObject that will serve as your Network Prefab containg your NetworkBehaviour
- This game object should at the minimum contain a
Networkidentitycomponent.- Your class inheriting NetworkBehaviour should also be attached to this game object either during in Unity or added during runtime.
- You cannot add a
Networkidentitycomponent at runtime because the assetId property will not be set properly.
- Once you have created your Prefab with the
NetworkIdentitycomponent, build it into an asset bundle.
Loading your GameObject Assetbundle as a Network Prefab
- Load your asset bundle containing your game object at Plugin Awake. If you have not added your Network Behaviour classes already, add them as components now.
- You'll want to cache your GameObject as it will be used in a few other places.
- Either at Plugin Start or at another appropriate time (before hosting a game session), you'll want to then use
NetworkClient.RegisterPrefabon your game object.- You'll also need to cache the assetId by performing
GetComponent<NetworkIdentity>().assetIdafter you've registered your prefab.
- You'll also need to cache the assetId by performing
Spawning your Network Prefab
- Once your prefab has been properly registered, you can now spawn it once a game session has been started and the server is active.
- Ensure you are ONLY spawning the object from the server client.
- To spawn a NetworkPrefab you will Instantiate a copy of your cached GameObject and then run
NetworkServer.Spawnon the copy with your cached assetId.
YAPYAP Simple NetworkPrefab Load/Spawn Example
internal static ManualLogSource Log { get; private set; } = null!;
internal static GameObject Networker = null!;
internal static uint NetworkerID = default!;
private void Awake()
{
Log = Logger;
Log.LogInfo($"Plugin {Name} is loaded!");
//Networker Bundle
string networkAsset = Path.Combine(Path.GetDirectoryName(Info.Location), "networker");
AssetBundle networker = AssetBundle.LoadFromFile(networkAsset);
Networker = networker.LoadAsset<GameObject>("Networker");
Networker.AddComponent<NetworkingTestWithPlumbing>();
GameManager.OnPlayerSpawned += OnPawnSpawn;
}
private void Start()
{
Log.LogMessage("Registering network prefabs");
NetworkClient.RegisterPrefab(Networker);
NetworkerID = Networker.GetComponent<NetworkIdentity>().assetId;
Log.LogDebug($"NetworkerID - {NetworkerID}");
}
private static void OnPawnSpawn(Pawn pawn)
{
Log.LogMessage($"Pawn spawned {pawn.PlayerName}");
if (!pawn.isLocalPlayer)
return;
if (pawn.isServer)
{
Log.LogDebug("Spawning networker");
var networker = Object.Instantiate(Networker);
NetworkServer.Spawn(networker, NetworkerID);
}
}
In the above example:
- The NetworkBehaviour
NetworkingTestWithPlumbingis added to the Networker GameObject at Plugin Awake - Networker is then registered as a Network Prefab in Plugin Start and the assetId is cached as NetworkerID
- OnPlayerSpawn is listening to the GameManager.OnPlayerSpawned event. When a player is spawned, it checks if the player is the server and then also spawns the testing networker object.
Where MirrorPlumber comes in
- Without MirrorPlumber, this is where you would find that the various Attributes
[ClientRpc],[Command], etc. are not actually utilizing Mirror to send the information across the network. - You could perform your own plumbing and register each and every NetworkAction yourself following the logic for
RemoteProcedureCalls.RegisterDelegateorRemoteProcedureCalls.RegisterRpcorRemoteProcedureCalls.RegisterCommand- However this process is incredibly tedious and will certainly cause you some headaches.
- MirrorPlumber does all of this manual plumbing for you. You'll just need to perform a few alternative steps in your NetworkBehaviour to start the process.
Using MirrorPlumber for your NetworkBehaviour
- To start, it is recommended to create a static reference to each Plumber you create.
- This is because you will be the one to invoke these network actions in your code, so you'll need a reference to it.
- Example:
internal static Plumber GeneratedCommand = null!;
internal static Plumber<string, int> GeneratedRPC = null!;
- Creating the Plumbers is recommended to be done in your NetworkBehaviour's Awake method, however it can be done any time after the prefab holding your NetworkBehaviour has been spawned.
- You create the Plumber with a simple constructor that takes the following parameters:
System.Type netBehaviourYou'll provide this by converting your NetworkBehaviour to a System.Type - ie:typeof(MyNetworkBehaviour)string methodNameThis is the name of the Method you are performing plumbing for - ie:nameof(MyNetworkedMethod)NetType netTypeThis is an enum created by MirrorPlumber to help identify what kind of NetworkAction you are requesting plumbing for.bool requiresAuthority = false(Optional) This bool determines if the NetworkAction requires ownership of the Network Prefab before being used.
- NOTE: You cannot invoke Network Actions without having created your Plumber.
- Once you have created your Plumber, you should then add the method you wish to run when the NetworkAction is received via
AddListener.- This can be multiple methods so long as each one has the number of parameters expected with the correct type.
- You create the Plumber with a simple constructor that takes the following parameters:
- Example:
private void Awake()
{
GeneratedCommand = new(typeof(NetworkingTestWithPlumbing), nameof(CmdSendHello), PlumberBase.NetType.Command);
GeneratedCommand.AddListener(RpcShowHelloMessage);
GeneratedRPC = new(typeof(NetworkingTestWithPlumbing), nameof(RpcShowHelloMessage), PlumberBase.NetType.TargetRpc);
GeneratedRPC.AddListener(HelloFromTheNetwork);
}
- Now that you have your Plumbers created, all you need to do now is Invoke them wherever you would typically call the method with the NetworkAction.
- It's recommended to use a null conditional operator before invoking your Plumber.
- Below are some of the parameters you can expect in the Plumber's Invoke method:
TSource instanceThis is the instance of your NetworkBehaviour that is calling this method.NetworkConnection target = null!(OPTIONAL) If your NetworkAction is a TargetRpc, you'll need to set this to the client you wish to send the NetworkAction to.TParam paramorTParam1 param1orTParam2 param2All of these potential parameters are values of the parameter types you are sending to other clients.
- Examples:
GeneratedCommand?.Invoke(this);GeneratedRPC?.Invoke(this, "Hello World from the network!", 1337, NetworkServer.connections[0]);- Both of these examples are called from inside non-static methods inside my NetworkBehaviour
NetworkingTestWithPlumbing
- Both of these examples are called from inside non-static methods inside my NetworkBehaviour
- For information on what types can be passed in TParams over to Mirror's NetworkWriter/NetworkReader, please see this page of Mirror's Documentation.
- Some games may also have custom NetworkWriter/NetworkReaders that you can utilize, YAPYAP does not and you cannot add new ones via a Mod (they require Weaving from Mirror)
CHANGELOG
MirrorPlumber Changelog
0.3.1
- Updated xml documentation for PlumbVars
- Added OnValueChanged event to PlumbVars that can be subscribed to similarly to Mirror's native SyncVar hooks attribute.
0.3.0
- Updated project to generate xml documentation file.
- Updated AutoPlugin version in project.
- Added PlumbVar which acts as a psuedo syncvar (using an internal command and clientrpc)
- Defined with the class name, value type, and initial value
- Get and set the value via the
Valueproperty. Setting the value will send your changes over the network.
- Found and provided fix for issue of NetworkEvent delegate listeners persisting past class destruction.
- In order to clear these delegates with destroyed (null) references, you can now use the
ClearListenersmethod in your NetworkBehaviour'sOnDestroymethod. - You can also swap to
SetListenerin place ofAddListenerthat will automatically clear existing listeners before adding your new listener. - To add additional listeners for one networkevent you can still utilize AddListener, just ensure it is after
ClearListenersorSetListener
- In order to clear these delegates with destroyed (null) references, you can now use the
- Found and provided fix for issue where NetworkPrefabs loaded from asset bundles will get cleared from the NetworkClient when they are no longer hosting.
- This is due to Mirror natively running
NetworkClient.ClearSpawnersduringNetworkClient.Shutdown(in yapyap this method is called when closing a hosted lobby) - The extension method
TryRegisterPrefabhas been updated to handle registration for you.- MirrorPlumber will keep a list of gameobjects that have been queued for registration and ensure they've been registered with NetworkClient at
NetworkClient.Initialize - An overload exists that does not provide the assetId as it's no longer necessary to keep track of.
- MirrorPlumber will keep a list of gameobjects that have been queued for registration and ensure they've been registered with NetworkClient at
- This is due to Mirror natively running
- New game object extension method can be used to remove a prefab from MirrorPlumber's prefab game object list via
TryUntrackPrefab- This will not remove the prefab from an active server, but will ensure it is not in the prefab list for the next time NetworkClient is initialized.
- New game object extension method for getting a prefab's assetId
- New game object extension method for spawning a prefab on the server.
- Examples updated with latest changes
- Readme updates for latest version.
0.2.1
- removed sample classes from compiler that I accidentally included in last build
0.2.0
- Moved Plumber registration from constructor to
Createmethod (breaking change from 0.1.1)- This was to solve an issue where Commands/Rpcs were trying to be re-added to Mirror after a lobby reload.
- Now rather than creating a new Plumber every awake, it should be defined only once and then
Createcan be ran multiple times without any issues.
- Added Examples folder to github.
- This should help the visual learners who learn strictly thru code.
- Added
BehaviourAdderclass for adding network behaviours to existing prefabs at runtime.- Handles both the PlayerPrefab and any spawnPrefab in the list that you can match to an assetId
- Added
GameObjectExtensionsclass for useful extension methods relating to Mirror/MirrorPlumberTryRegisterPrefabwill attempt to take your GameObject prefab and register it with MirrorClient- Returns true/false and provides you the NetworkIdentity assetId when successful.
- Some msbuild project changes to make building the release package a bit easier
0.1.1
- Fixed some typos in the readme
- Removed some old debugging logs for more accurate ones in Plumber.cs
0.1.0
- Initial release.