TIMESTAMP









How do I use T I M E S T A M P
Below are practical examples compiled from projects for learning and reference purposes

Featured Snippets


File name: CubeInter.cs Copy
10  // By default this is 10 times/second for OnSerialize. (See PhotonNetwork.sendIntervalOnSerialize)
17     {
18         internal double timestamp;
19         internal Vector3 pos;
20         internal Quaternion rot;
21     }
File name: CubeInter.cs Copy
34     void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
35     {
36         // Always send transform (depending on reliability of the network view)
37         if (stream.isWriting)
38         {
39             Vector3 pos = transform.localPosition;
40             Quaternion rot = transform.localRotation;
41             stream.Serialize(ref pos);
42             stream.Serialize(ref rot);
43         }
44         // When receiving, buffer the information
45         else
46         {
47    // Receive latest state information
48             Vector3 pos = Vector3.zero;
49             Quaternion rot = Quaternion.identity;
50             stream.Serialize(ref pos);
51             stream.Serialize(ref rot);
52
53             // Shift buffer contents, oldest data erased, 18 becomes 19, ... , 0 becomes 1
54             for (int i = m_BufferedState.Length - 1; i >= 1; i--)
55             {
56                 m_BufferedState[i] = m_BufferedState[i - 1];
57             }
58
59
60             // Save currect received state as 0 in the buffer, safe to overwrite after shifting
61             State state;
62             state.timestamp = info.timestamp;
63             state.pos = pos;
64             state.rot = rot;
65             m_BufferedState[0] = state;
66
67             // Increment state count but never exceed buffer size
68             m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.Length);
69
70             // Check integrity, lowest numbered state in the buffer is newest and so on
71             for (int i = 0; i < m_TimestampCount - 1; i++)
72             {
73                 if (m_BufferedState[i].timestamp < m_BufferedState[i + 1].timestamp)
74                     Debug.Log("State inconsistent");
75             }
76   }
77     }
File name: CubeInter.cs Copy
79     // This only runs where the component is enabled, which is only on remote peers (server/clients)
80     void Update()
81     {
82         double currentTime = PhotonNetwork.time;
83         double interpolationTime = currentTime - interpolationBackTime;
84         // We have a window of interpolationBackTime where we basically play
85         // By having interpolationBackTime the average ping, you will usually use interpolation.
86         // And only if no more data arrives we will use extrapolation
87
88         // Use interpolation
89         // Check if latest state exceeds interpolation time, if this is the case then
90         // it is too old and extrapolation should be used
91         if (m_BufferedState[0].timestamp > interpolationTime)
92         {
93     for (int i = 0; i < m_TimestampCount; i++)
94             {
95                 // Find the state which matches the interpolation time (time+0.1) or use last state
96                 if (m_BufferedState[i].timestamp <= interpolationTime || i == m_TimestampCount - 1)
97                 {
98                     // The state one slot newer (<100ms) than the best playback state
99                     State rhs = m_BufferedState[Mathf.Max(i - 1, 0)];
100                     // The best playback state (closest to 100 ms old (default time))
101                     State lhs = m_BufferedState[i];
102
103                     // Use the time between the two slots to determine if interpolation is necessary
104                     double length = rhs.timestamp - lhs.timestamp;
105                     float t = 0.0F;
106                     // As the time difference gets closer to 100 ms t gets closer to 1 in
107                     // which case rhs is only used
108                     if (length > 0.0001)
109                         t = (float)((interpolationTime - lhs.timestamp) / length);
110
111                     // if t=0 => lhs is used directly
112                     transform.localPosition = Vector3.Lerp(lhs.pos, rhs.pos, t);
113                     transform.localRotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
114      return;
115                 }
116             }
117         }
118         // Use extrapolation. Here we do something really simple and just repeat the last
119         // received state. You can do clever stuff with predicting what should happen.
120         else
121         {
122             State latest = m_BufferedState[0];
123
124             transform.localPosition = Vector3.Lerp(transform.localPosition, latest.pos, Time.deltaTime * 20 );
125             transform.localRotation = latest.rot;
126         }
127     }
File name: NetworkingPeer.cs Copy
1016     public void OnOperationResponse(OperationResponse operationResponse)
1017     {
1018         if (PhotonNetwork.networkingPeer.State == global::PeerState.Disconnecting)
1019         {
1020             if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1021             {
1022                 Debug.Log("OperationResponse ignored while disconnecting. Code: " + operationResponse.OperationCode);
1023             }
1024             return;
1025         }
1026
1027         // extra logging for error debugging (helping developers with a bit of automated analysis)
1028         if (operationResponse.ReturnCode == 0)
1029         {
1030             if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1031                 Debug.Log(operationResponse.ToString());
1032         }
1033         else
1034         {
1035             if (operationResponse.ReturnCode == ErrorCode.OperationNotAllowedInCurrentState)
1036             {
1037                 Debug.LogError("Operation " + operationResponse.OperationCode + " could not be executed (yet). Wait for state JoinedLobby or ConnectedToMaster and their callbacks before calling operations. WebRPCs need a server-side configuration. Enum OperationCode helps identify the operation.");
1038             }
1039             else if (operationResponse.ReturnCode == ErrorCode.WebHookCallFailed)
1040             {
1041                 Debug.LogError("Operation " + operationResponse.OperationCode + " failed in a server-side plugin. Check the configuration in the Dashboard. Message from server-plugin: " + operationResponse.DebugMessage);
1042             }
1043             else if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1044             {
1045                 Debug.LogError("Operation failed: " + operationResponse.ToStringFull() + " Server: " + this.server);
1046             }
1047         }
1048
1049         // use the "secret" or "token" whenever we get it. doesn't really matter if it's in AuthResponse.
1050         if (operationResponse.Parameters.ContainsKey(ParameterCode.Secret))
1051         {
1052             if (this.CustomAuthenticationValues == null)
1053             {
1054                 this.CustomAuthenticationValues = new AuthenticationValues();
1055                 // this.DebugReturn(DebugLevel.ERROR, "Server returned secret. Created CustomAuthenticationValues.");
1056             }
1057
1058             this.CustomAuthenticationValues.Secret = operationResponse[ParameterCode.Secret] as string;
1059         }
1060
1061         switch (operationResponse.OperationCode)
1062         {
1063             case OperationCode.Authenticate:
1064                 {
1065                     // PeerState oldState = this.State;
1066
1067                     if (operationResponse.ReturnCode != 0)
1068                     {
1069                         if (operationResponse.ReturnCode == ErrorCode.InvalidOperationCode)
1070                         {
1071                             Debug.LogError(string.Format("If you host Photon yourself, make sure to start the 'Instance LoadBalancing' "+ this.ServerAddress));
1072                         }
1073                         else if (operationResponse.ReturnCode == ErrorCode.InvalidAuthentication)
1074                         {
1075                             Debug.LogError(string.Format("The appId this client sent is unknown on the server (Cloud). Check settings. If using the Cloud, check account."));
1076                             SendMonoMessage(PhotonNetworkingMessage.OnFailedToConnectToPhoton, DisconnectCause.InvalidAuthentication);
1077                         }
1078                         else if (operationResponse.ReturnCode == ErrorCode.CustomAuthenticationFailed)
1079                         {
1080                             Debug.LogError(string.Format("Custom Authentication failed (either due to user-input or configuration or AuthParameter string format). Calling: OnCustomAuthenticationFailed()"));
1081                             SendMonoMessage(PhotonNetworkingMessage.OnCustomAuthenticationFailed, operationResponse.DebugMessage);
1082                         }
1083                         else
1084                         {
1085                             Debug.LogError(string.Format("Authentication failed: '{0}' Code: {1}", operationResponse.DebugMessage, operationResponse.ReturnCode));
1086                         }
1087
1088                         this.State = global::PeerState.Disconnecting;
1089                         this.Disconnect();
1090
1091                         if (operationResponse.ReturnCode == ErrorCode.MaxCcuReached)
1092                         {
1093                             if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1094                                 Debug.LogWarning(string.Format("Currently, the limit of users is reached for this title. Try again later. Disconnecting"));
1095                             SendMonoMessage(PhotonNetworkingMessage.OnPhotonMaxCccuReached);
1096                             SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, DisconnectCause.MaxCcuReached);
1097                         }
1098                         else if (operationResponse.ReturnCode == ErrorCode.InvalidRegion)
1099                         {
1100                             if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1101                                 Debug.LogError(string.Format("The used master server address is not available with the subscription currently used. Got to Photon Cloud Dashboard or change URL. Disconnecting."));
1102                             SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, DisconnectCause.InvalidRegion);
1103                         }
1104                         else if (operationResponse.ReturnCode == ErrorCode.AuthenticationTicketExpired)
1105                         {
1106                             if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1107                                 Debug.LogError(string.Format("The authentication ticket expired. You need to connect (and authenticate) again. Disconnecting."));
1108                             SendMonoMessage(PhotonNetworkingMessage.OnConnectionFail, DisconnectCause.AuthenticationTicketExpired);
1109                         }
1110                         break;
1111                     }
1112                     else
1113                     {
1114                         if (this.server == ServerConnection.NameServer)
1115                         {
1116                             // on the NameServer, authenticate returns the MasterServer address for a region and we hop off to there
1117                             this.MasterServerAddress = operationResponse[ParameterCode.Address] as string;
1118                             this.DisconnectToReconnect();
1119                         }
1120                         else if (this.server == ServerConnection.MasterServer)
1121                         {
1122                             if (PhotonNetwork.autoJoinLobby)
1123                             {
1124                                 this.State = global::PeerState.Authenticated;
1125                                 this.OpJoinLobby(this.lobby);
1126                             }
1127                             else
1128                             {
1129                                 this.State = global::PeerState.ConnectedToMaster;
1130                                 NetworkingPeer.SendMonoMessage(PhotonNetworkingMessage.OnConnectedToMaster);
1131                             }
1132                         }
1133                         else if (this.server == ServerConnection.GameServer)
1134                         {
1135                             this.State = global::PeerState.Joining;
1136
1137                             if (this.mLastJoinType == JoinType.JoinGame || this.mLastJoinType == JoinType.JoinRandomGame || this.mLastJoinType == JoinType.JoinOrCreateOnDemand)
1138                             {
1139                                 // if we just "join" the game, do so. if we wanted to "create the room on demand", we have to send this to the game server as well.
1140                                 this.OpJoinRoom(this.mRoomToGetInto.name, this.mRoomOptionsForCreate, this.mRoomToEnterLobby, this.mLastJoinType == JoinType.JoinOrCreateOnDemand);
1141                             }
1142                             else if (this.mLastJoinType == JoinType.CreateGame)
1143                             {
1144                                 // on the game server, we have to apply the room properties that were chosen for creation of the room, so we use this.mRoomToGetInto
1145                                 this.OpCreateGame(this.mRoomToGetInto.name, this.mRoomOptionsForCreate, this.mRoomToEnterLobby);
1146                             }
1147
1148                             break;
1149                         }
1150                     }
1151                     break;
1152                 }
1153
1154             case OperationCode.GetRegions:
1155                 // Debug.Log("GetRegions returned: " + operationResponse.ToStringFull());
1156
1157                 if (operationResponse.ReturnCode == ErrorCode.InvalidAuthentication)
1158                 {
1159                     Debug.LogError(string.Format("The appId this client sent is unknown on the server (Cloud). Check settings. If using the Cloud, check account."));
1160                     SendMonoMessage(PhotonNetworkingMessage.OnFailedToConnectToPhoton, DisconnectCause.InvalidAuthentication);
1161
1162                     this.State = global::PeerState.Disconnecting;
1163                     this.Disconnect();
1164                     return;
1165                 }
1166
1167                 string[] regions = operationResponse[ParameterCode.Region] as string[];
1168                 string[] servers = operationResponse[ParameterCode.Address] as string[];
1169
1170                 if (regions == null || servers == null || regions.Length != servers.Length)
1171                 {
1172                     Debug.LogError("The region arrays from Name Server are not ok. Must be non-null and same length.");
1173                     break;
1174                 }
1175
1176                 this.AvailableRegions = new List(regions.Length);
1177                 for (int i = 0; i < regions.Length; i++)
1178                 {
1179                     string regionCodeString = regions[i];
1180                     if (string.IsNullOrEmpty(regionCodeString))
1181                     {
1182                         continue;
1183                     }
1184                     regionCodeString = regionCodeString.ToLower();
1185
1186                     CloudRegionCode code = Region.Parse(regionCodeString);
1187                     this.AvailableRegions.Add(new Region() { Code = code, HostAndPort = servers[i] });
1188                 }
1189
1190                 // PUN assumes you fetch the name-server's list of regions to ping them
1191                 if (PhotonNetwork.PhotonServerSettings.HostType == ServerSettings.HostingOption.BestRegion)
1192                 {
1193                     PhotonHandler.PingAvailableRegionsAndConnectToBest();
1194                 }
1195                 break;
1196
1197             case OperationCode.CreateGame:
1198                 {
1199                     if (this.server == ServerConnection.GameServer)
1200                     {
1201                         this.GameEnteredOnGameServer(operationResponse);
1202                     }
1203                     else
1204                     {
1205                         if (operationResponse.ReturnCode != 0)
1206                         {
1207                             if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1208                                 Debug.LogWarning(string.Format("CreateRoom failed, client stays on masterserver: {0}.", operationResponse.ToStringFull()));
1209
1210                             SendMonoMessage(PhotonNetworkingMessage.OnPhotonCreateRoomFailed);
1211                             break;
1212                         }
1213
1214                         string gameID = (string) operationResponse[ParameterCode.RoomName];
1215                         if (!string.IsNullOrEmpty(gameID))
1216                         {
1217                             // is only sent by the server's response, if it has not been
1218                             // sent with the client's request before!
1219                             this.mRoomToGetInto.name = gameID;
1220                         }
1221
1222                         this.mGameserver = (string)operationResponse[ParameterCode.Address];
1223                         this.DisconnectToReconnect();
1224                     }
1225
1226                     break;
1227                 }
1228
1229             case OperationCode.JoinGame:
1230                 {
1231                     if (this.server != ServerConnection.GameServer)
1232                     {
1233                         if (operationResponse.ReturnCode != 0)
1234                         {
1235                             if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1236                                 Debug.Log(string.Format("JoinRoom failed (room maybe closed by now). Client stays on masterserver: {0}. State: {1}", operationResponse.ToStringFull(), this.State));
1237
1238                             SendMonoMessage(PhotonNetworkingMessage.OnPhotonJoinRoomFailed);
1239                             break;
1240                         }
1241
1242                         this.mGameserver = (string)operationResponse[ParameterCode.Address];
1243                         this.DisconnectToReconnect();
1244                     }
1245                     else
1246                     {
1247                         this.GameEnteredOnGameServer(operationResponse);
1248                     }
1249
1250                     break;
1251                 }
1252
1253             case OperationCode.JoinRandomGame:
1254                 {
1255                     // happens only on master. on gameserver, this is a regular join (we don't need to find a random game again)
1256                     // the operation OpJoinRandom either fails (with returncode 8) or returns game-to-join information
1257                     if (operationResponse.ReturnCode != 0)
1258                     {
1259                         if (operationResponse.ReturnCode == ErrorCode.NoRandomMatchFound)
1260                         {
1261                             if (PhotonNetwork.logLevel >= PhotonLogLevel.Full)
1262                                 Debug.Log("JoinRandom failed: No open game. Calling: OnPhotonRandomJoinFailed() and staying on master server.");
1263                         }
1264                         else if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1265                         {
1266                             Debug.LogWarning(string.Format("JoinRandom failed: {0}.", operationResponse.ToStringFull()));
1267                         }
1268
1269                         SendMonoMessage(PhotonNetworkingMessage.OnPhotonRandomJoinFailed, operationResponse.ReturnCode, operationResponse.DebugMessage);
1270                         break;
1271                     }
1272
1273                     string roomName = (string)operationResponse[ParameterCode.RoomName];
1274                     this.mRoomToGetInto.name = roomName;
1275                     this.mGameserver = (string)operationResponse[ParameterCode.Address];
1276                     this.DisconnectToReconnect();
1277                     break;
1278                 }
1279
1280             case OperationCode.JoinLobby:
1281                 this.State = global::PeerState.JoinedLobby;
1282                 this.insideLobby = true;
1283                 SendMonoMessage(PhotonNetworkingMessage.OnJoinedLobby);
1284
1285                 // this.mListener.joinLobbyReturn();
1286                 break;
1287             case OperationCode.LeaveLobby:
1288                 this.State = global::PeerState.Authenticated;
1289                 this.LeftLobbyCleanup(); // will set insideLobby = false
1290                 break;
1291
1292             case OperationCode.Leave:
1293                 this.DisconnectToReconnect();
1294                 break;
1295
1296             case OperationCode.SetProperties:
1297                 // this.mListener.setPropertiesReturn(returnCode, debugMsg);
1298                 break;
1299
1300             case OperationCode.GetProperties:
1301                 {
1302                     Hashtable actorProperties = (Hashtable)operationResponse[ParameterCode.PlayerProperties];
1303                     Hashtable gameProperties = (Hashtable)operationResponse[ParameterCode.GameProperties];
1304                     this.ReadoutProperties(gameProperties, actorProperties, 0);
1305
1306                     // RemoveByteTypedPropertyKeys(actorProperties, false);
1307                     // RemoveByteTypedPropertyKeys(gameProperties, false);
1308                     // this.mListener.getPropertiesReturn(gameProperties, actorProperties, returnCode, debugMsg);
1309                     break;
1310                 }
1311
1312             case OperationCode.RaiseEvent:
1313                 // this usually doesn't give us a result. only if the caching is affected the server will send one.
1314                 break;
1315
1316             case OperationCode.FindFriends:
1317                 bool[] onlineList = operationResponse[ParameterCode.FindFriendsResponseOnlineList] as bool[];
1318                 string[] roomList = operationResponse[ParameterCode.FindFriendsResponseRoomIdList] as string[];
1319
1320                 if (onlineList != null && roomList != null && this.friendListRequested != null && onlineList.Length == this.friendListRequested.Length)
1321                 {
1322                     List friendList = new List(this.friendListRequested.Length);
1323                     for (int index = 0; index < this.friendListRequested.Length; index++)
1324                     {
1325                         FriendInfo friend = new FriendInfo();
1326                         friend.Name = this.friendListRequested[index];
1327                         friend.Room = roomList[index];
1328                         friend.IsOnline = onlineList[index];
1329                         friendList.Insert(index, friend);
1330                     }
1331                     PhotonNetwork.Friends = friendList;
1332                 }
1333                 else
1334                 {
1335                     // any of the lists is null and shouldn't. print a error
1336                     Debug.LogError("FindFriends failed to apply the result, as a required value wasn't provided or the friend list length differed from result.");
1337                 }
1338
1339                 this.friendListRequested = null;
1340                 this.isFetchingFriends = false;
1341                 this.friendListTimestamp = Environment.TickCount;
1342                 if (this.friendListTimestamp == 0)
1343                 {
1344                     this.friendListTimestamp = 1; // makes sure the timestamp is not accidentally 0
1345                 }
1346
1347                 SendMonoMessage(PhotonNetworkingMessage.OnUpdatedFriendList);
1348                 break;
1349
1350             case OperationCode.WebRpc:
1351                 SendMonoMessage(PhotonNetworkingMessage.OnWebRpcResponse, operationResponse);
1352                 break;
1353
1354             default:
1355                 Debug.LogWarning(string.Format("OperationResponse unhandled: {0}", operationResponse.ToString()));
1356                 break;
1357         }
1358
1359         this.externalListener.OnOperationResponse(operationResponse);
1360     }
File name: NetworkingPeer.cs Copy
1369     protected internal int FriendsListAge { get { return (this.isFetchingFriends || this.friendListTimestamp == 0) ? 0 : Environment.TickCount - this.friendListTimestamp; } }
File name: NetworkingPeer.cs Copy
1631     public void OnEvent(EventData photonEvent)
1632     {
1633         if (PhotonNetwork.logLevel >= PhotonLogLevel.Informational)
1634             Debug.Log(string.Format("OnEvent: {0}", photonEvent.ToString()));
1635
1636         int actorNr = -1;
1637         PhotonPlayer originatingPlayer = null;
1638
1639         if (photonEvent.Parameters.ContainsKey(ParameterCode.ActorNr))
1640         {
1641             actorNr = (int)photonEvent[ParameterCode.ActorNr];
1642             if (this.mActors.ContainsKey(actorNr))
1643             {
1644                 originatingPlayer = (PhotonPlayer)this.mActors[actorNr];
1645             }
1646             //else
1647             //{
1648             // // the actor sending this event is not in actorlist. this is usually no problem
1649             // if (photonEvent.Code != (byte)LiteOpCode.Join)
1650             // {
1651             // Debug.LogWarning("Received event, but we do not have this actor: " + actorNr);
1652             // }
1653             //}
1654         }
1655
1656         switch (photonEvent.Code)
1657         {
1658             case PunEvent.OwnershipRequest:
1659             {
1660                 int[] requestValues = (int[]) photonEvent.Parameters[ParameterCode.CustomEventContent];
1661                 int requestedViewId = requestValues[0];
1662                 int currentOwner = requestValues[1];
1663                 Debug.Log("Ev OwnershipRequest: " + photonEvent.Parameters.ToStringFull() + " ViewID: " + requestedViewId + " from: " + currentOwner + " Time: " + Environment.TickCount%1000);
1664
1665                 PhotonView requestedView = PhotonView.Find(requestedViewId);
1666                 if (requestedView == null)
1667                 {
1668                     Debug.LogWarning("Can't find PhotonView of incoming OwnershipRequest. ViewId not found: " + requestedViewId);
1669                     break;
1670                 }
1671
1672                 Debug.Log("Ev OwnershipRequest PhotonView.ownershipTransfer: " + requestedView.ownershipTransfer + " .ownerId: " + requestedView.ownerId + " isOwnerActive: " + requestedView.isOwnerActive + ". This client's player: " + PhotonNetwork.player.ToStringFull());
1673
1674                 switch (requestedView.ownershipTransfer)
1675                 {
1676                     case OwnershipOption.Fixed:
1677                         Debug.LogWarning("Ownership mode == fixed. Ignoring request.");
1678                         break;
1679                     case OwnershipOption.Takeover:
1680                         if (currentOwner == requestedView.ownerId)
1681                         {
1682                             // a takeover is successful automatically, if taken from current owner
1683                             requestedView.ownerId = actorNr;
1684                         }
1685                         break;
1686                     case OwnershipOption.Request:
1687                         if (currentOwner == PhotonNetwork.player.ID || PhotonNetwork.player.isMasterClient)
1688                         {
1689                             if ((requestedView.ownerId == PhotonNetwork.player.ID) || (PhotonNetwork.player.isMasterClient && !requestedView.isOwnerActive))
1690                             {
1691                                 SendMonoMessage(PhotonNetworkingMessage.OnOwnershipRequest, new object[] {requestedView, originatingPlayer});
1692                             }
1693                         }
1694                         break;
1695                     default:
1696                         break;
1697                 }
1698             }
1699                 break;
1700
1701             case PunEvent.OwnershipTransfer:
1702                 {
1703                     int[] transferViewToUserID = (int[]) photonEvent.Parameters[ParameterCode.CustomEventContent];
1704                     Debug.Log("Ev OwnershipTransfer. ViewID " + transferViewToUserID[0] + " to: " + transferViewToUserID[1] + " Time: " + Environment.TickCount%1000);
1705
1706                     int requestedViewId = transferViewToUserID[0];
1707                     int newOwnerId = transferViewToUserID[1];
1708
1709                     PhotonView pv = PhotonView.Find(requestedViewId);
1710                     pv.ownerId = newOwnerId;
1711
1712                     break;
1713                 }
1714             case EventCode.GameList:
1715                 {
1716                     this.mGameList = new Dictionary();
1717                     Hashtable games = (Hashtable)photonEvent[ParameterCode.GameList];
1718                     foreach (DictionaryEntry game in games)
1719                     {
1720                         string gameName = (string)game.Key;
1721                         this.mGameList[gameName] = new RoomInfo(gameName, (Hashtable)game.Value);
1722                     }
1723                     mGameListCopy = new RoomInfo[mGameList.Count];
1724                     mGameList.Values.CopyTo(mGameListCopy, 0);
1725                     SendMonoMessage(PhotonNetworkingMessage.OnReceivedRoomListUpdate);
1726                     break;
1727                 }
1728
1729             case EventCode.GameListUpdate:
1730                 {
1731                     Hashtable games = (Hashtable)photonEvent[ParameterCode.GameList];
1732                     foreach (DictionaryEntry room in games)
1733                     {
1734                         string gameName = (string)room.Key;
1735                         RoomInfo game = new RoomInfo(gameName, (Hashtable)room.Value);
1736                         if (game.removedFromList)
1737                         {
1738                             this.mGameList.Remove(gameName);
1739                         }
1740                         else
1741                         {
1742                             this.mGameList[gameName] = game;
1743                         }
1744                     }
1745                     this.mGameListCopy = new RoomInfo[this.mGameList.Count];
1746                     this.mGameList.Values.CopyTo(this.mGameListCopy, 0);
1747                     SendMonoMessage(PhotonNetworkingMessage.OnReceivedRoomListUpdate);
1748                     break;
1749                 }
1750
1751             case EventCode.QueueState:
1752                 // not used anymore
1753                 break;
1754
1755             case EventCode.AppStats:
1756                 // Debug.LogInfo("Received stats!");
1757                 this.mPlayersInRoomsCount = (int)photonEvent[ParameterCode.PeerCount];
1758                 this.mPlayersOnMasterCount = (int)photonEvent[ParameterCode.MasterPeerCount];
1759                 this.mGameCount = (int)photonEvent[ParameterCode.GameCount];
1760                 break;
1761
1762             case EventCode.Join:
1763                 // actorNr is fetched out of event above
1764                 Hashtable actorProperties = (Hashtable)photonEvent[ParameterCode.PlayerProperties];
1765                 if (originatingPlayer == null)
1766                 {
1767                     bool isLocal = this.mLocalActor.ID == actorNr;
1768                     this.AddNewPlayer(actorNr, new PhotonPlayer(isLocal, actorNr, actorProperties));
1769                     this.ResetPhotonViewsOnSerialize(); // This sets the correct OnSerializeState for Reliable OnSerialize
1770                 }
1771
1772                 if (actorNr == this.mLocalActor.ID)
1773                 {
1774                     // in this player's 'own' join event, we get a complete list of players in the room, so check if we know all players
1775                     int[] actorsInRoom = (int[])photonEvent[ParameterCode.ActorList];
1776                     foreach (int actorNrToCheck in actorsInRoom)
1777                     {
1778                         if (this.mLocalActor.ID != actorNrToCheck && !this.mActors.ContainsKey(actorNrToCheck))
1779                         {
1780                             this.AddNewPlayer(actorNrToCheck, new PhotonPlayer(false, actorNrToCheck, string.Empty));
1781                         }
1782                     }
1783
1784                     // joinWithCreateOnDemand can turn an OpJoin into creating the room. Then actorNumber is 1 and callback: OnCreatedRoom()
1785                     if (this.mLastJoinType == JoinType.JoinOrCreateOnDemand && this.mLocalActor.ID == 1)
1786                     {
1787                         SendMonoMessage(PhotonNetworkingMessage.OnCreatedRoom);
1788                     }
1789                     SendMonoMessage(PhotonNetworkingMessage.OnJoinedRoom); //Always send OnJoinedRoom
1790
1791                 }
1792                 else
1793                 {
1794                     SendMonoMessage(PhotonNetworkingMessage.OnPhotonPlayerConnected, this.mActors[actorNr]);
1795                 }
1796                 break;
1797
1798             case EventCode.Leave:
1799                 this.HandleEventLeave(actorNr);
1800                 break;
1801
1802             case EventCode.PropertiesChanged:
1803                 int targetActorNr = (int)photonEvent[ParameterCode.TargetActorNr];
1804                 Hashtable gameProperties = null;
1805                 Hashtable actorProps = null;
1806                 if (targetActorNr == 0)
1807                 {
1808                     gameProperties = (Hashtable)photonEvent[ParameterCode.Properties];
1809                 }
1810                 else
1811                 {
1812                     actorProps = (Hashtable)photonEvent[ParameterCode.Properties];
1813                 }
1814
1815                 this.ReadoutProperties(gameProperties, actorProps, targetActorNr);
1816                 break;
1817
1818             case PunEvent.RPC:
1819                 //ts: each event now contains a single RPC. execute this
1820                 // Debug.Log("Ev RPC from: " + originatingPlayer);
1821                 this.ExecuteRPC(photonEvent[ParameterCode.Data] as Hashtable, originatingPlayer);
1822                 break;
1823
1824             case PunEvent.SendSerialize:
1825             case PunEvent.SendSerializeReliable:
1826                 Hashtable serializeData = (Hashtable)photonEvent[ParameterCode.Data];
1827                 //Debug.Log(serializeData.ToStringFull());
1828
1829                 int remoteUpdateServerTimestamp = (int)serializeData[(byte)0];
1830                 short remoteLevelPrefix = -1;
1831                 short initialDataIndex = 1;
1832                 if (serializeData.ContainsKey((byte)1))
1833                 {
1834                     remoteLevelPrefix = (short)serializeData[(byte)1];
1835                     initialDataIndex = 2;
1836                 }
1837
1838                 for (short s = initialDataIndex; s < serializeData.Count; s++)
1839                 {
1840                     this.OnSerializeRead(serializeData[s] as Hashtable, originatingPlayer, remoteUpdateServerTimestamp, remoteLevelPrefix);
1841                 }
1842                 break;
1843
1844             case PunEvent.Instantiation:
1845                 this.DoInstantiate((Hashtable)photonEvent[ParameterCode.Data], originatingPlayer, null);
1846                 break;
1847
1848             case PunEvent.CloseConnection:
1849                 // MasterClient "requests" a disconnection from us
1850                 if (originatingPlayer == null || !originatingPlayer.isMasterClient)
1851                 {
1852                     Debug.LogError("Error: Someone else(" + originatingPlayer + ") then the masterserver requests a disconnect!");
1853                 }
1854                 else
1855                 {
1856                     PhotonNetwork.LeaveRoom();
1857                 }
1858
1859                 break;
1860
1861             case PunEvent.DestroyPlayer:
1862                 Hashtable evData = (Hashtable)photonEvent[ParameterCode.Data];
1863                 int targetPlayerId = (int)evData[(byte)0];
1864                 if (targetPlayerId >= 0)
1865                 {
1866                     this.DestroyPlayerObjects(targetPlayerId, true);
1867                 }
1868                 else
1869                 {
1870                     if (this.DebugOut >= DebugLevel.INFO) Debug.Log("Ev DestroyAll! By PlayerId: " + actorNr);
1871                     this.DestroyAll(true);
1872                 }
1873                 break;
1874
1875             case PunEvent.Destroy:
1876                 evData = (Hashtable)photonEvent[ParameterCode.Data];
1877                 int instantiationId = (int)evData[(byte)0];
1878                 // Debug.Log("Ev Destroy for viewId: " + instantiationId + " sent by owner: " + (instantiationId / PhotonNetwork.MAX_VIEW_IDS == actorNr) + " this client is owner: " + (instantiationId / PhotonNetwork.MAX_VIEW_IDS == this.mLocalActor.ID));
1879
1880
1881                 PhotonView pvToDestroy = null;
1882                 if (this.photonViewList.TryGetValue(instantiationId, out pvToDestroy))
1883                 {
1884                     this.RemoveInstantiatedGO(pvToDestroy.gameObject, true);
1885                 }
1886                 else
1887                 {
1888                     if (this.DebugOut >= DebugLevel.ERROR) Debug.LogError("Ev Destroy Failed. Could not find PhotonView with instantiationId " + instantiationId + ". Sent by actorNr: " + actorNr);
1889                 }
1890
1891                 break;
1892
1893             case PunEvent.AssignMaster:
1894                 evData = (Hashtable)photonEvent[ParameterCode.Data];
1895                 int newMaster = (int)evData[(byte)1];
1896                 this.SetMasterClient(newMaster, false);
1897                 break;
1898
1899             default:
1900                 if (photonEvent.Code < 200 && PhotonNetwork.OnEventCall != null)
1901                 {
1902                     object content = photonEvent[ParameterCode.Data];
1903                     PhotonNetwork.OnEventCall(photonEvent.Code, content, actorNr);
1904                 }
1905                 else
1906                 {
1907                     // actorNr might be null. it is fetched out of event on top of method
1908                     // Hashtable eventContent = (Hashtable) photonEvent[ParameterCode.Data];
1909                     // this.mListener.customEventAction(actorNr, eventCode, eventContent);
1910                     Debug.LogError("Error. Unhandled event: " + photonEvent);
1911                 }
1912                 break;
1913         }
1914
1915         this.externalListener.OnEvent(photonEvent);
1916     }
File name: PhotonClasses.cs Copy
774         return string.Format("[PhotonMessageInfo: Sender='{1}' Senttime={0}]", this.timestamp, this.sender);
File name: PhotonNetwork.cs Copy
2214     public static void FetchServerTimestamp()
2215     {
2216         if (networkingPeer != null)
2217         {
2218             networkingPeer.FetchServerTimestamp();
2219         }
2220     }
File name: PickupItem.cs Copy
124     public void PunPickup(PhotonMessageInfo msgInfo)
125     {
126         // when this client's RPC gets executed, this client no longer waits for a sent pickup and can try again
127         if (msgInfo.sender.isLocal) this.SentPickup = false;
128
129
130         // In this solution, picked up items are disabled. They can't be picked up again this way, etc.
131         // You could check "active" first, if you're not interested in failed pickup-attempts.
132         if (!this.gameObject.GetActive())
133         {
134             // optional logging:
135             Debug.Log("Ignored PU RPC, cause item is inactive. " + this.gameObject + " SecondsBeforeRespawn: " + SecondsBeforeRespawn + " TimeOfRespawn: " + this.TimeOfRespawn + " respawn in future: " + (TimeOfRespawn > PhotonNetwork.time));
136             return; // makes this RPC being ignored
137         }
138
139
140         // if the RPC isn't ignored by now, this is a successful pickup. this might be "my" pickup and we should do a callback
141         this.PickupIsMine = msgInfo.sender.isLocal;
142
143         // call the method OnPickedUp(PickupItem item) if a GameObject was defined as callback target
144         if (this.OnPickedUpCall != null)
145         {
146             // you could also skip callbacks for items that are not picked up by this client by using: if (this.PickupIsMine)
147             this.OnPickedUpCall.SendMessage("OnPickedUp", this);
148         }
149
150
151         // setup a respawn (or none, if the item has to be dropped)
152         if (SecondsBeforeRespawn <= 0)
153         {
154             this.PickedUp(0.0f); // item doesn't auto-respawn. must be dropped
155         }
156         else
157         {
158             // how long it is until this item respanws, depends on the pickup time and the respawn time
159             double timeSinceRpcCall = (PhotonNetwork.time - msgInfo.timestamp);
160             double timeUntilRespawn = SecondsBeforeRespawn - timeSinceRpcCall;
161
162             //Debug.Log("msg timestamp: " + msgInfo.timestamp + " time until respawn: " + timeUntilRespawn);
163
164             if (timeUntilRespawn > 0)
165             {
166                 this.PickedUp((float)timeUntilRespawn);
167             }
168         }
169     }
File name: PickupItemSimple.cs Copy
40     public void PunPickupSimple(PhotonMessageInfo msgInfo)
41     {
42         // one of the messages might be ours
43         // note: you could check "active" first, if you're not interested in your own, failed pickup-attempts.
44         if (this.SentPickup && msgInfo.sender.isLocal)
45         {
46             if (this.gameObject.GetActive())
47             {
48                 // picked up! yay.
49             }
50             else
51             {
52                 // pickup failed. too late (compared to others)
53             }
54         }
55
56         this.SentPickup = false;
57
58         if (!this.gameObject.GetActive())
59         {
60             Debug.Log("Ignored PU RPC, cause item is inactive. " + this.gameObject);
61             return;
62         }
63
64
65         // how long it is until this item respanws, depends on the pickup time and the respawn time
66         double timeSinceRpcCall = (PhotonNetwork.time - msgInfo.timestamp);
67         float timeUntilRespawn = SecondsBeforeRespawn - (float)timeSinceRpcCall;
68         //Debug.Log("msg timestamp: " + msgInfo.timestamp + " time until respawn: " + timeUntilRespawn);
69
70         if (timeUntilRespawn > 0)
71         {
72             // this script simply disables the GO for a while until it respawns.
73             this.gameObject.SetActive(false);
74             Invoke("RespawnAfter", timeUntilRespawn);
75         }
76     }

TIMESTAMP 181 lượt xem

Gõ tìm kiếm nhanh...