Skip to content

Instantly share code, notes, and snippets.

@cnsoft
Last active December 28, 2015 04:59
Show Gist options
  • Save cnsoft/7446190 to your computer and use it in GitHub Desktop.
Save cnsoft/7446190 to your computer and use it in GitHub Desktop.
How networkpeer handle RPC (from Photon Unity SDK) .
/// RPC Hashtable Structure
/// (byte)0 -> (int) ViewId (combined from actorNr and actor-unique-id)
/// (byte)1 -> (short) prefix (level)
/// (byte)2 -> (int) server timestamp
/// (byte)3 -> (string) methodname
/// (byte)4 -> (object[]) parameters
/// (byte)5 -> (byte) method shortcut (alternative to name)
///
/// This is sent as event (code: 200) which will contain a sender (origin of this RPC).
internal void RPC(PhotonView view, string methodName, PhotonTargets target, params object[] parameters)
{
if (this.blockSendingGroups.Contains(view.group))
{
return; // Block sending on this group
}
if (view.viewID < 1)
{
Debug.LogError("Illegal view ID:" + view.viewID + " method: " + methodName + " GO:" + view.gameObject.name);
}
if (this.DebugOut >= DebugLevel.INFO)
{
this.DebugReturn(DebugLevel.INFO, "Sending RPC \"" + methodName + "\" to " + target);
}
//ts: changed RPCs to a one-level hashtable as described in internal.txt
Hashtable rpcEvent = new Hashtable();
rpcEvent[(byte)0] = (int)view.viewID; // LIMITS NETWORKVIEWS&PLAYERS
if (view.prefix > 0)
{
rpcEvent[(byte)1] = (short)view.prefix;
}
rpcEvent[(byte)2] = this.ServerTimeInMilliSeconds;
// send name or shortcut (if available)
int shortcut = 0;
if (rpcShortcuts.TryGetValue(methodName, out shortcut))
{
rpcEvent[(byte)5] = (byte)shortcut; // LIMITS RPC COUNT
}
else
{
rpcEvent[(byte)3] = methodName;
}
if (parameters != null && parameters.Length > 0)
{
rpcEvent[(byte)4] = (object[])parameters;
}
// Check scoping
if (target == PhotonTargets.All)
{
this.OpRaiseEvent(PunEvent.RPC, (byte)view.group, rpcEvent, true, 0);
// Execute local
this.ExecuteRPC(rpcEvent, this.mLocalActor);
}
else if (target == PhotonTargets.Others)
{
this.OpRaiseEvent(PunEvent.RPC, (byte)view.group, rpcEvent, true, 0);
}
else if (target == PhotonTargets.AllBuffered)
{
this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, 0, EventCaching.AddToRoomCache, ReceiverGroup.Others);
// Execute local
this.ExecuteRPC(rpcEvent, this.mLocalActor);
}
else if (target == PhotonTargets.OthersBuffered)
{
this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, 0, EventCaching.AddToRoomCache, ReceiverGroup.Others);
}
else if (target == PhotonTargets.MasterClient)
{
if (this.mMasterClient == this.mLocalActor)
{
this.ExecuteRPC(rpcEvent, this.mLocalActor);
}
else
{
this.OpRaiseEvent(PunEvent.RPC, rpcEvent, true, 0, EventCaching.DoNotCache, ReceiverGroup.MasterClient);//TS: changed from caching to non-cached. this goes to master only
}
}
else
{
Debug.LogError("Unsupported target enum: " + target);
}
}
//
LiteApplication support customProperties
/// <summary>
/// Updates and synchronizes the named properties of this Player with the values of propertiesToSet.
/// </summary>
/// <remarks>
/// Any player's properties are available in a Room only and only until the player disconnect or leaves.
/// Access any player's properties by: Player.CustomProperties (read-only!) but don't modify that hashtable.
///
/// New properties are added, existing values are updated.
/// Other values will not be changed, so only provide values that changed or are new.
/// To delete a named (custom) property of this player, use null as value.
/// Only string-typed keys are applied (everything else is ignored).
///
/// Local cache is updated immediately, other players are updated through Photon with a fitting operation.
/// To reduce network traffic, set only values that actually changed.
/// </remarks>
/// <param name="propertiesToSet">Hashtable of props to udpate, set and sync. See description.</param>
public void SetCustomProperties(Hashtable propertiesToSet)
{
Hashtable customProps = propertiesToSet.StripToStringKeys() as Hashtable;
// merge (delete null-values)
this.CustomProperties.Merge(customProps);
this.CustomProperties.StripKeysWithNullValues();
// send (sync) these new values if in room
if (this.RoomReference != null && this.RoomReference.IsLocalClientInside)
{
this.RoomReference.LoadBalancingClient.OpSetCustomPropertiesOfActor(this.actorID, customProps);
}
}
//WorldEnter status handle Event.
public void OnEventReceive(PhotonPeer peer, EventData eventData)
{
switch ((ClientEventCode)eventData.Code)
{
case ClientEventCode.ObjectSubscribed:
{
this.HandleObjectSubscribed(eventData);
}
break;
case ClientEventCode.ObjectUnsubscribed:
{
this.HandlObjectUnsubscribed(eventData);
}
break;
case ClientEventCode.ObjectMovement:
{
this.HandleObjectMovement(eventData);
}
break;
case ClientEventCode.ObjectTransform:
{
this.HandleObjectTransform(eventData);
}
break;
case ClientEventCode.ObjectDestroyed:
{
this.HandleObjectDestroyed(eventData);
}
break;
case ClientEventCode.ChatEvent:
{
this.HandleChatEvent(eventData);
}
break;
case ClientEventCode.ObjectProperties:
{
this.HandleObjectProperties(eventData);
}
break;
case ClientEventCode.ObjectFlags:
{
this.HandleObjectFlags(eventData);
}
break;
case ClientEventCode.PropertySet:
{
this.HandlePropertySet(eventData);
}
break;
case ClientEventCode.InteractorActionEvent:
{
this.HandleInteractorActionEvent(eventData);
}
break;
case ClientEventCode.ContainerEvent:
{
this.HandleContainerEvent(eventData);
}
break;
case ClientEventCode.SpellEvent:
{
this.HandleSpellEvent(eventData);
}
break;
case ClientEventCode.PlayerEvent:
{
this.HandlePlayerEvent(eventData);
}
break;
case ClientEventCode.LootEvent:
{
this.HandleLootEvent(eventData);
}
break;
case ClientEventCode.GroupEvent:
{
this.HandleGroupEvent(eventData);
}
break;
case ClientEventCode.QuestEvent:
{
this.HandleQuestEvent(eventData);
}
break;
case ClientEventCode.SocialEvent:
{
this.HandleSocialEvent(eventData);
}
break;
case ClientEventCode.Debug:
{
this.HandleDebugEvent(eventData);
}
break;
default:
{
GameManager.Instance.Chat.SendChat(ClientChannelType.Game, string.Format("Unhandled Event Received-> Code: {0}({1}). Full: {2}.", (ClientEventCode)eventData.Code, (int)eventData.Code, eventData.ToStringFull()));
}
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment