public static bool ProcessOneMessage(IbaCmsDbContext cmsDb, P2PMessage msg) { var senderId = msg.SenderId; var idToSendTo = msg.Thread.InitialRecipientId == senderId ? msg.Thread.InitialSenderId : msg.Thread.InitialRecipientId; var deviceOwners = cmsDb.DeviceOwners.Where(r => r.IbaId == idToSendTo); var count = 0; foreach (var owner in deviceOwners) { var appuserMessage = new AppP2PMessage { Created = DateTime.UtcNow, DeviceOwner = owner, Message = msg }; foreach (var device in owner.Devices.Where(d => !d.PushToken.IsNullOrWhiteSpace())) { //var push = new PushMessageQueue //{ // Created = DateTime.UtcNow, // Device = device, // AppP2PMessage = appuserMessage //}; //appuserMessage.Queued.Add(push); } count++; cmsDb.AppP2PMessages.Add(appuserMessage); SendPushMessage(appuserMessage); } msg.DeliveredTime = DateTime.UtcNow; return(count > 0); }
public void Connect(string obj) { MelonLogger.Log("Starting client and connecting"); ServerId = ulong.Parse(obj); MelonLogger.Log("Connecting to " + obj); P2PMessage msg = new P2PMessage(); msg.WriteByte((byte)MessageType.Join); msg.WriteByte(MultiplayerMod.PROTOCOL_VERSION); msg.WriteUnicodeString(SteamClient.Name); connection = transportLayer.ConnectTo(ServerId, msg); transportLayer.OnConnectionClosed += TransportLayer_OnConnectionClosed; transportLayer.OnMessageReceived += TransportLayer_OnMessageReceived; isConnected = true; localRigTransforms = BWUtil.GetLocalRigTransforms(); ui.SetState(MultiplayerUIState.Client); GunHooks.OnGunFire += BWUtil_OnFire; PlayerHooks.OnPlayerGrabObject += PlayerHooks_OnPlayerGrabObject; PlayerHooks.OnPlayerReleaseObject += PlayerHooks_OnPlayerReleaseObject; MultiplayerMod.OnLevelWasLoadedEvent += MultiplayerMod_OnLevelWasLoadedEvent; }
public void Connect(string obj) { MelonModLogger.Log("Starting client and connecting"); ServerId = ulong.Parse(obj); MelonModLogger.Log("Connecting to " + obj); P2PMessage msg = new P2PMessage(); msg.WriteByte((byte)MessageType.Join); msg.WriteByte(MultiplayerMod.PROTOCOL_VERSION); msg.WriteUnicodeString(SteamClient.Name); connection = transportLayer.ConnectTo(ServerId, msg); transportLayer.OnConnectionClosed += TransportLayer_OnConnectionClosed; transportLayer.OnMessageReceived += TransportLayer_OnMessageReceived; //SteamNetworking.SendP2PPacket(ServerId, msg.GetBytes()); isConnected = true; //PlayerHooks.OnPlayerGrabObject += PlayerHooks_OnPlayerGrabObject; //PlayerHooks.OnPlayerLetGoObject += PlayerHooks_OnPlayerLetGoObject; localRigTransforms = BWUtil.GetLocalRigTransforms(); //SteamNetworking.OnP2PSessionRequest = OnP2PSessionRequest; //SteamNetworking.OnP2PConnectionFailed = OnP2PConnectionFailed; ui.SetState(MultiplayerUIState.Client); }
private void SendToId(INetworkMessage msg, P2PSend send, SteamId id) { P2PMessage pMsg = msg.MakeMsg(); byte[] bytes = pMsg.GetBytes(); SteamNetworking.SendP2PPacket(id, bytes, bytes.Length, 0, send); }
private void TransportLayer_OnConnectionClosed(ITransportConnection connection, ConnectionClosedReason reason) { switch (reason) { case ConnectionClosedReason.Timeout: case ConnectionClosedReason.ClosedByRemote: if (smallPlayerIds.ContainsKey(connection.ConnectedTo)) { MelonLogger.Log("Player left with ID: " + connection.ConnectedTo); byte smallId = smallPlayerIds[connection.ConnectedTo]; P2PMessage disconnectMsg = new P2PMessage(); disconnectMsg.WriteByte((byte)MessageType.Disconnect); disconnectMsg.WriteByte(smallId); playerObjects[smallId].Delete(); playerObjects.Remove(smallId); players.RemoveAll((ulong val) => val == connection.ConnectedTo); smallPlayerIds.Remove(connection.ConnectedTo); foreach (SteamId p in players) { playerConnections[p].SendMessage(disconnectMsg, MessageSendType.Reliable); } } break; case ConnectionClosedReason.Other: break; } }
public override bool ProcessData(P2PBridge bridge, byte[] data, bool reset) { Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "DATA RECEIVED: " + P2PMessage.DumpBytes(data, 128, true), GetType().Name); return(true); }
public void HandleMessageTimeout(object source, SendMessageTimeoutEventArgs e) { P2PMessage msg = e.P2PMessage; logger.InfoFormat("HandleSendMessageTimeout, to:{0}, packetId:{1}, sequence:{2}, ts:{3}, payload:{4}", e.User.AppAccount, msg.PacketId, msg.Sequence, msg.Timestamp, Encoding.UTF8.GetString(msg.Payload)); }
private void ServerSendToAll(INetworkMessage msg, MessageSendType send) { P2PMessage pMsg = msg.MakeMsg(); foreach (SteamId p in players) { playerConnections[p].SendMessage(pMsg, send); } }
private void ServerSendToAll(INetworkMessage msg, P2PSend send) { P2PMessage pMsg = msg.MakeMsg(); byte[] bytes = pMsg.GetBytes(); foreach (SteamId p in players) { SteamNetworking.SendP2PPacket(p, bytes, bytes.Length, 0, send); } }
private void OnP2PConnectionFailed(SteamId id, P2PSessionError error) { if (error == P2PSessionError.NoRightsToApp) { MelonModLogger.LogError("You don't own the game on Steam."); } else if (error == P2PSessionError.NotRunningApp) { // Probably a leaver if (smallPlayerIds.ContainsKey(id)) { MelonModLogger.Log("Player left with SteamID: " + id); byte smallId = smallPlayerIds[id]; P2PMessage disconnectMsg = new P2PMessage(); disconnectMsg.WriteByte((byte)MessageType.Disconnect); disconnectMsg.WriteByte(smallId); foreach (SteamId p in players) { SteamNetworking.SendP2PPacket(p, disconnectMsg.GetBytes(), -1, 0, P2PSend.Reliable); } playerObjects[smallId].Destroy(); playerObjects.Remove(smallId); players.RemoveAll((ulong val) => val == id); smallPlayerIds.Remove(id); } } else if (error == P2PSessionError.Timeout) { MelonModLogger.LogError("Connection with " + id + "timed out."); byte smallId = smallPlayerIds[id]; P2PMessage disconnectMsg = new P2PMessage(); disconnectMsg.WriteByte((byte)MessageType.Disconnect); disconnectMsg.WriteByte(smallId); foreach (SteamId p in players) { SteamNetworking.SendP2PPacket(p, disconnectMsg.GetBytes(), -1, 0, P2PSend.Reliable); } playerObjects[smallId].Destroy(); playerObjects.Remove(smallId); players.RemoveAll((ulong val) => val == id); smallPlayerIds.Remove(id); } else { MelonModLogger.LogError("Unhandled P2P error: " + error.ToString()); } }
public void TestStringMessageRoundTrip() { P2PMessage msg = new P2PMessage(); msg.WriteUnicodeString("hello world!"); byte[] msgBytes = msg.GetBytes(); P2PMessage readMsg = new P2PMessage(msgBytes); Assert.AreEqual(readMsg.ReadUnicodeString(), "hello world!"); }
/// <summary> /// Sends a message with the specified <see cref="P2PMessage"/> and <see cref="AckHandler"/>. /// </summary> public virtual void SendMessage(P2PMessage p2pMessage, int ackTimeout, AckHandler ackHandler) { Debug.Assert(p2pMessage.Version == version); p2pMessage.Header.SessionId = p2pSession.SessionId; // If not an ack, set the footer (p2pv1 only) if (p2pMessage.Version == P2PVersion.P2PV1 && (p2pMessage.V1Header.Flags & P2PFlag.Acknowledgement) != P2PFlag.Acknowledgement) { p2pMessage.Footer = ApplicationId; } p2pSession.Send(p2pMessage, ackTimeout, ackHandler); }
public void TestByteMessageRoundTrip() { P2PMessage msg = new P2PMessage(); msg.WriteByte(12); msg.WriteByte(2); msg.WriteByte(102); byte[] msgBytes = msg.GetBytes(); P2PMessage readMsg = new P2PMessage(msgBytes); Assert.AreEqual(readMsg.ReadByte(), 12); Assert.AreEqual(readMsg.ReadByte(), 2); Assert.AreEqual(readMsg.ReadByte(), 102); }
public void TestFloatMessageRoundTrip() { P2PMessage msg = new P2PMessage(); msg.WriteFloat(0.1235f); msg.WriteFloat(0.2124f); msg.WriteFloat(0.135f); byte[] msgBytes = msg.GetBytes(); P2PMessage readMsg = new P2PMessage(msgBytes); Assert.AreEqual(readMsg.ReadFloat(), 0.1235f, TEST_MARGIN); Assert.AreEqual(readMsg.ReadFloat(), 0.2124f, TEST_MARGIN); Assert.AreEqual(readMsg.ReadFloat(), 0.135f, TEST_MARGIN); }
public void TestMultipleRoundTrip() { P2PMessage msg = new P2PMessage(); msg.WriteByte(172); msg.WriteUnicodeString("hello world! Зарегистрируйтесь ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌"); msg.WriteFloat(1412.2f); byte[] msgBytes = msg.GetBytes(); P2PMessage readMsg = new P2PMessage(msgBytes); Assert.AreEqual(readMsg.ReadByte(), 172); Assert.AreEqual(readMsg.ReadUnicodeString(), "hello world! Зарегистрируйтесь ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌"); Assert.AreEqual(readMsg.ReadFloat(), 1412.2f, TEST_MARGIN); }
public void TestPlayerNameMessage() { PlayerNameMessage pnm = new PlayerNameMessage(); pnm.name = "Someone Somewhere"; byte[] msgBytes = pnm.MakeMsg().GetBytes(); P2PMessage readMsg = new P2PMessage(msgBytes); Assert.AreEqual(readMsg.ReadByte(), (byte)MessageType.PlayerName); PlayerNameMessage pnm2 = new PlayerNameMessage(readMsg); Assert.AreEqual(pnm2.name, "Someone Somewhere"); }
public void TestOtherPlayerNameMessage() { OtherPlayerNameMessage opnm = new OtherPlayerNameMessage(); opnm.playerId = 124; opnm.name = "Someone Somewhere"; byte[] msgBytes = opnm.MakeMsg().GetBytes(); P2PMessage readMsg = new P2PMessage(msgBytes); Assert.AreEqual(readMsg.ReadByte(), (byte)MessageType.OtherPlayerName); OtherPlayerNameMessage opnm2 = new OtherPlayerNameMessage(readMsg); Assert.AreEqual(opnm2.playerId, 124); Assert.AreEqual(opnm2.name, "Someone Somewhere"); }
public void StopServer() { ui.SetState(MultiplayerUIState.PreConnect); IsRunning = false; try { foreach (PlayerRep r in playerObjects.Values) { r.Delete(); } } catch (Exception) { MelonLogger.LogError("Caught exception destroying player objects"); } playerObjects.Clear(); playerNames.Clear(); smallPlayerIds.Clear(); largePlayerIds.Clear(); smallIdCounter = 1; P2PMessage shutdownMsg = new P2PMessage(); shutdownMsg.WriteByte((byte)MessageType.ServerShutdown); foreach (SteamId p in players) { playerConnections[p].SendMessage(shutdownMsg, MessageSendType.Reliable); playerConnections[p].Disconnect(); } players.Clear(); transportLayer.OnMessageReceived -= TransportLayer_OnMessageReceived; transportLayer.OnConnectionClosed -= TransportLayer_OnConnectionClosed; GunHooks.OnGunFire -= GunHooks_OnGunFire; PlayerHooks.OnPlayerGrabObject -= PlayerHooks_OnPlayerGrabObject; PlayerHooks.OnPlayerReleaseObject -= PlayerHooks_OnPlayerReleaseObject; transportLayer.StopListening(); MultiplayerMod.OnLevelWasLoadedEvent -= MultiplayerMod_OnLevelWasLoadedEvent; }
private void TransportLayer_OnMessageReceived(ITransportConnection arg1, P2PMessage msg) { MessageType type = (MessageType)msg.ReadByte(); switch (type) { case MessageType.GunFireHit: { GunFireHit gfm = new GunFireHit(msg); if (playerObjects.ContainsKey(gfm.playerId)) { PlayerRep pr = playerObjects[gfm.playerId]; MelonModLogger.Log("Hit local player"); if (pr.rigTransforms.main != null) { GameObject instance = GameObject.Instantiate(GunResources.HurtSFX, pr.rigTransforms.main); Destroy(instance, 3); } } break; } case MessageType.GunFire: { bool didHit; GunFireMessage gfm = new GunFireMessage(msg); Ray ray = new Ray(gfm.fireOrigin, gfm.fireDirection); if (Physics.Raycast(ray, out RaycastHit hit, int.MaxValue, ~0, QueryTriggerInteraction.Ignore)) { if (hit.transform.root.gameObject == BWUtil.RigManager) { MelonModLogger.Log("Hit BRETT!"); int random = UnityEngine.Random.Range(0, 10); BWUtil.LocalPlayerHealth.TAKEDAMAGE(gfm.bulletDamage, random == 0); GunFireHitToServer gff = new GunFireHitToServer(); SendToServer(gff, MessageSendType.Reliable); } else { MelonModLogger.Log("Hit!"); } didHit = true; }
public void StopServer() { IsRunning = false; try { foreach (PlayerRep r in playerObjects.Values) { r.Destroy(); } } catch (Exception) { MelonModLogger.LogError("Caught exception destroying player objects"); } playerObjects.Clear(); playerNames.Clear(); smallPlayerIds.Clear(); largePlayerIds.Clear(); smallIdCounter = 1; P2PMessage shutdownMsg = new P2PMessage(); shutdownMsg.WriteByte((byte)MessageType.ServerShutdown); foreach (SteamId p in players) { SteamNetworking.SendP2PPacket(p, shutdownMsg.GetBytes(), -1, 0, P2PSend.Reliable); SteamNetworking.CloseP2PSessionWithUser(p); } players.Clear(); SteamNetworking.OnP2PSessionRequest = null; SteamNetworking.OnP2PConnectionFailed = null; RichPresence.SetActivity(new Activity() { Details = "Idle", Assets = { LargeImage = "jobsim" } }); }
public void Connect(string obj) { MelonModLogger.Log("Starting client and connecting"); ServerId = ulong.Parse(obj); MelonModLogger.Log("Connecting to " + obj); P2PMessage msg = new P2PMessage(); msg.WriteByte((byte)MessageType.Join); msg.WriteByte(JobSimulatorMultiplayer.PROTOCOL_VERSION); msg.WriteUnicodeString(SteamClient.Name); SteamNetworking.SendP2PPacket(ServerId, msg.GetBytes()); isConnected = true; JobSimulatorMultiplayer.isClient = true; SteamNetworking.OnP2PSessionRequest = OnP2PSessionRequest; SteamNetworking.OnP2PConnectionFailed = OnP2PConnectionFailed; MelonCoroutines.Start(PhysicSyncLoad()); }
public static Guid CreateGuidFromData(P2PVersion ver, byte[] data) { Guid ret = Guid.Empty; if (ver == P2PVersion.P2PV1) { P2PMessage message = new P2PMessage(ver); message.ParseBytes(data); ret = new Guid( (int)message.V1Header.AckSessionId, (short)(message.Header.AckIdentifier & 0x0000FFFF), (short)((message.Header.AckIdentifier & 0xFFFF0000) >> 16), (byte)((message.V1Header.AckTotalSize & 0x00000000000000FF)), (byte)((message.V1Header.AckTotalSize & 0x000000000000FF00) >> 8), (byte)((message.V1Header.AckTotalSize & 0x0000000000FF0000) >> 16), (byte)((message.V1Header.AckTotalSize & 0x00000000FF000000) >> 24), (byte)((message.V1Header.AckTotalSize & 0x000000FF00000000) >> 32), (byte)((message.V1Header.AckTotalSize & 0x0000FF0000000000) >> 40), (byte)((message.V1Header.AckTotalSize & 0x00FF000000000000) >> 48), (byte)((message.V1Header.AckTotalSize & 0xFF00000000000000) >> 56) ); } else if (ver == P2PVersion.P2PV2) { Int32 a = BitUtility.ToInt32(data, 0, BitConverter.IsLittleEndian); Int16 b = BitUtility.ToInt16(data, 4, BitConverter.IsLittleEndian); Int16 c = BitUtility.ToInt16(data, 6, BitConverter.IsLittleEndian); byte d = data[8], e = data[9], f = data[10], g = data[11]; byte h = data[12], i = data[13], j = data[14], k = data[15]; ret = new Guid(a, b, c, d, e, f, g, h, i, j, k); } return(ret); }
public override void Start() { base.Start(); if (Sending) { ushort packNum = ++base.P2PSession.Bridge.PackageNo; // Data prep P2PDataMessage prepData = new P2PDataMessage(P2PVersion); prepData.WritePreparationBytes(); if (P2PVersion == P2PVersion.P2PV2) { prepData.V2Header.TFCombination = TFCombination.First; } SendMessage(prepData); Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Data prep sent. Sending whole data...", GetType().Name); // All chunks byte[] allData = new byte[msnObject.Size]; lock (objStream) { using (Stream s = objStream) { s.Position = 0; s.Read(allData, 0, allData.Length); } } P2PDataMessage msg = new P2PDataMessage(P2PVersion); if (P2PVersion == P2PVersion.P2PV1) { msg.V1Header.Flags = P2PFlag.Data; msg.V1Header.AckSessionId = (uint)new Random().Next(50, int.MaxValue); } else if (P2PVersion == P2PVersion.P2PV2) { msg.V2Header.TFCombination = TFCombination.MsnObject | TFCombination.First; msg.V2Header.PackageNumber = packNum; } msg.InnerBody = allData; if (P2PVersion == P2PVersion.P2PV1) { // Object transfer must be finish in MaxTimeout seconds. (p2pv1) // Because ack is received after transfer finished. SendMessage(msg, P2PBridge.MaxTimeout, delegate(P2PMessage ack) { OnTransferFinished(EventArgs.Empty); // Close after remote client sends BYE. }); } else { SendMessage(msg, 0, null); // Register the ACKHandler P2PMessage rak = new P2PMessage(P2PVersion); SendMessage(rak, P2PBridge.DefaultTimeout, delegate(P2PMessage ack) { OnTransferFinished(EventArgs.Empty); // Close after remote client sends BYE. }); } } else { objStream = new MemoryStream(); } }
private void SendToServer(P2PMessage msg, MessageSendType send) { connection.SendMessage(msg, send); }
private void TransportLayer_OnMessageReceived(ITransportConnection arg1, P2PMessage msg) { MessageType type = (MessageType)msg.ReadByte(); try { switch (type) { case MessageType.GunFire: { GunFireMessageOther gfmo = new GunFireMessageOther(msg); PlayerRep pr = GetPlayerRep(gfmo.playerId); AmmoVariables ammoVariables = new AmmoVariables() { AttackDamage = gfmo.ammoDamage, AttackType = AttackType.Piercing, cartridgeType = Cart.Cal_9mm, ExitVelocity = gfmo.exitVelocity, ProjectileMass = gfmo.projectileMass, Tracer = false }; if ((StressLevelZero.Handedness)gfmo.handedness == StressLevelZero.Handedness.RIGHT) { pr.rightGunScript.firePointTransform.position = gfmo.firepointPos; pr.rightGunScript.firePointTransform.rotation = gfmo.firepointRotation; pr.rightGunScript.muzzleVelocity = gfmo.muzzleVelocity; pr.rightBulletObject.ammoVariables = ammoVariables; pr.rightGunScript.PullCartridge(); pr.rightGunScript.Fire(); } if ((StressLevelZero.Handedness)gfmo.handedness == StressLevelZero.Handedness.LEFT) { pr.leftGunScript.firePointTransform.position = gfmo.firepointPos; pr.leftGunScript.firePointTransform.rotation = gfmo.firepointRotation; pr.leftGunScript.muzzleVelocity = gfmo.muzzleVelocity; pr.leftBulletObject.ammoVariables = ammoVariables; pr.leftGunScript.PullCartridge(); pr.leftGunScript.Fire(); } pr.faceAnimator.faceState = Source.Representations.FaceAnimator.FaceState.Angry; pr.faceAnimator.faceTime = 5; break; } case MessageType.OtherPlayerPosition: { OtherPlayerPositionMessage oppm = new OtherPlayerPositionMessage(msg); if (playerObjects.ContainsKey(oppm.playerId)) { PlayerRep pr = GetPlayerRep(oppm.playerId); pr.head.transform.position = oppm.headPos; pr.handL.transform.position = oppm.lHandPos; pr.handR.transform.position = oppm.rHandPos; pr.pelvis.transform.position = oppm.pelvisPos; pr.ford.transform.position = oppm.pelvisPos - new Vector3(0.0f, 0.3f, 0.0f); pr.footL.transform.position = oppm.lFootPos; pr.footR.transform.position = oppm.rFootPos; pr.head.transform.rotation = oppm.headRot; pr.handL.transform.rotation = oppm.lHandRot; pr.handR.transform.rotation = oppm.rHandRot; pr.pelvis.transform.rotation = oppm.pelvisRot; pr.footL.transform.rotation = oppm.lFootRot; pr.footR.transform.rotation = oppm.rFootRot; } break; } case MessageType.OtherFullRig: { OtherFullRigTransformMessage ofrtm = new OtherFullRigTransformMessage(msg); byte playerId = ofrtm.playerId; if (playerObjects.ContainsKey(ofrtm.playerId)) { PlayerRep pr = GetPlayerRep(playerId); pr.ApplyTransformMessage(ofrtm); } break; } case MessageType.ServerShutdown: { foreach (PlayerRep pr in playerObjects.Values) { pr.Delete(); } break; } case MessageType.Disconnect: { byte pid = msg.ReadByte(); playerObjects[pid].Delete(); playerObjects.Remove(pid); largePlayerIds.Remove(pid); playerNames.Remove(pid); foreach (PlayerRep pr in playerObjects.Values) { pr.faceAnimator.faceState = Source.Representations.FaceAnimator.FaceState.Sad; pr.faceAnimator.faceTime = 10; } break; } case MessageType.JoinRejected: { MelonLogger.LogError("Join rejected - you are using an incompatible version of the mod!"); Disconnect(); break; } case MessageType.SceneTransition: { SceneTransitionMessage stm = new SceneTransitionMessage(msg); if (BoneworksSceneManager.GetCurrentSceneName() != stm.sceneName) { BoneworksSceneManager.LoadScene(stm.sceneName); } break; } case MessageType.Join: { ClientJoinMessage cjm = new ClientJoinMessage(msg); largePlayerIds.Add(cjm.playerId, cjm.steamId); playerNames.Add(cjm.playerId, cjm.name); playerObjects.Add(cjm.playerId, new PlayerRep(cjm.name, cjm.steamId)); foreach (PlayerRep pr in playerObjects.Values) { pr.faceAnimator.faceState = Source.Representations.FaceAnimator.FaceState.Happy; pr.faceAnimator.faceTime = 15; } break; } case MessageType.SetPartyId: { SetPartyIdMessage spid = new SetPartyIdMessage(msg); RichPresence.SetActivity( new Activity() { Details = "Connected to a server", Secrets = new ActivitySecrets() { Join = ServerId.ToString() }, Party = new ActivityParty() { Id = spid.partyId, Size = new PartySize() { CurrentSize = 1, MaxSize = MultiplayerMod.MAX_PLAYERS } } }); break; } case MessageType.EnemyRigTransform: { enemyPoolManager.FindMissingPools(); EnemyRigTransformMessage ertm = new EnemyRigTransformMessage(msg); Pool pool = enemyPoolManager.GetPool(ertm.enemyType); // HORRID PERFORMANCE Transform enemyTf = pool.transform.GetChild(ertm.poolChildIdx); GameObject rootObj = enemyTf.Find("enemyBrett@neutral").gameObject; BoneworksRigTransforms brt = BWUtil.GetHumanoidRigTransforms(rootObj); BWUtil.ApplyRigTransform(brt, ertm); break; } case MessageType.IdAllocation: { IDAllocationMessage iam = new IDAllocationMessage(msg); GameObject obj = BWUtil.GetObjectFromFullPath(iam.namePath); if (!obj) { MelonLogger.LogWarning("Got IdAllocation for nonexistent object???"); } ObjectIDManager.AddObject(iam.allocatedId, obj); var so = obj.AddComponent <SyncedObject>(); so.ID = iam.allocatedId; so.owner = iam.initialOwner; so.rb = obj.GetComponent <Rigidbody>(); syncedObjects.Add(so); if (so.owner != localSmallId) { so.rb.isKinematic = true; } MelonLogger.Log($"ID Allocation: {iam.namePath}, {so.ID}"); break; } case MessageType.ObjectSync: { ObjectSyncMessage osm = new ObjectSyncMessage(msg); GameObject obj = ObjectIDManager.GetObject(osm.id); if (!obj) { MelonLogger.LogError($"Couldn't find object with ID {osm.id}"); } else { obj.transform.position = osm.position; obj.transform.rotation = osm.rotation; } break; } case MessageType.ChangeObjectOwnership: { var coom = new ChangeObjectOwnershipMessage(msg); var obj = ObjectIDManager.GetObject(coom.objectId); var so = obj.GetComponent <SyncedObject>(); so.owner = coom.ownerId; if (so.owner == localSmallId) { so.rb.isKinematic = false; so.rb.velocity = coom.linVelocity; so.rb.angularVelocity = coom.angVelocity; } else { so.rb.isKinematic = true; } MelonLogger.Log($"Object {coom.objectId} is now owned by {coom.ownerId} (kinematic: {so.rb.isKinematic})"); break; } case MessageType.SetLocalSmallId: { var slsi = new SetLocalSmallIdMessage(msg); localSmallId = slsi.smallId; break; } } } catch (Exception e) { MelonLogger.LogError($"Caught exception in message handler for message {type}: {e}"); } }
private void SendToId(INetworkMessage msg, MessageSendType send, SteamId id) { P2PMessage pMsg = msg.MakeMsg(); playerConnections[id].SendMessage(pMsg, send); }
/// <summary> /// Sends a P2P message. /// </summary> /// <param name="p2pMessage"></param> public void SendMessage(P2PMessage p2pMessage) { SendMessage(p2pMessage, 0, null); }
private void SendChunk() { if (!_sendingData) { return; } P2PDataMessage p2pChunk = new P2PDataMessage(P2PVersion); long offset = _dataStream.Position; // First chunk if (offset == 0) { if (P2PVersion == P2PVersion.P2PV1) { P2PSession.IncreaseLocalIdentifier(); p2pChunk.V1Header.TotalSize = (ulong)_dataStream.Length; } else if (P2PVersion == P2PVersion.P2PV2) { p2pChunk.V2Header.TFCombination = TFCombination.First; } } p2pChunk.Header.Identifier = P2PSession.LocalIdentifier; p2pChunk.WriteBytes(_dataStream, P2PSession.Bridge.MaxDataSize); AckHandler ackHandler = null; int ackTimeout = P2PBridge.MaxTimeout; if (P2PVersion == P2PVersion.P2PV1) { p2pChunk.V1Header.Flags = P2PFlag.FileData; } else if (P2PVersion == P2PVersion.P2PV2) { p2pChunk.V2Header.PackageNumber = packNum; p2pChunk.V2Header.TFCombination |= TFCombination.FileTransfer; if (p2pv2NextRAK < DateTime.Now) { _sendingData = false; // Activate when ack received. p2pChunk.V2Header.OperationCode |= (byte)OperationCode.RAK; p2pv2NextRAK = DateTime.Now.AddSeconds(8); ackTimeout = P2PBridge.DefaultTimeout; ackHandler = delegate(P2PMessage ack) { _sendingData = true; // Ack received, continue sending... SendChunk(); }; } } if (_dataStream.Position == _dataStream.Length) { _sendingData = false; SendMessage(p2pChunk); // This is the last chunk of data, register the ACKHandler P2PMessage rak = new P2PMessage(P2PVersion); SendMessage(rak, P2PBridge.DefaultTimeout, delegate(P2PMessage ack) { Abort(); OnTransferFinished(EventArgs.Empty); }); } else { SendMessage(p2pChunk, ackTimeout, ackHandler); } OnProgressed(EventArgs.Empty); }
private void TransportLayer_OnMessageReceived(ITransportConnection connection, P2PMessage msg) { MessageType type = (MessageType)msg.ReadByte(); switch (type) { case MessageType.GunFire: { GunFireMessage gfm = new GunFireMessage(msg); byte LocalplayerId = smallPlayerIds[connection.ConnectedTo]; if (playerObjects.ContainsKey(LocalplayerId)) { PlayerRep pr = playerObjects[LocalplayerId]; AmmoVariables ammoVariables = new AmmoVariables() { AttackDamage = gfm.ammoDamage, AttackType = AttackType.Piercing, cartridgeType = Cart.Cal_9mm, ExitVelocity = gfm.exitVelocity, ProjectileMass = gfm.projectileMass, Tracer = false }; if ((StressLevelZero.Handedness)gfm.handedness == StressLevelZero.Handedness.RIGHT) { pr.rightGunScript.firePointTransform.position = gfm.firepointPos; pr.rightGunScript.firePointTransform.rotation = gfm.firepointRotation; pr.rightGunScript.muzzleVelocity = gfm.muzzleVelocity; pr.rightBulletObject.ammoVariables = ammoVariables; pr.leftGunScript.PullCartridge(); pr.rightGunScript.Fire(); } if ((StressLevelZero.Handedness)gfm.handedness == StressLevelZero.Handedness.LEFT) { pr.leftGunScript.firePointTransform.position = gfm.firepointPos; pr.leftGunScript.firePointTransform.rotation = gfm.firepointRotation; pr.leftGunScript.muzzleVelocity = gfm.muzzleVelocity; pr.leftBulletObject.ammoVariables = ammoVariables; pr.leftGunScript.PullCartridge(); pr.leftGunScript.Fire(); } GunFireMessageOther gfmo = new GunFireMessageOther() { playerId = LocalplayerId, handedness = gfm.handedness, firepointPos = gfm.firepointPos, firepointRotation = gfm.firepointRotation, ammoDamage = gfm.ammoDamage, projectileMass = gfm.projectileMass, exitVelocity = gfm.exitVelocity, muzzleVelocity = gfm.muzzleVelocity }; pr.faceAnimator.faceState = Source.Representations.FaceAnimator.FaceState.Angry; pr.faceAnimator.faceTime = 5; ServerSendToAllExcept(gfmo, MessageSendType.Reliable, connection.ConnectedTo); } break; } case MessageType.Join: { if (msg.ReadByte() != MultiplayerMod.PROTOCOL_VERSION) { // Somebody tried to join with an incompatible verison P2PMessage m2 = new P2PMessage(); m2.WriteByte((byte)MessageType.JoinRejected); connection.SendMessage(m2, MessageSendType.Reliable); connection.Disconnect(); } else { MelonLogger.Log("Player joined with ID: " + connection.ConnectedTo); if (players.Contains(connection.ConnectedTo)) { players.Remove(connection.ConnectedTo); } players.Add(connection.ConnectedTo); MelonLogger.Log("Player count: " + players.Count); byte newPlayerId = smallIdCounter; if (smallPlayerIds.ContainsKey(newPlayerId)) { smallPlayerIds.Remove(newPlayerId); } smallPlayerIds.Add(connection.ConnectedTo, newPlayerId); if (largePlayerIds.ContainsKey(newPlayerId)) { largePlayerIds.Remove(newPlayerId); } largePlayerIds.Add(newPlayerId, connection.ConnectedTo); smallIdCounter++; playerConnections.Add(connection.ConnectedTo, connection); string name = msg.ReadUnicodeString(); MelonLogger.Log("Name: " + name); foreach (var smallId in playerNames.Keys) { ClientJoinMessage cjm = new ClientJoinMessage { playerId = smallId, name = playerNames[smallId], steamId = largePlayerIds[smallId] }; connection.SendMessage(cjm.MakeMsg(), MessageSendType.Reliable); } ClientJoinMessage cjm2 = new ClientJoinMessage { playerId = 0, name = SteamClient.Name, steamId = SteamClient.SteamId }; connection.SendMessage(cjm2.MakeMsg(), MessageSendType.Reliable); if (playerNames.ContainsKey(newPlayerId)) { playerNames.Remove(newPlayerId); } playerNames.Add(newPlayerId, name); ClientJoinMessage cjm3 = new ClientJoinMessage { playerId = newPlayerId, name = name, steamId = connection.ConnectedTo }; ServerSendToAllExcept(cjm3, MessageSendType.Reliable, connection.ConnectedTo); if (playerObjects.ContainsKey(newPlayerId)) { playerObjects.Remove(newPlayerId); } playerObjects.Add(newPlayerId, new PlayerRep(name, connection.ConnectedTo)); RichPresence.SetActivity( new Activity() { Details = "Hosting a server", Secrets = new ActivitySecrets() { Join = SteamClient.SteamId.ToString() }, Party = new ActivityParty() { Id = partyId, Size = new PartySize() { CurrentSize = players.Count + 1, MaxSize = MultiplayerMod.MAX_PLAYERS } } }); SceneTransitionMessage stm = new SceneTransitionMessage() { sceneName = BoneworksSceneManager.GetCurrentSceneName() }; connection.SendMessage(stm.MakeMsg(), MessageSendType.Reliable); SetPartyIdMessage spid = new SetPartyIdMessage() { partyId = partyId }; connection.SendMessage(spid.MakeMsg(), MessageSendType.Reliable); SetLocalSmallIdMessage slsi = new SetLocalSmallIdMessage() { smallId = newPlayerId }; connection.SendMessage(slsi.MakeMsg(), MessageSendType.Reliable); foreach (var so in syncObjs) { var iam = new IDAllocationMessage { allocatedId = so.ID, namePath = BWUtil.GetFullNamePath(so.gameObject), initialOwner = so.owner }; connection.SendMessage(iam.MakeMsg(), MessageSendType.Reliable); } ui.SetPlayerCount(players.Count, MultiplayerUIState.Server); foreach (PlayerRep pr in playerObjects.Values) { pr.faceAnimator.faceState = Source.Representations.FaceAnimator.FaceState.Happy; pr.faceAnimator.faceTime = 15; } } break; } case MessageType.Disconnect: { MelonLogger.Log("Player left with ID: " + connection.ConnectedTo); byte smallId = smallPlayerIds[connection.ConnectedTo]; playerObjects[smallId].Delete(); playerObjects.Remove(smallId); players.RemoveAll((ulong val) => val == connection.ConnectedTo); smallPlayerIds.Remove(connection.ConnectedTo); P2PMessage disconnectMsg = new P2PMessage(); disconnectMsg.WriteByte((byte)MessageType.Disconnect); disconnectMsg.WriteByte(smallId); foreach (SteamId p in players) { playerConnections[p].SendMessage(disconnectMsg, MessageSendType.Reliable); } foreach (PlayerRep pr in playerObjects.Values) { pr.faceAnimator.faceState = Source.Representations.FaceAnimator.FaceState.Sad; pr.faceAnimator.faceTime = 6; } break; } case MessageType.FullRig: { FullRigTransformMessage frtm = new FullRigTransformMessage(msg); byte playerId = smallPlayerIds[connection.ConnectedTo]; if (playerObjects.ContainsKey(playerId)) { PlayerRep pr = playerObjects[playerId]; if (pr.rigTransforms.main != null) { //ApplyTransformMessage(pr, frtm); pr.ApplyTransformMessage(frtm); OtherFullRigTransformMessage ofrtm = new OtherFullRigTransformMessage { playerId = playerId, posMain = frtm.posMain, posRoot = frtm.posRoot, posLHip = frtm.posLHip, posRHip = frtm.posRHip, posLKnee = frtm.posLKnee, posRKnee = frtm.posRKnee, posLAnkle = frtm.posLAnkle, posRAnkle = frtm.posRAnkle, posSpine1 = frtm.posSpine1, posSpine2 = frtm.posSpine2, posSpineTop = frtm.posSpineTop, posLClavicle = frtm.posLClavicle, posRClavicle = frtm.posRClavicle, posNeck = frtm.posNeck, posLShoulder = frtm.posLShoulder, posRShoulder = frtm.posRShoulder, posLElbow = frtm.posLElbow, posRElbow = frtm.posRElbow, posLWrist = frtm.posLWrist, posRWrist = frtm.posRWrist, rotMain = frtm.rotMain, rotRoot = frtm.rotRoot, rotLHip = frtm.rotLHip, rotRHip = frtm.rotRHip, rotLKnee = frtm.rotLKnee, rotRKnee = frtm.rotRKnee, rotLAnkle = frtm.rotLAnkle, rotRAnkle = frtm.rotRAnkle, rotSpine1 = frtm.rotSpine1, rotSpine2 = frtm.rotSpine2, rotSpineTop = frtm.rotSpineTop, rotLClavicle = frtm.rotLClavicle, rotRClavicle = frtm.rotRClavicle, rotNeck = frtm.rotNeck, rotLShoulder = frtm.rotLShoulder, rotRShoulder = frtm.rotRShoulder, rotLElbow = frtm.rotLElbow, rotRElbow = frtm.rotRElbow, rotLWrist = frtm.rotLWrist, rotRWrist = frtm.rotRWrist }; ServerSendToAllExcept(ofrtm, MessageSendType.Unreliable, connection.ConnectedTo); } } break; } case MessageType.IdRequest: { var idrqm = new IDRequestMessage(msg); MelonLogger.Log("ID request: " + idrqm.namePath); var obj = BWUtil.GetObjectFromFullPath(idrqm.namePath); SetupSyncFor(obj, idrqm.initialOwner); break; } case MessageType.ChangeObjectOwnership: { var coom = new ChangeObjectOwnershipMessage(msg); if (coom.ownerId != smallPlayerIds[connection.ConnectedTo] && coom.ownerId != 0) { MelonLogger.LogError("Invalid object ownership change??"); } if (!ObjectIDManager.objects.ContainsKey(coom.objectId)) { MelonLogger.LogError($"Got ownership change for invalid object ID {coom.objectId}"); } MelonLogger.Log($"Object {coom.objectId} is now owned by {coom.ownerId}"); var obj = ObjectIDManager.GetObject(coom.objectId); var so = obj.GetComponent <SyncedObject>(); so.owner = coom.ownerId; if (so.owner != 0) { coom.linVelocity = so.rb.velocity; coom.angVelocity = so.rb.angularVelocity; so.rb.isKinematic = true; } else if (so.owner == 0) { so.rb.isKinematic = false; so.rb.velocity = coom.linVelocity; so.rb.angularVelocity = coom.angVelocity; } ServerSendToAll(coom, MessageSendType.Reliable); break; } case MessageType.ObjectSync: { ObjectSyncMessage osm = new ObjectSyncMessage(msg); GameObject obj = ObjectIDManager.GetObject(osm.id); var so = obj.GetComponent <SyncedObject>(); if (!obj) { MelonLogger.LogError($"Couldn't find object with ID {osm.id}"); } else { if (so.owner != smallPlayerIds[connection.ConnectedTo]) { MelonLogger.LogError("Got object sync from client that doesn't own the object"); } else { obj.transform.position = osm.position; obj.transform.rotation = osm.rotation; ServerSendToAllExcept(osm, MessageSendType.Reliable, connection.ConnectedTo); } } break; } default: MelonLogger.Log("Unknown message type: " + type.ToString()); break; } }
private Packet CreatePacket(P2PMessage message) { return(new Packet(message.Protocol, message.PacketType, _serializer.Serialize(message))); }