Skip to content

Commit

Permalink
added DeregisterNetworkObject
Browse files Browse the repository at this point in the history
  • Loading branch information
RugbugRedfern committed Apr 10, 2024
1 parent d43b12e commit 4346e42
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 7 deletions.
45 changes: 43 additions & 2 deletions MyceliumNetworkingForCW/MyceliumNetwork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -575,12 +575,12 @@ static List<MessageHandler> GetMessageHandlers(uint modID, string methodName)
}
else
{
throw new Exception($"The method ({modID}: {methodName}) was not found");
throw new Exception($"The RPC ({modID}: {methodName}) was not found");
}
}
else
{
throw new Exception($"The mod Id {modID} was not found (loaded mods: {string.Join(",", rpcs.Keys.ToArray())})");
throw new Exception($"The mod id {modID} was not found (loaded mods: {string.Join(",", rpcs.Keys.ToArray())})");
}
}

Expand Down Expand Up @@ -743,6 +743,47 @@ public static void RegisterNetworkObject(object obj, uint modId, int mask = 0)
RugLogger.Log($"Registered {registeredMethods} CustomRPCs for {modId}: {obj}.");
}

public static void DeregisterNetworkObject(object obj, uint modId, int mask = 0)
{
var t = obj.GetType();

int deregistered = 0;

foreach(var method in t.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
// Get the attributes attached to the method
var attributes = method.GetCustomAttributes(false).OfType<CustomRPCAttribute>().ToArray();

// If there are any attributes
if(attributes.Any())
{
if(!rpcs.ContainsKey(modId))
{
RugLogger.Log($"Attempted to deregister RPCs for mod id {modId}, but no RPCs from that mod are loaded.");
return;
}

if(!rpcs[modId].ContainsKey(method.Name))
{
RugLogger.Log($"Attempted to deregister RPC {method.Name} for mod id {modId}, but no RPCs by that name are loaded.");
return;
}

foreach(var rpc in rpcs[modId][method.Name].ToArray())
{
if(rpc.Mask == mask)
{
rpcs[modId][method.Name].Remove(rpc);
}
}

deregistered++;
}
}

RugLogger.Log($"Deregistered {deregistered} CustomRPCs for {modId}: {obj}.");
}

class MessageHandler
{
public object Target;
Expand Down
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,20 @@ void DoSomething(string message, int num, ulong id)
```

### Calling RPCs
To call an RPC, first register the object with the network. Each mod needs a **unique** ID, which is just a random number you define unique to your mod. This is to make sure mods don't accidentally call an RPC on a separate mod. I recommend you store the modId as a constant somewhere in your program.
To call an RPC, first register the object with the network. Each mod needs a **unique** ID, which is just a random number you define unique to your mod. This is to make sure mods don't accidentally call an RPC on a separate mod. I recommend you store the modId as a constant somewhere in your program. Deregister the object when it is destroyed (for singletons or static classes, it's fine to never deregister).

```cs
const uint modId = 12345;

void Start()
void Awake()
{
MyceliumNetwork.RegisterNetworkObject(this, modId);
}

void OnDestroy()
{
MyceliumNetwork.DeregisterNetworkObject(this, modId);
}
```

To call the RPC, use `MyceliumNetwork.RPC`. Pass in the mod ID, the name of the RPC you are calling, what kind of reliability you want the RPC to have (leave it at Reliable if you are unsure), and the parameters to pass in the RPC:
Expand Down Expand Up @@ -131,16 +136,25 @@ Debug.Log(data); // bar
```

## Using Masks
Sometimes you only want to run an RPC on a single instance of an object, for example calling an RPC on one player. To do this, you use masks.
RPCs are synced using the method name. If you have multiple methods with the same name on different objects, they will all be called when an RPC is fired. But sometimes you only want to run an RPC on a single instance of an object, for example calling an RPC on one player. To do this, you use masks.

Pass the ViewID of the PhotonView on your object in as the mask when registering a network object.

```cs
class PlayerTest : MonoBehaviour
{
void Start()
int viewId;

void Awake()
{
viewId = GetComponent<PhotonView>().ViewID;
MyceliumNetwork.RegisterNetworkObject(this, BasePlugin.MOD_ID, viewId);
}

void OnDestroy()
{
MyceliumNetwork.RegisterNetworkObject(this, BasePlugin.MOD_ID, GetComponent<PhotonView>().ViewID);
// you will need to store the viewId locally, because you cannot access a PhotonView in OnDestroy.
MyceliumNetwork.DeregisterNetworkObject(this, BasePlugin.MOD_ID, viewId);
}
}
```
Expand Down

0 comments on commit 4346e42

Please sign in to comment.