Beispiel #1
0
        public void SetupSyncFor(GameObject obj, byte initialOwner = 0)
        {
            ushort id = ObjectIDManager.AllocateID();

            ObjectIDManager.AddObject(id, obj);

            var so = obj.AddComponent <SyncedObject>();

            so.owner = initialOwner;
            so.ID    = id;
            so.rb    = obj.GetComponent <Rigidbody>();
            syncObjs.Add(so);

            var iam = new IDAllocationMessage
            {
                allocatedId  = id,
                namePath     = BWUtil.GetFullNamePath(obj),
                initialOwner = so.owner
            };

            ServerSendToAll(iam, MessageSendType.Reliable);
        }
Beispiel #2
0
        private void PlayerHooks_OnPlayerGrabObject(GameObject grabObj)
        {
            var rb = grabObj.GetComponentInParent <Rigidbody>();

            if (rb == null)
            {
                return;
            }
            MelonLogger.Log($"Grabbed {rb.gameObject.name}");

            var obj = rb.gameObject;
            var so  = obj.GetComponent <SyncedObject>();

            if (!so)
            {
                MelonLogger.Log($"Requesting ID for {obj.name}");
                var req = new IDRequestMessage
                {
                    namePath     = BWUtil.GetFullNamePath(obj),
                    initialOwner = localSmallId
                };

                SendToServer(req, MessageSendType.Reliable);
            }
            else
            {
                MelonLogger.Log($"Grapped object has ID of {so.ID}");
                var coom = new ChangeObjectOwnershipMessage
                {
                    objectId = so.ID,
                    ownerId  = localSmallId
                };

                SendToServer(coom, MessageSendType.Reliable);
            }
        }
Beispiel #3
0
        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;
            }
        }