//RPCPacketData Serializer - Minimum Calculatable Bytes: 10 bytes // - packetOwnerID int16, 2 bytes // - networkObjectID int32, 4 bytes // - rpcIndex int16, 2 bytes // - parameters string list // - element count int32, 4 bytes // - element byte length int32, 4 bytes // - element string, ? bytes // - paramTypes string list // - element count int32, 4 bytes // - element byte length int32, 4 bytes // - element string, ? bytes public static byte[] SerializeRPCPacketData(RPCPacketData rpc) { List <byte> objectAsBytes = new List <byte>(); //Packet OwnerID as a SHORT byte[] packetOwnerID = System.BitConverter.GetBytes((short)rpc.packetOwnerID); objectAsBytes.AddRange(packetOwnerID); //NetworkObjectID int32 byte[] networkObjectID = System.BitConverter.GetBytes(rpc.networkObjectID); objectAsBytes.AddRange(networkObjectID); //RPC Index as a SHORT byte[] rpcIndex = System.BitConverter.GetBytes((short)rpc.rpcIndex); objectAsBytes.AddRange(rpcIndex); //Parameters byte[] parameterElementCount = System.BitConverter.GetBytes(rpc.parameters.Count); objectAsBytes.AddRange(parameterElementCount); for (int i = 0; i < rpc.parameters.Count; i++) { byte[] arrayElement = Encoding.ASCII.GetBytes(rpc.parameters[i]); objectAsBytes.AddRange(System.BitConverter.GetBytes(arrayElement.Length)); //Element length objectAsBytes.AddRange(arrayElement); } //ParamTypes byte[] paramTypeElementCount = System.BitConverter.GetBytes(rpc.paramTypes.Count); objectAsBytes.AddRange(paramTypeElementCount); for (int i = 0; i < rpc.parameters.Count; i++) { byte[] arrayElement = Encoding.ASCII.GetBytes(rpc.paramTypes[i]); objectAsBytes.AddRange(System.BitConverter.GetBytes(arrayElement.Length)); //Element length objectAsBytes.AddRange(arrayElement); } return(objectAsBytes.ToArray()); }
public static RPCPacketData DeserializeRPCPacketData(byte[] givenBytes) { List <byte> rpcBytes = new List <byte>(); rpcBytes.AddRange(givenBytes); int intIndex = 0; short packetOwnerID = System.BitConverter.ToInt16(rpcBytes.GetRange(intIndex, 2).ToArray(), 0); intIndex += 2; int networkObjectID = System.BitConverter.ToInt32(rpcBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; short rpcIndex = System.BitConverter.ToInt16(rpcBytes.GetRange(intIndex, 2).ToArray(), 0); intIndex += 2; RPCPacketData rpc = new RPCPacketData(networkObjectID, rpcIndex, packetOwnerID); //Parameter List int parameterElementCount = System.BitConverter.ToInt32(rpcBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; for (int i = 0; i < parameterElementCount; i++) { int byteLength = System.BitConverter.ToInt32(rpcBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; string element = Encoding.ASCII.GetString(rpcBytes.GetRange(intIndex, byteLength).ToArray()); intIndex += byteLength; rpc.parameters.Add(element); } //ParamType List int paraTypeElementCount = System.BitConverter.ToInt32(rpcBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; for (int i = 0; i < paraTypeElementCount; i++) { int byteLength = System.BitConverter.ToInt32(rpcBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; string element = Encoding.ASCII.GetString(rpcBytes.GetRange(intIndex, byteLength).ToArray()); intIndex += byteLength; rpc.paramTypes.Add(element); } return(rpc); }
public void CallRPC(Packet.sendType sendType = Packet.sendType.culledbuffered, params object[] list) { RPCPacketData rpcData = GenerateRPCData(sendType, list); Packet p = new Packet(Packet.pType.rpc, sendType, ENSSerialization.SerializeRPCPacketData(rpcData)); p.sendToAll = true; p.relatesToNetObjID = net.networkID; if (NetTools.IsMultiplayerGame() == false) { InvokeRPC(rpcData.ReturnArgs()); return; } if (net == null || !net.initialized) { queued.Add(sendType, list); //Debug.Log("Rpc called before initialization. Adding to queue"); return; } NetClient.instanceClient.SendPacket(p); }
public Packet GenerateRPCPacket(Packet.sendType sendType = Packet.sendType.culledbuffered, params object[] list) { RPCPacketData rpcData = new RPCPacketData(net.networkID, rpcIndex, NetTools.clientID, list); Packet p = new Packet(Packet.pType.rpc, sendType, ENSSerialization.SerializeRPCPacketData(rpcData)); p.sendToAll = true; p.relatesToNetObjID = net.networkID; return(p); }
public void HandlePacketFromClient(Packet pack, NetworkPlayer client, bool fromSelf = false) { if (pack == null) { return; } //if (fromSelf) //{ // Debug.Log("SELF PACKET: " + pack.packetType); //} if (pack.packetOwnerID != client.clientID)// && client.tcpClient == NetClient.instanceClient.client) //if server dont change cause if it is -1 it has all authority. { pack.packetOwnerID = client.clientID; } if (client.clientID == NetClient.instanceClient.clientID) //Setup server authority. { pack.serverAuthority = true; } else { pack.serverAuthority = false; } if (pack.packetType == Packet.pType.rpc) { RPCPacketData rPD = ENSSerialization.DeserializeRPCPacketData(pack.packetData); rPD.packetOwnerID = client.clientID; pack.packetData = ENSSerialization.SerializeRPCPacketData(rPD); } if (pack.packetSendType == Packet.sendType.buffered || pack.packetSendType == Packet.sendType.culledbuffered) { //If it is a culledbuffered packet, if it is a netVarEdit packet, and it relates to the same netObj and is the RPC. //Then cull the previous of the same RPC to prevent RPC spam //This also happens with NetworkFields, even though network fields are generally *not buffered* the logic is here. //The reason NetworkFields aren't buffered is because the NetServer already syncs them when a client joins. if (pack.packetSendType == Packet.sendType.culledbuffered && (pack.packetType == Packet.pType.netVarEdit || pack.packetType == Packet.pType.rpc)) { List <Packet> related = new List <Packet>(); if (bufferedPackets.ContainsKey(pack.relatesToNetObjID.ToString())) { related.AddRange(bufferedPackets[pack.relatesToNetObjID.ToString()]); } if (bufferedPackets.ContainsKey(pack.tag) && bufferedPackets[pack.tag] != null) { related.AddRange(bufferedPackets[pack.tag]); } foreach (Packet buff in related) { if (buff.relatesToNetObjID == pack.relatesToNetObjID && buff.packetType == pack.packetType) { if (buff.packetType == Packet.pType.netVarEdit) { if (buff.GetPacketData <NetworkFieldPacket>().fieldName == pack.GetPacketData <NetworkField>().fieldName) { RemoveBufferedPacket(buff); } } else if (buff.packetType == Packet.pType.rpc) { if (buff.GetPacketData <RPCPacketData>().rpcIndex == pack.GetPacketData <RPCPacketData>().rpcIndex) { RemoveBufferedPacket(buff); } } } } } //Debug.Log("Buffered Packet"); AddBufferedPacket(pack); } UnityPacketHandler.instance.QueuePacket(pack); if (pack.sendToAll || pack.usersToRecieve.Count > 0) { foreach (NetworkPlayer player in connections.ToArray()) { //Debug.Log(player.clientID + " " + NetTools.clientID); if (player == null || player.tcpClient == null || (player.clientID == NetTools.clientID)) { continue; } if (pack.sendToAll == true || pack.usersToRecieve.Contains(player.clientID)) { if (player.tcpClient.Connected) { try { SendPacket(player, pack); } catch (System.Exception e) { if (player.tcpClient.Connected) { Debug.LogError(e); //If we ain't connected anymore then it makes sense. connections.Remove(player); } } } else { connections.Remove(player); } } } } }
public RPCPacketData GenerateRPCData(Packet.sendType sendType = Packet.sendType.culledbuffered, params object[] list) { RPCPacketData rpcData = new RPCPacketData(net.networkID, rpcIndex, NetTools.clientID, list); return(rpcData); }
public void ExecutePacket(Packet curPacket) { if (curPacket.packetType == Packet.pType.gOInstantiate) //It gets instantiated NetTools. { NetworkObject nObj = null; GameObjectInstantiateData gOID = ENSSerialization.DeserializeGOID(curPacket.packetData); //Debug.Log(NetTools.clientID + ", " + curPacket.packetOwnerID); if (NetTools.clientID != curPacket.packetOwnerID || NetworkObject.NetObjFromNetID(gOID.netObjID) == null) { if (!curPacket.serverAuthority && NetworkData.instance.networkPrefabList[gOID.prefabDomainID].prefabList[gOID.prefabID].serverInstantiateOnly) { return; //If it is server only, and you aren't the server, don't do it. } GameObject g = NetworkData.instance.RequestPooledObject(gOID.prefabDomainID, gOID.prefabID); if (g == null) //If a pooled object couldn't be found, make a new one. { try { g = Instantiate(NetworkData.instance.networkPrefabList[gOID.prefabDomainID].prefabList[gOID.prefabID].prefab, gOID.position.ToVec3(), gOID.rotation.ToQuaternion()); } catch (System.Exception e) { Debug.Log("Error NetInstantiating: domainID: " + gOID.prefabDomainID + ", prefabID: " + gOID.prefabID + e); return; } } else { //If pooled apply required position/rotation/etc. g.transform.position = gOID.position.ToVec3(); g.transform.rotation = gOID.rotation.ToQuaternion(); } nObj = g.GetComponent <NetworkObject>(); if (nObj == null) { nObj = g.AddComponent <NetworkObject>(); } foreach (NetworkField defaultField in NetworkData.instance.networkPrefabList[gOID.prefabDomainID].defaultFields) { nObj.fields.Add(defaultField.Clone()); } foreach (RPC defaultRPC in NetworkData.instance.networkPrefabList[gOID.prefabDomainID].defaultRpcs) { nObj.rpcs.Add(defaultRPC.Clone()); } nObj.ownerID = curPacket.packetOwnerID; nObj.prefabDomainID = gOID.prefabDomainID; nObj.prefabID = gOID.prefabID; nObj.networkID = gOID.netObjID; nObj.sharedObject = gOID.isShared; nObj.Initialize(); //nObj.DoRpcFieldInitialization(); if (nObj.onNetworkStart != null) { nObj.onNetworkStart.Invoke(); } if (gOID.fieldDefaults != null) { foreach (NetworkFieldPacket nFP in gOID.fieldDefaults) { nFP.networkObjID = gOID.netObjID; //Debug.Log(nFP.data); nObj.SetFieldLocal(nFP.fieldName, nFP.data.ToObject()); } } } } else if (curPacket.packetType == Packet.pType.gODestroy) { //Debug.Log(curPacket.jsonData); //Debug.Log(curPacket.GetPacketData()); //int netID = ENSSerialization.DeserializeInt(curPacket.packetData); NetworkObject found = NetworkObject.NetObjFromNetID(curPacket.relatesToNetObjID); if (found != null && (found.ownerID == curPacket.packetOwnerID || curPacket.serverAuthority || found.sharedObject)) { if (disableBeforeDestroy) { if (NetworkData.instance.ResetPooledObject(found) == false) { destroyQueue.Add(found.gameObject); } } else { if (NetworkData.instance.ResetPooledObject(found) == false) { Destroy(found.gameObject); } } if (NetTools.isServer && System.BitConverter.ToBoolean(curPacket.packetData, 0)) //Check NetTools.NetDestroy but basically it is cullRelatedPackets. { NetTools.CullPacketsByNetworkID(curPacket.relatesToNetObjID); } } else if (found == null) { Debug.LogWarning("Couldn't find NetworkObject of ID: " + curPacket.relatesToNetObjID); } } else if (curPacket.packetType == Packet.pType.multiPacket) { //Debug.Log("Recieved buffered packets."); List <byte[]> packetByteInfo = curPacket.GetPacketData <PacketListPacket>().packets; lock (packetQueue) { foreach (byte[] packetByte in packetByteInfo) { packetQueue.Add(ENSSerialization.DeserializePacket(packetByte)); } } syncingBuffered = true; } else if (curPacket.packetType == Packet.pType.loginInfo) { //Debug.Log("Login Info Packet Recieved."); PlayerLoginData pLD = curPacket.GetPacketData <PlayerLoginData>(); NetTools.clientID = pLD.clientID;//System.BitConverter.ToInt16(curPacket.packetData,0); NetClient.instanceClient.clientID = NetTools.clientID; NetClient.instanceClient.serversSteamID = pLD.serverSteamID; if (NetTools.isServer) { NetServer.serverInstance.myConnection = NetServer.serverInstance.GetPlayerByID(NetTools.clientID); } NetTools.onJoinServer.Invoke(); //print("Test"); } else if (curPacket.packetType == Packet.pType.netVarEdit) { NetworkFieldPacket nFP = ENSSerialization.DeserializeNetworkFieldPacket(curPacket.packetData); NetworkObject netObj = NetworkObject.NetObjFromNetID(nFP.networkObjID); if (netObj == null) { return; } if (netObj.initialized == false) { //netObj.queuedNetworkPackets.Add(curPacket); return; } if ((netObj.ownerID != curPacket.packetOwnerID && !curPacket.serverAuthority && !netObj.sharedObject) || (curPacket.packetOwnerID == NetTools.clientID && nFP.immediateOnSelf)) { return; } //Debug.Log("Seting NetVarEdit."); try { netObj.SetFieldLocal(nFP.fieldName, nFP.data.ToObject()); } catch (System.Exception e) { Debug.LogError(e); } } else if (curPacket.packetType == Packet.pType.rpc) { //Debug.Log(curPacket.jsonData); RPCPacketData rPD = ENSSerialization.DeserializeRPCPacketData(curPacket.packetData); NetworkObject nObj = NetworkObject.NetObjFromNetID(rPD.networkObjectID); if (nObj == null || (nObj.rpcs[rPD.rpcIndex].serverAuthorityRequired && !curPacket.serverAuthority) || (nObj.ownerID != curPacket.packetOwnerID && !nObj.sharedObject && !curPacket.serverAuthority)) { return; //Means only server can run it. } nObj.rpcs[rPD.rpcIndex].InvokeRPC(rPD.ReturnArgs()); } else if (curPacket.packetType == Packet.pType.connectionPacket) { if (!curPacket.serverAuthority && curPacket.packetOwnerID != -1) { return; //Prevents anyone from disconnecting everyone. } ConnectionPacket cP = ENSSerialization.DeserializeConnectionPacket(curPacket.packetData); if (cP.immediateDisconnect) { NetClient.instanceClient.DisconnectFromServer(); NetTools.onLeaveServer.Invoke(cP.reason); } } //else if (curPacket.packetType == Packet.pType.networkAuth && NetTools.isServer) //{ //} }